<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected{color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity=60)';}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0px; top:0px;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser

Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])

<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]

----
Also see [[AdvancedOptions]]
<<importTiddlers>>
/***
|''Name:''|ProcessingjsPlugin|
|''Description:''|TiddlyWiki Bundle of John Ressig's processing.js|
|''Date:''|May 9, 2008|
|''Author:''|PaulDowney (psd (at) osmosoft (dot) com)|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/PaulDowney/plugins/ProcessingPlugin.js|
|''Version:''|0.3|
|''License:''|[[MIT license]]|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''~CoreVersion:''|2.2|
With contributions from Simon Baird.

***/

//{{{
// Ensure Plugin is only installed once.
if(!version.extensions.Processingjs) {
version.extensions.Processingjs = {installed:true};

config.macros.Processing = {
	counter: 0,
	handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		var id = "processingcanvas"+this.counter;
		var canvas = createTiddlyElement(place,"canvas",id);

		// inlined code
		var code = paramString;

		// quick and dirty grab of code from a named tiddler
		if (store.tiddlerExists(params[0])) {
			code = store.getTiddlerText(params[0]);
		}

		// or with no params, grab code from this tiddler
		if (paramString.trim() == '') {
			code = tiddler.text;
		}

		createTiddlyElement(place,"br");
		var restartBtn = createTiddlyButton(place,"restart","restart",function() {
				story.refreshTiddler(tiddler.title,null,true);
				return false;
			},
			'processingRestart' // it's a class so you can style the button
		);

		var sketch = new Processing(canvas, code);
	}
};

// requires 2.4
merge(config.macros.view.views,{
	processing: function(value,place,params,wikifier,paramString,tiddler) {
		wikify("<<Processing\n"+value+"\n>>",place,highlightHack,tiddler);
	}
});

} //# end of "install only once"
//}}}

TiddlyProcessing
TiddlyProcessing
[[Basic Examples|BasicExample]]
ProcessingjsPlugin
Processing.js in TiddlyWiki
TiddlyProcessing

[[TiddlyWiki|http://tiddlywiki.com]], a wiki in a single HTML page. Open a [[Downloaded]] a copy of this page in Firefox, and you'll be able to edit the examples and save your changes locally on your computer. For more help on using TiddlyWiki, including support for other browsers, see [[Download Software|http://www.tiddlywiki.com/#DownloadSoftware]].

If you have questions, the ~TiddlyWiki community is incredibly helpful - there's a [[developer's group|http://groups.google.com/group/TiddlyWikiDev]] and a [[user's group|http://groups.google.com/group/TiddlyWiki]] on Google Groups. 
TiddlyProcessing is a TiddlyWiki containing [[John Ressig|http://ejohn.org]]'s [[Processing.js|http://ejohn.org/apps/processing.js/]] [[basic examples|BasicExample]]. Double click an example, e.g. [[Clock]] to view and edit the source. Most of the examples work, with the notable exception of those involving images.  [[Download|./download.php]] this file and reopen it in Firefox to save your work.

[[Simon Baird|http://simonbaird.com/]] has made some great tweaks and examples, and put [[his version|http://tiddlyprocessing-simon.tiddlyspot.com]] up on [[TiddlySpot|http://tiddlyspot.com]], a great place to store your ~TiddlyWikis.
by Daniel Shiffman. Create a more complex wave by adding two waves together.

<<Processing 

int xspacing = 8;   // How far apart should each horizontal location be spaced
int w;              // Width of entire wave
int maxwaves = 4;   // total # of waves to add together

float theta = 0.0f;
float[] amplitude = new float[maxwaves];   // Height of wave
float[] dx = new float[maxwaves];          // Value for incrementing X, to be calculated as a function of period and xspacing
float[] yvalues;                           // Using an array to store height values for the wave (not entirely necessary)

void setup() {
  size(200,200);
  frameRate(30);
  colorMode(RGB,255,255,255,100);
  smooth();
  w = width+16;

  for (int i = 0; i < maxwaves; i++) {
    amplitude[i] = random(10,30);
    float period = random(100,300); // How many pixels before the wave repeats
    dx[i] = (TWO_PI / period) * xspacing;
  }

  yvalues = new float[w/xspacing];
}

void draw() {
  background(0);
  calcWave();
  renderWave();
}

void calcWave() {
  // Increment theta (try different values for 'angular velocity' here
  theta += 0.02;

  // Set all height values to zero
  for (int i = 0; i < yvalues.length; i++) {
    yvalues[i] = 0.0f;
  }
 
  // Accumulate wave height values
  for (int j = 0; j < maxwaves; j++) {
    float x = theta;
    for (int 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];
    }
  }
}

void renderWave() {
  // A simple way to draw the wave with an ellipse at each location
  noStroke();
  fill(255,50);
  ellipseMode(CENTER);
  for (int x = 0; x < yvalues.length; x++) {
    ellipse(x*xspacing,width/2+yvalues[x],16,16);
  }
}

>>

Taken from [[basic/additivewave.html|http://ejohn.org/apps/processing.js/examples/basic/additivewave.html]]
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 PImage. Created 29 April 2003.

<<Processing 

PImage img;
PImage maskImg;

void setup() 
{
  size(200,200);
  img = loadImage("test.jpg");
  maskImg = loadImage("mask.jpg");
  img.mask(maskImg);
}

void draw() 
{
  background((mouseX+mouseY)/1.5);
  image(img, 50, 50);
  image(img, mouseX-50, mouseY-50);
}

>>

Taken from [[basic/alphamask.html|http://ejohn.org/apps/processing.js/examples/basic/alphamask.html]]
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 pushMatrix() and popMatrix() group.

<<Processing 

float x = 50;
float y = 100;
float angle1 = 0.0;
float angle2 = 0.0;
float segLength = 50;

void setup() {
  size(200, 200);
  smooth(); 
  strokeWeight(20.0);
  stroke(0, 100);
}

void draw() {
  background(226);
  
  angle1 = (mouseX/float(width) - 0.5) * -PI;
  angle2 = (mouseY/float(height) - 0.5) * PI;
  
  pushMatrix();
  segment(x, y, angle1); 
  segment(segLength, 0, angle2);
  popMatrix();
}

void segment(float x, float y, float a) {
  translate(x, y);
  rotate(a);
  line(0, 0, segLength, 0);
}

>>

Taken from [[basic/arm.html|http://ejohn.org/apps/processing.js/examples/basic/arm.html]]
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 "coswav" is created and filled with the cosine values. This data is displayed three separate ways on the screen.

<<Processing 

size(200, 200);

float[] coswave = new float[width];

for(int i=0; i<width; i++) {
  float ratio = (float)i/(float)width;
  coswave[i] = abs( cos(ratio*PI) );
}

for(int i=0; i<width; i++) {
  stroke(coswave[i]*255);
  line(i, 0, i, width/3);
}

for(int i=0; i<width; i++) {
  stroke(coswave[i]*255/4);
  line(i, width/3, i, width/3*2);
}

for(int i=0; i<width; i++) {
  stroke(255-coswave[i]*255);
  line(i, width/3*2, i, height);
}

>>

Taken from [[basic/array.html|http://ejohn.org/apps/processing.js/examples/basic/array.html]]
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.

<<Processing 

float[][] distances;
float maxDistance;

size(200, 200);
background(0);
maxDistance = dist(width/2, height/2, width, height);
distances = new float[width][height];
for(int i=0; i<height; i++) {
  for(int j=0; j<width; j++) {
    float d = dist(width/2, height/2, j, i);
    distances[j][i] = d/maxDistance * 255; 
  }
}

for(int i=0; i<height; i+=2) {
  for(int j=0; j<width; j+=2) {
    stroke(distances[j][i]);
    point(j, i);
  }
}

>>

Taken from [[basic/array2d.html|http://ejohn.org/apps/processing.js/examples/basic/array2d.html]]
Demonstrates the syntax for creating an array of custom objects.

<<Processing 

int unit = 40;
int num;
Module[] mods;

void setup() 
{
  size(200, 200);
  background(176);
  noStroke();
  
  num = width/unit * width/unit;
  mods = new Module[num];
  
  for (int i=0; i<height/unit; i++) {
    for(int j=0; j<height/unit; j++) {
      int index = i*height/unit + j;
      mods[index] = new Module(j*unit, i*unit, unit/2, unit/2, random(0.05, 0.8));  
    }
  }
}

void draw() 
{
  for(int i=0; i<num; i++) {
    mods[i].update();
    mods[i].draw();
  }
}

class Module {
  float mx, my;
  int size = unit;
  float x, y = 0;
  int xdir = 1;
  int ydir = 1;
  float speed; 
  
  // Contructor (required)
  Module(float imx, float imy, float ix, float iy, float ispeed) {
    mx = imy;
    my = imx;
    x = int(ix);
    y = int(iy);
    speed = ispeed;
  }
  
  // Custom method for updating the variables
  void update() {
    x = x + (speed * xdir);
    if (x >= size || x <= 0) {
      xdir *= -1;
      x = x + (1 * xdir);
      y = y + (1 * ydir);
    }
    if (y >= size || y <= 0) {
      ydir *= -1;
      y = y + (1 * ydir);
    }
  }
  
  // Custom method for drawing the object
  void draw() {
    stroke(second()*4);
    point(mx+x-1, my+y-1);
  }
}

>>

Taken from [[basic/arrayobjects.html|http://ejohn.org/apps/processing.js/examples/basic/arrayobjects.html]]
This example presents the fastest way to load a background image into Processing. To load an image as the background, it must be the same width and height as the program.

<<Processing 

PImage bg;
int a; 

void setup() 
{
  size(200,200);
  frameRate(30);
  // The background image must be the same size as the parameters
  // into the size() method. In this program, the size of "milan_rubbish.jpg"
  // is 200 x 200 pixels.
  bg = loadImage("milan_rubbish.jpg");
}

void draw() 
{
  background(bg);

  a = (a + 1)%(width+32);
  stroke(226, 204, 0);
  line(0, a, width, a-26);
  line(0, a-6, width, a-32);
}

>>

Taken from [[basic/backgroundimage.html|http://ejohn.org/apps/processing.js/examples/basic/backgroundimage.html]]
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.

<<Processing 

size(200, 200); 
background(0); 
stroke(255);
noFill();
smooth(); 

for(int i = 0; i < 100; i += 20) {
  bezier(90-(i/2.0), 20+i, 210, 10, 220, 150, 120-(i/8.0), 150+(i/4.0));
}

>>

Taken from [[basic/bezier.html|http://ejohn.org/apps/processing.js/examples/basic/bezier.html]]
by Rusty Robison. Brightness is the relative lightness or darkness of a color. Move the cursor vertically over each bar to alter its brightness.

<<Processing 

int barWidth = 5;
int[] brightness;

void setup() 
{
  size(200, 200);
  colorMode(HSB, 360, height, height);  
  brightness = new int[width/barWidth];
}

void draw() 
{
  int j = 0;
  for (int i = 0; i <= (width-barWidth); i += barWidth) {  
    noStroke();
    if ((mouseX > i) && (mouseX < i+barWidth)) {
      brightness[j] = mouseY;
    }
    fill(i, height, brightness[j]);
    rect(i, 0, barWidth, height);  
    j++;
  }
}

>>

Taken from [[basic/brightness.html|http://ejohn.org/apps/processing.js/examples/basic/brightness.html]]
Click on the image to give it focus and then type letters to shift the location of the image. Characters are typographic symbols such as A, d, and %. The character datatype, abbreviated as char, stores letters and symbols in the Unicode format, a coding system developed to support a variety of world languages. Characters are distinguished from other symbols by putting them between single quotes ('P'). A string is a sequence of characters. A string is noted by surrounding a group of letters with double quotes ("Processing"). Chars and strings are most often used with the keyboard methods, to display text to the screen, and to load images or files.

<<Processing 

PImage frog;
PFont fontA;
int lettersize = 90;
int xoffset;
char letter;

void setup() 
{
  size(200, 200);
  fontA = loadFont("Arial"); 
  textFont(fontA); 
  textSize(lettersize);
    
  // The String datatype must be capitalized because it is a complex datatype.
  // A String is actually a class with its own methods, some of which are
  // featured below.
  String name= "rathausFrog";
  String extension = ".jpg";
  int nameLength = name.length();
  println("The length of " + name + " is " + nameLength + ".");
  name = name.concat(extension);
  nameLength = name.length();
  println("The length of " + name + " is " + nameLength + ".");

  // The parameter for the loadImage() method must be a string
  // This line could also be written "frog = loadImage("rathausFrog.jpg");
  frog = loadImage(name);
}

void draw() 
{
  background(51); // Set background to dark gray
  
  image(frog, xoffset, 0);
  
  // Draw an X
  line(0, 0, width, height);  
  line(0, height, width, 0); 
  
  // Get the width of the letter
  int letterWidth = int(fontA.width(letter) * lettersize);
      
  // Draw the letter to the center of the screen
  text(letter, width/2-letterWidth/2, height/2);
}

void keyPressed()
{
  // The variable "key" always contains the value of the most recent key pressed.
  // If the key is an upper or lowercase letter between 'A' and 'z'
  // the image is shifted to the corresponding value of that key
  if(key >= 'A' && key <= 'z') {
    letter = char(key);
    // Scale the values to numbers between 0 and 100
    float scale = 100.0/57.0;
    int temp = int((key - 'A') * scale);
    // Set the offset for the image
    xoffset = temp;
    println(key);
  }
}

>>

Taken from [[basic/charactersstrings.html|http://ejohn.org/apps/processing.js/examples/basic/charactersstrings.html]]
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. *

<<Processing 

void setup() {
  size(200, 200);
  stroke(255);
  smooth();
}
void draw() {
  background(0);
  fill(80);
  noStroke();
  // Angles for sin() and cos() start at 3 o'clock;
  // subtract HALF_PI to make them start at the top
  ellipse(100, 100, 160, 160);
  float s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;
  float m = map(minute(), 0, 60, 0, TWO_PI) - HALF_PI;
  float h = map(hour() % 12, 0, 12, 0, TWO_PI) - HALF_PI;
  stroke(255);
  strokeWeight(1);
  line(100, 100, cos(s) * 72 + 100, sin(s) * 72 + 100);
  strokeWeight(2);
  line(100, 100, cos(m) * 60 + 100, sin(m) * 60 + 100);
  strokeWeight(4);
  line(100, 100, cos(h) * 50 + 100, sin(h) * 50 + 100);
}

>>

Taken from [[basic/clock.html|http://ejohn.org/apps/processing.js/examples/basic/clock.html]]
by Ira Greenberg. The primaries are red, yellow, and blue. The secondaries are green, purple, and orange. The tertiaries are  yellow-orange, red-orange, red-purple, blue-purple, blue-green, and yellow-green. Create a shade or tint of the subtractive color wheel using SHADE or TINT parameters.

<<Processing 

int segs = 12;
int steps = 6;
float rotAdjust = radians(360.0/segs/2.0);
float radius = 95.0;
float segWidth = radius/steps;
float interval = TWO_PI/segs;
int SHADE = 0;
int TINT = 1;

void setup(){
  size(200, 200);
  background(127);
  smooth();
  ellipseMode(CENTER_RADIUS);
  noStroke();
 // you can substitue TINT for SHADE argument
 createWheel(width/2, height/2, SHADE);
}

void createWheel(int x, int y, int valueShift){
  if (valueShift == SHADE){
    for (int j=0; j<steps; j++){
      color[]cols = { 
        color(255-(255/steps)*j, 255-(255/steps)*j, 0), 
        color(255-(255/steps)*j, (255/1.5)-((255/1.5)/steps)*j, 0), 
        color(255-(255/steps)*j, (255/2)-((255/2)/steps)*j, 0), 
        color(255-(255/steps)*j, (255/2.5)-((255/2.5)/steps)*j, 0), 
        color(255-(255/steps)*j, 0, 0), 
        color(255-(255/steps)*j, 0, (255/2)-((255/2)/steps)*j), 
        color(255-(255/steps)*j, 0, 255-(255/steps)*j), 
        color((255/2)-((255/2)/steps)*j, 0, 255-(255/steps)*j), 
        color(0, 0, 255-(255/steps)*j),
        color(0, 255-(255/steps)*j, (255/2.5)-((255/2.5)/steps)*j), 
        color(0, 255-(255/steps)*j, 0), 
        color((255/2)-((255/2)/steps)*j, 255-(255/steps)*j, 0) };
      for (int i=0; i< segs; i++){
        fill(cols[i]);
        arc(x, y, radius, radius, interval*i+rotAdjust, interval*(i+1)+rotAdjust);
      }
      radius -= segWidth;
    }
  } else  if (valueShift == TINT){
    for (int j=0; j<steps; j++){
      color[]cols = { 
        color((255/steps)*j, (255/steps)*j, 0), 
        color((255/steps)*j, ((255/1.5)/steps)*j, 0), 
        color((255/steps)*j, ((255/2)/steps)*j, 0), 
        color((255/steps)*j, ((255/2.5)/steps)*j, 0), 
        color((255/steps)*j, 0, 0), 
        color((255/steps)*j, 0, ((255/2)/steps)*j), 
        color((255/steps)*j, 0, (255/steps)*j), 
        color(((255/2)/steps)*j, 0, (255/steps)*j), 
        color(0, 0, (255/steps)*j),
        color(0, (255/steps)*j, ((255/2.5)/steps)*j), 
        color(0, (255/steps)*j, 0), 
        color(((255/2)/steps)*j, (255/steps)*j, 0) };
      for (int i=0; i< segs; i++){
        fill(cols[i]);
        arc(x, y, radius, radius, interval*i+rotAdjust, interval*(i+1)+rotAdjust);
      }
      radius -= segWidth;
    }
  } 
}

>>

Taken from [[basic/colorwheel.html|http://ejohn.org/apps/processing.js/examples/basic/colorwheel.html]]
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.

<<Processing 

EggRing er1, er2;

void setup() 
{
  size(200, 200);
  smooth();
  er1 = new EggRing(66, 132, 0.1, 66);
  er2 = new EggRing(132, 180, 0.05, 132);
}

void draw() 
{
  background(0);
  er1.transmit();
  er2.transmit();
}

class EggRing 
{
  Egg ovoid;
  Ring circle = new Ring();
  EggRing(int x, int y, float t, float sp) {
    ovoid = new Egg(x, y, t, sp);
    circle.start(x, y - sp/2);
  }
  void transmit() {
    ovoid.wobble();
    ovoid.display();
    circle.grow();
    circle.display();
    if (circle.on == false) {
      circle.on = true;
    }
  }
}

class Egg {
  float x, y; // X-coordinate, y-coordinate
  float tilt; // Left and right angle offset
  float angle; // Used to define the tilt
  float scalar; // Height of the egg
  // Constructor
  Egg(int xpos, int ypos, float t, float s) {
    x = xpos;
    y = ypos;
    tilt = t;
    scalar = s / 100.0;
  }
  void wobble() {
    tilt = cos(angle) / 8;
    angle += 0.1;
  }
  void display() {
    noStroke();
    fill(255);
    pushMatrix();
    translate(x, y);
    rotate(tilt);
    scale(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();
    popMatrix();
  }
}

class Ring {
  float x, y; // X-coordinate, y-coordinate
  float diameter; // Diameter of the ring
  boolean on = false; // Turns the display on and off
  void start(float xpos, float ypos) {
    x = xpos;
    y = ypos;
    on = true;
    diameter = 1;
  }
  void grow() {
    if (on == true) {
      diameter += 0.5;
      if (diameter > width*2) {
        diameter = 0.0;
      }
    }
  }
  void display() {
    if (on == true) {
      noFill();
      strokeWeight(4);
      stroke(155, 153);
      ellipse(x, y, diameter, diameter);
    }
  }
}

>>

Taken from [[basic/compositeobjects.html|http://ejohn.org/apps/processing.js/examples/basic/compositeobjects.html]]
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.

<<Processing 

size(200, 200);
background(0);

for(int 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(153);
    line(i, 40, i, height/2);
  } else {
    stroke(102);
    line(i, 20, i, 180); 
  }
}

>>

Taken from [[basic/conditionals1.html|http://ejohn.org/apps/processing.js/examples/basic/conditionals1.html]]
We extend the language of conditionals by adding the keyword "else". This allows conditionals to ask two or more sequential questions, each with a different action.

<<Processing 

size(200, 200);
background(0);

for(int i=2; i<width-2; i+=2) {
  // 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, 40, i, height/2);
  } else if (i%10 == 0) {
    stroke(153);
    line(i, 20, i, 180); 
  } else {
    stroke(102);
    line(i, height/2, i, height-40);
  }
}

>>

Taken from [[basic/conditionals2.html|http://ejohn.org/apps/processing.js/examples/basic/conditionals2.html]]
Move the mouse across the screen to move the circle. The program constrains the circle to its box.

<<Processing 

float mx;
float my;
float easing = 0.05;
float esize = 25.0;
int box = 30;

void setup() 
{
  size(200, 200);
  noStroke(); 
  smooth();
  ellipseMode(CENTER_RADIUS);  
}

void draw() 
{ 
  background(51);
  
  if(abs(mouseX - mx) > 0.1) {
    mx = mx + (mouseX - mx) * easing;
  }
  if(abs(mouseY - my) > 0.1) {
    my = my + (mouseY- my) * easing;
  }
  
  float distance = esize * 2;
  mx = constrain(mx, box+distance, width-box-distance);
  my = constrain(my, box+distance, height-box-distance);
  fill(76);
  rect(box+esize, box+esize, box*3, box*3);
  fill(255);  
  ellipse(mx, my, esize, esize);
}

>>

Taken from [[basic/constrain.html|http://ejohn.org/apps/processing.js/examples/basic/constrain.html]]
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 is in the upper left of the window and the coordinate in the lower right is [width-1, height-1].

<<Processing 

// Sets the screen to be 200, 200, so the width of the window is 200 pixels
// and the height of the window is 200 pixels
size(200, 200);
background(0);
noFill();
stroke(255);

// The two parameters of the point() method each specify coordinates.
// This call to point() draws at the position [100, 100]
point(width/2, height/2);

// Draws to the position [100, 50]
point(width/2, height/4); 

// It is also possible to specify a point with any parameter, 
// but only coordinates on the screen are visible
point(60, 30);
point(60, 134);
point(160, 50);
point(280, -800);
point(201, 100);

// Coordinates are used for drawing all shapes, not just points.
// Parameters for different methods are used for different purposes.
// For example, the first two parameters to line() specify the coordinates of the 
// first point and the second two parameters specify the second point
stroke(204);
line(0, 73, width, 73);

// The first two parameters to rect() are coordinates
// and the second two are the width and height
rect(110, 55, 40, 36);

>>

Taken from [[basic/coordinates.html|http://ejohn.org/apps/processing.js/examples/basic/coordinates.html]]
The createGraphics() function creates an object from the PGraphics class (PGraphics is the main graphics and rendering context for Processing). The beginDraw() method is necessary to prepare for drawing and endDraw() is necessary to finish. Use this class if you need to draw into an off-screen graphics buffer or to maintain two contexts with different properties.

<<Processing 

PGraphics pg;

void setup() {
  size(200, 200);
  pg = createGraphics(80, 80, P3D);
}

void draw() {
  fill(0, 12);
  rect(0, 0, width, height);
  fill(255);
  noStroke();
  ellipse(mouseX, mouseY, 60, 60);
  
  pg.beginDraw();
  pg.background(102);
  pg.noFill();
  pg.stroke(255);
  pg.ellipse(mouseX-60, mouseY-60, 60, 60);
  pg.endDraw();
  
  image(pg, 60, 60); 
}

>>

Taken from [[basic/creategraphics.html|http://ejohn.org/apps/processing.js/examples/basic/creategraphics.html]]
The createImage() function provides a fresh buffer of pixels to play with. This example creates an image gradient.

<<Processing 

PImage img;

void setup() 
{
  size(200, 200);  
  img = createImage(120, 120, RGB);
  for(int i=0; i < img.pixels.length; i++) {
    img.pixels[i] = color(0, 90, 102, i%img.width * 2); 
  }
}

void draw() 
{
  background(204);
  image(img, 33, 33);
  image(img, mouseX-60, mouseY-60);
}

>>

Taken from [[basic/createimage.html|http://ejohn.org/apps/processing.js/examples/basic/createimage.html]]
Creating variables for colors that may be referred to in the program by their name, rather than a number.

<<Processing 

size(200, 200);
noStroke();

color inside = color(204, 102, 0);
color middle = color(204, 153, 0);
color outside = color(153, 51, 0);

// These statements are equivalent to the statements above.
// Programmers may use the format they prefer.
//color inside = #CC6600;
//color middle = #CC9900;
//color outside = #993300;

fill(outside);
rect(0, 0, 200, 200);
fill(middle);
rect(40, 60, 120, 120);
fill(inside);
rect(60, 90, 80, 80);

>>

Taken from [[basic/creating.html|http://ejohn.org/apps/processing.js/examples/basic/creating.html]]
It is sometimes beneficial to convert a value from one type of data to another. Each of the conversion functions converts its parameter to an equivalent representation within its datatype. The conversion functions include int(), float(), char(), byte(), and others.

<<Processing 

size(200, 200);
background(51);
noStroke();

char c;    // Chars are used for storing typographic symbols
float f;   // Floats are decimal numbers
int i;     // Ints are values between 2,147,483,647 and -2147483648
byte b;    // Bytes are values between -128 and 128

c = 'A';
f = float(c);     // Sets f = 65.0
i = int(f * 1.4); // Sets i to 91
b = byte(c / 2);  // Sets b to 32

rect(f, 0, 40, 66);
fill(204);
rect(i, 67, 40, 66);
fill(255);
rect(b, 134, 40, 66);

>>

Taken from [[basic/datatypeconversion.html|http://ejohn.org/apps/processing.js/examples/basic/datatypeconversion.html]]
Images can be displayed to the screen at their actual size or any other size.

<<Processing 

size(200, 200);
PImage a;  // Declare variable "a" of type PImage
a = loadImage("arch.jpg"); // Load the images into the program
image(a, 0, 0); // Displays the image from point (0,0)
image(a, width/2, 0, a.width/2, a.height/2);

>>

Taken from [[basic/displaying.html|http://ejohn.org/apps/processing.js/examples/basic/displaying.html]]
Move the mouse across the image to obscure and reveal the matrix. Measures the distance from the mouse to each square and sets the size proportionally.

<<Processing 

float max_distance;

void setup() {
  size(200, 200); 
  smooth();
  noStroke();
  max_distance = dist(0, 0, width, height);
}

void draw() 
{
  background(51);

  for(int i = 0; i <= width; i += 20) {
    for(int j = 0; j <= width; j += 20) {
      float size = dist(mouseX, mouseY, i, j);
      size = size/max_distance * 66;
      //opera.postError(i, j, size);
      ellipse(i, j, size, size);
    }
  }
}

>>

Taken from [[basic/distance2d.html|http://ejohn.org/apps/processing.js/examples/basic/distance2d.html]]
by Ira Greenberg. Using 2 random() calls the and point() function to create an irregular sawtooth line.

<<Processing 

size(200, 200);
background(0);
int totalPts = 300;
float steps = totalPts+1;
stroke(255);
float rand = 0;

for  (int i=1; i< steps; i++){
  point( (width/steps) * i, (height/2) + random(-rand, rand) );
  rand += random(-5, 5);
}

>>

Taken from [[basic/doublerandom.html|http://ejohn.org/apps/processing.js/examples/basic/doublerandom.html]]
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 half of the distance from its current position toward the cursor.

<<Processing 

float x;
float y;
float targetX, targetY;
float easing = 0.05;

void setup() 
{
  size(200, 200); 
  smooth();
  noStroke();  
}

void draw() 
{ 
  background( 51 );
  
  targetX = mouseX;
  float dx = mouseX - x;
  if(abs(dx) > 1) {
    x += dx * easing;
  }
  
  targetY = mouseY;
  float dy = mouseY - y;
  if(abs(dy) > 1) {
    y += dy * easing;
  }
  
  ellipse(x, y, 33, 33);
}

>>

Taken from [[basic/easing.html|http://ejohn.org/apps/processing.js/examples/basic/easing.html]]
Embedding "for" structures allows repetition in two dimensions.

<<Processing 

float box_size = 11; 
float box_space = 12; 
int margin = 7; 
 
size(200, 200); 
background(0); 
noStroke(); 
 
// Draw gray boxes 
 
for(int i = margin; i < width-margin; i += box_space) { 
  for(int j = margin; j < height-margin; j += box_space) { 
    fill(255 - box_size*10); 
    rect(j, i, box_size, box_size); 
  } 
  box_size = box_size - 0.6; 
}

>>

Taken from [[basic/embeddediteration.html|http://ejohn.org/apps/processing.js/examples/basic/embeddediteration.html]]
Click on the left button to open a different URL in the same window (Only works online). Click on the right button to open a URL in a new browser window. Created 21 June 2003.

<<Processing 

boolean overLeftButton = false;
boolean overRightButton = false;

void setup()
{
  size(200, 200);
}

void draw()
{
  background(204);
  
  // Left buttom
  if(overLeftButton == true) {
    fill(255);
  } else {
    noFill();
  }
  rect(20, 60, 75, 75);
  rect(50, 90, 15, 15);
  
  // Right button
  if(overRightButton == true) {
    fill(255);
  } else {
    noFill();
  }
  rect(105, 60, 75, 75);
  line(135, 105, 155, 85);
  line(140, 85, 155, 85);
  line(155, 85, 155, 100);
}

void mousePressed() 
{
  if(overLeftButton) { 
    link("http://www.processing.org");
  } else if (overRightButton) {
    link("http://www.processing.org", "_new");
  }
}

void mouseMoved() { 
  checkButtons(); 
}
  
void mouseDragged() {
  checkButtons(); 
}

void checkButtons() {
  if(mouseX > 20 && mouseX < 95 &&
     mouseY > 60 && mouseY <135) {
    overLeftButton = true;   
  }  else if (mouseX > 105 && mouseX < 180 &&
     mouseY > 60 && mouseY <135) {
    overRightButton = true; 
  } else {
    overLeftButton = overRightButton = false;
  }

}

>>

Taken from [[basic/embeddedlinks.html|http://ejohn.org/apps/processing.js/examples/basic/embeddedlinks.html]]
The draw_target() function makes it easy to draw many distinct targets. Each call to draw_target() specifies the position, size, and number of rings for each target.

<<Processing 

void setup() 
{
  size(200, 200);
  background(51);
  noStroke();
  smooth();
  noLoop();
}

void draw() 
{
  draw_target(68, 34, 200, 10);
  draw_target(152, 16, 100, 3);
  draw_target(100, 144, 80, 5);
}

void draw_target(int xloc, int yloc, int size, int num) 
{
  float grayvalues = 255/num;
  float steps = size/num;
  for(int i=0; i<num; i++) {
    fill(i*grayvalues);
    ellipse(xloc, yloc, size-i*steps, size-i*steps);
  }
}

>>

Taken from [[basic/functions.html|http://ejohn.org/apps/processing.js/examples/basic/functions.html]]
by Daniel Shiffman. Graphics the following equation: sin(n*cos(r) + 5*theta) where n is a function of horizontal mouse location.

<<Processing 

void setup() {
  size(50,50);
  frameRate(30);
}

void draw() {
  loadPixels();
  float n = (mouseX * 10.0) / width;
  float w = 16.0;         // 2D space width
  float h = 16.0;         // 2D space height
  float dx = w / width;    // Increment x this amount per pixel
  float dy = h / height;   // Increment y this amount per pixel
  float x = -w/2;          // Start x at -1 * width / 2
  for (int i = 0; i < width; i++) {
    float y = -h/2;        // Start y at -1 * height / 2
    for (int j = 0; j < height; j++) {
      float r = sqrt((x*x) + (y*y));    // Convert cartesian to polar
      float theta = atan2(y,x);         // Convert cartesian to polar
      // Compute 2D polar coordinate function
      float val = sin(n*cos(r) + 5 * theta);           // Results in a value between -1 and 1
      //float val = cos(r);                            // Another simple function
      //float val = sin(theta);                        // Another simple function
      // Map resulting vale to grayscale value
      pixels[i+j*width] = color((val + 1.0) * 255.0/2.0);     // Scale to between 0 and 255
      y += dy;                // Increment y
    }
    x += dx;                  // Increment x
  }
  updatePixels();
}

>>

Taken from [[basic/graphing2dequation.html|http://ejohn.org/apps/processing.js/examples/basic/graphing2dequation.html]]
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.

<<Processing 

int barWidth = 5;
int[] hue;

void setup() 
{
  size(400, 400);
  colorMode(HSB, 360, height, height);  
  hue = new int[width/barWidth];
  noStroke();
}

void draw() 
{
  int j = 0;
  for (int i=0; i<=(width-barWidth); i+=barWidth) {  
    if ((mouseX > i) && (mouseX < i+barWidth)) {
      hue[j] = mouseY;
    }
    fill(hue[j], height/1.2, height/1.2);
    rect(i, 0, barWidth, height);  
    j++;
  }
}

>>

Taken from [[basic/hue.html|http://ejohn.org/apps/processing.js/examples/basic/hue.html]]
Writing "a++" is equivalent to "a = a + 1". Writing "a--" is equivalent to "a = a - 1".

<<Processing 

int a;
int b;
boolean direction;

void setup()
{
  size(200, 200);
  colorMode(RGB, width);
  a = 0;
  b = width;
  direction = true;
  frameRate(30);
}

void 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);
}

>>

Taken from [[basic/incrementdecrement.html|http://ejohn.org/apps/processing.js/examples/basic/incrementdecrement.html]]
A class can be defined using another class as a foundation. In object-oriented programming terminology, one class can inherit fi elds 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.

<<Processing 

SpinSpots spots;
SpinArm arm;

void setup() 
{
  size(200, 200);
  smooth();
  arm = new SpinArm(width/2, height/2, 0.01);
  spots = new SpinSpots(width/2, height/2, -0.02, 33.0);
}

void draw() 
{
  background(204);
  arm.update();
  arm.display();
  spots.update();
  spots.display();
}

class Spin 
{
  float x, y, speed;
  float angle = 0.0;
  Spin(float xpos, float ypos, float s) {
    x = xpos;
    y = ypos;
    speed = s;
  }
  void update() {
    angle += speed;
  }
}

class SpinArm extends Spin 
{
  SpinArm(float x, float y, float s) {
    super(x, y, s);
  }
  void display() {
    strokeWeight(1);
    stroke(0);
    pushMatrix();
    translate(x, y);
    angle += speed;
    rotate(angle);
    line(0, 0, 66, 0);
    popMatrix();
  }
}

class SpinSpots extends Spin 
{
  float dim;
  SpinSpots(float x, float y, float s, float d) {
    super(x, y, s);
    dim = d;
  }
  void display() {
    noStroke();
    pushMatrix();
    translate(x, y);
    angle += speed;
    rotate(angle);
    ellipse(-dim/2, 0, dim, dim);
    ellipse(dim/2, 0, dim, dim);
    popMatrix();
  }
}

>>

Taken from [[basic/inheritance.html|http://ejohn.org/apps/processing.js/examples/basic/inheritance.html]]
Integers and floats are two different kinds of numerical data. 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. Floats are used when more precision is needed.

<<Processing 

int a = 0;      // Create a variable "a" of the datatype "int"
float b = 0.0;  // Create a variable "b" of the datatype "float"

void setup()
{
  size(200, 200);
  stroke(255);
  frameRate(30);
}

void draw()
{
  background(51);
  
  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;
  }
}

>>

Taken from [[basic/integersfloats.html|http://ejohn.org/apps/processing.js/examples/basic/integersfloats.html]]
Iteration with a "for" structure constructs repetitive forms.

<<Processing 

int k;
int xpos1 = 100; 
int xpos2 = 118; 
int count = 0; 
int timey = 0;
int num = 12;

size(200, 200);
background(102);
noStroke();
 
// Draw gray bars 
fill(255);
k=60;
for(int i=0; i < num/3; i++) {
  rect(25, k, 155, 5);
  k+=10;
}

// Black bars
fill(51);
k = 40;
for(int i=0; i < num; i++) {
  rect(105, k, 30, 5);
  k += 10;
}
k = 15;
for(int i = 0; i < num; i++) {
  rect(125, k, 30, 5);
  k +=10;
}
  
// Thin lines
k = 42;
fill(0);
for(int i=0; i < num-1; i++) {
  rect(36, k, 20, 1);
  k+=10;
}

>>

Taken from [[basic/iteration.html|http://ejohn.org/apps/processing.js/examples/basic/iteration.html]]
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 called it's ASCII value. These numbers can be used to position shapes in space.

<<Processing 

int numChars = 26;
color[] colors = new color[numChars];
int keyIndex;
float keyScale;
int rectWidth;

    
void setup()
{
  size(200, 200);
  noStroke();
  background(0);
  keyScale = 200/numChars-1.0;
  rectWidth = width/4;
}

void draw()
{ 
  if(keyPressed) {
    if(key >= 'A' && key <= 'z') {
      if(key <= 'Z') {
        keyIndex = key-'A';
      } else {
        keyIndex = key-'a';
      }
      fill(millis()%255);
      float beginRect = rectWidth/2 + keyIndex*keyScale-rectWidth/2;
      rect(beginRect, 0.0, rectWidth, height);
    }
  }
}

>>

Taken from [[basic/keyboard.html|http://ejohn.org/apps/processing.js/examples/basic/keyboard.html]]
Modified from code by Martin. Original 'Color Typewriter' concept by John Maeda. Click on the window to give it focus and press the letter keys to type colors. The keyboard function keyPressed() is called whenever a key is pressed. keyReleased() is another keyboard function that is called when a key is released.

<<Processing 

int max_height = 20;
int min_height = 10;
int letter_height = max_height; // Height of the letters
int letter_width = 10;          // Width of the letter

int x = -letter_width;          // X position of the letters
int y = 0;                      // Y position of the letters

boolean newletter;              

int numChars = 26;      // There are 26 characters in the alphabet
color[] colors = new color[numChars];

void setup()
{
  size(200, 200);
  noStroke();
  colorMode(RGB, numChars);
  background(numChars/2);
  // Set a gray value for each key
  for(int i=0; i<numChars; i++) {
    colors[i] = color(i, i, i);    
  }
}

void draw()
{
  if(newletter == true) {
    // Draw the "letter"
    int y_pos;
    if (letter_height == max_height) {
      y_pos = y;
      rect( x, y_pos, letter_width, letter_height );
    } else {
      y_pos = y + min_height;
      rect( x, y_pos, letter_width, letter_height );
      fill(numChars/2);
      rect( x, y_pos-min_height, letter_width, letter_height );
    }
    newletter = false;
  }
}

void keyPressed()
{
  // if the key is between 'A'(65) and 'z'(122)
  if( key >= 'A' && key <= 'z') {
    int keyIndex;
    if(key <= 'Z') {
      keyIndex = key-'A';
      letter_height = max_height;
      fill(colors[key-'A']);
    } else {
      keyIndex = key-'a';
      letter_height = min_height;
      fill(colors[key-'a']);
    }
  } else {
    fill(0);
    letter_height = 10;
  }

  newletter = true;

  // Update the "letter" position
  x = ( x + letter_width ); 

  // Wrap horizontally
  if (x > width - letter_width) {
    x = 0;
    y+= max_height;
  }

  // Wrap vertically
  if( y > height - letter_height) {
    y = 0;      // reset y to 0
  }
}

>>

Taken from [[basic/keyboardfunctions.html|http://ejohn.org/apps/processing.js/examples/basic/keyboardfunctions.html]]
Drawing letters to the screen in Processing uses a technology developed in the mid 1990s at the Visual Language Workshop at the MIT Media Laboratory. It is a closed system, but we have supplied a number of fonts located in the "font" directory in the main "processing" directory. We expect to change the Processing font technology in the future.

<<Processing 

size(200, 200);
background(0);

// Load the font. Fonts are located within the 
// main Processing directory/folder and they
// must be placed within the data directory
// of your sketch for them to load
PFont fontA = loadFont("Courier New");
textFont(fontA, 36);
textAlign(CENTER);

// Set the gray value of the letters
fill(255);

// Set the left and top margin
int margin = 6;
int gap = 30;
translate(margin*1.5, margin*2);

// Create a matrix of letterforms
int counter = 0;
for(int i=0; i<margin; i++) {
  for(int j=0; j<margin; j++) {
    char letter;
    
    // Select the letter
    int count = 65+(i*margin)+j;
    if(count <= 90) {
      letter = char(65+counter);
      if(letter == 'A' || letter == 'E' || letter == 'I' || 
         letter == 'O' || letter == 'U') {
           fill(204, 204, 0);
      } else {
        fill(255);
      }
    } else {
      fill(153);
      letter = char(48+counter);
    }
 
    // Draw the letter to the screen
    text(letter, 15+j*gap, 20+i*gap);
 
    // Increment the counter
    counter++;
    if(counter >= 26) {
      counter = 0;
    }
  }
}

>>

Taken from [[basic/letters.html|http://ejohn.org/apps/processing.js/examples/basic/letters.html]]
by Ira Greenberg. Using the convenient red(), green() and blue() component functions, generate some linear gradients.

<<Processing 

// constants
int Y_AXIS = 1;
int X_AXIS = 2;

void setup(){
  size(200, 200);

  // create some gradients
  // background
  color b1 = color(190, 190, 190);
  color b2 = color(20, 20, 20);
  //setGradient(0, 0, width, height, b1, b2, Y_AXIS);
  //center squares
  color c1 = color(255, 120, 0);
  color c2 = color(10, 45, 255);
  color c3 = color(10, 255, 15);
  color c4 = color(125, 2, 140);
  color c5 = color(255, 255, 0);
  color c6 = color(25, 255, 200);
  setGradient(25, 25, 75, 75, c1, c2, Y_AXIS);
  setGradient(100, 25, 75, 75, c3, c4, X_AXIS);
  setGradient(25, 100, 75, 75, c2, c5, X_AXIS);
  setGradient(100, 100, 75, 75, c4, c6, Y_AXIS);
}

void setGradient(int x, int y, float w, float h, color c1, color c2, int axis ){
  // calculate differences between color components 
  float deltaR = red(c2)-red(c1);
  float deltaG = green(c2)-green(c1);
  float deltaB = blue(c2)-blue(c1);

  // choose axis
  if(axis == Y_AXIS){
    /*nested for loops set pixels
     in a basic table structure */
    // column
    for (int i=x; i<=(x+w); i++){
      // row
      for (int j = y; j<=(y+h); j++){
        color c = color(
        (red(c1)+(j-y)*(deltaR/h)),
        (green(c1)+(j-y)*(deltaG/h)),
        (blue(c1)+(j-y)*(deltaB/h)) 
          );
        set(i, j, c);
      }
    }  
  }  
  else if(axis == X_AXIS){
    // column 
    for (int i=y; i<=(y+h); i++){
      // row
      for (int j = x; j<=(x+w); j++){
        color c = color(
        (red(c1)+(j-x)*(deltaR/h)),
        (green(c1)+(j-x)*(deltaG/h)),
        (blue(c1)+(j-x)*(deltaB/h)) 
          );
        set(j, i, c);
      }
    }  
  }
}

>>

Taken from [[basic/lineargradient.html|http://ejohn.org/apps/processing.js/examples/basic/lineargradient.html]]
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.

<<Processing 

size(200, 200);
background(126);

boolean op = false;

for(int i=5; i<=195; i+=5) {
  // Logical AND
  stroke(0);
  if((i > 35) && (i < 100)) {
    line(5, i, 95, i);
    op = false;
  }
  
  // Logical OR
  stroke(76);
  if((i <= 35) || (i >= 100)) {
    line(105, i, 195, i);
    op = true;
  }
  
  // Testing if a boolean value is "true"
  // The expression "if(op)" is equivalent to "if(op == true)"
  if(op) {
    stroke(0);
    point(width/2, i);
  }
    
  // Testing if a boolean value is "false"
  // The expression "if(!op)" is equivalent to "if(op == false)"
  if(!op) {
    stroke(255);
    point(width/4, i);
  }
}

>>

Taken from [[basic/logicaloperators.html|http://ejohn.org/apps/processing.js/examples/basic/logicaloperators.html]]
The loop() function causes draw() to execute continuously. If noLoop is called in setup() the draw() is only executed once. In this example click the mouse to execute loop(), which will cause the draw() the execute continuously.

<<Processing 

// The statements in the setup() function 
// execute once when the program begins
void setup() 
{
  size(200, 200);  // Size should be the first statement
  stroke(255);     // Set stroke color to white
  noLoop();
}

float y = 100;

// The statements in draw() are run until the 
// program is stopped. Each statement is run in 
// sequence and after the last line is read, the first 
// line is run again.
void draw() 
{ 
  background(0);   // Set the background to black
  line(0, y, width, y);  
  
  y = y - 1; 
  if (y < 0) { 
    y = height; 
  } 
} 

void mousePressed() 
{
  loop();
}

>>

Taken from [[basic/loop.html|http://ejohn.org/apps/processing.js/examples/basic/loop.html]]
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.

<<Processing 

float scale;

void setup()
{
  size(200, 200);
  noStroke();
  scale = width/10;
}

void draw()
{ 
  for(int i=0; i<scale; i++) {
    colorMode(RGB, (i+1) * scale * 10);
    fill(millis()%((i+1) * scale * 10) );
    rect(i*scale, 0, scale, height);
  }
}

>>

Taken from [[basic/milliseconds.html|http://ejohn.org/apps/processing.js/examples/basic/milliseconds.html]]
The modulo operator (%) returns the remainder of a number divided by another. As in this example, it is often used to keep numerical values within a set range. Created 12 January 2003.

<<Processing 

int num = 20;
float c;

void setup()
{
  size(200,200);
  fill(255);
  frameRate(30);
}

void draw() 
{ 
  background(0);
  c+=0.1;
  for(int i=1; i<height/num; i++) { 
    float x = (c%i)*i*i;
    stroke(102);
    line(0, i*num, x, i*num);
    noStroke();
    rect(x, i*num-num/2, 8, num);
  } 
}

>>

Taken from [[basic/modulo.html|http://ejohn.org/apps/processing.js/examples/basic/modulo.html]]
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.

<<Processing 

int gx = 15;
int gy = 35;
float leftColor = 0.0;
float rightColor = 0.0;

void setup() 
{
  size(200, 200);
  colorMode(RGB, 1.0);
  noStroke();
}

void draw() 
{
  background(0.0);
  update(mouseX); 
  fill(0.0, leftColor + 0.4, leftColor + 0.6); 
  rect(width/4-gx, width/2-gx, gx*2, gx*2); 
  fill(0.0, rightColor + 0.2, rightColor + 0.4); 
  rect(width/1.33-gy, width/2-gy, gy*2, gy*2);
}

void update(int x) 
{
  leftColor = -0.002 * x/2 + 0.06;
  rightColor =  0.002 * x/2 + 0.06;
	
  gx = x/2;
  gy = 100-x/2;

  if (gx < 10) {
    gx = 10;
  } else if (gx > 90) {
    gx = 90;
  }

  if (gy > 90) {
    gy = 90;
  } else if (gy < 10) {
    gy = 10;
  }
}

>>

Taken from [[basic/mouse1d.html|http://ejohn.org/apps/processing.js/examples/basic/mouse1d.html]]
Moving the mouse changes the position and size of each box.

<<Processing 

void setup() 
{
  size(200, 200); 
  noStroke();
  colorMode(RGB, 255, 255, 255, 100);
  rectMode(CENTER);
}

void draw() 
{   
  background(51); 
  fill(255, 80);
  rect(mouseX, height/2, mouseY/2+10, mouseY/2+10);
  fill(255, 80);
  rect(width-mouseX, height/2, ((height-mouseY)/2)+10, ((height-mouseY)/2)+10);
}

>>

Taken from [[basic/mouse2d.html|http://ejohn.org/apps/processing.js/examples/basic/mouse2d.html]]
Click on the box and drag it across the screen.

<<Processing 

float bx;
float by;
int bs = 20;
boolean bover = false;
boolean locked = false;
float bdifx = 0.0; 
float bdify = 0.0; 


void setup() 
{
  size(200, 200);
  bx = width/2.0;
  by = height/2.0;
  rectMode(CENTER_RADIUS);  
}

void draw() 
{ 
  background(0);
  
  // Test if the cursor is over the box 
  if (mouseX > bx-bs && mouseX < bx+bs && 
      mouseY > by-bs && mouseY < by+bs) {
    bover = true;  
    if(!locked) { 
      stroke(255); 
      fill(153);
    } 
  } else {
    stroke(153);
    fill(153);
    bover = false;
  }
  
  // Draw the box
  rect(bx, by, bs, bs);
}

void mousePressed() {
  if(bover) { 
    locked = true; 
    fill(255, 255, 255);
  } else {
    locked = false;
  }
  bdifx = mouseX-bx; 
  bdify = mouseY-by; 

}

void mouseDragged() {
  if(locked) {
    bx = mouseX-bdifx; 
    by = mouseY-bdify; 
  }
}

void mouseReleased() {
  locked = false;
}

>>

Taken from [[basic/mousefunctions.html|http://ejohn.org/apps/processing.js/examples/basic/mousefunctions.html]]
Move the mouse to position the shape. Press the mouse button to invert the color.

<<Processing 

void setup() {
  size(200, 200);
  fill(126);
  background(102);
}

void draw() {
  if(mousePressed) {
    stroke(255);
  } else {
    stroke(0);
  }
  line(mouseX-66, mouseY, mouseX+66, mouseY);
  line(mouseX, mouseY-66, mouseX, mouseY+66); 
}

>>

Taken from [[basic/mousepress.html|http://ejohn.org/apps/processing.js/examples/basic/mousepress.html]]
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 "mousePressed".

<<Processing 

int[] xvals;
int[] yvals;
int[] bvals;

void setup() 
{
  size(200, 200);
  xvals = new int[width];
  yvals = new int[width];
  bvals = new int[width];
}

int arrayindex = 0;

void draw()
{
  background(102);
  
  for(int 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(mousePressed) {
    bvals[width-1] = 0;
  } else {
    bvals[width-1] = 255;
  }
  
  fill(255);
  noStroke();
  rect(0, height/3, width, height/3+1);

  for(int 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));
  }
}

>>

Taken from [[basic/mousesignals.html|http://ejohn.org/apps/processing.js/examples/basic/mousesignals.html]]
A class can have multiple constructors that assign the fields in different ways. Sometimes it's beneficial to specify every aspect of an objectÕs data by assigning parameters to the fields, but other times it might be appropriate to define only one or a few.

<<Processing 

Spot sp1, sp2;
void setup() 
{
  size(200, 200);
  background(204);
  smooth();
  noLoop();
  // Run the constructor without parameters
  sp1 = new Spot();
  // Run the constructor with three parameters
  sp2 = new Spot(122, 100, 40);
}

void draw() {
  sp1.display();
  sp2.display();
}

class Spot {
  float x, y, radius;
  // First version of the Spot constructor;
  // the fields are assigned default values
  Spot() {
    x = 66;
    y = 100;
    radius = 16;
  }
  // Second version of the Spot constructor;
  // the fields are assigned with parameters
  Spot(float xpos, float ypos, float r) {
    x = xpos;
    y = ypos;
    radius = r;
  }
  void display() {
    ellipse(x, y, radius*2, radius*2);
  }
}

>>

Taken from [[basic/multipleconstructors.html|http://ejohn.org/apps/processing.js/examples/basic/multipleconstructors.html]]
By Ira Greenberg Draw a neighborhood of houses using Door, Window, Roof and House classes. Good example of class composition, with component Door, Window, Roof class references encapsulated within House class. This arrangement allows House class to handle placement and sizing of its components, while still allowing user customization of the individual components.

<<Processing 

void setup(){
  size(200, 200);
  background(190);
  smooth();
  // Ground plane
  int groundHeight = 10;
  fill(0);
  rect(0, height-groundHeight, width, groundHeight);
  fill(255);
  
  // Center the houses
  translate(12, 0);

  // Houses
  Door door1 = new Door(20, 40);
  Window window1 = new Window(50, 62, false, Window.DOUBLE);
  Roof roof1 = new Roof(Roof.DOME);
  House house1 = new House(75, 75, door1, window1, roof1, House.MIDDLE_DOOR);
  house1.drawHouse(0, height-groundHeight-house1.h, true);

  Door door2 = new Door(20, 40);
  Window window2 = new Window(50, 62, true, Window.QUAD);
  Roof roof2 = new Roof(Roof.GAMBREL);
  House house2 = new House(100, 60, door2, window2, roof2, House.LEFT_DOOR);
  house2.drawHouse(house1.x + house1.w, height-groundHeight-house2.h, true);
}

class Door{
  //door properties
  int x;
  int y;
  int w;
  int h;

  // for knob
  int knobLoc = 1;
  //constants
  final static int RT = 0;
  final static int LFT = 1;

  // constructor
  Door(int w, int h){
    this.w = w;
    this.h = h;
  }

  // draw the door
  void drawDoor(int x, int y) {
    rect(x, y, w, h);
    int knobsize = w/10;
    if (knobLoc == 0){
      //right side
      ellipse(x+w-knobsize, y+h/2, knobsize, knobsize);
    }
    else {
      //left side
      ellipse(x+knobsize, y+h/2, knobsize, knobsize);
    }
  }

  // set knob position
  void setKnob(int knobLoc){
    this. knobLoc = knobLoc;
  }
}

class Window{
  //window properties
  int x;
  int y;
  int w;
  int h;

  // customized features
  boolean hasSash = false;

  // single, double, quad pane
  int style = 0;
  //constants
  final static int SINGLE = 0;
  final static int DOUBLE = 1;
  final static int QUAD = 2;

  // constructor 1
  Window(int w, int h){
    this.w = w;
    this.h = h;
  }
  // constructor 2
  Window(int w, int h, int style){
    this.w = w;
    this.h = h;
    this.style = style;
  }
  // constructor 3
  Window(int w, int h, boolean hasSash, int style){
    this.w = w;
    this.h = h;
    this.hasSash = hasSash;
    this.style = style;
  }

  // draw the window
  void drawWindow(int x, int y) {
    //local variables
    int margin = 0;
    int winHt = 0;
    int winWdth = 0;

    if (hasSash){
      margin = w/15;
    }

    switch(style){
    case 0:
      //outer window (sash)
      rect(x, y, w, h);
      //inner window
      rect(x+margin, y+margin, w-margin*2, h-margin*2);
      break;
    case 1:
      winHt = (h-margin*3)/2;
      //outer window (sash)
      rect(x, y, w, h);
      //inner window (top)
      rect(x+margin, y+margin, w-margin*2, winHt);
      //inner windows (bottom)
      rect(x+margin, y+winHt+margin*2, w-margin*2, winHt);
      break;
    case 2:
      winWdth = (w-margin*3)/2;
      winHt = (h-margin*3)/2;
      //outer window (sash)
      rect(x, y, w, h);
      //inner window (top-left)
      rect(x+margin, y+margin, winWdth, winHt);
      //inner window (top-right)
      rect(x+winWdth+margin*2,  y+margin, winWdth, winHt);
      //inner windows (bottom-left)
      rect(x+margin, y+winHt+margin*2, winWdth, winHt);
      //inner windows (bottom-right)
      rect(x+winWdth+margin*2,  y+winHt+margin*2, winWdth, winHt);
      break;
    }
  }

  // set window style (number of panes)
  void setStyle(int style){
    this.style = style;
  }
}

class Roof{
  //roof properties
  int x;
  int y;
  int w;
  int h;

  // roof style
  int style = 0;
  //constants  
  final static int CATHEDRAL = 0;
  final static int GAMBREL = 1;
  final static int DOME = 2;

  // default constructor
  Roof(){
  }
   
   // constructor 2
   Roof(int style){
    this.style = style;
  }

  // draw the roof
  void drawRoof(int x, int y, int w, int h) {
    switch(style){
    case 0:
      beginShape();
      vertex(x, y);
      vertex(x+w/2, y-h/3);
      vertex(x+w, y);
      endShape(CLOSE);
      break;
    case 1:
     beginShape();
      vertex(x, y);
      vertex(x+w/7, y-h/4);
      vertex(x+w/2, y-h/2);
      vertex(x+(w-w/7), y-h/4);
      vertex(x+w, y);
      endShape(CLOSE);
      break;
    case 2:
      ellipseMode(CORNER);
      arc(x, y-h/2, w, h, PI, TWO_PI);
      line(x, y, x+w, y);
      break;
    }

  }

  // set roof style
  void setStyle(int style){
    this.style = style;
  }
}

class House{
  //house properties
  int x;
  int y;
  int w;
  int h;

  //component reference variables
  Door door;
  Window window;
  Roof roof;

  //optional autosize variable
  boolean AutoSizeComponents = false;

  //door placement
  int doorLoc = 0;
  //constants
  final static int MIDDLE_DOOR = 0;
  final static int LEFT_DOOR = 1;
  final static int RIGHT_DOOR = 2;

  //constructor
  House(int w, int h, Door door, Window window, Roof roof, int doorLoc) {
    this.w = w;
    this.h = h;
    this.door = door;
    this.window = window;
    this.roof = roof;
    this.doorLoc = doorLoc;
  }

  void drawHouse(int x, int y, boolean AutoSizeComponents) {
    this.x = x;
    this.y =y;
    this.AutoSizeComponents = AutoSizeComponents;

    //automatically sizes doors and windows
    if(AutoSizeComponents){
      //autosize door
      door.h = h/4;
      door.w = door.h/2;

      //autosize windows
      window.h = h/3;
      window.w = window.h/2;

    }
    // draw bldg block
    rect(x, y, w, h);

    // draw door
    switch(doorLoc){
    case 0:
      door.drawDoor(x+w/2-door.w/2, y+h-door.h);
      break;
    case 1:
      door.drawDoor(x+w/8, y+h-door.h);
      break;
    case 2:
      door.drawDoor(x+w-w/8-door.w,  y+h-door.h);
      break;
    }

    // draw windows
    int windowMargin = (w-window.w*2)/3;
    window.drawWindow(x+windowMargin, y+h/6);
    window.drawWindow(x+windowMargin*2+window.w, y+h/6);

    // draw roof
    roof.drawRoof(x, y, w, h);
  }

  // catch drawHouse method without boolean argument
  void drawHouse(int x, int y){
    // recall with required 3rd argument
    drawHouse(x, y, false);
  }
}

>>

Taken from [[basic/neighborhood.html|http://ejohn.org/apps/processing.js/examples/basic/neighborhood.html]]
The noLoop() function causes draw() to only execute once. Without calling noLoop(), draw() executed continually.

<<Processing 

// The statements in the setup() function 
// execute once when the program begins
void setup() 
{
  size(200, 200);  // Size should be the first statement
  stroke(255);     // Set line drawing color to white
  frameRate(30);
  noLoop();
}

float y = 100;

// 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.
void draw() 
{ 
  background(0);   // Set the background to black
  y = y - 1; 
  if (y < 0) { y = height; } 
  line(0, y, width, y);  
}

>>

Taken from [[basic/noloop.html|http://ejohn.org/apps/processing.js/examples/basic/noloop.html]]
Using 1D Perlin Noise to assign location.

<<Processing 

float xoff = 0.0;
float xincrement = 0.01; 

void setup() {
  size(200,200);
  background(0);
  frameRate(30);
  smooth();
  noStroke();
}

void draw()
{
  // Create an alpha blended background
  fill(0, 10);
  rect(0,0,width,height);
  
  //float 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
  float 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,16,16);
}

>>

Taken from [[basic/noise1d.html|http://ejohn.org/apps/processing.js/examples/basic/noise1d.html]]
by Daniel Shiffman. Using 2D noise to create simple texture.

<<Processing 

float increment = 0.02;

void setup() {
  size(100,100);
  noLoop();
}

void draw() {
  background(0);
  
  // Optional: adjust noise detail here
  // noiseDetail(8,0.65f);
  
  loadPixels();

  float xoff = 0.0; // Start xoff at 0
  
  // For every x,y coordinate in a 2D space, calculate a noise value and produce a brightness value
  for (int x = 0; x < width; x++) {
    xoff += increment;   // Increment xoff 
    float yoff = 0.0;   // For every xoff, start yoff at 0
    for (int y = 0; y < height; y++) {
      yoff += increment; // Increment yoff
      
      // Calculate noise and scale by 255
      //float bright = noise(xoff,yoff)*255;

      // Try using this line instead
      float bright = random(0,255);
      
      // Set each pixel onscreen to a grayscale value
      pixels[x+y*width] = color(bright);
    }
  }
  
  updatePixels();
}

>>

Taken from [[basic/noise2d.html|http://ejohn.org/apps/processing.js/examples/basic/noise2d.html]]
Using 3D noise to create simple animated texture. Here, the third dimension ('z') is treated as time.

<<Processing 

float increment = 0.01;
// The noise function's 3rd argument, a global variable that increments once per cycle
float zoff = 0.0;  
// We will increment zoff differently than xoff and yoff
float zincrement = 0.02; 

void setup() {
  size(50,50);
  frameRate(30);
}

void draw() {
  background(0);
  
  // Optional: adjust noise detail here
  // noiseDetail(8,0.65f);
  
  loadPixels();

  float xoff = 0.0; // Start xoff at 0
  
  // For every x,y coordinate in a 2D space, calculate a noise value and produce a brightness value
  for (int x = 0; x < width; x++) {
    xoff += increment;   // Increment xoff 
    float yoff = 0.0f;   // For every xoff, start yoff at 0
    for (int y = 0; y < height; y++) {
      yoff += increment; // Increment yoff
      
      // Calculate noise and scale by 255
      //float bright = noise(xoff,yoff,zoff)*255;

      // Try using this line instead
      float bright = random(0,255);
      
      // Set each pixel onscreen to a grayscale value
      pixels[x+y*width] = color(bright,bright,bright);
    }
  }
  updatePixels();
  
  zoff += zincrement; // Increment zoff
  
  
}

>>

Taken from [[basic/noise3d.html|http://ejohn.org/apps/processing.js/examples/basic/noise3d.html]]
by Daniel Shiffman. Using Perlin Noise to generate a wave-like pattern.

<<Processing 

int xspacing = 8;   // How far apart should each horizontal location be spaced
int w;              // Width of entire wave

float yoff = 0.0f;        // 2nd dimension of perlin noise
float[] yvalues;          // Using an array to store height values for the wave (not entirely necessary)

void setup() {
  size(200,200);
  frameRate(30);
  colorMode(RGB,255,255,255,100);
  smooth();
  w = width+16;
  yvalues = new float[w/xspacing];
}

void draw() {
  background(0);
  calcWave();
  renderWave();

}

void calcWave() {
  float dx = 0.05f;
  float dy = 0.01f;
  float amplitude = 100.0f;

  // Increment y ('time')
  yoff += dy;

  //float xoff = 0.0;  // Option #1
  float xoff = yoff; // Option #2

  for (int i = 0; i < yvalues.length; i++) {
    // Using 2D noise function
    //yvalues[i] = (2*noise(xoff,yoff)-1)*amplitude; // Option #1
    // Using 1D noise function
    yvalues[i] = (2*noise(xoff)-1)*amplitude;    // Option #2
    xoff+=dx;
  }

}

void renderWave() {
  // A simple way to draw the wave with an ellipse at each location
  for (int x = 0; x < yvalues.length; x++) {
    noStroke();
    fill(255,50);
    ellipseMode(CENTER);
    ellipse(x*xspacing,width/2+yvalues[x],16,16);
  }
}

>>

Taken from [[basic/noisewave.html|http://ejohn.org/apps/processing.js/examples/basic/noisewave.html]]
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.

<<Processing 

MRect r1, r2, r3, r4;
 
void setup()
{
  size(200, 200);
  fill(255, 204);
  noStroke();
  r1 = new MRect(1, 134.0, 0.532, 0.083*height, 10.0, 60.0);
  r2 = new MRect(2, 44.0, 0.166, 0.332*height, 5.0, 50.0);
  r3 = new MRect(2, 58.0, 0.332, 0.4482*height, 10.0, 35.0);
  r4 = new MRect(1, 120.0, 0.0498, 0.913*height, 15.0, 60.0);
}
 
void 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 
{
  int w; // single bar width
  float xpos; // rect xposition
  float h; // rect height
  float ypos ; // rect yposition
  float d; // single bar distance
  float t; // number of bars
 
  MRect(int iw, float ixp, float ih, float iyp, float id, float it) {
    w = iw;
    xpos = ixp;
    h = ih;
    ypos = iyp;
    d = id;
    t = it;
  }
 
  void move (float posX, float posY, float damping) {
    float dif = ypos - posY;
    if (abs(dif) > 1) {
      ypos -= dif/damping;
    }
    dif = xpos - posX;
    if (abs(dif) > 1) {
      xpos -= dif/damping;
    }
  }
 
  void display() {
    for (int i=0; i<t; i++) {
      rect(xpos+(i*(d+w)), ypos, w, height*h);
    }
  }
}

>>

Taken from [[basic/objects.html|http://ejohn.org/apps/processing.js/examples/basic/objects.html]]
<<Processing '

// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated.
void setup()
{
  size(200, 200);
  background(102);
  smooth();
}

void 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 

void variableEllipse(int x, int y, int px, int py) 
{
  float speed = abs(x-px) + abs(y-py);
  stroke(speed);
  ellipse(x, y, speed, speed);
}

'>>
By Ira Greenberg Uses the arc() function to generate a pie chart from the data stored in an array.

<<Processing 

size(200, 200);
background(100);
smooth();
noStroke();

int diameter = 150;
int[] angs = {30, 10, 45, 35, 60, 38, 75, 67};
float lastAng = 0;

for (int i=0; i<angs.length; i++){
  fill(angs[i] * 3.0);
  arc(width/2, height/2, diameter, diameter, lastAng, lastAng+radians(angs[i]));
  lastAng += radians(angs[i]);  
}

>>

Taken from [[basic/piechart.html|http://ejohn.org/apps/processing.js/examples/basic/piechart.html]]
by Daniel Shiffman. Mouse horizontal location controls size of dots. Creates a simple pointillist effect using ellipses colored according to pixels in an image.

<<Processing 

PImage a;

void setup()
{
  a = loadImage("eames.jpg");
  size(200,200);
  noStroke();
  background(255);
  smooth();
}

void draw()
{ 
  float pointillize = map(mouseX, 0, width, 2, 18);
  int x = int(random(a.width));
  int y = int(random(a.height));
  color pix = a.get(x, y);
  fill(pix, 126);
  ellipse(x, y, pointillize, pointillize);
}

>>

Taken from [[basic/pointillism.html|http://ejohn.org/apps/processing.js/examples/basic/pointillism.html]]
Constructing a simple dimensional form with lines and rectangles. Changing the value of the variable 'd' scales the image. The four variables set the positions based on the value of 'd'.

<<Processing 

int d = 40;
int p1 = d;
int p2 = p1+d;
int p3 = p2+d;
int p4 = p3+d;

size(200, 200);
background(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);

>>

Taken from [[basic/pointslines.html|http://ejohn.org/apps/processing.js/examples/basic/pointslines.html]]
by Ira Greenberg. Using the convenient red(), green() and blue() component functions, generate an array of radial gradients.

<<Processing 

void setup(){
  size(50, 50);
  background(0);
  smooth();

  // create a simple table of gradients
  int columns = 1;
  //int radius = (width/columns)/2;
  int radius = width/2;
  // create some gradients
  for (int i=radius; i< width; i+=radius*2){
    for (int j =radius; j< height; j+=radius*2){
      createGradient(i, j, radius, 
      color(int(random(255)), int(random(255)), int(random(255))), 
      color(int(random(255)), int(random(255)), int(random(255))));
    }
  }
}

void createGradient (float x, float y, float radius, color c1, color c2){
  float px = 0, py = 0, angle = 0;

  // calculate differences between color components 
  float deltaR = red(c2)-red(c1);
  float deltaG = green(c2)-green(c1);
  float deltaB = blue(c2)-blue(c1);
  // hack to ensure there are no holes in gradient
  // needs to be increased, as radius increases
  float gapFiller = 8.0;

  for (int i=0; i< radius; i++){
    for (float j=0; j<360; j+=1.0/gapFiller){
      px = x+cos(radians(angle))*i;
      py = y+sin(radians(angle))*i;
      angle+=1.0/gapFiller;
      color c = color(
      (red(c1)+(i)*(deltaR/radius)),
      (green(c1)+(i)*(deltaG/radius)),
      (blue(c1)+(i)*(deltaB/radius)) 
        );
      set(int(px), int(py), c);      
    }
  }
  // adds smooth edge 
  // hack anti-aliasing
  noFill();
  strokeWeight(3);
  ellipse(x, y, radius*2, radius*2);
}

>>

Taken from [[basic/radialgradient.html|http://ejohn.org/apps/processing.js/examples/basic/radialgradient.html]]
Random numbers create the basis of this image. Each time the program is loaded the result is different.

<<Processing 

size(200, 200);
smooth();
background(0);
strokeWeight(10);

for(int i = 0; i < width; i++) {
  float r = random(255);
  float x = random(0, width);
  stroke(r, 100);
  line(i, 0, x, height);
}

>>

Taken from [[basic/random.html|http://ejohn.org/apps/processing.js/examples/basic/random.html]]
An image is recreated from its individual component colors. The many colors of the image are created through modulating the red, green, and blue values. This is an exageration of an LCD display.

<<Processing 

size(200, 200);
noStroke();
background(0);

// Load an image from the data directory
PImage c;
c = loadImage("cait.jpg");

int xoff = 0;
int yoff = 0;
int p = 2;
int pix = p*3;


for(int i = 0; i < c.width*c.height; i += 1) 
{  
  int here = c.pixels[i];
  
  fill(red(here), 0, 0);
  rect(xoff, yoff, p, pix);
  
  fill(0, green(here), 0);
  rect(xoff+p, yoff, p, pix);
  
  fill(0, 0, blue(here));
  rect(xoff+p*2, yoff, p, pix);
  
  xoff+=pix;
  if(xoff >= width-pix) {
    xoff = 0;
    yoff += pix;
  }
}

>>

Taken from [[basic/reading.html|http://ejohn.org/apps/processing.js/examples/basic/reading.html]]
A demonstration of recursion, which means functions call themselves. 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.

<<Processing 

void setup() 
{
  size(200, 200);
  noStroke();
  smooth();
  noLoop();
}

void draw() 
{
  drawCircle(126, 170, 6);
}

void drawCircle(int x, int radius, int level) 
{                    
  float tt = 126 * level/4.0;
  fill(tt);
  ellipse(x, 100, radius*2, radius*2);      
  if(level > 1) {
    level = level - 1;
    drawCircle(x - radius/2, radius/2, level);
    drawCircle(x + radius/2, radius/2, level);
  }
}

>>

Taken from [[basic/recursion.html|http://ejohn.org/apps/processing.js/examples/basic/recursion.html]]
A demonstration of recursion, which means functions call themselves. 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.

<<Processing 

void setup() 
{
  size(200, 200);
  noStroke();
  smooth();
  drawCircle(100, 100, 80, 8);
}

void drawCircle(float x, float y, int radius, int level) 
{                    
  float tt = 126 * level/6.0;
  fill(tt, 153);
  ellipse(x, y, radius*2, radius*2);      
  if(level > 1) {
    level = level - 1;
    int num = int(random(2, 6));
    for(int i=0; i<num; i++) {
      float a = random(0, TWO_PI);
      float nx = x + cos(a) * 6.0 * level;
      float ny = y + sin(a) * 6.0 * level;
      drawCircle(nx, ny, radius/2, level);
    }
  }
}

>>

Taken from [[basic/recursion2.html|http://ejohn.org/apps/processing.js/examples/basic/recursion2.html]]
The redraw() function makes draw() execute once. In this example, draw() is executed once every time the mouse is clicked.

<<Processing 

// The statements in the setup() function 
// execute once when the program begins
void setup() 
{
  size(200, 200);  // Size should be the first statement
  stroke(255);     // Set line drawing color to white
  noLoop();
}

float y = 100;

// 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.
void draw() 
{ 
  background(0);   // Set the background to black
  y = y - 1; 
  if (y < 0) { y = height; } 
  line(0, y, width, y);  
} 

void mousePressed() 
{
  redraw();
}

>>

Taken from [[basic/redraw.html|http://ejohn.org/apps/processing.js/examples/basic/redraw.html]]
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.

<<Processing 

color a, b, c, d, e;

void setup() {
  size(200, 200);
  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();
}

void draw() {
  drawBand(a, b, c, d, e, 0, 4);
  drawBand(c, a, d, b, e, height/2, 4);
}

void drawBand(color v, color w, color x, color y, color z, int ypos, int barWidth) {
  int num = 5;
  color[] colorOrder = { v, w, x, y, z };
  for(int i = 0; i < width; i += barWidth*num) {
    for(int j = 0; j < num; j++) {
      fill(colorOrder[j]);
      rect(i+j*barWidth, ypos, barWidth, height/2);
    }
  }
}

>>

Taken from [[basic/relativity.html|http://ejohn.org/apps/processing.js/examples/basic/relativity.html]]
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).

<<Processing 

void setup()
{
  size(200,200);
  noStroke();
  fill(255);
  frameRate(30);
}

float angle;
float cosine;
float jitter;

void draw()
{
  background(102);
  
  if(second()%2 == 0){
    jitter = (random(-0.1, 0.1));
  }
  angle = angle + jitter;
  cosine = cos(angle);
  
  translate(width/2, height/2);
  rotate(cosine);
  rectMode(CENTER);
  rect(0, 0, 115, 115);   
}

>>

Taken from [[basic/rotate.html|http://ejohn.org/apps/processing.js/examples/basic/rotate.html]]
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.

<<Processing 

int barWidth = 5;
int[] saturation;

void setup() 
{
  size(200, 200);
  colorMode(HSB, 360, height, height); 
  saturation = new int[width/barWidth];
}

void draw() 
{
  int j = 0;
  for (int i=0; i<=(width-barWidth); i+=barWidth) {  
    noStroke();
    if ((mouseX > i) && (mouseX < i+barWidth)) {
      saturation[j] = mouseY;
    }
    fill(i, saturation[j], height/1.5);
    rect(i, 0, barWidth, height);  
    j++;
  }
}

>>

Taken from [[basic/saturation.html|http://ejohn.org/apps/processing.js/examples/basic/saturation.html]]
by Denis Grutze. 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.

<<Processing 

float a = 0.0;
float s = 0.0;

void setup()
{
  size(200,200);
  noStroke();
  rectMode(CENTER);
  frameRate(30);
}

void draw()
{
  background(102);
  
  a = a + 0.04;
  s = cos(a)*2;
  
  translate(width/2, height/2);
  scale(s); 
  fill(51);
  rect(0, 0, 50, 50); 
  
  translate(75, 0);
  fill(255);
  scale(s);
  rect(0, 0, 50, 50);       
}

>>

Taken from [[basic/scale.html|http://ejohn.org/apps/processing.js/examples/basic/scale.html]]
The draw() function creates a structure in which to write programs that change with time.

<<Processing 

// The statements in the setup() function 
// execute once when the program begins
void setup() 
{
  size(200, 200);  // Size should be the first statement
  stroke(255);     // Set line drawing color to white
  frameRate(30);
}

float y = 100;

// 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.
void draw() 
{ 
  background(0);   // Set the background to black
  y = y - 1; 
  if (y < 0) { y = height; } 
  line(0, y, width, y);  
}

>>

Taken from [[basic/setupdraw.html|http://ejohn.org/apps/processing.js/examples/basic/setupdraw.html]]
Simple curves are drawn with simple equations. By using numbers with values between 0 and 1 in the equations, a series of elegant curves are created. The numbers are then scaled to fill the screen.

<<Processing 

void setup() {
  size(200, 200);
  colorMode(RGB, 100);
  background(0);
  noFill();
  noLoop();
}

void draw() {
  stroke(40);
  beginShape();
  for(int i=0; i<width; i++) {
   vertex(i, singraph((float)i/width)*height);
  }
  endShape();
  
  stroke(55);
  beginShape();
  for(int i=0; i<width; i++) {
   vertex(i, quad((float)i/width)*height);
  }
  endShape();
  
  stroke(70);
  beginShape();
  for(int i=0; i<width; i++) {
   vertex(i, quadHump((float)i/width)*height);
  }
  endShape();
  
  stroke(85);
  beginShape();
  for(int i=0; i<width; i++) {
   vertex(i, hump((float)i/width)*height);
  }
  endShape();
  
  stroke(100);
  beginShape();
  for(int i=0; i<width; i++) {
   vertex(i, squared((float)i/width)*height);
  }
  endShape();
}

float singraph(float sa) {
  sa = (sa - 0.5) * 1.0; //scale from -1 to 1
  sa = sin(sa*PI)/2 + 0.5;
  return sa;
}

float quad(float sa) {
  return sa*sa*sa*sa;
}

float quadHump(float sa) {
  sa = (sa - 0.5); //scale from -2 to 2
  sa = sa*sa*sa*sa * 16;
  return sa;
}

float hump(float sa) {
  sa = (sa - 0.5) * 2; //scale from -2 to 2
  sa = sa*sa;
  if(sa > 1) { sa = 1; }
  return 1-sa;
}

float squared(float sa) {
  sa = sa*sa;
  return sa;
}

>>

Taken from [[basic/simplecurves.html|http://ejohn.org/apps/processing.js/examples/basic/simplecurves.html]]
Smoothly scaling size with the sin() function.

<<Processing 

float spin = 0.0; 
float diameter = 84.0; 
float angle;

float angle_rot; 
int rad_points = 90;

void setup() 
{
  size(200, 200);
  noStroke();
  smooth();
}

void draw() 
{ 
  background(153);
  
  translate(130, 65);
  
  fill(255);
  ellipse(0, 0, 16, 16);
  
  angle_rot = 0;
  fill(51);

  for(int i=0; i<5; i++) {
    pushMatrix();
    rotate(angle_rot + -45);
    ellipse(-116, 0, diameter, diameter);
    popMatrix();
    angle_rot += PI*2/5;
  }

  diameter = 34 * sin(angle) + 168;
  
  angle += 0.02;
  if (angle > TWO_PI) { angle = 0; }
}

>>

Taken from [[basic/sine.html|http://ejohn.org/apps/processing.js/examples/basic/sine.html]]
Linear movement with sin() and cos(). Numbers between 0 and PI*2 (TWO_PI which is 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.

<<Processing 

int i = 45;
int j = 225; 
float pos1 = 0; 
float pos2 = 0; 
float pos3 = 0; 
float pos4 = 0;
int sc = 40;

void setup() 
{
  size(200, 200);
  noStroke();
  smooth();
}

void draw() 
{
  background(0);
  
  fill(51);
  rect(60, 60, 80, 80);

  fill(255);
  ellipse(pos1, 36, 32, 32);

  fill(153);
  ellipse(36, pos2, 32, 32);

  fill(255);
  ellipse(pos3, 164, 32, 32);

  fill(153);
  ellipse(164, pos4, 32, 32);

  i += 3;
  j -= 3;

  if(i > 405) {
    i = 45;
    j = 225;
  }

  float ang1 = radians(i); // convert degrees to radians
  float ang2 = radians(j); // convert degrees to radians
  pos1 = width/2 + (sc * cos(ang1));
  pos2 = width/2 + (sc * sin(ang1));
  pos3 = width/2 + (sc * cos(ang2));
  pos4 = width/2 + (sc * sin(ang2));
}

>>

Taken from [[basic/sinecosine.html|http://ejohn.org/apps/processing.js/examples/basic/sinecosine.html]]
by Daniel Shiffman. Render a simple sine wave.

<<Processing 

int xspacing = 8;   // How far apart should each horizontal location be spaced
int w;              // Width of entire wave

float theta = 0.0;       // Start angle at 0
float amplitude = 75.0;  // Height of wave
float period = 500.0;    // How many pixels before the wave repeats
float dx;                 // Value for incrementing X, to be calculated as a function of period and xspacing
float[] yvalues;          // Using an array to store height values for the wave (not entirely necessary)

void setup() {
  size(200,200);
  frameRate(30);
  colorMode(RGB,255,255,255,100);
  smooth();
  w = width+16;
  dx = (TWO_PI / period) * xspacing;
  yvalues = new float[w/xspacing];
}

void draw() {
  background(0);
  calcWave();
  renderWave();

}

void calcWave() {
  // Increment theta (try different values for 'angular velocity' here
  theta += 0.02;

  // For every x value, calculate a y value with sine function
  float x = theta;
  for (int i = 0; i < yvalues.length; i++) {
    yvalues[i] = sin(x)*amplitude;
    x+=dx;
  }
}

void renderWave() {
  // A simple way to draw the wave with an ellipse at each location
  for (int x = 0; x < yvalues.length; x++) {
    noStroke();
    fill(255,50);
    ellipseMode(CENTER);
    ellipse(x*xspacing,width/2+yvalues[x],16,16);
  }
}

>>

Taken from [[basic/sinewave.html|http://ejohn.org/apps/processing.js/examples/basic/sinewave.html]]
by <a href="http://www.presstube.com">James Patterson</a>. Demonstrates loading and displaying a transparent GIF image. Created 27 January 2003.

<<Processing 

PImage teddy;

float xpos;
float ypos;
float drag = 30.0;

void setup() 
{
  size(200,200);
  teddy = loadImage("teddy.gif");
  xpos = width/2;
  ypos = height/2;
  frameRate(60);
}

void draw() 
{ 
  background(102);
  
  float difx = mouseX - xpos-teddy.width/2;
  if(abs(difx) > 1.0) {
    xpos = xpos + difx/drag;
    xpos = constrain(xpos, 0, width-teddy.width);
  }  
  
  float dify = mouseY - ypos-teddy.height/2;
  if(abs(dify) > 1.0) {
    ypos = ypos + dify/drag;
    ypos = constrain(ypos, 0, height-teddy.height);
  }  
  
  // Display the sprite at the position xpos, ypos
  image(teddy, xpos, ypos);
}

>>

Taken from [[basic/sprite.html|http://ejohn.org/apps/processing.js/examples/basic/sprite.html]]
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 ("//").

<<Processing 

// The size 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 used as values for specifying what the computer will do.
size(200, 200);

// The background function is a statement that tells the computer
// which color to make the background of the window 
background(102);

>>

Taken from [[basic/statementscomments.html|http://ejohn.org/apps/processing.js/examples/basic/statementscomments.html]]
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.

<<Processing 

int num = 60;
float mx[] = new float[num];
float my[] = new float[num];

void setup() 
{
  size(200, 200);
  smooth();
  noStroke();
  fill(255, 153); 
}

void draw() 
{
  background(51); 
  
  // Reads throught the entire array
  // and shifts the values to the left
  for(int i=1; i<num; i++) {
    mx[i-1] = mx[i];
    my[i-1] = my[i];
  } 
  // Add the new values to the end of the array
  mx[num-1] = mouseX;
  my[num-1] = mouseY;
  
  for(int i=0; i<num; i++) {
    ellipse(mx[i], my[i], i/2, i/2);
  }
}

>>

Taken from [[basic/storinginput.html|http://ejohn.org/apps/processing.js/examples/basic/storinginput.html]]
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.

<<Processing 

float x, y;
float s = 40.0;

void setup() 
{
  size(200,200);
  noStroke();
  frameRate(30);
}

void draw() 
{
  background(102);
  
  x = x + 0.8;
  
  if (x > width + s) {
    x = -s;
  } 
  
  translate(x, height/2-s/2);
  fill(255);
  rect(-s/2, -s/2, s, s);
  
  // 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, s);
  fill(0);
  rect(-s/2, -s/2, s, s);
}

>>

Taken from [[basic/translate.html|http://ejohn.org/apps/processing.js/examples/basic/translate.html]]
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.

<<Processing 

PImage a, b;
float offset;

void setup() 
{
  size(200, 200);
  a = loadImage("construct.jpg");  // Load an image into the program 
  b = loadImage("wash.jpg");   // Load an image into the program 
  frameRate(60);
}

void draw() 
{ 
  image(a, 0, 0);
  float offsetTarget = map(mouseX, 0, width, -b.width/2 - width/2, 0);
  offset += (offsetTarget-offset)*0.05; 
  tint(255, 153);
  image(b, offset, 20);
}

>>

Taken from [[basic/transparency.html|http://ejohn.org/apps/processing.js/examples/basic/transparency.html]]
By Ira Greenberg Using rotate() and triangle() functions generate a pretty flower. Uncomment the line // rotate(rot+=radians(spin)); in the triBlur() function for a nice variation.

<<Processing 

Point[]p = new Point[3];
float shift = 1.0;
float fade = 0;
float fillCol = 0;
float rot = 0;
float spin = 0;

void setup(){
  size(200, 200);
  background(0);
  smooth();
  fade = 255.0/(width/2.0/shift);
  spin = 360.0/(width/2.0/shift);
  p[0] = new Point(-width/2, height/2);
  p[1] = new Point(width/2, height/2);
  p[2] = new Point(0, -height/2);
  noStroke();
  translate(width/2, height/2);
  triBlur();
}

void triBlur(){
  fill(fillCol);
  fillCol+=fade;
  rotate(spin);
  // another interesting variation: uncomment the line below 
  // rotate(rot+=radians(spin));
  triangle(p[0].x+=shift, p[0].y-=shift/2, p[1].x-=shift, p[1].y-=shift/2, p[2].x, p[2].y+=shift); 
  if(p[0].x<0){
    // recursive call
    triBlur();
  }
}

>>

Taken from [[basic/triangleflower.html|http://ejohn.org/apps/processing.js/examples/basic/triangleflower.html]]
By Ira Greenberg Generate a closed ring using vertex() function and beginShape(TRIANGLE_STRIP) mode. outerRad and innerRad variables control ring's outer/inner radii respectively. Trig functions generate ring.

<<Processing 

size(200, 200);
background(204);
smooth();

int x = width/2;
int y = height/2;
int outerRad = 80;
int innerRad = 50;
float px = 0, py = 0, angle = 0;
float pts = 36;
float rot = 360.0/pts;

beginShape(TRIANGLE_STRIP); 
for (int i=0; i<pts; i++) {
  px = x+cos(radians(angle))*outerRad;
  py = y+sin(radians(angle))*outerRad;
  angle+=rot;
  vertex(px, py);
  px = x+cos(radians(angle))*innerRad;
  py = y+sin(radians(angle))*innerRad;
  vertex(px, py); 
  angle+=rot;
}
endShape();

>>

Taken from [[basic/trianglestrip.html|http://ejohn.org/apps/processing.js/examples/basic/trianglestrip.html]]
Boolean data is one bit of information. 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 "x" is true, vertical black lines are drawn and when the boolean value "x" is false, horizontal gray lines are drawn.

<<Processing 

boolean x = false;

size(200, 200);
background(0);
stroke(0);

for (int i = 1; i < width; i += 2) 
{
  if (i < width/2) {
    x = true;
  } else {
    x = false;
  }
  
  if (x) {
    stroke(255);
    line(i, 1, i, height-1);
  }
  
  if (!x) {
    stroke(126);
    line(width/2 , i, width-2, i);
  }
}

>>

Taken from [[basic/truefalse.html|http://ejohn.org/apps/processing.js/examples/basic/truefalse.html]]
Variables may either have a global or local "scope". For example, variables declared within either the setup() or loop() functions may be only used in these functions. Global variables, variables declared outside of setup() and loop(), may be used anywhere within the program. If a local variable is declared with the same name as a global variable, the program will use the local variable to make its calculations within the current scope. Variables may be localized within classes, functions, and iterative statements.

<<Processing 

int a = 20;  // Create a global variable "a"

void setup() 
{
  size(200, 200);
  background(51);
  stroke(255);
  noLoop();
}

void draw()
{
  // Draw a line using the global variable "a"
  line(a, 0, a, height);
  
  // Create a new variable "a" local to the for() statement 
  for(int a=50; a<80; a += 2) {
    line(a, 0, a, height);
  }
  
  // Create a new variable "a" local to the loop() method
  int a = 100;
  // Draw a line using the new local variable "a"
  line(a, 0, a, height);  
  
  // Make a call to the custom function drawAnotherLine()
  drawAnotherLine();
  
  // Make a call to the custom function setYetAnotherLine()
  drawYetAnotherLine();
}

void drawAnotherLine() 
{
  // Create a new variable "a" local to this method
  int a = 185;
  // Draw a line using the local variable "a"
  line(a, 0, a, height);
}

void drawYetAnotherLine() 
{
  // Because no new local variable "a" is set, 
  // this lines draws using the original global
  // variable "a" which is set to the value 20.
  line(a+2, 0, a+2, height);
}

>>

Taken from [[basic/variablescope.html|http://ejohn.org/apps/processing.js/examples/basic/variablescope.html]]
Variables are used for storing values. In this example, changing the values of variables 'a' and 'b' significantly change the composition.

<<Processing 

size(200, 200);
background(0);
stroke(153);

int a = 20;
int b = 50;
int c = a*8;
int d = a*9;
int e = b-a;
int f = b*2;
int g = f+e;

line(a, f, b, g);
line(b, e, b, g);
line(b, e, d, c);
line(a, e, d-e, c);

>>

Taken from [[basic/variables.html|http://ejohn.org/apps/processing.js/examples/basic/variables.html]]
The beginShape() function begins recording vertices for a shape and endShape() stops recording. A vertex is a location in space specified by X, Y, and sometimes Z coordinates. After calling the beginShape() function, a series of vertex() functions must follow. To stop drawing the shape, call the endShape() functions.

<<Processing 

size(200, 200);
background(0);
noFill();

stroke(102);
beginShape();
curveVertex(168, 182);
curveVertex(168, 182);
curveVertex(136, 38);
curveVertex(42, 34);
curveVertex(64, 200);
curveVertex(64, 200);
endShape();

stroke(51);
beginShape(LINES);
vertex(60, 40);
vertex(160, 10);
vertex(170, 150);
vertex(60, 150);
endShape();

stroke(126);
beginShape();
vertex(60, 40);
bezierVertex(160, 10, 170, 150, 60, 150);
endShape();

stroke(255);
beginShape(POINTS);
vertex(60, 40);
vertex(160, 10);
vertex(170, 150);
vertex(60, 150);
endShape();

>>

Taken from [[basic/vertices.html|http://ejohn.org/apps/processing.js/examples/basic/vertices.html]]
by Ira Greenberg. Generate a gradient along a sin() wave.

<<Processing 

size(50, 50);
background(200,200,200);
float angle = 0;
float px = 0, py = 0;
float amplitude = 30;
float frequency = 0;
float fillGap = 2.5;
color c;

for (int i =- 75; i < height+75; i++){
  // reset angle to 0, so waves stack properly
  angle = 0;
  // increasing frequency causes more gaps
  frequency+=.006;
  for (float j=0; j<width+75; j++){
    py = i+sin(radians(angle))*amplitude;
    angle+=frequency;
    c =  color(abs(py-i)*255/amplitude, 255-abs(py-i)*255/amplitude, j*(255.0/(width+50)));
    // hack to fill gaps. Raise value of fillGap
    // if you increase frequency
    for (int filler = 0; filler<fillGap; filler++){
      set(int(j-filler), int(py)-filler, c);
      set(int(j), int(py), c);
      set(int(j+filler), int(py)+filler, c);
    }
  }
}

>>

Taken from [[basic/wavegradient.html|http://ejohn.org/apps/processing.js/examples/basic/wavegradient.html]]
The 'width' and 'height' variables contain the width and height of the display window as defined in the size() function.

<<Processing 

size(200, 200);
background(127);
noStroke();
for(int i=0; i<height; i+=20) {
  fill(0);
  rect(0, i, width, 10);
  fill(255);
  rect(i, 0, 10, height);
}

>>

Taken from [[basic/widthheight.html|http://ejohn.org/apps/processing.js/examples/basic/widthheight.html]]
The text() function is used for writing words to the screen.

<<Processing 

size(200, 200);
background(102);

// Load the font. Fonts are located within the 
// main Processing directory/folder and they
// must be placed within the data directory
// of your sketch for them to load
PFont fontA = loadFont("Arial");

// Set the font and its size (in units of pixels)
textFont(fontA, 32);

int x = 30;

// Use fill() to change the value or color of the text
fill(0);
text("ichi", x, 60);
fill(51);
text("ni", x, 95);
fill(204);
text("san", x, 130);
fill(255);
text("shi", x, 165);

>>

Taken from [[basic/words.html|http://ejohn.org/apps/processing.js/examples/basic/words.html]]
(function(){var undef;var ajax=function ajax(url){var xhr=new XMLHttpRequest();xhr.open("GET",url,false);xhr.setRequestHeader("If-Modified-Since","Fri, 01 Jan 1960 00:00:00 GMT");xhr.send(null);if(xhr.status!==200&&xhr.status!==0){throw ("XMLHttpRequest failed, status code "+xhr.status)}return xhr.responseText};function fixReplaceByRegExp(){var re=/t/g;if("t".replace(re,"")!==null&&re.exec("t")){return}var _ie_replace=String.prototype.replace;String.prototype.replace=function(searchValue,repaceValue){var result=_ie_replace.apply(this,arguments);if(searchValue instanceof RegExp&&searchValue.global){searchValue.lastIndex=0}return result}}function fixMatchByRegExp(){var re=/t/g;if("t".match(re)!==null&&re.exec("t")){return}var _ie_match=String.prototype.match;String.prototype.match=function(searchValue){var result=_ie_match.apply(this,arguments);if(searchValue instanceof RegExp&&searchValue.global){searchValue.lastIndex=0}return result}}fixReplaceByRegExp();fixMatchByRegExp();(function fixOperaCreateImageData(){try{if(!("createImageData" in CanvasRenderingContext2D.prototype)){CanvasRenderingContext2D.prototype.createImageData=function(sw,sh){return new ImageData(sw,sh)}}}catch(e){}}());var PConstants={X:0,Y:1,Z:2,R:3,G:4,B:5,A:6,U:7,V:8,NX:9,NY:10,NZ:11,EDGE:12,SR:13,SG:14,SB:15,SA:16,SW:17,TX:18,TY:19,TZ:20,VX:21,VY:22,VZ:23,VW:24,AR:25,AG:26,AB:27,DR:3,DG:4,DB:5,DA:6,SPR:28,SPG:29,SPB:30,SHINE:31,ER:32,EG:33,EB:34,BEEN_LIT:35,VERTEX_FIELD_COUNT:36,P2D:1,JAVA2D:1,WEBGL:2,P3D:2,OPENGL:2,PDF:0,DXF:0,OTHER:0,WINDOWS:1,MAXOSX:2,LINUX:3,EPSILON:0.0001,MAX_FLOAT:3.4028235e+38,MIN_FLOAT:-3.4028235e+38,MAX_INT:2147483647,MIN_INT:-2147483648,PI:Math.PI,TWO_PI:2*Math.PI,HALF_PI:Math.PI/2,THIRD_PI:Math.PI/3,QUARTER_PI:Math.PI/4,DEG_TO_RAD:Math.PI/180,RAD_TO_DEG:180/Math.PI,WHITESPACE:" \t\n\r\f\u00A0",RGB:1,ARGB:2,HSB:3,ALPHA:4,CMYK:5,TIFF:0,TARGA:1,JPEG:2,GIF:3,BLUR:11,GRAY:12,INVERT:13,OPAQUE:14,POSTERIZE:15,THRESHOLD:16,ERODE:17,DILATE:18,REPLACE:0,BLEND:1<<0,ADD:1<<1,SUBTRACT:1<<2,LIGHTEST:1<<3,DARKEST:1<<4,DIFFERENCE:1<<5,EXCLUSION:1<<6,MULTIPLY:1<<7,SCREEN:1<<8,OVERLAY:1<<9,HARD_LIGHT:1<<10,SOFT_LIGHT:1<<11,DODGE:1<<12,BURN:1<<13,ALPHA_MASK:4278190080,RED_MASK:16711680,GREEN_MASK:65280,BLUE_MASK:255,CUSTOM:0,ORTHOGRAPHIC:2,PERSPECTIVE:3,POINT:2,POINTS:2,LINE:4,LINES:4,TRIANGLE:8,TRIANGLES:9,TRIANGLE_STRIP:10,TRIANGLE_FAN:11,QUAD:16,QUADS:16,QUAD_STRIP:17,POLYGON:20,PATH:21,RECT:30,ELLIPSE:31,ARC:32,SPHERE:40,BOX:41,GROUP:0,PRIMITIVE:1,GEOMETRY:3,VERTEX:0,BEZIER_VERTEX:1,CURVE_VERTEX:2,BREAK:3,CLOSESHAPE:4,OPEN:1,CLOSE:2,CORNER:0,CORNERS:1,RADIUS:2,CENTER_RADIUS:2,CENTER:3,DIAMETER:3,CENTER_DIAMETER:3,BASELINE:0,TOP:101,BOTTOM:102,NORMAL:1,NORMALIZED:1,IMAGE:2,MODEL:4,SHAPE:5,SQUARE:"butt",ROUND:"round",PROJECT:"square",MITER:"miter",BEVEL:"bevel",AMBIENT:0,DIRECTIONAL:1,SPOT:3,BACKSPACE:8,TAB:9,ENTER:10,RETURN:13,ESC:27,DELETE:127,CODED:65535,SHIFT:16,CONTROL:17,ALT:18,CAPSLK:20,PGUP:33,PGDN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,INS:45,DEL:46,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLK:144,ARROW:"default",CROSS:"crosshair",HAND:"pointer",MOVE:"move",TEXT:"text",WAIT:"wait",NOCURSOR:"url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto",DISABLE_OPENGL_2X_SMOOTH:1,ENABLE_OPENGL_2X_SMOOTH:-1,ENABLE_OPENGL_4X_SMOOTH:2,ENABLE_NATIVE_FONTS:3,DISABLE_DEPTH_TEST:4,ENABLE_DEPTH_TEST:-4,ENABLE_DEPTH_SORT:5,DISABLE_DEPTH_SORT:-5,DISABLE_OPENGL_ERROR_REPORT:6,ENABLE_OPENGL_ERROR_REPORT:-6,ENABLE_ACCURATE_TEXTURES:7,DISABLE_ACCURATE_TEXTURES:-7,HINT_COUNT:10,SINCOS_LENGTH:parseInt(360/0.5,10),PRECISIONB:15,PRECISIONF:1<<15,PREC_MAXVAL:(1<<15)-1,PREC_ALPHA_SHIFT:24-15,PREC_RED_SHIFT:16-15,NORMAL_MODE_AUTO:0,NORMAL_MODE_SHAPE:1,NORMAL_MODE_VERTEX:2,MAX_LIGHTS:8};function setupTypedArray(name,fallback){if(typeof this[name]!=="function"&&typeof this[name]!=="object"){if(typeof this[fallback]==="function"){this[name]=this[fallback]}else{this[name]=function(obj){if(obj instanceof Array){return obj}else{if(typeof obj==="number"){return new Array(obj)}}}}}}setupTypedArray("Float32Array","WebGLFloatArray");setupTypedArray("Int32Array","WebGLIntArray");setupTypedArray("Uint16Array","WebGLUnsignedShortArray");setupTypedArray("Uint8Array","WebGLUnsignedByteArray");var ArrayList=(function(){function Iterator(array){var index=0;this.hasNext=function(){return index<array.length};this.next=function(){return array[index++]};this.remove=function(){array.splice(index,1)}}function ArrayList(){var array=arguments.length===0?[]:typeof arguments[0]==="number"?new Array(0|arguments[0]):arguments[0];this.get=function(i){return array[i]};this.contains=function(item){return array.indexOf(item)!==-1};this.add=function(){if(arguments.length===1){array.push(arguments[0])}else{if(arguments.length===2){var arg0=arguments[0];if(typeof arg0==="number"){if(arg0>=0&&arg0<=array.length){array.splice(arg0,0,arguments[1])}else{throw (arg0+" is not a valid index")}}else{throw (typeof arg0+" is not a number")}}else{throw ("Please use the proper number of parameters.")}}};this.set=function(){if(arguments.length===2){var arg0=arguments[0];if(typeof arg0==="number"){if(arg0>=0&&arg0<array.length){array.splice(arg0,1,arguments[1])}else{throw (arg0+" is not a valid index.")}}else{throw (typeof arg0+" is not a number")}}else{throw ("Please use the proper number of parameters.")}};this.size=function(){return array.length};this.clear=function(){array.length=0};this.remove=function(i){return array.splice(i,1)[0]};this.isEmpty=function(){return !array.length};this.clone=function(){return new ArrayList(array.slice(0))};this.toArray=function(){return array.slice(0)};this.iterator=function(){return new Iterator(array)}}return ArrayList}());var HashMap=(function(){function virtHashCode(obj){if(obj.constructor===String){var hash=0;for(var i=0;i<obj.length;++i){hash=(hash*31+obj.charCodeAt(i))&4294967295}return hash}else{if(typeof(obj)!=="object"){return obj&4294967295}else{if("hashCode" in obj){return obj.hashCode.call(obj)}else{if(obj.$id===undef){obj.$id=((Math.floor(Math.random()*65536)-32768)<<16)|Math.floor(Math.random()*65536)}return obj.$id}}}}function virtEquals(obj,other){if(obj===null||other===null){return(obj===null)&&(other===null)}else{if(obj.constructor===String){return obj===other}else{if(typeof(obj)!=="object"){return obj===other}else{if("equals" in obj){return obj.equals.call(obj,other)}else{return obj===other}}}}}function HashMap(){if(arguments.length===1&&arguments[0].constructor===HashMap){return arguments[0].clone()}var initialCapacity=arguments.length>0?arguments[0]:16;var loadFactor=arguments.length>1?arguments[1]:0.75;var buckets=new Array(initialCapacity);var count=0;var hashMap=this;function ensureLoad(){if(count<=loadFactor*buckets.length){return}var allEntries=[];for(var i=0;i<buckets.length;++i){if(buckets[i]!==undef){allEntries=allEntries.concat(buckets[i])}}buckets=new Array(buckets.length*2);for(var j=0;j<allEntries.length;++j){var index=virtHashCode(allEntries[j].key)%buckets.length;var bucket=buckets[index];if(bucket===undef){buckets[index]=bucket=[]}bucket.push(allEntries[j])}}function Iterator(conversion,removeItem){var bucketIndex=0;var itemIndex=-1;var endOfBuckets=false;function findNext(){while(!endOfBuckets){++itemIndex;if(bucketIndex>=buckets.length){endOfBuckets=true}else{if(buckets[bucketIndex]===undef||itemIndex>=buckets[bucketIndex].length){itemIndex=-1;++bucketIndex}else{return}}}}this.hasNext=function(){return !endOfBuckets};this.next=function(){var result=conversion(buckets[bucketIndex][itemIndex]);findNext();return result};this.remove=function(){removeItem(this.next());--itemIndex};findNext()}function Set(conversion,isIn,removeItem){this.clear=function(){hashMap.clear()};this.contains=function(o){return isIn(o)};this.containsAll=function(o){var it=o.iterator();while(it.hasNext()){if(!this.contains(it.next())){return false}}return true};this.isEmpty=function(){return hashMap.isEmpty()};this.iterator=function(){return new Iterator(conversion,removeItem)};this.remove=function(o){if(this.contains(o)){removeItem(o);return true}return false};this.removeAll=function(c){var it=c.iterator();var changed=false;while(it.hasNext()){var item=it.next();if(this.contains(item)){removeItem(item);changed=true}}return true};this.retainAll=function(c){var it=this.iterator();var toRemove=[];while(it.hasNext()){var entry=it.next();if(!c.contains(entry)){toRemove.push(entry)}}for(var i=0;i<toRemove.length;++i){removeItem(toRemove[i])}return toRemove.length>0};this.size=function(){return hashMap.size()};this.toArray=function(){var result=new ArrayList(0);var it=this.iterator();while(it.hasNext()){result.push(it.next())}return result}}function Entry(pair){this._isIn=function(map){return map===hashMap&&(pair.removed===undef)};this.equals=function(o){return virtEquals(pair.key,o.getKey())};this.getKey=function(){return pair.key};this.getValue=function(){return pair.value};this.hashCode=function(o){return virtHashCode(pair.key)};this.setValue=function(value){var old=pair.value;pair.value=value;return old}}this.clear=function(){count=0;buckets=new Array(initialCapacity)};this.clone=function(){var map=new HashMap();map.putAll(this);return map};this.containsKey=function(key){var index=virtHashCode(key)%buckets.length;var bucket=buckets[index];if(bucket===undef){return false}for(var i=0;i<bucket.length;++i){if(virtEquals(bucket[i].key,key)){return true}}return false};this.containsValue=function(value){for(var i=0;i<buckets.length;++i){var bucket=buckets[i];if(bucket===undef){continue}for(var j=0;j<bucket.length;++j){if(virtEquals(bucket[j].value,value)){return true}}}return false};this.entrySet=function(){return new Set(function(pair){return new Entry(pair)},function(pair){return pair.constructor===Entry&&pair._isIn(hashMap)},function(pair){return hashMap.remove(pair.getKey())})};this.get=function(key){var index=virtHashCode(key)%buckets.length;var bucket=buckets[index];if(bucket===undef){return null}for(var i=0;i<bucket.length;++i){if(virtEquals(bucket[i].key,key)){return bucket[i].value}}return null};this.isEmpty=function(){return count===0};this.keySet=function(){return new Set(function(pair){return pair.key},function(key){return hashMap.containsKey(key)},function(key){return hashMap.remove(key)})};this.put=function(key,value){var index=virtHashCode(key)%buckets.length;var bucket=buckets[index];if(bucket===undef){++count;buckets[index]=[{key:key,value:value}];ensureLoad();return null}for(var i=0;i<bucket.length;++i){if(virtEquals(bucket[i].key,key)){var previous=bucket[i].value;bucket[i].value=value;return previous}}++count;bucket.push({key:key,value:value});ensureLoad();return null};this.putAll=function(m){var it=m.entrySet().iterator();while(it.hasNext()){var entry=it.next();this.put(entry.getKey(),entry.getValue())}};this.remove=function(key){var index=virtHashCode(key)%buckets.length;var bucket=buckets[index];if(bucket===undef){return null}for(var i=0;i<bucket.length;++i){if(virtEquals(bucket[i].key,key)){--count;var previous=bucket[i].value;bucket[i].removed=true;if(bucket.length>1){bucket.splice(i,1)}else{buckets[index]=undef}return previous}}return null};this.size=function(){return count};this.values=function(){var result=new ArrayList(0);var it=this.entrySet().iterator();while(it.hasNext()){var entry=it.next();result.push(entry.getValue())}return result}}return HashMap}());var PVector=(function(){function PVector(x,y,z){this.x=x||0;this.y=y||0;this.z=z||0}function createPVectorMethod(method){return function(v1,v2){var v=v1.get();v[method](v2);return v}}function createSimplePVectorMethod(method){return function(v1,v2){return v1[method](v2)}}var simplePVMethods="dist dot cross".split(" ");var method=simplePVMethods.length;PVector.angleBetween=function(v1,v2){return Math.acos(v1.dot(v2)/(v1.mag()*v2.mag()))};PVector.prototype={set:function(v,y,z){if(arguments.length===1){this.set(v.x||v[0],v.y||v[1],v.z||v[2])}else{this.x=v;this.y=y;this.z=z}},get:function(){return new PVector(this.x,this.y,this.z)},mag:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},add:function(v,y,z){if(arguments.length===3){this.x+=v;this.y+=y;this.z+=z}else{if(arguments.length===1){this.x+=v.x;this.y+=v.y;this.z+=v.z}}},sub:function(v,y,z){if(arguments.length===3){this.x-=v;this.y-=y;this.z-=z}else{if(arguments.length===1){this.x-=v.x;this.y-=v.y;this.z-=v.z}}},mult:function(v){if(typeof v==="number"){this.x*=v;this.y*=v;this.z*=v}else{if(typeof v==="object"){this.x*=v.x;this.y*=v.y;this.z*=v.z}}},div:function(v){if(typeof v==="number"){this.x/=v;this.y/=v;this.z/=v}else{if(typeof v==="object"){this.x/=v.x;this.y/=v.y;this.z/=v.z}}},dist:function(v){var dx=this.x-v.x,dy=this.y-v.y,dz=this.z-v.z;return Math.sqrt(dx*dx+dy*dy+dz*dz)},dot:function(v,y,z){if(arguments.length===3){return(this.x*v+this.y*y+this.z*z)}else{if(arguments.length===1){return(this.x*v.x+this.y*v.y+this.z*v.z)}}},cross:function(v){return new PVector(this.y*v.z-v.y*this.z,this.z*v.x-v.z*this.x,this.x*v.y-v.x*this.y)},normalize:function(){var m=this.mag();if(m>0){this.div(m)}},limit:function(high){if(this.mag()>high){this.normalize();this.mult(high)}},heading2D:function(){return(-Math.atan2(-this.y,this.x))},toString:function(){return"["+this.x+", "+this.y+", "+this.z+"]"},array:function(){return[this.x,this.y,this.z]}};while(method--){PVector[simplePVMethods[method]]=createSimplePVectorMethod(simplePVMethods[method])}for(method in PVector.prototype){if(PVector.prototype.hasOwnProperty(method)&&!PVector.hasOwnProperty(method)){PVector[method]=createPVectorMethod(method)}}return PVector}());function DefaultScope(){}DefaultScope.prototype=PConstants;var defaultScope=new DefaultScope();defaultScope.ArrayList=ArrayList;defaultScope.HashMap=HashMap;defaultScope.PVector=PVector;var Processing=this.Processing=function Processing(curElement,aCode){if(!(this instanceof Processing)){throw ("called Processing constructor as if it were a function: missing 'new'.")}var p=this;p.externals={canvas:curElement,context:undef,sketch:undef,onblur:function(){},onfocus:function(){}};p.name="Processing.js Instance";p.use3DContext=false;p.focused=true;p.breakShape=false;p.glyphTable={};p.pmouseX=0;p.pmouseY=0;p.mouseX=0;p.mouseY=0;p.mouseButton=0;p.mouseScroll=0;p.mouseClicked=undef;p.mouseDragged=undef;p.mouseMoved=undef;p.mousePressed=undef;p.mouseReleased=undef;p.mouseScrolled=undef;p.key=undef;p.keyCode=undef;p.keyPressed=function(){};p.keyReleased=function(){};p.keyTyped=function(){};p.draw=undef;p.setup=undef;p.__mousePressed=false;p.__keyPressed=false;p.__frameRate=0;p.frameCount=0;p.width=curElement.width-0;p.height=curElement.height-0;p.defineProperty=function(obj,name,desc){if("defineProperty" in Object){Object.defineProperty(obj,name,desc)}else{if(desc.hasOwnProperty("get")){obj.__defineGetter__(name,desc.get)}if(desc.hasOwnProperty("set")){obj.__defineSetter__(name,desc.set)}}};var curContext,curSketch,online=true,doFill=true,fillStyle=[1,1,1,1],currentFillColor=4294967295,isFillDirty=true,doStroke=true,strokeStyle=[0.8,0.8,0.8,1],currentStrokeColor=4294835709,isStrokeDirty=true,lineWidth=1,loopStarted=false,doLoop=true,looping=0,curRectMode=PConstants.CORNER,curEllipseMode=PConstants.CENTER,normalX=0,normalY=0,normalZ=0,normalMode=PConstants.NORMAL_MODE_AUTO,inDraw=false,curFrameRate=60,curCursor=PConstants.ARROW,oldCursor=curElement.style.cursor,curMsPerFrame=1,curShape=PConstants.POLYGON,curShapeCount=0,curvePoints=[],curTightness=0,curveDet=20,curveInited=false,bezDetail=20,colorModeA=255,colorModeX=255,colorModeY=255,colorModeZ=255,pathOpen=false,mouseDragging=false,curColorMode=PConstants.RGB,curTint=null,curTextSize=12,curTextFont="Arial",curTextLeading=14,getLoaded=false,start=new Date().getTime(),timeSinceLastFPS=start,framesSinceLastFPS=0,textcanvas,curveBasisMatrix,curveToBezierMatrix,curveDrawMatrix,bezierDrawMatrix,bezierBasisInverse,bezierBasisMatrix,firstCodedDown=true,firstEDGKeyDown=true,firstEDMKeyDown=true,firstMKeyDown=true,firstGKeyDown=true,gRefire=false,curContextCache={attributes:{},locations:{}},programObject3D,programObject2D,programObjectUnlitShape,boxBuffer,boxNormBuffer,boxOutlineBuffer,rectBuffer,rectNormBuffer,sphereBuffer,lineBuffer,fillBuffer,fillColorBuffer,strokeColorBuffer,pointBuffer,shapeTexVBO,canTex,textTex,curTexture={width:0,height:0},curTextureMode=PConstants.IMAGE,usingTexture=false,textBuffer,textureBuffer,indexBuffer,horizontalTextAlignment=PConstants.LEFT,verticalTextAlignment=PConstants.BASELINE,baselineOffset=0.2,tMode=PConstants.MODEL,originalContext,proxyContext=null,isContextReplaced=false,setPixelsCached,maxPixelsCached=1000,codedKeys=[PConstants.SHIFT,PConstants.CONTROL,PConstants.ALT,PConstants.CAPSLK,PConstants.PGUP,PConstants.PGDN,PConstants.END,PConstants.HOME,PConstants.LEFT,PConstants.UP,PConstants.RIGHT,PConstants.DOWN,PConstants.NUMLK,PConstants.INS,PConstants.F1,PConstants.F2,PConstants.F3,PConstants.F4,PConstants.F5,PConstants.F6,PConstants.F7,PConstants.F8,PConstants.F9,PConstants.F10,PConstants.F11,PConstants.F12];var stylePaddingLeft,stylePaddingTop,styleBorderLeft,styleBorderTop;if(document.defaultView&&document.defaultView.getComputedStyle){stylePaddingLeft=parseInt(document.defaultView.getComputedStyle(curElement,null)["paddingLeft"],10)||0;stylePaddingTop=parseInt(document.defaultView.getComputedStyle(curElement,null)["paddingTop"],10)||0;styleBorderLeft=parseInt(document.defaultView.getComputedStyle(curElement,null)["borderLeftWidth"],10)||0;styleBorderTop=parseInt(document.defaultView.getComputedStyle(curElement,null)["borderTopWidth"],10)||0}var lightCount=0;var sphereDetailV=0,sphereDetailU=0,sphereX=[],sphereY=[],sphereZ=[],sinLUT=new Array(PConstants.SINCOS_LENGTH),cosLUT=new Array(PConstants.SINCOS_LENGTH),sphereVerts,sphereNorms;var cam,cameraInv,forwardTransform,reverseTransform,modelView,modelViewInv,userMatrixStack,inverseCopy,projection,manipulatingCamera=false,frustumMode=false,cameraFOV=60*(Math.PI/180),cameraX=curElement.width/2,cameraY=curElement.height/2,cameraZ=cameraY/Math.tan(cameraFOV/2),cameraNear=cameraZ/10,cameraFar=cameraZ*10,cameraAspect=curElement.width/curElement.height;var vertArray=[],curveVertArray=[],curveVertCount=0,isCurve=false,isBezier=false,firstVert=true;var curShapeMode=PConstants.CORNER;var 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",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#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",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",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#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",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"};var styleArray=new Array(0);var boxVerts=new Float32Array([0.5,0.5,-0.5,0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,0.5,0.5,0.5,-0.5,0.5,0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5,0.5,0.5,0.5,0.5,0.5,-0.5,0.5,0.5,0.5,0.5,-0.5,0.5,0.5,-0.5,0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,0.5,0.5,-0.5,0.5,-0.5,-0.5,-0.5,-0.5,0.5,0.5,0.5,0.5,0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,0.5,0.5,0.5,0.5]);var boxOutlineVerts=new Float32Array([0.5,0.5,0.5,0.5,-0.5,0.5,0.5,0.5,-0.5,0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,-0.5,-0.5,-0.5,0.5,0.5,-0.5,-0.5,0.5,0.5,0.5,0.5,0.5,0.5,-0.5,0.5,0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5,0.5,0.5,0.5,0.5,0.5,-0.5,0.5,0.5,-0.5,-0.5,0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5]);var boxNorms=new Float32Array([0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0]);var rectVerts=new Float32Array([0,0,0,0,1,0,1,1,0,1,0,0]);var rectNorms=new Float32Array([0,0,-1,0,0,-1,0,0,-1,0,0,-1]);var vShaderSrcUnlitShape="varying vec4 frontColor;attribute vec3 aVertex;attribute vec4 aColor;uniform mat4 uView;uniform mat4 uProjection;void main(void) {  frontColor = aColor;  gl_Position = uProjection * uView * vec4(aVertex, 1.0);}";var fShaderSrcUnlitShape="#ifdef GL_ES\nprecision highp float;\n#endif\nvarying vec4 frontColor;void main(void){  gl_FragColor = frontColor;}";var vertexShaderSource2D="varying vec4 frontColor;attribute vec3 Vertex;attribute vec2 aTextureCoord;uniform vec4 color;uniform mat4 model;uniform mat4 view;uniform mat4 projection;uniform float pointSize;varying vec2 vTextureCoord;void main(void) {  gl_PointSize = pointSize;  frontColor = color;  gl_Position = projection * view * model * vec4(Vertex, 1.0);  vTextureCoord = aTextureCoord;}";var fragmentShaderSource2D="#ifdef GL_ES\nprecision highp float;\n#endif\nvarying vec4 frontColor;varying vec2 vTextureCoord;uniform sampler2D uSampler;uniform int picktype;void main(void){  if(picktype == 0){    gl_FragColor = frontColor;  }  else if(picktype == 1){    float alpha = texture2D(uSampler, vTextureCoord).a;    gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n  }}";var vertexShaderSource3D="varying vec4 frontColor;attribute vec3 Vertex;attribute vec3 Normal;attribute vec4 aColor;attribute vec2 aTexture;varying   vec2 vTexture;uniform vec4 color;uniform bool usingMat;uniform vec3 specular;uniform vec3 mat_emissive;uniform vec3 mat_ambient;uniform vec3 mat_specular;uniform float shininess;uniform mat4 model;uniform mat4 view;uniform mat4 projection;uniform mat4 normalTransform;uniform int lightCount;uniform vec3 falloff;struct Light {  bool dummy;  int type;  vec3 color;  vec3 position;  vec3 direction;  float angle;  vec3 halfVector;  float concentration;};uniform Light lights[8];void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {  float d = length( light.position - ecPos );  float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));  totalAmbient += light.color * attenuation;}void DirectionalLight( inout vec3 col, in vec3 ecPos, inout vec3 spec, in vec3 vertNormal, in Light light ) {  float powerfactor = 0.0;  float nDotVP = max(0.0, dot( vertNormal, light.position ));  float nDotVH = max(0.0, dot( vertNormal, normalize( light.position-ecPos )));  if( nDotVP != 0.0 ){    powerfactor = pow( nDotVH, shininess );  }  col += light.color * nDotVP;  spec += specular * powerfactor;}void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in vec3 eye, in Light light ) {  float powerfactor;   vec3 VP = light.position - ecPos;  float d = length( VP );   VP = normalize( VP );  float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));  float nDotVP = max( 0.0, dot( vertNormal, VP ));  vec3 halfVector = normalize( VP + eye );  float nDotHV = max( 0.0, dot( vertNormal, halfVector ));  if( nDotVP == 0.0) {    powerfactor = 0.0;  }  else{    powerfactor = pow( nDotHV, shininess );  }  spec += specular * powerfactor * attenuation;  col += light.color * nDotVP * attenuation;}void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in vec3 eye, in Light light ) {  float spotAttenuation;  float powerfactor;  vec3 VP = light.position - ecPos;   vec3 ldir = normalize( light.direction );  float d = length( VP );  VP = normalize( VP );  float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );  float spotDot = dot( VP, ldir );  if( spotDot < cos( light.angle ) ) {    spotAttenuation = pow( spotDot, light.concentration );  }  else{    spotAttenuation = 1.0;  }  attenuation *= spotAttenuation;  float nDotVP = max( 0.0, dot( vertNormal, VP ));  vec3 halfVector = normalize( VP + eye );  float nDotHV = max( 0.0, dot( vertNormal, halfVector ));  if( nDotVP == 0.0 ) {    powerfactor = 0.0;  }  else {    powerfactor = pow( nDotHV, shininess );  }  spec += specular * powerfactor * attenuation;  col += light.color * nDotVP * attenuation;}void main(void) {  vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );  vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );  vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );  vec4 col = color;  if(color[0] == -1.0){    col = aColor;  }  vec3 norm = vec3( normalTransform * vec4( Normal, 0.0 ) );  vec4 ecPos4 = view * model * vec4(Vertex,1.0);  vec3 ecPos = (vec3(ecPos4))/ecPos4.w;  vec3 eye = vec3( 0.0, 0.0, 1.0 );  if( lightCount == 0 ) {    frontColor = col + vec4(mat_specular,1.0);  }  else {    for( int i = 0; i < lightCount; i++ ) {      if( lights[i].type == 0 ) {        AmbientLight( finalAmbient, ecPos, lights[i] );      }      else if( lights[i].type == 1 ) {        DirectionalLight( finalDiffuse,ecPos, finalSpecular, norm, lights[i] );      }      else if( lights[i].type == 2 ) {        PointLight( finalDiffuse, finalSpecular, norm, ecPos, eye, lights[i] );      }      else if( lights[i].type == 3 ) {        SpotLight( finalDiffuse, finalSpecular, norm, ecPos, eye, lights[i] );      }    }   if( usingMat == false ) {    frontColor = vec4(        vec3(col) * finalAmbient +      vec3(col) * finalDiffuse +      vec3(col) * finalSpecular,      col[3] );   }   else{     frontColor = vec4(        mat_emissive +        (vec3(col) * mat_ambient * finalAmbient) +        (vec3(col) * finalDiffuse) +        (mat_specular * finalSpecular),        col[3] );    }  }  vTexture.xy = aTexture.xy;  gl_Position = projection * view * model * vec4( Vertex, 1.0 );}";var fragmentShaderSource3D="#ifdef GL_ES\nprecision highp float;\n#endif\nvarying vec4 frontColor;uniform sampler2D sampler;uniform bool usingTexture;varying vec2 vTexture;void main(void){  if(usingTexture){    gl_FragColor =  vec4(texture2D(sampler, vTexture.xy));  }  else{    gl_FragColor = frontColor;  }}";function uniformf(cacheId,programObj,varName,varValue){var varLocation=curContextCache.locations[cacheId];if(varLocation===undef){varLocation=curContext.getUniformLocation(programObj,varName);curContextCache.locations[cacheId]=varLocation}if(varLocation!==-1){if(varValue.length===4){curContext.uniform4fv(varLocation,varValue)}else{if(varValue.length===3){curContext.uniform3fv(varLocation,varValue)}else{if(varValue.length===2){curContext.uniform2fv(varLocation,varValue)}else{curContext.uniform1f(varLocation,varValue)}}}}}function uniformi(cacheId,programObj,varName,varValue){var varLocation=curContextCache.locations[cacheId];if(varLocation===undef){varLocation=curContext.getUniformLocation(programObj,varName);curContextCache.locations[cacheId]=varLocation}if(varLocation!==-1){if(varValue.length===4){curContext.uniform4iv(varLocation,varValue)}else{if(varValue.length===3){curContext.uniform3iv(varLocation,varValue)}else{if(varValue.length===2){curContext.uniform2iv(varLocation,varValue)}else{curContext.uniform1i(varLocation,varValue)}}}}}function vertexAttribPointer(cacheId,programObj,varName,size,VBO){var varLocation=curContextCache.attributes[cacheId];if(varLocation===undef){varLocation=curContext.getAttribLocation(programObj,varName);curContextCache.attributes[cacheId]=varLocation}if(varLocation!==-1){curContext.bindBuffer(curContext.ARRAY_BUFFER,VBO);curContext.vertexAttribPointer(varLocation,size,curContext.FLOAT,false,0,0);curContext.enableVertexAttribArray(varLocation)}}function disableVertexAttribPointer(cacheId,programObj,varName){var varLocation=curContextCache.attributes[cacheId];if(varLocation===undef){varLocation=curContext.getAttribLocation(programObj,varName);curContextCache.attributes[cacheId]=varLocation}if(varLocation!==-1){curContext.disableVertexAttribArray(varLocation)}}function uniformMatrix(cacheId,programObj,varName,transpose,matrix){var varLocation=curContextCache.locations[cacheId];if(varLocation===undef){varLocation=curContext.getUniformLocation(programObj,varName);curContextCache.locations[cacheId]=varLocation}if(varLocation!==-1){if(matrix.length===16){curContext.uniformMatrix4fv(varLocation,transpose,matrix)}else{if(matrix.length===9){curContext.uniformMatrix3fv(varLocation,transpose,matrix)}else{curContext.uniformMatrix2fv(varLocation,transpose,matrix)}}}}var imageModeCorner=function imageModeCorner(x,y,w,h,whAreSizes){return{x:x,y:y,w:w,h:h}};var imageModeConvert=imageModeCorner;var imageModeCorners=function imageModeCorners(x,y,w,h,whAreSizes){return{x:x,y:y,w:whAreSizes?w:w-x,h:whAreSizes?h:h-y}};var imageModeCenter=function imageModeCenter(x,y,w,h,whAreSizes){return{x:x-w/2,y:y-h/2,w:w,h:h}};var createProgramObject=function(curContext,vetexShaderSource,fragmentShaderSource){var vertexShaderObject=curContext.createShader(curContext.VERTEX_SHADER);curContext.shaderSource(vertexShaderObject,vetexShaderSource);curContext.compileShader(vertexShaderObject);if(!curContext.getShaderParameter(vertexShaderObject,curContext.COMPILE_STATUS)){throw curContext.getShaderInfoLog(vertexShaderObject)}var fragmentShaderObject=curContext.createShader(curContext.FRAGMENT_SHADER);curContext.shaderSource(fragmentShaderObject,fragmentShaderSource);curContext.compileShader(fragmentShaderObject);if(!curContext.getShaderParameter(fragmentShaderObject,curContext.COMPILE_STATUS)){throw curContext.getShaderInfoLog(fragmentShaderObject)}var programObject=curContext.createProgram();curContext.attachShader(programObject,vertexShaderObject);curContext.attachShader(programObject,fragmentShaderObject);curContext.linkProgram(programObject);if(!curContext.getProgramParameter(programObject,curContext.LINK_STATUS)){throw"Error linking shaders."}return programObject};var charMap={};var Char=p.Character=function Char(chr){if(typeof chr==="string"&&chr.length===1){this.code=chr.charCodeAt(0)}else{this.code=NaN}return(charMap[this.code]===undef)?charMap[this.code]=this:charMap[this.code]};Char.prototype.toString=function(){return String.fromCharCode(this.code)};Char.prototype.valueOf=function(){return this.code};var PShape=p.PShape=function(family){this.family=family||PConstants.GROUP;this.visible=true;this.style=true;this.children=[];this.nameTable=[];this.params=[];this.name="";this.image=null;this.matrix=null;this.kind=null;this.close=null;this.width=null;this.height=null;this.parent=null;this.isVisible=function(){return this.visible};this.setVisible=function(visible){this.visible=visible};this.disableStyle=function(){this.style=false;for(var i=0;i<this.children.length;i++){this.children[i].disableStyle()}};this.enableStyle=function(){this.style=true;for(var i=0;i<this.children.length;i++){this.children[i].enableStyle()}};this.getFamily=function(){return this.family};this.getWidth=function(){return this.width};this.getHeight=function(){return this.height};this.setName=function(name){this.name=name};this.getName=function(){return this.name};this.draw=function(){if(this.visible){this.pre();this.drawImpl();this.post()}};this.drawImpl=function(){if(this.family===PConstants.GROUP){this.drawGroup()}else{if(this.family===PConstants.PRIMITIVE){this.drawPrimitive()}else{if(this.family===PConstants.GEOMETRY){this.drawGeometry()}else{if(this.family===PConstants.PATH){this.drawPath()}}}}};this.drawPath=function(){if(this.vertices.length===0){return}p.beginShape();var i;if(this.vertexCodes.length===0){if(this.vertices[0].length===2){for(i=0;i<this.vertices.length;i++){p.vertex(this.vertices[i][0],this.vertices[i][1])}}else{for(i=0;i<this.vertices.length;i++){p.vertex(this.vertices[i][0],this.vertices[i][1],this.vertices[i][2])}}}else{var index=0;var j;if(this.vertices[0].length===2){for(j=0;j<this.vertexCodes.length;j++){switch(this.vertexCodes[j]){case PConstants.VERTEX:p.vertex(this.vertices[index][0],this.vertices[index][1]);if(this.vertices[index]["moveTo"]===true){vertArray[vertArray.length-1]["moveTo"]=true}else{if(this.vertices[index]["moveTo"]===false){vertArray[vertArray.length-1]["moveTo"]=false}}p.breakShape=false;index++;break;case PConstants.BEZIER_VERTEX:p.bezierVertex(this.vertices[index+0][0],this.vertices[index+0][1],this.vertices[index+1][0],this.vertices[index+1][1],this.vertices[index+2][0],this.vertices[index+2][1]);index+=3;break;case PConstants.CURVE_VERTEX:p.curveVertex(this.vertices[index][0],this.vertices[index][1]);index++;break;case PConstants.BREAK:p.breakShape=true;break}}}else{for(j=0;j<this.vertexCodes.length;j++){switch(this.vertexCodes[j]){case PConstants.VERTEX:p.vertex(this.vertices[index][0],this.vertices[index][1],this.vertices[index][2]);if(this.vertices[index]["moveTo"]===true){vertArray[vertArray.length-1]["moveTo"]=true}else{if(this.vertices[index]["moveTo"]===false){vertArray[vertArray.length-1]["moveTo"]=false}}p.breakShape=false;break;case PConstants.BEZIER_VERTEX:p.bezierVertex(this.vertices[index+0][0],this.vertices[index+0][1],this.vertices[index+0][2],this.vertices[index+1][0],this.vertices[index+1][1],this.vertices[index+1][2],this.vertices[index+2][0],this.vertices[index+2][1],this.vertices[index+2][2]);index+=3;break;case PConstants.CURVE_VERTEX:p.curveVertex(this.vertices[index][0],this.vertices[index][1],this.vertices[index][2]);index++;break;case PConstants.BREAK:p.breakShape=true;break}}}}p.endShape(this.close?PConstants.CLOSE:PConstants.OPEN)};this.drawGeometry=function(){p.beginShape(this.kind);var i;if(this.style){for(i=0;i<this.vertices.length;i++){p.vertex(this.vertices[i])}}else{for(i=0;i<this.vertices.length;i++){var vert=this.vertices[i];if(vert[2]===0){p.vertex(vert[0],vert[1])}else{p.vertex(vert[0],vert[1],vert[2])}}}p.endShape()};this.drawGroup=function(){for(var i=0;i<this.children.length;i++){this.children[i].draw()}};this.drawPrimitive=function(){switch(this.kind){case PConstants.POINT:p.point(this.params[0],this.params[1]);break;case PConstants.LINE:if(this.params.length===4){p.line(this.params[0],this.params[1],this.params[2],this.params[3])}else{p.line(this.params[0],this.params[1],this.params[2],this.params[3],this.params[4],this.params[5])}break;case PConstants.TRIANGLE:p.triangle(this.params[0],this.params[1],this.params[2],this.params[3],this.params[4],this.params[5]);break;case PConstants.QUAD:p.quad(this.params[0],this.params[1],this.params[2],this.params[3],this.params[4],this.params[5],this.params[6],this.params[7]);break;case PConstants.RECT:if(this.image!==null){p.imageMode(PConstants.CORNER);p.image(this.image,this.params[0],this.params[1],this.params[2],this.params[3])}else{p.rectMode(PConstants.CORNER);p.rect(this.params[0],this.params[1],this.params[2],this.params[3])}break;case PConstants.ELLIPSE:p.ellipseMode(PConstants.CORNER);p.ellipse(this.params[0],this.params[1],this.params[2],this.params[3]);break;case PConstants.ARC:p.ellipseMode(PConstants.CORNER);p.arc(this.params[0],this.params[1],this.params[2],this.params[3],this.params[4],this.params[5]);break;case PConstants.BOX:if(this.params.length===1){p.box(this.params[0])}else{p.box(this.params[0],this.params[1],this.params[2])}break;case PConstants.SPHERE:p.sphere(this.params[0]);break}};this.pre=function(){if(this.matrix){p.pushMatrix();curContext.transform(this.matrix.elements[0],this.matrix.elements[3],this.matrix.elements[1],this.matrix.elements[4],this.matrix.elements[2],this.matrix.elements[5])}if(this.style){p.pushStyle();this.styles()}};this.post=function(){if(this.matrix){p.popMatrix()}if(this.style){p.popStyle()}};this.styles=function(){if(this.stroke){p.stroke(this.strokeColor);p.strokeWeight(this.strokeWeight);p.strokeCap(this.strokeCap);p.strokeJoin(this.strokeJoin)}else{p.noStroke()}if(this.fill){p.fill(this.fillColor)}else{p.noFill()}};this.getChild=function(){if(typeof arguments[0]==="number"){return this.children[arguments[0]]}else{var found,i;if(arguments[0]===""||this.name===arguments[0]){return this}else{if(this.nameTable.length>0){for(i=0;i<this.nameTable.length||found;i++){if(this.nameTable[i].getName===arguments[0]){found=this.nameTable[i]}}if(found){return found}}for(i=0;i<this.children.lenth;i++){found=this.children[i].getChild(arguments[0]);if(found){return found}}}return null}};this.getChildCount=function(){return this.children.length};this.addChild=function(child){this.children.push(child);child.parent=this;if(child.getName()!==null){this.addName(child.getName(),child)}};this.addName=function(name,shape){if(this.parent!==null){this.parent.addName(name,shape)}else{this.nameTable.push([name,shape])}};this.translate=function(){if(arguments.length===2){this.checkMatrix(2);this.matrix.translate(arguments[0],arguments[1])}else{this.checkMatrix(3);this.matrix.translate(arguments[0],arguments[1],0)}};this.checkMatrix=function(dimensions){if(this.matrix===null){if(dimensions===2){this.matrix=new p.PMatrix2D()}else{this.matrix=new p.PMatrix3D()}}else{if(dimensions===3&&this.matrix instanceof p.PMatrix2D){this.matrix=new p.PMatrix3D()}}};this.rotateX=function(angle){this.rotate(angle,1,0,0)};this.rotateY=function(angle){this.rotate(angle,0,1,0)};this.rotateZ=function(angle){this.rotate(angle,0,0,1)};this.rotate=function(){if(arguments.length===1){this.checkMatrix(2);this.matrix.rotate(arguments[0])}else{this.checkMatrix(3);this.matrix.rotate(arguments[0],arguments[1],arguments[2],arguments[3])}};this.scale=function(){if(arguments.length===2){this.checkMatrix(2);this.matrix.scale(arguments[0],arguments[1])}else{if(arguments.length===3){this.checkMatrix(2);this.matrix.scale(arguments[0],arguments[1],arguments[2])}else{this.checkMatrix(2);this.matrix.scale(arguments[0])}}};this.resetMatrix=function(){this.checkMatrix(2);this.matrix.reset()};this.applyMatrix=function(matrix){if(arguments.length===1){this.applyMatrix(matrix.elements[0],matrix.elements[1],0,matrix.elements[2],matrix.elements[3],matrix.elements[4],0,matrix.elements[5],0,0,1,0,0,0,0,1)}else{if(arguments.length===6){this.checkMatrix(2);this.matrix.apply(arguments[0],arguments[1],arguments[2],0,arguments[3],arguments[4],arguments[5],0,0,0,1,0,0,0,0,1)}else{if(arguments.length===16){this.checkMatrix(3);this.matrix.apply(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8],arguments[9],arguments[10],arguments[11],arguments[12],arguments[13],arguments[14],arguments[15])}}}}};var PShapeSVG=p.PShapeSVG=function(){p.PShape.call(this);if(arguments.length===1){this.element=arguments[0];this.vertexCodes=[];this.vertices=[];this.opacity=1;this.stroke=false;this.strokeColor=PConstants.ALPHA_MASK;this.strokeWeight=1;this.strokeCap=PConstants.SQUARE;this.strokeJoin=PConstants.MITER;this.strokeGradient=null;this.strokeGradientPaint=null;this.strokeName=null;this.strokeOpacity=1;this.fill=true;this.fillColor=PConstants.ALPHA_MASK;this.fillGradient=null;this.fillGradientPaint=null;this.fillName=null;this.fillOpacity=1;if(this.element.getName()!=="svg"){throw ("root is not <svg>, it's <"+this.element.getName()+">")}}else{if(arguments.length===2){if(typeof arguments[1]==="string"){if(arguments[1].indexOf(".svg")>-1){this.element=new p.XMLElement(null,arguments[1]);this.vertexCodes=[];this.vertices=[];this.opacity=1;this.stroke=false;this.strokeColor=PConstants.ALPHA_MASK;this.strokeWeight=1;this.strokeCap=PConstants.SQUARE;this.strokeJoin=PConstants.MITER;this.strokeGradient="";this.strokeGradientPaint="";this.strokeName="";this.strokeOpacity=1;this.fill=true;this.fillColor=PConstants.ALPHA_MASK;this.fillGradient=null;this.fillGradientPaint=null;this.fillOpacity=1}}else{if(arguments[0]){this.element=arguments[1];this.vertexCodes=arguments[0].vertexCodes.slice();this.vertices=arguments[0].vertices.slice();this.stroke=arguments[0].stroke;this.strokeColor=arguments[0].strokeColor;this.strokeWeight=arguments[0].strokeWeight;this.strokeCap=arguments[0].strokeCap;this.strokeJoin=arguments[0].strokeJoin;this.strokeGradient=arguments[0].strokeGradient;this.strokeGradientPaint=arguments[0].strokeGradientPaint;this.strokeName=arguments[0].strokeName;this.fill=arguments[0].fill;this.fillColor=arguments[0].fillColor;this.fillGradient=arguments[0].fillGradient;this.fillGradientPaint=arguments[0].fillGradientPaint;this.fillName=arguments[0].fillName;this.strokeOpacity=arguments[0].strokeOpacity;this.fillOpacity=arguments[0].fillOpacity;this.opacity=arguments[0].opacity}}}}this.name=this.element.getStringAttribute("id");var displayStr=this.element.getStringAttribute("display","inline");this.visible=displayStr!=="none";var str=this.element.getAttribute("transform");if(str){this.matrix=this.parseMatrix(str)}var viewBoxStr=this.element.getStringAttribute("viewBox");if(viewBoxStr!==null){var viewBox=viewBoxStr.split(" ");this.width=viewBox[2];this.height=viewBox[3]}var unitWidth=this.element.getStringAttribute("width");var unitHeight=this.element.getStringAttribute("height");if(unitWidth!==null){this.width=this.parseUnitSize(unitWidth);this.height=this.parseUnitSize(unitHeight)}else{if((this.width===0)||(this.height===0)){this.width=1;this.height=1;throw ("The width and/or height is not readable in the <svg> tag of this file.")}}this.parseColors(this.element);this.parseChildren(this.element)};PShapeSVG.prototype={parseMatrix:function(str){this.checkMatrix(2);var pieces=[];str.replace(/\s*(\w+)\((.*?)\)/g,function(all){pieces.push(p.trim(all))});if(pieces.length===0){p.println("Transformation:"+str+" is empty");return null}for(var i=0;i<pieces.length;i++){var m=[];pieces[i].replace(/\((.*?)\)/,(function(){return function(all,params){m=params.replace(/,+/g," ").split(/\s+/)}}()));if(pieces[i].indexOf("matrix")!==-1){this.matrix.set(m[0],m[2],m[4],m[1],m[3],m[5])}else{if(pieces[i].indexOf("translate")!==-1){var tx=m[0];var ty=(m.length===2)?m[1]:0;this.matrix.translate(tx,ty)}else{if(pieces[i].indexOf("scale")!==-1){var sx=m[0];var sy=(m.length===2)?m[1]:m[0];this.matrix.scale(sx,sy)}else{if(pieces[i].indexOf("rotate")!==-1){var angle=m[0];if(m.length===1){this.matrix.rotate(p.radians(angle))}else{if(m.length===3){this.matrix.translate(m[1],m[2]);this.matrix.rotate(p.radians(m[0]));this.matrix.translate(-m[1],-m[2])}}}else{if(pieces[i].indexOf("skewX")!==-1){this.matrix.skewX(parseFloat(m[0]))}else{if(pieces[i].indexOf("skewY")!==-1){this.matrix.skewY(m[0])}}}}}}}return this.matrix},parseChildren:function(element){var newelement=element.getChildren();var children=new p.PShape();for(var i=0;i<newelement.length;i++){var kid=this.parseChild(newelement[i]);if(kid){children.addChild(kid)}}this.children.push(children)},getName:function(){return this.name},parseChild:function(elem){var name=elem.getName();var shape;switch(name){case"g":shape=new PShapeSVG(this,elem);break;case"defs":shape=new PShapeSVG(this,elem);break;case"line":shape=new PShapeSVG(this,elem);shape.parseLine();break;case"circle":shape=new PShapeSVG(this,elem);shape.parseEllipse(true);break;case"ellipse":shape=new PShapeSVG(this,elem);shape.parseEllipse(false);break;case"rect":shape=new PShapeSVG(this,elem);shape.parseRect();break;case"polygon":shape=new PShapeSVG(this,elem);shape.parsePoly(true);break;case"polyline":shape=new PShapeSVG(this,elem);shape.parsePoly(false);break;case"path":shape=new PShapeSVG(this,elem);shape.parsePath();break;case"radialGradient":break;case"linearGradient":break;case"text":p.println("Text in SVG files is not currently supported, convert text to outlines instead.");break;case"filter":p.println("Filters are not supported.");break;case"mask":p.println("Masks are not supported.");break;default:p.println("Ignoring  <"+name+"> tag.");break}return shape},parsePath:function(){this.family=PConstants.PATH;this.kind=0;var pathDataChars=[];var c;var pathData=p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g," "));if(pathData===null){return}pathData=pathData.toCharArray();var cx=0,cy=0,ctrlX=0,ctrlY=0,ctrlX1=0,ctrlX2=0,ctrlY1=0,ctrlY2=0,endX=0,endY=0,ppx=0,ppy=0,px=0,py=0,i=0,j=0,valOf=0;var str="";var tmpArray=[];var flag=false;var lastInstruction;var command;while(i<pathData.length){valOf=pathData[i].valueOf();if((valOf>=65&&valOf<=90)||(valOf>=97&&valOf<=122)){j=i;i++;if(i<pathData.length){tmpArray=[];valOf=pathData[i].valueOf();while(!((valOf>=65&&valOf<=90)||(valOf>=97&&valOf<=100)||(valOf>=102&&valOf<=122))&&flag===false){if(valOf===32){if(str!==""){tmpArray.push(parseFloat(str));str=""}i++}else{if(valOf===45){if(pathData[i-1].valueOf()===101){str+=pathData[i].toString();i++}else{if(str!==""){tmpArray.push(parseFloat(str))}str=pathData[i].toString();i++}}else{str+=pathData[i].toString();i++}}if(i===pathData.length){flag=true}else{valOf=pathData[i].valueOf()}}}if(str!==""){tmpArray.push(parseFloat(str));str=""}command=pathData[j];switch(command.valueOf()){case 77:if(tmpArray.length>=2&&tmpArray.length%2===0){cx=tmpArray[0];cy=tmpArray[1];this.parsePathMoveto(cx,cy);if(tmpArray.length>2){for(j=2;j<tmpArray.length;j+=2){cx=tmpArray[j];cy=tmpArray[j+1];this.parsePathLineto(cx,cy)}}}break;case 109:if(tmpArray.length>=2&&tmpArray.length%2===0){cx+=tmpArray[0];cy+=tmpArray[1];this.parsePathMoveto(cx,cy);if(tmpArray.length>2){for(j=2;j<tmpArray.length;j+=2){cx+=tmpArray[j];cy+=tmpArray[j+1];this.parsePathLineto(cx,cy)}}}break;case 76:if(tmpArray.length>=2&&tmpArray.length%2===0){for(j=0;j<tmpArray.length;j+=2){cx=tmpArray[j];cy=tmpArray[j+1];this.parsePathLineto(cx,cy)}}break;case 108:if(tmpArray.length>=2&&tmpArray.length%2===0){for(j=0;j<tmpArray.length;j+=2){cx+=tmpArray[j];cy+=tmpArray[j+1];this.parsePathLineto(cx,cy)}}break;case 72:for(j=0;j<tmpArray.length;j++){cx=tmpArray[j];this.parsePathLineto(cx,cy)}break;case 104:for(j=0;j<tmpArray.length;j++){cx+=tmpArray[j];this.parsePathLineto(cx,cy)}break;case 86:for(j=0;j<tmpArray.length;j++){cy=tmpArray[j];this.parsePathLineto(cx,cy)}break;case 118:for(j=0;j<tmpArray.length;j++){cy+=tmpArray[j];this.parsePathLineto(cx,cy)}break;case 67:if(tmpArray.length>=6&&tmpArray.length%6===0){for(j=0;j<tmpArray.length;j+=6){ctrlX1=tmpArray[j];ctrlY1=tmpArray[j+1];ctrlX2=tmpArray[j+2];ctrlY2=tmpArray[j+3];endX=tmpArray[j+4];endY=tmpArray[j+5];this.parsePathCurveto(ctrlX1,ctrlY1,ctrlX2,ctrlY2,endX,endY);cx=endX;cy=endY}}break;case 99:if(tmpArray.length>=6&&tmpArray.length%6===0){for(j=0;j<tmpArray.length;j+=6){ctrlX1=cx+tmpArray[j];ctrlY1=cy+tmpArray[j+1];ctrlX2=cx+tmpArray[j+2];ctrlY2=cy+tmpArray[j+3];endX=cx+tmpArray[j+4];endY=cy+tmpArray[j+5];this.parsePathCurveto(ctrlX1,ctrlY1,ctrlX2,ctrlY2,endX,endY);cx=endX;cy=endY}}break;case 83:if(tmpArray.length>=4&&tmpArray.length%4===0){for(j=0;j<tmpArray.length;j+=4){if(lastInstruction.toLowerCase()==="c"||lastInstruction.toLowerCase()==="s"){ppx=this.vertices[this.vertices.length-2][0];ppy=this.vertices[this.vertices.length-2][1];px=this.vertices[this.vertices.length-1][0];py=this.vertices[this.vertices.length-1][1];ctrlX1=px+(px-ppx);ctrlY1=py+(py-ppy)}else{ctrlX1=this.vertices[this.vertices.length-1][0];ctrlY1=this.vertices[this.vertices.length-1][1]}ctrlX2=tmpArray[j];ctrlY2=tmpArray[j+1];endX=tmpArray[j+2];endY=tmpArray[j+3];this.parsePathCurveto(ctrlX1,ctrlY1,ctrlX2,ctrlY2,endX,endY);cx=endX;cy=endY}}break;case 115:if(tmpArray.length>=4&&tmpArray.length%4===0){for(j=0;j<tmpArray.length;j+=4){if(lastInstruction.toLowerCase()==="c"||lastInstruction.toLowerCase()==="s"){ppx=this.vertices[this.vertices.length-2][0];ppy=this.vertices[this.vertices.length-2][1];px=this.vertices[this.vertices.length-1][0];py=this.vertices[this.vertices.length-1][1];ctrlX1=px+(px-ppx);ctrlY1=py+(py-ppy)}else{ctrlX1=this.vertices[this.vertices.length-1][0];ctrlY1=this.vertices[this.vertices.length-1][1]}ctrlX2=cx+tmpArray[j];ctrlY2=cy+tmpArray[j+1];endX=cx+tmpArray[j+2];endY=cy+tmpArray[j+3];this.parsePathCurveto(ctrlX1,ctrlY1,ctrlX2,ctrlY2,endX,endY);cx=endX;cy=endY}}break;case 81:if(tmpArray.length>=4&&tmpArray.length%4===0){for(j=0;j<tmpArray.length;j+=4){ctrlX=tmpArray[j];ctrlY=tmpArray[j+1];endX=tmpArray[j+2];endY=tmpArray[j+3];this.parsePathQuadto(cx,cy,ctrlX,ctrlY,endX,endY);cx=endX;cy=endY}}break;case 113:if(tmpArray.length>=4&&tmpArray.length%4===0){for(j=0;j<tmpArray.length;j+=4){ctrlX=cx+tmpArray[j];ctrlY=cy+tmpArray[j+1];endX=cx+tmpArray[j+2];endY=cy+tmpArray[j+3];this.parsePathQuadto(cx,cy,ctrlX,ctrlY,endX,endY);cx=endX;cy=endY}}break;case 84:if(tmpArray.length>=2&&tmpArray.length%2===0){for(j=0;j<tmpArray.length;j+=2){if(lastInstruction.toLowerCase()==="q"||lastInstruction.toLowerCase()==="t"){ppx=this.vertices[this.vertices.length-2][0];ppy=this.vertices[this.vertices.length-2][1];px=this.vertices[this.vertices.length-1][0];py=this.vertices[this.vertices.length-1][1];ctrlX=px+(px-ppx);ctrlY=py+(py-ppy)}else{ctrlX=cx;ctrlY=cy}endX=tmpArray[j];endY=tmpArray[j+1];this.parsePathQuadto(cx,cy,ctrlX,ctrlY,endX,endY);cx=endX;cy=endY}}break;case 116:if(tmpArray.length>=2&&tmpArray.length%2===0){for(j=0;j<tmpArray.length;j+=2){if(lastInstruction.toLowerCase()==="q"||lastInstruction.toLowerCase()==="t"){ppx=this.vertices[this.vertices.length-2][0];ppy=this.vertices[this.vertices.length-2][1];px=this.vertices[this.vertices.length-1][0];py=this.vertices[this.vertices.length-1][1];ctrlX=px+(px-ppx);ctrlY=py+(py-ppy)}else{ctrlX=cx;ctrlY=cy}endX=cx+tmpArray[j];endY=cy+tmpArray[j+1];this.parsePathQuadto(cx,cy,ctrlX,ctrlY,endX,endY);cx=endX;cy=endY}}break;case 90:case 122:this.close=true;break}lastInstruction=command.toString()}else{i++}}},parsePathQuadto:function(x1,y1,cx,cy,x2,y2){if(this.vertices.length>0){this.parsePathCode(PConstants.BEZIER_VERTEX);this.parsePathVertex(x1+((cx-x1)*2/3),y1+((cy-y1)*2/3));this.parsePathVertex(x2+((cx-x2)*2/3),y2+((cy-y2)*2/3));this.parsePathVertex(x2,y2)}else{throw ("Path must start with M/m")}},parsePathCurveto:function(x1,y1,x2,y2,x3,y3){if(this.vertices.length>0){this.parsePathCode(PConstants.BEZIER_VERTEX);this.parsePathVertex(x1,y1);this.parsePathVertex(x2,y2);this.parsePathVertex(x3,y3)}else{throw ("Path must start with M/m")}},parsePathLineto:function(px,py){if(this.vertices.length>0){this.parsePathCode(PConstants.VERTEX);this.parsePathVertex(px,py);this.vertices[this.vertices.length-1]["moveTo"]=false}else{throw ("Path must start with M/m")}},parsePathMoveto:function(px,py){if(this.vertices.length>0){this.parsePathCode(PConstants.BREAK)}this.parsePathCode(PConstants.VERTEX);this.parsePathVertex(px,py);this.vertices[this.vertices.length-1]["moveTo"]=true},parsePathVertex:function(x,y){var verts=[];verts[0]=x;verts[1]=y;this.vertices.push(verts)},parsePathCode:function(what){this.vertexCodes.push(what)},parsePoly:function(val){this.family=PConstants.PATH;this.close=val;var pointsAttr=p.trim(this.element.getStringAttribute("points").replace(/[,\s]+/g," "));if(pointsAttr!==null){var pointsBuffer=pointsAttr.split(" ");if(pointsBuffer.length%2===0){for(var i=0;i<pointsBuffer.length;i++){var verts=[];verts[0]=pointsBuffer[i];verts[1]=pointsBuffer[++i];this.vertices.push(verts)}}else{p.println("Error parsing polygon points: odd number of coordinates provided")}}},parseRect:function(){this.kind=PConstants.RECT;this.family=PConstants.PRIMITIVE;this.params=[];this.params[0]=this.element.getFloatAttribute("x");this.params[1]=this.element.getFloatAttribute("y");this.params[2]=this.element.getFloatAttribute("width");this.params[3]=this.element.getFloatAttribute("height");if(this.params[2]<0||this.params[3]<0){throw ("svg error: negative width or height found while parsing <rect>")}},parseEllipse:function(val){this.kind=PConstants.ELLIPSE;this.family=PConstants.PRIMITIVE;this.params=[];this.params[0]=this.element.getFloatAttribute("cx")|0;this.params[1]=this.element.getFloatAttribute("cy")|0;var rx,ry;if(val){rx=ry=this.element.getFloatAttribute("r");if(rx<0){throw ("svg error: negative radius found while parsing <circle>")}}else{rx=this.element.getFloatAttribute("rx");ry=this.element.getFloatAttribute("ry");if(rx<0||ry<0){throw ("svg error: negative x-axis radius or y-axis radius found while parsing <ellipse>")}}this.params[0]-=rx;this.params[1]-=ry;this.params[2]=rx*2;this.params[3]=ry*2},parseLine:function(){this.kind=PConstants.LINE;this.family=PConstants.PRIMITIVE;this.params=[];this.params[0]=this.element.getFloatAttribute("x1");this.params[1]=this.element.getFloatAttribute("y1");this.params[2]=this.element.getFloatAttribute("x2");this.params[3]=this.element.getFloatAttribute("y2")},parseColors:function(element){if(element.hasAttribute("opacity")){this.setOpacity(element.getAttribute("opacity"))}if(element.hasAttribute("stroke")){this.setStroke(element.getAttribute("stroke"))}if(element.hasAttribute("stroke-width")){this.setStrokeWeight(element.getAttribute("stroke-width"))}if(element.hasAttribute("stroke-linejoin")){this.setStrokeJoin(element.getAttribute("stroke-linejoin"))}if(element.hasAttribute("stroke-linecap")){this.setStrokeCap(element.getStringAttribute("stroke-linecap"))}if(element.hasAttribute("fill")){this.setFill(element.getStringAttribute("fill"))}if(element.hasAttribute("style")){var styleText=element.getStringAttribute("style");var styleTokens=styleText.toString().split(";");for(var i=0;i<styleTokens.length;i++){var tokens=p.trim(styleTokens[i].split(":"));switch(tokens[0]){case"fill":this.setFill(tokens[1]);break;case"fill-opacity":this.setFillOpacity(tokens[1]);break;case"stroke":this.setStroke(tokens[1]);break;case"stroke-width":this.setStrokeWeight(tokens[1]);break;case"stroke-linecap":this.setStrokeCap(tokens[1]);break;case"stroke-linejoin":this.setStrokeJoin(tokens[1]);break;case"stroke-opacity":this.setStrokeOpacity(tokens[1]);break;case"opacity":this.setOpacity(tokens[1]);break}}}},setFillOpacity:function(opacityText){this.fillOpacity=parseFloat(opacityText);this.fillColor=this.fillOpacity*255<<24|this.fillColor&16777215},setFill:function(fillText){var opacityMask=this.fillColor&4278190080;if(fillText==="none"){this.fill=false}else{if(fillText.indexOf("#")===0){this.fill=true;if(fillText.length===4){fillText=fillText.replace(/#(.)(.)(.)/,"#$1$1$2$2$3$3")}this.fillColor=opacityMask|(parseInt(fillText.substring(1),16))&16777215}else{if(fillText.indexOf("rgb")===0){this.fill=true;this.fillColor=opacityMask|this.parseRGB(fillText)}else{if(fillText.indexOf("url(#")===0){this.fillName=fillText.substring(5,fillText.length-1)}else{if(colors[fillText]){this.fill=true;this.fillColor=opacityMask|(parseInt(colors[fillText].substring(1),16))&16777215}}}}}},setOpacity:function(opacity){this.strokeColor=parseFloat(opacity)*255<<24|this.strokeColor&16777215;this.fillColor=parseFloat(opacity)*255<<24|this.fillColor&16777215},setStroke:function(strokeText){var opacityMask=this.strokeColor&4278190080;if(strokeText==="none"){this.stroke=false}else{if(strokeText.charAt(0)==="#"){this.stroke=true;if(strokeText.length===4){strokeText=strokeText.replace(/#(.)(.)(.)/,"#$1$1$2$2$3$3")}this.strokeColor=opacityMask|(parseInt(strokeText.substring(1),16))&16777215}else{if(strokeText.indexOf("rgb")===0){this.stroke=true;this.strokeColor=opacityMask|this.parseRGB(strokeText)}else{if(strokeText.indexOf("url(#")===0){this.strokeName=strokeText.substring(5,strokeText.length-1)}else{if(colors[strokeText]){this.stroke=true;this.strokeColor=opacityMask|(parseInt(colors[strokeText].substring(1),16))&16777215}}}}}},setStrokeWeight:function(weight){this.strokeWeight=this.parseUnitSize(weight)},setStrokeJoin:function(linejoin){if(linejoin==="miter"){this.strokeJoin=PConstants.MITER}else{if(linejoin==="round"){this.strokeJoin=PConstants.ROUND}else{if(linejoin==="bevel"){this.strokeJoin=PConstants.BEVEL}}}},setStrokeCap:function(linecap){if(linecap==="butt"){this.strokeCap=PConstants.SQUARE}else{if(linecap==="round"){this.strokeCap=PConstants.ROUND}else{if(linecap==="square"){this.strokeCap=PConstants.PROJECT}}}},setStrokeOpacity:function(opacityText){this.strokeOpacity=parseFloat(opacityText);this.strokeColor=this.strokeOpacity*255<<24|this.strokeColor&16777215},parseRGB:function(color){var sub=color.substring(color.indexOf("(")+1,color.indexOf(")"));var values=sub.split(", ");return(values[0]<<16)|(values[1]<<8)|(values[2])},parseUnitSize:function(text){var len=text.length-2;if(len<0){return text}if(text.indexOf("pt")===len){return parseFloat(text.substring(0,len))*1.25}else{if(text.indexOf("pc")===len){return parseFloat(text.substring(0,len))*15}else{if(text.indexOf("mm")===len){return parseFloat(text.substring(0,len))*3.543307}else{if(text.indexOf("cm")===len){return parseFloat(text.substring(0,len))*35.43307}else{if(text.indexOf("in")===len){return parseFloat(text.substring(0,len))*90}else{if(text.indexOf("px")===len){return parseFloat(text.substring(0,len))}else{return parseFloat(text)}}}}}}}};p.shape=function(shape,x,y,width,height){if(arguments.length>=1&&arguments[0]!==null){if(shape.isVisible()){p.pushMatrix();if(curShapeMode===PConstants.CENTER){if(arguments.length===5){p.translate(x-width/2,y-height/2);p.scale(width/shape.getWidth(),height/shape.getHeight())}else{if(arguments.length===3){p.translate(x-shape.getWidth()/2,-shape.getHeight()/2)}else{p.translate(-shape.getWidth()/2,-shape.getHeight()/2)}}}else{if(curShapeMode===PConstants.CORNER){if(arguments.length===5){p.translate(x,y);p.scale(width/shape.getWidth(),height/shape.getHeight())}else{if(arguments.length===3){p.translate(x,y)}}}else{if(curShapeMode===PConstants.CORNERS){if(arguments.length===5){width-=x;height-=y;p.translate(x,y);p.scale(width/shape.getWidth(),height/shape.getHeight())}else{if(arguments.length===3){p.translate(x,y)}}}}}shape.draw();if((arguments.length===1&&curShapeMode===PConstants.CENTER)||arguments.length>1){p.popMatrix()}}}};p.shapeMode=function(mode){curShapeMode=mode};p.loadShape=function(filename){if(arguments.length===1){if(filename.indexOf(".svg")>-1){return new PShapeSVG(null,filename)}}return null};var XMLAttribute=function(fname,n,nameSpace,v,t){this.fullName=fname||"";this.name=n||"";this.namespace=nameSpace||"";this.value=v;this.type=t};XMLAttribute.prototype={getName:function(){return this.name},getFullName:function(){return this.fullName},getNamespace:function(){return this.namespace},getValue:function(){return this.value},getType:function(){return this.type},setValue:function(newval){this.value=newval}};var XMLElement=p.XMLElement=function(){if(arguments.length===4){this.attributes=[];this.children=[];this.fullName=arguments[0]||"";if(arguments[1]){this.name=arguments[1]}else{var index=this.fullName.indexOf(":");if(index>=0){this.name=this.fullName.substring(index+1)}else{this.name=this.fullName}}this.namespace=arguments[1];this.content="";this.lineNr=arguments[3];this.systemID=arguments[2];this.parent=null}else{if((arguments.length===2&&arguments[1].indexOf(".")>-1)){this.attributes=[];this.children=[];this.fullName="";this.name="";this.namespace="";this.content="";this.systemID="";this.lineNr="";this.parent=null;this.parse(arguments[arguments.length-1])}else{if(arguments.length===1&&typeof arguments[0]==="string"){this.attributes=[];this.children=[];this.fullName="";this.name="";this.namespace="";this.content="";this.systemID="";this.lineNr="";this.parent=null;this.parse(arguments[0])}else{this.attributes=[];this.children=[];this.fullName="";this.name="";this.namespace="";this.content="";this.systemID="";this.lineNr="";this.parent=null}}}return this};XMLElement.prototype={parse:function(filename){var xmlDoc;try{if(filename.indexOf(".xml")>-1||filename.indexOf(".svg")>-1){filename=ajax(filename)}xmlDoc=new DOMParser().parseFromString(filename,"text/xml");var elements=xmlDoc.documentElement;if(elements){this.parseChildrenRecursive(null,elements)}else{throw ("Error loading document")}return this}catch(e){throw (e)}},createElement:function(){if(arguments.length===2){return new XMLElement(arguments[0],arguments[1],null,null)}else{return new XMLElement(arguments[0],arguments[1],arguments[2],arguments[3])}},hasAttribute:function(){if(arguments.length===1){return this.getAttribute(arguments[0])!==null}else{if(arguments.length===2){return this.getAttribute(arguments[0],arguments[1])!==null}}},createPCDataElement:function(){return new XMLElement()},equals:function(object){if(typeof object==="Object"){return this.equalsXMLElement(object)}},equalsXMLElement:function(object){if(object instanceof XMLElement){if(this.name!==object.getLocalName()){return false}if(this.attributes.length!==object.getAttributeCount()){return false}for(var i=0;i<this.attributes.length;i++){if(!object.hasAttribute(this.attributes[i].getName(),this.attributes[i].getNamespace())){return false}if(this.attributes[i].getValue()!==object.attributes[i].getValue()){return false}if(this.attributes[i].getType()!==object.attributes[i].getType()){return false}}if(this.children.length!==object.getChildCount()){return false}var child1,child2;for(i=0;i<this.children.length;i++){child1=this.getChildAtIndex(i);child2=object.getChildAtIndex(i);if(!child1.equalsXMLElement(child2)){return false}}return true}},getContent:function(){return this.content},getAttribute:function(){var attribute;if(arguments.length===2){attribute=this.findAttribute(arguments[0]);if(attribute){return attribute.getValue()}else{return arguments[1]}}else{if(arguments.length===1){attribute=this.findAttribute(arguments[0]);if(attribute){return attribute.getValue()}else{return null}}else{if(arguments.length===3){attribute=this.findAttribute(arguments[0],arguments[1]);if(attribute){return attribute.getValue()}else{return arguments[2]}}}}},getStringAttribute:function(){if(arguments.length===1){return this.getAttribute(arguments[0])}else{if(arguments.length===2){return this.getAttribute(arguments[0],arguments[1])}else{return this.getAttribute(arguments[0],arguments[1],arguments[2])}}},getFloatAttribute:function(){if(arguments.length===1){return parseFloat(this.getAttribute(arguments[0],0))}else{if(arguments.length===2){return this.getAttribute(arguments[0],arguments[1])}else{return this.getAttribute(arguments[0],arguments[1],arguments[2])}}},getIntAttribute:function(){if(arguments.length===1){return this.getAttribute(arguments[0],0)}else{if(arguments.length===2){return this.getAttribute(arguments[0],arguments[1])}else{return this.getAttribute(arguments[0],arguments[1],arguments[2])}}},hasChildren:function(){return this.children.length>0},addChild:function(child){if(child!==null){child.parent=this;this.children.push(child)}},insertChild:function(child,index){if(child){if((child.getLocalName()===null)&&(!this.hasChildren())){var lastChild=this.children[this.children.length-1];if(lastChild.getLocalName()===null){lastChild.setContent(lastChild.getContent()+child.getContent());return}}child.parent=this;this.children.splice(index,0,child)}},getChild:function(){if(typeof arguments[0]==="number"){return this.children[arguments[0]]}else{if(arguments[0].indexOf("/")!==-1){this.getChildRecursive(arguments[0].split("/"),0)}else{var kid,kidName;for(var i=0;i<this.getChildCount();i++){kid=this.getChild(i);kidName=kid.getName();if(kidName!==null&&kidName===arguments[0]){return kid}}return null}}},getChildren:function(){if(arguments.length===1){if(typeof arguments[0]==="number"){return this.getChild(arguments[0])}else{if(arguments[0].indexOf("/")!==-1){return this.getChildrenRecursive(arguments[0].split("/"),0)}else{var matches=[];var kid,kidName;for(var i=0;i<this.getChildCount();i++){kid=this.getChild(i);kidName=kid.getName();if(kidName!==null&&kidName===arguments[0]){matches.push(kid)}}return matches}}}else{return this.children}},getChildCount:function(){return this.children.length},getChildRecursive:function(items,offset){var kid,kidName;for(var i=0;i<this.getChildCount();i++){kid=this.getChild(i);kidName=kid.getName();if(kidName!==null&&kidName===items[offset]){if(offset===items.length-1){return kid}else{offset+=1;return kid.getChildRecursive(items,offset)}}}return null},getChildrenRecursive:function(items,offset){if(offset===items.length-1){return this.getChildren(items[offset])}var matches=this.getChildren(items[offset]);var kidMatches;for(var i=0;i<matches.length;i++){kidMatches=matches[i].getChildrenRecursive(items,offset+1)}return kidMatches},parseChildrenRecursive:function(parent,elementpath){var xmlelement,xmlattribute,tmpattrib;if(!parent){this.fullName=elementpath.localName;this.name=elementpath.nodeName;this.content=elementpath.textContent||"";xmlelement=this}else{xmlelement=new XMLElement(elementpath.localName,elementpath.nodeName,"","");xmlelement.content=elementpath.textContent||"";xmlelement.parent=parent}for(var l=0;l<elementpath.attributes.length;l++){tmpattrib=elementpath.attributes[l];xmlattribute=new XMLAttribute(tmpattrib.getname,tmpattrib.nodeName,tmpattrib.namespaceURI,tmpattrib.nodeValue,tmpattrib.nodeType);xmlelement.attributes.push(xmlattribute)}for(var node in elementpath.childNodes){if(elementpath.childNodes[node].nodeType===1){xmlelement.children.push(xmlelement.parseChildrenRecursive(xmlelement,elementpath.childNodes[node]))}}return xmlelement},isLeaf:function(){return !this.hasChildren()},listChildren:function(){var arr=[];for(var i=0;i<this.children.length;i++){arr.push(this.getChild(i).getName())}return arr},removeAttribute:function(name,namespace){this.namespace=namespace||"";for(var i=0;i<this.attributes.length;i++){if(this.attributes[i].getName()===name&&this.attributes[i].getNamespace()===this.namespace){this.attributes.splice(i,1)}}},removeChild:function(child){if(child){for(var i=0;i<this.children.length;i++){if(this.children[i].equalsXMLElement(child)){this.children.splice(i,1)}}}},removeChildAtIndex:function(index){if(this.children.length>index){this.children.splice(index,1)}},findAttribute:function(name,namespace){this.namespace=namespace||"";for(var i=0;i<this.attributes.length;i++){if(this.attributes[i].getName()===name&&this.attributes[i].getNamespace()===this.namespace){return this.attributes[i]}}},setAttribute:function(){var attr;if(arguments.length===3){var index=arguments[0].indexOf(":");var name=arguments[0].substring(index+1);attr=this.findAttribute(name,arguments[1]);if(attr){attr.setValue(arguments[2])}else{attr=new XMLAttribute(arguments[0],name,arguments[1],arguments[2],"CDATA");this.attributes.push(attr)}}else{attr=this.findAttribute(arguments[0]);if(attr){attr.setValue(arguments[1])}else{attr=new XMLAttribute(arguments[0],arguments[0],null,arguments[1],"CDATA");this.attributes.push(attr)}}},setContent:function(content){this.content=content},setName:function(){if(arguments.length===1){this.name=arguments[0];this.fullName=arguments[0];this.namespace=null}else{var index=arguments[0].indexOf(":");if((arguments[1]===null)||(index<0)){this.name=arguments[0]}else{this.name=arguments[0].substring(index+1)}this.fullName=arguments[0];this.namespace=arguments[1]}},getName:function(){return this.fullName},getLocalName:function(){return this.name},getAttributeCount:function(){return this.attributes.length}};var printMatrixHelper=function printMatrixHelper(elements){var big=0;for(var i=0;i<elements.length;i++){if(i!==0){big=Math.max(big,Math.abs(elements[i]))}else{big=Math.abs(elements[i])}}var digits=(big+"").indexOf(".");if(digits===0){digits=1}else{if(digits===-1){digits=(big+"").length}}return digits};var PMatrix2D=p.PMatrix2D=function(){if(arguments.length===0){this.reset()}else{if(arguments.length===1&&arguments[0] instanceof PMatrix2D){this.set(arguments[0].array())}else{if(arguments.length===6){this.set(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5])}}}};PMatrix2D.prototype={set:function(){if(arguments.length===6){var a=arguments;this.set([a[0],a[1],a[2],a[3],a[4],a[5]])}else{if(arguments.length===1&&arguments[0] instanceof PMatrix2D){this.elements=arguments[0].array()}else{if(arguments.length===1&&arguments[0] instanceof Array){this.elements=arguments[0].slice()}}}},get:function(){var outgoing=new PMatrix2D();outgoing.set(this.elements);return outgoing},reset:function(){this.set([1,0,0,0,1,0])},array:function array(){return this.elements.slice()},translate:function(tx,ty){this.elements[2]=tx*this.elements[0]+ty*this.elements[1]+this.elements[2];this.elements[5]=tx*this.elements[3]+ty*this.elements[4]+this.elements[5]},transpose:function(){},mult:function(source,target){var x,y;if(source instanceof PVector){x=source.x;y=source.y;if(!target){target=new PVector()}}else{if(source instanceof Array){x=source[0];y=source[1];if(!target){target=[]}}}if(target instanceof Array){target[0]=this.elements[0]*x+this.elements[1]*y+this.elements[2];target[1]=this.elements[3]*x+this.elements[4]*y+this.elements[5]}else{if(target instanceof PVector){target.x=this.elements[0]*x+this.elements[1]*y+this.elements[2];target.y=this.elements[3]*x+this.elements[4]*y+this.elements[5];target.z=0}}return target},multX:function(x,y){return(x*this.elements[0]+y*this.elements[1]+this.elements[2])},multY:function(x,y){return(x*this.elements[3]+y*this.elements[4]+this.elements[5])},skewX:function(angle){this.apply(1,0,1,angle,0,0)},skewY:function(angle){this.apply(1,0,1,0,angle,0)},determinant:function(){return(this.elements[0]*this.elements[4]-this.elements[1]*this.elements[3])},invert:function(){var d=this.determinant();if(Math.abs(d)>PConstants.MIN_INT){var old00=this.elements[0];var old01=this.elements[1];var old02=this.elements[2];var old10=this.elements[3];var old11=this.elements[4];var old12=this.elements[5];this.elements[0]=old11/d;this.elements[3]=-old10/d;this.elements[1]=-old01/d;this.elements[4]=old00/d;this.elements[2]=(old01*old12-old11*old02)/d;this.elements[5]=(old10*old02-old00*old12)/d;return true}return false},scale:function(sx,sy){if(sx&&!sy){sy=sx}if(sx&&sy){this.elements[0]*=sx;this.elements[1]*=sy;this.elements[3]*=sx;this.elements[4]*=sy}},apply:function(){var source;if(arguments.length===1&&arguments[0] instanceof PMatrix2D){source=arguments[0].array()}else{if(arguments.length===6){source=Array.prototype.slice.call(arguments)}else{if(arguments.length===1&&arguments[0] instanceof Array){source=arguments[0]}}}var result=[0,0,this.elements[2],0,0,this.elements[5]];var e=0;for(var row=0;row<2;row++){for(var col=0;col<3;col++,e++){result[e]+=this.elements[row*3+0]*source[col+0]+this.elements[row*3+1]*source[col+3]}}this.elements=result.slice()},preApply:function(){var source;if(arguments.length===1&&arguments[0] instanceof PMatrix2D){source=arguments[0].array()}else{if(arguments.length===6){source=Array.prototype.slice.call(arguments)}else{if(arguments.length===1&&arguments[0] instanceof Array){source=arguments[0]}}}var result=[0,0,source[2],0,0,source[5]];result[2]=source[2]+this.elements[2]*source[0]+this.elements[5]*source[1];result[5]=source[5]+this.elements[2]*source[3]+this.elements[5]*source[4];result[0]=this.elements[0]*source[0]+this.elements[3]*source[1];result[3]=this.elements[0]*source[3]+this.elements[3]*source[4];result[1]=this.elements[1]*source[0]+this.elements[4]*source[1];result[4]=this.elements[1]*source[3]+this.elements[4]*source[4];this.elements=result.slice()},rotate:function(angle){var c=Math.cos(angle);var s=Math.sin(angle);var temp1=this.elements[0];var temp2=this.elements[1];this.elements[0]=c*temp1+s*temp2;this.elements[1]=-s*temp1+c*temp2;temp1=this.elements[3];temp2=this.elements[4];this.elements[3]=c*temp1+s*temp2;this.elements[4]=-s*temp1+c*temp2},rotateZ:function(angle){this.rotate(angle)},print:function(){var digits=printMatrixHelper(this.elements);var output=""+p.nfs(this.elements[0],digits,4)+" "+p.nfs(this.elements[1],digits,4)+" "+p.nfs(this.elements[2],digits,4)+"\n"+p.nfs(this.elements[3],digits,4)+" "+p.nfs(this.elements[4],digits,4)+" "+p.nfs(this.elements[5],digits,4)+"\n\n";p.println(output)}};var PMatrix3D=p.PMatrix3D=function PMatrix3D(){this.reset()};PMatrix3D.prototype={set:function(){if(arguments.length===16){this.elements=Array.prototype.slice.call(arguments)}else{if(arguments.length===1&&arguments[0] instanceof PMatrix3D){this.elements=arguments[0].array()}else{if(arguments.length===1&&arguments[0] instanceof Array){this.elements=arguments[0].slice()}}}},get:function(){var outgoing=new PMatrix3D();outgoing.set(this.elements);return outgoing},reset:function(){this.set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1])},array:function array(){return this.elements.slice()},translate:function(tx,ty,tz){if(tz===undef){tz=0}this.elements[3]+=tx*this.elements[0]+ty*this.elements[1]+tz*this.elements[2];this.elements[7]+=tx*this.elements[4]+ty*this.elements[5]+tz*this.elements[6];this.elements[11]+=tx*this.elements[8]+ty*this.elements[9]+tz*this.elements[10];this.elements[15]+=tx*this.elements[12]+ty*this.elements[13]+tz*this.elements[14]},transpose:function(){var temp=this.elements.slice();this.elements[0]=temp[0];this.elements[1]=temp[4];this.elements[2]=temp[8];this.elements[3]=temp[12];this.elements[4]=temp[1];this.elements[5]=temp[5];this.elements[6]=temp[9];this.elements[7]=temp[13];this.elements[8]=temp[2];this.elements[9]=temp[6];this.elements[10]=temp[10];this.elements[11]=temp[14];this.elements[12]=temp[3];this.elements[13]=temp[7];this.elements[14]=temp[11];this.elements[15]=temp[15]},mult:function(source,target){var x,y,z,w;if(source instanceof PVector){x=source.x;y=source.y;z=source.z;w=1;if(!target){target=new PVector()}}else{if(source instanceof Array){x=source[0];y=source[1];z=source[2];w=source[3]||1;if(!target||target.length!==3&&target.length!==4){target=[0,0,0]}}}if(target instanceof Array){if(target.length===3){target[0]=this.elements[0]*x+this.elements[1]*y+this.elements[2]*z+this.elements[3];target[1]=this.elements[4]*x+this.elements[5]*y+this.elements[6]*z+this.elements[7];target[2]=this.elements[8]*x+this.elements[9]*y+this.elements[10]*z+this.elements[11]}else{if(target.length===4){target[0]=this.elements[0]*x+this.elements[1]*y+this.elements[2]*z+this.elements[3]*w;target[1]=this.elements[4]*x+this.elements[5]*y+this.elements[6]*z+this.elements[7]*w;target[2]=this.elements[8]*x+this.elements[9]*y+this.elements[10]*z+this.elements[11]*w;target[3]=this.elements[12]*x+this.elements[13]*y+this.elements[14]*z+this.elements[15]*w}}}if(target instanceof PVector){target.x=this.elements[0]*x+this.elements[1]*y+this.elements[2]*z+this.elements[3];target.y=this.elements[4]*x+this.elements[5]*y+this.elements[6]*z+this.elements[7];target.z=this.elements[8]*x+this.elements[9]*y+this.elements[10]*z+this.elements[11]}return target},preApply:function(){var source;if(arguments.length===1&&arguments[0] instanceof PMatrix3D){source=arguments[0].array()}else{if(arguments.length===16){source=Array.prototype.slice.call(arguments)}else{if(arguments.length===1&&arguments[0] instanceof Array){source=arguments[0]}}}var result=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];var e=0;for(var row=0;row<4;row++){for(var col=0;col<4;col++,e++){result[e]+=this.elements[col+0]*source[row*4+0]+this.elements[col+4]*source[row*4+1]+this.elements[col+8]*source[row*4+2]+this.elements[col+12]*source[row*4+3]}}this.elements=result.slice()},apply:function(){var source;if(arguments.length===1&&arguments[0] instanceof PMatrix3D){source=arguments[0].array()}else{if(arguments.length===16){source=Array.prototype.slice.call(arguments)}else{if(arguments.length===1&&arguments[0] instanceof Array){source=arguments[0]}}}var result=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];var e=0;for(var row=0;row<4;row++){for(var col=0;col<4;col++,e++){result[e]+=this.elements[row*4+0]*source[col+0]+this.elements[row*4+1]*source[col+4]+this.elements[row*4+2]*source[col+8]+this.elements[row*4+3]*source[col+12]}}this.elements=result.slice()},rotate:function(angle,v0,v1,v2){if(!v1){this.rotateZ(angle)}else{var c=p.cos(angle);var s=p.sin(angle);var t=1-c;this.apply((t*v0*v0)+c,(t*v0*v1)-(s*v2),(t*v0*v2)+(s*v1),0,(t*v0*v1)+(s*v2),(t*v1*v1)+c,(t*v1*v2)-(s*v0),0,(t*v0*v2)-(s*v1),(t*v1*v2)+(s*v0),(t*v2*v2)+c,0,0,0,0,1)}},invApply:function(){if(inverseCopy===undef){inverseCopy=new PMatrix3D()}var a=arguments;inverseCopy.set(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],a[15]);if(!inverseCopy.invert()){return false}this.preApply(inverseCopy);return true},rotateX:function(angle){var c=p.cos(angle);var s=p.sin(angle);this.apply([1,0,0,0,0,c,-s,0,0,s,c,0,0,0,0,1])},rotateY:function(angle){var c=p.cos(angle);var s=p.sin(angle);this.apply([c,0,s,0,0,1,0,0,-s,0,c,0,0,0,0,1])},rotateZ:function(angle){var c=Math.cos(angle);var s=Math.sin(angle);this.apply([c,-s,0,0,s,c,0,0,0,0,1,0,0,0,0,1])},scale:function(sx,sy,sz){if(sx&&!sy&&!sz){sy=sz=sx}else{if(sx&&sy&&!sz){sz=1}}if(sx&&sy&&sz){this.elements[0]*=sx;this.elements[1]*=sy;this.elements[2]*=sz;this.elements[4]*=sx;this.elements[5]*=sy;this.elements[6]*=sz;this.elements[8]*=sx;this.elements[9]*=sy;this.elements[10]*=sz;this.elements[12]*=sx;this.elements[13]*=sy;this.elements[14]*=sz}},skewX:function(angle){var t=Math.tan(angle);this.apply(1,t,0,0,0,1,0,0,0,0,1,0,0,0,0,1)},skewY:function(angle){var t=Math.tan(angle);this.apply(1,0,0,0,t,1,0,0,0,0,1,0,0,0,0,1)},multX:function(x,y,z,w){if(!z){return this.elements[0]*x+this.elements[1]*y+this.elements[3]}else{if(!w){return this.elements[0]*x+this.elements[1]*y+this.elements[2]*z+this.elements[3]}else{return this.elements[0]*x+this.elements[1]*y+this.elements[2]*z+this.elements[3]*w}}},multY:function(x,y,z,w){if(!z){return this.elements[4]*x+this.elements[5]*y+this.elements[7]}else{if(!w){return this.elements[4]*x+this.elements[5]*y+this.elements[6]*z+this.elements[7]}else{return this.elements[4]*x+this.elements[5]*y+this.elements[6]*z+this.elements[7]*w}}},multZ:function(x,y,z,w){if(!w){return this.elements[8]*x+this.elements[9]*y+this.elements[10]*z+this.elements[11]}else{return this.elements[8]*x+this.elements[9]*y+this.elements[10]*z+this.elements[11]*w}},multW:function(x,y,z,w){if(!w){return this.elements[12]*x+this.elements[13]*y+this.elements[14]*z+this.elements[15]}else{return this.elements[12]*x+this.elements[13]*y+this.elements[14]*z+this.elements[15]*w}},invert:function(){var fA0=this.elements[0]*this.elements[5]-this.elements[1]*this.elements[4];var fA1=this.elements[0]*this.elements[6]-this.elements[2]*this.elements[4];var fA2=this.elements[0]*this.elements[7]-this.elements[3]*this.elements[4];var fA3=this.elements[1]*this.elements[6]-this.elements[2]*this.elements[5];var fA4=this.elements[1]*this.elements[7]-this.elements[3]*this.elements[5];var fA5=this.elements[2]*this.elements[7]-this.elements[3]*this.elements[6];var fB0=this.elements[8]*this.elements[13]-this.elements[9]*this.elements[12];var fB1=this.elements[8]*this.elements[14]-this.elements[10]*this.elements[12];var fB2=this.elements[8]*this.elements[15]-this.elements[11]*this.elements[12];var fB3=this.elements[9]*this.elements[14]-this.elements[10]*this.elements[13];var fB4=this.elements[9]*this.elements[15]-this.elements[11]*this.elements[13];var fB5=this.elements[10]*this.elements[15]-this.elements[11]*this.elements[14];var fDet=fA0*fB5-fA1*fB4+fA2*fB3+fA3*fB2-fA4*fB1+fA5*fB0;if(Math.abs(fDet)<=1e-9){return false}var kInv=[];kInv[0]=+this.elements[5]*fB5-this.elements[6]*fB4+this.elements[7]*fB3;kInv[4]=-this.elements[4]*fB5+this.elements[6]*fB2-this.elements[7]*fB1;kInv[8]=+this.elements[4]*fB4-this.elements[5]*fB2+this.elements[7]*fB0;kInv[12]=-this.elements[4]*fB3+this.elements[5]*fB1-this.elements[6]*fB0;kInv[1]=-this.elements[1]*fB5+this.elements[2]*fB4-this.elements[3]*fB3;kInv[5]=+this.elements[0]*fB5-this.elements[2]*fB2+this.elements[3]*fB1;kInv[9]=-this.elements[0]*fB4+this.elements[1]*fB2-this.elements[3]*fB0;kInv[13]=+this.elements[0]*fB3-this.elements[1]*fB1+this.elements[2]*fB0;kInv[2]=+this.elements[13]*fA5-this.elements[14]*fA4+this.elements[15]*fA3;kInv[6]=-this.elements[12]*fA5+this.elements[14]*fA2-this.elements[15]*fA1;kInv[10]=+this.elements[12]*fA4-this.elements[13]*fA2+this.elements[15]*fA0;kInv[14]=-this.elements[12]*fA3+this.elements[13]*fA1-this.elements[14]*fA0;kInv[3]=-this.elements[9]*fA5+this.elements[10]*fA4-this.elements[11]*fA3;kInv[7]=+this.elements[8]*fA5-this.elements[10]*fA2+this.elements[11]*fA1;kInv[11]=-this.elements[8]*fA4+this.elements[9]*fA2-this.elements[11]*fA0;kInv[15]=+this.elements[8]*fA3-this.elements[9]*fA1+this.elements[10]*fA0;var fInvDet=1/fDet;kInv[0]*=fInvDet;kInv[1]*=fInvDet;kInv[2]*=fInvDet;kInv[3]*=fInvDet;kInv[4]*=fInvDet;kInv[5]*=fInvDet;kInv[6]*=fInvDet;kInv[7]*=fInvDet;kInv[8]*=fInvDet;kInv[9]*=fInvDet;kInv[10]*=fInvDet;kInv[11]*=fInvDet;kInv[12]*=fInvDet;kInv[13]*=fInvDet;kInv[14]*=fInvDet;kInv[15]*=fInvDet;this.elements=kInv.slice();return true},toString:function(){var str="";for(var i=0;i<15;i++){str+=this.elements[i]+", "}str+=this.elements[15];return str},print:function(){var digits=printMatrixHelper(this.elements);var output=""+p.nfs(this.elements[0],digits,4)+" "+p.nfs(this.elements[1],digits,4)+" "+p.nfs(this.elements[2],digits,4)+" "+p.nfs(this.elements[3],digits,4)+"\n"+p.nfs(this.elements[4],digits,4)+" "+p.nfs(this.elements[5],digits,4)+" "+p.nfs(this.elements[6],digits,4)+" "+p.nfs(this.elements[7],digits,4)+"\n"+p.nfs(this.elements[8],digits,4)+" "+p.nfs(this.elements[9],digits,4)+" "+p.nfs(this.elements[10],digits,4)+" "+p.nfs(this.elements[11],digits,4)+"\n"+p.nfs(this.elements[12],digits,4)+" "+p.nfs(this.elements[13],digits,4)+" "+p.nfs(this.elements[14],digits,4)+" "+p.nfs(this.elements[15],digits,4)+"\n\n";p.println(output)},invTranslate:function(tx,ty,tz){this.preApply(1,0,0,-tx,0,1,0,-ty,0,0,1,-tz,0,0,0,1)},invRotateX:function(angle){var c=Math.cos(-angle);var s=Math.sin(-angle);this.preApply([1,0,0,0,0,c,-s,0,0,s,c,0,0,0,0,1])},invRotateY:function(angle){var c=Math.cos(-angle);var s=Math.sin(-angle);this.preApply([c,0,s,0,0,1,0,0,-s,0,c,0,0,0,0,1])},invRotateZ:function(angle){var c=Math.cos(-angle);var s=Math.sin(-angle);this.preApply([c,-s,0,0,s,c,0,0,0,0,1,0,0,0,0,1])},invScale:function(x,y,z){this.preApply([1/x,0,0,0,0,1/y,0,0,0,0,1/z,0,0,0,0,1])}};var PMatrixStack=p.PMatrixStack=function PMatrixStack(){this.matrixStack=[]};PMatrixStack.prototype.load=function load(){var tmpMatrix;if(p.use3DContext){tmpMatrix=new PMatrix3D()}else{tmpMatrix=new PMatrix2D()}if(arguments.length===1){tmpMatrix.set(arguments[0])}else{tmpMatrix.set(arguments)}this.matrixStack.push(tmpMatrix)};PMatrixStack.prototype.push=function push(){this.matrixStack.push(this.peek())};PMatrixStack.prototype.pop=function pop(){return this.matrixStack.pop()};PMatrixStack.prototype.peek=function peek(){var tmpMatrix;if(p.use3DContext){tmpMatrix=new PMatrix3D()}else{tmpMatrix=new PMatrix2D()}tmpMatrix.set(this.matrixStack[this.matrixStack.length-1]);return tmpMatrix};PMatrixStack.prototype.mult=function mult(matrix){this.matrixStack[this.matrixStack.length-1].apply(matrix)};p.split=function(str,delim){return str.split(delim)};p.splitTokens=function(str,tokens){if(arguments.length===1){tokens="\n\t\r\f "}tokens="["+tokens+"]";var ary=[];var index=0;var pos=str.search(tokens);while(pos>=0){if(pos===0){str=str.substring(1)}else{ary[index]=str.substring(0,pos);index++;str=str.substring(pos)}pos=str.search(tokens)}if(str.length>0){ary[index]=str}if(ary.length===0){ary=undef}return ary};p.append=function(array,element){array[array.length]=element;return array};p.concat=function(array1,array2){return array1.concat(array2)};p.sort=function(array,numElem){var ret=[];if(array.length>0){var elemsToCopy=numElem>0?numElem:array.length;for(var i=0;i<elemsToCopy;i++){ret.push(array[i])}if(typeof array[0]==="string"){ret.sort()}else{ret.sort(function(a,b){return a-b})}if(numElem>0){for(var j=ret.length;j<array.length;j++){ret.push(array[j])}}}return ret};p.splice=function(array,value,index){if(value.length===0){return array}if(value instanceof Array){for(var i=0,j=index;i<value.length;j++,i++){array.splice(j,0,value[i])}}else{array.splice(index,0,value)}return array};p.subset=function(array,offset,length){if(arguments.length===2){return array.slice(offset,array.length-offset)}else{if(arguments.length===3){return array.slice(offset,offset+length)}}};p.join=function(array,seperator){return array.join(seperator)};p.shorten=function(ary){var newary=[];var len=ary.length;for(var i=0;i<len;i++){newary[i]=ary[i]}newary.pop();return newary};p.expand=function(ary,newSize){var temp=ary.slice(0);if(arguments.length===1){temp.length=ary.length*2;return temp}else{if(arguments.length===2){temp.length=newSize;return temp}}};p.arrayCopy=function(){var src,srcPos=0,dest,destPos=0,length;if(arguments.length===2){src=arguments[0];dest=arguments[1];length=src.length}else{if(arguments.length===3){src=arguments[0];dest=arguments[1];length=arguments[2]}else{if(arguments.length===5){src=arguments[0];srcPos=arguments[1];dest=arguments[2];destPos=arguments[3];length=arguments[4]}}}for(var i=srcPos,j=destPos;i<length+srcPos;i++,j++){if(dest[j]!==undef){dest[j]=src[i]}else{throw"array index out of bounds exception"}}};p.reverse=function(array){return array.reverse()};p.mix=function(a,b,f){return a+(((b-a)*f)>>8)};p.peg=function(n){return(n<0)?0:((n>255)?255:n)};p.modes={replace:function(c1,c2){return c2},blend:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|p.mix(c1&PConstants.RED_MASK,c2&PConstants.RED_MASK,f)&PConstants.RED_MASK|p.mix(c1&PConstants.GREEN_MASK,c2&PConstants.GREEN_MASK,f)&PConstants.GREEN_MASK|p.mix(c1&PConstants.BLUE_MASK,c2&PConstants.BLUE_MASK,f))},add:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|Math.min(((c1&PConstants.RED_MASK)+((c2&PConstants.RED_MASK)>>8)*f),PConstants.RED_MASK)&PConstants.RED_MASK|Math.min(((c1&PConstants.GREEN_MASK)+((c2&PConstants.GREEN_MASK)>>8)*f),PConstants.GREEN_MASK)&PConstants.GREEN_MASK|Math.min((c1&PConstants.BLUE_MASK)+(((c2&PConstants.BLUE_MASK)*f)>>8),PConstants.BLUE_MASK))},subtract:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|Math.max(((c1&PConstants.RED_MASK)-((c2&PConstants.RED_MASK)>>8)*f),PConstants.GREEN_MASK)&PConstants.RED_MASK|Math.max(((c1&PConstants.GREEN_MASK)-((c2&PConstants.GREEN_MASK)>>8)*f),PConstants.BLUE_MASK)&PConstants.GREEN_MASK|Math.max((c1&PConstants.BLUE_MASK)-(((c2&PConstants.BLUE_MASK)*f)>>8),0))},lightest:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|Math.max(c1&PConstants.RED_MASK,((c2&PConstants.RED_MASK)>>8)*f)&PConstants.RED_MASK|Math.max(c1&PConstants.GREEN_MASK,((c2&PConstants.GREEN_MASK)>>8)*f)&PConstants.GREEN_MASK|Math.max(c1&PConstants.BLUE_MASK,((c2&PConstants.BLUE_MASK)*f)>>8))},darkest:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|p.mix(c1&PConstants.RED_MASK,Math.min(c1&PConstants.RED_MASK,((c2&PConstants.RED_MASK)>>8)*f),f)&PConstants.RED_MASK|p.mix(c1&PConstants.GREEN_MASK,Math.min(c1&PConstants.GREEN_MASK,((c2&PConstants.GREEN_MASK)>>8)*f),f)&PConstants.GREEN_MASK|p.mix(c1&PConstants.BLUE_MASK,Math.min(c1&PConstants.BLUE_MASK,((c2&PConstants.BLUE_MASK)*f)>>8),f))},difference:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;var ar=(c1&PConstants.RED_MASK)>>16;var ag=(c1&PConstants.GREEN_MASK)>>8;var ab=(c1&PConstants.BLUE_MASK);var br=(c2&PConstants.RED_MASK)>>16;var bg=(c2&PConstants.GREEN_MASK)>>8;var bb=(c2&PConstants.BLUE_MASK);var cr=(ar>br)?(ar-br):(br-ar);var cg=(ag>bg)?(ag-bg):(bg-ag);var cb=(ab>bb)?(ab-bb):(bb-ab);return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|(p.peg(ar+(((cr-ar)*f)>>8))<<16)|(p.peg(ag+(((cg-ag)*f)>>8))<<8)|(p.peg(ab+(((cb-ab)*f)>>8))))},exclusion:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;var ar=(c1&PConstants.RED_MASK)>>16;var ag=(c1&PConstants.GREEN_MASK)>>8;var ab=(c1&PConstants.BLUE_MASK);var br=(c2&PConstants.RED_MASK)>>16;var bg=(c2&PConstants.GREEN_MASK)>>8;var bb=(c2&PConstants.BLUE_MASK);var cr=ar+br-((ar*br)>>7);var cg=ag+bg-((ag*bg)>>7);var cb=ab+bb-((ab*bb)>>7);return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|(p.peg(ar+(((cr-ar)*f)>>8))<<16)|(p.peg(ag+(((cg-ag)*f)>>8))<<8)|(p.peg(ab+(((cb-ab)*f)>>8))))},multiply:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;var ar=(c1&PConstants.RED_MASK)>>16;var ag=(c1&PConstants.GREEN_MASK)>>8;var ab=(c1&PConstants.BLUE_MASK);var br=(c2&PConstants.RED_MASK)>>16;var bg=(c2&PConstants.GREEN_MASK)>>8;var bb=(c2&PConstants.BLUE_MASK);var cr=(ar*br)>>8;var cg=(ag*bg)>>8;var cb=(ab*bb)>>8;return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|(p.peg(ar+(((cr-ar)*f)>>8))<<16)|(p.peg(ag+(((cg-ag)*f)>>8))<<8)|(p.peg(ab+(((cb-ab)*f)>>8))))},screen:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;var ar=(c1&PConstants.RED_MASK)>>16;var ag=(c1&PConstants.GREEN_MASK)>>8;var ab=(c1&PConstants.BLUE_MASK);var br=(c2&PConstants.RED_MASK)>>16;var bg=(c2&PConstants.GREEN_MASK)>>8;var bb=(c2&PConstants.BLUE_MASK);var cr=255-(((255-ar)*(255-br))>>8);var cg=255-(((255-ag)*(255-bg))>>8);var cb=255-(((255-ab)*(255-bb))>>8);return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|(p.peg(ar+(((cr-ar)*f)>>8))<<16)|(p.peg(ag+(((cg-ag)*f)>>8))<<8)|(p.peg(ab+(((cb-ab)*f)>>8))))},hard_light:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;var ar=(c1&PConstants.RED_MASK)>>16;var ag=(c1&PConstants.GREEN_MASK)>>8;var ab=(c1&PConstants.BLUE_MASK);var br=(c2&PConstants.RED_MASK)>>16;var bg=(c2&PConstants.GREEN_MASK)>>8;var bb=(c2&PConstants.BLUE_MASK);var cr=(br<128)?((ar*br)>>7):(255-(((255-ar)*(255-br))>>7));var cg=(bg<128)?((ag*bg)>>7):(255-(((255-ag)*(255-bg))>>7));var cb=(bb<128)?((ab*bb)>>7):(255-(((255-ab)*(255-bb))>>7));return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|(p.peg(ar+(((cr-ar)*f)>>8))<<16)|(p.peg(ag+(((cg-ag)*f)>>8))<<8)|(p.peg(ab+(((cb-ab)*f)>>8))))},soft_light:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;var ar=(c1&PConstants.RED_MASK)>>16;var ag=(c1&PConstants.GREEN_MASK)>>8;var ab=(c1&PConstants.BLUE_MASK);var br=(c2&PConstants.RED_MASK)>>16;var bg=(c2&PConstants.GREEN_MASK)>>8;var bb=(c2&PConstants.BLUE_MASK);var cr=((ar*br)>>7)+((ar*ar)>>8)-((ar*ar*br)>>15);var cg=((ag*bg)>>7)+((ag*ag)>>8)-((ag*ag*bg)>>15);var cb=((ab*bb)>>7)+((ab*ab)>>8)-((ab*ab*bb)>>15);return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|(p.peg(ar+(((cr-ar)*f)>>8))<<16)|(p.peg(ag+(((cg-ag)*f)>>8))<<8)|(p.peg(ab+(((cb-ab)*f)>>8))))},overlay:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;var ar=(c1&PConstants.RED_MASK)>>16;var ag=(c1&PConstants.GREEN_MASK)>>8;var ab=(c1&PConstants.BLUE_MASK);var br=(c2&PConstants.RED_MASK)>>16;var bg=(c2&PConstants.GREEN_MASK)>>8;var bb=(c2&PConstants.BLUE_MASK);var cr=(ar<128)?((ar*br)>>7):(255-(((255-ar)*(255-br))>>7));var cg=(ag<128)?((ag*bg)>>7):(255-(((255-ag)*(255-bg))>>7));var cb=(ab<128)?((ab*bb)>>7):(255-(((255-ab)*(255-bb))>>7));return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|(p.peg(ar+(((cr-ar)*f)>>8))<<16)|(p.peg(ag+(((cg-ag)*f)>>8))<<8)|(p.peg(ab+(((cb-ab)*f)>>8))))},dodge:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;var ar=(c1&PConstants.RED_MASK)>>16;var ag=(c1&PConstants.GREEN_MASK)>>8;var ab=(c1&PConstants.BLUE_MASK);var br=(c2&PConstants.RED_MASK)>>16;var bg=(c2&PConstants.GREEN_MASK)>>8;var bb=(c2&PConstants.BLUE_MASK);var cr=(br===255)?255:p.peg((ar<<8)/(255-br));var cg=(bg===255)?255:p.peg((ag<<8)/(255-bg));var cb=(bb===255)?255:p.peg((ab<<8)/(255-bb));return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|(p.peg(ar+(((cr-ar)*f)>>8))<<16)|(p.peg(ag+(((cg-ag)*f)>>8))<<8)|(p.peg(ab+(((cb-ab)*f)>>8))))},burn:function(c1,c2){var f=(c2&PConstants.ALPHA_MASK)>>>24;var ar=(c1&PConstants.RED_MASK)>>16;var ag=(c1&PConstants.GREEN_MASK)>>8;var ab=(c1&PConstants.BLUE_MASK);var br=(c2&PConstants.RED_MASK)>>16;var bg=(c2&PConstants.GREEN_MASK)>>8;var bb=(c2&PConstants.BLUE_MASK);var cr=(br===0)?0:255-p.peg(((255-ar)<<8)/br);var cg=(bg===0)?0:255-p.peg(((255-ag)<<8)/bg);var cb=(bb===0)?0:255-p.peg(((255-ab)<<8)/bb);return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|(p.peg(ar+(((cr-ar)*f)>>8))<<16)|(p.peg(ag+(((cg-ag)*f)>>8))<<8)|(p.peg(ab+(((cb-ab)*f)>>8))))}};function color$4(aValue1,aValue2,aValue3,aValue4){var r,g,b,a;if(curColorMode===PConstants.HSB){var rgb=p.color.toRGB(aValue1,aValue2,aValue3);r=rgb[0];g=rgb[1];b=rgb[2]}else{r=Math.round(255*(aValue1/colorModeX));g=Math.round(255*(aValue2/colorModeY));b=Math.round(255*(aValue3/colorModeZ))}a=Math.round(255*(aValue4/colorModeA));r=(r>255)?255:r;g=(g>255)?255:g;b=(b>255)?255:b;a=(a>255)?255:a;return(a<<24)&PConstants.ALPHA_MASK|(r<<16)&PConstants.RED_MASK|(g<<8)&PConstants.GREEN_MASK|b&PConstants.BLUE_MASK}function color$2(aValue1,aValue2){var a;if(aValue1&PConstants.ALPHA_MASK){a=Math.round(255*(aValue2/colorModeA));a=(a>255)?255:a;return aValue1-(aValue1&PConstants.ALPHA_MASK)+((a<<24)&PConstants.ALPHA_MASK)}else{if(curColorMode===PConstants.RGB){return color$4(aValue1,aValue1,aValue1,aValue2)}else{if(curColorMode===PConstants.HSB){return color$4(0,0,(aValue1/colorModeX)*colorModeZ,aValue2)}}}}function color$1(aValue1){if(aValue1<=colorModeX&&aValue1>=0){if(curColorMode===PConstants.RGB){return color$4(aValue1,aValue1,aValue1,colorModeA)}else{if(curColorMode===PConstants.HSB){return color$4(0,0,(aValue1/colorModeX)*colorModeZ,colorModeA)}}}else{if(aValue1){return aValue1}}}p.color=function color(aValue1,aValue2,aValue3,aValue4){if(aValue1!==undef&&aValue2!==undef&&aValue3!==undef&&aValue4!==undef){return color$4(aValue1,aValue2,aValue3,aValue4)}else{if(aValue1!==undef&&aValue2!==undef&&aValue3!==undef){return color$4(aValue1,aValue2,aValue3,colorModeA)}else{if(aValue1!==undef&&aValue2!==undef){return color$2(aValue1,aValue2)}else{if(typeof aValue1==="number"){return color$1(aValue1)}else{return color$4(colorModeX,colorModeY,colorModeZ,colorModeA)}}}}};p.color.toString=function(colorInt){return"rgba("+((colorInt&PConstants.RED_MASK)>>>16)+","+((colorInt&PConstants.GREEN_MASK)>>>8)+","+((colorInt&PConstants.BLUE_MASK))+","+((colorInt&PConstants.ALPHA_MASK)>>>24)/255+")"};p.color.toInt=function(r,g,b,a){return(a<<24)&PConstants.ALPHA_MASK|(r<<16)&PConstants.RED_MASK|(g<<8)&PConstants.GREEN_MASK|b&PConstants.BLUE_MASK};p.color.toArray=function(colorInt){return[(colorInt&PConstants.RED_MASK)>>>16,(colorInt&PConstants.GREEN_MASK)>>>8,colorInt&PConstants.BLUE_MASK,(colorInt&PConstants.ALPHA_MASK)>>>24]};p.color.toGLArray=function(colorInt){return[((colorInt&PConstants.RED_MASK)>>>16)/255,((colorInt&PConstants.GREEN_MASK)>>>8)/255,(colorInt&PConstants.BLUE_MASK)/255,((colorInt&PConstants.ALPHA_MASK)>>>24)/255]};p.color.toRGB=function(h,s,b){h=(h>colorModeX)?colorModeX:h;s=(s>colorModeY)?colorModeY:s;b=(b>colorModeZ)?colorModeZ:b;h=(h/colorModeX)*360;s=(s/colorModeY)*100;b=(b/colorModeZ)*100;var br=Math.round(b/100*255);if(s===0){return[br,br,br]}else{var hue=h%360;var f=hue%60;var p=Math.round((b*(100-s))/10000*255);var q=Math.round((b*(6000-s*f))/600000*255);var t=Math.round((b*(6000-s*(60-f)))/600000*255);switch(Math.floor(hue/60)){case 0:return[br,t,p];case 1:return[q,br,p];case 2:return[p,br,t];case 3:return[p,q,br];case 4:return[t,p,br];case 5:return[br,p,q]}}};p.color.toHSB=function(colorInt){var red,green,blue;red=((colorInt&PConstants.RED_MASK)>>>16)/255;green=((colorInt&PConstants.GREEN_MASK)>>>8)/255;blue=(colorInt&PConstants.BLUE_MASK)/255;var max=p.max(p.max(red,green),blue),min=p.min(p.min(red,green),blue),hue,saturation;if(min===max){return[0,0,max]}else{saturation=(max-min)/max;if(red===max){hue=(green-blue)/(max-min)}else{if(green===max){hue=2+((blue-red)/(max-min))}else{hue=4+((red-green)/(max-min))}}hue/=6;if(hue<0){hue+=1}else{if(hue>1){hue-=1}}}return[hue*colorModeX,saturation*colorModeY,max*colorModeZ]};p.brightness=function(colInt){return p.color.toHSB(colInt)[2]};p.saturation=function(colInt){return p.color.toHSB(colInt)[1]};p.hue=function(colInt){return p.color.toHSB(colInt)[0]};var verifyChannel=function verifyChannel(aColor){if(aColor.constructor===Array){return aColor}else{return p.color(aColor)}};p.red=function(aColor){return((aColor&PConstants.RED_MASK)>>>16)/255*colorModeX};p.green=function(aColor){return((aColor&PConstants.GREEN_MASK)>>>8)/255*colorModeY};p.blue=function(aColor){return(aColor&PConstants.BLUE_MASK)/255*colorModeZ};p.alpha=function(aColor){return((aColor&PConstants.ALPHA_MASK)>>>24)/255*colorModeA};p.lerpColor=function lerpColor(c1,c2,amt){var colorBits1=p.color(c1);var r1=(colorBits1&PConstants.RED_MASK)>>>16;var g1=(colorBits1&PConstants.GREEN_MASK)>>>8;var b1=(colorBits1&PConstants.BLUE_MASK);var a1=((colorBits1&PConstants.ALPHA_MASK)>>>24)/colorModeA;var colorBits2=p.color(c2);var r2=(colorBits2&PConstants.RED_MASK)>>>16;var g2=(colorBits2&PConstants.GREEN_MASK)>>>8;var b2=(colorBits2&PConstants.BLUE_MASK);var a2=((colorBits2&PConstants.ALPHA_MASK)>>>24)/colorModeA;var r=parseInt(p.lerp(r1,r2,amt),10);var g=parseInt(p.lerp(g1,g2,amt),10);var b=parseInt(p.lerp(b1,b2,amt),10);var a=parseFloat(p.lerp(a1,a2,amt)*colorModeA);return p.color.toInt(r,g,b,a)};p.defaultColor=function(aValue1,aValue2,aValue3){var tmpColorMode=curColorMode;curColorMode=PConstants.RGB;var c=p.color(aValue1/255*colorModeX,aValue2/255*colorModeY,aValue3/255*colorModeZ);curColorMode=tmpColorMode;return c};p.colorMode=function colorMode(){curColorMode=arguments[0];if(arguments.length>1){colorModeX=arguments[1];colorModeY=arguments[2]||arguments[1];colorModeZ=arguments[3]||arguments[1];colorModeA=arguments[4]||arguments[1]}};p.blendColor=function(c1,c2,mode){var color=0;switch(mode){case PConstants.REPLACE:color=p.modes.replace(c1,c2);break;case PConstants.BLEND:color=p.modes.blend(c1,c2);break;case PConstants.ADD:color=p.modes.add(c1,c2);break;case PConstants.SUBTRACT:color=p.modes.subtract(c1,c2);break;case PConstants.LIGHTEST:color=p.modes.lightest(c1,c2);break;case PConstants.DARKEST:color=p.modes.darkest(c1,c2);break;case PConstants.DIFFERENCE:color=p.modes.difference(c1,c2);break;case PConstants.EXCLUSION:color=p.modes.exclusion(c1,c2);break;case PConstants.MULTIPLY:color=p.modes.multiply(c1,c2);break;case PConstants.SCREEN:color=p.modes.screen(c1,c2);break;case PConstants.HARD_LIGHT:color=p.modes.hard_light(c1,c2);break;case PConstants.SOFT_LIGHT:color=p.modes.soft_light(c1,c2);break;case PConstants.OVERLAY:color=p.modes.overlay(c1,c2);break;case PConstants.DODGE:color=p.modes.dodge(c1,c2);break;case PConstants.BURN:color=p.modes.burn(c1,c2);break}return color};function saveContext(){curContext.save()}function restoreContext(){curContext.restore();isStrokeDirty=true;isFillDirty=true}p.printMatrix=function printMatrix(){modelView.print()};p.translate=function translate(x,y,z){if(p.use3DContext){forwardTransform.translate(x,y,z);reverseTransform.invTranslate(x,y,z)}else{curContext.translate(x,y)}};p.scale=function scale(x,y,z){if(p.use3DContext){forwardTransform.scale(x,y,z);reverseTransform.invScale(x,y,z)}else{curContext.scale(x,y||x)}};p.pushMatrix=function pushMatrix(){if(p.use3DContext){userMatrixStack.load(modelView)}else{saveContext()}};p.popMatrix=function popMatrix(){if(p.use3DContext){modelView.set(userMatrixStack.pop())}else{restoreContext()}};p.resetMatrix=function resetMatrix(){if(p.use3DContext){forwardTransform.reset();reverseTransform.reset()}else{curContext.setTransform(1,0,0,1,0,0)}};p.applyMatrix=function applyMatrix(){var a=arguments;if(!p.use3DContext){for(var cnt=a.length;cnt<16;cnt++){a[cnt]=0}a[10]=a[15]=1}forwardTransform.apply(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],a[15]);reverseTransform.invApply(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],a[15])};p.rotateX=function(angleInRadians){forwardTransform.rotateX(angleInRadians);reverseTransform.invRotateX(angleInRadians)};p.rotateZ=function(angleInRadians){forwardTransform.rotateZ(angleInRadians);reverseTransform.invRotateZ(angleInRadians)};p.rotateY=function(angleInRadians){forwardTransform.rotateY(angleInRadians);reverseTransform.invRotateY(angleInRadians)};p.rotate=function rotate(angleInRadians){if(p.use3DContext){forwardTransform.rotateZ(angleInRadians);reverseTransform.invRotateZ(angleInRadians)}else{curContext.rotate(angleInRadians)}};p.pushStyle=function pushStyle(){saveContext();p.pushMatrix();var newState={doFill:doFill,currentFillColor:currentFillColor,doStroke:doStroke,currentStrokeColor:currentStrokeColor,curTint:curTint,curRectMode:curRectMode,curColorMode:curColorMode,colorModeX:colorModeX,colorModeZ:colorModeZ,colorModeY:colorModeY,colorModeA:colorModeA,curTextFont:curTextFont,curTextSize:curTextSize};styleArray.push(newState)};p.popStyle=function popStyle(){var oldState=styleArray.pop();if(oldState){restoreContext();p.popMatrix();doFill=oldState.doFill;currentFillColor=oldState.currentFillColor;doStroke=oldState.doStroke;currentStrokeColor=oldState.currentStrokeColor;curTint=oldState.curTint;curRectMode=oldState.curRectmode;curColorMode=oldState.curColorMode;colorModeX=oldState.colorModeX;colorModeZ=oldState.colorModeZ;colorModeY=oldState.colorModeY;colorModeA=oldState.colorModeA;curTextFont=oldState.curTextFont;curTextSize=oldState.curTextSize}else{throw"Too many popStyle() without enough pushStyle()"}};p.year=function year(){return new Date().getFullYear()};p.month=function month(){return new Date().getMonth()+1};p.day=function day(){return new Date().getDate()};p.hour=function hour(){return new Date().getHours()};p.minute=function minute(){return new Date().getMinutes()};p.second=function second(){return new Date().getSeconds()};p.millis=function millis(){return new Date().getTime()-start};p.redraw=function redraw(){var sec=(new Date().getTime()-timeSinceLastFPS)/1000;framesSinceLastFPS++;var fps=framesSinceLastFPS/sec;if(sec>0.5){timeSinceLastFPS=new Date().getTime();framesSinceLastFPS=0;p.__frameRate=fps}p.frameCount++;inDraw=true;if(p.use3DContext){curContext.clear(curContext.DEPTH_BUFFER_BIT);curContextCache={attributes:{},locations:{}};p.noLights();p.lightFalloff(1,0,0);p.shininess(1);p.ambient(255,255,255);p.specular(0,0,0);p.camera();p.draw()}else{saveContext();p.draw();restoreContext()}inDraw=false};p.noLoop=function noLoop(){doLoop=false;loopStarted=false;clearInterval(looping)};p.loop=function loop(){if(loopStarted){return}looping=window.setInterval(function(){try{if(document.hasFocus instanceof Function){p.focused=document.hasFocus()}p.redraw()}catch(e_loop){window.clearInterval(looping);throw e_loop}},curMsPerFrame);doLoop=true;loopStarted=true};p.frameRate=function frameRate(aRate){curFrameRate=aRate;curMsPerFrame=1000/curFrameRate;if(doLoop){p.noLoop();p.loop()}};var eventHandlers=[];p.exit=function exit(){window.clearInterval(looping);Processing.removeInstance(p.externals.canvas.id);for(var lib in Processing.lib){if(Processing.lib.hasOwnProperty(lib)){if(Processing.lib[lib].hasOwnProperty("detach")){Processing.lib[lib].detach(p)}}}for(var i=0,ehl=eventHandlers.length;i<ehl;i++){var elem=eventHandlers[i][0],type=eventHandlers[i][1],fn=eventHandlers[i][2];if(elem.removeEventListener){elem.removeEventListener(type,fn,false)}else{if(elem.detachEvent){elem.detachEvent("on"+type,fn)}}}};p.cursor=function cursor(){if(arguments.length>1||(arguments.length===1&&arguments[0] instanceof p.PImage)){var image=arguments[0],x,y;if(arguments.length>=3){x=arguments[1];y=arguments[2];if(x<0||y<0||y>=image.height||x>=image.width){throw"x and y must be non-negative and less than the dimensions of the image"}}else{x=image.width>>>1;y=image.height>>>1}var imageDataURL=image.toDataURL();var style='url("'+imageDataURL+'") '+x+" "+y+", default";curCursor=curElement.style.cursor=style}else{if(arguments.length===1){var mode=arguments[0];curCursor=curElement.style.cursor=mode}else{curCursor=curElement.style.cursor=oldCursor}}};p.noCursor=function noCursor(){curCursor=curElement.style.cursor=PConstants.NOCURSOR};p.link=function(href,target){if(target!==undef){window.open(href,target)}else{window.location=href}};p.beginDraw=function beginDraw(){};p.endDraw=function endDraw(){};p.Import=function Import(lib){};var contextMenu=function(e){e.preventDefault();e.stopPropagation()};p.disableContextMenu=function disableContextMenu(){curElement.addEventListener("contextmenu",contextMenu,false)};p.enableContextMenu=function enableContextMenu(){curElement.removeEventListener("contextmenu",contextMenu,false)};p.status=function(text){window.status=text};function decToBin(value,numBitsInValue){var mask=1;mask=mask<<(numBitsInValue-1);var str="";for(var i=0;i<numBitsInValue;i++){str+=(mask&value)?"1":"0";mask=mask>>>1}return str}p.binary=function(num,numBits){var numBitsInValue=32;if(typeof num==="number"){if(numBits){numBitsInValue=numBits}return decToBin(num,numBitsInValue)}if(num instanceof Char){num=num.toString().charCodeAt(0);if(numBits){numBitsInValue=32}else{numBitsInValue=16}}var str=decToBin(num,numBitsInValue);if(numBits){str=str.substr(-numBits)}return str};p.unbinary=function unbinary(binaryString){var binaryPattern=new RegExp("^[0|1]{8}$");var addUp=0;var i;if(binaryString instanceof Array){var values=[];for(i=0;i<binaryString.length;i++){values[i]=p.unbinary(binaryString[i])}return values}else{if(isNaN(binaryString)){throw"NaN_Err"}else{if(arguments.length===1||binaryString.length===8){if(binaryPattern.test(binaryString)){for(i=0;i<8;i++){addUp+=(Math.pow(2,i)*parseInt(binaryString.charAt(7-i),10))}return addUp+""}else{throw"notBinary: the value passed into unbinary was not an 8 bit binary number"}}else{throw"longErr"}}}};function nfCoreScalar(value,plus,minus,leftDigits,rightDigits,group){var sign=(value<0)?minus:plus;var autoDetectDecimals=rightDigits===0;var rightDigitsOfDefault=(rightDigits===undef||rightDigits<0)?0:rightDigits;var absValue=Math.abs(value);if(autoDetectDecimals){rightDigitsOfDefault=1;absValue*=10;while(Math.abs(Math.round(absValue)-absValue)>0.000001&&rightDigitsOfDefault<7){++rightDigitsOfDefault;absValue*=10}}else{if(rightDigitsOfDefault!==0){absValue*=Math.pow(10,rightDigitsOfDefault)}}var number,doubled=absValue*2;if(Math.floor(absValue)===absValue){number=absValue}else{if(Math.floor(doubled)===doubled){var floored=Math.floor(absValue);number=floored+(floored%2)}else{number=Math.round(absValue)}}var buffer="";var totalDigits=leftDigits+rightDigitsOfDefault;while(totalDigits>0||number>0){totalDigits--;buffer=""+(number%10)+buffer;number=Math.floor(number/10)}if(group!==undef){var i=buffer.length-3-rightDigitsOfDefault;while(i>0){buffer=buffer.substring(0,i)+group+buffer.substring(i);i-=3}}if(rightDigitsOfDefault>0){return sign+buffer.substring(0,buffer.length-rightDigitsOfDefault)+"."+buffer.substring(buffer.length-rightDigitsOfDefault,buffer.length)}else{return sign+buffer}}function nfCore(value,plus,minus,leftDigits,rightDigits,group){if(value instanceof Array){var arr=[];for(var i=0,len=value.length;i<len;i++){arr.push(nfCoreScalar(value[i],plus,minus,leftDigits,rightDigits,group))}return arr}else{return nfCoreScalar(value,plus,minus,leftDigits,rightDigits,group)}}p.nf=function(value,leftDigits,rightDigits){return nfCore(value,"","-",leftDigits,rightDigits)};p.nfs=function(value,leftDigits,rightDigits){return nfCore(value," ","-",leftDigits,rightDigits)};p.nfp=function(value,leftDigits,rightDigits){return nfCore(value,"+","-",leftDigits,rightDigits)};p.nfc=function(value,leftDigits,rightDigits){return nfCore(value,"","-",leftDigits,rightDigits,",")};var decimalToHex=function decimalToHex(d,padding){padding=(padding===undef||padding===null)?padding=8:padding;if(d<0){d=4294967295+d+1}var hex=Number(d).toString(16).toUpperCase();while(hex.length<padding){hex="0"+hex}if(hex.length>=padding){hex=hex.substring(hex.length-padding,hex.length)}return hex};p.hex=function hex(value,len){if(arguments.length===1){if(value instanceof Char){len=4}else{len=8}}return decimalToHex(value,len)};function unhexScalar(hex){var value=parseInt("0x"+hex,16);if(value>2147483647){value-=4294967296}return value}p.unhex=function(hex){if(hex instanceof Array){var arr=[];for(var i=0;i<hex.length;i++){arr.push(unhexScalar(hex[i]))}return arr}else{return unhexScalar(hex)}};p.loadStrings=function loadStrings(filename){if(localStorage[filename]){return localStorage[filename].split("\n")}var filecontent=ajax(filename);if(typeof filecontent!=="string"||filecontent===""){return[]}filecontent=filecontent.replace(/(\r\n?)/g,"\n").replace(/\n$/,"");return filecontent.split("\n")};p.saveStrings=function saveStrings(filename,strings){localStorage[filename]=strings.join("\n")};p.loadBytes=function loadBytes(url,strings){var string=ajax(url);var ret=[];for(var i=0;i<string.length;i++){ret.push(string.charCodeAt(i))}return ret};p.matchAll=function matchAll(aString,aRegExp){var results=[],latest;var regexp=new RegExp(aRegExp,"g");while((latest=regexp.exec(aString))!==null){results.push(latest);if(latest[0].length===0){++regexp.lastIndex}}return results.length>0?results:null};String.prototype.replaceAll=function(re,replace){return this.replace(new RegExp(re,"g"),replace)};String.prototype.equals=function equals(str){return this.valueOf()===str.valueOf()};String.prototype.toCharArray=function(){var chars=this.split("");for(var i=chars.length-1;i>=0;i--){chars[i]=new Char(chars[i])}return chars};p.match=function(str,regexp){return str.match(regexp)};var logBuffer=[];p.console=window.console||Processing.logger;p.println=function println(message){var bufferLen=logBuffer.length;if(bufferLen){Processing.logger.log(logBuffer.join(""));logBuffer.length=0}if(arguments.length===0&&bufferLen===0){Processing.logger.log("")}else{if(arguments.length!==0){Processing.logger.log(message)}}};p.print=function print(message){logBuffer.push(message)};p.str=function str(val){if(val instanceof Array){var arr=[];for(var i=0;i<val.length;i++){arr.push(val[i]+"")}return arr}else{return(val+"")}};p.trim=function(str){if(str instanceof Array){var arr=[];for(var i=0;i<str.length;i++){arr.push(str[i].replace(/^\s*/,"").replace(/\s*$/,"").replace(/\r*$/,""))}return arr}else{return str.replace(/^\s*/,"").replace(/\s*$/,"").replace(/\r*$/,"")}};function booleanScalar(val){if(typeof val==="number"){return val!==0}else{if(typeof val==="boolean"){return val}else{if(typeof val==="string"){return val.toLowerCase()==="true"}else{if(val instanceof Char){return val.code===49||val.code===84||val.code===116}}}}}p["boolean"]=function(val){if(val instanceof Array){var ret=[];for(var i=0;i<val.length;i++){ret.push(booleanScalar(val[i]))}return ret}else{return booleanScalar(val)}};p["byte"]=function(aNumber){if(aNumber instanceof Array){var bytes=[];for(var i=0;i<aNumber.length;i++){bytes.push((0-(aNumber[i]&128))|(aNumber[i]&127))}return bytes}else{return(0-(aNumber&128))|(aNumber&127)}};p["char"]=function(key){if(typeof key==="number"){return new Char(String.fromCharCode(key&65535))}else{if(key instanceof Array){var ret=[];for(var i=0;i<key.length;i++){ret.push(new Char(String.fromCharCode(key[i]&65535)))}return ret}else{throw"char() may receive only one argument of type int, byte, int[], or byte[]."}}};function floatScalar(val){if(typeof val==="number"){return val}else{if(typeof val==="boolean"){return val?1:0}else{if(typeof val==="string"){return parseFloat(val)}else{if(val instanceof Char){return val.code}}}}}p["float"]=function(val){if(val instanceof Array){var ret=[];for(var i=0;i<val.length;i++){ret.push(floatScalar(val[i]))}return ret}else{return floatScalar(val)}};function intScalar(val){if(typeof val==="number"){return val&4294967295}else{if(typeof val==="boolean"){return val?1:0}else{if(typeof val==="string"){var number=parseInt(val,10);return number&4294967295}else{if(val instanceof Char){return val.code}}}}}p["int"]=function(val){if(val instanceof Array){var ret=[];for(var i=0;i<val.length;i++){if(typeof val[i]==="string"&&!/^\s*[+\-]?\d+\s*$/.test(val[i])){ret.push(0)}else{ret.push(intScalar(val[i]))}}return ret}else{return intScalar(val)}};p.__int_cast=function(val){return 0|val};p.abs=Math.abs;p.ceil=Math.ceil;p.constrain=function(aNumber,aMin,aMax){return aNumber>aMax?aMax:aNumber<aMin?aMin:aNumber};p.dist=function(){var dx,dy,dz;if(arguments.length===4){dx=arguments[0]-arguments[2];dy=arguments[1]-arguments[3];return Math.sqrt(dx*dx+dy*dy)}else{if(arguments.length===6){dx=arguments[0]-arguments[3];dy=arguments[1]-arguments[4];dz=arguments[2]-arguments[5];return Math.sqrt(dx*dx+dy*dy+dz*dz)}}};p.exp=Math.exp;p.floor=Math.floor;p.lerp=function(value1,value2,amt){return((value2-value1)*amt)+value1};p.log=Math.log;p.mag=function(a,b,c){if(arguments.length===2){return Math.sqrt(a*a+b*b)}else{if(arguments.length===3){return Math.sqrt(a*a+b*b+c*c)}}};p.map=function(value,istart,istop,ostart,ostop){return ostart+(ostop-ostart)*((value-istart)/(istop-istart))};p.max=function(){if(arguments.length===2){return arguments[0]<arguments[1]?arguments[1]:arguments[0]}else{var numbers=arguments.length===1?arguments[0]:arguments;if(!("length" in numbers&&numbers.length>0)){throw"Non-empty array is expected"}var max=numbers[0],count=numbers.length;for(var i=1;i<count;++i){if(max<numbers[i]){max=numbers[i]}}return max}};p.min=function(){if(arguments.length===2){return arguments[0]<arguments[1]?arguments[0]:arguments[1]}else{var numbers=arguments.length===1?arguments[0]:arguments;if(!("length" in numbers&&numbers.length>0)){throw"Non-empty array is expected"}var min=numbers[0],count=numbers.length;for(var i=1;i<count;++i){if(min>numbers[i]){min=numbers[i]}}return min}};p.norm=function(aNumber,low,high){return(aNumber-low)/(high-low)};p.pow=Math.pow;p.round=Math.round;p.sq=function(aNumber){return aNumber*aNumber};p.sqrt=Math.sqrt;p.acos=Math.acos;p.asin=Math.asin;p.atan=Math.atan;p.atan2=Math.atan2;p.cos=Math.cos;p.degrees=function(aAngle){return(aAngle*180)/Math.PI};p.radians=function(aAngle){return(aAngle/180)*Math.PI};p.sin=Math.sin;p.tan=Math.tan;var currentRandom=Math.random;p.random=function random(){if(arguments.length===0){return currentRandom()}else{if(arguments.length===1){return currentRandom()*arguments[0]}else{var aMin=arguments[0],aMax=arguments[1];return currentRandom()*(aMax-aMin)+aMin}}};function Marsaglia(i1,i2){var z=i1||362436069,w=i2||521288629;var nextInt=function(){z=(36969*(z&65535)+(z>>>16))&4294967295;w=(18000*(w&65535)+(w>>>16))&4294967295;return(((z&65535)<<16)|(w&65535))&4294967295};this.nextDouble=function(){var i=nextInt()/4294967296;return i<0?1+i:i};this.nextInt=nextInt}Marsaglia.createRandomized=function(){var now=new Date();return new Marsaglia((now/60000)&4294967295,now&4294967295)};p.randomSeed=function(seed){currentRandom=(new Marsaglia(seed)).nextDouble};p.Random=function(seed){var haveNextNextGaussian=false,nextNextGaussian,random;this.nextGaussian=function(){if(haveNextNextGaussian){haveNextNextGaussian=false;return nextNextGaussian}else{var v1,v2,s;do{v1=2*random()-1;v2=2*random()-1;s=v1*v1+v2*v2}while(s>=1||s===0);var multiplier=Math.sqrt(-2*Math.log(s)/s);nextNextGaussian=v2*multiplier;haveNextNextGaussian=true;return v1*multiplier}};random=(seed===undef)?Math.random:(new Marsaglia(seed)).nextDouble};function PerlinNoise(seed){var rnd=seed!==undef?new Marsaglia(seed):Marsaglia.createRandomized();var i,j;var perm=new Array(512);for(i=0;i<256;++i){perm[i]=i}for(i=0;i<256;++i){var t=perm[j=rnd.nextInt()&255];perm[j]=perm[i];perm[i]=t}for(i=0;i<256;++i){perm[i+256]=perm[i]}function grad3d(i,x,y,z){var h=i&15;var u=h<8?x:y,v=h<4?y:h===12||h===14?x:z;return((h&1)===0?u:-u)+((h&2)===0?v:-v)}function grad2d(i,x,y){var v=(i&1)===0?x:y;return(i&2)===0?-v:v}function grad1d(i,x){return(i&1)===0?-x:x}function lerp(t,a,b){return a+t*(b-a)}this.noise3d=function(x,y,z){var X=Math.floor(x)&255,Y=Math.floor(y)&255,Z=Math.floor(z)&255;x-=Math.floor(x);y-=Math.floor(y);z-=Math.floor(z);var fx=(3-2*x)*x*x,fy=(3-2*y)*y*y,fz=(3-2*z)*z*z;var p0=perm[X]+Y,p00=perm[p0]+Z,p01=perm[p0+1]+Z,p1=perm[X+1]+Y,p10=perm[p1]+Z,p11=perm[p1+1]+Z;return lerp(fz,lerp(fy,lerp(fx,grad3d(perm[p00],x,y,z),grad3d(perm[p10],x-1,y,z)),lerp(fx,grad3d(perm[p01],x,y-1,z),grad3d(perm[p11],x-1,y-1,z))),lerp(fy,lerp(fx,grad3d(perm[p00+1],x,y,z-1),grad3d(perm[p10+1],x-1,y,z-1)),lerp(fx,grad3d(perm[p01+1],x,y-1,z-1),grad3d(perm[p11+1],x-1,y-1,z-1))))};this.noise2d=function(x,y){var X=Math.floor(x)&255,Y=Math.floor(y)&255;x-=Math.floor(x);y-=Math.floor(y);var fx=(3-2*x)*x*x,fy=(3-2*y)*y*y;var p0=perm[X]+Y,p1=perm[X+1]+Y;return lerp(fy,lerp(fx,grad2d(perm[p0],x,y),grad2d(perm[p1],x-1,y)),lerp(fx,grad2d(perm[p0+1],x,y-1),grad2d(perm[p1+1],x-1,y-1)))};this.noise1d=function(x){var X=Math.floor(x)&255;x-=Math.floor(x);var fx=(3-2*x)*x*x;return lerp(fx,grad1d(perm[X],x),grad1d(perm[X+1],x-1))}}var noiseProfile={generator:undef,octaves:4,fallout:0.5,seed:undef};p.noise=function(x,y,z){if(noiseProfile.generator===undef){noiseProfile.generator=new PerlinNoise(noiseProfile.seed)}var generator=noiseProfile.generator;var effect=1,k=1,sum=0;for(var i=0;i<noiseProfile.octaves;++i){effect*=noiseProfile.fallout;switch(arguments.length){case 1:sum+=effect*(1+generator.noise1d(k*x))/2;break;case 2:sum+=effect*(1+generator.noise2d(k*x,k*y))/2;break;case 3:sum+=effect*(1+generator.noise3d(k*x,k*y,k*z))/2;break}k*=2}return sum};p.noiseDetail=function(octaves,fallout){noiseProfile.octaves=octaves;if(fallout!==undef){noiseProfile.fallout=fallout}};p.noiseSeed=function(seed){noiseProfile.seed=seed;noiseProfile.generator=undef};var refreshBackground=function(){if(!curSketch.options.isTransparent){if(p.use3DContext){curContext.clearColor(204/255,204/255,204/255,1);curContext.clear(curContext.COLOR_BUFFER_BIT|curContext.DEPTH_BUFFER_BIT)}else{curContext.fillStyle="rgb(204, 204, 204)";curContext.fillRect(0,0,p.width,p.height);isFillDirty=true}}};p.size=function size(aWidth,aHeight,aMode){if(aMode&&(aMode===PConstants.WEBGL)){try{if(curElement.width!==aWidth||curElement.height!==aHeight){curElement.setAttribute("width",aWidth);curElement.setAttribute("height",aHeight)}curContext=curElement.getContext("experimental-webgl");p.use3DContext=true;canTex=curContext.createTexture();textTex=curContext.createTexture()}catch(e_size){Processing.debug(e_size)}if(!curContext){throw"WebGL context is not supported on this browser."}else{for(var i=0;i<PConstants.SINCOS_LENGTH;i++){sinLUT[i]=p.sin(i*(PConstants.PI/180)*0.5);cosLUT[i]=p.cos(i*(PConstants.PI/180)*0.5)}curContext.viewport(0,0,curElement.width,curElement.height);curContext.enable(curContext.DEPTH_TEST);curContext.enable(curContext.BLEND);curContext.blendFunc(curContext.SRC_ALPHA,curContext.ONE_MINUS_SRC_ALPHA);refreshBackground();programObject2D=createProgramObject(curContext,vertexShaderSource2D,fragmentShaderSource2D);curContext.useProgram(programObject2D);p.strokeWeight(1);programObject3D=createProgramObject(curContext,vertexShaderSource3D,fragmentShaderSource3D);programObjectUnlitShape=createProgramObject(curContext,vShaderSrcUnlitShape,fShaderSrcUnlitShape);curContext.useProgram(programObject3D);uniformi("usingTexture3d",programObject3D,"usingTexture",usingTexture);p.lightFalloff(1,0,0);p.shininess(1);p.ambient(255,255,255);p.specular(0,0,0);boxBuffer=curContext.createBuffer();curContext.bindBuffer(curContext.ARRAY_BUFFER,boxBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,boxVerts,curContext.STATIC_DRAW);boxNormBuffer=curContext.createBuffer();curContext.bindBuffer(curContext.ARRAY_BUFFER,boxNormBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,boxNorms,curContext.STATIC_DRAW);boxOutlineBuffer=curContext.createBuffer();curContext.bindBuffer(curContext.ARRAY_BUFFER,boxOutlineBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,boxOutlineVerts,curContext.STATIC_DRAW);rectBuffer=curContext.createBuffer();curContext.bindBuffer(curContext.ARRAY_BUFFER,rectBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,rectVerts,curContext.STATIC_DRAW);rectNormBuffer=curContext.createBuffer();curContext.bindBuffer(curContext.ARRAY_BUFFER,rectNormBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,rectNorms,curContext.STATIC_DRAW);sphereBuffer=curContext.createBuffer();lineBuffer=curContext.createBuffer();fillBuffer=curContext.createBuffer();fillColorBuffer=curContext.createBuffer();strokeColorBuffer=curContext.createBuffer();shapeTexVBO=curContext.createBuffer();pointBuffer=curContext.createBuffer();curContext.bindBuffer(curContext.ARRAY_BUFFER,pointBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,new Float32Array([0,0,0]),curContext.STATIC_DRAW);textBuffer=curContext.createBuffer();curContext.bindBuffer(curContext.ARRAY_BUFFER,textBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,new Float32Array([1,1,0,-1,1,0,-1,-1,0,1,-1,0]),curContext.STATIC_DRAW);textureBuffer=curContext.createBuffer();curContext.bindBuffer(curContext.ARRAY_BUFFER,textureBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,new Float32Array([0,0,1,0,1,1,0,1]),curContext.STATIC_DRAW);indexBuffer=curContext.createBuffer();curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER,indexBuffer);curContext.bufferData(curContext.ELEMENT_ARRAY_BUFFER,new Uint16Array([0,1,2,2,3,0]),curContext.STATIC_DRAW);cam=new PMatrix3D();cameraInv=new PMatrix3D();forwardTransform=new PMatrix3D();reverseTransform=new PMatrix3D();modelView=new PMatrix3D();modelViewInv=new PMatrix3D();projection=new PMatrix3D();p.camera();p.perspective();forwardTransform=modelView;reverseTransform=modelViewInv;userMatrixStack=new PMatrixStack();curveBasisMatrix=new PMatrix3D();curveToBezierMatrix=new PMatrix3D();curveDrawMatrix=new PMatrix3D();bezierDrawMatrix=new PMatrix3D();bezierBasisInverse=new PMatrix3D();bezierBasisMatrix=new PMatrix3D();bezierBasisMatrix.set(-1,3,-3,1,3,-6,3,0,-3,3,0,0,1,0,0,0)}p.stroke(0);p.fill(255)}else{if(curContext===undef){curContext=curElement.getContext("2d");p.use3DContext=false;userMatrixStack=new PMatrixStack();modelView=new PMatrix2D()}}var props={fillStyle:curContext.fillStyle,strokeStyle:curContext.strokeStyle,lineCap:curContext.lineCap,lineJoin:curContext.lineJoin};if(curElement.style.length>0){curElement.style.removeProperty("width");curElement.style.removeProperty("height")}curElement.width=p.width=aWidth||100;curElement.height=p.height=aHeight||100;for(var j in props){if(props){curContext[j]=props[j]}}refreshBackground();maxPixelsCached=Math.max(1000,aWidth*aHeight*0.05);p.externals.context=curContext;p.toImageData=function(){if(!p.use3DContext){return curContext.getImageData(0,0,this.width,this.height)}else{var c=document.createElement("canvas");var ctx=c.getContext("2d");var obj=ctx.createImageData(this.width,this.height);var uBuff=new Uint8Array(this.width*this.height*4);curContext.readPixels(0,0,this.width,this.height,curContext.RGBA,curContext.UNSIGNED_BYTE,uBuff);for(var i=0;i<uBuff.length;i++){obj.data[i]=uBuff[(this.height-1-Math.floor(i/4/this.width))*this.width*4+(i%(this.width*4))]}return obj}}};p.ambientLight=function(r,g,b,x,y,z){if(p.use3DContext){if(lightCount===PConstants.MAX_LIGHTS){throw"can only create "+PConstants.MAX_LIGHTS+" lights"}var pos=new PVector(x,y,z);var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.mult(pos,pos);curContext.useProgram(programObject3D);uniformf("lights.color.3d."+lightCount,programObject3D,"lights["+lightCount+"].color",[r/255,g/255,b/255]);uniformf("lights.position.3d."+lightCount,programObject3D,"lights["+lightCount+"].position",pos.array());uniformi("lights.type.3d."+lightCount,programObject3D,"lights["+lightCount+"].type",0);uniformi("lightCount3d",programObject3D,"lightCount",++lightCount)}};p.directionalLight=function(r,g,b,nx,ny,nz){if(p.use3DContext){if(lightCount===PConstants.MAX_LIGHTS){throw"can only create "+PConstants.MAX_LIGHTS+" lights"}curContext.useProgram(programObject3D);var dir=[nx,ny,nz,1e-7];var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.mult(dir,dir);uniformf("lights.color.3d."+lightCount,programObject3D,"lights["+lightCount+"].color",[r/255,g/255,b/255]);uniformf("lights.position.3d."+lightCount,programObject3D,"lights["+lightCount+"].position",[-dir[0],-dir[1],-dir[2]]);uniformi("lights.type.3d."+lightCount,programObject3D,"lights["+lightCount+"].type",1);uniformi("lightCount3d",programObject3D,"lightCount",++lightCount)}};p.lightFalloff=function lightFalloff(constant,linear,quadratic){if(p.use3DContext){curContext.useProgram(programObject3D);uniformf("falloff3d",programObject3D,"falloff",[constant,linear,quadratic])}};p.lightSpecular=function lightSpecular(r,g,b){if(p.use3DContext){curContext.useProgram(programObject3D);uniformf("specular3d",programObject3D,"specular",[r/255,g/255,b/255])}};p.lights=function lights(){p.ambientLight(128,128,128);p.directionalLight(128,128,128,0,0,-1);p.lightFalloff(1,0,0);p.lightSpecular(0,0,0)};p.pointLight=function(r,g,b,x,y,z){if(p.use3DContext){if(lightCount===PConstants.MAX_LIGHTS){throw"can only create "+PConstants.MAX_LIGHTS+" lights"}var pos=new PVector(x,y,z);var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.mult(pos,pos);curContext.useProgram(programObject3D);uniformf("lights.color.3d."+lightCount,programObject3D,"lights["+lightCount+"].color",[r/255,g/255,b/255]);uniformf("lights.position.3d."+lightCount,programObject3D,"lights["+lightCount+"].position",pos.array());uniformi("lights.type.3d."+lightCount,programObject3D,"lights["+lightCount+"].type",2);uniformi("lightCount3d",programObject3D,"lightCount",++lightCount)}};p.noLights=function noLights(){if(p.use3DContext){lightCount=0;curContext.useProgram(programObject3D);uniformi("lightCount3d",programObject3D,"lightCount",lightCount)}};p.spotLight=function spotLight(r,g,b,x,y,z,nx,ny,nz,angle,concentration){if(p.use3DContext){if(lightCount===PConstants.MAX_LIGHTS){throw"can only create "+PConstants.MAX_LIGHTS+" lights"}curContext.useProgram(programObject3D);var pos=new PVector(x,y,z);var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.mult(pos,pos);var dir=[nx,ny,nz,1e-7];view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.mult(dir,dir);uniformf("lights.color.3d."+lightCount,programObject3D,"lights["+lightCount+"].color",[r/255,g/255,b/255]);uniformf("lights.position.3d."+lightCount,programObject3D,"lights["+lightCount+"].position",pos.array());uniformf("lights.direction.3d."+lightCount,programObject3D,"lights["+lightCount+"].direction",[dir[0],dir[1],dir[2]]);uniformf("lights.concentration.3d."+lightCount,programObject3D,"lights["+lightCount+"].concentration",concentration);uniformf("lights.angle.3d."+lightCount,programObject3D,"lights["+lightCount+"].angle",angle);uniformi("lights.type.3d."+lightCount,programObject3D,"lights["+lightCount+"].type",3);uniformi("lightCount3d",programObject3D,"lightCount",++lightCount)}};p.beginCamera=function beginCamera(){if(manipulatingCamera){throw ("You cannot call beginCamera() again before calling endCamera()")}else{manipulatingCamera=true;forwardTransform=cameraInv;reverseTransform=cam}};p.endCamera=function endCamera(){if(!manipulatingCamera){throw ("You cannot call endCamera() before calling beginCamera()")}else{modelView.set(cam);modelViewInv.set(cameraInv);forwardTransform=modelView;reverseTransform=modelViewInv;manipulatingCamera=false}};p.camera=function camera(eyeX,eyeY,eyeZ,centerX,centerY,centerZ,upX,upY,upZ){if(arguments.length===0){cameraX=curElement.width/2;cameraY=curElement.height/2;cameraZ=cameraY/Math.tan(cameraFOV/2);eyeX=cameraX;eyeY=cameraY;eyeZ=cameraZ;centerX=cameraX;centerY=cameraY;centerZ=0;upX=0;upY=1;upZ=0}var z=new PVector(eyeX-centerX,eyeY-centerY,eyeZ-centerZ);var y=new PVector(upX,upY,upZ);var transX,transY,transZ;z.normalize();var x=PVector.cross(y,z);y=PVector.cross(z,x);x.normalize();y.normalize();cam.set(x.x,x.y,x.z,0,y.x,y.y,y.z,0,z.x,z.y,z.z,0,0,0,0,1);cam.translate(-eyeX,-eyeY,-eyeZ);cameraInv.reset();cameraInv.invApply(x.x,x.y,x.z,0,y.x,y.y,y.z,0,z.x,z.y,z.z,0,0,0,0,1);cameraInv.translate(eyeX,eyeY,eyeZ);modelView.set(cam);modelViewInv.set(cameraInv)};p.perspective=function perspective(fov,aspect,near,far){if(arguments.length===0){cameraY=curElement.height/2;cameraZ=cameraY/Math.tan(cameraFOV/2);cameraNear=cameraZ/10;cameraFar=cameraZ*10;cameraAspect=curElement.width/curElement.height;fov=cameraFOV;aspect=cameraAspect;near=cameraNear;far=cameraFar}var yMax,yMin,xMax,xMin;yMax=near*Math.tan(fov/2);yMin=-yMax;xMax=yMax*aspect;xMin=yMin*aspect;p.frustum(xMin,xMax,yMin,yMax,near,far)};p.frustum=function frustum(left,right,bottom,top,near,far){frustumMode=true;projection=new PMatrix3D();projection.set((2*near)/(right-left),0,(right+left)/(right-left),0,0,(2*near)/(top-bottom),(top+bottom)/(top-bottom),0,0,0,-(far+near)/(far-near),-(2*far*near)/(far-near),0,0,-1,0)};p.ortho=function ortho(left,right,bottom,top,near,far){if(arguments.length===0){left=0;right=p.width;bottom=0;top=p.height;near=-10;far=10}var x=2/(right-left);var y=2/(top-bottom);var z=-2/(far-near);var tx=-(right+left)/(right-left);var ty=-(top+bottom)/(top-bottom);var tz=-(far+near)/(far-near);projection=new PMatrix3D();projection.set(x,0,0,tx,0,y,0,ty,0,0,z,tz,0,0,0,1);frustumMode=false};p.printProjection=function(){projection.print()};p.printCamera=function(){cam.print()};p.box=function(w,h,d){if(p.use3DContext){if(!h||!d){h=d=w}var model=new PMatrix3D();model.scale(w,h,d);var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.transpose();var proj=new PMatrix3D();proj.set(projection);proj.transpose();if(doFill===true){curContext.useProgram(programObject3D);disableVertexAttribPointer("aTexture3d",programObject3D,"aTexture");uniformMatrix("model3d",programObject3D,"model",false,model.array());uniformMatrix("view3d",programObject3D,"view",false,view.array());uniformMatrix("projection3d",programObject3D,"projection",false,proj.array());curContext.enable(curContext.POLYGON_OFFSET_FILL);curContext.polygonOffset(1,1);uniformf("color3d",programObject3D,"color",fillStyle);var v=new PMatrix3D();v.set(view);var m=new PMatrix3D();m.set(model);v.mult(m);var normalMatrix=new PMatrix3D();normalMatrix.set(v);normalMatrix.invert();normalMatrix.transpose();uniformMatrix("normalTransform3d",programObject3D,"normalTransform",false,normalMatrix.array());vertexAttribPointer("vertex3d",programObject3D,"Vertex",3,boxBuffer);vertexAttribPointer("normal3d",programObject3D,"Normal",3,boxNormBuffer);vertexAttribPointer("aColor3d",programObject3D,"aColor",3,boxNormBuffer);curContext.drawArrays(curContext.TRIANGLES,0,boxVerts.length/3);curContext.disable(curContext.POLYGON_OFFSET_FILL)}if(lineWidth>0&&doStroke){curContext.useProgram(programObject2D);uniformMatrix("model2d",programObject2D,"model",false,model.array());uniformMatrix("view2d",programObject2D,"view",false,view.array());uniformMatrix("projection2d",programObject2D,"projection",false,proj.array());uniformf("color2d",programObject2D,"color",strokeStyle);uniformi("picktype2d",programObject2D,"picktype",0);vertexAttribPointer("vertex2d",programObject2D,"Vertex",3,boxOutlineBuffer);disableVertexAttribPointer("aTextureCoord2d",programObject2D,"aTextureCoord");curContext.lineWidth(lineWidth);curContext.drawArrays(curContext.LINES,0,boxOutlineVerts.length/3)}}};var initSphere=function(){var i;sphereVerts=[];for(i=0;i<sphereDetailU;i++){sphereVerts.push(0);sphereVerts.push(-1);sphereVerts.push(0);sphereVerts.push(sphereX[i]);sphereVerts.push(sphereY[i]);sphereVerts.push(sphereZ[i])}sphereVerts.push(0);sphereVerts.push(-1);sphereVerts.push(0);sphereVerts.push(sphereX[0]);sphereVerts.push(sphereY[0]);sphereVerts.push(sphereZ[0]);var v1,v11,v2;var voff=0;for(i=2;i<sphereDetailV;i++){v1=v11=voff;voff+=sphereDetailU;v2=voff;for(var j=0;j<sphereDetailU;j++){sphereVerts.push(parseFloat(sphereX[v1]));sphereVerts.push(parseFloat(sphereY[v1]));sphereVerts.push(parseFloat(sphereZ[v1++]));sphereVerts.push(parseFloat(sphereX[v2]));sphereVerts.push(parseFloat(sphereY[v2]));sphereVerts.push(parseFloat(sphereZ[v2++]))}v1=v11;v2=voff;sphereVerts.push(parseFloat(sphereX[v1]));sphereVerts.push(parseFloat(sphereY[v1]));sphereVerts.push(parseFloat(sphereZ[v1]));sphereVerts.push(parseFloat(sphereX[v2]));sphereVerts.push(parseFloat(sphereY[v2]));sphereVerts.push(parseFloat(sphereZ[v2]))}for(i=0;i<sphereDetailU;i++){v2=voff+i;sphereVerts.push(parseFloat(sphereX[v2]));sphereVerts.push(parseFloat(sphereY[v2]));sphereVerts.push(parseFloat(sphereZ[v2]));sphereVerts.push(0);sphereVerts.push(1);sphereVerts.push(0)}sphereVerts.push(parseFloat(sphereX[voff]));sphereVerts.push(parseFloat(sphereY[voff]));sphereVerts.push(parseFloat(sphereZ[voff]));sphereVerts.push(0);sphereVerts.push(1);sphereVerts.push(0);curContext.bindBuffer(curContext.ARRAY_BUFFER,sphereBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,new Float32Array(sphereVerts),curContext.STATIC_DRAW)};p.sphereDetail=function sphereDetail(ures,vres){var i;if(arguments.length===1){ures=vres=arguments[0]}if(ures<3){ures=3}if(vres<2){vres=2}if((ures===sphereDetailU)&&(vres===sphereDetailV)){return}var delta=PConstants.SINCOS_LENGTH/ures;var cx=new Array(ures);var cz=new Array(ures);for(i=0;i<ures;i++){cx[i]=cosLUT[parseInt((i*delta)%PConstants.SINCOS_LENGTH,10)];cz[i]=sinLUT[parseInt((i*delta)%PConstants.SINCOS_LENGTH,10)]}var vertCount=ures*(vres-1)+2;var currVert=0;sphereX=new Array(vertCount);sphereY=new Array(vertCount);sphereZ=new Array(vertCount);var angle_step=(PConstants.SINCOS_LENGTH*0.5)/vres;var angle=angle_step;for(i=1;i<vres;i++){var curradius=sinLUT[parseInt(angle%PConstants.SINCOS_LENGTH,10)];var currY=-cosLUT[parseInt(angle%PConstants.SINCOS_LENGTH,10)];for(var j=0;j<ures;j++){sphereX[currVert]=cx[j]*curradius;sphereY[currVert]=currY;sphereZ[currVert++]=cz[j]*curradius}angle+=angle_step}sphereDetailU=ures;sphereDetailV=vres;initSphere()};p.sphere=function(){if(p.use3DContext){var sRad=arguments[0],c;if((sphereDetailU<3)||(sphereDetailV<2)){p.sphereDetail(30)}var model=new PMatrix3D();model.scale(sRad,sRad,sRad);var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.transpose();var proj=new PMatrix3D();proj.set(projection);proj.transpose();if(doFill===true){var v=new PMatrix3D();v.set(view);var m=new PMatrix3D();m.set(model);v.mult(m);var normalMatrix=new PMatrix3D();normalMatrix.set(v);normalMatrix.invert();normalMatrix.transpose();curContext.useProgram(programObject3D);disableVertexAttribPointer("aTexture3d",programObject3D,"aTexture");uniformMatrix("model3d",programObject3D,"model",false,model.array());uniformMatrix("view3d",programObject3D,"view",false,view.array());uniformMatrix("projection3d",programObject3D,"projection",false,proj.array());uniformMatrix("normalTransform3d",programObject3D,"normalTransform",false,normalMatrix.array());vertexAttribPointer("vertex3d",programObject3D,"Vertex",3,sphereBuffer);vertexAttribPointer("normal3d",programObject3D,"Normal",3,sphereBuffer);vertexAttribPointer("aColor3d",programObject3D,"aColor",3,sphereBuffer);curContext.enable(curContext.POLYGON_OFFSET_FILL);curContext.polygonOffset(1,1);uniformf("color3d",programObject3D,"color",fillStyle);curContext.drawArrays(curContext.TRIANGLE_STRIP,0,sphereVerts.length/3);curContext.disable(curContext.POLYGON_OFFSET_FILL)}if(lineWidth>0&&doStroke){curContext.useProgram(programObject2D);uniformMatrix("model2d",programObject2D,"model",false,model.array());uniformMatrix("view2d",programObject2D,"view",false,view.array());uniformMatrix("projection2d",programObject2D,"projection",false,proj.array());vertexAttribPointer("vertex2d",programObject2D,"Vertex",3,sphereBuffer);disableVertexAttribPointer("aTextureCoord2d",programObject2D,"aTextureCoord");uniformf("color2d",programObject2D,"color",strokeStyle);uniformi("picktype2d",programObject2D,"picktype",0);curContext.lineWidth(lineWidth);curContext.drawArrays(curContext.LINE_STRIP,0,sphereVerts.length/3)}}};p.modelX=function modelX(x,y,z){var mv=modelView.array();var ci=cameraInv.array();var ax=mv[0]*x+mv[1]*y+mv[2]*z+mv[3];var ay=mv[4]*x+mv[5]*y+mv[6]*z+mv[7];var az=mv[8]*x+mv[9]*y+mv[10]*z+mv[11];var aw=mv[12]*x+mv[13]*y+mv[14]*z+mv[15];var ox=ci[0]*ax+ci[1]*ay+ci[2]*az+ci[3]*aw;var ow=ci[12]*ax+ci[13]*ay+ci[14]*az+ci[15]*aw;return(ow!==0)?ox/ow:ox};p.modelY=function modelY(x,y,z){var mv=modelView.array();var ci=cameraInv.array();var ax=mv[0]*x+mv[1]*y+mv[2]*z+mv[3];var ay=mv[4]*x+mv[5]*y+mv[6]*z+mv[7];var az=mv[8]*x+mv[9]*y+mv[10]*z+mv[11];var aw=mv[12]*x+mv[13]*y+mv[14]*z+mv[15];var oy=ci[4]*ax+ci[5]*ay+ci[6]*az+ci[7]*aw;var ow=ci[12]*ax+ci[13]*ay+ci[14]*az+ci[15]*aw;return(ow!==0)?oy/ow:oy};p.modelZ=function modelZ(x,y,z){var mv=modelView.array();var ci=cameraInv.array();var ax=mv[0]*x+mv[1]*y+mv[2]*z+mv[3];var ay=mv[4]*x+mv[5]*y+mv[6]*z+mv[7];var az=mv[8]*x+mv[9]*y+mv[10]*z+mv[11];var aw=mv[12]*x+mv[13]*y+mv[14]*z+mv[15];var oz=ci[8]*ax+ci[9]*ay+ci[10]*az+ci[11]*aw;var ow=ci[12]*ax+ci[13]*ay+ci[14]*az+ci[15]*aw;return(ow!==0)?oz/ow:oz};p.ambient=function ambient(){var a=arguments;if(p.use3DContext){curContext.useProgram(programObject3D);uniformi("usingMat3d",programObject3D,"usingMat",true);if(a.length===1){if(typeof a[0]==="string"){var c=a[0].slice(5,-1).split(",");uniformf("mat_ambient3d",programObject3D,"mat_ambient",[c[0]/255,c[1]/255,c[2]/255])}else{uniformf("mat_ambient3d",programObject3D,"mat_ambient",[a[0]/255,a[0]/255,a[0]/255])}}else{uniformf("mat_ambient3d",programObject3D,"mat_ambient",[a[0]/255,a[1]/255,a[2]/255])}}};p.emissive=function emissive(){var a=arguments;if(p.use3DContext){curContext.useProgram(programObject3D);uniformi("usingMat3d",programObject3D,"usingMat",true);if(a.length===1){if(typeof a[0]==="string"){var c=a[0].slice(5,-1).split(",");uniformf("mat_emissive3d",programObject3D,"mat_emissive",[c[0]/255,c[1]/255,c[2]/255])}else{uniformf("mat_emissive3d",programObject3D,"mat_emissive",[a[0]/255,a[0]/255,a[0]/255])}}else{uniformf("mat_emissive3d",programObject3D,"mat_emissive",[a[0]/255,a[1]/255,a[2]/255])}}};p.shininess=function shininess(shine){if(p.use3DContext){curContext.useProgram(programObject3D);uniformi("usingMat3d",programObject3D,"usingMat",true);uniformf("shininess3d",programObject3D,"shininess",shine)}};p.specular=function specular(){var c=p.color.apply(this,arguments);if(p.use3DContext){curContext.useProgram(programObject3D);uniformi("usingMat3d",programObject3D,"usingMat",true);uniformf("mat_specular3d",programObject3D,"mat_specular",p.color.toGLArray(c).slice(0,3))}};p.screenX=function screenX(x,y,z){var mv=modelView.array();var pj=projection.array();var ax=mv[0]*x+mv[1]*y+mv[2]*z+mv[3];var ay=mv[4]*x+mv[5]*y+mv[6]*z+mv[7];var az=mv[8]*x+mv[9]*y+mv[10]*z+mv[11];var aw=mv[12]*x+mv[13]*y+mv[14]*z+mv[15];var ox=pj[0]*ax+pj[1]*ay+pj[2]*az+pj[3]*aw;var ow=pj[12]*ax+pj[13]*ay+pj[14]*az+pj[15]*aw;if(ow!==0){ox/=ow}return p.width*(1+ox)/2};p.screenY=function screenY(x,y,z){var mv=modelView.array();var pj=projection.array();var ax=mv[0]*x+mv[1]*y+mv[2]*z+mv[3];var ay=mv[4]*x+mv[5]*y+mv[6]*z+mv[7];var az=mv[8]*x+mv[9]*y+mv[10]*z+mv[11];var aw=mv[12]*x+mv[13]*y+mv[14]*z+mv[15];var oy=pj[4]*ax+pj[5]*ay+pj[6]*az+pj[7]*aw;var ow=pj[12]*ax+pj[13]*ay+pj[14]*az+pj[15]*aw;if(ow!==0){oy/=ow}return p.height*(1+oy)/2};p.screenZ=function screenZ(x,y,z){var mv=modelView.array();var pj=projection.array();var ax=mv[0]*x+mv[1]*y+mv[2]*z+mv[3];var ay=mv[4]*x+mv[5]*y+mv[6]*z+mv[7];var az=mv[8]*x+mv[9]*y+mv[10]*z+mv[11];var aw=mv[12]*x+mv[13]*y+mv[14]*z+mv[15];var oz=pj[8]*ax+pj[9]*ay+pj[10]*az+pj[11]*aw;var ow=pj[12]*ax+pj[13]*ay+pj[14]*az+pj[15]*aw;if(ow!==0){oz/=ow}return(oz+1)/2};p.fill=function fill(){var color=p.color(arguments[0],arguments[1],arguments[2],arguments[3]);if(color===currentFillColor&&doFill){return}doFill=true;currentFillColor=color;if(p.use3DContext){fillStyle=p.color.toGLArray(color)}else{isFillDirty=true}};function executeContextFill(){if(doFill){if(isFillDirty){curContext.fillStyle=p.color.toString(currentFillColor);isFillDirty=false}curContext.fill()}}p.noFill=function noFill(){doFill=false};p.stroke=function stroke(){var color=p.color(arguments[0],arguments[1],arguments[2],arguments[3]);if(color===currentStrokeColor&&doStroke){return}doStroke=true;currentStrokeColor=color;if(p.use3DContext){strokeStyle=p.color.toGLArray(color)}else{isStrokeDirty=true}};function executeContextStroke(){if(doStroke){if(isStrokeDirty){curContext.strokeStyle=p.color.toString(currentStrokeColor);isStrokeDirty=false}curContext.stroke()}}p.noStroke=function noStroke(){doStroke=false};p.strokeWeight=function strokeWeight(w){lineWidth=w;if(p.use3DContext){curContext.useProgram(programObject2D);uniformf("pointSize2d",programObject2D,"pointSize",w)}else{curContext.lineWidth=w}};p.strokeCap=function strokeCap(value){curContext.lineCap=value};p.strokeJoin=function strokeJoin(value){curContext.lineJoin=value};p.smooth=function(){curElement.style.setProperty("image-rendering","optimizeQuality","important");if(!p.use3DContext&&"mozImageSmoothingEnabled" in curContext){curContext.mozImageSmoothingEnabled=true}};p.noSmooth=function(){curElement.style.setProperty("image-rendering","optimizeSpeed","important");if(!p.use3DContext&&"mozImageSmoothingEnabled" in curContext){curContext.mozImageSmoothingEnabled=false}};function colorBlendWithAlpha(c1,c2,k){var f=0|(k*((c2&PConstants.ALPHA_MASK)>>>24));return(Math.min(((c1&PConstants.ALPHA_MASK)>>>24)+f,255)<<24|p.mix(c1&PConstants.RED_MASK,c2&PConstants.RED_MASK,f)&PConstants.RED_MASK|p.mix(c1&PConstants.GREEN_MASK,c2&PConstants.GREEN_MASK,f)&PConstants.GREEN_MASK|p.mix(c1&PConstants.BLUE_MASK,c2&PConstants.BLUE_MASK,f))}p.point=function point(x,y,z){if(p.use3DContext){var model=new PMatrix3D();model.translate(x,y,z||0);model.transpose();var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.transpose();var proj=new PMatrix3D();proj.set(projection);proj.transpose();curContext.useProgram(programObject2D);uniformMatrix("model2d",programObject2D,"model",false,model.array());uniformMatrix("view2d",programObject2D,"view",false,view.array());uniformMatrix("projection2d",programObject2D,"projection",false,proj.array());if(lineWidth>0&&doStroke){uniformf("color2d",programObject2D,"color",strokeStyle);uniformi("picktype2d",programObject2D,"picktype",0);vertexAttribPointer("vertex2d",programObject2D,"Vertex",3,pointBuffer);disableVertexAttribPointer("aTextureCoord2d",programObject2D,"aTextureCoord");curContext.drawArrays(curContext.POINTS,0,1)}}else{if(doStroke){if(curSketch.options.crispLines){var alphaOfPointWeight=Math.PI/4;var c=p.get(x,y);p.set(x,y,colorBlendWithAlpha(c,currentStrokeColor,alphaOfPointWeight))}else{if(lineWidth>1){curContext.fillStyle=p.color.toString(currentStrokeColor);isFillDirty=true;curContext.beginPath();curContext.arc(x,y,lineWidth/2,0,PConstants.TWO_PI,false);curContext.fill();curContext.closePath()}else{curContext.fillStyle=p.color.toString(currentStrokeColor);curContext.fillRect(Math.round(x),Math.round(y),1,1);isFillDirty=true}}}}};p.beginShape=function beginShape(type){curShape=type;curvePoints=[];vertArray=[]};p.vertex=function vertex(){var vert=[];if(firstVert){firstVert=false}if(arguments.length===4){vert[0]=arguments[0];vert[1]=arguments[1];vert[2]=0;vert[3]=arguments[2];vert[4]=arguments[3]}else{vert[0]=arguments[0];vert[1]=arguments[1];vert[2]=arguments[2]||0;vert[3]=arguments[3]||0;vert[4]=arguments[4]||0}vert.isVert=true;if(p.use3DContext){vert[5]=fillStyle[0];vert[6]=fillStyle[1];vert[7]=fillStyle[2];vert[8]=fillStyle[3];vert[9]=strokeStyle[0];vert[10]=strokeStyle[1];vert[11]=strokeStyle[2];vert[12]=strokeStyle[3];vert[13]=normalX;vert[14]=normalY;vert[15]=normalZ}else{vert[5]=currentFillColor;vert[6]=currentStrokeColor}vertArray.push(vert)};var point3D=function point3D(vArray,cArray){var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.transpose();var proj=new PMatrix3D();proj.set(projection);proj.transpose();curContext.useProgram(programObjectUnlitShape);uniformMatrix("uViewUS",programObjectUnlitShape,"uView",false,view.array());uniformMatrix("uProjectionUS",programObjectUnlitShape,"uProjection",false,proj.array());vertexAttribPointer("aVertexUS",programObjectUnlitShape,"aVertex",3,pointBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,new Float32Array(vArray),curContext.STREAM_DRAW);vertexAttribPointer("aColorUS",programObjectUnlitShape,"aColor",4,fillColorBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,new Float32Array(cArray),curContext.STREAM_DRAW);curContext.drawArrays(curContext.POINTS,0,vArray.length/3)};var line3D=function line3D(vArray,mode,cArray){var ctxMode;if(mode==="LINES"){ctxMode=curContext.LINES}else{if(mode==="LINE_LOOP"){ctxMode=curContext.LINE_LOOP}else{ctxMode=curContext.LINE_STRIP}}var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.transpose();var proj=new PMatrix3D();proj.set(projection);proj.transpose();curContext.useProgram(programObjectUnlitShape);uniformMatrix("uViewUS",programObjectUnlitShape,"uView",false,view.array());uniformMatrix("uProjectionUS",programObjectUnlitShape,"uProjection",false,proj.array());vertexAttribPointer("aVertexUS",programObjectUnlitShape,"aVertex",3,lineBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,new Float32Array(vArray),curContext.STREAM_DRAW);vertexAttribPointer("aColorUS",programObjectUnlitShape,"aColor",4,strokeColorBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,new Float32Array(cArray),curContext.STREAM_DRAW);curContext.lineWidth(lineWidth);curContext.drawArrays(ctxMode,0,vArray.length/3)};var fill3D=function fill3D(vArray,mode,cArray,tArray){var ctxMode;if(mode==="TRIANGLES"){ctxMode=curContext.TRIANGLES}else{if(mode==="TRIANGLE_FAN"){ctxMode=curContext.TRIANGLE_FAN}else{ctxMode=curContext.TRIANGLE_STRIP}}var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.transpose();var proj=new PMatrix3D();proj.set(projection);proj.transpose();curContext.useProgram(programObject3D);uniformMatrix("model3d",programObject3D,"model",false,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);uniformMatrix("view3d",programObject3D,"view",false,view.array());uniformMatrix("projection3d",programObject3D,"projection",false,proj.array());curContext.enable(curContext.POLYGON_OFFSET_FILL);curContext.polygonOffset(1,1);uniformf("color3d",programObject3D,"color",[-1,0,0,0]);vertexAttribPointer("vertex3d",programObject3D,"Vertex",3,fillBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,new Float32Array(vArray),curContext.STREAM_DRAW);vertexAttribPointer("aColor3d",programObject3D,"aColor",4,fillColorBuffer);curContext.bufferData(curContext.ARRAY_BUFFER,new Float32Array(cArray),curContext.STREAM_DRAW);disableVertexAttribPointer("normal3d",programObject3D,"Normal");var i;if(usingTexture){if(curTextureMode===PConstants.IMAGE){for(i=0;i<tArray.length;i+=2){tArray[i]=tArray[i]/curTexture.width;tArray[i+1]/=curTexture.height}}for(i=0;i<tArray.length;i+=2){if(tArray[i+0]>1){tArray[i+0]-=(tArray[i+0]-1)}if(tArray[i+1]>1){tArray[i+1]-=(tArray[i+1]-1)}}uniformi("usingTexture3d",programObject3D,"usingTexture",usingTexture);vertexAttribPointer("aTexture3d",programObject3D,"aTexture",2,shapeTexVBO);curContext.bufferData(curContext.ARRAY_BUFFER,new Float32Array(tArray),curContext.STREAM_DRAW)}curContext.drawArrays(ctxMode,0,vArray.length/3);curContext.disable(curContext.POLYGON_OFFSET_FILL)};p.endShape=function endShape(mode){var closeShape=mode===PConstants.CLOSE;var lineVertArray=[];var fillVertArray=[];var colorVertArray=[];var strokeVertArray=[];var texVertArray=[];firstVert=true;var i,j,k;var last=vertArray.length-1;for(i=0;i<vertArray.length;i++){for(j=0;j<3;j++){fillVertArray.push(vertArray[i][j])}}for(i=0;i<vertArray.length;i++){for(j=5;j<9;j++){colorVertArray.push(vertArray[i][j])}}for(i=0;i<vertArray.length;i++){for(j=9;j<13;j++){strokeVertArray.push(vertArray[i][j])}}for(i=0;i<vertArray.length;i++){texVertArray.push(vertArray[i][3]);texVertArray.push(vertArray[i][4])}if(closeShape){fillVertArray.push(vertArray[0][0]);fillVertArray.push(vertArray[0][1]);fillVertArray.push(vertArray[0][2]);for(i=5;i<9;i++){colorVertArray.push(vertArray[0][i])}for(i=9;i<13;i++){strokeVertArray.push(vertArray[0][i])}texVertArray.push(vertArray[0][3]);texVertArray.push(vertArray[0][4])}if(isCurve&&curShape===PConstants.POLYGON||isCurve&&curShape===undef){if(p.use3DContext){lineVertArray=fillVertArray;if(doStroke){line3D(lineVertArray,null,strokeVertArray)}if(doFill){fill3D(fillVertArray,null,colorVertArray)}}else{if(vertArray.length>3){var b=[],s=1-curTightness;curContext.beginPath();curContext.moveTo(vertArray[1][0],vertArray[1][1]);for(i=1;(i+2)<vertArray.length;i++){b[0]=[vertArray[i][0],vertArray[i][1]];b[1]=[vertArray[i][0]+(s*vertArray[i+1][0]-s*vertArray[i-1][0])/6,vertArray[i][1]+(s*vertArray[i+1][1]-s*vertArray[i-1][1])/6];b[2]=[vertArray[i+1][0]+(s*vertArray[i][0]-s*vertArray[i+2][0])/6,vertArray[i+1][1]+(s*vertArray[i][1]-s*vertArray[i+2][1])/6];b[3]=[vertArray[i+1][0],vertArray[i+1][1]];curContext.bezierCurveTo(b[1][0],b[1][1],b[2][0],b[2][1],b[3][0],b[3][1])}if(closeShape){curContext.lineTo(vertArray[0][0],vertArray[0][1])}executeContextFill();executeContextStroke();curContext.closePath()}}}else{if(isBezier&&curShape===PConstants.POLYGON||isBezier&&curShape===undef){if(p.use3DContext){lineVertArray=fillVertArray;lineVertArray.splice(lineVertArray.length-3);strokeVertArray.splice(strokeVertArray.length-4);if(doStroke){line3D(lineVertArray,null,strokeVertArray)}if(doFill){fill3D(fillVertArray,"TRIANGLES",colorVertArray)}}else{curContext.beginPath();for(i=0;i<vertArray.length;i++){if(vertArray[i]["isVert"]===true){if(vertArray[i]["moveTo"]===true){curContext.moveTo(vertArray[i][0],vertArray[i][1])}else{if(vertArray[i]["moveTo"]===false){curContext.lineTo(vertArray[i][0],vertArray[i][1])}else{curContext.moveTo(vertArray[i][0],vertArray[i][1])}}}else{curContext.bezierCurveTo(vertArray[i][0],vertArray[i][1],vertArray[i][2],vertArray[i][3],vertArray[i][4],vertArray[i][5])}}if(closeShape){curContext.lineTo(vertArray[0][0],vertArray[0][1])}executeContextFill();executeContextStroke();curContext.closePath()}}else{if(p.use3DContext){if(curShape===PConstants.POINTS){for(i=0;i<vertArray.length;i++){for(j=0;j<3;j++){lineVertArray.push(vertArray[i][j])}}point3D(lineVertArray,strokeVertArray)}else{if(curShape===PConstants.LINES){for(i=0;i<vertArray.length;i++){for(j=0;j<3;j++){lineVertArray.push(vertArray[i][j])}}for(i=0;i<vertArray.length;i++){for(j=5;j<9;j++){colorVertArray.push(vertArray[i][j])}}line3D(lineVertArray,"LINES",strokeVertArray)}else{if(curShape===PConstants.TRIANGLES){if(vertArray.length>2){for(i=0;(i+2)<vertArray.length;i+=3){fillVertArray=[];texVertArray=[];lineVertArray=[];colorVertArray=[];strokeVertArray=[];for(j=0;j<3;j++){for(k=0;k<3;k++){lineVertArray.push(vertArray[i+j][k]);fillVertArray.push(vertArray[i+j][k])}}for(j=0;j<3;j++){for(k=3;k<5;k++){texVertArray.push(vertArray[i+j][k])}}for(j=0;j<3;j++){for(k=5;k<9;k++){colorVertArray.push(vertArray[i+j][k]);strokeVertArray.push(vertArray[i+j][k+4])}}if(doStroke){line3D(lineVertArray,"LINE_LOOP",strokeVertArray)}if(doFill||usingTexture){fill3D(fillVertArray,"TRIANGLES",colorVertArray,texVertArray)}}}}else{if(curShape===PConstants.TRIANGLE_STRIP){if(vertArray.length>2){for(i=0;(i+2)<vertArray.length;i++){lineVertArray=[];fillVertArray=[];strokeVertArray=[];colorVertArray=[];texVertArray=[];for(j=0;j<3;j++){for(k=0;k<3;k++){lineVertArray.push(vertArray[i+j][k]);fillVertArray.push(vertArray[i+j][k])}}for(j=0;j<3;j++){for(k=3;k<5;k++){texVertArray.push(vertArray[i+j][k])}}for(j=0;j<3;j++){for(k=5;k<9;k++){strokeVertArray.push(vertArray[i+j][k+4]);colorVertArray.push(vertArray[i+j][k])}}if(doFill||usingTexture){fill3D(fillVertArray,"TRIANGLE_STRIP",colorVertArray,texVertArray)}if(doStroke){line3D(lineVertArray,"LINE_LOOP",strokeVertArray)}}}}else{if(curShape===PConstants.TRIANGLE_FAN){if(vertArray.length>2){for(i=0;i<3;i++){for(j=0;j<3;j++){lineVertArray.push(vertArray[i][j])}}for(i=0;i<3;i++){for(j=9;j<13;j++){strokeVertArray.push(vertArray[i][j])}}if(doStroke){line3D(lineVertArray,"LINE_LOOP",strokeVertArray)}for(i=2;(i+1)<vertArray.length;i++){lineVertArray=[];strokeVertArray=[];lineVertArray.push(vertArray[0][0]);lineVertArray.push(vertArray[0][1]);lineVertArray.push(vertArray[0][2]);strokeVertArray.push(vertArray[0][9]);strokeVertArray.push(vertArray[0][10]);strokeVertArray.push(vertArray[0][11]);strokeVertArray.push(vertArray[0][12]);for(j=0;j<2;j++){for(k=0;k<3;k++){lineVertArray.push(vertArray[i+j][k])}}for(j=0;j<2;j++){for(k=9;k<13;k++){strokeVertArray.push(vertArray[i+j][k])}}if(doStroke){line3D(lineVertArray,"LINE_STRIP",strokeVertArray)}}if(doFill||usingTexture){fill3D(fillVertArray,"TRIANGLE_FAN",colorVertArray,texVertArray)}}}else{if(curShape===PConstants.QUADS){for(i=0;(i+3)<vertArray.length;i+=4){lineVertArray=[];for(j=0;j<4;j++){for(k=0;k<3;k++){lineVertArray.push(vertArray[i+j][k])}}if(doStroke){line3D(lineVertArray,"LINE_LOOP",strokeVertArray)}if(doFill){fillVertArray=[];colorVertArray=[];texVertArray=[];for(j=0;j<3;j++){fillVertArray.push(vertArray[i][j])}for(j=5;j<9;j++){colorVertArray.push(vertArray[i][j])}for(j=0;j<3;j++){fillVertArray.push(vertArray[i+1][j])}for(j=5;j<9;j++){colorVertArray.push(vertArray[i+1][j])}for(j=0;j<3;j++){fillVertArray.push(vertArray[i+3][j])}for(j=5;j<9;j++){colorVertArray.push(vertArray[i+3][j])}for(j=0;j<3;j++){fillVertArray.push(vertArray[i+2][j])}for(j=5;j<9;j++){colorVertArray.push(vertArray[i+2][j])}if(usingTexture){texVertArray.push(vertArray[i+0][3]);texVertArray.push(vertArray[i+0][4]);texVertArray.push(vertArray[i+1][3]);texVertArray.push(vertArray[i+1][4]);texVertArray.push(vertArray[i+3][3]);texVertArray.push(vertArray[i+3][4]);texVertArray.push(vertArray[i+2][3]);texVertArray.push(vertArray[i+2][4])}fill3D(fillVertArray,"TRIANGLE_STRIP",colorVertArray,texVertArray)}}}else{if(curShape===PConstants.QUAD_STRIP){var tempArray=[];if(vertArray.length>3){for(i=0;i<2;i++){for(j=0;j<3;j++){lineVertArray.push(vertArray[i][j])}}for(i=0;i<2;i++){for(j=9;j<13;j++){strokeVertArray.push(vertArray[i][j])}}line3D(lineVertArray,"LINE_STRIP",strokeVertArray);if(vertArray.length>4&&vertArray.length%2>0){tempArray=fillVertArray.splice(fillVertArray.length-3);vertArray.pop()}for(i=0;(i+3)<vertArray.length;i+=2){lineVertArray=[];strokeVertArray=[];for(j=0;j<3;j++){lineVertArray.push(vertArray[i+1][j])}for(j=0;j<3;j++){lineVertArray.push(vertArray[i+3][j])}for(j=0;j<3;j++){lineVertArray.push(vertArray[i+2][j])}for(j=0;j<3;j++){lineVertArray.push(vertArray[i+0][j])}for(j=9;j<13;j++){strokeVertArray.push(vertArray[i+1][j])}for(j=9;j<13;j++){strokeVertArray.push(vertArray[i+3][j])}for(j=9;j<13;j++){strokeVertArray.push(vertArray[i+2][j])}for(j=9;j<13;j++){strokeVertArray.push(vertArray[i+0][j])}if(doStroke){line3D(lineVertArray,"LINE_STRIP",strokeVertArray)}}if(doFill||usingTexture){fill3D(fillVertArray,"TRIANGLE_LIST",colorVertArray,texVertArray)}}}else{if(vertArray.length===1){for(j=0;j<3;j++){lineVertArray.push(vertArray[0][j])}for(j=9;j<13;j++){strokeVertArray.push(vertArray[0][j])}point3D(lineVertArray,strokeVertArray)}else{for(i=0;i<vertArray.length;i++){for(j=0;j<3;j++){lineVertArray.push(vertArray[i][j])}for(j=5;j<9;j++){strokeVertArray.push(vertArray[i][j])}}if(closeShape){line3D(lineVertArray,"LINE_LOOP",strokeVertArray)}else{line3D(lineVertArray,"LINE_STRIP",strokeVertArray)}if(doFill||usingTexture){fill3D(fillVertArray,"TRIANGLE_FAN",colorVertArray,texVertArray)}}}}}}}}}usingTexture=false;curContext.useProgram(programObject3D);uniformi("usingTexture3d",programObject3D,"usingTexture",usingTexture)}else{if(curShape===PConstants.POINTS){for(i=0;i<vertArray.length;i++){if(doStroke){p.stroke(vertArray[i][6])}p.point(vertArray[i][0],vertArray[i][1])}}else{if(curShape===PConstants.LINES){for(i=0;(i+1)<vertArray.length;i+=2){if(doStroke){p.stroke(vertArray[i+1][6])}p.line(vertArray[i][0],vertArray[i][1],vertArray[i+1][0],vertArray[i+1][1])}}else{if(curShape===PConstants.TRIANGLES){for(i=0;(i+2)<vertArray.length;i+=3){curContext.beginPath();curContext.moveTo(vertArray[i][0],vertArray[i][1]);curContext.lineTo(vertArray[i+1][0],vertArray[i+1][1]);curContext.lineTo(vertArray[i+2][0],vertArray[i+2][1]);curContext.lineTo(vertArray[i][0],vertArray[i][1]);if(doFill){p.fill(vertArray[i+2][5]);executeContextFill()}if(doStroke){p.stroke(vertArray[i+2][6]);executeContextStroke()}curContext.closePath()}}else{if(curShape===PConstants.TRIANGLE_STRIP){for(i=0;(i+1)<vertArray.length;i++){curContext.beginPath();curContext.moveTo(vertArray[i+1][0],vertArray[i+1][1]);curContext.lineTo(vertArray[i][0],vertArray[i][1]);if(doStroke){p.stroke(vertArray[i+1][6])}if(doFill){p.fill(vertArray[i+1][5])}if(i+2<vertArray.length){curContext.lineTo(vertArray[i+2][0],vertArray[i+2][1]);if(doStroke){p.stroke(vertArray[i+2][6])}if(doFill){p.fill(vertArray[i+2][5])}}executeContextFill();executeContextStroke();curContext.closePath()}}else{if(curShape===PConstants.TRIANGLE_FAN){if(vertArray.length>2){curContext.beginPath();curContext.moveTo(vertArray[0][0],vertArray[0][1]);curContext.lineTo(vertArray[1][0],vertArray[1][1]);curContext.lineTo(vertArray[2][0],vertArray[2][1]);if(doFill){p.fill(vertArray[2][5]);executeContextFill()}if(doStroke){p.stroke(vertArray[2][6]);executeContextStroke()}curContext.closePath();for(i=3;i<vertArray.length;i++){curContext.beginPath();curContext.moveTo(vertArray[0][0],vertArray[0][1]);curContext.lineTo(vertArray[i-1][0],vertArray[i-1][1]);curContext.lineTo(vertArray[i][0],vertArray[i][1]);if(doFill){p.fill(vertArray[i][5]);executeContextFill()}if(doStroke){p.stroke(vertArray[i][6]);executeContextStroke()}curContext.closePath()}}}else{if(curShape===PConstants.QUADS){for(i=0;(i+3)<vertArray.length;i+=4){curContext.beginPath();curContext.moveTo(vertArray[i][0],vertArray[i][1]);for(j=1;j<4;j++){curContext.lineTo(vertArray[i+j][0],vertArray[i+j][1])}curContext.lineTo(vertArray[i][0],vertArray[i][1]);if(doFill){p.fill(vertArray[i+3][5]);executeContextFill()}if(doStroke){p.stroke(vertArray[i+3][6]);executeContextStroke()}curContext.closePath()}}else{if(curShape===PConstants.QUAD_STRIP){if(vertArray.length>3){for(i=0;(i+1)<vertArray.length;i+=2){curContext.beginPath();if(i+3<vertArray.length){curContext.moveTo(vertArray[i+2][0],vertArray[i+2][1]);curContext.lineTo(vertArray[i][0],vertArray[i][1]);curContext.lineTo(vertArray[i+1][0],vertArray[i+1][1]);curContext.lineTo(vertArray[i+3][0],vertArray[i+3][1]);if(doFill){p.fill(vertArray[i+3][5])}if(doStroke){p.stroke(vertArray[i+3][6])}}else{curContext.moveTo(vertArray[i][0],vertArray[i][1]);curContext.lineTo(vertArray[i+1][0],vertArray[i+1][1])}executeContextFill();executeContextStroke();curContext.closePath()}}}else{curContext.beginPath();curContext.moveTo(vertArray[0][0],vertArray[0][1]);for(i=1;i<vertArray.length;i++){if(vertArray[i]["isVert"]===true){if(vertArray[i]["moveTo"]===true){curContext.moveTo(vertArray[i][0],vertArray[i][1])}else{if(vertArray[i]["moveTo"]===false){curContext.lineTo(vertArray[i][0],vertArray[i][1])}else{curContext.lineTo(vertArray[i][0],vertArray[i][1])}}}}if(closeShape){curContext.lineTo(vertArray[0][0],vertArray[0][1])}executeContextFill();executeContextStroke();curContext.closePath()}}}}}}}}}}isCurve=false;isBezier=false;curveVertArray=[];curveVertCount=0};var splineForward=function(segments,matrix){var f=1/segments;var ff=f*f;var fff=ff*f;matrix.set(0,0,0,1,fff,ff,f,0,6*fff,2*ff,0,0,6*fff,0,0,0)};var curveInit=function(){if(!curveDrawMatrix){curveBasisMatrix=new PMatrix3D();curveDrawMatrix=new PMatrix3D();curveInited=true}var s=curTightness;curveBasisMatrix.set((s-1)/2,(s+3)/2,(-3-s)/2,(1-s)/2,(1-s),(-5-s)/2,(s+2),(s-1)/2,(s-1)/2,0,(1-s)/2,0,0,1,0,0);splineForward(curveDet,curveDrawMatrix);if(!bezierBasisInverse){curveToBezierMatrix=new PMatrix3D()}curveToBezierMatrix.set(curveBasisMatrix);curveToBezierMatrix.preApply(bezierBasisInverse);curveDrawMatrix.apply(curveBasisMatrix)};p.bezierVertex=function bezierVertex(){isBezier=true;var vert=[];if(firstVert){throw ("vertex() must be used at least once before calling bezierVertex()")}else{if(arguments.length===9){if(p.use3DContext){if(bezierDrawMatrix===undef){bezierDrawMatrix=new PMatrix3D()}var lastPoint=vertArray.length-1;splineForward(bezDetail,bezierDrawMatrix);bezierDrawMatrix.apply(bezierBasisMatrix);var draw=bezierDrawMatrix.array();var x1=vertArray[lastPoint][0],y1=vertArray[lastPoint][1],z1=vertArray[lastPoint][2];var xplot1=draw[4]*x1+draw[5]*arguments[0]+draw[6]*arguments[3]+draw[7]*arguments[6];var xplot2=draw[8]*x1+draw[9]*arguments[0]+draw[10]*arguments[3]+draw[11]*arguments[6];var xplot3=draw[12]*x1+draw[13]*arguments[0]+draw[14]*arguments[3]+draw[15]*arguments[6];var yplot1=draw[4]*y1+draw[5]*arguments[1]+draw[6]*arguments[4]+draw[7]*arguments[7];var yplot2=draw[8]*y1+draw[9]*arguments[1]+draw[10]*arguments[4]+draw[11]*arguments[7];var yplot3=draw[12]*y1+draw[13]*arguments[1]+draw[14]*arguments[4]+draw[15]*arguments[7];var zplot1=draw[4]*z1+draw[5]*arguments[2]+draw[6]*arguments[5]+draw[7]*arguments[8];var zplot2=draw[8]*z1+draw[9]*arguments[2]+draw[10]*arguments[5]+draw[11]*arguments[8];var zplot3=draw[12]*z1+draw[13]*arguments[2]+draw[14]*arguments[5]+draw[15]*arguments[8];for(var j=0;j<bezDetail;j++){x1+=xplot1;xplot1+=xplot2;xplot2+=xplot3;y1+=yplot1;yplot1+=yplot2;yplot2+=yplot3;z1+=zplot1;zplot1+=zplot2;zplot2+=zplot3;p.vertex(x1,y1,z1)}p.vertex(arguments[6],arguments[7],arguments[8])}}else{for(var i=0;i<arguments.length;i++){vert[i]=arguments[i]}vertArray.push(vert);vertArray[vertArray.length-1]["isVert"]=false}}};var executeTexImage2D=function(){var canvas2d=document.createElement("canvas");try{curContext.texImage2D(curContext.TEXTURE_2D,0,curContext.RGBA,curContext.RGBA,curContext.UNSIGNED_BYTE,canvas2d);executeTexImage2D=function(texture){curContext.texImage2D(curContext.TEXTURE_2D,0,curContext.RGBA,curContext.RGBA,curContext.UNSIGNED_BYTE,texture)}}catch(e){executeTexImage2D=function(texture){curContext.texImage2D(curContext.TEXTURE_2D,0,texture,false)}}executeTexImage2D.apply(this,arguments)};p.texture=function(pimage){if(pimage.localName==="canvas"){curContext.bindTexture(curContext.TEXTURE_2D,canTex);executeTexImage2D(pimage);curContext.texParameteri(curContext.TEXTURE_2D,curContext.TEXTURE_MAG_FILTER,curContext.LINEAR);curContext.texParameteri(curContext.TEXTURE_2D,curContext.TEXTURE_MIN_FILTER,curContext.LINEAR);curContext.generateMipmap(curContext.TEXTURE_2D)}else{if(!pimage.__texture){var texture=curContext.createTexture();pimage.__texture=texture;var cvs=document.createElement("canvas");var pot;if(pimage.width&(pimage.width-1)===0){cvs.width=pimage.width}else{pot=1;while(pot<pimage.width){pot*=2}cvs.width=pot}if(pimage.height&(pimage.height-1)===0){cvs.height=pimage.height}else{pot=1;while(pot<pimage.height){pot*=2}cvs.height=pot}var ctx=cvs.getContext("2d");var textureImage=ctx.createImageData(cvs.width,cvs.height);var imgData=pimage.toImageData();for(var i=0;i<cvs.width;i+=1){for(var j=0;j<cvs.height;j+=1){var index=(j*cvs.width+i)*4;textureImage.data[index+0]=imgData.data[index+0];textureImage.data[index+1]=imgData.data[index+1];textureImage.data[index+2]=imgData.data[index+2];textureImage.data[index+3]=255}}ctx.putImageData(textureImage,0,0);pimage.__cvs=cvs;curContext.bindTexture(curContext.TEXTURE_2D,pimage.__texture);curContext.texParameteri(curContext.TEXTURE_2D,curContext.TEXTURE_MIN_FILTER,curContext.LINEAR_MIPMAP_LINEAR);curContext.texParameteri(curContext.TEXTURE_2D,curContext.TEXTURE_MAG_FILTER,curContext.LINEAR);curContext.texParameteri(curContext.TEXTURE_2D,curContext.TEXTURE_WRAP_T,curContext.CLAMP_TO_EDGE);curContext.texParameteri(curContext.TEXTURE_2D,curContext.TEXTURE_WRAP_S,curContext.CLAMP_TO_EDGE);executeTexImage2D(pimage.__cvs);curContext.generateMipmap(curContext.TEXTURE_2D)}else{curContext.bindTexture(curContext.TEXTURE_2D,pimage.__texture)}}curTexture.width=pimage.width;curTexture.height=pimage.height;usingTexture=true;curContext.useProgram(programObject3D);uniformi("usingTexture3d",programObject3D,"usingTexture",usingTexture)};p.textureMode=function(mode){curTextureMode=mode};var curveVertexSegment=function(x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4){var x0=x2;var y0=y2;var z0=z2;var draw=curveDrawMatrix.array();var xplot1=draw[4]*x1+draw[5]*x2+draw[6]*x3+draw[7]*x4;var xplot2=draw[8]*x1+draw[9]*x2+draw[10]*x3+draw[11]*x4;var xplot3=draw[12]*x1+draw[13]*x2+draw[14]*x3+draw[15]*x4;var yplot1=draw[4]*y1+draw[5]*y2+draw[6]*y3+draw[7]*y4;var yplot2=draw[8]*y1+draw[9]*y2+draw[10]*y3+draw[11]*y4;var yplot3=draw[12]*y1+draw[13]*y2+draw[14]*y3+draw[15]*y4;var zplot1=draw[4]*z1+draw[5]*z2+draw[6]*z3+draw[7]*z4;var zplot2=draw[8]*z1+draw[9]*z2+draw[10]*z3+draw[11]*z4;var zplot3=draw[12]*z1+draw[13]*z2+draw[14]*z3+draw[15]*z4;p.vertex(x0,y0,z0);for(var j=0;j<curveDet;j++){x0+=xplot1;xplot1+=xplot2;xplot2+=xplot3;y0+=yplot1;yplot1+=yplot2;yplot2+=yplot3;z0+=zplot1;zplot1+=zplot2;zplot2+=zplot3;p.vertex(x0,y0,z0)}};p.curveVertex=function(x,y,z){isCurve=true;if(p.use3DContext){if(!curveInited){curveInit()}var vert=[];vert[0]=x;vert[1]=y;vert[2]=z;curveVertArray.push(vert);curveVertCount++;if(curveVertCount>3){curveVertexSegment(curveVertArray[curveVertCount-4][0],curveVertArray[curveVertCount-4][1],curveVertArray[curveVertCount-4][2],curveVertArray[curveVertCount-3][0],curveVertArray[curveVertCount-3][1],curveVertArray[curveVertCount-3][2],curveVertArray[curveVertCount-2][0],curveVertArray[curveVertCount-2][1],curveVertArray[curveVertCount-2][2],curveVertArray[curveVertCount-1][0],curveVertArray[curveVertCount-1][1],curveVertArray[curveVertCount-1][2])}}else{p.vertex(x,y,z)}};p.curve=function curve(){if(arguments.length===8){p.beginShape();p.curveVertex(arguments[0],arguments[1]);p.curveVertex(arguments[2],arguments[3]);p.curveVertex(arguments[4],arguments[5]);p.curveVertex(arguments[6],arguments[7]);p.endShape()}else{if(p.use3DContext){p.beginShape();p.curveVertex(arguments[0],arguments[1],arguments[2]);p.curveVertex(arguments[3],arguments[4],arguments[5]);p.curveVertex(arguments[6],arguments[7],arguments[8]);p.curveVertex(arguments[9],arguments[10],arguments[11]);p.endShape()}}};p.curveTightness=function(tightness){curTightness=tightness};p.curveDetail=function curveDetail(detail){curveDet=detail;curveInit()};p.rectMode=function rectMode(aRectMode){curRectMode=aRectMode};p.imageMode=function(mode){switch(mode){case PConstants.CORNER:imageModeConvert=imageModeCorner;break;case PConstants.CORNERS:imageModeConvert=imageModeCorners;break;case PConstants.CENTER:imageModeConvert=imageModeCenter;break;default:throw"Invalid imageMode"}};p.ellipseMode=function ellipseMode(aEllipseMode){curEllipseMode=aEllipseMode};p.arc=function arc(x,y,width,height,start,stop){if(width<=0||stop<start){return}if(curEllipseMode===PConstants.CORNERS){width=width-x;height=height-y}else{if(curEllipseMode===PConstants.RADIUS){x=x-width;y=y-height;width=width*2;height=height*2}else{if(curEllipseMode===PConstants.CENTER){x=x-width/2;y=y-height/2}}}while(start<0){start+=PConstants.TWO_PI;stop+=PConstants.TWO_PI}if(stop-start>PConstants.TWO_PI){start=0;stop=PConstants.TWO_PI}var hr=width/2;var vr=height/2;var centerX=x+hr;var centerY=y+vr;var i,ii,startLUT,stopLUT;if(doFill){var savedStroke=doStroke;doStroke=false;startLUT=0.5+(start/PConstants.TWO_PI)*PConstants.SINCOS_LENGTH;stopLUT=0.5+(stop/PConstants.TWO_PI)*PConstants.SINCOS_LENGTH;p.beginShape();p.vertex(centerX,centerY);for(i=startLUT;i<stopLUT;i++){ii=i%PConstants.SINCOS_LENGTH;if(ii<0){ii+=PConstants.SINCOS_LENGTH}p.vertex(centerX+parseFloat(Math.cos(ii*PConstants.DEG_TO_RAD*0.5))*hr,centerY+parseFloat(Math.sin(ii*PConstants.DEG_TO_RAD*0.5))*vr)}p.endShape(PConstants.CLOSE);doStroke=savedStroke}if(doStroke){var savedFill=doFill;doFill=false;startLUT=0.5+(start/PConstants.TWO_PI)*PConstants.SINCOS_LENGTH;stopLUT=0.5+(stop/PConstants.TWO_PI)*PConstants.SINCOS_LENGTH;p.beginShape();for(i=startLUT;i<stopLUT;i++){ii=i%PConstants.SINCOS_LENGTH;if(ii<0){ii+=PConstants.SINCOS_LENGTH}p.vertex(centerX+parseFloat(Math.cos(ii*PConstants.DEG_TO_RAD*0.5))*hr,centerY+parseFloat(Math.sin(ii*PConstants.DEG_TO_RAD*0.5))*vr)}p.endShape();doFill=savedFill}};p.line=function line(){var x1,y1,z1,x2,y2,z2;if(p.use3DContext){if(arguments.length===6){x1=arguments[0];y1=arguments[1];z1=arguments[2];x2=arguments[3];y2=arguments[4];z2=arguments[5]}else{if(arguments.length===4){x1=arguments[0];y1=arguments[1];z1=0;x2=arguments[2];y2=arguments[3];z2=0}}var lineVerts=[x1,y1,z1,x2,y2,z2];var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.transpose();var proj=new PMatrix3D();proj.set(projection);proj.transpose();if(lineWidth>0&&doStroke){curContext.useProgram(programObject2D);uniformMatrix("model2d",programObject2D,"model",false,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);uniformMatrix("view2d",programObject2D,"view",false,view.array());uniformMatrix("projection2d",programObject2D,"projection",false,proj.array());uniformf("color2d",programObject2D,"color",strokeStyle);uniformi("picktype2d",programObject2D,"picktype",0);curContext.lineWidth(lineWidth);vertexAttribPointer("vertex2d",programObject2D,"Vertex",3,lineBuffer);disableVertexAttribPointer("aTextureCoord2d",programObject2D,"aTextureCoord");curContext.bufferData(curContext.ARRAY_BUFFER,new Float32Array(lineVerts),curContext.STREAM_DRAW);curContext.drawArrays(curContext.LINES,0,2)}}else{x1=arguments[0];y1=arguments[1];x2=arguments[2];y2=arguments[3];if((x1===x2||y1===y2)&&lineWidth<=1&&doStroke&&curSketch.options.crispLines){var temp;if(x1===x2){if(y1>y2){temp=y1;y1=y2;y2=temp}for(var y=y1;y<=y2;++y){p.set(x1,y,currentStrokeColor)}}else{if(x1>x2){temp=x1;x1=x2;x2=temp}for(var x=x1;x<=x2;++x){p.set(x,y1,currentStrokeColor)}}return}if(doStroke){curContext.beginPath();curContext.moveTo(x1||0,y1||0);curContext.lineTo(x2||0,y2||0);executeContextStroke();curContext.closePath()}}};p.bezier=function bezier(){if(arguments.length===8&&!p.use3DContext){p.beginShape();p.vertex(arguments[0],arguments[1]);p.bezierVertex(arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7]);p.endShape()}else{if(arguments.length===12&&p.use3DContext){p.beginShape();p.vertex(arguments[0],arguments[1],arguments[2]);p.bezierVertex(arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8],arguments[9],arguments[10],arguments[11]);p.endShape()}else{throw ("Please use the proper parameters!")}}};p.bezierDetail=function bezierDetail(detail){bezDetail=detail};p.bezierPoint=function bezierPoint(a,b,c,d,t){return(1-t)*(1-t)*(1-t)*a+3*(1-t)*(1-t)*t*b+3*(1-t)*t*t*c+t*t*t*d};p.bezierTangent=function bezierTangent(a,b,c,d,t){return(3*t*t*(-a+3*b-3*c+d)+6*t*(a-2*b+c)+3*(-a+b))};p.curvePoint=function curvePoint(a,b,c,d,t){return 0.5*((2*b)+(-a+c)*t+(2*a-5*b+4*c-d)*t*t+(-a+3*b-3*c+d)*t*t*t)};p.curveTangent=function curveTangent(a,b,c,d,t){return 0.5*((-a+c)+2*(2*a-5*b+4*c-d)*t+3*(-a+3*b-3*c+d)*t*t)};p.triangle=function triangle(x1,y1,x2,y2,x3,y3){p.beginShape(PConstants.TRIANGLES);p.vertex(x1,y1,0);p.vertex(x2,y2,0);p.vertex(x3,y3,0);p.endShape()};p.quad=function quad(x1,y1,x2,y2,x3,y3,x4,y4){p.beginShape(PConstants.QUADS);p.vertex(x1,y1,0);p.vertex(x2,y2,0);p.vertex(x3,y3,0);p.vertex(x4,y4,0);p.endShape()};p.rect=function rect(x,y,width,height){if(p.use3DContext){var model=new PMatrix3D();model.translate(x,y,0);model.scale(width,height,1);model.transpose();var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.transpose();var proj=new PMatrix3D();proj.set(projection);proj.transpose();if(lineWidth>0&&doStroke){curContext.useProgram(programObject2D);uniformMatrix("model2d",programObject2D,"model",false,model.array());uniformMatrix("view2d",programObject2D,"view",false,view.array());uniformMatrix("projection2d",programObject2D,"projection",false,proj.array());uniformf("color2d",programObject2D,"color",strokeStyle);uniformi("picktype2d",programObject2D,"picktype",0);vertexAttribPointer("vertex2d",programObject2D,"Vertex",3,rectBuffer);disableVertexAttribPointer("aTextureCoord2d",programObject2D,"aTextureCoord");curContext.lineWidth(lineWidth);curContext.drawArrays(curContext.LINE_LOOP,0,rectVerts.length/3)}if(doFill){curContext.useProgram(programObject3D);uniformMatrix("model3d",programObject3D,"model",false,model.array());uniformMatrix("view3d",programObject3D,"view",false,view.array());uniformMatrix("projection3d",programObject3D,"projection",false,proj.array());curContext.enable(curContext.POLYGON_OFFSET_FILL);curContext.polygonOffset(1,1);uniformf("color3d",programObject3D,"color",fillStyle);var v=new PMatrix3D();v.set(view);var m=new PMatrix3D();m.set(model);v.mult(m);var normalMatrix=new PMatrix3D();normalMatrix.set(v);normalMatrix.invert();normalMatrix.transpose();uniformMatrix("normalTransform3d",programObject3D,"normalTransform",false,normalMatrix.array());vertexAttribPointer("vertex3d",programObject3D,"Vertex",3,rectBuffer);vertexAttribPointer("normal3d",programObject3D,"Normal",3,rectNormBuffer);curContext.drawArrays(curContext.TRIANGLE_FAN,0,rectVerts.length/3);curContext.disable(curContext.POLYGON_OFFSET_FILL)}}else{if(!width&&!height){return}if(doStroke&&!doFill&&lineWidth<=1&&curSketch.options.crispLines){var i,x2=x+width-1,y2=y+height-1;for(i=0;i<width;++i){p.set(x+i,y,currentStrokeColor);p.set(x+i,y2,currentStrokeColor)}for(i=0;i<height;++i){p.set(x,y+i,currentStrokeColor);p.set(x2,y+i,currentStrokeColor)}return}curContext.beginPath();var offsetStart=0;var offsetEnd=0;if(curRectMode===PConstants.CORNERS){width-=x;height-=y}if(curRectMode===PConstants.RADIUS){width*=2;height*=2}if(curRectMode===PConstants.CENTER||curRectMode===PConstants.RADIUS){x-=width/2;y-=height/2}curContext.rect(Math.round(x)-offsetStart,Math.round(y)-offsetStart,Math.round(width)+offsetEnd,Math.round(height)+offsetEnd);executeContextFill();executeContextStroke();curContext.closePath()}};p.ellipse=function ellipse(x,y,width,height){x=x||0;y=y||0;if(width<=0&&height<=0){return}if(curEllipseMode===PConstants.RADIUS){width*=2;height*=2}if(curEllipseMode===PConstants.CORNERS){width=width-x;height=height-y}if(curEllipseMode===PConstants.CORNER||curEllipseMode===PConstants.CORNERS){x+=width/2;y+=height/2}var offsetStart=0;if((!p.use3DContext)&&(width===height)){curContext.beginPath();curContext.arc(x-offsetStart,y-offsetStart,width/2,0,PConstants.TWO_PI,false);executeContextFill();executeContextStroke();curContext.closePath()}else{var w=width/2,h=height/2,C=0.5522847498307933;var c_x=C*w,c_y=C*h;if(!p.use3DContext){p.beginShape();p.vertex(x+w,y);p.bezierVertex(x+w,y-c_y,x+c_x,y-h,x,y-h);p.bezierVertex(x-c_x,y-h,x-w,y-c_y,x-w,y);p.bezierVertex(x-w,y+c_y,x-c_x,y+h,x,y+h);p.bezierVertex(x+c_x,y+h,x+w,y+c_y,x+w,y);p.endShape()}else{p.beginShape();p.vertex(x+w,y);p.bezierVertex(x+w,y-c_y,0,x+c_x,y-h,0,x,y-h,0);p.bezierVertex(x-c_x,y-h,0,x-w,y-c_y,0,x-w,y,0);p.bezierVertex(x-w,y+c_y,0,x-c_x,y+h,0,x,y+h,0);p.bezierVertex(x+c_x,y+h,0,x+w,y+c_y,0,x+w,y,0);p.endShape();var xAv=0,yAv=0,i,j;for(i=0;i<vertArray.length;i++){xAv+=vertArray[i][0];yAv+=vertArray[i][1]}xAv/=vertArray.length;yAv/=vertArray.length;var vert=[],fillVertArray=[],colorVertArray=[];vert[0]=xAv;vert[1]=yAv;vert[2]=0;vert[3]=0;vert[4]=0;vert[5]=fillStyle[0];vert[6]=fillStyle[1];vert[7]=fillStyle[2];vert[8]=fillStyle[3];vert[9]=strokeStyle[0];vert[10]=strokeStyle[1];vert[11]=strokeStyle[2];vert[12]=strokeStyle[3];vert[13]=normalX;vert[14]=normalY;vert[15]=normalZ;vertArray.unshift(vert);for(i=0;i<vertArray.length;i++){for(j=0;j<3;j++){fillVertArray.push(vertArray[i][j])}for(j=5;j<9;j++){colorVertArray.push(vertArray[i][j])}}fill3D(fillVertArray,"TRIANGLE_FAN",colorVertArray)}}};p.normal=function normal(nx,ny,nz){if(arguments.length!==3||!(typeof nx==="number"&&typeof ny==="number"&&typeof nz==="number")){throw"normal() requires three numeric arguments."}normalX=nx;normalY=ny;normalZ=nz;if(curShape!==0){if(normalMode===PConstants.NORMAL_MODE_AUTO){normalMode=PConstants.NORMAL_MODE_SHAPE}else{if(normalMode===PConstants.NORMAL_MODE_SHAPE){normalMode=PConstants.NORMAL_MODE_VERTEX}}}};p.save=function save(file,img){if(img!==undef){return window.open(img.toDataURL(),"_blank")}else{return window.open(p.externals.canvas.toDataURL(),"_blank")}};var saveNumber=0;p.saveFrame=function saveFrame(file){if(file===undef){file="screen-####.png"}var frameFilename=file.replace(/#+/,function(all){var s=""+(saveNumber++);while(s.length<all.length){s="0"+s}return s});p.save(frameFilename)};var utilityContext2d=document.createElement("canvas").getContext("2d");var canvasDataCache=[undef,undef,undef];function getCanvasData(obj,w,h){var canvasData=canvasDataCache.shift();if(canvasData===undef){canvasData={};canvasData.canvas=document.createElement("canvas");canvasData.context=canvasData.canvas.getContext("2d")}canvasDataCache.push(canvasData);var canvas=canvasData.canvas,context=canvasData.context,width=w||obj.width,height=h||obj.height;canvas.width=width;canvas.height=height;if(!obj){context.clearRect(0,0,width,height)}else{if("data" in obj){context.putImageData(obj,0,0)}else{context.clearRect(0,0,width,height);context.drawImage(obj,0,0,width,height)}}return canvasData}var PImage=function PImage(aWidth,aHeight,aFormat){this.get=function(x,y,w,h){if(!arguments.length){return p.get(this)}else{if(arguments.length===2){return p.get(x,y,this)}else{if(arguments.length===4){return p.get(x,y,w,h,this)}}}};this.set=function(x,y,c){p.set(x,y,c,this)};this.blend=function(srcImg,x,y,width,height,dx,dy,dwidth,dheight,MODE){if(arguments.length===9){p.blend(this,srcImg,x,y,width,height,dx,dy,dwidth,dheight,this)}else{if(arguments.length===10){p.blend(srcImg,x,y,width,height,dx,dy,dwidth,dheight,MODE,this)}}delete this.sourceImg};this.copy=function(srcImg,sx,sy,swidth,sheight,dx,dy,dwidth,dheight){if(arguments.length===8){p.blend(this,srcImg,sx,sy,swidth,sheight,dx,dy,dwidth,PConstants.REPLACE,this)}else{if(arguments.length===9){p.blend(srcImg,sx,sy,swidth,sheight,dx,dy,dwidth,dheight,PConstants.REPLACE,this)}}delete this.sourceImg};this.filter=function(mode,param){if(arguments.length===2){p.filter(mode,param,this)}else{if(arguments.length===1){p.filter(mode,null,this)}}delete this.sourceImg};this.save=function(file){p.save(file,this)};this.resize=function(w,h){if(this.isRemote){throw"Image is loaded remotely. Cannot resize."}else{if(this.width!==0||this.height!==0){if(w===0&&h!==0){w=Math.floor(this.width/this.height*h)}else{if(h===0&&w!==0){h=Math.floor(this.height/this.width*w)}}var canvas=getCanvasData(this.imageData).canvas;var imageData=getCanvasData(canvas,w,h).context.getImageData(0,0,w,h);this.fromImageData(imageData)}}};this.mask=function(mask){this.__mask=undef;if(mask.constructor.name==="PImage"){if(mask.width===this.width&&mask.height===this.height){this.__mask=mask}else{throw"mask must have the same dimensions as PImage."}}else{if(typeof mask==="object"&&mask.constructor===Array){if(this.pixels.length===mask.length){this.__mask=mask}else{throw"mask array must be the same length as PImage pixels array."}}}};this.pixels={getLength:(function(aImg){if(aImg.isRemote){throw"Image is loaded remotely. Cannot get length."}else{return function(){return aImg.imageData.data.length?aImg.imageData.data.length/4:0}}}(this)),getPixel:(function(aImg){if(aImg.isRemote){throw"Image is loaded remotely. Cannot get pixels."}else{return function(i){var offset=i*4;return p.color.toInt(aImg.imageData.data[offset],aImg.imageData.data[offset+1],aImg.imageData.data[offset+2],aImg.imageData.data[offset+3])}}}(this)),setPixel:(function(aImg){if(aImg.isRemote){throw"Image is loaded remotely. Cannot set pixel."}else{return function(i,c){var offset=i*4;aImg.imageData.data[offset+0]=(c&PConstants.RED_MASK)>>>16;aImg.imageData.data[offset+1]=(c&PConstants.GREEN_MASK)>>>8;aImg.imageData.data[offset+2]=(c&PConstants.BLUE_MASK);aImg.imageData.data[offset+3]=(c&PConstants.ALPHA_MASK)>>>24}}}(this)),set:function(arr){if(this.isRemote){throw"Image is loaded remotely. Cannot set pixels."}else{for(var i=0,aL=arr.length;i<aL;i++){this.setPixel(i,arr[i])}}}};this.loadPixels=function(){};this.updatePixels=function(){};this.toImageData=function(){if(this.isRemote){return this.sourceImg}else{var canvasData=getCanvasData(this.imageData);return canvasData.context.getImageData(0,0,this.width,this.height)}};this.toDataURL=function(){if(this.isRemote){throw"Image is loaded remotely. Cannot create dataURI."}else{var canvasData=getCanvasData(this.imageData);return canvasData.canvas.toDataURL()}};this.fromImageData=function(canvasImg){this.width=canvasImg.width;this.height=canvasImg.height;this.imageData=canvasImg;this.format=PConstants.ARGB};this.fromHTMLImageData=function(htmlImg){var canvasData=getCanvasData(htmlImg);try{var imageData=canvasData.context.getImageData(0,0,htmlImg.width,htmlImg.height);this.fromImageData(imageData)}catch(e){if(htmlImg.width&&htmlImg.height){this.isRemote=true;this.width=htmlImg.width;this.height=htmlImg.height}}this.sourceImg=htmlImg};if(arguments.length===1){this.fromHTMLImageData(arguments[0])}else{if(arguments.length===2||arguments.length===3){this.width=aWidth||1;this.height=aHeight||1;this.imageData=utilityContext2d.createImageData(this.width,this.height);this.format=(aFormat===PConstants.ARGB||aFormat===PConstants.ALPHA)?aFormat:PConstants.RGB}else{this.width=0;this.height=0;this.imageData=utilityContext2d.createImageData(1,1);this.format=PConstants.ARGB}}};p.PImage=PImage;p.createImage=function createImage(w,h,mode){return new PImage(w,h,mode)};p.loadImage=function loadImage(file,type,callback){if(type){file=file+"."+type}if(curSketch.imageCache.images[file]){return new PImage(curSketch.imageCache.images[file])}else{var pimg=new PImage();var img=document.createElement("img");pimg.sourceImg=img;img.onload=(function(aImage,aPImage,aCallback){var image=aImage;var pimg=aPImage;var callback=aCallback;return function(){pimg.fromHTMLImageData(image);pimg.loaded=true;if(callback){callback()}}}(img,pimg,callback));img.src=file;return pimg}};p.requestImage=p.loadImage;function get$0(){var c=new PImage(p.width,p.height,PConstants.RGB);c.fromImageData(curContext.getImageData(0,0,p.width,p.height));return c}function get$2(x,y){var data;if(x<p.width&&x>=0&&y>=0&&y<p.height){if(isContextReplaced){var offset=((0|x)+p.width*(0|y))*4;data=p.imageData.data;return p.color.toInt(data[offset],data[offset+1],data[offset+2],data[offset+3])}data=curContext.getImageData(0|x,0|y,1,1).data;return p.color.toInt(data[0],data[1],data[2],data[3])}else{return 0}}function get$3(x,y,img){if(img.isRemote){throw"Image is loaded remotely. Cannot get x,y."}else{var offset=y*img.width*4+(x*4);return p.color.toInt(img.imageData.data[offset],img.imageData.data[offset+1],img.imageData.data[offset+2],img.imageData.data[offset+3])}}function get$4(x,y,w,h){var c=new PImage(w,h,PConstants.RGB);c.fromImageData(curContext.getImageData(x,y,w,h));return c}function get$5(x,y,w,h,img){if(img.isRemote){throw"Image is loaded remotely. Cannot get x,y,w,h."}else{var c=new PImage(w,h,PConstants.RGB),cData=c.imageData.data,imgWidth=img.width,imgHeight=img.height,imgData=img.imageData.data;var startRow=Math.max(0,-y),startColumn=Math.max(0,-x),stopRow=Math.min(h,imgHeight-y),stopColumn=Math.min(w,imgWidth-x);for(var i=startRow;i<stopRow;++i){var sourceOffset=((y+i)*imgWidth+(x+startColumn))*4;var targetOffset=(i*w+startColumn)*4;for(var j=startColumn;j<stopColumn;++j){cData[targetOffset++]=imgData[sourceOffset++];cData[targetOffset++]=imgData[sourceOffset++];cData[targetOffset++]=imgData[sourceOffset++];cData[targetOffset++]=imgData[sourceOffset++]}}return c}}p.get=function get(x,y,w,h,img){if(arguments.length===2){return get$2(x,y)}else{if(arguments.length===0){return get$0()}else{if(arguments.length===5){return get$5(x,y,w,h,img)}else{if(arguments.length===4){return get$4(x,y,w,h)}else{if(arguments.length===3){return get$3(x,y,w)}else{if(arguments.length===1){return x}}}}}}};p.createGraphics=function createGraphics(w,h,render){var canvas=document.createElement("canvas");var pg=new Processing(canvas);pg.size(w,h,render);pg.canvas=canvas;return pg};function resetContext(){if(isContextReplaced){curContext=originalContext;isContextReplaced=false;p.updatePixels()}}function SetPixelContextWrapper(){function wrapFunction(newContext,name){function wrapper(){resetContext();curContext[name].apply(curContext,arguments)}newContext[name]=wrapper}function wrapProperty(newContext,name){function getter(){resetContext();return curContext[name]}function setter(value){resetContext();curContext[name]=value}p.defineProperty(newContext,name,{get:getter,set:setter})}for(var n in curContext){if(typeof curContext[n]==="function"){wrapFunction(this,n)}else{wrapProperty(this,n)}}}function replaceContext(){if(isContextReplaced){return}p.loadPixels();if(proxyContext===null){originalContext=curContext;proxyContext=new SetPixelContextWrapper()}isContextReplaced=true;curContext=proxyContext;setPixelsCached=0}function set$3(x,y,c){if(x<p.width&&x>=0&&y>=0&&y<p.height){replaceContext();p.pixels.setPixel((0|x)+p.width*(0|y),c);if(++setPixelsCached>maxPixelsCached){resetContext()}}}function set$4(x,y,obj,img){if(img.isRemote){throw"Image is loaded remotely. Cannot set x,y."}else{var c=p.color.toArray(obj);var offset=y*img.width*4+(x*4);var data=img.imageData.data;data[offset]=c[0];data[offset+1]=c[1];data[offset+2]=c[2];data[offset+3]=c[3]}}p.set=function set(x,y,obj,img){var color,oldFill;if(arguments.length===3){if(typeof obj==="number"){set$3(x,y,obj)}else{if(obj instanceof PImage){p.image(obj,x,y)}}}else{if(arguments.length===4){set$4(x,y,obj,img)}}};p.imageData={};p.pixels={getLength:function(){return p.imageData.data.length?p.imageData.data.length/4:0},getPixel:function(i){var offset=i*4;return(p.imageData.data[offset+3]<<24)&4278190080|(p.imageData.data[offset+0]<<16)&16711680|(p.imageData.data[offset+1]<<8)&65280|p.imageData.data[offset+2]&255},setPixel:function(i,c){var offset=i*4;p.imageData.data[offset+0]=(c&16711680)>>>16;p.imageData.data[offset+1]=(c&65280)>>>8;p.imageData.data[offset+2]=(c&255);p.imageData.data[offset+3]=(c&4278190080)>>>24},set:function(arr){for(var i=0,aL=arr.length;i<aL;i++){this.setPixel(i,arr[i])}}};p.loadPixels=function(){p.imageData=curContext.getImageData(0,0,p.width,p.height)};p.updatePixels=function(){if(p.imageData){curContext.putImageData(p.imageData,0,0)}};p.hint=function hint(which){if(which===PConstants.DISABLE_DEPTH_TEST){curContext.disable(curContext.DEPTH_TEST);curContext.depthMask(false);curContext.clear(curContext.DEPTH_BUFFER_BIT)}else{if(which===PConstants.ENABLE_DEPTH_TEST){curContext.enable(curContext.DEPTH_TEST);curContext.depthMask(true)}}};p.background=function background(){var color,a,img;if(typeof arguments[0]==="number"){color=p.color.apply(this,arguments);if(!curSketch.options.isTransparent){color=color|PConstants.ALPHA_MASK}}else{if(arguments.length===1&&arguments[0] instanceof PImage){img=arguments[0];if(!img.pixels||img.width!==p.width||img.height!==p.height){throw"Background image must be the same dimensions as the canvas."}}else{throw"Incorrect background parameters."}}if(p.use3DContext){if(color!==undef){var c=p.color.toGLArray(color);refreshBackground=function(){curContext.clearColor(c[0],c[1],c[2],c[3]);curContext.clear(curContext.COLOR_BUFFER_BIT|curContext.DEPTH_BUFFER_BIT)}}else{refreshBackground=function(){}}}else{if(color!==undef){refreshBackground=function(){saveContext();curContext.setTransform(1,0,0,1,0,0);if(curSketch.options.isTransparent){curContext.clearRect(0,0,p.width,p.height)}curContext.fillStyle=p.color.toString(color);curContext.fillRect(0,0,p.width,p.height);isFillDirty=true;restoreContext()}}else{refreshBackground=function(){saveContext();curContext.setTransform(1,0,0,1,0,0);p.image(img,0,0);restoreContext()}}}refreshBackground()};p.image=function image(img,x,y,w,h){if(img.width>0){var wid=w||img.width;var hgt=h||img.height;if(p.use3DContext){p.beginShape(p.QUADS);p.texture(img.externals.canvas);p.vertex(x,y,0,0,0);p.vertex(x,y+hgt,0,0,hgt);p.vertex(x+wid,y+hgt,0,wid,hgt);p.vertex(x+wid,y,0,wid,0);p.endShape()}else{var bounds=imageModeConvert(x||0,y||0,w||img.width,h||img.height,arguments.length<4);var fastImage=!!img.sourceImg&&curTint===null&&!img.__mask;if(fastImage){var htmlElement=img.sourceImg;curContext.drawImage(htmlElement,0,0,htmlElement.width,htmlElement.height,bounds.x,bounds.y,bounds.w,bounds.h)}else{var obj=img.toImageData();if(img.__mask){var j,size;if(img.__mask.constructor.name==="PImage"){var objMask=img.__mask.toImageData();for(j=2,size=img.width*img.height*4;j<size;j+=4){obj.data[j+1]=objMask.data[j]}}else{for(j=0,size=img.__mask.length;j<size;++j){obj.data[(j<<2)+3]=img.__mask[j]}}}if(curTint!==null){curTint(obj)}curContext.drawImage(getCanvasData(obj).canvas,0,0,img.width,img.height,bounds.x,bounds.y,bounds.w,bounds.h)}}}};p.clear=function clear(x,y,width,height){if(arguments.length===0){curContext.clearRect(0,0,p.width,p.height)}else{curContext.clearRect(x,y,width,height)}};p.tint=function tint(){var tintColor=p.color.apply(this,arguments);var r=p.red(tintColor)/colorModeX;var g=p.green(tintColor)/colorModeY;var b=p.blue(tintColor)/colorModeZ;var a=p.alpha(tintColor)/colorModeA;curTint=function(obj){var data=obj.data,length=4*obj.width*obj.height;for(var i=0;i<length;){data[i++]*=r;data[i++]*=g;data[i++]*=b;data[i++]*=a}}};p.noTint=function noTint(){curTint=null};p.copy=function copy(src,sx,sy,sw,sh,dx,dy,dw,dh){if(arguments.length===8){dh=dw;dw=dy;dy=dx;dx=sh;sh=sw;sw=sy;sy=sx;sx=src;src=p}p.blend(src,sx,sy,sw,sh,dx,dy,dw,dh,PConstants.REPLACE)};p.blend=function blend(src,sx,sy,sw,sh,dx,dy,dw,dh,mode,pimgdest){if(arguments.length===9){mode=dh;dh=dw;dw=dy;dy=dx;dx=sh;sh=sw;sw=sy;sy=sx;sx=src;src=p}var sx2=sx+sw;var sy2=sy+sh;var dx2=dx+dw;var dy2=dy+dh;var dest;if(src.isRemote){throw"Image is loaded remotely. Cannot blend image."}else{if(arguments.length===10||arguments.length===9){p.loadPixels();dest=p}else{if(arguments.length===11&&pimgdest&&pimgdest.imageData){dest=pimgdest}}if(src===p){if(p.intersect(sx,sy,sx2,sy2,dx,dy,dx2,dy2)){p.blit_resize(p.get(sx,sy,sx2-sx,sy2-sy),0,0,sx2-sx-1,sy2-sy-1,dest.imageData.data,dest.width,dest.height,dx,dy,dx2,dy2,mode)}else{p.blit_resize(src,sx,sy,sx2,sy2,dest.imageData.data,dest.width,dest.height,dx,dy,dx2,dy2,mode)}}else{src.loadPixels();p.blit_resize(src,sx,sy,sx2,sy2,dest.imageData.data,dest.width,dest.height,dx,dy,dx2,dy2,mode)}if(arguments.length===10){p.updatePixels()}}};var buildBlurKernel=function buildBlurKernel(r){var radius=p.floor(r*3.5),i,radiusi;radius=(radius<1)?1:((radius<248)?radius:248);if(p.shared.blurRadius!==radius){p.shared.blurRadius=radius;p.shared.blurKernelSize=1+(p.shared.blurRadius<<1);p.shared.blurKernel=new Array(p.shared.blurKernelSize);for(i=0;i<p.shared.blurKernelSize;i++){p.shared.blurKernel[i]=0}for(i=1,radiusi=radius-1;i<radius;i++){p.shared.blurKernel[radius+i]=p.shared.blurKernel[radiusi]=radiusi*radiusi}p.shared.blurKernel[radius]=radius*radius}};var blurARGB=function blurARGB(r,aImg){var sum,cr,cg,cb,ca,c,m;var read,ri,ym,ymi,bk0;var wh=aImg.pixels.getLength();var r2=new Array(wh);var g2=new Array(wh);var b2=new Array(wh);var a2=new Array(wh);var yi=0;var x,y,i;buildBlurKernel(r);for(y=0;y<aImg.height;y++){for(x=0;x<aImg.width;x++){cb=cg=cr=ca=sum=0;read=x-p.shared.blurRadius;if(read<0){bk0=-read;read=0}else{if(read>=aImg.width){break}bk0=0}for(i=bk0;i<p.shared.blurKernelSize;i++){if(read>=aImg.width){break}c=aImg.pixels.getPixel(read+yi);m=p.shared.blurKernel[i];ca+=m*((c&PConstants.ALPHA_MASK)>>>24);cr+=m*((c&PConstants.RED_MASK)>>16);cg+=m*((c&PConstants.GREEN_MASK)>>8);cb+=m*(c&PConstants.BLUE_MASK);sum+=m;read++}ri=yi+x;a2[ri]=ca/sum;r2[ri]=cr/sum;g2[ri]=cg/sum;b2[ri]=cb/sum}yi+=aImg.width}yi=0;ym=-p.shared.blurRadius;ymi=ym*aImg.width;for(y=0;y<aImg.height;y++){for(x=0;x<aImg.width;x++){cb=cg=cr=ca=sum=0;if(ym<0){bk0=ri=-ym;read=x}else{if(ym>=aImg.height){break}bk0=0;ri=ym;read=x+ymi}for(i=bk0;i<p.shared.blurKernelSize;i++){if(ri>=aImg.height){break}m=p.shared.blurKernel[i];ca+=m*a2[read];cr+=m*r2[read];cg+=m*g2[read];cb+=m*b2[read];sum+=m;ri++;read+=aImg.width}aImg.pixels.setPixel(x+yi,((ca/sum)<<24|(cr/sum)<<16|(cg/sum)<<8|(cb/sum)))}yi+=aImg.width;ymi+=aImg.width;ym++}};var dilate=function dilate(isInverted,aImg){var currIdx=0;var maxIdx=aImg.pixels.getLength();var out=new Array(maxIdx);var currRowIdx,maxRowIdx,colOrig,colOut,currLum;var idxRight,idxLeft,idxUp,idxDown,colRight,colLeft,colUp,colDown,lumRight,lumLeft,lumUp,lumDown;if(!isInverted){while(currIdx<maxIdx){currRowIdx=currIdx;maxRowIdx=currIdx+aImg.width;while(currIdx<maxRowIdx){colOrig=colOut=aImg.pixels.getPixel(currIdx);idxLeft=currIdx-1;idxRight=currIdx+1;idxUp=currIdx-aImg.width;idxDown=currIdx+aImg.width;if(idxLeft<currRowIdx){idxLeft=currIdx}if(idxRight>=maxRowIdx){idxRight=currIdx}if(idxUp<0){idxUp=0}if(idxDown>=maxIdx){idxDown=currIdx}colUp=aImg.pixels.getPixel(idxUp);colLeft=aImg.pixels.getPixel(idxLeft);colDown=aImg.pixels.getPixel(idxDown);colRight=aImg.pixels.getPixel(idxRight);currLum=77*(colOrig>>16&255)+151*(colOrig>>8&255)+28*(colOrig&255);lumLeft=77*(colLeft>>16&255)+151*(colLeft>>8&255)+28*(colLeft&255);lumRight=77*(colRight>>16&255)+151*(colRight>>8&255)+28*(colRight&255);lumUp=77*(colUp>>16&255)+151*(colUp>>8&255)+28*(colUp&255);lumDown=77*(colDown>>16&255)+151*(colDown>>8&255)+28*(colDown&255);if(lumLeft>currLum){colOut=colLeft;currLum=lumLeft}if(lumRight>currLum){colOut=colRight;currLum=lumRight}if(lumUp>currLum){colOut=colUp;currLum=lumUp}if(lumDown>currLum){colOut=colDown;currLum=lumDown}out[currIdx++]=colOut}}}else{while(currIdx<maxIdx){currRowIdx=currIdx;maxRowIdx=currIdx+aImg.width;while(currIdx<maxRowIdx){colOrig=colOut=aImg.pixels.getPixel(currIdx);idxLeft=currIdx-1;idxRight=currIdx+1;idxUp=currIdx-aImg.width;idxDown=currIdx+aImg.width;if(idxLeft<currRowIdx){idxLeft=currIdx}if(idxRight>=maxRowIdx){idxRight=currIdx}if(idxUp<0){idxUp=0}if(idxDown>=maxIdx){idxDown=currIdx}colUp=aImg.pixels.getPixel(idxUp);colLeft=aImg.pixels.getPixel(idxLeft);colDown=aImg.pixels.getPixel(idxDown);colRight=aImg.pixels.getPixel(idxRight);currLum=77*(colOrig>>16&255)+151*(colOrig>>8&255)+28*(colOrig&255);lumLeft=77*(colLeft>>16&255)+151*(colLeft>>8&255)+28*(colLeft&255);lumRight=77*(colRight>>16&255)+151*(colRight>>8&255)+28*(colRight&255);lumUp=77*(colUp>>16&255)+151*(colUp>>8&255)+28*(colUp&255);lumDown=77*(colDown>>16&255)+151*(colDown>>8&255)+28*(colDown&255);if(lumLeft<currLum){colOut=colLeft;currLum=lumLeft}if(lumRight<currLum){colOut=colRight;currLum=lumRight}if(lumUp<currLum){colOut=colUp;currLum=lumUp}if(lumDown<currLum){colOut=colDown;currLum=lumDown}out[currIdx++]=colOut}}}aImg.pixels.set(out)};p.filter=function filter(kind,param,aImg){var img,col,lum,i;if(arguments.length===3){aImg.loadPixels();img=aImg}else{p.loadPixels();img=p}if(param===undef){param=null}if(img.isRemote){throw"Image is loaded remotely. Cannot filter image."}else{var imglen=img.pixels.getLength();switch(kind){case PConstants.BLUR:var radius=param||1;blurARGB(radius,img);break;case PConstants.GRAY:if(img.format===PConstants.ALPHA){for(i=0;i<imglen;i++){col=255-img.pixels.getPixel(i);img.pixels.setPixel(i,(4278190080|(col<<16)|(col<<8)|col))}img.format=PConstants.RGB}else{for(i=0;i<imglen;i++){col=img.pixels.getPixel(i);lum=(77*(col>>16&255)+151*(col>>8&255)+28*(col&255))>>8;img.pixels.setPixel(i,((col&PConstants.ALPHA_MASK)|lum<<16|lum<<8|lum))}}break;case PConstants.INVERT:for(i=0;i<imglen;i++){img.pixels.setPixel(i,(img.pixels.getPixel(i)^16777215))}break;case PConstants.POSTERIZE:if(param===null){throw"Use filter(POSTERIZE, int levels) instead of filter(POSTERIZE)"}var levels=p.floor(param);if((levels<2)||(levels>255)){throw"Levels must be between 2 and 255 for filter(POSTERIZE, levels)"}var levels1=levels-1;for(i=0;i<imglen;i++){var rlevel=(img.pixels.getPixel(i)>>16)&255;var glevel=(img.pixels.getPixel(i)>>8)&255;var blevel=img.pixels.getPixel(i)&255;rlevel=(((rlevel*levels)>>8)*255)/levels1;glevel=(((glevel*levels)>>8)*255)/levels1;blevel=(((blevel*levels)>>8)*255)/levels1;img.pixels.setPixel(i,((4278190080&img.pixels.getPixel(i))|(rlevel<<16)|(glevel<<8)|blevel))}break;case PConstants.OPAQUE:for(i=0;i<imglen;i++){img.pixels.setPixel(i,(img.pixels.getPixel(i)|4278190080))}img.format=PConstants.RGB;break;case PConstants.THRESHOLD:if(param===null){param=0.5}if((param<0)||(param>1)){throw"Level must be between 0 and 1 for filter(THRESHOLD, level)"}var thresh=p.floor(param*255);for(i=0;i<imglen;i++){var max=p.max((img.pixels.getPixel(i)&PConstants.RED_MASK)>>16,p.max((img.pixels.getPixel(i)&PConstants.GREEN_MASK)>>8,(img.pixels.getPixel(i)&PConstants.BLUE_MASK)));img.pixels.setPixel(i,((img.pixels.getPixel(i)&PConstants.ALPHA_MASK)|((max<thresh)?0:16777215)))}break;case PConstants.ERODE:dilate(true,img);break;case PConstants.DILATE:dilate(false,img);break}img.updatePixels()}};p.shared={fracU:0,ifU:0,fracV:0,ifV:0,u1:0,u2:0,v1:0,v2:0,sX:0,sY:0,iw:0,iw1:0,ih1:0,ul:0,ll:0,ur:0,lr:0,cUL:0,cLL:0,cUR:0,cLR:0,srcXOffset:0,srcYOffset:0,r:0,g:0,b:0,a:0,srcBuffer:null,blurRadius:0,blurKernelSize:0,blurKernel:null};p.intersect=function intersect(sx1,sy1,sx2,sy2,dx1,dy1,dx2,dy2){var sw=sx2-sx1+1;var sh=sy2-sy1+1;var dw=dx2-dx1+1;var dh=dy2-dy1+1;if(dx1<sx1){dw+=dx1-sx1;if(dw>sw){dw=sw}}else{var w=sw+sx1-dx1;if(dw>w){dw=w}}if(dy1<sy1){dh+=dy1-sy1;if(dh>sh){dh=sh}}else{var h=sh+sy1-dy1;if(dh>h){dh=h}}return !(dw<=0||dh<=0)};p.filter_new_scanline=function filter_new_scanline(){p.shared.sX=p.shared.srcXOffset;p.shared.fracV=p.shared.srcYOffset&PConstants.PREC_MAXVAL;p.shared.ifV=PConstants.PREC_MAXVAL-p.shared.fracV;p.shared.v1=(p.shared.srcYOffset>>PConstants.PRECISIONB)*p.shared.iw;p.shared.v2=Math.min((p.shared.srcYOffset>>PConstants.PRECISIONB)+1,p.shared.ih1)*p.shared.iw};p.filter_bilinear=function filter_bilinear(){p.shared.fracU=p.shared.sX&PConstants.PREC_MAXVAL;p.shared.ifU=PConstants.PREC_MAXVAL-p.shared.fracU;p.shared.ul=(p.shared.ifU*p.shared.ifV)>>PConstants.PRECISIONB;p.shared.ll=(p.shared.ifU*p.shared.fracV)>>PConstants.PRECISIONB;p.shared.ur=(p.shared.fracU*p.shared.ifV)>>PConstants.PRECISIONB;p.shared.lr=(p.shared.fracU*p.shared.fracV)>>PConstants.PRECISIONB;p.shared.u1=(p.shared.sX>>PConstants.PRECISIONB);p.shared.u2=Math.min(p.shared.u1+1,p.shared.iw1);var cULoffset=(p.shared.v1+p.shared.u1)*4;var cURoffset=(p.shared.v1+p.shared.u2)*4;var cLLoffset=(p.shared.v2+p.shared.u1)*4;var cLRoffset=(p.shared.v2+p.shared.u2)*4;p.shared.cUL=p.color.toInt(p.shared.srcBuffer[cULoffset],p.shared.srcBuffer[cULoffset+1],p.shared.srcBuffer[cULoffset+2],p.shared.srcBuffer[cULoffset+3]);p.shared.cUR=p.color.toInt(p.shared.srcBuffer[cURoffset],p.shared.srcBuffer[cURoffset+1],p.shared.srcBuffer[cURoffset+2],p.shared.srcBuffer[cURoffset+3]);p.shared.cLL=p.color.toInt(p.shared.srcBuffer[cLLoffset],p.shared.srcBuffer[cLLoffset+1],p.shared.srcBuffer[cLLoffset+2],p.shared.srcBuffer[cLLoffset+3]);p.shared.cLR=p.color.toInt(p.shared.srcBuffer[cLRoffset],p.shared.srcBuffer[cLRoffset+1],p.shared.srcBuffer[cLRoffset+2],p.shared.srcBuffer[cLRoffset+3]);p.shared.r=((p.shared.ul*((p.shared.cUL&PConstants.RED_MASK)>>16)+p.shared.ll*((p.shared.cLL&PConstants.RED_MASK)>>16)+p.shared.ur*((p.shared.cUR&PConstants.RED_MASK)>>16)+p.shared.lr*((p.shared.cLR&PConstants.RED_MASK)>>16))<<PConstants.PREC_RED_SHIFT)&PConstants.RED_MASK;p.shared.g=((p.shared.ul*(p.shared.cUL&PConstants.GREEN_MASK)+p.shared.ll*(p.shared.cLL&PConstants.GREEN_MASK)+p.shared.ur*(p.shared.cUR&PConstants.GREEN_MASK)+p.shared.lr*(p.shared.cLR&PConstants.GREEN_MASK))>>>PConstants.PRECISIONB)&PConstants.GREEN_MASK;p.shared.b=(p.shared.ul*(p.shared.cUL&PConstants.BLUE_MASK)+p.shared.ll*(p.shared.cLL&PConstants.BLUE_MASK)+p.shared.ur*(p.shared.cUR&PConstants.BLUE_MASK)+p.shared.lr*(p.shared.cLR&PConstants.BLUE_MASK))>>>PConstants.PRECISIONB;p.shared.a=((p.shared.ul*((p.shared.cUL&PConstants.ALPHA_MASK)>>>24)+p.shared.ll*((p.shared.cLL&PConstants.ALPHA_MASK)>>>24)+p.shared.ur*((p.shared.cUR&PConstants.ALPHA_MASK)>>>24)+p.shared.lr*((p.shared.cLR&PConstants.ALPHA_MASK)>>>24))<<PConstants.PREC_ALPHA_SHIFT)&PConstants.ALPHA_MASK;return p.shared.a|p.shared.r|p.shared.g|p.shared.b};p.blit_resize=function blit_resize(img,srcX1,srcY1,srcX2,srcY2,destPixels,screenW,screenH,destX1,destY1,destX2,destY2,mode){var x,y;if(srcX1<0){srcX1=0}if(srcY1<0){srcY1=0}if(srcX2>=img.width){srcX2=img.width-1}if(srcY2>=img.height){srcY2=img.height-1}var srcW=srcX2-srcX1;var srcH=srcY2-srcY1;var destW=destX2-destX1;var destH=destY2-destY1;var smooth=true;if(!smooth){srcW++;srcH++}if(destW<=0||destH<=0||srcW<=0||srcH<=0||destX1>=screenW||destY1>=screenH||srcX1>=img.width||srcY1>=img.height){return}var dx=Math.floor(srcW/destW*PConstants.PRECISIONF);var dy=Math.floor(srcH/destH*PConstants.PRECISIONF);p.shared.srcXOffset=Math.floor(destX1<0?-destX1*dx:srcX1*PConstants.PRECISIONF);p.shared.srcYOffset=Math.floor(destY1<0?-destY1*dy:srcY1*PConstants.PRECISIONF);if(destX1<0){destW+=destX1;destX1=0}if(destY1<0){destH+=destY1;destY1=0}destW=Math.min(destW,screenW-destX1);destH=Math.min(destH,screenH-destY1);var destOffset=destY1*screenW+destX1;var destColor;p.shared.srcBuffer=img.imageData.data;if(smooth){p.shared.iw=img.width;p.shared.iw1=img.width-1;p.shared.ih1=img.height-1;switch(mode){case PConstants.BLEND:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.blend(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.ADD:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.add(destColor,p.filter_bilinear()));destColor=p.color.toArray(p.modes.add(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.SUBTRACT:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.subtract(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.LIGHTEST:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.lightest(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.DARKEST:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.darkest(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.REPLACE:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.filter_bilinear());destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.DIFFERENCE:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.difference(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.EXCLUSION:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.exclusion(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.MULTIPLY:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.multiply(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.SCREEN:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.screen(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.OVERLAY:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.overlay(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.HARD_LIGHT:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.hard_light(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.SOFT_LIGHT:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.soft_light(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.DODGE:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.dodge(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break;case PConstants.BURN:for(y=0;y<destH;y++){p.filter_new_scanline();for(x=0;x<destW;x++){destColor=p.color.toInt(destPixels[(destOffset+x)*4],destPixels[((destOffset+x)*4)+1],destPixels[((destOffset+x)*4)+2],destPixels[((destOffset+x)*4)+3]);destColor=p.color.toArray(p.modes.burn(destColor,p.filter_bilinear()));destPixels[(destOffset+x)*4]=destColor[0];destPixels[(destOffset+x)*4+1]=destColor[1];destPixels[(destOffset+x)*4+2]=destColor[2];destPixels[(destOffset+x)*4+3]=destColor[3];p.shared.sX+=dx}destOffset+=screenW;p.shared.srcYOffset+=dy}break}}};function PFont(name){this.name="sans-serif";if(name!==undef){switch(name){case"sans-serif":case"serif":case"monospace":case"fantasy":case"cursive":this.name=name;break;default:this.name='"'+name+'", sans-serif';break}}this.origName=name}PFont.prototype.width=function(str){if("measureText" in curContext){return curContext.measureText(typeof str==="number"?String.fromCharCode(str):str).width/curTextSize}else{if("mozMeasureText" in curContext){return curContext.mozMeasureText(typeof str==="number"?String.fromCharCode(str):str)/curTextSize}else{return 0}}};PFont.list=function(){return["sans-serif","serif","monospace","fantasy","cursive"]};p.PFont=PFont;p.loadFont=function loadFont(name){if(name===undef||name.indexOf(".svg")===-1){return new PFont(name)}else{var font=p.loadGlyphs(name);return{name:name,glyph:true,units_per_em:font.units_per_em,horiz_adv_x:1/font.units_per_em*font.horiz_adv_x,ascent:font.ascent,descent:font.descent,width:function(str){var width=0;var len=str.length;for(var i=0;i<len;i++){try{width+=parseFloat(p.glyphLook(p.glyphTable[name],str[i]).horiz_adv_x)}catch(e){Processing.debug(e)}}return width/p.glyphTable[name].units_per_em}}}};p.createFont=function(name,size,smooth,charset){if(arguments.length===2){p.textSize(size);return p.loadFont(name)}else{if(arguments.length===3){p.textSize(size);return p.loadFont(name)}else{if(arguments.length===4){p.textSize(size);return p.loadFont(name)}else{throw ("incorrent number of parameters for createFont")}}}};p.textFont=function textFont(font,size){curTextFont=font;if(size){p.textSize(size)}else{curContext.font=curContext.mozTextStyle=curTextSize+"px "+curTextFont.name}};p.textSize=function textSize(size){if(size){curTextSize=size;curContext.font=curContext.mozTextStyle=curTextSize+"px "+curTextFont.name}};p.textAlign=function textAlign(){if(arguments.length===1){horizontalTextAlignment=arguments[0]}else{if(arguments.length===2){horizontalTextAlignment=arguments[0];verticalTextAlignment=arguments[1]}}};p.textWidth=function textWidth(str){if(p.use3DContext){if(textcanvas===undef){textcanvas=document.createElement("canvas")}var oldContext=curContext;curContext=textcanvas.getContext("2d");curContext.font=curContext.mozTextStyle=curTextSize+"px "+curTextFont.name;if("fillText" in curContext){textcanvas.width=curContext.measureText(str).width}else{if("mozDrawText" in curContext){textcanvas.width=curContext.mozMeasureText(str)}}curContext=oldContext;return textcanvas.width}else{curContext.font=curTextSize+"px "+curTextFont.name;if("fillText" in curContext){return curContext.measureText(str).width}else{if("mozDrawText" in curContext){return curContext.mozMeasureText(str)}}}};p.textLeading=function textLeading(leading){curTextLeading=leading};var measureTextCanvas=function(fontFace,fontSize,baseLine,text){this.canvas=document.createElement("canvas");this.canvas.setAttribute("width",fontSize+"px");this.canvas.setAttribute("height",fontSize+"px");this.ctx=this.canvas.getContext("2d");this.ctx.font=fontSize+"pt "+fontFace;this.ctx.fillStyle="black";this.ctx.fillRect(0,0,fontSize,fontSize);this.ctx.fillStyle="white";this.ctx.fillText(text,0,baseLine);this.imageData=this.ctx.getImageData(0,0,fontSize,fontSize);this.get=function(x,y){return this.imageData.data[((y*(this.imageData.width*4))+(x*4))]}};p.textAscent=(function(){var oldTextSize=undef,oldTextFont=undef,ascent=undef,graphics=undef;return function textAscent(){if(oldTextFont!==curTextFont||oldTextSize!==curTextSize){oldTextFont=curTextFont;oldTextSize=curTextSize;var found=false,character="k",colour=p.color(0),top=0,bottom=curTextSize,yLoc=curTextSize/2;graphics=new measureTextCanvas(curTextFont.name,curTextSize,curTextSize,character);while(yLoc!==bottom){for(var xLoc=0;xLoc<curTextSize;xLoc++){if(graphics.get(xLoc,yLoc)!==colour){found=true;xLoc=curTextSize}}if(found){bottom=yLoc;found=false}else{top=yLoc}yLoc=Math.ceil((bottom+top)/2)}ascent=((curTextSize-1)-yLoc)+1;return ascent}else{return ascent}}}());p.textDescent=(function(){var oldTextSize=undef,oldTextFont=undef,descent=undef,graphics=undef;return function textDescent(){if(oldTextFont!==curTextFont||oldTextSize!==curTextSize){oldTextFont=curTextFont;oldTextSize=curTextSize;var found=false,character="p",colour=p.color(0),top=0,bottom=curTextSize,yLoc=curTextSize/2;graphics=new measureTextCanvas(curTextFont.name,curTextSize,0,character);while(yLoc!==bottom){for(var xLoc=0;xLoc<curTextSize;xLoc++){if(graphics.get(xLoc,yLoc)!==colour){found=true;xLoc=curTextSize}}if(found){top=yLoc;found=false}else{bottom=yLoc}yLoc=Math.ceil((bottom+top)/2)}descent=yLoc+1;return descent}else{return descent}}}());p.glyphLook=function glyphLook(font,chr){try{switch(chr){case"1":return font.one;case"2":return font.two;case"3":return font.three;case"4":return font.four;case"5":return font.five;case"6":return font.six;case"7":return font.seven;case"8":return font.eight;case"9":return font.nine;case"0":return font.zero;case" ":return font.space;case"$":return font.dollar;case"!":return font.exclam;case'"':return font.quotedbl;case"#":return font.numbersign;case"%":return font.percent;case"&":return font.ampersand;case"'":return font.quotesingle;case"(":return font.parenleft;case")":return font.parenright;case"*":return font.asterisk;case"+":return font.plus;case",":return font.comma;case"-":return font.hyphen;case".":return font.period;case"/":return font.slash;case"_":return font.underscore;case":":return font.colon;case";":return font.semicolon;case"<":return font.less;case"=":return font.equal;case">":return font.greater;case"?":return font.question;case"@":return font.at;case"[":return font.bracketleft;case"\\":return font.backslash;case"]":return font.bracketright;case"^":return font.asciicircum;case"`":return font.grave;case"{":return font.braceleft;case"|":return font.bar;case"}":return font.braceright;case"~":return font.asciitilde;default:return font[chr]}}catch(e){Processing.debug(e)}};function toP5String(obj){if(obj instanceof String){return obj}else{if(typeof obj==="number"){if(obj===(0|obj)){return obj.toString()}else{return p.nf(obj,0,3)}}else{if(obj===null||obj===undef){return""}else{return obj.toString()}}}}function text$line(str,x,y,z,align){var textWidth=0,xOffset=0;if(!curTextFont.glyph){if(str&&("fillText" in curContext||"mozDrawText" in curContext)){if(isFillDirty){curContext.fillStyle=p.color.toString(currentFillColor);isFillDirty=false}if(align===PConstants.RIGHT||align===PConstants.CENTER){if("fillText" in curContext){textWidth=curContext.measureText(str).width}else{if("mozDrawText" in curContext){textWidth=curContext.mozMeasureText(str)}}if(align===PConstants.RIGHT){xOffset=-textWidth}else{xOffset=-textWidth/2}}if("fillText" in curContext){curContext.fillText(str,x+xOffset,y)}else{if("mozDrawText" in curContext){saveContext();curContext.translate(x+xOffset,y);curContext.mozDrawText(str);restoreContext()}}}}else{var font=p.glyphTable[curTextFont.name];saveContext();curContext.translate(x,y+curTextSize);if(align===PConstants.RIGHT||align===PConstants.CENTER){textWidth=font.width(str);if(align===PConstants.RIGHT){xOffset=-textWidth}else{xOffset=-textWidth/2}}var upem=font.units_per_em,newScale=1/upem*curTextSize;curContext.scale(newScale,newScale);for(var i=0,len=str.length;i<len;i++){try{p.glyphLook(font,str[i]).draw()}catch(e){Processing.debug(e)}}restoreContext()}}function text$line$3d(str,x,y,z,align){if(textcanvas===undef){textcanvas=document.createElement("canvas")}var oldContext=curContext;curContext=textcanvas.getContext("2d");curContext.font=curContext.mozTextStyle=curTextSize+"px "+curTextFont.name;var textWidth=0;if("fillText" in curContext){textWidth=curContext.measureText(str).width}else{if("mozDrawText" in curContext){textWidth=curContext.mozMeasureText(str)}}textcanvas.width=textWidth;textcanvas.height=curTextSize;curContext=textcanvas.getContext("2d");curContext.font=curContext.mozTextStyle=curTextSize+"px "+curTextFont.name;curContext.textBaseline="top";text$line(str,0,0,0,PConstants.LEFT);var aspect=textcanvas.width/textcanvas.height;curContext=oldContext;curContext.bindTexture(curContext.TEXTURE_2D,textTex);executeTexImage2D(textcanvas);curContext.texParameteri(curContext.TEXTURE_2D,curContext.TEXTURE_MAG_FILTER,curContext.LINEAR);curContext.texParameteri(curContext.TEXTURE_2D,curContext.TEXTURE_MIN_FILTER,curContext.LINEAR);curContext.texParameteri(curContext.TEXTURE_2D,curContext.TEXTURE_WRAP_T,curContext.CLAMP_TO_EDGE);curContext.texParameteri(curContext.TEXTURE_2D,curContext.TEXTURE_WRAP_S,curContext.CLAMP_TO_EDGE);var xOffset=0;if(align===PConstants.RIGHT){xOffset=-textWidth}else{if(align===PConstants.CENTER){xOffset=-textWidth/2}}var model=new PMatrix3D();var scalefactor=curTextSize*0.5;model.translate(x+xOffset-scalefactor/2,y-scalefactor,z);model.scale(-aspect*scalefactor,-scalefactor,scalefactor);model.translate(-1,-1,-1);model.transpose();var view=new PMatrix3D();view.scale(1,-1,1);view.apply(modelView.array());view.transpose();var proj=new PMatrix3D();proj.set(projection);proj.transpose();curContext.useProgram(programObject2D);vertexAttribPointer("vertex2d",programObject2D,"Vertex",3,textBuffer);vertexAttribPointer("aTextureCoord2d",programObject2D,"aTextureCoord",2,textureBuffer);uniformi("uSampler2d",programObject2D,"uSampler",[0]);uniformi("picktype2d",programObject2D,"picktype",1);uniformMatrix("model2d",programObject2D,"model",false,model.array());uniformMatrix("view2d",programObject2D,"view",false,view.array());uniformMatrix("projection2d",programObject2D,"projection",false,proj.array());uniformf("color2d",programObject2D,"color",fillStyle);curContext.bindBuffer(curContext.ELEMENT_ARRAY_BUFFER,indexBuffer);curContext.drawElements(curContext.TRIANGLES,6,curContext.UNSIGNED_SHORT,0)}function text$4(str,x,y,z){var lineFunction=p.use3DContext?text$line$3d:text$line;var lines,linesCount;if(str.indexOf("\n")<0){lines=[str];linesCount=1}else{lines=str.split(/\r?\n/g);linesCount=lines.length}var yOffset;if(verticalTextAlignment===PConstants.TOP){yOffset=(1-baselineOffset)*curTextLeading}else{if(verticalTextAlignment===PConstants.CENTER){yOffset=(1-baselineOffset-linesCount/2)*curTextLeading}else{if(verticalTextAlignment===PConstants.BOTTOM){yOffset=(1-baselineOffset-linesCount)*curTextLeading}else{yOffset=0}}}for(var i=0;i<linesCount;++i){var line=lines[i];lineFunction(line,x,y+yOffset,z,horizontalTextAlignment);yOffset+=curTextLeading}}function text$6(str,x,y,width,height,z){if(str.length===0){return}if(curTextSize>height){return}curContext.font=curTextSize+"px "+curTextFont.name;var spaceLoc=null,yOffset=0,lineWidth=0,letterWidth=0,strings=str.split("\n");for(var j=0;j<strings.length;j++){for(var jj=0;jj<strings[j].length;jj++){if("fillText" in curContext){letterWidth=curContext.measureText(strings[j][jj]).width}else{if("mozDrawText" in curContext){letterWidth=curContext.mozMeasureText(strings[j][jj])}}lineWidth+=letterWidth;if(strings[j][jj]===" "){spaceLoc=jj}if(lineWidth>=width&&strings[j][jj]!==" "){if(spaceLoc===null){spaceLoc=jj}strings.splice(j,1,strings[j].substring(0,spaceLoc+1),strings[j].substring(spaceLoc+1));spaceLoc=null}}lineWidth=letterWidth=0}var lineFunction=p.use3DContext?text$line$3d:text$line;var xOffset=0;if(horizontalTextAlignment===PConstants.CENTER){xOffset=width/2}else{if(horizontalTextAlignment===PConstants.RIGHT){xOffset=width}}var boxYOffset1=(1-baselineOffset)*curTextSize,boxYOffset2=0;if(verticalTextAlignment===PConstants.BOTTOM){boxYOffset2=height-(strings.length*curTextLeading)}else{if(verticalTextAlignment===PConstants.CENTER){boxYOffset2=(height-(strings.length*curTextLeading))/2}}for(var il=0,ll=strings.length;il<ll;++il,yOffset+=curTextLeading){if(yOffset+boxYOffset2<0){continue}if(yOffset+boxYOffset2+curTextLeading>height){break}lineFunction(strings[il],x+xOffset,y+yOffset+boxYOffset1+boxYOffset2,z,horizontalTextAlignment)}}p.text=function text(){if(tMode===PConstants.SCREEN){p.pushMatrix();p.resetMatrix();var asc=p.textAscent();var des=p.textDescent();var tWidth=p.textWidth(arguments[0]);var tHeight=asc+des;var font=p.loadFont(curTextFont.origName);var hud=p.createGraphics(tWidth,tHeight);hud.beginDraw();hud.fill(currentFillColor);hud.opaque=false;hud.background(0,0,0,0);hud.textFont(font);hud.textSize(curTextSize);hud.text(arguments[0],0,asc);hud.endDraw();if(arguments.length===5||arguments.length===6){p.image(hud,arguments[1],arguments[2]-asc,arguments[3],arguments[4])}else{p.image(hud,arguments[1],arguments[2]-asc)}p.popMatrix()}else{if(tMode===PConstants.SHAPE){}else{if(arguments.length===3){text$4(toP5String(arguments[0]),arguments[1],arguments[2],0)}else{if(arguments.length===4){text$4(toP5String(arguments[0]),arguments[1],arguments[2],arguments[3])}else{if(arguments.length===5){text$6(toP5String(arguments[0]),arguments[1],arguments[2],arguments[3],arguments[4],0)}else{if(arguments.length===6){text$6(toP5String(arguments[0]),arguments[1],arguments[2],arguments[3],arguments[4],arguments[5])}}}}}}};p.textMode=function textMode(mode){tMode=mode};p.loadGlyphs=function loadGlyph(url){var x,y,cx,cy,nx,ny,d,a,lastCom,lenC,horiz_adv_x,getXY="[0-9\\-]+",path;var regex=function regex(needle,hay){var i=0,results=[],latest,regexp=new RegExp(needle,"g");latest=results[i]=regexp.exec(hay);while(latest){i++;latest=results[i]=regexp.exec(hay)}return results};var buildPath=function buildPath(d){var c=regex("[A-Za-z][0-9\\- ]+|Z",d);path="var path={draw:function(){saveContext();curContext.beginPath();";x=0;y=0;cx=0;cy=0;nx=0;ny=0;d=0;a=0;lastCom="";lenC=c.length-1;for(var j=0;j<lenC;j++){var com=c[j][0],xy=regex(getXY,com);switch(com[0]){case"M":x=parseFloat(xy[0][0]);y=parseFloat(xy[1][0]);path+="curContext.moveTo("+x+","+(-y)+");";break;case"L":x=parseFloat(xy[0][0]);y=parseFloat(xy[1][0]);path+="curContext.lineTo("+x+","+(-y)+");";break;case"H":x=parseFloat(xy[0][0]);path+="curContext.lineTo("+x+","+(-y)+");";break;case"V":y=parseFloat(xy[0][0]);path+="curContext.lineTo("+x+","+(-y)+");";break;case"T":nx=parseFloat(xy[0][0]);ny=parseFloat(xy[1][0]);if(lastCom==="Q"||lastCom==="T"){d=Math.sqrt(Math.pow(x-cx,2)+Math.pow(cy-y,2));a=Math.PI+Math.atan2(cx-x,cy-y);cx=x+(Math.sin(a)*(d));cy=y+(Math.cos(a)*(d))}else{cx=x;cy=y}path+="curContext.quadraticCurveTo("+cx+","+(-cy)+","+nx+","+(-ny)+");";x=nx;y=ny;break;case"Q":cx=parseFloat(xy[0][0]);cy=parseFloat(xy[1][0]);nx=parseFloat(xy[2][0]);ny=parseFloat(xy[3][0]);path+="curContext.quadraticCurveTo("+cx+","+(-cy)+","+nx+","+(-ny)+");";x=nx;y=ny;break;case"Z":path+="curContext.closePath();";break}lastCom=com[0]}path+="executeContextFill();executeContextStroke();";path+="restoreContext();";path+="curContext.translate("+horiz_adv_x+",0);";path+="}}";return path};var parseSVGFont=function parseSVGFontse(svg){var font=svg.getElementsByTagName("font");p.glyphTable[url].horiz_adv_x=font[0].getAttribute("horiz-adv-x");var font_face=svg.getElementsByTagName("font-face")[0];p.glyphTable[url].units_per_em=parseFloat(font_face.getAttribute("units-per-em"));p.glyphTable[url].ascent=parseFloat(font_face.getAttribute("ascent"));p.glyphTable[url].descent=parseFloat(font_face.getAttribute("descent"));var glyph=svg.getElementsByTagName("glyph"),len=glyph.length;for(var i=0;i<len;i++){var unicode=glyph[i].getAttribute("unicode");var name=glyph[i].getAttribute("glyph-name");horiz_adv_x=glyph[i].getAttribute("horiz-adv-x");if(horiz_adv_x===null){horiz_adv_x=p.glyphTable[url].horiz_adv_x}d=glyph[i].getAttribute("d");if(d!==undef){path=buildPath(d);eval(path);p.glyphTable[url][name]={name:name,unicode:unicode,horiz_adv_x:horiz_adv_x,draw:path.draw}}}};var loadXML=function loadXML(){var xmlDoc;try{xmlDoc=document.implementation.createDocument("","",null)}catch(e_fx_op){Processing.debug(e_fx_op.message);return}try{xmlDoc.async=false;xmlDoc.load(url);parseSVGFont(xmlDoc.getElementsByTagName("svg")[0])}catch(e_sf_ch){Processing.debug(e_sf_ch);try{var xmlhttp=new window.XMLHttpRequest();xmlhttp.open("GET",url,false);xmlhttp.send(null);parseSVGFont(xmlhttp.responseXML.documentElement)}catch(e){Processing.debug(e_sf_ch)}}};p.glyphTable[url]={};loadXML(url);return p.glyphTable[url]};function extendClass(subClass,baseClass){function extendGetterSetter(propertyName){p.defineProperty(subClass,propertyName,{get:function(){return baseClass[propertyName]},set:function(v){baseClass[propertyName]=v},enumerable:true})}var properties=[];for(var propertyName in baseClass){if(!(propertyName in subClass)){if(typeof baseClass[propertyName]==="function"){subClass[propertyName]=baseClass[propertyName]}else{if(propertyName!=="$upcast"){properties.push(propertyName)}}}}while(properties.length>0){extendGetterSetter(properties.shift())}}p.extendClassChain=function(base){var path=[base];for(var self=base.$upcast;self;self=self.$upcast){extendClass(self,base);path.push(self);base=self}while(path.length>0){path.pop().$self=base}};p.addMethod=function addMethod(object,name,fn,superAccessor){if(object[name]){var args=fn.length,oldfn=object[name];object[name]=function(){if(arguments.length===args){return fn.apply(this,arguments)}else{return oldfn.apply(this,arguments)}}}else{object[name]=fn}};p.createJavaArray=function createJavaArray(type,bounds){var result=null;if(typeof bounds[0]==="number"){var itemsCount=0|bounds[0];if(bounds.length<=1){if(type==="int"){result=new Int32Array(itemsCount)}else{if(type==="float"){result=new Float32Array(itemsCount)}else{result=new Array(itemsCount)}}for(var i=0;i<itemsCount;++i){result[i]=0}}else{result=[];var newBounds=bounds.slice(1);for(var j=0;j<itemsCount;++j){result.push(createJavaArray(type,newBounds))}}}return result};function attach(elem,type,fn){if(elem.addEventListener){elem.addEventListener(type,fn,false)}else{elem.attachEvent("on"+type,fn)}eventHandlers.push([elem,type,fn])}attach(curElement,"mousemove",function(e){var element=curElement,offsetX=0,offsetY=0;p.pmouseX=p.mouseX;p.pmouseY=p.mouseY;if(element.offsetParent){do{offsetX+=element.offsetLeft;offsetY+=element.offsetTop}while((element=element.offsetParent))}element=curElement;do{offsetX-=element.scrollLeft||0;offsetY-=element.scrollTop||0}while((element=element.parentNode));offsetX+=stylePaddingLeft;offsetY+=stylePaddingTop;offsetX+=styleBorderLeft;offsetY+=styleBorderTop;p.mouseX=e.clientX-offsetX;p.mouseY=e.clientY-offsetY;if(typeof p.mouseMoved==="function"&&!p.__mousePressed){p.mouseMoved()}if(typeof p.mouseDragged==="function"&&p.__mousePressed){p.mouseDragged();p.mouseDragging=true}});attach(curElement,"mouseout",function(e){});attach(curElement,"mousedown",function(e){p.__mousePressed=true;p.mouseDragging=false;switch(e.which){case 1:p.mouseButton=PConstants.LEFT;break;case 2:p.mouseButton=PConstants.CENTER;break;case 3:p.mouseButton=PConstants.RIGHT;break}if(typeof p.mousePressed==="function"){p.mousePressed()}});attach(curElement,"mouseup",function(e){p.__mousePressed=false;if(typeof p.mouseClicked==="function"&&!p.mouseDragging){p.mouseClicked()}if(typeof p.mouseReleased==="function"){p.mouseReleased()}});var mouseWheelHandler=function(e){var delta=0;if(e.wheelDelta){delta=e.wheelDelta/120;if(window.opera){delta=-delta}}else{if(e.detail){delta=-e.detail/3}}p.mouseScroll=delta;if(delta&&typeof p.mouseScrolled==="function"){p.mouseScrolled()}};attach(document,"DOMMouseScroll",mouseWheelHandler);attach(document,"mousewheel",mouseWheelHandler);function keyCodeMap(code){if(codedKeys.indexOf(code)>=0){p.keyCode=code;if(code===p.INS){p.keyCode=155}return PConstants.CODED}switch(code){case 13:return 10;case 46:return 127}return code}function charCodeMap(code,shift){if(code>=65&&code<=90){if(shift){return code}else{return code+32}}else{if(code>=48&&code<=57){if(shift){switch(code){case 49:return 33;case 50:return 64;case 51:return 35;case 52:return 36;case 53:return 37;case 54:return 94;case 55:return 38;case 56:return 42;case 57:return 40;case 48:return 41}}}else{if(shift){switch(code){case 107:return 43;case 219:return 123;case 221:return 125;case 222:return 34}}else{switch(code){case 188:return 44;case 109:return 45;case 190:return 46;case 191:return 47;case 192:return 96;case 219:return 91;case 220:return 92;case 221:return 93;case 222:return 39}}}}return code}function normalKeyDown(){var tempKeyCode;p.keyPressed();tempKeyCode=p.keyCode;p.keyCode=0;p.keyTyped();p.keyCode=tempKeyCode}function refireKeyDown(){var tempKeyCode;p.keyPressed();tempKeyCode=p.keyCode;p.keyCode=0;p.keyTyped();p.keyCode=tempKeyCode}function keyFunc(e,type){var tempKeyCode;p.key=keyCodeMap(e.keyCode,e.shiftKey);if(type==="keypress"){if(e.keyCode===e.charCode){p.keyCode=-1}}switch(p.keyCode){case 19:case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 45:case 112:case 113:case 114:case 115:case 116:case 117:case 118:case 119:case 120:case 121:case 122:case 123:case 145:case 155:case 224:case 225:case 226:case 227:if(type==="keydown"){if(gRefire){p.keyReleased();p.keyPressed()}else{p.keyPressed();gRefire=true}}else{if(type==="keypress"){if(firstCodedDown){firstCodedDown=false}else{p.keyReleased();p.keyPressed()}}else{if(type==="keyup"){p.keyReleased();if(firstCodedDown===false){firstCodedDown=true}if(gRefire){gRefire=false}}}}break;case 16:case 17:case 18:case 20:case 144:if(type==="keydown"){p.keyPressed()}else{if(type==="keyup"){p.keyReleased()}}break;case 46:case 13:if(type==="keydown"){if(firstEDGKeyDown===true){firstEDGKeyDown=false;normalKeyDown()}else{refireKeyDown()}}else{if(type==="keypress"){if(firstEDMKeyDown===true){firstEDMKeyDown=false}else{refireKeyDown()}}else{if(type==="keyup"){p.keyCode=e.keyCode;p.keyReleased();if(firstEDGKeyDown===false){firstEDGKeyDown=true}if(firstEDMKeyDown===false){firstEDMKeyDown=true}}}}break;default:if(p.keyCode===-1){p.keyCode=e.keyCode}if(e.keyCode===0){p.key=charCodeMap(e.charCode,e.shiftKey);if(type==="keypress"){if(firstMKeyDown===true){firstMKeyDown=false}else{refireKeyDown()}}else{if(type==="keyup"){p.keyCode=e.keyCode;p.keyReleased();if(firstMKeyDown===false){firstMKeyDown=true}}}}else{p.key=charCodeMap(e.keyCode,e.shiftKey);if(type==="keydown"){if(firstGKeyDown===true){firstGKeyDown=false;normalKeyDown()}else{refireKeyDown()}}else{if(type==="keyup"){p.keyCode=e.keyCode;p.keyReleased();if(firstMKeyDown===false){firstMKeyDown=true}if(firstGKeyDown===false){firstGKeyDown=true}}}}break}}attach(document,"keydown",function(e){p.keyCode=e.keyCode;p.__keyPressed=true;p.key=keyCodeMap(e.keyCode,e.shiftKey);if(p.key!==PConstants.CODED){p.key=charCodeMap(e.keyCode,e.shiftKey)}keyFunc(e,"keydown")});attach(document,"keypress",function(e){keyFunc(e,"keypress")});attach(document,"keyup",function(e){p.keyCode=e.keyCode;p.__keyPressed=false;p.key=keyCodeMap(e.keyCode,e.shiftKey);if(p.key!==PConstants.CODED){p.key=charCodeMap(e.keyCode,e.shiftKey)}keyFunc(e,"keyup")});Processing.debug=function(e){};if(typeof curElement==="string"){curElement=document.getElementById(curElement)}if(aCode){if(aCode instanceof Processing.Sketch){curSketch=aCode}else{if(typeof aCode==="function"){curSketch=new Processing.Sketch(aCode)}else{curSketch=Processing.compile(aCode)}}p.externals.sketch=curSketch;p.use3DContext=curSketch.use3DContext;if("mozOpaque" in curElement){curElement.mozOpaque=!curSketch.options.isTransparent}if(curSketch.options.pauseOnBlur){p.externals.onfocus=function(){if(doLoop){p.loop()}};p.externals.onblur=function(){if(doLoop&&loopStarted){p.noLoop();doLoop=true}}}if(!curSketch.use3DContext){curContext=curElement.getContext("2d");p.externals.context=curContext;modelView=new PMatrix2D();curContext.translate(0.5,0.5);curContext.lineCap="round";p.stroke(0);p.fill(255);p.noSmooth();p.disableContextMenu()}for(var i in Processing.lib){if(Processing.lib.hasOwnProperty(i)){if(Processing.lib[i].hasOwnProperty("attach")){Processing.lib[i].attach(p)}else{if(Processing.lib[i] instanceof Function){Processing.lib[i].call(this)}}}}var executeSketch=function(processing){if(!curSketch.imageCache.pending&&curSketch.fonts.pending()){curSketch.attach(processing,defaultScope);if(processing.setup){processing.setup();if(!curSketch.use3DContext){curContext.setTransform(1,0,0,1,0,0)}}resetContext();if(processing.draw){if(!doLoop){processing.redraw()}else{processing.loop()}}}else{window.setTimeout(function(){executeSketch(processing)},10)}};executeSketch(p)}else{curSketch=new Processing.Sketch();curSketch.options.isTransparent=true}};Processing.prototype=defaultScope;function getGlobalMembers(){var names=["abs","acos","alpha","ambient","ambientLight","append","applyMatrix","arc","arrayCopy","asin","atan","atan2","background","beginCamera","beginDraw","beginShape","bezier","bezierDetail","bezierPoint","bezierTangent","bezierVertex","binary","blend","blendColor","blit_resize","blue","boolean","box","breakShape","brightness","byte","camera","ceil","char","Character","clear","color","colorMode","concat","console","constrain","copy","cos","createFont","createGraphics","createImage","cursor","curve","curveDetail","curvePoint","curveTangent","curveTightness","curveVertex","day","defaultColor","degrees","directionalLight","disableContextMenu","dist","draw","ellipse","ellipseMode","emissive","enableContextMenu","endCamera","endDraw","endShape","exit","exp","expand","externals","fill","filter","filter_bilinear","filter_new_scanline","float","floor","focused","frameCount","frameRate","frustum","get","glyphLook","glyphTable","green","height","hex","hint","hour","hue","image","imageMode","Import","int","intersect","join","key","keyCode","keyPressed","keyReleased","keyTyped","lerp","lerpColor","lightFalloff","lights","lightSpecular","line","link","loadBytes","loadFont","loadGlyphs","loadImage","loadPixels","loadShape","loadStrings","log","loop","mag","map","match","matchAll","max","millis","min","minute","mix","modelX","modelY","modelZ","modes","month","mouseButton","mouseClicked","mouseDragged","mouseMoved","mousePressed","mouseReleased","mouseScroll","mouseScrolled","mouseX","mouseY","name","nf","nfc","nfp","nfs","noCursor","noFill","noise","noiseDetail","noiseSeed","noLights","noLoop","norm","normal","noSmooth","noStroke","noTint","ortho","peg","perspective","PFont","PImage","pixels","PMatrix2D","PMatrix3D","PMatrixStack","pmouseX","pmouseY","point","pointLight","popMatrix","popStyle","pow","print","printCamera","println","printMatrix","printProjection","PShape","PShapeSVG","pushMatrix","pushStyle","quad","radians","random","Random","randomSeed","rect","rectMode","red","redraw","requestImage","resetMatrix","reverse","rotate","rotateX","rotateY","rotateZ","round","saturation","save","saveFrame","saveStrings","scale","screenX","screenY","screenZ","second","set","setup","shape","shapeMode","shared","shininess","shorten","sin","size","smooth","sort","specular","sphere","sphereDetail","splice","split","splitTokens","spotLight","sq","sqrt","status","str","stroke","strokeCap","strokeJoin","strokeWeight","subset","tan","text","textAlign","textAscent","textDescent","textFont","textLeading","textMode","textSize","texture","textureMode","textWidth","tint","translate","triangle","trim","unbinary","unhex","updatePixels","use3DContext","vertex","width","XMLElement","year","__frameRate","__keyPressed","__mousePressed","__int_cast"];var members={};var i,l;for(i=0,l=names.length;i<l;++i){members[names[i]]=null}for(var lib in Processing.lib){if(Processing.lib.hasOwnProperty(lib)){if(Processing.lib[lib].exports){var exportedNames=Processing.lib[lib].exports;for(i=0,l=exportedNames.length;i<l;++i){members[exportedNames[i]]=null}}}}return members}function parseProcessing(code){var globalMembers=getGlobalMembers();function splitToAtoms(code){var atoms=[];var items=code.split(/([\{\[\(\)\]\}])/);var result=items[0];var stack=[];for(var i=1;i<items.length;i+=2){var item=items[i];if(item==="["||item==="{"||item==="("){stack.push(result);result=item}else{if(item==="]"||item==="}"||item===")"){var kind=item==="}"?"A":item===")"?"B":"C";var index=atoms.length;atoms.push(result+item);result=stack.pop()+'"'+kind+(index+1)+'"'}}result+=items[i+1]}atoms.unshift(result);return atoms}function injectStrings(code,strings){return code.replace(/'(\d+)'/g,function(all,index){var val=strings[index];if(val.charAt(0)==="/"){return val}else{return(/^'((?:[^'\\\n])|(?:\\.[0-9A-Fa-f]*))'$/).test(val)?"(new $p.Character("+val+"))":val}})}function trimSpaces(string){var m1=/^\s*/.exec(string),result;if(m1[0].length===string.length){result={left:m1[0],middle:"",right:""}}else{var m2=/\s*$/.exec(string);result={left:m1[0],middle:string.substring(m1[0].length,m2.index),right:m2[0]}}result.untrim=function(t){return this.left+t+this.right};return result}function trim(string){return string.replace(/^\s+/,"").replace(/\s+$/,"")}function appendToLookupTable(table,array){for(var i=0,l=array.length;i<l;++i){table[array[i]]=null}return table}function isLookupTableEmpty(table){for(var i in table){if(table.hasOwnProperty(i)){return false}}return true}function getAtomIndex(templ){return templ.substring(2,templ.length-1)}var codeWoExtraCr=code.replace(/\r\n?|\n\r/g,"\n");var strings=[];var codeWoStrings=codeWoExtraCr.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g,function(all,quoted,aposed,regexCtx,prefix,regex,singleComment,comment){var index;if(quoted||aposed){index=strings.length;strings.push(all);return"'"+index+"'"}else{if(regexCtx){index=strings.length;strings.push(regex);return prefix+"'"+index+"'"}else{return comment!==""?" ":"\n"}}});var atoms=splitToAtoms(codeWoStrings);var replaceContext;var declaredClasses={},currentClassId,classIdSeed=0;function addAtom(text,type){var lastIndex=atoms.length;atoms.push(text);return'"'+type+lastIndex+'"'}function generateClassId(){return"class"+(++classIdSeed)}function appendClass(class_,classId,scopeId){class_.classId=classId;class_.scopeId=scopeId;declaredClasses[classId]=class_}var transformClassBody,transformStatementsBlock,transformStatements,transformMain,transformExpression;var classesRegex=/\b((?:(?:public|private|final|protected|static|abstract)\s+)*)(class|interface)\s+([A-Za-z_$][\w$]*\b)(\s+extends\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)?(\s+implements\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\b)*)?\s*("A\d+")/g;var methodsRegex=/\b((?:(?:public|private|final|protected|static|abstract|synchronized)\s+)*)((?!(?:else|new|return|throw|function|public|private|protected)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+"|;)/g;var fieldTest=/^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:else|new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*([A-Za-z_$][\w$]*\b)\s*(?:"C\d+"\s*)*([=,]|$)/;var cstrsRegex=/\b((?:(?:public|private|final|protected|static|abstract)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b)\s*("B\d+")(\s*throws\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*,\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)*)?\s*("A\d+")/g;var attrAndTypeRegex=/^((?:(?:public|private|final|protected|static)\s+)*)((?!(?:new|return|throw)\b)[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*(?:\s*"C\d+")*)\s*/;var functionsRegex=/\bfunction(?:\s+([A-Za-z_$][\w$]*))?\s*("B\d+")\s*("A\d+")/g;function extractClassesAndMethods(code){var s=code;s=s.replace(classesRegex,function(all){return addAtom(all,"E")});s=s.replace(methodsRegex,function(all){return addAtom(all,"D")});s=s.replace(functionsRegex,function(all){return addAtom(all,"H")});return s}function extractConstructors(code,className){var result=code.replace(cstrsRegex,function(all,attr,name,params,throws_,body){if(name!==className){return all}else{return addAtom(all,"G")}});return result}function AstParam(name){this.name=name}AstParam.prototype.toString=function(){return this.name};function AstParams(params){this.params=params}AstParams.prototype.getNames=function(){var names=[];for(var i=0,l=this.params.length;i<l;++i){names.push(this.params[i].name)}return names};AstParams.prototype.toString=function(){if(this.params.length===0){return"()"}var result="(";for(var i=0,l=this.params.length;i<l;++i){result+=this.params[i]+", "}return result.substring(0,result.length-2)+")"};function transformParams(params){var paramsWoPars=trim(params.substring(1,params.length-1));var result=[];if(paramsWoPars!==""){var paramList=paramsWoPars.split(",");for(var i=0;i<paramList.length;++i){var param=/\b([A-Za-z_$][\w$]*\b)\s*("[ABC][\d]*")?$/.exec(paramList[i]);result.push(new AstParam(param[1]))}}return new AstParams(result)}function preExpressionTransform(expr){var s=expr;s=s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"C\d+")+\s*("A\d+")/g,function(all,type,init){return init});s=s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\s*"B\d+")\s*("A\d+")/g,function(all,type,init){return addAtom(all,"F")});s=s.replace(functionsRegex,function(all){return addAtom(all,"H")});s=s.replace(/\bnew\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*("C\d+"(?:\s*"C\d+")*)/g,function(all,type,index){var args=index.replace(/"C(\d+)"/g,function(all,j){return atoms[j]}).replace(/\[\s*\]/g,"[null]").replace(/\s*\]\s*\[\s*/g,", ");var arrayInitializer="{"+args.substring(1,args.length-1)+"}";var createArrayArgs="('"+type+"', "+addAtom(arrayInitializer,"A")+")";return"$p.createJavaArray"+addAtom(createArrayArgs,"B")});s=s.replace(/(\.\s*length)\s*"B\d+"/g,"$1");s=s.replace(/#([0-9A-Fa-f]{6})\b/g,function(all,digits){return"0xFF"+digits});s=s.replace(/"B(\d+)"(\s*(?:[\w$']|"B))/g,function(all,index,next){var atom=atoms[index];if(!/^\(\s*[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*\s*(?:"C\d+"\s*)*\)$/.test(atom)){return all}else{if(/^\(\s*int\s*\)$/.test(atom)){return"(int)"+next}else{var indexParts=atom.split(/"C(\d+)"/g);if(indexParts.length>1){if(!/^\[\s*\]$/.test(atoms[indexParts[1]])){return all}}return""+next}}});s=s.replace(/\(int\)([^,\]\)\}\?\:\*\+\-\/\^\|\%\&\~]+)/g,function(all,arg){var trimmed=trimSpaces(arg);return trimmed.untrim("__int_cast("+trimmed.middle+")")});s=s.replace(/\bsuper(\s*"B\d+")/g,"$$superCstr$1").replace(/\bsuper(\s*\.)/g,"$$super$1");s=s.replace(/\b0+((\d*)(?:\.[\d*])?(?:[eE][\-\+]?\d+)?[fF]?)\b/,function(all,numberWo0,intPart){if(numberWo0===intPart){return all}return intPart===""?"0"+numberWo0:numberWo0});s=s.replace(/\b(\.?\d+\.?)[fF]\b/g,"$1");s=s.replace(/([^\s])%([^=\s])/g,"$1 % $2");s=s.replace(/\b(frameRate|keyPressed|mousePressed)\b(?!\s*"B)/g,"__$1");s=s.replace(/\bpixels\s*(("C(\d+)")|\.length)?(\s*=(?!=)([^,\]\)\}\?\:]+))?/g,function(all,indexOrLength,index,atomIndex,equalsPart,rightSide){if(index){var atom=atoms[atomIndex];if(equalsPart){return"pixels.setPixel"+addAtom("("+atom.substring(1,atom.length-1)+","+rightSide+")","B")}else{return"pixels.getPixel"+addAtom("("+atom.substring(1,atom.length-1)+")","B")}}else{if(indexOrLength){return"pixels.getLength"+addAtom("()","B")}else{if(equalsPart){return"pixels.set"+addAtom("("+rightSide+")","B")}else{return"pixels.toArray"+addAtom("()","B")}}}});s=s.replace(/\bthis(\s*"B\d+")/g,"$$constr$1");return s}function AstInlineClass(baseInterfaceName,body){this.baseInterfaceName=baseInterfaceName;this.body=body;body.owner=this}AstInlineClass.prototype.toString=function(){return"new (function() {\n"+this.body+"})"};function transformInlineClass(class_){var m=new RegExp(/\bnew\s*(Runnable)\s*"B\d+"\s*"A(\d+)"/).exec(class_);if(m===null){return"null"}else{var oldClassId=currentClassId,newClassId=generateClassId();currentClassId=newClassId;var inlineClass=new AstInlineClass("Runnable",transformClassBody(atoms[m[2]],m[1]));appendClass(inlineClass,newClassId,oldClassId);currentClassId=oldClassId;return inlineClass}}function AstFunction(name,params,body){this.name=name;this.params=params;this.body=body}AstFunction.prototype.toString=function(){var oldContext=replaceContext;var names=appendToLookupTable({"this":null},this.params.getNames());replaceContext=function(subject){return names.hasOwnProperty(subject.name)?subject.name:oldContext(subject)};var result="function";if(this.name){result+=" "+this.name}result+=this.params+" "+this.body;replaceContext=oldContext;return result};function transformFunction(class_){var m=new RegExp(/\b([A-Za-z_$][\w$]*)\s*"B(\d+)"\s*"A(\d+)"/).exec(class_);return new AstFunction(m[1]!=="function"?m[1]:null,transformParams(atoms[m[2]]),transformStatementsBlock(atoms[m[3]]))}function AstInlineObject(members){this.members=members}AstInlineObject.prototype.toString=function(){var oldContext=replaceContext;replaceContext=function(subject){return subject.name==="this"?"this":oldContext(subject)};var result="";for(var i=0,l=this.members.length;i<l;++i){if(this.members[i].label){result+=this.members[i].label+": "}result+=this.members[i].value.toString()+", "}replaceContext=oldContext;return result.substring(0,result.length-2)};function transformInlineObject(obj){var members=obj.split(",");for(var i=0;i<members.length;++i){var label=members[i].indexOf(":");if(label<0){members[i]={value:transformExpression(members[i])}}else{members[i]={label:trim(members[i].substring(0,label)),value:transformExpression(trim(members[i].substring(label+1)))}}}return new AstInlineObject(members)}function expandExpression(expr){if(expr.charAt(0)==="("||expr.charAt(0)==="["){return expr.charAt(0)+expandExpression(expr.substring(1,expr.length-1))+expr.charAt(expr.length-1)}else{if(expr.charAt(0)==="{"){if(/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)){return"{"+addAtom(expr.substring(1,expr.length-1),"I")+"}"}else{return"["+expandExpression(expr.substring(1,expr.length-1))+"]"}}else{var trimmed=trimSpaces(expr);var result=preExpressionTransform(trimmed.middle);result=result.replace(/"[ABC](\d+)"/g,function(all,index){return expandExpression(atoms[index])});return trimmed.untrim(result)}}}function replaceContextInVars(expr){return expr.replace(/(\.\s*)?(\b[A-Za-z_$][\w$]*\b)(\s*\.\s*(\b[A-Za-z_$][\w$]*\b)(\s*\()?)?/g,function(all,memberAccessSign,identifier,suffix,subMember,callSign){if(memberAccessSign){return all}else{var subject={name:identifier,member:subMember,callSign:!!callSign};return replaceContext(subject)+(suffix===undef?"":suffix)}})}function AstExpression(expr,transforms){this.expr=expr;this.transforms=transforms}AstExpression.prototype.toString=function(){var transforms=this.transforms;var expr=replaceContextInVars(this.expr);return expr.replace(/"!(\d+)"/g,function(all,index){return transforms[index].toString()})};transformExpression=function(expr){var transforms=[];var s=expandExpression(expr);s=s.replace(/"H(\d+)"/g,function(all,index){transforms.push(transformFunction(atoms[index]));return'"!'+(transforms.length-1)+'"'});s=s.replace(/"F(\d+)"/g,function(all,index){transforms.push(transformInlineClass(atoms[index]));return'"!'+(transforms.length-1)+'"'});s=s.replace(/"I(\d+)"/g,function(all,index){transforms.push(transformInlineObject(atoms[index]));return'"!'+(transforms.length-1)+'"'});return new AstExpression(s,transforms)};function AstVarDefinition(name,value,isDefault){this.name=name;this.value=value;this.isDefault=isDefault}AstVarDefinition.prototype.toString=function(){return this.name+" = "+this.value};function transformVarDefinition(def,defaultTypeValue){var eqIndex=def.indexOf("=");var name,value,isDefault;if(eqIndex<0){name=def;value=defaultTypeValue;isDefault=true}else{name=def.substring(0,eqIndex);value=transformExpression(def.substring(eqIndex+1));isDefault=false}return new AstVarDefinition(trim(name.replace(/(\s*"C\d+")+/g,"")),value,isDefault)}function getDefaultValueForType(type){if(type==="int"||type==="float"){return"0"}else{if(type==="boolean"){return"false"}else{if(type==="color"){return"0x00000000"}else{return"null"}}}}function AstVar(definitions,varType){this.definitions=definitions;this.varType=varType}AstVar.prototype.getNames=function(){var names=[];for(var i=0,l=this.definitions.length;i<l;++i){names.push(this.definitions[i].name)}return names};AstVar.prototype.toString=function(){return"var "+this.definitions.join(",")};function AstStatement(expression){this.expression=expression}AstStatement.prototype.toString=function(){return this.expression.toString()};function transformStatement(statement){if(fieldTest.test(statement)){var attrAndType=attrAndTypeRegex.exec(statement);var definitions=statement.substring(attrAndType[0].length).split(",");var defaultTypeValue=getDefaultValueForType(attrAndType[2]);for(var i=0;i<definitions.length;++i){definitions[i]=transformVarDefinition(definitions[i],defaultTypeValue)}return new AstVar(definitions,attrAndType[2])}else{return new AstStatement(transformExpression(statement))}}function AstForExpression(initStatement,condition,step){this.initStatement=initStatement;this.condition=condition;this.step=step}AstForExpression.prototype.toString=function(){return"("+this.initStatement+"; "+this.condition+"; "+this.step+")"};function AstForInExpression(initStatement,container){this.initStatement=initStatement;this.container=container}AstForInExpression.prototype.toString=function(){var init=this.initStatement.toString();if(init.indexOf("=")>=0){init=init.substring(0,init.indexOf("="))}return"("+init+" in "+this.container+")"};function transformForExpression(expr){var content;if(/\bin\b/.test(expr)){content=expr.substring(1,expr.length-1).split(/\bin\b/g);return new AstForInExpression(transformStatement(trim(content[0])),transformExpression(content[1]))}else{content=expr.substring(1,expr.length-1).split(";");return new AstForExpression(transformStatement(trim(content[0])),transformExpression(content[1]),transformExpression(content[2]))}}function AstInnerInterface(name){this.name=name}AstInnerInterface.prototype.toString=function(){return"this."+this.name+" = function "+this.name+"() { throw 'This is an interface'; };"};function AstInnerClass(name,body){this.name=name;this.body=body;body.owner=this}AstInnerClass.prototype.toString=function(){return"this."+this.name+" = function "+this.name+"() {\n"+this.body+"};"};function transformInnerClass(class_){var m=classesRegex.exec(class_);classesRegex.lastIndex=0;var body=atoms[getAtomIndex(m[6])];if(m[2]==="interface"){return new AstInnerInterface(m[3])}else{var oldClassId=currentClassId,newClassId=generateClassId();currentClassId=newClassId;var innerClass=new AstInnerClass(m[3],transformClassBody(body,m[3],m[4],m[5]));appendClass(innerClass,newClassId,oldClassId);currentClassId=oldClassId;return innerClass}}function AstClassMethod(name,params,body){this.name=name;this.params=params;this.body=body}AstClassMethod.prototype.toString=function(){var thisReplacement=replaceContext({name:"this"});var paramNames=appendToLookupTable({},this.params.getNames());var oldContext=replaceContext;replaceContext=function(subject){return paramNames.hasOwnProperty(subject.name)?subject.name:oldContext(subject)};var result="$p.addMethod("+thisReplacement+", '"+this.name+"', function "+this.params+" "+this.body+");";replaceContext=oldContext;return result};function transformClassMethod(method){var m=methodsRegex.exec(method);methodsRegex.lastIndex=0;var body=m[6]!==";"?atoms[getAtomIndex(m[6])]:"{}";return new AstClassMethod(m[3],transformParams(atoms[getAtomIndex(m[4])]),transformStatementsBlock(body))}function AstClassField(definitions,fieldType,isStatic){this.definitions=definitions;this.fieldType=fieldType;this.isStatic=isStatic}AstClassField.prototype.getNames=function(){var names=[];for(var i=0,l=this.definitions.length;i<l;++i){names.push(this.definitions[i].name)}return names};AstClassField.prototype.toString=function(){var thisPrefix=replaceContext({name:"this"});if(this.isStatic){var className=this.owner.name;var staticDeclarations=[];for(var i=0,l=this.definitions.length;i<l;++i){var definition=this.definitions[i];var name=definition.name,staticName=className+"."+name;var declaration="if("+staticName+" === void(0)) {\n "+staticName+" = "+definition.value+"; }\n$p.defineProperty("+thisPrefix+", '"+name+"', { get: function(){return "+staticName+";}, set: function(val){"+staticName+" = val;} });\n";staticDeclarations.push(declaration)}return staticDeclarations.join("")}else{return thisPrefix+"."+this.definitions.join("; "+thisPrefix+".")}};function transformClassField(statement){var attrAndType=attrAndTypeRegex.exec(statement);var isStatic=attrAndType[1].indexOf("static")>=0;var definitions=statement.substring(attrAndType[0].length).split(/,\s*/g);var defaultTypeValue=getDefaultValueForType(attrAndType[2]);for(var i=0;i<definitions.length;++i){definitions[i]=transformVarDefinition(definitions[i],defaultTypeValue)}return new AstClassField(definitions,attrAndType[2],isStatic)}function AstConstructor(params,body){this.params=params;this.body=body}AstConstructor.prototype.toString=function(){var paramNames=appendToLookupTable({},this.params.getNames());var oldContext=replaceContext;replaceContext=function(subject){return paramNames.hasOwnProperty(subject.name)?subject.name:oldContext(subject)};var prefix="function $constr_"+this.params.params.length+this.params.toString();var body=this.body.toString();if(!/\$(superCstr|constr)\b/.test(body)){body="{\n$superCstr();\n"+body.substring(1)}replaceContext=oldContext;return prefix+body+"\n"};function transformConstructor(cstr){var m=new RegExp(/"B(\d+)"\s*"A(\d+)"/).exec(cstr);var params=transformParams(atoms[m[1]]);return new AstConstructor(params,transformStatementsBlock(atoms[m[2]]))}function AstClassBody(name,baseClassName,functions,methods,fields,cstrs,innerClasses,misc){var i,l;this.name=name;this.baseClassName=baseClassName;this.functions=functions;this.methods=methods;this.fields=fields;this.cstrs=cstrs;this.innerClasses=innerClasses;this.misc=misc;for(i=0,l=fields.length;i<l;++i){fields[i].owner=this}}AstClassBody.prototype.getMembers=function(){var members;if(this.owner.base){members=this.owner.base.body.getMembers()}else{members={fields:[],methods:[],innerClasses:[]}}var i,j,l,m;for(i=0,l=this.fields.length;i<l;++i){members.fields=members.fields.concat(this.fields[i].getNames())}for(i=0,l=this.methods.length;i<l;++i){var method=this.methods[i];members.methods.push(method.name)}for(i=0,l=this.innerClasses.length;i<l;++i){var innerClass=this.innerClasses[i];members.innerClasses.push(innerClass.name)}return members};AstClassBody.prototype.toString=function(){function getScopeLevel(p){var i=0;while(p){++i;p=p.scope}return i}var scopeLevel=getScopeLevel(this.owner);var selfId="$this_"+scopeLevel;var result="var "+selfId+" = this;\n";var members=this.getMembers();var thisClassFields=appendToLookupTable({},members.fields),thisClassMethods=appendToLookupTable({},members.methods),thisClassInners=appendToLookupTable({},members.innerClasses);var oldContext=replaceContext;replaceContext=function(subject){var name=subject.name;if(name==="this"){return subject.callSign?selfId+".$self":selfId}else{if(thisClassFields.hasOwnProperty(name)||thisClassInners.hasOwnProperty(name)){return selfId+"."+name}else{if(thisClassMethods.hasOwnProperty(name)){return selfId+".$self."+name}}}return oldContext(subject)};if(this.baseClassName){result+="var $super = { $upcast: "+selfId+" };\n";result+="function $superCstr(){"+this.baseClassName+".apply($super,arguments)}\n"}else{result+="function $superCstr(){$p.extendClassChain("+selfId+")}\n"}result+=this.functions.join("\n")+"\n";result+=this.innerClasses.join("\n");result+=this.fields.join(";\n")+";\n";result+=this.methods.join("\n")+"\n";result+=this.misc.tail;result+=this.cstrs.join("\n")+"\n";result+="function $constr() {\n";var cstrsIfs=[];for(var i=0,l=this.cstrs.length;i<l;++i){var paramsLength=this.cstrs[i].params.params.length;cstrsIfs.push("if(arguments.length === "+paramsLength+") { $constr_"+paramsLength+".apply("+selfId+", arguments); }")}if(cstrsIfs.length>0){result+=cstrsIfs.join(" else ")+" else "}result+="$superCstr(); }\n";result+="$constr.apply(null, arguments);\n";replaceContext=oldContext;return result};transformClassBody=function(body,name,baseName,impls){var declarations=body.substring(1,body.length-1);declarations=extractClassesAndMethods(declarations);declarations=extractConstructors(declarations,name);var methods=[],classes=[],cstrs=[],functions=[];declarations=declarations.replace(/"([DEGH])(\d+)"/g,function(all,type,index){if(type==="D"){methods.push(index)}else{if(type==="E"){classes.push(index)}else{if(type==="H"){functions.push(index)}else{cstrs.push(index)}}}return""});var fields=declarations.split(/;(?:\s*;)*/g);var baseClassName;var i;if(baseName!==undef){baseClassName=baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*)\s*$/g,"$1")}for(i=0;i<functions.length;++i){functions[i]=transformFunction(atoms[functions[i]])}for(i=0;i<methods.length;++i){methods[i]=transformClassMethod(atoms[methods[i]])}for(i=0;i<fields.length-1;++i){var field=trimSpaces(fields[i]);fields[i]=transformClassField(field.middle)}var tail=fields.pop();for(i=0;i<cstrs.length;++i){cstrs[i]=transformConstructor(atoms[cstrs[i]])}for(i=0;i<classes.length;++i){classes[i]=transformInnerClass(atoms[classes[i]])}return new AstClassBody(name,baseClassName,functions,methods,fields,cstrs,classes,{tail:tail})};function AstInterface(name){this.name=name}AstInterface.prototype.toString=function(){return"function "+this.name+"() {  throw 'This is an interface'; }\n$p."+this.name+" = "+this.name+";"};function AstClass(name,body){this.name=name;this.body=body;body.owner=this}AstClass.prototype.toString=function(){var staticVars="";for(var i=0,l=this.body.fields.length;i<l;i++){if(this.body.fields[i].isStatic){for(var x=0,xl=this.body.fields[i].definitions.length;x<xl;x++){staticVars+="var "+this.body.fields[i].definitions[x].name+" = "+this.body.name+"."+this.body.fields[i].definitions[x]+";"}}}return"function "+this.name+"() {\n"+this.body+"}\n"+staticVars+"\n$p."+this.name+" = "+this.name+";"};function transformGlobalClass(class_){var m=classesRegex.exec(class_);classesRegex.lastIndex=0;var body=atoms[getAtomIndex(m[6])];if(m[2]==="interface"){return new AstInterface(m[3])}else{var oldClassId=currentClassId,newClassId=generateClassId();currentClassId=newClassId;var globalClass=new AstClass(m[3],transformClassBody(body,m[3],m[4],m[5]));appendClass(globalClass,newClassId,oldClassId);currentClassId=oldClassId;return globalClass}}function AstMethod(name,params,body){this.name=name;this.params=params;this.body=body}AstMethod.prototype.toString=function(){var paramNames=appendToLookupTable({},this.params.getNames());var oldContext=replaceContext;replaceContext=function(subject){return paramNames.hasOwnProperty(subject.name)?subject.name:oldContext(subject)};var result="function "+this.name+this.params+" "+this.body+"\n$p."+this.name+" = "+this.name+";";replaceContext=oldContext;return result};function transformGlobalMethod(method){var m=methodsRegex.exec(method);var result=methodsRegex.lastIndex=0;return new AstMethod(m[3],transformParams(atoms[getAtomIndex(m[4])]),transformStatementsBlock(atoms[getAtomIndex(m[6])]))}function preStatementsTransform(statements){var s=statements;s=s.replace(/\b(catch\s*"B\d+"\s*"A\d+")(\s*catch\s*"B\d+"\s*"A\d+")+/g,"$1");return s}function AstForStatement(argument,misc){this.argument=argument;this.misc=misc}AstForStatement.prototype.toString=function(){return this.misc.prefix+this.argument.toString()};function AstCatchStatement(argument,misc){this.argument=argument;this.misc=misc}AstCatchStatement.prototype.toString=function(){return this.misc.prefix+this.argument.toString()};function AstPrefixStatement(name,argument,misc){this.name=name;this.argument=argument;this.misc=misc}AstPrefixStatement.prototype.toString=function(){var result=this.misc.prefix;if(this.argument!==undef){result+=this.argument.toString()}return result};function AstLabel(label){this.label=label}AstLabel.prototype.toString=function(){return this.label};transformStatements=function(statements,transformMethod,transformClass){var nextStatement=new RegExp(/\b(catch|for|if|switch|while|with)\s*"B(\d+)"|\b(do|else|finally|return|throw|try|break|continue)\b|("[ADEH](\d+)")|\b((?:case\s[^:]+|[A-Za-z_$][\w$]*\s*):)|(;)/g);var res=[];statements=preStatementsTransform(statements);var lastIndex=0,m,space;while((m=nextStatement.exec(statements))!==null){if(m[1]!==undef){var i=statements.lastIndexOf('"B',nextStatement.lastIndex);var statementsPrefix=statements.substring(lastIndex,i);if(m[1]==="for"){res.push(new AstForStatement(transformForExpression(atoms[m[2]]),{prefix:statementsPrefix}))}else{if(m[1]==="catch"){res.push(new AstCatchStatement(transformParams(atoms[m[2]]),{prefix:statementsPrefix}))}else{res.push(new AstPrefixStatement(m[1],transformExpression(atoms[m[2]]),{prefix:statementsPrefix}))}}}else{if(m[3]!==undef){res.push(new AstPrefixStatement(m[3],undef,{prefix:statements.substring(lastIndex,nextStatement.lastIndex)}))}else{if(m[4]!==undef){space=statements.substring(lastIndex,nextStatement.lastIndex-m[4].length);if(trim(space).length!==0){continue}res.push(space);var kind=m[4].charAt(1),atomIndex=m[5];if(kind==="D"){res.push(transformMethod(atoms[atomIndex]))}else{if(kind==="E"){res.push(transformClass(atoms[atomIndex]))}else{if(kind==="H"){res.push(transformFunction(atoms[atomIndex]))}else{res.push(transformStatementsBlock(atoms[atomIndex]))}}}}else{if(m[6]!==undef){space=statements.substring(lastIndex,nextStatement.lastIndex-m[6].length);if(trim(space).length!==0){continue}res.push(new AstLabel(statements.substring(lastIndex,nextStatement.lastIndex)))}else{var statement=trimSpaces(statements.substring(lastIndex,nextStatement.lastIndex-1));res.push(statement.left);res.push(transformStatement(statement.middle));res.push(statement.right+";")}}}}lastIndex=nextStatement.lastIndex}var statementsTail=trimSpaces(statements.substring(lastIndex));res.push(statementsTail.left);if(statementsTail.middle!==""){res.push(transformStatement(statementsTail.middle));res.push(";"+statementsTail.right)}return res};function getLocalNames(statements){var localNames=[];for(var i=0,l=statements.length;i<l;++i){var statement=statements[i];if(statement instanceof AstVar){localNames=localNames.concat(statement.getNames())}else{if(statement instanceof AstForStatement&&statement.argument.initStatement instanceof AstVar){localNames=localNames.concat(statement.argument.initStatement.getNames())}else{if(statement instanceof AstInnerInterface||statement instanceof AstInnerClass||statement instanceof AstInterface||statement instanceof AstClass||statement instanceof AstMethod||statement instanceof AstFunction){localNames.push(statement.name)}}}}return appendToLookupTable({},localNames)}function AstStatementsBlock(statements){this.statements=statements}AstStatementsBlock.prototype.toString=function(){var localNames=getLocalNames(this.statements);var oldContext=replaceContext;if(!isLookupTableEmpty(localNames)){replaceContext=function(subject){return localNames.hasOwnProperty(subject.name)?subject.name:oldContext(subject)}}var result="{\n"+this.statements.join("")+"\n}";replaceContext=oldContext;return result};transformStatementsBlock=function(block){var content=trimSpaces(block.substring(1,block.length-1));return new AstStatementsBlock(transformStatements(content.middle))};function AstRoot(statements){this.statements=statements}AstRoot.prototype.toString=function(){var localNames=getLocalNames(this.statements);replaceContext=function(subject){var name=subject.name;if(localNames.hasOwnProperty(name)){return name}else{if(globalMembers.hasOwnProperty(name)||PConstants.hasOwnProperty(name)||defaultScope.hasOwnProperty(name)){return"$p."+name}}return name};var result="// this code was autogenerated from PJS\n(function($p) {\n"+this.statements.join("")+"\n})";replaceContext=null;return result};transformMain=function(){var statements=extractClassesAndMethods(atoms[0]);statements=statements.replace(/\bimport\s+[^;]+;/g,"");return new AstRoot(transformStatements(statements,transformGlobalMethod,transformGlobalClass))};function generateMetadata(ast){var globalScope={};var id,class_;for(id in declaredClasses){if(declaredClasses.hasOwnProperty(id)){class_=declaredClasses[id];var scopeId=class_.scopeId,name=class_.name;if(scopeId){var scope=declaredClasses[scopeId];class_.scope=scope;if(scope.inScope===undef){scope.inScope={}}scope.inScope[name]=class_}else{globalScope[name]=class_}}}function findInScopes(class_,name){var parts=name.split(".");var currentScope=class_.scope,found;while(currentScope){if(currentScope.hasOwnProperty(parts[0])){found=currentScope[parts[0]];break}currentScope=currentScope.scope}if(found===undef){found=globalScope[parts[0]]}for(var i=1,l=parts.length;i<l&&found;++i){found=found.inScope[parts[i]]}return found}for(id in declaredClasses){if(declaredClasses.hasOwnProperty(id)){class_=declaredClasses[id];var baseClassName=class_.body.baseClassName;if(baseClassName){class_.base=findInScopes(class_,baseClassName)}}}}var transformed=transformMain();generateMetadata(transformed);var redendered=transformed.toString();redendered=redendered.replace(/\s*\n(?:[\t ]*\n)+/g,"\n\n");return injectStrings(redendered,strings)}function preprocessCode(aCode,sketch){var dm=new RegExp(/\/\*\s*@pjs\s+((?:[^\*]|\*+[^\*\/])*)\*\//g).exec(aCode);if(dm&&dm.length===2){var jsonItems=[],directives=dm.splice(1,2)[0].replace(/\{([\s\S]*?)\}/g,(function(){return function(all,item){jsonItems.push(item);return"{"+(jsonItems.length-1)+"}"}}())).replace("\n","").replace("\r","").split(";");var clean=function(s){return s.replace(/^\s*["']?/,"").replace(/["']?\s*$/,"")};for(var i=0,dl=directives.length;i<dl;i++){var pair=directives[i].split("=");if(pair&&pair.length===2){var key=clean(pair[0]),value=clean(pair[1]),list=[];if(key==="preload"){list=value.split(",");for(var j=0,jl=list.length;j<jl;j++){var imageName=clean(list[j]);sketch.imageCache.add(imageName)}}else{if(key==="transparent"){sketch.options.isTransparent=value==="true"}else{if(key==="font"){list=value.split(",");for(var x=0,xl=list.length;x<xl;x++){var fontName=clean(list[x]),index=/^\{(\d*?)\}$/.exec(fontName);sketch.fonts.add(index?JSON.parse("{"+jsonItems[index[1]]+"}"):fontName)}}else{if(key==="crisp"){sketch.options.crispLines=value==="true"}else{if(key==="pauseOnBlur"){sketch.options.pauseOnBlur=value==="true"}else{sketch.options[key]=value}}}}}}}}var codeWoStrings=aCode.replace(/("(?:[^"\\\n]|\\.)*")|('(?:[^'\\\n]|\\.)*')|(([\[\(=|&!\^:?]\s*)(\/(?![*\/])(?:[^\/\\\n]|\\.)*\/[gim]*)\b)|(\/\/[^\n]*\n)|(\/\*(?:(?!\*\/)(?:.|\n))*\*\/)/g,"");if(codeWoStrings.match(/\bsize\((?:.+),(?:.+),\s*(OPENGL|P3D)\s*\);/)){sketch.use3DContext=true}return aCode}Processing.compile=function(pdeCode){var sketch=new Processing.Sketch();var code=preprocessCode(pdeCode,sketch);var compiledPde=parseProcessing(code);sketch.sourceCode=compiledPde;return sketch};Error.prototype.printStackTrace=function(){return this.toString()};var tinylogLite=(function(){var tinylogLite={},undef="undefined",func="function",False=!1,True=!0,logLimit=512,log="log";if(typeof tinylog!==undef&&typeof tinylog[log]===func){tinylogLite[log]=tinylog[log]}else{if(typeof document!==undef&&!document.fake){(function(){var doc=document,$div="div",$style="style",$title="title",containerStyles={zIndex:10000,position:"fixed",bottom:"0px",width:"100%",height:"15%",fontFamily:"sans-serif",color:"#ccc",backgroundColor:"black"},outputStyles={position:"relative",fontFamily:"monospace",overflow:"auto",height:"100%",paddingTop:"5px"},resizerStyles={height:"5px",marginTop:"-5px",cursor:"n-resize",backgroundColor:"darkgrey"},closeButtonStyles={position:"absolute",top:"5px",right:"20px",color:"#111",MozBorderRadius:"4px",webkitBorderRadius:"4px",borderRadius:"4px",cursor:"pointer",fontWeight:"normal",textAlign:"center",padding:"3px 5px",backgroundColor:"#333",fontSize:"12px"},entryStyles={minHeight:"16px"},entryTextStyles={fontSize:"12px",margin:"0 8px 0 8px",maxWidth:"100%",whiteSpace:"pre-wrap",overflow:"auto"},view=doc.defaultView,docElem=doc.documentElement,docElemStyle=docElem[$style],setStyles=function(){var i=arguments.length,elemStyle,styles,style;while(i--){styles=arguments[i--];elemStyle=arguments[i][$style];for(style in styles){if(styles.hasOwnProperty(style)){elemStyle[style]=styles[style]}}}},observer=function(obj,event,handler){if(obj.addEventListener){obj.addEventListener(event,handler,False)}else{if(obj.attachEvent){obj.attachEvent("on"+event,handler)}}return[obj,event,handler]},unobserve=function(obj,event,handler){if(obj.removeEventListener){obj.removeEventListener(event,handler,False)}else{if(obj.detachEvent){obj.detachEvent("on"+event,handler)}}},clearChildren=function(node){var children=node.childNodes,child=children.length;while(child--){node.removeChild(children.item(0))}},append=function(to,elem){return to.appendChild(elem)},createElement=function(localName){return doc.createElement(localName)},createTextNode=function(text){return doc.createTextNode(text)},createLog=tinylogLite[log]=function(message){var uninit,originalPadding=docElemStyle.paddingBottom,container=createElement($div),containerStyle=container[$style],resizer=append(container,createElement($div)),output=append(container,createElement($div)),closeButton=append(container,createElement($div)),resizingLog=False,previousHeight=False,previousScrollTop=False,messages=0,updateSafetyMargin=function(){docElemStyle.paddingBottom=container.clientHeight+"px"},setContainerHeight=function(height){var viewHeight=view.innerHeight,resizerHeight=resizer.clientHeight;if(height<0){height=0}else{if(height+resizerHeight>viewHeight){height=viewHeight-resizerHeight}}containerStyle.height=height/viewHeight*100+"%";updateSafetyMargin()},observers=[observer(doc,"mousemove",function(evt){if(resizingLog){setContainerHeight(view.innerHeight-evt.clientY);output.scrollTop=previousScrollTop}}),observer(doc,"mouseup",function(){if(resizingLog){resizingLog=previousScrollTop=False}}),observer(resizer,"dblclick",function(evt){evt.preventDefault();if(previousHeight){setContainerHeight(previousHeight);previousHeight=False}else{previousHeight=container.clientHeight;containerStyle.height="0px"}}),observer(resizer,"mousedown",function(evt){evt.preventDefault();resizingLog=True;previousScrollTop=output.scrollTop}),observer(resizer,"contextmenu",function(){resizingLog=False}),observer(closeButton,"click",function(){uninit()})];uninit=function(){var i=observers.length;while(i--){unobserve.apply(tinylogLite,observers[i])}docElem.removeChild(container);docElemStyle.paddingBottom=originalPadding;clearChildren(output);clearChildren(container);tinylogLite[log]=createLog};setStyles(container,containerStyles,output,outputStyles,resizer,resizerStyles,closeButton,closeButtonStyles);closeButton[$title]="Close Log";append(closeButton,createTextNode("\u2716"));resizer[$title]="Double-click to toggle log minimization";docElem.insertBefore(container,docElem.firstChild);tinylogLite[log]=function(message){if(messages===logLimit){output.removeChild(output.firstChild)}else{messages++}var entry=append(output,createElement($div)),entryText=append(entry,createElement($div));entry[$title]=(new Date()).toLocaleTimeString();setStyles(entry,entryStyles,entryText,entryTextStyles);append(entryText,createTextNode(message));output.scrollTop=output.scrollHeight};tinylogLite[log](message)}}())}else{if(typeof print===func){tinylogLite[log]=print}}}return tinylogLite}());Processing.logger=tinylogLite;Processing.version="@VERSION@";Processing.lib={};Processing.registerLibrary=function(name,desc){Processing.lib[name]=desc;if(desc.hasOwnProperty("init")){desc.init(defaultScope)}};Processing.instances=[];Processing.instanceIds={};Processing.removeInstance=function(id){Processing.instances.splice(Processing.instanceIds[id],1);delete Processing.instanceIds[id]};Processing.addInstance=function(processing){if(processing.externals.canvas.id===undef||!processing.externals.canvas.id.length){processing.externals.canvas.id="__processing"+Processing.instances.length}Processing.instanceIds[processing.externals.canvas.id]=Processing.instances.length;Processing.instances.push(processing)};Processing.getInstanceById=function(name){return Processing.instances[Processing.instanceIds[name]]};Processing.Sketch=function(attachFunction){this.attachFunction=attachFunction;this.use3DContext=false;this.options={isTransparent:false,crispLines:false,pauseOnBlur:false};this.imageCache={pending:0,images:{},add:function(href){var img=new Image();img.onload=(function(owner){return function(){owner.pending--}}(this));this.pending++;this.images[href]=img;img.src=href}};this.fonts={template:(function(){var element=document.createElement("p");element.style.fontFamily="serif";element.style.fontSize="72px";element.style.visibility="hidden";element.innerHTML="abcmmmmmmmmmmlll";document.getElementsByTagName("body")[0].appendChild(element);return element}()),attempt:0,pending:function(){var r=true;for(var i=0;i<this.fontList.length;i++){if(this.fontList[i].offsetWidth===this.template.offsetWidth&&this.fontList[i].offsetHeight===this.template.offsetHeight){r=false;this.attempt++}else{document.getElementsByTagName("body")[0].removeChild(this.fontList[i]);this.fontList.splice(i--,1);this.attempt=0}}if(this.attempt>=30){r=true;for(var j=0;j<this.fontList.length;j++){document.getElementsByTagName("body")[0].removeChild(this.fontList[j]);this.fontList.splice(j--,1)}}if(r){document.getElementsByTagName("body")[0].removeChild(this.template)}return r},fontList:[],fontFamily:"",style:document.createElement("style"),add:function(fontSrc){var fontName=(typeof fontSrc==="object"?fontSrc.fontFace:fontSrc),fontUrl=(typeof fontSrc==="object"?fontSrc.url:fontSrc);this.fontFamily+="@font-face{\n  font-family: '"+fontName+"';\n  src:  url('"+fontUrl+"');\n}\n";this.style.innerHTML=this.fontFamily;document.getElementsByTagName("head")[0].appendChild(this.style);var preLoader=document.createElement("p");preLoader.style.fontFamily="'"+fontName+"', serif";preLoader.style.fontSize="72px";preLoader.style.visibility="hidden";preLoader.innerHTML="abcmmmmmmmmmmlll";document.getElementsByTagName("body")[0].appendChild(preLoader);this.fontList.push(preLoader)}};this.sourceCode=undefined;this.attach=function(processing){if(typeof this.attachFunction==="function"){this.attachFunction(processing)}else{if(this.sourceCode){var func=eval(this.sourceCode);func(processing);this.attachFunction=func}else{throw"Unable to attach sketch to the processing instance"}}};this.toString=function(){return this.sourceCode||"[attach: "+this.attachFunction+"]"};this.onblur=function(){};this.onfocus=function(){}};var init=function(){var canvas=document.getElementsByTagName("canvas");for(var i=0,l=canvas.length;i<l;i++){var processingSources=canvas[i].getAttribute("data-processing-sources");if(processingSources===null){processingSources=canvas[i].getAttribute("data-src");if(processingSources===null){processingSources=canvas[i].getAttribute("datasrc")}}if(processingSources){var filenames=processingSources.split(" ");var code="";for(var j=0,fl=filenames.length;j<fl;j++){if(filenames[j]){var block=ajax(filenames[j]);if(block!==false){code+=";\n"+block}}}Processing.addInstance(new Processing(canvas[i],code))}}};document.addEventListener("DOMContentLoaded",function(){init()},false);window.addEventListener("blur",function(){for(var i=0;i<Processing.instances.length;i++){Processing.instances[i].externals.onblur()}},false);window.addEventListener("focus",function(){for(var i=0;i<Processing.instances.length;i++){Processing.instances[i].externals.onfocus()}},false)}());