From: Loic Baron Date: Wed, 20 Nov 2013 15:51:13 +0000 (+0100) Subject: Merge branch 'master' of ssh://git.onelab.eu/git/myslice X-Git-Tag: myslice-0.3-0~113^2~7 X-Git-Url: http://git.onelab.eu/?p=myslice.git;a=commitdiff_plain;h=dc832ad1a26a47483f8297678a9417640b7c9925;hp=4805b1478e681cd2304c156a7869225623649c2f Merge branch 'master' of ssh://git.onelab.eu/git/myslice --- diff --git a/README b/README index 7bcba427..2a183a89 100644 --- a/README +++ b/README @@ -18,6 +18,7 @@ $ apt-get install python-django-south * edit myslice/config.py and enter the details of your manifold backend +$ apt-get install python-django-south * init django $ ./manage.py syncdb $ ./manage.py migrate @@ -45,7 +46,7 @@ $ make redo == make redo-static redo-templates * run a local server: -$ manage.py runserver 0.0.0.0:8000 +$ ./manage.py runserver 0.0.0.0:8000 -- or -- my advice: $ devel/server-loop.sh when you just need to hit ^C yourself when your static files need to be refreshed - see below diff --git a/auth/static/css/login.css b/auth/static/css/login.css index bcb25da7..f31fe716 100644 --- a/auth/static/css/login.css +++ b/auth/static/css/login.css @@ -1,4 +1,5 @@ p.login-status { + padding-top: 10px; font-weight: bold; } diff --git a/auth/templates/widget-login.html b/auth/templates/widget-login.html index ffb6244d..37fb938b 100644 --- a/auth/templates/widget-login.html +++ b/auth/templates/widget-login.html @@ -1,7 +1,6 @@ {% insert_str prelude 'css/login.css' %}

{{ state }}

- -
+
{% csrf_token %} {% if next %} diff --git a/debian/unfold.install b/debian/unfold.install index a86e983a..53291581 100644 --- a/debian/unfold.install +++ b/debian/unfold.install @@ -8,7 +8,5 @@ usr/share/unfold/unfold usr/share/unfold/ui usr/share/unfold/myslice usr/share/unfold/sample -usr/share/unfold/trash -usr/share/unfold/debug_platform manage.py usr/share/unfold/ apache/myslice.conf /etc/apache2/sites-available diff --git a/manifold/manifoldapi.py b/manifold/manifoldapi.py index 700a7654..6d168bb3 100644 --- a/manifold/manifoldapi.py +++ b/manifold/manifoldapi.py @@ -32,6 +32,12 @@ class ManifoldAPI: def __repr__ (self): return "ManifoldAPI[%s]"%self.url + def _print_value (self, value): + print "+++",'value', + if isinstance (value,list): print "[%d]"%len(value), + elif isinstance (value,dict): print "{%d}"%len(value), + print mytruncate (value,80) + # a one-liner to give a hint of what the return value looks like def _print_result (self, result): if not result: print "[no/empty result]" @@ -41,7 +47,8 @@ class ManifoldAPI: print "result is a dict with %d keys : %s"%(len(result),result.keys()) for (k,v) in result.iteritems(): if v is None: continue - print '+++',k,':',mytruncate (v,60) + if k=='value': self._print_value(v) + else: print '+++',k,':',mytruncate (v,30) else: print "[dont know how to display result] %s"%result # xxx temporary code for scaffolding a ManifolResult on top of an API that does not expose error info diff --git a/manifold/metadata.py b/manifold/metadata.py index 4fbbc066..90a09eab 100644 --- a/manifold/metadata.py +++ b/manifold/metadata.py @@ -27,24 +27,29 @@ class MetaData: except: print "metadata.work_offline: failed to decode %s"%offline_filename manifold_api = ManifoldAPI(self.auth) - fields = ['table', 'column.name', 'column.qualifier', 'column.type', 'column.is_array', 'column.description', 'column.default', 'key', 'capability'] + fields = ['table', 'column.name', 'column.qualifier', 'column.type', + 'column.is_array', 'column.description', 'column.default', 'key', 'capability'] #fields = ['table', 'column.column', # 'column.description','column.header', 'column.title', # 'column.unit', 'column.info_type', # 'column.resource_type', 'column.value_type', # 'column.allowed_values', 'column.platforms.platform', # 'column.platforms.platform_url'] - result = manifold_api.forward({ - 'action': 'get', - 'object': 'local:object', # proposed to replace metadata:table - 'fields': fields - }) + request={ 'action': 'get', + 'object': 'local:object', # proposed to replace metadata:table + 'fields': fields , + } + result = manifold_api.forward(request) + # xxx need a way to export error messages to the UI if result['code'] == 1: # warning - messages.warning(request, result['description']) + # messages.warning(request, result['description']) + print ("METADATA WARNING -",request,result['description']) elif result['code'] == 2: - messages.error(request, result['description']) + # messages.error(request, result['description']) + print ("METADATA ERROR -",request,result['description']) # XXX FAIL HERE XXX + return rows = result.ok_value() # API errors will be handled by the outer logic diff --git a/manifold/static/js/manifold.js b/manifold/static/js/manifold.js index 11fad7da..3f514345 100644 --- a/manifold/static/js/manifold.js +++ b/manifold/static/js/manifold.js @@ -323,9 +323,9 @@ var manifold = { * \brief We use js function closure to be able to pass the query (array) * to the callback function used when data is received */ - success_closure: function(query, publish_uuid, callback /*domid*/) { + success_closure: function(query, publish_uuid, callback) { return function(data, textStatus) { - manifold.asynchroneous_success(data, query, publish_uuid, callback /*domid*/); + manifold.asynchroneous_success(data, query, publish_uuid, callback); } }, @@ -341,23 +341,16 @@ var manifold = { // manifold.raise_record_event(sq.query_uuid, IN_PROGRESS); //}); - $.post(manifold.proxy_url, {'json': query_json} , manifold.success_closure(query, null, callback /*domid*/)); + $.post(manifold.proxy_url, {'json': query_json} , manifold.success_closure(query, null, callback)); }, - // Executes all async. queries - // input queries are specified as a list of {'query_uuid': , 'id': } - asynchroneous_exec : function (query_publish_dom_tuples) { - // start spinners - - // in case the spin stuff was not loaded, let's make sure we proceed to the exit - //try { - // if (manifold.asynchroneous_debug) - // messages.debug("Turning on spin with " + jQuery(".need-spin").length + " matches for .need-spin"); - // jQuery('.need-spin').spin(manifold.spin_presets); - //} catch (err) { messages.debug("Cannot turn on spins " + err); } + // Executes all async. queries - intended for the javascript header to initialize queries + // input queries are specified as a list of {'query_uuid': } + // each plugin is responsible for managing its spinner through on_query_in_progress + asynchroneous_exec : function (query_exec_tuples) { // Loop through input array, and use publish_uuid to publish back results - jQuery.each(query_publish_dom_tuples, function(index, tuple) { + $.each(query_exec_tuples, function(index, tuple) { var query=manifold.find_query(tuple.query_uuid); var query_json=JSON.stringify (query); var publish_uuid=tuple.publish_uuid; @@ -373,8 +366,8 @@ var manifold = { // not quite sure what happens if we send a string directly, as POST data is named.. // this gets reconstructed on the proxy side with ManifoldQuery.fill_from_POST - jQuery.post(manifold.proxy_url, {'json':query_json}, - manifold.success_closure(query, publish_uuid, tuple.callback /*domid*/)); + $.post(manifold.proxy_url, {'json':query_json}, + manifold.success_closure(query, publish_uuid, tuple.callback)); }) }, @@ -382,13 +375,11 @@ var manifold = { * \brief Forward a query to the manifold backend * \param query (dict) the query to be executed asynchronously * \param callback (function) the function to be called when the query terminates - * Deprecated: - * \param domid (string) the domid to be notified about the results (null for using the pub/sub system */ - forward: function(query, callback /*domid*/) { + forward: function(query, callback) { var query_json = JSON.stringify(query); $.post(manifold.proxy_url, {'json': query_json} , - manifold.success_closure(query, query.query_uuid, callback/*domid*/)); + manifold.success_closure(query, query.query_uuid, callback)); }, /*! @@ -431,7 +422,7 @@ var manifold = { /* Publish an update announce */ var channel="/results/" + query.query_uuid + "/changed"; if (manifold.publish_result_debug) messages.debug(".. publish_result OLD API (3) " + channel); - jQuery.publish(channel, [result, query]); + $.publish(channel, [result, query]); if (manifold.publish_result_debug) messages.debug(".. publish_result - END (4) q=" + query.__repr()); }, @@ -451,7 +442,7 @@ var manifold = { if (manifold.publish_result_debug) messages.debug (">>>>> publish_result_rec " + query.object); if (manifold.query_expects_unique_result(query)) { /* Also publish subqueries */ - jQuery.each(query.subqueries, function(object, subquery) { + $.each(query.subqueries, function(object, subquery) { manifold.publish_result_rec(subquery, result[0][object]); /* TODO remove object from result */ }); @@ -693,27 +684,17 @@ var manifold = { } }, - // if set domid allows the result to be directed to just one plugin + // if set callback is provided it is called // most of the time publish_uuid will be query.query_uuid // however in some cases we wish to publish the result under a different uuid // e.g. an updater wants to publish its result as if from the original (get) query - asynchroneous_success : function (data, query, publish_uuid, callback /*domid*/) { + asynchroneous_success : function (data, query, publish_uuid, callback) { // xxx should have a nicer declaration of that enum in sync with the python code somehow var start = new Date(); if (manifold.asynchroneous_debug) messages.debug(">>>>>>>>>> asynchroneous_success query.object=" + query.object); - /* If a callback has been specified, we redirect results to it */ - if (!!callback) { - callback(data); - if (manifold.asynchroneous_debug) { - duration=new Date()-start; - messages.debug ("<<<<<<<<<< asynchroneous_success " + query.object + " -- callback ended " + duration + " ms"); - } - return; - } - if (data.code == 2) { // ERROR // We need to make sense of error codes here alert("Your session has expired, please log in again"); @@ -730,16 +711,18 @@ var manifold = { if (publish_uuid) $.publish("/results/" + publish_uuid + "/failed", [data.code, data.description] ); -/* DEMO - Debug Messages desactivated - $("#notifications").notify("create", "sticky", { - title: 'Warning', - text: data.description - },{ - expires: false, - speed: 1000 - }); -*/ } + + // If a callback has been specified, we redirect results to it + if (!!callback) { + callback(data); + if (manifold.asynchroneous_debug) { + duration=new Date()-start; + messages.debug ("<<<<<<<<<< asynchroneous_success " + query.object + " -- callback ended " + duration + " ms"); + } + return; + } + if (manifold.asynchroneous_debug) messages.debug ("========== asynchroneous_success " + query.object + " -- before process_query_records"); @@ -767,7 +750,15 @@ var manifold = { raise_event_handler: function(type, query_uuid, event_type, value) { if ((type != 'query') && (type != 'record')) throw 'Incorrect type for manifold.raise_event()'; + // xxx we observe quite a lot of incoming calls with an undefined query_uuid + // this should be fixed upstream + if (query_uuid === undefined) { + messages.warning("undefined query in raise_event_handler"); + return; + } + // notify the change to objects that either listen to this channel specifically, + // or to the wildcard channel var channels = [ manifold.get_channel(type, query_uuid), manifold.get_channel(type, '*') ]; $.each(channels, function(i, channel) { diff --git a/myslice.spec b/myslice.spec index 291ce6d4..97b121b1 100644 --- a/myslice.spec +++ b/myslice.spec @@ -1,3 +1,9 @@ +# NOTE +# in real-life we use a debian packaging, so this fedora packaging is very rough +# it turns out we need to have one specfile for the PL build.. +# in any case the contents here should be more carefully split +# into several components pieces for generic and plugins and all that... + %define name myslice %define version 0.2 %define taglevel 4 diff --git a/myslice/urls.py b/myslice/urls.py index de14785f..32109579 100644 --- a/myslice/urls.py +++ b/myslice/urls.py @@ -59,7 +59,7 @@ urlpatterns = patterns( # Portal url(r'^sample/', include('sample.urls')), # Debug - url(r'^debug/', include('debug_platform.urls')), +# url(r'^debug/', include('debug_platform.urls')), # # various trash views - bound to go away # diff --git a/plugins/googlemap/static/js/googlemap.js b/plugins/googlemap/static/js/googlemap.js index 424b3aad..8501c741 100644 --- a/plugins/googlemap/static/js/googlemap.js +++ b/plugins/googlemap/static/js/googlemap.js @@ -35,7 +35,7 @@ googlemap_debug_detailed=false; /* XXX Events */ this.elmt().on('show', this, this.on_show); // TODO in destructor - // $(window).unbind('Hazelnut'); + // $(window).unbind('QueryTable'); var query = manifold.query_store.find_analyzed_query(this.options.query_uuid); this.object = query.object; @@ -104,8 +104,8 @@ googlemap_debug_detailed=false; // XXX BACKSLASHES original code was reading like this //return this.escape_id(key_value).replace(/\\/g, ''); // however this sequence removes backslashes from hrn's and as a result - // resources_selected was getting all mixed up - // hazelnut does publish hrn's with backslashes and that seems like the thing to do + // queryupdater was getting all mixed up + // querytable does publish hrn's with backslashes and that seems like the thing to do return key_value; }, @@ -146,7 +146,11 @@ googlemap_debug_detailed=false; // retrieve DOM checkbox and make sure it is checked/unchecked set_checkbox: function(record, checked) { var hrn=this.record_hrn (record); - if (! hrn) { messages.warning ("googlemap.set_checkbox: record has no hrn"); return; } + if (! hrn) { + try {messages.warning ("googlemap.set_checkbox: record has no hrn -- hostname="+record.hostname); } + catch (err) {messages.warning ("googlemap.set_checkbox: record has no hrn"); } + return; + } var checkbox_s = this.by_hrn [ hrn ]; if (! checkbox_s ) { messages.warning ("googlemap.set_checkbox: could not spot checkbox for hrn "+hrn); return; } checkbox_s.checkbox.prop('checked',checked); diff --git a/plugins/lists/simplelist.py b/plugins/lists/simplelist.py index 69e47aa5..26510303 100644 --- a/plugins/lists/simplelist.py +++ b/plugins/lists/simplelist.py @@ -3,10 +3,12 @@ from unfold.plugin import Plugin class SimpleList (Plugin) : # only deal with our own stuff here and let Plugin handle the rest - def __init__ (self, key, with_datatables=False, **settings): + def __init__ (self, key, with_datatables=False, classname=None, **settings): Plugin.__init__ (self, **settings) self.key=key self.with_datatables = with_datatables + # the DOM classname + self.classname = classname if classname is not None else "simplelist" # SimpleList is useless per se anyways def template_file (self): @@ -18,6 +20,7 @@ class SimpleList (Plugin) : header=getattr(self,'header',None) if header: env['header']=header env['with_datatables']= "yes" if self.with_datatables else "" + env['classname']=self.classname return env def requirements (self): @@ -34,5 +37,5 @@ class SimpleList (Plugin) : reqs['js_files'].append ("js/with-datatables.js") return reqs - def json_settings_list (self): return ['plugin_uuid','query_uuid','key'] + def json_settings_list (self): return ['plugin_uuid','query_uuid','key','classname'] diff --git a/plugins/lists/slicelist.py b/plugins/lists/slicelist.py index b9220db9..adfb9bf8 100644 --- a/plugins/lists/slicelist.py +++ b/plugins/lists/slicelist.py @@ -5,8 +5,13 @@ from plugins.lists.simplelist import SimpleList class SliceList (SimpleList): def __init__ (self, **settings): - SimpleList.__init__(self, key='slice_hrn', **settings) + SimpleList.__init__(self, key='slice.slice_hrn', classname='slicelist', **settings) # writing a js plugin for that would be overkill, just use SimpleList def plugin_classname (self): return 'SimpleList' + + def requirements (self): + req = SimpleList.requirements(self) + req['css_files'] += [ 'css/slicelist.css' ] + return req diff --git a/plugins/lists/static/css/simplelist.css b/plugins/lists/static/css/simplelist.css index bbf537e7..77f80ce4 100644 --- a/plugins/lists/static/css/simplelist.css +++ b/plugins/lists/static/css/simplelist.css @@ -15,14 +15,9 @@ thead.simplelist>tr>th { tbody.simplelist i { padding-right: 8px; } -/* make previous next buttons a bit nicer */ -div.paging_two_button>a { padding: 0px 4px 0px 4px; } -/* ---------- */ -/* xxx this probably should be separated in something related to datatables */ -select { - width: auto; -} -div.dataTables_filter input[type=text] { - width: 60; +.simplelist { + font-size: 100%; + text-align: center !important; + margin: 0 auto; } diff --git a/plugins/lists/static/css/slicelist.css b/plugins/lists/static/css/slicelist.css new file mode 100644 index 00000000..34a427c0 --- /dev/null +++ b/plugins/lists/static/css/slicelist.css @@ -0,0 +1,23 @@ +/* font size for regular (non datatable'd) slicelists */ +tbody.slicelist { + font-size: 150%; +} +/* datatable'd tables behave differently */ +table.with-datatables>tbody.slicelist { + font-size: 80%; +} +/* larger headers */ +thead.slicelist>tr>th { + font-size: 150%; + padding: 10px 10px 20px 10px; +} +/* some space after the arrow */ +tbody.slicelist i { + padding-right: 8px; +} + +.slicelist { + font-size: 100%; + text-align: center !important; + margin: 0 auto; +} diff --git a/plugins/lists/static/css/testbedlist.css b/plugins/lists/static/css/testbedlist.css new file mode 100644 index 00000000..fd312bab --- /dev/null +++ b/plugins/lists/static/css/testbedlist.css @@ -0,0 +1,23 @@ +/* font size for regular (non datatable'd) testbedlists */ +tbody.testbedlist { + font-size: 300%; +} +/* datatable'd tables behave differently */ +table.with-datatables>tbody.testbedlist { + font-size: 80%; +} +/* larger headers */ +thead.testbedlist>tr>th { + font-size: 150%; + padding: 10px 10px 20px 10px; +} +/* some space after the arrow */ +tbody.testbedlist i { + padding-right: 8px; +} + +.testbedlist { + font-size: 100%; + text-align: center !important; + margin: 0 auto; +} diff --git a/plugins/lists/static/js/simplelist.js b/plugins/lists/static/js/simplelist.js index 6a61ca53..a8f90b94 100644 --- a/plugins/lists/static/js/simplelist.js +++ b/plugins/lists/static/js/simplelist.js @@ -7,145 +7,132 @@ (function($){ var debug=false; - // debug=true + debug=true - $.fn.SimpleList = function( method ) { - /* Method calling logic */ - if ( methods[method] ) { - return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); - } else if ( typeof method === 'object' || ! method ) { - return methods.init.apply( this, arguments ); - } else { - $.error( 'Method ' + method + ' does not exist on jQuery.SimpleList' ); - } - }; + var SimpleList = Plugin.extend ({ - var methods = { - init : function( options ) { - return this.each(function(){ - var $this = $(this), data = $this.data('SimpleList'); - /* Subscribe to query updates */ - var channel='/results/' + options.query_uuid + '/changed'; - /* passing $this as 2nd arg: callbacks will retrieve $this as e.data */ - $.subscribe(channel, $this, update_plugin); - if (debug) window.messages.debug('subscribing to ' + channel); - $this.data('SimpleList', options); - }); - }, - destroy : function( ) { - if (debug) messages.debug("SimpleList.destroy..."); - return this.each(function(){ - var $this = $(this), data = $this.data('SimpleList'); - // xxx not too sure what this is about - $(window).unbind('SimpleList'); - $this.removeData('SimpleList'); - }); - }, - update : function( content ) { - if (debug) messages.debug("SimpleList.update..."); - }, - }; // methods + init: function (options, element) { + this._super (options, element); + this.buffered_records=[]; + this.listen_query(options.query_uuid); + }, + + on_query_in_progress: function() { + messages.debug("on_query_in_progress"); + this.spin(); + }, + + on_query_done: function() { + this._display_table(); + this.unspin(); + }, + + on_new_record: function(record) { + this.buffered_records.push(record); + }, /* Private methods */ - // complexity here is mostly because a datatables-enabled table cannot - // be updated in a "normal" way using .html() - function update_plugin(e, rows) { - // e.data is what we passed in second argument to subscribe - // so here it is the jquery object attached to the plugin
- var $plugindiv = e.data; - // locate the element; with datatables in the way, - // this might not be a direct son of the div-plugin - var $table = $plugindiv.find("table.simplelist").first(); - // also we may or may not have a header - var $tbody = $table.find("tbody.simplelist").first(); - var use_datatables = $table.hasClass("with-datatables"); - if (debug) - messages.debug($plugindiv.attr('id') + " udt= " + use_datatables); - - // clear the spinning wheel: look up an ancestor that has the need-spin class - // do this before we might return - $plugindiv.closest('.need-spin').spin(false); - if (rows.length == 0) { - if (use_datatables) - datatables_set_message ($table, $tbody, unfold.warning("No result")); - else - regular_set_message ($table, $tbody, unfold.warning("No result")); - return; - } + _display_table: function() { + var self=this; + var $plugindiv = this.elmt(); + var options = this.options; + var classname=options.classname; + // locate the
element; with datatables in the way, + // this might not be a direct son of the div-plugin + var $table = $plugindiv.find("table."+classname).first(); + // also we may or may not have a header + var $tbody = $table.find("tbody."+classname).first(); + var use_datatables = $table.hasClass("with-datatables"); + var rows=self.buffered_records; + self.buffered_records=[]; + if (debug) + messages.debug($plugindiv.attr('id') + " udt= " + use_datatables + " rows="+rows.length); + + if (rows.length == 0) { + if (use_datatables) + this._datatables_set_message ($table, $tbody, unfold.warning("No result")); + else + this._regular_set_message ($table, $tbody, unfold.warning("No result")); + return; + } - if (typeof rows[0].error != 'undefined') { - var error="ERROR: " + rows[0].error; - if (use_datatables) - datatables_set_message ($table, $tbody, unfold.error(error)); - else - regular_set_message ($table, $tbody, unfold.error(error)); - return; - } + if (typeof rows[0].error != 'undefined') { + var error="ERROR: " + rows[0].error; + if (use_datatables) + this._datatables_set_message ($table, $tbody, unfold.error(error)); + else + this._regular_set_message ($table, $tbody, unfold.error(error)); + return; + } - var options = $plugindiv.data().SimpleList; if (use_datatables) - datatables_update_table($table, $tbody, rows, options.key); + this._datatables_update_table($table, $tbody, rows, options.key); else - regular_update_table($table, $tbody, rows, options.key); - - } - - // hard-wire a separate presentation depending on the key being used.... - function cell(key, value) { - if (key == 'slice.slice_hrn') { - return "" + value + ""; - } else if (key == 'platform') { - return "" + value + ""; - } else { - return value; - } - } + this._regular_update_table($table, $tbody, rows, options.key, classname); + }, - function regular_set_message ($table, $tbody, message) { - $tbody.html(""); - } + _regular_set_message: function ($table, $tbody, message) { + $tbody.html(""); + }, - function regular_update_table ($table, $tbody, rows, key) { - if (debug) - messages.debug('regular_update_table ' + rows.length + " rows"); + _regular_update_table: function ($table, $tbody, rows, key, classname) { + if (debug) + messages.debug('regular_update_table ' + rows.length + " rows" + " key=" + key + " classname=" + classname); + var self=this; var html=$.map(rows, function (row) { - value = row; - $.each(key.split('.'), function(i, k) { - if ($.isArray(value)) { - value = $.map(value, function(val, i) { return val[k]}); - } else { - value = value[k]; - } - }); - if ($.isArray(value)) { - x = $.map(value, function(val, i) { return html_row ( cell (key, val)); }); - return x; - } else { - return html_row ( cell (key, value)); - } - }).join(); - $tbody.html(html); - } + var value = row; + $.each(key.split('.'), function(i, k) { + if ($.isArray(value)) { + value = $.map(value, function(val, i) { return val[k]}); + } else { + value = value[k]; + } + }); + if ($.isArray(value)) { + return $.map(value, function(val, i) { + return self._html_row ( self._cell (key, val), classname); + }); + } else { + return self._html_row ( self._cell (key, value), classname); + } + }).join(); + $tbody.html(html); + }, - function datatables_set_message ($table, $tbody, message) { - $table.dataTable().fnClearTable(); - $table.dataTable().fnAddData( [ message ] ); - $table.dataTable().fnDraw(); - } + _datatables_set_message: function ($table, $tbody, message) { + $table.dataTable().fnClearTable(); + $table.dataTable().fnAddData( [ message ] ); + $table.dataTable().fnDraw(); + }, - function datatables_update_table ($table, $tbody, rows, key) { - if (debug) messages.debug('datatables_update_table ' + rows.length + " rows"); - $table.dataTable().fnClearTable(); - // the lambda here returns a [[]] because $.map is kind of broken; as per the doc: - // The function can return any value to add to the array. A returned array will be flattened into the resulting array. - // this is wrong indeed so let's work around that - $table.dataTable().fnAddData( $.map(rows, function (row) { return [[ cell (key,row[key]) ]] }) ); - $table.dataTable().fnDraw(); - } + _datatables_update_table: function ($table, $tbody, rows, key) { + if (debug) messages.debug('datatables_update_table ' + rows.length + " rows"); + $table.dataTable().fnClearTable(); + // the lambda here returns a [[]] because $.map is kind of broken; as per the doc: + // The function can return any value to add to the array. A returned array will be flattened into the resulting array. + // this is wrong indeed so let's work around that + var self=this; + $table.dataTable().fnAddData( $.map(rows, function (row) { return [[ self._cell (key,row[key]) ]] }) ); + $table.dataTable().fnDraw(); + }, - function html_row (cell) { - return ""; - } + _html_row: function (cell, classname) { + return ""; + }, + // hard-wire a separate presentation depending on the key being used.... + _cell: function (key, value) { + if (key == 'slice.slice_hrn') { + return "" + value + ""; + } else if (key == 'platform') { + return "" + value + ""; + } else { + return value; + } + }, + }); + + $.plugin('SimpleList', SimpleList); + })( jQuery ); diff --git a/plugins/lists/staticlist.py b/plugins/lists/staticlist.py index c5a254ac..f53a2acb 100644 --- a/plugins/lists/staticlist.py +++ b/plugins/lists/staticlist.py @@ -2,6 +2,12 @@ from unfold.plugin import Plugin class StaticList (Plugin) : + """ StaticList allows you to display an html list + that you provide the contents for in the 'list' input argument + It is static in the sense that no query is going to be used to + manage this contents + """ + # only deal with our own stuff here and let Plugin handle the rest def __init__ (self, list=[], with_datatables=False, **settings): Plugin.__init__ (self, **settings) diff --git a/plugins/lists/templates/simplelist.html b/plugins/lists/templates/simplelist.html index e34d087e..c3e2954d 100644 --- a/plugins/lists/templates/simplelist.html +++ b/plugins/lists/templates/simplelist.html @@ -1,4 +1,4 @@ -
"+message+"
"+message+"
"+cell+"
"+cell+"
-{% if header %} {% endif %} - +
{{ header }}
+{% if header %} {% endif %} +
{{ header }}
diff --git a/plugins/lists/testbedlist.py b/plugins/lists/testbedlist.py new file mode 100644 index 00000000..6496d909 --- /dev/null +++ b/plugins/lists/testbedlist.py @@ -0,0 +1,15 @@ +from plugins.lists.simplelist import SimpleList + +class TestbedList (SimpleList): + + def __init__ (self, **settings): + SimpleList.__init__(self, key='platform', classname='testbedlist', **settings) + + # writing a js plugin for that would be overkill, just use SimpleList + def plugin_classname (self): + return 'SimpleList' + + def requirements (self): + req = SimpleList.requirements(self) + req['css_files'] += [ 'css/testbedlist.css' ] + return req diff --git a/plugins/messages/__init__.py b/plugins/messages/__init__.py index 7ee0c3ce..f765d50d 100644 --- a/plugins/messages/__init__.py +++ b/plugins/messages/__init__.py @@ -41,6 +41,3 @@ class Messages (Plugin): def json_settings_list (self): return [ 'plugin_uuid', 'levels' ] - # and we don't need a spin wheel - def start_with_spin (self): - return False diff --git a/plugins/myplugin/static/js/myplugin.js b/plugins/myplugin/static/js/myplugin.js index 20f85734..26a29922 100644 --- a/plugins/myplugin/static/js/myplugin.js +++ b/plugins/myplugin/static/js/myplugin.js @@ -44,7 +44,7 @@ }, /* PLUGIN EVENTS */ - // on_show like in hazelnut + // on_show like in querytable /* GUI EVENTS */ diff --git a/plugins/querycode/__init__.py b/plugins/querycode/__init__.py index 55da3e9c..d46a8421 100644 --- a/plugins/querycode/__init__.py +++ b/plugins/querycode/__init__.py @@ -25,6 +25,3 @@ class QueryCode (Plugin): } def json_settings_list (self): return ['plugin_uuid','query_uuid'] - - # because we have a link to a query it looks like we need a spin, let's make this right - def start_with_spin (self): return False diff --git a/plugins/hazelnut/__init__.py b/plugins/querytable/__init__.py similarity index 89% rename from plugins/hazelnut/__init__.py rename to plugins/querytable/__init__.py index eab50049..96456f56 100644 --- a/plugins/hazelnut/__init__.py +++ b/plugins/querytable/__init__.py @@ -1,6 +1,6 @@ from unfold.plugin import Plugin -class Hazelnut (Plugin): +class QueryTable (Plugin): # set checkboxes if a final column with checkboxes is desired # pass columns as the initial set of columns @@ -37,16 +37,16 @@ class Hazelnut (Plugin): if self.checkboxes: # we use aoColumnDefs rather than aoColumns -- ignore user-provided aoColumns if 'aoColumns' in self.datatables_options: - print 'WARNING: hazelnut uses aoColumnDefs, your aoColumns spec. is discarded' + print 'WARNING: querytable uses aoColumnDefs, your aoColumns spec. is discarded' del self.datatables_options['aoColumns'] # set aoColumnDefs in datatables_options - might already have stuff in there aoColumnDefs = self.datatables_options.setdefault ('aoColumnDefs',[]) # here 'checkbox' is the class that we give to the dom elem - # dom-checkbox is a sorting type that we define in hazelnut.js + # dom-checkbox is a sorting type that we define in querytable.js aoColumnDefs.append ( {'aTargets': ['checkbox'], 'sSortDataType': 'dom-checkbox' } ) def template_file (self): - return "hazelnut.html" + return "querytable.html" def template_env (self, request): env={} @@ -60,15 +60,15 @@ class Hazelnut (Plugin): "js/dataTables.js", "js/dataTables.bootstrap.js", "js/with-datatables.js", "js/manifold.js", "js/manifold-query.js", "js/unfold-helper.js", - # hazelnut.js needs to be loaded after dataTables.js as it extends + # querytable.js needs to be loaded after dataTables.js as it extends # dataTableExt.afnSortData - "js/hazelnut.js", + "js/querytable.js", ] , 'css_files': [ "css/dataTables.bootstrap.css", # hopefully temporary, when/if datatables supports sPaginationType=bootstrap3 # for now we use full_numbers, with our own ad hoc css "css/dataTables.full_numbers.css", - "css/hazelnut.css" , + "css/querytable.css" , ], } return reqs diff --git a/plugins/hazelnut/static/css/hazelnut.css b/plugins/querytable/static/css/querytable.css similarity index 60% rename from plugins/hazelnut/static/css/hazelnut.css rename to plugins/querytable/static/css/querytable.css index 31c11846..edbc683e 100644 --- a/plugins/hazelnut/static/css/hazelnut.css +++ b/plugins/querytable/static/css/querytable.css @@ -1,7 +1,7 @@ /* the bottom of the datatable needs more space */ -div.hazelnut-spacer { padding: 8px 4px 15px 4px; } +div.querytable-spacer { padding: 8px 4px 15px 4px; } -div.Hazelnut table.dataTable th { +div.QueryTable table.dataTable th { font: bold 12px/22px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; color: #4f6b72; border-right: 1px solid #C1DAD7; @@ -15,25 +15,25 @@ div.Hazelnut table.dataTable th { /* background: #CAE8EA url(../img/tablesort-header.jpg) no-repeat; */ } -div.Hazelnut table.dataTable th.checkbox { +div.QueryTable table.dataTable th.checkbox { padding-left: 14px; } -div.Hazelnut table.dataTable td, div.Hazelnut table.dataTable textarea, div.Hazelnut table.dataTable input [type="text"] { +div.QueryTable table.dataTable td, div.QueryTable table.dataTable textarea, div.QueryTable table.dataTable input [type="text"] { font: normal 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; border-right: 1px solid #C1DAD7; border-bottom: 1px solid #C1DAD7; } -div.Hazelnut table.dataTable td { +div.QueryTable table.dataTable td { padding: 4px 8px 4px 8px; /* this applies on even rows only, odd ones have a setting in bootstrap of rbg 249.249.249 */ background-color: #f4f4f4; } -div.Hazelnut table.dataTable td a { +div.QueryTable table.dataTable td a { font-weight:normal; } /* these come from bootstrap */ -div.Hazelnut div.dataTables_info { +div.QueryTable div.dataTables_info { font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; } @@ -43,20 +43,20 @@ div.Hazelnut div.dataTables_info { * which would look less conspicuous in case of overflow */ -div.Hazelnut table.dataTable thead .sorting { background: url('../img/tablesort-header-sortable.png') no-repeat; } -div.Hazelnut table.dataTable thead .sorting_asc { background: url('../img/tablesort-header-up.png') no-repeat; } -div.Hazelnut table.dataTable thead .sorting_desc { background: url('../img/tablesort-header-down.png') no-repeat; } +div.QueryTable table.dataTable thead .sorting { background: url('../img/tablesort-header-sortable.png') no-repeat; } +div.QueryTable table.dataTable thead .sorting_asc { background: url('../img/tablesort-header-up.png') no-repeat; } +div.QueryTable table.dataTable thead .sorting_desc { background: url('../img/tablesort-header-down.png') no-repeat; } /* this icons set does not have that exact equivalent - using an approximation for now */ -div.Hazelnut table.dataTable thead .sorting_asc_disabled { background: url('../img/tablesort-header.png') repeat-x; } -div.Hazelnut table.dataTable thead .sorting_desc_disabled { background: url('../img/tablesort-header.png') repeat-x; } +div.QueryTable table.dataTable thead .sorting_asc_disabled { background: url('../img/tablesort-header.png') repeat-x; } +div.QueryTable table.dataTable thead .sorting_desc_disabled { background: url('../img/tablesort-header.png') repeat-x; } /* the footers are not active */ -div.Hazelnut table.dataTable tfoot { +div.QueryTable table.dataTable tfoot { background: url('../img/tablesort-header.png') repeat-x; background-color: #caebea; } /* and when sorting is turned off it's useful to set this on header too */ -div.Hazelnut table.dataTable thead { +div.QueryTable table.dataTable thead { background: url('../img/tablesort-header.png') repeat-x; background-color: #caebea; } diff --git a/plugins/hazelnut/static/img/README b/plugins/querytable/static/img/README similarity index 100% rename from plugins/hazelnut/static/img/README rename to plugins/querytable/static/img/README diff --git a/plugins/hazelnut/static/img/tablesort-bullet1.png b/plugins/querytable/static/img/tablesort-bullet1.png similarity index 100% rename from plugins/hazelnut/static/img/tablesort-bullet1.png rename to plugins/querytable/static/img/tablesort-bullet1.png diff --git a/plugins/hazelnut/static/img/tablesort-bullet2.png b/plugins/querytable/static/img/tablesort-bullet2.png similarity index 100% rename from plugins/hazelnut/static/img/tablesort-bullet2.png rename to plugins/querytable/static/img/tablesort-bullet2.png diff --git a/plugins/hazelnut/static/img/tablesort-col-alt.png b/plugins/querytable/static/img/tablesort-col-alt.png similarity index 100% rename from plugins/hazelnut/static/img/tablesort-col-alt.png rename to plugins/querytable/static/img/tablesort-col-alt.png diff --git a/plugins/hazelnut/static/img/tablesort-gradient.png b/plugins/querytable/static/img/tablesort-gradient.png similarity index 100% rename from plugins/hazelnut/static/img/tablesort-gradient.png rename to plugins/querytable/static/img/tablesort-gradient.png diff --git a/plugins/hazelnut/static/img/tablesort-header-down.png b/plugins/querytable/static/img/tablesort-header-down.png similarity index 100% rename from plugins/hazelnut/static/img/tablesort-header-down.png rename to plugins/querytable/static/img/tablesort-header-down.png diff --git a/plugins/hazelnut/static/img/tablesort-header-sortable.png b/plugins/querytable/static/img/tablesort-header-sortable.png similarity index 100% rename from plugins/hazelnut/static/img/tablesort-header-sortable.png rename to plugins/querytable/static/img/tablesort-header-sortable.png diff --git a/plugins/hazelnut/static/img/tablesort-header-up.png b/plugins/querytable/static/img/tablesort-header-up.png similarity index 100% rename from plugins/hazelnut/static/img/tablesort-header-up.png rename to plugins/querytable/static/img/tablesort-header-up.png diff --git a/plugins/hazelnut/static/img/tablesort-header.png b/plugins/querytable/static/img/tablesort-header.png similarity index 100% rename from plugins/hazelnut/static/img/tablesort-header.png rename to plugins/querytable/static/img/tablesort-header.png diff --git a/plugins/hazelnut/static/img/tablesort-td-alt.png b/plugins/querytable/static/img/tablesort-td-alt.png similarity index 100% rename from plugins/hazelnut/static/img/tablesort-td-alt.png rename to plugins/querytable/static/img/tablesort-td-alt.png diff --git a/plugins/hazelnut/static/img/toggle-hidden.png b/plugins/querytable/static/img/toggle-hidden.png similarity index 100% rename from plugins/hazelnut/static/img/toggle-hidden.png rename to plugins/querytable/static/img/toggle-hidden.png diff --git a/plugins/hazelnut/static/img/toggle-visible.png b/plugins/querytable/static/img/toggle-visible.png similarity index 100% rename from plugins/hazelnut/static/img/toggle-visible.png rename to plugins/querytable/static/img/toggle-visible.png diff --git a/plugins/hazelnut/static/js/hazelnut.js b/plugins/querytable/static/js/querytable.js similarity index 92% rename from plugins/hazelnut/static/js/hazelnut.js rename to plugins/querytable/static/js/querytable.js index 7c042b18..6a553bc9 100644 --- a/plugins/hazelnut/static/js/hazelnut.js +++ b/plugins/querytable/static/js/querytable.js @@ -9,7 +9,7 @@ var debug=false; // debug=true - var Hazelnut = Plugin.extend({ + var QueryTable = Plugin.extend({ init: function(options, element) { @@ -36,7 +36,7 @@ this.elmt().on('show', this, this.on_show); // Unbind all events using namespacing // TODO in destructor - // $(window).unbind('Hazelnut'); + // $(window).unbind('QueryTable'); var query = manifold.query_store.find_analyzed_query(this.options.query_uuid); this.method = query.object; @@ -64,9 +64,9 @@ /* temp disabled... useful ? -- jordan $(this).each(function(i,elt) { if (jQuery(elt).hasClass('dataTables')) { - var myDiv=jQuery('#hazelnut-' + this.id).parent(); + var myDiv=jQuery('#querytable-' + this.id).parent(); if(myDiv.height()==0) { - var oTable=$('#hazelnut-' + this.id).dataTable(); + var oTable=$('#querytable-' + this.id).dataTable(); oTable.fnDraw(); } } @@ -96,7 +96,7 @@ // WARNING: this one causes tables in a 'tabs' that are not exposed at the time this is run to show up empty // sScrollX: '100%', /* Horizontal scrolling */ bProcessing: true, /* Loading */ - fnDrawCallback: function() { self._hazelnut_draw_callback.call(self); } + fnDrawCallback: function() { self._querytable_draw_callback.call(self); } // XXX use $.proxy here ! }; // the intention here is that options.datatables_options as coming from the python object take precedence @@ -131,7 +131,7 @@ /* No filtering if the table does not match */ if (oSettings.nTable.id != self.options.plugin_uuid + '__table') return true; - return self._hazelnut_filter.call(self, oSettings, aData, iDataIndex); + return self._querytable_filter.call(self, oSettings, aData, iDataIndex); }); /* Processing hidden_columns */ @@ -156,7 +156,7 @@ var result=""; // Prefix id with plugin_uuid result += " +
diff --git a/plugins/queryupdater/__init__.py b/plugins/queryupdater/__init__.py new file mode 100644 index 00000000..d74caa32 --- /dev/null +++ b/plugins/queryupdater/__init__.py @@ -0,0 +1,17 @@ +from unfold.plugin import Plugin + +class QueryUpdater(Plugin): + + def template_file (self): + return "queryupdater.html" + + def requirements (self): + reqs = { + 'js_files' : [ "js/queryupdater.js" ] , + 'css_files': [ "css/queryupdater.css" ], + } + return reqs + + def json_settings_list (self): + return ['plugin_uuid', 'domid', 'query_uuid'] + diff --git a/plugins/resources_selected/static/css/resources_selected.css b/plugins/queryupdater/static/css/queryupdater.css similarity index 94% rename from plugins/resources_selected/static/css/resources_selected.css rename to plugins/queryupdater/static/css/queryupdater.css index dfefb466..05c7a35e 100644 --- a/plugins/resources_selected/static/css/resources_selected.css +++ b/plugins/queryupdater/static/css/queryupdater.css @@ -1,5 +1,5 @@ /* - Document : ResourcesSelected + Document : QueryUpdater Created on : 9 aout 2012, 11:54:41 Author : loicbaron Description: diff --git a/plugins/resources_selected/static/js/resources_selected.js b/plugins/queryupdater/static/js/queryupdater.js similarity index 98% rename from plugins/resources_selected/static/js/resources_selected.js rename to plugins/queryupdater/static/js/queryupdater.js index 9a064476..7d7de24f 100644 --- a/plugins/resources_selected/static/js/resources_selected.js +++ b/plugins/queryupdater/static/js/queryupdater.js @@ -1,5 +1,5 @@ /** - * MySlice ResourcesSelected plugin + * MySlice QueryUpdater plugin * Version: 0.1.0 * URL: http://www.myslice.info * Description: display of selected resources @@ -23,7 +23,7 @@ // Record state through the query cycle - var ResourcesSelected = Plugin.extend({ + var QueryUpdater = Plugin.extend({ init: function(options, element) { @@ -31,7 +31,7 @@ var self = this; this.table = this.elmt('table').dataTable({ -// the original hazelnut layout was +// the original querytable layout was // sDom: "<'row'<'col-xs-5'l><'col-xs-1'r><'col-xs-6'f>>t<'row'<'col-xs-5'i><'col-xs-7'p>>", // however the bottom line with 'showing blabla...' and the navigation widget are not really helpful sDom: "<'row'<'col-xs-5'l><'col-xs-1'r><'col-xs-6'f>>t>", @@ -80,12 +80,12 @@ do_reset: function(e) { - throw 'resources_selected.do_reset Not implemented'; + throw 'queryupdater.do_reset Not implemented'; }, do_clear_annotations: function(e) { - throw 'resources_selected.do_clear_annotations Not implemented'; + throw 'queryupdater.do_clear_annotations Not implemented'; }, /************************** GUI MANIPULATION **************************/ @@ -178,7 +178,7 @@ button ]; if (!row) { - // XXX second parameter refresh = false can improve performance. todo in hazelnut also + // XXX second parameter refresh = false can improve performance. todo in querytable also this.table.fnAddData(newline); row = this.find_row(data.value); } else { @@ -447,6 +447,6 @@ }); - $.plugin('ResourcesSelected', ResourcesSelected); + $.plugin('QueryUpdater', QueryUpdater); })(jQuery); diff --git a/plugins/resources_selected/templates/resources_selected.html b/plugins/queryupdater/templates/queryupdater.html similarity index 100% rename from plugins/resources_selected/templates/resources_selected.html rename to plugins/queryupdater/templates/queryupdater.html diff --git a/plugins/resources_selected/__init__.py b/plugins/resources_selected/__init__.py deleted file mode 100644 index a5bbac70..00000000 --- a/plugins/resources_selected/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -from unfold.plugin import Plugin - -class ResourcesSelected(Plugin): - - def template_file (self): - return "resources_selected.html" - - def requirements (self): - reqs = { - 'js_files' : [ "js/resources_selected.js" ] , - 'css_files': [ "css/resources_selected.css" ], - } - return reqs - - def json_settings_list (self): - return ['plugin_uuid', 'domid', 'query_uuid'] - - def export_json_settings (self): - return True diff --git a/plugins/senslabmap/__init__.py b/plugins/senslabmap/__init__.py index 7540edb0..92895d05 100644 --- a/plugins/senslabmap/__init__.py +++ b/plugins/senslabmap/__init__.py @@ -22,9 +22,9 @@ class SensLabMap (Plugin): reqs = { 'js_files' : [ "js/senslabmap.js", "js/spin.presets.js", "js/spin.min.js", "js/jquery.spin.js", - "js/three.js", "js/grenoble.js", "js/viewer3D.js", - ] , - 'css_files': [ "css/senslabmap.css" , + "js/three.min.js", "js/jquery-mousewheel.min.js", "js/map.js", + ], + 'css_files': [ "css/map.css", ], } return reqs diff --git a/plugins/senslabmap/static/css/map.css b/plugins/senslabmap/static/css/map.css new file mode 100644 index 00000000..ac4b7e0e --- /dev/null +++ b/plugins/senslabmap/static/css/map.css @@ -0,0 +1,5 @@ +canvas { + border:1px gray solid; + background-color: #202020; + margin: 10px; +} \ No newline at end of file diff --git a/plugins/senslabmap/static/js/grenoble.js b/plugins/senslabmap/static/js/grenoble.js deleted file mode 100644 index bcf49867..00000000 --- a/plugins/senslabmap/static/js/grenoble.js +++ /dev/null @@ -1,259 +0,0 @@ -var nodes_gre = [ -[1,2.67,.30,1.98,"b2ce"], -[2,2.99,0,2.70,"bdc0"], -[3,4.09,0,2.22,"cdf2"], -[4,4.78,0,2.80,"c6c0"], -[5,5.82,0,2.42,"b27c"], -[6,6.57,0,2.85,"bfc6"], -[7,7.55,0,2.28,"b39e"], -[8,8.82,0,2.37,"b07f"], -[9,9.78,0,2.80,"c7e6"], -[10,10.95,0,2.30,"beed"], -[11,12.17,0,2.65,"bb40"], -[12,1.45,.70,2.54,"c1fe"], -[13,2.25,.70,2.54,"b807"], -[14,3.22,.70,2.54,"b2ca"], -[15,4.16,.70,2.54,"b020"], -[16,5.18,.70,2.54,"b6d8"], -[17,6.28,.70,2.54,"c631"], -[18,7.35,.70,2.54,"cc8b"], -[19,8.55,.70,2.54,"b03d"], -[20,9.70,.70,2.54,"c24c"], -[21,10.60,.70,2.54,"cc0d"], -[22,11.60,.70,2.54,"b047"], -[23,12.60,.70,2.54,"bc97"], -[24,13.35,.70,2.54,"c13d"], -[25,14.15,.70,2.54,"bed2"], -[26,.40,1.98,3.60,"b1cb"], -[27,1.55,1.98,3.60,"b94f"], -[28,2.50,1.98,3.60,"c33e"], -[29,3.60,1.98,3.60,"1cbe"], -[30,4.80,1.98,3.60,"ccc8"], -[31,5.87,1.98,3.60,"b1a5"], -[32,6.72,1.98,3.60,"b63b"], -[33,7.22,1.98,3.60,"c78e"], -[34,8.59,1.98,3.60,"b902"], -[35,9.50,1.98,3.60,"c443"], -[36,10.54,1.98,3.60,"b615"], -[37,11.31,1.98,3.60,"cf33"], -[38,12.53,1.98,3.60,"b8bd"], -[39,13.55,1.98,3.60,"b32d"], -[40,2.37,1.73,2.53,"c21d"], -[41,3.93,1.68,2.53,"c216"], -[42,5.95,1.85,2.53,"ca2d"], -[43,7.95,1.65,2.53,"c7ee"], -[44,10.15,1.90,2.53,"bb04"], -[45,12.20,1.64,2.53,"c878"], -[46,14.00,1.56,2.53,"b85a"], -[47,1.40,2.76,2.52,"b2f9"], -[48,2.75,2.84,2.52,"bd6f"], -[49,3.72,2.84,2.52,"c2f6"], -[50,4.70,2.80,2.52,"c18d"], -[51,5.93,2.80,2.52,"c474"], -[52,7.00,2.80,2.52,"c4bb"], -[53,8.00,2.80,2.52,"b384"], -[54,8.87,2.80,2.52,"b0a8"], -[55,9.74,2.80,2.52,"bfc4"], -[56,10.68,2.80,2.52,"c597"], -[57,11.70,2.80,2.52,"c90d"], -[58,12.70,2.80,2.52,"ca91"], -[59,13.95,2.80,2.52,"b35b"], -[60,14.95,2.35,2.50,"bba0"], -[61,2.40,3.00,3.60,"b328"], -[62,3.50,3.10,3.60,"b7a5"], -[63,4.60,3.10,3.60,"c7b0"], -[64,5.62,3.10,3.60,"c873"], -[65,7.10,3.10,3.60,"c04d"], -[66,8.00,3.10,3.60,"c5b5"], -[67,8.95,3.05,3.60,"c115"], -[68,9.77,2.90,3.60,"be03"], -[69,10.77,3.05,3.60,"bfa6"], -[70,11.70,3.05,3.60,"be64"], -[71,12.73,3.05,3.60,"c596"], -[72,13.63,3.05,3.60,"c01c"], -[73,6.25,3.55,3.53,"c8dd"], -[74,2.42,4.60,3.66,"b18b"], -[75,3.39,4.60,3.66,"bfc5"], -[76,4.42,4.60,3.66,"b0e9"], -[77,5.43,4.60,3.66,"1fa0"], -[78,6.58,4.60,3.66,"b2ba"], -[79,7.50,4.60,3.66,"b1ae"], -[80,8.52,4.62,3.66,"b89a"], -[81,9.47,4.55,3.66,"b41e"], -[82,10.49,4.66,3.66,"????"], -[83,11.49,4.66,3.66,"b666"], -[84,12.68,4.68,3.66,"bde3"], -[85,13.83,4.68,3.66,"b029"], -[86,1.59,4.65,2.58,"????"], -[87, 2.69, 4.65, 2.58, "????"], -[88,3.86,4.66,2.58,"b65d"], -[89,4.82,4.66,2.58,"c8e0"], -[90,5.87,4.66,2.58,"c1d7"], -[91,6.84,4.66,2.58,"c494"], -[92,7.79,4.67,2.58,"b193"], -[93,8.72,4.67,2.58,"c828"], -[94,9.72,4.65,2.58,"cd06"], -[95,10.82,4.65,2.58,"afed"], -[96,11.78,4.60,2.58,"baea"], -[97,12.85,4.60,2.58,"c19c"], -[98,13.83,4.58,2.58,"be7f"], -[99,.72,0,2.65,"becb"], -[100,15.48,6.20,2.62,"ba2d"], -[101,2.22,3.48,2.60,"baa9"], -[102,14.00,3.60,2.60,"bad5"], -[103,2.50,4.63,.37,"beb6"], -[104,3.24,4.63,.37,"b4de"], -[105,4.14,4.63,.37,"c79d"], -[106,4.88,4.63,.37,"c16a"], -[107,2.40,4.35,1.07,"b323"], -[108,3.21,4.35,1.07,"b396"], -[109,4.08,4.35,1.07,"b4c1"], -[110,4.90,4.35,1.07,"bea9"], -[111,2.54,4.77,2.00,"ba73"], -[112,3.32,4.77,2.00,"b092"], -[113,4.20,4.77,2.00,"b2bc"], -[114,4.92,4.82,2.00,"ba62"], -[115,2.30,5.48,.20,"b34b"], -[116,3.40,5.52,.20,"b974"], -[117,4.20,5.52,.20,"b230"], -[118,4.95,5.40,.43,"c319"], -[119,2.52,5.29,1.04,"cbe5"], -[120,3.28,5.29,1.04,"c639"], -[121,4.89,5.32,1.04,"bfca"], -[122,2.49,5.71,1.82,"c5fb"], -[123,3.48,5.71,1.80,"c552"], -[124,4.37,5.71,1.83,"b413"], -[125,.54,10.27,2.60,"????"], -[126,.76,8.23,2.63,"c3b4"], -[127,7.23,.40,3.00,"c38d"], -[128,9.33,.35,3.02,"b5d0"], -[129,.40,6.27,2.60,"c9cd"], -[130,1.13,6.20,2.57,"b491"], -[131,2.15,6.20,2.57,"beab"], -[132,3.23,6.20,2.57,"b053"], -[133,4.14,6.20,2.58,"c349"], -[134,5.12,6.20,2.59,"be0f"], -[135,6.10,6.20,2.59,"b8a3"], -[136,7.12,6.20,2.60,"c4d1"], -[137,8.12,6.20,2.60,"c686"], -[138,9.11,6.20,2.61,"bfba"], -[139,10.13,6.20,2.61,"baa2"], -[140,11.13,6.20,2.62,"c529"], -[141,12.16,6.20,2.62,"b7c6"], -[142,13.17,6.20,2.62,"ccdc"], -[143,14.15,6.20,2.62,"b74f"], -[144,6.37,6.64,3.60,"bb93"], -[145,9.65,6.62,3.58,"204e"], -[146,.98,7.70,3.67,"b797"], -[147,1.78,7.70,3.67,"b71f"], -[148,2.82,7.70,3.67,"c98d"], -[149,3.77,7.70,3.67,"bfea"], -[150,4.82,7.70,3.67,"bfcd"], -[151,5.87,7.70,3.67,"afb3"], -[152,6.85,7.70,3.67,"c067"], -[153,8.17,7.70,3.67,"bd0c"], -[154,9.18,7.70,3.67,"cc6e"], -[155,10.08,7.70,3.67,"1f58"], -[156,11.08,7.70,3.67,"c4de"], -[157,12.18,7.70,3.67,"c84d"], -[158,13.18,7.70,3.67,"bee7"], -[159,14.20,7.70,3.67,"b5aa"], -[160,.33,7.72,2.60,"cea4"], -[161,1.17,7.70,2.58,"c1d2"], -[162,2.07,7.70,2.58,"b961"], -[163,2.99,7.70,2.58,"b013"], -[164,3.96,7.70,2.58,"????"], -[165,4.97,7.70,2.58,"c4cf"], -[166,5.95,7.70,2.58,"bfa1"], -[167,6.96,7.70,2.58,"bb56"], -[168,7.98,7.70,2.58,"ba8c"], -[169,9.08,7.70,2.58,"b8e1"], -[170,10.18,7.70,2.58,"b978"], -[171,11.22,7.70,2.58,"cac7"], -[172,.94,9.00,3.67,"b6c1"], -[173,1.79,9.00,3.67,"b9c2"], -[174,2.86,9.00,3.67,"af8d"], -[175,3.81,9.00,3.67,"b105"], -[176,4.97,9.00,3.67,"baa8"], -[177,5.88,9.00,3.67,"b650"], -[178,6.95,9.00,3.67,"b097"], -[179,7.98,9.00,3.67,"c1fd"], -[180,8.93,9.00,3.67,"c0ce"], -[181,10.08,9.00,3.67,"bf9c"], -[182,10.97,9.00,3.67,"c938"], -[183,11.97,9.00,3.67,"b2d8"], -[184,13.03,9.00,3.67,"b01d"], -[185,14.07,9.00,3.67,"c432"], -[186,.35,9.00,2.56,"2030"], -[187,1.33,9.00,2.55,"b31e"], -[188,2.33,9.00,2.55,"cb9b"], -[189,3.33,9.00,2.55,"ba2e"], -[190,4.33,9.00,2.55,"b1b2"], -[191,5.33,9.00,2.55,"b916"], -[192,6.34,8.97,2.55,"c15f"], -[193,7.34,9.00,2.55,"1f69"], -[194,8.44,8.97,2.55,"b8df"], -[195,9.49,9.00,2.55,"cde9"], -[196,10.48,9.00,2.55,"b355"], -[197,11.60,9.00,2.55,"ced8"], -[198,5.58,10.23,3.37,"cb46"], -[199,10.65,10.18,3.37,"c863"], -[200,11.67,10.18,3.37,"bf1e"], -[201,12.68,10.18,3.37,"c311"], -[202,13.68,10.18,3.37,"b4f0"], -[203,14.68,10.18,3.37,"cebe"], -[204,1.65,10.45,2.80,"b6b3"], -[205,2.65,10.45,2.95,"b5d5"], -[206,3.45,10.45,3.10,"c8fd"], -[207,3.20,10.45,2.30,"b8f3"], -[208,4.55,10.45,2.55,"ca86"], -[209,5.33,10.70,3.20,"b9a2"], -[210,5.33,10.70,2.18,"cf50"], -[211,5.33,11.50,2.13,"bfb3"], -[212,10.65,10.40,2.43,"b72f"], -[213,11.40,10.40,2.37,"c08f"], -[214,12.35,10.40,2.48,"b7e4"], -[215,13.38,10.40,2.60,"c00a"], -[216,14.48,10.40,2.70,"cdfc"], -[217,15.50,10.40,2.20,"b451"], -[218,6.26,11.22,3.35,"b48c"], -[219,6.26,12.18,3.35,"c3ee"], -[220,6.28,13.18,3.35,"b8c3"], -[221,6.28,14.08,3.35,"b7b6"], -[222,8.38,11.17,3.60,"b15e"], -[223,8.40,12.12,3.60,"b434"], -[224,8.40,13.14,3.60,"ccb0"], -[225,8.40,14.04,3.60,"cc9f"], -[226,8.38,15.04,3.60,"c836"], -[227,9.76,11.20,3.35,"ca8a"], -[228,9.78,12.20,3.35,"cd71"], -[229,9.78,13.20,3.35,"b2c4"], -[230,9.78,14.10,3.35,"b33f"], -[231,6.95,9.95,2.57,"c31a"], -[232,6.95,11.06,2.57,"b565"], -[233,6.95,12.08,2.57,"b700"], -[234,8.66,9.97,2.57,"c63c"], -[235,8.66,10.87,2.57,"c5cc"], -[236,8.66,12.10,2.57,"cee7"], -[237,5.33,12.40,3.50,"c543"], -[238,7.25,12.91,2.66,"ce47"], -[239,5.33,14.40,3.25,"c108"], -[240,7.93,15.43,3.34,"bc0f"], -[241,6.98,12.68,3.70,"ca22"], -[242,5.33,13.50,3.53,"c6c4"], -[243,7.93,14.50,3.34,"b14d"], -[244,8.78,12.72,3.70,"b8c8"], -[245,8.93,11.05,3.37,"ce6c"], -[246,9.83,15.58,3.63,"bdf0"], -[247,10.65,13.94,3.65,"c819"], -[248,8.66,12.91,2.60,"b4e4"], -[249,10.65,14.54,3.27,"c94e"], -[250,10.65,13.20,3.53,"c8fb"], -[251,5.73,15.58,3.62,"be2e"], -[252,6.54,15.58,3.63,"c4ed"], -[253,7.30,15.58,3.63,"b669"], -[254,6.11,14.53,3.35,"cd4c"], -[255,8.55,15.58,3.66,"????"], -[256,4.12,5.31,1.04,"b806"] -]; - diff --git a/plugins/senslabmap/static/js/jquery-mousewheel.min.js b/plugins/senslabmap/static/js/jquery-mousewheel.min.js new file mode 100644 index 00000000..549aa709 --- /dev/null +++ b/plugins/senslabmap/static/js/jquery-mousewheel.min.js @@ -0,0 +1 @@ +(function(e){if(typeof define==="function"&&define.amd){define(["jquery"],e)}else if(typeof exports==="object"){module.exports=e}else{e(jQuery)}})(function(e){function o(t){var n=t||window.event,s=[].slice.call(arguments,1),o=0,u=0,a=0,f=0,l=0,c;t=e.event.fix(n);t.type="mousewheel";if(n.wheelDelta){o=n.wheelDelta}if(n.detail){o=n.detail*-1}a=o;if(n.axis!==undefined&&n.axis===n.HORIZONTAL_AXIS){a=0;u=o*-1}if(n.deltaY){a=n.deltaY*-1;o=a}if(n.deltaX){u=n.deltaX;o=u*-1}if(n.wheelDeltaY!==undefined){a=n.wheelDeltaY}if(n.wheelDeltaX!==undefined){u=n.wheelDeltaX*-1}f=Math.abs(o);if(!r||f0?"floor":"ceil";o=Math[c](o/r);u=Math[c](u/i);a=Math[c](a/i);s.unshift(t,o,u,a);return(e.event.dispatch||e.event.handle).apply(this,s)}var t=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"];var n="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"];var r,i;if(e.event.fixHooks){for(var s=t.length;s;){e.event.fixHooks[t[--s]]=e.event.mouseHooks}}e.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var e=n.length;e;){this.addEventListener(n[--e],o,false)}}else{this.onmousewheel=o}},teardown:function(){if(this.removeEventListener){for(var e=n.length;e;){this.removeEventListener(n[--e],o,false)}}else{this.onmousewheel=null}}};e.fn.extend({mousewheel:function(e){return e?this.bind("mousewheel",e):this.trigger("mousewheel")},unmousewheel:function(e){return this.unbind("mousewheel",e)}})}) \ No newline at end of file diff --git a/plugins/senslabmap/static/js/map.js b/plugins/senslabmap/static/js/map.js new file mode 100644 index 00000000..0e8e1407 --- /dev/null +++ b/plugins/senslabmap/static/js/map.js @@ -0,0 +1,293 @@ +var Senslab = { + normalize: function(node) { + var info; + + if (node.component_name) { // wsn430-11.devlille.iot-lab.info + info = node.component_name.split("."); + } /*else if (node.hrn) { // iotlab.a8-11\.devgrenoble\.iot-lab\.info + var info = node.hrn.split("\\."); + info[0] = info[0].split(".")[1]; + }*/ + + if (info && info[2] == "iot-lab" && info[3] == "info") { + node.arch = info[0].split("-")[0]; + node.id = info[0].split("-")[1]; + node.site = info[1]; + node.normalized = true; + } + }, + notify: function(node) { + console.log("[Notify] node " + node.id + " is " + node.boot_state); + }, + createMaps: function($container, sites, nodes) { + var maps = {}; + $.each(sites, function(i, site) { + var $div = $("
").appendTo($container); + maps[site] = new Senslab.Map($div); + maps[site].addNodes(nodes[site]); + }); + } +}; + +Senslab.Map = function() { + var colors = { + "Alive": 0x7FFF00, + "Busy": 0x9943BE, + "Suspected": 0xFF3030, + "Selected": 0x0099CC + }; + + var archs = [ + "wsn430", + "m3", + "a8" + ]; + + function Map($container, options) { + this.width = 600; + this.height = 400; + + this.distance = 50; + this.phi = -100; + this.theta = 0; + this.onRot = false; + + this.pointerDetectRay = new THREE.Raycaster(); + this.pointerDetectRay.ray.direction.set(0, -1, 0); + this.projector = new THREE.Projector(); + this.mouse2D = new THREE.Vector3(0, 0, 0); + + this.renderer = new THREE.CanvasRenderer(); + this.renderer.setSize(this.width, this.height); + + this.camera = new THREE.PerspectiveCamera(75, this.width / this.height, 1, 10000); + + this.scene = new THREE.Scene(); + this.scene.add(this.camera); + + this.updatePosition(); + + var self = this; + + this.$nodeInputs = {}; + + $.each(archs, function(i, arch) { + self.$nodeInputs[arch] = $("") + .appendTo($container) + .change(function() { + self.updateSelected(arch, expand($(this).val())); + self.update(); + }); + }); + + var $canvas = $(this.renderer.domElement) + .mousemove(function(e) { + self.mouse2D.x = ((e.pageX - $canvas.offset().left) / $canvas.width()) * 2 - 1; + self.mouse2D.y = -((e.pageY - $canvas.offset().top) / $canvas.height()) * 2 + 1; + + if (self.onRot) { + self.theta -= e.pageX - self.mouse2D.pageX; + self.phi += e.pageY - self.mouse2D.pageY; + if (self.phi > 180) + self.phi = 180; + if (self.phi < -180) + self.phi = -180; + + self.mouse2D.pageX = e.pageX; + self.mouse2D.pageY = e.pageY; + + self.updatePosition(); + self.update(); + } + }).mousedown(function(e) { + e.preventDefault(); + switch (e.which) { + case 1: + self.pointerDetectRay = self.projector.pickingRay(self.mouse2D.clone(), self.camera); + var intersects = self.pointerDetectRay.intersectObjects(self.scene.children); + if (intersects.length > 0) { + var particle = intersects[0].object; + if (particle.data.boot_state != "Suspected") { + setState(particle, particle.data.boot_state == "Alive" ? "Selected" : "Alive"); + var $nodeInput = self.$nodeInputs[particle.data.arch]; + $nodeInput.val(factorize(self.getNodesId(particle.data.arch))); + self.update(); + } + } + break; + case 3: + self.mouse2D.pageX = e.pageX; + self.mouse2D.pageY = e.pageY; + self.onRot = true; + break; + } + }).mouseup(function(e) { + e.preventDefault(); + switch (e.which) { + case 3: + self.onRot = false; + break; + } + }).mouseleave(function(e) { + self.onRot = false; + }).mousewheel(function(e, delta) { + e.preventDefault(); + self.distance += delta * 5; + self.updatePosition(); + self.update(); + }); + + $container.append($canvas); + } + + Map.prototype.getNodesId = function(arch) { + var particles = this.scene.children; + var nodes = []; + for (var i = 0; i < particles.length; ++i) { + if (particles[i].data && particles[i].data.arch == arch && particles[i].data.boot_state == "Selected") { + nodes.push(particles[i].id); + } + } + return nodes; + } + + Map.prototype.addNodes = function(nodes) { + var center = getCenter(nodes); + + nodes.sort(function(a, b) { + return a.id - b.id; + }); + + for(var i = 0; i < nodes.length; ++i) { + var material = new THREE.ParticleCanvasMaterial({program: circle}); + var particle = new THREE.Particle(material); + particle.data = nodes[i]; + particle.id = parseInt(nodes[i].id); + particle.position.x = (nodes[i].x - center.x) * 10; + particle.position.y = (nodes[i].y - center.y) * 10; + particle.position.z = (nodes[i].z - center.z) * 10; + particle.scale.x = particle.scale.y = 1; + setColor(particle) + this.scene.add(particle); + } + this.update(); + }; + + Map.prototype.updateSelected = function(arch, selected) { + var particles = this.scene.children; + for (var i = 0; i < particles.length; ++i) { + if (particles[i].data && particles[i].data.arch == arch && particles[i].data.boot_state != "Suspected") { + var particle = particles[i]; + var state = $.inArray(particle.id, selected) == -1 ? "Alive" : "Selected"; + if (particle.data.boot_state != state) { + setState(particle, state); + } + } + } + } + + Map.prototype.updatePosition = function() { + this.camera.position.x = this.distance + * Math.sin(this.theta * Math.PI / 360) + * Math.cos(this.phi * Math.PI / 360); + this.camera.position.y = this.distance * Math.sin(this.phi * Math.PI / 360); + this.camera.position.z = this.distance + * Math.cos(this.theta * Math.PI / 360) + * Math.cos(this.phi * Math.PI / 360); + this.camera.lookAt(this.scene.position); + this.camera.updateMatrix(); + }; + + Map.prototype.update = function() { + this.renderer.render(this.scene, this.camera); + }; + + function setState(particle, state) { + particle.data.boot_state = state; + setColor(particle); + Senslab.notify(particle.data); + } + + function setColor(particle) { + var color = colors[particle.data.boot_state] || colors["Selected"]; + particle.material.color.setHex(color); + } + + function getCenter(nodes) { + var xmin = 0, ymin = 0, zmin = 0; + var xmax = 0, ymax = 0, zmax = 0; + + for (var i = 0; i < nodes.length; ++i) { + if (nodes[i].x > xmax) xmax = nodes[i].x; + if (nodes[i].x < xmin) xmin = nodes[i].x; + if (nodes[i].y > ymax) ymax = nodes[i].y; + if (nodes[i].y < ymin) ymin = nodes[i].y; + if (nodes[i].z > zmax) zmax = nodes[i].z; + if (nodes[i].z < zmin) zmin = nodes[i].z; + } + return {x: (xmax + xmin) / 2, y: (ymax + ymin) / 2, z: (zmax + zmin) / 2}; + } + + function factorize(nodes) { + var factorized = []; + var prev = 0; + var intervalStart = 0; + + for (var i = 0; i < nodes.length; ++i) { + if (intervalStart) { + if (nodes[i] == prev + 1) { + prev++; + } else { + factorized.push(intervalStart + "-" + prev); + intervalStart = 0; + prev = nodes[i]; + } + } else { + if (nodes[i] == prev + 1) { + intervalStart = prev; + prev++; + } else { + prev && factorized.push(prev); + prev = nodes[i]; + } + } + } + factorized.push(intervalStart ? intervalStart + "-" + prev : prev); + return factorized.join(","); + } + + function expand(input) { + var factorized = input.split(","); + var expanded = []; + for (var i = 0; i < factorized.length; ++i) { + var d = factorized[i].split("-"); + if (d.length == 2) { + for (var j = parseInt(d[0]); j < parseInt(d[1]) + 1; j++) { + expanded.push(j); + } + } else { + expanded.push(parseInt(factorized[i])); + } + } + + expanded.sort(function(a, b) { + return a - b; + }); + + for (var i = 1; i < expanded.length; i++) { + if (expanded[i] == expanded[i - 1]) { + expanded.splice(i--, 1); + } + } + return expanded; + } + + function circle(context) { + context.beginPath(); + context.arc(0, 0, 1, 0, Math.PI * 2, true); + context.closePath(); + context.fill(); + }; + + return Map; +}(); \ No newline at end of file diff --git a/plugins/senslabmap/static/js/senslabmap.js b/plugins/senslabmap/static/js/senslabmap.js index 1fe7810c..2945e0d8 100644 --- a/plugins/senslabmap/static/js/senslabmap.js +++ b/plugins/senslabmap/static/js/senslabmap.js @@ -4,47 +4,48 @@ this._super(options, element); this.elmt().on('show', this, this.on_show); - + + var query = manifold.query_store.find_analyzed_query(options.query_uuid); this.method = query.object; + this.key = manifold.metadata.get_key(this.method); /* Setup query and record handlers */ this.listen_query(options.query_uuid); this.listen_query(options.query_all_uuid, 'all'); - - /* GUI setup and event binding */ - this.initialize_map(); - }, - - initialize_map: function() { - this.nodes = []; - this.id = 0; - init(); - }, - - refresh: function() { - console.log("refresh"); - myrender(); + + this.sites = []; + this.nodes = {}; }, on_show: function(e) { e.data.refresh(); }, - on_all_new_record: function(n) { - // format is : [name, x, y, z, uid, state] - // state = "Busy", "Alive" or "Suspected" - if (n.x == null || n.y == null || n.z == null) { - console.log("Warning: no coord for " + n.hrn); - return; + on_all_new_record: function(node) { + Senslab.normalize(node, this.key); + if (node.normalized) { + var site = node.site; + if ($.inArray(site, this.sites) == -1) { + this.sites.push(site); + this.nodes[site] = []; + } + this.nodes[site].push(node); + } else { + console.warn("node has no site:"); + console.warn(node); } - this.id++; - node = [this.id, n.x, n.y, n.z, this.id, n.boot_state]; - this.nodes.push(node); }, on_all_query_done: function() { - drawNodes(this.nodes); - parseNodebox(); + var self = this; + + Senslab.createMaps($('#maps-container'), this.sites, this.nodes); + Senslab.notify = function(node) { + manifold.raise_event(self.options.query_uuid, + node.boot_state == "Alive" ? SET_REMOVED : SET_ADD, + node[self.key] + ); + } } }); $.plugin('SensLabMap', SensLabMap); diff --git a/plugins/senslabmap/static/js/three.js b/plugins/senslabmap/static/js/three.js deleted file mode 100644 index b36e7d87..00000000 --- a/plugins/senslabmap/static/js/three.js +++ /dev/null @@ -1,794 +0,0 @@ -// Three.js - http://github.com/mrdoob/three.js -'use strict';var THREE=THREE||{REVISION:"48"};if(!self.Int32Array)self.Int32Array=Array,self.Float32Array=Array; -(function(){for(var a=0,b=["ms","moz","webkit","o"],c=0;c>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},getHex:function(){return Math.floor(255*this.r)<<16^Math.floor(255*this.g)<<8^Math.floor(255*this.b)},getContextStyle:function(){return"rgb("+Math.floor(255*this.r)+","+Math.floor(255*this.g)+","+Math.floor(255*this.b)+")"},clone:function(){return(new THREE.Color).setRGB(this.r,this.g,this.b)}};THREE.Vector2=function(a,b){this.x=a||0;this.y=b||0}; -THREE.Vector2.prototype={constructor:THREE.Vector2,set:function(a,b){this.x=a;this.y=b;return this},copy:function(a){this.x=a.x;this.y=a.y;return this},clone:function(){return new THREE.Vector2(this.x,this.y)},add:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addSelf:function(a){this.x+=a.x;this.y+=a.y;return this},sub:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},subSelf:function(a){this.x-=a.x;this.y-=a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this}, -divideScalar:function(a){a?(this.x/=a,this.y/=a):this.set(0,0);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.lengthSq())},normalize:function(){return this.divideScalar(this.length())},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,a=this.y-a.y;return b*b+a*a},setLength:function(a){return this.normalize().multiplyScalar(a)}, -lerpSelf:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},equals:function(a){return a.x===this.x&&a.y===this.y},isZero:function(){return 1.0E-4>this.lengthSq()}};THREE.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}; -THREE.Vector3.prototype={constructor:THREE.Vector3,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},clone:function(){return new THREE.Vector3(this.x,this.y,this.z)},add:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addSelf:function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z;return this}, -addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},sub:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},subSelf:function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},multiply:function(a,b){this.x=a.x*b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},multiplySelf:function(a){this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},divideSelf:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this}, -divideScalar:function(a){a?(this.x/=a,this.y/=a,this.z/=a):this.z=this.y=this.x=0;return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.lengthSq())},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.normalize().multiplyScalar(a)}, -lerpSelf:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},cross:function(a,b){this.x=a.y*b.z-a.z*b.y;this.y=a.z*b.x-a.x*b.z;this.z=a.x*b.y-a.y*b.x;return this},crossSelf:function(a){var b=this.x,c=this.y,d=this.z;this.x=c*a.z-d*a.y;this.y=d*a.x-b*a.z;this.z=b*a.y-c*a.x;return this},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){return(new THREE.Vector3).sub(this,a).lengthSq()},getPositionFromMatrix:function(a){this.x= -a.n14;this.y=a.n24;this.z=a.n34;return this},getRotationFromMatrix:function(a,b){var c=b?b.x:1,d=b?b.y:1,f=b?b.z:1,g=a.n11/c,e=a.n12/d,c=a.n21/c,d=a.n22/d,h=a.n23/f,i=a.n33/f;this.y=Math.asin(a.n13/f);f=Math.cos(this.y);1.0E-5this.lengthSq()}};THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}; -THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)},add:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},addSelf:function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},sub:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y; -this.z=a.z-b.z;this.w=a.w-b.w;return this},subSelf:function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},divideScalar:function(a){a?(this.x/=a,this.y/=a,this.z/=a,this.w/=a):(this.z=this.y=this.x=0,this.w=1);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.dot(this)},length:function(){return Math.sqrt(this.lengthSq())}, -normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.normalize().multiplyScalar(a)},lerpSelf:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this}};THREE.Frustum=function(){this.planes=[new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4]}; -THREE.Frustum.prototype.setFromMatrix=function(a){var b,c=this.planes;c[0].set(a.n41-a.n11,a.n42-a.n12,a.n43-a.n13,a.n44-a.n14);c[1].set(a.n41+a.n11,a.n42+a.n12,a.n43+a.n13,a.n44+a.n14);c[2].set(a.n41+a.n21,a.n42+a.n22,a.n43+a.n23,a.n44+a.n24);c[3].set(a.n41-a.n21,a.n42-a.n22,a.n43-a.n23,a.n44-a.n24);c[4].set(a.n41-a.n31,a.n42-a.n32,a.n43-a.n33,a.n44-a.n34);c[5].set(a.n41+a.n31,a.n42+a.n32,a.n43+a.n33,a.n44+a.n34);for(a=0;6>a;a++)b=c[a],b.divideScalar(Math.sqrt(b.x*b.x+b.y*b.y+b.z*b.z))}; -THREE.Frustum.prototype.contains=function(a){for(var b=this.planes,c=a.matrixWorld,d=THREE.Frustum.__v1.set(c.getColumnX().length(),c.getColumnY().length(),c.getColumnZ().length()),d=-a.geometry.boundingSphere.radius*Math.max(d.x,Math.max(d.y,d.z)),f=0;6>f;f++)if(a=b[f].x*c.n14+b[f].y*c.n24+b[f].z*c.n34+b[f].w,a<=d)return!1;return!0};THREE.Frustum.__v1=new THREE.Vector3; -THREE.Ray=function(a,b){function c(a,b,c){p.sub(c,a);s=p.dot(b);t=n.add(a,r.copy(b).multiplyScalar(s));return w=c.distanceTo(t)}function d(a,b,c,d){p.sub(d,b);n.sub(c,b);r.sub(a,b);u=p.dot(p);v=p.dot(n);A=p.dot(r);F=n.dot(n);B=n.dot(r);D=1/(u*F-v*v);H=(F*A-v*B)*D;I=(u*B-v*A)*D;return 0<=H&&0<=I&&1>H+I}this.origin=a||new THREE.Vector3;this.direction=b||new THREE.Vector3;this.intersectObjects=function(a){var b,c,d=[];for(b=0,c=a.length;ba.scale.x)return[];b={distance:p,point:a.position,face:null,object:a}; -n.push(b)}else if(a instanceof THREE.Mesh){var p=c(this.origin,this.direction,a.matrixWorld.getPosition()),r=THREE.Frustum.__v1.set(a.matrixWorld.getColumnX().length(),a.matrixWorld.getColumnY().length(),a.matrixWorld.getColumnZ().length());if(p>a.geometry.boundingSphere.radius*Math.max(r.x,Math.max(r.y,r.z)))return n;var s,l,t=a.geometry,u=t.vertices,E;a.matrixRotationWorld.extractRotation(a.matrixWorld);for(p=0,r=t.faces.length;pl)&&(a.doubleSided||(a.flipSided?0s))))if(o.add(j,k.multiplyScalar(l)),b instanceof THREE.Face3)g=E.multiplyVector3(g.copy(u[b.a].position)),e=E.multiplyVector3(e.copy(u[b.b].position)),h=E.multiplyVector3(h.copy(u[b.c].position)),d(o,g,e,h)&&(b={distance:j.distanceTo(o),point:o.clone(),face:b,object:a},n.push(b));else if(b instanceof -THREE.Face4&&(g=E.multiplyVector3(g.copy(u[b.a].position)),e=E.multiplyVector3(e.copy(u[b.b].position)),h=E.multiplyVector3(h.copy(u[b.c].position)),i=E.multiplyVector3(i.copy(u[b.d].position)),d(o,g,e,i)||d(o,e,h,i)))b={distance:j.distanceTo(o),point:o.clone(),face:b,object:a},n.push(b)}return n};var p=new THREE.Vector3,n=new THREE.Vector3,r=new THREE.Vector3,s,t,w,u,v,A,F,B,D,H,I}; -THREE.Rectangle=function(){function a(){g=d-b;e=f-c}var b,c,d,f,g,e,h=!0;this.getX=function(){return b};this.getY=function(){return c};this.getWidth=function(){return g};this.getHeight=function(){return e};this.getLeft=function(){return b};this.getTop=function(){return c};this.getRight=function(){return d};this.getBottom=function(){return f};this.set=function(g,e,k,q){h=!1;b=g;c=e;d=k;f=q;a()};this.addPoint=function(g,e){h?(h=!1,b=g,c=e,d=g,f=e):(b=bg?d:g,f=f>e?f:e);a()};this.add3Points= -function(g,e,k,q,m,o){h?(h=!1,b=gk?g>m?g:m:k>m?k:m,f=e>q?e>o?e:o:q>o?q:o):(b=gk?g>m?g>d?g:d:m>d?m:d:k>m?k>d?k:d:m>d?m:d,f=e>q?e>o?e>f?e:f:o>f?o:f:q>o?q>f?q:f:o>f?o:f);a()};this.addRectangle=function(g){h?(h=!1,b=g.getLeft(),c=g.getTop(),d=g.getRight(),f=g.getBottom()):(b=bg.getRight()?d:g.getRight(),f=f> -g.getBottom()?f:g.getBottom());a()};this.inflate=function(g){b-=g;c-=g;d+=g;f+=g;a()};this.minSelf=function(g){b=b>g.getLeft()?b:g.getLeft();c=c>g.getTop()?c:g.getTop();d=da.getRight()||fa.getBottom()?!1:!0};this.empty=function(){h=!0;f=d=c=b=0;a()};this.isEmpty=function(){return h}}; -THREE.Math={clamp:function(a,b,c){return ac?c:a},clampBottom:function(a,b){return aa?-1:0f&&0>g||0>e&&0>h)return!1;0>f?c=Math.max(c,f/(f-g)):0>g&&(d=Math.min(d,f/(f-g)));0>e?c=Math.max(c,e/(e-h)):0>h&&(d=Math.min(d,e/(e-h)));if(de&&h.positionScreen.z(ka.positionScreen.x-R.positionScreen.x)*(ca.positionScreen.y-R.positionScreen.y)-(ka.positionScreen.y-R.positionScreen.y)*(ca.positionScreen.x-R.positionScreen.x), -N.doubleSided||l!=N.flipSided)ia=m[q]=m[q]||new THREE.RenderableFace3,q++,k=ia,k.v1.copy(R),k.v2.copy(ca),k.v3.copy(ka);else continue;else continue;else if(E instanceof THREE.Face4)if(R=j[E.a],ca=j[E.b],ka=j[E.c],ia=j[E.d],R.visible&&ca.visible&&ka.visible&&ia.visible)if(l=0>(ia.positionScreen.x-R.positionScreen.x)*(ca.positionScreen.y-R.positionScreen.y)-(ia.positionScreen.y-R.positionScreen.y)*(ca.positionScreen.x-R.positionScreen.x)||0>(ca.positionScreen.x-ka.positionScreen.x)*(ia.positionScreen.y- -ka.positionScreen.y)-(ca.positionScreen.y-ka.positionScreen.y)*(ia.positionScreen.x-ka.positionScreen.x),N.doubleSided||l!=N.flipSided)Ja=p[o]=p[o]||new THREE.RenderableFace4,o++,k=Ja,k.v1.copy(R),k.v2.copy(ca),k.v3.copy(ka),k.v4.copy(ia);else continue;else continue;k.normalWorld.copy(E.normal);!l&&(N.flipSided||N.doubleSided)&&k.normalWorld.negate();U.multiplyVector3(k.normalWorld);k.centroidWorld.copy(E.centroid);aa.multiplyVector3(k.centroidWorld);k.centroidScreen.copy(k.centroidWorld);B.multiplyVector3(k.centroidScreen); -ka=E.vertexNormals;for(R=0,ca=ka.length;RF.z))e=u[w]=u[w]||new THREE.RenderableParticle,w++,t=e,t.x=F.x/F.w,t.y=F.y/F.w,t.z=F.z,t.rotation=N.rotation.z,t.scale.x=N.scale.x*Math.abs(t.x-(F.x+f.projectionMatrix.n11)/(F.w+f.projectionMatrix.n14)),t.scale.y=N.scale.y*Math.abs(t.y-(F.y+f.projectionMatrix.n22)/(F.w+f.projectionMatrix.n24)),t.material=N.material,v.elements.push(t);g&&v.elements.sort(c);return v}}; -THREE.Quaternion=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}; -THREE.Quaternion.prototype={constructor:THREE.Quaternion,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=a.w;return this},clone:function(){return new THREE.Quaternion(this.x,this.y,this.z,this.w)},setFromEuler:function(a){var b=Math.PI/360,c=a.x*b,d=a.y*b,f=a.z*b,a=Math.cos(d),d=Math.sin(d),b=Math.cos(-f),f=Math.sin(-f),g=Math.cos(c),c=Math.sin(c),e=a*b,h=d*f;this.w=e*g-h*c;this.x=e*c+h*g;this.y=d*b*g+a*f*c;this.z=a*f* -g-d*b*c;return this},setFromAxisAngle:function(a,b){var c=b/2,d=Math.sin(c);this.x=a.x*d;this.y=a.y*d;this.z=a.z*d;this.w=Math.cos(c);return this},setFromRotationMatrix:function(a){var b=Math.pow(a.determinant(),1/3);this.w=Math.sqrt(Math.max(0,b+a.n11+a.n22+a.n33))/2;this.x=Math.sqrt(Math.max(0,b+a.n11-a.n22-a.n33))/2;this.y=Math.sqrt(Math.max(0,b-a.n11+a.n22-a.n33))/2;this.z=Math.sqrt(Math.max(0,b-a.n11-a.n22+a.n33))/2;this.x=0>a.n32-a.n23?-Math.abs(this.x):Math.abs(this.x);this.y=0>a.n13-a.n31? --Math.abs(this.y):Math.abs(this.y);this.z=0>a.n21-a.n12?-Math.abs(this.z):Math.abs(this.z);this.normalize();return this},calculateW:function(){this.w=-Math.sqrt(Math.abs(1-this.x*this.x-this.y*this.y-this.z*this.z));return this},inverse:function(){this.x*=-1;this.y*=-1;this.z*=-1;return this},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},normalize:function(){var a=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);0===a?this.w=this.z= -this.y=this.x=0:(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a);return this},multiplySelf:function(a){var b=this.x,c=this.y,d=this.z,f=this.w,g=a.x,e=a.y,h=a.z,a=a.w;this.x=b*a+f*g+c*h-d*e;this.y=c*a+f*e+d*g-b*h;this.z=d*a+f*h+b*e-c*g;this.w=f*a-b*g-c*e-d*h;return this},multiply:function(a,b){this.x=a.x*b.w+a.y*b.z-a.z*b.y+a.w*b.x;this.y=-a.x*b.z+a.y*b.w+a.z*b.x+a.w*b.y;this.z=a.x*b.y-a.y*b.x+a.z*b.w+a.w*b.z;this.w=-a.x*b.x-a.y*b.y-a.z*b.z+a.w*b.w;return this},multiplyVector3:function(a,b){b||(b= -a);var c=a.x,d=a.y,f=a.z,g=this.x,e=this.y,h=this.z,i=this.w,j=i*c+e*f-h*d,k=i*d+h*c-g*f,q=i*f+g*d-e*c,c=-g*c-e*d-h*f;b.x=j*i+c*-g+k*-h-q*-e;b.y=k*i+c*-e+q*-g-j*-h;b.z=q*i+c*-h+j*-e-k*-g;return b}}; -THREE.Quaternion.slerp=function(a,b,c,d){var f=a.w*b.w+a.x*b.x+a.y*b.y+a.z*b.z;0>f?(c.w=-b.w,c.x=-b.x,c.y=-b.y,c.z=-b.z,f=-f):c.copy(b);if(1<=Math.abs(f))return c.w=a.w,c.x=a.x,c.y=a.y,c.z=a.z,c;var g=Math.acos(f),f=Math.sqrt(1-f*f);if(0.001>Math.abs(f))return c.w=0.5*(a.w+b.w),c.x=0.5*(a.x+b.x),c.y=0.5*(a.y+b.y),c.z=0.5*(a.z+b.z),c;b=Math.sin((1-d)*g)/f;d=Math.sin(d*g)/f;c.w=a.w*b+c.w*d;c.x=a.x*b+c.x*d;c.y=a.y*b+c.y*d;c.z=a.z*b+c.z*d;return c};THREE.Vertex=function(a){this.position=a||new THREE.Vector3}; -THREE.Vertex.prototype={constructor:THREE.Vertex,clone:function(){return new THREE.Vertex(this.position.clone())}};THREE.Face3=function(a,b,c,d,f,g){this.a=a;this.b=b;this.c=c;this.normal=d instanceof THREE.Vector3?d:new THREE.Vector3;this.vertexNormals=d instanceof Array?d:[];this.color=f instanceof THREE.Color?f:new THREE.Color;this.vertexColors=f instanceof Array?f:[];this.vertexTangents=[];this.materialIndex=g;this.centroid=new THREE.Vector3}; -THREE.Face3.prototype={constructor:THREE.Face3,clone:function(){var a=new THREE.Face3(this.a,this.b,this.c);a.normal.copy(this.normal);a.color.copy(this.color);a.centroid.copy(this.centroid);a.materialIndex=this.materialIndex;var b,c;for(b=0,c=this.vertexNormals.length;bf?-1:1,g.vertexTangents[d]=new THREE.Vector4(P.x,P.y,P.z,f)}this.hasTangents=!0},computeBoundingBox:function(){if(!this.boundingBox)this.boundingBox={min:new THREE.Vector3,max:new THREE.Vector3};if(0c.x)c.x=a.x;if(a.yc.y)c.y=a.y;if(a.zc.z)c.z=a.z}}else this.boundingBox.min.set(0,0,0),this.boundingBox.max.set(0,0,0)},computeBoundingSphere:function(){if(!this.boundingSphere)this.boundingSphere={radius:0};for(var a,b=0,c=0,d=this.vertices.length;cb&&(b=a);this.boundingSphere.radius=b},mergeVertices:function(){var a={},b=[],c=[],d,f=Math.pow(10, -4),g,e;for(g=0,e=this.vertices.length;gthis.points.length-2?g:g+1;c[3]=g>this.points.length-3?g:g+2;j=this.points[c[0]];k=this.points[c[1]]; -q=this.points[c[2]];m=this.points[c[3]];h=e*e;i=e*h;d.x=b(j.x,k.x,q.x,m.x,e,h,i);d.y=b(j.y,k.y,q.y,m.y,e,h,i);d.z=b(j.z,k.z,q.z,m.z,e,h,i);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;ah.end)h.end=f;b||(b=e)}}a.firstAnimation=b}; -THREE.MorphAnimMesh.prototype.setAnimationLabel=function(a,b,c){if(!this.geometry.animations)this.geometry.animations={};this.geometry.animations[a]={start:b,end:c}};THREE.MorphAnimMesh.prototype.playAnimation=function(a,b){var c=this.geometry.animations[a];c?(this.setFrameRange(c.start,c.end),this.duration=1E3*((c.end-c.start)/b),this.time=0):console.warn("animation["+a+"] undefined")}; -THREE.MorphAnimMesh.prototype.updateAnimation=function(a){var b=this.duration/this.length;this.time+=this.direction*a;if(this.mirroredLoop){if(this.time>this.duration||0>this.time){this.direction*=-1;if(this.time>this.duration)this.time=this.duration,this.directionBackwards=!0;if(0>this.time)this.time=0,this.directionBackwards=!1}}else this.time%=this.duration,0>this.time&&(this.time+=this.duration);a=this.startKeyframe+THREE.Math.clamp(Math.floor(this.time/b),0,this.length-1);if(a!==this.currentKeyframe)this.morphTargetInfluences[this.lastKeyframe]= -0,this.morphTargetInfluences[this.currentKeyframe]=1,this.morphTargetInfluences[a]=0,this.lastKeyframe=this.currentKeyframe,this.currentKeyframe=a;b=this.time%b/b;this.directionBackwards&&(b=1-b);this.morphTargetInfluences[this.currentKeyframe]=b;this.morphTargetInfluences[this.lastKeyframe]=1-b};THREE.Ribbon=function(a,b){THREE.Object3D.call(this);this.geometry=a;this.material=b};THREE.Ribbon.prototype=new THREE.Object3D;THREE.Ribbon.prototype.constructor=THREE.Ribbon; -THREE.LOD=function(){THREE.Object3D.call(this);this.LODs=[]};THREE.LOD.prototype=new THREE.Object3D;THREE.LOD.prototype.constructor=THREE.LOD;THREE.LOD.prototype.supr=THREE.Object3D.prototype;THREE.LOD.prototype.addLevel=function(a,b){void 0===b&&(b=0);for(var b=Math.abs(b),c=0;c=this.LODs[b].visibleAtDistance)this.LODs[b-1].object3D.visible=!1,this.LODs[b].object3D.visible=!0;else break;for(;bs&&n.clearRect(Math.floor(sa.getX()),Math.floor(sa.getY()),Math.floor(sa.getWidth()),Math.floor(sa.getHeight())),0=i||(i*=e.intensity,d.r+=h.r*i,d.g+=h.g*i,d.b+=h.b*i)):e instanceof THREE.PointLight&&(l=e.matrixWorld.getPosition(),i=c.dot(Z.sub(l,b).normalize()),0>=i||(i*=0==e.distance?1:1-Math.min(b.distanceTo(l)/e.distance,1),0!=i&&(i*=e.intensity,d.r+=h.r*i,d.g+=h.g*i,d.b+=h.b*i)))}function r(a,g,e){b(e.opacity);c(e.blending);var Z,h,l,i,k,j;if(e instanceof THREE.ParticleBasicMaterial){if(e.map)i= -e.map.image,k=i.width>>1,j=i.height>>1,e=g.scale.x*o,l=g.scale.y*p,Z=e*k,h=l*j,za.set(a.x-Z,a.y-h,a.x+Z,a.y+h),La.intersects(za)&&(n.save(),n.translate(a.x,a.y),n.rotate(-g.rotation),n.scale(e,-l),n.translate(-k,-j),n.drawImage(i,0,0),n.restore())}else e instanceof THREE.ParticleCanvasMaterial&&(Z=g.scale.x*o,h=g.scale.y*p,za.set(a.x-Z,a.y-h,a.x+Z,a.y+h),La.intersects(za)&&(d(e.color.getContextStyle()),f(e.color.getContextStyle()),n.save(),n.translate(a.x,a.y),n.rotate(-g.rotation),n.scale(Z,h),e.program(n), -n.restore()))}function s(a,f,g,e){b(e.opacity);c(e.blending);n.beginPath();n.moveTo(a.positionScreen.x,a.positionScreen.y);n.lineTo(f.positionScreen.x,f.positionScreen.y);n.closePath();if(e instanceof THREE.LineBasicMaterial){a=e.linewidth;if(A!=a)n.lineWidth=A=a;a=e.linecap;if(F!=a)n.lineCap=F=a;a=e.linejoin;if(B!=a)n.lineJoin=B=a;d(e.color.getContextStyle());n.stroke();za.inflate(2*e.linewidth)}}function t(a,d,f,e,h,j,n,T){g.info.render.vertices+=3;g.info.render.faces++;b(T.opacity);c(T.blending); -K=a.positionScreen.x;O=a.positionScreen.y;y=d.positionScreen.x;l=d.positionScreen.y;$=f.positionScreen.x;C=f.positionScreen.y;v(K,O,y,l,$,C);if(T instanceof THREE.MeshBasicMaterial)if(T.map)T.map.mapping instanceof THREE.UVMapping&&(ha=n.uvs[0],Vc(K,O,y,l,$,C,ha[e].u,ha[e].v,ha[h].u,ha[h].v,ha[j].u,ha[j].v,T.map));else if(T.envMap){if(T.envMap.mapping instanceof THREE.SphericalReflectionMapping)a=k.matrixWorldInverse,Z.copy(n.vertexNormalsWorld[e]),ib=0.5*(Z.x*a.n11+Z.y*a.n12+Z.z*a.n13)+0.5,db=0.5* --(Z.x*a.n21+Z.y*a.n22+Z.z*a.n23)+0.5,Z.copy(n.vertexNormalsWorld[h]),lb=0.5*(Z.x*a.n11+Z.y*a.n12+Z.z*a.n13)+0.5,cb=0.5*-(Z.x*a.n21+Z.y*a.n22+Z.z*a.n23)+0.5,Z.copy(n.vertexNormalsWorld[j]),Za=0.5*(Z.x*a.n11+Z.y*a.n12+Z.z*a.n13)+0.5,Sa=0.5*-(Z.x*a.n21+Z.y*a.n22+Z.z*a.n23)+0.5,Vc(K,O,y,l,$,C,ib,db,lb,cb,Za,Sa,T.envMap)}else T.wireframe?Mb(T.color,T.wireframeLinewidth,T.wireframeLinecap,T.wireframeLinejoin):Gb(T.color);else if(T instanceof THREE.MeshLambertMaterial)T.map&&!T.wireframe&&(T.map.mapping instanceof -THREE.UVMapping&&(ha=n.uvs[0],Vc(K,O,y,l,$,C,ha[e].u,ha[e].v,ha[h].u,ha[h].v,ha[j].u,ha[j].v,T.map)),c(THREE.SubtractiveBlending)),Ea?!T.wireframe&&T.shading==THREE.SmoothShading&&3==n.vertexNormalsWorld.length?(aa.r=U.r=ba.r=Fa.r,aa.g=U.g=ba.g=Fa.g,aa.b=U.b=ba.b=Fa.b,q(i,n.v1.positionWorld,n.vertexNormalsWorld[0],aa),q(i,n.v2.positionWorld,n.vertexNormalsWorld[1],U),q(i,n.v3.positionWorld,n.vertexNormalsWorld[2],ba),aa.r=Math.max(0,Math.min(T.color.r*aa.r,1)),aa.g=Math.max(0,Math.min(T.color.g*aa.g, -1)),aa.b=Math.max(0,Math.min(T.color.b*aa.b,1)),U.r=Math.max(0,Math.min(T.color.r*U.r,1)),U.g=Math.max(0,Math.min(T.color.g*U.g,1)),U.b=Math.max(0,Math.min(T.color.b*U.b,1)),ba.r=Math.max(0,Math.min(T.color.r*ba.r,1)),ba.g=Math.max(0,Math.min(T.color.g*ba.g,1)),ba.b=Math.max(0,Math.min(T.color.b*ba.b,1)),ea.r=0.5*(U.r+ba.r),ea.g=0.5*(U.g+ba.g),ea.b=0.5*(U.b+ba.b),qa=Dc(aa,U,ba,ea),gc(K,O,y,l,$,C,0,0,1,0,0,1,qa)):(N.r=Fa.r,N.g=Fa.g,N.b=Fa.b,q(i,n.centroidWorld,n.normalWorld,N),N.r=Math.max(0,Math.min(T.color.r* -N.r,1)),N.g=Math.max(0,Math.min(T.color.g*N.g,1)),N.b=Math.max(0,Math.min(T.color.b*N.b,1)),T.wireframe?Mb(N,T.wireframeLinewidth,T.wireframeLinecap,T.wireframeLinejoin):Gb(N)):T.wireframe?Mb(T.color,T.wireframeLinewidth,T.wireframeLinecap,T.wireframeLinejoin):Gb(T.color);else if(T instanceof THREE.MeshDepthMaterial)Ka=k.near,Ga=k.far,aa.r=aa.g=aa.b=1-ac(a.positionScreen.z,Ka,Ga),U.r=U.g=U.b=1-ac(d.positionScreen.z,Ka,Ga),ba.r=ba.g=ba.b=1-ac(f.positionScreen.z,Ka,Ga),ea.r=0.5*(U.r+ba.r),ea.g=0.5* -(U.g+ba.g),ea.b=0.5*(U.b+ba.b),qa=Dc(aa,U,ba,ea),gc(K,O,y,l,$,C,0,0,1,0,0,1,qa);else if(T instanceof THREE.MeshNormalMaterial)N.r=hc(n.normalWorld.x),N.g=hc(n.normalWorld.y),N.b=hc(n.normalWorld.z),T.wireframe?Mb(N,T.wireframeLinewidth,T.wireframeLinecap,T.wireframeLinejoin):Gb(N)}function u(a,d,f,e,Z,h,T,j,n){g.info.render.vertices+=4;g.info.render.faces++;b(j.opacity);c(j.blending);if(j.map||j.envMap)t(a,d,e,0,1,3,T,j,n),t(Z,f,h,1,2,3,T,j,n);else if(K=a.positionScreen.x,O=a.positionScreen.y,y=d.positionScreen.x, -l=d.positionScreen.y,$=f.positionScreen.x,C=f.positionScreen.y,E=e.positionScreen.x,S=e.positionScreen.y,R=Z.positionScreen.x,ca=Z.positionScreen.y,ka=h.positionScreen.x,ia=h.positionScreen.y,j instanceof THREE.MeshBasicMaterial)w(K,O,y,l,$,C,E,S),j.wireframe?Mb(j.color,j.wireframeLinewidth,j.wireframeLinecap,j.wireframeLinejoin):Gb(j.color);else if(j instanceof THREE.MeshLambertMaterial)Ea?!j.wireframe&&j.shading==THREE.SmoothShading&&4==T.vertexNormalsWorld.length?(aa.r=U.r=ba.r=ea.r=Fa.r,aa.g= -U.g=ba.g=ea.g=Fa.g,aa.b=U.b=ba.b=ea.b=Fa.b,q(i,T.v1.positionWorld,T.vertexNormalsWorld[0],aa),q(i,T.v2.positionWorld,T.vertexNormalsWorld[1],U),q(i,T.v4.positionWorld,T.vertexNormalsWorld[3],ba),q(i,T.v3.positionWorld,T.vertexNormalsWorld[2],ea),aa.r=Math.max(0,Math.min(j.color.r*aa.r,1)),aa.g=Math.max(0,Math.min(j.color.g*aa.g,1)),aa.b=Math.max(0,Math.min(j.color.b*aa.b,1)),U.r=Math.max(0,Math.min(j.color.r*U.r,1)),U.g=Math.max(0,Math.min(j.color.g*U.g,1)),U.b=Math.max(0,Math.min(j.color.b*U.b,1)), -ba.r=Math.max(0,Math.min(j.color.r*ba.r,1)),ba.g=Math.max(0,Math.min(j.color.g*ba.g,1)),ba.b=Math.max(0,Math.min(j.color.b*ba.b,1)),ea.r=Math.max(0,Math.min(j.color.r*ea.r,1)),ea.g=Math.max(0,Math.min(j.color.g*ea.g,1)),ea.b=Math.max(0,Math.min(j.color.b*ea.b,1)),qa=Dc(aa,U,ba,ea),v(K,O,y,l,E,S),gc(K,O,y,l,E,S,0,0,1,0,0,1,qa),v(R,ca,$,C,ka,ia),gc(R,ca,$,C,ka,ia,1,0,1,1,0,1,qa)):(N.r=Fa.r,N.g=Fa.g,N.b=Fa.b,q(i,T.centroidWorld,T.normalWorld,N),N.r=Math.max(0,Math.min(j.color.r*N.r,1)),N.g=Math.max(0, -Math.min(j.color.g*N.g,1)),N.b=Math.max(0,Math.min(j.color.b*N.b,1)),w(K,O,y,l,$,C,E,S),j.wireframe?Mb(N,j.wireframeLinewidth,j.wireframeLinecap,j.wireframeLinejoin):Gb(N)):(w(K,O,y,l,$,C,E,S),j.wireframe?Mb(j.color,j.wireframeLinewidth,j.wireframeLinecap,j.wireframeLinejoin):Gb(j.color));else if(j instanceof THREE.MeshNormalMaterial)N.r=hc(T.normalWorld.x),N.g=hc(T.normalWorld.y),N.b=hc(T.normalWorld.z),w(K,O,y,l,$,C,E,S),j.wireframe?Mb(N,j.wireframeLinewidth,j.wireframeLinecap,j.wireframeLinejoin): -Gb(N);else if(j instanceof THREE.MeshDepthMaterial)Ka=k.near,Ga=k.far,aa.r=aa.g=aa.b=1-ac(a.positionScreen.z,Ka,Ga),U.r=U.g=U.b=1-ac(d.positionScreen.z,Ka,Ga),ba.r=ba.g=ba.b=1-ac(e.positionScreen.z,Ka,Ga),ea.r=ea.g=ea.b=1-ac(f.positionScreen.z,Ka,Ga),qa=Dc(aa,U,ba,ea),v(K,O,y,l,E,S),gc(K,O,y,l,E,S,0,0,1,0,0,1,qa),v(R,ca,$,C,ka,ia),gc(R,ca,$,C,ka,ia,1,0,1,1,0,1,qa)}function v(a,b,c,d,f,e){n.beginPath();n.moveTo(a,b);n.lineTo(c,d);n.lineTo(f,e);n.lineTo(a,b);n.closePath()}function w(a,b,c,d,f,e,g,Z){n.beginPath(); -n.moveTo(a,b);n.lineTo(c,d);n.lineTo(f,e);n.lineTo(g,Z);n.lineTo(a,b);n.closePath()}function Mb(a,b,c,f){if(A!=b)n.lineWidth=A=b;if(F!=c)n.lineCap=F=c;if(B!=f)n.lineJoin=B=f;d(a.getContextStyle());n.stroke();za.inflate(2*b)}function Gb(a){f(a.getContextStyle());n.fill()}function Vc(a,b,c,d,e,g,Z,h,l,i,j,T,k){if(0!=k.image.width){if(!0==k.needsUpdate||void 0==Ta[k.id]){var m=k.wrapS==THREE.RepeatWrapping,o=k.wrapT==THREE.RepeatWrapping;Ta[k.id]=n.createPattern(k.image,m&&o?"repeat":m&&!o?"repeat-x": -!m&&o?"repeat-y":"no-repeat");k.needsUpdate=!1}f(Ta[k.id]);var m=k.offset.x/k.repeat.x,o=k.offset.y/k.repeat.y,p=k.image.width*k.repeat.x,Fb=k.image.height*k.repeat.y,Z=(Z+m)*p,h=(h+o)*Fb,c=c-a,d=d-b,e=e-a,g=g-b,l=(l+m)*p-Z,i=(i+o)*Fb-h,j=(j+m)*p-Z,T=(T+o)*Fb-h,m=l*T-j*i;if(0==m){if(void 0===Ja[k.id])b=document.createElement("canvas"),b.width=k.image.width,b.height=k.image.height,b=b.getContext("2d"),b.drawImage(k.image,0,0),Ja[k.id]=b.getImageData(0,0,k.image.width,k.image.height).data;b=Ja[k.id]; -Z=4*(Math.floor(Z)+Math.floor(h)*k.image.width);N.setRGB(b[Z]/255,b[Z+1]/255,b[Z+2]/255);Gb(N)}else m=1/m,k=(T*c-i*e)*m,i=(T*d-i*g)*m,c=(l*e-j*c)*m,d=(l*g-j*d)*m,a=a-k*Z-c*h,Z=b-i*Z-d*h,n.save(),n.transform(k,i,c,d,a,Z),n.fill(),n.restore()}}function gc(a,b,c,d,f,e,g,Z,h,l,i,j,T){var k,m;k=T.width-1;m=T.height-1;g*=k;Z*=m;c-=a;d-=b;f-=a;e-=b;h=h*k-g;l=l*m-Z;i=i*k-g;j=j*m-Z;m=1/(h*j-i*l);k=(j*c-l*f)*m;l=(j*d-l*e)*m;c=(h*f-i*c)*m;d=(h*e-i*d)*m;a=a-k*g-c*Z;b=b-l*g-d*Z;n.save();n.transform(k,l,c,d,a, -b);n.clip();n.drawImage(T,0,0);n.restore()}function Dc(a,b,c,d){var f=~~(255*a.r),e=~~(255*a.g),a=~~(255*a.b),g=~~(255*b.r),Z=~~(255*b.g),b=~~(255*b.b),h=~~(255*c.r),l=~~(255*c.g),c=~~(255*c.b),i=~~(255*d.r),j=~~(255*d.g),d=~~(255*d.b);eb[0]=0>f?0:255e?0:255a?0:255g?0:255Z?0:255b?0:255h?0:255l?0:255c?0:255i?0:255j?0:255d?0:255a?0:1=j||(j*=g.intensity,d.r+=h.r*j,d.g+=h.g*j,d.b+=h.b*j)):g instanceof THREE.PointLight&&(i=g.matrixWorld.getPosition(),j=c.dot(D.sub(i,b).normalize()),0>=j||(j*=0==g.distance?1:1-Math.min(b.distanceTo(i)/g.distance,1),0!=j&&(j*=g.intensity,d.r+=h.r*j,d.g+=h.g*j,d.b+=h.b*j)))}function b(a){null==H[a]&&(H[a]=document.createElementNS("http://www.w3.org/2000/svg", -"path"),0==K&&H[a].setAttribute("shape-rendering","crispEdges"));return H[a]}function c(a){a=0.5*(a+1);return 0>a?0:1 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif", -lights_lambert_vertex:"vLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\nvLightBack = vec3( 0.0 );\n#endif\ntransformedNormal = normalize( transformedNormal );\n#if MAX_DIR_LIGHTS > 0\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( transformedNormal, dirVector );\nvec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n#ifdef DOUBLE_SIDED\nvec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n#ifdef WRAP_AROUND\nvec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n#endif\n#endif\n#ifdef WRAP_AROUND\nvec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\ndirectionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n#ifdef DOUBLE_SIDED\ndirectionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n#endif\n#endif\nvLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n#ifdef DOUBLE_SIDED\nvLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n#endif\n}\n#endif\n#if MAX_POINT_LIGHTS > 0\nfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\nfloat dotProduct = dot( transformedNormal, lVector );\nvec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n#ifdef DOUBLE_SIDED\nvec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n#ifdef WRAP_AROUND\nvec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n#endif\n#endif\n#ifdef WRAP_AROUND\nvec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\npointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n#ifdef DOUBLE_SIDED\npointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n#endif\n#endif\nvLightFront += pointLightColor[ i ] * pointLightWeighting * lDistance;\n#ifdef DOUBLE_SIDED\nvLightBack += pointLightColor[ i ] * pointLightWeightingBack * lDistance;\n#endif\n}\n#endif\nvLightFront = vLightFront * diffuse + ambient * ambientLightColor;\n#ifdef DOUBLE_SIDED\nvLightBack = vLightBack * diffuse + ambient * ambientLightColor;\n#endif", -lights_phong_pars_vertex:"#if MAX_POINT_LIGHTS > 0\n#ifndef PHONG_PER_PIXEL\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\nvarying vec4 vPointLight[ MAX_POINT_LIGHTS ];\n#endif\n#endif",lights_phong_vertex:"#if MAX_POINT_LIGHTS > 0\n#ifndef PHONG_PER_PIXEL\nfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nvPointLight[ i ] = vec4( lVector, lDistance );\n}\n#endif\n#endif", -lights_phong_pars_fragment:"uniform vec3 ambientLightColor;\n#if MAX_DIR_LIGHTS > 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n#ifdef PHONG_PER_PIXEL\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n#else\nvarying vec4 vPointLight[ MAX_POINT_LIGHTS ];\n#endif\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif\nvarying vec3 vViewPosition;\nvarying vec3 vNormal;", -lights_phong_fragment:"vec3 normal = normalize( vNormal );\nvec3 viewPosition = normalize( vViewPosition );\n#ifdef DOUBLE_SIDED\nnormal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n#endif\n#if MAX_POINT_LIGHTS > 0\nvec3 pointDiffuse = vec3( 0.0 );\nvec3 pointSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n#ifdef PHONG_PER_PIXEL\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz + vViewPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\n#else\nvec3 lVector = normalize( vPointLight[ i ].xyz );\nfloat lDistance = vPointLight[ i ].w;\n#endif\nfloat dotProduct = dot( normal, lVector );\n#ifdef WRAP_AROUND\nfloat pointDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n#else\nfloat pointDiffuseWeight = max( dotProduct, 0.0 );\n#endif\npointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;\nvec3 pointHalfVector = normalize( lVector + viewPosition );\nfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\nfloat pointSpecularWeight = max( pow( pointDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( dot( lVector, pointHalfVector ), 5.0 );\npointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance;\n#else\npointSpecular += specular * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance;\n#endif\n}\n#endif\n#if MAX_DIR_LIGHTS > 0\nvec3 dirDiffuse = vec3( 0.0 );\nvec3 dirSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( normal, dirVector );\n#ifdef WRAP_AROUND\nfloat dirDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n#else\nfloat dirDiffuseWeight = max( dotProduct, 0.0 );\n#endif\ndirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\nvec3 dirHalfVector = normalize( dirVector + viewPosition );\nfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\nfloat dirSpecularWeight = max( pow( dirDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( dot( dirVector, dirHalfVector ), 5.0 );\ndirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight;\n#else\ndirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight;\n#endif\n}\n#endif\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n#if MAX_DIR_LIGHTS > 0\ntotalDiffuse += dirDiffuse;\ntotalSpecular += dirSpecular;\n#endif\n#if MAX_POINT_LIGHTS > 0\ntotalDiffuse += pointDiffuse;\ntotalSpecular += pointSpecular;\n#endif\n#ifdef METAL\ngl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient + totalSpecular );\n#else\ngl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * ambient ) + totalSpecular;\n#endif", -color_pars_fragment:"#ifdef USE_COLOR\nvarying vec3 vColor;\n#endif",color_fragment:"#ifdef USE_COLOR\ngl_FragColor = gl_FragColor * vec4( vColor, opacity );\n#endif",color_pars_vertex:"#ifdef USE_COLOR\nvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n#ifdef GAMMA_INPUT\nvColor = color * color;\n#else\nvColor = color;\n#endif\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\nuniform mat4 boneGlobalMatrices[ MAX_BONES ];\n#endif",skinning_vertex:"#ifdef USE_SKINNING\ngl_Position = ( boneGlobalMatrices[ int( skinIndex.x ) ] * skinVertexA ) * skinWeight.x;\ngl_Position += ( boneGlobalMatrices[ int( skinIndex.y ) ] * skinVertexB ) * skinWeight.y;\ngl_Position = projectionMatrix * modelViewMatrix * gl_Position;\n#endif", -morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n#ifndef USE_MORPHNORMALS\nuniform float morphTargetInfluences[ 8 ];\n#else\nuniform float morphTargetInfluences[ 4 ];\n#endif\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\nvec3 morphed = vec3( 0.0 );\nmorphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\nmorphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\nmorphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\nmorphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n#ifndef USE_MORPHNORMALS\nmorphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\nmorphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\nmorphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\nmorphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n#endif\nmorphed += position;\ngl_Position = projectionMatrix * modelViewMatrix * vec4( morphed, 1.0 );\n#endif", -default_vertex:"#ifndef USE_MORPHTARGETS\n#ifndef USE_SKINNING\ngl_Position = projectionMatrix * mvPosition;\n#endif\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\nvec3 morphedNormal = vec3( 0.0 );\nmorphedNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\nmorphedNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\nmorphedNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\nmorphedNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\nmorphedNormal += normal;\nvec3 transformedNormal = normalMatrix * morphedNormal;\n#else\nvec3 transformedNormal = normalMatrix * normal;\n#endif", -shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\nuniform sampler2D shadowMap[ MAX_SHADOWS ];\nuniform vec2 shadowMapSize[ MAX_SHADOWS ];\nuniform float shadowDarkness[ MAX_SHADOWS ];\nuniform float shadowBias[ MAX_SHADOWS ];\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nfloat unpackDepth( const in vec4 rgba_depth ) {\nconst vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\nfloat depth = dot( rgba_depth, bit_shift );\nreturn depth;\n}\n#endif",shadowmap_fragment:"#ifdef USE_SHADOWMAP\n#ifdef SHADOWMAP_DEBUG\nvec3 frustumColors[3];\nfrustumColors[0] = vec3( 1.0, 0.5, 0.0 );\nfrustumColors[1] = vec3( 0.0, 1.0, 0.8 );\nfrustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n#endif\n#ifdef SHADOWMAP_CASCADE\nint inFrustumCount = 0;\n#endif\nfloat fDepth;\nvec3 shadowColor = vec3( 1.0 );\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\nbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\nbool inFrustum = all( inFrustumVec );\n#ifdef SHADOWMAP_CASCADE\ninFrustumCount += int( inFrustum );\nbvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n#else\nbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n#endif\nbool frustumTest = all( frustumTestVec );\nif ( frustumTest ) {\nshadowCoord.z += shadowBias[ i ];\n#ifdef SHADOWMAP_SOFT\nfloat shadow = 0.0;\nconst float shadowDelta = 1.0 / 9.0;\nfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\nfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\nfloat dx0 = -1.25 * xPixelOffset;\nfloat dy0 = -1.25 * yPixelOffset;\nfloat dx1 = 1.25 * xPixelOffset;\nfloat dy1 = 1.25 * yPixelOffset;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n#else\nvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n#endif\n}\n#ifdef SHADOWMAP_DEBUG\n#ifdef SHADOWMAP_CASCADE\nif ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];\n#else\nif ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];\n#endif\n#endif\n}\n#ifdef GAMMA_OUTPUT\nshadowColor *= shadowColor;\n#endif\ngl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n#endif", -shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nuniform mat4 shadowMatrix[ MAX_SHADOWS ];\n#endif",shadowmap_vertex:"#ifdef USE_SHADOWMAP\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\n#ifdef USE_MORPHTARGETS\nvShadowCoord[ i ] = shadowMatrix[ i ] * objectMatrix * vec4( morphed, 1.0 );\n#else\nvShadowCoord[ i ] = shadowMatrix[ i ] * objectMatrix * vec4( position, 1.0 );\n#endif\n}\n#endif",alphatest_fragment:"#ifdef ALPHATEST\nif ( gl_FragColor.a < ALPHATEST ) discard;\n#endif", -linear_to_gamma_fragment:"#ifdef GAMMA_OUTPUT\ngl_FragColor.xyz = sqrt( gl_FragColor.xyz );\n#endif"}; -THREE.UniformsUtils={merge:function(a){var b,c,d,f={};for(b=0;bn;n++){m=k;r=n;if(y.autoScaleCubemaps){if(s=h.image[n],E=Ea,!(s.width<=E&&s.height<=E))u=Math.max(s.width, -s.height),t=Math.floor(s.width*E/u),E=Math.floor(s.height*E/u),u=document.createElement("canvas"),u.width=t,u.height=E,u.getContext("2d").drawImage(s,0,0,s.width,s.height,0,0,t,E),s=u}else s=h.image[n];m[r]=s}n=k[0];m=0===(n.width&n.width-1)&&0===(n.height&n.height-1);r=A(h.format);s=A(h.type);w(l.TEXTURE_CUBE_MAP,h,m);for(n=0;6>n;n++)l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+n,0,r,r,s,k[n]);h.generateMipmaps&&m&&l.generateMipmap(l.TEXTURE_CUBE_MAP);h.needsUpdate=!1;if(h.onUpdate)h.onUpdate()}else l.activeTexture(l.TEXTURE0+ -k),l.bindTexture(l.TEXTURE_CUBE_MAP,h.image.__webglTextureCube)}else n instanceof THREE.WebGLRenderTargetCube?(h=n,l.activeTexture(l.TEXTURE0+k),l.bindTexture(l.TEXTURE_CUBE_MAP,h.__webglTexture)):y.setTexture(n,k)}else if("tv"===m){if(!h._array){h._array=[];for(m=0,r=h.texture.length;mj&&(k=m,j=h[k]);l.bindBuffer(l.ARRAY_BUFFER,f.__webglMorphTargetsBuffers[k]);l.vertexAttribPointer(c["morphTarget"+g],3,l.FLOAT,!1,0,0);d.morphNormals&&(l.bindBuffer(l.ARRAY_BUFFER,f.__webglMorphNormalsBuffers[k]),l.vertexAttribPointer(c["morphNormal"+ -g],3,l.FLOAT,!1,0,0));e.__webglMorphTargetInfluences[g]=j;i[k]=1;j=-1;g++}}null!==d.program.uniforms.morphTargetInfluences&&l.uniform1fv(d.program.uniforms.morphTargetInfluences,e.__webglMorphTargetInfluences)}if(a){if(f.__webglCustomAttributesList)for(g=0,h=f.__webglCustomAttributesList.length;gla;la++)Vb=jc[la],hb[Ra]=Vb.x,hb[Ra+1]=Vb.y,hb[Ra+2]=Vb.z,Ra+=3;else for(la=0;3>la;la++)hb[Ra]=Ob.x,hb[Ra+1]=Ob.y,hb[Ra+2]=Ob.z,Ra+=3;for(G=0,V=na.length;Gla;la++)Vb=jc[la], -hb[Ra]=Vb.x,hb[Ra+1]=Vb.y,hb[Ra+2]=Vb.z,Ra+=3;else for(la=0;4>la;la++)hb[Ra]=Ob.x,hb[Ra+1]=Ob.y,hb[Ra+2]=Ob.z,Ra+=3;l.bindBuffer(l.ARRAY_BUFFER,fa.__webglNormalBuffer);l.bufferData(l.ARRAY_BUFFER,hb,$a)}if(kd&&bd&&hd){for(G=0,V=ma.length;Gla;la++)mc=kc[la],wc[Jb]=mc.u,wc[Jb+1]=mc.v,Jb+=2;for(G=0,V=na.length;Gla;la++)mc=kc[la],wc[Jb]=mc.u,wc[Jb+1]=mc.v,Jb+=2;0la;la++)nc=lc[la],xc[Kb]=nc.u,xc[Kb+1]=nc.v,Kb+=2;for(G=0,V=na.length;Gla;la++)nc=lc[la],xc[Kb]=nc.u,xc[Kb+1]=nc.v,Kb+=2;0c;c++){a.__webglFramebuffer[c]=l.createFramebuffer();a.__webglRenderbuffer[c]=l.createRenderbuffer();l.texImage2D(l.TEXTURE_CUBE_MAP_POSITIVE_X+c,0,d,a.width,a.height,0,d,f,null);var e=a,g=l.TEXTURE_CUBE_MAP_POSITIVE_X+c;l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer[c]);l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,g,e.__webglTexture,0);u(a.__webglRenderbuffer[c],a)}}else a.__webglFramebuffer=l.createFramebuffer(),a.__webglRenderbuffer= -l.createRenderbuffer(),l.bindTexture(l.TEXTURE_2D,a.__webglTexture),w(l.TEXTURE_2D,a,c),l.texImage2D(l.TEXTURE_2D,0,d,a.width,a.height,0,d,f,null),d=l.TEXTURE_2D,l.bindFramebuffer(l.FRAMEBUFFER,a.__webglFramebuffer),l.framebufferTexture2D(l.FRAMEBUFFER,l.COLOR_ATTACHMENT0,d,a.__webglTexture,0),u(a.__webglRenderbuffer,a);b?l.bindTexture(l.TEXTURE_CUBE_MAP,null):l.bindTexture(l.TEXTURE_2D,null);l.bindRenderbuffer(l.RENDERBUFFER,null);l.bindFramebuffer(l.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]: -a.__webglFramebuffer,d=a.width,a=a.height,c=f=0):(b=null,d=ha,a=ib,f=Ga,c=qa);b!==E&&(l.bindFramebuffer(l.FRAMEBUFFER,b),l.viewport(f,c,d,a),E=b);db=d;lb=a};this.shadowMapPlugin=new THREE.ShadowMapPlugin;this.addPrePlugin(this.shadowMapPlugin);this.addPostPlugin(new THREE.SpritePlugin);this.addPostPlugin(new THREE.LensFlarePlugin)}; -THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format:THREE.RGBAFormat;this.type=void 0!==c.type?c.type: -THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0}; -THREE.WebGLRenderTarget.prototype.clone=function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;return a};THREE.WebGLRenderTargetCube=function(a,b,c){THREE.WebGLRenderTarget.call(this,a,b,c);this.activeCubeFace=0}; -THREE.WebGLRenderTargetCube.prototype=new THREE.WebGLRenderTarget;THREE.WebGLRenderTargetCube.prototype.constructor=THREE.WebGLRenderTargetCube;THREE.RenderableVertex=function(){this.positionWorld=new THREE.Vector3;this.positionScreen=new THREE.Vector4;this.visible=!0};THREE.RenderableVertex.prototype.copy=function(a){this.positionWorld.copy(a.positionWorld);this.positionScreen.copy(a.positionScreen)}; -THREE.RenderableFace3=function(){this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.v3=new THREE.RenderableVertex;this.centroidWorld=new THREE.Vector3;this.centroidScreen=new THREE.Vector3;this.normalWorld=new THREE.Vector3;this.vertexNormalsWorld=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.faceMaterial=this.material=null;this.uvs=[[]];this.z=null}; -THREE.RenderableFace4=function(){this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.v3=new THREE.RenderableVertex;this.v4=new THREE.RenderableVertex;this.centroidWorld=new THREE.Vector3;this.centroidScreen=new THREE.Vector3;this.normalWorld=new THREE.Vector3;this.vertexNormalsWorld=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.faceMaterial=this.material=null;this.uvs=[[]];this.z=null};THREE.RenderableObject=function(){this.z=this.object=null}; -THREE.RenderableParticle=function(){this.rotation=this.z=this.y=this.x=null;this.scale=new THREE.Vector2;this.material=null};THREE.RenderableLine=function(){this.z=null;this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.material=null}; -THREE.ColorUtils={adjustHSV:function(a,b,c,d){var f=THREE.ColorUtils.__hsv;THREE.ColorUtils.rgbToHsv(a,f);f.h=THREE.Math.clamp(f.h+b,0,1);f.s=THREE.Math.clamp(f.s+c,0,1);f.v=THREE.Math.clamp(f.v+d,0,1);a.setHSV(f.h,f.s,f.v)},rgbToHsv:function(a,b){var c=a.r,d=a.g,f=a.b,g=Math.max(Math.max(c,d),f),e=Math.min(Math.min(c,d),f);if(e===g)e=c=0;else{var h=g-e,e=h/g,c=(c===g?(d-f)/h:d===g?2+(f-c)/h:4+(c-d)/h)/6;0>c&&(c+=1);1a?b(c,f-1):j[f]b||o>b||q>b){h=a.vertices.length;t=d.clone();d=d.clone();m>=o&&m>=q?(i=i.clone(),i.position.lerpSelf(j.position,0.5),t.a=f,t.b=h,t.c=e,d.a=h,d.b=g,d.c=e,f= -0):o>=m&&o>=q?(i=j.clone(),i.position.lerpSelf(k.position,0.5),t.a=f,t.b=g,t.c=h,d.a=h,d.b=e,d.c=f,f=1):(i=i.clone(),i.position.lerpSelf(k.position,0.5),t.a=f,t.b=g,t.c=h,d.a=h,d.b=g,d.c=e,f=2);a.faces.splice(c,1,t,d);a.vertices.push(i);for(g=0;gb||o>b||p>b||n>b){r=a.vertices.length;s=a.vertices.length+1;t=d.clone(); -d=d.clone();m>=o&&m>=p&&m>=n||p>=o&&p>=m&&p>=n?(m=i.clone(),m.position.lerpSelf(j.position,0.5),j=k.clone(),j.position.lerpSelf(q.position,0.5),t.a=f,t.b=r,t.c=s,t.d=h,d.a=r,d.b=g,d.c=e,d.d=s,f=0):(m=j.clone(),m.position.lerpSelf(k.position,0.5),j=q.clone(),j.position.lerpSelf(i.position,0.5),t.a=f,t.b=g,t.c=r,t.d=s,d.a=s,d.b=r,d.c=e,d.d=h,f=1);a.faces.splice(c,1,t,d);a.vertices.push(m);a.vertices.push(j);for(g=0;gq-1?f-1:q-1,o=(q+1)%f,p=0>k-1?d-1:k-1,n=(k+1)%d,r=[],s=[0,0,h[4*(q*d+k)]/255*b];r.push([-1,0,h[4*(q*d+p)]/255*b]);r.push([-1,-1,h[4*(m*d+p)]/255*b]);r.push([0,-1, -h[4*(m*d+k)]/255*b]);r.push([1,-1,h[4*(m*d+n)]/255*b]);r.push([1,0,h[4*(q*d+n)]/255*b]);r.push([1,1,h[4*(o*d+n)]/255*b]);r.push([0,1,h[4*(o*d+k)]/255*b]);r.push([-1,1,h[4*(o*d+p)]/255*b]);m=[];p=r.length;for(o=0;o 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\nvarying vec4 vPointLight[ MAX_POINT_LIGHTS ];\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif\nvarying vec3 vViewPosition;", -THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,"void main() {\ngl_FragColor = vec4( vec3( 1.0 ), uOpacity );\nvec3 specularTex = vec3( 1.0 );\nvec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;\nnormalTex.xy *= uNormalScale;\nnormalTex = normalize( normalTex );\nif( enableDiffuse ) {\n#ifdef GAMMA_INPUT\nvec4 texelColor = texture2D( tDiffuse, vUv );\ntexelColor.xyz *= texelColor.xyz;\ngl_FragColor = gl_FragColor * texelColor;\n#else\ngl_FragColor = gl_FragColor * texture2D( tDiffuse, vUv );\n#endif\n}\nif( enableAO ) {\n#ifdef GAMMA_INPUT\nvec4 aoColor = texture2D( tAO, vUv );\naoColor.xyz *= aoColor.xyz;\ngl_FragColor.xyz = gl_FragColor.xyz * aoColor.xyz;\n#else\ngl_FragColor.xyz = gl_FragColor.xyz * texture2D( tAO, vUv ).xyz;\n#endif\n}\nif( enableSpecular )\nspecularTex = texture2D( tSpecular, vUv ).xyz;\nmat3 tsb = mat3( normalize( vTangent ), normalize( vBinormal ), normalize( vNormal ) );\nvec3 finalNormal = tsb * normalTex;\nvec3 normal = normalize( finalNormal );\nvec3 viewPosition = normalize( vViewPosition );\n#if MAX_POINT_LIGHTS > 0\nvec3 pointDiffuse = vec3( 0.0 );\nvec3 pointSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\nvec3 pointVector = normalize( vPointLight[ i ].xyz );\nfloat pointDistance = vPointLight[ i ].w;\n#ifdef WRAP_AROUND\nfloat pointDiffuseWeightFull = max( dot( normal, pointVector ), 0.0 );\nfloat pointDiffuseWeightHalf = max( 0.5 * dot( normal, pointVector ) + 0.5, 0.0 );\nvec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n#else\nfloat pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );\n#endif\npointDiffuse += pointDistance * pointLightColor[ i ] * uDiffuseColor * pointDiffuseWeight;\nvec3 pointHalfVector = normalize( pointVector + viewPosition );\nfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\nfloat pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, uShininess ), 0.0 );\npointSpecular += pointDistance * pointLightColor[ i ] * uSpecularColor * pointSpecularWeight * pointDiffuseWeight;\n}\n#endif\n#if MAX_DIR_LIGHTS > 0\nvec3 dirDiffuse = vec3( 0.0 );\nvec3 dirSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\n#ifdef WRAP_AROUND\nfloat directionalLightWeightingFull = max( dot( normal, dirVector ), 0.0 );\nfloat directionalLightWeightingHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );\nvec3 dirDiffuseWeight = mix( vec3( directionalLightWeightingFull ), vec3( directionalLightWeightingHalf ), wrapRGB );\n#else\nfloat dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );\n#endif\ndirDiffuse += directionalLightColor[ i ] * uDiffuseColor * dirDiffuseWeight;\nvec3 dirHalfVector = normalize( dirVector + viewPosition );\nfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\nfloat dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, uShininess ), 0.0 );\ndirSpecular += directionalLightColor[ i ] * uSpecularColor * dirSpecularWeight * dirDiffuseWeight;\n}\n#endif\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n#if MAX_DIR_LIGHTS > 0\ntotalDiffuse += dirDiffuse;\ntotalSpecular += dirSpecular;\n#endif\n#if MAX_POINT_LIGHTS > 0\ntotalDiffuse += pointDiffuse;\ntotalSpecular += pointSpecular;\n#endif\ngl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor) + totalSpecular;\nif ( enableReflection ) {\nvec3 wPos = cameraPosition - vViewPosition;\nvec3 vReflect = reflect( normalize( wPos ), normal );\nvec4 cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );\n#ifdef GAMMA_INPUT\ncubeColor.xyz *= cubeColor.xyz;\n#endif\ngl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularTex.r * uReflectivity );\n}", -THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n"),vertexShader:["attribute vec4 tangent;\nuniform vec2 uOffset;\nuniform vec2 uRepeat;\n#ifdef VERTEX_TEXTURES\nuniform sampler2D tDisplacement;\nuniform float uDisplacementScale;\nuniform float uDisplacementBias;\n#endif\nvarying vec3 vTangent;\nvarying vec3 vBinormal;\nvarying vec3 vNormal;\nvarying vec2 vUv;\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\nvarying vec4 vPointLight[ MAX_POINT_LIGHTS ];\n#endif\nvarying vec3 vViewPosition;", -THREE.ShaderChunk.shadowmap_pars_vertex,"void main() {\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\nvViewPosition = -mvPosition.xyz;\nvNormal = normalMatrix * normal;\nvTangent = normalMatrix * tangent.xyz;\nvBinormal = cross( vNormal, vTangent ) * tangent.w;\nvUv = uv * uRepeat + uOffset;\n#if MAX_POINT_LIGHTS > 0\nfor( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\nvPointLight[ i ] = vec4( lVector, lDistance );\n}\n#endif\n#ifdef VERTEX_TEXTURES\nvec3 dv = texture2D( tDisplacement, uv ).xyz;\nfloat df = uDisplacementScale * dv.x + uDisplacementBias;\nvec4 displacedPosition = vec4( normalize( vNormal.xyz ) * df, 0.0 ) + mvPosition;\ngl_Position = projectionMatrix * displacedPosition;\n#else\ngl_Position = projectionMatrix * mvPosition;\n#endif", -THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n")},cube:{uniforms:{tCube:{type:"t",value:1,texture:null},tFlip:{type:"f",value:-1}},vertexShader:"varying vec3 vViewPosition;\nvoid main() {\nvec4 mPosition = objectMatrix * vec4( position, 1.0 );\nvViewPosition = cameraPosition - mPosition.xyz;\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vViewPosition;\nvoid main() {\nvec3 wPos = cameraPosition - vViewPosition;\ngl_FragColor = textureCube( tCube, vec3( tFlip * wPos.x, wPos.yz ) );\n}"}}}; -THREE.BufferGeometry=function(){this.id=THREE.GeometryCount++;this.vertexColorArray=this.vertexUvArray=this.vertexNormalArray=this.vertexPositionArray=this.vertexIndexArray=this.vertexColorBuffer=this.vertexUvBuffer=this.vertexNormalBuffer=this.vertexPositionBuffer=this.vertexIndexBuffer=null;this.dynamic=!1;this.boundingSphere=this.boundingBox=null;this.morphTargets=[]};THREE.BufferGeometry.prototype={constructor:THREE.BufferGeometry,computeBoundingBox:function(){},computeBoundingSphere:function(){}}; -THREE.Curve=function(){};THREE.Curve.prototype.getPoint=function(){console.log("Warning, getPoint() not implemented!");return null};THREE.Curve.prototype.getPointAt=function(a){return this.getPoint(this.getUtoTmapping(a))};THREE.Curve.prototype.getPoints=function(a){a||(a=5);var b,c=[];for(b=0;b<=a;b++)c.push(this.getPoint(b/a));return c};THREE.Curve.prototype.getSpacedPoints=function(a){a||(a=5);var b,c=[];for(b=0;b<=a;b++)c.push(this.getPointAt(b/a));return c}; -THREE.Curve.prototype.getLength=function(){var a=this.getLengths();return a[a.length-1]};THREE.Curve.prototype.getLengths=function(a){a||(a=200);if(this.cacheArcLengths&&this.cacheArcLengths.length==a+1)return this.cacheArcLengths;var b=[],c,d=this.getPoint(0),f,g=0;b.push(0);for(f=1;f<=a;f++)c=this.getPoint(f/a),g+=c.distanceTo(d),b.push(g),d=c;return this.cacheArcLengths=b}; -THREE.Curve.prototype.getUtoTmapping=function(a,b){var c=this.getLengths(),d=0,f=c.length,g;g=b?b:a*c[f-1];for(var e=0,h=f-1,i;e<=h;)if(d=Math.floor(e+(h-e)/2),i=c[d]-g,0>i)e=d+1;else if(0b&&(b=0);1d.length-2?a:a+1;c[3]=a>d.length-3?a:a+2;b.x=THREE.Curve.Utils.interpolate(d[c[0]].x,d[c[1]].x,d[c[2]].x,d[c[3]].x,f);b.y=THREE.Curve.Utils.interpolate(d[c[0]].y,d[c[1]].y,d[c[2]].y,d[c[3]].y,f);return b};THREE.ArcCurve=function(a,b,c,d,f,g){this.aX=a;this.aY=b;this.aRadius=c;this.aStartAngle=d;this.aEndAngle=f;this.aClockwise=g}; -THREE.ArcCurve.prototype=new THREE.Curve;THREE.ArcCurve.prototype.constructor=THREE.ArcCurve;THREE.ArcCurve.prototype.getPoint=function(a){var b=this.aEndAngle-this.aStartAngle;this.aClockwise||(a=1-a);b=this.aStartAngle+a*b;a=this.aX+this.aRadius*Math.cos(b);b=this.aY+this.aRadius*Math.sin(b);return new THREE.Vector2(a,b)}; -THREE.Curve.Utils={tangentQuadraticBezier:function(a,b,c,d){return 2*(1-a)*(c-b)+2*a*(d-c)},tangentCubicBezier:function(a,b,c,d,f){return-3*b*(1-a)*(1-a)+3*c*(1-a)*(1-a)-6*a*c*(1-a)+6*a*d*(1-a)-3*a*a*d+3*a*a*f},tangentSpline:function(a){return 6*a*a-6*a+(3*a*a-4*a+1)+(-6*a*a+6*a)+(3*a*a-2*a)},interpolate:function(a,b,c,d,f){var a=0.5*(c-a),d=0.5*(d-b),g=f*f;return(2*b-2*c+a+d)*f*g+(-3*b+3*c-2*a-d)*g+a*f+b}}; -THREE.Curve.create=function(a,b){a.prototype=new THREE.Curve;a.prototype.constructor=a;a.prototype.getPoint=b;return a};THREE.LineCurve3=THREE.Curve.create(function(a,b){this.v1=a;this.v2=b},function(a){var b=new THREE.Vector3;b.sub(this.v2,this.v1);b.multiplyScalar(a);b.addSelf(this.v1);return b}); -THREE.QuadraticBezierCurve3=THREE.Curve.create(function(a,b,c){this.v0=a;this.v1=b;this.v2=c},function(a){var b,c;b=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);c=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);a=THREE.Shape.Utils.b2(a,this.v0.z,this.v1.z,this.v2.z);return new THREE.Vector3(b,c,a)}); -THREE.CubicBezierCurve3=THREE.Curve.create(function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d},function(a){var b,c;b=THREE.Shape.Utils.b3(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);c=THREE.Shape.Utils.b3(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);a=THREE.Shape.Utils.b3(a,this.v0.z,this.v1.z,this.v2.z,this.v3.z);return new THREE.Vector3(b,c,a)}); -THREE.SplineCurve3=THREE.Curve.create(function(a){this.points=void 0==a?[]:a},function(a){var b=new THREE.Vector3,c=[],d=this.points,f;f=(d.length-1)*a;a=Math.floor(f);f-=a;c[0]=0==a?a:a-1;c[1]=a;c[2]=a>d.length-2?a:a+1;c[3]=a>d.length-3?a:a+2;b.x=THREE.Curve.Utils.interpolate(d[c[0]].x,d[c[1]].x,d[c[2]].x,d[c[3]].x,f);b.y=THREE.Curve.Utils.interpolate(d[c[0]].y,d[c[1]].y,d[c[2]].y,d[c[3]].y,f);b.z=THREE.Curve.Utils.interpolate(d[c[0]].z,d[c[1]].z,d[c[2]].z,d[c[3]].z,f);return b}); -THREE.CurvePath=function(){this.curves=[];this.bends=[];this.autoClose=!1};THREE.CurvePath.prototype=new THREE.Curve;THREE.CurvePath.prototype.constructor=THREE.CurvePath;THREE.CurvePath.prototype.add=function(a){this.curves.push(a)};THREE.CurvePath.prototype.checkConnection=function(){};THREE.CurvePath.prototype.closePath=function(){var a=this.curves[0].getPoint(0),b=this.curves[this.curves.length-1].getPoint(1);a.equals(b)||this.curves.push(new THREE.LineCurve(b,a))}; -THREE.CurvePath.prototype.getPoint=function(a){for(var b=a*this.getLength(),c=this.getCurveLengths(),a=0;a=b)return b=c[a]-b,a=this.curves[a],b=1-b/a.getLength(),a.getPointAt(b);a++}return null};THREE.CurvePath.prototype.getLength=function(){var a=this.getCurveLengths();return a[a.length-1]}; -THREE.CurvePath.prototype.getCurveLengths=function(){if(this.cacheLengths&&this.cacheLengths.length==this.curves.length)return this.cacheLengths;var a=[],b=0,c,d=this.curves.length;for(c=0;cb)b=g.x;else if(g.xc)c=g.y;else if(g.y -h&&(h+=c.length);h%=c.length;0>e&&(e+=j.length);e%=j.length;f=0<=h-1?h-1:c.length-1;g=0<=e-1?e-1:j.length-1;n=[j[e],c[h],c[f]];n=THREE.FontUtils.Triangulate.area(n);r=[j[e],j[g],c[h]];r=THREE.FontUtils.Triangulate.area(r);q+m>n+r&&(h=o,e=k,0>h&&(h+=c.length),h%=c.length,0>e&&(e+=j.length),e%=j.length,f=0<=h-1?h-1:c.length-1,g=0<=e-1?e-1:j.length-1);q=c.slice(0,h);m=c.slice(h);o=j.slice(e);k=j.slice(0,e);g=[j[e],j[g],c[h]];p.push([j[e],c[h],c[f]]);p.push(g);c=q.concat(o).concat(k).concat(m)}return{shape:c, -isolatedPts:p,allpoints:d}},triangulateShape:function(a,b){var c=THREE.Shape.Utils.removeHoles(a,b),d=c.allpoints,f=c.isolatedPts,c=THREE.FontUtils.Triangulate(c.shape,!1),g,e,h,i,j={};for(g=0,e=d.length;gd;d++)i=h[d].x+":"+h[d].y,i=j[i],void 0!==i&&(h[d]=i)}for(g=0,e=f.length;gd;d++)i=h[d].x+":"+h[d].y,i=j[i],void 0!==i&&(h[d]=i)}return c.concat(f)}, -isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a*a*a*b},b3:function(a,b,c,d,f){return this.b3p0(a,b)+this.b3p1(a,c)+this.b3p2(a,d)+ -this.b3p3(a,f)}};THREE.TextPath=function(a,b){THREE.Path.call(this);this.parameters=b||{};this.set(a)};THREE.TextPath.prototype.set=function(a,b){b=b||this.parameters;this.text=a;var c=void 0!==b.curveSegments?b.curveSegments:4,d=void 0!==b.font?b.font:"helvetiker",f=void 0!==b.weight?b.weight:"normal",g=void 0!==b.style?b.style:"normal";THREE.FontUtils.size=void 0!==b.size?b.size:100;THREE.FontUtils.divisions=c;THREE.FontUtils.face=d;THREE.FontUtils.weight=f;THREE.FontUtils.style=g}; -THREE.TextPath.prototype.toShapes=function(){for(var a=THREE.FontUtils.drawText(this.text).paths,b=[],c=0,d=a.length;ca.hierarchy[c].keys[d].time)a.hierarchy[c].keys[d].time= -0;if(void 0!==a.hierarchy[c].keys[d].rot&&!(a.hierarchy[c].keys[d].rot instanceof THREE.Quaternion)){var h=a.hierarchy[c].keys[d].rot;a.hierarchy[c].keys[d].rot=new THREE.Quaternion(h[0],h[1],h[2],h[3])}}if(a.hierarchy[c].keys.length&&void 0!==a.hierarchy[c].keys[0].morphTargets){h={};for(d=0;dn;n++){c=b[n];e=i.prevKey[c];h=i.nextKey[c];if(h.time<=m){if(qd||1d?0:1;if("pos"===c)if(c=a.position,this.interpolationType===THREE.AnimationHandler.LINEAR)c.x=f[0]+(g[0]-f[0])*d,c.y=f[1]+(g[1]-f[1])*d,c.z=f[2]+(g[2]-f[2])*d;else{if(this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD)if(this.points[0]= -this.getPrevKeyWith("pos",o,e.index-1).pos,this.points[1]=f,this.points[2]=g,this.points[3]=this.getNextKeyWith("pos",o,h.index+1).pos,d=0.33*d+0.33,f=this.interpolateCatmullRom(this.points,d),c.x=f[0],c.y=f[1],c.z=f[2],this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD)d=this.interpolateCatmullRom(this.points,1.01*d),this.target.set(d[0],d[1],d[2]),this.target.subSelf(c),this.target.y=0,this.target.normalize(),d=Math.atan2(this.target.x,this.target.z),a.rotation.set(0,d,0)}else if("rot"=== -c)THREE.Quaternion.slerp(f,g,a.quaternion,d);else if("scl"===c)c=a.scale,c.x=f[0]+(g[0]-f[0])*d,c.y=f[1]+(g[1]-f[1])*d,c.z=f[2]+(g[2]-f[2])*d}}if(this.JITCompile&&void 0===k[0][j]){this.hierarchy[0].updateMatrixWorld(!0);for(o=0;oa.length-2?g:g+1;c[3]=g>a.length-3?g:g+2;g=a[c[0]];h=a[c[1]];i=a[c[2]];j=a[c[3]];c=f*f;e=f*c;d[0]=this.interpolate(g[0],h[0],i[0],j[0],f,c,e);d[1]=this.interpolate(g[1],h[1],i[1],j[1],f,c,e);d[2]=this.interpolate(g[2],h[2],i[2],j[2],f,c,e);return d}; -THREE.Animation.prototype.interpolate=function(a,b,c,d,f,g,e){a=0.5*(c-a);d=0.5*(d-b);return(2*(b-c)+a+d)*e+(-3*(b-c)-2*a-d)*g+a*f+b};THREE.Animation.prototype.getNextKeyWith=function(a,b,c){for(var d=this.data.hierarchy[b].keys,c=this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD?c=e?b.interpolate(c,e):b.interpolate(c,c.time)}this.data.hierarchy[a].node.updateMatrix();d.matrixWorldNeedsUpdate=!0}}if(this.JITCompile&&void 0===g[0][f]){this.hierarchy[0].updateMatrixWorld(!0);for(a=0;a(a*=2)?0.5*a*a:-0.5*(--a*(a-2)-1)}function d(a,b){return function(){b.apply(a,arguments)}}function f(a,b,c,d){var f={name:c,fps:0.6,length:d,hierarchy:[]},e,g=b.getControlPointsArray(),h=b.getLength(),r=g.length,s=0;e=r-1;b={parent:-1,keys:[]};b.keys[0]={time:0,pos:g[0],rot:[0,0,0,1],scl:[1,1,1]};b.keys[e]={time:d,pos:g[e],rot:[0,0,0,1],scl:[1,1,1]};for(e=1;ei)?1:i));this.object.translateX(b*j);this.object.translateY(b*k);e&&(this.roll+=this.rollSpeed*a*h);if(this.forward.y>this.constrainVertical[1])this.forward.y=this.constrainVertical[1],this.forward.normalize();else if(this.forward.yc.maxDistance*c.maxDistance&&c.object.position.setLength(c.maxDistance),e.lengthSq()o;o++)this.materials.push(e)}o=0;r=1;p=2;s= -3;n=4;t=5}else this.materials=[];this.sides={px:!0,nx:!0,py:!0,ny:!0,pz:!0,nz:!0};if(void 0!=h)for(var w in h)void 0!==this.sides[w]&&(this.sides[w]=h[w]);this.sides.px&&i("z","y",-1,-1,c,b,k,o);this.sides.nx&&i("z","y",1,-1,c,b,-k,r);this.sides.py&&i("x","z",1,1,a,c,q,p);this.sides.ny&&i("x","z",1,-1,a,c,-q,s);this.sides.pz&&i("x","y",1,-1,a,b,m,n);this.sides.nz&&i("x","y",-1,-1,a,b,-m,t);this.computeCentroids();this.mergeVertices()};THREE.CubeGeometry.prototype=new THREE.Geometry; -THREE.CubeGeometry.prototype.constructor=THREE.CubeGeometry; -THREE.CylinderGeometry=function(a,b,c,d,f,g){THREE.Geometry.call(this);var a=void 0!==a?a:20,b=void 0!==b?b:20,c=void 0!==c?c:100,e=c/2,d=d||8,f=f||1,h,i,j=[],k=[];for(i=0;i<=f;i++){var q=[],m=[],o=i/f,p=o*(b-a)+a;for(h=0;h<=d;h++){var n=h/d,r=p*Math.sin(2*n*Math.PI),s=-o*c+e,t=p*Math.cos(2*n*Math.PI);this.vertices.push(new THREE.Vertex(new THREE.Vector3(r,s,t)));q.push(this.vertices.length-1);m.push(new THREE.UV(n,o))}j.push(q);k.push(m)}for(i=0;ig?(b=Math.atan2(b.y-a.y,b.x-a.x),a=Math.atan2(c.y-a.y,c.x-a.x),b>a&&(a+=2*Math.PI),c=(b+a)/2,a=-Math.cos(c),c=-Math.sin(c),new THREE.Vector2(a,c)):d.multiplyScalar(g).addSelf(h).subSelf(a).clone()}function f(a){for(y=a.length;0<=--y;){$=y;C=y-1;0>C&&(C=a.length-1);for(var b= -0,c=o+2*k,b=0;bMath.abs(d-l)? -B.faceVertexUvs[0].push([new THREE.UV(f,e),new THREE.UV(j,g),new THREE.UV(m,h),new THREE.UV(q,i)]):B.faceVertexUvs[0].push([new THREE.UV(d,e),new THREE.UV(l,g),new THREE.UV(n,h),new THREE.UV(p,i)])}}}function g(a,b,c){B.vertices.push(new THREE.Vertex(new THREE.Vector3(a,b,c)))}function e(a,b,c){a+=D;b+=D;c+=D;B.faces.push(new THREE.Face3(a,b,c,null,null,w));var d=B.vertices[b].position.x,b=B.vertices[b].position.y,f=B.vertices[c].position.x,c=B.vertices[c].position.y;B.faceVertexUvs[0].push([new THREE.UV(B.vertices[a].position.x, -1-B.vertices[a].position.y),new THREE.UV(d,1-b),new THREE.UV(f,1-c)])}var h=void 0!==b.amount?b.amount:100,i=void 0!==b.bevelThickness?b.bevelThickness:6,j=void 0!==b.bevelSize?b.bevelSize:i-2,k=void 0!==b.bevelSegments?b.bevelSegments:3,q=void 0!==b.bevelEnabled?b.bevelEnabled:!0,m=void 0!==b.curveSegments?b.curveSegments:12,o=void 0!==b.steps?b.steps:1,p=b.bendPath,n=b.extrudePath,r,s=!1,t=void 0!==b.useSpacedPoints?b.useSpacedPoints:!1,w=b.material,u=b.extrudeMaterial;if(n)r=n.getPoints(m),o=r.length, -s=!0,q=!1;q||(j=i=k=0);var v,A,F,B=this,D=this.vertices.length;p&&a.addWrapPath(p);m=t?a.extractAllSpacedPoints(m):a.extractAllPoints(m);p=m.shape;m=m.holes;if(n=!THREE.Shape.Utils.isClockWise(p)){p=p.reverse();for(A=0,F=m.length;Af)return null;var g=[],e=[],h=[],i,j,k;if(0=q--){console.log("Warning, unable to triangulate polygon!");break}i=j;f<=i&&(i=0);j=i+1;f<=j&&(j=0);k=j+1;f<=k&&(k=0);var m;a:{m=a;var o=i,p=j,n=k,r=f,s=e,t=void 0,w=void 0,u=void 0,v=void 0,A=void 0, -F=void 0,B=void 0,D=void 0,H=void 0,w=m[s[o]].x,u=m[s[o]].y,v=m[s[p]].x,A=m[s[p]].y,F=m[s[n]].x,B=m[s[n]].y;if(1.0E-10>(v-w)*(B-u)-(A-u)*(F-w))m=!1;else{for(t=0;td?(d=new THREE.Face3(a.index,b.index,c.index,[a.position.clone(),b.position.clone(),c.position.clone()]),d.centroid.addSelf(a.position).addSelf(b.position).addSelf(c.position).divideScalar(3),d.normal=d.centroid.clone().normalize(), -i.faces.push(d),d=Math.atan2(d.centroid.z,-d.centroid.x),i.faceVertexUvs[0].push([h(a.uv,a.position,d),h(b.uv,b.position,d),h(c.uv,c.position,d)])):(d-=1,g(a,e(a,b),e(a,c),d),g(e(a,b),b,e(b,c),d),g(e(a,c),e(b,c),c,d),g(e(a,b),e(b,c),e(a,c),d))}function e(a,b){q[a.index]||(q[a.index]=[]);q[b.index]||(q[b.index]=[]);var c=q[a.index][b.index];void 0===c&&(q[a.index][b.index]=q[b.index][a.index]=c=f((new THREE.Vector3).add(a.position,b.position).divideScalar(2)));return c}function h(a,b,c){0>c&&1===a.u&& -(a=new THREE.UV(a.u-1,a.v));0===b.x&&0===b.z&&(a=new THREE.UV(c/2/Math.PI+0.5,a.v));return a}THREE.Geometry.call(this);for(var c=c||1,d=d||0,i=this,j=0,k=a.length;jq;q++){o=i[q];k=new THREE.Color;k.setRGB(0,0,0);for(var p=0;pw.length&&(q[o]=!0)}for(o in p)if(w=p[o],s=w[0],w=w[1],v=o.split("_"),A=v[0],v=v[1],r=new THREE.Vector3,q[o]?(r.addSelf(h[A].position),r.addSelf(h[v].position),r.multiplyScalar(0.5)):(r.addSelf(j[s]),r.addSelf(j[w]),r.addSelf(h[A].position),r.addSelf(h[v].position),r.multiplyScalar(0.25)), -k[o]=t+d.length+u,i.push(new THREE.Vertex(r)),u++,e.supportUVs&&0!=m.length)w=new THREE.UV,w.u=m[A].u+m[v].u,w.v=m[A].v+m[v].v,w.u/=2,w.v/=2,m.push(w);var I,Q;v=["123","12","2","23"];r=["123","23","3","31"];var D=["123","31","1","12"],H=["1234","12","2","23"],P=["1234","23","3","34"],L=["1234","34","4","41"],K=["1234","41","1","12"];for(o=0,p=j.length;oa.length?".":a.join("/"))+"/"},initMaterials:function(a,b,c){a.materials=[];for(var d=0;da.opacity)j.transparent=a.transparent;if(void 0!==a.depthTest)j.depthTest=a.depthTest;if(void 0!==a.vertexColors)if("face"==a.vertexColors)j.vertexColors=THREE.FaceColors;else if(a.vertexColors)j.vertexColors= -THREE.VertexColors;if(a.colorDiffuse)j.color=e(a.colorDiffuse);else if(a.DbgColor)j.color=a.DbgColor;if(a.colorSpecular)j.specular=e(a.colorSpecular);if(a.colorAmbient)j.ambient=e(a.colorAmbient);if(a.transparency)j.opacity=a.transparency;if(a.specularCoef)j.shininess=a.specularCoef;a.mapDiffuse&&b&&g(j,"map",a.mapDiffuse,a.mapDiffuseRepeat,a.mapDiffuseOffset,a.mapDiffuseWrap);a.mapLight&&b&&g(j,"lightMap",a.mapLight,a.mapLightRepeat,a.mapLightOffset,a.mapLightWrap);a.mapNormal&&b&&g(j,"normalMap", -a.mapNormal,a.mapNormalRepeat,a.mapNormalOffset,a.mapNormalWrap);a.mapSpecular&&b&&g(j,"specularMap",a.mapSpecular,a.mapSpecularRepeat,a.mapSpecularOffset,a.mapSpecularWrap);if(a.mapNormal){var i=THREE.ShaderUtils.lib.normal,k=THREE.UniformsUtils.clone(i.uniforms);k.tNormal.texture=j.normalMap;if(a.mapNormalFactor)k.uNormalScale.value=a.mapNormalFactor;if(j.map)k.tDiffuse.texture=j.map,k.enableDiffuse.value=!0;if(j.specularMap)k.tSpecular.texture=j.specularMap,k.enableSpecular.value=!0;if(j.lightMap)k.tAO.texture= -j.lightMap,k.enableAO.value=!0;k.uDiffuseColor.value.setHex(j.color);k.uSpecularColor.value.setHex(j.specular);k.uAmbientColor.value.setHex(j.ambient);k.uShininess.value=j.shininess;if(void 0!==j.opacity)k.uOpacity.value=j.opacity;j=new THREE.ShaderMaterial({fragmentShader:i.fragmentShader,vertexShader:i.vertexShader,uniforms:k,lights:!0,fog:!0})}else j=new THREE[i](j);if(void 0!==a.DbgName)j.name=a.DbgName;return j}};THREE.BinaryLoader=function(a){THREE.Loader.call(this,a)}; -THREE.BinaryLoader.prototype=new THREE.Loader;THREE.BinaryLoader.prototype.constructor=THREE.BinaryLoader;THREE.BinaryLoader.prototype.supr=THREE.Loader.prototype;THREE.BinaryLoader.prototype.load=function(a,b,c,d){var c=c?c:this.extractUrlBase(a),d=d?d:this.extractUrlBase(a),f=this.showProgress?THREE.Loader.prototype.updateProgress:null;this.onLoadStart();this.loadAjaxJSON(this,a,b,c,d,f)}; -THREE.BinaryLoader.prototype.loadAjaxJSON=function(a,b,c,d,f,g){var e=new XMLHttpRequest;e.onreadystatechange=function(){if(4==e.readyState)if(200==e.status||0==e.status){var h=JSON.parse(e.responseText);a.loadAjaxBuffers(h,c,f,d,g)}else console.error("THREE.BinaryLoader: Couldn't load ["+b+"] ["+e.status+"]")};e.open("GET",b,!0);e.overrideMimeType&&e.overrideMimeType("text/plain; charset=x-user-defined");e.setRequestHeader("Content-Type","text/plain");e.send(null)}; -THREE.BinaryLoader.prototype.loadAjaxBuffers=function(a,b,c,d,f){var g=new XMLHttpRequest,e=c+"/"+a.buffers,h=0;g.onreadystatechange=function(){4==g.readyState?200==g.status||0==g.status?THREE.BinaryLoader.prototype.createBinModel(g.response,b,d,a.materials):console.error("THREE.BinaryLoader: Couldn't load ["+e+"] ["+g.status+"]"):3==g.readyState?f&&(0==h&&(h=g.getResponseHeader("Content-Length")),f({total:h,loaded:g.responseText.length})):2==g.readyState&&(h=g.getResponseHeader("Content-Length"))}; -g.open("GET",e,!0);g.responseType="arraybuffer";g.send(null)}; -THREE.BinaryLoader.prototype.createBinModel=function(a,b,c,d){var f=function(b){var c,f,i,j,k,q,m,o,p,n,r,s,t,w,u;function v(a){return a%4?4-a%4:0}function A(a,b){return(new Uint8Array(a,b,1))[0]}function F(a,b){return(new Uint32Array(a,b,1))[0]}function B(b,c){var d,e,f,g,h,i,j,k,l=new Uint32Array(a,c,3*b);for(d=0;da.length?".":a.join("/"))+"/");if((a=U.evaluate("//dae:asset",U,E,XPathResult.ORDERED_NODE_ITERATOR_TYPE,null).iterateNext())&&a.childNodes)for(f=0;fp)break}if(!s){s=new l(p);t=-1;u=0;for(v=d.length;u=p&&(t=u);p=t;d.splice(-1==p?d.length: -p,0,s)}s.addTarget(f,j,g,r)}}else console.log('Could not find transform "'+b.sid+'" in node '+this.id)}for(c=0;cthis.set)this.set=0;return this};F.prototype.parse=function(a){this.id=a.getAttribute("id");for(var b=0;bthis.transparency,c;for(c in this)switch(c){case "ambient":case "emission":case "diffuse":case "specular":var d=this[c]; -if(d instanceof D)if(d.isTexture()){if(this.effect.sampler&&this.effect.surface&&this.effect.sampler.source==this.effect.surface.sid){var e=Ka[this.effect.surface.init_from];if(e)e=THREE.ImageUtils.loadTexture(Sa+e.init_from),e.wrapS=d.texOpts.wrapU?THREE.RepeatWrapping:THREE.ClampToEdgeWrapping,e.wrapT=d.texOpts.wrapV?THREE.RepeatWrapping:THREE.ClampToEdgeWrapping,e.offset.x=d.texOpts.offsetU,e.offset.y=d.texOpts.offsetV,e.repeat.x=d.texOpts.repeatU,e.repeat.y=d.texOpts.repeatV,a.map=e}}else"diffuse"== -c?a.color=d.color.getHex():b||(a[c]=d.color.getHex());break;case "shininess":case "reflectivity":a[c]=this[c];break;case "transparency":if(b)a.transparent=!0,a.opacity=this[c],b=!0}a.shading=za;return this.material=new THREE.MeshLambertMaterial(a)};I.prototype.parse=function(a){for(var b=0;bf||1f?0:1;if(h.length)for(var e=[],i=0;ir.parameters.opacity)r.parameters.transparent=!0;if(r.parameters.normalMap){a=THREE.ShaderUtils.lib.normal;k=THREE.UniformsUtils.clone(a.uniforms);n=r.parameters.color;P=r.parameters.specular;c=r.parameters.ambient;K=r.parameters.shininess;k.tNormal.texture=C.textures[r.parameters.normalMap];if(r.parameters.normalMapFactor)k.uNormalScale.value=r.parameters.normalMapFactor;if(r.parameters.map)k.tDiffuse.texture=r.parameters.map,k.enableDiffuse.value=!0;if(r.parameters.lightMap)k.tAO.texture= -r.parameters.lightMap,k.enableAO.value=!0;if(r.parameters.specularMap)k.tSpecular.texture=C.textures[r.parameters.specularMap],k.enableSpecular.value=!0;k.uDiffuseColor.value.setHex(n);k.uSpecularColor.value.setHex(P);k.uAmbientColor.value.setHex(c);k.uShininess.value=K;if(r.parameters.opacity)k.uOpacity.value=r.parameters.opacity;I=new THREE.ShaderMaterial({fragmentShader:a.fragmentShader,vertexShader:a.vertexShader,uniforms:k,lights:!0,fog:!0})}else I=new THREE[r.type](r.parameters);C.materials[q]= -I}f();i.callbackSync(C);h()};THREE.UTF8Loader=function(){}; -THREE.UTF8Loader.prototype.load=function(a,b,c){var d=new XMLHttpRequest,f=void 0!==c.scale?c.scale:1,g=void 0!==c.offsetX?c.offsetX:0,e=void 0!==c.offsetY?c.offsetY:0,h=void 0!==c.offsetZ?c.offsetZ:0;d.onreadystatechange=function(){4==d.readyState?200==d.status||0==d.status?THREE.UTF8Loader.prototype.createModel(d.responseText,b,f,g,e,h):console.error("THREE.UTF8Loader: Couldn't load ["+a+"] ["+d.status+"]"):3!=d.readyState&&2==d.readyState&&d.getResponseHeader("Content-Length")};d.open("GET",a, -!0);d.send(null)};THREE.UTF8Loader.prototype.decompressMesh=function(a){var b=a.charCodeAt(0);57344<=b&&(b-=2048);b++;for(var c=new Float32Array(8*b),d=1,f=0;8>f;f++){for(var g=0,e=0;e>1^-(h&1));c[8*e+f]=g}d+=b}b=a.length-d;g=new Uint16Array(b);for(f=e=0;f=this.maxCount-3&&h(this)};this.begin=function(){this.count=0; -this.hasNormal=this.hasPos=!1};this.end=function(a){if(0!==this.count){for(var b=3*this.count;bq&&(q=1);i=Math.floor(i+h);i>this.size-1&&(i=this.size-1);var m=Math.floor(j-h);1>m&&(m=1);j=Math.floor(j+h);j>this.size-1&&(j=this.size-1);var o=Math.floor(k-h);1>o&&(o=1);h=Math.floor(k+h);h>this.size-1&&(h=this.size- -1);for(var p,n,r,s,t,w,u,k=q;kj&&(o=j);for(f=0;fk&&(p=k);for(g=0;gk&&(p=k);for(e=0;e=b.getParameter(b.MAX_VERTEX_TEXTURE_IMAGE_UNITS)?(j=!1,k=a(THREE.ShaderFlares.lensFlare)):(j=!0,k=a(THREE.ShaderFlares.lensFlareVertexTexture));q={};m={};q.vertex=b.getAttribLocation(k,"position");q.uv=b.getAttribLocation(k,"uv");m.renderType=b.getUniformLocation(k,"renderType");m.map=b.getUniformLocation(k,"map");m.occlusionMap=b.getUniformLocation(k,"occlusionMap");m.opacity=b.getUniformLocation(k,"opacity");m.color=b.getUniformLocation(k, -"color");m.scale=b.getUniformLocation(k,"scale");m.rotation=b.getUniformLocation(k,"rotation");m.screenPosition=b.getUniformLocation(k,"screenPosition");o=!1};this.render=function(a,d,f,s){var a=a.__webglFlares,t=a.length;if(t){var w=new THREE.Vector3,u=s/f,v=0.5*f,A=0.5*s,F=16/s,B=new THREE.Vector2(F*u,F),D=new THREE.Vector3(1,1,0),H=new THREE.Vector2(1,1),I=m,F=q;b.useProgram(k);o||(b.enableVertexAttribArray(q.vertex),b.enableVertexAttribArray(q.uv),o=!0);b.uniform1i(I.occlusionMap,0);b.uniform1i(I.map, -1);b.bindBuffer(b.ARRAY_BUFFER,g);b.vertexAttribPointer(F.vertex,2,b.FLOAT,!1,16,0);b.vertexAttribPointer(F.uv,2,b.FLOAT,!1,16,8);b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,e);b.disable(b.CULL_FACE);b.depthMask(!1);var Q,P,L,K,O;for(Q=0;Qv;v++)s[v]=new THREE.Vector3,n[v]=new THREE.Vector3;s=t.shadowCascadeNearZ[r];t=t.shadowCascadeFarZ[r];n[0].set(-1,-1,s);n[1].set(1,-1,s);n[2].set(-1,1,s);n[3].set(1,1,s);n[4].set(-1,-1,t);n[5].set(1,-1,t);n[6].set(-1,1,t);n[7].set(1,1,t);u.originalCamera=j;n=new THREE.Gyroscope;n.position=m.shadowCascadeOffset;n.add(u);n.add(u.target);j.add(n);m.shadowCascadeArray[p]=u;console.log("Created virtualLight",u)}r=m;s=p;t=r.shadowCascadeArray[s];t.position.copy(r.position); -t.target.position.copy(r.target.position);t.lookAt(t.target);t.shadowCameraVisible=r.shadowCameraVisible;t.shadowDarkness=r.shadowDarkness;t.shadowBias=r.shadowCascadeBias[s];n=r.shadowCascadeNearZ[s];r=r.shadowCascadeFarZ[s];t=t.pointsFrustum;t[0].z=n;t[1].z=n;t[2].z=n;t[3].z=n;t[4].z=r;t[5].z=r;t[6].z=r;t[7].z=r;w[o]=u;o++}else w[o]=m,o++;for(k=0,q=w.length;kr;r++){s=t[r];s.copy(n[r]);THREE.ShadowMapPlugin.__projector.unprojectVector(s, -p);o.matrixWorldInverse.multiplyVector3(s);if(s.xh.x)h.x=s.x;if(s.yh.y)h.y=s.y;if(s.zh.z)h.z=s.z}o.left=e.x;o.right=h.x;o.top=h.y;o.bottom=e.y;o.updateProjectionMatrix()}o=m.shadowMap;n=m.shadowMatrix;p=m.shadowCamera;p.position.copy(m.matrixWorld.getPosition());p.lookAt(m.target.matrixWorld.getPosition());p.updateMatrixWorld();p.matrixWorldInverse.getInverse(p.matrixWorld);if(m.cameraHelper)m.cameraHelper.lines.visible=m.shadowCameraVisible; -m.shadowCameraVisible&&m.cameraHelper.update(m.shadowCamera);n.set(0.5,0,0,0.5,0,0.5,0,0.5,0,0,0.5,0.5,0,0,0,1);n.multiplySelf(p.projectionMatrix);n.multiplySelf(p.matrixWorldInverse);if(!p._viewMatrixArray)p._viewMatrixArray=new Float32Array(16);p.matrixWorldInverse.flattenToArray(p._viewMatrixArray);if(!p._projectionMatrixArray)p._projectionMatrixArray=new Float32Array(16);p.projectionMatrix.flattenToArray(p._projectionMatrixArray);g.multiply(p.projectionMatrix,p.matrixWorldInverse);f.setFromMatrix(g); -b.setRenderTarget(o);b.clear();t=i.__webglObjects;for(m=0,o=t.length;m>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){if(0===b)this.r=this.g=this.b=c;else{var d=function(a,b,c){0>c&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a},b=0.5>=c?c*(1+b):c+b-c*b,c=2*c-b;this.r=d(c,b,a+1/3);this.g=d(c,b,a);this.b=d(c,b,a-1/3)}return this},setStyle:function(a){if(/^rgb\((\d+), ?(\d+), ?(\d+)\)$/i.test(a))return a=/^rgb\((\d+), ?(\d+), ?(\d+)\)$/i.exec(a),this.r=Math.min(255,parseInt(a[1],10))/255,this.g=Math.min(255,parseInt(a[2],10))/255,this.b=Math.min(255,parseInt(a[3],10))/255,this;if(/^rgb\((\d+)\%, ?(\d+)\%, ?(\d+)\%\)$/i.test(a))return a=/^rgb\((\d+)\%, ?(\d+)\%, ?(\d+)\%\)$/i.exec(a),this.r= +Math.min(100,parseInt(a[1],10))/100,this.g=Math.min(100,parseInt(a[2],10))/100,this.b=Math.min(100,parseInt(a[3],10))/100,this;if(/^\#([0-9a-f]{6})$/i.test(a))return a=/^\#([0-9a-f]{6})$/i.exec(a),this.setHex(parseInt(a[1],16)),this;if(/^\#([0-9a-f])([0-9a-f])([0-9a-f])$/i.test(a))return a=/^\#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(a),this.setHex(parseInt(a[1]+a[1]+a[2]+a[2]+a[3]+a[3],16)),this;if(/^(\w+)$/i.test(a))return this.setHex(THREE.ColorKeywords[a]),this},copy:function(a){this.r=a.r;this.g= +a.g;this.b=a.b;return this},copyGammaToLinear:function(a){this.r=a.r*a.r;this.g=a.g*a.g;this.b=a.b*a.b;return this},copyLinearToGamma:function(a){this.r=Math.sqrt(a.r);this.g=Math.sqrt(a.g);this.b=Math.sqrt(a.b);return this},convertGammaToLinear:function(){var a=this.r,b=this.g,c=this.b;this.r=a*a;this.g=b*b;this.b=c*c;return this},convertLinearToGamma:function(){this.r=Math.sqrt(this.r);this.g=Math.sqrt(this.g);this.b=Math.sqrt(this.b);return this},getHex:function(){return 255*this.r<<16^255*this.g<< +8^255*this.b<<0},getHexString:function(){return("000000"+this.getHex().toString(16)).slice(-6)},getHSL:function(){var a={h:0,s:0,l:0};return function(){var b=this.r,c=this.g,d=this.b,e=Math.max(b,c,d),f=Math.min(b,c,d),h,g=(f+e)/2;if(f===e)f=h=0;else{var i=e-f,f=0.5>=g?i/(e+f):i/(2-e-f);switch(e){case b:h=(c-d)/i+(cf&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(i-h)/c,this._x=0.25*c, +this._y=(a+e)/c,this._z=(d+g)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-g)/c,this._x=(a+e)/c,this._y=0.25*c,this._z=(h+i)/c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+g)/c,this._y=(h+i)/c,this._z=0.25*c);this._updateEuler();return this},inverse:function(){this.conjugate().normalize();return this},conjugate:function(){this._x*=-1;this._y*=-1;this._z*=-1;this._updateEuler();return this},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x* +this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a=this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);return this},multiply:function(a,b){return void 0!==b?(console.warn("DEPRECATED: Quaternion's .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z,f= +a._w,h=b._x,g=b._y,i=b._z,k=b._w;this._x=c*k+f*h+d*i-e*g;this._y=d*k+f*g+e*h-c*i;this._z=e*k+f*i+c*g-d*h;this._w=f*k-c*h-d*g-e*i;this._updateEuler();return this},multiplyVector3:function(a){console.warn("DEPRECATED: Quaternion's .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.");return a.applyQuaternion(this)},slerp:function(a,b){var c=this._x,d=this._y,e=this._z,f=this._w,h=f*a._w+c*a._x+d*a._y+e*a._z;0>h?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z= +-a._z,h=-h):this.copy(a);if(1<=h)return this._w=f,this._x=c,this._y=d,this._z=e,this;var g=Math.acos(h),i=Math.sqrt(1-h*h);if(0.0010>Math.abs(i))return this._w=0.5*(f+this._w),this._x=0.5*(c+this._x),this._y=0.5*(d+this._y),this._z=0.5*(e+this._z),this;h=Math.sin((1-b)*g)/i;g=Math.sin(b*g)/i;this._w=f*h+this._w*g;this._x=c*h+this._x*g;this._y=d*h+this._y*g;this._z=e*h+this._z*g;this._updateEuler();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w}, +fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];this._w=a[3];this._updateEuler();return this},toArray:function(){return[this._x,this._y,this._z,this._w]},clone:function(){return new THREE.Quaternion(this._x,this._y,this._z,this._w)}};THREE.Quaternion.slerp=function(a,b,c,d){return c.copy(a).slerp(b,d)};THREE.Vector2=function(a,b){this.x=a||0;this.y=b||0}; +THREE.Vector2.prototype={constructor:THREE.Vector2,set:function(a,b){this.x=a;this.y=b;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a, +b){if(void 0!==b)return console.warn("DEPRECATED: Vector2's .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},sub:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector2's .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-= +a.y;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a):this.y=this.x=0;return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y); +return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},normalize:function(){return this.divideScalar(this.length())},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,a=this.y-a.y;return b*b+a*a},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/ +b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a){this.x=a[0];this.y=a[1];return this},toArray:function(){return[this.x,this.y]},clone:function(){return new THREE.Vector2(this.x,this.y)}};THREE.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}; +THREE.Vector3.prototype={constructor:THREE.Vector3,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+ +a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector3's .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},sub:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector3's .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), +this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector3's .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x* +b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z,a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},applyProjection:function(a){var b=this.x,c=this.y,d=this.z,a=a.elements,e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]); +this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,h=a.z,a=a.w,g=a*b+f*d-h*c,i=a*c+h*b-e*d,k=a*d+e*c-f*b,b=-e*b-f*c-h*d;this.x=g*a+b*-e+i*-h-k*-f;this.y=i*a+b*-f+k*-e-g*-h;this.z=k*a+b*-h+g*-f-i*-e;return this},transformDirection:function(a){var b=this.x,c=this.y,d=this.z,a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]* +b+a[6]*c+a[10]*d;this.normalize();return this},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*=a):this.z=this.y=this.x=0;return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);return this},max:function(a){this.xb.x&&(this.x=b.x);this.y< +a.y?this.y=a.y:this.y>b.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())}, +setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},cross:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector3's .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){var c= +a.x,d=a.y,e=a.z,f=b.x,h=b.y,g=b.z;this.x=d*g-e*h;this.y=e*f-c*g;this.z=c*h-d*f;return this},angleTo:function(a){a=this.dot(a)/(this.length()*a.length());return Math.acos(THREE.Math.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y,a=this.z-a.z;return b*b+c*c+a*a},setEulerFromRotationMatrix:function(){console.error("REMOVED: Vector3's setEulerFromRotationMatrix has been removed in favor of Euler.setFromRotationMatrix(), please update your code.")}, +setEulerFromQuaternion:function(){console.error("REMOVED: Vector3's setEulerFromQuaternion: has been removed in favor of Euler.setFromQuaternion(), please update your code.")},getPositionFromMatrix:function(a){this.x=a.elements[12];this.y=a.elements[13];this.z=a.elements[14];return this},getScaleFromMatrix:function(a){var b=this.set(a.elements[0],a.elements[1],a.elements[2]).length(),c=this.set(a.elements[4],a.elements[5],a.elements[6]).length(),a=this.set(a.elements[8],a.elements[9],a.elements[10]).length(); +this.x=b;this.y=c;this.z=a;return this},getColumnFromMatrix:function(a,b){var c=4*a,d=b.elements;this.x=d[c];this.y=d[c+1];this.z=d[c+2];return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a){this.x=a[0];this.y=a[1];this.z=a[2];return this},toArray:function(){return[this.x,this.y,this.z]},clone:function(){return new THREE.Vector3(this.x,this.y,this.z)}}; +THREE.extend(THREE.Vector3.prototype,{applyEuler:function(){var a=new THREE.Quaternion;return function(b){!1===b instanceof THREE.Euler&&console.error("ERROR: Vector3's .applyEuler() now expects a Euler rotation rather than a Vector3 and order. Please update your code.");this.applyQuaternion(a.setFromEuler(b));return this}}(),applyAxisAngle:function(){var a=new THREE.Quaternion;return function(b,c){this.applyQuaternion(a.setFromAxisAngle(b,c));return this}}(),projectOnVector:function(){var a=new THREE.Vector3; +return function(b){a.copy(b).normalize();b=this.dot(a);return this.copy(a).multiplyScalar(b)}}(),projectOnPlane:function(){var a=new THREE.Vector3;return function(b){a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a=new THREE.Vector3;return function(b){a.copy(this).projectOnVector(b).multiplyScalar(2);return this.subVectors(a,this)}}()});THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}; +THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x; +case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector4's .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this}, +addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},sub:function(a,b){if(void 0!==b)return console.warn("DEPRECATED: Vector4's .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this}, +applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w,a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a):(this.z=this.y=this.x=0,this.w=1);return this},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b, +this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){var b,c,d,a=a.elements,e=a[0];d=a[4];var f=a[8],h=a[1],g=a[5],i=a[9];c=a[2];b=a[6];var k=a[10];if(0.01>Math.abs(d-h)&&0.01>Math.abs(f-c)&&0.01>Math.abs(i-b)){if(0.1>Math.abs(d+h)&&0.1>Math.abs(f+c)&&0.1>Math.abs(i+b)&&0.1>Math.abs(e+g+k-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;g=(g+1)/2;k=(k+1)/2;d=(d+h)/4;f=(f+c)/4;i=(i+b)/4;e>g&&e>k?0.01>e?(b=0,d=c=0.707106781):(b=Math.sqrt(e),c=d/b,d=f/b):g>k?0.01>g? +(b=0.707106781,c=0,d=0.707106781):(c=Math.sqrt(g),b=d/c,d=i/c):0.01>k?(c=b=0.707106781,d=0):(d=Math.sqrt(k),b=f/d,c=i/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-i)*(b-i)+(f-c)*(f-c)+(h-d)*(h-d));0.0010>Math.abs(a)&&(a=1);this.x=(b-i)/a;this.y=(f-c)/a;this.z=(h-d)/a;this.w=Math.acos((e+g+k-1)/2);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);this.w>a.w&&(this.w=a.w);return this},max:function(a){this.xb.x&&(this.x=b.x);this.yb.y&&(this.y=b.y);this.zb.z&&(this.z=b.z);this.wb.w&&(this.w=b.w);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x* +this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&& +a.w===this.w},fromArray:function(a){this.x=a[0];this.y=a[1];this.z=a[2];this.w=a[3];return this},toArray:function(){return[this.x,this.y,this.z,this.w]},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)}};THREE.Euler=function(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._order=d||THREE.Euler.DefaultOrder};THREE.Euler.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" ");THREE.Euler.DefaultOrder="XYZ"; +THREE.Euler.prototype={constructor:THREE.Euler,_x:0,_y:0,_z:0,_order:THREE.Euler.DefaultOrder,_quaternion:void 0,_updateQuaternion:function(){void 0!==this._quaternion&&this._quaternion.setFromEuler(this,!1)},get x(){return this._x},set x(a){this._x=a;this._updateQuaternion()},get y(){return this._y},set y(a){this._y=a;this._updateQuaternion()},get z(){return this._z},set z(a){this._z=a;this._updateQuaternion()},get order(){return this._order},set order(a){this._order=a;this._updateQuaternion()}, +set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this._updateQuaternion();return this},copy:function(a){this._x=a._x;this._y=a._y;this._z=a._z;this._order=a._order;this._updateQuaternion();return this},setFromRotationMatrix:function(a,b){function c(a){return Math.min(Math.max(a,-1),1)}var d=a.elements,e=d[0],f=d[4],h=d[8],g=d[1],i=d[5],k=d[9],m=d[2],l=d[6],d=d[10],b=b||this._order;"XYZ"===b?(this._y=Math.asin(c(h)),0.99999>Math.abs(h)?(this._x=Math.atan2(-k,d),this._z= +Math.atan2(-f,e)):(this._x=Math.atan2(l,i),this._z=0)):"YXZ"===b?(this._x=Math.asin(-c(k)),0.99999>Math.abs(k)?(this._y=Math.atan2(h,d),this._z=Math.atan2(g,i)):(this._y=Math.atan2(-m,e),this._z=0)):"ZXY"===b?(this._x=Math.asin(c(l)),0.99999>Math.abs(l)?(this._y=Math.atan2(-m,d),this._z=Math.atan2(-f,i)):(this._y=0,this._z=Math.atan2(g,e))):"ZYX"===b?(this._y=Math.asin(-c(m)),0.99999>Math.abs(m)?(this._x=Math.atan2(l,d),this._z=Math.atan2(g,e)):(this._x=0,this._z=Math.atan2(-f,i))):"YZX"===b?(this._z= +Math.asin(c(g)),0.99999>Math.abs(g)?(this._x=Math.atan2(-k,i),this._y=Math.atan2(-m,e)):(this._x=0,this._y=Math.atan2(h,d))):"XZY"===b?(this._z=Math.asin(-c(f)),0.99999>Math.abs(f)?(this._x=Math.atan2(l,i),this._y=Math.atan2(h,e)):(this._x=Math.atan2(-k,d),this._y=0)):console.warn("WARNING: Euler.setFromRotationMatrix() given unsupported order: "+b);this._order=b;this._updateQuaternion();return this},setFromQuaternion:function(a,b,c){function d(a){return Math.min(Math.max(a,-1),1)}var e=a.x*a.x,f= +a.y*a.y,h=a.z*a.z,g=a.w*a.w,b=b||this._order;"XYZ"===b?(this._x=Math.atan2(2*(a.x*a.w-a.y*a.z),g-e-f+h),this._y=Math.asin(d(2*(a.x*a.z+a.y*a.w))),this._z=Math.atan2(2*(a.z*a.w-a.x*a.y),g+e-f-h)):"YXZ"===b?(this._x=Math.asin(d(2*(a.x*a.w-a.y*a.z))),this._y=Math.atan2(2*(a.x*a.z+a.y*a.w),g-e-f+h),this._z=Math.atan2(2*(a.x*a.y+a.z*a.w),g-e+f-h)):"ZXY"===b?(this._x=Math.asin(d(2*(a.x*a.w+a.y*a.z))),this._y=Math.atan2(2*(a.y*a.w-a.z*a.x),g-e-f+h),this._z=Math.atan2(2*(a.z*a.w-a.x*a.y),g-e+f-h)):"ZYX"=== +b?(this._x=Math.atan2(2*(a.x*a.w+a.z*a.y),g-e-f+h),this._y=Math.asin(d(2*(a.y*a.w-a.x*a.z))),this._z=Math.atan2(2*(a.x*a.y+a.z*a.w),g+e-f-h)):"YZX"===b?(this._x=Math.atan2(2*(a.x*a.w-a.z*a.y),g-e+f-h),this._y=Math.atan2(2*(a.y*a.w-a.x*a.z),g+e-f-h),this._z=Math.asin(d(2*(a.x*a.y+a.z*a.w)))):"XZY"===b?(this._x=Math.atan2(2*(a.x*a.w+a.y*a.z),g-e+f-h),this._y=Math.atan2(2*(a.x*a.z+a.y*a.w),g+e-f-h),this._z=Math.asin(d(2*(a.z*a.w-a.x*a.y)))):console.warn("WARNING: Euler.setFromQuaternion() given unsupported order: "+ +b);this._order=b;!1!==c&&this._updateQuaternion();return this},reorder:function(){var a=new THREE.Quaternion;return function(b){a.setFromEuler(this);this.setFromQuaternion(a,b)}}(),fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this._updateQuaternion();return this},toArray:function(){return[this._x,this._y,this._z,this._order]},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},clone:function(){return new THREE.Euler(this._x, +this._y,this._z,this._order)}};THREE.Line3=function(a,b){this.start=void 0!==a?a:new THREE.Vector3;this.end=void 0!==b?b:new THREE.Vector3}; +THREE.Line3.prototype={constructor:THREE.Line3,set:function(a,b){this.start.copy(a);this.end.copy(b);return this},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},center:function(a){return(a||new THREE.Vector3).addVectors(this.start,this.end).multiplyScalar(0.5)},delta:function(a){return(a||new THREE.Vector3).subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a, +b){var c=b||new THREE.Vector3;return this.delta(c).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c,d){a.subVectors(c,this.start);b.subVectors(this.end,this.start);var e=b.dot(b),e=b.dot(a)/e;d&&(e=THREE.Math.clamp(e,0,1));return e}}(),closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);c=c||new THREE.Vector3;return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a); +this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)},clone:function(){return(new THREE.Line3).copy(this)}};THREE.Box2=function(a,b){this.min=void 0!==a?a:new THREE.Vector2(Infinity,Infinity);this.max=void 0!==b?b:new THREE.Vector2(-Infinity,-Infinity)}; +THREE.Box2.prototype={constructor:THREE.Box2,set:function(a,b){this.min.copy(a);this.max.copy(b);return this},setFromPoints:function(a){if(0this.max.x&&(this.max.x=b.x),b.ythis.max.y&&(this.max.y=b.y)}else this.makeEmpty();return this},setFromCenterAndSize:function(){var a=new THREE.Vector2;return function(b,c){var d=a.copy(c).multiplyScalar(0.5); +this.min.copy(b).sub(d);this.max.copy(b).add(d);return this}}(),copy:function(a){this.min.copy(a.min);this.max.copy(a.max);return this},makeEmpty:function(){this.min.x=this.min.y=Infinity;this.max.x=this.max.y=-Infinity;return this},empty:function(){return this.max.xthis.max.x||a.ythis.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y?!0:!1},getParameter:function(a){return new THREE.Vector2((a.x-this.min.x)/(this.max.x-this.min.x), +(a.y-this.min.y)/(this.max.y-this.min.y))},isIntersectionBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y?!1:!0},clampPoint:function(a,b){return(b||new THREE.Vector2).copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new THREE.Vector2;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max); +return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)},clone:function(){return(new THREE.Box2).copy(this)}};THREE.Box3=function(a,b){this.min=void 0!==a?a:new THREE.Vector3(Infinity,Infinity,Infinity);this.max=void 0!==b?b:new THREE.Vector3(-Infinity,-Infinity,-Infinity)}; +THREE.Box3.prototype={constructor:THREE.Box3,set:function(a,b){this.min.copy(a);this.max.copy(b);return this},addPoint:function(a){a.xthis.max.x&&(this.max.x=a.x);a.ythis.max.y&&(this.max.y=a.y);a.zthis.max.z&&(this.max.z=a.z)},setFromPoints:function(a){if(0this.max.x||a.ythis.max.y||a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z?!0:!1},getParameter:function(a){return new THREE.Vector3((a.x-this.min.x)/(this.max.x-this.min.x), +(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},isIntersectionBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},clampPoint:function(a,b){return(b||new THREE.Vector3).copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new THREE.Vector3;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),getBoundingSphere:function(){var a= +new THREE.Vector3;return function(b){b=b||new THREE.Sphere;b.center=this.center();b.radius=0.5*this.size(a).length();return b}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(){var a=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];return function(b){a[0].set(this.min.x,this.min.y, +this.min.z).applyMatrix4(b);a[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(b);a[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(b);a[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(b);a[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(b);a[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(b);a[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(b);a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b);this.makeEmpty();this.setFromPoints(a);return this}}(),translate:function(a){this.min.add(a); +this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)},clone:function(){return(new THREE.Box3).copy(this)}};THREE.Matrix3=function(a,b,c,d,e,f,h,g,i){this.elements=new Float32Array(9);this.set(void 0!==a?a:1,b||0,c||0,d||0,void 0!==e?e:1,f||0,h||0,g||0,void 0!==i?i:1)}; +THREE.Matrix3.prototype={constructor:THREE.Matrix3,set:function(a,b,c,d,e,f,h,g,i){var k=this.elements;k[0]=a;k[3]=b;k[6]=c;k[1]=d;k[4]=e;k[7]=f;k[2]=h;k[5]=g;k[8]=i;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},copy:function(a){a=a.elements;this.set(a[0],a[3],a[6],a[1],a[4],a[7],a[2],a[5],a[8]);return this},multiplyVector3:function(a){console.warn("DEPRECATED: Matrix3's .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.");return a.applyMatrix3(this)}, +multiplyVector3Array:function(){var a=new THREE.Vector3;return function(b){for(var c=0,d=b.length;cd?c.copy(this.origin):c.copy(this.direction).multiplyScalar(d).add(this.origin)},distanceToPoint:function(){var a=new THREE.Vector3;return function(b){var c=a.subVectors(b,this.origin).dot(this.direction);if(0>c)return this.origin.distanceTo(b);a.copy(this.direction).multiplyScalar(c).add(this.origin);return a.distanceTo(b)}}(),distanceSqToSegment:function(a,b,c,d){var e=a.clone().add(b).multiplyScalar(0.5),f=b.clone().sub(a).normalize(),h=0.5*a.distanceTo(b), +g=this.origin.clone().sub(e),a=-this.direction.dot(f),b=g.dot(this.direction),i=-g.dot(f),k=g.lengthSq(),m=Math.abs(1-a*a),l,p;0<=m?(g=a*i-b,l=a*b-i,p=h*m,0<=g?l>=-p?l<=p?(h=1/m,g*=h,l*=h,a=g*(g+a*l+2*b)+l*(a*g+l+2*i)+k):(l=h,g=Math.max(0,-(a*l+b)),a=-g*g+l*(l+2*i)+k):(l=-h,g=Math.max(0,-(a*l+b)),a=-g*g+l*(l+2*i)+k):l<=-p?(g=Math.max(0,-(-a*h+b)),l=0a.normal.dot(this.direction)*b?!0:!1},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0==b)return 0==a.distanceToPoint(this.origin)? +0:null;a=-(this.origin.dot(a.normal)+a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){var c=this.distanceToPlane(a);return null===c?null:this.at(c,b)},isIntersectionBox:function(){var a=new THREE.Vector3;return function(b){return null!==this.intersectBox(b,a)}}(),intersectBox:function(a,b){var c,d,e,f,h;d=1/this.direction.x;f=1/this.direction.y;h=1/this.direction.z;var g=this.origin;0<=d?(c=(a.min.x-g.x)*d,d*=a.max.x-g.x):(c=(a.max.x-g.x)*d,d*=a.min.x-g.x);0<=f?(e=(a.min.y-g.y)*f,f*= +a.max.y-g.y):(e=(a.max.y-g.y)*f,f*=a.min.y-g.y);if(c>f||e>d)return null;if(e>c||c!==c)c=e;if(fh||e>d)return null;if(e>c||c!==c)c=e;if(hd?null:this.at(0<=c?c:d,b)},intersectTriangle:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3,d=new THREE.Vector3;return function(e,f,h,g,i){b.subVectors(f,e);c.subVectors(h,e);d.crossVectors(b,c);f=this.direction.dot(d);if(0< +f){if(g)return null;g=1}else if(0>f)g=-1,f=-f;else return null;a.subVectors(this.origin,e);e=g*this.direction.dot(c.crossVectors(a,c));if(0>e)return null;h=g*this.direction.dot(b.cross(a));if(0>h||e+h>f)return null;e=-g*a.dot(d);return 0>e?null:this.at(e/f,i)}}(),applyMatrix4:function(a){this.direction.add(this.origin).applyMatrix4(a);this.origin.applyMatrix4(a);this.direction.sub(this.origin);this.direction.normalize();return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}, +clone:function(){return(new THREE.Ray).copy(this)}};THREE.Sphere=function(a,b){this.center=void 0!==a?a:new THREE.Vector3;this.radius=void 0!==b?b:0}; +THREE.Sphere.prototype={constructor:THREE.Sphere,set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(){var a=new THREE.Box3;return function(b,c){var d=this.center;void 0!==c?d.copy(c):a.setFromPoints(b).center(d);for(var e=0,f=0,h=b.length;f=this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<= +this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)-this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},clampPoint:function(a,b){var c=this.center.distanceToSquared(a),d=b||new THREE.Vector3;d.copy(a);c>this.radius*this.radius&&(d.sub(this.center).normalize(),d.multiplyScalar(this.radius).add(this.center));return d},getBoundingBox:function(a){a=a||new THREE.Box3;a.set(this.center,this.center);a.expandByScalar(this.radius); +return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius},clone:function(){return(new THREE.Sphere).copy(this)}};THREE.Frustum=function(a,b,c,d,e,f){this.planes=[void 0!==a?a:new THREE.Plane,void 0!==b?b:new THREE.Plane,void 0!==c?c:new THREE.Plane,void 0!==d?d:new THREE.Plane,void 0!==e?e:new THREE.Plane,void 0!==f?f:new THREE.Plane]}; +THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var h=this.planes;h[0].copy(a);h[1].copy(b);h[2].copy(c);h[3].copy(d);h[4].copy(e);h[5].copy(f);return this},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements,a=c[0],d=c[1],e=c[2],f=c[3],h=c[4],g=c[5],i=c[6],k=c[7],m=c[8],l=c[9],p=c[10],r=c[11],t=c[12],n=c[13],s=c[14],c=c[15];b[0].setComponents(f-a,k-h,r-m,c-t).normalize();b[1].setComponents(f+ +a,k+h,r+m,c+t).normalize();b[2].setComponents(f+d,k+g,r+l,c+n).normalize();b[3].setComponents(f-d,k-g,r-l,c-n).normalize();b[4].setComponents(f-e,k-i,r-p,c-s).normalize();b[5].setComponents(f+e,k+i,r+p,c+s).normalize();return this},intersectsObject:function(){var a=new THREE.Sphere;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere);a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){for(var b=this.planes, +c=a.center,a=-a.radius,d=0;6>d;d++)if(b[d].distanceToPoint(c)e;e++){var f=d[e];a.x=0h&&0>f)return!1}return!0}}(),containsPoint:function(a){for(var b= +this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0},clone:function(){return(new THREE.Frustum).copy(this)}};THREE.Plane=function(a,b){this.normal=void 0!==a?a:new THREE.Vector3(1,0,0);this.constant=void 0!==b?b:0}; +THREE.Plane.prototype={constructor:THREE.Plane,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c,d,e){d=a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.setFromNormalAndCoplanarPoint(d, +c);return this}}(),copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*=-1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},projectPoint:function(a,b){return this.orthoPoint(a,b).sub(a).negate()},orthoPoint:function(a, +b){var c=this.distanceToPoint(a);return(b||new THREE.Vector3).copy(this.normal).multiplyScalar(c)},isIntersectionLine:function(a){var b=this.distanceToPoint(a.start),a=this.distanceToPoint(a.end);return 0>b&&0a&&0f||1e;e++)8==e||13==e||18==e||23==e?b[e]="-":14==e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19==e?d&3|8:d]);return b.join("")}}(),clamp:function(a,b,c){return ac?c:a},clampBottom:function(a,b){return a=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},random16:function(){return(65280*Math.random()+255*Math.random())/65535},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(0.5-Math.random())},sign:function(a){return 0>a?-1:0this.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1: +f+2;k=this.points[c[0]];m=this.points[c[1]];l=this.points[c[2]];p=this.points[c[3]];g=h*h;i=h*g;d.x=b(k.x,m.x,l.x,p.x,h,g,i);d.y=b(k.y,m.y,l.y,p.y,h,g,i);d.z=b(k.z,m.z,l.z,p.z,h,g,i);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;a=b.x+b.y}}(); +THREE.Triangle.prototype={constructor:THREE.Triangle,set:function(a,b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},area:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a,this.b);return 0.5*a.cross(b).length()}}(),midpoint:function(a){return(a|| +new THREE.Vector3).addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},normal:function(a){return THREE.Triangle.normal(this.a,this.b,this.c,a)},plane:function(a){return(a||new THREE.Plane).setFromCoplanarPoints(this.a,this.b,this.c)},barycoordFromPoint:function(a,b){return THREE.Triangle.barycoordFromPoint(a,this.a,this.b,this.c,b)},containsPoint:function(a){return THREE.Triangle.containsPoint(a,this.a,this.b,this.c)},equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}, +clone:function(){return(new THREE.Triangle).copy(this)}};THREE.Vertex=function(a){console.warn("THREE.Vertex has been DEPRECATED. Use THREE.Vector3 instead.");return a};THREE.UV=function(a,b){console.warn("THREE.UV has been DEPRECATED. Use THREE.Vector2 instead.");return new THREE.Vector2(a,b)};THREE.Clock=function(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1}; +THREE.Clock.prototype={constructor:THREE.Clock,start:function(){this.oldTime=this.startTime=void 0!==self.performance&&void 0!==self.performance.now?self.performance.now():Date.now();this.running=!0},stop:function(){this.getElapsedTime();this.running=!1},getElapsedTime:function(){this.getDelta();return this.elapsedTime},getDelta:function(){var a=0;this.autoStart&&!this.running&&this.start();if(this.running){var b=void 0!==self.performance&&void 0!==self.performance.now?self.performance.now():Date.now(), +a=0.0010*(b-this.oldTime);this.oldTime=b;this.elapsedTime+=a}return a}};THREE.EventDispatcher=function(){}; +THREE.EventDispatcher.prototype={constructor:THREE.EventDispatcher,apply:function(a){a.addEventListener=THREE.EventDispatcher.prototype.addEventListener;a.hasEventListener=THREE.EventDispatcher.prototype.hasEventListener;a.removeEventListener=THREE.EventDispatcher.prototype.removeEventListener;a.dispatchEvent=THREE.EventDispatcher.prototype.dispatchEvent},addEventListener:function(a,b){void 0===this._listeners&&(this._listeners={});var c=this._listeners;void 0===c[a]&&(c[a]=[]);-1===c[a].indexOf(b)&& +c[a].push(b)},hasEventListener:function(a,b){if(void 0===this._listeners)return!1;var c=this._listeners;return void 0!==c[a]&&-1!==c[a].indexOf(b)?!0:!1},removeEventListener:function(a,b){if(void 0!==this._listeners){var c=this._listeners,d=c[a].indexOf(b);-1!==d&&c[a].splice(d,1)}},dispatchEvent:function(a){if(void 0!==this._listeners){var b=this._listeners[a.type];if(void 0!==b){a.target=this;for(var c=0,d=b.length;cf.scale.x)return r;r.push({distance:t,point:f.position,face:null,object:f})}else if(f instanceof +a.LOD)d.getPositionFromMatrix(f.matrixWorld),t=m.ray.origin.distanceTo(d),k(f.getObjectForDistance(t),m,r);else if(f instanceof a.Mesh){var n=f.geometry;null===n.boundingSphere&&n.computeBoundingSphere();b.copy(n.boundingSphere);b.applyMatrix4(f.matrixWorld);if(!1===m.ray.isIntersectionSphere(b))return r;e.getInverse(f.matrixWorld);c.copy(m.ray).applyMatrix4(e);if(null!==n.boundingBox&&!1===c.isIntersectionBox(n.boundingBox))return r;if(n instanceof a.BufferGeometry){var s=f.material;if(void 0=== +s||!1===n.dynamic)return r;var q,u,w=m.precision;if(void 0!==n.attributes.index)for(var E=n.offsets,C=n.attributes.index.array,F=n.attributes.position.array,y=n.offsets.length,A=n.attributes.index.array.length/3,A=0;Am.far)||r.push({distance:t,point:q,face:null,faceIndex:null,object:f}));else{F=n.attributes.position.array;A=n.attributes.position.array.length;for(n=0;nm.far)||r.push({distance:t,point:q,face:null, +faceIndex:null,object:f}))}}else if(n instanceof a.Geometry){C=f.material instanceof a.MeshFaceMaterial;F=!0===C?f.material.materials:null;w=m.precision;E=n.vertices;y=0;for(A=n.faces.length;ym.far)||r.push({distance:t,point:q,face:z,faceIndex:y,object:f})))}}else if(f instanceof +a.Line){w=m.linePrecision;s=w*w;n=f.geometry;null===n.boundingSphere&&n.computeBoundingSphere();b.copy(n.boundingSphere);b.applyMatrix4(f.matrixWorld);if(!1===m.ray.isIntersectionSphere(b))return r;e.getInverse(f.matrixWorld);c.copy(m.ray).applyMatrix4(e);if(n instanceof a.Geometry){E=n.vertices;w=E.length;q=new a.Vector3;u=new a.Vector3;A=f.type===a.LineStrip?1:2;for(n=0;ns||(t=c.origin.distanceTo(u),tm.far||r.push({distance:t,point:q.clone().applyMatrix4(f.matrixWorld), +face:null,faceIndex:null,object:f}))}}},m=function(a,b,c){for(var a=a.getDescendants(),d=0,e=a.length;de&&0>f||0>h&&0>g)return!1;0>e?c=Math.max(c,e/(e-f)):0>f&&(d=Math.min(d,e/(e-f)));0>h?c=Math.max(c,h/(h-g)):0>g&&(d=Math.min(d,h/(h-g)));if(dg.positionScreen.x||1g.positionScreen.y||1g.positionScreen.z||1(ia.positionScreen.x-V.positionScreen.x)*(P.positionScreen.y-V.positionScreen.y)-(ia.positionScreen.y-V.positionScreen.y)*(P.positionScreen.x-V.positionScreen.x), +Y===THREE.DoubleSide||A===(Y===THREE.FrontSide)){if(p===t){var Ea=new THREE.RenderableFace3;r.push(Ea);t++;p++;l=Ea}else l=r[p++];l.id=U.id;l.v1.copy(V);l.v2.copy(P);l.v3.copy(ia);l.normalModel.copy($.normal);!1===A&&(Y===THREE.BackSide||Y===THREE.DoubleSide)&&l.normalModel.negate();l.normalModel.applyMatrix3(Q).normalize();l.normalModelView.copy(l.normalModel).applyMatrix3(J);l.centroidModel.copy($.centroid).applyMatrix4(x);ia=$.vertexNormals;V=0;for(P=Math.min(ia.length,3);Vz.z&&(E===F?(ta=new THREE.RenderableParticle,C.push(ta),F++,E++,w=ta):w=C[E++],w.id=U.id,w.x=z.x*fa,w.y=z.y*fa,w.z=z.z,w.object=U,w.rotation=U.rotation.z,w.scale.x=U.scale.x*Math.abs(w.x-(z.x+f.projectionMatrix.elements[0])/(z.w+f.projectionMatrix.elements[12])), +w.scale.y=U.scale.y*Math.abs(w.y-(z.y+f.projectionMatrix.elements[5])/(z.w+f.projectionMatrix.elements[13])),w.material=U.material,y.elements.push(w)));!0===m&&y.elements.sort(b);return y}};THREE.Face3=function(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d instanceof THREE.Vector3?d:new THREE.Vector3;this.vertexNormals=d instanceof Array?d:[];this.color=e instanceof THREE.Color?e:new THREE.Color;this.vertexColors=e instanceof Array?e:[];this.vertexTangents=[];this.materialIndex=void 0!==f?f:0;this.centroid=new THREE.Vector3}; +THREE.Face3.prototype={constructor:THREE.Face3,clone:function(){var a=new THREE.Face3(this.a,this.b,this.c);a.normal.copy(this.normal);a.color.copy(this.color);a.centroid.copy(this.centroid);a.materialIndex=this.materialIndex;var b,c;b=0;for(c=this.vertexNormals.length;bd?-1:1,e.vertexTangents[c]=new THREE.Vector4(E.x,E.y,E.z,d)}this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd;d++)if(e[d]==e[(d+1)%3]){a.push(f);break}}for(f=a.length-1;0<=f;f--){e=a[f];this.faces.splice(e,1);c=0;for(h=this.faceVertexUvs.length;cb.max.x&&(b.max.x=c),db.max.y&&(b.max.y=d),eb.max.z&&(b.max.z=e)}if(void 0===a||0===a.length)this.boundingBox.min.set(0,0,0),this.boundingBox.max.set(0,0,0)},computeBoundingSphere:function(){var a=new THREE.Box3,b=new THREE.Vector3;return function(){null=== +this.boundingSphere&&(this.boundingSphere=new THREE.Sphere);var c=this.attributes.position.array;if(c){for(var d=this.boundingSphere.center,e=0,f=c.length;eR?-1:1;h[4*a]=J.x;h[4*a+1]=J.y;h[4*a+2]=J.z;h[4*a+3]=N}if(void 0===this.attributes.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var b=this.attributes.index.array,c=this.attributes.position.array,d=this.attributes.normal.array,e=this.attributes.uv.array,f=c.length/3;void 0===this.attributes.tangent&&(this.attributes.tangent= +{itemSize:4,array:new Float32Array(4*f)});for(var h=this.attributes.tangent.array,g=[],i=[],k=0;ka.length?".":a.join("/"))+"/"},initMaterials:function(a,b){for(var c=[],d=0;da.opacity)i.transparent=a.transparent;void 0!==a.depthTest&&(i.depthTest=a.depthTest);void 0!==a.depthWrite&&(i.depthWrite=a.depthWrite);void 0!==a.visible&&(i.visible=a.visible);void 0!==a.flipSided&&(i.side=THREE.BackSide); +void 0!==a.doubleSided&&(i.side=THREE.DoubleSide);void 0!==a.wireframe&&(i.wireframe=a.wireframe);void 0!==a.vertexColors&&("face"===a.vertexColors?i.vertexColors=THREE.FaceColors:a.vertexColors&&(i.vertexColors=THREE.VertexColors));a.colorDiffuse?i.color=f(a.colorDiffuse):a.DbgColor&&(i.color=a.DbgColor);a.colorSpecular&&(i.specular=f(a.colorSpecular));a.colorAmbient&&(i.ambient=f(a.colorAmbient));a.transparency&&(i.opacity=a.transparency);a.specularCoef&&(i.shininess=a.specularCoef);a.mapDiffuse&& +b&&e(i,"map",a.mapDiffuse,a.mapDiffuseRepeat,a.mapDiffuseOffset,a.mapDiffuseWrap,a.mapDiffuseAnisotropy);a.mapLight&&b&&e(i,"lightMap",a.mapLight,a.mapLightRepeat,a.mapLightOffset,a.mapLightWrap,a.mapLightAnisotropy);a.mapBump&&b&&e(i,"bumpMap",a.mapBump,a.mapBumpRepeat,a.mapBumpOffset,a.mapBumpWrap,a.mapBumpAnisotropy);a.mapNormal&&b&&e(i,"normalMap",a.mapNormal,a.mapNormalRepeat,a.mapNormalOffset,a.mapNormalWrap,a.mapNormalAnisotropy);a.mapSpecular&&b&&e(i,"specularMap",a.mapSpecular,a.mapSpecularRepeat, +a.mapSpecularOffset,a.mapSpecularWrap,a.mapSpecularAnisotropy);a.mapBumpScale&&(i.bumpScale=a.mapBumpScale);a.mapNormal?(g=THREE.ShaderLib.normalmap,k=THREE.UniformsUtils.clone(g.uniforms),k.tNormal.value=i.normalMap,a.mapNormalFactor&&k.uNormalScale.value.set(a.mapNormalFactor,a.mapNormalFactor),i.map&&(k.tDiffuse.value=i.map,k.enableDiffuse.value=!0),i.specularMap&&(k.tSpecular.value=i.specularMap,k.enableSpecular.value=!0),i.lightMap&&(k.tAO.value=i.lightMap,k.enableAO.value=!0),k.uDiffuseColor.value.setHex(i.color), +k.uSpecularColor.value.setHex(i.specular),k.uAmbientColor.value.setHex(i.ambient),k.uShininess.value=i.shininess,void 0!==i.opacity&&(k.uOpacity.value=i.opacity),g=new THREE.ShaderMaterial({fragmentShader:g.fragmentShader,vertexShader:g.vertexShader,uniforms:k,lights:!0,fog:!0}),i.transparent&&(g.transparent=!0)):g=new THREE[g](i);void 0!==a.DbgName&&(g.name=a.DbgName);return g}};THREE.XHRLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager}; +THREE.XHRLoader.prototype={constructor:THREE.XHRLoader,load:function(a,b,c,d){var e=this,f=new XMLHttpRequest;void 0!==b&&f.addEventListener("load",function(c){b(c.target.responseText);e.manager.itemEnd(a)},!1);void 0!==c&&f.addEventListener("progress",function(a){c(a)},!1);void 0!==d&&f.addEventListener("error",function(a){d(a)},!1);void 0!==this.crossOrigin&&(f.crossOrigin=this.crossOrigin);f.open("GET",a,!0);f.send(null);e.manager.itemStart(a)},setCrossOrigin:function(a){this.crossOrigin=a}};THREE.ImageLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager}; +THREE.ImageLoader.prototype={constructor:THREE.ImageLoader,load:function(a,b,c,d){var e=this,f=document.createElement("img");void 0!==b&&f.addEventListener("load",function(){e.manager.itemEnd(a);b(this)},!1);void 0!==c&&f.addEventListener("progress",function(a){c(a)},!1);void 0!==d&&f.addEventListener("error",function(a){d(a)},!1);void 0!==this.crossOrigin&&(f.crossOrigin=this.crossOrigin);f.src=a;e.manager.itemStart(a);return f},setCrossOrigin:function(a){this.crossOrigin=a}};THREE.JSONLoader=function(a){THREE.Loader.call(this,a);this.withCredentials=!1};THREE.JSONLoader.prototype=Object.create(THREE.Loader.prototype);THREE.JSONLoader.prototype.load=function(a,b,c){c=c&&"string"===typeof c?c:this.extractUrlBase(a);this.onLoadStart();this.loadAjaxJSON(this,a,b,c)}; +THREE.JSONLoader.prototype.loadAjaxJSON=function(a,b,c,d,e){var f=new XMLHttpRequest,h=0;f.onreadystatechange=function(){if(f.readyState===f.DONE)if(200===f.status||0===f.status){if(f.responseText){var g=JSON.parse(f.responseText),g=a.parse(g,d);c(g.geometry,g.materials)}else console.warn("THREE.JSONLoader: ["+b+"] seems to be unreachable or file there is empty");a.onLoadComplete()}else console.error("THREE.JSONLoader: Couldn't load ["+b+"] ["+f.status+"]");else f.readyState===f.LOADING?e&&(0===h&& +(h=f.getResponseHeader("Content-Length")),e({total:h,loaded:f.responseText.length})):f.readyState===f.HEADERS_RECEIVED&&void 0!==e&&(h=f.getResponseHeader("Content-Length"))};f.open("GET",b,!0);f.withCredentials=this.withCredentials;f.send(null)}; +THREE.JSONLoader.prototype.parse=function(a,b){var c=new THREE.Geometry,d=void 0!==a.scale?1/a.scale:1,e,f,h,g,i,k,m,l,p,r,t,n,s,q,u=a.faces;p=a.vertices;var w=a.normals,E=a.colors,C=0;if(void 0!==a.uvs){for(e=0;ef;f++)l=u[g++],q=s[2*l],l=s[2*l+1],q=new THREE.Vector2(q,l),2!==f&&c.faceVertexUvs[e][h].push(q),0!==f&&c.faceVertexUvs[e][h+1].push(q)}m&&(m=3*u[g++],r.normal.set(w[m++],w[m++],w[m]),n.normal.copy(r.normal));if(t)for(e=0;4>e;e++)m=3*u[g++],t=new THREE.Vector3(w[m++], +w[m++],w[m]),2!==e&&r.vertexNormals.push(t),0!==e&&n.vertexNormals.push(t);k&&(k=u[g++],k=E[k],r.color.setHex(k),n.color.setHex(k));if(p)for(e=0;4>e;e++)k=u[g++],k=E[k],2!==e&&r.vertexColors.push(new THREE.Color(k)),0!==e&&n.vertexColors.push(new THREE.Color(k));c.faces.push(r);c.faces.push(n)}else{r=new THREE.Face3;r.a=u[g++];r.b=u[g++];r.c=u[g++];h&&(h=u[g++],r.materialIndex=h);h=c.faces.length;if(e)for(e=0;ef;f++)l=u[g++],q=s[2*l],l=s[2*l+1], +q=new THREE.Vector2(q,l),c.faceVertexUvs[e][h].push(q)}m&&(m=3*u[g++],r.normal.set(w[m++],w[m++],w[m]));if(t)for(e=0;3>e;e++)m=3*u[g++],t=new THREE.Vector3(w[m++],w[m++],w[m]),r.vertexNormals.push(t);k&&(k=u[g++],r.color.setHex(E[k]));if(p)for(e=0;3>e;e++)k=u[g++],r.vertexColors.push(new THREE.Color(E[k]));c.faces.push(r)}if(a.skinWeights){g=0;for(i=a.skinWeights.length;gG.parameters.opacity&&(G.parameters.transparent=!0);G.parameters.normalMap?(D=THREE.ShaderLib.normalmap,v=THREE.UniformsUtils.clone(D.uniforms), +q=G.parameters.color,x=G.parameters.specular,s=G.parameters.ambient,I=G.parameters.shininess,v.tNormal.value=z.textures[G.parameters.normalMap],G.parameters.normalScale&&v.uNormalScale.value.set(G.parameters.normalScale[0],G.parameters.normalScale[1]),G.parameters.map&&(v.tDiffuse.value=G.parameters.map,v.enableDiffuse.value=!0),G.parameters.envMap&&(v.tCube.value=G.parameters.envMap,v.enableReflection.value=!0,v.uReflectivity.value=G.parameters.reflectivity),G.parameters.lightMap&&(v.tAO.value=G.parameters.lightMap, +v.enableAO.value=!0),G.parameters.specularMap&&(v.tSpecular.value=z.textures[G.parameters.specularMap],v.enableSpecular.value=!0),G.parameters.displacementMap&&(v.tDisplacement.value=z.textures[G.parameters.displacementMap],v.enableDisplacement.value=!0,v.uDisplacementBias.value=G.parameters.displacementBias,v.uDisplacementScale.value=G.parameters.displacementScale),v.uDiffuseColor.value.setHex(q),v.uSpecularColor.value.setHex(x),v.uAmbientColor.value.setHex(s),v.uShininess.value=I,G.parameters.opacity&& +(v.uOpacity.value=G.parameters.opacity),t=new THREE.ShaderMaterial({fragmentShader:D.fragmentShader,vertexShader:D.vertexShader,uniforms:v,lights:!0,fog:!0})):t=new THREE[G.type](G.parameters);t.name=Q;z.materials[Q]=t}for(Q in B.materials)if(G=B.materials[Q],G.parameters.materials){J=[];for(q=0;qg.end&&(g.end=e);b||(b=h)}}a.firstAnimation=b}; +THREE.MorphAnimMesh.prototype.setAnimationLabel=function(a,b,c){this.geometry.animations||(this.geometry.animations={});this.geometry.animations[a]={start:b,end:c}};THREE.MorphAnimMesh.prototype.playAnimation=function(a,b){var c=this.geometry.animations[a];c?(this.setFrameRange(c.start,c.end),this.duration=1E3*((c.end-c.start)/b),this.time=0):console.warn("animation["+a+"] undefined")}; +THREE.MorphAnimMesh.prototype.updateAnimation=function(a){var b=this.duration/this.length;this.time+=this.direction*a;if(this.mirroredLoop){if(this.time>this.duration||0>this.time)this.direction*=-1,this.time>this.duration&&(this.time=this.duration,this.directionBackwards=!0),0>this.time&&(this.time=0,this.directionBackwards=!1)}else this.time%=this.duration,0>this.time&&(this.time+=this.duration);a=this.startKeyframe+THREE.Math.clamp(Math.floor(this.time/b),0,this.length-1);a!==this.currentKeyframe&& +(this.morphTargetInfluences[this.lastKeyframe]=0,this.morphTargetInfluences[this.currentKeyframe]=1,this.morphTargetInfluences[a]=0,this.lastKeyframe=this.currentKeyframe,this.currentKeyframe=a);b=this.time%b/b;this.directionBackwards&&(b=1-b);this.morphTargetInfluences[this.currentKeyframe]=b;this.morphTargetInfluences[this.lastKeyframe]=1-b}; +THREE.MorphAnimMesh.prototype.clone=function(a){void 0===a&&(a=new THREE.MorphAnimMesh(this.geometry,this.material));a.duration=this.duration;a.mirroredLoop=this.mirroredLoop;a.time=this.time;a.lastKeyframe=this.lastKeyframe;a.currentKeyframe=this.currentKeyframe;a.direction=this.direction;a.directionBackwards=this.directionBackwards;THREE.Mesh.prototype.clone.call(this,a);return a};THREE.LOD=function(){THREE.Object3D.call(this);this.objects=[]};THREE.LOD.prototype=Object.create(THREE.Object3D.prototype);THREE.LOD.prototype.addLevel=function(a,b){void 0===b&&(b=0);for(var b=Math.abs(b),c=0;c=this.objects[d].distance)this.objects[d-1].object.visible=!1,this.objects[d].object.visible=!0;else break;for(;d=g||(g*=f.intensity,c.add(La.multiplyScalar(g)))}else f instanceof THREE.PointLight&&(h=ua.getPositionFromMatrix(f.matrixWorld),g=b.dot(ua.subVectors(h,a).normalize()),0>=g||(g*=0==f.distance?1:1-Math.min(a.distanceTo(h)/f.distance,1),0!=g&&(g*=f.intensity,c.add(La.multiplyScalar(g)))))}} +function c(a,b,c,d){m(b);l(c);p(d);r(a.getStyle());B.stroke();ra.expandByScalar(2*b)}function d(a){t(a.getStyle());B.fill()}function e(a,b,c,e,f,h,g,j,i,k,m,l,p){if(!(p instanceof THREE.DataTexture||void 0===p.image||0==p.image.width)){if(!0===p.needsUpdate){var n=p.wrapS==THREE.RepeatWrapping,s=p.wrapT==THREE.RepeatWrapping;Ga[p.id]=B.createPattern(p.image,!0===n&&!0===s?"repeat":!0===n&&!1===s?"repeat-x":!1===n&&!0===s?"repeat-y":"no-repeat");p.needsUpdate=!1}void 0===Ga[p.id]?t("rgba(0,0,0,1)"): +t(Ga[p.id]);var n=p.offset.x/p.repeat.x,s=p.offset.y/p.repeat.y,r=p.image.width*p.repeat.x,q=p.image.height*p.repeat.y,g=(g+n)*r,j=(1-j+s)*q,c=c-a,e=e-b,f=f-a,h=h-b,i=(i+n)*r-g,k=(1-k+s)*q-j,m=(m+n)*r-g,l=(1-l+s)*q-j,n=i*l-m*k;0===n?(void 0===fa[p.id]&&(b=document.createElement("canvas"),b.width=p.image.width,b.height=p.image.height,b=b.getContext("2d"),b.drawImage(p.image,0,0),fa[p.id]=b.getImageData(0,0,p.image.width,p.image.height).data),b=fa[p.id],g=4*(Math.floor(g)+Math.floor(j)*p.image.width), +V.setRGB(b[g]/255,b[g+1]/255,b[g+2]/255),d(V)):(n=1/n,p=(l*c-k*f)*n,k=(l*e-k*h)*n,c=(i*f-m*c)*n,e=(i*h-m*e)*n,a=a-p*g-c*j,g=b-k*g-e*j,B.save(),B.transform(p,k,c,e,a,g),B.fill(),B.restore())}}function f(a,b,c,d,e,f,h,g,j,i,k,m,l){var p,n;p=l.width-1;n=l.height-1;h*=p;g*=n;c-=a;d-=b;e-=a;f-=b;j=j*p-h;i=i*n-g;k=k*p-h;m=m*n-g;n=1/(j*m-k*i);p=(m*c-i*e)*n;i=(m*d-i*f)*n;c=(j*e-k*c)*n;d=(j*f-k*d)*n;a=a-p*h-c*g;b=b-i*h-d*g;B.save();B.transform(p,i,c,d,a,b);B.clip();B.drawImage(l,0,0);B.restore()}function h(a, +b,c,d){va[0]=255*a.r|0;va[1]=255*a.g|0;va[2]=255*a.b|0;va[4]=255*b.r|0;va[5]=255*b.g|0;va[6]=255*b.b|0;va[8]=255*c.r|0;va[9]=255*c.g|0;va[10]=255*c.b|0;va[12]=255*d.r|0;va[13]=255*d.g|0;va[14]=255*d.b|0;j.putImageData(Na,0,0);Fa.drawImage(Oa,0,0);return wa}function g(a,b,c){var d=b.x-a.x,e=b.y-a.y,f=d*d+e*e;0!==f&&(c/=Math.sqrt(f),d*=c,e*=c,b.x+=d,b.y+=e,a.x-=d,a.y-=e)}function i(a){v!==a&&(v=B.globalAlpha=a)}function k(a){x!==a&&(a===THREE.NormalBlending?B.globalCompositeOperation="source-over": +a===THREE.AdditiveBlending?B.globalCompositeOperation="lighter":a===THREE.SubtractiveBlending&&(B.globalCompositeOperation="darker"),x=a)}function m(a){J!==a&&(J=B.lineWidth=a)}function l(a){ca!==a&&(ca=B.lineCap=a)}function p(a){oa!==a&&(oa=B.lineJoin=a)}function r(a){G!==a&&(G=B.strokeStyle=a)}function t(a){Q!==a&&(Q=B.fillStyle=a)}function n(a,b){if(pa!==a||N!==b)B.setLineDash([a,b]),pa=a,N=b}console.log("THREE.CanvasRenderer",THREE.REVISION);var s=THREE.Math.smoothstep,a=a||{},q=this,u,w,E,C= +new THREE.Projector,F=void 0!==a.canvas?a.canvas:document.createElement("canvas"),y,A,z,O,B=F.getContext("2d"),D=new THREE.Color(0),I=0,v=1,x=0,G=null,Q=null,J=null,ca=null,oa=null,pa=null,N=0,M,R,K,da;new THREE.RenderableVertex;new THREE.RenderableVertex;var Aa,Ca,ba,Ba,$,ea,V=new THREE.Color,P=new THREE.Color,Y=new THREE.Color,U=new THREE.Color,ka=new THREE.Color,ta=new THREE.Color,ia=new THREE.Color,La=new THREE.Color,Ga={},fa={},Ea,Ta,Pa,xa,cb,db,ob,pb,qb,eb,Ha=new THREE.Box2,la=new THREE.Box2, +ra=new THREE.Box2,fb=new THREE.Color,sa=new THREE.Color,ga=new THREE.Color,ua=new THREE.Vector3,Oa,j,Na,va,wa,Fa,Qa=16;Oa=document.createElement("canvas");Oa.width=Oa.height=2;j=Oa.getContext("2d");j.fillStyle="rgba(0,0,0,1)";j.fillRect(0,0,2,2);Na=j.getImageData(0,0,2,2);va=Na.data;wa=document.createElement("canvas");wa.width=wa.height=Qa;Fa=wa.getContext("2d");Fa.translate(-Qa/2,-Qa/2);Fa.scale(Qa,Qa);Qa--;void 0===B.setLineDash&&(B.setLineDash=void 0!==B.mozDash?function(a){B.mozDash=null!==a[0]? +a:null}:function(){});this.domElement=F;this.devicePixelRatio=void 0!==a.devicePixelRatio?a.devicePixelRatio:void 0!==self.devicePixelRatio?self.devicePixelRatio:1;this.sortElements=this.sortObjects=this.autoClear=!0;this.info={render:{vertices:0,faces:0}};this.supportsVertexTextures=function(){};this.setFaceCulling=function(){};this.setSize=function(a,b,c){y=a*this.devicePixelRatio;A=b*this.devicePixelRatio;z=Math.floor(y/2);O=Math.floor(A/2);F.width=y;F.height=A;1!==this.devicePixelRatio&&!1!== +c&&(F.style.width=a+"px",F.style.height=b+"px");Ha.set(new THREE.Vector2(-z,-O),new THREE.Vector2(z,O));la.set(new THREE.Vector2(-z,-O),new THREE.Vector2(z,O));v=1;x=0;oa=ca=J=Q=G=null};this.setClearColor=function(a,b){D.set(a);I=void 0!==b?b:1;la.set(new THREE.Vector2(-z,-O),new THREE.Vector2(z,O))};this.setClearColorHex=function(a,b){console.warn("DEPRECATED: .setClearColorHex() is being removed. Use .setClearColor() instead.");this.setClearColor(a,b)};this.getMaxAnisotropy=function(){return 0}; +this.clear=function(){B.setTransform(1,0,0,-1,z,O);!1===la.empty()&&(la.intersect(Ha),la.expandByScalar(2),1>I&&B.clearRect(la.min.x|0,la.min.y|0,la.max.x-la.min.x|0,la.max.y-la.min.y|0),0>1,ca=I.height>>1,N=F.scale.x*z,D=F.scale.y*O,v=N*Q,x=D*ca,ra.min.set(y.x-v,y.y-x),ra.max.set(y.x+v,y.y+x),!1===Ha.isIntersectionBox(ra)?ra.makeEmpty():(B.save(),B.translate(y.x,y.y),B.rotate(-F.rotation),B.scale(N,-D),B.translate(-Q,-ca),B.drawImage(I,0,0),B.restore())):J instanceof THREE.ParticleCanvasMaterial&&(v=F.scale.x*z,x=F.scale.y*O,ra.min.set(y.x-v,y.y-x),ra.max.set(y.x+v,y.y+x),!1===Ha.isIntersectionBox(ra)?ra.makeEmpty():(r(J.color.getStyle()), +t(J.color.getStyle()),B.save(),B.translate(y.x,y.y),B.rotate(-F.rotation),B.scale(v,x),J.program(B),B.restore()))}else if(v instanceof THREE.RenderableLine){if(R=v.v1,K=v.v2,R.positionScreen.x*=z,R.positionScreen.y*=O,K.positionScreen.x*=z,K.positionScreen.y*=O,ra.setFromPoints([R.positionScreen,K.positionScreen]),!0===Ha.isIntersectionBox(ra))if(y=R,F=K,J=v,v=x,i(v.opacity),k(v.blending),B.beginPath(),B.moveTo(y.positionScreen.x,y.positionScreen.y),B.lineTo(F.positionScreen.x,F.positionScreen.y), +v instanceof THREE.LineBasicMaterial){m(v.linewidth);l(v.linecap);p(v.linejoin);if(v.vertexColors!==THREE.VertexColors)r(v.color.getStyle());else if(x=J.vertexColors[0].getStyle(),J=J.vertexColors[1].getStyle(),x===J)r(x);else{try{var fa=B.createLinearGradient(y.positionScreen.x,y.positionScreen.y,F.positionScreen.x,F.positionScreen.y);fa.addColorStop(0,x);fa.addColorStop(1,J)}catch(oa){fa=x}r(fa)}B.stroke();ra.expandByScalar(2*v.linewidth)}else v instanceof THREE.LineDashedMaterial&&(m(v.linewidth), +l(v.linecap),p(v.linejoin),r(v.color.getStyle()),n(v.dashSize,v.gapSize),B.stroke(),ra.expandByScalar(2*v.linewidth),n(null,null))}else if(v instanceof THREE.RenderableFace3){R=v.v1;K=v.v2;da=v.v3;if(-1>R.positionScreen.z||1K.positionScreen.z||1da.positionScreen.z||1 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_HEMI_LIGHTS > 0\nuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\nuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\nuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif", +lights_lambert_vertex:"vLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\nvLightBack = vec3( 0.0 );\n#endif\ntransformedNormal = normalize( transformedNormal );\n#if MAX_DIR_LIGHTS > 0\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( transformedNormal, dirVector );\nvec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );\n#ifdef DOUBLE_SIDED\nvec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n#ifdef WRAP_AROUND\nvec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n#endif\n#endif\n#ifdef WRAP_AROUND\nvec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\ndirectionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );\n#ifdef DOUBLE_SIDED\ndirectionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );\n#endif\n#endif\nvLightFront += directionalLightColor[ i ] * directionalLightWeighting;\n#ifdef DOUBLE_SIDED\nvLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;\n#endif\n}\n#endif\n#if MAX_POINT_LIGHTS > 0\nfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\nfloat dotProduct = dot( transformedNormal, lVector );\nvec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );\n#ifdef DOUBLE_SIDED\nvec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n#ifdef WRAP_AROUND\nvec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n#endif\n#endif\n#ifdef WRAP_AROUND\nvec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\npointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );\n#ifdef DOUBLE_SIDED\npointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );\n#endif\n#endif\nvLightFront += pointLightColor[ i ] * pointLightWeighting * lDistance;\n#ifdef DOUBLE_SIDED\nvLightBack += pointLightColor[ i ] * pointLightWeightingBack * lDistance;\n#endif\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nfor( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - worldPosition.xyz ) );\nif ( spotEffect > spotLightAngleCos[ i ] ) {\nspotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );\nfloat lDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\nfloat dotProduct = dot( transformedNormal, lVector );\nvec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );\n#ifdef DOUBLE_SIDED\nvec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );\n#ifdef WRAP_AROUND\nvec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );\n#endif\n#endif\n#ifdef WRAP_AROUND\nvec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );\nspotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );\n#ifdef DOUBLE_SIDED\nspotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );\n#endif\n#endif\nvLightFront += spotLightColor[ i ] * spotLightWeighting * lDistance * spotEffect;\n#ifdef DOUBLE_SIDED\nvLightBack += spotLightColor[ i ] * spotLightWeightingBack * lDistance * spotEffect;\n#endif\n}\n}\n#endif\n#if MAX_HEMI_LIGHTS > 0\nfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );\nvec3 lVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( transformedNormal, lVector );\nfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\nfloat hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;\nvLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\n#ifdef DOUBLE_SIDED\nvLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );\n#endif\n}\n#endif\nvLightFront = vLightFront * diffuse + ambient * ambientLightColor + emissive;\n#ifdef DOUBLE_SIDED\nvLightBack = vLightBack * diffuse + ambient * ambientLightColor + emissive;\n#endif", +lights_phong_pars_vertex:"#ifndef PHONG_PER_PIXEL\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\nvarying vec4 vPointLight[ MAX_POINT_LIGHTS ];\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\nvarying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];\n#endif\n#endif\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )\nvarying vec3 vWorldPosition;\n#endif", +lights_phong_vertex:"#ifndef PHONG_PER_PIXEL\n#if MAX_POINT_LIGHTS > 0\nfor( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nvPointLight[ i ] = vec4( lVector, lDistance );\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nfor( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz - mvPosition.xyz;\nfloat lDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );\nvSpotLight[ i ] = vec4( lVector, lDistance );\n}\n#endif\n#endif\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )\nvWorldPosition = worldPosition.xyz;\n#endif", +lights_phong_pars_fragment:"uniform vec3 ambientLightColor;\n#if MAX_DIR_LIGHTS > 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_HEMI_LIGHTS > 0\nuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\n#ifdef PHONG_PER_PIXEL\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n#else\nvarying vec4 vPointLight[ MAX_POINT_LIGHTS ];\n#endif\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\nuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\nuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\n#ifdef PHONG_PER_PIXEL\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n#else\nvarying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];\n#endif\n#endif\n#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )\nvarying vec3 vWorldPosition;\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif\nvarying vec3 vViewPosition;\nvarying vec3 vNormal;", +lights_phong_fragment:"vec3 normal = normalize( vNormal );\nvec3 viewPosition = normalize( vViewPosition );\n#ifdef DOUBLE_SIDED\nnormal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n#endif\n#ifdef USE_NORMALMAP\nnormal = perturbNormal2Arb( -vViewPosition, normal );\n#elif defined( USE_BUMPMAP )\nnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n#if MAX_POINT_LIGHTS > 0\nvec3 pointDiffuse = vec3( 0.0 );\nvec3 pointSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\n#ifdef PHONG_PER_PIXEL\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz + vViewPosition.xyz;\nfloat lDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\n#else\nvec3 lVector = normalize( vPointLight[ i ].xyz );\nfloat lDistance = vPointLight[ i ].w;\n#endif\nfloat dotProduct = dot( normal, lVector );\n#ifdef WRAP_AROUND\nfloat pointDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n#else\nfloat pointDiffuseWeight = max( dotProduct, 0.0 );\n#endif\npointDiffuse += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;\nvec3 pointHalfVector = normalize( lVector + viewPosition );\nfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\nfloat pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, pointHalfVector ), 5.0 );\npointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;\n#else\npointSpecular += specular * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance;\n#endif\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nvec3 spotDiffuse = vec3( 0.0 );\nvec3 spotSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\n#ifdef PHONG_PER_PIXEL\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 lVector = lPosition.xyz + vViewPosition.xyz;\nfloat lDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nlDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );\nlVector = normalize( lVector );\n#else\nvec3 lVector = normalize( vSpotLight[ i ].xyz );\nfloat lDistance = vSpotLight[ i ].w;\n#endif\nfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\nif ( spotEffect > spotLightAngleCos[ i ] ) {\nspotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );\nfloat dotProduct = dot( normal, lVector );\n#ifdef WRAP_AROUND\nfloat spotDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n#else\nfloat spotDiffuseWeight = max( dotProduct, 0.0 );\n#endif\nspotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;\nvec3 spotHalfVector = normalize( lVector + viewPosition );\nfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\nfloat spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, spotHalfVector ), 5.0 );\nspotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;\n#else\nspotSpecular += specular * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * spotEffect;\n#endif\n}\n}\n#endif\n#if MAX_DIR_LIGHTS > 0\nvec3 dirDiffuse = vec3( 0.0 );\nvec3 dirSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( normal, dirVector );\n#ifdef WRAP_AROUND\nfloat dirDiffuseWeightFull = max( dotProduct, 0.0 );\nfloat dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );\nvec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );\n#else\nfloat dirDiffuseWeight = max( dotProduct, 0.0 );\n#endif\ndirDiffuse += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;\nvec3 dirHalfVector = normalize( dirVector + viewPosition );\nfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\nfloat dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );\ndirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n#else\ndirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight;\n#endif\n}\n#endif\n#if MAX_HEMI_LIGHTS > 0\nvec3 hemiDiffuse = vec3( 0.0 );\nvec3 hemiSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );\nvec3 lVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( normal, lVector );\nfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\nvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\nhemiDiffuse += diffuse * hemiColor;\nvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\nfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\nfloat hemiSpecularWeightSky = specularStrength * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );\nvec3 lVectorGround = -lVector;\nvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\nfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\nfloat hemiSpecularWeightGround = specularStrength * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat dotProductGround = dot( normal, lVectorGround );\nfloat specularNormalization = ( shininess + 2.0001 ) / 8.0;\nvec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );\nvec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );\nhemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n#else\nhemiSpecular += specular * hemiColor * ( hemiSpecularWeightSky + hemiSpecularWeightGround ) * hemiDiffuseWeight;\n#endif\n}\n#endif\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n#if MAX_DIR_LIGHTS > 0\ntotalDiffuse += dirDiffuse;\ntotalSpecular += dirSpecular;\n#endif\n#if MAX_HEMI_LIGHTS > 0\ntotalDiffuse += hemiDiffuse;\ntotalSpecular += hemiSpecular;\n#endif\n#if MAX_POINT_LIGHTS > 0\ntotalDiffuse += pointDiffuse;\ntotalSpecular += pointSpecular;\n#endif\n#if MAX_SPOT_LIGHTS > 0\ntotalDiffuse += spotDiffuse;\ntotalSpecular += spotSpecular;\n#endif\n#ifdef METAL\ngl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular );\n#else\ngl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular;\n#endif", +color_pars_fragment:"#ifdef USE_COLOR\nvarying vec3 vColor;\n#endif",color_fragment:"#ifdef USE_COLOR\ngl_FragColor = gl_FragColor * vec4( vColor, opacity );\n#endif",color_pars_vertex:"#ifdef USE_COLOR\nvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n#ifdef GAMMA_INPUT\nvColor = color * color;\n#else\nvColor = color;\n#endif\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n#ifdef BONE_TEXTURE\nuniform sampler2D boneTexture;\nuniform int boneTextureWidth;\nuniform int boneTextureHeight;\nmat4 getBoneMatrix( const in float i ) {\nfloat j = i * 4.0;\nfloat x = mod( j, float( boneTextureWidth ) );\nfloat y = floor( j / float( boneTextureWidth ) );\nfloat dx = 1.0 / float( boneTextureWidth );\nfloat dy = 1.0 / float( boneTextureHeight );\ny = dy * ( y + 0.5 );\nvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\nvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\nvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\nvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\nmat4 bone = mat4( v1, v2, v3, v4 );\nreturn bone;\n}\n#else\nuniform mat4 boneGlobalMatrices[ MAX_BONES ];\nmat4 getBoneMatrix( const in float i ) {\nmat4 bone = boneGlobalMatrices[ int(i) ];\nreturn bone;\n}\n#endif\n#endif", +skinbase_vertex:"#ifdef USE_SKINNING\nmat4 boneMatX = getBoneMatrix( skinIndex.x );\nmat4 boneMatY = getBoneMatrix( skinIndex.y );\n#endif",skinning_vertex:"#ifdef USE_SKINNING\n#ifdef USE_MORPHTARGETS\nvec4 skinVertex = vec4( morphed, 1.0 );\n#else\nvec4 skinVertex = vec4( position, 1.0 );\n#endif\nvec4 skinned = boneMatX * skinVertex * skinWeight.x;\nskinned \t += boneMatY * skinVertex * skinWeight.y;\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n#ifndef USE_MORPHNORMALS\nuniform float morphTargetInfluences[ 8 ];\n#else\nuniform float morphTargetInfluences[ 4 ];\n#endif\n#endif", +morphtarget_vertex:"#ifdef USE_MORPHTARGETS\nvec3 morphed = vec3( 0.0 );\nmorphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\nmorphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\nmorphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\nmorphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n#ifndef USE_MORPHNORMALS\nmorphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\nmorphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\nmorphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\nmorphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n#endif\nmorphed += position;\n#endif", +default_vertex:"vec4 mvPosition;\n#ifdef USE_SKINNING\nmvPosition = modelViewMatrix * skinned;\n#endif\n#if !defined( USE_SKINNING ) && defined( USE_MORPHTARGETS )\nmvPosition = modelViewMatrix * vec4( morphed, 1.0 );\n#endif\n#if !defined( USE_SKINNING ) && ! defined( USE_MORPHTARGETS )\nmvPosition = modelViewMatrix * vec4( position, 1.0 );\n#endif\ngl_Position = projectionMatrix * mvPosition;",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\nvec3 morphedNormal = vec3( 0.0 );\nmorphedNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\nmorphedNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\nmorphedNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\nmorphedNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\nmorphedNormal += normal;\n#endif", +skinnormal_vertex:"#ifdef USE_SKINNING\nmat4 skinMatrix = skinWeight.x * boneMatX;\nskinMatrix \t+= skinWeight.y * boneMatY;\n#ifdef USE_MORPHNORMALS\nvec4 skinnedNormal = skinMatrix * vec4( morphedNormal, 0.0 );\n#else\nvec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );\n#endif\n#endif",defaultnormal_vertex:"vec3 objectNormal;\n#ifdef USE_SKINNING\nobjectNormal = skinnedNormal.xyz;\n#endif\n#if !defined( USE_SKINNING ) && defined( USE_MORPHNORMALS )\nobjectNormal = morphedNormal;\n#endif\n#if !defined( USE_SKINNING ) && ! defined( USE_MORPHNORMALS )\nobjectNormal = normal;\n#endif\n#ifdef FLIP_SIDED\nobjectNormal = -objectNormal;\n#endif\nvec3 transformedNormal = normalMatrix * objectNormal;", +shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\nuniform sampler2D shadowMap[ MAX_SHADOWS ];\nuniform vec2 shadowMapSize[ MAX_SHADOWS ];\nuniform float shadowDarkness[ MAX_SHADOWS ];\nuniform float shadowBias[ MAX_SHADOWS ];\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nfloat unpackDepth( const in vec4 rgba_depth ) {\nconst vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\nfloat depth = dot( rgba_depth, bit_shift );\nreturn depth;\n}\n#endif",shadowmap_fragment:"#ifdef USE_SHADOWMAP\n#ifdef SHADOWMAP_DEBUG\nvec3 frustumColors[3];\nfrustumColors[0] = vec3( 1.0, 0.5, 0.0 );\nfrustumColors[1] = vec3( 0.0, 1.0, 0.8 );\nfrustumColors[2] = vec3( 0.0, 0.5, 1.0 );\n#endif\n#ifdef SHADOWMAP_CASCADE\nint inFrustumCount = 0;\n#endif\nfloat fDepth;\nvec3 shadowColor = vec3( 1.0 );\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\nbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\nbool inFrustum = all( inFrustumVec );\n#ifdef SHADOWMAP_CASCADE\ninFrustumCount += int( inFrustum );\nbvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );\n#else\nbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n#endif\nbool frustumTest = all( frustumTestVec );\nif ( frustumTest ) {\nshadowCoord.z += shadowBias[ i ];\n#if defined( SHADOWMAP_TYPE_PCF )\nfloat shadow = 0.0;\nconst float shadowDelta = 1.0 / 9.0;\nfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\nfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\nfloat dx0 = -1.25 * xPixelOffset;\nfloat dy0 = -1.25 * yPixelOffset;\nfloat dx1 = 1.25 * xPixelOffset;\nfloat dy1 = 1.25 * yPixelOffset;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nfDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\nif ( fDepth < shadowCoord.z ) shadow += shadowDelta;\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\nfloat shadow = 0.0;\nfloat xPixelOffset = 1.0 / shadowMapSize[ i ].x;\nfloat yPixelOffset = 1.0 / shadowMapSize[ i ].y;\nfloat dx0 = -1.0 * xPixelOffset;\nfloat dy0 = -1.0 * yPixelOffset;\nfloat dx1 = 1.0 * xPixelOffset;\nfloat dy1 = 1.0 * yPixelOffset;\nmat3 shadowKernel;\nmat3 depthKernel;\ndepthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );\ndepthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );\ndepthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );\ndepthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );\ndepthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );\ndepthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );\ndepthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );\ndepthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );\ndepthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );\nvec3 shadowZ = vec3( shadowCoord.z );\nshadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ ));\nshadowKernel[0] *= vec3(0.25);\nshadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ ));\nshadowKernel[1] *= vec3(0.25);\nshadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ ));\nshadowKernel[2] *= vec3(0.25);\nvec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy );\nshadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x );\nshadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x );\nvec4 shadowValues;\nshadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y );\nshadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y );\nshadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y );\nshadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y );\nshadow = dot( shadowValues, vec4( 1.0 ) );\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );\n#else\nvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );\n#endif\n}\n#ifdef SHADOWMAP_DEBUG\n#ifdef SHADOWMAP_CASCADE\nif ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];\n#else\nif ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];\n#endif\n#endif\n}\n#ifdef GAMMA_OUTPUT\nshadowColor *= shadowColor;\n#endif\ngl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n#endif", +shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nuniform mat4 shadowMatrix[ MAX_SHADOWS ];\n#endif",shadowmap_vertex:"#ifdef USE_SHADOWMAP\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;\n}\n#endif",alphatest_fragment:"#ifdef ALPHATEST\nif ( gl_FragColor.a < ALPHATEST ) discard;\n#endif",linear_to_gamma_fragment:"#ifdef GAMMA_OUTPUT\ngl_FragColor.xyz = sqrt( gl_FragColor.xyz );\n#endif"}; +THREE.UniformsUtils={merge:function(a){var b,c,d,e={};for(b=0;b dashSize ) {\ndiscard;\n}\ngl_FragColor = vec4( diffuse, opacity );",THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n")},depth:{uniforms:{mNear:{type:"f",value:1},mFar:{type:"f",value:2E3},opacity:{type:"f", +value:1}},vertexShader:"void main() {\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform float mNear;\nuniform float mFar;\nuniform float opacity;\nvoid main() {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat color = 1.0 - smoothstep( mNear, mFar, depth );\ngl_FragColor = vec4( vec3( color ), opacity );\n}"},normal:{uniforms:{opacity:{type:"f",value:1}},vertexShader:["varying vec3 vNormal;",THREE.ShaderChunk.morphtarget_pars_vertex,"void main() {\nvNormal = normalize( normalMatrix * normal );", +THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.default_vertex,"}"].join("\n"),fragmentShader:"uniform float opacity;\nvarying vec3 vNormal;\nvoid main() {\ngl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );\n}"},normalmap:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{enableAO:{type:"i",value:0},enableDiffuse:{type:"i",value:0},enableSpecular:{type:"i",value:0},enableReflection:{type:"i",value:0},enableDisplacement:{type:"i", +value:0},tDisplacement:{type:"t",value:null},tDiffuse:{type:"t",value:null},tCube:{type:"t",value:null},tNormal:{type:"t",value:null},tSpecular:{type:"t",value:null},tAO:{type:"t",value:null},uNormalScale:{type:"v2",value:new THREE.Vector2(1,1)},uDisplacementBias:{type:"f",value:0},uDisplacementScale:{type:"f",value:1},uDiffuseColor:{type:"c",value:new THREE.Color(16777215)},uSpecularColor:{type:"c",value:new THREE.Color(1118481)},uAmbientColor:{type:"c",value:new THREE.Color(16777215)},uShininess:{type:"f", +value:30},uOpacity:{type:"f",value:1},useRefract:{type:"i",value:0},uRefractionRatio:{type:"f",value:0.98},uReflectivity:{type:"f",value:0.5},uOffset:{type:"v2",value:new THREE.Vector2(0,0)},uRepeat:{type:"v2",value:new THREE.Vector2(1,1)},wrapRGB:{type:"v3",value:new THREE.Vector3(1,1,1)}}]),fragmentShader:["uniform vec3 uAmbientColor;\nuniform vec3 uDiffuseColor;\nuniform vec3 uSpecularColor;\nuniform float uShininess;\nuniform float uOpacity;\nuniform bool enableDiffuse;\nuniform bool enableSpecular;\nuniform bool enableAO;\nuniform bool enableReflection;\nuniform sampler2D tDiffuse;\nuniform sampler2D tNormal;\nuniform sampler2D tSpecular;\nuniform sampler2D tAO;\nuniform samplerCube tCube;\nuniform vec2 uNormalScale;\nuniform bool useRefract;\nuniform float uRefractionRatio;\nuniform float uReflectivity;\nvarying vec3 vTangent;\nvarying vec3 vBinormal;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nuniform vec3 ambientLightColor;\n#if MAX_DIR_LIGHTS > 0\nuniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];\nuniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];\n#endif\n#if MAX_HEMI_LIGHTS > 0\nuniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];\nuniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ];\n#endif\n#if MAX_POINT_LIGHTS > 0\nuniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];\nuniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];\nuniform float pointLightDistance[ MAX_POINT_LIGHTS ];\n#endif\n#if MAX_SPOT_LIGHTS > 0\nuniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];\nuniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];\nuniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ];\nuniform float spotLightExponent[ MAX_SPOT_LIGHTS ];\nuniform float spotLightDistance[ MAX_SPOT_LIGHTS ];\n#endif\n#ifdef WRAP_AROUND\nuniform vec3 wrapRGB;\n#endif\nvarying vec3 vWorldPosition;\nvarying vec3 vViewPosition;", +THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,"void main() {\ngl_FragColor = vec4( vec3( 1.0 ), uOpacity );\nvec3 specularTex = vec3( 1.0 );\nvec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;\nnormalTex.xy *= uNormalScale;\nnormalTex = normalize( normalTex );\nif( enableDiffuse ) {\n#ifdef GAMMA_INPUT\nvec4 texelColor = texture2D( tDiffuse, vUv );\ntexelColor.xyz *= texelColor.xyz;\ngl_FragColor = gl_FragColor * texelColor;\n#else\ngl_FragColor = gl_FragColor * texture2D( tDiffuse, vUv );\n#endif\n}\nif( enableAO ) {\n#ifdef GAMMA_INPUT\nvec4 aoColor = texture2D( tAO, vUv );\naoColor.xyz *= aoColor.xyz;\ngl_FragColor.xyz = gl_FragColor.xyz * aoColor.xyz;\n#else\ngl_FragColor.xyz = gl_FragColor.xyz * texture2D( tAO, vUv ).xyz;\n#endif\n}\nif( enableSpecular )\nspecularTex = texture2D( tSpecular, vUv ).xyz;\nmat3 tsb = mat3( normalize( vTangent ), normalize( vBinormal ), normalize( vNormal ) );\nvec3 finalNormal = tsb * normalTex;\n#ifdef FLIP_SIDED\nfinalNormal = -finalNormal;\n#endif\nvec3 normal = normalize( finalNormal );\nvec3 viewPosition = normalize( vViewPosition );\n#if MAX_POINT_LIGHTS > 0\nvec3 pointDiffuse = vec3( 0.0 );\nvec3 pointSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );\nvec3 pointVector = lPosition.xyz + vViewPosition.xyz;\nfloat pointDistance = 1.0;\nif ( pointLightDistance[ i ] > 0.0 )\npointDistance = 1.0 - min( ( length( pointVector ) / pointLightDistance[ i ] ), 1.0 );\npointVector = normalize( pointVector );\n#ifdef WRAP_AROUND\nfloat pointDiffuseWeightFull = max( dot( normal, pointVector ), 0.0 );\nfloat pointDiffuseWeightHalf = max( 0.5 * dot( normal, pointVector ) + 0.5, 0.0 );\nvec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );\n#else\nfloat pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );\n#endif\npointDiffuse += pointDistance * pointLightColor[ i ] * uDiffuseColor * pointDiffuseWeight;\nvec3 pointHalfVector = normalize( pointVector + viewPosition );\nfloat pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );\nfloat pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, uShininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( uShininess + 2.0001 ) / 8.0;\nvec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( pointVector, pointHalfVector ), 5.0 );\npointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;\n#else\npointSpecular += pointDistance * pointLightColor[ i ] * uSpecularColor * pointSpecularWeight * pointDiffuseWeight;\n#endif\n}\n#endif\n#if MAX_SPOT_LIGHTS > 0\nvec3 spotDiffuse = vec3( 0.0 );\nvec3 spotSpecular = vec3( 0.0 );\nfor ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {\nvec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );\nvec3 spotVector = lPosition.xyz + vViewPosition.xyz;\nfloat spotDistance = 1.0;\nif ( spotLightDistance[ i ] > 0.0 )\nspotDistance = 1.0 - min( ( length( spotVector ) / spotLightDistance[ i ] ), 1.0 );\nspotVector = normalize( spotVector );\nfloat spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );\nif ( spotEffect > spotLightAngleCos[ i ] ) {\nspotEffect = max( pow( spotEffect, spotLightExponent[ i ] ), 0.0 );\n#ifdef WRAP_AROUND\nfloat spotDiffuseWeightFull = max( dot( normal, spotVector ), 0.0 );\nfloat spotDiffuseWeightHalf = max( 0.5 * dot( normal, spotVector ) + 0.5, 0.0 );\nvec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );\n#else\nfloat spotDiffuseWeight = max( dot( normal, spotVector ), 0.0 );\n#endif\nspotDiffuse += spotDistance * spotLightColor[ i ] * uDiffuseColor * spotDiffuseWeight * spotEffect;\nvec3 spotHalfVector = normalize( spotVector + viewPosition );\nfloat spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );\nfloat spotSpecularWeight = specularTex.r * max( pow( spotDotNormalHalf, uShininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( uShininess + 2.0001 ) / 8.0;\nvec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( spotVector, spotHalfVector ), 5.0 );\nspotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;\n#else\nspotSpecular += spotDistance * spotLightColor[ i ] * uSpecularColor * spotSpecularWeight * spotDiffuseWeight * spotEffect;\n#endif\n}\n}\n#endif\n#if MAX_DIR_LIGHTS > 0\nvec3 dirDiffuse = vec3( 0.0 );\nvec3 dirSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {\nvec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\n#ifdef WRAP_AROUND\nfloat directionalLightWeightingFull = max( dot( normal, dirVector ), 0.0 );\nfloat directionalLightWeightingHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );\nvec3 dirDiffuseWeight = mix( vec3( directionalLightWeightingFull ), vec3( directionalLightWeightingHalf ), wrapRGB );\n#else\nfloat dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );\n#endif\ndirDiffuse += directionalLightColor[ i ] * uDiffuseColor * dirDiffuseWeight;\nvec3 dirHalfVector = normalize( dirVector + viewPosition );\nfloat dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );\nfloat dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, uShininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat specularNormalization = ( uShininess + 2.0001 ) / 8.0;\nvec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );\ndirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;\n#else\ndirSpecular += directionalLightColor[ i ] * uSpecularColor * dirSpecularWeight * dirDiffuseWeight;\n#endif\n}\n#endif\n#if MAX_HEMI_LIGHTS > 0\nvec3 hemiDiffuse = vec3( 0.0 );\nvec3 hemiSpecular = vec3( 0.0 );\nfor( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {\nvec4 lDirection = viewMatrix * vec4( hemisphereLightDirection[ i ], 0.0 );\nvec3 lVector = normalize( lDirection.xyz );\nfloat dotProduct = dot( normal, lVector );\nfloat hemiDiffuseWeight = 0.5 * dotProduct + 0.5;\nvec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );\nhemiDiffuse += uDiffuseColor * hemiColor;\nvec3 hemiHalfVectorSky = normalize( lVector + viewPosition );\nfloat hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;\nfloat hemiSpecularWeightSky = specularTex.r * max( pow( hemiDotNormalHalfSky, uShininess ), 0.0 );\nvec3 lVectorGround = -lVector;\nvec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );\nfloat hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;\nfloat hemiSpecularWeightGround = specularTex.r * max( pow( hemiDotNormalHalfGround, uShininess ), 0.0 );\n#ifdef PHYSICALLY_BASED_SHADING\nfloat dotProductGround = dot( normal, lVectorGround );\nfloat specularNormalization = ( uShininess + 2.0001 ) / 8.0;\nvec3 schlickSky = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );\nvec3 schlickGround = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );\nhemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );\n#else\nhemiSpecular += uSpecularColor * hemiColor * ( hemiSpecularWeightSky + hemiSpecularWeightGround ) * hemiDiffuseWeight;\n#endif\n}\n#endif\nvec3 totalDiffuse = vec3( 0.0 );\nvec3 totalSpecular = vec3( 0.0 );\n#if MAX_DIR_LIGHTS > 0\ntotalDiffuse += dirDiffuse;\ntotalSpecular += dirSpecular;\n#endif\n#if MAX_HEMI_LIGHTS > 0\ntotalDiffuse += hemiDiffuse;\ntotalSpecular += hemiSpecular;\n#endif\n#if MAX_POINT_LIGHTS > 0\ntotalDiffuse += pointDiffuse;\ntotalSpecular += pointSpecular;\n#endif\n#if MAX_SPOT_LIGHTS > 0\ntotalDiffuse += spotDiffuse;\ntotalSpecular += spotSpecular;\n#endif\n#ifdef METAL\ngl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor + totalSpecular );\n#else\ngl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor ) + totalSpecular;\n#endif\nif ( enableReflection ) {\nvec3 vReflect;\nvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\nif ( useRefract ) {\nvReflect = refract( cameraToVertex, normal, uRefractionRatio );\n} else {\nvReflect = reflect( cameraToVertex, normal );\n}\nvec4 cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );\n#ifdef GAMMA_INPUT\ncubeColor.xyz *= cubeColor.xyz;\n#endif\ngl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularTex.r * uReflectivity );\n}", +THREE.ShaderChunk.shadowmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"}"].join("\n"),vertexShader:["attribute vec4 tangent;\nuniform vec2 uOffset;\nuniform vec2 uRepeat;\nuniform bool enableDisplacement;\n#ifdef VERTEX_TEXTURES\nuniform sampler2D tDisplacement;\nuniform float uDisplacementScale;\nuniform float uDisplacementBias;\n#endif\nvarying vec3 vTangent;\nvarying vec3 vBinormal;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec3 vWorldPosition;\nvarying vec3 vViewPosition;", +THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex,"#ifdef USE_SKINNING\nvNormal = normalize( normalMatrix * skinnedNormal.xyz );\nvec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );\nvTangent = normalize( normalMatrix * skinnedTangent.xyz );\n#else\nvNormal = normalize( normalMatrix * normal );\nvTangent = normalize( normalMatrix * tangent.xyz );\n#endif\nvBinormal = normalize( cross( vNormal, vTangent ) * tangent.w );\nvUv = uv * uRepeat + uOffset;\nvec3 displacedPosition;\n#ifdef VERTEX_TEXTURES\nif ( enableDisplacement ) {\nvec3 dv = texture2D( tDisplacement, uv ).xyz;\nfloat df = uDisplacementScale * dv.x + uDisplacementBias;\ndisplacedPosition = position + normalize( normal ) * df;\n} else {\n#ifdef USE_SKINNING\nvec4 skinVertex = vec4( position, 1.0 );\nvec4 skinned = boneMatX * skinVertex * skinWeight.x;\nskinned \t += boneMatY * skinVertex * skinWeight.y;\ndisplacedPosition = skinned.xyz;\n#else\ndisplacedPosition = position;\n#endif\n}\n#else\n#ifdef USE_SKINNING\nvec4 skinVertex = vec4( position, 1.0 );\nvec4 skinned = boneMatX * skinVertex * skinWeight.x;\nskinned \t += boneMatY * skinVertex * skinWeight.y;\ndisplacedPosition = skinned.xyz;\n#else\ndisplacedPosition = position;\n#endif\n#endif\nvec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );\nvec4 worldPosition = modelMatrix * vec4( displacedPosition, 1.0 );\ngl_Position = projectionMatrix * mvPosition;\nvWorldPosition = worldPosition.xyz;\nvViewPosition = -mvPosition.xyz;\n#ifdef USE_SHADOWMAP\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;\n}\n#endif\n}"].join("\n")}, +cube:{uniforms:{tCube:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:"varying vec3 vWorldPosition;\nvoid main() {\nvec4 worldPosition = modelMatrix * vec4( position, 1.0 );\nvWorldPosition = worldPosition.xyz;\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\nvoid main() {\ngl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n}"}, +depthRGBA:{uniforms:{},vertexShader:[THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.default_vertex,"}"].join("\n"),fragmentShader:"vec4 pack_depth( const in float depth ) {\nconst vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\nconst vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\nvec4 res = fract( depth * bit_shift );\nres -= res.xxyz * bit_mask;\nreturn res;\n}\nvoid main() {\ngl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );\n}"}};THREE.WebGLRenderer=function(a){function b(a,b){var c=a.vertices.length,d=b.material;if(d.attributes){void 0===a.__webglCustomAttributesList&&(a.__webglCustomAttributesList=[]);for(var e in d.attributes){var f=d.attributes[e];if(!f.__webglInitialized||f.createUniqueBuffers){f.__webglInitialized=!0;var h=1;"v2"===f.type?h=2:"v3"===f.type?h=3:"v4"===f.type?h=4:"c"===f.type&&(h=3);f.size=h;f.array=new Float32Array(c*h);f.buffer=j.createBuffer();f.buffer.belongsToAttribute=e;f.needsUpdate=!0}a.__webglCustomAttributesList.push(f)}}} +function c(a,b){var c=b.geometry,h=a.faces3,g=3*h.length,i=1*h.length,k=3*h.length,h=d(b,a),m=f(h),l=e(h),p=h.vertexColors?h.vertexColors:!1;a.__vertexArray=new Float32Array(3*g);l&&(a.__normalArray=new Float32Array(3*g));c.hasTangents&&(a.__tangentArray=new Float32Array(4*g));p&&(a.__colorArray=new Float32Array(3*g));m&&(0l;l++)K.autoScaleCubemaps&&!f?(p=k,q=l,t=c.image[l],w=ac,t.width<=w&&t.height<=w||(v=Math.max(t.width,t.height),u=Math.floor(t.width*w/v),w=Math.floor(t.height*w/v),v=document.createElement("canvas"),v.width=u,v.height=w,v.getContext("2d").drawImage(t,0,0,t.width,t.height,0,0,u,w),t=v),p[q]=t):k[l]=c.image[l];l=k[0];p=0===(l.width&l.width-1)&&0===(l.height&l.height-1);q=x(c.format);t=x(c.type);D(j.TEXTURE_CUBE_MAP, +c,p);for(l=0;6>l;l++)if(f){w=k[l].mipmaps;v=0;for(z=w.length;v=Nb&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+Nb);P+=1;return a}function F(a,b,c,d){a[b]=c.r*c.r*d;a[b+1]=c.g*c.g*d;a[b+2]=c.b*c.b*d}function y(a,b,c,d){a[b]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function A(a){a!==xa&&(j.lineWidth(a),xa=a)}function z(a,b,c){Ea!==a&&(a?j.enable(j.POLYGON_OFFSET_FILL):j.disable(j.POLYGON_OFFSET_FILL),Ea=a); +if(a&&(Ta!==b||Pa!==c))j.polygonOffset(b,c),Ta=b,Pa=c}function O(a){for(var a=a.split("\n"),b=0,c=a.length;bb;b++)j.deleteFramebuffer(a.__webglFramebuffer[b]),j.deleteRenderbuffer(a.__webglRenderbuffer[b]); +else j.deleteFramebuffer(a.__webglFramebuffer),j.deleteRenderbuffer(a.__webglRenderbuffer);K.info.memory.textures--},Gb=function(a){a=a.target;a.removeEventListener("dispose",Gb);Hb(a)},Ib=function(a){void 0!==a.__webglVertexBuffer&&j.deleteBuffer(a.__webglVertexBuffer);void 0!==a.__webglNormalBuffer&&j.deleteBuffer(a.__webglNormalBuffer);void 0!==a.__webglTangentBuffer&&j.deleteBuffer(a.__webglTangentBuffer);void 0!==a.__webglColorBuffer&&j.deleteBuffer(a.__webglColorBuffer);void 0!==a.__webglUVBuffer&& +j.deleteBuffer(a.__webglUVBuffer);void 0!==a.__webglUV2Buffer&&j.deleteBuffer(a.__webglUV2Buffer);void 0!==a.__webglSkinIndicesBuffer&&j.deleteBuffer(a.__webglSkinIndicesBuffer);void 0!==a.__webglSkinWeightsBuffer&&j.deleteBuffer(a.__webglSkinWeightsBuffer);void 0!==a.__webglFaceBuffer&&j.deleteBuffer(a.__webglFaceBuffer);void 0!==a.__webglLineBuffer&&j.deleteBuffer(a.__webglLineBuffer);void 0!==a.__webglLineDistanceBuffer&&j.deleteBuffer(a.__webglLineDistanceBuffer);if(void 0!==a.__webglCustomAttributesList)for(var b in a.__webglCustomAttributesList)j.deleteBuffer(a.__webglCustomAttributesList[b].buffer); +K.info.memory.geometries--},Hb=function(a){var b=a.program;if(void 0!==b){a.program=void 0;var c,d,e=!1,a=0;for(c=da.length;ad.numSupportedMorphTargets?(l.sort(k),l.length=d.numSupportedMorphTargets):l.length>d.numSupportedMorphNormals?l.sort(k):0===l.length&&l.push([0,0]);for(m=0;mDa;Da++)Ga=Q[Da],vb[gb]=Ga.x,vb[gb+1]=Ga.y,vb[gb+2]=Ga.z,gb+=3;else for(Da=0;3>Da;Da++)vb[gb]=U.x,vb[gb+1]=U.y,vb[gb+2]=U.z,gb+=3;j.bindBuffer(j.ARRAY_BUFFER,x.__webglNormalBuffer);j.bufferData(j.ARRAY_BUFFER,vb,C)}if(zb&&Db&&N){D=0;for(I=aa.length;DDa;Da++)Fa=Aa[Da],cb[Na]=Fa.x,cb[Na+1]=Fa.y,Na+=2;0Da;Da++)La=$[Da],db[Oa]=La.x,db[Oa+1]=La.y,Oa+=2;0f;f++){a.__webglFramebuffer[f]=j.createFramebuffer();a.__webglRenderbuffer[f]=j.createRenderbuffer();j.texImage2D(j.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,d,a.width,a.height,0,d,e,null);var h=a,g=j.TEXTURE_CUBE_MAP_POSITIVE_X+f;j.bindFramebuffer(j.FRAMEBUFFER,a.__webglFramebuffer[f]);j.framebufferTexture2D(j.FRAMEBUFFER,j.COLOR_ATTACHMENT0,g,h.__webglTexture,0);I(a.__webglRenderbuffer[f],a)}c&&j.generateMipmap(j.TEXTURE_CUBE_MAP)}else a.__webglFramebuffer=j.createFramebuffer(),a.__webglRenderbuffer= +a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:j.createRenderbuffer(),j.bindTexture(j.TEXTURE_2D,a.__webglTexture),D(j.TEXTURE_2D,a,c),j.texImage2D(j.TEXTURE_2D,0,d,a.width,a.height,0,d,e,null),d=j.TEXTURE_2D,j.bindFramebuffer(j.FRAMEBUFFER,a.__webglFramebuffer),j.framebufferTexture2D(j.FRAMEBUFFER,j.COLOR_ATTACHMENT0,d,a.__webglTexture,0),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?j.framebufferRenderbuffer(j.FRAMEBUFFER,j.DEPTH_ATTACHMENT,j.RENDERBUFFER,a.__webglRenderbuffer):a.depthBuffer&& +a.stencilBuffer&&j.framebufferRenderbuffer(j.FRAMEBUFFER,j.DEPTH_STENCIL_ATTACHMENT,j.RENDERBUFFER,a.__webglRenderbuffer):I(a.__webglRenderbuffer,a),c&&j.generateMipmap(j.TEXTURE_2D);b?j.bindTexture(j.TEXTURE_CUBE_MAP,null):j.bindTexture(j.TEXTURE_2D,null);j.bindRenderbuffer(j.RENDERBUFFER,null);j.bindFramebuffer(j.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=ob,a=pb,d=cb,e=db);b!==ba&&(j.bindFramebuffer(j.FRAMEBUFFER,b), +j.viewport(d,e,c,a),ba=b);qb=c;eb=a};this.shadowMapPlugin=new THREE.ShadowMapPlugin;this.addPrePlugin(this.shadowMapPlugin);this.addPostPlugin(new THREE.SpritePlugin);this.addPostPlugin(new THREE.LensFlarePlugin)};THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=void 0!==c.format?c.format: +THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=null}; +THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,clone:function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.anisotropy=this.anisotropy;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;a.generateMipmaps=this.generateMipmaps;a.shareDepthFrom=this.shareDepthFrom; +return a},dispose:function(){this.dispatchEvent({type:"dispose"})}};THREE.EventDispatcher.prototype.apply(THREE.WebGLRenderTarget.prototype);THREE.WebGLRenderTargetCube=function(a,b,c){THREE.WebGLRenderTarget.call(this,a,b,c);this.activeCubeFace=0};THREE.WebGLRenderTargetCube.prototype=Object.create(THREE.WebGLRenderTarget.prototype);THREE.RenderableVertex=function(){this.positionWorld=new THREE.Vector3;this.positionScreen=new THREE.Vector4;this.visible=!0};THREE.RenderableVertex.prototype.copy=function(a){this.positionWorld.copy(a.positionWorld);this.positionScreen.copy(a.positionScreen)};THREE.RenderableFace3=function(){this.id=0;this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.v3=new THREE.RenderableVertex;this.centroidModel=new THREE.Vector3;this.normalModel=new THREE.Vector3;this.normalModelView=new THREE.Vector3;this.vertexNormalsLength=0;this.vertexNormalsModel=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.vertexNormalsModelView=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];this.material=this.color=null;this.uvs=[[]];this.z= +0};THREE.RenderableObject=function(){this.id=0;this.object=null;this.z=0};THREE.RenderableParticle=function(){this.id=0;this.object=null;this.z=this.y=this.x=0;this.rotation=null;this.scale=new THREE.Vector2;this.material=null};THREE.RenderableLine=function(){this.id=0;this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.vertexColors=[new THREE.Color,new THREE.Color];this.material=null;this.z=0};THREE.GeometryUtils={merge:function(a,b,c){var d,e,f=a.vertices.length,h=b instanceof THREE.Mesh?b.geometry:b,g=a.vertices,i=h.vertices,k=a.faces,m=h.faces,a=a.faceVertexUvs[0],h=h.faceVertexUvs[0];void 0===c&&(c=0);b instanceof THREE.Mesh&&(b.matrixAutoUpdate&&b.updateMatrix(),d=b.matrix,e=(new THREE.Matrix3).getNormalMatrix(d));for(var b=0,l=i.length;ba?b(c,e-1):k[e]>8&255,i>>16&255,i>>24&255)),d}d.mipmapCount=1;g[2]&131072&&!1!==b&&(d.mipmapCount=Math.max(1,g[7]));d.isCubemap=g[28]&512?!0:!1;d.width=g[4];d.height=g[3];for(var g=g[1]+4,f=d.width,h=d.height,i=d.isCubemap?6:1,m=0;ml-1?0:l-1,r=l+1>e-1?e-1:l+1,t=0>m-1?0:m-1,n=m+1>d-1?d-1:m+1,s=[],q=[0,0,g[4*(l*d+m)]/255*b];s.push([-1,0,g[4*(l*d+t)]/255*b]);s.push([-1,-1,g[4*(p*d+t)]/255*b]);s.push([0,-1,g[4*(p*d+m)]/255*b]);s.push([1,-1,g[4*(p*d+n)]/255*b]);s.push([1,0,g[4*(l*d+n)]/255*b]);s.push([1,1,g[4*(r*d+n)]/255*b]);s.push([0,1,g[4*(r*d+m)]/255*b]);s.push([-1,1,g[4*(r*d+t)]/255*b]);p=[];t=s.length;for(r=0;re)return null;var f=[],h=[],g=[],i,k,m;if(0=l--){console.log("Warning, unable to triangulate polygon!");break}i=k;e<=i&&(i=0);k=i+1;e<=k&&(k=0);m=k+1;e<=m&&(m=0);var p;a:{var r=p=void 0,t=void 0,n=void 0,s=void 0,q=void 0,u=void 0,w=void 0,E= +void 0,r=a[h[i]].x,t=a[h[i]].y,n=a[h[k]].x,s=a[h[k]].y,q=a[h[m]].x,u=a[h[m]].y;if(1E-10>(n-r)*(u-t)-(s-t)*(q-r))p=!1;else{var C=void 0,F=void 0,y=void 0,A=void 0,z=void 0,O=void 0,B=void 0,D=void 0,I=void 0,v=void 0,I=D=B=E=w=void 0,C=q-n,F=u-s,y=r-q,A=t-u,z=n-r,O=s-t;for(p=0;pi)h=d+1;else if(0b&&(b=0);1=b)return b=c[a]-b,a=this.curves[a],b=1-b/a.getLength(),a.getPointAt(b);a++}return null};THREE.CurvePath.prototype.getLength=function(){var a=this.getCurveLengths();return a[a.length-1]}; +THREE.CurvePath.prototype.getCurveLengths=function(){if(this.cacheLengths&&this.cacheLengths.length==this.curves.length)return this.cacheLengths;var a=[],b=0,c,d=this.curves.length;for(c=0;cb?b=g.x:g.xc?c=g.y:g.yd?d=g.z:g.zMath.abs(d.x-c[0].x)&&1E-10>Math.abs(d.y-c[0].y)&&c.splice(c.length-1,1);b&&c.push(c[0]);return c}; +THREE.Path.prototype.toShapes=function(a){var b,c,d,e,f=[],h=new THREE.Path;b=0;for(c=this.actions.length;b +g&&(g+=c.length);g%=c.length;0>h&&(h+=k.length);h%=k.length;e=0<=g-1?g-1:c.length-1;f=0<=h-1?h-1:k.length-1;n=[k[h],c[g],c[e]];n=THREE.FontUtils.Triangulate.area(n);s=[k[h],k[f],c[g]];s=THREE.FontUtils.Triangulate.area(s);l+p>n+s&&(g=r,h=m,0>g&&(g+=c.length),g%=c.length,0>h&&(h+=k.length),h%=k.length,e=0<=g-1?g-1:c.length-1,f=0<=h-1?h-1:k.length-1);l=c.slice(0,g);p=c.slice(g);r=k.slice(h);m=k.slice(0,h);f=[k[h],k[f],c[g]];t.push([k[h],c[g],c[e]]);t.push(f);c=l.concat(r).concat(m).concat(p)}return{shape:c, +isolatedPts:t,allpoints:d}},triangulateShape:function(a,b){var c=THREE.Shape.Utils.removeHoles(a,b),d=c.allpoints,e=c.isolatedPts,c=THREE.FontUtils.Triangulate(c.shape,!1),f,h,g,i,k={};f=0;for(h=d.length;fd;d++)i=g[d].x+":"+g[d].y,i=k[i],void 0!==i&&(g[d]=i)}f=0;for(h=e.length;fd;d++)i=g[d].x+":"+g[d].y,i=k[i],void 0!==i&&(g[d]=i)}return c.concat(e)}, +isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1-a)*a*a*b},b3p3:function(a,b){return a*a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a,b)+this.b3p1(a,c)+this.b3p2(a,d)+ +this.b3p3(a,e)}};THREE.LineCurve=function(a,b){this.v1=a;this.v2=b};THREE.LineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};THREE.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)};THREE.LineCurve.prototype.getTangent=function(){return this.v2.clone().sub(this.v1).normalize()};THREE.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};THREE.QuadraticBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.QuadraticBezierCurve.prototype.getPoint=function(a){var b;b=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);a=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);return new THREE.Vector2(b,a)}; +THREE.QuadraticBezierCurve.prototype.getTangent=function(a){var b;b=THREE.Curve.Utils.tangentQuadraticBezier(a,this.v0.x,this.v1.x,this.v2.x);a=THREE.Curve.Utils.tangentQuadraticBezier(a,this.v0.y,this.v1.y,this.v2.y);b=new THREE.Vector2(b,a);b.normalize();return b};THREE.CubicBezierCurve=function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d};THREE.CubicBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.CubicBezierCurve.prototype.getPoint=function(a){var b;b=THREE.Shape.Utils.b3(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);a=THREE.Shape.Utils.b3(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);return new THREE.Vector2(b,a)}; +THREE.CubicBezierCurve.prototype.getTangent=function(a){var b;b=THREE.Curve.Utils.tangentCubicBezier(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);a=THREE.Curve.Utils.tangentCubicBezier(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);b=new THREE.Vector2(b,a);b.normalize();return b};THREE.SplineCurve=function(a){this.points=void 0==a?[]:a};THREE.SplineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.SplineCurve.prototype.getPoint=function(a){var b=new THREE.Vector2,c=[],d=this.points,e;e=(d.length-1)*a;a=Math.floor(e);e-=a;c[0]=0==a?a:a-1;c[1]=a;c[2]=a>d.length-2?d.length-1:a+1;c[3]=a>d.length-3?d.length-1:a+2;b.x=THREE.Curve.Utils.interpolate(d[c[0]].x,d[c[1]].x,d[c[2]].x,d[c[3]].x,e);b.y=THREE.Curve.Utils.interpolate(d[c[0]].y,d[c[1]].y,d[c[2]].y,d[c[3]].y,e);return b};THREE.EllipseCurve=function(a,b,c,d,e,f,h){this.aX=a;this.aY=b;this.xRadius=c;this.yRadius=d;this.aStartAngle=e;this.aEndAngle=f;this.aClockwise=h};THREE.EllipseCurve.prototype=Object.create(THREE.Curve.prototype); +THREE.EllipseCurve.prototype.getPoint=function(a){var b;b=this.aEndAngle-this.aStartAngle;0>b&&(b+=2*Math.PI);b>2*Math.PI&&(b-=2*Math.PI);b=!0===this.aClockwise?this.aEndAngle+(1-a)*(2*Math.PI-b):this.aStartAngle+a*b;a=this.aX+this.xRadius*Math.cos(b);b=this.aY+this.yRadius*Math.sin(b);return new THREE.Vector2(a,b)};THREE.ArcCurve=function(a,b,c,d,e,f){THREE.EllipseCurve.call(this,a,b,c,c,d,e,f)};THREE.ArcCurve.prototype=Object.create(THREE.EllipseCurve.prototype);THREE.LineCurve3=THREE.Curve.create(function(a,b){this.v1=a;this.v2=b},function(a){var b=new THREE.Vector3;b.subVectors(this.v2,this.v1);b.multiplyScalar(a);b.add(this.v1);return b});THREE.QuadraticBezierCurve3=THREE.Curve.create(function(a,b,c){this.v0=a;this.v1=b;this.v2=c},function(a){var b,c;b=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);c=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);a=THREE.Shape.Utils.b2(a,this.v0.z,this.v1.z,this.v2.z);return new THREE.Vector3(b,c,a)});THREE.CubicBezierCurve3=THREE.Curve.create(function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d},function(a){var b,c;b=THREE.Shape.Utils.b3(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);c=THREE.Shape.Utils.b3(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);a=THREE.Shape.Utils.b3(a,this.v0.z,this.v1.z,this.v2.z,this.v3.z);return new THREE.Vector3(b,c,a)});THREE.SplineCurve3=THREE.Curve.create(function(a){this.points=void 0==a?[]:a},function(a){var b=new THREE.Vector3,c=[],d=this.points,e,a=(d.length-1)*a;e=Math.floor(a);a-=e;c[0]=0==e?e:e-1;c[1]=e;c[2]=e>d.length-2?d.length-1:e+1;c[3]=e>d.length-3?d.length-1:e+2;e=d[c[0]];var f=d[c[1]],h=d[c[2]],c=d[c[3]];b.x=THREE.Curve.Utils.interpolate(e.x,f.x,h.x,c.x,a);b.y=THREE.Curve.Utils.interpolate(e.y,f.y,h.y,c.y,a);b.z=THREE.Curve.Utils.interpolate(e.z,f.z,h.z,c.z,a);return b});THREE.ClosedSplineCurve3=THREE.Curve.create(function(a){this.points=void 0==a?[]:a},function(a){var b=new THREE.Vector3,c=[],d=this.points,e;e=(d.length-0)*a;a=Math.floor(e);e-=a;a+=0a.hierarchy[c].keys[d].time&& +(a.hierarchy[c].keys[d].time=0),void 0!==a.hierarchy[c].keys[d].rot&&!(a.hierarchy[c].keys[d].rot instanceof THREE.Quaternion)){var g=a.hierarchy[c].keys[d].rot;a.hierarchy[c].keys[d].rot=new THREE.Quaternion(g[0],g[1],g[2],g[3])}if(a.hierarchy[c].keys.length&&void 0!==a.hierarchy[c].keys[0].morphTargets){g={};for(d=0;dr;r++){c=b[r];h=i.prevKey[c];g=i.nextKey[c];if(g.time<=m){if(kd||1d?0:1;if("pos"===c)if(c=a.position,this.interpolationType===THREE.AnimationHandler.LINEAR)c.x=e[0]+(f[0]-e[0])*d,c.y=e[1]+(f[1]-e[1])*d,c.z=e[2]+ +(f[2]-e[2])*d;else{if(this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD)this.points[0]=this.getPrevKeyWith("pos",l,h.index-1).pos,this.points[1]=e,this.points[2]=f,this.points[3]=this.getNextKeyWith("pos",l,g.index+1).pos,d=0.33*d+0.33,e=this.interpolateCatmullRom(this.points,d),c.x=e[0],c.y=e[1],c.z=e[2],this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD&&(d=this.interpolateCatmullRom(this.points,1.01*d), +this.target.set(d[0],d[1],d[2]),this.target.sub(c),this.target.y=0,this.target.normalize(),d=Math.atan2(this.target.x,this.target.z),a.rotation.set(0,d,0))}else"rot"===c?THREE.Quaternion.slerp(e,f,a.quaternion,d):"scl"===c&&(c=a.scale,c.x=e[0]+(f[0]-e[0])*d,c.y=e[1]+(f[1]-e[1])*d,c.z=e[2]+(f[2]-e[2])*d)}}}}; +THREE.Animation.prototype.interpolateCatmullRom=function(a,b){var c=[],d=[],e,f,h,g,i,k;e=(a.length-1)*b;f=Math.floor(e);e-=f;c[0]=0===f?f:f-1;c[1]=f;c[2]=f>a.length-2?f:f+1;c[3]=f>a.length-3?f:f+2;f=a[c[0]];g=a[c[1]];i=a[c[2]];k=a[c[3]];c=e*e;h=e*c;d[0]=this.interpolate(f[0],g[0],i[0],k[0],e,c,h);d[1]=this.interpolate(f[1],g[1],i[1],k[1],e,c,h);d[2]=this.interpolate(f[2],g[2],i[2],k[2],e,c,h);return d}; +THREE.Animation.prototype.interpolate=function(a,b,c,d,e,f,h){a=0.5*(c-a);d=0.5*(d-b);return(2*(b-c)+a+d)*h+(-3*(b-c)-2*a-d)*f+a*e+b};THREE.Animation.prototype.getNextKeyWith=function(a,b,c){for(var d=this.data.hierarchy[b].keys,c=this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD?c=h?b.interpolate(c,h):b.interpolate(c,c.time)}this.data.hierarchy[a].node.updateMatrix();d.matrixWorldNeedsUpdate=!0}}if(this.JITCompile&&void 0===f[0][e]){this.hierarchy[0].updateMatrixWorld(!0);for(a=0;ag?(b=Math.atan2(b.y-a.y,b.x-a.x),a=Math.atan2(c.y-a.y,c.x-a.x),b>a&&(a+=2*Math.PI),c=(b+a)/2,a=-Math.cos(c),c=-Math.sin(c),new THREE.Vector2(a,c)):d.multiplyScalar(g).add(h).sub(a).clone()}function e(c,d){var e,f;for(N=c.length;0<=--N;){e=N;f=N-1;0>f&&(f=c.length-1);for(var g=0,h=r+2*m, +g=0;gMath.abs(c-i)?[new THREE.Vector2(b,1-e),new THREE.Vector2(d,1-f),new THREE.Vector2(k,1-h),new THREE.Vector2(l,1-a)]:[new THREE.Vector2(c,1-e),new THREE.Vector2(i,1-f),new THREE.Vector2(m,1-h),new THREE.Vector2(p,1-a)]}};THREE.ExtrudeGeometry.__v1=new THREE.Vector2;THREE.ExtrudeGeometry.__v2=new THREE.Vector2;THREE.ExtrudeGeometry.__v3=new THREE.Vector2;THREE.ExtrudeGeometry.__v4=new THREE.Vector2; +THREE.ExtrudeGeometry.__v5=new THREE.Vector2;THREE.ExtrudeGeometry.__v6=new THREE.Vector2;THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);!1===a instanceof Array&&(a=[a]);this.shapebb=a[a.length-1].getBoundingBox();this.addShapeList(a,b);this.computeCentroids();this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;cc&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/2/Math.PI+0.5,a.y));return a.clone()}THREE.Geometry.call(this);for(var c=c||1,d=d||0,g=this,i=0,k=a.length;ip&&(0.2>a&&(d[0].x+=1),0.2>b&&(d[1].x+=1),0.2>m&&(d[2].x+=1));i=0;for(k=this.vertices.length;ic.y?this.quaternion.set(1,0,0,0):(a.set(c.z,0,-c.x).normalize(),b=Math.acos(c.y),this.quaternion.setFromAxisAngle(a,b))}}();THREE.ArrowHelper.prototype.setLength=function(a){this.scale.set(a,a,a)}; +THREE.ArrowHelper.prototype.setColor=function(a){this.line.material.color.setHex(a);this.cone.material.color.setHex(a)};THREE.BoxHelper=function(a){var b=[new THREE.Vector3(1,1,1),new THREE.Vector3(-1,1,1),new THREE.Vector3(-1,-1,1),new THREE.Vector3(1,-1,1),new THREE.Vector3(1,1,-1),new THREE.Vector3(-1,1,-1),new THREE.Vector3(-1,-1,-1),new THREE.Vector3(1,-1,-1)];this.vertices=b;var c=new THREE.Geometry;c.vertices.push(b[0],b[1],b[1],b[2],b[2],b[3],b[3],b[0],b[4],b[5],b[5],b[6],b[6],b[7],b[7],b[4],b[0],b[4],b[1],b[5],b[2],b[6],b[3],b[7]);THREE.Line.call(this,c,new THREE.LineBasicMaterial({color:16776960}),THREE.LinePieces); +void 0!==a&&this.update(a)};THREE.BoxHelper.prototype=Object.create(THREE.Line.prototype); +THREE.BoxHelper.prototype.update=function(a){var b=a.geometry;null===b.boundingBox&&b.computeBoundingBox();var c=b.boundingBox.min,b=b.boundingBox.max,d=this.vertices;d[0].set(b.x,b.y,b.z);d[1].set(c.x,b.y,b.z);d[2].set(c.x,c.y,b.z);d[3].set(b.x,c.y,b.z);d[4].set(b.x,b.y,c.z);d[5].set(c.x,b.y,c.z);d[6].set(c.x,c.y,c.z);d[7].set(b.x,c.y,c.z);this.geometry.computeBoundingSphere();this.geometry.verticesNeedUpdate=!0;this.matrixAutoUpdate=!1;this.matrixWorld=a.matrixWorld};THREE.BoundingBoxHelper=function(a,b){var c=b||8947848;this.object=a;this.box=new THREE.Box3;THREE.Mesh.call(this,new THREE.CubeGeometry(1,1,1),new THREE.MeshBasicMaterial({color:c,wireframe:!0}))};THREE.BoundingBoxHelper.prototype=Object.create(THREE.Mesh.prototype);THREE.BoundingBoxHelper.prototype.update=function(){this.box.setFromObject(this.object);this.box.size(this.scale);this.box.center(this.position)};THREE.CameraHelper=function(a){function b(a,b,d){c(a,d);c(b,d)}function c(a,b){d.vertices.push(new THREE.Vector3);d.colors.push(new THREE.Color(b));void 0===f[a]&&(f[a]=[]);f[a].push(d.vertices.length-1)}var d=new THREE.Geometry,e=new THREE.LineBasicMaterial({color:16777215,vertexColors:THREE.FaceColors}),f={};b("n1","n2",16755200);b("n2","n4",16755200);b("n4","n3",16755200);b("n3","n1",16755200);b("f1","f2",16755200);b("f2","f4",16755200);b("f4","f3",16755200);b("f3","f1",16755200);b("n1","f1",16755200); +b("n2","f2",16755200);b("n3","f3",16755200);b("n4","f4",16755200);b("p","n1",16711680);b("p","n2",16711680);b("p","n3",16711680);b("p","n4",16711680);b("u1","u2",43775);b("u2","u3",43775);b("u3","u1",43775);b("c","t",16777215);b("p","c",3355443);b("cn1","cn2",3355443);b("cn3","cn4",3355443);b("cf1","cf2",3355443);b("cf3","cf4",3355443);THREE.Line.call(this,d,e,THREE.LinePieces);this.camera=a;this.matrixWorld=a.matrixWorld;this.matrixAutoUpdate=!1;this.pointMap=f;this.update()}; +THREE.CameraHelper.prototype=Object.create(THREE.Line.prototype); +THREE.CameraHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Camera,c=new THREE.Projector;return function(){function d(d,h,g,i){a.set(h,g,i);c.unprojectVector(a,b);d=e.pointMap[d];if(void 0!==d){h=0;for(g=d.length;hd;d++)c.faces[d].color=this.colors[4>d?0:1];d=new THREE.MeshBasicMaterial({vertexColors:THREE.FaceColors,wireframe:!0});this.lightSphere=new THREE.Mesh(c,d);this.add(this.lightSphere); +this.update()};THREE.HemisphereLightHelper.prototype=Object.create(THREE.Object3D.prototype);THREE.HemisphereLightHelper.prototype.dispose=function(){this.lightSphere.geometry.dispose();this.lightSphere.material.dispose()}; +THREE.HemisphereLightHelper.prototype.update=function(){var a=new THREE.Vector3;return function(){this.colors[0].copy(this.light.color).multiplyScalar(this.light.intensity);this.colors[1].copy(this.light.groundColor).multiplyScalar(this.light.intensity);this.lightSphere.lookAt(a.getPositionFromMatrix(this.light.matrixWorld).negate());this.lightSphere.geometry.colorsNeedUpdate=!0}}();THREE.PointLightHelper=function(a,b){this.light=a;this.light.updateMatrixWorld();var c=new THREE.SphereGeometry(b,4,2),d=new THREE.MeshBasicMaterial({wireframe:!0,fog:!1});d.color.copy(this.light.color).multiplyScalar(this.light.intensity);THREE.Mesh.call(this,c,d);this.matrixWorld=this.light.matrixWorld;this.matrixAutoUpdate=!1};THREE.PointLightHelper.prototype=Object.create(THREE.Mesh.prototype);THREE.PointLightHelper.prototype.dispose=function(){this.geometry.dispose();this.material.dispose()}; +THREE.PointLightHelper.prototype.update=function(){this.material.color.copy(this.light.color).multiplyScalar(this.light.intensity)};THREE.SpotLightHelper=function(a){THREE.Object3D.call(this);this.light=a;this.light.updateMatrixWorld();this.matrixWorld=a.matrixWorld;this.matrixAutoUpdate=!1;a=new THREE.CylinderGeometry(0,1,1,8,1,!0);a.applyMatrix((new THREE.Matrix4).makeTranslation(0,-0.5,0));a.applyMatrix((new THREE.Matrix4).makeRotationX(-Math.PI/2));var b=new THREE.MeshBasicMaterial({wireframe:!0,fog:!1});this.cone=new THREE.Mesh(a,b);this.add(this.cone);this.update()};THREE.SpotLightHelper.prototype=Object.create(THREE.Object3D.prototype); +THREE.SpotLightHelper.prototype.dispose=function(){this.cone.geometry.dispose();this.cone.material.dispose()};THREE.SpotLightHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(){var c=this.light.distance?this.light.distance:1E4,d=c*Math.tan(this.light.angle);this.cone.scale.set(d,d,c);a.getPositionFromMatrix(this.light.matrixWorld);b.getPositionFromMatrix(this.light.target.matrixWorld);this.cone.lookAt(b.sub(a));this.cone.material.color.copy(this.light.color).multiplyScalar(this.light.intensity)}}();THREE.VertexNormalsHelper=function(a,b,c,d){this.object=a;this.size=b||1;for(var b=c||16711680,d=d||1,c=new THREE.Geometry,a=a.geometry.faces,e=0,f=a.length;el;l++){b[0]=m[e[l]];b[1]=m[e[(l+1)%3]];b.sort(d);var p=b.toString();void 0===c[p]&&(f.vertices.push(h[b[0]]),f.vertices.push(h[b[1]]),c[p]=!0)}THREE.Line.call(this,f,new THREE.LineBasicMaterial({color:16777215}),THREE.LinePieces);this.matrixAutoUpdate=!1;this.matrixWorld=a.matrixWorld}; +THREE.WireframeHelper.prototype=Object.create(THREE.Line.prototype);THREE.ImmediateRenderObject=function(){THREE.Object3D.call(this);this.render=function(){}};THREE.ImmediateRenderObject.prototype=Object.create(THREE.Object3D.prototype);THREE.LensFlare=function(a,b,c,d,e){THREE.Object3D.call(this);this.lensFlares=[];this.positionScreen=new THREE.Vector3;this.customUpdateCallback=void 0;void 0!==a&&this.add(a,b,c,d,e)};THREE.LensFlare.prototype=Object.create(THREE.Object3D.prototype); +THREE.LensFlare.prototype.add=function(a,b,c,d,e,f){void 0===b&&(b=-1);void 0===c&&(c=0);void 0===f&&(f=1);void 0===e&&(e=new THREE.Color(16777215));void 0===d&&(d=THREE.NormalBlending);c=Math.min(c,Math.max(0,c));this.lensFlares.push({texture:a,size:b,distance:c,x:0,y:0,z:0,scale:1,rotation:1,opacity:f,color:e,blending:d})}; +THREE.LensFlare.prototype.updateLensFlares=function(){var a,b=this.lensFlares.length,c,d=2*-this.positionScreen.x,e=2*-this.positionScreen.y;for(a=0;ag.end&&(g.end=f);c||(c=i)}}for(i in d)g=d[i],this.createAnimation(i,g.start,g.end,a);this.firstAnimation=c}; +THREE.MorphBlendMesh.prototype.setAnimationDirectionForward=function(a){if(a=this.animationsMap[a])a.direction=1,a.directionBackwards=!1};THREE.MorphBlendMesh.prototype.setAnimationDirectionBackward=function(a){if(a=this.animationsMap[a])a.direction=-1,a.directionBackwards=!0};THREE.MorphBlendMesh.prototype.setAnimationFPS=function(a,b){var c=this.animationsMap[a];c&&(c.fps=b,c.duration=(c.end-c.start)/c.fps)}; +THREE.MorphBlendMesh.prototype.setAnimationDuration=function(a,b){var c=this.animationsMap[a];c&&(c.duration=b,c.fps=(c.end-c.start)/c.duration)};THREE.MorphBlendMesh.prototype.setAnimationWeight=function(a,b){var c=this.animationsMap[a];c&&(c.weight=b)};THREE.MorphBlendMesh.prototype.setAnimationTime=function(a,b){var c=this.animationsMap[a];c&&(c.time=b)};THREE.MorphBlendMesh.prototype.getAnimationTime=function(a){var b=0;if(a=this.animationsMap[a])b=a.time;return b}; +THREE.MorphBlendMesh.prototype.getAnimationDuration=function(a){var b=-1;if(a=this.animationsMap[a])b=a.duration;return b};THREE.MorphBlendMesh.prototype.playAnimation=function(a){var b=this.animationsMap[a];b?(b.time=0,b.active=!0):console.warn("animation["+a+"] undefined")};THREE.MorphBlendMesh.prototype.stopAnimation=function(a){if(a=this.animationsMap[a])a.active=!1}; +THREE.MorphBlendMesh.prototype.update=function(a){for(var b=0,c=this.animationsList.length;bd.duration||0>d.time)d.direction*=-1,d.time>d.duration&&(d.time=d.duration,d.directionBackwards=!0),0>d.time&&(d.time=0,d.directionBackwards=!1)}else d.time%=d.duration,0>d.time&&(d.time+=d.duration);var f=d.startFrame+THREE.Math.clamp(Math.floor(d.time/e),0,d.length-1),h=d.weight; +f!==d.currentFrame&&(this.morphTargetInfluences[d.lastFrame]=0,this.morphTargetInfluences[d.currentFrame]=1*h,this.morphTargetInfluences[f]=0,d.lastFrame=d.currentFrame,d.currentFrame=f);e=d.time%e/e;d.directionBackwards&&(e=1-e);this.morphTargetInfluences[d.currentFrame]=e*h;this.morphTargetInfluences[d.lastFrame]=(1-e)*h}}};THREE.LensFlarePlugin=function(){function a(a,c){var d=b.createProgram(),e=b.createShader(b.FRAGMENT_SHADER),f=b.createShader(b.VERTEX_SHADER),g="precision "+c+" float;\n";b.shaderSource(e,g+a.fragmentShader);b.shaderSource(f,g+a.vertexShader);b.compileShader(e);b.compileShader(f);b.attachShader(d,e);b.attachShader(d,f);b.linkProgram(d);return d}var b,c,d,e,f,h,g,i,k,m,l,p,r;this.init=function(t){b=t.context;c=t;d=t.getPrecision();e=new Float32Array(16);f=new Uint16Array(6);t=0;e[t++]=-1;e[t++]=-1; +e[t++]=0;e[t++]=0;e[t++]=1;e[t++]=-1;e[t++]=1;e[t++]=0;e[t++]=1;e[t++]=1;e[t++]=1;e[t++]=1;e[t++]=-1;e[t++]=1;e[t++]=0;e[t++]=1;t=0;f[t++]=0;f[t++]=1;f[t++]=2;f[t++]=0;f[t++]=2;f[t++]=3;h=b.createBuffer();g=b.createBuffer();b.bindBuffer(b.ARRAY_BUFFER,h);b.bufferData(b.ARRAY_BUFFER,e,b.STATIC_DRAW);b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,g);b.bufferData(b.ELEMENT_ARRAY_BUFFER,f,b.STATIC_DRAW);i=b.createTexture();k=b.createTexture();b.bindTexture(b.TEXTURE_2D,i);b.texImage2D(b.TEXTURE_2D,0,b.RGB,16,16, +0,b.RGB,b.UNSIGNED_BYTE,null);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MAG_FILTER,b.NEAREST);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MIN_FILTER,b.NEAREST);b.bindTexture(b.TEXTURE_2D,k);b.texImage2D(b.TEXTURE_2D,0,b.RGBA,16,16,0,b.RGBA,b.UNSIGNED_BYTE,null);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.CLAMP_TO_EDGE); +b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MAG_FILTER,b.NEAREST);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MIN_FILTER,b.NEAREST);0>=b.getParameter(b.MAX_VERTEX_TEXTURE_IMAGE_UNITS)?(m=!1,l=a(THREE.ShaderFlares.lensFlare,d)):(m=!0,l=a(THREE.ShaderFlares.lensFlareVertexTexture,d));p={};r={};p.vertex=b.getAttribLocation(l,"position");p.uv=b.getAttribLocation(l,"uv");r.renderType=b.getUniformLocation(l,"renderType");r.map=b.getUniformLocation(l,"map");r.occlusionMap=b.getUniformLocation(l,"occlusionMap");r.opacity= +b.getUniformLocation(l,"opacity");r.color=b.getUniformLocation(l,"color");r.scale=b.getUniformLocation(l,"scale");r.rotation=b.getUniformLocation(l,"rotation");r.screenPosition=b.getUniformLocation(l,"screenPosition")};this.render=function(a,d,e,f){var a=a.__webglFlares,u=a.length;if(u){var w=new THREE.Vector3,E=f/e,C=0.5*e,F=0.5*f,y=16/f,A=new THREE.Vector2(y*E,y),z=new THREE.Vector3(1,1,0),O=new THREE.Vector2(1,1),B=r,y=p;b.useProgram(l);b.enableVertexAttribArray(p.vertex);b.enableVertexAttribArray(p.uv); +b.uniform1i(B.occlusionMap,0);b.uniform1i(B.map,1);b.bindBuffer(b.ARRAY_BUFFER,h);b.vertexAttribPointer(y.vertex,2,b.FLOAT,!1,16,0);b.vertexAttribPointer(y.uv,2,b.FLOAT,!1,16,8);b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,g);b.disable(b.CULL_FACE);b.depthMask(!1);var D,I,v,x,G;for(D=0;DA;A++)E[A]=new THREE.Vector3,u[A]=new THREE.Vector3;E=C.shadowCascadeNearZ[w];C=C.shadowCascadeFarZ[w];u[0].set(-1,-1,E);u[1].set(1,-1,E);u[2].set(-1, +1,E);u[3].set(1,1,E);u[4].set(-1,-1,C);u[5].set(1,-1,C);u[6].set(-1,1,C);u[7].set(1,1,C);y.originalCamera=p;u=new THREE.Gyroscope;u.position=n.shadowCascadeOffset;u.add(y);u.add(y.target);p.add(u);n.shadowCascadeArray[q]=y;console.log("Created virtualLight",y)}w=n;E=q;C=w.shadowCascadeArray[E];C.position.copy(w.position);C.target.position.copy(w.target.position);C.lookAt(C.target);C.shadowCameraVisible=w.shadowCameraVisible;C.shadowDarkness=w.shadowDarkness;C.shadowBias=w.shadowCascadeBias[E];u=w.shadowCascadeNearZ[E]; +w=w.shadowCascadeFarZ[E];C=C.pointsFrustum;C[0].z=u;C[1].z=u;C[2].z=u;C[3].z=u;C[4].z=w;C[5].z=w;C[6].z=w;C[7].z=w;F[s]=y;s++}else F[s]=n,s++;r=0;for(t=F.length;rw;w++)E=C[w],E.copy(u[w]),THREE.ShadowMapPlugin.__projector.unprojectVector(E,q),E.applyMatrix4(s.matrixWorldInverse),E.xk.x&&(k.x=E.x),E.yk.y&&(k.y=E.y),E.zk.z&& +(k.z=E.z);s.left=i.x;s.right=k.x;s.top=k.y;s.bottom=i.y;s.updateProjectionMatrix()}s=n.shadowMap;u=n.shadowMatrix;q=n.shadowCamera;q.position.getPositionFromMatrix(n.matrixWorld);m.getPositionFromMatrix(n.target.matrixWorld);q.lookAt(m);q.updateMatrixWorld();q.matrixWorldInverse.getInverse(q.matrixWorld);n.cameraHelper&&(n.cameraHelper.visible=n.shadowCameraVisible);n.shadowCameraVisible&&n.cameraHelper.update();u.set(0.5,0,0,0.5,0,0.5,0,0.5,0,0,0.5,0.5,0,0,0,1);u.multiply(q.projectionMatrix);u.multiply(q.matrixWorldInverse); +g.multiplyMatrices(q.projectionMatrix,q.matrixWorldInverse);h.setFromMatrix(g);b.setRenderTarget(s);b.clear();C=l.__webglObjects;n=0;for(s=C.length;n 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"}}; diff --git a/plugins/senslabmap/static/js/viewer3D.js b/plugins/senslabmap/static/js/viewer3D.js deleted file mode 100644 index 33ae659e..00000000 --- a/plugins/senslabmap/static/js/viewer3D.js +++ /dev/null @@ -1,342 +0,0 @@ -// Various global variables -var mouseX = 0, mouseY = 0, camera, scene, renderer, projector; - -// Camera parameters -var phi = -100, theta = 0, distance = 130; - -// graphical nodes -var objects = []; - -// list of selected nodes -var selectedNodes = []; - -var div3d, nodebox, infobox; - -function onResize() { - renderer.setSize(div3d.offsetWidth, div3d.offsetHeight); - camera.aspect = div3d.offsetWidth / div3d.offsetHeight; - camera.updateProjectionMatrix(); - myrender(); -} - -function getCenter(nodes) { - var xmin = 0, ymin = 0, zmin = 0; - var xmax = 0, ymax = 0, zmax = 0; - - for (var i = 0; i < nodes.length; i++) { - if (nodes[i][1] > xmax) xmax = nodes[i][1]; - if (nodes[i][1] < xmin) xmin = nodes[i][1]; - if (nodes[i][2] > ymax) ymax = nodes[i][2]; - if (nodes[i][2] < ymin) ymin = nodes[i][2]; - if (nodes[i][3] > zmax) zmax = nodes[i][3]; - if (nodes[i][3] < zmin) zmin = nodes[i][3]; - } - return {x: (xmax + xmin) / 2, y: (ymax + ymin) / 2, z: (zmax + zmin) / 2}; -} - -function debugaxis(axisLength) { - var v = function(x, y, z) { - return new THREE.Vertex(new THREE.Vector3(x, y, z)); - } - - var createAxis = function (p1, p2, color) { - var lineGeometry = new THREE.Geometry(); - var lineMat = new THREE.LineBasicMaterial({ color: color, lineWidth: 2 }); - lineGeometry.vertices.push(p1, p2); - var line = new THREE.Line(lineGeometry, lineMat); - scene.add(line); - } - - createAxis(v(0, 0, 0), v(axisLength, 0, 0), 0xFF0000); - createAxis(v(0, 0, 0), v(0, axisLength, 0), 0x00FF00); - createAxis(v(0, 0, 0), v(0, 0, axisLength), 0x0000FF); -}; - -function drawNodes(nodes) { - var geometry = new THREE.Geometry(); - var center = getCenter(nodes); - - onResize(); - for (var i = 0; i < nodes.length; i++) { - var material = new THREE.ParticleCanvasMaterial({ - color: 0xffffff, - program: function (context) { - context.beginPath(); - context.arc(0, 0, 1, 0, Math.PI * 2, true); - context.closePath(); - context.fill(); - } - }); - var particle = new THREE.Particle(material); - particle.name = nodes[i][0]; - particle.position.x = nodes[i][1] - center.x; - particle.position.y = nodes[i][2] - center.y; - particle.position.z = nodes[i][3] - center.z; - particle.uid = nodes[i][4]; - particle.state = nodes[i][5]; - particle.position.multiplyScalar(10); - particle.scale.x = particle.scale.y = 1; - scene.add(particle); - - var vertex = new THREE.Vertex(particle.position); - geometry.vertices.push(vertex); - objects.push(particle) - - debugaxis(10); - myrender(); - } -} - -function init(nodes) { - div3d = document.getElementById('div3d'); - nodebox = document.getElementById('nodebox'); - infobox = document.getElementById('infobox'); - - infobox.innerHTML = 'Node info : '; - nodebox.value = ""; - - camera = new THREE.PerspectiveCamera(75, div3d.offsetWidth / div3d.offsetHeight, 1, 10000); - scene = new THREE.Scene(); - renderer = new THREE.CanvasRenderer(); - projector = new THREE.Projector(); - - div3d.appendChild(renderer.domElement); - - window.addEventListener('resize', onResize, false); - scene.add(camera); - - nodebox.onkeyup = parseNodebox; - - div3d.onmousedown = OnMouseDown; - div3d.onmouseup = OnMouseUp; - div3d.onmousemove = displayNodeInfo; - if (div3d.addEventListener) { - div3d.addEventListener('DOMMouseScroll', wheel, false); // mozilla - } - div3d.onmousewheel = wheel; // IE & Opera -} - -function sortfunction(a, b) { - return (a - b) //causes an array to be sorted numerically and ascending -} - -// factorize the expanded list in selectedNode to produce dash intervals -// 1,2,3,5,9 -> 1-3,5,9 -function factorize() { - var fact = []; - var previous = 0; - var intervalStart = 0; - selectedNodes.sort(sortfunction); - for (j = 0; j < selectedNodes.length; j++) { - if (intervalStart) { - // we are in an interval - if (selectedNodes[j] == previous + 1) { - // interval grows - previous += 1; - } else { - // end of interval - fact.push(intervalStart + "-" + previous); - intervalStart = 0; - previous = selectedNodes[j]; - } - } else { - // we are not in an interval - if (selectedNodes[j] == previous + 1) { - // let's begin an interval - intervalStart = previous; - previous += 1; - } else { - if (previous) { - fact.push(previous); - } - previous = selectedNodes[j]; - } - } - } // for end - // at the end of the loop, two cases - // we were still in an interval, then add it to the result - // we were not in an interval, then add the last selectednode (previous) - if (intervalStart) { - fact.push(intervalStart + "-" + previous); - } else if (previous) { - fact.push(previous); - } - return fact; -} - -// expand a list of nodes containing dash intervals -// 1-3,5,9 -> 1,2,3,5,9 -function expand(input) { - var factorized = input.split(","); - var expanded = []; - for (var i = 0; i < factorized.length; i++) { - var d = factorized[i].split("-"); - if (d.length == 2) { - for (var j = parseInt(d[0]); j < parseInt(d[1]) + 1; j++) { - expanded.push(j); - } - } else { - expanded.push(parseInt(factorized[i])); - } - } - expanded.sort(sortfunction); - for (var i = 1; i < expanded.length; i++) { - if (expanded[i] == expanded[i - 1]) { - expanded.splice(i--, 1); - } - } - return expanded; -} - -function parseNodebox() { - selectedNodes = expand(nodebox.value); - myrender(); -} - -// set the camera position according two angles theta and phi and the distance -// and display the scene -function myrender() { - camera.position.x = distance * Math.sin(theta * Math.PI / 360) * Math.cos(phi * Math.PI / 360); - camera.position.y = distance * Math.sin(this.phi * Math.PI / 360); - camera.position.z = distance * Math.cos(this.theta * Math.PI / 360) * Math.cos(this.phi * Math.PI / 360); - camera.lookAt(scene.position); - camera.updateMatrix(); - - for (i = 0; i < objects.length; i++) { - if (selectedNodes.indexOf(objects[i].name) != -1) { - objects[i].material.color.setHex(0x0099CC); - } else { - if (objects[i].state == "Busy") { - objects[i].material.color.setHex(0x9943BE); - } else if (objects[i].state == "Alive") { - objects[i].material.color.setHex(0x7FFF00); - } else { - objects[i].material.color.setHex(0xFF3030); - } - } - } - renderer.render(scene, camera); -} - -// rigthbutton is used for rotations -function onDocumentMouseMoveRot(event) { - var NewmouseX = event.clientX; - var NewmouseY = event.clientY; - var DeltaX = NewmouseX - mouseX; - var DeltaY = NewmouseY - mouseY; - - mouseX = NewmouseX; - mouseY = NewmouseY; - - theta -= DeltaX; - phi += DeltaY; - if (phi > 180) phi = 180; - if (phi < -180) phi = -180; - myrender(); -} -// mousewheel is used for zoom -function Zoom(delta) { - distance += delta * 5; - myrender(); -} - -// return the graphical node under the mouse -function findNodeUnderMouse(event) { - var x, y, z; - - event.preventDefault(); - - x = ((event.clientX - div3d.offsetLeft) / div3d.offsetWidth) * 2 - 1; - y = -((event.clientY - div3d.offsetTop) / div3d.offsetHeight) * 2 + 1; - z = 0.5; - - var vector = new THREE.Vector3(x, y, z); - projector.unprojectVector(vector, camera); - - var ray = new THREE.Ray(camera.position, vector.subSelf(camera.position).normalize()); - var intersects = ray.intersectObjects(objects); - - if (intersects.length > 0) { - return intersects[0]; - } else { - return null; - } -} - -// display some info of the node under the mouse -function displayNodeInfo(e) { - obj = findNodeUnderMouse(e); - if (obj) { - infobox.innerHTML = 'Node info : number ' + obj.object.name + " with id " + obj.object.uid; - } -} - -// select/unselect nodes -function toggleNode(obj) { - var nodeId = obj.object.name; - var index = selectedNodes.indexOf(nodeId); - - if (index == -1) { - selectedNodes.push(nodeId); - } else { - selectedNodes.splice(index, 1); - } - nodebox.value = factorize().join(","); - myrender(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Mouse handling functions -// -function OnMouseDown(e) { - var clickType = 'LEFT'; - if (e.type != 'mousedown') return true - if (e.which) { - if (e.which == 3) clickType = 'RIGHT'; - if (e.which == 2) clickType = 'MIDDLE'; - //infobox.innerHTML = clickType + " - Cam Pos = " + camera.position.x + "," + camera.position.y + "," + camera.position.z; - } - mouseX = e.clientX; - mouseY = e.clientY; - if (clickType == 'RIGHT') { - document.onmousemove = onDocumentMouseMoveRot; - } - if (clickType == 'LEFT') { - obj = findNodeUnderMouse(e); - if (obj != null) toggleNode(obj); - } -} - -function OnMouseUp(e) { - document.onmousemove = displayNodeInfo; -} - -// This function was taken here : http://www.adomas.org/javascript-mouse-wheel/ -// Event handler for mouse wheel event. - -function wheel(event) { - var delta = 0; - if (!event) /* For IE. */ - event = window.event; - if (event.wheelDelta) { /* IE/Opera. */ - delta = event.wheelDelta / 120; - } else if (event.detail) { /** Mozilla case. */ - /** In Mozilla, sign of delta is different than in IE. - * Also, delta is multiple of 3. - */ - delta = -event.detail / 3; - } - /** If delta is nonzero, handle it. - * Basically, delta is now positive if wheel was scrolled up, - * and negative, if wheel was scrolled down. - */ - if (delta) - Zoom(delta); - /** Prevent default actions caused by mouse wheel. - * That might be ugly, but we handle scrolls somehow - * anyway, so don't bother here.. - */ - if (event.preventDefault) - event.preventDefault(); - event.returnValue = false; -} diff --git a/plugins/senslabmap/templates/senslabmap.html b/plugins/senslabmap/templates/senslabmap.html index c00ea643..aa9a39fb 100644 --- a/plugins/senslabmap/templates/senslabmap.html +++ b/plugins/senslabmap/templates/senslabmap.html @@ -1,18 +1,30 @@ -
-
-
-
- Selected Nodes - -
-
-
-
-
Alive - -
Down - -
Selected - -
Busy -
-
-
-
\ No newline at end of file +
+ \ No newline at end of file diff --git a/plugins/slicestat/static/js/slicestat.js b/plugins/slicestat/static/js/slicestat.js index 0e3dc532..da177222 100644 --- a/plugins/slicestat/static/js/slicestat.js +++ b/plugins/slicestat/static/js/slicestat.js @@ -51,7 +51,7 @@ }, /* PLUGIN EVENTS */ - // on_show like in hazelnut + // on_show like in querytable /* GUI EVENTS */ diff --git a/plugins/tabs/__init__.py b/plugins/tabs/__init__.py index 6da94da1..d1b9bda3 100644 --- a/plugins/tabs/__init__.py +++ b/plugins/tabs/__init__.py @@ -15,5 +15,3 @@ class Tabs (Composite): def json_settings_list (self): return [] - def export_json_settings(self): - return True diff --git a/portal/accountview.py b/portal/accountview.py index d4b68f40..f7fa1b8d 100644 --- a/portal/accountview.py +++ b/portal/accountview.py @@ -161,12 +161,20 @@ def account_process(request): # private_key = k.as_pem() # private_key = ''.join(private_key.split()) # public_key = "ssh-rsa " + public_key - keypair = '{"user_public_key":'+ public_key + ', "user_private_key":'+ private_key + '}' + # now we overwrite the config field with keypair + # once there will be user_hrn, we need to keep user_hrn and change only the keypair + # see submit_name section for implementing this # keypair = re.sub("\r", "", keypair) # keypair = re.sub("\n", "\\n", keypair) # #keypair = keypair.rstrip('\r\n') # keypair = ''.join(keypair.split()) # updating maniolf local:account table + account_config = json.loads(account_detail['config']) + # preserving user_hrn + user_hrn = account_config.get('user_hrn','N/A') + keypair = '{"user_public_key":'+ public_key + ', "user_private_key":'+ private_key + ', "user_hrn":"'+ user_hrn + '"}' + updated_config = json.dumps(account_config) + user_params = { 'config': keypair, 'auth_type':'managed'} manifold_update_account(request,user_params) messages.success(request, 'Sucess: New Keypair Generated!') @@ -186,7 +194,10 @@ def account_process(request): file_extension = os.path.splitext(file_name)[1] allowed_extension = ['.pub','.txt'] if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content): - file_content = '{"user_public_key":"'+ file_content +'"}' + account_config = json.loads(account_detail['config']) + # preserving user_hrn + user_hrn = account_config.get('user_hrn','N/A') + file_content = '{"user_public_key":"'+ file_content + '", "user_hrn":"'+ user_hrn +'"}' #file_content = re.sub("\r", "", file_content) #file_content = re.sub("\n", "\\n",file_content) file_content = ''.join(file_content.split()) diff --git a/portal/dashboardview.py b/portal/dashboardview.py index 1cc12e0e..44a3ea91 100644 --- a/portal/dashboardview.py +++ b/portal/dashboardview.py @@ -1,7 +1,8 @@ from manifold.core.query import Query from unfold.page import Page -from plugins.lists.simplelist import SimpleList +from plugins.lists.testbedlist import TestbedList +from plugins.lists.slicelist import SliceList from unfold.loginrequired import LoginRequiredAutoLogoutView @@ -22,32 +23,29 @@ class DashboardView (LoginRequiredAutoLogoutView): # Slow... #slice_query = Query().get('slice').filter_by('user.user_hrn', 'contains', user_hrn).select('slice_hrn') - auth_query = Query().get('network').select('network_hrn','platform') + testbed_query = Query().get('network').select('network_hrn','platform') # DEMO GEC18 Query only PLE slice_query = Query().get('user').filter_by('user_hrn', '==', '$user_hrn').select('user_hrn', 'slice.slice_hrn') page.enqueue_query(slice_query) - page.enqueue_query(auth_query) + page.enqueue_query(testbed_query) page.expose_js_metadata() page.expose_queries() - slicelist = SimpleList( - title = None, + slicelist = SliceList( page = page, - key = 'slice.slice_hrn', + title = "slices", query = slice_query, ) - # XXX TODO: plugins/lists/static/js/simplelist.js => hardcoded keys that give links : slice_hrn & platform - authlist = SimpleList( - title = None, + testbedlist = TestbedList( page = page, - key = 'platform', - query = auth_query, + title = "testbeds", + query = testbed_query, ) context = super(DashboardView, self).get_context_data(**kwargs) context['person'] = self.request.user - context['networks'] = authlist.render(self.request) + context['testbeds'] = testbedlist.render(self.request) context['slices'] = slicelist.render(self.request) # XXX This is repeated in all pages diff --git a/portal/homeview.py b/portal/homeview.py index b6af0644..5b822212 100644 --- a/portal/homeview.py +++ b/portal/homeview.py @@ -33,6 +33,8 @@ class HomeView (FreeAccessView): # . a django User in case of success # . or None if the backend could be reached but the authentication failed auth_result = authenticate(token=token) + # use one or two columns for the layout - not logged in users will see the login prompt + env['layout_1_or_2']="layout-unfold2.html" if not username else "layout-unfold1.html" # high-level errors, like connection refused or the like if isinstance (auth_result, ManifoldResult): manifoldresult = auth_result @@ -61,5 +63,7 @@ class HomeView (FreeAccessView): env['topmenu_items'] = topmenu_items(None, request) if state: env['state'] = state elif not env['username']: env['state'] = "Please sign in" + # use one or two columns for the layout - not logged in users will see the login prompt + env['layout_1_or_2']="layout-unfold2.html" if not env['username'] else "layout-unfold1.html" return render_to_response('home-view.html',env, context_instance=RequestContext(request)) diff --git a/portal/platformsview.py b/portal/platformsview.py index 0a6677e3..67446436 100644 --- a/portal/platformsview.py +++ b/portal/platformsview.py @@ -4,7 +4,7 @@ from unfold.page import Page from unfold.loginrequired import FreeAccessView from ui.topmenu import topmenu_items, the_user -from plugins.hazelnut import Hazelnut +from plugins.querytable import QueryTable # View for platforms class PlatformsView(FreeAccessView): @@ -19,7 +19,7 @@ class PlatformsView(FreeAccessView): page.expose_js_metadata() page.expose_queries() - platformlist = Hazelnut( + platformlist = QueryTable( page = page, title = 'List', domid = 'checkboxes', @@ -48,4 +48,6 @@ class PlatformsView(FreeAccessView): context.update(page.prelude_env()) + context['layout_1_or_2']="layout-unfold2.html" if not context['username'] else "layout-unfold1.html" + return context diff --git a/portal/platformview.py b/portal/platformview.py index 69fd1b02..f3ea7f7a 100644 --- a/portal/platformview.py +++ b/portal/platformview.py @@ -4,7 +4,7 @@ from unfold.page import Page from unfold.loginrequired import FreeAccessView from ui.topmenu import topmenu_items, the_user -from plugins.hazelnut import Hazelnut +from plugins.querytable import QueryTable # View for 1 platform and its details class PlatformView(FreeAccessView): @@ -25,7 +25,7 @@ class PlatformView(FreeAccessView): page.expose_js_metadata() page.expose_queries() - networklist = Hazelnut( + networklist = QueryTable( page = page, title = 'List', domid = 'checkboxes', @@ -61,6 +61,3 @@ class PlatformView(FreeAccessView): context.update(page.prelude_env()) return context - - - diff --git a/portal/portalpage.py b/portal/portalpage.py index b5470fd2..f592444d 100644 --- a/portal/portalpage.py +++ b/portal/portalpage.py @@ -15,8 +15,8 @@ class PortalPage(Page): def render(self): template_env = {} - # define 'unfold1_main' to the template engine - the main contents - template_env [ 'unfold1_main' ] = "\n".join(self._content) + # define 'unfold_main' to the template engine - the main contents + template_env [ 'unfold_main' ] = "\n".join(self._content) # more general variables expected in the template template_env [ 'title' ] = 'Test view that combines various plugins' diff --git a/portal/registrationview.py b/portal/registrationview.py index e27dfb4d..85935f2d 100644 --- a/portal/registrationview.py +++ b/portal/registrationview.py @@ -63,7 +63,11 @@ class RegistrationView (FreeAccessView): reg_auth = request.POST.get('authority_hrn', '') reg_login = request.POST.get('login', '') reg_email = request.POST.get('email','').lower() - + #prepare user_hrn + split_email = reg_email.split("@")[0] + split_email = split_email.replace(".", "_") + user_hrn = reg_auth + '.' + split_email + #POST value validation if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None): errors.append('First Name may contain only letters, numbers, spaces and @/./+/-/_ characters.') @@ -89,7 +93,7 @@ class RegistrationView (FreeAccessView): # private_key = ''.join(private_key.split()) # public_key = "ssh-rsa " + public_key # Saving to DB - keypair = '{"user_public_key":'+ public_key + ', "user_private_key":'+ private_key + '}' + keypair = '{"user_public_key":'+ public_key + ', "user_private_key":'+ private_key + ', "user_hrn":"'+ user_hrn + '"}' #keypair = re.sub("\r", "", keypair) #keypair = re.sub("\n", "\\n", keypair) #keypair = keypair.rstrip('\r\n') @@ -101,7 +105,7 @@ class RegistrationView (FreeAccessView): file_extension = os.path.splitext(file_name)[1] allowed_extension = ['.pub','.txt'] if file_extension in allowed_extension and re.search(r'ssh-rsa',file_content): - keypair = '{"user_public_key":"'+ file_content +'"}' + keypair = '{"user_public_key":"'+ file_content + '", "user_hrn":"'+ user_hrn +'"}' keypair = re.sub("\r", "", keypair) keypair = re.sub("\n", "\\n",keypair) keypair = ''.join(keypair.split()) @@ -131,11 +135,11 @@ class RegistrationView (FreeAccessView): 'first_name' : reg_fname, 'last_name' : reg_lname, 'authority_hrn' : reg_auth, - 'email' : reg_email, + 'email' : reg_email, + 'user_hrn' : user_hrn, 'keypair' : 'Public Key :' + public_key, 'cc_myself' : True # form.cleaned_data['cc_myself'] } - recipients = authority_get_pi_emails(request,reg_auth) if ctx['cc_myself']: diff --git a/portal/resourceview.py b/portal/resourceview.py index c9fa5ba8..f0f856ae 100644 --- a/portal/resourceview.py +++ b/portal/resourceview.py @@ -5,7 +5,7 @@ from unfold.loginrequired import FreeAccessView from ui.topmenu import topmenu_items, the_user from plugins.googlemap import GoogleMap -from plugins.hazelnut import Hazelnut +from plugins.querytable import QueryTable from plugins.lists.simplelist import SimpleList from plugins.slicestat import SliceStat @@ -31,7 +31,7 @@ class ResourceView(FreeAccessView): page.expose_js_metadata() page.expose_queries() - resourcelist = Hazelnut( + resourcelist = QueryTable( page = page, title = 'List', domid = 'checkboxes', diff --git a/portal/sliceview.py b/portal/sliceview.py index 8461b1a6..38c90fca 100644 --- a/portal/sliceview.py +++ b/portal/sliceview.py @@ -11,8 +11,8 @@ from ui.topmenu import topmenu_items, the_user from plugins.raw import Raw from plugins.stack import Stack from plugins.tabs import Tabs -from plugins.hazelnut import Hazelnut -from plugins.resources_selected import ResourcesSelected +from plugins.querytable import QueryTable +from plugins.queryupdater import QueryUpdater from plugins.googlemap import GoogleMap from plugins.senslabmap import SensLabMap from plugins.querycode import QueryCode @@ -102,9 +102,9 @@ class SliceView (LoginRequiredAutoLogoutView): ) # -------------------------------------------------------------------------- - # ResourcesSelected (Pending Operations) + # QueryUpdater (Pending Operations) - main_stack.insert(ResourcesSelected( + main_stack.insert(QueryUpdater( page = page, title = 'Pending operations', query = main_query, @@ -145,7 +145,7 @@ class SliceView (LoginRequiredAutoLogoutView): # RESOURCES # the resources part is made of a Tabs (Geographic, List), - resources_as_map = GoogleMap( + resources_as_gmap = GoogleMap( page = page, title = 'Geographic view', domid = 'resources-map', @@ -160,7 +160,15 @@ class SliceView (LoginRequiredAutoLogoutView): zoom = 4, ) - resources_as_list = Hazelnut( + resources_as_3dmap = SensLabMap( + page = page, + title = '3D Map', + domid = 'senslabmap', + query = sq_resource, + query_all = query_resource_all, + ) + + resources_as_list = QueryTable( page = page, domid = 'resources-list', title = 'List view', @@ -175,7 +183,7 @@ class SliceView (LoginRequiredAutoLogoutView): }, ) - # with the new 'Filter' stuff on top, no need for anything but the hazelnut + # with the new 'Filter' stuff on top, no need for anything but the querytable resources_as_list_area = resources_as_list resources_area = Tabs ( page=page, @@ -183,7 +191,9 @@ class SliceView (LoginRequiredAutoLogoutView): togglable=True, title="Resources", outline_complete=True, - sons=[ resources_as_map, resources_as_list_area ], + sons=[ resources_as_gmap, + resources_as_3dmap, + resources_as_list_area, ], active_domid = 'resources-map', ) main_stack.insert (resources_area) @@ -202,7 +212,7 @@ class SliceView (LoginRequiredAutoLogoutView): ) main_stack.insert(tab_users) - tab_users.insert(Hazelnut( + tab_users.insert(QueryTable( page = page, title = 'Users List', domid = 'users-list', @@ -287,7 +297,7 @@ class SliceView (LoginRequiredAutoLogoutView): # ) # main_stack.insert(tab_measurements) # -# tab_measurements.insert(Hazelnut( +# tab_measurements.insert(QueryTable( # page = page, # title = 'Measurements', # domid = 'measurements-list', @@ -324,8 +334,8 @@ class SliceView (LoginRequiredAutoLogoutView): # variables that will get passed to the view-unfold1.html template template_env = {} - # define 'unfold1_main' to the template engine - the main contents - template_env [ 'unfold1_main' ] = main_stack.render(request) + # define 'unfold_main' to the template engine - the main contents + template_env [ 'unfold_main' ] = main_stack.render(request) # more general variables expected in the template template_env [ 'title' ] = '%(slicename)s'%locals() diff --git a/unfold/static/css/onelab_marko.css b/portal/static/css/onelab_marko.css similarity index 93% rename from unfold/static/css/onelab_marko.css rename to portal/static/css/onelab_marko.css index ab82706b..2d4f71cb 100644 --- a/unfold/static/css/onelab_marko.css +++ b/portal/static/css/onelab_marko.css @@ -5,8 +5,8 @@ /* GENERAL */ .container { - padding: 0 !important; - color: #fff; + padding: 0 !important; + color: #fff; background: url(http://new.fit-equipex.fr/images/background.jpg) no-repeat; margin: 0; width: 100%; @@ -165,16 +165,21 @@ h2.well.well-lg { - +/* if window enlarged wider than background picture */ +body { + background: black !important; +} /* TOPMENU.CSS */ +/* Thierry : turning this off body { - /* background: #30196d !important; */ - background: black !important; + *//* background: #30196d !important; *//* + background: black !important; padding-top: 60px; padding-bottom: 0px; } +Thierry */ /* Thierry : turning this off div.topmenu { @@ -283,9 +288,9 @@ div.dataTables_info { -/* HAZELNUT */ +/* QUERYTABLE */ -div.Hazelnut table.dataTable th { +div.QueryTable table.dataTable th { font: bold 12px/22px Ubuntu, Arial, sans-serif; color: #333 !important; border-right: 0px solid #333 !important; @@ -299,18 +304,18 @@ div.Hazelnut table.dataTable th { background: url('../img/tablesort-header.jpg') no-repeat !important; } -div.Hazelnut table.dataTable td, div.Hazelnut table.dataTable textarea, div.Hazelnut table.dataTable input [type="text"] { +div.QueryTable table.dataTable td, div.QueryTable table.dataTable textarea, div.QueryTable table.dataTable input [type="text"] { font: normal 12px Ubuntu, Arial, Helvetica, sans-serif; border-right: 0px solid #fff !important; border-bottom: 1px solid #fff !important; } -div.Hazelnut table.dataTable thead { +div.QueryTable table.dataTable thead { background: url('../img/tablesort-header.png') repeat-x !important; background-color: #caebea; } -div.Hazelnut table.dataTable tfoot { +div.QueryTable table.dataTable tfoot { background: url('../img/tablesort-header.png') repeat-x !important; /* background-color: # !important; */ } @@ -327,8 +332,11 @@ table.query-editor { } .query-editor-spacer, -.plugin.ResourcesSelected, -.plugin.Tabs { +.plugin.QueryUpdater, +/* Thierry : turning this off +.plugin.Tabs +Thierry */ +{ margin-top: 60px !important; } @@ -414,8 +422,3 @@ table.query-editor td { padding-left: 0 !important; } -.simplelist { - font-size: 100%; - text-align: center !important; - margin: 0 auto; -} diff --git a/portal/static/js/common.functions.js b/portal/static/js/common.functions.js index 56b02ca9..d6f3f995 100644 --- a/portal/static/js/common.functions.js +++ b/portal/static/js/common.functions.js @@ -1,6 +1,3 @@ -/* - * This file is included in tophat_render.php - */ // Escape special characters in jQuery Selector function escape_id( myid ) { return "#" + myid.replace( /(:|\.|\[|\])/g, "\\$1" ); diff --git a/portal/templates/account-view.html b/portal/templates/account-view.html index 60f05bcf..4b042468 100644 --- a/portal/templates/account-view.html +++ b/portal/templates/account-view.html @@ -8,7 +8,7 @@ {% endblock %} -{% block unfold1_main %} +{% block unfold_main %}

MySlice Account

diff --git a/portal/templates/contact.html b/portal/templates/contact.html index 8ffbf9c9..ab00b157 100644 --- a/portal/templates/contact.html +++ b/portal/templates/contact.html @@ -4,12 +4,12 @@ {{ wizard.form.media }} {% endblock %} -{% block unfold1_main %} +{% block unfold_main %}

Onelab Support

-

If you have already registered, then please send an e-mail +

If you have already registered, then please send an e-mail or visit us

diff --git a/portal/templates/contact_sent.html b/portal/templates/contact_sent.html index ca12d5f5..62a2ab98 100644 --- a/portal/templates/contact_sent.html +++ b/portal/templates/contact_sent.html @@ -1,6 +1,6 @@ {% extends "layout-unfold1.html" %} -{% block unfold1_main %} +{% block unfold_main %}

Query Received !

diff --git a/portal/templates/dashboard.html b/portal/templates/dashboard.html index 5ca062db..e4c61b42 100644 --- a/portal/templates/dashboard.html +++ b/portal/templates/dashboard.html @@ -3,7 +3,7 @@ {% block head %} {% endblock %} -{% block unfold1_main %} +{% block unfold_main %}
@@ -28,7 +28,7 @@

Testbeds

- {{networks}} + {{testbeds}}
diff --git a/portal/templates/home-view.html b/portal/templates/home-view.html index 446cc31e..c5f3bfc6 100644 --- a/portal/templates/home-view.html +++ b/portal/templates/home-view.html @@ -1,12 +1,11 @@ -{% extends 'layout-unfold2.html' %} +{# fine for either layout-unfold1.html (logged in) or layout-unfold2.html (needs a login prompt) #} +{% extends layout_1_or_2 %} -{% block unfold2_margin %} -{% if not username %} +{% block unfold_margin %} {% include 'widget-login.html' %} -{% endif %} -{% endblock unfold2_margin %} +{% endblock unfold_margin %} -{% block unfold2_main %} +{% block unfold_main %} @@ -28,4 +27,4 @@ federated testbeds.

This UI server is connected to the manifold backend running at {{ MANIFOLD_URL }}.

-{% endblock unfold2_main %} +{% endblock unfold_main %} diff --git a/portal/templates/platform.html b/portal/templates/platform.html index d24d9ede..48afd944 100644 --- a/portal/templates/platform.html +++ b/portal/templates/platform.html @@ -4,7 +4,7 @@ {% endblock %} -{% block unfold1_main %} +{% block unfold_main %}

Platform

{{networks}} diff --git a/portal/templates/platforms.html b/portal/templates/platforms.html index 22340661..ee86241b 100644 --- a/portal/templates/platforms.html +++ b/portal/templates/platforms.html @@ -1,10 +1,15 @@ -{% extends "layout-unfold1.html" %} +{# fine for either layout-unfold1.html (logged in) or layout-unfold2.html (needs a login prompt) #} +{% extends layout_1_or_2 %} + +{% block unfold_margin %} +{% include 'widget-login.html' %} +{% endblock unfold_margin %} {% block head %} {% endblock %} -{% block unfold1_main %} +{% block unfold_main %}

Platforms

{{platforms}} diff --git a/portal/templates/register_user_wizard.html b/portal/templates/register_user_wizard.html index 8d1d5280..1f480a1b 100644 --- a/portal/templates/register_user_wizard.html +++ b/portal/templates/register_user_wizard.html @@ -8,7 +8,7 @@ {% endblock %} -{% block unfold1_main %} +{% block unfold_main %}

User registration

diff --git a/portal/templates/registration_view.html b/portal/templates/registration_view.html index b0bb3896..52cb402d 100644 --- a/portal/templates/registration_view.html +++ b/portal/templates/registration_view.html @@ -1,6 +1,6 @@ {% extends "layout-unfold1.html" %} -{% block unfold1_main %} +{% block unfold_main %}

OneLab Experimenter Registration

diff --git a/portal/templates/resource.html b/portal/templates/resource.html index d379470a..5b59f73e 100644 --- a/portal/templates/resource.html +++ b/portal/templates/resource.html @@ -4,7 +4,7 @@ {% endblock %} -{% block unfold1_main %} +{% block unfold_main %}

Resource

diff --git a/portal/templates/slice-request-ack-view.html b/portal/templates/slice-request-ack-view.html index 7ea26ed8..dc98c27a 100644 --- a/portal/templates/slice-request-ack-view.html +++ b/portal/templates/slice-request-ack-view.html @@ -1,6 +1,6 @@ {% extends "layout-unfold1.html" %} -{% block unfold1_main %} +{% block unfold_main %}

Slice request Received !

diff --git a/portal/templates/slice-request-view.html b/portal/templates/slice-request-view.html index b9e0e22d..4568864a 100644 --- a/portal/templates/slice-request-view.html +++ b/portal/templates/slice-request-view.html @@ -5,7 +5,7 @@ {{ wizard.form.media }} {% endblock %} -{% block unfold1_main %} +{% block unfold_main %} diff --git a/portal/templates/user_register.html b/portal/templates/user_register.html index baa56675..bfb08f12 100644 --- a/portal/templates/user_register.html +++ b/portal/templates/user_register.html @@ -5,7 +5,7 @@ {% endblock %} -{% block unfold1_main %} +{% block unfold_main %}

User registration

diff --git a/portal/templates/user_register_complete.html b/portal/templates/user_register_complete.html index 9e134cfb..35b252e8 100644 --- a/portal/templates/user_register_complete.html +++ b/portal/templates/user_register_complete.html @@ -1,6 +1,6 @@ {% extends "layout-unfold1.html" %} -{% block unfold1_main %} +{% block unfold_main %}

User registration complete !

diff --git a/portal/templates/validate_pending.html b/portal/templates/validate_pending.html index 9ddf01c9..0ab0e572 100644 --- a/portal/templates/validate_pending.html +++ b/portal/templates/validate_pending.html @@ -45,7 +45,7 @@ {% endblock %} -{% block unfold1_main %} +{% block unfold_main %}

Pending requests

diff --git a/portal/views.py b/portal/views.py index 167f324e..d454502e 100644 --- a/portal/views.py +++ b/portal/views.py @@ -62,7 +62,7 @@ class PresViewView(FreeAccessView): context = super(PresViewView, self).get_context_data(**kwargs) #context['ALL_STATIC'] = "all_static" - context['unfold1_main'] = pres_view.render(self.request) + context['unfold_main'] = pres_view.render(self.request) # XXX This is repeated in all pages # more general variables expected in the template diff --git a/debug_platform/__init__.py b/to-be-integrated/debug_platform/__init__.py similarity index 100% rename from debug_platform/__init__.py rename to to-be-integrated/debug_platform/__init__.py diff --git a/debug_platform/urls.py b/to-be-integrated/debug_platform/urls.py similarity index 100% rename from debug_platform/urls.py rename to to-be-integrated/debug_platform/urls.py diff --git a/debug_platform/views.py b/to-be-integrated/debug_platform/views.py similarity index 97% rename from debug_platform/views.py rename to to-be-integrated/debug_platform/views.py index e6b0c955..ead4ed7e 100644 --- a/debug_platform/views.py +++ b/to-be-integrated/debug_platform/views.py @@ -45,7 +45,7 @@ class PlatformView(TemplateView): context = super(PlatformView, self).get_context_data(**kwargs) context['ALL_STATIC'] = "all_static" - context['unfold1_main'] = debug_platform.render(self.request) + context['unfold_main'] = debug_platform.render(self.request) # XXX This is repeated in all pages # more general variables expected in the template diff --git a/to-be-integrated/plugins/code_editor/static/js/code_editor.js b/to-be-integrated/plugins/code_editor/static/js/code_editor.js index 664bbdc7..48111018 100644 --- a/to-be-integrated/plugins/code_editor/static/js/code_editor.js +++ b/to-be-integrated/plugins/code_editor/static/js/code_editor.js @@ -78,13 +78,13 @@ return this.each(function() { var $this = $(this); - var hazelnut = $this.data('Manifold'); + var querytable = $this.data('Manifold'); // Unbind all events using namespacing $(window).unbind('Manifold'); // Remove associated data - hazelnut.remove(); + querytable.remove(); $this.removeData('Manifold'); }); }, // destroy @@ -93,16 +93,16 @@ var $this=$(this); // xxx wtf. why [1] ? would expect 0... if (debug) - messages.debug("Hitting suspicious line in hazelnut.show"); + messages.debug("Hitting suspicious line in querytable.show"); var oTable = $($('.dataTable', $this)[1]).dataTable(); oTable.fnAdjustColumnSizing() /* Refresh dataTabeles if click on the menu to display it : fix dataTables 1.9.x Bug */ $(this).each(function(i,elt) { if (jQuery(elt).hasClass('dataTables')) { - var myDiv=jQuery('#hazelnut-' + this.id).parent(); + var myDiv=jQuery('#querytable-' + this.id).parent(); if(myDiv.height()==0) { - var oTable=$('#hazelnut-' + this.id).dataTable(); + var oTable=$('#querytable-' + this.id).dataTable(); oTable.fnDraw(); } } diff --git a/plugins/debug_platform/__init__.py b/to-be-integrated/plugins/debug_platform/__init__.py similarity index 85% rename from plugins/debug_platform/__init__.py rename to to-be-integrated/plugins/debug_platform/__init__.py index e14a478e..fa76ba40 100644 --- a/plugins/debug_platform/__init__.py +++ b/to-be-integrated/plugins/debug_platform/__init__.py @@ -1,7 +1,7 @@ from unfold.plugin import Plugin from unfold.page import Page #from plugins.code_editor import CodeEditor -from plugins.hazelnut import Hazelnut +from plugins.querytable import QueryTable class DebugPlatform(Plugin): @@ -29,6 +29,6 @@ class DebugPlatform(Plugin): # This part should be moved to a Layout env = {} env['topleft'] = CodeEditor(page=self.page, lineNumbers=True).render(request) - env['bottomleft'] = Hazelnut(page=self.page, columns=['dummy']).render(request) + env['bottomleft'] = QueryTable(page=self.page, columns=['dummy']).render(request) return env diff --git a/plugins/debug_platform/static/css/debug_platform.css b/to-be-integrated/plugins/debug_platform/static/css/debug_platform.css similarity index 100% rename from plugins/debug_platform/static/css/debug_platform.css rename to to-be-integrated/plugins/debug_platform/static/css/debug_platform.css diff --git a/plugins/debug_platform/static/js/debug_platform.js b/to-be-integrated/plugins/debug_platform/static/js/debug_platform.js similarity index 97% rename from plugins/debug_platform/static/js/debug_platform.js rename to to-be-integrated/plugins/debug_platform/static/js/debug_platform.js index cbbd0b75..dda946c3 100644 --- a/plugins/debug_platform/static/js/debug_platform.js +++ b/to-be-integrated/plugins/debug_platform/static/js/debug_platform.js @@ -79,13 +79,13 @@ return this.each(function() { var $this = $(this); - var hazelnut = $this.data('Manifold'); + var querytable = $this.data('Manifold'); // Unbind all events using namespacing $(window).unbind('Manifold'); // Remove associated data - hazelnut.remove(); + querytable.remove(); $this.removeData('Manifold'); }); }, // destroy diff --git a/plugins/debug_platform/templates/debug_platform.html b/to-be-integrated/plugins/debug_platform/templates/debug_platform.html similarity index 100% rename from plugins/debug_platform/templates/debug_platform.html rename to to-be-integrated/plugins/debug_platform/templates/debug_platform.html diff --git a/trash/dashboard.py b/trash/dashboard.py index a9742267..f4bde8fc 100644 --- a/trash/dashboard.py +++ b/trash/dashboard.py @@ -65,8 +65,8 @@ def dashboard_view (request): # variables that will get passed to the view-unfold2.html template template_env = {} - # define 'unfold2_main' to the template engine - template_env [ 'unfold2_main' ] = main_plugin.render(request) + # define 'unfold_main' to the template engine + template_env [ 'unfold_main' ] = main_plugin.render(request) # more general variables expected in the template template_env [ 'title' ] = 'Test view for a full request cycle' @@ -87,7 +87,7 @@ def dashboard_view (request): query=slices_query, ) # likewise but on the side view - template_env [ 'unfold2_margin' ] = related_plugin.render (request) + template_env [ 'unfold_margin' ] = related_plugin.render (request) # add our own css in the mix #page.add_css_files ( 'css/dashboard.css') diff --git a/trash/pluginview.py b/trash/pluginview.py index 0b22e119..f2003127 100644 --- a/trash/pluginview.py +++ b/trash/pluginview.py @@ -17,7 +17,7 @@ from plugins.quickfilter import QuickFilter from plugins.querycode import QueryCode from plugins.raw import Raw from plugins.messages import Messages -from plugins.hazelnut import Hazelnut +from plugins.querytable import QueryTable from ui.topmenu import topmenu_items, the_user from trash.trashutils import hard_wired_slice_names, hard_wired_list, lorem_p, lorem, quickfilter_criterias @@ -35,7 +35,7 @@ def test_plugin_view (request): slicename='ple.inria.heartbeat' main_query = Query.get('resource').filter_by('slice_hrn', '=', slicename).select(['network','type','hrn','hostname','sliver']) - # without an hazelnut, this would use use : run_it=False as nothing would listen to the results + # without an querytable, this would use use : run_it=False as nothing would listen to the results page.enqueue_query (main_query, # run_it=False ) @@ -53,11 +53,11 @@ def test_plugin_view (request): domid="messages-transient", levels='ALL', ), - Hazelnut ( + QueryTable ( page=page, title="Slice %s - checkboxes"%slicename, query=main_query, - domid="hazelnut", + domid="querytable", checkboxes=True, togglable=True, ), @@ -84,8 +84,8 @@ function issue_debug() {console.log("issue_debug");messages.debug("issue_debug") $(function(){$("#bouton").click(issue_debug);}); """) - # define 'unfold1_main' to the template engine - template_env [ 'unfold1_main' ] = main_plugin.render(request) + # define 'unfold_main' to the template engine + template_env [ 'unfold_main' ] = main_plugin.render(request) # more general variables expected in the template template_env [ 'title' ] = 'Single Plugin View' diff --git a/trash/sampleviews.py b/trash/sampleviews.py index 5d257a4f..e1c66d8c 100644 --- a/trash/sampleviews.py +++ b/trash/sampleviews.py @@ -84,8 +84,8 @@ def test_plugin_view (request): title='QuickFilter in main content', criterias=quickfilter_criterias, ) ] ) - # define 'unfold2_main' to the template engine - template_env [ 'unfold2_main' ] = main_plugin.render(request) + # define 'unfold_main' to the template engine + template_env [ 'unfold_main' ] = main_plugin.render(request) ########## related_plugin = StaticList (page=page, @@ -94,7 +94,7 @@ def test_plugin_view (request): list=hard_wired_slice_names, header='Slices') # likewise but on the side view - template_env [ 'unfold2_margin' ] = related_plugin.render (request) + template_env [ 'unfold_margin' ] = related_plugin.render (request) # more general variables expected in the template template_env [ 'title' ] = 'Test Plugin View' diff --git a/trash/templates/view-scroll.html b/trash/templates/view-scroll.html index 5fa9400b..f6f6b933 100644 --- a/trash/templates/view-scroll.html +++ b/trash/templates/view-scroll.html @@ -1,6 +1,6 @@ {% extends 'layout-unfold2.html' %} -{% block unfold2_main %} +{% block unfold_main %} {% insert_str prelude "css/sample.css" %} @@ -11,9 +11,9 @@
scroll3 area {{ lorem }}
scroll4 area {{ lorem }} {{ lorem }} {{ lorem }}
-{% endblock unfold2_main %} +{% endblock unfold_main %} -{% block unfold2_margin %} +{% block unfold_margin %}
-{% endblock unfold2_margin %} +{% endblock unfold_margin %} diff --git a/trash/templates/view-tab.html b/trash/templates/view-tab.html index c3ba335c..6b4472bd 100644 --- a/trash/templates/view-tab.html +++ b/trash/templates/view-tab.html @@ -1,6 +1,6 @@ {% extends 'layout-unfold2.html' %} -{% block unfold2_main %} +{% block unfold_main %} {% insert_str prelude "css/sample.css" %} {% insert prelude_js %} @@ -58,13 +58,13 @@ $(function() {$('#mylougout').click(foo);}) decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.
-{% endblock unfold2_main %} +{% endblock unfold_main %} -{% block unfold2_margin %} +{% block unfold_margin %} This text is shorter on purpose Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. -{% endblock unfold2_margin %} +{% endblock unfold_margin %} diff --git a/trash/templates/view-unfold2.html b/trash/templates/view-unfold2.html index 7626ab1e..e1e43171 100644 --- a/trash/templates/view-unfold2.html +++ b/trash/templates/view-unfold2.html @@ -1,9 +1,9 @@ {% extends 'layout-unfold2.html' %} -{% block unfold2_main %} -{{ unfold2_main|safe }} -{% endblock unfold2_main %} +{% block unfold_main %} +{{ unfold_main|safe }} +{% endblock unfold_main %} -{% block unfold2_margin %} -{{ unfold2_margin|safe }} -{% endblock unfold2_margin %} +{% block unfold_margin %} +{{ unfold_margin|safe }} +{% endblock unfold_margin %} diff --git a/ui/static/css/layout-unfold.css b/ui/static/css/layout-unfold.css new file mode 100644 index 00000000..43b8920e --- /dev/null +++ b/ui/static/css/layout-unfold.css @@ -0,0 +1,9 @@ +/* single column layout - layout-unfold1.html */ +#unfold1-main { +} +/* dual column layout - layout-unfold2.html */ +#unfold2-main { +} +#unfold2-margin { +/* trying to set a right padding here results in undesired results (spans beyond right end) */ +} diff --git a/ui/static/css/layout-unfold2.css b/ui/static/css/layout-unfold2.css deleted file mode 100644 index 9e068372..00000000 --- a/ui/static/css/layout-unfold2.css +++ /dev/null @@ -1,7 +0,0 @@ -/* this relates to the unfold-layout1 template */ -#unfold2-main { -} -#unfold2-margin { - padding: 10; -/* background-color: #fff2ff; */ -} diff --git a/ui/static/css/topmenu.css b/ui/static/css/topmenu.css index 792377b8..70acc0e7 100644 --- a/ui/static/css/topmenu.css +++ b/ui/static/css/topmenu.css @@ -1,13 +1,12 @@ /* this is to get the content below the navbar */ body { padding-top: 60px; - padding-bottom: 20px; } /* center the buttons vertically in the header */ div.topmenu { padding-top: 7px; } ul.logged-in { - padding-top: 12px; + padding-top: 14px; } button.logged-in { font-size: small; diff --git a/ui/templates/base.html b/ui/templates/base.html index b551df76..f7787353 100644 --- a/ui/templates/base.html +++ b/ui/templates/base.html @@ -20,7 +20,7 @@ {% insert_str prelude "js/plugin.js" %} {% insert_str prelude "js/manifold.js" %} {% insert_str prelude "js/topmenu.js" %} -{% insert_str prelude "css/layout-unfold2.css" %} +{% insert_str prelude "css/layout-unfold.css" %} {% insert_str prelude "css/manifold.css" %} {% insert_str prelude "css/plugin.css" %} {% insert_str prelude "css/onelab_marko.css" %} diff --git a/ui/templates/layout-unfold1.html b/ui/templates/layout-unfold1.html index fa796b93..7d3ee2e6 100644 --- a/ui/templates/layout-unfold1.html +++ b/ui/templates/layout-unfold1.html @@ -2,8 +2,8 @@ {% block base_content %}
- {% block unfold1_main %} - "The main content area (define block 'unfold1_main')" - {% endblock unfold1_main %} + {% block unfold_main %} + "The main content area (define block 'unfold_main')" + {% endblock unfold_main %}
{% endblock %} diff --git a/ui/templates/layout-unfold2.html b/ui/templates/layout-unfold2.html index 345f57f2..7022aa59 100644 --- a/ui/templates/layout-unfold2.html +++ b/ui/templates/layout-unfold2.html @@ -2,13 +2,13 @@ {% block base_content %}
- {% block unfold2_main %} - "The main content area (define block 'unfold2_main')" - {% endblock unfold2_main %} + {% block unfold_main %} + "The main content area (define block 'unfold_main')" + {% endblock unfold_main %}
- {% block unfold2_margin %} - "The related content area (define block 'unfold2_margin')" - {% endblock unfold2_margin %} + {% block unfold_margin %} + "The related content area (define block 'unfold_margin')" + {% endblock unfold_margin %}
{% endblock %} diff --git a/ui/templates/view-unfold1.html b/ui/templates/view-unfold1.html index 75a10096..8fc17f1f 100644 --- a/ui/templates/view-unfold1.html +++ b/ui/templates/view-unfold1.html @@ -1,5 +1,5 @@ {% extends 'layout-unfold1.html' %} -{% block unfold1_main %} -{{ unfold1_main|safe }} -{% endblock unfold1_main %} +{% block unfold_main %} +{{ unfold_main|safe }} +{% endblock unfold_main %} diff --git a/ui/topmenu.py b/ui/topmenu.py index 3a94a212..1fc3b4b2 100644 --- a/ui/topmenu.py +++ b/ui/topmenu.py @@ -17,6 +17,7 @@ def topmenu_items (current,request=None): result.append({'label':'Request a slice', 'href': '/portal/slice_request/'}) result.append({'label':'Validation', 'href': '/portal/validate/'}) dropdown = [] + dropdown.append({'label':'Platforms', 'href': '/portal/platforms/'}) dropdown.append({'label':'My Account', 'href': '/portal/account/'}) dropdown.append({'label':'Contact Support', 'href': '/portal/contact/'}) result.append({'label': 'More', 'href':"#", 'dropdown':True, 'contents':dropdown}) diff --git a/unfold/page.py b/unfold/page.py index 7c6d60bd..7f071c0b 100644 --- a/unfold/page.py +++ b/unfold/page.py @@ -33,10 +33,7 @@ class Page: # queue of queries with maybe a domid, see enqueue_query self._queue=[] # global prelude object - self.prelude=Prelude(css_files='css/plugin.css') - print "Loading... CSS OneLab" - self.prelude=Prelude(css_files='css/onelab_marko.css') -# self.prelude=Prelude(css_files=['css/plugin.css','css/onelab_marko.css',]) + self.prelude=Prelude(css_files=['css/plugin.css','css/onelab_marko.css',]) # record known plugins hashed on their domid def record_plugin (self, plugin): @@ -83,7 +80,7 @@ class Page: result={'query_uuid':a} if b: result['domid']=b return result - env['query_publish_dom_tuples'] = [ query_publish_dom_tuple (a,b) for (a,b) in self._queue ] + env['query_exec_tuples'] = [ query_publish_dom_tuple (a,b) for (a,b) in self._queue ] javascript = render_to_string ("page-queries.js",env) self.add_js_chunks (javascript) # self.reset_queue() @@ -91,29 +88,6 @@ class Page: self.expose_js_manifold_config() -# DEPRECATED # # needs to be called explicitly and only when metadata is actually required -# DEPRECATED # # in particular user needs to be logged -# DEPRECATED # def get_metadata (self): -# DEPRECATED # # look in session's cache - we don't want to retrieve this for every request -# DEPRECATED # session=self.request.session -# DEPRECATED # if 'manifold' not in session: -# DEPRECATED # print "Page.expose_js_metadata: no 'manifold' in session... - cannot retrieve metadata - skipping" -# DEPRECATED # return -# DEPRECATED # manifold=session['manifold'] -# DEPRECATED # # if cached, use it -# DEPRECATED # if 'metadata' in manifold and isinstance(manifold['metadata'],MetaData): -# DEPRECATED # if debug: print "Page.get_metadata: return cached value" -# DEPRECATED # return manifold['metadata'] -# DEPRECATED # # otherwise retrieve it -# DEPRECATED # manifold_api_session_auth = session['manifold']['auth'] -# DEPRECATED # print "get_metadata(), manifold_api_session_auth =", session['manifold']['auth'] -# DEPRECATED # metadata=MetaData (manifold_api_session_auth) -# DEPRECATED # metadata.fetch() -# DEPRECATED # # store it for next time -# DEPRECATED # manifold['metadata']=metadata -# DEPRECATED # if debug: print "Page.get_metadata: return new value" -# DEPRECATED # return metadata - # needs to be called explicitly and only when metadata is actually required # in particular user needs to be logged def get_metadata (self): @@ -139,12 +113,13 @@ class Page: return metadata def expose_js_metadata (self): - # export in this js global... - self.add_js_chunks("var MANIFOLD_METADATA =" + self.get_metadata().to_json() + ";") + # expose global MANIFOLD_METADATA as a js variable + # xxx this is fetched synchroneously.. + self.add_js_init_chunks("var MANIFOLD_METADATA =" + self.get_metadata().to_json() + ";") def expose_js_manifold_config (self): config=Config() - self.add_js_chunks(config.manifold_js_export()) + self.add_js_init_chunks(config.manifold_js_export()) #################### requirements/prelude management # just forward to self.prelude - see decorator above @@ -153,6 +128,8 @@ class Page: @to_prelude def add_css_files (self):pass @to_prelude + def add_js_init_chunks (self):pass + @to_prelude def add_js_chunks (self):pass @to_prelude def add_css_chunks (self):pass diff --git a/unfold/plugin.py b/unfold/plugin.py index 61af0e07..229f196c 100644 --- a/unfold/plugin.py +++ b/unfold/plugin.py @@ -163,10 +163,6 @@ class Plugin: def export_json_settings (self): return 'query_uuid' in self.json_settings_list() - # by default we create a timer if there's a query attached, redefine to change this behaviour - def start_with_spin (self): - return self.export_json_settings() - # returns the html code for that plugin # in essence, wraps the results of self.render_content () def render (self, request): @@ -175,8 +171,6 @@ class Plugin: # shove this into plugin.html env = {} env ['plugin_content']= plugin_content - # need_spin is used in plugin.html - self.need_spin=self.start_with_spin() env.update(self.__dict__) # translate high-level 'toggled' into 4 different booleans self.need_toggle = False @@ -201,7 +195,8 @@ class Plugin: env ['settings_json' ] = self.settings_json() # compute plugin-specific initialization js_init = render_to_string ( 'plugin-init.js', env ) - self.add_js_chunks (js_init) + # make sure this happens first in js + self.add_js_init_chunks (js_init) # interpret the result of requirements () self.handle_requirements (request) @@ -258,6 +253,8 @@ class Plugin: @to_prelude def add_css_files (self):pass @to_prelude + def add_js_init_chunks (self):pass + @to_prelude def add_js_chunks (self):pass @to_prelude def add_css_chunks (self):pass @@ -312,6 +309,3 @@ class Plugin: # # whether we export the json settings to js # def export_json_settings (self) - # - # whether we show an initial spinner - # def start_with_spin (self) diff --git a/unfold/prelude.py b/unfold/prelude.py index 8c90a19b..03e6def7 100644 --- a/unfold/prelude.py +++ b/unfold/prelude.py @@ -2,17 +2,29 @@ from types import StringTypes, ListType from django.template.loader import render_to_string -debug=True +debug=False +# the need for js_init_chunks is because we need to have the plugins initialized +# before the queries fly +# and when writing a view it is not very easy to remember in which order +# all the js initialization will end up, so we use these 2 categories +# as a simple way to enforce this dependency +# far from perfect but good enough for now class Prelude: - """A class for collecting dependencies on js/css files or fragments""" + """A class for collecting dependencies on js/css stuff + files are expected from your 'static' area, typically 'css/foo.css' or 'js/foo.js' + fragments (chunks) is for raw code + you can specify a string or a list of strings + js_init_chunks get collated with js_chunks but come first + """ - keys=[ 'js_files','css_files','js_chunks', 'css_chunks' ] - def __init__ (self, js_files=None, css_files=None, js_chunks=None, css_chunks=None): + keys=[ 'js_files', 'css_files', 'js_init_chunks', 'js_chunks', 'css_chunks' ] + def __init__ (self, js_files=None, css_files=None, js_init_chunks=None, js_chunks=None, css_chunks=None): # it's tempting to use sets but sets are not ordered.. self.js_files = Prelude._normalize(js_files) self.css_files = Prelude._normalize(css_files) + self.js_init_chunks = Prelude._normalize(js_init_chunks) self.js_chunks = Prelude._normalize(js_chunks) self.css_chunks= Prelude._normalize(css_chunks) @@ -29,6 +41,8 @@ class Prelude: def add_css_files (self, x): for i in Prelude._normalize (x): if i not in self.css_files: self.css_files.append(i) + def add_js_init_chunks (self, x): + self.js_init_chunks += Prelude._normalize (x) def add_js_chunks (self, x): self.js_chunks += Prelude._normalize (x) def add_css_chunks (self, x): @@ -36,7 +50,7 @@ class Prelude: def inspect_string (self,msg): result = 'Prelude.inspect %s (%s) with '%(msg,self) - result += ",".join( [ "%s->%s"%(k,len(getattr(self,k))) for k in ['js_files','js_chunks','css_files','css_chunks'] ] ) + result += ",".join( [ "%s->%s"%(k,len(getattr(self,k))) for k in Prelude.keys ] ) return result def inspect (self,msg): print self.inspect_string(msg) @@ -69,11 +83,11 @@ class Prelude: env={} env['js_urls'] = [ Prelude.full_url (js_file) for js_file in self.js_files ] env['css_urls'] = [ Prelude.full_url (css_file) for css_file in self.css_files ] - env['js_chunks']= self.js_chunks + env['all_js_chunks']= self.js_init_chunks + self.js_chunks env['css_chunks']=self.css_chunks if debug: - print "prelude has %d js_files, %d css files, %d js chunks and %d css_chunks"%\ - (len(self.js_files),len(self.css_files),len(self.js_chunks),len(self.css_chunks),) + print "prelude has %d js_files, %d css files, (%d+%d) js chunks and %d css_chunks"%\ + (len(self.js_files),len(self.css_files),len(self.js_init_chunks),len(self.js_chunks),len(self.css_chunks),) # render this with prelude.html and put the result in header_prelude header_prelude = render_to_string ('prelude.html',env) return { 'header_prelude' : header_prelude } diff --git a/unfold/templates/page-queries.js b/unfold/templates/page-queries.js index a6ab97f4..a7c3e223 100644 --- a/unfold/templates/page-queries.js +++ b/unfold/templates/page-queries.js @@ -1,9 +1,8 @@ {% for json in queries_json %}manifold.insert_query({{ json|safe }}); {% endfor %} $(document).ready(function () { -var query_publish_dom_tuples = new Array(); -{% for d in query_publish_dom_tuples %}try {query_publish_dom_tuples.push({'query_uuid':"{{ d.query_uuid }}"{%if d.domid %},'domid':"{{ d.domid }}"{% endif %}}) } -catch(err){messages.debug ("Could not expose query {{ d.query_uuid }}")} +var query_exec_tuples = []; +{% for tuple in query_exec_tuples %} query_exec_tuples.push({'query_uuid':"{{ tuple.query_uuid }}"}); {% endfor %} -manifold.asynchroneous_exec(query_publish_dom_tuples); +manifold.asynchroneous_exec(query_exec_tuples); }) diff --git a/unfold/templates/plugin.html b/unfold/templates/plugin.html index 354b5608..0c022f68 100644 --- a/unfold/templates/plugin.html +++ b/unfold/templates/plugin.html @@ -1,5 +1,5 @@ {% if visible %} -
+
{% if togglable %}