From 9af4142548dc395407c7a4a1564bacd55fde672d Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Wed, 14 Nov 2012 15:33:29 -0500 Subject: [PATCH 01/57] class example --- examples/week2/examples/.htaccess | 4 ++ examples/week2/examples/app.rb | 61 +++++++++++++++++++ examples/week2/examples/config.ru | 9 +++ .../week2/examples/tmp/always_restart.txt | 0 examples/week2/examples/views/form.erb | 35 +++++++++++ 5 files changed, 109 insertions(+) create mode 100644 examples/week2/examples/.htaccess create mode 100644 examples/week2/examples/app.rb create mode 100644 examples/week2/examples/config.ru create mode 100644 examples/week2/examples/tmp/always_restart.txt create mode 100644 examples/week2/examples/views/form.erb diff --git a/examples/week2/examples/.htaccess b/examples/week2/examples/.htaccess new file mode 100644 index 0000000..9f3f895 --- /dev/null +++ b/examples/week2/examples/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/example1 +RackEnv development diff --git a/examples/week2/examples/app.rb b/examples/week2/examples/app.rb new file mode 100644 index 0000000..78592b1 --- /dev/null +++ b/examples/week2/examples/app.rb @@ -0,0 +1,61 @@ +require 'sinatra' + +# Main route - this is the form is shown +get '/' do + "Hello" +end + +get '/html' do + + "This is an example of simple routes. Check out the Home

Done

" + +end + +get '/form' do + + #@title = "This is passing a variable" + erb :form + +end + + +post '/form' do + + var = params[:yourname] + "This is my name #{var}" + ##"This is my name" + params[:yourname] + +end + +get '/urlparams' do + + + id = params[:id] + name = params[:name] + + "This is the id: #{id} name: #{name}" + + +end + +get '/name/:id' do + + "This is the id #{params[:id]}" + +end + +get '/name' do + + "Name" + +end + + + +get '/same_route' do + "Same route #1" +end + +get '/same_route' do + "Same route #2" +end diff --git a/examples/week2/examples/config.ru b/examples/week2/examples/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/week2/examples/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/week2/examples/tmp/always_restart.txt b/examples/week2/examples/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/week2/examples/views/form.erb b/examples/week2/examples/views/form.erb new file mode 100644 index 0000000..fc175e2 --- /dev/null +++ b/examples/week2/examples/views/form.erb @@ -0,0 +1,35 @@ + + + + Simple Form Example + + + + +

<%=@title%>

+

Simple form

+

This is a simple form example.

+
+

+

+
+ + + From d8d745ce190812705886cc9ef9306ea315d164e3 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Wed, 14 Nov 2012 15:34:46 -0500 Subject: [PATCH 02/57] class examples --- examples/week2/{examples => week2 class examples}/.htaccess | 0 examples/week2/{examples => week2 class examples}/app.rb | 0 examples/week2/{examples => week2 class examples}/config.ru | 0 .../{examples => week2 class examples}/tmp/always_restart.txt | 0 examples/week2/{examples => week2 class examples}/views/form.erb | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename examples/week2/{examples => week2 class examples}/.htaccess (100%) rename examples/week2/{examples => week2 class examples}/app.rb (100%) rename examples/week2/{examples => week2 class examples}/config.ru (100%) rename examples/week2/{examples => week2 class examples}/tmp/always_restart.txt (100%) rename examples/week2/{examples => week2 class examples}/views/form.erb (100%) diff --git a/examples/week2/examples/.htaccess b/examples/week2/week2 class examples/.htaccess similarity index 100% rename from examples/week2/examples/.htaccess rename to examples/week2/week2 class examples/.htaccess diff --git a/examples/week2/examples/app.rb b/examples/week2/week2 class examples/app.rb similarity index 100% rename from examples/week2/examples/app.rb rename to examples/week2/week2 class examples/app.rb diff --git a/examples/week2/examples/config.ru b/examples/week2/week2 class examples/config.ru similarity index 100% rename from examples/week2/examples/config.ru rename to examples/week2/week2 class examples/config.ru diff --git a/examples/week2/examples/tmp/always_restart.txt b/examples/week2/week2 class examples/tmp/always_restart.txt similarity index 100% rename from examples/week2/examples/tmp/always_restart.txt rename to examples/week2/week2 class examples/tmp/always_restart.txt diff --git a/examples/week2/examples/views/form.erb b/examples/week2/week2 class examples/views/form.erb similarity index 100% rename from examples/week2/examples/views/form.erb rename to examples/week2/week2 class examples/views/form.erb From 90ccd1f9391539639a3df4a46b1a6bf7d848cc2e Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Wed, 14 Nov 2012 15:37:40 -0500 Subject: [PATCH 03/57] update title --- examples/week2/week2 class examples/app.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/week2/week2 class examples/app.rb b/examples/week2/week2 class examples/app.rb index 78592b1..41a2fd2 100644 --- a/examples/week2/week2 class examples/app.rb +++ b/examples/week2/week2 class examples/app.rb @@ -13,7 +13,7 @@ get '/form' do - #@title = "This is passing a variable" + @title = "This is passing a variable" erb :form end From 064285c3160ea01ab6b4f22ca6436b6bb7ad9ed5 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Wed, 14 Nov 2012 15:38:19 -0500 Subject: [PATCH 04/57] final change --- .../week2/{week2 class examples => week2classexamples}/.htaccess | 0 .../week2/{week2 class examples => week2classexamples}/app.rb | 0 .../week2/{week2 class examples => week2classexamples}/config.ru | 0 .../tmp/always_restart.txt | 0 .../{week2 class examples => week2classexamples}/views/form.erb | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename examples/week2/{week2 class examples => week2classexamples}/.htaccess (100%) rename examples/week2/{week2 class examples => week2classexamples}/app.rb (100%) rename examples/week2/{week2 class examples => week2classexamples}/config.ru (100%) rename examples/week2/{week2 class examples => week2classexamples}/tmp/always_restart.txt (100%) rename examples/week2/{week2 class examples => week2classexamples}/views/form.erb (100%) diff --git a/examples/week2/week2 class examples/.htaccess b/examples/week2/week2classexamples/.htaccess similarity index 100% rename from examples/week2/week2 class examples/.htaccess rename to examples/week2/week2classexamples/.htaccess diff --git a/examples/week2/week2 class examples/app.rb b/examples/week2/week2classexamples/app.rb similarity index 100% rename from examples/week2/week2 class examples/app.rb rename to examples/week2/week2classexamples/app.rb diff --git a/examples/week2/week2 class examples/config.ru b/examples/week2/week2classexamples/config.ru similarity index 100% rename from examples/week2/week2 class examples/config.ru rename to examples/week2/week2classexamples/config.ru diff --git a/examples/week2/week2 class examples/tmp/always_restart.txt b/examples/week2/week2classexamples/tmp/always_restart.txt similarity index 100% rename from examples/week2/week2 class examples/tmp/always_restart.txt rename to examples/week2/week2classexamples/tmp/always_restart.txt diff --git a/examples/week2/week2 class examples/views/form.erb b/examples/week2/week2classexamples/views/form.erb similarity index 100% rename from examples/week2/week2 class examples/views/form.erb rename to examples/week2/week2classexamples/views/form.erb From eefbff4125182f340a3984c39a93566716c4cd0c Mon Sep 17 00:00:00 2001 From: zeven Date: Wed, 14 Nov 2012 15:41:16 -0500 Subject: [PATCH 05/57] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index efc8385..41c3f63 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,8 @@ Sinatra Up and Running, p. 15-21 (It’s not much, so please read it thoroughly) * Functions * Loops * Gems + +* [Week 2 Class Examples](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week2/week2classexamples) * [Basic Sinatra App](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week2/basic_sinatra_app) * [Routes](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week2/routes) * [Returning something](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week2/returning_something) From c1b38122f5eb140948f1f16c4689338763001634 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Fri, 16 Nov 2012 14:36:53 -0500 Subject: [PATCH 06/57] datamapper example --- examples/week3/datamapperexample1/.htaccess | 4 + examples/week3/datamapperexample1/app.rb | 131 ++++++++++++++++++ examples/week3/datamapperexample1/config.ru | 9 ++ .../week3/datamapperexample1/db/visitors.yml | 5 + .../datamapperexample1/tmp/always_restart.txt | 0 .../week3/datamapperexample1/views/all.erb | 5 + .../week3/datamapperexample1/views/edit.erb | 33 +++++ .../week3/datamapperexample1/views/form.erb | 34 +++++ 8 files changed, 221 insertions(+) create mode 100644 examples/week3/datamapperexample1/.htaccess create mode 100644 examples/week3/datamapperexample1/app.rb create mode 100644 examples/week3/datamapperexample1/config.ru create mode 100644 examples/week3/datamapperexample1/db/visitors.yml create mode 100644 examples/week3/datamapperexample1/tmp/always_restart.txt create mode 100644 examples/week3/datamapperexample1/views/all.erb create mode 100644 examples/week3/datamapperexample1/views/edit.erb create mode 100644 examples/week3/datamapperexample1/views/form.erb diff --git a/examples/week3/datamapperexample1/.htaccess b/examples/week3/datamapperexample1/.htaccess new file mode 100644 index 0000000..d93ccf0 --- /dev/null +++ b/examples/week3/datamapperexample1/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/datamapperexample1 +RackEnv development diff --git a/examples/week3/datamapperexample1/app.rb b/examples/week3/datamapperexample1/app.rb new file mode 100644 index 0000000..40f78b0 --- /dev/null +++ b/examples/week3/datamapperexample1/app.rb @@ -0,0 +1,131 @@ +require 'sinatra' +require 'dm-core' + +DataMapper::setup(:default, {:adapter => 'yaml', :path => 'db'}) + +#Create the class the Datamapper will base off of +class Visitor + include DataMapper::Resource + + property :id, Serial + property :username, String +end + +DataMapper.finalize + +# Main route - this is the form is shown +get '/' do + erb :form +end + +post '/username' do + + # create a new visitor + user = Visitor.new + user.username = params[:username] + user.save + + # or you could have done it like this + # user = Visitor.create(:name => params[:yourname]) + + "User name saved." +end + +get '/first-visitor' do + user = Visitor.first + "User name is #{user.username}" +end + +get '/edit-visitor' do + + erb :edit +end + +post '/edit-visitor' do + user = Visitor.first + user.update(:username => params[:username]) + "Users new name is #{user.username}" +end + +get '/delete-first-visitor' do + user = Visitor.first + user.destroy + "User was deleted" +end + + + + +get '/find' do + user = Visitor.first + + # get a user by id + #user = Visitor.get(1) + + # get first user with name "rune" + #users = Visitor.first(:username => "rune") + + # get last user with name "rune" + #user = Visitor.last(:name => "rune") + + # get all users with name "rune" + #user = Visitor.all(:name => "rune") + + # Find all users with age between 18 and 60 + #user = Visitor.all(:age.gt => 18, :age.lt => 60) + + # You can use all of these conditions + # gt, greater than + # lt, less than + # gte, greater than or equal + # lte, less than or equal + # not, not equal + # eql, equal + # like, like + + # order visitors by age (you also use .asc) + #user = Visitor.all(:order => [ :age.desc ]) + + # find the number of visitors in your database with age greater than 18 + #count = Visitor.count(:age.gt => 18) + + # find the youngest age in the database + #min_age = Visitor.min(:age) + + # find the oldest age in the database + #max_age = Visitor.max(:age) + + "User is #{user.username}" + +end + + + +get '/all' do + + @userList = Visitor.all + #Look here to look at how to itterate through the object array + erb :all + +end + + +# Remember that sinatra finds the best match of what you put in the url +get '/:name/home' do + +"This is #{params[:name]}'s home page" + +end + +get '/:name/:cat' do + + name = params[:name] + cat = params[:cat] + + + "This is the Name: #{name} and the cat: #{cat}" + +end + + + diff --git a/examples/week3/datamapperexample1/config.ru b/examples/week3/datamapperexample1/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/week3/datamapperexample1/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/week3/datamapperexample1/db/visitors.yml b/examples/week3/datamapperexample1/db/visitors.yml new file mode 100644 index 0000000..c2b8ddd --- /dev/null +++ b/examples/week3/datamapperexample1/db/visitors.yml @@ -0,0 +1,5 @@ +--- +- username: hello + id: 2 +- username: goodbye + id: 3 diff --git a/examples/week3/datamapperexample1/tmp/always_restart.txt b/examples/week3/datamapperexample1/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/week3/datamapperexample1/views/all.erb b/examples/week3/datamapperexample1/views/all.erb new file mode 100644 index 0000000..1239c29 --- /dev/null +++ b/examples/week3/datamapperexample1/views/all.erb @@ -0,0 +1,5 @@ +<%@userList.each do |users|%> + +

This is <%=users.username%> Home page

+ +<%end%> \ No newline at end of file diff --git a/examples/week3/datamapperexample1/views/edit.erb b/examples/week3/datamapperexample1/views/edit.erb new file mode 100644 index 0000000..b995ba7 --- /dev/null +++ b/examples/week3/datamapperexample1/views/edit.erb @@ -0,0 +1,33 @@ + + + + Simple Form Example + + + + +

Update Username

+
+

+

+
+ + + diff --git a/examples/week3/datamapperexample1/views/form.erb b/examples/week3/datamapperexample1/views/form.erb new file mode 100644 index 0000000..25eb66a --- /dev/null +++ b/examples/week3/datamapperexample1/views/form.erb @@ -0,0 +1,34 @@ + + + + Simple Form Example + + + + +

Simple form

+

This is a simple form example.

+
+

+

+
+ + + From a14befa37caeb575901676bc9e236ea191c13336 Mon Sep 17 00:00:00 2001 From: zeven Date: Fri, 16 Nov 2012 14:44:50 -0500 Subject: [PATCH 07/57] Update README.md --- README.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/README.md b/README.md index 41c3f63..278a605 100644 --- a/README.md +++ b/README.md @@ -85,16 +85,6 @@ Sinatra Up and Running, p. 15-21 (It’s not much, so please read it thoroughly) * Gems * [Week 2 Class Examples](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week2/week2classexamples) -* [Basic Sinatra App](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week2/basic_sinatra_app) -* [Routes](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week2/routes) -* [Returning something](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week2/returning_something) -* [Returning something with views](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week4/views) -* [Params](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week2/params) - * GET request in URL params - * POST request - * Params in route -* [First route gets picked up](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week2/first_route) - ### HTML Forms From 9c2afb7218a00e744154563353b33bf686d52971 Mon Sep 17 00:00:00 2001 From: zeven Date: Fri, 16 Nov 2012 14:47:03 -0500 Subject: [PATCH 08/57] Update README.md --- README.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 278a605..d5a185e 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,16 @@ Sinatra Up and Running, p. 15-21 (It’s not much, so please read it thoroughly) Create a new Sinatra application on the ITP Server. Create a GET “/form” route that returns an HTML form with a few different input types. Create a POST “/form” route that reads these parameters and sends back a dynamic HTML page. This HTML page should at least have an image that changes depending on the input from the form. + +###Putting images into your app directory. + +You need to make a folder called public. Inside of that make a folder called images and place your images there. Double click into your app folder. Right click and add new folder. Type public. Double click to go into the new public folder you created. Right click and add new folder called images. Put your images in there. You should put the full path to your file in the image src. It will look something like this: +`` + +If your image does not appear there could be another issue with permissions. Right click on your public folder you just created and select info. Click on the permissions tab. Where it says unix permissions type 755 and click apply changes recursively. + + + ## Week 3: Basics of Datamapper ### Readings For This Week @@ -121,12 +131,8 @@ Create a new Sinatra application on the ITP Server. Create a GET “/form” rou * Setup Datamapper * Write your Datamapper class * Properties: Serial, Boolean, String, Text, Float, Integer, Datetime, -* [Create](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week3/create) -* [Read](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week3/read) -* [Update](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week3/update) -* [Delete](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week3/delete) -* [Find](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week3/find) -* [Example with everything](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week3/everything) + +* [Datamapper Class Example](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week3/datamapperexample1) ### Using Datamapper with Forms From 98d9f7371537018e6042e9aadbd5ee2ae0bb563f Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Thu, 29 Nov 2012 20:51:46 -0500 Subject: [PATCH 09/57] blog --- examples/blog/.htaccess | 4 ++ examples/blog/app.rb | 90 ++++++++++++++++++++++++++++ examples/blog/config.ru | 9 +++ examples/blog/db/blog_posts.yml | 13 ++++ examples/blog/tmp/always_restart.txt | 0 examples/blog/views/admin.erb | 10 ++++ examples/blog/views/blog.erb | 5 ++ examples/blog/views/blog_new.erb | 5 ++ examples/blog/views/blog_save.erb | 2 + examples/blog/views/edit.erb | 5 ++ examples/blog/views/form.erb | 34 +++++++++++ examples/blog/views/front.erb | 3 + examples/blog/views/layout.erb | 9 +++ examples/blog/views/post.erb | 5 ++ 14 files changed, 194 insertions(+) create mode 100644 examples/blog/.htaccess create mode 100644 examples/blog/app.rb create mode 100644 examples/blog/config.ru create mode 100644 examples/blog/db/blog_posts.yml create mode 100644 examples/blog/tmp/always_restart.txt create mode 100644 examples/blog/views/admin.erb create mode 100644 examples/blog/views/blog.erb create mode 100644 examples/blog/views/blog_new.erb create mode 100644 examples/blog/views/blog_save.erb create mode 100644 examples/blog/views/edit.erb create mode 100644 examples/blog/views/form.erb create mode 100644 examples/blog/views/front.erb create mode 100644 examples/blog/views/layout.erb create mode 100644 examples/blog/views/post.erb diff --git a/examples/blog/.htaccess b/examples/blog/.htaccess new file mode 100644 index 0000000..2065ead --- /dev/null +++ b/examples/blog/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/blog +RackEnv development diff --git a/examples/blog/app.rb b/examples/blog/app.rb new file mode 100644 index 0000000..8f09474 --- /dev/null +++ b/examples/blog/app.rb @@ -0,0 +1,90 @@ +require 'sinatra' +require 'dm-core' + +DataMapper::setup(:default, {:adapter => 'yaml', :path => 'db'}) + +class BlogPost + include DataMapper::Resource + property :id, Serial + property :title, String + property :body, Text +end + +DataMapper.finalize + +get "/" do + @nav = "Splash page" + erb :front +end + +get "/blog" do + @nav = "Zeven's Blog" + @posts = BlogPost.all + erb :blog +end + +get "/blog/new" do + erb :blog_new +end + +post "/blog/save" do + myPost = BlogPost.new + myPost.title = params[:title] + myPost.body = params[:body] + + if(myPost.save) + @message = "Your post was saved!" + else + @message = "Your post was NOT SAVED!!!!!!!" + end + + erb :blog_save +end + +get "/blog/admin" do + @nav = "Admin" + @posts = BlogPost.all + erb :admin +end + +get "/blog/:id/edit" do + @nav = "You are on the edit username page" + @updatePost = BlogPost.get(params[:id]) + @id = params[:id] + erb :edit +end + +post "/blog/:id/edit" do + updatePost = BlogPost.get(params[:id]) + updatePost.title = params[:title] + updatePost.body = params[:body] + + if(updatePost.save) + redirect to("http://itp.nyu.edu/~zr279/sinatra/blog/blog") + else + "Your post was NOT SAVED!!!!!!!" + end + + +end + +get "/blog/:id/delete" do + + deletePost = BlogPost.get(params[:id]) + + + deletePost.destroy + + redirect to("http://itp.nyu.edu/~zr279/sinatra/blog/blog/admin") + + +end + +get "/blog/:id" do + @post = BlogPost.get(params[:id]) + erb :post, :layout => false +end + + + + diff --git a/examples/blog/config.ru b/examples/blog/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/blog/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/blog/db/blog_posts.yml b/examples/blog/db/blog_posts.yml new file mode 100644 index 0000000..1a01081 --- /dev/null +++ b/examples/blog/db/blog_posts.yml @@ -0,0 +1,13 @@ +--- +- title: this is no longer a test + body: this is no longer a test + id: 2 +- title: Hello this my first post + body: Hello i love sintar + id: 4 +- title: this is a post + body: this is a post + id: 3 +- title: this is another post + body: this is another post + id: 4 diff --git a/examples/blog/tmp/always_restart.txt b/examples/blog/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/blog/views/admin.erb b/examples/blog/views/admin.erb new file mode 100644 index 0000000..5c42f91 --- /dev/null +++ b/examples/blog/views/admin.erb @@ -0,0 +1,10 @@ + + +

Posts

+ +<% @posts.each do |thisPost| %> +

<%=thisPost.title%>

+Edit +Delete + +<% end %> \ No newline at end of file diff --git a/examples/blog/views/blog.erb b/examples/blog/views/blog.erb new file mode 100644 index 0000000..085ab70 --- /dev/null +++ b/examples/blog/views/blog.erb @@ -0,0 +1,5 @@ +<% for thisPost in @posts %> +

<%= thisPost.title %>

+

<%= thisPost.body %>

+ Permalink +<% end %> \ No newline at end of file diff --git a/examples/blog/views/blog_new.erb b/examples/blog/views/blog_new.erb new file mode 100644 index 0000000..8638f3c --- /dev/null +++ b/examples/blog/views/blog_new.erb @@ -0,0 +1,5 @@ +
+

+

+

+
\ No newline at end of file diff --git a/examples/blog/views/blog_save.erb b/examples/blog/views/blog_save.erb new file mode 100644 index 0000000..06a5a38 --- /dev/null +++ b/examples/blog/views/blog_save.erb @@ -0,0 +1,2 @@ +

<%= @message %>

+Go to the blog \ No newline at end of file diff --git a/examples/blog/views/edit.erb b/examples/blog/views/edit.erb new file mode 100644 index 0000000..2788271 --- /dev/null +++ b/examples/blog/views/edit.erb @@ -0,0 +1,5 @@ +
+

+

+

+
\ No newline at end of file diff --git a/examples/blog/views/form.erb b/examples/blog/views/form.erb new file mode 100644 index 0000000..bf5cf76 --- /dev/null +++ b/examples/blog/views/form.erb @@ -0,0 +1,34 @@ + + + + Simple Form Example + + + + +

Simple form

+

This is a simple form example.

+
+

+

+
+ + + diff --git a/examples/blog/views/front.erb b/examples/blog/views/front.erb new file mode 100644 index 0000000..43df916 --- /dev/null +++ b/examples/blog/views/front.erb @@ -0,0 +1,3 @@ + +

Hello

+ Go to the blog diff --git a/examples/blog/views/layout.erb b/examples/blog/views/layout.erb new file mode 100644 index 0000000..5d9c75f --- /dev/null +++ b/examples/blog/views/layout.erb @@ -0,0 +1,9 @@ + + + Zeven's Blog + + +

<%=@nav%>

+ <%= yield %> + + \ No newline at end of file diff --git a/examples/blog/views/post.erb b/examples/blog/views/post.erb new file mode 100644 index 0000000..12c7bd6 --- /dev/null +++ b/examples/blog/views/post.erb @@ -0,0 +1,5 @@ +

<%= @post.title %>

+

<%= @post.body %>

+
+
+Return to blog \ No newline at end of file From d4ea0f33468d92b93eef3543d4dc7b0c94617549 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 29 Nov 2012 20:54:23 -0500 Subject: [PATCH 10/57] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5a185e..3b7215e 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ Sinatra Up and Running, p. 21-30 ### Creating a Blog in Sinatra -* [A full blog in Sinatra and Datamapper](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week4/full_blog) +* [A full blog in Sinatra and Datamapper](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/blog) ### Advanced routes From 38aa96249a471aa8842ec40e9b1fe371104debd8 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Wed, 5 Dec 2012 16:50:57 -0500 Subject: [PATCH 11/57] week5 --- examples/week5/advancedatamapper/.htaccess | 4 ++ examples/week5/advancedatamapper/app.rb | 53 +++++++++++++++++++ examples/week5/advancedatamapper/config.ru | 9 ++++ .../week5/advancedatamapper/db/visitors.yml | 31 +++++++++++ .../advancedatamapper/tmp/always_restart.txt | 0 .../advancedatamapper/views/allentries.erb | 10 ++++ .../week5/advancedatamapper/views/form.erb | 14 +++++ examples/week5/advancesearch/.htaccess | 4 ++ examples/week5/advancesearch/app.rb | 50 +++++++++++++++++ examples/week5/advancesearch/config.ru | 9 ++++ examples/week5/advancesearch/db/people.yml | 41 ++++++++++++++ .../advancesearch/tmp/always_restart.txt | 0 examples/week5/advancesearch/views/form.erb | 34 ++++++++++++ examples/week5/advancesearch/views/front.erb | 31 +++++++++++ examples/week5/advancesearch/views/person.erb | 2 + examples/week6/image_upload/app.rb | 17 ++++++ examples/week6/image_upload/views/form.erb | 13 +++++ .../week6/image_upload/views/show_image.erb | 9 ++++ 18 files changed, 331 insertions(+) create mode 100644 examples/week5/advancedatamapper/.htaccess create mode 100644 examples/week5/advancedatamapper/app.rb create mode 100644 examples/week5/advancedatamapper/config.ru create mode 100644 examples/week5/advancedatamapper/db/visitors.yml create mode 100644 examples/week5/advancedatamapper/tmp/always_restart.txt create mode 100644 examples/week5/advancedatamapper/views/allentries.erb create mode 100644 examples/week5/advancedatamapper/views/form.erb create mode 100644 examples/week5/advancesearch/.htaccess create mode 100644 examples/week5/advancesearch/app.rb create mode 100644 examples/week5/advancesearch/config.ru create mode 100644 examples/week5/advancesearch/db/people.yml create mode 100644 examples/week5/advancesearch/tmp/always_restart.txt create mode 100644 examples/week5/advancesearch/views/form.erb create mode 100644 examples/week5/advancesearch/views/front.erb create mode 100644 examples/week5/advancesearch/views/person.erb create mode 100755 examples/week6/image_upload/app.rb create mode 100755 examples/week6/image_upload/views/form.erb create mode 100755 examples/week6/image_upload/views/show_image.erb diff --git a/examples/week5/advancedatamapper/.htaccess b/examples/week5/advancedatamapper/.htaccess new file mode 100644 index 0000000..45853dd --- /dev/null +++ b/examples/week5/advancedatamapper/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/advancedatamapper +RackEnv development diff --git a/examples/week5/advancedatamapper/app.rb b/examples/week5/advancedatamapper/app.rb new file mode 100644 index 0000000..b280eb4 --- /dev/null +++ b/examples/week5/advancedatamapper/app.rb @@ -0,0 +1,53 @@ +require 'sinatra' +require 'dm-core' +require 'dm-validations' +require 'date' + +DataMapper::setup(:default, {:adapter => 'yaml', :path => 'db'}) + + + +class Visitor + include DataMapper::Resource + + property :id, Serial + property :firstname, String, :required => true + property :lastname, String + property :catlover, Boolean, :default => false + property :petno, Integer + property :time, DateTime +end + +DataMapper.finalize + +get '/' do + erb :form +end + +post '/save_info' do + user = Visitor.new + + user.firstname = params[:fname] + user.lastname = params[:lname] + + if (params[:catlover] == "true") + user.catlover = true; + end + + user.petno = Integer(params[:pets]) + user.time = DateTime.now + + uservalid = user.save + if uservalid == true + "User name saved. Take a look at all the entries." +else + "User not saved! Return Home" + end + +end + +get '/all_entries' do + @visitors = Visitor.all + + erb :allentries +end \ No newline at end of file diff --git a/examples/week5/advancedatamapper/config.ru b/examples/week5/advancedatamapper/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/week5/advancedatamapper/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/week5/advancedatamapper/db/visitors.yml b/examples/week5/advancedatamapper/db/visitors.yml new file mode 100644 index 0000000..e856951 --- /dev/null +++ b/examples/week5/advancedatamapper/db/visitors.yml @@ -0,0 +1,31 @@ +--- +- time: 2012-12-03 16:45:33 -05:00 + firstname: zeven + catlover: false + lastname: rodriguez + petno: 1 + id: 1 +- time: 2012-12-03 17:06:19 -05:00 + firstname: zeven + catlover: false + lastname: rodriguez + petno: 1 + id: 2 +- time: 2012-12-04 09:56:40 -05:00 + firstname: zeven + catlover: false + lastname: rodriguez + id: 3 + petno: 0 +- time: 2012-12-04 09:57:30 -05:00 + firstname: Ju Young + catlover: false + lastname: Park + id: 4 + petno: 0 +- time: 2012-12-04T09:58:34-05:00 + firstname: Myriam + catlover: true + lastname: "" + petno: 2 + id: 5 diff --git a/examples/week5/advancedatamapper/tmp/always_restart.txt b/examples/week5/advancedatamapper/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/week5/advancedatamapper/views/allentries.erb b/examples/week5/advancedatamapper/views/allentries.erb new file mode 100644 index 0000000..2056952 --- /dev/null +++ b/examples/week5/advancedatamapper/views/allentries.erb @@ -0,0 +1,10 @@ +

+<%for entry in @visitors%> +

Name: <%=entry.firstname%>, <%entry.lastname%>

+

Loves cats -> <%=entry.catlover%>

+

Has <%=entry.petno%> pets

+

When? <%=entry.time.strftime('%a %d %b %Y')%>

+

___________________

+ +<%end%> +

\ No newline at end of file diff --git a/examples/week5/advancedatamapper/views/form.erb b/examples/week5/advancedatamapper/views/form.erb new file mode 100644 index 0000000..e9a551e --- /dev/null +++ b/examples/week5/advancedatamapper/views/form.erb @@ -0,0 +1,14 @@ +
+ +

+

+ +

+ Yes + No +

+ +

+ +

+
diff --git a/examples/week5/advancesearch/.htaccess b/examples/week5/advancesearch/.htaccess new file mode 100644 index 0000000..3973ba6 --- /dev/null +++ b/examples/week5/advancesearch/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/advancesearch +RackEnv development diff --git a/examples/week5/advancesearch/app.rb b/examples/week5/advancesearch/app.rb new file mode 100644 index 0000000..36ac3d6 --- /dev/null +++ b/examples/week5/advancesearch/app.rb @@ -0,0 +1,50 @@ +require 'sinatra' +require 'dm-core' + +DataMapper::setup(:default, {:adapter => 'yaml', :path => 'db'}) + +class Person + include DataMapper::Resource + property :id, Serial + property :name, String + property :email, String + property :age, Integer + property :created_at, DateTime +end + +DataMapper.finalize + +get "/" do + @people = Person.all(:order => [:created_at.desc]) + erb :front +end + +get '/person/:personid' do + @person = Person.get(params[:personid]) + erb :person +end + + +post '/save' do + + p = Person.new + p.name = params[:name] + p.age = params[:age] + p.email = params[:email] + p.created_at = Time.now + + if p.save + redirect "http://itp.nyu.edu/~zr279/sinatra/advancesearch/" + else + "IT DIDNT WORK" + end + +end + +get '/stats' do + @first = Person.first() + @last = Person.last() + @age20 = Person.all(:age.gte =>20, :age.lte => 29) + + "First visitor: #{@first.name}, Last Visitor: #{@last.name}, Visitors in 20s: #{@age20.length}" +end \ No newline at end of file diff --git a/examples/week5/advancesearch/config.ru b/examples/week5/advancesearch/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/week5/advancesearch/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/week5/advancesearch/db/people.yml b/examples/week5/advancesearch/db/people.yml new file mode 100644 index 0000000..9a188c1 --- /dev/null +++ b/examples/week5/advancesearch/db/people.yml @@ -0,0 +1,41 @@ +--- +- name: zeven + created_at: 2012-12-03 17:59:33 -05:00 + age: 26 + email: zeven@zevenwolf.com + id: 1 +- name: z + created_at: 2012-12-03 18:10:41 -05:00 + age: 25 + email: z + id: 2 +- name: a + created_at: 2012-12-03 18:10:52 -05:00 + age: 15 + email: a + id: 3 +- name: b + created_at: 2012-12-03 18:11:05 -05:00 + age: 45 + email: b + id: 4 +- name: c + created_at: 2012-12-03 18:11:57 -05:00 + age: 20 + email: c + id: 5 +- name: d + created_at: 2012-12-03 18:12:26 -05:00 + age: 41 + email: d + id: 6 +- name: ben + created_at: 2012-12-04 10:25:52 -05:00 + age: 29 + email: ben@ben.com + id: 7 +- name: Hey + created_at: 2012-12-04T10:30:14-05:00 + age: 22 + id: 8 + email: "no" diff --git a/examples/week5/advancesearch/tmp/always_restart.txt b/examples/week5/advancesearch/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/week5/advancesearch/views/form.erb b/examples/week5/advancesearch/views/form.erb new file mode 100644 index 0000000..365f4dc --- /dev/null +++ b/examples/week5/advancesearch/views/form.erb @@ -0,0 +1,34 @@ + + + + Simple Form Example + + + + +

Simple form

+

This is a simple form example.

+
+

+

+
+ + + diff --git a/examples/week5/advancesearch/views/front.erb b/examples/week5/advancesearch/views/front.erb new file mode 100644 index 0000000..fba99b4 --- /dev/null +++ b/examples/week5/advancesearch/views/front.erb @@ -0,0 +1,31 @@ +

Welcome to my birthday registration page

+ +

Register

+ +
+ +

Name

+ + +

Email

+ + +

Age

+ + + + +
+ +

Already registered friends

+ +<% for currentPerson in @people %> + +

<%= currentPerson.name %>

+

<%= currentPerson.email %>

+

<%= currentPerson.age %>

+ +

<%= currentPerson.created_at.strftime("%m/%d/%y") %>

+ Profile page + +<% end %> \ No newline at end of file diff --git a/examples/week5/advancesearch/views/person.erb b/examples/week5/advancesearch/views/person.erb new file mode 100644 index 0000000..0f61484 --- /dev/null +++ b/examples/week5/advancesearch/views/person.erb @@ -0,0 +1,2 @@ +

<%= @person.name %>

+

<%= @person.email %>

\ No newline at end of file diff --git a/examples/week6/image_upload/app.rb b/examples/week6/image_upload/app.rb new file mode 100755 index 0000000..f7f1287 --- /dev/null +++ b/examples/week6/image_upload/app.rb @@ -0,0 +1,17 @@ +require 'sinatra' + +get "/" do + erb :form +end + +post '/save_image' do + + @filename = params[:file][:filename] + file = params[:file][:tempfile] + + File.open("./public/#{@filename}", 'wb') do |f| + f.write(file.read) + end + + erb :show_image +end \ No newline at end of file diff --git a/examples/week6/image_upload/views/form.erb b/examples/week6/image_upload/views/form.erb new file mode 100755 index 0000000..df2c566 --- /dev/null +++ b/examples/week6/image_upload/views/form.erb @@ -0,0 +1,13 @@ + + + Image Upload + + +

Upload Image

+ +
+ + +
+ + \ No newline at end of file diff --git a/examples/week6/image_upload/views/show_image.erb b/examples/week6/image_upload/views/show_image.erb new file mode 100755 index 0000000..57418fd --- /dev/null +++ b/examples/week6/image_upload/views/show_image.erb @@ -0,0 +1,9 @@ + + + Show Image + + +

See Image

+ + + \ No newline at end of file From a1470c0b784ffc90161b470be819bbfecd3ab0b7 Mon Sep 17 00:00:00 2001 From: zeven Date: Wed, 5 Dec 2012 16:54:27 -0500 Subject: [PATCH 12/57] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3b7215e..8bcecb0 100644 --- a/README.md +++ b/README.md @@ -178,14 +178,14 @@ What do you want to do? What is preventing you from doing it? ### Advanced Datamapper -* [Birthday Registration Example](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week5/birthdays) +* [Birthday Registration Example](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week5/advancesearch) * More Datatypes * Serial * String * Boolean * Integer * DateTime - * [Example of all of these](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week5/datatypes) + * [Example of all of these](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week5/advancedatamapper) * Datatype options * Required * Default From c7ac9c763e312f8fb7e02e3b377a2c1cdb47ee9c Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Wed, 5 Dec 2012 17:16:58 -0500 Subject: [PATCH 13/57] week6 --- .../code/jsoup-1.7.1.jar | Bin 0 -> 278273 bytes .../httprocessingjsoupGet.pde | 38 ++++++++++++++++++ .../httprocessingpost/code/jsoup-1.7.1.jar | Bin 0 -> 278273 bytes .../httprocessingpost/httprocessingpost.pde | 17 ++++++++ .../code/jsoup-1.7.1.jar | Bin 0 -> 278273 bytes .../httprocessingpostimage/data/narwhal.jpeg | Bin 0 -> 4928 bytes .../httprocessingpostimage.pde | 17 ++++++++ examples/week6/imageupload/.htaccess | 4 ++ examples/week6/imageupload/app.rb | 17 ++++++++ examples/week6/imageupload/config.ru | 9 +++++ .../imageupload/public/images/penguin.jpeg | Bin 0 -> 3938 bytes .../week6/imageupload/tmp/always_restart.txt | 0 examples/week6/imageupload/views/form.erb | 13 ++++++ .../week6/imageupload/views/show_image.erb | 9 +++++ 14 files changed, 124 insertions(+) create mode 100644 examples/week6/httprocessingjsoupGet/code/jsoup-1.7.1.jar create mode 100644 examples/week6/httprocessingjsoupGet/httprocessingjsoupGet.pde create mode 100644 examples/week6/httprocessingpost/code/jsoup-1.7.1.jar create mode 100644 examples/week6/httprocessingpost/httprocessingpost.pde create mode 100644 examples/week6/httprocessingpostimage/code/jsoup-1.7.1.jar create mode 100644 examples/week6/httprocessingpostimage/data/narwhal.jpeg create mode 100644 examples/week6/httprocessingpostimage/httprocessingpostimage.pde create mode 100755 examples/week6/imageupload/.htaccess create mode 100755 examples/week6/imageupload/app.rb create mode 100755 examples/week6/imageupload/config.ru create mode 100644 examples/week6/imageupload/public/images/penguin.jpeg create mode 100755 examples/week6/imageupload/tmp/always_restart.txt create mode 100755 examples/week6/imageupload/views/form.erb create mode 100644 examples/week6/imageupload/views/show_image.erb diff --git a/examples/week6/httprocessingjsoupGet/code/jsoup-1.7.1.jar b/examples/week6/httprocessingjsoupGet/code/jsoup-1.7.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..75d9f6adc79ec007652f2df2a61bb6f37519def3 GIT binary patch literal 278273 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

{?y69&W@wJhnJ4jr9kO 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�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Í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

{?y69&W@wJhnJ4jr9kO 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�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Í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

{?y69&W@wJhnJ4jr9kO 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�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Í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

Upload Image

+ +
+ + +
+ + \ No newline at end of file diff --git a/examples/week6/imageupload/views/show_image.erb b/examples/week6/imageupload/views/show_image.erb new file mode 100644 index 0000000..d74eac9 --- /dev/null +++ b/examples/week6/imageupload/views/show_image.erb @@ -0,0 +1,9 @@ + + + Show Image + + +

See Image

+ + + \ No newline at end of file From 6c8f75def25c1fd11a35361f596fa3563345d8be Mon Sep 17 00:00:00 2001 From: zeven Date: Fri, 7 Dec 2012 20:17:49 -0500 Subject: [PATCH 14/57] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8bcecb0..ffed21a 100644 --- a/README.md +++ b/README.md @@ -212,9 +212,13 @@ What do you want to do? What is preventing you from doing it? ### Processing * loadStrings to your app -* Making calls from[HTTProcessing](https://github.com/runemadsen/HTTProcessing) +* Making calls from [HTTProcessing](https://github.com/runemadsen/HTTProcessing) * Other file formats (XML and JSON) +* [Processing GET and Jsoup](https://github.com/runemadsen/HTTProcessing) +* [Processing POST](https://github.com/runemadsen/HTTProcessing) +* [Processing POST Image](https://github.com/runemadsen/HTTProcessing) + ### Ruby Calling your site with a Ruby script on your machine From 1e785e7de25922f96f0e51e9cc058e48aa987d80 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Fri, 7 Dec 2012 20:18:29 -0500 Subject: [PATCH 15/57] processing --- .../httprocessingjsoupGet.pde | 11 ++++--- .../httprocessingpost/httprocessingpost.pde | 3 +- .../httprocessingpostimage.pde | 13 ++++---- examples/week6/imageupload/app.rb | 8 ++++- .../imageupload/public/images/zebra.jpeg | Bin 0 -> 12544 bytes examples/week6/processingExamples/.htaccess | 4 +++ examples/week6/processingExamples/app.rb | 30 ++++++++++++++++++ examples/week6/processingExamples/config.ru | 9 ++++++ .../public/images/developer.png | Bin 0 -> 31889 bytes .../public/images/narwhal.jpeg | Bin 0 -> 4928 bytes .../public/images/zebra.jpeg | Bin 0 -> 12544 bytes .../processingExamples/tmp/always_restart.txt | 0 .../week6/processingExamples/views/form.erb | 13 ++++++++ .../processingExamples/views/show_image.erb | 9 ++++++ 14 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 examples/week6/imageupload/public/images/zebra.jpeg create mode 100644 examples/week6/processingExamples/.htaccess create mode 100644 examples/week6/processingExamples/app.rb create mode 100644 examples/week6/processingExamples/config.ru create mode 100644 examples/week6/processingExamples/public/images/developer.png create mode 100644 examples/week6/processingExamples/public/images/narwhal.jpeg create mode 100644 examples/week6/processingExamples/public/images/zebra.jpeg create mode 100644 examples/week6/processingExamples/tmp/always_restart.txt create mode 100644 examples/week6/processingExamples/views/form.erb create mode 100644 examples/week6/processingExamples/views/show_image.erb diff --git a/examples/week6/httprocessingjsoupGet/httprocessingjsoupGet.pde b/examples/week6/httprocessingjsoupGet/httprocessingjsoupGet.pde index b271f04..e52c1a7 100644 --- a/examples/week6/httprocessingjsoupGet/httprocessingjsoupGet.pde +++ b/examples/week6/httprocessingjsoupGet/httprocessingjsoupGet.pde @@ -7,8 +7,9 @@ void setup() { GetRequest get = new GetRequest("http://itp.nyu.edu/~zr279/sinatra/processingExamples/processingget"); get.send(); - // println("Reponse Content: " + get.getContent()); - // println("Reponse Content-Length Header: " + get.getHeader("Content-Length")); + //println("Reponse Content: " + get.getContent()); + //This gives the status message. + //println("Reponse Content-Length Header: " + get.getHeader("Status")); String html = get.getContent(); @@ -19,16 +20,18 @@ void setup() { //Shows the body text - String texts = doc.body().text(); + //String texts = doc.body().text(); //Shows the "a" select String nameText = name.text(); String ageText = age.text(); - println(texts); + //println(texts); println(nameText); println(ageText); + + } diff --git a/examples/week6/httprocessingpost/httprocessingpost.pde b/examples/week6/httprocessingpost/httprocessingpost.pde index 005d4ce..47747ae 100644 --- a/examples/week6/httprocessingpost/httprocessingpost.pde +++ b/examples/week6/httprocessingpost/httprocessingpost.pde @@ -6,10 +6,11 @@ import httprocessing.*; void setup() { PostRequest post = new PostRequest("http://itp.nyu.edu/~zr279/sinatra/processingExamples/processingpost"); - post.addData("name", "Zeven"); + post.addData("name", "Jorge"); post.send(); println("Reponse Content: " + post.getContent()); println("Reponse Content-Length Header: " + post.getHeader("Content-Length")); + } void draw() { diff --git a/examples/week6/httprocessingpostimage/httprocessingpostimage.pde b/examples/week6/httprocessingpostimage/httprocessingpostimage.pde index 5cd5abe..e1e9247 100644 --- a/examples/week6/httprocessingpostimage/httprocessingpostimage.pde +++ b/examples/week6/httprocessingpostimage/httprocessingpostimage.pde @@ -1,17 +1,18 @@ //Can be downloaded at https://github.com/runemadsen/HTTProcessing import httprocessing.*; -//not working yet - -void setup() { - File picture = new File("narhwal.jpeg"); +void setup(){ + size(400, 400); + smooth(); + //Where you image is on your computer + String img = "/Users/zevenwolf/Desktop/Dropbox/Code/processing/httprocessingpostimage/data/" + "narwhal.jpeg"; + PostRequest post = new PostRequest("http://itp.nyu.edu/~zr279/sinatra/processingExamples/save_image"); - post.addFile("file", picture); + post.addFile("file", img); post.send(); println("Reponse Content: " + post.getContent()); println("Reponse Content-Length Header: " + post.getHeader("Content-Length")); } - void draw() { } diff --git a/examples/week6/imageupload/app.rb b/examples/week6/imageupload/app.rb index d3b0004..462bf93 100755 --- a/examples/week6/imageupload/app.rb +++ b/examples/week6/imageupload/app.rb @@ -12,6 +12,12 @@ File.open("./public/images/#{@filename}", 'wb') do |f| f.write(file.read) end - + + #image = Image.new + #image.link = @filename + #image.save + + #@full_path = "http://itp.nyu.edu...../public/images/" + image.link + erb :show_image end \ No newline at end of file diff --git a/examples/week6/imageupload/public/images/zebra.jpeg b/examples/week6/imageupload/public/images/zebra.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..10104fccd52f4a44bfb22ce84db88eae71af2458 GIT binary patch literal 12544 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 literal 0 HcmV?d00001 diff --git a/examples/week6/processingExamples/.htaccess b/examples/week6/processingExamples/.htaccess new file mode 100644 index 0000000..6feaa0b --- /dev/null +++ b/examples/week6/processingExamples/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/processingExamples +RackEnv development diff --git a/examples/week6/processingExamples/app.rb b/examples/week6/processingExamples/app.rb new file mode 100644 index 0000000..36f8c64 --- /dev/null +++ b/examples/week6/processingExamples/app.rb @@ -0,0 +1,30 @@ +require 'sinatra' + +get "/" do + erb :form +end + +get '/processingget' do + + '
Zeven
27
' +end + +post '/processingpost' do + + name = params[:name] + + "Welcome #{name}" + +end + +post '/save_image' do + + @filename = params[:file][:filename] + file = params[:file][:tempfile] + + File.open("./public/images/#{@filename}", 'wb') do |f| + f.write(file.read) + end + + erb :show_image +end \ No newline at end of file diff --git a/examples/week6/processingExamples/config.ru b/examples/week6/processingExamples/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/week6/processingExamples/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/week6/processingExamples/public/images/developer.png b/examples/week6/processingExamples/public/images/developer.png new file mode 100644 index 0000000000000000000000000000000000000000..6feb1a11021dfc452f90958bdf8ac6000944c1da GIT binary patch literal 31889 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 literal 0 HcmV?d00001 diff --git a/examples/week6/processingExamples/tmp/always_restart.txt b/examples/week6/processingExamples/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/week6/processingExamples/views/form.erb b/examples/week6/processingExamples/views/form.erb new file mode 100644 index 0000000..c3cb321 --- /dev/null +++ b/examples/week6/processingExamples/views/form.erb @@ -0,0 +1,13 @@ + + + Image Upload + + +

Upload Image

+ +
+ + +
+ + \ No newline at end of file diff --git a/examples/week6/processingExamples/views/show_image.erb b/examples/week6/processingExamples/views/show_image.erb new file mode 100644 index 0000000..385280a --- /dev/null +++ b/examples/week6/processingExamples/views/show_image.erb @@ -0,0 +1,9 @@ + + + Show Image + + +

See Image

+ + + \ No newline at end of file From 84dac1429cc46bd5ff6ea853d6caf3572f5a42fb Mon Sep 17 00:00:00 2001 From: zeven Date: Fri, 7 Dec 2012 20:26:40 -0500 Subject: [PATCH 16/57] Update README.md --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ffed21a..a0dc3b6 100644 --- a/README.md +++ b/README.md @@ -207,17 +207,19 @@ What do you want to do? What is preventing you from doing it? ## Week 6: More Clients and Project Help -### Image Upload +### [Image Upload](https://github.com/runemadsen/HTTProcessing) ### Processing * loadStrings to your app -* Making calls from [HTTProcessing](https://github.com/runemadsen/HTTProcessing) +* Making calls from [HTTProcessing](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week6/imageupload) * Other file formats (XML and JSON) -* [Processing GET and Jsoup](https://github.com/runemadsen/HTTProcessing) -* [Processing POST](https://github.com/runemadsen/HTTProcessing) -* [Processing POST Image](https://github.com/runemadsen/HTTProcessing) +* [Processing GET and Jsoup](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week6/httprocessingjsoupGet) +* [Processing POST](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week6/httprocessingpost) +* [Processing POST Image](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week6/httprocessingpostimage) +* [Processing POST Sinatra App](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week6/processingExamples) + ### Ruby From e61df23c2ff9aa11200f295d7e1f2586fd674409 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Thu, 13 Dec 2012 16:41:14 -0500 Subject: [PATCH 17/57] past --- PastStudentWork.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 PastStudentWork.md diff --git a/PastStudentWork.md b/PastStudentWork.md new file mode 100644 index 0000000..e69de29 From b1874d09804231e574b85a0a6d7caac448153e5a Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 13 Dec 2012 16:43:03 -0500 Subject: [PATCH 18/57] Update PastStudentWork.md --- PastStudentWork.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PastStudentWork.md b/PastStudentWork.md index e69de29..656d5ed 100644 --- a/PastStudentWork.md +++ b/PastStudentWork.md @@ -0,0 +1,3 @@ +*Past Student Work +**Fall 2012 +*** Tiffany K Hewlett From 50880212d703baceaf76c4559b45b704fb245043 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 13 Dec 2012 16:49:16 -0500 Subject: [PATCH 19/57] Update PastStudentWork.md --- PastStudentWork.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/PastStudentWork.md b/PastStudentWork.md index 656d5ed..4a622d4 100644 --- a/PastStudentWork.md +++ b/PastStudentWork.md @@ -1,3 +1,6 @@ -*Past Student Work -**Fall 2012 -*** Tiffany K Hewlett +#Past Student Work + +##Fall 2012 +[Tiffany K Hewlett Personal Trainer Site](http://itp.nyu.edu/~tkh242/sinatra/final/) + +[Myriam Melki PinTube](http://itp.nyu.edu/~mgm415/sinatra/pintube)-[Blog post](http://itp.nyu.edu/~mgm415/blog/?p=407) From 33f5189691813c906f0560f3774168e797d83f13 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 13 Dec 2012 16:50:53 -0500 Subject: [PATCH 20/57] Update PastStudentWork.md --- PastStudentWork.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/PastStudentWork.md b/PastStudentWork.md index 4a622d4..c5e3282 100644 --- a/PastStudentWork.md +++ b/PastStudentWork.md @@ -1,6 +1,7 @@ #Past Student Work ##Fall 2012 -[Tiffany K Hewlett Personal Trainer Site](http://itp.nyu.edu/~tkh242/sinatra/final/) +*[Tiffany K Hewlett Personal Trainer Site](http://itp.nyu.edu/~tkh242/sinatra/final/) -[Myriam Melki PinTube](http://itp.nyu.edu/~mgm415/sinatra/pintube)-[Blog post](http://itp.nyu.edu/~mgm415/blog/?p=407) +*[Myriam Melki PinTube](http://itp.nyu.edu/~mgm415/sinatra/pintube) + **[Blog post](http://itp.nyu.edu/~mgm415/blog/?p=407) From eefc1b26f85ad374c74bed455548a299d8c27bda Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 13 Dec 2012 16:52:42 -0500 Subject: [PATCH 21/57] Update PastStudentWork.md --- PastStudentWork.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PastStudentWork.md b/PastStudentWork.md index c5e3282..922f520 100644 --- a/PastStudentWork.md +++ b/PastStudentWork.md @@ -1,7 +1,7 @@ #Past Student Work ##Fall 2012 -*[Tiffany K Hewlett Personal Trainer Site](http://itp.nyu.edu/~tkh242/sinatra/final/) +* [Tiffany K Hewlett Personal Trainer Site](http://itp.nyu.edu/~tkh242/sinatra/final/) -*[Myriam Melki PinTube](http://itp.nyu.edu/~mgm415/sinatra/pintube) - **[Blog post](http://itp.nyu.edu/~mgm415/blog/?p=407) +* [Myriam Melki PinTube](http://itp.nyu.edu/~mgm415/sinatra/pintube) + * [Blog post](http://itp.nyu.edu/~mgm415/blog/?p=407) From 819785187fecb62a22ea3640d749ddd4a3f7ab8d Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 13 Dec 2012 16:57:58 -0500 Subject: [PATCH 22/57] Update PastStudentWork.md --- PastStudentWork.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/PastStudentWork.md b/PastStudentWork.md index 922f520..4e40227 100644 --- a/PastStudentWork.md +++ b/PastStudentWork.md @@ -5,3 +5,11 @@ * [Myriam Melki PinTube](http://itp.nyu.edu/~mgm415/sinatra/pintube) * [Blog post](http://itp.nyu.edu/~mgm415/blog/?p=407) + + +* [Ju Young Park Color Calendar](http://itp.nyu.edu/~jyp323/sinatra/test1) + * [Blog post](http://itp.nyu.edu/~jyp323/ju/?p=125) + + +* [Sergio Majluf Excuses Generator](http://itp.nyu.edu/~sam926/sinatra/excuseme/) + * [Blog post](http://itp.nyu.edu/~sam926/the-excuses-generator/) From d50ac0d098a76bad40e21ccae0764f9c385768ef Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 13 Dec 2012 16:58:25 -0500 Subject: [PATCH 23/57] Update PastStudentWork.md --- PastStudentWork.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/PastStudentWork.md b/PastStudentWork.md index 4e40227..b35b941 100644 --- a/PastStudentWork.md +++ b/PastStudentWork.md @@ -5,11 +5,9 @@ * [Myriam Melki PinTube](http://itp.nyu.edu/~mgm415/sinatra/pintube) * [Blog post](http://itp.nyu.edu/~mgm415/blog/?p=407) - - + * [Ju Young Park Color Calendar](http://itp.nyu.edu/~jyp323/sinatra/test1) * [Blog post](http://itp.nyu.edu/~jyp323/ju/?p=125) - * [Sergio Majluf Excuses Generator](http://itp.nyu.edu/~sam926/sinatra/excuseme/) * [Blog post](http://itp.nyu.edu/~sam926/the-excuses-generator/) From 63be12c87a25baa790218cc2adc9defdfe0b6019 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 13 Dec 2012 18:44:48 -0500 Subject: [PATCH 24/57] Update PastStudentWork.md --- PastStudentWork.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PastStudentWork.md b/PastStudentWork.md index b35b941..39cf879 100644 --- a/PastStudentWork.md +++ b/PastStudentWork.md @@ -11,3 +11,6 @@ * [Sergio Majluf Excuses Generator](http://itp.nyu.edu/~sam926/sinatra/excuseme/) * [Blog post](http://itp.nyu.edu/~sam926/the-excuses-generator/) + +* [Christina Carter Paint Your Face](http://itp.nyu.edu/~cvc261/sinatra/paintyourface) + * [Blog post](http://itp.nyu.edu/~cvc261/blog/?p=482) From 307a0368f6b20765c553b1289fb96f6741d53c94 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 31 Jan 2013 10:39:16 -0500 Subject: [PATCH 25/57] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a0dc3b6..07f2840 100644 --- a/README.md +++ b/README.md @@ -94,9 +94,9 @@ Sinatra Up and Running, p. 15-21 (It’s not much, so please read it thoroughly) ### Setting up a Sinatra app on the ITP server 1. Open Terminal (Putty for Windows) -2. run `ssh[netid](mailto:netid@stu.itp.nyu.edu) [@stu.itp.nyu.edu](mailto:netid@stu.itp.nyu.edu) `. Remember to put in your netid instead of “netid” +2. run `ssh netid@stu.itp.nyu.edu`. Remember to put in your netid instead of “netid” 3. Type in your password when prompted -4. run `ruby < <(curl -s http://runemadsen-2012.s3.amazonaws.com/new_sinatra_app.rb) - nameofapp`. Remember to replace “nameofapp” with the name of your application. +4. run `ruby /etc/new_sinatra_app.rb nameofapp`. Remember to replace “nameofapp” with the name of your application. 5. Go to your blank Sinatra app here (using your netid and the name of your app):[http://itp.nyu.edu/](http://itp.nyu.edu/~netID/sinatra/nameofapp) [~](http://itp.nyu.edu/~netID/sinatra/nameofapp) [netID](http://itp.nyu.edu/~netID/sinatra/nameofapp) [/sinatra/](http://itp.nyu.edu/~netID/sinatra/nameofapp) [nameofapp](http://itp.nyu.edu/~netID/sinatra/nameofapp) ### Homework For Next Week From 8508be319ebdc425643af7ebb8bd3aa451d9b525 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 31 Jan 2013 10:46:05 -0500 Subject: [PATCH 26/57] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 07f2840..44995b4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # Comm Lab Web Syllabus Fall 2012 +#Posting your HW +* [Submit your HW here](https://docs.google.com/spreadsheet/viewform?formkey=dG1ZTHlUdlhQX21GMWlpdlFlcDI2X1E6MQ) +If you miss more then 1 assignment you will not pass! + + ## Week 1: Hello, Sinatra ### Readings For This Week From fe5dca17ea96dd9f2c0ce4ef4b0be0b6c7de2fa4 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 31 Jan 2013 10:46:29 -0500 Subject: [PATCH 27/57] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 44995b4..de43b0b 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ #Posting your HW * [Submit your HW here](https://docs.google.com/spreadsheet/viewform?formkey=dG1ZTHlUdlhQX21GMWlpdlFlcDI2X1E6MQ) + If you miss more then 1 assignment you will not pass! From b2bbda9f286c72eb7d274ca3cb5fc8d039908225 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 31 Jan 2013 10:46:56 -0500 Subject: [PATCH 28/57] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index de43b0b..1921a65 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ # Comm Lab Web Syllabus Fall 2012 #Posting your HW -* [Submit your HW here](https://docs.google.com/spreadsheet/viewform?formkey=dG1ZTHlUdlhQX21GMWlpdlFlcDI2X1E6MQ) If you miss more then 1 assignment you will not pass! +* [Submit your HW here](https://docs.google.com/spreadsheet/viewform?formkey=dG1ZTHlUdlhQX21GMWlpdlFlcDI2X1E6MQ) + + ## Week 1: Hello, Sinatra From 80d464a126afbad06bd57f3d29b3db94125d1510 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Thu, 31 Jan 2013 10:51:27 -0500 Subject: [PATCH 29/57] userclient --- userclient.jpeg | Bin 0 -> 85472 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 userclient.jpeg diff --git a/userclient.jpeg b/userclient.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..230a2a539d46c172089ae3e4cbc63af4905ea4e5 GIT binary patch literal 85472 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 literal 0 HcmV?d00001 From 8f3cd8da02d06c053df2fb3164edfa43c354a17f Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 31 Jan 2013 10:57:37 -0500 Subject: [PATCH 30/57] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1921a65..fb59849 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# Comm Lab Web Syllabus Fall 2012 +# Comm Lab Web + +The goal of Comm Lab Web is to develop creative web applications. #Posting your HW From 83ac81fda77996e3eb3009dc9f2c045e8edf63e7 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 31 Jan 2013 11:28:13 -0500 Subject: [PATCH 31/57] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fb59849..b830f46 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ If you miss more then 1 assignment you will not pass! * Your Sinatra folder * Simple Sinatra script -* [Simple HTML form example in Sinatra](https://github.com/ITPNYU/CommLabWeb/tree/master/examples/week1/simple_form) +* [Simple HTML form example in Sinatra](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week1/simple_form) ### Assignment From 16cbb700b4fb686ab51fe1c0a95cfc89e1361439 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 31 Jan 2013 11:28:58 -0500 Subject: [PATCH 32/57] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b830f46..248cf8d 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ If you miss more then 1 assignment you will not pass! * Tags * `, , <body>, <em>, <strong>, <h1-h5>, <a>, <img>, <ol>, <ul>, <p>` * Introduce `<form>` and `<input>` types - * [Example with many form inputs](https://github.com/ITPNYU/CommLabWeb/blob/master/examples/basic_form.html) + * [Example with many form inputs](https://github.com/zevenwolf/CommLabWeb/blob/master/examples/basic_form.html) ### Dynamic HTML with Sinatra and HTML form From 202b88ebf1a91c875a70fd4c58d5e31e8bd789bd Mon Sep 17 00:00:00 2001 From: zeven <zevenwolf@gmail.com> Date: Thu, 31 Jan 2013 11:59:02 -0500 Subject: [PATCH 33/57] Update README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 248cf8d..6a7e868 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,8 @@ If you miss more then 1 assignment you will not pass! ### Assignment #### Part 1 + +##### Option 1: Etzy App You've got a great idea for the next big thing: it's called Etzy, and it's a place to sell artwork online. You want to drum up interest and get some visitor feedback, so you decide to create a signup form! @@ -64,6 +66,14 @@ The page should include the following: * a dropdown menu for "How you heard about us" ("google", "from a friend", "online ad", etc.) * a radio button group for choosing a role ("buyer", "seller", or "both") +##### Option 2: Making your own text adventure! Create your character form: +* Name +* Small back story +* Dropdown menu for "Weapon choice" (“Sword”, “Ax”, “Wand”) +* A radio button group for choosing a role ("Male", "Female", or "Ambiguous") +* Check boxes “What to carry:” (“Potions”, “Food”, “etc”) + + ##### Reference * Read [WHATWG: Forms](http://developers.whatwg.org/forms.html) * If you're stuck, look at this [basic form example](https://github.com/ckundo/CommLabWeb/blob/master/examples/basic_form.html) for guidance. From 485321ef0e28e542708355f8b3a54dd308cc52b9 Mon Sep 17 00:00:00 2001 From: zeven <zevenwolf@gmail.com> Date: Thu, 31 Jan 2013 12:04:35 -0500 Subject: [PATCH 34/57] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a7e868..6d4979b 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ The page should include the following: ##### Reference * Read [WHATWG: Forms](http://developers.whatwg.org/forms.html) -* If you're stuck, look at this [basic form example](https://github.com/ckundo/CommLabWeb/blob/master/examples/basic_form.html) for guidance. +* If you're stuck, look at this [basic form example](https://github.com/zevenwolf/CommLabWeb/blob/master/examples/basic_form.html) for guidance. #### Part 2 We will also start looking at Ruby and Sinatra this week too, so we can start building a backend for our signup form. From f49164b5c18cce425f1084bdaf797b84f607993a Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez <zevenwolf@gmail.com> Date: Thu, 31 Jan 2013 11:26:04 -0500 Subject: [PATCH 35/57] basic_form --- examples/basic_form.html | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/basic_form.html b/examples/basic_form.html index 1c426f8..54dfc5d 100644 --- a/examples/basic_form.html +++ b/examples/basic_form.html @@ -11,24 +11,24 @@ <ul> <li> <label for="full-name">Your name</label> - <input id="full-name" type="text" name="settings[full_name]" /> + <input id="full-name" type="text" name="full_name" /> </li> <li> <!-- Some browsers automatically validate HTML5 input types, such as "email" --> <label for="email">Your email</label> - <input id="email" type="email" name="settings[email]" /> + <input id="email" type="email" name="email" /> </li> <li> - <input id="gender-male" type="radio" name="settings[gender]" value="male" /> + <input id="gender-male" type="radio" name="gender" value="male" /> <label for="gender-male">Male</label> - <input id="gender-female" type="radio" name="settings[gender]" value="female" /> + <input id="gender-female" type="radio" name="gender" value="female" /> <label for="gender-female">Female</label> - <input id="gender-na" type="radio" name="settings[gender]" value="na" /> + <input id="gender-na" type="radio" name="gender" value="na" /> <label for="gender-na">Not telling</label> </li> <li> <label for="party">Political Party</label> - <select id="party" name="settings[party]"> + <select id="party" name="party"> <option value></option> <option value="democrat">Democrat</option> <option value="republican">Republican</option> @@ -38,26 +38,26 @@ <li> <!-- Placeholders give a visual hint to the user --> <label for="bio">Bio</label> - <textarea id="bio" name="settings[bio]" placeholder="Tell us your life story"></textarea> + <textarea id="bio" name="bio" placeholder="Tell us your life story"></textarea> </li> <li> <!-- Checkboxes are for true/false responses --> - <input id="contact-spam" type="checkbox" value="1" name="settings[spam_contacts]"/> + <input id="contact-spam" type="checkbox" value="1" name="spam_contacts"/> <label for="contact-spam">Send invites to all my contacts</label> </li> <li> <!-- Set checkbox or radio default to be selected with the "checked" attribute --> - <input id="personal-spam" type="checkbox" checked="checked" value="1" name="settings[personal_spam]"/> + <input id="personal-spam" type="checkbox" checked="checked" value="1" name="personal_spam"/> <label for="personal-spam">Send me spam based on my personal details</label> </li> <li> - <input id="third-party-spam" type="checkbox" checked="checked" disabled="disabled" value="1" name="settings[third_party_spam]"/> + <input id="third-party-spam" type="checkbox" checked="checked" disabled="disabled" value="1" name="third_party_spam"/> <label for="third-party-spam">Sell my information to the highest bidder</label> </li> <li> <!-- Disable inputs with the "disabled" attribute --> <label for="current-password">Current password</label> - <input id="current-password" type="password" name="settings[current_password]" /> + <input id="current-password" type="password" name="current_password" /> </li> </ul> <input type="submit" value="Update Profile" /> From 0d66860f855ef24f2ba3f530c2107765efe38961 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez <zevenwolf@gmail.com> Date: Thu, 31 Jan 2013 12:24:13 -0500 Subject: [PATCH 36/57] basic html --- examples/basic_html.html | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 examples/basic_html.html diff --git a/examples/basic_html.html b/examples/basic_html.html new file mode 100644 index 0000000..b922ac0 --- /dev/null +++ b/examples/basic_html.html @@ -0,0 +1,43 @@ +<html> + <head> + <title>This is a basic HTML Document + + + +

Header 1

+

Header 2

+

Header 3

+

Header 4

+
Header 5
+ +

This is a paragraph tag

+ + Italics + Bold + +
This is a link + + + +
    + +
  1. Ordered List 1
  2. +
  3. Ordered List 2
  4. +
  5. Ordered List 3
  6. + +
+ + +
    + +
  • Unordered List 1
  • +
  • Unordered List 2
  • +
  • Unordered List 3
  • + +
+ + + + + + \ No newline at end of file From 01ff9d45c498b50a2e80df2c30db75cdf65e946f Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 31 Jan 2013 12:26:08 -0500 Subject: [PATCH 37/57] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6d4979b..c91b4c1 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ If you miss more then 1 assignment you will not pass! * Tags that open and close * Mark up content * Nested tags + * [Basic Html Example](https://github.com/zevenwolf/CommLabWeb/blob/master/examples/basic_html.html) * Tags * `, , <body>, <em>, <strong>, <h1-h5>, <a>, <img>, <ol>, <ul>, <p>` From 313bd96113a9bcab4614932cacc014a4f516680a Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez <zevenwolf@gmail.com> Date: Thu, 31 Jan 2013 14:13:33 -0500 Subject: [PATCH 38/57] textadventure --- examples/about.html | 15 +++++++++++++++ examples/basic_html.html | 15 +++++++++++---- examples/contact.html | 15 +++++++++++++++ examples/textadventrue/adventure.html | 21 +++++++++++++++++++++ examples/textadventrue/hall.html | 14 ++++++++++++++ examples/textadventrue/lever.html | 12 ++++++++++++ examples/textadventrue/right.html | 15 +++++++++++++++ 7 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 examples/about.html create mode 100644 examples/contact.html create mode 100644 examples/textadventrue/adventure.html create mode 100644 examples/textadventrue/hall.html create mode 100644 examples/textadventrue/lever.html create mode 100644 examples/textadventrue/right.html diff --git a/examples/about.html b/examples/about.html new file mode 100644 index 0000000..554c612 --- /dev/null +++ b/examples/about.html @@ -0,0 +1,15 @@ +<html> + <head> + <title>This is the About Page + + + +

This is the About Page

+ + Home + About + Contact + + + + \ No newline at end of file diff --git a/examples/basic_html.html b/examples/basic_html.html index b922ac0..a9d163c 100644 --- a/examples/basic_html.html +++ b/examples/basic_html.html @@ -11,14 +11,21 @@

Header 4

Header 5

This is a paragraph tag

- +
Italics +
Bold +
+
+ Home - This is a link + About + Contact +
+
- +
  1. Ordered List 1
  2. @@ -26,7 +33,7 @@
    Header 5
  3. Ordered List 3
- +
    diff --git a/examples/contact.html b/examples/contact.html new file mode 100644 index 0000000..6277b11 --- /dev/null +++ b/examples/contact.html @@ -0,0 +1,15 @@ + + + This is the Contact Page + + + +

    This is the Contact Page

    + + Home + About + Contact + + + + \ No newline at end of file diff --git a/examples/textadventrue/adventure.html b/examples/textadventrue/adventure.html new file mode 100644 index 0000000..0e4cb8b --- /dev/null +++ b/examples/textadventrue/adventure.html @@ -0,0 +1,21 @@ + + + +You are in a cave. + + +

    You are in a cave.

    + +
    + +Look to the right + +
    + +Pull Lever + +
    + +Walk through the hall + + \ No newline at end of file diff --git a/examples/textadventrue/hall.html b/examples/textadventrue/hall.html new file mode 100644 index 0000000..ccf3524 --- /dev/null +++ b/examples/textadventrue/hall.html @@ -0,0 +1,14 @@ + + + +You walked down the Hall. + + +

    You walked down the Hall. Arrows fly from all directions. You are DEAD!

    + +
    + +Go back to the beginning + + + \ No newline at end of file diff --git a/examples/textadventrue/lever.html b/examples/textadventrue/lever.html new file mode 100644 index 0000000..3f667e7 --- /dev/null +++ b/examples/textadventrue/lever.html @@ -0,0 +1,12 @@ + + + +You pulled the lever! + + +

    You pulled the lever! A gate opens you walk through.

    + +
    + + + \ No newline at end of file diff --git a/examples/textadventrue/right.html b/examples/textadventrue/right.html new file mode 100644 index 0000000..2e87138 --- /dev/null +++ b/examples/textadventrue/right.html @@ -0,0 +1,15 @@ + + + +Watch Out! You are looking down a cliff! + + +

    Watch Out! You are looking down a cliff!

    + +
    + +Go back to the beginning + + + + \ No newline at end of file From ecec097f85afe60c024227ce89681749e7ce784d Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Thu, 31 Jan 2013 14:15:49 -0500 Subject: [PATCH 39/57] textadventure fix --- examples/{textadventrue => textadventure}/adventure.html | 0 examples/{textadventrue => textadventure}/hall.html | 0 examples/{textadventrue => textadventure}/lever.html | 0 examples/{textadventrue => textadventure}/right.html | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename examples/{textadventrue => textadventure}/adventure.html (100%) rename examples/{textadventrue => textadventure}/hall.html (100%) rename examples/{textadventrue => textadventure}/lever.html (100%) rename examples/{textadventrue => textadventure}/right.html (100%) diff --git a/examples/textadventrue/adventure.html b/examples/textadventure/adventure.html similarity index 100% rename from examples/textadventrue/adventure.html rename to examples/textadventure/adventure.html diff --git a/examples/textadventrue/hall.html b/examples/textadventure/hall.html similarity index 100% rename from examples/textadventrue/hall.html rename to examples/textadventure/hall.html diff --git a/examples/textadventrue/lever.html b/examples/textadventure/lever.html similarity index 100% rename from examples/textadventrue/lever.html rename to examples/textadventure/lever.html diff --git a/examples/textadventrue/right.html b/examples/textadventure/right.html similarity index 100% rename from examples/textadventrue/right.html rename to examples/textadventure/right.html From b093a18045441cb8109c5c478650c1635fa29ab1 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 31 Jan 2013 14:18:46 -0500 Subject: [PATCH 40/57] Update README.md --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c91b4c1..6f4c109 100644 --- a/README.md +++ b/README.md @@ -67,14 +67,18 @@ The page should include the following: * a dropdown menu for "How you heard about us" ("google", "from a friend", "online ad", etc.) * a radio button group for choosing a role ("buyer", "seller", or "both") -##### Option 2: Making your own text adventure! Create your character form: +You should also create a 3 page site with a Home (which can be your form) and 2 other links with text and image + + +##### Option 2: Making your own text Game! Create your character form: * Name * Small back story * Dropdown menu for "Weapon choice" (“Sword”, “Ax”, “Wand”) * A radio button group for choosing a role ("Male", "Female", or "Ambiguous") * Check boxes “What to carry:” (“Potions”, “Food”, “etc”) - +Most text adventures operate in the following: Your character enters a room and is able to investigate. Your investigations leads to consequences. +[Click on the link for an example](http://itp.nyu.edu/~zr279/textadventure/adventure.html) [Code](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/textadventure) ##### Reference * Read [WHATWG: Forms](http://developers.whatwg.org/forms.html) * If you're stuck, look at this [basic form example](https://github.com/zevenwolf/CommLabWeb/blob/master/examples/basic_form.html) for guidance. From 5861e6a7416b0231516336a34b9b1af6f37ea329 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 31 Jan 2013 14:19:21 -0500 Subject: [PATCH 41/57] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f4c109..1cda102 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,9 @@ You should also create a 3 page site with a Home (which can be your form) and 2 * Check boxes “What to carry:” (“Potions”, “Food”, “etc”) Most text adventures operate in the following: Your character enters a room and is able to investigate. Your investigations leads to consequences. -[Click on the link for an example](http://itp.nyu.edu/~zr279/textadventure/adventure.html) [Code](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/textadventure) +[Click on the link for an example](http://itp.nyu.edu/~zr279/textadventure/adventure.html) +[Code](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/textadventure) + ##### Reference * Read [WHATWG: Forms](http://developers.whatwg.org/forms.html) * If you're stuck, look at this [basic form example](https://github.com/zevenwolf/CommLabWeb/blob/master/examples/basic_form.html) for guidance. From 99fe5d9a83c52807c0ffca43762b327011f13f2c Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 31 Jan 2013 14:19:43 -0500 Subject: [PATCH 42/57] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1cda102..6055272 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ You should also create a 3 page site with a Home (which can be your form) and 2 Most text adventures operate in the following: Your character enters a room and is able to investigate. Your investigations leads to consequences. [Click on the link for an example](http://itp.nyu.edu/~zr279/textadventure/adventure.html) + [Code](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/textadventure) ##### Reference From ab41b6f343c1834767ca6ce1cc40679246a0e2af Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Tue, 12 Feb 2013 17:25:41 -0500 Subject: [PATCH 43/57] readme --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 6055272..915652f 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,16 @@ Sinatra Up and Running, p. 15-21 (It’s not much, so please read it thoroughly) * Render HTML with Sinatra * Send to route in Sinatra +### Intro to Sinatra + +Sinatra works by declaring routes. Routes are the URLs associated with your application. A simple route looks like this: + +get '/home' do + +end + + + ### Setting up a Sinatra app on the ITP server 1. Open Terminal (Putty for Windows) From caa9db05504a4bfeef45b3a5bb55e2e7703d93bc Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Tue, 12 Feb 2013 22:57:29 -0500 Subject: [PATCH 44/57] sinatra notes --- README.md | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 915652f..0a61a86 100644 --- a/README.md +++ b/README.md @@ -119,13 +119,68 @@ Sinatra Up and Running, p. 15-21 (It’s not much, so please read it thoroughly) * Render HTML with Sinatra * Send to route in Sinatra +The components of a for have 2 parts, the form tag and the body + +
    + + + +
    + +* Form Tag + * Action - Route where the form data will be processed + * Method - Which Http request protocol to use + +* Body - Form inputs + * type - The method of input + * name - The reference for the value + * value - The user input selection or text + + ### Intro to Sinatra Sinatra works by declaring routes. Routes are the URLs associated with your application. A simple route looks like this: -get '/home' do + get '/home' do + "Code goes in here" + end + +Think of routes as litte programs that are going to run when you you visit the link. The route is composed of 2 imporant parts the method and the link. + +Methods include: GET, POST, DELETE, PUT, etc. After the method you declare the link. In class, we mostly use GET and POST. + +GET - Requests data from a specified resource +POST - Submits data to be processed to a specified resource + +GET requests can be used in routes that: + * Serve up content + * Process form + * Form data public + * The form data is sent in the URL in name and value pairs + +POST requests can be used in routes that: + * Process form + * Form data private + * Information is sent in the HTTP message body + + +For more differences visit [click here](http://www.w3schools.com/tags/ref_httpmethods.asp). + +What about the form data? + +Sinatra uses a global variable called parameters. The syntax for parameters is params[:name]. The :name is the reference name pulled from the form. Parameters can also be pulled from a url route. When used in a route /home/:name , this can be referenced by params[:name] + +This is an example for taking in a value from a form: + + post '/home' do + name = params[:name] + end + +This is an example for taking in a value from a url -end + get '/home/:name' do + name = params[:name] + end From 20725d2842561aae5b477bd61ce16890e118de91 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Mon, 18 Feb 2013 18:32:30 -0500 Subject: [PATCH 45/57] notes and examples --- README.md | 65 +++++++++-- examples/week2/week2classexamples/app.rb | 101 +++++++++++++----- .../week2classexamples/views/adventure.erb | 22 ++++ .../week2classexamples/views/category.erb | 4 + .../views/characterform.erb | 7 ++ .../week2/week2classexamples/views/check.erb | 11 ++ .../week2/week2classexamples/views/form.erb | 13 ++- .../week2/week2classexamples/views/left.erb | 0 .../week2/week2classexamples/views/pull.erb | 0 .../week2/week2classexamples/views/right.erb | 16 +++ .../week2/week2classexamples/views/test.erb | 0 .../week2/week2classexamples/views/yesno.erb | 15 +++ 12 files changed, 217 insertions(+), 37 deletions(-) create mode 100644 examples/week2/week2classexamples/views/adventure.erb create mode 100644 examples/week2/week2classexamples/views/category.erb create mode 100644 examples/week2/week2classexamples/views/characterform.erb create mode 100644 examples/week2/week2classexamples/views/check.erb create mode 100644 examples/week2/week2classexamples/views/left.erb create mode 100644 examples/week2/week2classexamples/views/pull.erb create mode 100644 examples/week2/week2classexamples/views/right.erb create mode 100644 examples/week2/week2classexamples/views/test.erb create mode 100644 examples/week2/week2classexamples/views/yesno.erb diff --git a/README.md b/README.md index 0a61a86..df5ce49 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,16 @@ Sinatra Up and Running, p. 15-21 (It’s not much, so please read it thoroughly) ### [Sinatra](http://goo.gl/ZLGyk) + +### Setting up a Sinatra app on the ITP server + +1. Open Terminal (Putty for Windows) +2. run `ssh netid@stu.itp.nyu.edu`. Remember to put in your netid instead of “netid” +3. Type in your password when prompted +4. run `ruby /etc/new_sinatra_app.rb nameofapp`. Remember to replace “nameofapp” with the name of your application. +5. Go to your blank Sinatra app here (using your netid and the name of your app):[http://itp.nyu.edu/](http://itp.nyu.edu/~netID/sinatra/nameofapp) [~](http://itp.nyu.edu/~netID/sinatra/nameofapp) [netID](http://itp.nyu.edu/~netID/sinatra/nameofapp) [/sinatra/](http://itp.nyu.edu/~netID/sinatra/nameofapp) [nameofapp](http://itp.nyu.edu/~netID/sinatra/nameofapp) + + * Ruby * General (no types, etc) * Syntax @@ -182,15 +192,58 @@ This is an example for taking in a value from a url name = params[:name] end +When we want to output variables from sinatra from our route: + post '/home' do + + name = params[:name] + "This is my name #{name}" + + end + +When we want to output variables from sinatra to our erb: + +The @ symbol is use to signify that the variable can be accessed from the erb template + +app.rb + + post '/home' do + + @name = params[:name] + + erb :name + + end + +name.erb + +

    <%=@name%>

    + + +You can run ruby code in your erb. + +name.erb + <% name = "zeven" %> +

    My name is <%=name%>

    + + +This will output the HTML code: + +

    My name is zeven

    + +The <% %> escape characters are used to write ruby code: + + <% name = "zeven" %> + +This will not output anything in your template + +To output variables to your template: + +The sinatra reads the = sign and understands to render the variable + + <%=variable%> -### Setting up a Sinatra app on the ITP server -1. Open Terminal (Putty for Windows) -2. run `ssh netid@stu.itp.nyu.edu`. Remember to put in your netid instead of “netid” -3. Type in your password when prompted -4. run `ruby /etc/new_sinatra_app.rb nameofapp`. Remember to replace “nameofapp” with the name of your application. -5. Go to your blank Sinatra app here (using your netid and the name of your app):[http://itp.nyu.edu/](http://itp.nyu.edu/~netID/sinatra/nameofapp) [~](http://itp.nyu.edu/~netID/sinatra/nameofapp) [netID](http://itp.nyu.edu/~netID/sinatra/nameofapp) [/sinatra/](http://itp.nyu.edu/~netID/sinatra/nameofapp) [nameofapp](http://itp.nyu.edu/~netID/sinatra/nameofapp) ### Homework For Next Week diff --git a/examples/week2/week2classexamples/app.rb b/examples/week2/week2classexamples/app.rb index 41a2fd2..2c88b71 100644 --- a/examples/week2/week2classexamples/app.rb +++ b/examples/week2/week2classexamples/app.rb @@ -1,61 +1,110 @@ require 'sinatra' # Main route - this is the form is shown -get '/' do - "Hello" +get '/' do + erb :form end -get '/html' do +get '/character' do - "This is an example of simple routes. Check out the Home

    Done

    " - + erb :characterform end -get '/form' do +post '/name' do - @title = "This is passing a variable" - erb :form + name = params[:character] + #name is the ruby variable I am inputing + #if I want to display from my sinatra file + "Hello #{name}" end - -post '/form' do +get '/apple/:type' do + #when bring a variable from app.rb to an erb use @variable sign. In your erb use this syntax <%=@variable%> + @category = params[:type] - var = params[:yourname] - "This is my name #{var}" - ##"This is my name" + params[:yourname] + erb :category +end +get '/yesno' do + + erb :yesno end -get '/urlparams' do +post '/yesno' do + response = params[:question] - id = params[:id] - name = params[:name] + if response == "yes" + #"The response was yes" + erb :adventure + elsif response == "no" + "The response was no" + else + "Something didnt happen correctly" + end - "This is the id: #{id} name: #{name}" +end +get '/check' do + erb :check end -get '/name/:id' do +post '/check' do + #When a checkbox is not selected no param is sent. + checkbox1 = params[:check1] + checkbox2 = params[:check2] + checkbox3 = params[:check3] + + - "This is the id #{params[:id]}" + if checkbox1 == "1" + "We love ruby/sinatra" + else + "We hate ruby/sinatra" + end + +end + + + + + + + + + + + + + +get '/adventure' do + erb :adventure +end + +get '/left' do + erb :left end -get '/name' do +get '/pull' do - "Name" + erb :pull +end + +get '/right' do + erb :right end -get '/same_route' do - "Same route #1" -end -get '/same_route' do - "Same route #2" + +# Second route - this is the form is posted to +get '/hello' do + # params[:yourname] will be replaced with the value entered for + # the input with name 'yourname' + "Hello " + params[:yourname] end diff --git a/examples/week2/week2classexamples/views/adventure.erb b/examples/week2/week2classexamples/views/adventure.erb new file mode 100644 index 0000000..8a64fcc --- /dev/null +++ b/examples/week2/week2classexamples/views/adventure.erb @@ -0,0 +1,22 @@ + + + + +You are in a cave. + + +

    You are in a cave.

    + +
    + +Look to the right + +
    + +Pull Lever + +
    + +Walk through the hall + + \ No newline at end of file diff --git a/examples/week2/week2classexamples/views/category.erb b/examples/week2/week2classexamples/views/category.erb new file mode 100644 index 0000000..2ec925a --- /dev/null +++ b/examples/week2/week2classexamples/views/category.erb @@ -0,0 +1,4 @@ +

    This apple is a <%=@category%>

    + +<%var = "hello"%> +<%=var%> \ No newline at end of file diff --git a/examples/week2/week2classexamples/views/characterform.erb b/examples/week2/week2classexamples/views/characterform.erb new file mode 100644 index 0000000..64c4a83 --- /dev/null +++ b/examples/week2/week2classexamples/views/characterform.erb @@ -0,0 +1,7 @@ +
    +

    Enter your character name here

    + + + + +
    \ No newline at end of file diff --git a/examples/week2/week2classexamples/views/check.erb b/examples/week2/week2classexamples/views/check.erb new file mode 100644 index 0000000..833925e --- /dev/null +++ b/examples/week2/week2classexamples/views/check.erb @@ -0,0 +1,11 @@ +
    + + + + + + + + + +
    \ No newline at end of file diff --git a/examples/week2/week2classexamples/views/form.erb b/examples/week2/week2classexamples/views/form.erb index fc175e2..2d0b2a4 100644 --- a/examples/week2/week2classexamples/views/form.erb +++ b/examples/week2/week2classexamples/views/form.erb @@ -23,13 +23,16 @@ -

    <%=@title%>

    -

    Simple form

    +

    Simple form

    This is a simple form example.

    -
    -

    + + + +

    -
    + + + diff --git a/examples/week2/week2classexamples/views/left.erb b/examples/week2/week2classexamples/views/left.erb new file mode 100644 index 0000000..e69de29 diff --git a/examples/week2/week2classexamples/views/pull.erb b/examples/week2/week2classexamples/views/pull.erb new file mode 100644 index 0000000..e69de29 diff --git a/examples/week2/week2classexamples/views/right.erb b/examples/week2/week2classexamples/views/right.erb new file mode 100644 index 0000000..7c6947c --- /dev/null +++ b/examples/week2/week2classexamples/views/right.erb @@ -0,0 +1,16 @@ + + + + +Watch Out! You are looking down a cliff! + + +

    Watch Out! You are looking down a cliff!

    + +
    + +Go back to the beginning + + + + \ No newline at end of file diff --git a/examples/week2/week2classexamples/views/test.erb b/examples/week2/week2classexamples/views/test.erb new file mode 100644 index 0000000..e69de29 diff --git a/examples/week2/week2classexamples/views/yesno.erb b/examples/week2/week2classexamples/views/yesno.erb new file mode 100644 index 0000000..9e29732 --- /dev/null +++ b/examples/week2/week2classexamples/views/yesno.erb @@ -0,0 +1,15 @@ +
    + + + + + + + + + + + +
    \ No newline at end of file From b6a22db17c228ea3453ebd446b2a16467dc74f95 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Wed, 20 Feb 2013 21:06:30 -0500 Subject: [PATCH 46/57] isnil --- examples/week2/week2classexamples/app.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/week2/week2classexamples/app.rb b/examples/week2/week2classexamples/app.rb index 2c88b71..f20477a 100644 --- a/examples/week2/week2classexamples/app.rb +++ b/examples/week2/week2classexamples/app.rb @@ -61,8 +61,10 @@ if checkbox1 == "1" "We love ruby/sinatra" + elsif checkbox1.nil? + "We do not love ruby/sinatra" else - "We hate ruby/sinatra" + "not working" end end From 29f218b725dda5355f2fce03f63f5f695cef91b2 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Tue, 26 Feb 2013 10:57:41 -0500 Subject: [PATCH 47/57] week4 --- README.md | 56 +++++++++ examples/blog/app.rb | 111 +++++++++--------- examples/blog/db/blog_posts.yml | 18 +-- examples/blog/fall2012/app.rb | 90 ++++++++++++++ examples/blog/fall2012/config.ru | 9 ++ examples/blog/fall2012/db/blog_posts.yml | 13 ++ examples/blog/fall2012/tmp/always_restart.txt | 0 examples/blog/{ => fall2012}/views/admin.erb | 0 examples/blog/{ => fall2012}/views/blog.erb | 0 .../blog/{ => fall2012}/views/blog_new.erb | 0 .../blog/{ => fall2012}/views/blog_save.erb | 0 examples/blog/{ => fall2012}/views/edit.erb | 0 examples/blog/fall2012/views/form.erb | 34 ++++++ examples/blog/{ => fall2012}/views/front.erb | 0 examples/blog/{ => fall2012}/views/layout.erb | 0 examples/blog/{ => fall2012}/views/post.erb | 0 examples/blog/views/entry.erb | 13 ++ examples/blog/views/form.erb | 2 +- examples/blog/views/home.erb | 10 ++ examples/blog/views/singleEdit.erb | 13 ++ examples/blog/views/singleEntry.erb | 6 + 21 files changed, 304 insertions(+), 71 deletions(-) create mode 100644 examples/blog/fall2012/app.rb create mode 100644 examples/blog/fall2012/config.ru create mode 100644 examples/blog/fall2012/db/blog_posts.yml create mode 100644 examples/blog/fall2012/tmp/always_restart.txt rename examples/blog/{ => fall2012}/views/admin.erb (100%) rename examples/blog/{ => fall2012}/views/blog.erb (100%) rename examples/blog/{ => fall2012}/views/blog_new.erb (100%) rename examples/blog/{ => fall2012}/views/blog_save.erb (100%) rename examples/blog/{ => fall2012}/views/edit.erb (100%) create mode 100644 examples/blog/fall2012/views/form.erb rename examples/blog/{ => fall2012}/views/front.erb (100%) rename examples/blog/{ => fall2012}/views/layout.erb (100%) rename examples/blog/{ => fall2012}/views/post.erb (100%) create mode 100644 examples/blog/views/entry.erb create mode 100644 examples/blog/views/home.erb create mode 100644 examples/blog/views/singleEdit.erb create mode 100644 examples/blog/views/singleEntry.erb diff --git a/README.md b/README.md index df5ce49..6de82ba 100644 --- a/README.md +++ b/README.md @@ -278,6 +278,62 @@ If your image does not appear there could be another issue with permissions. Rig * Write your Datamapper class * Properties: Serial, Boolean, String, Text, Float, Integer, Datetime, +### Setting up the Database + +First you need to add the library: + +require 'dm-core' + +Second add the basic database setup: + +DataMapper::setup(:default, {:adapter =>'yaml', :path => 'db'}) + +We are using a yaml database saved to the path db + + +### Setting up the Database Class + +The Class is what Datamapper uses to create the database model + +class BlogPost + + include DataMapper::Resource #This line makes sure Datamapper uses this class to build our database structure + + property :id, Serial #We always need a Serial property. This ensures every new data entry has a unique number attributed with it. + property :title, String + property :body, Text + +end + +### Acessing the Data + + Asking for entry based on the Serial property. This returns a single entry + + @entry = BlogPost.get(params[:id]) + + To access the data you use the instance name @entry followed by a . and the name of the property you want to access i.e. @entry.title, will return the title of your current query + + Asking for all entries in the database. This returns an array of objects + + @allEntries = BlogPost.all + + To display the data in your erb you need to loop through an array: + + <%@allEntries.each do |content|%> + <%=content.id%> +
    + <%=content.title%> +
    + <%=content.body%> +
    + <%end%> + + + + + + + * [Datamapper Class Example](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week3/datamapperexample1) ### Using Datamapper with Forms diff --git a/examples/blog/app.rb b/examples/blog/app.rb index 8f09474..6fc01c1 100644 --- a/examples/blog/app.rb +++ b/examples/blog/app.rb @@ -1,90 +1,85 @@ require 'sinatra' require 'dm-core' -DataMapper::setup(:default, {:adapter => 'yaml', :path => 'db'}) +#Setting up what kind of database and what directory to save it +#yaml is a simple database that saves in a text file you can read +DataMapper::setup(:default, {:adapter =>'yaml', :path => 'db'}) class BlogPost - include DataMapper::Resource - property :id, Serial + include DataMapper::Resource #This line makes sure Datamapper uses this class to build our database structure + + property :id, Serial #We always need a Serial property. This ensures every new data entry has a unique number attributed with it. property :title, String property :body, Text end -DataMapper.finalize - -get "/" do - @nav = "Splash page" - erb :front -end - -get "/blog" do - @nav = "Zeven's Blog" - @posts = BlogPost.all - erb :blog -end - -get "/blog/new" do - erb :blog_new -end - -post "/blog/save" do - myPost = BlogPost.new - myPost.title = params[:title] - myPost.body = params[:body] +get '/' do - if(myPost.save) - @message = "Your post was saved!" - else - @message = "Your post was NOT SAVED!!!!!!!" - end + #Asking for all entries in the database + + @allEntries = BlogPost.all + + #Look at home.erb to see how to loop through an array + erb :home - erb :blog_save end -get "/blog/admin" do - @nav = "Admin" - @posts = BlogPost.all - erb :admin +get '/:id' do + + #Asking for entry based on the Serial number + @entry = BlogPost.get(params[:id]) + erb :singleEntry end -get "/blog/:id/edit" do - @nav = "You are on the edit username page" - @updatePost = BlogPost.get(params[:id]) +get '/:id/edit' do + @id = params[:id] - erb :edit + + erb :singleEdit end -post "/blog/:id/edit" do - updatePost = BlogPost.get(params[:id]) - updatePost.title = params[:title] - updatePost.body = params[:body] +post '/:id/edit' do - if(updatePost.save) - redirect to("http://itp.nyu.edu/~zr279/sinatra/blog/blog") + #Edit a new entry. @entryEdit is the current instance of BlogPost based on a query or search by the ID + @entryEdit = BlogPost.get(params[:id]) + + title = params[:title] + body = params[:body] + + @entryEdit.title = title + @entryEdit.body = body + + if (@entryEdit.save) + redirect to("http://itp.nyu.edu/~zr279/sinatra/blogs/") else - "Your post was NOT SAVED!!!!!!!" + "It did not save" end - end -get "/blog/:id/delete" do - - deletePost = BlogPost.get(params[:id]) - - - deletePost.destroy - - redirect to("http://itp.nyu.edu/~zr279/sinatra/blog/blog/admin") - +get '/entry' do + erb :entry end + +post '/entry' do + #Create a new entry. myEntry is the current instance of BlogPost + myEntry = BlogPost.new + #Add data from the form to new entry + myEntry.title = params[:title] + myEntry.body = params[:body] + #Save to the Database. If it fails it will repond with "You entry was not saved!!!!!!!!!!!!" + if(myEntry.save) + "Your entry was saved!" + else + "You entry was not saved!!!!!!!!!!!!" + end -get "/blog/:id" do - @post = BlogPost.get(params[:id]) - erb :post, :layout => false end + + + diff --git a/examples/blog/db/blog_posts.yml b/examples/blog/db/blog_posts.yml index 1a01081..353f12c 100644 --- a/examples/blog/db/blog_posts.yml +++ b/examples/blog/db/blog_posts.yml @@ -1,13 +1,7 @@ --- -- title: this is no longer a test - body: this is no longer a test - id: 2 -- title: Hello this my first post - body: Hello i love sintar - id: 4 -- title: this is a post - body: this is a post - id: 3 -- title: this is another post - body: this is another post - id: 4 +- id: 1 + title: This is my first post + body: the first blah stuff +- id: 2 + title: this is the new title for post 2 + body: I have not changed post 2 diff --git a/examples/blog/fall2012/app.rb b/examples/blog/fall2012/app.rb new file mode 100644 index 0000000..8f09474 --- /dev/null +++ b/examples/blog/fall2012/app.rb @@ -0,0 +1,90 @@ +require 'sinatra' +require 'dm-core' + +DataMapper::setup(:default, {:adapter => 'yaml', :path => 'db'}) + +class BlogPost + include DataMapper::Resource + property :id, Serial + property :title, String + property :body, Text +end + +DataMapper.finalize + +get "/" do + @nav = "Splash page" + erb :front +end + +get "/blog" do + @nav = "Zeven's Blog" + @posts = BlogPost.all + erb :blog +end + +get "/blog/new" do + erb :blog_new +end + +post "/blog/save" do + myPost = BlogPost.new + myPost.title = params[:title] + myPost.body = params[:body] + + if(myPost.save) + @message = "Your post was saved!" + else + @message = "Your post was NOT SAVED!!!!!!!" + end + + erb :blog_save +end + +get "/blog/admin" do + @nav = "Admin" + @posts = BlogPost.all + erb :admin +end + +get "/blog/:id/edit" do + @nav = "You are on the edit username page" + @updatePost = BlogPost.get(params[:id]) + @id = params[:id] + erb :edit +end + +post "/blog/:id/edit" do + updatePost = BlogPost.get(params[:id]) + updatePost.title = params[:title] + updatePost.body = params[:body] + + if(updatePost.save) + redirect to("http://itp.nyu.edu/~zr279/sinatra/blog/blog") + else + "Your post was NOT SAVED!!!!!!!" + end + + +end + +get "/blog/:id/delete" do + + deletePost = BlogPost.get(params[:id]) + + + deletePost.destroy + + redirect to("http://itp.nyu.edu/~zr279/sinatra/blog/blog/admin") + + +end + +get "/blog/:id" do + @post = BlogPost.get(params[:id]) + erb :post, :layout => false +end + + + + diff --git a/examples/blog/fall2012/config.ru b/examples/blog/fall2012/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/blog/fall2012/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/blog/fall2012/db/blog_posts.yml b/examples/blog/fall2012/db/blog_posts.yml new file mode 100644 index 0000000..1a01081 --- /dev/null +++ b/examples/blog/fall2012/db/blog_posts.yml @@ -0,0 +1,13 @@ +--- +- title: this is no longer a test + body: this is no longer a test + id: 2 +- title: Hello this my first post + body: Hello i love sintar + id: 4 +- title: this is a post + body: this is a post + id: 3 +- title: this is another post + body: this is another post + id: 4 diff --git a/examples/blog/fall2012/tmp/always_restart.txt b/examples/blog/fall2012/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/blog/views/admin.erb b/examples/blog/fall2012/views/admin.erb similarity index 100% rename from examples/blog/views/admin.erb rename to examples/blog/fall2012/views/admin.erb diff --git a/examples/blog/views/blog.erb b/examples/blog/fall2012/views/blog.erb similarity index 100% rename from examples/blog/views/blog.erb rename to examples/blog/fall2012/views/blog.erb diff --git a/examples/blog/views/blog_new.erb b/examples/blog/fall2012/views/blog_new.erb similarity index 100% rename from examples/blog/views/blog_new.erb rename to examples/blog/fall2012/views/blog_new.erb diff --git a/examples/blog/views/blog_save.erb b/examples/blog/fall2012/views/blog_save.erb similarity index 100% rename from examples/blog/views/blog_save.erb rename to examples/blog/fall2012/views/blog_save.erb diff --git a/examples/blog/views/edit.erb b/examples/blog/fall2012/views/edit.erb similarity index 100% rename from examples/blog/views/edit.erb rename to examples/blog/fall2012/views/edit.erb diff --git a/examples/blog/fall2012/views/form.erb b/examples/blog/fall2012/views/form.erb new file mode 100644 index 0000000..bf5cf76 --- /dev/null +++ b/examples/blog/fall2012/views/form.erb @@ -0,0 +1,34 @@ + + + + Simple Form Example + + + + +

    Simple form

    +

    This is a simple form example.

    +
    +

    +

    +
    + + + diff --git a/examples/blog/views/front.erb b/examples/blog/fall2012/views/front.erb similarity index 100% rename from examples/blog/views/front.erb rename to examples/blog/fall2012/views/front.erb diff --git a/examples/blog/views/layout.erb b/examples/blog/fall2012/views/layout.erb similarity index 100% rename from examples/blog/views/layout.erb rename to examples/blog/fall2012/views/layout.erb diff --git a/examples/blog/views/post.erb b/examples/blog/fall2012/views/post.erb similarity index 100% rename from examples/blog/views/post.erb rename to examples/blog/fall2012/views/post.erb diff --git a/examples/blog/views/entry.erb b/examples/blog/views/entry.erb new file mode 100644 index 0000000..4cae15c --- /dev/null +++ b/examples/blog/views/entry.erb @@ -0,0 +1,13 @@ +
    + + + +
    + + +
    + +
    + + +
    \ No newline at end of file diff --git a/examples/blog/views/form.erb b/examples/blog/views/form.erb index bf5cf76..f4b1a0b 100644 --- a/examples/blog/views/form.erb +++ b/examples/blog/views/form.erb @@ -25,7 +25,7 @@

    Simple form

    This is a simple form example.

    -
    +

    diff --git a/examples/blog/views/home.erb b/examples/blog/views/home.erb new file mode 100644 index 0000000..a3a0e19 --- /dev/null +++ b/examples/blog/views/home.erb @@ -0,0 +1,10 @@ +<%@allEntries.each do |content|%> + +

    <%=content.title%>

    +
    +<%=content.body%> +
    + +This is a link to entry #<%=content.id%> + +<%end%> \ No newline at end of file diff --git a/examples/blog/views/singleEdit.erb b/examples/blog/views/singleEdit.erb new file mode 100644 index 0000000..9fc5b36 --- /dev/null +++ b/examples/blog/views/singleEdit.erb @@ -0,0 +1,13 @@ +
    + + + +
    + + +
    + +
    + + +
    \ No newline at end of file diff --git a/examples/blog/views/singleEntry.erb b/examples/blog/views/singleEntry.erb new file mode 100644 index 0000000..01ce47c --- /dev/null +++ b/examples/blog/views/singleEntry.erb @@ -0,0 +1,6 @@ +

    <%=@entry.title%>

    +
    +<%=@entry.body%> +
    +Edit Entry +Go home \ No newline at end of file From 6df17ab6981f59d67199d9d2c0420758ccff243a Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Tue, 26 Feb 2013 11:18:26 -0500 Subject: [PATCH 48/57] space change --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 6de82ba..11b5e0f 100644 --- a/README.md +++ b/README.md @@ -329,11 +329,6 @@ end <%end%> - - - - - * [Datamapper Class Example](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week3/datamapperexample1) ### Using Datamapper with Forms From 04d852498b56c511c478cd50273e4b7d483f33da Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Sun, 3 Mar 2013 15:15:43 -0500 Subject: [PATCH 49/57] new comp --- README.md | 72 ++++++++++++++----- examples/week5/week5spring13/.htaccess | 4 ++ examples/week5/week5spring13/app.rb | 46 ++++++++++++ examples/week5/week5spring13/config.ru | 9 +++ examples/week5/week5spring13/db/visitors.yml | 16 +++++ .../week5spring13/tmp/always_restart.txt | 0 examples/week5/week5spring13/views/form.erb | 25 +++++++ examples/week5/week5spring13/views/hello.erb | 1 + examples/week5/week5spring13/views/layout.erb | 13 ++++ 9 files changed, 168 insertions(+), 18 deletions(-) create mode 100644 examples/week5/week5spring13/.htaccess create mode 100644 examples/week5/week5spring13/app.rb create mode 100644 examples/week5/week5spring13/config.ru create mode 100644 examples/week5/week5spring13/db/visitors.yml create mode 100644 examples/week5/week5spring13/tmp/always_restart.txt create mode 100644 examples/week5/week5spring13/views/form.erb create mode 100644 examples/week5/week5spring13/views/hello.erb create mode 100644 examples/week5/week5spring13/views/layout.erb diff --git a/README.md b/README.md index 11b5e0f..f9235ed 100644 --- a/README.md +++ b/README.md @@ -329,7 +329,46 @@ end <%end%> -* [Datamapper Class Example](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week3/datamapperexample1) +* [Datamapper Example](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week3/datamapperexample1) + +Here are some more Datamapper Query types: + + Get a user by id + #user = Visitor.get(1) + + Get first user with name "rune" + #users = Visitor.first(:username => "rune") + + Get last user with name "rune" + #user = Visitor.last(:name => "rune") + + Get all users with name "rune" + #user = Visitor.all(:name => "rune") + + Find all users with age between 18 and 60 + #user = Visitor.all(:age.gt => 18, :age.lt => 60) + + # You can use all of these conditions + # gt, greater than + # lt, less than + # gte, greater than or equal + # lte, less than or equal + # not, not equal + # eql, equal + # like, like + + Order visitors by age (you also use .asc) + #user = Visitor.all(:order => [ :age.desc ]) + + Find the number of visitors in your database with age greater than 18 + #count = Visitor.count(:age.gt => 18) + + Find the youngest age in the database + #min_age = Visitor.min(:age) + + Find the oldest age in the database + #max_age = Visitor.max(:age) + ### Using Datamapper with Forms @@ -375,25 +414,22 @@ What do you want to do? What is preventing you from doing it? ### Advanced Datamapper -* [Birthday Registration Example](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week5/advancesearch) * More Datatypes - * Serial - * String - * Boolean - * Integer - * DateTime - * [Example of all of these](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week5/advancedatamapper) + * Serial - is your unique identifier + * String - use when you want to save text + * Boolean - true and false + * Integer - numbers + * DateTime - To save a Time object + + * Datatype options - * Required - * Default - * Length -* Finding Records - * first - * all - * first_or_new - * Conditions (gt, lt, gte, lte, not, eql, like) - * Ordering (desc, asc) - * Counting + * Required - property :firstname, String, :required => true + * Default - property :catlover, Boolean, :default => false + * Length - property :content, Text, :length => 0..500 + +[Birthday Registration Example](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week5/advancesearch) + +[Example of all of these](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week5/advancedatamapper) ### Some hints about CSS diff --git a/examples/week5/week5spring13/.htaccess b/examples/week5/week5spring13/.htaccess new file mode 100644 index 0000000..d9f2b61 --- /dev/null +++ b/examples/week5/week5spring13/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/week5spring13 +RackEnv development diff --git a/examples/week5/week5spring13/app.rb b/examples/week5/week5spring13/app.rb new file mode 100644 index 0000000..f878ca2 --- /dev/null +++ b/examples/week5/week5spring13/app.rb @@ -0,0 +1,46 @@ +require 'sinatra' +require 'dm-core' +require 'dm-validations' +require 'date' + +DataMapper::setup(:default, {:adapter => 'yaml', :path => 'db'}) + + +class Visitor + include DataMapper::Resource + property :id, Serial + property :firstname, String, :required => true + property :catlover, Boolean, :default => false + property :petno, Integer + property :time, DateTime + +end + +DataMapper.finalize + +# Main route - this is the form is shown +get '/' do + @title = "Home" + @first = Visitor.first() + @last = Visitor.last() + @petnumber = Visitor.all(:petno.gte => 3) + erb :form +end + +# Second route - this is the form is posted to +post '/newvisitor' do + + p = Visitor.new + p.firstname = params[:yourname] + p.catlover = params[:catlover] + p.petno = params[:petno] + p.time = Time.now + + #If any of the validations are not met, p.save will be false + if p.save + redirect to("http://itp.nyu.edu/~zr279/sinatra/week5spring13") + else + "You missed something!" + end + +end diff --git a/examples/week5/week5spring13/config.ru b/examples/week5/week5spring13/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/week5/week5spring13/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/week5/week5spring13/db/visitors.yml b/examples/week5/week5spring13/db/visitors.yml new file mode 100644 index 0000000..4e3afd6 --- /dev/null +++ b/examples/week5/week5spring13/db/visitors.yml @@ -0,0 +1,16 @@ +--- +- petno: 3 + catlover: false + id: 1 + time: 2013-02-28 20:53:56 -05:00 + firstname: zeven +- petno: 4 + catlover: true + id: 2 + time: 2013-02-28 20:54:13 -05:00 + firstname: erin +- petno: 1 + catlover: true + id: 3 + time: 2013-02-28T20:55:08-05:00 + firstname: Cecilia diff --git a/examples/week5/week5spring13/tmp/always_restart.txt b/examples/week5/week5spring13/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/week5/week5spring13/views/form.erb b/examples/week5/week5spring13/views/form.erb new file mode 100644 index 0000000..ff7a484 --- /dev/null +++ b/examples/week5/week5spring13/views/form.erb @@ -0,0 +1,25 @@ + +
    +

    + + +

    + +

    +
    + +

    First visitor: <%=@first.firstname%>

    +

    Last visitor: <%=@last.firstname%>

    + + <%@petnumber.each do |pets|%> +

    <%=pets.firstname%> has <%=pets.petno%> pets. This is the time they enter: <%=pets.time.strftime('%B' '%d' '%Y')%>

    + + + + + <%end%> + + diff --git a/examples/week5/week5spring13/views/hello.erb b/examples/week5/week5spring13/views/hello.erb new file mode 100644 index 0000000..64c5882 --- /dev/null +++ b/examples/week5/week5spring13/views/hello.erb @@ -0,0 +1 @@ +<%=@hello%> \ No newline at end of file diff --git a/examples/week5/week5spring13/views/layout.erb b/examples/week5/week5spring13/views/layout.erb new file mode 100644 index 0000000..50bb054 --- /dev/null +++ b/examples/week5/week5spring13/views/layout.erb @@ -0,0 +1,13 @@ + + + + + +

    <%=@title%>

    + +<%=yield%> + + + + + From b04cb991a9e6c44ddb0426e880a22caccdba7058 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Sun, 3 Mar 2013 15:44:53 -0500 Subject: [PATCH 50/57] class example --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index f9235ed..b105e58 100644 --- a/README.md +++ b/README.md @@ -414,6 +414,9 @@ What do you want to do? What is preventing you from doing it? ### Advanced Datamapper +[Class Example](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week5/week5spring13) + + * More Datatypes * Serial - is your unique identifier * String - use when you want to save text From 2d8106ebd4a530a7b18dc5b7169ecdc9f944419d Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Thu, 7 Mar 2013 17:30:37 -0500 Subject: [PATCH 51/57] new examples --- examples/week6/jsonexample/.htaccess | 4 + examples/week6/jsonexample/app.rb | 80 + examples/week6/jsonexample/config.ru | 9 + examples/week6/jsonexample/db/visitors.yml | 10 + .../week6/jsonexample/tmp/always_restart.txt | 0 examples/week6/jsonexample/views/form.erb | 36 + .../week6/jsonexample/views/jsonOutput.erb | 14 + examples/week6/processingjspost/.htaccess | 4 + examples/week6/processingjspost/app.rb | 33 + examples/week6/processingjspost/config.ru | 9 + .../week6/processingjspost/db/visitors.yml | 9 + .../public/js/postExample.pde | 33 + .../processingjspost/public/js/processing.js | 10203 ++++++++++++++++ .../processingjspost/tmp/always_restart.txt | 0 .../week6/processingjspost/views/form.erb | 34 + .../processingjspost/views/processing.erb | 79 + examples/week6/sqltest/.htaccess | 4 + examples/week6/sqltest/app.rb | 42 + examples/week6/sqltest/config.ru | 9 + examples/week6/sqltest/tmp/always_restart.txt | 0 examples/week6/sqltest/views/form.erb | 35 + 21 files changed, 10647 insertions(+) create mode 100644 examples/week6/jsonexample/.htaccess create mode 100644 examples/week6/jsonexample/app.rb create mode 100644 examples/week6/jsonexample/config.ru create mode 100644 examples/week6/jsonexample/db/visitors.yml create mode 100644 examples/week6/jsonexample/tmp/always_restart.txt create mode 100644 examples/week6/jsonexample/views/form.erb create mode 100644 examples/week6/jsonexample/views/jsonOutput.erb create mode 100644 examples/week6/processingjspost/.htaccess create mode 100644 examples/week6/processingjspost/app.rb create mode 100644 examples/week6/processingjspost/config.ru create mode 100644 examples/week6/processingjspost/db/visitors.yml create mode 100644 examples/week6/processingjspost/public/js/postExample.pde create mode 100644 examples/week6/processingjspost/public/js/processing.js create mode 100644 examples/week6/processingjspost/tmp/always_restart.txt create mode 100644 examples/week6/processingjspost/views/form.erb create mode 100644 examples/week6/processingjspost/views/processing.erb create mode 100644 examples/week6/sqltest/.htaccess create mode 100644 examples/week6/sqltest/app.rb create mode 100644 examples/week6/sqltest/config.ru create mode 100644 examples/week6/sqltest/tmp/always_restart.txt create mode 100644 examples/week6/sqltest/views/form.erb diff --git a/examples/week6/jsonexample/.htaccess b/examples/week6/jsonexample/.htaccess new file mode 100644 index 0000000..491f7b1 --- /dev/null +++ b/examples/week6/jsonexample/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/jsonexample +RackEnv development diff --git a/examples/week6/jsonexample/app.rb b/examples/week6/jsonexample/app.rb new file mode 100644 index 0000000..ab1358f --- /dev/null +++ b/examples/week6/jsonexample/app.rb @@ -0,0 +1,80 @@ +require 'sinatra' +require 'dm-core' +require 'json' +require 'open-uri' + +DataMapper::setup(:default, {:adapter => 'yaml', :path => 'db'}) + +class Visitor + include DataMapper::Resource + property :id, Serial + property :firstname, String + property :age, Integer +end + +DataMapper.finalize + + +# Main route - this is the form is shown +get '/' do + erb :form +end + + +post '/data' do + + p = Visitor.new + p.firstname = params[:firstname] + p.age = params[:age] + + + #If any of the validations are not met, p.save will be false + if p.save + redirect to("http://itp.nyu.edu/~zr279/sinatra/jsonexample") + else + "You missed something!" + end + +end + +get '/json' do + + allVisitors = Visitor.all + jsonOutput = "" + + + allVisitors.each_with_index do |visit, index| + + + + jsonOutput += '{ "name" : "' + visit.firstname + '", "age" : "' + visit.age.to_s + '" }' + + if index < allVisitors.length-1 + + jsonOutput += ',' + + end + + + end + + '{ "Visitors": [ ' + jsonOutput + ' ] }' + + + +end + +get '/parsejson' do + + web_contents = open('http://itp.nyu.edu/~zr279/sinatra/jsonexample/json') {|f| f.read } + + @parseJson = JSON.parse(web_contents) + + # ie of simple parse ..... parseJson["Visitors"][0]["age"] + + erb :jsonOutput + + +end + + diff --git a/examples/week6/jsonexample/config.ru b/examples/week6/jsonexample/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/week6/jsonexample/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/week6/jsonexample/db/visitors.yml b/examples/week6/jsonexample/db/visitors.yml new file mode 100644 index 0000000..8a8a626 --- /dev/null +++ b/examples/week6/jsonexample/db/visitors.yml @@ -0,0 +1,10 @@ +--- +- id: 1 + age: 27 + firstname: zeven +- id: 2 + age: 30 + firstname: rune +- id: 3 + firstname: greg + age: 30 diff --git a/examples/week6/jsonexample/tmp/always_restart.txt b/examples/week6/jsonexample/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/week6/jsonexample/views/form.erb b/examples/week6/jsonexample/views/form.erb new file mode 100644 index 0000000..edd1293 --- /dev/null +++ b/examples/week6/jsonexample/views/form.erb @@ -0,0 +1,36 @@ + + + + Simple Form Example + + + + +

    Simple form

    +

    This is a simple form example.

    +
    +

    +

    + +

    +
    + + + diff --git a/examples/week6/jsonexample/views/jsonOutput.erb b/examples/week6/jsonexample/views/jsonOutput.erb new file mode 100644 index 0000000..533eb12 --- /dev/null +++ b/examples/week6/jsonexample/views/jsonOutput.erb @@ -0,0 +1,14 @@ +@parseJson["Visitors"] gives you: <%=@parseJson["Visitors"]%> +
    +@parseJson["Visitors"][0].keys gives you: <%=@parseJson["Visitors"][0].keys%> +
    +@parseJson["Visitors"][0].keys[0] gives you: <%=@parseJson["Visitors"][0].keys[0]%> +
    + +<%@parseJson["Visitors"].each do |output|%> + +

    The persons name: <%=output["name"]%> and age: <%=output["age"]%>

    + + +<%end%> + diff --git a/examples/week6/processingjspost/.htaccess b/examples/week6/processingjspost/.htaccess new file mode 100644 index 0000000..8e0b4e9 --- /dev/null +++ b/examples/week6/processingjspost/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/processingjspost +RackEnv development diff --git a/examples/week6/processingjspost/app.rb b/examples/week6/processingjspost/app.rb new file mode 100644 index 0000000..8e55421 --- /dev/null +++ b/examples/week6/processingjspost/app.rb @@ -0,0 +1,33 @@ +require 'sinatra' +require 'dm-core' + +DataMapper::setup(:default, {:adapter => 'yaml', :path => 'db'}) + +class Visitor + include DataMapper::Resource + property :id, Serial + property :firstname, String +end + +DataMapper.finalize + + +# Main route - this is the form is shown +get '/' do + erb :form +end + +get '/processingExample' do + + erb :processing +end + +post '/processing' do + + #Looking at the pde for the code to do a jquery post into database + p = Visitor.new + p.firstname = params[:firstname] + p.save + + +end diff --git a/examples/week6/processingjspost/config.ru b/examples/week6/processingjspost/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/week6/processingjspost/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/week6/processingjspost/db/visitors.yml b/examples/week6/processingjspost/db/visitors.yml new file mode 100644 index 0000000..7bd4bd7 --- /dev/null +++ b/examples/week6/processingjspost/db/visitors.yml @@ -0,0 +1,9 @@ +--- +- firstname: John + id: 1 +- firstname: "1" + id: 2 +- firstname: "2" + id: 3 +- firstname: "3" + id: 4 diff --git a/examples/week6/processingjspost/public/js/postExample.pde b/examples/week6/processingjspost/public/js/postExample.pde new file mode 100644 index 0000000..1d3ae65 --- /dev/null +++ b/examples/week6/processingjspost/public/js/postExample.pde @@ -0,0 +1,33 @@ +boolean pressed = false; +var name = 0; +void setup(){ + + +} + + +void draw(){ + + + if(pressed == true){ + background(0); + }else{ + background(255); + } + +} + +void mousePressed(){ + if(pressed == false){ + pressed = true; + + name = name + 1; + // In between the {} you insert your parameters + $.post("http://itp.nyu.edu/~zr279/sinatra/processingjspost/processing", { firstname: name} ); + + }else{ + pressed = false; + } + +} + diff --git a/examples/week6/processingjspost/public/js/processing.js b/examples/week6/processingjspost/public/js/processing.js new file mode 100644 index 0000000..d9b41d7 --- /dev/null +++ b/examples/week6/processingjspost/public/js/processing.js @@ -0,0 +1,10203 @@ +/*** + + P R O C E S S I N G . J S - 1.4.1 + a port of the Processing visualization language + + Processing.js is licensed under the MIT License, see LICENSE. + For a list of copyright holders, please refer to AUTHORS. + + http://processingjs.org + +***/ + +(function(window, document, Math, undef) { + var nop = function() {}; + var debug = function() { + if ("console" in window) return function(msg) { + window.console.log("Processing.js: " + msg) + }; + return nop + }(); + var ajax = function(url) { + var xhr = new XMLHttpRequest; + xhr.open("GET", url, false); + if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); + 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 + }; + var isDOMPresent = "document" in this && !("fake" in this.document); + document.head = document.head || document.getElementsByTagName("head")[0]; + + function setupTypedArray(name, fallback) { + if (name in window) return window[name]; + if (typeof window[fallback] === "function") return window[fallback]; + return function(obj) { + if (obj instanceof Array) return obj; + if (typeof obj === "number") { + var arr = []; + arr.length = obj; + return arr + } + } + } + if (document.documentMode >= 9 && !document.doctype) throw "The doctype directive is missing. The recommended doctype in Internet Explorer is the HTML5 doctype: "; + var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), + Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), + Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), + Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); + 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: 1.0E-4, + MAX_FLOAT: 3.4028235E38, + MIN_FLOAT: -3.4028235E38, + 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\u000c\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, + 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, + META: 157, + INSERT: 155, + 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: 720, + 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 virtHashCode(obj) { + if (typeof obj === "string") { + var hash = 0; + for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; + return hash + } + if (typeof obj !== "object") return obj & 4294967295; + if (obj.hashCode instanceof Function) return obj.hashCode(); + 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; + if (typeof obj === "string") return obj === other; + if (typeof obj !== "object") return obj === other; + if (obj.equals instanceof Function) return obj.equals(other); + return obj === other + } + var ObjectIterator = function(obj) { + if (obj.iterator instanceof + Function) return obj.iterator(); + if (obj instanceof Array) { + var index = -1; + this.hasNext = function() { + return ++index < obj.length + }; + this.next = function() { + return obj[index] + } + } else throw "Unable to iterate: " + obj; + }; + 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(a) { + var array; + if (a instanceof ArrayList) array = a.toArray(); + else { + array = []; + if (typeof a === "number") array.length = a > 0 ? a : 0 + } + this.get = function(i) { + return array[i] + }; + this.contains = function(item) { + return this.indexOf(item) > -1 + }; + this.indexOf = function(item) { + for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; + return -1 + }; + this.lastIndexOf = function(item) { + for (var i = array.length - 1; i >= 0; --i) if (virtEquals(item, array[i])) return i; + return -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.addAll = function(arg1, arg2) { + var it; + if (typeof arg1 === "number") { + if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; + it = new ObjectIterator(arg2); + while (it.hasNext()) array.splice(arg1++, 0, it.next()) + } else { + it = new ObjectIterator(arg1); + while (it.hasNext()) array.push(it.next()) + } + }; + 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(item) { + if (typeof item === "number") return array.splice(item, 1)[0]; + item = this.indexOf(item); + if (item > -1) { + array.splice(item, 1); + return true + } + return false + }; + this.removeAll = function(c) { + var i, x, item, newList = new ArrayList; + newList.addAll(this); + this.clear(); + for (i = 0, x = 0; i < newList.size(); i++) { + item = newList.get(i); + if (!c.contains(item)) this.add(x++, item) + } + if (this.size() < newList.size()) return true; + return false + }; + this.isEmpty = function() { + return !array.length + }; + this.clone = function() { + return new ArrayList(this) + }; + this.toArray = function() { + return array.slice(0) + }; + this.iterator = function() { + return new Iterator(array) + } + } + return ArrayList + }(); + var HashMap = function() { + function HashMap() { + if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); + var initialCapacity = arguments.length > 0 ? arguments[0] : 16; + var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; + var buckets = []; + buckets.length = initialCapacity; + var count = 0; + var hashMap = this; + + function getBucketIndex(key) { + var index = virtHashCode(key) % buckets.length; + return index < 0 ? buckets.length + index : index + } + 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]); + var newBucketsLength = buckets.length * 2; + buckets = []; + buckets.length = newBucketsLength; + for (var j = 0; j < allEntries.length; ++j) { + var index = getBucketIndex(allEntries[j].key); + 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; + var currentItem; + + 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() { + currentItem = conversion(buckets[bucketIndex][itemIndex]); + findNext(); + return currentItem + }; + this.remove = function() { + if (currentItem !== undef) { + removeItem(currentItem); + --itemIndex; + findNext() + } + }; + 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 = []; + 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 = []; + buckets.length = initialCapacity + }; + this.clone = function() { + var map = new HashMap; + map.putAll(this); + return map + }; + this.containsKey = function(key) { + var index = getBucketIndex(key); + 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 instanceof Entry && pair._isIn(hashMap) + }, + + + function(pair) { + return hashMap.remove(pair.getKey()) + }) + }; + this.get = function(key) { + var index = getBucketIndex(key); + 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.values = function() { + return new Set(function(pair) { + return pair.value + }, + + + function(value) { + return hashMap.containsValue(value) + }, + + function(value) { + return hashMap.removeByValue(value) + }) + }; + this.put = function(key, value) { + var index = getBucketIndex(key); + 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 = getBucketIndex(key); + 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.removeByValue = function(value) { + var bucket, i, ilen, pair; + for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { + pair = buckets[bucket][i]; + if (pair.value === value) { + buckets[bucket].splice(i, 1); + return true + } + } + return false + }; + this.size = function() { + return count + } + } + return HashMap + }(); + var PVector = function() { + function PVector(x, y, z) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0 + } + PVector.dist = function(v1, v2) { + return v1.dist(v2) + }; + PVector.dot = function(v1, v2) { + return v1.dot(v2) + }; + PVector.cross = function(v1, v2) { + return v1.cross(v2) + }; + 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] || 0, v.y || v[1] || 0, v.z || v[2] || 0); + else { + this.x = v; + this.y = y; + this.z = z + } + }, + get: function() { + return new PVector(this.x, this.y, this.z) + }, + mag: function() { + var x = this.x, + y = this.y, + z = this.z; + return Math.sqrt(x * x + y * y + z * z) + }, + add: function(v, y, z) { + if (arguments.length === 1) { + this.x += v.x; + this.y += v.y; + this.z += v.z + } else { + this.x += v; + this.y += y; + this.z += z + } + }, + sub: function(v, y, z) { + if (arguments.length === 1) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z + } else { + this.x -= v; + this.y -= y; + this.z -= z + } + }, + mult: function(v) { + if (typeof v === "number") { + this.x *= v; + this.y *= v; + this.z *= v + } else { + 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 { + 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 === 1) return this.x * v.x + this.y * v.y + this.z * v.z; + return this.x * v + this.y * y + this.z * z + }, + cross: function(v) { + var x = this.x, + y = this.y, + z = this.z; + return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * 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] + } + }; + + function createPVectorMethod(method) { + return function(v1, v2) { + var v = v1.get(); + v[method](v2); + return v + } + } + for (var 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; + defaultScope.ObjectIterator = ObjectIterator; + defaultScope.PConstants = PConstants; + defaultScope.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) + } + }; + + function overloadBaseClassFunction(object, name, basefn) { + if (!object.hasOwnProperty(name) || typeof object[name] !== "function") { + object[name] = basefn; + return + } + var fn = object[name]; + if ("$overloads" in fn) { + fn.$defaultOverload = basefn; + return + } + if (! ("$overloads" in basefn) && fn.length === basefn.length) return; + var overloads, defaultOverload; + if ("$overloads" in basefn) { + overloads = basefn.$overloads.slice(0); + overloads[fn.length] = fn; + defaultOverload = basefn.$defaultOverload + } else { + overloads = []; + overloads[basefn.length] = basefn; + overloads[fn.length] = fn; + defaultOverload = fn + } + var hubfn = function() { + var fn = hubfn.$overloads[arguments.length] || ("$methodArgsIndex" in hubfn && arguments.length > hubfn.$methodArgsIndex ? hubfn.$overloads[hubfn.$methodArgsIndex] : null) || hubfn.$defaultOverload; + return fn.apply(this, arguments) + }; + hubfn.$overloads = overloads; + if ("$methodArgsIndex" in basefn) hubfn.$methodArgsIndex = basefn.$methodArgsIndex; + hubfn.$defaultOverload = defaultOverload; + hubfn.name = name; + object[name] = hubfn + } + function extendClass(subClass, baseClass) { + function extendGetterSetter(propertyName) { + defaultScope.defineProperty(subClass, propertyName, { + get: function() { + return baseClass[propertyName] + }, + set: function(v) { + baseClass[propertyName] = v + }, + enumerable: true + }) + } + var properties = []; + for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") overloadBaseClassFunction(subClass, propertyName, baseClass[propertyName]); + else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); + while (properties.length > 0) extendGetterSetter(properties.shift()); + subClass.$super = baseClass + } + defaultScope.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 + }; + defaultScope.extendStaticMembers = function(derived, base) { + extendClass(derived, base) + }; + defaultScope.extendInterfaceMembers = function(derived, base) { + extendClass(derived, base) + }; + defaultScope.addMethod = function(object, name, fn, hasMethodArgs) { + var existingfn = object[name]; + if (existingfn || hasMethodArgs) { + var args = fn.length; + if ("$overloads" in existingfn) existingfn.$overloads[args] = fn; + else { + var hubfn = function() { + var fn = hubfn.$overloads[arguments.length] || ("$methodArgsIndex" in hubfn && arguments.length > hubfn.$methodArgsIndex ? hubfn.$overloads[hubfn.$methodArgsIndex] : null) || hubfn.$defaultOverload; + return fn.apply(this, arguments) + }; + var overloads = []; + if (existingfn) overloads[existingfn.length] = existingfn; + overloads[args] = fn; + hubfn.$overloads = overloads; + hubfn.$defaultOverload = existingfn || fn; + if (hasMethodArgs) hubfn.$methodArgsIndex = args; + hubfn.name = name; + object[name] = hubfn + } + } else object[name] = fn + }; + + function isNumericalJavaType(type) { + if (typeof type !== "string") return false; + return ["byte", "int", "char", "color", "float", "long", "double"].indexOf(type) !== -1 + } + defaultScope.createJavaArray = function(type, bounds) { + var result = null, + defaultValue = null; + if (typeof type === "string") if (type === "boolean") defaultValue = false; + else if (isNumericalJavaType(type)) defaultValue = 0; + if (typeof bounds[0] === "number") { + var itemsCount = 0 | bounds[0]; + if (bounds.length <= 1) { + result = []; + result.length = itemsCount; + for (var i = 0; i < itemsCount; ++i) result[i] = defaultValue + } else { + result = []; + var newBounds = bounds.slice(1); + for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) + } + } + return result + }; + 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" + }; + (function(Processing) { + var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), + count = unsupportedP5.length, + prettyName, p5Name; + + function createUnsupportedFunc(n) { + return function() { + throw "Processing.js does not support " + n + "."; + } + } + while (count--) { + prettyName = unsupportedP5[count]; + p5Name = prettyName.replace("()", ""); + Processing[p5Name] = createUnsupportedFunc(prettyName) + } + })(defaultScope); + defaultScope.defineProperty(defaultScope, "screenWidth", { + get: function() { + return window.innerWidth + } + }); + defaultScope.defineProperty(defaultScope, "screenHeight", { + get: function() { + return window.innerHeight + } + }); + defaultScope.defineProperty(defaultScope, "online", { + get: function() { + return true + } + }); + var processingInstances = []; + var processingInstanceIds = {}; + var removeInstance = function(id) { + processingInstances.splice(processingInstanceIds[id], 1); + delete processingInstanceIds[id] + }; + var addInstance = function(processing) { + if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; + processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; + processingInstances.push(processing) + }; + + function computeFontMetrics(pfont) { + var emQuad = 250, + correctionFactor = pfont.size / emQuad, + canvas = document.createElement("canvas"); + canvas.width = 2 * emQuad; + canvas.height = 2 * emQuad; + canvas.style.opacity = 0; + var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), + ctx = canvas.getContext("2d"); + ctx.font = cfmFont; + var protrusions = "dbflkhyjqpg"; + canvas.width = ctx.measureText(protrusions).width; + ctx.font = cfmFont; + var leadDiv = document.createElement("div"); + leadDiv.style.position = "absolute"; + leadDiv.style.opacity = 0; + leadDiv.style.fontFamily = '"' + pfont.name + '"'; + leadDiv.style.fontSize = emQuad + "px"; + leadDiv.innerHTML = protrusions + "
    " + protrusions; + document.body.appendChild(leadDiv); + var w = canvas.width, + h = canvas.height, + baseline = h / 2; + ctx.fillStyle = "white"; + ctx.fillRect(0, 0, w, h); + ctx.fillStyle = "black"; + ctx.fillText(protrusions, 0, baseline); + var pixelData = ctx.getImageData(0, 0, w, h).data; + var i = 0, + w4 = w * 4, + len = pixelData.length; + while (++i < len && pixelData[i] === 255) nop(); + var ascent = Math.round(i / w4); + i = len - 1; + while (--i > 0 && pixelData[i] === 255) nop(); + var descent = Math.round(i / w4); + pfont.ascent = correctionFactor * (baseline - ascent); + pfont.descent = correctionFactor * (descent - baseline); + if (document.defaultView.getComputedStyle) { + var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); + leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); + if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) + } + document.body.removeChild(leadDiv); + if (pfont.caching) return ctx + } + function PFont(name, size) { + if (name === undef) name = ""; + this.name = name; + if (size === undef) size = 0; + this.size = size; + this.glyph = false; + this.ascent = 0; + this.descent = 0; + this.leading = 1.2 * size; + var illegalIndicator = name.indexOf(" Italic Bold"); + if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); + this.style = "normal"; + var italicsIndicator = name.indexOf(" Italic"); + if (italicsIndicator !== -1) { + name = name.substring(0, italicsIndicator); + this.style = "italic" + } + this.weight = "normal"; + var boldIndicator = name.indexOf(" Bold"); + if (boldIndicator !== -1) { + name = name.substring(0, boldIndicator); + this.weight = "bold" + } + this.family = "sans-serif"; + if (name !== undef) switch (name) { + case "sans-serif": + case "serif": + case "monospace": + case "fantasy": + case "cursive": + this.family = name; + break; + default: + this.family = '"' + name + '", sans-serif'; + break + } + this.context2d = computeFontMetrics(this); + this.css = this.getCSSDefinition(); + if (this.context2d) this.context2d.font = this.css + } + PFont.prototype.caching = true; + PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { + if (fontSize === undef) fontSize = this.size + "px"; + if (lineHeight === undef) lineHeight = this.leading + "px"; + var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; + return components.join(" ") + }; + PFont.prototype.measureTextWidth = function(string) { + return this.context2d.measureText(string).width + }; + PFont.prototype.measureTextWidthFallback = function(string) { + var canvas = document.createElement("canvas"), + ctx = canvas.getContext("2d"); + ctx.font = this.css; + return ctx.measureText(string).width + }; + PFont.PFontCache = { + length: 0 + }; + PFont.get = function(fontName, fontSize) { + fontSize = (fontSize * 10 + 0.5 | 0) / 10; + var cache = PFont.PFontCache, + idx = fontName + "/" + fontSize; + if (!cache[idx]) { + cache[idx] = new PFont(fontName, fontSize); + cache.length++; + if (cache.length === 50) { + PFont.prototype.measureTextWidth = PFont.prototype.measureTextWidthFallback; + PFont.prototype.caching = false; + var entry; + for (entry in cache) if (entry !== "length") cache[entry].context2d = null; + return new PFont(fontName, fontSize) + } + if (cache.length === 400) { + PFont.PFontCache = {}; + PFont.get = PFont.getFallback; + return new PFont(fontName, fontSize) + } + } + return cache[idx] + }; + PFont.getFallback = function(fontName, fontSize) { + return new PFont(fontName, fontSize) + }; + PFont.list = function() { + return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] + }; + PFont.preloading = { + template: {}, + initialized: false, + initialize: function() { + var generateTinyFont = function() { + var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; + var expand = function(input) { + return "AAAAAAAA".substr(~~input ? 7 - input : 6) + }; + return encoded.replace(/[#237]/g, expand) + }; + var fontface = document.createElement("style"); + fontface.setAttribute("type", "text/css"); + fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; + document.head.appendChild(fontface); + var element = document.createElement("span"); + element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; + element.innerHTML = "AAAAAAAA"; + document.body.appendChild(element); + this.template = element; + this.initialized = true + }, + getElementWidth: function(element) { + return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") + }, + timeAttempted: 0, + pending: function(intervallength) { + if (!this.initialized) this.initialize(); + var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); + for (var i = 0; i < this.fontList.length; i++) { + element = this.fontList[i]; + computedWidthFont = this.getElementWidth(element); + if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { + this.timeAttempted += intervallength; + return true + } else { + document.body.removeChild(element); + this.fontList.splice(i--, 1); + this.timeAttempted = 0 + } + } + if (this.fontList.length === 0) return false; + return true + }, + fontList: [], + addedList: {}, + add: function(fontSrc) { + if (!this.initialized) this.initialize(); + var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, + fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; + if (this.addedList[fontName]) return; + var style = document.createElement("style"); + style.setAttribute("type", "text/css"); + style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; + document.head.appendChild(style); + this.addedList[fontName] = true; + var element = document.createElement("span"); + element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; + element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; + element.innerHTML = "AAAAAAAA"; + document.body.appendChild(element); + this.fontList.push(element) + } + }; + defaultScope.PFont = PFont; + var Processing = this.Processing = function(aCanvas, aCode) { + if (! (this instanceof + Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; + var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; + if (pgraphicsMode) curElement = document.createElement("canvas"); + else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; + if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; + + function unimplemented(s) { + Processing.debug("Unimplemented - " + s) + } + var p = this; + p.externals = { + canvas: curElement, + context: undef, + sketch: undef + }; + p.name = "Processing.js Instance"; + p.use3DContext = false; + p.focused = false; + 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.mouseOver = undef; + p.mouseOut = undef; + p.touchStart = undef; + p.touchEnd = undef; + p.touchMove = undef; + p.touchCancel = undef; + p.key = undef; + p.keyCode = undef; + p.keyPressed = nop; + p.keyReleased = nop; + p.keyTyped = nop; + p.draw = undef; + p.setup = undef; + p.__mousePressed = false; + p.__keyPressed = false; + p.__frameRate = 60; + p.frameCount = 0; + p.width = 100; + p.height = 100; + var curContext, curSketch, drawing, online = true, + doFill = true, + fillStyle = [1, 1, 1, 1], + currentFillColor = 4294967295, + isFillDirty = true, + doStroke = true, + strokeStyle = [0, 0, 0, 1], + currentStrokeColor = 4278190080, + isStrokeDirty = true, + lineWidth = 1, + loopStarted = false, + renderSmooth = false, + doLoop = true, + looping = 0, + curRectMode = 0, + curEllipseMode = 3, + normalX = 0, + normalY = 0, + normalZ = 0, + normalMode = 0, + curFrameRate = 60, + curMsPerFrame = 1E3 / curFrameRate, + curCursor = 'default', + oldCursor = curElement.style.cursor, + curShape = 20, + curShapeCount = 0, + curvePoints = [], + curTightness = 0, + curveDet = 20, + curveInited = false, + backgroundObj = -3355444, + bezDetail = 20, + colorModeA = 255, + colorModeX = 255, + colorModeY = 255, + colorModeZ = 255, + pathOpen = false, + mouseDragging = false, + pmouseXLastFrame = 0, + pmouseYLastFrame = 0, + curColorMode = 1, + curTint = null, + curTint3d = null, + getLoaded = false, + start = Date.now(), + timeSinceLastFPS = start, + framesSinceLastFPS = 0, + textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, 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 = 2, + usingTexture = false, + textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, + verticalTextAlignment = 0, + textMode = 4, + curFontName = "Arial", + curTextSize = 12, + curTextAscent = 9, + curTextDescent = 2, + curTextLeading = 14, + curTextFont = PFont.get(curFontName, curTextSize), + originalContext, proxyContext = null, + isContextReplaced = false, + setPixelsCached, maxPixelsCached = 1E3, + pressedKeysMap = [], + lastPressedKeyCode = null, + codedKeys = [16, + 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; + 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 Float32Array(720), + cosLUT = new Float32Array(720), + sphereVerts, sphereNorms; + var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, + frustumMode = false, + cameraFOV = 60 * (Math.PI / 180), + cameraX = p.width / 2, + cameraY = p.height / 2, + cameraZ = cameraY / Math.tan(cameraFOV / 2), + cameraNear = cameraZ / 10, + cameraFar = cameraZ * 10, + cameraAspect = p.width / p.height; + var vertArray = [], + curveVertArray = [], + curveVertCount = 0, + isCurve = false, + isBezier = false, + firstVert = true; + var curShapeMode = 0; + var styleArray = []; + 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 vertexShaderSrcUnlitShape = "varying vec4 vFrontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float uPointSize;" + "void main(void) {" + " vFrontColor = aColor;" + " gl_PointSize = uPointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; + var fragmentShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 vFrontColor;" + "uniform bool uSmooth;" + "void main(void){" + " if(uSmooth == true){" + " float dist = distance(gl_PointCoord, vec2(0.5));" + " if(dist > 0.5){" + " discard;" + " }" + " }" + " gl_FragColor = vFrontColor;" + "}"; + var vertexShaderSrc2D = "varying vec4 vFrontColor;" + "attribute vec3 aVertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 uColor;" + "uniform mat4 uModel;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float uPointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = uPointSize;" + " vFrontColor = uColor;" + " gl_Position = uProjection * uView * uModel * vec4(aVertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; + var fragmentShaderSrc2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 vFrontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int uIsDrawingText;" + "uniform bool uSmooth;" + "void main(void){" + " if(uSmooth == true){" + " float dist = distance(gl_PointCoord, vec2(0.5));" + " if(dist > 0.5){" + " discard;" + " }" + " }" + " if(uIsDrawingText == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(vFrontColor.rgb * alpha, alpha);" + " }" + " else{" + " gl_FragColor = vFrontColor;" + " }" + "}"; + var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); + var vertexShaderSrc3D = "varying vec4 vFrontColor;" + "attribute vec3 aVertex;" + "attribute vec3 aNormal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 uColor;" + "uniform bool uUsingMat;" + "uniform vec3 uSpecular;" + "uniform vec3 uMaterialEmissive;" + "uniform vec3 uMaterialAmbient;" + "uniform vec3 uMaterialSpecular;" + "uniform float uShininess;" + "uniform mat4 uModel;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform mat4 uNormalTransform;" + "uniform int uLightCount;" + "uniform vec3 uFalloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light uLights0;" + "uniform Light uLights1;" + "uniform Light uLights2;" + "uniform Light uLights3;" + "uniform Light uLights4;" + "uniform Light uLights5;" + "uniform Light uLights6;" + "uniform Light uLights7;" + "Light getLight(int index){" + " if(index == 0) return uLights0;" + " if(index == 1) return uLights1;" + " if(index == 2) return uLights2;" + " if(index == 3) return uLights3;" + " if(index == 4) return uLights4;" + " if(index == 5) return uLights5;" + " if(index == 6) return uLights6;" + " return uLights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( uFalloff[0] + ( uFalloff[1] * d ) + ( uFalloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerFactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerFactor = pow( nDotVH, uShininess );" + " }" + " col += light.color * nDotVP;" + " spec += uSpecular * powerFactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerFactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( uFalloff[0] + ( uFalloff[1] * d ) + ( uFalloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerFactor = 0.0;" + " }" + " else {" + " powerFactor = pow( nDotHV, uShininess );" + " }" + " spec += uSpecular * powerFactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerFactor = 0.0;" + " vec3 VP = light.position - ecPos;" + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( uFalloff[0] + ( uFalloff[1] * d ) + ( uFalloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ) );" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ) );" + " if( nDotVP != 0.0 ) {" + " powerFactor = pow( nDotHV, uShininess );" + " }" + " spec += uSpecular * powerFactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0 );" + " vec3 finalDiffuse = vec3( 0.0 );" + " vec3 finalSpecular = vec3( 0.0 );" + " vec4 col = uColor;" + " if ( uColor[0] == -1.0 ){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( uNormalTransform * vec4( aNormal, 0.0 ) ));" + " vec4 ecPos4 = uView * uModel * vec4(aVertex, 1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( uLightCount == 0 ) {" + " vFrontColor = col + vec4(uMaterialSpecular, 1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= uLightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( uUsingMat == false ) {" + " vFrontColor = vec4(" + " vec3( col ) * finalAmbient +" + " vec3( col ) * finalDiffuse +" + " vec3( col ) * finalSpecular," + " col[3] );" + " }" + " else{" + " vFrontColor = vec4( " + " uMaterialEmissive + " + " (vec3(col) * uMaterialAmbient * finalAmbient ) + " + " (vec3(col) * finalDiffuse) + " + " (uMaterialSpecular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = uProjection * uView * uModel * vec4( aVertex, 1.0 );" + "}"; + var fragmentShaderSrc3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 vFrontColor;" + "uniform sampler2D uSampler;" + "uniform bool uUsingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if( uUsingTexture ){" + " gl_FragColor = vec4(texture2D(uSampler, vTexture.xy)) * vFrontColor;" + " }" + " else{" + " gl_FragColor = vFrontColor;" + " }" + "}"; + + 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 !== null) 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 !== null) 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 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) + } + 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) + } + 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 imageModeCorner = function(x, y, w, h, whAreSizes) { + return { + x: x, + y: y, + w: w, + h: h + } + }; + var imageModeConvert = imageModeCorner; + var imageModeCorners = function(x, y, w, h, whAreSizes) { + return { + x: x, + y: y, + w: whAreSizes ? w : w - x, + h: whAreSizes ? h : h - y + } + }; + var imageModeCenter = function(x, y, w, h, whAreSizes) { + return { + x: x - w / 2, + y: y - h / 2, + w: w, + h: h + } + }; + var DrawingShared = function() {}; + var Drawing2D = function() {}; + var Drawing3D = function() {}; + var DrawingPre = function() {}; + Drawing2D.prototype = new DrawingShared; + Drawing2D.prototype.constructor = Drawing2D; + Drawing3D.prototype = new DrawingShared; + Drawing3D.prototype.constructor = Drawing3D; + DrawingPre.prototype = new DrawingShared; + DrawingPre.prototype.constructor = DrawingPre; + DrawingShared.prototype.a3DOnlyFunction = nop; + var charMap = {}; + var Char = p.Character = function(chr) { + if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); + else if (typeof chr === "number") this.code = chr; + else if (chr instanceof Char) this.code = chr; + 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 || 0; + 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 + }; + PShape.prototype = { + isVisible: function() { + return this.visible + }, + setVisible: function(visible) { + this.visible = visible + }, + disableStyle: function() { + this.style = false; + for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() + }, + enableStyle: function() { + this.style = true; + for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() + }, + getFamily: function() { + return this.family + }, + getWidth: function() { + return this.width + }, + getHeight: function() { + return this.height + }, + setName: function(name) { + this.name = name + }, + getName: function() { + return this.name + }, + draw: function(renderContext) { + renderContext = renderContext || p; + if (this.visible) { + this.pre(renderContext); + this.drawImpl(renderContext); + this.post(renderContext) + } + }, + drawImpl: function(renderContext) { + if (this.family === 0) this.drawGroup(renderContext); + else if (this.family === 1) this.drawPrimitive(renderContext); + else if (this.family === 3) this.drawGeometry(renderContext); + else if (this.family === 21) this.drawPath(renderContext) + }, + drawPath: function(renderContext) { + var i, j; + if (this.vertices.length === 0) return; + renderContext.beginShape(); + if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) renderContext.vertex(this.vertices[i][0], this.vertices[i][1]); + else for (i = 0, j = this.vertices.length; i < j; i++) renderContext.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); + else { + var index = 0; + if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { + renderContext.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index]["moveTo"]); + renderContext.breakShape = false; + index++ + } else if (this.vertexCodes[i] === 1) { + renderContext.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 + } else if (this.vertexCodes[i] === 2) { + renderContext.curveVertex(this.vertices[index][0], this.vertices[index][1]); + index++ + } else { + if (this.vertexCodes[i] === 3) renderContext.breakShape = true + } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { + renderContext.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; + renderContext.breakShape = false + } else if (this.vertexCodes[i] === 1) { + renderContext.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 + } else if (this.vertexCodes[i] === 2) { + renderContext.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); + index++ + } else if (this.vertexCodes[i] === 3) renderContext.breakShape = true + } + renderContext.endShape(this.close ? 2 : 1) + }, + drawGeometry: function(renderContext) { + var i, j; + renderContext.beginShape(this.kind); + if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) renderContext.vertex(this.vertices[i]); + else for (i = 0, j = this.vertices.length; i < j; i++) { + var vert = this.vertices[i]; + if (vert[2] === 0) renderContext.vertex(vert[0], vert[1]); + else renderContext.vertex(vert[0], vert[1], vert[2]) + } + renderContext.endShape() + }, + drawGroup: function(renderContext) { + for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw(renderContext) + }, + drawPrimitive: function(renderContext) { + if (this.kind === 2) renderContext.point(this.params[0], this.params[1]); + else if (this.kind === 4) if (this.params.length === 4) renderContext.line(this.params[0], this.params[1], this.params[2], this.params[3]); + else renderContext.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); + else if (this.kind === 8) renderContext.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); + else if (this.kind === 16) renderContext.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]); + else if (this.kind === 30) if (this.image !== null) { + var imMode = imageModeConvert; + renderContext.imageMode(0); + renderContext.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]); + imageModeConvert = imMode + } else { + var rcMode = curRectMode; + renderContext.rectMode(0); + renderContext.rect(this.params[0], this.params[1], this.params[2], this.params[3]); + curRectMode = rcMode + } else if (this.kind === 31) { + var elMode = curEllipseMode; + renderContext.ellipseMode(0); + renderContext.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]); + curEllipseMode = elMode + } else if (this.kind === 32) { + var eMode = curEllipseMode; + renderContext.ellipseMode(0); + renderContext.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); + curEllipseMode = eMode + } else if (this.kind === 41) if (this.params.length === 1) renderContext.box(this.params[0]); + else renderContext.box(this.params[0], this.params[1], this.params[2]); + else if (this.kind === 40) renderContext.sphere(this.params[0]) + }, + pre: function(renderContext) { + if (this.matrix) { + renderContext.pushMatrix(); + renderContext.transform(this.matrix) + } + if (this.style) { + renderContext.pushStyle(); + this.styles(renderContext) + } + }, + post: function(renderContext) { + if (this.matrix) renderContext.popMatrix(); + if (this.style) renderContext.popStyle() + }, + styles: function(renderContext) { + if (this.stroke) { + renderContext.stroke(this.strokeColor); + renderContext.strokeWeight(this.strokeWeight); + renderContext.strokeCap(this.strokeCap); + renderContext.strokeJoin(this.strokeJoin) + } else renderContext.noStroke(); + if (this.fill) renderContext.fill(this.fillColor); + else renderContext.noFill() + }, + getChild: function(child) { + var i, j; + if (typeof child === "number") return this.children[child]; + var found; + if (child === "" || this.name === child) return this; + if (this.nameTable.length > 0) { + for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { + found = this.nameTable[i]; + break + } + if (found) return found + } + for (i = 0, j = this.children.length; i < j; i++) { + found = this.children[i].getChild(child); + if (found) return found + } + return null + }, + getChildCount: function() { + return this.children.length + }, + addChild: function(child) { + this.children.push(child); + child.parent = this; + if (child.getName() !== null) this.addName(child.getName(), child) + }, + addName: function(name, shape) { + if (this.parent !== null) this.parent.addName(name, shape); + else this.nameTable.push([name, shape]) + }, + 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) + } + }, + 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 + }, + rotateX: function(angle) { + this.rotate(angle, 1, 0, 0) + }, + rotateY: function(angle) { + this.rotate(angle, 0, 1, 0) + }, + rotateZ: function(angle) { + this.rotate(angle, 0, 0, 1) + }, + 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]) + } + }, + 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]) + } + }, + resetMatrix: function() { + this.checkMatrix(2); + this.matrix.reset() + }, + 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 = 4278190080; + this.strokeWeight = 1; + this.strokeCap = 'butt'; + this.strokeJoin = 'miter'; + this.strokeGradient = null; + this.strokeGradientPaint = null; + this.strokeName = null; + this.strokeOpacity = 1; + this.fill = true; + this.fillColor = 4278190080; + this.fillGradient = null; + this.fillGradientPaint = null; + this.fillName = null; + this.fillOpacity = 1; + if (this.element.getName() !== "svg") throw "root is not , 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(p, arguments[1]); + this.vertexCodes = []; + this.vertices = []; + this.opacity = 1; + this.stroke = false; + this.strokeColor = 4278190080; + this.strokeWeight = 1; + this.strokeCap = 'butt'; + this.strokeJoin = 'miter'; + this.strokeGradient = ""; + this.strokeGradientPaint = ""; + this.strokeName = ""; + this.strokeOpacity = 1; + this.fill = true; + this.fillColor = 4278190080; + 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 tag of this file."; + } + this.parseColors(this.element); + this.parseChildren(this.element) + }; + PShapeSVG.prototype = new PShape; + PShapeSVG.prototype.parseMatrix = function() { + function getCoords(s) { + var m = []; + s.replace(/\((.*?)\)/, function() { + return function(all, params) { + m = params.replace(/,+/g, " ").split(/\s+/) + } + }()); + return m + } + return function(str) { + this.checkMatrix(2); + var pieces = []; + str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { + pieces.push(p.trim(all)) + }); + if (pieces.length === 0) return null; + for (var i = 0, j = pieces.length; i < j; i++) { + var m = getCoords(pieces[i]); + 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]); + else if (pieces[i].indexOf("shearX") !== -1) this.matrix.shearX(m[0]); + else if (pieces[i].indexOf("shearY") !== -1) this.matrix.shearY(m[0]) + } + return this.matrix + } + }(); + PShapeSVG.prototype.parseChildren = function(element) { + var newelement = element.getChildren(); + var children = new p.PShape; + for (var i = 0, j = newelement.length; i < j; i++) { + var kid = this.parseChild(newelement[i]); + if (kid) children.addChild(kid) + } + this.children.push(children) + }; + PShapeSVG.prototype.getName = function() { + return this.name + }; + PShapeSVG.prototype.parseChild = function(elem) { + var name = elem.getName(); + var shape; + if (name === "g") shape = new PShapeSVG(this, elem); + else if (name === "defs") shape = new PShapeSVG(this, elem); + else if (name === "line") { + shape = new PShapeSVG(this, elem); + shape.parseLine() + } else if (name === "circle") { + shape = new PShapeSVG(this, elem); + shape.parseEllipse(true) + } else if (name === "ellipse") { + shape = new PShapeSVG(this, elem); + shape.parseEllipse(false) + } else if (name === "rect") { + shape = new PShapeSVG(this, elem); + shape.parseRect() + } else if (name === "polygon") { + shape = new PShapeSVG(this, elem); + shape.parsePoly(true) + } else if (name === "polyline") { + shape = new PShapeSVG(this, elem); + shape.parsePoly(false) + } else if (name === "path") { + shape = new PShapeSVG(this, elem); + shape.parsePath() + } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); + else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); + else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); + else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); + else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); + else nop(); + return shape + }; + PShapeSVG.prototype.parsePath = function() { + this.family = 21; + this.kind = 0; + var pathDataChars = []; + var c; + var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); + if (pathData === null) return; + pathData = p.__toCharArray(pathData); + 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, + valOf = 0; + var str = ""; + var tmpArray = []; + var flag = false; + var lastInstruction; + var command; + var j, k; + 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]; + valOf = command.valueOf(); + if (valOf === 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, k = tmpArray.length; j < k; j += 2) { + cx = tmpArray[j]; + cy = tmpArray[j + 1]; + this.parsePathLineto(cx, cy) + } + } + } else if (valOf === 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, k = tmpArray.length; j < k; j += 2) { + cx += tmpArray[j]; + cy += tmpArray[j + 1]; + this.parsePathLineto(cx, cy) + } + } + } else if (valOf === 76) { + if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { + cx = tmpArray[j]; + cy = tmpArray[j + 1]; + this.parsePathLineto(cx, cy) + } + } else if (valOf === 108) { + if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { + cx += tmpArray[j]; + cy += tmpArray[j + 1]; + this.parsePathLineto(cx, cy) + } + } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { + cx = tmpArray[j]; + this.parsePathLineto(cx, cy) + } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { + cx += tmpArray[j]; + this.parsePathLineto(cx, cy) + } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { + cy = tmpArray[j]; + this.parsePathLineto(cx, cy) + } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { + cy += tmpArray[j]; + this.parsePathLineto(cx, cy) + } else if (valOf === 67) { + if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 99) { + if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 83) { + if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 115) { + if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 81) { + if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 113) { + if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 84) { + if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 116) { + if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 90 || valOf === 122) this.close = true; + lastInstruction = command.toString() + } else i++ + } + }; + PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { + if (this.vertices.length > 0) { + this.parsePathCode(1); + 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"; + }; + PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { + if (this.vertices.length > 0) { + this.parsePathCode(1); + this.parsePathVertex(x1, y1); + this.parsePathVertex(x2, y2); + this.parsePathVertex(x3, y3) + } else throw "Path must start with M/m"; + }; + PShapeSVG.prototype.parsePathLineto = function(px, py) { + if (this.vertices.length > 0) { + this.parsePathCode(0); + this.parsePathVertex(px, py); + this.vertices[this.vertices.length - 1]["moveTo"] = false + } else throw "Path must start with M/m"; + }; + PShapeSVG.prototype.parsePathMoveto = function(px, py) { + if (this.vertices.length > 0) this.parsePathCode(3); + this.parsePathCode(0); + this.parsePathVertex(px, py); + this.vertices[this.vertices.length - 1]["moveTo"] = true + }; + PShapeSVG.prototype.parsePathVertex = function(x, y) { + var verts = []; + verts[0] = x; + verts[1] = y; + this.vertices.push(verts) + }; + PShapeSVG.prototype.parsePathCode = function(what) { + this.vertexCodes.push(what) + }; + PShapeSVG.prototype.parsePoly = function(val) { + this.family = 21; + 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, j = pointsBuffer.length; i < j; i++) { + var verts = []; + verts[0] = pointsBuffer[i]; + verts[1] = pointsBuffer[++i]; + this.vertices.push(verts) + } else throw "Error parsing polygon points: odd number of coordinates provided"; + } + }; + PShapeSVG.prototype.parseRect = function() { + this.kind = 30; + this.family = 1; + 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 "; + }; + PShapeSVG.prototype.parseEllipse = function(val) { + this.kind = 31; + this.family = 1; + 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 "; + } 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 "; + } + this.params[0] -= rx; + this.params[1] -= ry; + this.params[2] = rx * 2; + this.params[3] = ry * 2 + }; + PShapeSVG.prototype.parseLine = function() { + this.kind = 4; + this.family = 1; + 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") + }; + PShapeSVG.prototype.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, j = styleTokens.length; i < j; i++) { + var tokens = p.trim(styleTokens[i].split(":")); + if (tokens[0] === "fill") this.setFill(tokens[1]); + else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); + else if (tokens[0] === "stroke") this.setStroke(tokens[1]); + else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); + else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); + else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); + else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); + else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) + } + } + }; + PShapeSVG.prototype.setFillOpacity = function(opacityText) { + this.fillOpacity = parseFloat(opacityText); + this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 + }; + PShapeSVG.prototype.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 + } + }; + PShapeSVG.prototype.setOpacity = function(opacity) { + this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; + this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 + }; + PShapeSVG.prototype.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 + } + }; + PShapeSVG.prototype.setStrokeWeight = function(weight) { + this.strokeWeight = this.parseUnitSize(weight) + }; + PShapeSVG.prototype.setStrokeJoin = function(linejoin) { + if (linejoin === "miter") this.strokeJoin = 'miter'; + else if (linejoin === "round") this.strokeJoin = 'round'; + else if (linejoin === "bevel") this.strokeJoin = 'bevel' + }; + PShapeSVG.prototype.setStrokeCap = function(linecap) { + if (linecap === "butt") this.strokeCap = 'butt'; + else if (linecap === "round") this.strokeCap = 'round'; + else if (linecap === "square") this.strokeCap = 'square' + }; + PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { + this.strokeOpacity = parseFloat(opacityText); + this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 + }; + PShapeSVG.prototype.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] + }; + PShapeSVG.prototype.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; + if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; + if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; + if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; + if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; + if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); + 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 === 3) 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 === 0) 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 === 1) 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(p); + if (arguments.length === 1 && curShapeMode === 3 || 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(selector, uri, sysid, line) { + this.attributes = []; + this.children = []; + this.fullName = null; + this.name = null; + this.namespace = ""; + this.content = null; + this.parent = null; + this.lineNr = ""; + this.systemID = ""; + this.type = "ELEMENT"; + if (selector) if (typeof selector === "string") if (uri === undef && selector.indexOf("<") > -1) this.parse(selector); + else { + this.fullName = selector; + this.namespace = uri; + this.systemId = sysid; + this.lineNr = line + } else this.parse(uri) + }; + XMLElement.prototype = { + parse: function(textstring) { + var xmlDoc; + try { + var extension = textstring.substring(textstring.length - 4); + if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); + xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); + var elements = xmlDoc.documentElement; + if (elements) this.parseChildrenRecursive(null, elements); + else throw "Error loading document"; + return this + } catch(e) { + throw e; + } + }, + parseChildrenRecursive: function(parent, elementpath) { + var xmlelement, xmlattribute, tmpattrib, l, m, child; + if (!parent) { + this.fullName = elementpath.localName; + this.name = elementpath.nodeName; + xmlelement = this + } else { + xmlelement = new XMLElement(elementpath.nodeName); + xmlelement.parent = parent + } + if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); + if (elementpath.nodeType === 4) return this.createCDataElement(elementpath.textContent); + if (elementpath.attributes) for (l = 0, m = elementpath.attributes.length; l < m; l++) { + tmpattrib = elementpath.attributes[l]; + xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); + xmlelement.attributes.push(xmlattribute) + } + if (elementpath.childNodes) for (l = 0, m = elementpath.childNodes.length; l < m; l++) { + var node = elementpath.childNodes[l]; + child = xmlelement.parseChildrenRecursive(xmlelement, node); + if (child !== null) xmlelement.children.push(child) + } + return xmlelement + }, + createElement: function(fullname, namespaceuri, sysid, line) { + if (sysid === undef) return new XMLElement(fullname, namespaceuri); + return new XMLElement(fullname, namespaceuri, sysid, line) + }, + createPCDataElement: function(content, isCDATA) { + if (content.replace(/^\s+$/g, "") === "") return null; + var pcdata = new XMLElement; + pcdata.type = "TEXT"; + pcdata.content = content; + return pcdata + }, + createCDataElement: function(content) { + var cdata = this.createPCDataElement(content); + if (cdata === null) return null; + cdata.type = "CDATA"; + var htmlentities = { + "<": "<", + ">": ">", + "'": "'", + '"': """ + }, + entity; + for (entity in htmlentities) if (!Object.hasOwnProperty(htmlentities, entity)) content = content.replace(new RegExp(entity, "g"), htmlentities[entity]); + cdata.cdata = content; + return cdata + }, + hasAttribute: function() { + if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; + if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null + }, + equals: function(other) { + if (! (other instanceof XMLElement)) return false; + var i, j; + if (this.fullName !== other.fullName) return false; + if (this.attributes.length !== other.getAttributeCount()) return false; + if (this.attributes.length !== other.attributes.length) return false; + var attr_name, attr_ns, attr_value, attr_type, attr_other; + for (i = 0, j = this.attributes.length; i < j; i++) { + attr_name = this.attributes[i].getName(); + attr_ns = this.attributes[i].getNamespace(); + attr_other = other.findAttribute(attr_name, attr_ns); + if (attr_other === null) return false; + if (this.attributes[i].getValue() !== attr_other.getValue()) return false; + if (this.attributes[i].getType() !== attr_other.getType()) return false + } + if (this.children.length !== other.getChildCount()) return false; + if (this.children.length > 0) { + var child1, child2; + for (i = 0, j = this.children.length; i < j; i++) { + child1 = this.getChild(i); + child2 = other.getChild(i); + if (!child1.equals(child2)) return false + } + return true + } + return this.content === other.content + }, + getContent: function() { + if (this.type === "TEXT" || this.type === "CDATA") return this.content; + var children = this.children; + if (children.length === 1 && (children[0].type === "TEXT" || children[0].type === "CDATA")) return children[0].content; + return null + }, + getAttribute: function() { + var attribute; + if (arguments.length === 2) { + attribute = this.findAttribute(arguments[0]); + if (attribute) return attribute.getValue(); + return arguments[1] + } else if (arguments.length === 1) { + attribute = this.findAttribute(arguments[0]); + if (attribute) return attribute.getValue(); + return null + } else if (arguments.length === 3) { + attribute = this.findAttribute(arguments[0], arguments[1]); + if (attribute) return attribute.getValue(); + return arguments[2] + } + }, + getStringAttribute: function() { + if (arguments.length === 1) return this.getAttribute(arguments[0]); + if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); + return this.getAttribute(arguments[0], arguments[1], arguments[2]) + }, + getString: function(attributeName) { + return this.getStringAttribute(attributeName) + }, + getFloatAttribute: function() { + if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); + if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); + return this.getAttribute(arguments[0], arguments[1], arguments[2]) + }, + getFloat: function(attributeName) { + return this.getFloatAttribute(attributeName) + }, + getIntAttribute: function() { + if (arguments.length === 1) return this.getAttribute(arguments[0], 0); + if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); + return this.getAttribute(arguments[0], arguments[1], arguments[2]) + }, + getInt: function(attributeName) { + return this.getIntAttribute(attributeName) + }, + 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(selector) { + if (typeof selector === "number") return this.children[selector]; + if (selector.indexOf("/") !== -1) return this.getChildRecursive(selector.split("/"), 0); + var kid, kidName; + for (var i = 0, j = this.getChildCount(); i < j; i++) { + kid = this.getChild(i); + kidName = kid.getName(); + if (kidName !== null && kidName === selector) return kid + } + return null + }, + getChildren: function() { + if (arguments.length === 1) { + if (typeof arguments[0] === "number") return this.getChild(arguments[0]); + if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); + var matches = []; + var kid, kidName; + for (var i = 0, j = this.getChildCount(); i < j; i++) { + kid = this.getChild(i); + kidName = kid.getName(); + if (kidName !== null && kidName === arguments[0]) matches.push(kid) + } + return matches + } + return this.children + }, + getChildCount: function() { + return this.children.length + }, + getChildRecursive: function(items, offset) { + if (offset === items.length) return this; + var kid, kidName, matchName = items[offset]; + for (var i = 0, j = this.getChildCount(); i < j; i++) { + kid = this.getChild(i); + kidName = kid.getName(); + if (kidName !== null && kidName === matchName) return kid.getChildRecursive(items, offset + 1) + } + 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 = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); + return kidMatches + }, + isLeaf: function() { + return !this.hasChildren() + }, + listChildren: function() { + var arr = []; + for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); + return arr + }, + removeAttribute: function(name, namespace) { + this.namespace = namespace || ""; + for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { + this.attributes.splice(i, 1); + break + } + }, + removeChild: function(child) { + if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { + this.children.splice(i, 1); + break + } + }, + removeChildAtIndex: function(index) { + if (this.children.length > index) this.children.splice(index, 1) + }, + findAttribute: function(name, namespace) { + this.namespace = namespace || ""; + for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; + return null + }, + 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) + } + } + }, + setString: function(attribute, value) { + this.setAttribute(attribute, value) + }, + setInt: function(attribute, value) { + this.setAttribute(attribute, value) + }, + setFloat: function(attribute, value) { + this.setAttribute(attribute, value) + }, + setContent: function(content) { + if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); + 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 + }, + toString: function() { + if (this.type === "TEXT") return this.content; + if (this.type === "CDATA") return this.cdata; + var tagstring = this.fullName; + var xmlstring = "<" + tagstring; + var a, c; + for (a = 0; a < this.attributes.length; a++) { + var attr = this.attributes[a]; + xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' + } + if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; + else xmlstring += ">" + this.content + ""; + else { + xmlstring += ">"; + for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); + xmlstring += "" + } + return xmlstring + } + }; + XMLElement.parse = function(xmlstring) { + var element = new XMLElement; + element.parse(xmlstring); + return element + }; + var XML = p.XML = p.XMLElement; + p.loadXML = function(uri) { + return new XML(p, uri) + }; + var printMatrixHelper = function(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] + }, + invTranslate: function(tx, ty) { + this.translate(-tx, -ty) + }, + 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) + }, + shearX: function(angle) { + this.apply(1, 0, 1, Math.tan(angle), 0, 0) + }, + shearY: function(angle) { + this.apply(1, 0, 1, 0, Math.tan(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) > -2147483648) { + 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 + } + }, + invScale: function(sx, sy) { + if (sx && !sy) sy = sx; + this.scale(1 / sx, 1 / 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) + }, + invRotateZ: function(angle) { + this.rotateZ(angle - Math.PI) + }, + 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() { + 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.elements = [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[4]; + this.elements[4] = this.elements[1]; + this.elements[1] = temp; + temp = this.elements[8]; + this.elements[8] = this.elements[2]; + this.elements[2] = temp; + temp = this.elements[6]; + this.elements[6] = this.elements[9]; + this.elements[9] = temp; + temp = this.elements[3]; + this.elements[3] = this.elements[12]; + this.elements[12] = temp; + temp = this.elements[7]; + this.elements[7] = this.elements[13]; + this.elements[13] = temp; + temp = this.elements[11]; + this.elements[11] = this.elements[14]; + this.elements[14] = temp + }, + 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) + }, + shearX: 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) + }, + shearY: 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]; + if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; + 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]; + if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; + 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]; + 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]; + 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) <= 1.0E-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() { + this.matrixStack = [] + }; + PMatrixStack.prototype.load = function() { + var tmpMatrix = drawing.$newPMatrix(); + if (arguments.length === 1) tmpMatrix.set(arguments[0]); + else tmpMatrix.set(arguments); + this.matrixStack.push(tmpMatrix) + }; + Drawing2D.prototype.$newPMatrix = function() { + return new PMatrix2D + }; + Drawing3D.prototype.$newPMatrix = function() { + return new PMatrix3D + }; + PMatrixStack.prototype.push = function() { + this.matrixStack.push(this.peek()) + }; + PMatrixStack.prototype.pop = function() { + return this.matrixStack.pop() + }; + PMatrixStack.prototype.peek = function() { + var tmpMatrix = drawing.$newPMatrix(); + tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); + return tmpMatrix + }; + PMatrixStack.prototype.mult = function(matrix) { + this.matrixStack[this.matrixStack.length - 1].apply(matrix) + }; + p.split = function(str, delim) { + return str.split(delim) + }; + p.splitTokens = function(str, tokens) { + if (tokens === undef) return str.split(/\s+/g); + var chars = tokens.split(/()/g), + buffer = "", + len = str.length, + i, c, tokenized = []; + for (i = 0; i < len; i++) { + c = str[i]; + if (chars.indexOf(c) > -1) { + if (buffer !== "") tokenized.push(buffer); + buffer = "" + } else buffer += c + } + if (buffer !== "") tokenized.push(buffer); + return tokenized + }; + 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) { + var end = length !== undef ? offset + length : array.length; + return array.slice(offset, end) + }; + 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, targetSize) { + var temp = ary.slice(0), + newSize = targetSize || ary.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 = function() { + var ALPHA_MASK = 4278190080, + RED_MASK = 16711680, + GREEN_MASK = 65280, + BLUE_MASK = 255, + min = Math.min, + max = Math.max; + + function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { + var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; + var r = ar + ((cr - ar) * f >> 8); + r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; + var g = ag + ((cg - ag) * f >> 8); + g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; + var b = ab + ((cb - ab) * f >> 8); + b = b < 0 ? 0 : b > 255 ? 255 : b; + return a | r | g | b + } + return { + replace: function(c1, c2) { + return c2 + }, + blend: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = c1 & RED_MASK, + ag = c1 & GREEN_MASK, + ab = c1 & BLUE_MASK, + br = c2 & RED_MASK, + bg = c2 & GREEN_MASK, + bb = c2 & BLUE_MASK; + return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK + }, + add: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24; + return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) + }, + subtract: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24; + return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) + }, + lightest: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24; + return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) + }, + darkest: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = c1 & RED_MASK, + ag = c1 & GREEN_MASK, + ab = c1 & BLUE_MASK, + br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), + bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), + bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); + return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK + }, + difference: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = ar > br ? ar - br : br - ar, + cg = ag > bg ? ag - bg : bg - ag, + cb = ab > bb ? ab - bb : bb - ab; + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + exclusion: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = ar + br - (ar * br >> 7), + cg = ag + bg - (ag * bg >> 7), + cb = ab + bb - (ab * bb >> 7); + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + multiply: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = ar * br >> 8, + cg = ag * bg >> 8, + cb = ab * bb >> 8; + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + screen: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = 255 - ((255 - ar) * (255 - br) >> 8), + cg = 255 - ((255 - ag) * (255 - bg) >> 8), + cb = 255 - ((255 - ab) * (255 - bb) >> 8); + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + hard_light: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), + cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), + cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + soft_light: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), + cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), + cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + overlay: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), + cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), + cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + dodge: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK; + var cr = 255; + if (br !== 255) { + cr = (ar << 8) / (255 - br); + cr = cr < 0 ? 0 : cr > 255 ? 255 : cr + } + var cg = 255; + if (bg !== 255) { + cg = (ag << 8) / (255 - bg); + cg = cg < 0 ? 0 : cg > 255 ? 255 : cg + } + var cb = 255; + if (bb !== 255) { + cb = (ab << 8) / (255 - bb); + cb = cb < 0 ? 0 : cb > 255 ? 255 : cb + } + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + burn: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK; + var cr = 0; + if (br !== 0) { + cr = (255 - ar << 8) / br; + cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) + } + var cg = 0; + if (bg !== 0) { + cg = (255 - ag << 8) / bg; + cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) + } + var cb = 0; + if (bb !== 0) { + cb = (255 - ab << 8) / bb; + cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) + } + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + } + } + }(); + + function color$4(aValue1, aValue2, aValue3, aValue4) { + var r, g, b, a; + if (curColorMode === 3) { + 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 < 0 ? 0 : r; + g = g < 0 ? 0 : g; + b = b < 0 ? 0 : b; + a = a < 0 ? 0 : a; + r = r > 255 ? 255 : r; + g = g > 255 ? 255 : g; + b = b > 255 ? 255 : b; + a = a > 255 ? 255 : a; + return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 + } + function color$2(aValue1, aValue2) { + var a; + if (aValue1 & 4278190080) { + a = Math.round(255 * (aValue2 / colorModeA)); + a = a > 255 ? 255 : a; + a = a < 0 ? 0 : a; + return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) + } + if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); + if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) + } + function color$1(aValue1) { + if (aValue1 <= colorModeX && aValue1 >= 0) { + if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); + if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) + } + if (aValue1) { + if (aValue1 > 2147483647) aValue1 -= 4294967296; + return aValue1 + } + } + p.color = function(aValue1, aValue2, aValue3, aValue4) { + if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); + if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); + if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); + if (typeof aValue1 === "number") return color$1(aValue1); + return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) + }; + p.color.toString = function(colorInt) { + return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" + }; + p.color.toInt = function(r, g, b, a) { + return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 + }; + p.color.toArray = function(colorInt) { + return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] + }; + p.color.toGLArray = function(colorInt) { + return [((colorInt & 16711680) >>> 16) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt >> 24) & 255) / 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]; + var hue = h % 360; + var f = hue % 60; + var p = Math.round(b * (100 - s) / 1E4 * 255); + var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); + var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 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] + } + }; + + function colorToHSB(colorInt) { + var red, green, blue; + red = ((colorInt >> 16) & 255) / 255; + green = ((colorInt >> 8) & 255) / 255; + blue = (colorInt & 255) / 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 * colorModeZ]; + 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 colorToHSB(colInt)[2] + }; + p.saturation = function(colInt) { + return colorToHSB(colInt)[1] + }; + p.hue = function(colInt) { + return colorToHSB(colInt)[0] + }; + p.red = function(aColor) { + return ((aColor >> 16) & 255) / 255 * colorModeX + }; + p.green = function(aColor) { + return ((aColor & 65280) >>> 8) / 255 * colorModeY + }; + p.blue = function(aColor) { + return (aColor & 255) / 255 * colorModeZ + }; + p.alpha = function(aColor) { + return ((aColor >> 24) & 255) / 255 * colorModeA + }; + p.lerpColor = function(c1, c2, amt) { + var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; + var hsb1, hsb2, rgb, h, s; + var colorBits1 = p.color(c1); + var colorBits2 = p.color(c2); + if (curColorMode === 3) { + hsb1 = colorToHSB(colorBits1); + a1 = ((colorBits1 >> 24) & 255) / colorModeA; + hsb2 = colorToHSB(colorBits2); + a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; + h = p.lerp(hsb1[0], hsb2[0], amt); + s = p.lerp(hsb1[1], hsb2[1], amt); + b = p.lerp(hsb1[2], hsb2[2], amt); + rgb = p.color.toRGB(h, s, b); + a = p.lerp(a1, a2, amt) * colorModeA; + return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 + } + r1 = (colorBits1 >> 16) & 255; + g1 = (colorBits1 >> 8) & 255; + b1 = colorBits1 & 255; + a1 = ((colorBits1 >> 24) & 255) / colorModeA; + r2 = (colorBits2 & 16711680) >>> 16; + g2 = (colorBits2 >> 8) & 255; + b2 = colorBits2 & 255; + a2 = ((colorBits2 >> 24) & 255) / colorModeA; + r = p.lerp(r1, r2, amt) | 0; + g = p.lerp(g1, g2, amt) | 0; + b = p.lerp(b1, b2, amt) | 0; + a = p.lerp(a1, a2, amt) * colorModeA; + return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 + }; + p.colorMode = function() { + 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) { + if (mode === 0) return p.modes.replace(c1, c2); + else if (mode === 1) return p.modes.blend(c1, c2); + else if (mode === 2) return p.modes.add(c1, c2); + else if (mode === 4) return p.modes.subtract(c1, c2); + else if (mode === 8) return p.modes.lightest(c1, c2); + else if (mode === 16) return p.modes.darkest(c1, c2); + else if (mode === 32) return p.modes.difference(c1, c2); + else if (mode === 64) return p.modes.exclusion(c1, c2); + else if (mode === 128) return p.modes.multiply(c1, c2); + else if (mode === 256) return p.modes.screen(c1, c2); + else if (mode === 1024) return p.modes.hard_light(c1, c2); + else if (mode === 2048) return p.modes.soft_light(c1, c2); + else if (mode === 512) return p.modes.overlay(c1, c2); + else if (mode === 4096) return p.modes.dodge(c1, c2); + else if (mode === 8192) return p.modes.burn(c1, c2) + }; + + function saveContext() { + curContext.save() + } + function restoreContext() { + curContext.restore(); + isStrokeDirty = true; + isFillDirty = true + } + p.printMatrix = function() { + modelView.print() + }; + Drawing2D.prototype.translate = function(x, y) { + modelView.translate(x, y); + modelViewInv.invTranslate(x, y); + curContext.translate(x, y) + }; + Drawing3D.prototype.translate = function(x, y, z) { + modelView.translate(x, y, z); + modelViewInv.invTranslate(x, y, z) + }; + Drawing2D.prototype.scale = function(x, y) { + modelView.scale(x, y); + modelViewInv.invScale(x, y); + curContext.scale(x, y || x) + }; + Drawing3D.prototype.scale = function(x, y, z) { + modelView.scale(x, y, z); + modelViewInv.invScale(x, y, z) + }; + Drawing2D.prototype.transform = function(pmatrix) { + var e = pmatrix.array(); + curContext.transform(e[0], e[3], e[1], e[4], e[2], e[5]) + }; + Drawing3D.prototype.transformm = function(pmatrix3d) { + throw "p.transform is currently not supported in 3D mode"; + }; + Drawing2D.prototype.pushMatrix = function() { + userMatrixStack.load(modelView); + userReverseMatrixStack.load(modelViewInv); + saveContext() + }; + Drawing3D.prototype.pushMatrix = function() { + userMatrixStack.load(modelView); + userReverseMatrixStack.load(modelViewInv) + }; + Drawing2D.prototype.popMatrix = function() { + modelView.set(userMatrixStack.pop()); + modelViewInv.set(userReverseMatrixStack.pop()); + restoreContext() + }; + Drawing3D.prototype.popMatrix = function() { + modelView.set(userMatrixStack.pop()); + modelViewInv.set(userReverseMatrixStack.pop()) + }; + Drawing2D.prototype.resetMatrix = function() { + modelView.reset(); + modelViewInv.reset(); + curContext.setTransform(1, 0, 0, 1, 0, 0) + }; + Drawing3D.prototype.resetMatrix = function() { + modelView.reset(); + modelViewInv.reset() + }; + DrawingShared.prototype.applyMatrix = function() { + var a = arguments; + modelView.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]); + modelViewInv.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]) + }; + Drawing2D.prototype.applyMatrix = function() { + var a = arguments; + for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; + a[10] = a[15] = 1; + DrawingShared.prototype.applyMatrix.apply(this, a) + }; + p.rotateX = function(angleInRadians) { + modelView.rotateX(angleInRadians); + modelViewInv.invRotateX(angleInRadians) + }; + Drawing2D.prototype.rotateZ = function() { + throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; + }; + Drawing3D.prototype.rotateZ = function(angleInRadians) { + modelView.rotateZ(angleInRadians); + modelViewInv.invRotateZ(angleInRadians) + }; + p.rotateY = function(angleInRadians) { + modelView.rotateY(angleInRadians); + modelViewInv.invRotateY(angleInRadians) + }; + Drawing2D.prototype.rotate = function(angleInRadians) { + modelView.rotateZ(angleInRadians); + modelViewInv.invRotateZ(angleInRadians); + curContext.rotate(angleInRadians) + }; + Drawing3D.prototype.rotate = function(angleInRadians) { + p.rotateZ(angleInRadians) + }; + Drawing2D.prototype.shearX = function(angleInRadians) { + modelView.shearX(angleInRadians); + curContext.transform(1, 0, angleInRadians, 1, 0, 0) + }; + Drawing3D.prototype.shearX = function(angleInRadians) { + modelView.shearX(angleInRadians) + }; + Drawing2D.prototype.shearY = function(angleInRadians) { + modelView.shearY(angleInRadians); + curContext.transform(1, angleInRadians, 0, 1, 0, 0) + }; + Drawing3D.prototype.shearY = function(angleInRadians) { + modelView.shearY(angleInRadians) + }; + p.pushStyle = function() { + 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, + "horizontalTextAlignment": horizontalTextAlignment, + "verticalTextAlignment": verticalTextAlignment, + "textMode": textMode, + "curFontName": curFontName, + "curTextSize": curTextSize, + "curTextAscent": curTextAscent, + "curTextDescent": curTextDescent, + "curTextLeading": curTextLeading + }; + styleArray.push(newState) + }; + p.popStyle = function() { + 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; + curFontName = oldState.curFontName; + curTextSize = oldState.curTextSize; + horizontalTextAlignment = oldState.horizontalTextAlignment; + verticalTextAlignment = oldState.verticalTextAlignment; + textMode = oldState.textMode; + curTextAscent = oldState.curTextAscent; + curTextDescent = oldState.curTextDescent; + curTextLeading = oldState.curTextLeading + } else throw "Too many popStyle() without enough pushStyle()"; + }; + p.year = function() { + return (new Date).getFullYear() + }; + p.month = function() { + return (new Date).getMonth() + 1 + }; + p.day = function() { + return (new Date).getDate() + }; + p.hour = function() { + return (new Date).getHours() + }; + p.minute = function() { + return (new Date).getMinutes() + }; + p.second = function() { + return (new Date).getSeconds() + }; + p.millis = function() { + return Date.now() - start + }; + + function redrawHelper() { + var sec = (Date.now() - timeSinceLastFPS) / 1E3; + framesSinceLastFPS++; + var fps = framesSinceLastFPS / sec; + if (sec > 0.5) { + timeSinceLastFPS = Date.now(); + framesSinceLastFPS = 0; + p.__frameRate = fps + } + p.frameCount++ + } + Drawing2D.prototype.redraw = function() { + redrawHelper(); + curContext.lineWidth = lineWidth; + var pmouseXLastEvent = p.pmouseX, + pmouseYLastEvent = p.pmouseY; + p.pmouseX = pmouseXLastFrame; + p.pmouseY = pmouseYLastFrame; + saveContext(); + p.draw(); + restoreContext(); + pmouseXLastFrame = p.mouseX; + pmouseYLastFrame = p.mouseY; + p.pmouseX = pmouseXLastEvent; + p.pmouseY = pmouseYLastEvent + }; + Drawing3D.prototype.redraw = function() { + redrawHelper(); + var pmouseXLastEvent = p.pmouseX, + pmouseYLastEvent = p.pmouseY; + p.pmouseX = pmouseXLastFrame; + p.pmouseY = pmouseYLastFrame; + 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.emissive(0, 0, 0); + p.camera(); + p.draw(); + pmouseXLastFrame = p.mouseX; + pmouseYLastFrame = p.mouseY; + p.pmouseX = pmouseXLastEvent; + p.pmouseY = pmouseYLastEvent + }; + p.noLoop = function() { + doLoop = false; + loopStarted = false; + clearInterval(looping); + curSketch.onPause() + }; + p.loop = function() { + if (loopStarted) return; + timeSinceLastFPS = Date.now(); + framesSinceLastFPS = 0; + looping = window.setInterval(function() { + try { + curSketch.onFrameStart(); + p.redraw(); + curSketch.onFrameEnd() + } catch(e_loop) { + window.clearInterval(looping); + throw e_loop; + } + }, + curMsPerFrame); + doLoop = true; + loopStarted = true; + curSketch.onLoop() + }; + p.frameRate = function(aRate) { + curFrameRate = aRate; + curMsPerFrame = 1E3 / curFrameRate; + if (doLoop) { + p.noLoop(); + p.loop() + } + }; + var eventHandlers = []; + + function attachEventHandler(elem, type, fn) { + if (elem.addEventListener) elem.addEventListener(type, fn, false); + else elem.attachEvent("on" + type, fn); + eventHandlers.push({ + elem: elem, + type: type, + fn: fn + }) + } + function detachEventHandler(eventHandler) { + var elem = eventHandler.elem, + type = eventHandler.type, + fn = eventHandler.fn; + if (elem.removeEventListener) elem.removeEventListener(type, fn, false); + else if (elem.detachEvent) elem.detachEvent("on" + type, fn) + } + p.exit = function() { + window.clearInterval(looping); + removeInstance(p.externals.canvas.id); + delete curElement.onmousedown; + for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); + var i = eventHandlers.length; + while (i--) detachEventHandler(eventHandlers[i]); + curSketch.onExit() + }; + p.cursor = function() { + 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() { + curCursor = curElement.style.cursor = PConstants.NOCURSOR + }; + p.link = function(href, target) { + if (target !== undef) window.open(href, target); + else window.location = href + }; + p.beginDraw = nop; + p.endDraw = nop; + Drawing2D.prototype.toImageData = function(x, y, w, h) { + x = x !== undef ? x : 0; + y = y !== undef ? y : 0; + w = w !== undef ? w : p.width; + h = h !== undef ? h : p.height; + return curContext.getImageData(x, y, w, h) + }; + Drawing3D.prototype.toImageData = function(x, y, w, h) { + x = x !== undef ? x : 0; + y = y !== undef ? y : 0; + w = w !== undef ? w : p.width; + h = h !== undef ? h : p.height; + var c = document.createElement("canvas"), + ctx = c.getContext("2d"), + obj = ctx.createImageData(w, h), + uBuff = new Uint8Array(w * h * 4); + curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); + for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; + return obj + }; + p.status = function(text) { + window.status = text + }; + p.binary = function(num, numBits) { + var bit; + if (numBits > 0) bit = numBits; + else if (num instanceof Char) { + bit = 16; + num |= 0 + } else { + bit = 32; + while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- + } + var result = ""; + while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; + return result + }; + p.unbinary = function(binaryString) { + var i = binaryString.length - 1, + mask = 1, + result = 0; + while (i >= 0) { + var ch = binaryString[i--]; + if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; + if (ch === "1") result += mask; + mask <<= 1 + } + return result + }; + + 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) > 1.0E-6 && 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); + 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 + } + 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(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(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 + } + return unhexScalar(hex) + }; + p.loadStrings = function(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(filename, strings) { + localStorage[filename] = strings.join("\n") + }; + p.loadBytes = function(url) { + var string = ajax(url); + var ret = []; + for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); + return ret + }; + + function removeFirstArgument(args) { + return Array.prototype.slice.call(args, 1) + } + p.matchAll = function(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 + }; + p.__contains = function(subject, subStr) { + if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); + return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 + }; + p.__replaceAll = function(subject, regex, replacement) { + if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); + return subject.replace(new RegExp(regex, "g"), replacement) + }; + p.__replaceFirst = function(subject, regex, replacement) { + if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); + return subject.replace(new RegExp(regex, ""), replacement) + }; + p.__replace = function(subject, what, replacement) { + if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); + if (what instanceof RegExp) return subject.replace(what, replacement); + if (typeof what !== "string") what = what.toString(); + if (what === "") return subject; + var i = subject.indexOf(what); + if (i < 0) return subject; + var j = 0, + result = ""; + do { + result += subject.substring(j, i) + replacement; + j = i + what.length + } while ((i = subject.indexOf(what, j)) >= 0); + return result + subject.substring(j) + }; + p.__equals = function(subject, other) { + if (subject.equals instanceof + Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); + return subject.valueOf() === other.valueOf() + }; + p.__equalsIgnoreCase = function(subject, other) { + if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); + return subject.toLowerCase() === other.toLowerCase() + }; + p.__toCharArray = function(subject) { + if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); + var chars = []; + for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); + return chars + }; + p.__split = function(subject, regex, limit) { + if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); + var pattern = new RegExp(regex); + if (limit === undef || limit < 1) return subject.split(pattern); + var result = [], + currSubject = subject, + pos; + while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { + var match = pattern.exec(currSubject).toString(); + result.push(currSubject.substring(0, pos)); + currSubject = currSubject.substring(pos + match.length) + } + if (pos !== -1 || currSubject !== "") result.push(currSubject); + return result + }; + p.__codePointAt = function(subject, idx) { + var code = subject.charCodeAt(idx), + hi, low; + if (55296 <= code && code <= 56319) { + hi = code; + low = subject.charCodeAt(idx + 1); + return (hi - 55296) * 1024 + (low - 56320) + 65536 + } + return code + }; + p.match = function(str, regexp) { + return str.match(regexp) + }; + p.__matches = function(str, regexp) { + return (new RegExp(regexp)).test(str) + }; + p.__startsWith = function(subject, prefix, toffset) { + if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); + toffset = toffset || 0; + if (toffset < 0 || toffset > subject.length) return false; + return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset + }; + p.__endsWith = function(subject, suffix) { + if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); + var suffixLen = suffix ? suffix.length : 0; + return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen + }; + p.__hashCode = function(subject) { + if (subject.hashCode instanceof + Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); + return virtHashCode(subject) + }; + p.__printStackTrace = function(subject) { + p.println("Exception: " + subject.toString()) + }; + var logBuffer = []; + p.println = function(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(message) { + logBuffer.push(message) + }; + p.str = function(val) { + if (val instanceof Array) { + var arr = []; + for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); + return arr + } + return val.toString() + "" + }; + 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 + } + return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") + }; + + function booleanScalar(val) { + if (typeof val === "number") return val !== 0; + if (typeof val === "boolean") return val; + if (typeof val === "string") return val.toLowerCase() === "true"; + if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 + } + p.parseBoolean = function(val) { + if (val instanceof Array) { + var ret = []; + for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); + return ret + } + return booleanScalar(val) + }; + p.parseByte = function(what) { + if (what instanceof Array) { + var bytes = []; + for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); + return bytes + } + return 0 - (what & 128) | what & 127 + }; + p.parseChar = function(key) { + if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); + 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 + } + throw "char() may receive only one argument of type int, byte, int[], or byte[]."; + }; + + function floatScalar(val) { + if (typeof val === "number") return val; + if (typeof val === "boolean") return val ? 1 : 0; + if (typeof val === "string") return parseFloat(val); + if (val instanceof Char) return val.code + } + p.parseFloat = function(val) { + if (val instanceof + Array) { + var ret = []; + for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); + return ret + } + return floatScalar(val) + }; + + function intScalar(val, radix) { + if (typeof val === "number") return val & 4294967295; + if (typeof val === "boolean") return val ? 1 : 0; + if (typeof val === "string") { + var number = parseInt(val, radix || 10); + return number & 4294967295 + } + if (val instanceof Char) return val.code + } + p.parseInt = function(val, radix) { + 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], radix)); + return ret + } + return intScalar(val, radix) + }; + p.__int_cast = function(val) { + return 0 | val + }; + p.__instanceof = function(obj, type) { + if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; + if (typeof obj === "string") return type === Object || type === String; + if (obj instanceof type) return true; + if (typeof obj !== "object" || obj === null) return false; + var objType = obj.constructor; + if (type.$isInterface) { + var interfaces = []; + while (objType) { + if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); + objType = objType.$base + } + while (interfaces.length > 0) { + var i = interfaces.shift(); + if (i === type) return true; + if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) + } + return false + } + while (objType.hasOwnProperty("$base")) { + objType = objType.$base; + if (objType === type) return true + } + return false + }; + 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) + } + 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 (c) return Math.sqrt(a * a + b * b + c * c); + return Math.sqrt(a * a + b * b) + }; + 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]; + 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]; + 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() { + if (arguments.length === 0) return currentRandom(); + if (arguments.length === 1) return currentRandom() * arguments[0]; + 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 = 18E3 * (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 / 6E4 & 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 + } + 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 Uint8Array(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 + }; + DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { + if (doStroke) p.stroke(0); + if (doFill) p.fill(255); + var savedProperties = { + 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 prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; + p.textFont(curTextFont); + p.background(); + maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); + p.externals.context = curContext; + for (var i = 0; i < 720; i++) { + sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); + cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) + } + }; + Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { + if (curContext === undef) { + curContext = curElement.getContext("2d"); + userMatrixStack = new PMatrixStack; + userReverseMatrixStack = new PMatrixStack; + modelView = new PMatrix2D; + modelViewInv = new PMatrix2D + } + DrawingShared.prototype.size.apply(this, arguments) + }; + Drawing3D.prototype.size = function() { + var size3DCalled = false; + return function size(aWidth, aHeight, aMode) { + if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; + size3DCalled = true; + + function getGLContext(canvas) { + var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], + gl; + for (var i = 0, l = ctxNames.length; i < l; i++) { + gl = canvas.getContext(ctxNames[i], { + antialias: false, + preserveDrawingBuffer: true + }); + if (gl) break + } + return gl + } + try { + curElement.width = p.width = aWidth || 100; + curElement.height = p.height = aHeight || 100; + curContext = getGLContext(curElement); + canTex = curContext.createTexture(); + textTex = curContext.createTexture() + } catch(e_size) { + Processing.debug(e_size) + } + if (!curContext) throw "WebGL context is not supported on this browser."; + 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); + programObject2D = createProgramObject(curContext, vertexShaderSrc2D, fragmentShaderSrc2D); + programObjectUnlitShape = createProgramObject(curContext, vertexShaderSrcUnlitShape, fragmentShaderSrcUnlitShape); + p.strokeWeight(1); + programObject3D = createProgramObject(curContext, vertexShaderSrc3D, fragmentShaderSrc3D); + 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); + p.emissive(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; + modelView = new PMatrix3D; + modelViewInv = new PMatrix3D; + projection = new PMatrix3D; + p.camera(); + p.perspective(); + userMatrixStack = new PMatrixStack; + userReverseMatrixStack = 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); + DrawingShared.prototype.size.apply(this, arguments) + } + }(); + Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { + if (lightCount === 8) throw "can only create " + 8 + " 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); + var col = color$4(r, g, b, 0); + var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; + curContext.useProgram(programObject3D); + uniformf("uLights.color.3d." + lightCount, programObject3D, "uLights" + lightCount + ".color", normalizedCol); + uniformf("uLights.position.3d." + lightCount, programObject3D, "uLights" + lightCount + ".position", pos.array()); + uniformi("uLights.type.3d." + lightCount, programObject3D, "uLights" + lightCount + ".type", 0); + uniformi("uLightCount3d", programObject3D, "uLightCount", ++lightCount) + }; + Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { + if (lightCount === 8) throw "can only create " + 8 + " lights"; + curContext.useProgram(programObject3D); + var mvm = new PMatrix3D; + mvm.scale(1, -1, 1); + mvm.apply(modelView.array()); + mvm = mvm.array(); + var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; + var col = color$4(r, g, b, 0); + var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; + uniformf("uLights.color.3d." + lightCount, programObject3D, "uLights" + lightCount + ".color", normalizedCol); + uniformf("uLights.position.3d." + lightCount, programObject3D, "uLights" + lightCount + ".position", dir); + uniformi("uLights.type.3d." + lightCount, programObject3D, "uLights" + lightCount + ".type", 1); + uniformi("uLightCount3d", programObject3D, "uLightCount", ++lightCount) + }; + Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { + curContext.useProgram(programObject3D); + uniformf("uFalloff3d", programObject3D, "uFalloff", [constant, linear, quadratic]) + }; + Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.lightSpecular = function(r, g, b) { + var col = color$4(r, g, b, 0); + var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; + curContext.useProgram(programObject3D); + uniformf("uSpecular3d", programObject3D, "uSpecular", normalizedCol) + }; + p.lights = function() { + p.ambientLight(128, 128, 128); + p.directionalLight(128, 128, 128, 0, 0, -1); + p.lightFalloff(1, 0, 0); + p.lightSpecular(0, 0, 0) + }; + Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { + if (lightCount === 8) throw "can only create " + 8 + " 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); + var col = color$4(r, g, b, 0); + var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; + curContext.useProgram(programObject3D); + uniformf("uLights.color.3d." + lightCount, programObject3D, "uLights" + lightCount + ".color", normalizedCol); + uniformf("uLights.position.3d." + lightCount, programObject3D, "uLights" + lightCount + ".position", pos.array()); + uniformi("uLights.type.3d." + lightCount, programObject3D, "uLights" + lightCount + ".type", 2); + uniformi("uLightCount3d", programObject3D, "uLightCount", ++lightCount) + }; + Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.noLights = function() { + lightCount = 0; + curContext.useProgram(programObject3D); + uniformi("uLightCount3d", programObject3D, "uLightCount", lightCount) + }; + Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { + if (lightCount === 8) throw "can only create " + 8 + " lights"; + curContext.useProgram(programObject3D); + var pos = new PVector(x, y, z); + var mvm = new PMatrix3D; + mvm.scale(1, -1, 1); + mvm.apply(modelView.array()); + mvm.mult(pos, pos); + mvm = mvm.array(); + var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * + nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; + var col = color$4(r, g, b, 0); + var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; + uniformf("uLights.color.3d." + lightCount, programObject3D, "uLights" + lightCount + ".color", normalizedCol); + uniformf("uLights.position.3d." + lightCount, programObject3D, "uLights" + lightCount + ".position", pos.array()); + uniformf("uLights.direction.3d." + lightCount, programObject3D, "uLights" + lightCount + ".direction", dir); + uniformf("uLights.concentration.3d." + lightCount, programObject3D, "uLights" + lightCount + ".concentration", concentration); + uniformf("uLights.angle.3d." + lightCount, programObject3D, "uLights" + lightCount + ".angle", angle); + uniformi("uLights.type.3d." + lightCount, programObject3D, "uLights" + lightCount + ".type", 3); + uniformi("uLightCount3d", programObject3D, "uLightCount", ++lightCount) + }; + Drawing2D.prototype.beginCamera = function() { + throw "beginCamera() is not available in 2D mode"; + }; + Drawing3D.prototype.beginCamera = function() { + if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; + manipulatingCamera = true; + modelView = cameraInv; + modelViewInv = cam + }; + Drawing2D.prototype.endCamera = function() { + throw "endCamera() is not available in 2D mode"; + }; + Drawing3D.prototype.endCamera = function() { + if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; + modelView.set(cam); + modelViewInv.set(cameraInv); + manipulatingCamera = false + }; + p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { + if (eyeX === undef) { + cameraX = p.width / 2; + cameraY = p.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); + z.normalize(); + var x = PVector.cross(y, z); + y = PVector.cross(z, x); + x.normalize(); + y.normalize(); + var xX = x.x, + xY = x.y, + xZ = x.z; + var yX = y.x, + yY = y.y, + yZ = y.z; + var zX = z.x, + zY = z.y, + zZ = z.z; + cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); + cam.translate(-eyeX, -eyeY, -eyeZ); + cameraInv.reset(); + cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); + cameraInv.translate(eyeX, eyeY, eyeZ); + modelView.set(cam); + modelViewInv.set(cameraInv) + }; + p.perspective = function(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 = p.width / p.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) + }; + Drawing2D.prototype.frustum = function() { + throw "Processing.js: frustum() is not supported in 2D mode"; + }; + Drawing3D.prototype.frustum = function(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); + var proj = new PMatrix3D; + proj.set(projection); + proj.transpose(); + curContext.useProgram(programObject2D); + uniformMatrix("projection2d", programObject2D, "uProjection", false, proj.array()); + curContext.useProgram(programObject3D); + uniformMatrix("projection3d", programObject3D, "uProjection", false, proj.array()); + curContext.useProgram(programObjectUnlitShape); + uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) + }; + p.ortho = function(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); + var proj = new PMatrix3D; + proj.set(projection); + proj.transpose(); + curContext.useProgram(programObject2D); + uniformMatrix("projection2d", programObject2D, "uProjection", false, proj.array()); + curContext.useProgram(programObject3D); + uniformMatrix("projection3d", programObject3D, "uProjection", false, proj.array()); + curContext.useProgram(programObjectUnlitShape); + uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); + frustumMode = false + }; + p.printProjection = function() { + projection.print() + }; + p.printCamera = function() { + cam.print() + }; + Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.box = function(w, h, d) { + 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(); + if (doFill) { + curContext.useProgram(programObject3D); + uniformMatrix("model3d", programObject3D, "uModel", false, model.array()); + uniformMatrix("view3d", programObject3D, "uView", false, view.array()); + curContext.enable(curContext.POLYGON_OFFSET_FILL); + curContext.polygonOffset(1, 1); + uniformf("color3d", programObject3D, "uColor", fillStyle); + if (lightCount > 0) { + 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("uNormalTransform3d", programObject3D, "uNormalTransform", false, normalMatrix.array()); + vertexAttribPointer("aNormal3d", programObject3D, "aNormal", 3, boxNormBuffer) + } else disableVertexAttribPointer("aNormal3d", programObject3D, "aNormal"); + vertexAttribPointer("aVertex3d", programObject3D, "aVertex", 3, boxBuffer); + disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); + disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); + curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); + curContext.disable(curContext.POLYGON_OFFSET_FILL) + } + if (lineWidth > 0 && doStroke) { + curContext.useProgram(programObject2D); + uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array()); + uniformMatrix("uView2d", programObject2D, "uView", false, view.array()); + uniformf("uColor2d", programObject2D, "uColor", strokeStyle); + uniformi("uIsDrawingText2d", programObject2D, "uIsDrawingText", false); + vertexAttribPointer("vertex2d", programObject2D, "aVertex", 3, boxOutlineBuffer); + disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); + 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(sphereX[v1]); + sphereVerts.push(sphereY[v1]); + sphereVerts.push(sphereZ[v1++]); + sphereVerts.push(sphereX[v2]); + sphereVerts.push(sphereY[v2]); + sphereVerts.push(sphereZ[v2++]) + } + v1 = v11; + v2 = voff; + sphereVerts.push(sphereX[v1]); + sphereVerts.push(sphereY[v1]); + sphereVerts.push(sphereZ[v1]); + sphereVerts.push(sphereX[v2]); + sphereVerts.push(sphereY[v2]); + sphereVerts.push(sphereZ[v2]) + } + for (i = 0; i < sphereDetailU; i++) { + v2 = voff + i; + sphereVerts.push(sphereX[v2]); + sphereVerts.push(sphereY[v2]); + sphereVerts.push(sphereZ[v2]); + sphereVerts.push(0); + sphereVerts.push(1); + sphereVerts.push(0) + } + sphereVerts.push(sphereX[voff]); + sphereVerts.push(sphereY[voff]); + sphereVerts.push(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(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 = 720 / ures; + var cx = new Float32Array(ures); + var cz = new Float32Array(ures); + for (i = 0; i < ures; i++) { + cx[i] = cosLUT[i * delta % 720 | 0]; + cz[i] = sinLUT[i * delta % 720 | 0] + } + var vertCount = ures * (vres - 1) + 2; + var currVert = 0; + sphereX = new Float32Array(vertCount); + sphereY = new Float32Array(vertCount); + sphereZ = new Float32Array(vertCount); + var angle_step = 720 * 0.5 / vres; + var angle = angle_step; + for (i = 1; i < vres; i++) { + var curradius = sinLUT[angle % 720 | 0]; + var currY = -cosLUT[angle % 720 | 0]; + 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() + }; + Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.sphere = function() { + var sRad = arguments[0]; + 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(); + if (doFill) { + if (lightCount > 0) { + 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("uNormalTransform3d", programObject3D, "uNormalTransform", false, normalMatrix.array()); + vertexAttribPointer("aNormal3d", programObject3D, "aNormal", 3, sphereBuffer) + } else disableVertexAttribPointer("aNormal3d", programObject3D, "aNormal"); + curContext.useProgram(programObject3D); + disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); + uniformMatrix("uModel3d", programObject3D, "uModel", false, model.array()); + uniformMatrix("uView3d", programObject3D, "uView", false, view.array()); + vertexAttribPointer("aVertex3d", programObject3D, "aVertex", 3, sphereBuffer); + disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); + curContext.enable(curContext.POLYGON_OFFSET_FILL); + curContext.polygonOffset(1, 1); + uniformf("uColor3d", programObject3D, "uColor", fillStyle); + curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); + curContext.disable(curContext.POLYGON_OFFSET_FILL) + } + if (lineWidth > 0 && doStroke) { + curContext.useProgram(programObject2D); + uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array()); + uniformMatrix("uView2d", programObject2D, "uView", false, view.array()); + vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, sphereBuffer); + disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); + uniformf("uColor2d", programObject2D, "uColor", strokeStyle); + uniformi("uIsDrawingText", programObject2D, "uIsDrawingText", false); + curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) + } + }; + p.modelX = function(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(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(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 + }; + Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.ambient = function(v1, v2, v3) { + curContext.useProgram(programObject3D); + uniformi("uUsingMat3d", programObject3D, "uUsingMat", true); + var col = p.color(v1, v2, v3); + uniformf("uMaterialAmbient3d", programObject3D, "uMaterialAmbient", p.color.toGLArray(col).slice(0, 3)) + }; + Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.emissive = function(v1, v2, v3) { + curContext.useProgram(programObject3D); + uniformi("uUsingMat3d", programObject3D, "uUsingMat", true); + var col = p.color(v1, v2, v3); + uniformf("uMaterialEmissive3d", programObject3D, "uMaterialEmissive", p.color.toGLArray(col).slice(0, 3)) + }; + Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.shininess = function(shine) { + curContext.useProgram(programObject3D); + uniformi("uUsingMat3d", programObject3D, "uUsingMat", true); + uniformf("uShininess3d", programObject3D, "uShininess", shine) + }; + Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.specular = function(v1, v2, v3) { + curContext.useProgram(programObject3D); + uniformi("uUsingMat3d", programObject3D, "uUsingMat", true); + var col = p.color(v1, v2, v3); + uniformf("uMaterialSpecular3d", programObject3D, "uMaterialSpecular", p.color.toGLArray(col).slice(0, 3)) + }; + p.screenX = function(x, y, z) { + var mv = modelView.array(); + if (mv.length === 16) { + 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 pj = projection.array(); + 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 + } + return modelView.multX(x, y) + }; + p.screenY = function screenY(x, y, z) { + var mv = modelView.array(); + if (mv.length === 16) { + 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 pj = projection.array(); + 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 + } + return modelView.multY(x, y) + }; + p.screenZ = function screenZ(x, y, z) { + var mv = modelView.array(); + if (mv.length !== 16) return 0; + 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 + }; + DrawingShared.prototype.fill = function() { + var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); + if (color === currentFillColor && doFill) return; + doFill = true; + currentFillColor = color + }; + Drawing2D.prototype.fill = function() { + DrawingShared.prototype.fill.apply(this, arguments); + isFillDirty = true + }; + Drawing3D.prototype.fill = function() { + DrawingShared.prototype.fill.apply(this, arguments); + fillStyle = p.color.toGLArray(currentFillColor) + }; + + function executeContextFill() { + if (doFill) { + if (isFillDirty) { + curContext.fillStyle = p.color.toString(currentFillColor); + isFillDirty = false + } + curContext.fill() + } + } + p.noFill = function() { + doFill = false + }; + DrawingShared.prototype.stroke = function() { + var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); + if (color === currentStrokeColor && doStroke) return; + doStroke = true; + currentStrokeColor = color + }; + Drawing2D.prototype.stroke = function() { + DrawingShared.prototype.stroke.apply(this, arguments); + isStrokeDirty = true + }; + Drawing3D.prototype.stroke = function() { + DrawingShared.prototype.stroke.apply(this, arguments); + strokeStyle = p.color.toGLArray(currentStrokeColor) + }; + + function executeContextStroke() { + if (doStroke) { + if (isStrokeDirty) { + curContext.strokeStyle = p.color.toString(currentStrokeColor); + isStrokeDirty = false + } + curContext.stroke() + } + } + p.noStroke = function() { + doStroke = false + }; + DrawingShared.prototype.strokeWeight = function(w) { + lineWidth = w + }; + Drawing2D.prototype.strokeWeight = function(w) { + DrawingShared.prototype.strokeWeight.apply(this, arguments); + curContext.lineWidth = w + }; + Drawing3D.prototype.strokeWeight = function(w) { + DrawingShared.prototype.strokeWeight.apply(this, arguments); + curContext.useProgram(programObject2D); + uniformf("pointSize2d", programObject2D, "uPointSize", w); + curContext.useProgram(programObjectUnlitShape); + uniformf("pointSizeUnlitShape", programObjectUnlitShape, "uPointSize", w); + curContext.lineWidth(w) + }; + p.strokeCap = function(value) { + drawing.$ensureContext().lineCap = value + }; + p.strokeJoin = function(value) { + drawing.$ensureContext().lineJoin = value + }; + Drawing2D.prototype.smooth = function() { + renderSmooth = true; + var style = curElement.style; + style.setProperty("image-rendering", "optimizeQuality", "important"); + style.setProperty("-ms-interpolation-mode", "bicubic", "important"); + if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true + }; + Drawing3D.prototype.smooth = function() { + renderSmooth = true + }; + Drawing2D.prototype.noSmooth = function() { + renderSmooth = false; + var style = curElement.style; + style.setProperty("image-rendering", "optimizeSpeed", "important"); + style.setProperty("image-rendering", "-moz-crisp-edges", "important"); + style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); + style.setProperty("image-rendering", "optimize-contrast", "important"); + style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); + if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false + }; + Drawing3D.prototype.noSmooth = function() { + renderSmooth = false + }; + Drawing2D.prototype.point = function(x, y) { + if (!doStroke) return; + x = Math.round(x); + y = Math.round(y); + curContext.fillStyle = p.color.toString(currentStrokeColor); + isFillDirty = true; + if (lineWidth > 1) { + curContext.beginPath(); + curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); + curContext.fill() + } else curContext.fillRect(x, y, 1, 1) + }; + Drawing3D.prototype.point = function(x, y, z) { + 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(); + curContext.useProgram(programObject2D); + uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array()); + uniformMatrix("uView2d", programObject2D, "uView", false, view.array()); + if (lineWidth > 0 && doStroke) { + uniformf("uColor2d", programObject2D, "uColor", strokeStyle); + uniformi("uIsDrawingText2d", programObject2D, "uIsDrawingText", false); + uniformi("uSmooth2d", programObject2D, "uSmooth", renderSmooth); + vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, pointBuffer); + disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); + curContext.drawArrays(curContext.POINTS, 0, 1) + } + }; + p.beginShape = function(type) { + curShape = type; + curvePoints = []; + vertArray = [] + }; + Drawing2D.prototype.vertex = function(x, y, moveTo) { + var vert = []; + if (firstVert) firstVert = false; + vert["isVert"] = true; + vert[0] = x; + vert[1] = y; + vert[2] = 0; + vert[3] = 0; + vert[4] = 0; + vert[5] = currentFillColor; + vert[6] = currentStrokeColor; + vertArray.push(vert); + if (moveTo) vertArray[vertArray.length - 1]["moveTo"] = moveTo + }; + Drawing3D.prototype.vertex = function(x, y, z, u, v) { + var vert = []; + if (firstVert) firstVert = false; + vert["isVert"] = true; + if (v === undef && usingTexture) { + v = u; + u = z; + z = 0 + } + if (u !== undef && v !== undef) { + if (curTextureMode === 2) { + u /= curTexture.width; + v /= curTexture.height + } + u = u > 1 ? 1 : u; + u = u < 0 ? 0 : u; + v = v > 1 ? 1 : v; + v = v < 0 ? 0 : v + } + vert[0] = x; + vert[1] = y; + vert[2] = z || 0; + vert[3] = u || 0; + vert[4] = v || 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.push(vert) + }; + var point3D = function(vArray, cArray) { + var view = new PMatrix3D; + view.scale(1, -1, 1); + view.apply(modelView.array()); + view.transpose(); + curContext.useProgram(programObjectUnlitShape); + uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); + uniformi("uSmoothUS", programObjectUnlitShape, "uSmooth", renderSmooth); + 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(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(); + curContext.useProgram(programObjectUnlitShape); + uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.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.drawArrays(ctxMode, 0, vArray.length / 3) + }; + var fill3D = function(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(); + curContext.useProgram(programObject3D); + uniformMatrix("model3d", programObject3D, "uModel", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); + uniformMatrix("view3d", programObject3D, "uView", false, view.array()); + curContext.enable(curContext.POLYGON_OFFSET_FILL); + curContext.polygonOffset(1, 1); + uniformf("color3d", programObject3D, "uColor", [-1, 0, 0, 0]); + vertexAttribPointer("vertex3d", programObject3D, "aVertex", 3, fillBuffer); + curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); + if (usingTexture && curTint !== null) curTint3d(cArray); + vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); + curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); + disableVertexAttribPointer("aNormal3d", programObject3D, "aNormal"); + if (usingTexture) { + uniformi("uUsingTexture3d", programObject3D, "uUsingTexture", 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) + }; + + function fillStrokeClose() { + executeContextFill(); + executeContextStroke(); + curContext.closePath() + } + Drawing2D.prototype.endShape = function(mode) { + if (vertArray.length === 0) return; + var closeShape = mode === 2; + if (closeShape) vertArray.push(vertArray[0]); + var lineVertArray = []; + var fillVertArray = []; + var colorVertArray = []; + var strokeVertArray = []; + var texVertArray = []; + var cachedVertArray; + firstVert = true; + var i, j, k; + var vertArrayLength = vertArray.length; + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + texVertArray.push(cachedVertArray[3]); + texVertArray.push(cachedVertArray[4]) + } + if (isCurve && (curShape === 20 || curShape === undef)) { + if (vertArrayLength > 3) { + var b = [], + s = 1 - curTightness; + curContext.beginPath(); + curContext.moveTo(vertArray[1][0], vertArray[1][1]); + for (i = 1; i + 2 < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + b[0] = [cachedVertArray[0], cachedVertArray[1]]; + b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[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]) + } + fillStrokeClose() + } + } else if (isBezier && (curShape === 20 || curShape === undef)) { + curContext.beginPath(); + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); + else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); + else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) + } + fillStrokeClose() + } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + if (doStroke) p.stroke(cachedVertArray[6]); + p.point(cachedVertArray[0], cachedVertArray[1]) + } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { + cachedVertArray = vertArray[i]; + if (doStroke) p.stroke(vertArray[i + 1][6]); + p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) + } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { + cachedVertArray = vertArray[i]; + curContext.beginPath(); + curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); + curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); + curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); + curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); + if (doFill) { + p.fill(vertArray[i + 2][5]); + executeContextFill() + } + if (doStroke) { + p.stroke(vertArray[i + 2][6]); + executeContextStroke() + } + curContext.closePath() + } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + curContext.beginPath(); + curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); + curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); + if (doStroke) p.stroke(vertArray[i + 1][6]); + if (doFill) p.fill(vertArray[i + 1][5]); + if (i + 2 < vertArrayLength) { + 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]) + } + fillStrokeClose() + } else if (curShape === 11) { + if (vertArrayLength > 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 < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + curContext.beginPath(); + curContext.moveTo(vertArray[0][0], vertArray[0][1]); + curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); + curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); + if (doFill) { + p.fill(cachedVertArray[5]); + executeContextFill() + } + if (doStroke) { + p.stroke(cachedVertArray[6]); + executeContextStroke() + } + curContext.closePath() + } + } + } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { + cachedVertArray = vertArray[i]; + curContext.beginPath(); + curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); + for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); + curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); + if (doFill) { + p.fill(vertArray[i + 3][5]); + executeContextFill() + } + if (doStroke) { + p.stroke(vertArray[i + 3][6]); + executeContextStroke() + } + curContext.closePath() + } else if (curShape === 17) { + if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { + cachedVertArray = vertArray[i]; + curContext.beginPath(); + if (i + 3 < vertArrayLength) { + curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); + curContext.lineTo(cachedVertArray[0], cachedVertArray[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(cachedVertArray[0], cachedVertArray[1]); + curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) + } + fillStrokeClose() + } + } else { + curContext.beginPath(); + curContext.moveTo(vertArray[0][0], vertArray[0][1]); + for (i = 1; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); + else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) + } + fillStrokeClose() + } + isCurve = false; + isBezier = false; + curveVertArray = []; + curveVertCount = 0; + if (closeShape) vertArray.pop() + }; + Drawing3D.prototype.endShape = function(mode) { + if (vertArray.length === 0) return; + var closeShape = mode === 2; + var lineVertArray = []; + var fillVertArray = []; + var colorVertArray = []; + var strokeVertArray = []; + var texVertArray = []; + var cachedVertArray; + firstVert = true; + var i, j, k; + var vertArrayLength = vertArray.length; + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + texVertArray.push(cachedVertArray[3]); + texVertArray.push(cachedVertArray[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 === 20 || curShape === undef)) { + lineVertArray = fillVertArray; + if (doStroke) line3D(lineVertArray, null, strokeVertArray); + if (doFill) fill3D(fillVertArray, null, colorVertArray) + } else if (isBezier && (curShape === 20 || curShape === undef)) { + 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 { + if (curShape === 2) { + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) + } + point3D(lineVertArray, strokeVertArray) + } else if (curShape === 4) { + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) + } + line3D(lineVertArray, "LINES", strokeVertArray) + } else if (curShape === 9) { + if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; 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 === 10) { + if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; 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 === 11) { + if (vertArrayLength > 2) { + for (i = 0; i < 3; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < 3; i++) { + cachedVertArray = vertArray[i]; + for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) + } + if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); + for (i = 2; i + 1 < vertArrayLength; 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 === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { + lineVertArray = []; + for (j = 0; j < 4; j++) { + cachedVertArray = vertArray[i + j]; + for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[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 === 17) { + var tempArray = []; + if (vertArrayLength > 3) { + for (i = 0; i < 2; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < 2; i++) { + cachedVertArray = vertArray[i]; + for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) + } + line3D(lineVertArray, "LINE_STRIP", strokeVertArray); + if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { + tempArray = fillVertArray.splice(fillVertArray.length - 3); + vertArray.pop() + } + for (i = 0; i + 3 < vertArrayLength; 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 (vertArrayLength === 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 < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); + for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) + } + if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); + else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); + if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) + } + usingTexture = false; + curContext.useProgram(programObject3D); + uniformi("usingTexture3d", programObject3D, "uUsingTexture", usingTexture) + } + 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) + }; + Drawing2D.prototype.bezierVertex = function() { + isBezier = true; + var vert = []; + if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; + for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; + vertArray.push(vert); + vertArray[vertArray.length - 1]["isVert"] = false + }; + Drawing3D.prototype.bezierVertex = function() { + isBezier = true; + var vert = []; + if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; + if (arguments.length === 9) { + 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]) + } + }; + p.texture = function(pimage) { + var curContext = drawing.$ensureContext(); + if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); + else if (pimage.localName === "canvas") { + curContext.bindTexture(curContext.TEXTURE_2D, canTex); + curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, 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); + curTexture.width = pimage.width; + curTexture.height = pimage.height + } else { + var texture = curContext.createTexture(), + cvs = document.createElement("canvas"), + cvsTextureCtx = cvs.getContext("2d"), + 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 + } + cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); + curContext.bindTexture(curContext.TEXTURE_2D, 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); + curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); + curContext.generateMipmap(curContext.TEXTURE_2D); + pimage.__texture = texture; + curTexture.width = pimage.width; + curTexture.height = pimage.height + } + usingTexture = true; + curContext.useProgram(programObject3D); + uniformi("usingTexture3d", programObject3D, "uUsingTexture", 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) + } + }; + Drawing2D.prototype.curveVertex = function(x, y) { + isCurve = true; + p.vertex(x, y) + }; + Drawing3D.prototype.curveVertex = function(x, y, z) { + isCurve = true; + 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]) + }; + Drawing2D.prototype.curve = function(x1, y1, x2, y2, x3, y3, x4, y4) { + p.beginShape(); + p.curveVertex(x1, y1); + p.curveVertex(x2, y2); + p.curveVertex(x3, y3); + p.curveVertex(x4, y4); + p.endShape() + }; + Drawing3D.prototype.curve = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { + if (z4 !== undef) { + p.beginShape(); + p.curveVertex(x1, y1, z1); + p.curveVertex(x2, y2, z2); + p.curveVertex(x3, y3, z3); + p.curveVertex(x4, y4, z4); + p.endShape(); + return + } + p.beginShape(); + p.curveVertex(x1, y1); + p.curveVertex(z1, x2); + p.curveVertex(y2, z2); + p.curveVertex(x3, y3); + p.endShape() + }; + p.curveTightness = function(tightness) { + curTightness = tightness + }; + p.curveDetail = function(detail) { + curveDet = detail; + curveInit() + }; + p.rectMode = function(aRectMode) { + curRectMode = aRectMode + }; + p.imageMode = function(mode) { + switch (mode) { + case 0: + imageModeConvert = imageModeCorner; + break; + case 1: + imageModeConvert = imageModeCorners; + break; + case 3: + imageModeConvert = imageModeCenter; + break; + default: + throw "Invalid imageMode"; + } + }; + p.ellipseMode = function(aEllipseMode) { + curEllipseMode = aEllipseMode + }; + p.arc = function(x, y, width, height, start, stop) { + if (width <= 0 || stop < start) return; + if (curEllipseMode === 1) { + width = width - x; + height = height - y + } else if (curEllipseMode === 2) { + x = x - width; + y = y - height; + width = width * 2; + height = height * 2 + } else if (curEllipseMode === 3) { + x = x - width / 2; + y = y - height / 2 + } + while (start < 0) { + start += 6.283185307179586; + stop += 6.283185307179586 + } + if (stop - start > 6.283185307179586) { + start = 0; + stop = 6.283185307179586 + } + var hr = width / 2, + vr = height / 2, + centerX = x + hr, + centerY = y + vr, + startLUT = 0 | 0.5 + start * p.RAD_TO_DEG * 2, + stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2, + i, j; + if (doFill) { + var savedStroke = doStroke; + doStroke = false; + p.beginShape(); + p.vertex(centerX, centerY); + for (i = startLUT; i <= stopLUT; i++) { + j = i % 720; + p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) + } + p.endShape(2); + doStroke = savedStroke + } + if (doStroke) { + var savedFill = doFill; + doFill = false; + p.beginShape(); + for (i = startLUT; i <= stopLUT; i++) { + j = i % 720; + p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) + } + p.endShape(); + doFill = savedFill + } + }; + Drawing2D.prototype.line = function(x1, y1, x2, y2) { + if (!doStroke) return; + x1 = Math.round(x1); + x2 = Math.round(x2); + y1 = Math.round(y1); + y2 = Math.round(y2); + if (x1 === x2 && y1 === y2) { + p.point(x1, y1); + return + } + var swap = undef, + lineCap = undef, + drawCrisp = true, + currentModelView = modelView.array(), + identityMatrix = [1, 0, 0, 0, 1, 0]; + for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; + if (drawCrisp) { + if (x1 === x2) { + if (y1 > y2) { + swap = y1; + y1 = y2; + y2 = swap + } + y2++; + if (lineWidth % 2 === 1) curContext.translate(0.5, 0) + } else if (y1 === y2) { + if (x1 > x2) { + swap = x1; + x1 = x2; + x2 = swap + } + x2++; + if (lineWidth % 2 === 1) curContext.translate(0, 0.5) + } + if (lineWidth === 1) { + lineCap = curContext.lineCap; + curContext.lineCap = "butt" + } + } + curContext.beginPath(); + curContext.moveTo(x1 || 0, y1 || 0); + curContext.lineTo(x2 || 0, y2 || 0); + executeContextStroke(); + if (drawCrisp) { + if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); + else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); + if (lineWidth === 1) curContext.lineCap = lineCap + } + }; + Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { + if (y2 === undef || z2 === undef) { + z2 = 0; + y2 = x2; + x2 = z1; + z1 = 0 + } + if (x1 === x2 && y1 === y2 && z1 === z2) { + p.point(x1, y1, z1); + return + } + var lineVerts = [x1, y1, z1, x2, y2, z2]; + var view = new PMatrix3D; + view.scale(1, -1, 1); + view.apply(modelView.array()); + view.transpose(); + if (lineWidth > 0 && doStroke) { + curContext.useProgram(programObject2D); + uniformMatrix("uModel2d", programObject2D, "uModel", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); + uniformMatrix("uView2d", programObject2D, "uView", false, view.array()); + uniformf("uColor2d", programObject2D, "uColor", strokeStyle); + uniformi("uIsDrawingText", programObject2D, "uIsDrawingText", false); + vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, lineBuffer); + disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); + curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); + curContext.drawArrays(curContext.LINES, 0, 2) + } + }; + Drawing2D.prototype.bezier = function() { + if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; + p.beginShape(); + p.vertex(arguments[0], arguments[1]); + p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); + p.endShape() + }; + Drawing3D.prototype.bezier = function() { + if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; + 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() + }; + p.bezierDetail = function(detail) { + bezDetail = detail + }; + p.bezierPoint = function(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(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(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(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(x1, y1, x2, y2, x3, y3) { + p.beginShape(9); + p.vertex(x1, y1, 0); + p.vertex(x2, y2, 0); + p.vertex(x3, y3, 0); + p.endShape() + }; + p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { + p.beginShape(16); + p.vertex(x1, y1, 0); + p.vertex(x2, y2, 0); + p.vertex(x3, y3, 0); + p.vertex(x4, y4, 0); + p.endShape() + }; + var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { + if (bl === undef) { + tr = tl; + br = tl; + bl = tl + } + var halfWidth = width / 2, + halfHeight = height / 2; + if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); + if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); + if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); + if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); + if (!doFill || doStroke) curContext.translate(0.5, 0.5); + curContext.beginPath(); + curContext.moveTo(x + tl, y); + curContext.lineTo(x + width - tr, y); + curContext.quadraticCurveTo(x + width, y, x + width, y + tr); + curContext.lineTo(x + width, y + height - br); + curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); + curContext.lineTo(x + bl, y + height); + curContext.quadraticCurveTo(x, y + height, x, y + height - bl); + curContext.lineTo(x, y + tl); + curContext.quadraticCurveTo(x, y, x + tl, y); + if (!doFill || doStroke) curContext.translate(-0.5, -0.5); + executeContextFill(); + executeContextStroke() + }; + Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { + if (!width && !height) return; + if (curRectMode === 1) { + width -= x; + height -= y + } else if (curRectMode === 2) { + width *= 2; + height *= 2; + x -= width / 2; + y -= height / 2 + } else if (curRectMode === 3) { + x -= width / 2; + y -= height / 2 + } + x = Math.round(x); + y = Math.round(y); + width = Math.round(width); + height = Math.round(height); + if (tl !== undef) { + roundedRect$2d(x, y, width, height, tl, tr, br, bl); + return + } + if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); + curContext.beginPath(); + curContext.rect(x, y, width, height); + executeContextFill(); + executeContextStroke(); + if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) + }; + Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { + if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; + if (curRectMode === 1) { + width -= x; + height -= y + } else if (curRectMode === 2) { + width *= 2; + height *= 2; + x -= width / 2; + y -= height / 2 + } else if (curRectMode === 3) { + x -= width / 2; + y -= height / 2 + } + 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(); + if (lineWidth > 0 && doStroke) { + curContext.useProgram(programObject2D); + uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array()); + uniformMatrix("uView2d", programObject2D, "uView", false, view.array()); + uniformf("uColor2d", programObject2D, "uColor", strokeStyle); + uniformi("uIsDrawingText2d", programObject2D, "uIsDrawingText", false); + vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, rectBuffer); + disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); + curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) + } + if (doFill) { + curContext.useProgram(programObject3D); + uniformMatrix("uModel3d", programObject3D, "uModel", false, model.array()); + uniformMatrix("uView3d", programObject3D, "uView", false, view.array()); + curContext.enable(curContext.POLYGON_OFFSET_FILL); + curContext.polygonOffset(1, 1); + uniformf("color3d", programObject3D, "uColor", fillStyle); + if (lightCount > 0) { + 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("uNormalTransform3d", programObject3D, "uNormalTransform", false, normalMatrix.array()); + vertexAttribPointer("aNormal3d", programObject3D, "aNormal", 3, rectNormBuffer) + } else disableVertexAttribPointer("normal3d", programObject3D, "aNormal"); + vertexAttribPointer("vertex3d", programObject3D, "aVertex", 3, rectBuffer); + curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); + curContext.disable(curContext.POLYGON_OFFSET_FILL) + } + }; + Drawing2D.prototype.ellipse = function(x, y, width, height) { + x = x || 0; + y = y || 0; + if (width <= 0 && height <= 0) return; + if (curEllipseMode === 2) { + width *= 2; + height *= 2 + } else if (curEllipseMode === 1) { + width = width - x; + height = height - y; + x += width / 2; + y += height / 2 + } else if (curEllipseMode === 0) { + x += width / 2; + y += height / 2 + } + if (width === height) { + curContext.beginPath(); + curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); + executeContextFill(); + executeContextStroke() + } else { + var w = width / 2, + h = height / 2, + C = 0.5522847498307933, + c_x = C * w, + c_y = C * h; + 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() + } + }; + Drawing3D.prototype.ellipse = function(x, y, width, height) { + x = x || 0; + y = y || 0; + if (width <= 0 && height <= 0) return; + if (curEllipseMode === 2) { + width *= 2; + height *= 2 + } else if (curEllipseMode === 1) { + width = width - x; + height = height - y; + x += width / 2; + y += height / 2 + } else if (curEllipseMode === 0) { + x += width / 2; + y += height / 2 + } + var w = width / 2, + h = height / 2, + C = 0.5522847498307933, + c_x = C * w, + c_y = C * h; + 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(); + if (doFill) { + 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(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 === 0) normalMode = 1; + else if (normalMode === 1) normalMode = 2 + }; + p.save = function(file, img) { + if (img !== undef) return window.open(img.toDataURL(), "_blank"); + return window.open(p.externals.canvas.toDataURL(), "_blank") + }; + var saveNumber = 0; + p.saveFrame = function(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 + } + function buildPixelsObject(pImage) { + return { + getLength: function(aImg) { + return function() { + if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; + else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 + } + }(pImage), + getPixel: function(aImg) { + return function(i) { + var offset = i * 4, + data = aImg.imageData.data; + if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; + return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 + } + }(pImage), + setPixel: function(aImg) { + return function(i, c) { + var offset = i * 4, + data = aImg.imageData.data; + if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; + data[offset + 0] = (c >> 16) & 255; + data[offset + 1] = (c >> 8) & 255; + data[offset + 2] = c & 255; + data[offset + 3] = (c >> 24) & 255; + aImg.__isDirty = true + } + }(pImage), + toArray: function(aImg) { + return function() { + var arr = [], + data = aImg.imageData.data, + length = aImg.width * aImg.height; + if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; + for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); + return arr + } + }(pImage), + set: function(aImg) { + return function(arr) { + var offset, data, c; + if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; + data = aImg.imageData.data; + for (var i = 0, aL = arr.length; i < aL; i++) { + c = arr[i]; + offset = i * 4; + data[offset + 0] = (c >> 16) & 255; + data[offset + 1] = (c >> 8) & 255; + data[offset + 2] = c & 255; + data[offset + 3] = (c >> 24) & 255 + } + aImg.__isDirty = true + } + }(pImage) + } + } + var PImage = function(aWidth, aHeight, aFormat) { + this.__isDirty = false; + if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); + else if (aHeight || aFormat) { + this.width = aWidth || 1; + this.height = aHeight || 1; + var canvas = this.sourceImg = document.createElement("canvas"); + canvas.width = this.width; + canvas.height = this.height; + var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); + this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; + if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; + this.__isDirty = true; + this.updatePixels() + } else { + this.width = 0; + this.height = 0; + this.imageData = utilityContext2d.createImageData(1, 1); + this.format = 2 + } + this.pixels = buildPixelsObject(this) + }; + PImage.prototype = { + __isPImage: true, + updatePixels: function() { + var canvas = this.sourceImg; + if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); + this.__isDirty = false + }, + 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 + }, + "get": function(x, y, w, h) { + if (!arguments.length) return p.get(this); + if (arguments.length === 2) return p.get(x, y, this); + if (arguments.length === 4) return p.get(x, y, w, h, this) + }, + "set": function(x, y, c) { + p.set(x, y, c, this); + this.__isDirty = true + }, + 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 + }, + 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, 0, this); + else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); + delete this.sourceImg + }, + 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 + }, + save: function(file) { + p.save(file, this) + }, + resize: function(w, h) { + if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; + 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) + } + }, + mask: function(mask) { + var obj = this.toImageData(), + i, size; + if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { + mask = mask.toImageData(); + for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] + } else throw "mask must have the same dimensions as PImage."; + else if (mask instanceof + Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; + else throw "mask array must be the same length as PImage pixels array."; + this.fromImageData(obj) + }, + loadPixels: nop, + toImageData: function() { + if (this.isRemote) return this.sourceImg; + if (!this.__isDirty) return this.imageData; + var canvasData = getCanvasData(this.sourceImg); + return canvasData.context.getImageData(0, 0, this.width, this.height) + }, + toDataURL: function() { + if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; + var canvasData = getCanvasData(this.imageData); + return canvasData.canvas.toDataURL() + }, + fromImageData: function(canvasImg) { + var w = canvasImg.width, + h = canvasImg.height, + canvas = document.createElement("canvas"), + ctx = canvas.getContext("2d"); + this.width = canvas.width = w; + this.height = canvas.height = h; + ctx.putImageData(canvasImg, 0, 0); + this.format = 2; + this.imageData = canvasImg; + this.sourceImg = canvas + } + }; + p.PImage = PImage; + p.createImage = function(w, h, mode) { + return new PImage(w, h, mode) + }; + p.loadImage = function(file, type, callback) { + if (type) file = file + "." + type; + var pimg; + if (curSketch.imageCache.images[file]) { + pimg = new PImage(curSketch.imageCache.images[file]); + pimg.loaded = true; + return pimg + } + 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$2(x, y) { + var data; + if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; + if (isContextReplaced) { + var offset = ((0 | x) + p.width * (0 | y)) * 4; + data = p.imageData.data; + return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 + } + data = p.toImageData(0 | x, 0 | y, 1, 1).data; + return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 + } + function get$3(x, y, img) { + if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; + var offset = y * img.width * 4 + x * 4, + data = img.imageData.data; + return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 + } + function get$4(x, y, w, h) { + var c = new PImage(w, h, 2); + c.fromImageData(p.toImageData(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."; + var c = new PImage(w, h, 2), + 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++] + } + } + c.__isDirty = true; + return c + } + p.get = function(x, y, w, h, img) { + if (img !== undefined) return get$5(x, y, w, h, img); + if (h !== undefined) return get$4(x, y, w, h); + if (w !== undefined) return get$3(x, y, w); + if (y !== undefined) return get$2(x, y); + if (x !== undefined) return get$5(0, 0, x.width, x.height, x); + return get$4(0, 0, p.width, p.height) + }; + p.createGraphics = function(w, h, render) { + var pg = new Processing; + pg.size(w, h, render); + pg.background(0, 0); + 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."; + 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(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 || obj.__isPImage) 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, + data = p.imageData.data; + return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 + }, + setPixel: function(i, c) { + var offset = i * 4, + data = p.imageData.data; + data[offset + 0] = (c & 16711680) >>> 16; + data[offset + 1] = (c & 65280) >>> 8; + data[offset + 2] = c & 255; + data[offset + 3] = (c & 4278190080) >>> 24 + }, + toArray: function() { + var arr = [], + length = p.imageData.width * p.imageData.height, + data = p.imageData.data; + for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); + return arr + }, + set: function(arr) { + for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) + } + }; + p.loadPixels = function() { + p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) + }; + p.updatePixels = function() { + if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) + }; + p.hint = function(which) { + var curContext = drawing.$ensureContext(); + if (which === 4) { + curContext.disable(curContext.DEPTH_TEST); + curContext.depthMask(false); + curContext.clear(curContext.DEPTH_BUFFER_BIT) + } else if (which === -4) { + curContext.enable(curContext.DEPTH_TEST); + curContext.depthMask(true) + } else if (which === -1 || which === 2) renderSmooth = true; + else if (which === 1) renderSmooth = false + }; + var backgroundHelper = function(arg1, arg2, arg3, arg4) { + var obj; + if (arg1 instanceof PImage || arg1.__isPImage) { + obj = arg1; + if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; + if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; + } else obj = p.color(arg1, arg2, arg3, arg4); + backgroundObj = obj + }; + Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { + if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); + if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { + saveContext(); + curContext.setTransform(1, 0, 0, 1, 0, 0); + p.image(backgroundObj, 0, 0); + restoreContext() + } else { + saveContext(); + curContext.setTransform(1, 0, 0, 1, 0, 0); + if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); + curContext.fillStyle = p.color.toString(backgroundObj); + curContext.fillRect(0, 0, p.width, p.height); + isFillDirty = true; + restoreContext() + } + }; + Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { + if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); + var c = p.color.toGLArray(backgroundObj); + curContext.clearColor(c[0], c[1], c[2], c[3]); + curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) + }; + Drawing2D.prototype.image = function(img, x, y, w, h) { + x = Math.round(x); + y = Math.round(y); + if (img.width > 0) { + var wid = w || img.width; + var hgt = h || img.height; + var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); + var fastImage = !!img.sourceImg && curTint === null; + if (fastImage) { + var htmlElement = img.sourceImg; + if (img.__isDirty) img.updatePixels(); + curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) + } else { + var obj = img.toImageData(); + if (curTint !== null) { + curTint(obj); + img.__isDirty = true + } + curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) + } + } + }; + Drawing3D.prototype.image = function(img, x, y, w, h) { + if (img.width > 0) { + x = Math.round(x); + y = Math.round(y); + w = w || img.width; + h = h || img.height; + p.beginShape(p.QUADS); + p.texture(img); + p.vertex(x, y, 0, 0, 0); + p.vertex(x, y + h, 0, 0, h); + p.vertex(x + w, y + h, 0, w, h); + p.vertex(x + w, y, 0, w, 0); + p.endShape() + } + }; + p.tint = function(a1, a2, a3, a4) { + var tintColor = p.color(a1, a2, a3, a4); + 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 + } + }; + curTint3d = function(data) { + for (var i = 0; i < data.length;) { + data[i++] = r; + data[i++] = g; + data[i++] = b; + data[i++] = a + } + } + }; + p.noTint = function() { + curTint = null; + curTint3d = null + }; + p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { + if (dh === undef) { + 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, 0) + }; + p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { + if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; + if (mode === undef) { + mode = dh; + dh = dw; + dw = dy; + dy = dx; + dx = sh; + sh = sw; + sw = sy; + sy = sx; + sx = src; + src = p + } + var sx2 = sx + sw, + sy2 = sy + sh, + dx2 = dx + dw, + dy2 = dy + dh, + dest = pimgdest || p; + if (pimgdest === undef || mode === undef) p.loadPixels(); + src.loadPixels(); + if (src === p && 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); + if (pimgdest === undef) p.updatePixels() + }; + var buildBlurKernel = function(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 Float32Array(p.shared.blurKernelSize); + var sharedBlurKernal = p.shared.blurKernel; + var sharedBlurKernelSize = p.shared.blurKernelSize; + var sharedBlurRadius = p.shared.blurRadius; + for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; + var radiusiSquared = (radius - 1) * (radius - 1); + for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; + sharedBlurKernal[radius] = radius * radius + } + }; + var blurARGB = function(r, aImg) { + var sum, cr, cg, cb, ca, c, m; + var read, ri, ym, ymi, bk0; + var wh = aImg.pixels.getLength(); + var r2 = new Float32Array(wh); + var g2 = new Float32Array(wh); + var b2 = new Float32Array(wh); + var a2 = new Float32Array(wh); + var yi = 0; + var x, y, i, offset; + buildBlurKernel(r); + var aImgHeight = aImg.height; + var aImgWidth = aImg.width; + var sharedBlurKernelSize = p.shared.blurKernelSize; + var sharedBlurRadius = p.shared.blurRadius; + var sharedBlurKernal = p.shared.blurKernel; + var pix = aImg.imageData.data; + for (y = 0; y < aImgHeight; y++) { + for (x = 0; x < aImgWidth; x++) { + cb = cg = cr = ca = sum = 0; + read = x - sharedBlurRadius; + if (read < 0) { + bk0 = -read; + read = 0 + } else { + if (read >= aImgWidth) break; + bk0 = 0 + } + for (i = bk0; i < sharedBlurKernelSize; i++) { + if (read >= aImgWidth) break; + offset = (read + yi) * 4; + m = sharedBlurKernal[i]; + ca += m * pix[offset + 3]; + cr += m * pix[offset]; + cg += m * pix[offset + 1]; + cb += m * pix[offset + 2]; + sum += m; + read++ + } + ri = yi + x; + a2[ri] = ca / sum; + r2[ri] = cr / sum; + g2[ri] = cg / sum; + b2[ri] = cb / sum + } + yi += aImgWidth + } + yi = 0; + ym = -sharedBlurRadius; + ymi = ym * aImgWidth; + for (y = 0; y < aImgHeight; y++) { + for (x = 0; x < aImgWidth; x++) { + cb = cg = cr = ca = sum = 0; + if (ym < 0) { + bk0 = ri = -ym; + read = x + } else { + if (ym >= aImgHeight) break; + bk0 = 0; + ri = ym; + read = x + ymi + } + for (i = bk0; i < sharedBlurKernelSize; i++) { + if (ri >= aImgHeight) break; + m = sharedBlurKernal[i]; + ca += m * a2[read]; + cr += m * r2[read]; + cg += m * g2[read]; + cb += m * b2[read]; + sum += m; + ri++; + read += aImgWidth + } + offset = (x + yi) * 4; + pix[offset] = cr / sum; + pix[offset + 1] = cg / sum; + pix[offset + 2] = cb / sum; + pix[offset + 3] = ca / sum + } + yi += aImgWidth; + ymi += aImgWidth; + ym++ + } + }; + var dilate = function(isInverted, aImg) { + var currIdx = 0; + var maxIdx = aImg.pixels.getLength(); + var out = new Int32Array(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(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."; + var imglen = img.pixels.getLength(); + switch (kind) { + case 11: + var radius = param || 1; + blurARGB(radius, img); + break; + case 12: + if (img.format === 4) { + for (i = 0; i < imglen; i++) { + col = 255 - img.pixels.getPixel(i); + img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) + } + img.format = 1 + } 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 & 4278190080 | lum << 16 | lum << 8 | lum) + } + break; + case 13: + for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); + break; + case 15: + 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 14: + for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); + img.format = 1; + break; + case 16: + 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) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); + img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) + } + break; + case 17: + dilate(true, img); + break; + case 18: + 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(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) + }; + var blendFuncs = {}; + blendFuncs[1] = p.modes.blend; + blendFuncs[2] = p.modes.add; + blendFuncs[4] = p.modes.subtract; + blendFuncs[8] = p.modes.lightest; + blendFuncs[16] = p.modes.darkest; + blendFuncs[0] = p.modes.replace; + blendFuncs[32] = p.modes.difference; + blendFuncs[64] = p.modes.exclusion; + blendFuncs[128] = p.modes.multiply; + blendFuncs[256] = p.modes.screen; + blendFuncs[512] = p.modes.overlay; + blendFuncs[1024] = p.modes.hard_light; + blendFuncs[2048] = p.modes.soft_light; + blendFuncs[4096] = p.modes.dodge; + blendFuncs[8192] = p.modes.burn; + p.blit_resize = function(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; + 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 * 32768); + var dy = Math.floor(srcH / destH * 32768); + var pshared = p.shared; + pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); + pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); + 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; + pshared.srcBuffer = img.imageData.data; + pshared.iw = img.width; + pshared.iw1 = img.width - 1; + pshared.ih1 = img.height - 1; + var filterBilinear = p.filter_bilinear, + filterNewScanline = p.filter_new_scanline, + blendFunc = blendFuncs[mode], + blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, + RED_MASK = 16711680, + GREEN_MASK = 65280, + BLUE_MASK = 255, + PREC_MAXVAL = 32767, + PRECISIONB = 15, + PREC_RED_SHIFT = 1, + PREC_ALPHA_SHIFT = 9, + srcBuffer = pshared.srcBuffer, + min = Math.min; + for (y = 0; y < destH; y++) { + pshared.sX = pshared.srcXOffset; + pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; + pshared.ifV = PREC_MAXVAL - pshared.fracV; + pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; + pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; + for (x = 0; x < destW; x++) { + idx = (destOffset + x) * 4; + destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; + pshared.fracU = pshared.sX & PREC_MAXVAL; + pshared.ifU = PREC_MAXVAL - pshared.fracU; + pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; + pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; + pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; + pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; + pshared.u1 = pshared.sX >> PRECISIONB; + pshared.u2 = min(pshared.u1 + 1, pshared.iw1); + cULoffset = (pshared.v1 + pshared.u1) * 4; + cURoffset = (pshared.v1 + pshared.u2) * 4; + cLLoffset = (pshared.v2 + pshared.u1) * 4; + cLRoffset = (pshared.v2 + pshared.u2) * 4; + pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; + pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; + pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; + pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; + pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; + pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; + pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; + pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; + blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); + destPixels[idx] = (blendedColor & RED_MASK) >>> 16; + destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; + destPixels[idx + 2] = blendedColor & BLUE_MASK; + destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; + pshared.sX += dx + } + destOffset += screenW; + pshared.srcYOffset += dy + } + }; + p.loadFont = function(name, size) { + if (name === undef) throw "font name required in loadFont."; + if (name.indexOf(".svg") === -1) { + if (size === undef) size = curTextFont.size; + return PFont.get(name, size) + } + var font = p.loadGlyphs(name); + return { + name: name, + css: "12px sans-serif", + 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) { + return p.loadFont(name, size) + }; + p.textFont = function(pfont, size) { + if (size !== undef) { + if (!pfont.glyph) pfont = PFont.get(pfont.name, size); + curTextSize = size + } + curTextFont = pfont; + curFontName = curTextFont.name; + curTextAscent = curTextFont.ascent; + curTextDescent = curTextFont.descent; + curTextLeading = curTextFont.leading; + var curContext = drawing.$ensureContext(); + curContext.font = curTextFont.css + }; + p.textSize = function(size) { + curTextFont = PFont.get(curFontName, size); + curTextSize = size; + curTextAscent = curTextFont.ascent; + curTextDescent = curTextFont.descent; + curTextLeading = curTextFont.leading; + var curContext = drawing.$ensureContext(); + curContext.font = curTextFont.css + }; + p.textAscent = function() { + return curTextAscent + }; + p.textDescent = function() { + return curTextDescent + }; + p.textLeading = function(leading) { + curTextLeading = leading + }; + p.textAlign = function(xalign, yalign) { + horizontalTextAlignment = xalign; + verticalTextAlignment = yalign || 0 + }; + + function toP5String(obj) { + if (obj instanceof String) return obj; + if (typeof obj === "number") { + if (obj === (0 | obj)) return obj.toString(); + return p.nf(obj, 0, 3) + } + if (obj === null || obj === undef) return ""; + return obj.toString() + } + Drawing2D.prototype.textWidth = function(str) { + var lines = toP5String(str).split(/\r?\n/g), + width = 0; + var i, linesCount = lines.length; + curContext.font = curTextFont.css; + for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); + return width | 0 + }; + Drawing3D.prototype.textWidth = function(str) { + var lines = toP5String(str).split(/\r?\n/g), + width = 0; + var i, linesCount = lines.length; + if (textcanvas === undef) textcanvas = document.createElement("canvas"); + var textContext = textcanvas.getContext("2d"); + textContext.font = curTextFont.css; + for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); + return width | 0 + }; + p.glyphLook = function(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) + } + }; + Drawing2D.prototype.text$line = function(str, x, y, z, align) { + var textWidth = 0, + xOffset = 0; + if (!curTextFont.glyph) { + if (str && "fillText" in curContext) { + if (isFillDirty) { + curContext.fillStyle = p.color.toString(currentFillColor); + isFillDirty = false + } + if (align === 39 || align === 3) { + textWidth = curTextFont.measureTextWidth(str); + if (align === 39) xOffset = -textWidth; + else xOffset = -textWidth / 2 + } + curContext.fillText(str, x + xOffset, y) + } + } else { + var font = p.glyphTable[curFontName]; + saveContext(); + curContext.translate(x, y + curTextSize); + if (align === 39 || align === 3) { + textWidth = font.width(str); + if (align === 39) 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() + } + }; + Drawing3D.prototype.text$line = function(str, x, y, z, align) { + if (textcanvas === undef) textcanvas = document.createElement("canvas"); + var oldContext = curContext; + curContext = textcanvas.getContext("2d"); + curContext.font = curTextFont.css; + var textWidth = curTextFont.measureTextWidth(str); + textcanvas.width = textWidth; + textcanvas.height = curTextSize; + curContext = textcanvas.getContext("2d"); + curContext.font = curTextFont.css; + curContext.textBaseline = "top"; + Drawing2D.prototype.text$line(str, 0, 0, 0, 37); + var aspect = textcanvas.width / textcanvas.height; + curContext = oldContext; + curContext.bindTexture(curContext.TEXTURE_2D, textTex); + curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, 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 === 39) xOffset = -textWidth; + else if (align === 3) 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(); + curContext.useProgram(programObject2D); + vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, textBuffer); + vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); + uniformi("uSampler2d", programObject2D, "uSampler", [0]); + uniformi("uIsDrawingText2d", programObject2D, "uIsDrawingText", true); + uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array()); + uniformMatrix("uView2d", programObject2D, "uView", false, view.array()); + uniformf("uColor2d", programObject2D, "uColor", 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 lines, linesCount; + if (str.indexOf("\n") < 0) { + lines = [str]; + linesCount = 1 + } else { + lines = str.split(/\r?\n/g); + linesCount = lines.length + } + var yOffset = 0; + if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; + else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; + else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); + for (var i = 0; i < linesCount; ++i) { + var line = lines[i]; + drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); + yOffset += curTextLeading + } + } + function text$6(str, x, y, width, height, z) { + if (str.length === 0 || width === 0 || height === 0) return; + if (curTextSize > height) return; + var spaceMark = -1; + var start = 0; + var lineWidth = 0; + var drawCommands = []; + for (var charPos = 0, len = str.length; charPos < len; charPos++) { + var currentChar = str[charPos]; + var spaceChar = currentChar === " "; + var letterWidth = curTextFont.measureTextWidth(currentChar); + if (currentChar !== "\n" && lineWidth + letterWidth <= width) { + if (spaceChar) spaceMark = charPos; + lineWidth += letterWidth + } else { + if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; + else return; + if (currentChar === "\n") { + drawCommands.push({ + text: str.substring(start, charPos), + width: lineWidth + }); + start = charPos + 1 + } else { + drawCommands.push({ + text: str.substring(start, spaceMark + 1), + width: lineWidth + }); + start = spaceMark + 1 + } + lineWidth = 0; + charPos = start - 1 + } + } + if (start < len) drawCommands.push({ + text: str.substring(start), + width: lineWidth + }); + var xOffset = 1, + yOffset = curTextAscent; + if (horizontalTextAlignment === 3) xOffset = width / 2; + else if (horizontalTextAlignment === 39) xOffset = width; + var linesCount = drawCommands.length, + visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); + if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; + else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); + else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; + var command, drawCommand, leading; + for (command = 0; command < linesCount; command++) { + leading = command * curTextLeading; + if (yOffset + leading > height - curTextDescent) break; + drawCommand = drawCommands[command]; + drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) + } + } + p.text = function() { + if (textMode === 5) return; + 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(mode) { + textMode = mode + }; + p.loadGlyphs = function(url) { + var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", + path; + var regex = function(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(d) { + var c = regex("[A-Za-z][0-9\\- ]+|Z", d); + var beforePathDraw = function() { + saveContext(); + return drawing.$ensureContext() + }; + var afterPathDraw = function() { + executeContextFill(); + executeContextStroke(); + restoreContext() + }; + path = "return {draw:function(){var curContext=beforePathDraw();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 += "afterPathDraw();"; + path += "curContext.translate(" + horiz_adv_x + ",0);"; + path += "}}"; + return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) + }; + var parseSVGFont = function(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); + p.glyphTable[url][name] = { + name: name, + unicode: unicode, + horiz_adv_x: horiz_adv_x, + draw: path.draw + } + } + } + }; + var loadXML = function() { + 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] + }; + p.param = function(name) { + var attributeName = "data-processing-" + name; + if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); + for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { + var item = curElement.childNodes.item(i); + if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; + if (item.getAttribute("name") === name) return item.getAttribute("value") + } + if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; + return null + }; + + function wireDimensionalFunctions(mode) { + if (mode === "3D") drawing = new Drawing3D; + else if (mode === "2D") drawing = new Drawing2D; + else drawing = new DrawingPre; + for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; + drawing.$init() + } + function createDrawingPreFunction(name) { + return function() { + wireDimensionalFunctions("2D"); + return drawing[name].apply(this, arguments) + } + } + DrawingPre.prototype.translate = createDrawingPreFunction("translate"); + DrawingPre.prototype.transform = createDrawingPreFunction("transform"); + DrawingPre.prototype.scale = createDrawingPreFunction("scale"); + DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); + DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); + DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); + DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); + DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); + DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); + DrawingPre.prototype.shearX = createDrawingPreFunction("shearX"); + DrawingPre.prototype.shearY = createDrawingPreFunction("shearY"); + DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); + DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); + DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); + DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); + DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); + DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); + DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); + DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); + DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); + DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); + DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); + DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); + DrawingPre.prototype.box = createDrawingPreFunction("box"); + DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); + DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); + DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); + DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); + DrawingPre.prototype.specular = createDrawingPreFunction("specular"); + DrawingPre.prototype.fill = createDrawingPreFunction("fill"); + DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); + DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); + DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); + DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); + DrawingPre.prototype.point = createDrawingPreFunction("point"); + DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); + DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); + DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); + DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); + DrawingPre.prototype.curve = createDrawingPreFunction("curve"); + DrawingPre.prototype.line = createDrawingPreFunction("line"); + DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); + DrawingPre.prototype.rect = createDrawingPreFunction("rect"); + DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); + DrawingPre.prototype.background = createDrawingPreFunction("background"); + DrawingPre.prototype.image = createDrawingPreFunction("image"); + DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); + DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); + DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); + DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); + DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { + wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); + p.size(aWidth, aHeight, aMode) + }; + DrawingPre.prototype.$init = nop; + Drawing2D.prototype.$init = function() { + p.size(p.width, p.height); + curContext.lineCap = "round"; + p.noSmooth(); + p.disableContextMenu() + }; + Drawing3D.prototype.$init = function() { + p.use3DContext = true; + p.disableContextMenu() + }; + DrawingShared.prototype.$ensureContext = function() { + return curContext + }; + + function calculateOffset(curElement, event) { + 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; + offsetX += window.pageXOffset; + offsetY += window.pageYOffset; + return { + "X": offsetX, + "Y": offsetY + } + } + function updateMousePosition(curElement, event) { + var offset = calculateOffset(curElement, event); + p.mouseX = event.pageX - offset.X; + p.mouseY = event.pageY - offset.Y + } + function addTouchEventOffset(t) { + var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), + i; + for (i = 0; i < t.touches.length; i++) { + var touch = t.touches[i]; + touch.offsetX = touch.pageX - offset.X; + touch.offsetY = touch.pageY - offset.Y + } + for (i = 0; i < t.targetTouches.length; i++) { + var targetTouch = t.targetTouches[i]; + targetTouch.offsetX = targetTouch.pageX - offset.X; + targetTouch.offsetY = targetTouch.pageY - offset.Y + } + for (i = 0; i < t.changedTouches.length; i++) { + var changedTouch = t.changedTouches[i]; + changedTouch.offsetX = changedTouch.pageX - offset.X; + changedTouch.offsetY = changedTouch.pageY - offset.Y + } + return t + } + attachEventHandler(curElement, "touchstart", function(t) { + curElement.setAttribute("style", "-webkit-user-select: none"); + curElement.setAttribute("onclick", "void(0)"); + curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); + for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { + var type = eventHandlers[i].type; + if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) + } + if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { + attachEventHandler(curElement, "touchstart", function(t) { + if (p.touchStart !== undef) { + t = addTouchEventOffset(t); + p.touchStart(t) + } + }); + attachEventHandler(curElement, "touchmove", function(t) { + if (p.touchMove !== undef) { + t.preventDefault(); + t = addTouchEventOffset(t); + p.touchMove(t) + } + }); + attachEventHandler(curElement, "touchend", function(t) { + if (p.touchEnd !== undef) { + t = addTouchEventOffset(t); + p.touchEnd(t) + } + }); + attachEventHandler(curElement, "touchcancel", function(t) { + if (p.touchCancel !== undef) { + t = addTouchEventOffset(t); + p.touchCancel(t) + } + }) + } else { + attachEventHandler(curElement, "touchstart", function(e) { + updateMousePosition(curElement, e.touches[0]); + p.__mousePressed = true; + p.mouseDragging = false; + p.mouseButton = 37; + if (typeof p.mousePressed === "function") p.mousePressed() + }); + attachEventHandler(curElement, "touchmove", function(e) { + e.preventDefault(); + updateMousePosition(curElement, e.touches[0]); + if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); + if (typeof p.mouseDragged === "function" && p.__mousePressed) { + p.mouseDragged(); + p.mouseDragging = true + } + }); + attachEventHandler(curElement, "touchend", function(e) { + p.__mousePressed = false; + if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); + if (typeof p.mouseReleased === "function") p.mouseReleased() + }) + } + curElement.dispatchEvent(t) + }); + (function() { + var enabled = true, + contextMenu = function(e) { + e.preventDefault(); + e.stopPropagation() + }; + p.disableContextMenu = function() { + if (!enabled) return; + attachEventHandler(curElement, "contextmenu", contextMenu); + enabled = false + }; + p.enableContextMenu = function() { + if (enabled) return; + detachEventHandler({ + elem: curElement, + type: "contextmenu", + fn: contextMenu + }); + enabled = true + } + })(); + attachEventHandler(curElement, "mousemove", function(e) { + updateMousePosition(curElement, e); + if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); + if (typeof p.mouseDragged === "function" && p.__mousePressed) { + p.mouseDragged(); + p.mouseDragging = true + } + }); + attachEventHandler(curElement, "mouseout", function(e) { + if (typeof p.mouseOut === "function") p.mouseOut() + }); + attachEventHandler(curElement, "mouseover", function(e) { + updateMousePosition(curElement, e); + if (typeof p.mouseOver === "function") p.mouseOver() + }); + curElement.onmousedown = function() { + curElement.focus(); + return false + }; + attachEventHandler(curElement, "mousedown", function(e) { + p.__mousePressed = true; + p.mouseDragging = false; + switch (e.which) { + case 1: + p.mouseButton = 37; + break; + case 2: + p.mouseButton = 3; + break; + case 3: + p.mouseButton = 39; + break + } + if (typeof p.mousePressed === "function") p.mousePressed() + }); + attachEventHandler(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() + }; + attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); + attachEventHandler(document, "mousewheel", mouseWheelHandler); + if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); + + function getKeyCode(e) { + var code = e.which || e.keyCode; + switch (code) { + case 13: + return 10; + case 91: + case 93: + case 224: + return 157; + case 57392: + return 17; + case 46: + return 127; + case 45: + return 155 + } + return code + } + function getKeyChar(e) { + var c = e.which || e.keyCode; + var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; + switch (c) { + case 13: + c = anyShiftPressed ? 13 : 10; + break; + case 8: + c = anyShiftPressed ? 127 : 8; + break + } + return new Char(c) + } + function suppressKeyEvent(e) { + if (typeof e.preventDefault === "function") e.preventDefault(); + else if (typeof e.stopPropagation === "function") e.stopPropagation(); + return false + } + function updateKeyPressed() { + var ch; + for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { + p.__keyPressed = true; + return + } + p.__keyPressed = false + } + function resetKeyPressed() { + p.__keyPressed = false; + pressedKeysMap = []; + lastPressedKeyCode = null + } + function simulateKeyTyped(code, c) { + pressedKeysMap[code] = c; + lastPressedKeyCode = null; + p.key = c; + p.keyCode = code; + p.keyPressed(); + p.keyCode = 0; + p.keyTyped(); + updateKeyPressed() + } + function handleKeydown(e) { + var code = getKeyCode(e); + if (code === 127) { + simulateKeyTyped(code, new Char(127)); + return + } + if (codedKeys.indexOf(code) < 0) { + lastPressedKeyCode = code; + return + } + var c = new Char(65535); + p.key = c; + p.keyCode = code; + pressedKeysMap[code] = c; + p.keyPressed(); + lastPressedKeyCode = null; + updateKeyPressed(); + return suppressKeyEvent(e) + } + function handleKeypress(e) { + if (lastPressedKeyCode === null) return; + var code = lastPressedKeyCode, + c = getKeyChar(e); + simulateKeyTyped(code, c); + return suppressKeyEvent(e) + } + function handleKeyup(e) { + var code = getKeyCode(e), + c = pressedKeysMap[code]; + if (c === undef) return; + p.key = c; + p.keyCode = code; + p.keyReleased(); + delete pressedKeysMap[code]; + updateKeyPressed() + } + if (!pgraphicsMode) { + if (aCode instanceof Processing.Sketch) curSketch = aCode; + else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); + else if (!aCode) curSketch = new Processing.Sketch(function() {}); + else curSketch = Processing.compile(aCode); + p.externals.sketch = curSketch; + wireDimensionalFunctions(); + curElement.onfocus = function() { + p.focused = true + }; + curElement.onblur = function() { + p.focused = false; + if (!curSketch.options.globalKeyEvents) resetKeyPressed() + }; + if (curSketch.options.pauseOnBlur) { + attachEventHandler(window, "focus", function() { + if (doLoop) p.loop() + }); + attachEventHandler(window, "blur", function() { + if (doLoop && loopStarted) { + p.noLoop(); + doLoop = true + } + resetKeyPressed() + }) + } + var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; + attachEventHandler(keyTrigger, "keydown", handleKeydown); + attachEventHandler(keyTrigger, "keypress", handleKeypress); + attachEventHandler(keyTrigger, "keyup", handleKeyup); + 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 retryInterval = 100; + var executeSketch = function(processing) { + if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { + if (window.opera) { + var link, element, operaCache = curSketch.imageCache.operaCache; + for (link in operaCache) if (operaCache.hasOwnProperty(link)) { + element = operaCache[link]; + if (element !== null) document.body.removeChild(element); + delete operaCache[link] + } + } + curSketch.attach(processing, defaultScope); + curSketch.onLoad(processing); + if (processing.setup) { + processing.setup(); + processing.resetMatrix(); + curSketch.onSetup() + } + resetContext(); + if (processing.draw) if (!doLoop) processing.redraw(); + else processing.loop() + } else window.setTimeout(function() { + executeSketch(processing) + }, + retryInterval) + }; + addInstance(this); + executeSketch(p) + } else { + curSketch = new Processing.Sketch; + wireDimensionalFunctions(); + p.size = function(w, h, render) { + if (render && render === 2) wireDimensionalFunctions("3D"); + else wireDimensionalFunctions("2D"); + p.size(w, h, render) + } + } + }; + Processing.debug = debug; + 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", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", + "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", + "loadImage", "loadPixels", "loadShape", "loadXML", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", + "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "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", "shearX", "shearY", "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", "toImageData", + "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "transform", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "XML", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith", "__matches"]; + 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; + 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 + "'" + } + if (regexCtx) { + index = strings.length; + strings.push(regex); + return prefix + "'" + index + "'" + } + return comment !== "" ? " " : "\n" + }); + codeWoStrings = codeWoStrings.replace(/__x([0-9A-F]{4})/g, function(all, hexCode) { + return "__x005F_x" + hexCode + }); + codeWoStrings = codeWoStrings.replace(/\$/g, "__x0024"); + var genericsWereRemoved; + var codeWoGenerics = codeWoStrings; + var replaceFunc = function(all, before, types, after) { + if ( !! before || !!after) return all; + genericsWereRemoved = true; + return "" + }; + do { + genericsWereRemoved = false; + codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\[\])*(?:\s+(?:extends|super)\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+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) + } while (genericsWereRemoved); + var atoms = splitToAtoms(codeWoGenerics); + 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, transformInterfaceBody, 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)*(?:\s*,\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; + return addAtom(all, "G") + }); + return result + } + function AstParam(name) { + this.name = name + } + AstParam.prototype.toString = function() { + return this.name + }; + + function AstParams(params, methodArgsParam) { + this.params = params; + this.methodArgsParam = methodArgsParam + } + 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.prependMethodArgs = function(body) { + if (!this.methodArgsParam) return body; + return "{\nvar " + this.methodArgsParam.name + " = Array.prototype.slice.call(arguments, " + this.params.length + ");\n" + body.substring(1) + }; + 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 = [], + methodArgsParam = null; + 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]*")*\s*$/.exec(paramList[i]); + if (i === paramList.length - 1 && paramList[i].indexOf("...") >= 0) { + methodArgsParam = new AstParam(param[1]); + break + } + result.push(new AstParam(param[1])) + } + } + return new AstParams(result, methodArgsParam) + } + 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; + if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; + 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(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { + return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' + }); + s = s.replace(/\bpixels\b\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"); + return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") + } + if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); + if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); + return "pixels.toArray" + addAtom("()", "B") + }); + var repeatJavaReplacement; + + function replacePrototypeMethods(all, subject, method, atomIndex) { + var atom = atoms[atomIndex]; + repeatJavaReplacement = true; + var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); + return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) + } + do { + repeatJavaReplacement = false; + s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt|matches)\s*"B(\d+)"/g, replacePrototypeMethods) + } while (repeatJavaReplacement); + + function replaceInstanceof(all, subject, type) { + repeatJavaReplacement = true; + return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") + } + do { + repeatJavaReplacement = false; + s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) + } while (repeatJavaReplacement); + 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 (" + this.body + ")" + }; + + function transformInlineClass(class_) { + var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); + var oldClassId = currentClassId, + newClassId = generateClassId(); + currentClassId = newClassId; + var uniqueClassName = m[1] + "$" + newClassId; + var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + 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; + var body = this.params.prependMethodArgs(this.body.toString()); + result += this.params + " " + 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); + if (expr.charAt(0) === "{") { + if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; + return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" + } + 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$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { + if (memberAccessSign) return all; + 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"; + if (type === "boolean") return "false"; + if (type === "color") return "0x00000000"; + 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]) + } + 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 AstForEachExpression(initStatement, container) { + this.initStatement = initStatement; + this.container = container + } + AstForEachExpression.iteratorId = 0; + AstForEachExpression.prototype.toString = function() { + var init = this.initStatement.toString(); + var iterator = "$it" + AstForEachExpression.iteratorId++; + var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; + var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; + var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; + return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" + }; + + 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])) + } + if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { + content = expr.substring(1, expr.length - 1).split(":"); + return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) + } + content = expr.substring(1, expr.length - 1).split(";"); + return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) + } + + function sortByWeight(array) { + array.sort(function(a, b) { + return b.weight - a.weight + }) + } + function AstInnerInterface(name, body, isStatic) { + this.name = name; + this.body = body; + this.isStatic = isStatic; + body.owner = this + } + AstInnerInterface.prototype.toString = function() { + return "" + this.body + }; + + function AstInnerClass(name, body, isStatic) { + this.name = name; + this.body = body; + this.isStatic = isStatic; + body.owner = this + } + AstInnerClass.prototype.toString = function() { + return "" + this.body + }; + + function transformInnerClass(class_) { + var m = classesRegex.exec(class_); + classesRegex.lastIndex = 0; + var isStatic = m[1].indexOf("static") >= 0; + var body = atoms[getAtomIndex(m[6])], + innerClass; + var oldClassId = currentClassId, + newClassId = generateClassId(); + currentClassId = newClassId; + if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); + else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); + appendClass(innerClass, newClassId, oldClassId); + currentClassId = oldClassId; + return innerClass + } + function AstClassMethod(name, params, body, isStatic) { + this.name = name; + this.params = params; + this.body = body; + this.isStatic = isStatic + } + AstClassMethod.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 body = this.params.prependMethodArgs(this.body.toString()); + var result = "function " + this.methodId + this.params + " " + body + "\n"; + replaceContext = oldContext; + return result + }; + + function transformClassMethod(method) { + var m = methodsRegex.exec(method); + methodsRegex.lastIndex = 0; + var isStatic = m[1].indexOf("static") >= 0; + var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; + return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) + } + 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("") + } + 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.params.prependMethodArgs(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 AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { + var i, l; + this.name = name; + this.interfacesNames = interfacesNames; + this.methodsNames = methodsNames; + this.fields = fields; + this.innerClasses = innerClasses; + this.misc = misc; + for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this + } + AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { + if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); + var i, j, l, m; + for (i = 0, l = this.fields.length; i < l; ++i) { + var fieldNames = this.fields[i].getNames(); + for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] + } + for (i = 0, l = this.methodsNames.length; i < l; ++i) { + var methodName = this.methodsNames[i]; + classMethods[methodName] = true + } + for (i = 0, l = this.innerClasses.length; i < l; ++i) { + var innerClass = this.innerClasses[i]; + classInners[innerClass.name] = innerClass + } + }; + AstInterfaceBody.prototype.toString = function() { + function getScopeLevel(p) { + var i = 0; + while (p) { + ++i; + p = p.scope + } + return i + } + var scopeLevel = getScopeLevel(this.owner); + var className = this.name; + var staticDefinitions = ""; + var metadata = ""; + var thisClassFields = {}, + thisClassMethods = {}, + thisClassInners = {}; + this.getMembers(thisClassFields, thisClassMethods, thisClassInners); + var i, l, j, m; + if (this.owner.interfaces) { + var resolvedInterfaces = [], + resolvedInterface; + for (i = 0, l = this.interfacesNames.length; i < l; ++i) { + if (!this.owner.interfaces[i]) continue; + resolvedInterface = replaceContext({ + name: this.interfacesNames[i] + }); + resolvedInterfaces.push(resolvedInterface); + staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" + } + metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" + } + metadata += className + ".$isInterface = true;\n"; + metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; + sortByWeight(this.innerClasses); + for (i = 0, l = this.innerClasses.length; i < l; ++i) { + var innerClass = this.innerClasses[i]; + if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" + } + for (i = 0, l = this.fields.length; i < l; ++i) { + var field = this.fields[i]; + if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" + } + return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" + }; + transformInterfaceBody = function(body, name, baseInterfaces) { + var declarations = body.substring(1, body.length - 1); + declarations = extractClassesAndMethods(declarations); + declarations = extractConstructors(declarations, name); + var methodsNames = [], + classes = []; + declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { + if (type === "D") methodsNames.push(index); + else if (type === "E") classes.push(index); + return "" + }); + var fields = declarations.split(/;(?:\s*;)*/g); + var baseInterfaceNames; + var i, l; + if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); + for (i = 0, l = methodsNames.length; i < l; ++i) { + var method = transformClassMethod(atoms[methodsNames[i]]); + methodsNames[i] = method.name + } + for (i = 0, l = fields.length - 1; i < l; ++i) { + var field = trimSpaces(fields[i]); + fields[i] = transformClassField(field.middle) + } + var tail = fields.pop(); + for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); + return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { + tail: tail + }) + }; + + function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { + var i, l; + this.name = name; + this.baseClassName = baseClassName; + this.interfacesNames = interfacesNames; + 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(classFields, classMethods, classInners) { + if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); + var i, j, l, m; + for (i = 0, l = this.fields.length; i < l; ++i) { + var fieldNames = this.fields[i].getNames(); + for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] + } + for (i = 0, l = this.methods.length; i < l; ++i) { + var method = this.methods[i]; + classMethods[method.name] = method + } + for (i = 0, l = this.innerClasses.length; i < l; ++i) { + var innerClass = this.innerClasses[i]; + classInners[innerClass.name] = innerClass + } + }; + 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 className = this.name; + var result = "var " + selfId + " = this;\n"; + var staticDefinitions = ""; + var metadata = ""; + var thisClassFields = {}, + thisClassMethods = {}, + thisClassInners = {}; + this.getMembers(thisClassFields, thisClassMethods, thisClassInners); + var oldContext = replaceContext; + replaceContext = function(subject) { + var name = subject.name; + if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; + if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; + if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; + if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; + return oldContext(subject) + }; + var resolvedBaseClassName; + if (this.baseClassName) { + resolvedBaseClassName = oldContext({ + name: this.baseClassName + }); + result += "var $super = { $upcast: " + selfId + " };\n"; + result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; + metadata += className + ".$base = " + resolvedBaseClassName + ";\n" + } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; + if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; + var i, l, j, m; + if (this.owner.interfaces) { + var resolvedInterfaces = [], + resolvedInterface; + for (i = 0, l = this.interfacesNames.length; i < l; ++i) { + if (!this.owner.interfaces[i]) continue; + resolvedInterface = oldContext({ + name: this.interfacesNames[i] + }); + resolvedInterfaces.push(resolvedInterface); + staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" + } + metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" + } + if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; + sortByWeight(this.innerClasses); + for (i = 0, l = this.innerClasses.length; i < l; ++i) { + var innerClass = this.innerClasses[i]; + if (innerClass.isStatic) { + staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; + result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" + } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" + } + for (i = 0, l = this.fields.length; i < l; ++i) { + var field = this.fields[i]; + if (field.isStatic) { + staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; + for (j = 0, m = field.definitions.length; j < m; ++j) { + var fieldName = field.definitions[j].name, + staticName = className + "." + fieldName; + result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" + } + } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" + } + var methodOverloads = {}; + for (i = 0, l = this.methods.length; i < l; ++i) { + var method = this.methods[i]; + var overload = methodOverloads[method.name]; + var methodId = method.name + "$" + method.params.params.length; + var hasMethodArgs = !!method.params.methodArgsParam; + if (overload) { + ++overload; + methodId += "_" + overload + } else overload = 1; + method.methodId = methodId; + methodOverloads[method.name] = overload; + if (method.isStatic) { + staticDefinitions += method; + staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ", " + hasMethodArgs + ");\n"; + result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ", " + hasMethodArgs + ");\n" + } else { + result += method; + result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ", " + hasMethodArgs + ");\n" + } + } + result += trim(this.misc.tail); + if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; + result += "function $constr() {\n"; + var cstrsIfs = []; + for (i = 0, l = this.cstrs.length; i < l; ++i) { + var paramsLength = this.cstrs[i].params.params.length; + var methodArgsPresent = !!this.cstrs[i].params.methodArgsParam; + cstrsIfs.push("if(arguments.length " + (methodArgsPresent ? ">=" : "===") + " " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") + } + if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; + result += "$superCstr();\n}\n"; + result += "$constr.apply(null, arguments);\n"; + replaceContext = oldContext; + return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" + }; + transformClassBody = function(body, name, baseName, interfaces) { + 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.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); + var baseClassName, interfacesNames; + var i; + if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); + if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); + 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, interfacesNames, functions, methods, fields, cstrs, classes, { + tail: tail + }) + }; + + function AstInterface(name, body) { + this.name = name; + this.body = body; + body.owner = this + } + AstInterface.prototype.toString = function() { + return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" + }; + + function AstClass(name, body) { + this.name = name; + this.body = body; + body.owner = this + } + AstClass.prototype.toString = function() { + return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" + }; + + function transformGlobalClass(class_) { + var m = classesRegex.exec(class_); + classesRegex.lastIndex = 0; + var body = atoms[getAtomIndex(m[6])]; + var oldClassId = currentClassId, + newClassId = generateClassId(); + currentClassId = newClassId; + var globalClass; + if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); + else 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 body = this.params.prependMethodArgs(this.body.toString()); + var result = "function " + this.name + this.params + " " + 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 AstSwitchCase(expr) { + this.expr = expr + } + AstSwitchCase.prototype.toString = function() { + return "case " + this.expr + ":" + }; + + 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+([^:]+):|\b([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) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); + else if (m[8] !== undef) { + space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].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 classes = [], + otherStatements = [], + statement; + for (var i = 0, len = this.statements.length; i < len; ++i) { + statement = this.statements[i]; + if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); + else otherStatements.push(statement) + } + sortByWeight(classes); + var localNames = getLocalNames(this.statements); + replaceContext = function(subject) { + var name = subject.name; + if (localNames.hasOwnProperty(name)) return name; + 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" + classes.join("") + "\n" + otherStatements.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) { + var parent = findInScopes(class_, baseClassName); + if (parent) { + class_.base = parent; + if (!parent.derived) parent.derived = []; + parent.derived.push(class_) + } + } + var interfacesNames = class_.body.interfacesNames, + interfaces = [], + i, l; + if (interfacesNames && interfacesNames.length > 0) { + for (i = 0, l = interfacesNames.length; i < l; ++i) { + var interface_ = findInScopes(class_, interfacesNames[i]); + interfaces.push(interface_); + if (!interface_) continue; + if (!interface_.derived) interface_.derived = []; + interface_.derived.push(class_) + } + if (interfaces.length > 0) class_.interfaces = interfaces + } + } + } + function setWeight(ast) { + var queue = [], + tocheck = {}; + var id, scopeId, class_; + for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { + class_ = declaredClasses[id]; + if (!class_.inScope && !class_.derived) { + queue.push(id); + class_.weight = 0 + } else { + var dependsOn = []; + if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); + if (class_.derived) dependsOn = dependsOn.concat(class_.derived); + tocheck[id] = dependsOn + } + } + function removeDependentAndCheck(targetId, from) { + var dependsOn = tocheck[targetId]; + if (!dependsOn) return false; + var i = dependsOn.indexOf(from); + if (i < 0) return false; + dependsOn.splice(i, 1); + if (dependsOn.length > 0) return false; + delete tocheck[targetId]; + return true + } + while (queue.length > 0) { + id = queue.shift(); + class_ = declaredClasses[id]; + if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { + queue.push(class_.scopeId); + declaredClasses[class_.scopeId].weight = class_.weight + 1 + } + if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { + queue.push(class_.base.classId); + class_.base.weight = class_.weight + 1 + } + if (class_.interfaces) { + var i, l; + for (i = 0, l = class_.interfaces.length; i < l; ++i) { + if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; + queue.push(class_.interfaces[i].classId); + class_.interfaces[i].weight = class_.weight + 1 + } + } + } + } + var transformed = transformMain(); + generateMetadata(transformed); + setWeight(transformed); + var redendered = transformed.toString(); + redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); + redendered = redendered.replace(/__x([0-9A-F]{4})/g, function(all, hexCode) { + return String.fromCharCode(parseInt(hexCode, 16)) + }); + 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 === "font") { + list = value.split(","); + for (var x = 0, xl = list.length; x < xl; x++) { + var fontName = clean(list[x]), + index = /^\{(\d*?)\}$/.exec(fontName); + PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) + } + } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; + else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; + else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; + else sketch.options[key] = value + } + } + } + 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 + }; + 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: 1E4, + 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); + updateSafetyMargin() + } + })(); + else if (typeof print === func) tinylogLite[log] = print; + return tinylogLite + }(); + Processing.logger = tinylogLite; + Processing.version = "1.4.1"; + Processing.lib = {}; + Processing.registerLibrary = function(name, desc) { + Processing.lib[name] = desc; + if (desc.hasOwnProperty("init")) desc.init(defaultScope) + }; + Processing.instances = processingInstances; + Processing.getInstanceById = function(name) { + return processingInstances[processingInstanceIds[name]] + }; + Processing.Sketch = function(attachFunction) { + this.attachFunction = attachFunction; + this.options = { + pauseOnBlur: false, + globalKeyEvents: false + }; + this.onLoad = nop; + this.onSetup = nop; + this.onPause = nop; + this.onLoop = nop; + this.onFrameStart = nop; + this.onFrameEnd = nop; + this.onExit = nop; + this.params = {}; + this.imageCache = { + pending: 0, + images: {}, + operaCache: {}, + add: function(href, img) { + if (this.images[href]) return; + if (!isDOMPresent) this.images[href] = null; + if (!img) { + img = new Image; + img.onload = function(owner) { + return function() { + owner.pending-- + } + }(this); + this.pending++; + img.src = href + } + this.images[href] = img; + if (window.opera) { + var div = document.createElement("div"); + div.appendChild(img); + div.style.position = "absolute"; + div.style.opacity = 0; + div.style.width = "1px"; + div.style.height = "1px"; + if (!this.operaCache[href]) { + document.body.appendChild(div); + this.operaCache[href] = div + } + } + } + }; + this.sourceCode = undefined; + this.attach = function(processing) { + if (typeof this.attachFunction === "function") this.attachFunction(processing); + else if (this.sourceCode) { + var func = (new Function("return (" + this.sourceCode + ");"))(); + func(processing); + this.attachFunction = func + } else throw "Unable to attach sketch to the processing instance"; + }; + this.toString = function() { + var i; + var code = "((function(Sketch) {\n"; + code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; + for (i in this.options) if (this.options.hasOwnProperty(i)) { + var value = this.options[i]; + code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" + } + for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; + code += "return sketch;\n})(Processing.Sketch))"; + return code + } + }; + var loadSketchFromSources = function(canvas, sources) { + var code = [], + errors = [], + sourcesCount = sources.length, + loaded = 0; + + function ajaxAsync(url, callback) { + var xhr = new XMLHttpRequest; + xhr.onreadystatechange = function() { + if (xhr.readyState === 4) { + var error; + if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; + else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; + else error = "File is empty."; + callback(xhr.responseText, error) + } + }; + xhr.open("GET", url, true); + if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); + xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); + xhr.send(null) + } + function loadBlock(index, filename) { + function callback(block, error) { + code[index] = block; + ++loaded; + if (error) errors.push(filename + " ==> " + error); + if (loaded === sourcesCount) if (errors.length === 0) try { + return new Processing(canvas, code.join("\n")) + } catch(e) { + throw "Processing.js: Unable to execute pjs sketch: " + e; + } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); + } + if (filename.charAt(0) === "#") { + var scriptElement = document.getElementById(filename.substring(1)); + if (scriptElement) callback(scriptElement.text || scriptElement.textContent); + else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); + return + } + ajaxAsync(filename, callback) + } + for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) + }; + var init = function() { + document.removeEventListener("DOMContentLoaded", init, false); + processingInstances = []; + var canvas = document.getElementsByTagName("canvas"), + filenames; + 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) { + filenames = processingSources.split(/\s+/g); + for (var j = 0; j < filenames.length;) if (filenames[j]) j++; + else filenames.splice(j, 1); + loadSketchFromSources(canvas[i], filenames) + } + } + var s, last, source, instance, nodelist = document.getElementsByTagName("script"), + scripts = []; + for (s = nodelist.length - 1; s >= 0; s--) scripts.push(nodelist[s]); + for (s = 0, last = scripts.length; s < last; s++) { + var script = scripts[s]; + if (!script.getAttribute) continue; + var type = script.getAttribute("type"); + if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { + var target = script.getAttribute("data-processing-target"); + canvas = undef; + if (target) canvas = document.getElementById(target); + else { + var nextSibling = script.nextSibling; + while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; + if (nextSibling && nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling + } + if (canvas) { + if (script.getAttribute("src")) { + filenames = script.getAttribute("src").split(/\s+/); + loadSketchFromSources(canvas, filenames); + continue + } + source = script.textContent || script.text; + instance = new Processing(canvas, source) + } + } + } + }; + Processing.reload = function() { + if (processingInstances.length > 0) for (var i = processingInstances.length - 1; i >= 0; i--) if (processingInstances[i]) processingInstances[i].exit(); + init() + }; + Processing.loadSketchFromSources = loadSketchFromSources; + Processing.disableInit = function() { + if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) + }; + if (isDOMPresent) { + window["Processing"] = Processing; + document.addEventListener("DOMContentLoaded", init, false) + } else this.Processing = Processing +})(window, window.document, Math); + diff --git a/examples/week6/processingjspost/tmp/always_restart.txt b/examples/week6/processingjspost/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/week6/processingjspost/views/form.erb b/examples/week6/processingjspost/views/form.erb new file mode 100644 index 0000000..c65d96b --- /dev/null +++ b/examples/week6/processingjspost/views/form.erb @@ -0,0 +1,34 @@ + + + + Simple Form Example + + + + +

    Simple form

    +

    This is a simple form example.

    +
    +

    +

    +
    + + + diff --git a/examples/week6/processingjspost/views/processing.erb b/examples/week6/processingjspost/views/processing.erb new file mode 100644 index 0000000..2e247fc --- /dev/null +++ b/examples/week6/processingjspost/views/processing.erb @@ -0,0 +1,79 @@ + + + + postExample : Built with Processing and Processing.js + + + + + + + + + + + + +
    +
    + +

    Your browser does not support the canvas tag.

    + +
    + +
    +

    postExample

    +

    +

    Source code: postExample

    +

    + Built with Processing + and Processing.js +

    +
    + + diff --git a/examples/week6/sqltest/.htaccess b/examples/week6/sqltest/.htaccess new file mode 100644 index 0000000..4b69aca --- /dev/null +++ b/examples/week6/sqltest/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/sqltest +RackEnv development diff --git a/examples/week6/sqltest/app.rb b/examples/week6/sqltest/app.rb new file mode 100644 index 0000000..3bb6ea8 --- /dev/null +++ b/examples/week6/sqltest/app.rb @@ -0,0 +1,42 @@ +require 'sinatra' +require 'dm-core' +require 'dm-migrations' + +DataMapper.setup(:default, { + :adapter => 'mysql', + :host => 'localhost', + :username => 'zr279' , + :password => '', + :database => 'zr279'}) + +class Test + include DataMapper::Resource + + property :id, Serial # An auto-increment integer key + property :name, String # A varchar type string, for short strings +end + +# Automatically create the tables if they don't exist +DataMapper.auto_upgrade! +# Finish setup +DataMapper.finalize + +# Main route - this is the form is shown +get '/' do + erb :form +end + +post '/data' do + + p = Test.new + p.name = params[:name] + + + #If any of the validations are not met, p.save will be false + if p.save + redirect to("http://itp.nyu.edu/~zr279/sinatra/sqltest") + else + "You missed something!" + end + +end \ No newline at end of file diff --git a/examples/week6/sqltest/config.ru b/examples/week6/sqltest/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/week6/sqltest/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/week6/sqltest/tmp/always_restart.txt b/examples/week6/sqltest/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/week6/sqltest/views/form.erb b/examples/week6/sqltest/views/form.erb new file mode 100644 index 0000000..a05cf73 --- /dev/null +++ b/examples/week6/sqltest/views/form.erb @@ -0,0 +1,35 @@ + + + + Simple Form Example + + + + +

    Simple form

    +

    This is a simple form example.

    +
    +

    + Birthday (date and time): +

    +
    + + + From ccc0aa07b054fa08e0d99f58c8555c35167daf34 Mon Sep 17 00:00:00 2001 From: zeven Date: Thu, 7 Mar 2013 17:41:34 -0500 Subject: [PATCH 52/57] Update README.md --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index b105e58..78e39e9 100644 --- a/README.md +++ b/README.md @@ -457,6 +457,18 @@ What do you want to do? What is preventing you from doing it? * [Processing POST Sinatra App](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week6/processingExamples) +###ProcessingJS +* [ProcessingJS POST](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week6/processingjspost) + +###JSON +* [JSON Example](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week6/jsonexample) + +###MYSQL +* [MYSQL Example](https://github.com/zevenwolf/CommLabWeb/tree/master/examples/week6/sqltest) + + + + ### Ruby Calling your site with a Ruby script on your machine From 96642abdf877471219a695a74f418e1a8e0ea70a Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Thu, 7 Mar 2013 18:31:23 -0500 Subject: [PATCH 53/57] sqlupdate --- examples/week6/sqltest/app.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/week6/sqltest/app.rb b/examples/week6/sqltest/app.rb index 3bb6ea8..e411529 100644 --- a/examples/week6/sqltest/app.rb +++ b/examples/week6/sqltest/app.rb @@ -5,9 +5,9 @@ DataMapper.setup(:default, { :adapter => 'mysql', :host => 'localhost', - :username => 'zr279' , - :password => '', - :database => 'zr279'}) + :username => 'netid' , + :password => 'Enteryour password here from sqlpw', + :database => 'netid'}) class Test include DataMapper::Resource From e8dcd2edd426a3a5d6c35bd1b1b7dcdb34dadf54 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Mon, 11 Mar 2013 22:24:38 -0400 Subject: [PATCH 54/57] multiparams --- examples/week2/multiparams/.htaccess | 4 ++ examples/week2/multiparams/app.rb | 12 ++++++ examples/week2/multiparams/config.ru | 9 +++++ .../week2/multiparams/tmp/always_restart.txt | 0 examples/week2/multiparams/views/form.erb | 37 +++++++++++++++++++ 5 files changed, 62 insertions(+) create mode 100644 examples/week2/multiparams/.htaccess create mode 100644 examples/week2/multiparams/app.rb create mode 100644 examples/week2/multiparams/config.ru create mode 100644 examples/week2/multiparams/tmp/always_restart.txt create mode 100644 examples/week2/multiparams/views/form.erb diff --git a/examples/week2/multiparams/.htaccess b/examples/week2/multiparams/.htaccess new file mode 100644 index 0000000..7f54019 --- /dev/null +++ b/examples/week2/multiparams/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/multiparams +RackEnv development diff --git a/examples/week2/multiparams/app.rb b/examples/week2/multiparams/app.rb new file mode 100644 index 0000000..0a6a0a4 --- /dev/null +++ b/examples/week2/multiparams/app.rb @@ -0,0 +1,12 @@ +require 'sinatra' + +# Main route - this is the form is shown +get '/' do + erb :form +end + +# Second route - this is the form is posted to +post '/multiparams' do + allnames = params[:names] + "Hello " + allnames['name'] + " " + allnames['name1'] + " " + allnames['name2'] + " " + allnames['name3'] +end diff --git a/examples/week2/multiparams/config.ru b/examples/week2/multiparams/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/week2/multiparams/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/week2/multiparams/tmp/always_restart.txt b/examples/week2/multiparams/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/week2/multiparams/views/form.erb b/examples/week2/multiparams/views/form.erb new file mode 100644 index 0000000..dc79904 --- /dev/null +++ b/examples/week2/multiparams/views/form.erb @@ -0,0 +1,37 @@ + + + + Simple Form Example + + + + +

    Simple form

    +

    This is a simple form example.

    +
    +

    +

    +

    +

    +

    +
    + + + From b20b81313270931bf34b2f98799670f76a8a1156 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Mon, 11 Mar 2013 22:52:12 -0400 Subject: [PATCH 55/57] loop --- examples/week2/multiparams/app.rb | 4 ++-- examples/week2/multiparams/views/form.erb | 2 +- examples/week2/multiparams/views/multiparams.erb | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 examples/week2/multiparams/views/multiparams.erb diff --git a/examples/week2/multiparams/app.rb b/examples/week2/multiparams/app.rb index 0a6a0a4..746b285 100644 --- a/examples/week2/multiparams/app.rb +++ b/examples/week2/multiparams/app.rb @@ -7,6 +7,6 @@ # Second route - this is the form is posted to post '/multiparams' do - allnames = params[:names] - "Hello " + allnames['name'] + " " + allnames['name1'] + " " + allnames['name2'] + " " + allnames['name3'] + @allnames = params[:names] + erb :multiparams end diff --git a/examples/week2/multiparams/views/form.erb b/examples/week2/multiparams/views/form.erb index dc79904..45aa57c 100644 --- a/examples/week2/multiparams/views/form.erb +++ b/examples/week2/multiparams/views/form.erb @@ -26,7 +26,7 @@

    Simple form

    This is a simple form example.

    -

    +

    diff --git a/examples/week2/multiparams/views/multiparams.erb b/examples/week2/multiparams/views/multiparams.erb new file mode 100644 index 0000000..98d20c7 --- /dev/null +++ b/examples/week2/multiparams/views/multiparams.erb @@ -0,0 +1,3 @@ +<%@allnames.each do |key, value|%> + <%=key%> = <%=value%> +<%end%> \ No newline at end of file From e8c65f8806e70d6e2a608503b699c5823eede484 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Mon, 11 Mar 2013 23:32:54 -0400 Subject: [PATCH 56/57] processingjswithsinatra --- .../week6/processingjswithsinatra/.htaccess | 4 + examples/week6/processingjswithsinatra/app.rb | 10 + .../week6/processingjswithsinatra/config.ru | 9 + .../public/js/postExample.pde | 27 + .../public/js/processing.js | 10203 ++++++++++++++++ .../tmp/always_restart.txt | 0 .../processingjswithsinatra/views/form.erb | 34 + .../views/processing.erb | 82 + 8 files changed, 10369 insertions(+) create mode 100644 examples/week6/processingjswithsinatra/.htaccess create mode 100644 examples/week6/processingjswithsinatra/app.rb create mode 100644 examples/week6/processingjswithsinatra/config.ru create mode 100644 examples/week6/processingjswithsinatra/public/js/postExample.pde create mode 100644 examples/week6/processingjswithsinatra/public/js/processing.js create mode 100644 examples/week6/processingjswithsinatra/tmp/always_restart.txt create mode 100644 examples/week6/processingjswithsinatra/views/form.erb create mode 100644 examples/week6/processingjswithsinatra/views/processing.erb diff --git a/examples/week6/processingjswithsinatra/.htaccess b/examples/week6/processingjswithsinatra/.htaccess new file mode 100644 index 0000000..8bd74d4 --- /dev/null +++ b/examples/week6/processingjswithsinatra/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/processingjswithsinatra +RackEnv development diff --git a/examples/week6/processingjswithsinatra/app.rb b/examples/week6/processingjswithsinatra/app.rb new file mode 100644 index 0000000..d28398c --- /dev/null +++ b/examples/week6/processingjswithsinatra/app.rb @@ -0,0 +1,10 @@ +require 'sinatra' +require 'dm-core' + + +get '/' do + @color1 = "255" + @color2 = "255" + erb :processing +end + diff --git a/examples/week6/processingjswithsinatra/config.ru b/examples/week6/processingjswithsinatra/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/week6/processingjswithsinatra/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/week6/processingjswithsinatra/public/js/postExample.pde b/examples/week6/processingjswithsinatra/public/js/postExample.pde new file mode 100644 index 0000000..8759300 --- /dev/null +++ b/examples/week6/processingjswithsinatra/public/js/postExample.pde @@ -0,0 +1,27 @@ +boolean pressed = false; +void setup(){ + + +} + + +void draw(){ + + + if(pressed == true){ + background(color1,0,0); + }else{ + background(0,color2,0); + } + +} + +void mousePressed(){ + if(pressed == false){ + pressed = true; + }else{ + pressed = false; + } + +} + diff --git a/examples/week6/processingjswithsinatra/public/js/processing.js b/examples/week6/processingjswithsinatra/public/js/processing.js new file mode 100644 index 0000000..d9b41d7 --- /dev/null +++ b/examples/week6/processingjswithsinatra/public/js/processing.js @@ -0,0 +1,10203 @@ +/*** + + P R O C E S S I N G . J S - 1.4.1 + a port of the Processing visualization language + + Processing.js is licensed under the MIT License, see LICENSE. + For a list of copyright holders, please refer to AUTHORS. + + http://processingjs.org + +***/ + +(function(window, document, Math, undef) { + var nop = function() {}; + var debug = function() { + if ("console" in window) return function(msg) { + window.console.log("Processing.js: " + msg) + }; + return nop + }(); + var ajax = function(url) { + var xhr = new XMLHttpRequest; + xhr.open("GET", url, false); + if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain"); + 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 + }; + var isDOMPresent = "document" in this && !("fake" in this.document); + document.head = document.head || document.getElementsByTagName("head")[0]; + + function setupTypedArray(name, fallback) { + if (name in window) return window[name]; + if (typeof window[fallback] === "function") return window[fallback]; + return function(obj) { + if (obj instanceof Array) return obj; + if (typeof obj === "number") { + var arr = []; + arr.length = obj; + return arr + } + } + } + if (document.documentMode >= 9 && !document.doctype) throw "The doctype directive is missing. The recommended doctype in Internet Explorer is the HTML5 doctype: "; + var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"), + Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"), + Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"), + Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray"); + 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: 1.0E-4, + MAX_FLOAT: 3.4028235E38, + MIN_FLOAT: -3.4028235E38, + 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\u000c\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, + 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, + META: 157, + INSERT: 155, + 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: 720, + 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 virtHashCode(obj) { + if (typeof obj === "string") { + var hash = 0; + for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295; + return hash + } + if (typeof obj !== "object") return obj & 4294967295; + if (obj.hashCode instanceof Function) return obj.hashCode(); + 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; + if (typeof obj === "string") return obj === other; + if (typeof obj !== "object") return obj === other; + if (obj.equals instanceof Function) return obj.equals(other); + return obj === other + } + var ObjectIterator = function(obj) { + if (obj.iterator instanceof + Function) return obj.iterator(); + if (obj instanceof Array) { + var index = -1; + this.hasNext = function() { + return ++index < obj.length + }; + this.next = function() { + return obj[index] + } + } else throw "Unable to iterate: " + obj; + }; + 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(a) { + var array; + if (a instanceof ArrayList) array = a.toArray(); + else { + array = []; + if (typeof a === "number") array.length = a > 0 ? a : 0 + } + this.get = function(i) { + return array[i] + }; + this.contains = function(item) { + return this.indexOf(item) > -1 + }; + this.indexOf = function(item) { + for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i; + return -1 + }; + this.lastIndexOf = function(item) { + for (var i = array.length - 1; i >= 0; --i) if (virtEquals(item, array[i])) return i; + return -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.addAll = function(arg1, arg2) { + var it; + if (typeof arg1 === "number") { + if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length; + it = new ObjectIterator(arg2); + while (it.hasNext()) array.splice(arg1++, 0, it.next()) + } else { + it = new ObjectIterator(arg1); + while (it.hasNext()) array.push(it.next()) + } + }; + 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(item) { + if (typeof item === "number") return array.splice(item, 1)[0]; + item = this.indexOf(item); + if (item > -1) { + array.splice(item, 1); + return true + } + return false + }; + this.removeAll = function(c) { + var i, x, item, newList = new ArrayList; + newList.addAll(this); + this.clear(); + for (i = 0, x = 0; i < newList.size(); i++) { + item = newList.get(i); + if (!c.contains(item)) this.add(x++, item) + } + if (this.size() < newList.size()) return true; + return false + }; + this.isEmpty = function() { + return !array.length + }; + this.clone = function() { + return new ArrayList(this) + }; + this.toArray = function() { + return array.slice(0) + }; + this.iterator = function() { + return new Iterator(array) + } + } + return ArrayList + }(); + var HashMap = function() { + function HashMap() { + if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone(); + var initialCapacity = arguments.length > 0 ? arguments[0] : 16; + var loadFactor = arguments.length > 1 ? arguments[1] : 0.75; + var buckets = []; + buckets.length = initialCapacity; + var count = 0; + var hashMap = this; + + function getBucketIndex(key) { + var index = virtHashCode(key) % buckets.length; + return index < 0 ? buckets.length + index : index + } + 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]); + var newBucketsLength = buckets.length * 2; + buckets = []; + buckets.length = newBucketsLength; + for (var j = 0; j < allEntries.length; ++j) { + var index = getBucketIndex(allEntries[j].key); + 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; + var currentItem; + + 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() { + currentItem = conversion(buckets[bucketIndex][itemIndex]); + findNext(); + return currentItem + }; + this.remove = function() { + if (currentItem !== undef) { + removeItem(currentItem); + --itemIndex; + findNext() + } + }; + 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 = []; + 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 = []; + buckets.length = initialCapacity + }; + this.clone = function() { + var map = new HashMap; + map.putAll(this); + return map + }; + this.containsKey = function(key) { + var index = getBucketIndex(key); + 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 instanceof Entry && pair._isIn(hashMap) + }, + + + function(pair) { + return hashMap.remove(pair.getKey()) + }) + }; + this.get = function(key) { + var index = getBucketIndex(key); + 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.values = function() { + return new Set(function(pair) { + return pair.value + }, + + + function(value) { + return hashMap.containsValue(value) + }, + + function(value) { + return hashMap.removeByValue(value) + }) + }; + this.put = function(key, value) { + var index = getBucketIndex(key); + 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 = getBucketIndex(key); + 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.removeByValue = function(value) { + var bucket, i, ilen, pair; + for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) { + pair = buckets[bucket][i]; + if (pair.value === value) { + buckets[bucket].splice(i, 1); + return true + } + } + return false + }; + this.size = function() { + return count + } + } + return HashMap + }(); + var PVector = function() { + function PVector(x, y, z) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0 + } + PVector.dist = function(v1, v2) { + return v1.dist(v2) + }; + PVector.dot = function(v1, v2) { + return v1.dot(v2) + }; + PVector.cross = function(v1, v2) { + return v1.cross(v2) + }; + 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] || 0, v.y || v[1] || 0, v.z || v[2] || 0); + else { + this.x = v; + this.y = y; + this.z = z + } + }, + get: function() { + return new PVector(this.x, this.y, this.z) + }, + mag: function() { + var x = this.x, + y = this.y, + z = this.z; + return Math.sqrt(x * x + y * y + z * z) + }, + add: function(v, y, z) { + if (arguments.length === 1) { + this.x += v.x; + this.y += v.y; + this.z += v.z + } else { + this.x += v; + this.y += y; + this.z += z + } + }, + sub: function(v, y, z) { + if (arguments.length === 1) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z + } else { + this.x -= v; + this.y -= y; + this.z -= z + } + }, + mult: function(v) { + if (typeof v === "number") { + this.x *= v; + this.y *= v; + this.z *= v + } else { + 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 { + 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 === 1) return this.x * v.x + this.y * v.y + this.z * v.z; + return this.x * v + this.y * y + this.z * z + }, + cross: function(v) { + var x = this.x, + y = this.y, + z = this.z; + return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * 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] + } + }; + + function createPVectorMethod(method) { + return function(v1, v2) { + var v = v1.get(); + v[method](v2); + return v + } + } + for (var 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; + defaultScope.ObjectIterator = ObjectIterator; + defaultScope.PConstants = PConstants; + defaultScope.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) + } + }; + + function overloadBaseClassFunction(object, name, basefn) { + if (!object.hasOwnProperty(name) || typeof object[name] !== "function") { + object[name] = basefn; + return + } + var fn = object[name]; + if ("$overloads" in fn) { + fn.$defaultOverload = basefn; + return + } + if (! ("$overloads" in basefn) && fn.length === basefn.length) return; + var overloads, defaultOverload; + if ("$overloads" in basefn) { + overloads = basefn.$overloads.slice(0); + overloads[fn.length] = fn; + defaultOverload = basefn.$defaultOverload + } else { + overloads = []; + overloads[basefn.length] = basefn; + overloads[fn.length] = fn; + defaultOverload = fn + } + var hubfn = function() { + var fn = hubfn.$overloads[arguments.length] || ("$methodArgsIndex" in hubfn && arguments.length > hubfn.$methodArgsIndex ? hubfn.$overloads[hubfn.$methodArgsIndex] : null) || hubfn.$defaultOverload; + return fn.apply(this, arguments) + }; + hubfn.$overloads = overloads; + if ("$methodArgsIndex" in basefn) hubfn.$methodArgsIndex = basefn.$methodArgsIndex; + hubfn.$defaultOverload = defaultOverload; + hubfn.name = name; + object[name] = hubfn + } + function extendClass(subClass, baseClass) { + function extendGetterSetter(propertyName) { + defaultScope.defineProperty(subClass, propertyName, { + get: function() { + return baseClass[propertyName] + }, + set: function(v) { + baseClass[propertyName] = v + }, + enumerable: true + }) + } + var properties = []; + for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") overloadBaseClassFunction(subClass, propertyName, baseClass[propertyName]); + else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName); + while (properties.length > 0) extendGetterSetter(properties.shift()); + subClass.$super = baseClass + } + defaultScope.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 + }; + defaultScope.extendStaticMembers = function(derived, base) { + extendClass(derived, base) + }; + defaultScope.extendInterfaceMembers = function(derived, base) { + extendClass(derived, base) + }; + defaultScope.addMethod = function(object, name, fn, hasMethodArgs) { + var existingfn = object[name]; + if (existingfn || hasMethodArgs) { + var args = fn.length; + if ("$overloads" in existingfn) existingfn.$overloads[args] = fn; + else { + var hubfn = function() { + var fn = hubfn.$overloads[arguments.length] || ("$methodArgsIndex" in hubfn && arguments.length > hubfn.$methodArgsIndex ? hubfn.$overloads[hubfn.$methodArgsIndex] : null) || hubfn.$defaultOverload; + return fn.apply(this, arguments) + }; + var overloads = []; + if (existingfn) overloads[existingfn.length] = existingfn; + overloads[args] = fn; + hubfn.$overloads = overloads; + hubfn.$defaultOverload = existingfn || fn; + if (hasMethodArgs) hubfn.$methodArgsIndex = args; + hubfn.name = name; + object[name] = hubfn + } + } else object[name] = fn + }; + + function isNumericalJavaType(type) { + if (typeof type !== "string") return false; + return ["byte", "int", "char", "color", "float", "long", "double"].indexOf(type) !== -1 + } + defaultScope.createJavaArray = function(type, bounds) { + var result = null, + defaultValue = null; + if (typeof type === "string") if (type === "boolean") defaultValue = false; + else if (isNumericalJavaType(type)) defaultValue = 0; + if (typeof bounds[0] === "number") { + var itemsCount = 0 | bounds[0]; + if (bounds.length <= 1) { + result = []; + result.length = itemsCount; + for (var i = 0; i < itemsCount; ++i) result[i] = defaultValue + } else { + result = []; + var newBounds = bounds.slice(1); + for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds)) + } + } + return result + }; + 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" + }; + (function(Processing) { + var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "), + count = unsupportedP5.length, + prettyName, p5Name; + + function createUnsupportedFunc(n) { + return function() { + throw "Processing.js does not support " + n + "."; + } + } + while (count--) { + prettyName = unsupportedP5[count]; + p5Name = prettyName.replace("()", ""); + Processing[p5Name] = createUnsupportedFunc(prettyName) + } + })(defaultScope); + defaultScope.defineProperty(defaultScope, "screenWidth", { + get: function() { + return window.innerWidth + } + }); + defaultScope.defineProperty(defaultScope, "screenHeight", { + get: function() { + return window.innerHeight + } + }); + defaultScope.defineProperty(defaultScope, "online", { + get: function() { + return true + } + }); + var processingInstances = []; + var processingInstanceIds = {}; + var removeInstance = function(id) { + processingInstances.splice(processingInstanceIds[id], 1); + delete processingInstanceIds[id] + }; + var addInstance = function(processing) { + if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length; + processingInstanceIds[processing.externals.canvas.id] = processingInstances.length; + processingInstances.push(processing) + }; + + function computeFontMetrics(pfont) { + var emQuad = 250, + correctionFactor = pfont.size / emQuad, + canvas = document.createElement("canvas"); + canvas.width = 2 * emQuad; + canvas.height = 2 * emQuad; + canvas.style.opacity = 0; + var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"), + ctx = canvas.getContext("2d"); + ctx.font = cfmFont; + var protrusions = "dbflkhyjqpg"; + canvas.width = ctx.measureText(protrusions).width; + ctx.font = cfmFont; + var leadDiv = document.createElement("div"); + leadDiv.style.position = "absolute"; + leadDiv.style.opacity = 0; + leadDiv.style.fontFamily = '"' + pfont.name + '"'; + leadDiv.style.fontSize = emQuad + "px"; + leadDiv.innerHTML = protrusions + "
    " + protrusions; + document.body.appendChild(leadDiv); + var w = canvas.width, + h = canvas.height, + baseline = h / 2; + ctx.fillStyle = "white"; + ctx.fillRect(0, 0, w, h); + ctx.fillStyle = "black"; + ctx.fillText(protrusions, 0, baseline); + var pixelData = ctx.getImageData(0, 0, w, h).data; + var i = 0, + w4 = w * 4, + len = pixelData.length; + while (++i < len && pixelData[i] === 255) nop(); + var ascent = Math.round(i / w4); + i = len - 1; + while (--i > 0 && pixelData[i] === 255) nop(); + var descent = Math.round(i / w4); + pfont.ascent = correctionFactor * (baseline - ascent); + pfont.descent = correctionFactor * (descent - baseline); + if (document.defaultView.getComputedStyle) { + var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height"); + leadDivHeight = correctionFactor * leadDivHeight.replace("px", ""); + if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2) + } + document.body.removeChild(leadDiv); + if (pfont.caching) return ctx + } + function PFont(name, size) { + if (name === undef) name = ""; + this.name = name; + if (size === undef) size = 0; + this.size = size; + this.glyph = false; + this.ascent = 0; + this.descent = 0; + this.leading = 1.2 * size; + var illegalIndicator = name.indexOf(" Italic Bold"); + if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator); + this.style = "normal"; + var italicsIndicator = name.indexOf(" Italic"); + if (italicsIndicator !== -1) { + name = name.substring(0, italicsIndicator); + this.style = "italic" + } + this.weight = "normal"; + var boldIndicator = name.indexOf(" Bold"); + if (boldIndicator !== -1) { + name = name.substring(0, boldIndicator); + this.weight = "bold" + } + this.family = "sans-serif"; + if (name !== undef) switch (name) { + case "sans-serif": + case "serif": + case "monospace": + case "fantasy": + case "cursive": + this.family = name; + break; + default: + this.family = '"' + name + '", sans-serif'; + break + } + this.context2d = computeFontMetrics(this); + this.css = this.getCSSDefinition(); + if (this.context2d) this.context2d.font = this.css + } + PFont.prototype.caching = true; + PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) { + if (fontSize === undef) fontSize = this.size + "px"; + if (lineHeight === undef) lineHeight = this.leading + "px"; + var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family]; + return components.join(" ") + }; + PFont.prototype.measureTextWidth = function(string) { + return this.context2d.measureText(string).width + }; + PFont.prototype.measureTextWidthFallback = function(string) { + var canvas = document.createElement("canvas"), + ctx = canvas.getContext("2d"); + ctx.font = this.css; + return ctx.measureText(string).width + }; + PFont.PFontCache = { + length: 0 + }; + PFont.get = function(fontName, fontSize) { + fontSize = (fontSize * 10 + 0.5 | 0) / 10; + var cache = PFont.PFontCache, + idx = fontName + "/" + fontSize; + if (!cache[idx]) { + cache[idx] = new PFont(fontName, fontSize); + cache.length++; + if (cache.length === 50) { + PFont.prototype.measureTextWidth = PFont.prototype.measureTextWidthFallback; + PFont.prototype.caching = false; + var entry; + for (entry in cache) if (entry !== "length") cache[entry].context2d = null; + return new PFont(fontName, fontSize) + } + if (cache.length === 400) { + PFont.PFontCache = {}; + PFont.get = PFont.getFallback; + return new PFont(fontName, fontSize) + } + } + return cache[idx] + }; + PFont.getFallback = function(fontName, fontSize) { + return new PFont(fontName, fontSize) + }; + PFont.list = function() { + return ["sans-serif", "serif", "monospace", "fantasy", "cursive"] + }; + PFont.preloading = { + template: {}, + initialized: false, + initialize: function() { + var generateTinyFont = function() { + var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#"; + var expand = function(input) { + return "AAAAAAAA".substr(~~input ? 7 - input : 6) + }; + return encoded.replace(/[#237]/g, expand) + }; + var fontface = document.createElement("style"); + fontface.setAttribute("type", "text/css"); + fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}"; + document.head.appendChild(fontface); + var element = document.createElement("span"); + element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;'; + element.innerHTML = "AAAAAAAA"; + document.body.appendChild(element); + this.template = element; + this.initialized = true + }, + getElementWidth: function(element) { + return document.defaultView.getComputedStyle(element, "").getPropertyValue("width") + }, + timeAttempted: 0, + pending: function(intervallength) { + if (!this.initialized) this.initialize(); + var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template); + for (var i = 0; i < this.fontList.length; i++) { + element = this.fontList[i]; + computedWidthFont = this.getElementWidth(element); + if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) { + this.timeAttempted += intervallength; + return true + } else { + document.body.removeChild(element); + this.fontList.splice(i--, 1); + this.timeAttempted = 0 + } + } + if (this.fontList.length === 0) return false; + return true + }, + fontList: [], + addedList: {}, + add: function(fontSrc) { + if (!this.initialized) this.initialize(); + var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc, + fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc; + if (this.addedList[fontName]) return; + var style = document.createElement("style"); + style.setAttribute("type", "text/css"); + style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n"; + document.head.appendChild(style); + this.addedList[fontName] = true; + var element = document.createElement("span"); + element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;"; + element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy'; + element.innerHTML = "AAAAAAAA"; + document.body.appendChild(element); + this.fontList.push(element) + } + }; + defaultScope.PFont = PFont; + var Processing = this.Processing = function(aCanvas, aCode) { + if (! (this instanceof + Processing)) throw "called Processing constructor as if it were a function: missing 'new'."; + var curElement, pgraphicsMode = aCanvas === undef && aCode === undef; + if (pgraphicsMode) curElement = document.createElement("canvas"); + else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas; + if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id."; + + function unimplemented(s) { + Processing.debug("Unimplemented - " + s) + } + var p = this; + p.externals = { + canvas: curElement, + context: undef, + sketch: undef + }; + p.name = "Processing.js Instance"; + p.use3DContext = false; + p.focused = false; + 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.mouseOver = undef; + p.mouseOut = undef; + p.touchStart = undef; + p.touchEnd = undef; + p.touchMove = undef; + p.touchCancel = undef; + p.key = undef; + p.keyCode = undef; + p.keyPressed = nop; + p.keyReleased = nop; + p.keyTyped = nop; + p.draw = undef; + p.setup = undef; + p.__mousePressed = false; + p.__keyPressed = false; + p.__frameRate = 60; + p.frameCount = 0; + p.width = 100; + p.height = 100; + var curContext, curSketch, drawing, online = true, + doFill = true, + fillStyle = [1, 1, 1, 1], + currentFillColor = 4294967295, + isFillDirty = true, + doStroke = true, + strokeStyle = [0, 0, 0, 1], + currentStrokeColor = 4278190080, + isStrokeDirty = true, + lineWidth = 1, + loopStarted = false, + renderSmooth = false, + doLoop = true, + looping = 0, + curRectMode = 0, + curEllipseMode = 3, + normalX = 0, + normalY = 0, + normalZ = 0, + normalMode = 0, + curFrameRate = 60, + curMsPerFrame = 1E3 / curFrameRate, + curCursor = 'default', + oldCursor = curElement.style.cursor, + curShape = 20, + curShapeCount = 0, + curvePoints = [], + curTightness = 0, + curveDet = 20, + curveInited = false, + backgroundObj = -3355444, + bezDetail = 20, + colorModeA = 255, + colorModeX = 255, + colorModeY = 255, + colorModeZ = 255, + pathOpen = false, + mouseDragging = false, + pmouseXLastFrame = 0, + pmouseYLastFrame = 0, + curColorMode = 1, + curTint = null, + curTint3d = null, + getLoaded = false, + start = Date.now(), + timeSinceLastFPS = start, + framesSinceLastFPS = 0, + textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, 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 = 2, + usingTexture = false, + textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37, + verticalTextAlignment = 0, + textMode = 4, + curFontName = "Arial", + curTextSize = 12, + curTextAscent = 9, + curTextDescent = 2, + curTextLeading = 14, + curTextFont = PFont.get(curFontName, curTextSize), + originalContext, proxyContext = null, + isContextReplaced = false, + setPixelsCached, maxPixelsCached = 1E3, + pressedKeysMap = [], + lastPressedKeyCode = null, + codedKeys = [16, + 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157]; + 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 Float32Array(720), + cosLUT = new Float32Array(720), + sphereVerts, sphereNorms; + var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false, + frustumMode = false, + cameraFOV = 60 * (Math.PI / 180), + cameraX = p.width / 2, + cameraY = p.height / 2, + cameraZ = cameraY / Math.tan(cameraFOV / 2), + cameraNear = cameraZ / 10, + cameraFar = cameraZ * 10, + cameraAspect = p.width / p.height; + var vertArray = [], + curveVertArray = [], + curveVertCount = 0, + isCurve = false, + isBezier = false, + firstVert = true; + var curShapeMode = 0; + var styleArray = []; + 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 vertexShaderSrcUnlitShape = "varying vec4 vFrontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float uPointSize;" + "void main(void) {" + " vFrontColor = aColor;" + " gl_PointSize = uPointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}"; + var fragmentShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 vFrontColor;" + "uniform bool uSmooth;" + "void main(void){" + " if(uSmooth == true){" + " float dist = distance(gl_PointCoord, vec2(0.5));" + " if(dist > 0.5){" + " discard;" + " }" + " }" + " gl_FragColor = vFrontColor;" + "}"; + var vertexShaderSrc2D = "varying vec4 vFrontColor;" + "attribute vec3 aVertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 uColor;" + "uniform mat4 uModel;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float uPointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = uPointSize;" + " vFrontColor = uColor;" + " gl_Position = uProjection * uView * uModel * vec4(aVertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}"; + var fragmentShaderSrc2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 vFrontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int uIsDrawingText;" + "uniform bool uSmooth;" + "void main(void){" + " if(uSmooth == true){" + " float dist = distance(gl_PointCoord, vec2(0.5));" + " if(dist > 0.5){" + " discard;" + " }" + " }" + " if(uIsDrawingText == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(vFrontColor.rgb * alpha, alpha);" + " }" + " else{" + " gl_FragColor = vFrontColor;" + " }" + "}"; + var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent); + var vertexShaderSrc3D = "varying vec4 vFrontColor;" + "attribute vec3 aVertex;" + "attribute vec3 aNormal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 uColor;" + "uniform bool uUsingMat;" + "uniform vec3 uSpecular;" + "uniform vec3 uMaterialEmissive;" + "uniform vec3 uMaterialAmbient;" + "uniform vec3 uMaterialSpecular;" + "uniform float uShininess;" + "uniform mat4 uModel;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform mat4 uNormalTransform;" + "uniform int uLightCount;" + "uniform vec3 uFalloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light uLights0;" + "uniform Light uLights1;" + "uniform Light uLights2;" + "uniform Light uLights3;" + "uniform Light uLights4;" + "uniform Light uLights5;" + "uniform Light uLights6;" + "uniform Light uLights7;" + "Light getLight(int index){" + " if(index == 0) return uLights0;" + " if(index == 1) return uLights1;" + " if(index == 2) return uLights2;" + " if(index == 3) return uLights3;" + " if(index == 4) return uLights4;" + " if(index == 5) return uLights5;" + " if(index == 6) return uLights6;" + " return uLights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( uFalloff[0] + ( uFalloff[1] * d ) + ( uFalloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerFactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerFactor = pow( nDotVH, uShininess );" + " }" + " col += light.color * nDotVP;" + " spec += uSpecular * powerFactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerFactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( uFalloff[0] + ( uFalloff[1] * d ) + ( uFalloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerFactor = 0.0;" + " }" + " else {" + " powerFactor = pow( nDotHV, uShininess );" + " }" + " spec += uSpecular * powerFactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerFactor = 0.0;" + " vec3 VP = light.position - ecPos;" + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( uFalloff[0] + ( uFalloff[1] * d ) + ( uFalloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ) );" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ) );" + " if( nDotVP != 0.0 ) {" + " powerFactor = pow( nDotHV, uShininess );" + " }" + " spec += uSpecular * powerFactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0 );" + " vec3 finalDiffuse = vec3( 0.0 );" + " vec3 finalSpecular = vec3( 0.0 );" + " vec4 col = uColor;" + " if ( uColor[0] == -1.0 ){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( uNormalTransform * vec4( aNormal, 0.0 ) ));" + " vec4 ecPos4 = uView * uModel * vec4(aVertex, 1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( uLightCount == 0 ) {" + " vFrontColor = col + vec4(uMaterialSpecular, 1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= uLightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( uUsingMat == false ) {" + " vFrontColor = vec4(" + " vec3( col ) * finalAmbient +" + " vec3( col ) * finalDiffuse +" + " vec3( col ) * finalSpecular," + " col[3] );" + " }" + " else{" + " vFrontColor = vec4( " + " uMaterialEmissive + " + " (vec3(col) * uMaterialAmbient * finalAmbient ) + " + " (vec3(col) * finalDiffuse) + " + " (uMaterialSpecular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = uProjection * uView * uModel * vec4( aVertex, 1.0 );" + "}"; + var fragmentShaderSrc3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 vFrontColor;" + "uniform sampler2D uSampler;" + "uniform bool uUsingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if( uUsingTexture ){" + " gl_FragColor = vec4(texture2D(uSampler, vTexture.xy)) * vFrontColor;" + " }" + " else{" + " gl_FragColor = vFrontColor;" + " }" + "}"; + + 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 !== null) 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 !== null) 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 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) + } + 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) + } + 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 imageModeCorner = function(x, y, w, h, whAreSizes) { + return { + x: x, + y: y, + w: w, + h: h + } + }; + var imageModeConvert = imageModeCorner; + var imageModeCorners = function(x, y, w, h, whAreSizes) { + return { + x: x, + y: y, + w: whAreSizes ? w : w - x, + h: whAreSizes ? h : h - y + } + }; + var imageModeCenter = function(x, y, w, h, whAreSizes) { + return { + x: x - w / 2, + y: y - h / 2, + w: w, + h: h + } + }; + var DrawingShared = function() {}; + var Drawing2D = function() {}; + var Drawing3D = function() {}; + var DrawingPre = function() {}; + Drawing2D.prototype = new DrawingShared; + Drawing2D.prototype.constructor = Drawing2D; + Drawing3D.prototype = new DrawingShared; + Drawing3D.prototype.constructor = Drawing3D; + DrawingPre.prototype = new DrawingShared; + DrawingPre.prototype.constructor = DrawingPre; + DrawingShared.prototype.a3DOnlyFunction = nop; + var charMap = {}; + var Char = p.Character = function(chr) { + if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0); + else if (typeof chr === "number") this.code = chr; + else if (chr instanceof Char) this.code = chr; + 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 || 0; + 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 + }; + PShape.prototype = { + isVisible: function() { + return this.visible + }, + setVisible: function(visible) { + this.visible = visible + }, + disableStyle: function() { + this.style = false; + for (var i = 0, j = this.children.length; i < j; i++) this.children[i].disableStyle() + }, + enableStyle: function() { + this.style = true; + for (var i = 0, j = this.children.length; i < j; i++) this.children[i].enableStyle() + }, + getFamily: function() { + return this.family + }, + getWidth: function() { + return this.width + }, + getHeight: function() { + return this.height + }, + setName: function(name) { + this.name = name + }, + getName: function() { + return this.name + }, + draw: function(renderContext) { + renderContext = renderContext || p; + if (this.visible) { + this.pre(renderContext); + this.drawImpl(renderContext); + this.post(renderContext) + } + }, + drawImpl: function(renderContext) { + if (this.family === 0) this.drawGroup(renderContext); + else if (this.family === 1) this.drawPrimitive(renderContext); + else if (this.family === 3) this.drawGeometry(renderContext); + else if (this.family === 21) this.drawPath(renderContext) + }, + drawPath: function(renderContext) { + var i, j; + if (this.vertices.length === 0) return; + renderContext.beginShape(); + if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) renderContext.vertex(this.vertices[i][0], this.vertices[i][1]); + else for (i = 0, j = this.vertices.length; i < j; i++) renderContext.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]); + else { + var index = 0; + if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { + renderContext.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index]["moveTo"]); + renderContext.breakShape = false; + index++ + } else if (this.vertexCodes[i] === 1) { + renderContext.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 + } else if (this.vertexCodes[i] === 2) { + renderContext.curveVertex(this.vertices[index][0], this.vertices[index][1]); + index++ + } else { + if (this.vertexCodes[i] === 3) renderContext.breakShape = true + } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) { + renderContext.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; + renderContext.breakShape = false + } else if (this.vertexCodes[i] === 1) { + renderContext.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 + } else if (this.vertexCodes[i] === 2) { + renderContext.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]); + index++ + } else if (this.vertexCodes[i] === 3) renderContext.breakShape = true + } + renderContext.endShape(this.close ? 2 : 1) + }, + drawGeometry: function(renderContext) { + var i, j; + renderContext.beginShape(this.kind); + if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) renderContext.vertex(this.vertices[i]); + else for (i = 0, j = this.vertices.length; i < j; i++) { + var vert = this.vertices[i]; + if (vert[2] === 0) renderContext.vertex(vert[0], vert[1]); + else renderContext.vertex(vert[0], vert[1], vert[2]) + } + renderContext.endShape() + }, + drawGroup: function(renderContext) { + for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw(renderContext) + }, + drawPrimitive: function(renderContext) { + if (this.kind === 2) renderContext.point(this.params[0], this.params[1]); + else if (this.kind === 4) if (this.params.length === 4) renderContext.line(this.params[0], this.params[1], this.params[2], this.params[3]); + else renderContext.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); + else if (this.kind === 8) renderContext.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); + else if (this.kind === 16) renderContext.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]); + else if (this.kind === 30) if (this.image !== null) { + var imMode = imageModeConvert; + renderContext.imageMode(0); + renderContext.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3]); + imageModeConvert = imMode + } else { + var rcMode = curRectMode; + renderContext.rectMode(0); + renderContext.rect(this.params[0], this.params[1], this.params[2], this.params[3]); + curRectMode = rcMode + } else if (this.kind === 31) { + var elMode = curEllipseMode; + renderContext.ellipseMode(0); + renderContext.ellipse(this.params[0], this.params[1], this.params[2], this.params[3]); + curEllipseMode = elMode + } else if (this.kind === 32) { + var eMode = curEllipseMode; + renderContext.ellipseMode(0); + renderContext.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]); + curEllipseMode = eMode + } else if (this.kind === 41) if (this.params.length === 1) renderContext.box(this.params[0]); + else renderContext.box(this.params[0], this.params[1], this.params[2]); + else if (this.kind === 40) renderContext.sphere(this.params[0]) + }, + pre: function(renderContext) { + if (this.matrix) { + renderContext.pushMatrix(); + renderContext.transform(this.matrix) + } + if (this.style) { + renderContext.pushStyle(); + this.styles(renderContext) + } + }, + post: function(renderContext) { + if (this.matrix) renderContext.popMatrix(); + if (this.style) renderContext.popStyle() + }, + styles: function(renderContext) { + if (this.stroke) { + renderContext.stroke(this.strokeColor); + renderContext.strokeWeight(this.strokeWeight); + renderContext.strokeCap(this.strokeCap); + renderContext.strokeJoin(this.strokeJoin) + } else renderContext.noStroke(); + if (this.fill) renderContext.fill(this.fillColor); + else renderContext.noFill() + }, + getChild: function(child) { + var i, j; + if (typeof child === "number") return this.children[child]; + var found; + if (child === "" || this.name === child) return this; + if (this.nameTable.length > 0) { + for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) { + found = this.nameTable[i]; + break + } + if (found) return found + } + for (i = 0, j = this.children.length; i < j; i++) { + found = this.children[i].getChild(child); + if (found) return found + } + return null + }, + getChildCount: function() { + return this.children.length + }, + addChild: function(child) { + this.children.push(child); + child.parent = this; + if (child.getName() !== null) this.addName(child.getName(), child) + }, + addName: function(name, shape) { + if (this.parent !== null) this.parent.addName(name, shape); + else this.nameTable.push([name, shape]) + }, + 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) + } + }, + 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 + }, + rotateX: function(angle) { + this.rotate(angle, 1, 0, 0) + }, + rotateY: function(angle) { + this.rotate(angle, 0, 1, 0) + }, + rotateZ: function(angle) { + this.rotate(angle, 0, 0, 1) + }, + 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]) + } + }, + 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]) + } + }, + resetMatrix: function() { + this.checkMatrix(2); + this.matrix.reset() + }, + 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 = 4278190080; + this.strokeWeight = 1; + this.strokeCap = 'butt'; + this.strokeJoin = 'miter'; + this.strokeGradient = null; + this.strokeGradientPaint = null; + this.strokeName = null; + this.strokeOpacity = 1; + this.fill = true; + this.fillColor = 4278190080; + this.fillGradient = null; + this.fillGradientPaint = null; + this.fillName = null; + this.fillOpacity = 1; + if (this.element.getName() !== "svg") throw "root is not , 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(p, arguments[1]); + this.vertexCodes = []; + this.vertices = []; + this.opacity = 1; + this.stroke = false; + this.strokeColor = 4278190080; + this.strokeWeight = 1; + this.strokeCap = 'butt'; + this.strokeJoin = 'miter'; + this.strokeGradient = ""; + this.strokeGradientPaint = ""; + this.strokeName = ""; + this.strokeOpacity = 1; + this.fill = true; + this.fillColor = 4278190080; + 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 tag of this file."; + } + this.parseColors(this.element); + this.parseChildren(this.element) + }; + PShapeSVG.prototype = new PShape; + PShapeSVG.prototype.parseMatrix = function() { + function getCoords(s) { + var m = []; + s.replace(/\((.*?)\)/, function() { + return function(all, params) { + m = params.replace(/,+/g, " ").split(/\s+/) + } + }()); + return m + } + return function(str) { + this.checkMatrix(2); + var pieces = []; + str.replace(/\s*(\w+)\((.*?)\)/g, function(all) { + pieces.push(p.trim(all)) + }); + if (pieces.length === 0) return null; + for (var i = 0, j = pieces.length; i < j; i++) { + var m = getCoords(pieces[i]); + 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]); + else if (pieces[i].indexOf("shearX") !== -1) this.matrix.shearX(m[0]); + else if (pieces[i].indexOf("shearY") !== -1) this.matrix.shearY(m[0]) + } + return this.matrix + } + }(); + PShapeSVG.prototype.parseChildren = function(element) { + var newelement = element.getChildren(); + var children = new p.PShape; + for (var i = 0, j = newelement.length; i < j; i++) { + var kid = this.parseChild(newelement[i]); + if (kid) children.addChild(kid) + } + this.children.push(children) + }; + PShapeSVG.prototype.getName = function() { + return this.name + }; + PShapeSVG.prototype.parseChild = function(elem) { + var name = elem.getName(); + var shape; + if (name === "g") shape = new PShapeSVG(this, elem); + else if (name === "defs") shape = new PShapeSVG(this, elem); + else if (name === "line") { + shape = new PShapeSVG(this, elem); + shape.parseLine() + } else if (name === "circle") { + shape = new PShapeSVG(this, elem); + shape.parseEllipse(true) + } else if (name === "ellipse") { + shape = new PShapeSVG(this, elem); + shape.parseEllipse(false) + } else if (name === "rect") { + shape = new PShapeSVG(this, elem); + shape.parseRect() + } else if (name === "polygon") { + shape = new PShapeSVG(this, elem); + shape.parsePoly(true) + } else if (name === "polyline") { + shape = new PShapeSVG(this, elem); + shape.parsePoly(false) + } else if (name === "path") { + shape = new PShapeSVG(this, elem); + shape.parsePath() + } else if (name === "radialGradient") unimplemented("PShapeSVG.prototype.parseChild, name = radialGradient"); + else if (name === "linearGradient") unimplemented("PShapeSVG.prototype.parseChild, name = linearGradient"); + else if (name === "text") unimplemented("PShapeSVG.prototype.parseChild, name = text"); + else if (name === "filter") unimplemented("PShapeSVG.prototype.parseChild, name = filter"); + else if (name === "mask") unimplemented("PShapeSVG.prototype.parseChild, name = mask"); + else nop(); + return shape + }; + PShapeSVG.prototype.parsePath = function() { + this.family = 21; + this.kind = 0; + var pathDataChars = []; + var c; + var pathData = p.trim(this.element.getStringAttribute("d").replace(/[\s,]+/g, " ")); + if (pathData === null) return; + pathData = p.__toCharArray(pathData); + 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, + valOf = 0; + var str = ""; + var tmpArray = []; + var flag = false; + var lastInstruction; + var command; + var j, k; + 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]; + valOf = command.valueOf(); + if (valOf === 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, k = tmpArray.length; j < k; j += 2) { + cx = tmpArray[j]; + cy = tmpArray[j + 1]; + this.parsePathLineto(cx, cy) + } + } + } else if (valOf === 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, k = tmpArray.length; j < k; j += 2) { + cx += tmpArray[j]; + cy += tmpArray[j + 1]; + this.parsePathLineto(cx, cy) + } + } + } else if (valOf === 76) { + if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { + cx = tmpArray[j]; + cy = tmpArray[j + 1]; + this.parsePathLineto(cx, cy) + } + } else if (valOf === 108) { + if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; j += 2) { + cx += tmpArray[j]; + cy += tmpArray[j + 1]; + this.parsePathLineto(cx, cy) + } + } else if (valOf === 72) for (j = 0, k = tmpArray.length; j < k; j++) { + cx = tmpArray[j]; + this.parsePathLineto(cx, cy) + } else if (valOf === 104) for (j = 0, k = tmpArray.length; j < k; j++) { + cx += tmpArray[j]; + this.parsePathLineto(cx, cy) + } else if (valOf === 86) for (j = 0, k = tmpArray.length; j < k; j++) { + cy = tmpArray[j]; + this.parsePathLineto(cx, cy) + } else if (valOf === 118) for (j = 0, k = tmpArray.length; j < k; j++) { + cy += tmpArray[j]; + this.parsePathLineto(cx, cy) + } else if (valOf === 67) { + if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 99) { + if (tmpArray.length >= 6 && tmpArray.length % 6 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 83) { + if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 115) { + if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 81) { + if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 113) { + if (tmpArray.length >= 4 && tmpArray.length % 4 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 84) { + if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 116) { + if (tmpArray.length >= 2 && tmpArray.length % 2 === 0) for (j = 0, k = tmpArray.length; j < k; 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 + } + } else if (valOf === 90 || valOf === 122) this.close = true; + lastInstruction = command.toString() + } else i++ + } + }; + PShapeSVG.prototype.parsePathQuadto = function(x1, y1, cx, cy, x2, y2) { + if (this.vertices.length > 0) { + this.parsePathCode(1); + 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"; + }; + PShapeSVG.prototype.parsePathCurveto = function(x1, y1, x2, y2, x3, y3) { + if (this.vertices.length > 0) { + this.parsePathCode(1); + this.parsePathVertex(x1, y1); + this.parsePathVertex(x2, y2); + this.parsePathVertex(x3, y3) + } else throw "Path must start with M/m"; + }; + PShapeSVG.prototype.parsePathLineto = function(px, py) { + if (this.vertices.length > 0) { + this.parsePathCode(0); + this.parsePathVertex(px, py); + this.vertices[this.vertices.length - 1]["moveTo"] = false + } else throw "Path must start with M/m"; + }; + PShapeSVG.prototype.parsePathMoveto = function(px, py) { + if (this.vertices.length > 0) this.parsePathCode(3); + this.parsePathCode(0); + this.parsePathVertex(px, py); + this.vertices[this.vertices.length - 1]["moveTo"] = true + }; + PShapeSVG.prototype.parsePathVertex = function(x, y) { + var verts = []; + verts[0] = x; + verts[1] = y; + this.vertices.push(verts) + }; + PShapeSVG.prototype.parsePathCode = function(what) { + this.vertexCodes.push(what) + }; + PShapeSVG.prototype.parsePoly = function(val) { + this.family = 21; + 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, j = pointsBuffer.length; i < j; i++) { + var verts = []; + verts[0] = pointsBuffer[i]; + verts[1] = pointsBuffer[++i]; + this.vertices.push(verts) + } else throw "Error parsing polygon points: odd number of coordinates provided"; + } + }; + PShapeSVG.prototype.parseRect = function() { + this.kind = 30; + this.family = 1; + 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 "; + }; + PShapeSVG.prototype.parseEllipse = function(val) { + this.kind = 31; + this.family = 1; + 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 "; + } 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 "; + } + this.params[0] -= rx; + this.params[1] -= ry; + this.params[2] = rx * 2; + this.params[3] = ry * 2 + }; + PShapeSVG.prototype.parseLine = function() { + this.kind = 4; + this.family = 1; + 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") + }; + PShapeSVG.prototype.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, j = styleTokens.length; i < j; i++) { + var tokens = p.trim(styleTokens[i].split(":")); + if (tokens[0] === "fill") this.setFill(tokens[1]); + else if (tokens[0] === "fill-opacity") this.setFillOpacity(tokens[1]); + else if (tokens[0] === "stroke") this.setStroke(tokens[1]); + else if (tokens[0] === "stroke-width") this.setStrokeWeight(tokens[1]); + else if (tokens[0] === "stroke-linecap") this.setStrokeCap(tokens[1]); + else if (tokens[0] === "stroke-linejoin") this.setStrokeJoin(tokens[1]); + else if (tokens[0] === "stroke-opacity") this.setStrokeOpacity(tokens[1]); + else if (tokens[0] === "opacity") this.setOpacity(tokens[1]) + } + } + }; + PShapeSVG.prototype.setFillOpacity = function(opacityText) { + this.fillOpacity = parseFloat(opacityText); + this.fillColor = this.fillOpacity * 255 << 24 | this.fillColor & 16777215 + }; + PShapeSVG.prototype.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 + } + }; + PShapeSVG.prototype.setOpacity = function(opacity) { + this.strokeColor = parseFloat(opacity) * 255 << 24 | this.strokeColor & 16777215; + this.fillColor = parseFloat(opacity) * 255 << 24 | this.fillColor & 16777215 + }; + PShapeSVG.prototype.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 + } + }; + PShapeSVG.prototype.setStrokeWeight = function(weight) { + this.strokeWeight = this.parseUnitSize(weight) + }; + PShapeSVG.prototype.setStrokeJoin = function(linejoin) { + if (linejoin === "miter") this.strokeJoin = 'miter'; + else if (linejoin === "round") this.strokeJoin = 'round'; + else if (linejoin === "bevel") this.strokeJoin = 'bevel' + }; + PShapeSVG.prototype.setStrokeCap = function(linecap) { + if (linecap === "butt") this.strokeCap = 'butt'; + else if (linecap === "round") this.strokeCap = 'round'; + else if (linecap === "square") this.strokeCap = 'square' + }; + PShapeSVG.prototype.setStrokeOpacity = function(opacityText) { + this.strokeOpacity = parseFloat(opacityText); + this.strokeColor = this.strokeOpacity * 255 << 24 | this.strokeColor & 16777215 + }; + PShapeSVG.prototype.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] + }; + PShapeSVG.prototype.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; + if (text.indexOf("pc") === len) return parseFloat(text.substring(0, len)) * 15; + if (text.indexOf("mm") === len) return parseFloat(text.substring(0, len)) * 3.543307; + if (text.indexOf("cm") === len) return parseFloat(text.substring(0, len)) * 35.43307; + if (text.indexOf("in") === len) return parseFloat(text.substring(0, len)) * 90; + if (text.indexOf("px") === len) return parseFloat(text.substring(0, len)); + 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 === 3) 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 === 0) 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 === 1) 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(p); + if (arguments.length === 1 && curShapeMode === 3 || 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(selector, uri, sysid, line) { + this.attributes = []; + this.children = []; + this.fullName = null; + this.name = null; + this.namespace = ""; + this.content = null; + this.parent = null; + this.lineNr = ""; + this.systemID = ""; + this.type = "ELEMENT"; + if (selector) if (typeof selector === "string") if (uri === undef && selector.indexOf("<") > -1) this.parse(selector); + else { + this.fullName = selector; + this.namespace = uri; + this.systemId = sysid; + this.lineNr = line + } else this.parse(uri) + }; + XMLElement.prototype = { + parse: function(textstring) { + var xmlDoc; + try { + var extension = textstring.substring(textstring.length - 4); + if (extension === ".xml" || extension === ".svg") textstring = ajax(textstring); + xmlDoc = (new DOMParser).parseFromString(textstring, "text/xml"); + var elements = xmlDoc.documentElement; + if (elements) this.parseChildrenRecursive(null, elements); + else throw "Error loading document"; + return this + } catch(e) { + throw e; + } + }, + parseChildrenRecursive: function(parent, elementpath) { + var xmlelement, xmlattribute, tmpattrib, l, m, child; + if (!parent) { + this.fullName = elementpath.localName; + this.name = elementpath.nodeName; + xmlelement = this + } else { + xmlelement = new XMLElement(elementpath.nodeName); + xmlelement.parent = parent + } + if (elementpath.nodeType === 3 && elementpath.textContent !== "") return this.createPCDataElement(elementpath.textContent); + if (elementpath.nodeType === 4) return this.createCDataElement(elementpath.textContent); + if (elementpath.attributes) for (l = 0, m = elementpath.attributes.length; l < m; l++) { + tmpattrib = elementpath.attributes[l]; + xmlattribute = new XMLAttribute(tmpattrib.getname, tmpattrib.nodeName, tmpattrib.namespaceURI, tmpattrib.nodeValue, tmpattrib.nodeType); + xmlelement.attributes.push(xmlattribute) + } + if (elementpath.childNodes) for (l = 0, m = elementpath.childNodes.length; l < m; l++) { + var node = elementpath.childNodes[l]; + child = xmlelement.parseChildrenRecursive(xmlelement, node); + if (child !== null) xmlelement.children.push(child) + } + return xmlelement + }, + createElement: function(fullname, namespaceuri, sysid, line) { + if (sysid === undef) return new XMLElement(fullname, namespaceuri); + return new XMLElement(fullname, namespaceuri, sysid, line) + }, + createPCDataElement: function(content, isCDATA) { + if (content.replace(/^\s+$/g, "") === "") return null; + var pcdata = new XMLElement; + pcdata.type = "TEXT"; + pcdata.content = content; + return pcdata + }, + createCDataElement: function(content) { + var cdata = this.createPCDataElement(content); + if (cdata === null) return null; + cdata.type = "CDATA"; + var htmlentities = { + "<": "<", + ">": ">", + "'": "'", + '"': """ + }, + entity; + for (entity in htmlentities) if (!Object.hasOwnProperty(htmlentities, entity)) content = content.replace(new RegExp(entity, "g"), htmlentities[entity]); + cdata.cdata = content; + return cdata + }, + hasAttribute: function() { + if (arguments.length === 1) return this.getAttribute(arguments[0]) !== null; + if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]) !== null + }, + equals: function(other) { + if (! (other instanceof XMLElement)) return false; + var i, j; + if (this.fullName !== other.fullName) return false; + if (this.attributes.length !== other.getAttributeCount()) return false; + if (this.attributes.length !== other.attributes.length) return false; + var attr_name, attr_ns, attr_value, attr_type, attr_other; + for (i = 0, j = this.attributes.length; i < j; i++) { + attr_name = this.attributes[i].getName(); + attr_ns = this.attributes[i].getNamespace(); + attr_other = other.findAttribute(attr_name, attr_ns); + if (attr_other === null) return false; + if (this.attributes[i].getValue() !== attr_other.getValue()) return false; + if (this.attributes[i].getType() !== attr_other.getType()) return false + } + if (this.children.length !== other.getChildCount()) return false; + if (this.children.length > 0) { + var child1, child2; + for (i = 0, j = this.children.length; i < j; i++) { + child1 = this.getChild(i); + child2 = other.getChild(i); + if (!child1.equals(child2)) return false + } + return true + } + return this.content === other.content + }, + getContent: function() { + if (this.type === "TEXT" || this.type === "CDATA") return this.content; + var children = this.children; + if (children.length === 1 && (children[0].type === "TEXT" || children[0].type === "CDATA")) return children[0].content; + return null + }, + getAttribute: function() { + var attribute; + if (arguments.length === 2) { + attribute = this.findAttribute(arguments[0]); + if (attribute) return attribute.getValue(); + return arguments[1] + } else if (arguments.length === 1) { + attribute = this.findAttribute(arguments[0]); + if (attribute) return attribute.getValue(); + return null + } else if (arguments.length === 3) { + attribute = this.findAttribute(arguments[0], arguments[1]); + if (attribute) return attribute.getValue(); + return arguments[2] + } + }, + getStringAttribute: function() { + if (arguments.length === 1) return this.getAttribute(arguments[0]); + if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); + return this.getAttribute(arguments[0], arguments[1], arguments[2]) + }, + getString: function(attributeName) { + return this.getStringAttribute(attributeName) + }, + getFloatAttribute: function() { + if (arguments.length === 1) return parseFloat(this.getAttribute(arguments[0], 0)); + if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); + return this.getAttribute(arguments[0], arguments[1], arguments[2]) + }, + getFloat: function(attributeName) { + return this.getFloatAttribute(attributeName) + }, + getIntAttribute: function() { + if (arguments.length === 1) return this.getAttribute(arguments[0], 0); + if (arguments.length === 2) return this.getAttribute(arguments[0], arguments[1]); + return this.getAttribute(arguments[0], arguments[1], arguments[2]) + }, + getInt: function(attributeName) { + return this.getIntAttribute(attributeName) + }, + 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(selector) { + if (typeof selector === "number") return this.children[selector]; + if (selector.indexOf("/") !== -1) return this.getChildRecursive(selector.split("/"), 0); + var kid, kidName; + for (var i = 0, j = this.getChildCount(); i < j; i++) { + kid = this.getChild(i); + kidName = kid.getName(); + if (kidName !== null && kidName === selector) return kid + } + return null + }, + getChildren: function() { + if (arguments.length === 1) { + if (typeof arguments[0] === "number") return this.getChild(arguments[0]); + if (arguments[0].indexOf("/") !== -1) return this.getChildrenRecursive(arguments[0].split("/"), 0); + var matches = []; + var kid, kidName; + for (var i = 0, j = this.getChildCount(); i < j; i++) { + kid = this.getChild(i); + kidName = kid.getName(); + if (kidName !== null && kidName === arguments[0]) matches.push(kid) + } + return matches + } + return this.children + }, + getChildCount: function() { + return this.children.length + }, + getChildRecursive: function(items, offset) { + if (offset === items.length) return this; + var kid, kidName, matchName = items[offset]; + for (var i = 0, j = this.getChildCount(); i < j; i++) { + kid = this.getChild(i); + kidName = kid.getName(); + if (kidName !== null && kidName === matchName) return kid.getChildRecursive(items, offset + 1) + } + 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 = kidMatches.concat(matches[i].getChildrenRecursive(items, offset + 1)); + return kidMatches + }, + isLeaf: function() { + return !this.hasChildren() + }, + listChildren: function() { + var arr = []; + for (var i = 0, j = this.children.length; i < j; i++) arr.push(this.getChild(i).getName()); + return arr + }, + removeAttribute: function(name, namespace) { + this.namespace = namespace || ""; + for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) { + this.attributes.splice(i, 1); + break + } + }, + removeChild: function(child) { + if (child) for (var i = 0, j = this.children.length; i < j; i++) if (this.children[i].equals(child)) { + this.children.splice(i, 1); + break + } + }, + removeChildAtIndex: function(index) { + if (this.children.length > index) this.children.splice(index, 1) + }, + findAttribute: function(name, namespace) { + this.namespace = namespace || ""; + for (var i = 0, j = this.attributes.length; i < j; i++) if (this.attributes[i].getName() === name && this.attributes[i].getNamespace() === this.namespace) return this.attributes[i]; + return null + }, + 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) + } + } + }, + setString: function(attribute, value) { + this.setAttribute(attribute, value) + }, + setInt: function(attribute, value) { + this.setAttribute(attribute, value) + }, + setFloat: function(attribute, value) { + this.setAttribute(attribute, value) + }, + setContent: function(content) { + if (this.children.length > 0) Processing.debug("Tried to set content for XMLElement with children"); + 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 + }, + toString: function() { + if (this.type === "TEXT") return this.content; + if (this.type === "CDATA") return this.cdata; + var tagstring = this.fullName; + var xmlstring = "<" + tagstring; + var a, c; + for (a = 0; a < this.attributes.length; a++) { + var attr = this.attributes[a]; + xmlstring += " " + attr.getName() + "=" + '"' + attr.getValue() + '"' + } + if (this.children.length === 0) if (this.content === "") xmlstring += "/>"; + else xmlstring += ">" + this.content + ""; + else { + xmlstring += ">"; + for (c = 0; c < this.children.length; c++) xmlstring += this.children[c].toString(); + xmlstring += "" + } + return xmlstring + } + }; + XMLElement.parse = function(xmlstring) { + var element = new XMLElement; + element.parse(xmlstring); + return element + }; + var XML = p.XML = p.XMLElement; + p.loadXML = function(uri) { + return new XML(p, uri) + }; + var printMatrixHelper = function(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] + }, + invTranslate: function(tx, ty) { + this.translate(-tx, -ty) + }, + 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) + }, + shearX: function(angle) { + this.apply(1, 0, 1, Math.tan(angle), 0, 0) + }, + shearY: function(angle) { + this.apply(1, 0, 1, 0, Math.tan(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) > -2147483648) { + 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 + } + }, + invScale: function(sx, sy) { + if (sx && !sy) sy = sx; + this.scale(1 / sx, 1 / 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) + }, + invRotateZ: function(angle) { + this.rotateZ(angle - Math.PI) + }, + 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() { + 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.elements = [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[4]; + this.elements[4] = this.elements[1]; + this.elements[1] = temp; + temp = this.elements[8]; + this.elements[8] = this.elements[2]; + this.elements[2] = temp; + temp = this.elements[6]; + this.elements[6] = this.elements[9]; + this.elements[9] = temp; + temp = this.elements[3]; + this.elements[3] = this.elements[12]; + this.elements[12] = temp; + temp = this.elements[7]; + this.elements[7] = this.elements[13]; + this.elements[13] = temp; + temp = this.elements[11]; + this.elements[11] = this.elements[14]; + this.elements[14] = temp + }, + 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) + }, + shearX: 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) + }, + shearY: 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]; + if (!w) return this.elements[0] * x + this.elements[1] * y + this.elements[2] * z + this.elements[3]; + 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]; + if (!w) return this.elements[4] * x + this.elements[5] * y + this.elements[6] * z + this.elements[7]; + 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]; + 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]; + 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) <= 1.0E-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() { + this.matrixStack = [] + }; + PMatrixStack.prototype.load = function() { + var tmpMatrix = drawing.$newPMatrix(); + if (arguments.length === 1) tmpMatrix.set(arguments[0]); + else tmpMatrix.set(arguments); + this.matrixStack.push(tmpMatrix) + }; + Drawing2D.prototype.$newPMatrix = function() { + return new PMatrix2D + }; + Drawing3D.prototype.$newPMatrix = function() { + return new PMatrix3D + }; + PMatrixStack.prototype.push = function() { + this.matrixStack.push(this.peek()) + }; + PMatrixStack.prototype.pop = function() { + return this.matrixStack.pop() + }; + PMatrixStack.prototype.peek = function() { + var tmpMatrix = drawing.$newPMatrix(); + tmpMatrix.set(this.matrixStack[this.matrixStack.length - 1]); + return tmpMatrix + }; + PMatrixStack.prototype.mult = function(matrix) { + this.matrixStack[this.matrixStack.length - 1].apply(matrix) + }; + p.split = function(str, delim) { + return str.split(delim) + }; + p.splitTokens = function(str, tokens) { + if (tokens === undef) return str.split(/\s+/g); + var chars = tokens.split(/()/g), + buffer = "", + len = str.length, + i, c, tokenized = []; + for (i = 0; i < len; i++) { + c = str[i]; + if (chars.indexOf(c) > -1) { + if (buffer !== "") tokenized.push(buffer); + buffer = "" + } else buffer += c + } + if (buffer !== "") tokenized.push(buffer); + return tokenized + }; + 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) { + var end = length !== undef ? offset + length : array.length; + return array.slice(offset, end) + }; + 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, targetSize) { + var temp = ary.slice(0), + newSize = targetSize || ary.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 = function() { + var ALPHA_MASK = 4278190080, + RED_MASK = 16711680, + GREEN_MASK = 65280, + BLUE_MASK = 255, + min = Math.min, + max = Math.max; + + function applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) { + var a = min(((c1 & 4278190080) >>> 24) + f, 255) << 24; + var r = ar + ((cr - ar) * f >> 8); + r = (r < 0 ? 0 : r > 255 ? 255 : r) << 16; + var g = ag + ((cg - ag) * f >> 8); + g = (g < 0 ? 0 : g > 255 ? 255 : g) << 8; + var b = ab + ((cb - ab) * f >> 8); + b = b < 0 ? 0 : b > 255 ? 255 : b; + return a | r | g | b + } + return { + replace: function(c1, c2) { + return c2 + }, + blend: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = c1 & RED_MASK, + ag = c1 & GREEN_MASK, + ab = c1 & BLUE_MASK, + br = c2 & RED_MASK, + bg = c2 & GREEN_MASK, + bb = c2 & BLUE_MASK; + return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK + }, + add: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24; + return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | min((c1 & RED_MASK) + ((c2 & RED_MASK) >> 8) * f, RED_MASK) & RED_MASK | min((c1 & GREEN_MASK) + ((c2 & GREEN_MASK) >> 8) * f, GREEN_MASK) & GREEN_MASK | min((c1 & BLUE_MASK) + ((c2 & BLUE_MASK) * f >> 8), BLUE_MASK) + }, + subtract: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24; + return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max((c1 & RED_MASK) - ((c2 & RED_MASK) >> 8) * f, GREEN_MASK) & RED_MASK | max((c1 & GREEN_MASK) - ((c2 & GREEN_MASK) >> 8) * f, BLUE_MASK) & GREEN_MASK | max((c1 & BLUE_MASK) - ((c2 & BLUE_MASK) * f >> 8), 0) + }, + lightest: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24; + return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | max(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f) & RED_MASK | max(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f) & GREEN_MASK | max(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8) + }, + darkest: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = c1 & RED_MASK, + ag = c1 & GREEN_MASK, + ab = c1 & BLUE_MASK, + br = min(c1 & RED_MASK, ((c2 & RED_MASK) >> 8) * f), + bg = min(c1 & GREEN_MASK, ((c2 & GREEN_MASK) >> 8) * f), + bb = min(c1 & BLUE_MASK, (c2 & BLUE_MASK) * f >> 8); + return min(((c1 & ALPHA_MASK) >>> 24) + f, 255) << 24 | ar + ((br - ar) * f >> 8) & RED_MASK | ag + ((bg - ag) * f >> 8) & GREEN_MASK | ab + ((bb - ab) * f >> 8) & BLUE_MASK + }, + difference: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = ar > br ? ar - br : br - ar, + cg = ag > bg ? ag - bg : bg - ag, + cb = ab > bb ? ab - bb : bb - ab; + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + exclusion: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = ar + br - (ar * br >> 7), + cg = ag + bg - (ag * bg >> 7), + cb = ab + bb - (ab * bb >> 7); + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + multiply: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = ar * br >> 8, + cg = ag * bg >> 8, + cb = ab * bb >> 8; + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + screen: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = 255 - ((255 - ar) * (255 - br) >> 8), + cg = 255 - ((255 - ag) * (255 - bg) >> 8), + cb = 255 - ((255 - ab) * (255 - bb) >> 8); + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + hard_light: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = br < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), + cg = bg < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), + cb = bb < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + soft_light: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = (ar * br >> 7) + (ar * ar >> 8) - (ar * ar * br >> 15), + cg = (ag * bg >> 7) + (ag * ag >> 8) - (ag * ag * bg >> 15), + cb = (ab * bb >> 7) + (ab * ab >> 8) - (ab * ab * bb >> 15); + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + overlay: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK, + cr = ar < 128 ? ar * br >> 7 : 255 - ((255 - ar) * (255 - br) >> 7), + cg = ag < 128 ? ag * bg >> 7 : 255 - ((255 - ag) * (255 - bg) >> 7), + cb = ab < 128 ? ab * bb >> 7 : 255 - ((255 - ab) * (255 - bb) >> 7); + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + dodge: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK; + var cr = 255; + if (br !== 255) { + cr = (ar << 8) / (255 - br); + cr = cr < 0 ? 0 : cr > 255 ? 255 : cr + } + var cg = 255; + if (bg !== 255) { + cg = (ag << 8) / (255 - bg); + cg = cg < 0 ? 0 : cg > 255 ? 255 : cg + } + var cb = 255; + if (bb !== 255) { + cb = (ab << 8) / (255 - bb); + cb = cb < 0 ? 0 : cb > 255 ? 255 : cb + } + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + }, + burn: function(c1, c2) { + var f = (c2 & ALPHA_MASK) >>> 24, + ar = (c1 & RED_MASK) >> 16, + ag = (c1 & GREEN_MASK) >> 8, + ab = c1 & BLUE_MASK, + br = (c2 & RED_MASK) >> 16, + bg = (c2 & GREEN_MASK) >> 8, + bb = c2 & BLUE_MASK; + var cr = 0; + if (br !== 0) { + cr = (255 - ar << 8) / br; + cr = 255 - (cr < 0 ? 0 : cr > 255 ? 255 : cr) + } + var cg = 0; + if (bg !== 0) { + cg = (255 - ag << 8) / bg; + cg = 255 - (cg < 0 ? 0 : cg > 255 ? 255 : cg) + } + var cb = 0; + if (bb !== 0) { + cb = (255 - ab << 8) / bb; + cb = 255 - (cb < 0 ? 0 : cb > 255 ? 255 : cb) + } + return applyMode(c1, f, ar, ag, ab, br, bg, bb, cr, cg, cb) + } + } + }(); + + function color$4(aValue1, aValue2, aValue3, aValue4) { + var r, g, b, a; + if (curColorMode === 3) { + 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 < 0 ? 0 : r; + g = g < 0 ? 0 : g; + b = b < 0 ? 0 : b; + a = a < 0 ? 0 : a; + r = r > 255 ? 255 : r; + g = g > 255 ? 255 : g; + b = b > 255 ? 255 : b; + a = a > 255 ? 255 : a; + return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 + } + function color$2(aValue1, aValue2) { + var a; + if (aValue1 & 4278190080) { + a = Math.round(255 * (aValue2 / colorModeA)); + a = a > 255 ? 255 : a; + a = a < 0 ? 0 : a; + return aValue1 - (aValue1 & 4278190080) + (a << 24 & 4278190080) + } + if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, aValue2); + if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, aValue2) + } + function color$1(aValue1) { + if (aValue1 <= colorModeX && aValue1 >= 0) { + if (curColorMode === 1) return color$4(aValue1, aValue1, aValue1, colorModeA); + if (curColorMode === 3) return color$4(0, 0, aValue1 / colorModeX * colorModeZ, colorModeA) + } + if (aValue1) { + if (aValue1 > 2147483647) aValue1 -= 4294967296; + return aValue1 + } + } + p.color = function(aValue1, aValue2, aValue3, aValue4) { + if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef && aValue4 !== undef) return color$4(aValue1, aValue2, aValue3, aValue4); + if (aValue1 !== undef && aValue2 !== undef && aValue3 !== undef) return color$4(aValue1, aValue2, aValue3, colorModeA); + if (aValue1 !== undef && aValue2 !== undef) return color$2(aValue1, aValue2); + if (typeof aValue1 === "number") return color$1(aValue1); + return color$4(colorModeX, colorModeY, colorModeZ, colorModeA) + }; + p.color.toString = function(colorInt) { + return "rgba(" + ((colorInt >> 16) & 255) + "," + ((colorInt >> 8) & 255) + "," + (colorInt & 255) + "," + ((colorInt >> 24) & 255) / 255 + ")" + }; + p.color.toInt = function(r, g, b, a) { + return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 + }; + p.color.toArray = function(colorInt) { + return [(colorInt >> 16) & 255, (colorInt >> 8) & 255, colorInt & 255, (colorInt >> 24) & 255] + }; + p.color.toGLArray = function(colorInt) { + return [((colorInt & 16711680) >>> 16) / 255, ((colorInt >> 8) & 255) / 255, (colorInt & 255) / 255, ((colorInt >> 24) & 255) / 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]; + var hue = h % 360; + var f = hue % 60; + var p = Math.round(b * (100 - s) / 1E4 * 255); + var q = Math.round(b * (6E3 - s * f) / 6E5 * 255); + var t = Math.round(b * (6E3 - s * (60 - f)) / 6E5 * 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] + } + }; + + function colorToHSB(colorInt) { + var red, green, blue; + red = ((colorInt >> 16) & 255) / 255; + green = ((colorInt >> 8) & 255) / 255; + blue = (colorInt & 255) / 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 * colorModeZ]; + 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 colorToHSB(colInt)[2] + }; + p.saturation = function(colInt) { + return colorToHSB(colInt)[1] + }; + p.hue = function(colInt) { + return colorToHSB(colInt)[0] + }; + p.red = function(aColor) { + return ((aColor >> 16) & 255) / 255 * colorModeX + }; + p.green = function(aColor) { + return ((aColor & 65280) >>> 8) / 255 * colorModeY + }; + p.blue = function(aColor) { + return (aColor & 255) / 255 * colorModeZ + }; + p.alpha = function(aColor) { + return ((aColor >> 24) & 255) / 255 * colorModeA + }; + p.lerpColor = function(c1, c2, amt) { + var r, g, b, a, r1, g1, b1, a1, r2, g2, b2, a2; + var hsb1, hsb2, rgb, h, s; + var colorBits1 = p.color(c1); + var colorBits2 = p.color(c2); + if (curColorMode === 3) { + hsb1 = colorToHSB(colorBits1); + a1 = ((colorBits1 >> 24) & 255) / colorModeA; + hsb2 = colorToHSB(colorBits2); + a2 = ((colorBits2 & 4278190080) >>> 24) / colorModeA; + h = p.lerp(hsb1[0], hsb2[0], amt); + s = p.lerp(hsb1[1], hsb2[1], amt); + b = p.lerp(hsb1[2], hsb2[2], amt); + rgb = p.color.toRGB(h, s, b); + a = p.lerp(a1, a2, amt) * colorModeA; + return a << 24 & 4278190080 | (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255 + } + r1 = (colorBits1 >> 16) & 255; + g1 = (colorBits1 >> 8) & 255; + b1 = colorBits1 & 255; + a1 = ((colorBits1 >> 24) & 255) / colorModeA; + r2 = (colorBits2 & 16711680) >>> 16; + g2 = (colorBits2 >> 8) & 255; + b2 = colorBits2 & 255; + a2 = ((colorBits2 >> 24) & 255) / colorModeA; + r = p.lerp(r1, r2, amt) | 0; + g = p.lerp(g1, g2, amt) | 0; + b = p.lerp(b1, b2, amt) | 0; + a = p.lerp(a1, a2, amt) * colorModeA; + return a << 24 & 4278190080 | r << 16 & 16711680 | g << 8 & 65280 | b & 255 + }; + p.colorMode = function() { + 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) { + if (mode === 0) return p.modes.replace(c1, c2); + else if (mode === 1) return p.modes.blend(c1, c2); + else if (mode === 2) return p.modes.add(c1, c2); + else if (mode === 4) return p.modes.subtract(c1, c2); + else if (mode === 8) return p.modes.lightest(c1, c2); + else if (mode === 16) return p.modes.darkest(c1, c2); + else if (mode === 32) return p.modes.difference(c1, c2); + else if (mode === 64) return p.modes.exclusion(c1, c2); + else if (mode === 128) return p.modes.multiply(c1, c2); + else if (mode === 256) return p.modes.screen(c1, c2); + else if (mode === 1024) return p.modes.hard_light(c1, c2); + else if (mode === 2048) return p.modes.soft_light(c1, c2); + else if (mode === 512) return p.modes.overlay(c1, c2); + else if (mode === 4096) return p.modes.dodge(c1, c2); + else if (mode === 8192) return p.modes.burn(c1, c2) + }; + + function saveContext() { + curContext.save() + } + function restoreContext() { + curContext.restore(); + isStrokeDirty = true; + isFillDirty = true + } + p.printMatrix = function() { + modelView.print() + }; + Drawing2D.prototype.translate = function(x, y) { + modelView.translate(x, y); + modelViewInv.invTranslate(x, y); + curContext.translate(x, y) + }; + Drawing3D.prototype.translate = function(x, y, z) { + modelView.translate(x, y, z); + modelViewInv.invTranslate(x, y, z) + }; + Drawing2D.prototype.scale = function(x, y) { + modelView.scale(x, y); + modelViewInv.invScale(x, y); + curContext.scale(x, y || x) + }; + Drawing3D.prototype.scale = function(x, y, z) { + modelView.scale(x, y, z); + modelViewInv.invScale(x, y, z) + }; + Drawing2D.prototype.transform = function(pmatrix) { + var e = pmatrix.array(); + curContext.transform(e[0], e[3], e[1], e[4], e[2], e[5]) + }; + Drawing3D.prototype.transformm = function(pmatrix3d) { + throw "p.transform is currently not supported in 3D mode"; + }; + Drawing2D.prototype.pushMatrix = function() { + userMatrixStack.load(modelView); + userReverseMatrixStack.load(modelViewInv); + saveContext() + }; + Drawing3D.prototype.pushMatrix = function() { + userMatrixStack.load(modelView); + userReverseMatrixStack.load(modelViewInv) + }; + Drawing2D.prototype.popMatrix = function() { + modelView.set(userMatrixStack.pop()); + modelViewInv.set(userReverseMatrixStack.pop()); + restoreContext() + }; + Drawing3D.prototype.popMatrix = function() { + modelView.set(userMatrixStack.pop()); + modelViewInv.set(userReverseMatrixStack.pop()) + }; + Drawing2D.prototype.resetMatrix = function() { + modelView.reset(); + modelViewInv.reset(); + curContext.setTransform(1, 0, 0, 1, 0, 0) + }; + Drawing3D.prototype.resetMatrix = function() { + modelView.reset(); + modelViewInv.reset() + }; + DrawingShared.prototype.applyMatrix = function() { + var a = arguments; + modelView.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]); + modelViewInv.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]) + }; + Drawing2D.prototype.applyMatrix = function() { + var a = arguments; + for (var cnt = a.length; cnt < 16; cnt++) a[cnt] = 0; + a[10] = a[15] = 1; + DrawingShared.prototype.applyMatrix.apply(this, a) + }; + p.rotateX = function(angleInRadians) { + modelView.rotateX(angleInRadians); + modelViewInv.invRotateX(angleInRadians) + }; + Drawing2D.prototype.rotateZ = function() { + throw "rotateZ() is not supported in 2D mode. Use rotate(float) instead."; + }; + Drawing3D.prototype.rotateZ = function(angleInRadians) { + modelView.rotateZ(angleInRadians); + modelViewInv.invRotateZ(angleInRadians) + }; + p.rotateY = function(angleInRadians) { + modelView.rotateY(angleInRadians); + modelViewInv.invRotateY(angleInRadians) + }; + Drawing2D.prototype.rotate = function(angleInRadians) { + modelView.rotateZ(angleInRadians); + modelViewInv.invRotateZ(angleInRadians); + curContext.rotate(angleInRadians) + }; + Drawing3D.prototype.rotate = function(angleInRadians) { + p.rotateZ(angleInRadians) + }; + Drawing2D.prototype.shearX = function(angleInRadians) { + modelView.shearX(angleInRadians); + curContext.transform(1, 0, angleInRadians, 1, 0, 0) + }; + Drawing3D.prototype.shearX = function(angleInRadians) { + modelView.shearX(angleInRadians) + }; + Drawing2D.prototype.shearY = function(angleInRadians) { + modelView.shearY(angleInRadians); + curContext.transform(1, angleInRadians, 0, 1, 0, 0) + }; + Drawing3D.prototype.shearY = function(angleInRadians) { + modelView.shearY(angleInRadians) + }; + p.pushStyle = function() { + 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, + "horizontalTextAlignment": horizontalTextAlignment, + "verticalTextAlignment": verticalTextAlignment, + "textMode": textMode, + "curFontName": curFontName, + "curTextSize": curTextSize, + "curTextAscent": curTextAscent, + "curTextDescent": curTextDescent, + "curTextLeading": curTextLeading + }; + styleArray.push(newState) + }; + p.popStyle = function() { + 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; + curFontName = oldState.curFontName; + curTextSize = oldState.curTextSize; + horizontalTextAlignment = oldState.horizontalTextAlignment; + verticalTextAlignment = oldState.verticalTextAlignment; + textMode = oldState.textMode; + curTextAscent = oldState.curTextAscent; + curTextDescent = oldState.curTextDescent; + curTextLeading = oldState.curTextLeading + } else throw "Too many popStyle() without enough pushStyle()"; + }; + p.year = function() { + return (new Date).getFullYear() + }; + p.month = function() { + return (new Date).getMonth() + 1 + }; + p.day = function() { + return (new Date).getDate() + }; + p.hour = function() { + return (new Date).getHours() + }; + p.minute = function() { + return (new Date).getMinutes() + }; + p.second = function() { + return (new Date).getSeconds() + }; + p.millis = function() { + return Date.now() - start + }; + + function redrawHelper() { + var sec = (Date.now() - timeSinceLastFPS) / 1E3; + framesSinceLastFPS++; + var fps = framesSinceLastFPS / sec; + if (sec > 0.5) { + timeSinceLastFPS = Date.now(); + framesSinceLastFPS = 0; + p.__frameRate = fps + } + p.frameCount++ + } + Drawing2D.prototype.redraw = function() { + redrawHelper(); + curContext.lineWidth = lineWidth; + var pmouseXLastEvent = p.pmouseX, + pmouseYLastEvent = p.pmouseY; + p.pmouseX = pmouseXLastFrame; + p.pmouseY = pmouseYLastFrame; + saveContext(); + p.draw(); + restoreContext(); + pmouseXLastFrame = p.mouseX; + pmouseYLastFrame = p.mouseY; + p.pmouseX = pmouseXLastEvent; + p.pmouseY = pmouseYLastEvent + }; + Drawing3D.prototype.redraw = function() { + redrawHelper(); + var pmouseXLastEvent = p.pmouseX, + pmouseYLastEvent = p.pmouseY; + p.pmouseX = pmouseXLastFrame; + p.pmouseY = pmouseYLastFrame; + 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.emissive(0, 0, 0); + p.camera(); + p.draw(); + pmouseXLastFrame = p.mouseX; + pmouseYLastFrame = p.mouseY; + p.pmouseX = pmouseXLastEvent; + p.pmouseY = pmouseYLastEvent + }; + p.noLoop = function() { + doLoop = false; + loopStarted = false; + clearInterval(looping); + curSketch.onPause() + }; + p.loop = function() { + if (loopStarted) return; + timeSinceLastFPS = Date.now(); + framesSinceLastFPS = 0; + looping = window.setInterval(function() { + try { + curSketch.onFrameStart(); + p.redraw(); + curSketch.onFrameEnd() + } catch(e_loop) { + window.clearInterval(looping); + throw e_loop; + } + }, + curMsPerFrame); + doLoop = true; + loopStarted = true; + curSketch.onLoop() + }; + p.frameRate = function(aRate) { + curFrameRate = aRate; + curMsPerFrame = 1E3 / curFrameRate; + if (doLoop) { + p.noLoop(); + p.loop() + } + }; + var eventHandlers = []; + + function attachEventHandler(elem, type, fn) { + if (elem.addEventListener) elem.addEventListener(type, fn, false); + else elem.attachEvent("on" + type, fn); + eventHandlers.push({ + elem: elem, + type: type, + fn: fn + }) + } + function detachEventHandler(eventHandler) { + var elem = eventHandler.elem, + type = eventHandler.type, + fn = eventHandler.fn; + if (elem.removeEventListener) elem.removeEventListener(type, fn, false); + else if (elem.detachEvent) elem.detachEvent("on" + type, fn) + } + p.exit = function() { + window.clearInterval(looping); + removeInstance(p.externals.canvas.id); + delete curElement.onmousedown; + for (var lib in Processing.lib) if (Processing.lib.hasOwnProperty(lib)) if (Processing.lib[lib].hasOwnProperty("detach")) Processing.lib[lib].detach(p); + var i = eventHandlers.length; + while (i--) detachEventHandler(eventHandlers[i]); + curSketch.onExit() + }; + p.cursor = function() { + 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() { + curCursor = curElement.style.cursor = PConstants.NOCURSOR + }; + p.link = function(href, target) { + if (target !== undef) window.open(href, target); + else window.location = href + }; + p.beginDraw = nop; + p.endDraw = nop; + Drawing2D.prototype.toImageData = function(x, y, w, h) { + x = x !== undef ? x : 0; + y = y !== undef ? y : 0; + w = w !== undef ? w : p.width; + h = h !== undef ? h : p.height; + return curContext.getImageData(x, y, w, h) + }; + Drawing3D.prototype.toImageData = function(x, y, w, h) { + x = x !== undef ? x : 0; + y = y !== undef ? y : 0; + w = w !== undef ? w : p.width; + h = h !== undef ? h : p.height; + var c = document.createElement("canvas"), + ctx = c.getContext("2d"), + obj = ctx.createImageData(w, h), + uBuff = new Uint8Array(w * h * 4); + curContext.readPixels(x, y, w, h, curContext.RGBA, curContext.UNSIGNED_BYTE, uBuff); + for (var i = 0, ul = uBuff.length, obj_data = obj.data; i < ul; i++) obj_data[i] = uBuff[(h - 1 - Math.floor(i / 4 / w)) * w * 4 + i % (w * 4)]; + return obj + }; + p.status = function(text) { + window.status = text + }; + p.binary = function(num, numBits) { + var bit; + if (numBits > 0) bit = numBits; + else if (num instanceof Char) { + bit = 16; + num |= 0 + } else { + bit = 32; + while (bit > 1 && !(num >>> bit - 1 & 1)) bit-- + } + var result = ""; + while (bit > 0) result += num >>> --bit & 1 ? "1" : "0"; + return result + }; + p.unbinary = function(binaryString) { + var i = binaryString.length - 1, + mask = 1, + result = 0; + while (i >= 0) { + var ch = binaryString[i--]; + if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number"; + if (ch === "1") result += mask; + mask <<= 1 + } + return result + }; + + 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) > 1.0E-6 && 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); + 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 + } + 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(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(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 + } + return unhexScalar(hex) + }; + p.loadStrings = function(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(filename, strings) { + localStorage[filename] = strings.join("\n") + }; + p.loadBytes = function(url) { + var string = ajax(url); + var ret = []; + for (var i = 0; i < string.length; i++) ret.push(string.charCodeAt(i)); + return ret + }; + + function removeFirstArgument(args) { + return Array.prototype.slice.call(args, 1) + } + p.matchAll = function(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 + }; + p.__contains = function(subject, subStr) { + if (typeof subject !== "string") return subject.contains.apply(subject, removeFirstArgument(arguments)); + return subject !== null && subStr !== null && typeof subStr === "string" && subject.indexOf(subStr) > -1 + }; + p.__replaceAll = function(subject, regex, replacement) { + if (typeof subject !== "string") return subject.replaceAll.apply(subject, removeFirstArgument(arguments)); + return subject.replace(new RegExp(regex, "g"), replacement) + }; + p.__replaceFirst = function(subject, regex, replacement) { + if (typeof subject !== "string") return subject.replaceFirst.apply(subject, removeFirstArgument(arguments)); + return subject.replace(new RegExp(regex, ""), replacement) + }; + p.__replace = function(subject, what, replacement) { + if (typeof subject !== "string") return subject.replace.apply(subject, removeFirstArgument(arguments)); + if (what instanceof RegExp) return subject.replace(what, replacement); + if (typeof what !== "string") what = what.toString(); + if (what === "") return subject; + var i = subject.indexOf(what); + if (i < 0) return subject; + var j = 0, + result = ""; + do { + result += subject.substring(j, i) + replacement; + j = i + what.length + } while ((i = subject.indexOf(what, j)) >= 0); + return result + subject.substring(j) + }; + p.__equals = function(subject, other) { + if (subject.equals instanceof + Function) return subject.equals.apply(subject, removeFirstArgument(arguments)); + return subject.valueOf() === other.valueOf() + }; + p.__equalsIgnoreCase = function(subject, other) { + if (typeof subject !== "string") return subject.equalsIgnoreCase.apply(subject, removeFirstArgument(arguments)); + return subject.toLowerCase() === other.toLowerCase() + }; + p.__toCharArray = function(subject) { + if (typeof subject !== "string") return subject.toCharArray.apply(subject, removeFirstArgument(arguments)); + var chars = []; + for (var i = 0, len = subject.length; i < len; ++i) chars[i] = new Char(subject.charAt(i)); + return chars + }; + p.__split = function(subject, regex, limit) { + if (typeof subject !== "string") return subject.split.apply(subject, removeFirstArgument(arguments)); + var pattern = new RegExp(regex); + if (limit === undef || limit < 1) return subject.split(pattern); + var result = [], + currSubject = subject, + pos; + while ((pos = currSubject.search(pattern)) !== -1 && result.length < limit - 1) { + var match = pattern.exec(currSubject).toString(); + result.push(currSubject.substring(0, pos)); + currSubject = currSubject.substring(pos + match.length) + } + if (pos !== -1 || currSubject !== "") result.push(currSubject); + return result + }; + p.__codePointAt = function(subject, idx) { + var code = subject.charCodeAt(idx), + hi, low; + if (55296 <= code && code <= 56319) { + hi = code; + low = subject.charCodeAt(idx + 1); + return (hi - 55296) * 1024 + (low - 56320) + 65536 + } + return code + }; + p.match = function(str, regexp) { + return str.match(regexp) + }; + p.__matches = function(str, regexp) { + return (new RegExp(regexp)).test(str) + }; + p.__startsWith = function(subject, prefix, toffset) { + if (typeof subject !== "string") return subject.startsWith.apply(subject, removeFirstArgument(arguments)); + toffset = toffset || 0; + if (toffset < 0 || toffset > subject.length) return false; + return prefix === "" || prefix === subject ? true : subject.indexOf(prefix) === toffset + }; + p.__endsWith = function(subject, suffix) { + if (typeof subject !== "string") return subject.endsWith.apply(subject, removeFirstArgument(arguments)); + var suffixLen = suffix ? suffix.length : 0; + return suffix === "" || suffix === subject ? true : subject.indexOf(suffix) === subject.length - suffixLen + }; + p.__hashCode = function(subject) { + if (subject.hashCode instanceof + Function) return subject.hashCode.apply(subject, removeFirstArgument(arguments)); + return virtHashCode(subject) + }; + p.__printStackTrace = function(subject) { + p.println("Exception: " + subject.toString()) + }; + var logBuffer = []; + p.println = function(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(message) { + logBuffer.push(message) + }; + p.str = function(val) { + if (val instanceof Array) { + var arr = []; + for (var i = 0; i < val.length; i++) arr.push(val[i].toString() + ""); + return arr + } + return val.toString() + "" + }; + 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 + } + return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "") + }; + + function booleanScalar(val) { + if (typeof val === "number") return val !== 0; + if (typeof val === "boolean") return val; + if (typeof val === "string") return val.toLowerCase() === "true"; + if (val instanceof Char) return val.code === 49 || val.code === 84 || val.code === 116 + } + p.parseBoolean = function(val) { + if (val instanceof Array) { + var ret = []; + for (var i = 0; i < val.length; i++) ret.push(booleanScalar(val[i])); + return ret + } + return booleanScalar(val) + }; + p.parseByte = function(what) { + if (what instanceof Array) { + var bytes = []; + for (var i = 0; i < what.length; i++) bytes.push(0 - (what[i] & 128) | what[i] & 127); + return bytes + } + return 0 - (what & 128) | what & 127 + }; + p.parseChar = function(key) { + if (typeof key === "number") return new Char(String.fromCharCode(key & 65535)); + 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 + } + throw "char() may receive only one argument of type int, byte, int[], or byte[]."; + }; + + function floatScalar(val) { + if (typeof val === "number") return val; + if (typeof val === "boolean") return val ? 1 : 0; + if (typeof val === "string") return parseFloat(val); + if (val instanceof Char) return val.code + } + p.parseFloat = function(val) { + if (val instanceof + Array) { + var ret = []; + for (var i = 0; i < val.length; i++) ret.push(floatScalar(val[i])); + return ret + } + return floatScalar(val) + }; + + function intScalar(val, radix) { + if (typeof val === "number") return val & 4294967295; + if (typeof val === "boolean") return val ? 1 : 0; + if (typeof val === "string") { + var number = parseInt(val, radix || 10); + return number & 4294967295 + } + if (val instanceof Char) return val.code + } + p.parseInt = function(val, radix) { + 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], radix)); + return ret + } + return intScalar(val, radix) + }; + p.__int_cast = function(val) { + return 0 | val + }; + p.__instanceof = function(obj, type) { + if (typeof type !== "function") throw "Function is expected as type argument for instanceof operator"; + if (typeof obj === "string") return type === Object || type === String; + if (obj instanceof type) return true; + if (typeof obj !== "object" || obj === null) return false; + var objType = obj.constructor; + if (type.$isInterface) { + var interfaces = []; + while (objType) { + if (objType.$interfaces) interfaces = interfaces.concat(objType.$interfaces); + objType = objType.$base + } + while (interfaces.length > 0) { + var i = interfaces.shift(); + if (i === type) return true; + if (i.$interfaces) interfaces = interfaces.concat(i.$interfaces) + } + return false + } + while (objType.hasOwnProperty("$base")) { + objType = objType.$base; + if (objType === type) return true + } + return false + }; + 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) + } + 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 (c) return Math.sqrt(a * a + b * b + c * c); + return Math.sqrt(a * a + b * b) + }; + 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]; + 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]; + 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() { + if (arguments.length === 0) return currentRandom(); + if (arguments.length === 1) return currentRandom() * arguments[0]; + 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 = 18E3 * (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 / 6E4 & 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 + } + 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 Uint8Array(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 + }; + DrawingShared.prototype.size = function(aWidth, aHeight, aMode) { + if (doStroke) p.stroke(0); + if (doFill) p.fill(255); + var savedProperties = { + 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 prop in savedProperties) if (savedProperties.hasOwnProperty(prop)) curContext[prop] = savedProperties[prop]; + p.textFont(curTextFont); + p.background(); + maxPixelsCached = Math.max(1E3, aWidth * aHeight * 0.05); + p.externals.context = curContext; + for (var i = 0; i < 720; i++) { + sinLUT[i] = p.sin(i * (Math.PI / 180) * 0.5); + cosLUT[i] = p.cos(i * (Math.PI / 180) * 0.5) + } + }; + Drawing2D.prototype.size = function(aWidth, aHeight, aMode) { + if (curContext === undef) { + curContext = curElement.getContext("2d"); + userMatrixStack = new PMatrixStack; + userReverseMatrixStack = new PMatrixStack; + modelView = new PMatrix2D; + modelViewInv = new PMatrix2D + } + DrawingShared.prototype.size.apply(this, arguments) + }; + Drawing3D.prototype.size = function() { + var size3DCalled = false; + return function size(aWidth, aHeight, aMode) { + if (size3DCalled) throw "Multiple calls to size() for 3D renders are not allowed."; + size3DCalled = true; + + function getGLContext(canvas) { + var ctxNames = ["experimental-webgl", "webgl", "webkit-3d"], + gl; + for (var i = 0, l = ctxNames.length; i < l; i++) { + gl = canvas.getContext(ctxNames[i], { + antialias: false, + preserveDrawingBuffer: true + }); + if (gl) break + } + return gl + } + try { + curElement.width = p.width = aWidth || 100; + curElement.height = p.height = aHeight || 100; + curContext = getGLContext(curElement); + canTex = curContext.createTexture(); + textTex = curContext.createTexture() + } catch(e_size) { + Processing.debug(e_size) + } + if (!curContext) throw "WebGL context is not supported on this browser."; + 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); + programObject2D = createProgramObject(curContext, vertexShaderSrc2D, fragmentShaderSrc2D); + programObjectUnlitShape = createProgramObject(curContext, vertexShaderSrcUnlitShape, fragmentShaderSrcUnlitShape); + p.strokeWeight(1); + programObject3D = createProgramObject(curContext, vertexShaderSrc3D, fragmentShaderSrc3D); + 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); + p.emissive(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; + modelView = new PMatrix3D; + modelViewInv = new PMatrix3D; + projection = new PMatrix3D; + p.camera(); + p.perspective(); + userMatrixStack = new PMatrixStack; + userReverseMatrixStack = 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); + DrawingShared.prototype.size.apply(this, arguments) + } + }(); + Drawing2D.prototype.ambientLight = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.ambientLight = function(r, g, b, x, y, z) { + if (lightCount === 8) throw "can only create " + 8 + " 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); + var col = color$4(r, g, b, 0); + var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; + curContext.useProgram(programObject3D); + uniformf("uLights.color.3d." + lightCount, programObject3D, "uLights" + lightCount + ".color", normalizedCol); + uniformf("uLights.position.3d." + lightCount, programObject3D, "uLights" + lightCount + ".position", pos.array()); + uniformi("uLights.type.3d." + lightCount, programObject3D, "uLights" + lightCount + ".type", 0); + uniformi("uLightCount3d", programObject3D, "uLightCount", ++lightCount) + }; + Drawing2D.prototype.directionalLight = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.directionalLight = function(r, g, b, nx, ny, nz) { + if (lightCount === 8) throw "can only create " + 8 + " lights"; + curContext.useProgram(programObject3D); + var mvm = new PMatrix3D; + mvm.scale(1, -1, 1); + mvm.apply(modelView.array()); + mvm = mvm.array(); + var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; + var col = color$4(r, g, b, 0); + var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; + uniformf("uLights.color.3d." + lightCount, programObject3D, "uLights" + lightCount + ".color", normalizedCol); + uniformf("uLights.position.3d." + lightCount, programObject3D, "uLights" + lightCount + ".position", dir); + uniformi("uLights.type.3d." + lightCount, programObject3D, "uLights" + lightCount + ".type", 1); + uniformi("uLightCount3d", programObject3D, "uLightCount", ++lightCount) + }; + Drawing2D.prototype.lightFalloff = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.lightFalloff = function(constant, linear, quadratic) { + curContext.useProgram(programObject3D); + uniformf("uFalloff3d", programObject3D, "uFalloff", [constant, linear, quadratic]) + }; + Drawing2D.prototype.lightSpecular = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.lightSpecular = function(r, g, b) { + var col = color$4(r, g, b, 0); + var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; + curContext.useProgram(programObject3D); + uniformf("uSpecular3d", programObject3D, "uSpecular", normalizedCol) + }; + p.lights = function() { + p.ambientLight(128, 128, 128); + p.directionalLight(128, 128, 128, 0, 0, -1); + p.lightFalloff(1, 0, 0); + p.lightSpecular(0, 0, 0) + }; + Drawing2D.prototype.pointLight = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.pointLight = function(r, g, b, x, y, z) { + if (lightCount === 8) throw "can only create " + 8 + " 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); + var col = color$4(r, g, b, 0); + var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; + curContext.useProgram(programObject3D); + uniformf("uLights.color.3d." + lightCount, programObject3D, "uLights" + lightCount + ".color", normalizedCol); + uniformf("uLights.position.3d." + lightCount, programObject3D, "uLights" + lightCount + ".position", pos.array()); + uniformi("uLights.type.3d." + lightCount, programObject3D, "uLights" + lightCount + ".type", 2); + uniformi("uLightCount3d", programObject3D, "uLightCount", ++lightCount) + }; + Drawing2D.prototype.noLights = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.noLights = function() { + lightCount = 0; + curContext.useProgram(programObject3D); + uniformi("uLightCount3d", programObject3D, "uLightCount", lightCount) + }; + Drawing2D.prototype.spotLight = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.spotLight = function(r, g, b, x, y, z, nx, ny, nz, angle, concentration) { + if (lightCount === 8) throw "can only create " + 8 + " lights"; + curContext.useProgram(programObject3D); + var pos = new PVector(x, y, z); + var mvm = new PMatrix3D; + mvm.scale(1, -1, 1); + mvm.apply(modelView.array()); + mvm.mult(pos, pos); + mvm = mvm.array(); + var dir = [mvm[0] * nx + mvm[4] * ny + mvm[8] * nz, mvm[1] * + nx + mvm[5] * ny + mvm[9] * nz, mvm[2] * nx + mvm[6] * ny + mvm[10] * nz]; + var col = color$4(r, g, b, 0); + var normalizedCol = [((col >> 16) & 255) / 255, ((col >> 8) & 255) / 255, (col & 255) / 255]; + uniformf("uLights.color.3d." + lightCount, programObject3D, "uLights" + lightCount + ".color", normalizedCol); + uniformf("uLights.position.3d." + lightCount, programObject3D, "uLights" + lightCount + ".position", pos.array()); + uniformf("uLights.direction.3d." + lightCount, programObject3D, "uLights" + lightCount + ".direction", dir); + uniformf("uLights.concentration.3d." + lightCount, programObject3D, "uLights" + lightCount + ".concentration", concentration); + uniformf("uLights.angle.3d." + lightCount, programObject3D, "uLights" + lightCount + ".angle", angle); + uniformi("uLights.type.3d." + lightCount, programObject3D, "uLights" + lightCount + ".type", 3); + uniformi("uLightCount3d", programObject3D, "uLightCount", ++lightCount) + }; + Drawing2D.prototype.beginCamera = function() { + throw "beginCamera() is not available in 2D mode"; + }; + Drawing3D.prototype.beginCamera = function() { + if (manipulatingCamera) throw "You cannot call beginCamera() again before calling endCamera()"; + manipulatingCamera = true; + modelView = cameraInv; + modelViewInv = cam + }; + Drawing2D.prototype.endCamera = function() { + throw "endCamera() is not available in 2D mode"; + }; + Drawing3D.prototype.endCamera = function() { + if (!manipulatingCamera) throw "You cannot call endCamera() before calling beginCamera()"; + modelView.set(cam); + modelViewInv.set(cameraInv); + manipulatingCamera = false + }; + p.camera = function(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) { + if (eyeX === undef) { + cameraX = p.width / 2; + cameraY = p.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); + z.normalize(); + var x = PVector.cross(y, z); + y = PVector.cross(z, x); + x.normalize(); + y.normalize(); + var xX = x.x, + xY = x.y, + xZ = x.z; + var yX = y.x, + yY = y.y, + yZ = y.z; + var zX = z.x, + zY = z.y, + zZ = z.z; + cam.set(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); + cam.translate(-eyeX, -eyeY, -eyeZ); + cameraInv.reset(); + cameraInv.invApply(xX, xY, xZ, 0, yX, yY, yZ, 0, zX, zY, zZ, 0, 0, 0, 0, 1); + cameraInv.translate(eyeX, eyeY, eyeZ); + modelView.set(cam); + modelViewInv.set(cameraInv) + }; + p.perspective = function(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 = p.width / p.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) + }; + Drawing2D.prototype.frustum = function() { + throw "Processing.js: frustum() is not supported in 2D mode"; + }; + Drawing3D.prototype.frustum = function(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); + var proj = new PMatrix3D; + proj.set(projection); + proj.transpose(); + curContext.useProgram(programObject2D); + uniformMatrix("projection2d", programObject2D, "uProjection", false, proj.array()); + curContext.useProgram(programObject3D); + uniformMatrix("projection3d", programObject3D, "uProjection", false, proj.array()); + curContext.useProgram(programObjectUnlitShape); + uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()) + }; + p.ortho = function(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); + var proj = new PMatrix3D; + proj.set(projection); + proj.transpose(); + curContext.useProgram(programObject2D); + uniformMatrix("projection2d", programObject2D, "uProjection", false, proj.array()); + curContext.useProgram(programObject3D); + uniformMatrix("projection3d", programObject3D, "uProjection", false, proj.array()); + curContext.useProgram(programObjectUnlitShape); + uniformMatrix("uProjectionUS", programObjectUnlitShape, "uProjection", false, proj.array()); + frustumMode = false + }; + p.printProjection = function() { + projection.print() + }; + p.printCamera = function() { + cam.print() + }; + Drawing2D.prototype.box = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.box = function(w, h, d) { + 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(); + if (doFill) { + curContext.useProgram(programObject3D); + uniformMatrix("model3d", programObject3D, "uModel", false, model.array()); + uniformMatrix("view3d", programObject3D, "uView", false, view.array()); + curContext.enable(curContext.POLYGON_OFFSET_FILL); + curContext.polygonOffset(1, 1); + uniformf("color3d", programObject3D, "uColor", fillStyle); + if (lightCount > 0) { + 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("uNormalTransform3d", programObject3D, "uNormalTransform", false, normalMatrix.array()); + vertexAttribPointer("aNormal3d", programObject3D, "aNormal", 3, boxNormBuffer) + } else disableVertexAttribPointer("aNormal3d", programObject3D, "aNormal"); + vertexAttribPointer("aVertex3d", programObject3D, "aVertex", 3, boxBuffer); + disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); + disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); + curContext.drawArrays(curContext.TRIANGLES, 0, boxVerts.length / 3); + curContext.disable(curContext.POLYGON_OFFSET_FILL) + } + if (lineWidth > 0 && doStroke) { + curContext.useProgram(programObject2D); + uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array()); + uniformMatrix("uView2d", programObject2D, "uView", false, view.array()); + uniformf("uColor2d", programObject2D, "uColor", strokeStyle); + uniformi("uIsDrawingText2d", programObject2D, "uIsDrawingText", false); + vertexAttribPointer("vertex2d", programObject2D, "aVertex", 3, boxOutlineBuffer); + disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); + 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(sphereX[v1]); + sphereVerts.push(sphereY[v1]); + sphereVerts.push(sphereZ[v1++]); + sphereVerts.push(sphereX[v2]); + sphereVerts.push(sphereY[v2]); + sphereVerts.push(sphereZ[v2++]) + } + v1 = v11; + v2 = voff; + sphereVerts.push(sphereX[v1]); + sphereVerts.push(sphereY[v1]); + sphereVerts.push(sphereZ[v1]); + sphereVerts.push(sphereX[v2]); + sphereVerts.push(sphereY[v2]); + sphereVerts.push(sphereZ[v2]) + } + for (i = 0; i < sphereDetailU; i++) { + v2 = voff + i; + sphereVerts.push(sphereX[v2]); + sphereVerts.push(sphereY[v2]); + sphereVerts.push(sphereZ[v2]); + sphereVerts.push(0); + sphereVerts.push(1); + sphereVerts.push(0) + } + sphereVerts.push(sphereX[voff]); + sphereVerts.push(sphereY[voff]); + sphereVerts.push(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(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 = 720 / ures; + var cx = new Float32Array(ures); + var cz = new Float32Array(ures); + for (i = 0; i < ures; i++) { + cx[i] = cosLUT[i * delta % 720 | 0]; + cz[i] = sinLUT[i * delta % 720 | 0] + } + var vertCount = ures * (vres - 1) + 2; + var currVert = 0; + sphereX = new Float32Array(vertCount); + sphereY = new Float32Array(vertCount); + sphereZ = new Float32Array(vertCount); + var angle_step = 720 * 0.5 / vres; + var angle = angle_step; + for (i = 1; i < vres; i++) { + var curradius = sinLUT[angle % 720 | 0]; + var currY = -cosLUT[angle % 720 | 0]; + 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() + }; + Drawing2D.prototype.sphere = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.sphere = function() { + var sRad = arguments[0]; + 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(); + if (doFill) { + if (lightCount > 0) { + 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("uNormalTransform3d", programObject3D, "uNormalTransform", false, normalMatrix.array()); + vertexAttribPointer("aNormal3d", programObject3D, "aNormal", 3, sphereBuffer) + } else disableVertexAttribPointer("aNormal3d", programObject3D, "aNormal"); + curContext.useProgram(programObject3D); + disableVertexAttribPointer("aTexture3d", programObject3D, "aTexture"); + uniformMatrix("uModel3d", programObject3D, "uModel", false, model.array()); + uniformMatrix("uView3d", programObject3D, "uView", false, view.array()); + vertexAttribPointer("aVertex3d", programObject3D, "aVertex", 3, sphereBuffer); + disableVertexAttribPointer("aColor3d", programObject3D, "aColor"); + curContext.enable(curContext.POLYGON_OFFSET_FILL); + curContext.polygonOffset(1, 1); + uniformf("uColor3d", programObject3D, "uColor", fillStyle); + curContext.drawArrays(curContext.TRIANGLE_STRIP, 0, sphereVerts.length / 3); + curContext.disable(curContext.POLYGON_OFFSET_FILL) + } + if (lineWidth > 0 && doStroke) { + curContext.useProgram(programObject2D); + uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array()); + uniformMatrix("uView2d", programObject2D, "uView", false, view.array()); + vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, sphereBuffer); + disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); + uniformf("uColor2d", programObject2D, "uColor", strokeStyle); + uniformi("uIsDrawingText", programObject2D, "uIsDrawingText", false); + curContext.drawArrays(curContext.LINE_STRIP, 0, sphereVerts.length / 3) + } + }; + p.modelX = function(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(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(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 + }; + Drawing2D.prototype.ambient = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.ambient = function(v1, v2, v3) { + curContext.useProgram(programObject3D); + uniformi("uUsingMat3d", programObject3D, "uUsingMat", true); + var col = p.color(v1, v2, v3); + uniformf("uMaterialAmbient3d", programObject3D, "uMaterialAmbient", p.color.toGLArray(col).slice(0, 3)) + }; + Drawing2D.prototype.emissive = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.emissive = function(v1, v2, v3) { + curContext.useProgram(programObject3D); + uniformi("uUsingMat3d", programObject3D, "uUsingMat", true); + var col = p.color(v1, v2, v3); + uniformf("uMaterialEmissive3d", programObject3D, "uMaterialEmissive", p.color.toGLArray(col).slice(0, 3)) + }; + Drawing2D.prototype.shininess = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.shininess = function(shine) { + curContext.useProgram(programObject3D); + uniformi("uUsingMat3d", programObject3D, "uUsingMat", true); + uniformf("uShininess3d", programObject3D, "uShininess", shine) + }; + Drawing2D.prototype.specular = DrawingShared.prototype.a3DOnlyFunction; + Drawing3D.prototype.specular = function(v1, v2, v3) { + curContext.useProgram(programObject3D); + uniformi("uUsingMat3d", programObject3D, "uUsingMat", true); + var col = p.color(v1, v2, v3); + uniformf("uMaterialSpecular3d", programObject3D, "uMaterialSpecular", p.color.toGLArray(col).slice(0, 3)) + }; + p.screenX = function(x, y, z) { + var mv = modelView.array(); + if (mv.length === 16) { + 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 pj = projection.array(); + 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 + } + return modelView.multX(x, y) + }; + p.screenY = function screenY(x, y, z) { + var mv = modelView.array(); + if (mv.length === 16) { + 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 pj = projection.array(); + 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 + } + return modelView.multY(x, y) + }; + p.screenZ = function screenZ(x, y, z) { + var mv = modelView.array(); + if (mv.length !== 16) return 0; + 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 + }; + DrawingShared.prototype.fill = function() { + var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); + if (color === currentFillColor && doFill) return; + doFill = true; + currentFillColor = color + }; + Drawing2D.prototype.fill = function() { + DrawingShared.prototype.fill.apply(this, arguments); + isFillDirty = true + }; + Drawing3D.prototype.fill = function() { + DrawingShared.prototype.fill.apply(this, arguments); + fillStyle = p.color.toGLArray(currentFillColor) + }; + + function executeContextFill() { + if (doFill) { + if (isFillDirty) { + curContext.fillStyle = p.color.toString(currentFillColor); + isFillDirty = false + } + curContext.fill() + } + } + p.noFill = function() { + doFill = false + }; + DrawingShared.prototype.stroke = function() { + var color = p.color(arguments[0], arguments[1], arguments[2], arguments[3]); + if (color === currentStrokeColor && doStroke) return; + doStroke = true; + currentStrokeColor = color + }; + Drawing2D.prototype.stroke = function() { + DrawingShared.prototype.stroke.apply(this, arguments); + isStrokeDirty = true + }; + Drawing3D.prototype.stroke = function() { + DrawingShared.prototype.stroke.apply(this, arguments); + strokeStyle = p.color.toGLArray(currentStrokeColor) + }; + + function executeContextStroke() { + if (doStroke) { + if (isStrokeDirty) { + curContext.strokeStyle = p.color.toString(currentStrokeColor); + isStrokeDirty = false + } + curContext.stroke() + } + } + p.noStroke = function() { + doStroke = false + }; + DrawingShared.prototype.strokeWeight = function(w) { + lineWidth = w + }; + Drawing2D.prototype.strokeWeight = function(w) { + DrawingShared.prototype.strokeWeight.apply(this, arguments); + curContext.lineWidth = w + }; + Drawing3D.prototype.strokeWeight = function(w) { + DrawingShared.prototype.strokeWeight.apply(this, arguments); + curContext.useProgram(programObject2D); + uniformf("pointSize2d", programObject2D, "uPointSize", w); + curContext.useProgram(programObjectUnlitShape); + uniformf("pointSizeUnlitShape", programObjectUnlitShape, "uPointSize", w); + curContext.lineWidth(w) + }; + p.strokeCap = function(value) { + drawing.$ensureContext().lineCap = value + }; + p.strokeJoin = function(value) { + drawing.$ensureContext().lineJoin = value + }; + Drawing2D.prototype.smooth = function() { + renderSmooth = true; + var style = curElement.style; + style.setProperty("image-rendering", "optimizeQuality", "important"); + style.setProperty("-ms-interpolation-mode", "bicubic", "important"); + if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = true + }; + Drawing3D.prototype.smooth = function() { + renderSmooth = true + }; + Drawing2D.prototype.noSmooth = function() { + renderSmooth = false; + var style = curElement.style; + style.setProperty("image-rendering", "optimizeSpeed", "important"); + style.setProperty("image-rendering", "-moz-crisp-edges", "important"); + style.setProperty("image-rendering", "-webkit-optimize-contrast", "important"); + style.setProperty("image-rendering", "optimize-contrast", "important"); + style.setProperty("-ms-interpolation-mode", "nearest-neighbor", "important"); + if (curContext.hasOwnProperty("mozImageSmoothingEnabled")) curContext.mozImageSmoothingEnabled = false + }; + Drawing3D.prototype.noSmooth = function() { + renderSmooth = false + }; + Drawing2D.prototype.point = function(x, y) { + if (!doStroke) return; + x = Math.round(x); + y = Math.round(y); + curContext.fillStyle = p.color.toString(currentStrokeColor); + isFillDirty = true; + if (lineWidth > 1) { + curContext.beginPath(); + curContext.arc(x, y, lineWidth / 2, 0, 6.283185307179586, false); + curContext.fill() + } else curContext.fillRect(x, y, 1, 1) + }; + Drawing3D.prototype.point = function(x, y, z) { + 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(); + curContext.useProgram(programObject2D); + uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array()); + uniformMatrix("uView2d", programObject2D, "uView", false, view.array()); + if (lineWidth > 0 && doStroke) { + uniformf("uColor2d", programObject2D, "uColor", strokeStyle); + uniformi("uIsDrawingText2d", programObject2D, "uIsDrawingText", false); + uniformi("uSmooth2d", programObject2D, "uSmooth", renderSmooth); + vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, pointBuffer); + disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); + curContext.drawArrays(curContext.POINTS, 0, 1) + } + }; + p.beginShape = function(type) { + curShape = type; + curvePoints = []; + vertArray = [] + }; + Drawing2D.prototype.vertex = function(x, y, moveTo) { + var vert = []; + if (firstVert) firstVert = false; + vert["isVert"] = true; + vert[0] = x; + vert[1] = y; + vert[2] = 0; + vert[3] = 0; + vert[4] = 0; + vert[5] = currentFillColor; + vert[6] = currentStrokeColor; + vertArray.push(vert); + if (moveTo) vertArray[vertArray.length - 1]["moveTo"] = moveTo + }; + Drawing3D.prototype.vertex = function(x, y, z, u, v) { + var vert = []; + if (firstVert) firstVert = false; + vert["isVert"] = true; + if (v === undef && usingTexture) { + v = u; + u = z; + z = 0 + } + if (u !== undef && v !== undef) { + if (curTextureMode === 2) { + u /= curTexture.width; + v /= curTexture.height + } + u = u > 1 ? 1 : u; + u = u < 0 ? 0 : u; + v = v > 1 ? 1 : v; + v = v < 0 ? 0 : v + } + vert[0] = x; + vert[1] = y; + vert[2] = z || 0; + vert[3] = u || 0; + vert[4] = v || 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.push(vert) + }; + var point3D = function(vArray, cArray) { + var view = new PMatrix3D; + view.scale(1, -1, 1); + view.apply(modelView.array()); + view.transpose(); + curContext.useProgram(programObjectUnlitShape); + uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.array()); + uniformi("uSmoothUS", programObjectUnlitShape, "uSmooth", renderSmooth); + 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(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(); + curContext.useProgram(programObjectUnlitShape); + uniformMatrix("uViewUS", programObjectUnlitShape, "uView", false, view.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.drawArrays(ctxMode, 0, vArray.length / 3) + }; + var fill3D = function(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(); + curContext.useProgram(programObject3D); + uniformMatrix("model3d", programObject3D, "uModel", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); + uniformMatrix("view3d", programObject3D, "uView", false, view.array()); + curContext.enable(curContext.POLYGON_OFFSET_FILL); + curContext.polygonOffset(1, 1); + uniformf("color3d", programObject3D, "uColor", [-1, 0, 0, 0]); + vertexAttribPointer("vertex3d", programObject3D, "aVertex", 3, fillBuffer); + curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(vArray), curContext.STREAM_DRAW); + if (usingTexture && curTint !== null) curTint3d(cArray); + vertexAttribPointer("aColor3d", programObject3D, "aColor", 4, fillColorBuffer); + curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(cArray), curContext.STREAM_DRAW); + disableVertexAttribPointer("aNormal3d", programObject3D, "aNormal"); + if (usingTexture) { + uniformi("uUsingTexture3d", programObject3D, "uUsingTexture", 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) + }; + + function fillStrokeClose() { + executeContextFill(); + executeContextStroke(); + curContext.closePath() + } + Drawing2D.prototype.endShape = function(mode) { + if (vertArray.length === 0) return; + var closeShape = mode === 2; + if (closeShape) vertArray.push(vertArray[0]); + var lineVertArray = []; + var fillVertArray = []; + var colorVertArray = []; + var strokeVertArray = []; + var texVertArray = []; + var cachedVertArray; + firstVert = true; + var i, j, k; + var vertArrayLength = vertArray.length; + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + texVertArray.push(cachedVertArray[3]); + texVertArray.push(cachedVertArray[4]) + } + if (isCurve && (curShape === 20 || curShape === undef)) { + if (vertArrayLength > 3) { + var b = [], + s = 1 - curTightness; + curContext.beginPath(); + curContext.moveTo(vertArray[1][0], vertArray[1][1]); + for (i = 1; i + 2 < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + b[0] = [cachedVertArray[0], cachedVertArray[1]]; + b[1] = [cachedVertArray[0] + (s * vertArray[i + 1][0] - s * vertArray[i - 1][0]) / 6, cachedVertArray[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]) + } + fillStrokeClose() + } + } else if (isBezier && (curShape === 20 || curShape === undef)) { + curContext.beginPath(); + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + if (vertArray[i]["isVert"]) if (vertArray[i]["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); + else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); + else curContext.bezierCurveTo(vertArray[i][0], vertArray[i][1], vertArray[i][2], vertArray[i][3], vertArray[i][4], vertArray[i][5]) + } + fillStrokeClose() + } else if (curShape === 2) for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + if (doStroke) p.stroke(cachedVertArray[6]); + p.point(cachedVertArray[0], cachedVertArray[1]) + } else if (curShape === 4) for (i = 0; i + 1 < vertArrayLength; i += 2) { + cachedVertArray = vertArray[i]; + if (doStroke) p.stroke(vertArray[i + 1][6]); + p.line(cachedVertArray[0], cachedVertArray[1], vertArray[i + 1][0], vertArray[i + 1][1]) + } else if (curShape === 9) for (i = 0; i + 2 < vertArrayLength; i += 3) { + cachedVertArray = vertArray[i]; + curContext.beginPath(); + curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); + curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]); + curContext.lineTo(vertArray[i + 2][0], vertArray[i + 2][1]); + curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); + if (doFill) { + p.fill(vertArray[i + 2][5]); + executeContextFill() + } + if (doStroke) { + p.stroke(vertArray[i + 2][6]); + executeContextStroke() + } + curContext.closePath() + } else if (curShape === 10) for (i = 0; i + 1 < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + curContext.beginPath(); + curContext.moveTo(vertArray[i + 1][0], vertArray[i + 1][1]); + curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); + if (doStroke) p.stroke(vertArray[i + 1][6]); + if (doFill) p.fill(vertArray[i + 1][5]); + if (i + 2 < vertArrayLength) { + 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]) + } + fillStrokeClose() + } else if (curShape === 11) { + if (vertArrayLength > 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 < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + curContext.beginPath(); + curContext.moveTo(vertArray[0][0], vertArray[0][1]); + curContext.lineTo(vertArray[i - 1][0], vertArray[i - 1][1]); + curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); + if (doFill) { + p.fill(cachedVertArray[5]); + executeContextFill() + } + if (doStroke) { + p.stroke(cachedVertArray[6]); + executeContextStroke() + } + curContext.closePath() + } + } + } else if (curShape === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { + cachedVertArray = vertArray[i]; + curContext.beginPath(); + curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); + for (j = 1; j < 4; j++) curContext.lineTo(vertArray[i + j][0], vertArray[i + j][1]); + curContext.lineTo(cachedVertArray[0], cachedVertArray[1]); + if (doFill) { + p.fill(vertArray[i + 3][5]); + executeContextFill() + } + if (doStroke) { + p.stroke(vertArray[i + 3][6]); + executeContextStroke() + } + curContext.closePath() + } else if (curShape === 17) { + if (vertArrayLength > 3) for (i = 0; i + 1 < vertArrayLength; i += 2) { + cachedVertArray = vertArray[i]; + curContext.beginPath(); + if (i + 3 < vertArrayLength) { + curContext.moveTo(vertArray[i + 2][0], vertArray[i + 2][1]); + curContext.lineTo(cachedVertArray[0], cachedVertArray[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(cachedVertArray[0], cachedVertArray[1]); + curContext.lineTo(vertArray[i + 1][0], vertArray[i + 1][1]) + } + fillStrokeClose() + } + } else { + curContext.beginPath(); + curContext.moveTo(vertArray[0][0], vertArray[0][1]); + for (i = 1; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + if (cachedVertArray["isVert"]) if (cachedVertArray["moveTo"]) curContext.moveTo(cachedVertArray[0], cachedVertArray[1]); + else curContext.lineTo(cachedVertArray[0], cachedVertArray[1]) + } + fillStrokeClose() + } + isCurve = false; + isBezier = false; + curveVertArray = []; + curveVertCount = 0; + if (closeShape) vertArray.pop() + }; + Drawing3D.prototype.endShape = function(mode) { + if (vertArray.length === 0) return; + var closeShape = mode === 2; + var lineVertArray = []; + var fillVertArray = []; + var colorVertArray = []; + var strokeVertArray = []; + var texVertArray = []; + var cachedVertArray; + firstVert = true; + var i, j, k; + var vertArrayLength = vertArray.length; + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) fillVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + texVertArray.push(cachedVertArray[3]); + texVertArray.push(cachedVertArray[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 === 20 || curShape === undef)) { + lineVertArray = fillVertArray; + if (doStroke) line3D(lineVertArray, null, strokeVertArray); + if (doFill) fill3D(fillVertArray, null, colorVertArray) + } else if (isBezier && (curShape === 20 || curShape === undef)) { + 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 { + if (curShape === 2) { + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) + } + point3D(lineVertArray, strokeVertArray) + } else if (curShape === 4) { + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 5; j < 9; j++) colorVertArray.push(cachedVertArray[j]) + } + line3D(lineVertArray, "LINES", strokeVertArray) + } else if (curShape === 9) { + if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; 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 === 10) { + if (vertArrayLength > 2) for (i = 0; i + 2 < vertArrayLength; 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 === 11) { + if (vertArrayLength > 2) { + for (i = 0; i < 3; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < 3; i++) { + cachedVertArray = vertArray[i]; + for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) + } + if (doStroke) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); + for (i = 2; i + 1 < vertArrayLength; 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 === 16) for (i = 0; i + 3 < vertArrayLength; i += 4) { + lineVertArray = []; + for (j = 0; j < 4; j++) { + cachedVertArray = vertArray[i + j]; + for (k = 0; k < 3; k++) lineVertArray.push(cachedVertArray[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 === 17) { + var tempArray = []; + if (vertArrayLength > 3) { + for (i = 0; i < 2; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]) + } + for (i = 0; i < 2; i++) { + cachedVertArray = vertArray[i]; + for (j = 9; j < 13; j++) strokeVertArray.push(cachedVertArray[j]) + } + line3D(lineVertArray, "LINE_STRIP", strokeVertArray); + if (vertArrayLength > 4 && vertArrayLength % 2 > 0) { + tempArray = fillVertArray.splice(fillVertArray.length - 3); + vertArray.pop() + } + for (i = 0; i + 3 < vertArrayLength; 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 (vertArrayLength === 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 < vertArrayLength; i++) { + cachedVertArray = vertArray[i]; + for (j = 0; j < 3; j++) lineVertArray.push(cachedVertArray[j]); + for (j = 5; j < 9; j++) strokeVertArray.push(cachedVertArray[j]) + } + if (doStroke && closeShape) line3D(lineVertArray, "LINE_LOOP", strokeVertArray); + else if (doStroke && !closeShape) line3D(lineVertArray, "LINE_STRIP", strokeVertArray); + if (doFill || usingTexture) fill3D(fillVertArray, "TRIANGLE_FAN", colorVertArray, texVertArray) + } + usingTexture = false; + curContext.useProgram(programObject3D); + uniformi("usingTexture3d", programObject3D, "uUsingTexture", usingTexture) + } + 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) + }; + Drawing2D.prototype.bezierVertex = function() { + isBezier = true; + var vert = []; + if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; + for (var i = 0; i < arguments.length; i++) vert[i] = arguments[i]; + vertArray.push(vert); + vertArray[vertArray.length - 1]["isVert"] = false + }; + Drawing3D.prototype.bezierVertex = function() { + isBezier = true; + var vert = []; + if (firstVert) throw "vertex() must be used at least once before calling bezierVertex()"; + if (arguments.length === 9) { + 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]) + } + }; + p.texture = function(pimage) { + var curContext = drawing.$ensureContext(); + if (pimage.__texture) curContext.bindTexture(curContext.TEXTURE_2D, pimage.__texture); + else if (pimage.localName === "canvas") { + curContext.bindTexture(curContext.TEXTURE_2D, canTex); + curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, 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); + curTexture.width = pimage.width; + curTexture.height = pimage.height + } else { + var texture = curContext.createTexture(), + cvs = document.createElement("canvas"), + cvsTextureCtx = cvs.getContext("2d"), + 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 + } + cvsTextureCtx.drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width, cvs.height); + curContext.bindTexture(curContext.TEXTURE_2D, 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); + curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, cvs); + curContext.generateMipmap(curContext.TEXTURE_2D); + pimage.__texture = texture; + curTexture.width = pimage.width; + curTexture.height = pimage.height + } + usingTexture = true; + curContext.useProgram(programObject3D); + uniformi("usingTexture3d", programObject3D, "uUsingTexture", 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) + } + }; + Drawing2D.prototype.curveVertex = function(x, y) { + isCurve = true; + p.vertex(x, y) + }; + Drawing3D.prototype.curveVertex = function(x, y, z) { + isCurve = true; + 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]) + }; + Drawing2D.prototype.curve = function(x1, y1, x2, y2, x3, y3, x4, y4) { + p.beginShape(); + p.curveVertex(x1, y1); + p.curveVertex(x2, y2); + p.curveVertex(x3, y3); + p.curveVertex(x4, y4); + p.endShape() + }; + Drawing3D.prototype.curve = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) { + if (z4 !== undef) { + p.beginShape(); + p.curveVertex(x1, y1, z1); + p.curveVertex(x2, y2, z2); + p.curveVertex(x3, y3, z3); + p.curveVertex(x4, y4, z4); + p.endShape(); + return + } + p.beginShape(); + p.curveVertex(x1, y1); + p.curveVertex(z1, x2); + p.curveVertex(y2, z2); + p.curveVertex(x3, y3); + p.endShape() + }; + p.curveTightness = function(tightness) { + curTightness = tightness + }; + p.curveDetail = function(detail) { + curveDet = detail; + curveInit() + }; + p.rectMode = function(aRectMode) { + curRectMode = aRectMode + }; + p.imageMode = function(mode) { + switch (mode) { + case 0: + imageModeConvert = imageModeCorner; + break; + case 1: + imageModeConvert = imageModeCorners; + break; + case 3: + imageModeConvert = imageModeCenter; + break; + default: + throw "Invalid imageMode"; + } + }; + p.ellipseMode = function(aEllipseMode) { + curEllipseMode = aEllipseMode + }; + p.arc = function(x, y, width, height, start, stop) { + if (width <= 0 || stop < start) return; + if (curEllipseMode === 1) { + width = width - x; + height = height - y + } else if (curEllipseMode === 2) { + x = x - width; + y = y - height; + width = width * 2; + height = height * 2 + } else if (curEllipseMode === 3) { + x = x - width / 2; + y = y - height / 2 + } + while (start < 0) { + start += 6.283185307179586; + stop += 6.283185307179586 + } + if (stop - start > 6.283185307179586) { + start = 0; + stop = 6.283185307179586 + } + var hr = width / 2, + vr = height / 2, + centerX = x + hr, + centerY = y + vr, + startLUT = 0 | 0.5 + start * p.RAD_TO_DEG * 2, + stopLUT = 0 | 0.5 + stop * p.RAD_TO_DEG * 2, + i, j; + if (doFill) { + var savedStroke = doStroke; + doStroke = false; + p.beginShape(); + p.vertex(centerX, centerY); + for (i = startLUT; i <= stopLUT; i++) { + j = i % 720; + p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) + } + p.endShape(2); + doStroke = savedStroke + } + if (doStroke) { + var savedFill = doFill; + doFill = false; + p.beginShape(); + for (i = startLUT; i <= stopLUT; i++) { + j = i % 720; + p.vertex(centerX + cosLUT[j] * hr, centerY + sinLUT[j] * vr) + } + p.endShape(); + doFill = savedFill + } + }; + Drawing2D.prototype.line = function(x1, y1, x2, y2) { + if (!doStroke) return; + x1 = Math.round(x1); + x2 = Math.round(x2); + y1 = Math.round(y1); + y2 = Math.round(y2); + if (x1 === x2 && y1 === y2) { + p.point(x1, y1); + return + } + var swap = undef, + lineCap = undef, + drawCrisp = true, + currentModelView = modelView.array(), + identityMatrix = [1, 0, 0, 0, 1, 0]; + for (var i = 0; i < 6 && drawCrisp; i++) drawCrisp = currentModelView[i] === identityMatrix[i]; + if (drawCrisp) { + if (x1 === x2) { + if (y1 > y2) { + swap = y1; + y1 = y2; + y2 = swap + } + y2++; + if (lineWidth % 2 === 1) curContext.translate(0.5, 0) + } else if (y1 === y2) { + if (x1 > x2) { + swap = x1; + x1 = x2; + x2 = swap + } + x2++; + if (lineWidth % 2 === 1) curContext.translate(0, 0.5) + } + if (lineWidth === 1) { + lineCap = curContext.lineCap; + curContext.lineCap = "butt" + } + } + curContext.beginPath(); + curContext.moveTo(x1 || 0, y1 || 0); + curContext.lineTo(x2 || 0, y2 || 0); + executeContextStroke(); + if (drawCrisp) { + if (x1 === x2 && lineWidth % 2 === 1) curContext.translate(-0.5, 0); + else if (y1 === y2 && lineWidth % 2 === 1) curContext.translate(0, -0.5); + if (lineWidth === 1) curContext.lineCap = lineCap + } + }; + Drawing3D.prototype.line = function(x1, y1, z1, x2, y2, z2) { + if (y2 === undef || z2 === undef) { + z2 = 0; + y2 = x2; + x2 = z1; + z1 = 0 + } + if (x1 === x2 && y1 === y2 && z1 === z2) { + p.point(x1, y1, z1); + return + } + var lineVerts = [x1, y1, z1, x2, y2, z2]; + var view = new PMatrix3D; + view.scale(1, -1, 1); + view.apply(modelView.array()); + view.transpose(); + if (lineWidth > 0 && doStroke) { + curContext.useProgram(programObject2D); + uniformMatrix("uModel2d", programObject2D, "uModel", false, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); + uniformMatrix("uView2d", programObject2D, "uView", false, view.array()); + uniformf("uColor2d", programObject2D, "uColor", strokeStyle); + uniformi("uIsDrawingText", programObject2D, "uIsDrawingText", false); + vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, lineBuffer); + disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); + curContext.bufferData(curContext.ARRAY_BUFFER, new Float32Array(lineVerts), curContext.STREAM_DRAW); + curContext.drawArrays(curContext.LINES, 0, 2) + } + }; + Drawing2D.prototype.bezier = function() { + if (arguments.length !== 8) throw "You must use 8 parameters for bezier() in 2D mode"; + p.beginShape(); + p.vertex(arguments[0], arguments[1]); + p.bezierVertex(arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]); + p.endShape() + }; + Drawing3D.prototype.bezier = function() { + if (arguments.length !== 12) throw "You must use 12 parameters for bezier() in 3D mode"; + 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() + }; + p.bezierDetail = function(detail) { + bezDetail = detail + }; + p.bezierPoint = function(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(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(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(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(x1, y1, x2, y2, x3, y3) { + p.beginShape(9); + p.vertex(x1, y1, 0); + p.vertex(x2, y2, 0); + p.vertex(x3, y3, 0); + p.endShape() + }; + p.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { + p.beginShape(16); + p.vertex(x1, y1, 0); + p.vertex(x2, y2, 0); + p.vertex(x3, y3, 0); + p.vertex(x4, y4, 0); + p.endShape() + }; + var roundedRect$2d = function(x, y, width, height, tl, tr, br, bl) { + if (bl === undef) { + tr = tl; + br = tl; + bl = tl + } + var halfWidth = width / 2, + halfHeight = height / 2; + if (tl > halfWidth || tl > halfHeight) tl = Math.min(halfWidth, halfHeight); + if (tr > halfWidth || tr > halfHeight) tr = Math.min(halfWidth, halfHeight); + if (br > halfWidth || br > halfHeight) br = Math.min(halfWidth, halfHeight); + if (bl > halfWidth || bl > halfHeight) bl = Math.min(halfWidth, halfHeight); + if (!doFill || doStroke) curContext.translate(0.5, 0.5); + curContext.beginPath(); + curContext.moveTo(x + tl, y); + curContext.lineTo(x + width - tr, y); + curContext.quadraticCurveTo(x + width, y, x + width, y + tr); + curContext.lineTo(x + width, y + height - br); + curContext.quadraticCurveTo(x + width, y + height, x + width - br, y + height); + curContext.lineTo(x + bl, y + height); + curContext.quadraticCurveTo(x, y + height, x, y + height - bl); + curContext.lineTo(x, y + tl); + curContext.quadraticCurveTo(x, y, x + tl, y); + if (!doFill || doStroke) curContext.translate(-0.5, -0.5); + executeContextFill(); + executeContextStroke() + }; + Drawing2D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { + if (!width && !height) return; + if (curRectMode === 1) { + width -= x; + height -= y + } else if (curRectMode === 2) { + width *= 2; + height *= 2; + x -= width / 2; + y -= height / 2 + } else if (curRectMode === 3) { + x -= width / 2; + y -= height / 2 + } + x = Math.round(x); + y = Math.round(y); + width = Math.round(width); + height = Math.round(height); + if (tl !== undef) { + roundedRect$2d(x, y, width, height, tl, tr, br, bl); + return + } + if (doStroke && lineWidth % 2 === 1) curContext.translate(0.5, 0.5); + curContext.beginPath(); + curContext.rect(x, y, width, height); + executeContextFill(); + executeContextStroke(); + if (doStroke && lineWidth % 2 === 1) curContext.translate(-0.5, -0.5) + }; + Drawing3D.prototype.rect = function(x, y, width, height, tl, tr, br, bl) { + if (tl !== undef) throw "rect() with rounded corners is not supported in 3D mode"; + if (curRectMode === 1) { + width -= x; + height -= y + } else if (curRectMode === 2) { + width *= 2; + height *= 2; + x -= width / 2; + y -= height / 2 + } else if (curRectMode === 3) { + x -= width / 2; + y -= height / 2 + } + 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(); + if (lineWidth > 0 && doStroke) { + curContext.useProgram(programObject2D); + uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array()); + uniformMatrix("uView2d", programObject2D, "uView", false, view.array()); + uniformf("uColor2d", programObject2D, "uColor", strokeStyle); + uniformi("uIsDrawingText2d", programObject2D, "uIsDrawingText", false); + vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, rectBuffer); + disableVertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord"); + curContext.drawArrays(curContext.LINE_LOOP, 0, rectVerts.length / 3) + } + if (doFill) { + curContext.useProgram(programObject3D); + uniformMatrix("uModel3d", programObject3D, "uModel", false, model.array()); + uniformMatrix("uView3d", programObject3D, "uView", false, view.array()); + curContext.enable(curContext.POLYGON_OFFSET_FILL); + curContext.polygonOffset(1, 1); + uniformf("color3d", programObject3D, "uColor", fillStyle); + if (lightCount > 0) { + 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("uNormalTransform3d", programObject3D, "uNormalTransform", false, normalMatrix.array()); + vertexAttribPointer("aNormal3d", programObject3D, "aNormal", 3, rectNormBuffer) + } else disableVertexAttribPointer("normal3d", programObject3D, "aNormal"); + vertexAttribPointer("vertex3d", programObject3D, "aVertex", 3, rectBuffer); + curContext.drawArrays(curContext.TRIANGLE_FAN, 0, rectVerts.length / 3); + curContext.disable(curContext.POLYGON_OFFSET_FILL) + } + }; + Drawing2D.prototype.ellipse = function(x, y, width, height) { + x = x || 0; + y = y || 0; + if (width <= 0 && height <= 0) return; + if (curEllipseMode === 2) { + width *= 2; + height *= 2 + } else if (curEllipseMode === 1) { + width = width - x; + height = height - y; + x += width / 2; + y += height / 2 + } else if (curEllipseMode === 0) { + x += width / 2; + y += height / 2 + } + if (width === height) { + curContext.beginPath(); + curContext.arc(x, y, width / 2, 0, 6.283185307179586, false); + executeContextFill(); + executeContextStroke() + } else { + var w = width / 2, + h = height / 2, + C = 0.5522847498307933, + c_x = C * w, + c_y = C * h; + 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() + } + }; + Drawing3D.prototype.ellipse = function(x, y, width, height) { + x = x || 0; + y = y || 0; + if (width <= 0 && height <= 0) return; + if (curEllipseMode === 2) { + width *= 2; + height *= 2 + } else if (curEllipseMode === 1) { + width = width - x; + height = height - y; + x += width / 2; + y += height / 2 + } else if (curEllipseMode === 0) { + x += width / 2; + y += height / 2 + } + var w = width / 2, + h = height / 2, + C = 0.5522847498307933, + c_x = C * w, + c_y = C * h; + 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(); + if (doFill) { + 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(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 === 0) normalMode = 1; + else if (normalMode === 1) normalMode = 2 + }; + p.save = function(file, img) { + if (img !== undef) return window.open(img.toDataURL(), "_blank"); + return window.open(p.externals.canvas.toDataURL(), "_blank") + }; + var saveNumber = 0; + p.saveFrame = function(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 + } + function buildPixelsObject(pImage) { + return { + getLength: function(aImg) { + return function() { + if (aImg.isRemote) throw "Image is loaded remotely. Cannot get length."; + else return aImg.imageData.data.length ? aImg.imageData.data.length / 4 : 0 + } + }(pImage), + getPixel: function(aImg) { + return function(i) { + var offset = i * 4, + data = aImg.imageData.data; + if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; + return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 + } + }(pImage), + setPixel: function(aImg) { + return function(i, c) { + var offset = i * 4, + data = aImg.imageData.data; + if (aImg.isRemote) throw "Image is loaded remotely. Cannot set pixel."; + data[offset + 0] = (c >> 16) & 255; + data[offset + 1] = (c >> 8) & 255; + data[offset + 2] = c & 255; + data[offset + 3] = (c >> 24) & 255; + aImg.__isDirty = true + } + }(pImage), + toArray: function(aImg) { + return function() { + var arr = [], + data = aImg.imageData.data, + length = aImg.width * aImg.height; + if (aImg.isRemote) throw "Image is loaded remotely. Cannot get pixels."; + for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push((data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255); + return arr + } + }(pImage), + set: function(aImg) { + return function(arr) { + var offset, data, c; + if (this.isRemote) throw "Image is loaded remotely. Cannot set pixels."; + data = aImg.imageData.data; + for (var i = 0, aL = arr.length; i < aL; i++) { + c = arr[i]; + offset = i * 4; + data[offset + 0] = (c >> 16) & 255; + data[offset + 1] = (c >> 8) & 255; + data[offset + 2] = c & 255; + data[offset + 3] = (c >> 24) & 255 + } + aImg.__isDirty = true + } + }(pImage) + } + } + var PImage = function(aWidth, aHeight, aFormat) { + this.__isDirty = false; + if (aWidth instanceof HTMLImageElement) this.fromHTMLImageData(aWidth); + else if (aHeight || aFormat) { + this.width = aWidth || 1; + this.height = aHeight || 1; + var canvas = this.sourceImg = document.createElement("canvas"); + canvas.width = this.width; + canvas.height = this.height; + var imageData = this.imageData = canvas.getContext("2d").createImageData(this.width, this.height); + this.format = aFormat === 2 || aFormat === 4 ? aFormat : 1; + if (this.format === 1) for (var i = 3, data = this.imageData.data, len = data.length; i < len; i += 4) data[i] = 255; + this.__isDirty = true; + this.updatePixels() + } else { + this.width = 0; + this.height = 0; + this.imageData = utilityContext2d.createImageData(1, 1); + this.format = 2 + } + this.pixels = buildPixelsObject(this) + }; + PImage.prototype = { + __isPImage: true, + updatePixels: function() { + var canvas = this.sourceImg; + if (canvas && canvas instanceof HTMLCanvasElement && this.__isDirty) canvas.getContext("2d").putImageData(this.imageData, 0, 0); + this.__isDirty = false + }, + 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 + }, + "get": function(x, y, w, h) { + if (!arguments.length) return p.get(this); + if (arguments.length === 2) return p.get(x, y, this); + if (arguments.length === 4) return p.get(x, y, w, h, this) + }, + "set": function(x, y, c) { + p.set(x, y, c, this); + this.__isDirty = true + }, + 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 + }, + 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, 0, this); + else if (arguments.length === 9) p.blend(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight, 0, this); + delete this.sourceImg + }, + 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 + }, + save: function(file) { + p.save(file, this) + }, + resize: function(w, h) { + if (this.isRemote) throw "Image is loaded remotely. Cannot resize."; + 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) + } + }, + mask: function(mask) { + var obj = this.toImageData(), + i, size; + if (mask instanceof PImage || mask.__isPImage) if (mask.width === this.width && mask.height === this.height) { + mask = mask.toImageData(); + for (i = 2, size = this.width * this.height * 4; i < size; i += 4) obj.data[i + 1] = mask.data[i] + } else throw "mask must have the same dimensions as PImage."; + else if (mask instanceof + Array) if (this.width * this.height === mask.length) for (i = 0, size = mask.length; i < size; ++i) obj.data[i * 4 + 3] = mask[i]; + else throw "mask array must be the same length as PImage pixels array."; + this.fromImageData(obj) + }, + loadPixels: nop, + toImageData: function() { + if (this.isRemote) return this.sourceImg; + if (!this.__isDirty) return this.imageData; + var canvasData = getCanvasData(this.sourceImg); + return canvasData.context.getImageData(0, 0, this.width, this.height) + }, + toDataURL: function() { + if (this.isRemote) throw "Image is loaded remotely. Cannot create dataURI."; + var canvasData = getCanvasData(this.imageData); + return canvasData.canvas.toDataURL() + }, + fromImageData: function(canvasImg) { + var w = canvasImg.width, + h = canvasImg.height, + canvas = document.createElement("canvas"), + ctx = canvas.getContext("2d"); + this.width = canvas.width = w; + this.height = canvas.height = h; + ctx.putImageData(canvasImg, 0, 0); + this.format = 2; + this.imageData = canvasImg; + this.sourceImg = canvas + } + }; + p.PImage = PImage; + p.createImage = function(w, h, mode) { + return new PImage(w, h, mode) + }; + p.loadImage = function(file, type, callback) { + if (type) file = file + "." + type; + var pimg; + if (curSketch.imageCache.images[file]) { + pimg = new PImage(curSketch.imageCache.images[file]); + pimg.loaded = true; + return pimg + } + 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$2(x, y) { + var data; + if (x >= p.width || x < 0 || y < 0 || y >= p.height) return 0; + if (isContextReplaced) { + var offset = ((0 | x) + p.width * (0 | y)) * 4; + data = p.imageData.data; + return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 + } + data = p.toImageData(0 | x, 0 | y, 1, 1).data; + return (data[3] & 255) << 24 | (data[0] & 255) << 16 | (data[1] & 255) << 8 | data[2] & 255 + } + function get$3(x, y, img) { + if (img.isRemote) throw "Image is loaded remotely. Cannot get x,y."; + var offset = y * img.width * 4 + x * 4, + data = img.imageData.data; + return (data[offset + 3] & 255) << 24 | (data[offset] & 255) << 16 | (data[offset + 1] & 255) << 8 | data[offset + 2] & 255 + } + function get$4(x, y, w, h) { + var c = new PImage(w, h, 2); + c.fromImageData(p.toImageData(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."; + var c = new PImage(w, h, 2), + 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++] + } + } + c.__isDirty = true; + return c + } + p.get = function(x, y, w, h, img) { + if (img !== undefined) return get$5(x, y, w, h, img); + if (h !== undefined) return get$4(x, y, w, h); + if (w !== undefined) return get$3(x, y, w); + if (y !== undefined) return get$2(x, y); + if (x !== undefined) return get$5(0, 0, x.width, x.height, x); + return get$4(0, 0, p.width, p.height) + }; + p.createGraphics = function(w, h, render) { + var pg = new Processing; + pg.size(w, h, render); + pg.background(0, 0); + 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."; + 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(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 || obj.__isPImage) 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, + data = p.imageData.data; + return data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255 + }, + setPixel: function(i, c) { + var offset = i * 4, + data = p.imageData.data; + data[offset + 0] = (c & 16711680) >>> 16; + data[offset + 1] = (c & 65280) >>> 8; + data[offset + 2] = c & 255; + data[offset + 3] = (c & 4278190080) >>> 24 + }, + toArray: function() { + var arr = [], + length = p.imageData.width * p.imageData.height, + data = p.imageData.data; + for (var i = 0, offset = 0; i < length; i++, offset += 4) arr.push(data[offset + 3] << 24 & 4278190080 | data[offset + 0] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255); + return arr + }, + set: function(arr) { + for (var i = 0, aL = arr.length; i < aL; i++) this.setPixel(i, arr[i]) + } + }; + p.loadPixels = function() { + p.imageData = drawing.$ensureContext().getImageData(0, 0, p.width, p.height) + }; + p.updatePixels = function() { + if (p.imageData) drawing.$ensureContext().putImageData(p.imageData, 0, 0) + }; + p.hint = function(which) { + var curContext = drawing.$ensureContext(); + if (which === 4) { + curContext.disable(curContext.DEPTH_TEST); + curContext.depthMask(false); + curContext.clear(curContext.DEPTH_BUFFER_BIT) + } else if (which === -4) { + curContext.enable(curContext.DEPTH_TEST); + curContext.depthMask(true) + } else if (which === -1 || which === 2) renderSmooth = true; + else if (which === 1) renderSmooth = false + }; + var backgroundHelper = function(arg1, arg2, arg3, arg4) { + var obj; + if (arg1 instanceof PImage || arg1.__isPImage) { + obj = arg1; + if (!obj.loaded) throw "Error using image in background(): PImage not loaded."; + if (obj.width !== p.width || obj.height !== p.height) throw "Background image must be the same dimensions as the canvas."; + } else obj = p.color(arg1, arg2, arg3, arg4); + backgroundObj = obj + }; + Drawing2D.prototype.background = function(arg1, arg2, arg3, arg4) { + if (arg1 !== undef) backgroundHelper(arg1, arg2, arg3, arg4); + if (backgroundObj instanceof PImage || backgroundObj.__isPImage) { + saveContext(); + curContext.setTransform(1, 0, 0, 1, 0, 0); + p.image(backgroundObj, 0, 0); + restoreContext() + } else { + saveContext(); + curContext.setTransform(1, 0, 0, 1, 0, 0); + if (p.alpha(backgroundObj) !== colorModeA) curContext.clearRect(0, 0, p.width, p.height); + curContext.fillStyle = p.color.toString(backgroundObj); + curContext.fillRect(0, 0, p.width, p.height); + isFillDirty = true; + restoreContext() + } + }; + Drawing3D.prototype.background = function(arg1, arg2, arg3, arg4) { + if (arguments.length > 0) backgroundHelper(arg1, arg2, arg3, arg4); + var c = p.color.toGLArray(backgroundObj); + curContext.clearColor(c[0], c[1], c[2], c[3]); + curContext.clear(curContext.COLOR_BUFFER_BIT | curContext.DEPTH_BUFFER_BIT) + }; + Drawing2D.prototype.image = function(img, x, y, w, h) { + x = Math.round(x); + y = Math.round(y); + if (img.width > 0) { + var wid = w || img.width; + var hgt = h || img.height; + var bounds = imageModeConvert(x || 0, y || 0, w || img.width, h || img.height, arguments.length < 4); + var fastImage = !!img.sourceImg && curTint === null; + if (fastImage) { + var htmlElement = img.sourceImg; + if (img.__isDirty) img.updatePixels(); + curContext.drawImage(htmlElement, 0, 0, htmlElement.width, htmlElement.height, bounds.x, bounds.y, bounds.w, bounds.h) + } else { + var obj = img.toImageData(); + if (curTint !== null) { + curTint(obj); + img.__isDirty = true + } + curContext.drawImage(getCanvasData(obj).canvas, 0, 0, img.width, img.height, bounds.x, bounds.y, bounds.w, bounds.h) + } + } + }; + Drawing3D.prototype.image = function(img, x, y, w, h) { + if (img.width > 0) { + x = Math.round(x); + y = Math.round(y); + w = w || img.width; + h = h || img.height; + p.beginShape(p.QUADS); + p.texture(img); + p.vertex(x, y, 0, 0, 0); + p.vertex(x, y + h, 0, 0, h); + p.vertex(x + w, y + h, 0, w, h); + p.vertex(x + w, y, 0, w, 0); + p.endShape() + } + }; + p.tint = function(a1, a2, a3, a4) { + var tintColor = p.color(a1, a2, a3, a4); + 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 + } + }; + curTint3d = function(data) { + for (var i = 0; i < data.length;) { + data[i++] = r; + data[i++] = g; + data[i++] = b; + data[i++] = a + } + } + }; + p.noTint = function() { + curTint = null; + curTint3d = null + }; + p.copy = function(src, sx, sy, sw, sh, dx, dy, dw, dh) { + if (dh === undef) { + 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, 0) + }; + p.blend = function(src, sx, sy, sw, sh, dx, dy, dw, dh, mode, pimgdest) { + if (src.isRemote) throw "Image is loaded remotely. Cannot blend image."; + if (mode === undef) { + mode = dh; + dh = dw; + dw = dy; + dy = dx; + dx = sh; + sh = sw; + sw = sy; + sy = sx; + sx = src; + src = p + } + var sx2 = sx + sw, + sy2 = sy + sh, + dx2 = dx + dw, + dy2 = dy + dh, + dest = pimgdest || p; + if (pimgdest === undef || mode === undef) p.loadPixels(); + src.loadPixels(); + if (src === p && 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); + if (pimgdest === undef) p.updatePixels() + }; + var buildBlurKernel = function(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 Float32Array(p.shared.blurKernelSize); + var sharedBlurKernal = p.shared.blurKernel; + var sharedBlurKernelSize = p.shared.blurKernelSize; + var sharedBlurRadius = p.shared.blurRadius; + for (i = 0; i < sharedBlurKernelSize; i++) sharedBlurKernal[i] = 0; + var radiusiSquared = (radius - 1) * (radius - 1); + for (i = 1; i < radius; i++) sharedBlurKernal[radius + i] = sharedBlurKernal[radiusi] = radiusiSquared; + sharedBlurKernal[radius] = radius * radius + } + }; + var blurARGB = function(r, aImg) { + var sum, cr, cg, cb, ca, c, m; + var read, ri, ym, ymi, bk0; + var wh = aImg.pixels.getLength(); + var r2 = new Float32Array(wh); + var g2 = new Float32Array(wh); + var b2 = new Float32Array(wh); + var a2 = new Float32Array(wh); + var yi = 0; + var x, y, i, offset; + buildBlurKernel(r); + var aImgHeight = aImg.height; + var aImgWidth = aImg.width; + var sharedBlurKernelSize = p.shared.blurKernelSize; + var sharedBlurRadius = p.shared.blurRadius; + var sharedBlurKernal = p.shared.blurKernel; + var pix = aImg.imageData.data; + for (y = 0; y < aImgHeight; y++) { + for (x = 0; x < aImgWidth; x++) { + cb = cg = cr = ca = sum = 0; + read = x - sharedBlurRadius; + if (read < 0) { + bk0 = -read; + read = 0 + } else { + if (read >= aImgWidth) break; + bk0 = 0 + } + for (i = bk0; i < sharedBlurKernelSize; i++) { + if (read >= aImgWidth) break; + offset = (read + yi) * 4; + m = sharedBlurKernal[i]; + ca += m * pix[offset + 3]; + cr += m * pix[offset]; + cg += m * pix[offset + 1]; + cb += m * pix[offset + 2]; + sum += m; + read++ + } + ri = yi + x; + a2[ri] = ca / sum; + r2[ri] = cr / sum; + g2[ri] = cg / sum; + b2[ri] = cb / sum + } + yi += aImgWidth + } + yi = 0; + ym = -sharedBlurRadius; + ymi = ym * aImgWidth; + for (y = 0; y < aImgHeight; y++) { + for (x = 0; x < aImgWidth; x++) { + cb = cg = cr = ca = sum = 0; + if (ym < 0) { + bk0 = ri = -ym; + read = x + } else { + if (ym >= aImgHeight) break; + bk0 = 0; + ri = ym; + read = x + ymi + } + for (i = bk0; i < sharedBlurKernelSize; i++) { + if (ri >= aImgHeight) break; + m = sharedBlurKernal[i]; + ca += m * a2[read]; + cr += m * r2[read]; + cg += m * g2[read]; + cb += m * b2[read]; + sum += m; + ri++; + read += aImgWidth + } + offset = (x + yi) * 4; + pix[offset] = cr / sum; + pix[offset + 1] = cg / sum; + pix[offset + 2] = cb / sum; + pix[offset + 3] = ca / sum + } + yi += aImgWidth; + ymi += aImgWidth; + ym++ + } + }; + var dilate = function(isInverted, aImg) { + var currIdx = 0; + var maxIdx = aImg.pixels.getLength(); + var out = new Int32Array(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(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."; + var imglen = img.pixels.getLength(); + switch (kind) { + case 11: + var radius = param || 1; + blurARGB(radius, img); + break; + case 12: + if (img.format === 4) { + for (i = 0; i < imglen; i++) { + col = 255 - img.pixels.getPixel(i); + img.pixels.setPixel(i, 4278190080 | col << 16 | col << 8 | col) + } + img.format = 1 + } 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 & 4278190080 | lum << 16 | lum << 8 | lum) + } + break; + case 13: + for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) ^ 16777215); + break; + case 15: + 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 14: + for (i = 0; i < imglen; i++) img.pixels.setPixel(i, img.pixels.getPixel(i) | 4278190080); + img.format = 1; + break; + case 16: + 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) & 16711680) >> 16, p.max((img.pixels.getPixel(i) & 65280) >> 8, img.pixels.getPixel(i) & 255)); + img.pixels.setPixel(i, img.pixels.getPixel(i) & 4278190080 | (max < thresh ? 0 : 16777215)) + } + break; + case 17: + dilate(true, img); + break; + case 18: + 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(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) + }; + var blendFuncs = {}; + blendFuncs[1] = p.modes.blend; + blendFuncs[2] = p.modes.add; + blendFuncs[4] = p.modes.subtract; + blendFuncs[8] = p.modes.lightest; + blendFuncs[16] = p.modes.darkest; + blendFuncs[0] = p.modes.replace; + blendFuncs[32] = p.modes.difference; + blendFuncs[64] = p.modes.exclusion; + blendFuncs[128] = p.modes.multiply; + blendFuncs[256] = p.modes.screen; + blendFuncs[512] = p.modes.overlay; + blendFuncs[1024] = p.modes.hard_light; + blendFuncs[2048] = p.modes.soft_light; + blendFuncs[4096] = p.modes.dodge; + blendFuncs[8192] = p.modes.burn; + p.blit_resize = function(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; + 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 * 32768); + var dy = Math.floor(srcH / destH * 32768); + var pshared = p.shared; + pshared.srcXOffset = Math.floor(destX1 < 0 ? -destX1 * dx : srcX1 * 32768); + pshared.srcYOffset = Math.floor(destY1 < 0 ? -destY1 * dy : srcY1 * 32768); + 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; + pshared.srcBuffer = img.imageData.data; + pshared.iw = img.width; + pshared.iw1 = img.width - 1; + pshared.ih1 = img.height - 1; + var filterBilinear = p.filter_bilinear, + filterNewScanline = p.filter_new_scanline, + blendFunc = blendFuncs[mode], + blendedColor, idx, cULoffset, cURoffset, cLLoffset, cLRoffset, ALPHA_MASK = 4278190080, + RED_MASK = 16711680, + GREEN_MASK = 65280, + BLUE_MASK = 255, + PREC_MAXVAL = 32767, + PRECISIONB = 15, + PREC_RED_SHIFT = 1, + PREC_ALPHA_SHIFT = 9, + srcBuffer = pshared.srcBuffer, + min = Math.min; + for (y = 0; y < destH; y++) { + pshared.sX = pshared.srcXOffset; + pshared.fracV = pshared.srcYOffset & PREC_MAXVAL; + pshared.ifV = PREC_MAXVAL - pshared.fracV; + pshared.v1 = (pshared.srcYOffset >> PRECISIONB) * pshared.iw; + pshared.v2 = min((pshared.srcYOffset >> PRECISIONB) + 1, pshared.ih1) * pshared.iw; + for (x = 0; x < destW; x++) { + idx = (destOffset + x) * 4; + destColor = destPixels[idx + 3] << 24 & ALPHA_MASK | destPixels[idx] << 16 & RED_MASK | destPixels[idx + 1] << 8 & GREEN_MASK | destPixels[idx + 2] & BLUE_MASK; + pshared.fracU = pshared.sX & PREC_MAXVAL; + pshared.ifU = PREC_MAXVAL - pshared.fracU; + pshared.ul = pshared.ifU * pshared.ifV >> PRECISIONB; + pshared.ll = pshared.ifU * pshared.fracV >> PRECISIONB; + pshared.ur = pshared.fracU * pshared.ifV >> PRECISIONB; + pshared.lr = pshared.fracU * pshared.fracV >> PRECISIONB; + pshared.u1 = pshared.sX >> PRECISIONB; + pshared.u2 = min(pshared.u1 + 1, pshared.iw1); + cULoffset = (pshared.v1 + pshared.u1) * 4; + cURoffset = (pshared.v1 + pshared.u2) * 4; + cLLoffset = (pshared.v2 + pshared.u1) * 4; + cLRoffset = (pshared.v2 + pshared.u2) * 4; + pshared.cUL = srcBuffer[cULoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cULoffset] << 16 & RED_MASK | srcBuffer[cULoffset + 1] << 8 & GREEN_MASK | srcBuffer[cULoffset + 2] & BLUE_MASK; + pshared.cUR = srcBuffer[cURoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cURoffset] << 16 & RED_MASK | srcBuffer[cURoffset + 1] << 8 & GREEN_MASK | srcBuffer[cURoffset + 2] & BLUE_MASK; + pshared.cLL = srcBuffer[cLLoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLLoffset] << 16 & RED_MASK | srcBuffer[cLLoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLLoffset + 2] & BLUE_MASK; + pshared.cLR = srcBuffer[cLRoffset + 3] << 24 & ALPHA_MASK | srcBuffer[cLRoffset] << 16 & RED_MASK | srcBuffer[cLRoffset + 1] << 8 & GREEN_MASK | srcBuffer[cLRoffset + 2] & BLUE_MASK; + pshared.r = pshared.ul * ((pshared.cUL & RED_MASK) >> 16) + pshared.ll * ((pshared.cLL & RED_MASK) >> 16) + pshared.ur * ((pshared.cUR & RED_MASK) >> 16) + pshared.lr * ((pshared.cLR & RED_MASK) >> 16) << PREC_RED_SHIFT & RED_MASK; + pshared.g = pshared.ul * (pshared.cUL & GREEN_MASK) + pshared.ll * (pshared.cLL & GREEN_MASK) + pshared.ur * (pshared.cUR & GREEN_MASK) + pshared.lr * (pshared.cLR & GREEN_MASK) >>> PRECISIONB & GREEN_MASK; + pshared.b = pshared.ul * (pshared.cUL & BLUE_MASK) + pshared.ll * (pshared.cLL & BLUE_MASK) + pshared.ur * (pshared.cUR & BLUE_MASK) + pshared.lr * (pshared.cLR & BLUE_MASK) >>> PRECISIONB; + pshared.a = pshared.ul * ((pshared.cUL & ALPHA_MASK) >>> 24) + pshared.ll * ((pshared.cLL & ALPHA_MASK) >>> 24) + pshared.ur * ((pshared.cUR & ALPHA_MASK) >>> 24) + pshared.lr * ((pshared.cLR & ALPHA_MASK) >>> 24) << PREC_ALPHA_SHIFT & ALPHA_MASK; + blendedColor = blendFunc(destColor, pshared.a | pshared.r | pshared.g | pshared.b); + destPixels[idx] = (blendedColor & RED_MASK) >>> 16; + destPixels[idx + 1] = (blendedColor & GREEN_MASK) >>> 8; + destPixels[idx + 2] = blendedColor & BLUE_MASK; + destPixels[idx + 3] = (blendedColor & ALPHA_MASK) >>> 24; + pshared.sX += dx + } + destOffset += screenW; + pshared.srcYOffset += dy + } + }; + p.loadFont = function(name, size) { + if (name === undef) throw "font name required in loadFont."; + if (name.indexOf(".svg") === -1) { + if (size === undef) size = curTextFont.size; + return PFont.get(name, size) + } + var font = p.loadGlyphs(name); + return { + name: name, + css: "12px sans-serif", + 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) { + return p.loadFont(name, size) + }; + p.textFont = function(pfont, size) { + if (size !== undef) { + if (!pfont.glyph) pfont = PFont.get(pfont.name, size); + curTextSize = size + } + curTextFont = pfont; + curFontName = curTextFont.name; + curTextAscent = curTextFont.ascent; + curTextDescent = curTextFont.descent; + curTextLeading = curTextFont.leading; + var curContext = drawing.$ensureContext(); + curContext.font = curTextFont.css + }; + p.textSize = function(size) { + curTextFont = PFont.get(curFontName, size); + curTextSize = size; + curTextAscent = curTextFont.ascent; + curTextDescent = curTextFont.descent; + curTextLeading = curTextFont.leading; + var curContext = drawing.$ensureContext(); + curContext.font = curTextFont.css + }; + p.textAscent = function() { + return curTextAscent + }; + p.textDescent = function() { + return curTextDescent + }; + p.textLeading = function(leading) { + curTextLeading = leading + }; + p.textAlign = function(xalign, yalign) { + horizontalTextAlignment = xalign; + verticalTextAlignment = yalign || 0 + }; + + function toP5String(obj) { + if (obj instanceof String) return obj; + if (typeof obj === "number") { + if (obj === (0 | obj)) return obj.toString(); + return p.nf(obj, 0, 3) + } + if (obj === null || obj === undef) return ""; + return obj.toString() + } + Drawing2D.prototype.textWidth = function(str) { + var lines = toP5String(str).split(/\r?\n/g), + width = 0; + var i, linesCount = lines.length; + curContext.font = curTextFont.css; + for (i = 0; i < linesCount; ++i) width = Math.max(width, curTextFont.measureTextWidth(lines[i])); + return width | 0 + }; + Drawing3D.prototype.textWidth = function(str) { + var lines = toP5String(str).split(/\r?\n/g), + width = 0; + var i, linesCount = lines.length; + if (textcanvas === undef) textcanvas = document.createElement("canvas"); + var textContext = textcanvas.getContext("2d"); + textContext.font = curTextFont.css; + for (i = 0; i < linesCount; ++i) width = Math.max(width, textContext.measureText(lines[i]).width); + return width | 0 + }; + p.glyphLook = function(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) + } + }; + Drawing2D.prototype.text$line = function(str, x, y, z, align) { + var textWidth = 0, + xOffset = 0; + if (!curTextFont.glyph) { + if (str && "fillText" in curContext) { + if (isFillDirty) { + curContext.fillStyle = p.color.toString(currentFillColor); + isFillDirty = false + } + if (align === 39 || align === 3) { + textWidth = curTextFont.measureTextWidth(str); + if (align === 39) xOffset = -textWidth; + else xOffset = -textWidth / 2 + } + curContext.fillText(str, x + xOffset, y) + } + } else { + var font = p.glyphTable[curFontName]; + saveContext(); + curContext.translate(x, y + curTextSize); + if (align === 39 || align === 3) { + textWidth = font.width(str); + if (align === 39) 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() + } + }; + Drawing3D.prototype.text$line = function(str, x, y, z, align) { + if (textcanvas === undef) textcanvas = document.createElement("canvas"); + var oldContext = curContext; + curContext = textcanvas.getContext("2d"); + curContext.font = curTextFont.css; + var textWidth = curTextFont.measureTextWidth(str); + textcanvas.width = textWidth; + textcanvas.height = curTextSize; + curContext = textcanvas.getContext("2d"); + curContext.font = curTextFont.css; + curContext.textBaseline = "top"; + Drawing2D.prototype.text$line(str, 0, 0, 0, 37); + var aspect = textcanvas.width / textcanvas.height; + curContext = oldContext; + curContext.bindTexture(curContext.TEXTURE_2D, textTex); + curContext.texImage2D(curContext.TEXTURE_2D, 0, curContext.RGBA, curContext.RGBA, curContext.UNSIGNED_BYTE, 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 === 39) xOffset = -textWidth; + else if (align === 3) 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(); + curContext.useProgram(programObject2D); + vertexAttribPointer("aVertex2d", programObject2D, "aVertex", 3, textBuffer); + vertexAttribPointer("aTextureCoord2d", programObject2D, "aTextureCoord", 2, textureBuffer); + uniformi("uSampler2d", programObject2D, "uSampler", [0]); + uniformi("uIsDrawingText2d", programObject2D, "uIsDrawingText", true); + uniformMatrix("uModel2d", programObject2D, "uModel", false, model.array()); + uniformMatrix("uView2d", programObject2D, "uView", false, view.array()); + uniformf("uColor2d", programObject2D, "uColor", 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 lines, linesCount; + if (str.indexOf("\n") < 0) { + lines = [str]; + linesCount = 1 + } else { + lines = str.split(/\r?\n/g); + linesCount = lines.length + } + var yOffset = 0; + if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; + else if (verticalTextAlignment === 3) yOffset = curTextAscent / 2 - (linesCount - 1) * curTextLeading / 2; + else if (verticalTextAlignment === 102) yOffset = -(curTextDescent + (linesCount - 1) * curTextLeading); + for (var i = 0; i < linesCount; ++i) { + var line = lines[i]; + drawing.text$line(line, x, y + yOffset, z, horizontalTextAlignment); + yOffset += curTextLeading + } + } + function text$6(str, x, y, width, height, z) { + if (str.length === 0 || width === 0 || height === 0) return; + if (curTextSize > height) return; + var spaceMark = -1; + var start = 0; + var lineWidth = 0; + var drawCommands = []; + for (var charPos = 0, len = str.length; charPos < len; charPos++) { + var currentChar = str[charPos]; + var spaceChar = currentChar === " "; + var letterWidth = curTextFont.measureTextWidth(currentChar); + if (currentChar !== "\n" && lineWidth + letterWidth <= width) { + if (spaceChar) spaceMark = charPos; + lineWidth += letterWidth + } else { + if (spaceMark + 1 === start) if (charPos > 0) spaceMark = charPos; + else return; + if (currentChar === "\n") { + drawCommands.push({ + text: str.substring(start, charPos), + width: lineWidth + }); + start = charPos + 1 + } else { + drawCommands.push({ + text: str.substring(start, spaceMark + 1), + width: lineWidth + }); + start = spaceMark + 1 + } + lineWidth = 0; + charPos = start - 1 + } + } + if (start < len) drawCommands.push({ + text: str.substring(start), + width: lineWidth + }); + var xOffset = 1, + yOffset = curTextAscent; + if (horizontalTextAlignment === 3) xOffset = width / 2; + else if (horizontalTextAlignment === 39) xOffset = width; + var linesCount = drawCommands.length, + visibleLines = Math.min(linesCount, Math.floor(height / curTextLeading)); + if (verticalTextAlignment === 101) yOffset = curTextAscent + curTextDescent; + else if (verticalTextAlignment === 3) yOffset = height / 2 - curTextLeading * (visibleLines / 2 - 1); + else if (verticalTextAlignment === 102) yOffset = curTextDescent + curTextLeading; + var command, drawCommand, leading; + for (command = 0; command < linesCount; command++) { + leading = command * curTextLeading; + if (yOffset + leading > height - curTextDescent) break; + drawCommand = drawCommands[command]; + drawing.text$line(drawCommand.text, x + xOffset, y + yOffset + leading, z, horizontalTextAlignment) + } + } + p.text = function() { + if (textMode === 5) return; + 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(mode) { + textMode = mode + }; + p.loadGlyphs = function(url) { + var x, y, cx, cy, nx, ny, d, a, lastCom, lenC, horiz_adv_x, getXY = "[0-9\\-]+", + path; + var regex = function(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(d) { + var c = regex("[A-Za-z][0-9\\- ]+|Z", d); + var beforePathDraw = function() { + saveContext(); + return drawing.$ensureContext() + }; + var afterPathDraw = function() { + executeContextFill(); + executeContextStroke(); + restoreContext() + }; + path = "return {draw:function(){var curContext=beforePathDraw();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 += "afterPathDraw();"; + path += "curContext.translate(" + horiz_adv_x + ",0);"; + path += "}}"; + return (new Function("beforePathDraw", "afterPathDraw", path))(beforePathDraw, afterPathDraw) + }; + var parseSVGFont = function(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); + p.glyphTable[url][name] = { + name: name, + unicode: unicode, + horiz_adv_x: horiz_adv_x, + draw: path.draw + } + } + } + }; + var loadXML = function() { + 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] + }; + p.param = function(name) { + var attributeName = "data-processing-" + name; + if (curElement.hasAttribute(attributeName)) return curElement.getAttribute(attributeName); + for (var i = 0, len = curElement.childNodes.length; i < len; ++i) { + var item = curElement.childNodes.item(i); + if (item.nodeType !== 1 || item.tagName.toLowerCase() !== "param") continue; + if (item.getAttribute("name") === name) return item.getAttribute("value") + } + if (curSketch.params.hasOwnProperty(name)) return curSketch.params[name]; + return null + }; + + function wireDimensionalFunctions(mode) { + if (mode === "3D") drawing = new Drawing3D; + else if (mode === "2D") drawing = new Drawing2D; + else drawing = new DrawingPre; + for (var i in DrawingPre.prototype) if (DrawingPre.prototype.hasOwnProperty(i) && i.indexOf("$") < 0) p[i] = drawing[i]; + drawing.$init() + } + function createDrawingPreFunction(name) { + return function() { + wireDimensionalFunctions("2D"); + return drawing[name].apply(this, arguments) + } + } + DrawingPre.prototype.translate = createDrawingPreFunction("translate"); + DrawingPre.prototype.transform = createDrawingPreFunction("transform"); + DrawingPre.prototype.scale = createDrawingPreFunction("scale"); + DrawingPre.prototype.pushMatrix = createDrawingPreFunction("pushMatrix"); + DrawingPre.prototype.popMatrix = createDrawingPreFunction("popMatrix"); + DrawingPre.prototype.resetMatrix = createDrawingPreFunction("resetMatrix"); + DrawingPre.prototype.applyMatrix = createDrawingPreFunction("applyMatrix"); + DrawingPre.prototype.rotate = createDrawingPreFunction("rotate"); + DrawingPre.prototype.rotateZ = createDrawingPreFunction("rotateZ"); + DrawingPre.prototype.shearX = createDrawingPreFunction("shearX"); + DrawingPre.prototype.shearY = createDrawingPreFunction("shearY"); + DrawingPre.prototype.redraw = createDrawingPreFunction("redraw"); + DrawingPre.prototype.toImageData = createDrawingPreFunction("toImageData"); + DrawingPre.prototype.ambientLight = createDrawingPreFunction("ambientLight"); + DrawingPre.prototype.directionalLight = createDrawingPreFunction("directionalLight"); + DrawingPre.prototype.lightFalloff = createDrawingPreFunction("lightFalloff"); + DrawingPre.prototype.lightSpecular = createDrawingPreFunction("lightSpecular"); + DrawingPre.prototype.pointLight = createDrawingPreFunction("pointLight"); + DrawingPre.prototype.noLights = createDrawingPreFunction("noLights"); + DrawingPre.prototype.spotLight = createDrawingPreFunction("spotLight"); + DrawingPre.prototype.beginCamera = createDrawingPreFunction("beginCamera"); + DrawingPre.prototype.endCamera = createDrawingPreFunction("endCamera"); + DrawingPre.prototype.frustum = createDrawingPreFunction("frustum"); + DrawingPre.prototype.box = createDrawingPreFunction("box"); + DrawingPre.prototype.sphere = createDrawingPreFunction("sphere"); + DrawingPre.prototype.ambient = createDrawingPreFunction("ambient"); + DrawingPre.prototype.emissive = createDrawingPreFunction("emissive"); + DrawingPre.prototype.shininess = createDrawingPreFunction("shininess"); + DrawingPre.prototype.specular = createDrawingPreFunction("specular"); + DrawingPre.prototype.fill = createDrawingPreFunction("fill"); + DrawingPre.prototype.stroke = createDrawingPreFunction("stroke"); + DrawingPre.prototype.strokeWeight = createDrawingPreFunction("strokeWeight"); + DrawingPre.prototype.smooth = createDrawingPreFunction("smooth"); + DrawingPre.prototype.noSmooth = createDrawingPreFunction("noSmooth"); + DrawingPre.prototype.point = createDrawingPreFunction("point"); + DrawingPre.prototype.vertex = createDrawingPreFunction("vertex"); + DrawingPre.prototype.endShape = createDrawingPreFunction("endShape"); + DrawingPre.prototype.bezierVertex = createDrawingPreFunction("bezierVertex"); + DrawingPre.prototype.curveVertex = createDrawingPreFunction("curveVertex"); + DrawingPre.prototype.curve = createDrawingPreFunction("curve"); + DrawingPre.prototype.line = createDrawingPreFunction("line"); + DrawingPre.prototype.bezier = createDrawingPreFunction("bezier"); + DrawingPre.prototype.rect = createDrawingPreFunction("rect"); + DrawingPre.prototype.ellipse = createDrawingPreFunction("ellipse"); + DrawingPre.prototype.background = createDrawingPreFunction("background"); + DrawingPre.prototype.image = createDrawingPreFunction("image"); + DrawingPre.prototype.textWidth = createDrawingPreFunction("textWidth"); + DrawingPre.prototype.text$line = createDrawingPreFunction("text$line"); + DrawingPre.prototype.$ensureContext = createDrawingPreFunction("$ensureContext"); + DrawingPre.prototype.$newPMatrix = createDrawingPreFunction("$newPMatrix"); + DrawingPre.prototype.size = function(aWidth, aHeight, aMode) { + wireDimensionalFunctions(aMode === 2 ? "3D" : "2D"); + p.size(aWidth, aHeight, aMode) + }; + DrawingPre.prototype.$init = nop; + Drawing2D.prototype.$init = function() { + p.size(p.width, p.height); + curContext.lineCap = "round"; + p.noSmooth(); + p.disableContextMenu() + }; + Drawing3D.prototype.$init = function() { + p.use3DContext = true; + p.disableContextMenu() + }; + DrawingShared.prototype.$ensureContext = function() { + return curContext + }; + + function calculateOffset(curElement, event) { + 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; + offsetX += window.pageXOffset; + offsetY += window.pageYOffset; + return { + "X": offsetX, + "Y": offsetY + } + } + function updateMousePosition(curElement, event) { + var offset = calculateOffset(curElement, event); + p.mouseX = event.pageX - offset.X; + p.mouseY = event.pageY - offset.Y + } + function addTouchEventOffset(t) { + var offset = calculateOffset(t.changedTouches[0].target, t.changedTouches[0]), + i; + for (i = 0; i < t.touches.length; i++) { + var touch = t.touches[i]; + touch.offsetX = touch.pageX - offset.X; + touch.offsetY = touch.pageY - offset.Y + } + for (i = 0; i < t.targetTouches.length; i++) { + var targetTouch = t.targetTouches[i]; + targetTouch.offsetX = targetTouch.pageX - offset.X; + targetTouch.offsetY = targetTouch.pageY - offset.Y + } + for (i = 0; i < t.changedTouches.length; i++) { + var changedTouch = t.changedTouches[i]; + changedTouch.offsetX = changedTouch.pageX - offset.X; + changedTouch.offsetY = changedTouch.pageY - offset.Y + } + return t + } + attachEventHandler(curElement, "touchstart", function(t) { + curElement.setAttribute("style", "-webkit-user-select: none"); + curElement.setAttribute("onclick", "void(0)"); + curElement.setAttribute("style", "-webkit-tap-highlight-color:rgba(0,0,0,0)"); + for (var i = 0, ehl = eventHandlers.length; i < ehl; i++) { + var type = eventHandlers[i].type; + if (type === "mouseout" || type === "mousemove" || type === "mousedown" || type === "mouseup" || type === "DOMMouseScroll" || type === "mousewheel" || type === "touchstart") detachEventHandler(eventHandlers[i]) + } + if (p.touchStart !== undef || p.touchMove !== undef || p.touchEnd !== undef || p.touchCancel !== undef) { + attachEventHandler(curElement, "touchstart", function(t) { + if (p.touchStart !== undef) { + t = addTouchEventOffset(t); + p.touchStart(t) + } + }); + attachEventHandler(curElement, "touchmove", function(t) { + if (p.touchMove !== undef) { + t.preventDefault(); + t = addTouchEventOffset(t); + p.touchMove(t) + } + }); + attachEventHandler(curElement, "touchend", function(t) { + if (p.touchEnd !== undef) { + t = addTouchEventOffset(t); + p.touchEnd(t) + } + }); + attachEventHandler(curElement, "touchcancel", function(t) { + if (p.touchCancel !== undef) { + t = addTouchEventOffset(t); + p.touchCancel(t) + } + }) + } else { + attachEventHandler(curElement, "touchstart", function(e) { + updateMousePosition(curElement, e.touches[0]); + p.__mousePressed = true; + p.mouseDragging = false; + p.mouseButton = 37; + if (typeof p.mousePressed === "function") p.mousePressed() + }); + attachEventHandler(curElement, "touchmove", function(e) { + e.preventDefault(); + updateMousePosition(curElement, e.touches[0]); + if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); + if (typeof p.mouseDragged === "function" && p.__mousePressed) { + p.mouseDragged(); + p.mouseDragging = true + } + }); + attachEventHandler(curElement, "touchend", function(e) { + p.__mousePressed = false; + if (typeof p.mouseClicked === "function" && !p.mouseDragging) p.mouseClicked(); + if (typeof p.mouseReleased === "function") p.mouseReleased() + }) + } + curElement.dispatchEvent(t) + }); + (function() { + var enabled = true, + contextMenu = function(e) { + e.preventDefault(); + e.stopPropagation() + }; + p.disableContextMenu = function() { + if (!enabled) return; + attachEventHandler(curElement, "contextmenu", contextMenu); + enabled = false + }; + p.enableContextMenu = function() { + if (enabled) return; + detachEventHandler({ + elem: curElement, + type: "contextmenu", + fn: contextMenu + }); + enabled = true + } + })(); + attachEventHandler(curElement, "mousemove", function(e) { + updateMousePosition(curElement, e); + if (typeof p.mouseMoved === "function" && !p.__mousePressed) p.mouseMoved(); + if (typeof p.mouseDragged === "function" && p.__mousePressed) { + p.mouseDragged(); + p.mouseDragging = true + } + }); + attachEventHandler(curElement, "mouseout", function(e) { + if (typeof p.mouseOut === "function") p.mouseOut() + }); + attachEventHandler(curElement, "mouseover", function(e) { + updateMousePosition(curElement, e); + if (typeof p.mouseOver === "function") p.mouseOver() + }); + curElement.onmousedown = function() { + curElement.focus(); + return false + }; + attachEventHandler(curElement, "mousedown", function(e) { + p.__mousePressed = true; + p.mouseDragging = false; + switch (e.which) { + case 1: + p.mouseButton = 37; + break; + case 2: + p.mouseButton = 3; + break; + case 3: + p.mouseButton = 39; + break + } + if (typeof p.mousePressed === "function") p.mousePressed() + }); + attachEventHandler(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() + }; + attachEventHandler(document, "DOMMouseScroll", mouseWheelHandler); + attachEventHandler(document, "mousewheel", mouseWheelHandler); + if (!curElement.getAttribute("tabindex")) curElement.setAttribute("tabindex", 0); + + function getKeyCode(e) { + var code = e.which || e.keyCode; + switch (code) { + case 13: + return 10; + case 91: + case 93: + case 224: + return 157; + case 57392: + return 17; + case 46: + return 127; + case 45: + return 155 + } + return code + } + function getKeyChar(e) { + var c = e.which || e.keyCode; + var anyShiftPressed = e.shiftKey || e.ctrlKey || e.altKey || e.metaKey; + switch (c) { + case 13: + c = anyShiftPressed ? 13 : 10; + break; + case 8: + c = anyShiftPressed ? 127 : 8; + break + } + return new Char(c) + } + function suppressKeyEvent(e) { + if (typeof e.preventDefault === "function") e.preventDefault(); + else if (typeof e.stopPropagation === "function") e.stopPropagation(); + return false + } + function updateKeyPressed() { + var ch; + for (ch in pressedKeysMap) if (pressedKeysMap.hasOwnProperty(ch)) { + p.__keyPressed = true; + return + } + p.__keyPressed = false + } + function resetKeyPressed() { + p.__keyPressed = false; + pressedKeysMap = []; + lastPressedKeyCode = null + } + function simulateKeyTyped(code, c) { + pressedKeysMap[code] = c; + lastPressedKeyCode = null; + p.key = c; + p.keyCode = code; + p.keyPressed(); + p.keyCode = 0; + p.keyTyped(); + updateKeyPressed() + } + function handleKeydown(e) { + var code = getKeyCode(e); + if (code === 127) { + simulateKeyTyped(code, new Char(127)); + return + } + if (codedKeys.indexOf(code) < 0) { + lastPressedKeyCode = code; + return + } + var c = new Char(65535); + p.key = c; + p.keyCode = code; + pressedKeysMap[code] = c; + p.keyPressed(); + lastPressedKeyCode = null; + updateKeyPressed(); + return suppressKeyEvent(e) + } + function handleKeypress(e) { + if (lastPressedKeyCode === null) return; + var code = lastPressedKeyCode, + c = getKeyChar(e); + simulateKeyTyped(code, c); + return suppressKeyEvent(e) + } + function handleKeyup(e) { + var code = getKeyCode(e), + c = pressedKeysMap[code]; + if (c === undef) return; + p.key = c; + p.keyCode = code; + p.keyReleased(); + delete pressedKeysMap[code]; + updateKeyPressed() + } + if (!pgraphicsMode) { + if (aCode instanceof Processing.Sketch) curSketch = aCode; + else if (typeof aCode === "function") curSketch = new Processing.Sketch(aCode); + else if (!aCode) curSketch = new Processing.Sketch(function() {}); + else curSketch = Processing.compile(aCode); + p.externals.sketch = curSketch; + wireDimensionalFunctions(); + curElement.onfocus = function() { + p.focused = true + }; + curElement.onblur = function() { + p.focused = false; + if (!curSketch.options.globalKeyEvents) resetKeyPressed() + }; + if (curSketch.options.pauseOnBlur) { + attachEventHandler(window, "focus", function() { + if (doLoop) p.loop() + }); + attachEventHandler(window, "blur", function() { + if (doLoop && loopStarted) { + p.noLoop(); + doLoop = true + } + resetKeyPressed() + }) + } + var keyTrigger = curSketch.options.globalKeyEvents ? window : curElement; + attachEventHandler(keyTrigger, "keydown", handleKeydown); + attachEventHandler(keyTrigger, "keypress", handleKeypress); + attachEventHandler(keyTrigger, "keyup", handleKeyup); + 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 retryInterval = 100; + var executeSketch = function(processing) { + if (! (curSketch.imageCache.pending || PFont.preloading.pending(retryInterval))) { + if (window.opera) { + var link, element, operaCache = curSketch.imageCache.operaCache; + for (link in operaCache) if (operaCache.hasOwnProperty(link)) { + element = operaCache[link]; + if (element !== null) document.body.removeChild(element); + delete operaCache[link] + } + } + curSketch.attach(processing, defaultScope); + curSketch.onLoad(processing); + if (processing.setup) { + processing.setup(); + processing.resetMatrix(); + curSketch.onSetup() + } + resetContext(); + if (processing.draw) if (!doLoop) processing.redraw(); + else processing.loop() + } else window.setTimeout(function() { + executeSketch(processing) + }, + retryInterval) + }; + addInstance(this); + executeSketch(p) + } else { + curSketch = new Processing.Sketch; + wireDimensionalFunctions(); + p.size = function(w, h, render) { + if (render && render === 2) wireDimensionalFunctions("3D"); + else wireDimensionalFunctions("2D"); + p.size(w, h, render) + } + } + }; + Processing.debug = debug; + 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", "box", "breakShape", "brightness", "camera", "ceil", "Character", "color", "colorMode", "concat", "constrain", "copy", "cos", "createFont", "createGraphics", "createImage", "cursor", "curve", "curveDetail", "curvePoint", "curveTangent", "curveTightness", "curveVertex", "day", "degrees", "directionalLight", + "disableContextMenu", "dist", "draw", "ellipse", "ellipseMode", "emissive", "enableContextMenu", "endCamera", "endDraw", "endShape", "exit", "exp", "expand", "externals", "fill", "filter", "floor", "focused", "frameCount", "frameRate", "frustum", "get", "glyphLook", "glyphTable", "green", "height", "hex", "hint", "hour", "hue", "image", "imageMode", "intersect", "join", "key", "keyCode", "keyPressed", "keyReleased", "keyTyped", "lerp", "lerpColor", "lightFalloff", "lights", "lightSpecular", "line", "link", "loadBytes", "loadFont", "loadGlyphs", + "loadImage", "loadPixels", "loadShape", "loadXML", "loadStrings", "log", "loop", "mag", "map", "match", "matchAll", "max", "millis", "min", "minute", "mix", "modelX", "modelY", "modelZ", "modes", "month", "mouseButton", "mouseClicked", "mouseDragged", "mouseMoved", "mouseOut", "mouseOver", "mousePressed", "mouseReleased", "mouseScroll", "mouseScrolled", "mouseX", "mouseY", "name", "nf", "nfc", "nfp", "nfs", "noCursor", "noFill", "noise", "noiseDetail", "noiseSeed", "noLights", "noLoop", "norm", "normal", "noSmooth", "noStroke", "noTint", "ortho", + "param", "parseBoolean", "parseByte", "parseChar", "parseFloat", "parseInt", "peg", "perspective", "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", "shearX", "shearY", "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", "toImageData", + "touchCancel", "touchEnd", "touchMove", "touchStart", "translate", "transform", "triangle", "trim", "unbinary", "unhex", "updatePixels", "use3DContext", "vertex", "width", "XMLElement", "XML", "year", "__contains", "__equals", "__equalsIgnoreCase", "__frameRate", "__hashCode", "__int_cast", "__instanceof", "__keyPressed", "__mousePressed", "__printStackTrace", "__replace", "__replaceAll", "__replaceFirst", "__toCharArray", "__split", "__codePointAt", "__startsWith", "__endsWith", "__matches"]; + 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; + 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 + "'" + } + if (regexCtx) { + index = strings.length; + strings.push(regex); + return prefix + "'" + index + "'" + } + return comment !== "" ? " " : "\n" + }); + codeWoStrings = codeWoStrings.replace(/__x([0-9A-F]{4})/g, function(all, hexCode) { + return "__x005F_x" + hexCode + }); + codeWoStrings = codeWoStrings.replace(/\$/g, "__x0024"); + var genericsWereRemoved; + var codeWoGenerics = codeWoStrings; + var replaceFunc = function(all, before, types, after) { + if ( !! before || !!after) return all; + genericsWereRemoved = true; + return "" + }; + do { + genericsWereRemoved = false; + codeWoGenerics = codeWoGenerics.replace(/([<]?)<\s*((?:\?|[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)(?:\[\])*(?:\s+(?:extends|super)\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+(?:extends|super)\s+[A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)?)*)\s*>([=]?)/g, replaceFunc) + } while (genericsWereRemoved); + var atoms = splitToAtoms(codeWoGenerics); + 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, transformInterfaceBody, 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)*(?:\s*,\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; + return addAtom(all, "G") + }); + return result + } + function AstParam(name) { + this.name = name + } + AstParam.prototype.toString = function() { + return this.name + }; + + function AstParams(params, methodArgsParam) { + this.params = params; + this.methodArgsParam = methodArgsParam + } + 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.prependMethodArgs = function(body) { + if (!this.methodArgsParam) return body; + return "{\nvar " + this.methodArgsParam.name + " = Array.prototype.slice.call(arguments, " + this.params.length + ");\n" + body.substring(1) + }; + 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 = [], + methodArgsParam = null; + 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]*")*\s*$/.exec(paramList[i]); + if (i === paramList.length - 1 && paramList[i].indexOf("...") >= 0) { + methodArgsParam = new AstParam(param[1]); + break + } + result.push(new AstParam(param[1])) + } + } + return new AstParams(result, methodArgsParam) + } + 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; + if (/^\(\s*int\s*\)$/.test(atom)) return "(int)" + next; + 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(/\b(boolean|byte|char|float|int)\s*"B/g, function(all, name) { + return "parse" + name.substring(0, 1).toUpperCase() + name.substring(1) + '"B' + }); + s = s.replace(/\bpixels\b\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"); + return "pixels.getPixel" + addAtom("(" + atom.substring(1, atom.length - 1) + ")", "B") + } + if (indexOrLength) return "pixels.getLength" + addAtom("()", "B"); + if (equalsPart) return "pixels.set" + addAtom("(" + rightSide + ")", "B"); + return "pixels.toArray" + addAtom("()", "B") + }); + var repeatJavaReplacement; + + function replacePrototypeMethods(all, subject, method, atomIndex) { + var atom = atoms[atomIndex]; + repeatJavaReplacement = true; + var trimmed = trimSpaces(atom.substring(1, atom.length - 1)); + return "__" + method + (trimmed.middle === "" ? addAtom("(" + subject.replace(/\.\s*$/, "") + ")", "B") : addAtom("(" + subject.replace(/\.\s*$/, "") + "," + trimmed.middle + ")", "B")) + } + do { + repeatJavaReplacement = false; + s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*\.\s*(?:[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*\.\s*)*)(replace|replaceAll|replaceFirst|contains|equals|equalsIgnoreCase|hashCode|toCharArray|printStackTrace|split|startsWith|endsWith|codePointAt|matches)\s*"B(\d+)"/g, replacePrototypeMethods) + } while (repeatJavaReplacement); + + function replaceInstanceof(all, subject, type) { + repeatJavaReplacement = true; + return "__instanceof" + addAtom("(" + subject + ", " + type + ")", "B") + } + do { + repeatJavaReplacement = false; + s = s.replace(/((?:'\d+'|\b[A-Za-z_$][\w$]*\s*(?:"[BC]\d+")*)\s*(?:\.\s*[A-Za-z_$][\w$]*\s*(?:"[BC]\d+"\s*)*)*)instanceof\s+([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)/g, replaceInstanceof) + } while (repeatJavaReplacement); + 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 (" + this.body + ")" + }; + + function transformInlineClass(class_) { + var m = (new RegExp(/\bnew\s*([A-Za-z_$][\w$]*\s*(?:\.\s*[A-Za-z_$][\w$]*)*)\s*"B\d+"\s*"A(\d+)"/)).exec(class_); + var oldClassId = currentClassId, + newClassId = generateClassId(); + currentClassId = newClassId; + var uniqueClassName = m[1] + "$" + newClassId; + var inlineClass = new AstInlineClass(uniqueClassName, transformClassBody(atoms[m[2]], uniqueClassName, "", "implements " + 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; + var body = this.params.prependMethodArgs(this.body.toString()); + result += this.params + " " + 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); + if (expr.charAt(0) === "{") { + if (/^\{\s*(?:[A-Za-z_$][\w$]*|'\d+')\s*:/.test(expr)) return "{" + addAtom(expr.substring(1, expr.length - 1), "I") + "}"; + return "[" + expandExpression(expr.substring(1, expr.length - 1)) + "]" + } + 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$]*)(\s*\.\s*([A-Za-z_$][\w$]*)(\s*\()?)?/g, function(all, memberAccessSign, identifier, suffix, subMember, callSign) { + if (memberAccessSign) return all; + 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"; + if (type === "boolean") return "false"; + if (type === "color") return "0x00000000"; + 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]) + } + 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 AstForEachExpression(initStatement, container) { + this.initStatement = initStatement; + this.container = container + } + AstForEachExpression.iteratorId = 0; + AstForEachExpression.prototype.toString = function() { + var init = this.initStatement.toString(); + var iterator = "$it" + AstForEachExpression.iteratorId++; + var variableName = init.replace(/^\s*var\s*/, "").split("=")[0]; + var initIteratorAndVariable = "var " + iterator + " = new $p.ObjectIterator(" + this.container + "), " + variableName + " = void(0)"; + var nextIterationCondition = iterator + ".hasNext() && ((" + variableName + " = " + iterator + ".next()) || true)"; + return "(" + initIteratorAndVariable + "; " + nextIterationCondition + ";)" + }; + + 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])) + } + if (expr.indexOf(":") >= 0 && expr.indexOf(";") < 0) { + content = expr.substring(1, expr.length - 1).split(":"); + return new AstForEachExpression(transformStatement(trim(content[0])), transformExpression(content[1])) + } + content = expr.substring(1, expr.length - 1).split(";"); + return new AstForExpression(transformStatement(trim(content[0])), transformExpression(content[1]), transformExpression(content[2])) + } + + function sortByWeight(array) { + array.sort(function(a, b) { + return b.weight - a.weight + }) + } + function AstInnerInterface(name, body, isStatic) { + this.name = name; + this.body = body; + this.isStatic = isStatic; + body.owner = this + } + AstInnerInterface.prototype.toString = function() { + return "" + this.body + }; + + function AstInnerClass(name, body, isStatic) { + this.name = name; + this.body = body; + this.isStatic = isStatic; + body.owner = this + } + AstInnerClass.prototype.toString = function() { + return "" + this.body + }; + + function transformInnerClass(class_) { + var m = classesRegex.exec(class_); + classesRegex.lastIndex = 0; + var isStatic = m[1].indexOf("static") >= 0; + var body = atoms[getAtomIndex(m[6])], + innerClass; + var oldClassId = currentClassId, + newClassId = generateClassId(); + currentClassId = newClassId; + if (m[2] === "interface") innerClass = new AstInnerInterface(m[3], transformInterfaceBody(body, m[3], m[4]), isStatic); + else innerClass = new AstInnerClass(m[3], transformClassBody(body, m[3], m[4], m[5]), isStatic); + appendClass(innerClass, newClassId, oldClassId); + currentClassId = oldClassId; + return innerClass + } + function AstClassMethod(name, params, body, isStatic) { + this.name = name; + this.params = params; + this.body = body; + this.isStatic = isStatic + } + AstClassMethod.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 body = this.params.prependMethodArgs(this.body.toString()); + var result = "function " + this.methodId + this.params + " " + body + "\n"; + replaceContext = oldContext; + return result + }; + + function transformClassMethod(method) { + var m = methodsRegex.exec(method); + methodsRegex.lastIndex = 0; + var isStatic = m[1].indexOf("static") >= 0; + var body = m[6] !== ";" ? atoms[getAtomIndex(m[6])] : "{}"; + return new AstClassMethod(m[3], transformParams(atoms[getAtomIndex(m[4])]), transformStatementsBlock(body), isStatic) + } + 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("") + } + 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.params.prependMethodArgs(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 AstInterfaceBody(name, interfacesNames, methodsNames, fields, innerClasses, misc) { + var i, l; + this.name = name; + this.interfacesNames = interfacesNames; + this.methodsNames = methodsNames; + this.fields = fields; + this.innerClasses = innerClasses; + this.misc = misc; + for (i = 0, l = fields.length; i < l; ++i) fields[i].owner = this + } + AstInterfaceBody.prototype.getMembers = function(classFields, classMethods, classInners) { + if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); + var i, j, l, m; + for (i = 0, l = this.fields.length; i < l; ++i) { + var fieldNames = this.fields[i].getNames(); + for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] + } + for (i = 0, l = this.methodsNames.length; i < l; ++i) { + var methodName = this.methodsNames[i]; + classMethods[methodName] = true + } + for (i = 0, l = this.innerClasses.length; i < l; ++i) { + var innerClass = this.innerClasses[i]; + classInners[innerClass.name] = innerClass + } + }; + AstInterfaceBody.prototype.toString = function() { + function getScopeLevel(p) { + var i = 0; + while (p) { + ++i; + p = p.scope + } + return i + } + var scopeLevel = getScopeLevel(this.owner); + var className = this.name; + var staticDefinitions = ""; + var metadata = ""; + var thisClassFields = {}, + thisClassMethods = {}, + thisClassInners = {}; + this.getMembers(thisClassFields, thisClassMethods, thisClassInners); + var i, l, j, m; + if (this.owner.interfaces) { + var resolvedInterfaces = [], + resolvedInterface; + for (i = 0, l = this.interfacesNames.length; i < l; ++i) { + if (!this.owner.interfaces[i]) continue; + resolvedInterface = replaceContext({ + name: this.interfacesNames[i] + }); + resolvedInterfaces.push(resolvedInterface); + staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" + } + metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" + } + metadata += className + ".$isInterface = true;\n"; + metadata += className + ".$methods = ['" + this.methodsNames.join("', '") + "'];\n"; + sortByWeight(this.innerClasses); + for (i = 0, l = this.innerClasses.length; i < l; ++i) { + var innerClass = this.innerClasses[i]; + if (innerClass.isStatic) staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n" + } + for (i = 0, l = this.fields.length; i < l; ++i) { + var field = this.fields[i]; + if (field.isStatic) staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n" + } + return "(function() {\n" + "function " + className + "() { throw 'Unable to create the interface'; }\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" + }; + transformInterfaceBody = function(body, name, baseInterfaces) { + var declarations = body.substring(1, body.length - 1); + declarations = extractClassesAndMethods(declarations); + declarations = extractConstructors(declarations, name); + var methodsNames = [], + classes = []; + declarations = declarations.replace(/"([DE])(\d+)"/g, function(all, type, index) { + if (type === "D") methodsNames.push(index); + else if (type === "E") classes.push(index); + return "" + }); + var fields = declarations.split(/;(?:\s*;)*/g); + var baseInterfaceNames; + var i, l; + if (baseInterfaces !== undef) baseInterfaceNames = baseInterfaces.replace(/^\s*extends\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); + for (i = 0, l = methodsNames.length; i < l; ++i) { + var method = transformClassMethod(atoms[methodsNames[i]]); + methodsNames[i] = method.name + } + for (i = 0, l = fields.length - 1; i < l; ++i) { + var field = trimSpaces(fields[i]); + fields[i] = transformClassField(field.middle) + } + var tail = fields.pop(); + for (i = 0, l = classes.length; i < l; ++i) classes[i] = transformInnerClass(atoms[classes[i]]); + return new AstInterfaceBody(name, baseInterfaceNames, methodsNames, fields, classes, { + tail: tail + }) + }; + + function AstClassBody(name, baseClassName, interfacesNames, functions, methods, fields, cstrs, innerClasses, misc) { + var i, l; + this.name = name; + this.baseClassName = baseClassName; + this.interfacesNames = interfacesNames; + 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(classFields, classMethods, classInners) { + if (this.owner.base) this.owner.base.body.getMembers(classFields, classMethods, classInners); + var i, j, l, m; + for (i = 0, l = this.fields.length; i < l; ++i) { + var fieldNames = this.fields[i].getNames(); + for (j = 0, m = fieldNames.length; j < m; ++j) classFields[fieldNames[j]] = this.fields[i] + } + for (i = 0, l = this.methods.length; i < l; ++i) { + var method = this.methods[i]; + classMethods[method.name] = method + } + for (i = 0, l = this.innerClasses.length; i < l; ++i) { + var innerClass = this.innerClasses[i]; + classInners[innerClass.name] = innerClass + } + }; + 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 className = this.name; + var result = "var " + selfId + " = this;\n"; + var staticDefinitions = ""; + var metadata = ""; + var thisClassFields = {}, + thisClassMethods = {}, + thisClassInners = {}; + this.getMembers(thisClassFields, thisClassMethods, thisClassInners); + var oldContext = replaceContext; + replaceContext = function(subject) { + var name = subject.name; + if (name === "this") return subject.callSign || !subject.member ? selfId + ".$self" : selfId; + if (thisClassFields.hasOwnProperty(name)) return thisClassFields[name].isStatic ? className + "." + name : selfId + "." + name; + if (thisClassInners.hasOwnProperty(name)) return selfId + "." + name; + if (thisClassMethods.hasOwnProperty(name)) return thisClassMethods[name].isStatic ? className + "." + name : selfId + ".$self." + name; + return oldContext(subject) + }; + var resolvedBaseClassName; + if (this.baseClassName) { + resolvedBaseClassName = oldContext({ + name: this.baseClassName + }); + result += "var $super = { $upcast: " + selfId + " };\n"; + result += "function $superCstr(){" + resolvedBaseClassName + ".apply($super,arguments);if(!('$self' in $super)) $p.extendClassChain($super)}\n"; + metadata += className + ".$base = " + resolvedBaseClassName + ";\n" + } else result += "function $superCstr(){$p.extendClassChain(" + selfId + ")}\n"; + if (this.owner.base) staticDefinitions += "$p.extendStaticMembers(" + className + ", " + resolvedBaseClassName + ");\n"; + var i, l, j, m; + if (this.owner.interfaces) { + var resolvedInterfaces = [], + resolvedInterface; + for (i = 0, l = this.interfacesNames.length; i < l; ++i) { + if (!this.owner.interfaces[i]) continue; + resolvedInterface = oldContext({ + name: this.interfacesNames[i] + }); + resolvedInterfaces.push(resolvedInterface); + staticDefinitions += "$p.extendInterfaceMembers(" + className + ", " + resolvedInterface + ");\n" + } + metadata += className + ".$interfaces = [" + resolvedInterfaces.join(", ") + "];\n" + } + if (this.functions.length > 0) result += this.functions.join("\n") + "\n"; + sortByWeight(this.innerClasses); + for (i = 0, l = this.innerClasses.length; i < l; ++i) { + var innerClass = this.innerClasses[i]; + if (innerClass.isStatic) { + staticDefinitions += className + "." + innerClass.name + " = " + innerClass + ";\n"; + result += selfId + "." + innerClass.name + " = " + className + "." + innerClass.name + ";\n" + } else result += selfId + "." + innerClass.name + " = " + innerClass + ";\n" + } + for (i = 0, l = this.fields.length; i < l; ++i) { + var field = this.fields[i]; + if (field.isStatic) { + staticDefinitions += className + "." + field.definitions.join(";\n" + className + ".") + ";\n"; + for (j = 0, m = field.definitions.length; j < m; ++j) { + var fieldName = field.definitions[j].name, + staticName = className + "." + fieldName; + result += "$p.defineProperty(" + selfId + ", '" + fieldName + "', {" + "get: function(){return " + staticName + "}, " + "set: function(val){" + staticName + " = val}});\n" + } + } else result += selfId + "." + field.definitions.join(";\n" + selfId + ".") + ";\n" + } + var methodOverloads = {}; + for (i = 0, l = this.methods.length; i < l; ++i) { + var method = this.methods[i]; + var overload = methodOverloads[method.name]; + var methodId = method.name + "$" + method.params.params.length; + var hasMethodArgs = !!method.params.methodArgsParam; + if (overload) { + ++overload; + methodId += "_" + overload + } else overload = 1; + method.methodId = methodId; + methodOverloads[method.name] = overload; + if (method.isStatic) { + staticDefinitions += method; + staticDefinitions += "$p.addMethod(" + className + ", '" + method.name + "', " + methodId + ", " + hasMethodArgs + ");\n"; + result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ", " + hasMethodArgs + ");\n" + } else { + result += method; + result += "$p.addMethod(" + selfId + ", '" + method.name + "', " + methodId + ", " + hasMethodArgs + ");\n" + } + } + result += trim(this.misc.tail); + if (this.cstrs.length > 0) result += this.cstrs.join("\n") + "\n"; + result += "function $constr() {\n"; + var cstrsIfs = []; + for (i = 0, l = this.cstrs.length; i < l; ++i) { + var paramsLength = this.cstrs[i].params.params.length; + var methodArgsPresent = !!this.cstrs[i].params.methodArgsParam; + cstrsIfs.push("if(arguments.length " + (methodArgsPresent ? ">=" : "===") + " " + paramsLength + ") { " + "$constr_" + paramsLength + ".apply(" + selfId + ", arguments); }") + } + if (cstrsIfs.length > 0) result += cstrsIfs.join(" else ") + " else "; + result += "$superCstr();\n}\n"; + result += "$constr.apply(null, arguments);\n"; + replaceContext = oldContext; + return "(function() {\n" + "function " + className + "() {\n" + result + "}\n" + staticDefinitions + metadata + "return " + className + ";\n" + "})()" + }; + transformClassBody = function(body, name, baseName, interfaces) { + 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.replace(/^(?:\s*;)+/, "").split(/;(?:\s*;)*/g); + var baseClassName, interfacesNames; + var i; + if (baseName !== undef) baseClassName = baseName.replace(/^\s*extends\s+([A-Za-z_$][\w$]*\b(?:\s*\.\s*[A-Za-z_$][\w$]*\b)*)\s*$/g, "$1"); + if (interfaces !== undef) interfacesNames = interfaces.replace(/^\s*implements\s+(.+?)\s*$/g, "$1").split(/\s*,\s*/g); + 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, interfacesNames, functions, methods, fields, cstrs, classes, { + tail: tail + }) + }; + + function AstInterface(name, body) { + this.name = name; + this.body = body; + body.owner = this + } + AstInterface.prototype.toString = function() { + return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" + }; + + function AstClass(name, body) { + this.name = name; + this.body = body; + body.owner = this + } + AstClass.prototype.toString = function() { + return "var " + this.name + " = " + this.body + ";\n" + "$p." + this.name + " = " + this.name + ";\n" + }; + + function transformGlobalClass(class_) { + var m = classesRegex.exec(class_); + classesRegex.lastIndex = 0; + var body = atoms[getAtomIndex(m[6])]; + var oldClassId = currentClassId, + newClassId = generateClassId(); + currentClassId = newClassId; + var globalClass; + if (m[2] === "interface") globalClass = new AstInterface(m[3], transformInterfaceBody(body, m[3], m[4])); + else 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 body = this.params.prependMethodArgs(this.body.toString()); + var result = "function " + this.name + this.params + " " + 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 AstSwitchCase(expr) { + this.expr = expr + } + AstSwitchCase.prototype.toString = function() { + return "case " + this.expr + ":" + }; + + 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+([^:]+):|\b([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) res.push(new AstSwitchCase(transformExpression(trim(m[7])))); + else if (m[8] !== undef) { + space = statements.substring(lastIndex, nextStatement.lastIndex - m[8].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 classes = [], + otherStatements = [], + statement; + for (var i = 0, len = this.statements.length; i < len; ++i) { + statement = this.statements[i]; + if (statement instanceof AstClass || statement instanceof AstInterface) classes.push(statement); + else otherStatements.push(statement) + } + sortByWeight(classes); + var localNames = getLocalNames(this.statements); + replaceContext = function(subject) { + var name = subject.name; + if (localNames.hasOwnProperty(name)) return name; + 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" + classes.join("") + "\n" + otherStatements.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) { + var parent = findInScopes(class_, baseClassName); + if (parent) { + class_.base = parent; + if (!parent.derived) parent.derived = []; + parent.derived.push(class_) + } + } + var interfacesNames = class_.body.interfacesNames, + interfaces = [], + i, l; + if (interfacesNames && interfacesNames.length > 0) { + for (i = 0, l = interfacesNames.length; i < l; ++i) { + var interface_ = findInScopes(class_, interfacesNames[i]); + interfaces.push(interface_); + if (!interface_) continue; + if (!interface_.derived) interface_.derived = []; + interface_.derived.push(class_) + } + if (interfaces.length > 0) class_.interfaces = interfaces + } + } + } + function setWeight(ast) { + var queue = [], + tocheck = {}; + var id, scopeId, class_; + for (id in declaredClasses) if (declaredClasses.hasOwnProperty(id)) { + class_ = declaredClasses[id]; + if (!class_.inScope && !class_.derived) { + queue.push(id); + class_.weight = 0 + } else { + var dependsOn = []; + if (class_.inScope) for (scopeId in class_.inScope) if (class_.inScope.hasOwnProperty(scopeId)) dependsOn.push(class_.inScope[scopeId]); + if (class_.derived) dependsOn = dependsOn.concat(class_.derived); + tocheck[id] = dependsOn + } + } + function removeDependentAndCheck(targetId, from) { + var dependsOn = tocheck[targetId]; + if (!dependsOn) return false; + var i = dependsOn.indexOf(from); + if (i < 0) return false; + dependsOn.splice(i, 1); + if (dependsOn.length > 0) return false; + delete tocheck[targetId]; + return true + } + while (queue.length > 0) { + id = queue.shift(); + class_ = declaredClasses[id]; + if (class_.scopeId && removeDependentAndCheck(class_.scopeId, class_)) { + queue.push(class_.scopeId); + declaredClasses[class_.scopeId].weight = class_.weight + 1 + } + if (class_.base && removeDependentAndCheck(class_.base.classId, class_)) { + queue.push(class_.base.classId); + class_.base.weight = class_.weight + 1 + } + if (class_.interfaces) { + var i, l; + for (i = 0, l = class_.interfaces.length; i < l; ++i) { + if (!class_.interfaces[i] || !removeDependentAndCheck(class_.interfaces[i].classId, class_)) continue; + queue.push(class_.interfaces[i].classId); + class_.interfaces[i].weight = class_.weight + 1 + } + } + } + } + var transformed = transformMain(); + generateMetadata(transformed); + setWeight(transformed); + var redendered = transformed.toString(); + redendered = redendered.replace(/\s*\n(?:[\t ]*\n)+/g, "\n\n"); + redendered = redendered.replace(/__x([0-9A-F]{4})/g, function(all, hexCode) { + return String.fromCharCode(parseInt(hexCode, 16)) + }); + 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 === "font") { + list = value.split(","); + for (var x = 0, xl = list.length; x < xl; x++) { + var fontName = clean(list[x]), + index = /^\{(\d*?)\}$/.exec(fontName); + PFont.preloading.add(index ? JSON.parse("{" + jsonItems[index[1]] + "}") : fontName) + } + } else if (key === "pauseOnBlur") sketch.options.pauseOnBlur = value === "true"; + else if (key === "globalKeyEvents") sketch.options.globalKeyEvents = value === "true"; + else if (key.substring(0, 6) === "param-") sketch.params[key.substring(6)] = value; + else sketch.options[key] = value + } + } + } + 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 + }; + 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: 1E4, + 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); + updateSafetyMargin() + } + })(); + else if (typeof print === func) tinylogLite[log] = print; + return tinylogLite + }(); + Processing.logger = tinylogLite; + Processing.version = "1.4.1"; + Processing.lib = {}; + Processing.registerLibrary = function(name, desc) { + Processing.lib[name] = desc; + if (desc.hasOwnProperty("init")) desc.init(defaultScope) + }; + Processing.instances = processingInstances; + Processing.getInstanceById = function(name) { + return processingInstances[processingInstanceIds[name]] + }; + Processing.Sketch = function(attachFunction) { + this.attachFunction = attachFunction; + this.options = { + pauseOnBlur: false, + globalKeyEvents: false + }; + this.onLoad = nop; + this.onSetup = nop; + this.onPause = nop; + this.onLoop = nop; + this.onFrameStart = nop; + this.onFrameEnd = nop; + this.onExit = nop; + this.params = {}; + this.imageCache = { + pending: 0, + images: {}, + operaCache: {}, + add: function(href, img) { + if (this.images[href]) return; + if (!isDOMPresent) this.images[href] = null; + if (!img) { + img = new Image; + img.onload = function(owner) { + return function() { + owner.pending-- + } + }(this); + this.pending++; + img.src = href + } + this.images[href] = img; + if (window.opera) { + var div = document.createElement("div"); + div.appendChild(img); + div.style.position = "absolute"; + div.style.opacity = 0; + div.style.width = "1px"; + div.style.height = "1px"; + if (!this.operaCache[href]) { + document.body.appendChild(div); + this.operaCache[href] = div + } + } + } + }; + this.sourceCode = undefined; + this.attach = function(processing) { + if (typeof this.attachFunction === "function") this.attachFunction(processing); + else if (this.sourceCode) { + var func = (new Function("return (" + this.sourceCode + ");"))(); + func(processing); + this.attachFunction = func + } else throw "Unable to attach sketch to the processing instance"; + }; + this.toString = function() { + var i; + var code = "((function(Sketch) {\n"; + code += "var sketch = new Sketch(\n" + this.sourceCode + ");\n"; + for (i in this.options) if (this.options.hasOwnProperty(i)) { + var value = this.options[i]; + code += "sketch.options." + i + " = " + (typeof value === "string" ? '"' + value + '"' : "" + value) + ";\n" + } + for (i in this.imageCache) if (this.options.hasOwnProperty(i)) code += 'sketch.imageCache.add("' + i + '");\n'; + code += "return sketch;\n})(Processing.Sketch))"; + return code + } + }; + var loadSketchFromSources = function(canvas, sources) { + var code = [], + errors = [], + sourcesCount = sources.length, + loaded = 0; + + function ajaxAsync(url, callback) { + var xhr = new XMLHttpRequest; + xhr.onreadystatechange = function() { + if (xhr.readyState === 4) { + var error; + if (xhr.status !== 200 && xhr.status !== 0) error = "Invalid XHR status " + xhr.status; + else if (xhr.responseText === "") if ("withCredentials" in new XMLHttpRequest && (new XMLHttpRequest).withCredentials === false && window.location.protocol === "file:") error = "XMLHttpRequest failure, possibly due to a same-origin policy violation. You can try loading this page in another browser, or load it from http://localhost using a local webserver. See the Processing.js README for a more detailed explanation of this problem and solutions."; + else error = "File is empty."; + callback(xhr.responseText, error) + } + }; + xhr.open("GET", url, true); + if (xhr.overrideMimeType) xhr.overrideMimeType("application/json"); + xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT"); + xhr.send(null) + } + function loadBlock(index, filename) { + function callback(block, error) { + code[index] = block; + ++loaded; + if (error) errors.push(filename + " ==> " + error); + if (loaded === sourcesCount) if (errors.length === 0) try { + return new Processing(canvas, code.join("\n")) + } catch(e) { + throw "Processing.js: Unable to execute pjs sketch: " + e; + } else throw "Processing.js: Unable to load pjs sketch files: " + errors.join("\n"); + } + if (filename.charAt(0) === "#") { + var scriptElement = document.getElementById(filename.substring(1)); + if (scriptElement) callback(scriptElement.text || scriptElement.textContent); + else callback("", "Unable to load pjs sketch: element with id '" + filename.substring(1) + "' was not found"); + return + } + ajaxAsync(filename, callback) + } + for (var i = 0; i < sourcesCount; ++i) loadBlock(i, sources[i]) + }; + var init = function() { + document.removeEventListener("DOMContentLoaded", init, false); + processingInstances = []; + var canvas = document.getElementsByTagName("canvas"), + filenames; + 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) { + filenames = processingSources.split(/\s+/g); + for (var j = 0; j < filenames.length;) if (filenames[j]) j++; + else filenames.splice(j, 1); + loadSketchFromSources(canvas[i], filenames) + } + } + var s, last, source, instance, nodelist = document.getElementsByTagName("script"), + scripts = []; + for (s = nodelist.length - 1; s >= 0; s--) scripts.push(nodelist[s]); + for (s = 0, last = scripts.length; s < last; s++) { + var script = scripts[s]; + if (!script.getAttribute) continue; + var type = script.getAttribute("type"); + if (type && (type.toLowerCase() === "text/processing" || type.toLowerCase() === "application/processing")) { + var target = script.getAttribute("data-processing-target"); + canvas = undef; + if (target) canvas = document.getElementById(target); + else { + var nextSibling = script.nextSibling; + while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextSibling; + if (nextSibling && nextSibling.nodeName.toLowerCase() === "canvas") canvas = nextSibling + } + if (canvas) { + if (script.getAttribute("src")) { + filenames = script.getAttribute("src").split(/\s+/); + loadSketchFromSources(canvas, filenames); + continue + } + source = script.textContent || script.text; + instance = new Processing(canvas, source) + } + } + } + }; + Processing.reload = function() { + if (processingInstances.length > 0) for (var i = processingInstances.length - 1; i >= 0; i--) if (processingInstances[i]) processingInstances[i].exit(); + init() + }; + Processing.loadSketchFromSources = loadSketchFromSources; + Processing.disableInit = function() { + if (isDOMPresent) document.removeEventListener("DOMContentLoaded", init, false) + }; + if (isDOMPresent) { + window["Processing"] = Processing; + document.addEventListener("DOMContentLoaded", init, false) + } else this.Processing = Processing +})(window, window.document, Math); + diff --git a/examples/week6/processingjswithsinatra/tmp/always_restart.txt b/examples/week6/processingjswithsinatra/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/week6/processingjswithsinatra/views/form.erb b/examples/week6/processingjswithsinatra/views/form.erb new file mode 100644 index 0000000..c65d96b --- /dev/null +++ b/examples/week6/processingjswithsinatra/views/form.erb @@ -0,0 +1,34 @@ + + + + Simple Form Example + + + + +

    Simple form

    +

    This is a simple form example.

    + +

    +

    + + + + diff --git a/examples/week6/processingjswithsinatra/views/processing.erb b/examples/week6/processingjswithsinatra/views/processing.erb new file mode 100644 index 0000000..fac967d --- /dev/null +++ b/examples/week6/processingjswithsinatra/views/processing.erb @@ -0,0 +1,82 @@ + + + + postExample : Built with Processing and Processing.js + + + + + + + + + + +
    +
    + +

    Your browser does not support the canvas tag.

    + +
    + +
    +

    postExample

    +

    +

    Source code: postExample

    +

    + Built with Processing + and Processing.js +

    +
    + + From 94f29bfb0078b6fe08ebeb7de7f26fc403012e12 Mon Sep 17 00:00:00 2001 From: Zevensuy Rodriguez Date: Thu, 14 Mar 2013 13:04:47 -0400 Subject: [PATCH 57/57] arduino example --- examples/week6/arduinoExample/.htaccess | 4 +++ examples/week6/arduinoExample/app.rb | 8 +++++ examples/week6/arduinoExample/config.ru | 9 +++++ .../arduinoExample/tmp/always_restart.txt | 0 examples/week6/arduinoExample/views/form.erb | 34 +++++++++++++++++++ 5 files changed, 55 insertions(+) create mode 100644 examples/week6/arduinoExample/.htaccess create mode 100644 examples/week6/arduinoExample/app.rb create mode 100644 examples/week6/arduinoExample/config.ru create mode 100644 examples/week6/arduinoExample/tmp/always_restart.txt create mode 100644 examples/week6/arduinoExample/views/form.erb diff --git a/examples/week6/arduinoExample/.htaccess b/examples/week6/arduinoExample/.htaccess new file mode 100644 index 0000000..71ccaed --- /dev/null +++ b/examples/week6/arduinoExample/.htaccess @@ -0,0 +1,4 @@ +PassengerEnabled on +RackBaseURI /sinatra +PassengerAppRoot /home/zr279/sinatra/arduinoExample +RackEnv development diff --git a/examples/week6/arduinoExample/app.rb b/examples/week6/arduinoExample/app.rb new file mode 100644 index 0000000..dc51b5c --- /dev/null +++ b/examples/week6/arduinoExample/app.rb @@ -0,0 +1,8 @@ +require 'sinatra' + +# Main route - this is the form is shown +get '/' do + +"**#{rand(2).to_s}" + +end diff --git a/examples/week6/arduinoExample/config.ru b/examples/week6/arduinoExample/config.ru new file mode 100644 index 0000000..c462621 --- /dev/null +++ b/examples/week6/arduinoExample/config.ru @@ -0,0 +1,9 @@ +require File.dirname(__FILE__) + '/app.rb' + +before do + s = request.path_info + s[/^\/~(\w)+(\d)+\/sinatra\/[^\/|?]+/i] = "" + request.path_info = s +end + +run Sinatra::Application diff --git a/examples/week6/arduinoExample/tmp/always_restart.txt b/examples/week6/arduinoExample/tmp/always_restart.txt new file mode 100644 index 0000000..e69de29 diff --git a/examples/week6/arduinoExample/views/form.erb b/examples/week6/arduinoExample/views/form.erb new file mode 100644 index 0000000..f6b1249 --- /dev/null +++ b/examples/week6/arduinoExample/views/form.erb @@ -0,0 +1,34 @@ + + + + Simple Form Example + + + + +

    Simple form

    +

    This is a simple form example.

    +
    +

    +

    +
    + + +

t0-x?PT?0!I2XaaGvUNKt|Yv~BU><7LujVLxf z0;_{T^<=jxp^n(xt+s_nj{nXkJTHbyhC`ZBN_PR>%?3m&XAJr|bm(0jp7|)X=pTX! zhpyrk;U_Y~b@CFqB2KxQG~j`yMAILSeI1O*bjBoa^SK~iA2B6}?(MF?1n?L6zSvY51tZyAp@2&v7GvYauEt&L5?syKZQ;uw~(1q?_;9fP_lZ%0ViZ3FC)c3feM!6Y2zrsU;6*ad!2a^x^nl zT#a%NSA!8|CaGyY*W;J{P3dv!QPLk#A5{vsONP@G^O%?ZvfDOE%ZnkX7bspM*yK}yAUCIwO|fhlAHFS+qVDu*1qKijb93m~v6&IoNA;i;G6 zvzz0VI9n_pHnYp;U`kMSfY`wl0tb!i&Ka&uA$qSm(2a6>KPZp|4a;S0u+8(h>FehK zO3J%qbVj=?c9b7X)C2dt#Nb-kvGg7f9#>Ud%05y8ci0G3#mVj`yrRG_sP!}#m{GSm zE;nTTS!UK%UYMJ`sfQ#8b`tL`&h!~-{XqL|PXgLDT?+Mx%BQdr)mlm&M3ngAJIX3i zS9xBa`QT3)OUXB^f$LS_$$>b4r8Q#OyRPdBL(Y$~H|H@%^>N32R>o(ip;vyEBDlCR zK3nl{=?BTuL=$;T2cb75O+RvCl)De*=_dUVIt+_x0@urvG!x4RGHTBUR138zIlaxu z!hzIbg!@@M%wR{laxOE1ZsxPG-{8>QKH=_^x+~Citzf3$F^D0ben!QZXRS#>WYuwm z&jmUBdNYC@u`xWMH5=+};adBe;R}CHck+O6!FQOqR~FS*Sj9hO+!J{w(Lz$OKYI}ZBJ5rFTeNVN8+!g3K z^!`tuLw~!Hwn4>*{GRIA-je%WLL&ba9Yit)Q|VoTL!Y&MDnP#NgO2kI9Jr6w|B?Af z91x3y8v`LH9t`~TA>(qtMh(}LHhI1^+1kjqJ$)Hx^aA|}a6KF5d;91NsnuORz(Evr zl0thxfpK4m^d^Wvy!ZJ_fb3}g?H3si`hXvF*ecG!1)QaL9RyZw*zyjxOij|7Y)fQv zEhTtobLLlY;7aK@eadGz(h)SjOU1pQ;$@bU zIG6|&9)`q6uw{`b(;$e@11^8h!K72lFh8bF2Bly&c2qY5w?9LX2Z%35CroGh>^Ui} z;8{vafJ75MZFGDv%Z!OAgUr(zcb6M!e9LBC7#~JJizESmLlP zbaO-iv9!dH@Cf@<1fIXZab2x1swJ_46FFo2NTkr)gSr!&Loy~{2Xa|XtUD_&#N1o6 zzZ6)vl;HSmE-3`BRjL*x_m35C_BY7u>ZLJSG*Cw)U?^0isugu8!Y-;wieu2THfcer zfLpO=b>u%`_o+b&=-HN*s_DDqHPxQjPJlmVZf8@gYx$Hu>H=|zKsULjnOf}WG^NJZYca?U-f%pM4a zZ#x*YmXz~(BPrmCS^p-nIJmwgd&P!|C2K?^BP7Emf@G5of7Po25fB{eTn^*qjn&+# zjQbpQ{n%Yhh}L`j35tA2z6~Zt-iko&OvQU0<#xMizd`<;(D5Biq(SQO3*d=S@`;Mv z2PMi6N$!;`_xc4E^i<&b73#l>rrd4_RT`vN1^-mB{}#J0#e-fN~Q%Q`8CUAmDrksW^@&Ye)2W85zrd0SqGcxSkAaM`xY{9S~I zRl#OtzTbuXqKT6JE4}Y{z3ZyA=1Oc+5!sTB4X!z2XMak~S?AZ2E(VE6ldt6vT~-}T zoQ(Df?j_&CW6?w@ru6~CswOa|Z1hY-G2dkpvBiv6##d!{tjl$=UiEr)L5(2>SCY*H z$@{&m*M{sVOrez6kJy@%g*pW(p_VgjVfm3SgB}R9&1hn{_b1ZEOkxt`g(i8iZ`}Ed zA_Sf2&+)1Q;cC;M1g*9vRIy1&!PnB3GzX0`DQ7pHJ?y4p3*L5w1PvTpvUgm|IC*di zHUM5DD~?SEba6(ZewUjqj2BE=n*&W6PBZP!TE9EOa-Do;hpL-8cR~M4v4dW+h{Da! zA9h3TkWkKZOknRlhil+3H@_UUBGi8UprP*_~W$n#*hS9aDAK96c3XK zBa>P@^TJqKYArxCUBv2#$B(p)n2p$atb&pIof9mejyF!&S&{G=<@4m-Cn>n^>*YX0 zueX>VG1MoB?iEu$AA=6Ln60Nj>H=&96)}Q@LgIw_E#I-bUtvvOX`r6i&Ua^AqJIiU z{v5;(2xSjI4Ex!K^NxA^$fv(^<&qH4OYx49_C%$BnCB7`(C6`vf%b}b3A`dqyMXNR zcjJkmq`!O28DwQwqZHgAnNC$RqOI?rsKKDKIW&YmlffNTJDWQjN!`O8a_q=@{ohn- zmzN^*G)ThoKoa&(3^sp{H$bCl6=cxamsM4*+8|dI{TRoWbd{iI1`We8 z1(ioDQb%g{dLlDbyXw*rKI3>DL-%xY4eE!ziw*6Y`P@~iLKqmrbEE}q zMuqbTN)u~hvjt84{>rcJLBh0H(0K1nQ=3wTC#{o|KdIQ6#yi1;#5LCIrinrAC=stV z9uI{0AiN~?Y8UmX1VN%$5wf*{^vMUD_hk_ZvJFxI+MF6M1|JXX1-1+4sq{sreCl5{ z+AKQDiwGKVFMp>G2oT5=vu`Z3#6k1UM>6ab#3EpF(6ikB8o@EtHL|=$(K_W1NF>~? zPt?S&<;vz7Fa{?=RKh;`of8e{+wKQQyRVu}a1C6%N=I zp+ps3r8jkiH!BTb;u*k!=a)f3D^@kqZ`__q@iT(eOWw}>Jv_%h>b{AD;hg0^BFYH} z-1+!qG66)l%EZ`FNOfX$O1V;4K+Bs?nl2G-mt!LC`;loySl_6CLMZtN-+45}7Nlmv zIY_tb!(j{2RniHI$ezpg^LDHH0=~CE{5^6u{xk{0niI$tR|FXF2`QsIy6 z6?-T2-vR}klSg3$36%Fg6ey0r4M6`lrx2(ssfCfCAofy`v!mHD$PYTCJtXA<Wg{QkaTX8T_BoG| z7LgFxY$zmAW!-idI81U8L7!`g^K4Wd5@m2XP zfts^^A1t83aC0_?df-y{wZT&(s+ir3h4oCkqke^Lsi(Ks%u<#4Jp2rhK3U2HXQ$Yi zP8uiVNZGU)WO+Jo=;dl9(~8rZABzL1Go_hof%IA1D{aPZx6fLYCoj@zsUvke!Z0~0 zp5o0UTZ?tSSMH){A|DXW|I~H-(Y%sqX#*>z&4#WBqr>fn{Tsf7Bz$OAmmd!djhqE) zyE>y8)l@sJTk~U6IP4%U9G4Z9W`XjZGNjR*QsZ&1C|^s0s1Q!E;$*}IGME;?Jh=lK zriUI~4q~B4vSDkXjD$qW$XBGN9_iS`no16RXSZSzk-(x#DyV>w?!zC5m^w0a*EC=p zm>NnqQ${T{v04~RrJ7ZQSaQh8C?GW{UFdf%4NWNKrRGibn$^@xUTlda1{~wy!Uvx` z$l89HD!>1kt7LVj?!U;PM?a?nnnqMclXSsaT|la8R$mF3lS6ZSjVLI=?n6Itqo1nt zkm5q*6$qUc6BPY2$TZ)9_7WyeYDl;*()vf$M2GTDl_(sea)oYEPRz$#ZZ05@F>Z?G zEysOZT||(A++Tg6yDq88(RsE8!iiaZhA>dT8Kv{YKoaKKYDJ-g*27yRn3rpWaPfFw zhpT|cCl%>P8P%bUNy{nT`5=!bky$35T$WXsYX|omTLFf*X75`GPjU{tKuBWn10iFG zD>c=`v94Ny@t1W@(l^^L>l9u6knYmGu|G}k?L)Zig+EU16FZ;-VpZQi=e$xpKhh!G zEMxCFF;8!s0)7tg2gLn(1y_9~vww%xda}~rH*(Gi7*cpgY<=|FI1+MB`_X{_`G@}1 z(i#WR+FeIa5-ro_Sam}L#MN;?y6lIxY z8l%+kPXHAgjpox1^dpOZ&`M*3E-AU*ue2ONw#{#r&o48eBZ|d9?hxi-(Y9D^WM0P* zXSCMjNIDKe@)Q`-2-v%?dLoo5Y4gk_BvZ3J#;d8FqqA5{_}Cm|8l30d>T@Zn-Dx^R z+m_eI*@?#CnDlz~nsJ^X8?2t=P4foM@-{5|zJwGluyOvak)mr#cUEq6q%!O{hsHKtG%Q|(BuK&$t-!+S)V^xAkPYd#Y7 z-AM~K>70cBMzk*d2h7m>MJ#un5*_tsGqd$j<5lG-`T6#CUd;T z7?>z8=6L2KDWRs^&t>nz%Yj295jC|I^=HxvUh)qY^(*Y^=1m&BwrwA#Fb08ih@GbG zsb&jRw)cv^M=I99`&SJT<_j*mDZ7~;ycA|a3`kMCf?%;|a&(q(xotm!#Ot9*i%fz| z%6Y;If?-&O{!~&R*-)>@;gY$Sw_8mBj}grG9)$TSKK;%1VI`v&4-OlkHt4~1ArdN&>`w$fP& z{H=8j$Ai`h{8-T32icB41hICX2B~P2%zLQFdy21qqSF{ixYC8Cv32Z`R_=9O)`?qN zxP8_Ju*1$rz;|K}CovrlGhsT0ksN#OHe^h=RTIApv;WRrvre9xAhCn>-}<9scuuYk z(x04vsz3iR#i)Z!F*4}yxbyO;P;)!9lJOITS)i*2Dku`{-wP8oM7kC=b*73#=a|u~ zcvDlEbPtP=dUT$5sx+PW?Z@ON>a=|RVho;#5&TMr+idYo<8Ze8*%qZ+r*$#4b;3X%rU=LftGgP??@<7|V+n~_#yIC^=_`y=28 zwy!YdHY2p{g1cTKl^Ctoq=7ErBMRBQA%RJhlrH0gHU|pwCToKT)9Kt*B|6z$&V7UU z@0`wagB1FlEI%0F+e}SWMhqaE=eDus0J%_#P_-=4Z;t1PQXKf7Hr8Rd0WBH@)flH( z#j4MpJSjbW@f-X?1D;Wu!ecbcsz~EEh3=7yYREDadSZ9k+9hDO9Ja}nSX#NxetN65 zVshF}HMS@nktXf2MspbDw0%=0$L))2se4KaI3|1{LzEHFqDX7s&p`ZNzPV?`E;gyGGyW3YiY&VRvGWX>=~{fgSQwCz_ua? z$g^}M(fJY(T+b!77;>yi z5eLR+kvPHoIK?>GBOCd~(5=d2NZu0^ULng3R#|uBYWl>mIIsoxo5yuY;f?8yZV;v? zedtj)yma=0w$Y1DxgmXCMJZk+eVucCUuVa@0+F`EviL(umG&8Db_8ekNQAyi`5`NL ze^Giu&IOwAACq~HA?;!i4dMA?+r3(U*DnQ3YaJ}j#R!09o}Cn^aTcI4&4u}Ain6^U z_~P~&?j;x-c7`XKuT}($Ukf1w%nfv%3gb#sAp?@)`GL`>f3X$V)BafUKo)q%? zu(h@fJrw*aCMPL5%Bc2^6sn#!Ke==rBveQ!kq=@O*ix!z%BDv7L29MG>lBGbPqAxc zRU+t8iq>H~-12ML;Hi$oss;GG=AEa~%re`i(afaK$J-Ouci7~jlL2dV8hzED^)QTN z1by6;g>6AqD*6K+96*s|O2KGiKwPqim=0G;%IPP=_bTTkTW`4`OAdLPbjy=$c7}xs zPyt~QM*WcJAg!)(pL3J9qibYVHHA4mZ!kZhNl(?U)Z!{`q~xSMh`_KHQ$`Ni!F z=yF*2%N}8@Ge4#gawdC&fMst*_qNh}*6gmpUF$w?caLV1VU8iNJGOhK#fE+*tzwxj z)AHTw%k*JOC>eqhZxyIP6mpSMe`7}i-Lv2acvmsN>@g!WZ%2HGl8GhJZ90o3IaU}F z+s+y?(Bwgma7$IGHyAfj@m=@SkrJ}xIB-8;DKjG^vU?OC`Fv@uz374>2YP8~YrbO; z{0kl;KtNG_)&_cS5$+|#Dy7_IG-v|bW0{igD69tx?u*&-(Mq4`rm zt=Esv8ertsGi(Ok@^f5D$MTzV+pMJO{TMH8rT$qdH$m+Al0+8faknvd%8bvn4tP*d zV3ezpcZOovc31Y7T4cc|X2mTZ!O{)Jo+cc%X>rud3@d)PpaC$>Fs|^qON7YvmBodZ z(9zm*jAxjf$7A9j?B3<-_U6t|63nJoXBxgUU|P#=rgUAOw2`lIBx}a_#@6XCusK9I zdQ^Q~i&ma^n6_8_2&zeYwHqthUr{&U&#==F(_YJRQ!rmHRamwwapYAx5ioJ*M|FrJ z>b46rD;+uYIS+o0O}O1B7tkpi?Fd3X=@a*6$FO4R_53zy^Xvs$mr+i~gT^5y*%BK@ zW}mP!fs@4U;ruUYxZL;XR?;5yCHKf{;6!%$jbIMn(z18Yd#`A3qyln|T18Mv+Lcfd zn+Q)Xg^{3moH*(LEAs@3zU+buQ6LJWK5eUXP`G9Q$CH!Wt_Mm&B z^B&=HZ%F-*>>g9L2b{V>40>V(KnIKeNC_q^_f`xV`u>Lcw)SA8(h&y%@XLGvegV*= zLHPG|ddE2vcyG@zMxe}-{7g8OnVyrEhg1q z7@gF&-EcL~-yL@?108im{hMOyNl;QC5ELAK$>Jp;>)Oc3gBQ>1uETHiQr1Ov%H{As zo=3&?m`{GqU02C=$$kfWE5e`IB>t5N$XWe51GAHBmT@lz{kwn=7zPsO`5 z12IVe6Ju~JfwiLG6Z2UFs&(7W7lfY24Kcu2tCS^-v>lb*I%Y)uLTUd*-^7moRAtAD zLp#kBu7%=54FMf>dn-iv9kLDL;`l@vsJbt;*%2T30NqkWQ{^Gy_BfYocn_)`zrl6U z7$I|T()nUC{ta1WJ)K2$Y$nOUNDAKrO5sSPP}U?ItUAmA?=rV%ek$G2D>0C%dMDS4N>@v+rl=d=R%5=*D|4KHnkVP31o zcjOd}gU#8JdL)TuLhD3`^;H!VtBeA%q7H&9fy;IcGOd!Lam^nh)a=7vh>!2?-qq&zboNv#iil7MX5qA!Icv?Ne5;|n z53@bvut|EKA0#>msO(wQW1-#HJeczTli#lwY{%k6c-;tmS6ZGwO~79Udj^ z_qcBO*%t5Pi;*+91r-SHx9zFBFw!mR(CHD+ltwqz^z+E^tbNHr30MPy!WXe^waTYK zhdx344mcGzV>n8f$4P%uZ$e~qQyTj{tT`|BdaTbb6jXXpHDhHC9ZwhF?lvIIvB@%{blf8z#(UFb z#!9#nf}iakOl+of!A!3e z!7l$Eu~em2R@#F_=cl%#{7J0t6k7(3EJdQQUo7CzCu*ulZ+cPu#Y zYZ=z20f7Rr$XPbk6cCRTe$sAgGblrt_VBj$Qf54PGNMwWja@%NJl>|_JZ`-bwW-a> zfy!A0TgbmR3mhpjh*#xU<>r-KA-$gxZ*vCK7L$>mFd8GKQMogk19^aJ?4RA5?B64- z4{%H)Q1{Svi9&qcNA)=tuRWL4?1>-n;2NIWURk++2K{-(rF`NVy>Uu7hIfAQ(BI*5 zPS_sQcqga@O3+{HX&ad%qkRCoL6J${EkDTC7NgB<{k!Xuusy zB5w3Q@V#(^5)o=pQA++(o&DPrHuJB5FBGr69;WhZASo^Ncw8X{I(lU|x_T2bq(l*P zV-q-iG68ER2Mcfq6nu)3LL!W&lq931g|p?b<$sona7xuE`s{FX|LtXqi|y*0Q`vUF zfe^U$kTUw=3W0>cy|^-nlk7HJVm9d8v&T=xK@Q%0m8w8aaA+La*tOUT z4>o&8c?F&28t)}n%005&hMb5&;RR|jY8tkn0#XY;Q)(_Y%0);!dbx!0WO=<+6}i=C z0T@7+%sQxb=GoyErD#k&gNs}&E6xm8YG>ub%WF=iQ-2N0#*9_49&F@S+1^UXzmwI* z0iea$&7yrACnlvf%;zc(G-YFVI3KYrRyQN6pbymcccQQ;q?(7vj%Le7CAD073~VEw zFN1t5Z;HHh2J=qJ-bt)xg`Y2=c;)ejQP6TuSmT*p&`0FmizWtLVti-q@@K?_6f?O& z*I=OBFQcb(B(PF+v;_eFvs(S^I(KE_&s5I5H?Mf>Z(`Xg}!G!4wL7J>X)7)l&D@av2DC-D|F_eE2q} zE1OS&Zxu1{CFBGuxv(ewW5|KNh)YS#RoM?`At8Yx00O%tY}pZtZ-&QiEt#c!1GTdZ zXlyOZ4>Rq>)jb*CQl*IWwMT*Pho7emc@o?Lt~9lr%iXWEj&AYu10q~cj8JqSm*!Fo zmC6xG(36n3Mr>F3>XrqI5_2gAKLvy%hA70K3`?p%eYNjfI=r(_Um=M+(8E+&?Ea=` zMU*J<8ISV+QTCQWbuC-eXcB^3aCdii3l72EgS*4V-QC^Y9X1}^-Ccq^!8OR+Iaj`S z&#PB;zCWv0?VhXG{?Vg)^_XLh83C~g=c%z}3Dy;HMyvt0!d7p?jH9ke?DLzda+x9loy99PQhgZHn{f2MQa*w9Ghq{bY zT{~d!2Q#sor}!aqgZf5l?|&TQP)7FGJX3dXjpcnHEk5u>-Nf34WhCrig9 z&|U?hZNsE}0rQXD)ve&$XAsv~OV0mj#EQ+fxkESTlh0XV%?Ja`7(Y8pyZB?Earoo; zb&txIUPPzVe=R70Q#tw@u5%AqjdG`h;+q3-SAwecZ7c}k^PXwRt+S+EGccO^NMU+R zo;??*jc>Si2}NVR+T1VDWE?UdBwe}bseK?0ATb&Q7giDB=r?kAQ&neKwenZBAU2Vf z(w?W)@jk@ByZ6sF_z-~24yPZ4tVvB~Hh{-e_0(-JDop_LvK(;xj?SR9_^Jgk2v%rIE4zFfy6+qG6@tFrV>;1 z9L!`X)NWpD7}>9?4obcrd7J1s6oaMjc?@}}n5)V%NWIng}Y+H7Q^&1tbGoHP5I=Rt$fVxx9%n)-vb_8+)EgIvR52_%0A;mT}9zgpxPc4 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 b$V$$$U$HuFyezY$lGz!iMo59!>xKUSdFOQs literal 0 HcmV?d00001 diff --git a/examples/week6/imageupload/tmp/always_restart.txt b/examples/week6/imageupload/tmp/always_restart.txt new file mode 100755 index 0000000..e69de29 diff --git a/examples/week6/imageupload/views/form.erb b/examples/week6/imageupload/views/form.erb new file mode 100755 index 0000000..75c160f --- /dev/null +++ b/examples/week6/imageupload/views/form.erb @@ -0,0 +1,13 @@ + + + Image Upload + + +

t0-x?PT?0!I2XaaGvUNKt|Yv~BU><7LujVLxf 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%0A;mT}9zgpxPc4 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

t0-x?PT?0!I2XaaGvUNKt|Yv~BU><7LujVLxf z0;_{T^<=jxp^n(xt+s_nj{nXkJTHbyhC`ZBN_PR>%?3m&XAJr|bm(0jp7|)X=pTX! zhpyrk;U_Y~b@CFqB2KxQG~j`yMAILSeI1O*bjBoa^SK~iA2B6}?(MF?1n?L6zSvY51tZyAp@2&v7GvYauEt&L5?syKZQ;uw~(1q?_;9fP_lZ%0ViZ3FC)c3feM!6Y2zrsU;6*ad!2a^x^nl zT#a%NSA!8|CaGyY*W;J{P3dv!QPLk#A5{vsONP@G^O%?ZvfDOE%ZnkX7bspM*yK}yAUCIwO|fhlAHFS+qVDu*1qKijb93m~v6&IoNA;i;G6 zvzz0VI9n_pHnYp;U`kMSfY`wl0tb!i&Ka&uA$qSm(2a6>KPZp|4a;S0u+8(h>FehK zO3J%qbVj=?c9b7X)C2dt#Nb-kvGg7f9#>Ud%05y8ci0G3#mVj`yrRG_sP!}#m{GSm zE;nTTS!UK%UYMJ`sfQ#8b`tL`&h!~-{XqL|PXgLDT?+Mx%BQdr)mlm&M3ngAJIX3i zS9xBa`QT3)OUXB^f$LS_$$>b4r8Q#OyRPdBL(Y$~H|H@%^>N32R>o(ip;vyEBDlCR zK3nl{=?BTuL=$;T2cb75O+RvCl)De*=_dUVIt+_x0@urvG!x4RGHTBUR138zIlaxu z!hzIbg!@@M%wR{laxOE1ZsxPG-{8>QKH=_^x+~Citzf3$F^D0ben!QZXRS#>WYuwm z&jmUBdNYC@u`xWMH5=+};adBe;R}CHck+O6!FQOqR~FS*Sj9hO+!J{w(Lz$OKYI}ZBJ5rFTeNVN8+!g3K z^!`tuLw~!Hwn4>*{GRIA-je%WLL&ba9Yit)Q|VoTL!Y&MDnP#NgO2kI9Jr6w|B?Af z91x3y8v`LH9t`~TA>(qtMh(}LHhI1^+1kjqJ$)Hx^aA|}a6KF5d;91NsnuORz(Evr zl0thxfpK4m^d^Wvy!ZJ_fb3}g?H3si`hXvF*ecG!1)QaL9RyZw*zyjxOij|7Y)fQv zEhTtobLLlY;7aK@eadGz(h)SjOU1pQ;$@bU zIG6|&9)`q6uw{`b(;$e@11^8h!K72lFh8bF2Bly&c2qY5w?9LX2Z%35CroGh>^Ui} z;8{vafJ75MZFGDv%Z!OAgUr(zcb6M!e9LBC7#~JJizESmLlP zbaO-iv9!dH@Cf@<1fIXZab2x1swJ_46FFo2NTkr)gSr!&Loy~{2Xa|XtUD_&#N1o6 zzZ6)vl;HSmE-3`BRjL*x_m35C_BY7u>ZLJSG*Cw)U?^0isugu8!Y-;wieu2THfcer zfLpO=b>u%`_o+b&=-HN*s_DDqHPxQjPJlmVZf8@gYx$Hu>H=|zKsULjnOf}WG^NJZYca?U-f%pM4a zZ#x*YmXz~(BPrmCS^p-nIJmwgd&P!|C2K?^BP7Emf@G5of7Po25fB{eTn^*qjn&+# zjQbpQ{n%Yhh}L`j35tA2z6~Zt-iko&OvQU0<#xMizd`<;(D5Biq(SQO3*d=S@`;Mv z2PMi6N$!;`_xc4E^i<&b73#l>rrd4_RT`vN1^-mB{}#J0#e-fN~Q%Q`8CUAmDrksW^@&Ye)2W85zrd0SqGcxSkAaM`xY{9S~I zRl#OtzTbuXqKT6JE4}Y{z3ZyA=1Oc+5!sTB4X!z2XMak~S?AZ2E(VE6ldt6vT~-}T zoQ(Df?j_&CW6?w@ru6~CswOa|Z1hY-G2dkpvBiv6##d!{tjl$=UiEr)L5(2>SCY*H z$@{&m*M{sVOrez6kJy@%g*pW(p_VgjVfm3SgB}R9&1hn{_b1ZEOkxt`g(i8iZ`}Ed zA_Sf2&+)1Q;cC;M1g*9vRIy1&!PnB3GzX0`DQ7pHJ?y4p3*L5w1PvTpvUgm|IC*di zHUM5DD~?SEba6(ZewUjqj2BE=n*&W6PBZP!TE9EOa-Do;hpL-8cR~M4v4dW+h{Da! zA9h3TkWkKZOknRlhil+3H@_UUBGi8UprP*_~W$n#*hS9aDAK96c3XK zBa>P@^TJqKYArxCUBv2#$B(p)n2p$atb&pIof9mejyF!&S&{G=<@4m-Cn>n^>*YX0 zueX>VG1MoB?iEu$AA=6Ln60Nj>H=&96)}Q@LgIw_E#I-bUtvvOX`r6i&Ua^AqJIiU z{v5;(2xSjI4Ex!K^NxA^$fv(^<&qH4OYx49_C%$BnCB7`(C6`vf%b}b3A`dqyMXNR zcjJkmq`!O28DwQwqZHgAnNC$RqOI?rsKKDKIW&YmlffNTJDWQjN!`O8a_q=@{ohn- zmzN^*G)ThoKoa&(3^sp{H$bCl6=cxamsM4*+8|dI{TRoWbd{iI1`We8 z1(ioDQb%g{dLlDbyXw*rKI3>DL-%xY4eE!ziw*6Y`P@~iLKqmrbEE}q zMuqbTN)u~hvjt84{>rcJLBh0H(0K1nQ=3wTC#{o|KdIQ6#yi1;#5LCIrinrAC=stV z9uI{0AiN~?Y8UmX1VN%$5wf*{^vMUD_hk_ZvJFxI+MF6M1|JXX1-1+4sq{sreCl5{ z+AKQDiwGKVFMp>G2oT5=vu`Z3#6k1UM>6ab#3EpF(6ikB8o@EtHL|=$(K_W1NF>~? zPt?S&<;vz7Fa{?=RKh;`of8e{+wKQQyRVu}a1C6%N=I zp+ps3r8jkiH!BTb;u*k!=a)f3D^@kqZ`__q@iT(eOWw}>Jv_%h>b{AD;hg0^BFYH} z-1+!qG66)l%EZ`FNOfX$O1V;4K+Bs?nl2G-mt!LC`;loySl_6CLMZtN-+45}7Nlmv zIY_tb!(j{2RniHI$ezpg^LDHH0=~CE{5^6u{xk{0niI$tR|FXF2`QsIy6 z6?-T2-vR}klSg3$36%Fg6ey0r4M6`lrx2(ssfCfCAofy`v!mHD$PYTCJtXA<Wg{QkaTX8T_BoG| z7LgFxY$zmAW!-idI81U8L7!`g^K4Wd5@m2XP zfts^^A1t83aC0_?df-y{wZT&(s+ir3h4oCkqke^Lsi(Ks%u<#4Jp2rhK3U2HXQ$Yi zP8uiVNZGU)WO+Jo=;dl9(~8rZABzL1Go_hof%IA1D{aPZx6fLYCoj@zsUvke!Z0~0 zp5o0UTZ?tSSMH){A|DXW|I~H-(Y%sqX#*>z&4#WBqr>fn{Tsf7Bz$OAmmd!djhqE) zyE>y8)l@sJTk~U6IP4%U9G4Z9W`XjZGNjR*QsZ&1C|^s0s1Q!E;$*}IGME;?Jh=lK zriUI~4q~B4vSDkXjD$qW$XBGN9_iS`no16RXSZSzk-(x#DyV>w?!zC5m^w0a*EC=p zm>NnqQ${T{v04~RrJ7ZQSaQh8C?GW{UFdf%4NWNKrRGibn$^@xUTlda1{~wy!Uvx` z$l89HD!>1kt7LVj?!U;PM?a?nnnqMclXSsaT|la8R$mF3lS6ZSjVLI=?n6Itqo1nt zkm5q*6$qUc6BPY2$TZ)9_7WyeYDl;*()vf$M2GTDl_(sea)oYEPRz$#ZZ05@F>Z?G zEysOZT||(A++Tg6yDq88(RsE8!iiaZhA>dT8Kv{YKoaKKYDJ-g*27yRn3rpWaPfFw zhpT|cCl%>P8P%bUNy{nT`5=!bky$35T$WXsYX|omTLFf*X75`GPjU{tKuBWn10iFG zD>c=`v94Ny@t1W@(l^^L>l9u6knYmGu|G}k?L)Zig+EU16FZ;-VpZQi=e$xpKhh!G zEMxCFF;8!s0)7tg2gLn(1y_9~vww%xda}~rH*(Gi7*cpgY<=|FI1+MB`_X{_`G@}1 z(i#WR+FeIa5-ro_Sam}L#MN;?y6lIxY z8l%+kPXHAgjpox1^dpOZ&`M*3E-AU*ue2ONw#{#r&o48eBZ|d9?hxi-(Y9D^WM0P* zXSCMjNIDKe@)Q`-2-v%?dLoo5Y4gk_BvZ3J#;d8FqqA5{_}Cm|8l30d>T@Zn-Dx^R z+m_eI*@?#CnDlz~nsJ^X8?2t=P4foM@-{5|zJwGluyOvak)mr#cUEq6q%!O{hsHKtG%Q|(BuK&$t-!+S)V^xAkPYd#Y7 z-AM~K>70cBMzk*d2h7m>MJ#un5*_tsGqd$j<5lG-`T6#CUd;T z7?>z8=6L2KDWRs^&t>nz%Yj295jC|I^=HxvUh)qY^(*Y^=1m&BwrwA#Fb08ih@GbG zsb&jRw)cv^M=I99`&SJT<_j*mDZ7~;ycA|a3`kMCf?%;|a&(q(xotm!#Ot9*i%fz| z%6Y;If?-&O{!~&R*-)>@;gY$Sw_8mBj}grG9)$TSKK;%1VI`v&4-OlkHt4~1ArdN&>`w$fP& z{H=8j$Ai`h{8-T32icB41hICX2B~P2%zLQFdy21qqSF{ixYC8Cv32Z`R_=9O)`?qN zxP8_Ju*1$rz;|K}CovrlGhsT0ksN#OHe^h=RTIApv;WRrvre9xAhCn>-}<9scuuYk z(x04vsz3iR#i)Z!F*4}yxbyO;P;)!9lJOITS)i*2Dku`{-wP8oM7kC=b*73#=a|u~ zcvDlEbPtP=dUT$5sx+PW?Z@ON>a=|RVho;#5&TMr+idYo<8Ze8*%qZ+r*$#4b;3X%rU=LftGgP??@<7|V+n~_#yIC^=_`y=28 zwy!YdHY2p{g1cTKl^Ctoq=7ErBMRBQA%RJhlrH0gHU|pwCToKT)9Kt*B|6z$&V7UU z@0`wagB1FlEI%0F+e}SWMhqaE=eDus0J%_#P_-=4Z;t1PQXKf7Hr8Rd0WBH@)flH( z#j4MpJSjbW@f-X?1D;Wu!ecbcsz~EEh3=7yYREDadSZ9k+9hDO9Ja}nSX#NxetN65 zVshF}HMS@nktXf2MspbDw0%=0$L))2se4KaI3|1{LzEHFqDX7s&p`ZNzPV?`E;gyGGyW3YiY&VRvGWX>=~{fgSQwCz_ua? z$g^}M(fJY(T+b!77;>yi z5eLR+kvPHoIK?>GBOCd~(5=d2NZu0^ULng3R#|uBYWl>mIIsoxo5yuY;f?8yZV;v? zedtj)yma=0w$Y1DxgmXCMJZk+eVucCUuVa@0+F`EviL(umG&8Db_8ekNQAyi`5`NL ze^Giu&IOwAACq~HA?;!i4dMA?+r3(U*DnQ3YaJ}j#R!09o}Cn^aTcI4&4u}Ain6^U z_~P~&?j;x-c7`XKuT}($Ukf1w%nfv%3gb#sAp?@)`GL`>f3X$V)BafUKo)q%? zu(h@fJrw*aCMPL5%Bc2^6sn#!Ke==rBveQ!kq=@O*ix!z%BDv7L29MG>lBGbPqAxc zRU+t8iq>H~-12ML;Hi$oss;GG=AEa~%re`i(afaK$J-Ouci7~jlL2dV8hzED^)QTN z1by6;g>6AqD*6K+96*s|O2KGiKwPqim=0G;%IPP=_bTTkTW`4`OAdLPbjy=$c7}xs zPyt~QM*WcJAg!)(pL3J9qibYVHHA4mZ!kZhNl(?U)Z!{`q~xSMh`_KHQ$`Ni!F z=yF*2%N}8@Ge4#gawdC&fMst*_qNh}*6gmpUF$w?caLV1VU8iNJGOhK#fE+*tzwxj z)AHTw%k*JOC>eqhZxyIP6mpSMe`7}i-Lv2acvmsN>@g!WZ%2HGl8GhJZ90o3IaU}F z+s+y?(Bwgma7$IGHyAfj@m=@SkrJ}xIB-8;DKjG^vU?OC`Fv@uz374>2YP8~YrbO; z{0kl;KtNG_)&_cS5$+|#Dy7_IG-v|bW0{igD69tx?u*&-(Mq4`rm zt=Esv8ertsGi(Ok@^f5D$MTzV+pMJO{TMH8rT$qdH$m+Al0+8faknvd%8bvn4tP*d zV3ezpcZOovc31Y7T4cc|X2mTZ!O{)Jo+cc%X>rud3@d)PpaC$>Fs|^qON7YvmBodZ z(9zm*jAxjf$7A9j?B3<-_U6t|63nJoXBxgUU|P#=rgUAOw2`lIBx}a_#@6XCusK9I zdQ^Q~i&ma^n6_8_2&zeYwHqthUr{&U&#==F(_YJRQ!rmHRamwwapYAx5ioJ*M|FrJ z>b46rD;+uYIS+o0O}O1B7tkpi?Fd3X=@a*6$FO4R_53zy^Xvs$mr+i~gT^5y*%BK@ zW}mP!fs@4U;ruUYxZL;XR?;5yCHKf{;6!%$jbIMn(z18Yd#`A3qyln|T18Mv+Lcfd zn+Q)Xg^{3moH*(LEAs@3zU+buQ6LJWK5eUXP`G9Q$CH!Wt_Mm&B z^B&=HZ%F-*>>g9L2b{V>40>V(KnIKeNC_q^_f`xV`u>Lcw)SA8(h&y%@XLGvegV*= zLHPG|ddE2vcyG@zMxe}-{7g8OnVyrEhg1q z7@gF&-EcL~-yL@?108im{hMOyNl;QC5ELAK$>Jp;>)Oc3gBQ>1uETHiQr1Ov%H{As zo=3&?m`{GqU02C=$$kfWE5e`IB>t5N$XWe51GAHBmT@lz{kwn=7zPsO`5 z12IVe6Ju~JfwiLG6Z2UFs&(7W7lfY24Kcu2tCS^-v>lb*I%Y)uLTUd*-^7moRAtAD zLp#kBu7%=54FMf>dn-iv9kLDL;`l@vsJbt;*%2T30NqkWQ{^Gy_BfYocn_)`zrl6U z7$I|T()nUC{ta1WJ)K2$Y$nOUNDAKrO5sSPP}U?ItUAmA?=rV%ek$G2D>0C%dMDS4N>@v+rl=d=R%5=*D|4KHnkVP31o zcjOd}gU#8JdL)TuLhD3`^;H!VtBeA%q7H&9fy;IcGOd!Lam^nh)a=7vh>!2?-qq&zboNv#iil7MX5qA!Icv?Ne5;|n z53@bvut|EKA0#>msO(wQW1-#HJeczTli#lwY{%k6c-;tmS6ZGwO~79Udj^ z_qcBO*%t5Pi;*+91r-SHx9zFBFw!mR(CHD+ltwqz^z+E^tbNHr30MPy!WXe^waTYK zhdx344mcGzV>n8f$4P%uZ$e~qQyTj{tT`|BdaTbb6jXXpHDhHC9ZwhF?lvIIvB@%{blf8z#(UFb z#!9#nf}iakOl+of!A!3e z!7l$Eu~em2R@#F_=cl%#{7J0t6k7(3EJdQQUo7CzCu*ulZ+cPu#Y zYZ=z20f7Rr$XPbk6cCRTe$sAgGblrt_VBj$Qf54PGNMwWja@%NJl>|_JZ`-bwW-a> zfy!A0TgbmR3mhpjh*#xU<>r-KA-$gxZ*vCK7L$>mFd8GKQMogk19^aJ?4RA5?B64- z4{%H)Q1{Svi9&qcNA)=tuRWL4?1>-n;2NIWURk++2K{-(rF`NVy>Uu7hIfAQ(BI*5 zPS_sQcqga@O3+{HX&ad%qkRCoL6J${EkDTC7NgB<{k!Xuusy zB5w3Q@V#(^5)o=pQA++(o&DPrHuJB5FBGr69;WhZASo^Ncw8X{I(lU|x_T2bq(l*P zV-q-iG68ER2Mcfq6nu)3LL!W&lq931g|p?b<$sona7xuE`s{FX|LtXqi|y*0Q`vUF zfe^U$kTUw=3W0>cy|^-nlk7HJVm9d8v&T=xK@Q%0m8w8aaA+La*tOUT z4>o&8c?F&28t)}n%005&hMb5&;RR|jY8tkn0#XY;Q)(_Y%0);!dbx!0WO=<+6}i=C z0T@7+%sQxb=GoyErD#k&gNs}&E6xm8YG>ub%WF=iQ-2N0#*9_49&F@S+1^UXzmwI* z0iea$&7yrACnlvf%;zc(G-YFVI3KYrRyQN6pbymcccQQ;q?(7vj%Le7CAD073~VEw zFN1t5Z;HHh2J=qJ-bt)xg`Y2=c;)ejQP6TuSmT*p&`0FmizWtLVti-q@@K?_6f?O& z*I=OBFQcb(B(PF+v;_eFvs(S^I(KE_&s5I5H?Mf>Z(`Xg}!G!4wL7J>X)7)l&D@av2DC-D|F_eE2q} zE1OS&Zxu1{CFBGuxv(ewW5|KNh)YS#RoM?`At8Yx00O%tY}pZtZ-&QiEt#c!1GTdZ zXlyOZ4>Rq>)jb*CQl*IWwMT*Pho7emc@o?Lt~9lr%iXWEj&AYu10q~cj8JqSm*!Fo zmC6xG(36n3Mr>F3>XrqI5_2gAKLvy%hA70K3`?p%eYNjfI=r(_Um=M+(8E+&?Ea=` zMU*J<8ISV+QTCQWbuC-eXcB^3aCdii3l72EgS*4V-QC^Y9X1}^-Ccq^!8OR+Iaj`S z&#PB;zCWv0?VhXG{?Vg)^_XLh83C~g=c%z}3Dy;HMyvt0!d7p?jH9ke?DLzda+x9loy99PQhgZHn{f2MQa*w9Ghq{bY zT{~d!2Q#sor}!aqgZf5l?|&TQP)7FGJX3dXjpcnHEk5u>-Nf34WhCrig9 z&|U?hZNsE}0rQXD)ve&$XAsv~OV0mj#EQ+fxkESTlh0XV%?Ja`7(Y8pyZB?Earoo; zb&txIUPPzVe=R70Q#tw@u5%AqjdG`h;+q3-SAwecZ7c}k^PXwRt+S+EGccO^NMU+R zo;??*jc>Si2}NVR+T1VDWE?UdBwe}bseK?0ATb&Q7giDB=r?kAQ&neKwenZBAU2Vf z(w?W)@jk@ByZ6sF_z-~24yPZ4tVvB~Hh{-e_0(-JDop_LvK(;xj?SR9_^Jgk2v%rIE4zFfy6+qG6@tFrV>;1 z9L!`X)NWpD7}>9?4obcrd7J1s6oaMjc?@}}n5)V%NWIng}Y+H7Q^&1tbGoHP5I=Rt$fVxx9%n)-vb_8+)EgIvR52_%0A;mT}9zgpxPc4 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