diff --git a/vpython/vpython.py b/vpython/vpython.py index c0288ae..daded23 100644 --- a/vpython/vpython.py +++ b/vpython/vpython.py @@ -15,8 +15,8 @@ from ._vector_import_helper import (vector, mag, norm, dot, adjust_up, adjust_axis, object_rotate) -# List of names that will be imported form this file with import * -__all__ = ['Camera', 'GlowWidget', 'GSversion', 'Mouse', 'arrow', 'attach_arrow', +# List of names that will be imported from this file with import * +__all__ = ['Camera', 'GlowWidget', 'version', 'GSversion', 'Mouse', 'arrow', 'attach_arrow', 'attach_trail', 'baseObj', 'box', 'bumpmaps', 'button', 'canvas', 'checkbox', 'clock', 'color', 'combin', 'compound', 'cone', 'controls', 'curve', 'curveMethods', 'cylinder', 'distant_light', 'ellipsoid', @@ -25,7 +25,7 @@ 'local_light', 'menu', 'meta_canvas', 'points', 'pyramid', 'quad', 'radio', 'ring', 'simple_sphere', 'sleep', 'slider', 'sphere', 'standardAttributes', 'text', 'textures', 'triangle', 'vertex', - 'wtext'] + 'wtext', 'winput'] __p = platform.python_version() _ispython3 = (__p[0] == '3') @@ -360,6 +360,9 @@ def handle_msg(self, msg): obj._checked = evt['value'] elif evt['widget'] == 'radio': obj._checked = evt['value'] + elif evt['widget'] == 'winput': + obj._text = evt['text'] + obj._number = evt['value'] # inspect the bound function and see what it's expecting if _ispython3: # Python 3 a = signature(obj._bind) @@ -3296,7 +3299,8 @@ class controls(baseObj): 'radio':['checked', 'text', 'disabled'], 'menu':['selected', 'choices', 'index', 'disabled'], 'slider':['vertical', 'min', 'max', 'step', 'value', 'length', - 'width', 'left', 'right', 'top', 'bottom', 'align', 'disabled'] + 'width', 'left', 'right', 'top', 'bottom', 'align', 'disabled'], + 'winput':['width', 'height', 'text', 'type', 'disabled'] } def setup(self, args): super(controls, self).__init__() ## get idx, attrsupdt from baseObj @@ -3479,6 +3483,47 @@ def checked(self, value): if not self._constructing: self.addattr('checked') +class winput(controls): + def __init__(self, **args): + args['_objName'] = 'winput' + self._checked = False + self._text = '' + self._type = 'numeric' + self._number = None + self._width = 100 + self._height = 20 + super(winput, self).setup(args) + + @property + def text(self): + return self._text + @text.setter + def text(self, value): + self._text = value + if not self._constructing: + self.addattr('text') + + @property + def number(self): + return self._number + @number.setter + def number(self, value): + raise AttributeError('Cannot change the winput number attribute.') + + @property + def width(self): + return self._width + @width.setter + def width(self, value): + raise AttributeError('Cannot change the winput width attribute.') + + @property + def type(self): + return self._type + @type.setter + def type(self, value): + raise AttributeError('Cannot change the winput type attribute.') + class menu(controls): def __init__(self, **args): args['_objName'] = 'menu' diff --git a/vpython/vpython_libraries/glow.min.js b/vpython/vpython_libraries/glow.min.js index b0bf91c..7f9dfda 100644 --- a/vpython/vpython_libraries/glow.min.js +++ b/vpython/vpython_libraries/glow.min.js @@ -1,3 +1,3 @@ -(function(){})();(function(factory){if(typeof define==="function"&&define.amd){define(["jquery"],factory)}else if(typeof exports==="object"){module.exports=factory}else{factory(jQuery)}})(function($){var toFix=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],toBind="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],slice=Array.prototype.slice,nullLowestDeltaTimeout,lowestDelta;if($.event.fixHooks){for(var i=toFix.length;i;){$.event.fixHooks[toFix[--i]]=$.event.mouseHooks}}var special=$.event.special.mousewheel={version:"3.1.11",setup:function(){if(this.addEventListener){for(var i=toBind.length;i;){this.addEventListener(toBind[--i],handler,false)}}else{this.onmousewheel=handler}$.data(this,"mousewheel-line-height",special.getLineHeight(this));$.data(this,"mousewheel-page-height",special.getPageHeight(this))},teardown:function(){if(this.removeEventListener){for(var i=toBind.length;i;){this.removeEventListener(toBind[--i],handler,false)}}else{this.onmousewheel=null}$.removeData(this,"mousewheel-line-height");$.removeData(this,"mousewheel-page-height")},getLineHeight:function(elem){var $parent=$(elem)["offsetParent"in $.fn?"offsetParent":"parent"]();if(!$parent.length){$parent=$("body")}return parseInt($parent.css("fontSize"),10)},getPageHeight:function(elem){return $(elem).height()},settings:{adjustOldDeltas:true,normalizeOffset:true}};$.fn.extend({mousewheel:function(fn){return fn?this.bind("mousewheel",fn):this.trigger("mousewheel")},unmousewheel:function(fn){return this.unbind("mousewheel",fn)}});function handler(event){var orgEvent=event||window.event,args=slice.call(arguments,1),delta=0,deltaX=0,deltaY=0,absDelta=0,offsetX=0,offsetY=0;event=$.event.fix(orgEvent);event.type="mousewheel";if("detail"in orgEvent){deltaY=orgEvent.detail*-1}if("wheelDelta"in orgEvent){deltaY=orgEvent.wheelDelta}if("wheelDeltaY"in orgEvent){deltaY=orgEvent.wheelDeltaY}if("wheelDeltaX"in orgEvent){deltaX=orgEvent.wheelDeltaX*-1}if("axis"in orgEvent&&orgEvent.axis===orgEvent.HORIZONTAL_AXIS){deltaX=deltaY*-1;deltaY=0}delta=deltaY===0?deltaX:deltaY;if("deltaY"in orgEvent){deltaY=orgEvent.deltaY*-1;delta=deltaY}if("deltaX"in orgEvent){deltaX=orgEvent.deltaX;if(deltaY===0){delta=deltaX*-1}}if(deltaY===0&&deltaX===0){return}if(orgEvent.deltaMode===1){var lineHeight=$.data(this,"mousewheel-line-height");delta*=lineHeight;deltaY*=lineHeight;deltaX*=lineHeight}else if(orgEvent.deltaMode===2){var pageHeight=$.data(this,"mousewheel-page-height");delta*=pageHeight;deltaY*=pageHeight;deltaX*=pageHeight}absDelta=Math.max(Math.abs(deltaY),Math.abs(deltaX));if(!lowestDelta||absDelta=1?"floor":"ceil"](delta/lowestDelta);deltaX=Math[deltaX>=1?"floor":"ceil"](deltaX/lowestDelta);deltaY=Math[deltaY>=1?"floor":"ceil"](deltaY/lowestDelta);if(special.settings.normalizeOffset&&this.getBoundingClientRect){var boundingRect=this.getBoundingClientRect();offsetX=event.clientX-boundingRect.left;offsetY=event.clientY-boundingRect.top}event.deltaX=deltaX;event.deltaY=deltaY;event.deltaFactor=lowestDelta;event.offsetX=offsetX;event.offsetY=offsetY;event.deltaMode=0;args.unshift(event,delta,deltaX,deltaY);if(nullLowestDeltaTimeout){clearTimeout(nullLowestDeltaTimeout)}nullLowestDeltaTimeout=setTimeout(nullLowestDelta,200);return($.event.dispatch||$.event.handle).apply(this,args)}function nullLowestDelta(){lowestDelta=null}function shouldAdjustOldDeltas(orgEvent,absDelta){return special.settings.adjustOldDeltas&&orgEvent.type==="mousewheel"&&absDelta%120===0}});(function(B){B.color={};B.color.make=function(F,E,C,D){var G={};G.r=F||0;G.g=E||0;G.b=C||0;G.a=D!=null?D:1;G.add=function(J,I){for(var H=0;H=1){return"rgb("+[G.r,G.g,G.b].join(",")+")"}else{return"rgba("+[G.r,G.g,G.b,G.a].join(",")+")"}};G.normalize=function(){function H(J,K,I){return KI?I:K}G.r=H(0,parseInt(G.r),255);G.g=H(0,parseInt(G.g),255);G.b=H(0,parseInt(G.b),255);G.a=H(0,G.a,1);return G};G.clone=function(){return B.color.make(G.r,G.b,G.g,G.a)};return G.normalize()};B.color.extract=function(D,C){var E;do{E=D.css(C).toLowerCase();if(E!=""&&E!="transparent"){break}D=D.parent()}while(!B.nodeName(D.get(0),"body"));if(E=="rgba(0, 0, 0, 0)"){E="transparent"}return B.color.parse(E)};B.color.parse=function(F){var E,C=B.color.make;if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10))}if(E=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10),parseFloat(E[4]))}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55)}if(E=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55,parseFloat(E[4]))}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return C(parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16))}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return C(parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16))}var D=B.trim(F).toLowerCase();if(D=="transparent"){return C(255,255,255,0)}else{E=A[D]||[0,0,0];return C(E[0],E[1],E[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);(function($){function Plot(placeholder,data_,options_,plugins){var series=[],options={colors:["#edc240","#afd8f8","#cb4b4b","#4da74d","#9440ed"],legend:{show:true,noColumns:1,labelFormatter:null,labelBoxBorderColor:"#ccc",container:null,position:"ne",margin:5,backgroundColor:null,backgroundOpacity:.85},xaxis:{show:null,position:"bottom",mode:null,color:null,tickColor:null,transform:null,inverseTransform:null,min:null,max:null,autoscaleMargin:null,ticks:null,tickFormatter:null,labelWidth:null,labelHeight:null,reserveSpace:null,tickLength:null,alignTicksWithAxis:null,tickDecimals:null,tickSize:null,minTickSize:null,monthNames:null,timeformat:null,twelveHourClock:false},yaxis:{autoscaleMargin:.02,position:"left"},xaxes:[],yaxes:[],series:{points:{show:false,radius:3,lineWidth:2,fill:true,fillColor:"#ffffff",symbol:"circle"},lines:{lineWidth:2,fill:false,fillColor:null,steps:false},bars:{show:false,lineWidth:2,barWidth:1,fill:true,fillColor:null,align:"left",horizontal:false},shadowSize:3},grid:{show:true,aboveData:false,color:"#545454",backgroundColor:null,borderColor:null,tickColor:null,labelMargin:5,axisMargin:8,borderWidth:2,minBorderMargin:null,markings:null,markingsColor:"#f4f4f4",markingsLineWidth:2,clickable:false,hoverable:false,autoHighlight:true,mouseActiveRadius:10},hooks:{}},canvas=null,overlay=null,eventHolder=null,ctx=null,octx=null,xaxes=[],yaxes=[],plotOffset={left:0,right:0,top:0,bottom:0},canvasWidth=0,canvasHeight=0,plotWidth=0,plotHeight=0,hooks={processOptions:[],processRawData:[],processDatapoints:[],drawSeries:[],draw:[],bindEvents:[],drawOverlay:[],shutdown:[]},plot=this;plot.setData=setData;plot.setupGrid=setupGrid;plot.draw=draw;plot.getPlaceholder=function(){return placeholder};plot.getCanvas=function(){return canvas};plot.getPlotOffset=function(){return plotOffset};plot.width=function(){return plotWidth};plot.height=function(){return plotHeight};plot.offset=function(){var o=eventHolder.offset();o.left+=plotOffset.left;o.top+=plotOffset.top;return o};plot.getData=function(){return series};plot.getAxes=function(){var res={},i;$.each(xaxes.concat(yaxes),function(_,axis){if(axis)res[axis.direction+(axis.n!=1?axis.n:"")+"axis"]=axis});return res};plot.getXAxes=function(){return xaxes};plot.getYAxes=function(){return yaxes};plot.c2p=canvasToAxisCoords;plot.p2c=axisToCanvasCoords;plot.getOptions=function(){return options};plot.highlight=highlight;plot.unhighlight=unhighlight;plot.triggerRedrawOverlay=triggerRedrawOverlay;plot.pointOffset=function(point){return{left:parseInt(xaxes[axisNumber(point,"x")-1].p2c(+point.x)+plotOffset.left),top:parseInt(yaxes[axisNumber(point,"y")-1].p2c(+point.y)+plotOffset.top)}};plot.shutdown=shutdown;plot.resize=function(){getCanvasDimensions();resizeCanvas(canvas);resizeCanvas(overlay)};plot.hooks=hooks;initPlugins(plot);parseOptions(options_);setupCanvases();setData(data_);setupGrid();draw();bindEvents();function executeHooks(hook,args){args=[plot].concat(args);for(var i=0;i=options.colors.length){i=0;++variation}}var colori=0,s;for(i=0;iaxis.datamax&&max!=fakeInfinity)axis.datamax=max}$.each(allAxes(),function(_,axis){axis.datamin=topSentry;axis.datamax=bottomSentry;axis.used=false});for(i=0;i0&&points[k-ps]!=null&&points[k-ps]!=points[k]&&points[k-ps+1]!=points[k+1]){for(m=0;mxmax)xmax=val}if(f.y){if(valymax)ymax=val}}}if(s.bars.show){var delta=s.bars.align=="left"?0:-s.bars.barWidth/2;if(s.bars.horizontal){ymin+=delta;ymax+=delta+s.bars.barWidth}else{xmin+=delta;xmax+=delta+s.bars.barWidth}}updateAxis(s.xaxis,xmin,xmax);updateAxis(s.yaxis,ymin,ymax)}$.each(allAxes(),function(_,axis){if(axis.datamin==topSentry)axis.datamin=null;if(axis.datamax==bottomSentry)axis.datamax=null})}function makeCanvas(skipPositioning,cls){var c=document.createElement("canvas");c.className=cls;c.width=canvasWidth;c.height=canvasHeight;if(!skipPositioning)$(c).css({position:"absolute",left:0,top:0});$(c).appendTo(placeholder);if(!c.getContext)c=window.G_vmlCanvasManager.initElement(c);c.getContext("2d").save();return c}function getCanvasDimensions(){canvasWidth=placeholder.width();canvasHeight=placeholder.height();if(canvasWidth<=0||canvasHeight<=0)throw"Invalid dimensions for plot, width = "+canvasWidth+", height = "+canvasHeight}function resizeCanvas(c){if(c.width!=canvasWidth)c.width=canvasWidth;if(c.height!=canvasHeight)c.height=canvasHeight;var cctx=c.getContext("2d");cctx.restore();cctx.save()}function setupCanvases(){var reused,existingCanvas=placeholder.children("canvas.base"),existingOverlay=placeholder.children("canvas.overlay");if(existingCanvas.length==0||existingOverlay==0){placeholder.html("");placeholder.css({padding:0});if(placeholder.css("position")=="static")placeholder.css("position","relative");getCanvasDimensions();canvas=makeCanvas(true,"base");overlay=makeCanvas(false,"overlay");reused=false}else{canvas=existingCanvas.get(0);overlay=existingOverlay.get(0);reused=true}ctx=canvas.getContext("2d");octx=overlay.getContext("2d");eventHolder=$([overlay,canvas]);if(reused){placeholder.data("plot").shutdown();plot.resize();octx.clearRect(0,0,canvasWidth,canvasHeight);eventHolder.unbind();placeholder.children().not([canvas,overlay]).remove()}placeholder.data("plot",plot)}function bindEvents(){if(options.grid.hoverable){eventHolder.mousemove(onMouseMove);eventHolder.mouseleave(onMouseLeave)}if(options.grid.clickable)eventHolder.click(onClick);executeHooks(hooks.bindEvents,[eventHolder])}function shutdown(){if(redrawTimeout)clearTimeout(redrawTimeout);eventHolder.unbind("mousemove",onMouseMove);eventHolder.unbind("mouseleave",onMouseLeave);eventHolder.unbind("click",onClick);executeHooks(hooks.shutdown,[eventHolder])}function setTransformationHelpers(axis){function identity(x){return x}var s,m,t=axis.options.transform||identity,it=axis.options.inverseTransform;if(axis.direction=="x"){s=axis.scale=plotWidth/Math.abs(t(axis.max)-t(axis.min));m=Math.min(t(axis.max),t(axis.min))}else{s=axis.scale=plotHeight/Math.abs(t(axis.max)-t(axis.min));s=-s;m=Math.max(t(axis.max),t(axis.min))}if(t==identity)axis.p2c=function(p){return(p-m)*s};else axis.p2c=function(p){return(t(p)-m)*s};if(!it)axis.c2p=function(c){return m+c/s};else axis.c2p=function(c){return it(m+c/s)}}function measureTickLabels(axis){var opts=axis.options,i,ticks=axis.ticks||[],labels=[],l,w=opts.labelWidth,h=opts.labelHeight,dummyDiv;function makeDummyDiv(labels,width){return $('
'+'
'+labels.join("")+"
").appendTo(placeholder)}if(axis.direction=="x"){if(w==null)w=Math.floor(canvasWidth/(ticks.length>0?ticks.length:1));if(h==null){labels=[];for(i=0;i'+l+"")}if(labels.length>0){labels.push('
');dummyDiv=makeDummyDiv(labels,"width:10000px;");h=dummyDiv.height();dummyDiv.remove()}}}else if(w==null||h==null){for(i=0;i'+l+"")}if(labels.length>0){dummyDiv=makeDummyDiv(labels,"");if(w==null)w=dummyDiv.children().width();if(h==null)h=dummyDiv.find("div.tickLabel").height();dummyDiv.remove()}}if(w==null)w=0;if(h==null)h=0;axis.labelWidth=w;axis.labelHeight=h}function allocateAxisBoxFirstPhase(axis){var lw=axis.labelWidth,lh=axis.labelHeight,pos=axis.options.position,tickLength=axis.options.tickLength,axismargin=options.grid.axisMargin,padding=options.grid.labelMargin,all=axis.direction=="x"?xaxes:yaxes,index;var samePosition=$.grep(all,function(a){return a&&a.options.position==pos&&a.reserveSpace});if($.inArray(axis,samePosition)==samePosition.length-1)axismargin=0;if(tickLength==null)tickLength="full";var sameDirection=$.grep(all,function(a){return a&&a.reserveSpace});var innermost=$.inArray(axis,sameDirection)==0;if(!innermost&&tickLength=="full")tickLength=5;if(!isNaN(+tickLength))padding+=+tickLength;if(axis.direction=="x"){lh+=padding;if(pos=="bottom"){plotOffset.bottom+=lh+axismargin;axis.box={top:canvasHeight-plotOffset.bottom,height:lh}}else{axis.box={top:plotOffset.top+axismargin,height:lh};plotOffset.top+=lh+axismargin}}else{lw+=padding;if(pos=="left"){axis.box={left:plotOffset.left+axismargin,width:lw};plotOffset.left+=lw+axismargin}else{plotOffset.right+=lw+axismargin;axis.box={left:canvasWidth-plotOffset.right,width:lw}}}axis.position=pos;axis.tickLength=tickLength;axis.box.padding=padding;axis.innermost=innermost}function allocateAxisBoxSecondPhase(axis){if(axis.direction=="x"){axis.box.left=plotOffset.left;axis.box.width=plotWidth}else{axis.box.top=plotOffset.top;axis.box.height=plotHeight}}function setupGrid(){var i,axes=allAxes();$.each(axes,function(_,axis){axis.show=axis.options.show;if(axis.show==null)axis.show=axis.used;axis.reserveSpace=axis.show||axis.options.reserveSpace;setRange(axis)});allocatedAxes=$.grep(axes,function(axis){return axis.reserveSpace});plotOffset.left=plotOffset.right=plotOffset.top=plotOffset.bottom=0;if(options.grid.offsets!==undefined){var o=options.grid.offsets;plotOffset.left=o.left;plotOffset.right=o.right;plotOffset.top=o.top;plotOffset.bottom=o.bottom}if(options.grid.show){$.each(allocatedAxes,function(_,axis){setupTickGeneration(axis);setTicks(axis);snapRangeToTicks(axis,axis.ticks);measureTickLabels(axis)});for(i=allocatedAxes.length-1;i>=0;--i)allocateAxisBoxFirstPhase(allocatedAxes[i]);var minMargin=options.grid.minBorderMargin;if(minMargin==null){minMargin=0;for(i=0;i=0)min=0}if(opts.max==null){max+=delta*margin;if(max>0&&axis.datamax!=null&&axis.datamax<=0)max=0}}}axis.min=min;axis.max=max}function setupTickGeneration(axis){var opts=axis.options;var noTicks;if(typeof opts.ticks=="number"&&opts.ticks>0)noTicks=opts.ticks;else noTicks=.3*Math.sqrt(axis.direction=="x"?canvasWidth:canvasHeight);var delta=(axis.max-axis.min)/noTicks,size,generator,unit,formatter,i,magn,norm;if(opts.mode=="time"){var timeUnitSize={second:1e3,minute:60*1e3,hour:60*60*1e3,day:24*60*60*1e3,month:30*24*60*60*1e3,year:365.2425*24*60*60*1e3};var spec=[[1,"second"],[2,"second"],[5,"second"],[10,"second"],[30,"second"],[1,"minute"],[2,"minute"],[5,"minute"],[10,"minute"],[30,"minute"],[1,"hour"],[2,"hour"],[4,"hour"],[8,"hour"],[12,"hour"],[1,"day"],[2,"day"],[3,"day"],[.25,"month"],[.5,"month"],[1,"month"],[2,"month"],[3,"month"],[6,"month"],[1,"year"]];var minSize=0;if(opts.minTickSize!=null){if(typeof opts.tickSize=="number")minSize=opts.tickSize;else minSize=opts.minTickSize[0]*timeUnitSize[opts.minTickSize[1]]}for(var i=0;i=minSize)break;size=spec[i][0];unit=spec[i][1];if(unit=="year"){magn=Math.pow(10,Math.floor(Math.log(delta/timeUnitSize.year)/Math.LN10));norm=delta/timeUnitSize.year/magn;if(norm<1.5)size=1;else if(norm<3)size=2;else if(norm<7.5)size=5;else size=10;size*=magn}axis.tickSize=opts.tickSize||[size,unit];generator=function(axis){var ticks=[],tickSize=axis.tickSize[0],unit=axis.tickSize[1],d=new Date(axis.min);var step=tickSize*timeUnitSize[unit];if(unit=="second")d.setUTCSeconds(floorInBase(d.getUTCSeconds(),tickSize));if(unit=="minute")d.setUTCMinutes(floorInBase(d.getUTCMinutes(),tickSize));if(unit=="hour")d.setUTCHours(floorInBase(d.getUTCHours(),tickSize));if(unit=="month")d.setUTCMonth(floorInBase(d.getUTCMonth(),tickSize));if(unit=="year")d.setUTCFullYear(floorInBase(d.getUTCFullYear(),tickSize));d.setUTCMilliseconds(0);if(step>=timeUnitSize.minute)d.setUTCSeconds(0);if(step>=timeUnitSize.hour)d.setUTCMinutes(0);if(step>=timeUnitSize.day)d.setUTCHours(0);if(step>=timeUnitSize.day*4)d.setUTCDate(1);if(step>=timeUnitSize.year)d.setUTCMonth(0);var carry=0,v=Number.NaN,prev;do{prev=v;v=d.getTime();ticks.push(v);if(unit=="month"){if(tickSize<1){d.setUTCDate(1);var start=d.getTime();d.setUTCMonth(d.getUTCMonth()+1);var end=d.getTime();d.setTime(v+carry*timeUnitSize.hour+(end-start)*tickSize);carry=d.getUTCHours();d.setUTCHours(0)}else d.setUTCMonth(d.getUTCMonth()+tickSize)}else if(unit=="year"){d.setUTCFullYear(d.getUTCFullYear()+tickSize)}else d.setTime(v+step)}while(vmaxDec)dec=maxDec;magn=Math.pow(10,-dec);norm=delta/magn;if(norm<1.5)size=1;else if(norm<3){size=2;if(norm>2.25&&(maxDec==null||dec+1<=maxDec)){size=2.5;++dec}}else if(norm<7.5)size=5;else size=10;size*=magn;if(opts.minTickSize!=null&&size0){if(opts.min==null)axis.min=Math.min(axis.min,niceTicks[0]);if(opts.max==null&&niceTicks.length>1)axis.max=Math.max(axis.max,niceTicks[niceTicks.length-1])}generator=function(axis){var ticks=[],v,i;for(i=0;i1&&/\..*0$/.test((ts[1]-ts[0]).toFixed(extraDec))))axis.tickDecimals=extraDec}}}axis.tickGenerator=generator;if($.isFunction(opts.tickFormatter))axis.tickFormatter=function(v,axis){return""+opts.tickFormatter(v,axis)};else axis.tickFormatter=formatter}function setTicks(axis){var oticks=axis.options.ticks,ticks=[];if(oticks==null||typeof oticks=="number"&&oticks>0)ticks=axis.tickGenerator(axis);else if(oticks){if($.isFunction(oticks))ticks=oticks({min:axis.min,max:axis.max});else ticks=oticks}var i,v;axis.ticks=[];for(i=0;i1)label=t[1]}else v=+t;if(label==null)label=axis.tickFormatter(v,axis);if(!isNaN(v))axis.ticks.push({v:v,label:label})}}function snapRangeToTicks(axis,ticks){if(axis.options.autoscaleMargin&&ticks.length>0){if(axis.options.min==null)axis.min=Math.min(axis.min,ticks[0].v);if(axis.options.max==null&&ticks.length>1)axis.max=Math.max(axis.max,ticks[ticks.length-1].v)}}function draw(){var o=options.grid.offsets;ctx.clearRect(o.left,o.top,canvasWidth-o.left,canvasHeight-o.bottom-o.top);var grid=options.grid;if(grid.show&&grid.backgroundColor)drawBackground();if(grid.show&&!grid.aboveData)drawGrid();for(var i=0;ito){var tmp=from;from=to;to=tmp}return{from:from,to:to,axis:axis}}function drawBackground(){ctx.save();ctx.translate(plotOffset.left,plotOffset.top);ctx.fillStyle=getColorOrGradient(options.grid.backgroundColor,plotHeight,0,"rgba(255, 255, 255, 0)");ctx.fillRect(0,0,plotWidth,plotHeight);ctx.restore()}function drawGrid(){var i;ctx.save();ctx.translate(plotOffset.left,plotOffset.top);var markings=options.grid.markings;if(markings){if($.isFunction(markings)){var axes=plot.getAxes();axes.xmin=axes.xaxis.min;axes.xmax=axes.xaxis.max;axes.ymin=axes.yaxis.min;axes.ymax=axes.yaxis.max;markings=markings(axes)}for(i=0;ixrange.axis.max||yrange.toyrange.axis.max)continue;xrange.from=Math.max(xrange.from,xrange.axis.min);xrange.to=Math.min(xrange.to,xrange.axis.max);yrange.from=Math.max(yrange.from,yrange.axis.min);yrange.to=Math.min(yrange.to,yrange.axis.max);if(xrange.from==xrange.to&&yrange.from==yrange.to)continue;xrange.from=xrange.axis.p2c(xrange.from);xrange.to=xrange.axis.p2c(xrange.to);yrange.from=yrange.axis.p2c(yrange.from);yrange.to=yrange.axis.p2c(yrange.to);if(xrange.from==xrange.to||yrange.from==yrange.to){ctx.beginPath();ctx.strokeStyle=m.color||options.grid.markingsColor;ctx.lineWidth=m.lineWidth||options.grid.markingsLineWidth;ctx.moveTo(xrange.from,yrange.from);ctx.lineTo(xrange.to,yrange.to);ctx.stroke()}else{ctx.fillStyle=m.color||options.grid.markingsColor;ctx.fillRect(xrange.from,yrange.to,xrange.to-xrange.from,yrange.from-yrange.to)}}}var axes=allAxes(),bw=options.grid.borderWidth;for(var j=0;jaxis.max||t=="full"&&bw>0&&(v==axis.min||v==axis.max))continue;if(axis.direction=="x"){x=axis.p2c(v);yoff=t=="full"?-plotHeight:t;if(axis.position=="top")yoff=-yoff}else{y=axis.p2c(v);xoff=t=="full"?-plotWidth:t;if(axis.position=="left")xoff=-xoff}if(ctx.lineWidth==1){if(axis.direction=="x")x=Math.floor(x)+.5;else y=Math.floor(y)+.5}ctx.moveTo(x,y);ctx.lineTo(x+xoff,y+yoff)}ctx.stroke()}if(bw){ctx.lineWidth=bw;ctx.strokeStyle=options.grid.borderColor;ctx.strokeRect(-bw/2,-bw/2,plotWidth+bw,plotHeight+bw)}ctx.restore()}function insertAxisLabels(){placeholder.find(".tickLabels").remove();var html=['
'];var axes=allAxes();for(var j=0;j');for(var i=0;iaxis.max)continue;var pos={},align;if(axis.direction=="x"){align="center";pos.left=Math.round(plotOffset.left+axis.p2c(tick.v)-axis.labelWidth/2);if(axis.position=="bottom")pos.top=box.top+box.padding;else pos.bottom=canvasHeight-(box.top+box.height-box.padding)}else{pos.top=Math.round(plotOffset.top+axis.p2c(tick.v)-axis.labelHeight/2);if(axis.position=="left"){pos.right=canvasWidth-(box.left+box.width-box.padding);align="right"}else{pos.left=box.left+box.padding;align="left"}}pos.width=axis.labelWidth;var style=["position:absolute","text-align:"+align];for(var a in pos)style.push(a+":"+pos[a]+"px");html.push('
'+tick.label+"
")}html.push("
")}html.push("");placeholder.append(html.join(""))}function drawSeries(series){if(series.lines.show)drawSeriesLines(series);if(series.bars.show)drawSeriesBars(series);if(series.points.show)drawSeriesPoints(series)}function drawSeriesLines(series){function plotLine(datapoints,xoffset,yoffset,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize,prevx=null,prevy=null;ctx.beginPath();for(var i=ps;i=y2&&y1>axisy.max){if(y2>axisy.max)continue;x1=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y1=axisy.max}else if(y2>=y1&&y2>axisy.max){if(y1>axisy.max)continue;x2=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y2=axisy.max}if(x1<=x2&&x1=x2&&x1>axisx.max){if(x2>axisx.max)continue;y1=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x1=axisx.max}else if(x2>=x1&&x2>axisx.max){if(x1>axisx.max)continue;y2=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x2=axisx.max}if(x1!=prevx||y1!=prevy)ctx.moveTo(axisx.p2c(x1)+xoffset,axisy.p2c(y1)+yoffset);prevx=x2;prevy=y2;ctx.lineTo(axisx.p2c(x2)+xoffset,axisy.p2c(y2)+yoffset)}ctx.stroke()}function plotLineArea(datapoints,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize,bottom=Math.min(Math.max(0,axisy.min),axisy.max),i=0,top,areaOpen=false,ypos=1,segmentStart=0,segmentEnd=0;while(true){if(ps>0&&i>points.length+ps)break;i+=ps;var x1=points[i-ps],y1=points[i-ps+ypos],x2=points[i],y2=points[i+ypos];if(areaOpen){if(ps>0&&x1!=null&&x2==null){segmentEnd=i;ps=-ps;ypos=2;continue}if(ps<0&&i==segmentStart+ps){ctx.fill();areaOpen=false;ps=-ps;ypos=1;i=segmentStart=segmentEnd+ps;continue}}if(x1==null||x2==null)continue;if(x1<=x2&&x1=x2&&x1>axisx.max){if(x2>axisx.max)continue;y1=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x1=axisx.max}else if(x2>=x1&&x2>axisx.max){if(x1>axisx.max)continue;y2=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x2=axisx.max}if(!areaOpen){ctx.beginPath();ctx.moveTo(axisx.p2c(x1),axisy.p2c(bottom));areaOpen=true}if(y1>=axisy.max&&y2>=axisy.max){ctx.lineTo(axisx.p2c(x1),axisy.p2c(axisy.max));ctx.lineTo(axisx.p2c(x2),axisy.p2c(axisy.max));continue}else if(y1<=axisy.min&&y2<=axisy.min){ctx.lineTo(axisx.p2c(x1),axisy.p2c(axisy.min));ctx.lineTo(axisx.p2c(x2),axisy.p2c(axisy.min));continue}var x1old=x1,x2old=x2;if(y1<=y2&&y1=axisy.min){x1=(axisy.min-y1)/(y2-y1)*(x2-x1)+x1;y1=axisy.min}else if(y2<=y1&&y2=axisy.min){x2=(axisy.min-y1)/(y2-y1)*(x2-x1)+x1;y2=axisy.min}if(y1>=y2&&y1>axisy.max&&y2<=axisy.max){x1=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y1=axisy.max}else if(y2>=y1&&y2>axisy.max&&y1<=axisy.max){x2=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y2=axisy.max}if(x1!=x1old){ctx.lineTo(axisx.p2c(x1old),axisy.p2c(y1))}ctx.lineTo(axisx.p2c(x1),axisy.p2c(y1));ctx.lineTo(axisx.p2c(x2),axisy.p2c(y2));if(x2!=x2old){ctx.lineTo(axisx.p2c(x2),axisy.p2c(y2));ctx.lineTo(axisx.p2c(x2old),axisy.p2c(y2))}}}ctx.save();ctx.translate(plotOffset.left,plotOffset.top);ctx.lineJoin="round";var lw=series.lines.lineWidth,sw=series.shadowSize;if(lw>0&&sw>0){ctx.lineWidth=sw;ctx.strokeStyle="rgba(0,0,0,0.1)";var angle=Math.PI/18;plotLine(series.datapoints,Math.sin(angle)*(lw/2+sw/2),Math.cos(angle)*(lw/2+sw/2),series.xaxis,series.yaxis);ctx.lineWidth=sw/2;plotLine(series.datapoints,Math.sin(angle)*(lw/2+sw/4),Math.cos(angle)*(lw/2+sw/4),series.xaxis,series.yaxis)}ctx.lineWidth=lw;ctx.strokeStyle=series.color;var fillStyle=getFillStyle(series.lines,series.color,0,plotHeight);if(fillStyle){ctx.fillStyle=fillStyle;plotLineArea(series.datapoints,series.xaxis,series.yaxis)}if(lw>0)plotLine(series.datapoints,0,0,series.xaxis,series.yaxis);ctx.restore()}function drawSeriesPoints(series){function plotPoints(datapoints,radius,fillStyle,offset,shadow,axisx,axisy,symbol){var points=datapoints.points,ps=datapoints.pointsize;for(var i=0;iaxisx.max||yaxisy.max)continue;ctx.beginPath();x=axisx.p2c(x);y=axisy.p2c(y)+offset;if(symbol=="circle")ctx.arc(x,y,radius,0,shadow?Math.PI:Math.PI*2,false);else symbol(ctx,x,y,radius,shadow);ctx.closePath();if(fillStyle){ctx.fillStyle=fillStyle;ctx.fill()}ctx.stroke()}}ctx.save();ctx.translate(plotOffset.left,plotOffset.top);var lw=series.points.lineWidth,sw=series.shadowSize,radius=series.points.radius,symbol=series.points.symbol;if(lw>0&&sw>0){var w=sw/2;ctx.lineWidth=w;ctx.strokeStyle="rgba(0,0,0,0.1)";plotPoints(series.datapoints,radius,null,w+w/2,true,series.xaxis,series.yaxis,symbol);ctx.strokeStyle="rgba(0,0,0,0.2)";plotPoints(series.datapoints,radius,null,w/2,true,series.xaxis,series.yaxis,symbol)}ctx.lineWidth=lw;ctx.strokeStyle=series.color;plotPoints(series.datapoints,radius,getFillStyle(series.points,series.color),0,false,series.xaxis,series.yaxis,symbol);ctx.restore()}function drawBar(x,y,b,barLeft,barRight,offset,fillStyleCallback,axisx,axisy,c,horizontal,lineWidth){var left,right,bottom,top,drawLeft,drawRight,drawTop,drawBottom,tmp;if(horizontal){drawBottom=drawRight=drawTop=true;drawLeft=false;left=b;right=x;top=y+barLeft;bottom=y+barRight;if(rightaxisx.max||topaxisy.max)return;if(leftaxisx.max){right=axisx.max;drawRight=false}if(bottomaxisy.max){top=axisy.max;drawTop=false}left=axisx.p2c(left);bottom=axisy.p2c(bottom);right=axisx.p2c(right);top=axisy.p2c(top);if(fillStyleCallback){c.beginPath();c.moveTo(left,bottom);c.lineTo(left,top);c.lineTo(right,top);c.lineTo(right,bottom);c.fillStyle=fillStyleCallback(bottom,top);c.fill()}if(lineWidth>0&&(drawLeft||drawRight||drawTop||drawBottom)){c.beginPath();c.moveTo(left,bottom+offset);if(drawLeft)c.lineTo(left,top+offset);else c.moveTo(left,top+offset);if(drawTop)c.lineTo(right,top+offset);else c.moveTo(right,top+offset);if(drawRight)c.lineTo(right,bottom+offset);else c.moveTo(right,bottom+offset);if(drawBottom)c.lineTo(left,bottom+offset);else c.moveTo(left,bottom+offset);c.stroke()}}function drawSeriesBars(series){function plotBars(datapoints,barLeft,barRight,offset,fillStyleCallback,axisx,axisy){var points=datapoints.points,ps=datapoints.pointsize;for(var i=0;i");fragments.push("");rowStarted=true}if(lf)label=lf(label,s);fragments.push('
'+''+label+"")}if(rowStarted)fragments.push("");if(fragments.length==0)return;var table=''+fragments.join("")+"
";if(options.legend.container!=null)$(options.legend.container).html(table);else{var pos="",p=options.legend.position,m=options.legend.margin;if(m[0]==null)m=[m,m];if(p.charAt(0)=="n")pos+="top:"+(m[1]+plotOffset.top)+"px;";else if(p.charAt(0)=="s")pos+="bottom:"+(m[1]+plotOffset.bottom)+"px;";if(p.charAt(1)=="e")pos+="right:"+(m[0]+plotOffset.right)+"px;";else if(p.charAt(1)=="w")pos+="left:"+(m[0]+plotOffset.left)+"px;";var legend=$('
'+table.replace('style="','style="position:absolute;'+pos+";")+"
").appendTo(placeholder);if(options.legend.backgroundOpacity!=0){var c=options.legend.backgroundColor;if(c==null){c=options.grid.backgroundColor;if(c&&typeof c=="string")c=$.color.parse(c);else c=$.color.extract(legend,"background-color");c.a=1;c=c.toString()}var div=legend.children();$('
').prependTo(legend).css("opacity",options.legend.backgroundOpacity)}}}var highlights=[],redrawTimeout=null;function findNearbyItem(mouseX,mouseY,seriesFilter){var maxDistance=options.grid.mouseActiveRadius,smallestDistance=maxDistance*maxDistance+1,item=null,foundPoint=false,i,j;for(i=series.length-1;i>=0;--i){if(!seriesFilter(series[i]))continue;var s=series[i],axisx=s.xaxis,axisy=s.yaxis,points=s.datapoints.points,ps=s.datapoints.pointsize,mx=axisx.c2p(mouseX),my=axisy.c2p(mouseY),maxx=maxDistance/axisx.scale,maxy=maxDistance/axisy.scale;if(axisx.options.inverseTransform)maxx=Number.MAX_VALUE;if(axisy.options.inverseTransform)maxy=Number.MAX_VALUE;if(s.lines.show||s.points.show){for(j=0;jmaxx||x-mx<-maxx||y-my>maxy||y-my<-maxy)continue;var dx=Math.abs(axisx.p2c(x)-mouseX),dy=Math.abs(axisy.p2c(y)-mouseY),dist=dx*dx+dy*dy;if(dist=Math.min(b,x)&&my>=y+barLeft&&my<=y+barRight:mx>=x+barLeft&&mx<=x+barRight&&my>=Math.min(b,y)&&my<=Math.max(b,y))item=[i,j/ps]}}}if(item){i=item[0];j=item[1];ps=series[i].datapoints.pointsize;return{datapoint:series[i].datapoints.points.slice(j*ps,(j+1)*ps),dataIndex:j,series:series[i],seriesIndex:i}}return null}function onMouseMove(e){if(options.grid.hoverable)triggerClickHoverEvent("plothover",e,function(s){return s["hoverable"]!=false})}function onMouseLeave(e){if(options.grid.hoverable)triggerClickHoverEvent("plothover",e,function(s){return false})}function onClick(e){triggerClickHoverEvent("plotclick",e,function(s){return s["clickable"]!=false})}function triggerClickHoverEvent(eventname,event,seriesFilter){var offset=eventHolder.offset(),canvasX=event.pageX-offset.left-plotOffset.left,canvasY=event.pageY-offset.top-plotOffset.top,pos=canvasToAxisCoords({left:canvasX,top:canvasY});pos.pageX=event.pageX;pos.pageY=event.pageY;var item=findNearbyItem(canvasX,canvasY,seriesFilter);if(item){item.pageX=parseInt(item.series.xaxis.p2c(item.datapoint[0])+offset.left+plotOffset.left);item.pageY=parseInt(item.series.yaxis.p2c(item.datapoint[1])+offset.top+plotOffset.top)}if(options.grid.autoHighlight){for(var i=0;iaxisx.max||yaxisy.max)return;var pointRadius=series.points.radius+series.points.lineWidth/2;octx.lineWidth=pointRadius;octx.strokeStyle=$.color.parse(series.color).scale("a",.5).toString();var radius=1.5*pointRadius,x=axisx.p2c(x),y=axisy.p2c(y);octx.beginPath();if(series.points.symbol=="circle")octx.arc(x,y,radius,0,2*Math.PI,false);else series.points.symbol(octx,x,y,radius,false);octx.closePath();octx.stroke()}function drawBarHighlight(series,point){octx.lineWidth=series.bars.lineWidth;octx.strokeStyle=$.color.parse(series.color).scale("a",.5).toString();var fillStyle=$.color.parse(series.color).scale("a",.5).toString();var barLeft=series.bars.align=="left"?0:-series.bars.barWidth/2;drawBar(point[0],point[1],point[2]||0,barLeft,barLeft+series.bars.barWidth,0,function(){return fillStyle},series.xaxis,series.yaxis,octx,series.bars.horizontal,series.bars.lineWidth)}function getColorOrGradient(spec,bottom,top,defaultColor){if(typeof spec=="string")return spec;else{var gradient=ctx.createLinearGradient(0,top,0,bottom);for(var i=0,l=spec.colors.length;i12){hours=hours-12}else if(hours==0){hours=12}}for(var i=0;i=0?"":"-";val=Math.abs(val);var before=Math.floor(log10(val))+1;if(before>n){val=val.toPrecision(n);return sign+val.replace("+","")}else if(before<0){var mantissa=val*pow(10,abs(before)+1);before-=1;return sign+mantissa.toFixed(n-1)+"e"+before}else{return sign+val.toFixed(n-before)}}function init(plot){var crosshair={x:-1,y:-1,locked:false};plot.setCrosshair=function setCrosshair(pos){if(!pos)crosshair.x=-1;else{var o=plot.p2c(pos);crosshair.x=Math.max(0,Math.min(o.left,plot.width()));crosshair.y=Math.max(0,Math.min(o.top,plot.height()))}plot.triggerRedrawOverlay()};plot.clearCrosshair=plot.setCrosshair;plot.lockCrosshair=function lockCrosshair(pos){if(pos)plot.setCrosshair(pos);crosshair.locked=true};plot.unlockCrosshair=function unlockCrosshair(){crosshair.locked=false};function onMouseOut(e){if(crosshair.locked)return;if(crosshair.x!=-1){crosshair.x=-1;plot.triggerRedrawOverlay()}}function onMouseMove(e){if(crosshair.locked)return;if(plot.getSelection&&plot.getSelection()){crosshair.x=-1;return}var offset=plot.offset();crosshair.x=Math.max(0,Math.min(e.pageX-offset.left,plot.width()));crosshair.y=Math.max(0,Math.min(e.pageY-offset.top,plot.height()));plot.triggerRedrawOverlay()}plot.hooks.bindEvents.push(function(plot,eventHolder){if(!plot.getOptions().crosshair.mode)return;eventHolder.mouseout(onMouseOut);eventHolder.mousemove(onMouseMove)});plot.hooks.drawOverlay.push(function(plot,ctx){var c=plot.getOptions().crosshair;if(!c.mode)return;var plotOffset=plot.getPlotOffset();ctx.save();ctx.translate(plotOffset.left,plotOffset.top);if(crosshair.x!=-1){var pos=plot.c2p({left:crosshair.x,top:crosshair.y});text=format_number(pos.x,3)+","+format_number(pos.y,3);var fontheight=13;ctx.fillStyle=c.color;ctx.font=fontheight+"px Verdana";var twidth=ctx.measureText(text).width;var dx=0,dy=0;if(crosshair.yplot.width()-(twidth+5)){ctx.textAlign="right";dx+=-3}else{ctx.textAlign="left";dx+=3}ctx.fillText(text,crosshair.x+dx,crosshair.y+dy);ctx.strokeStyle=c.color;ctx.lineWidth=c.lineWidth;ctx.lineJoin="round";ctx.beginPath();if(c.mode.indexOf("x")!=-1){ctx.moveTo(crosshair.x,0);ctx.lineTo(crosshair.x,plot.height())}if(c.mode.indexOf("y")!=-1){ctx.moveTo(0,crosshair.y);ctx.lineTo(plot.width(),crosshair.y)}ctx.stroke()}ctx.restore()});plot.hooks.shutdown.push(function(plot,eventHolder){eventHolder.unbind("mouseout",onMouseOut);eventHolder.unbind("mousemove",onMouseMove)})}$.plot.plugins.push({init:init,options:options,name:"crosshair_GS",version:"1.0"})})(jQuery);function assert(condition,message){if(!condition){throw new Error(message||"Assert Failed")}}var Node=function(p,t){this.point=p;this.triangle=t||null;this.next=null;this.prev=null;this.value=p.x};var AdvancingFront=function(head,tail){this.head_=head;this.tail_=tail;this.search_node_=head};AdvancingFront.prototype.head=function(){return this.head_};AdvancingFront.prototype.setHead=function(node){this.head_=node};AdvancingFront.prototype.tail=function(){return this.tail_};AdvancingFront.prototype.setTail=function(node){this.tail_=node};AdvancingFront.prototype.search=function(){return this.search_node_};AdvancingFront.prototype.setSearch=function(node){this.search_node_=node};AdvancingFront.prototype.findSearchNode=function(){return this.search_node_};AdvancingFront.prototype.locateNode=function(x){var node=this.search_node_;if(x=node.value){this.search_node_=node;return node}}}else{while(node=node.next){if(x-EPSILON&&val0){return Orientation.CCW}else{return Orientation.CW}}function inScanArea(pa,pb,pc,pd){var oadb=(pa.x-pb.x)*(pd.y-pb.y)-(pd.x-pb.x)*(pa.y-pb.y);if(oadb>=-EPSILON){return false}var oadc=(pa.x-pc.x)*(pd.y-pc.y)-(pd.x-pc.x)*(pa.y-pc.y);if(oadc<=EPSILON){return false}return true}function isAngleObtuse(pa,pb,pc){var ax=pb.x-pa.x;var ay=pb.y-pa.y;var bx=pc.x-pa.x;var by=pc.y-pa.y;return ax*bx+ay*by<0}function triangulate(tcx){tcx.initTriangulation();tcx.createAdvancingFront();sweepPoints(tcx);finalizationPolygon(tcx)}function sweepPoints(tcx){var i,len=tcx.pointCount();for(i=1;iedge.q.x;if(isEdgeSideOfTriangle(node.triangle,edge.p,edge.q)){return}fillEdgeEvent(tcx,edge,node);edgeEventByPoints(tcx,edge.p,edge.q,node.triangle,edge.q)}function edgeEventByPoints(tcx,ep,eq,triangle,point){if(isEdgeSideOfTriangle(triangle,ep,eq)){return}var p1=triangle.pointCCW(point);var o1=orient2d(eq,p1,ep);if(o1===Orientation.COLLINEAR){throw new PointError("poly2tri EdgeEvent: Collinear not supported!",[eq,p1,ep])}var p2=triangle.pointCW(point);var o2=orient2d(eq,p2,ep);if(o2===Orientation.COLLINEAR){throw new PointError("poly2tri EdgeEvent: Collinear not supported!",[eq,p2,ep])}if(o1===o2){if(o1===Orientation.CW){triangle=triangle.neighborCCW(point)}else{triangle=triangle.neighborCW(point)}edgeEventByPoints(tcx,ep,eq,triangle,point)}else{flipEdgeEvent(tcx,ep,eq,triangle,point)}}function isEdgeSideOfTriangle(triangle,ep,eq){var index=triangle.edgeIndex(ep,eq);if(index!==-1){triangle.markConstrainedEdgeByIndex(index);var t=triangle.getNeighbor(index);if(t){t.markConstrainedEdgeByPoints(ep,eq)}return true}return false}function newFrontTriangle(tcx,point,node){var triangle=new Triangle(point,node.point,node.next.point);triangle.markNeighbor(node.triangle);tcx.addToMap(triangle);var new_node=new Node(point);new_node.next=node.next;new_node.prev=node;node.next.prev=new_node;node.next=new_node;if(!legalize(tcx,triangle)){tcx.mapTriangleToNodes(triangle)}return new_node}function fill(tcx,node){var triangle=new Triangle(node.prev.point,node.point,node.next.point);triangle.markNeighbor(node.prev.triangle);triangle.markNeighbor(node.triangle);tcx.addToMap(triangle);node.prev.next=node.next;node.next.prev=node.prev;if(!legalize(tcx,triangle)){tcx.mapTriangleToNodes(triangle)}}function fillAdvancingFront(tcx,n){var node=n.next;while(node.next){if(isAngleObtuse(node.point,node.next.point,node.prev.point)){break}fill(tcx,node);node=node.next}node=n.prev;while(node.prev){if(isAngleObtuse(node.point,node.next.point,node.prev.point)){break}fill(tcx,node);node=node.prev}if(n.next&&n.next.next){if(isBasinAngleRight(n)){fillBasin(tcx,n)}}}function isBasinAngleRight(node){var ax=node.point.x-node.next.next.point.x;var ay=node.point.y-node.next.next.point.y;assert(ay>=0,"unordered y");return ax>=0||Math.abs(ax)0}function rotateTrianglePair(t,p,ot,op){var n1,n2,n3,n4;n1=t.neighborCCW(p);n2=t.neighborCW(p);n3=ot.neighborCCW(op);n4=ot.neighborCW(op);var ce1,ce2,ce3,ce4;ce1=t.getConstrainedEdgeCCW(p);ce2=t.getConstrainedEdgeCW(p);ce3=ot.getConstrainedEdgeCCW(op);ce4=ot.getConstrainedEdgeCW(op);var de1,de2,de3,de4;de1=t.getDelaunayEdgeCCW(p);de2=t.getDelaunayEdgeCW(p);de3=ot.getDelaunayEdgeCCW(op);de4=ot.getDelaunayEdgeCW(op);t.legalize(p,op);ot.legalize(op,p);ot.setDelaunayEdgeCCW(p,de1);t.setDelaunayEdgeCW(p,de2);t.setDelaunayEdgeCCW(op,de3);ot.setDelaunayEdgeCW(op,de4);ot.setConstrainedEdgeCCW(p,ce1);t.setConstrainedEdgeCW(p,ce2);t.setConstrainedEdgeCCW(op,ce3);ot.setConstrainedEdgeCW(op,ce4);t.clearNeighbors();ot.clearNeighbors();if(n1){ot.markNeighbor(n1)}if(n2){t.markNeighbor(n2)}if(n3){t.markNeighbor(n3)}if(n4){ot.markNeighbor(n4)}t.markNeighbor(ot)}function fillBasin(tcx,node){if(orient2d(node.point,node.next.point,node.next.next.point)===Orientation.CCW){tcx.basin.left_node=node.next.next}else{tcx.basin.left_node=node.next}tcx.basin.bottom_node=tcx.basin.left_node;while(tcx.basin.bottom_node.next&&tcx.basin.bottom_node.point.y>=tcx.basin.bottom_node.next.point.y){tcx.basin.bottom_node=tcx.basin.bottom_node.next}if(tcx.basin.bottom_node===tcx.basin.left_node){return}tcx.basin.right_node=tcx.basin.bottom_node;while(tcx.basin.right_node.next&&tcx.basin.right_node.point.ytcx.basin.right_node.point.y;fillBasinReq(tcx,tcx.basin.bottom_node)}function fillBasinReq(tcx,node){if(isShallow(tcx,node)){return}fill(tcx,node);var o;if(node.prev===tcx.basin.left_node&&node.next===tcx.basin.right_node){return}else if(node.prev===tcx.basin.left_node){o=orient2d(node.point,node.next.point,node.next.next.point);if(o===Orientation.CW){return}node=node.next}else if(node.next===tcx.basin.right_node){o=orient2d(node.point,node.prev.point,node.prev.prev.point);if(o===Orientation.CCW){return}node=node.prev}else{if(node.prev.point.yheight){return true}return false}function fillEdgeEvent(tcx,edge,node){if(tcx.edge_event.right){fillRightAboveEdgeEvent(tcx,edge,node)}else{fillLeftAboveEdgeEvent(tcx,edge,node)}}function fillRightAboveEdgeEvent(tcx,edge,node){while(node.next.point.xedge.p.x){if(orient2d(edge.q,node.prev.point,edge.p)===Orientation.CW){fillLeftBelowEdgeEvent(tcx,edge,node)}else{node=node.prev}}}function fillLeftBelowEdgeEvent(tcx,edge,node){if(node.point.x>edge.p.x){if(orient2d(node.point,node.prev.point,node.prev.prev.point)===Orientation.CW){fillLeftConcaveEdgeEvent(tcx,edge,node)}else{fillLeftConvexEdgeEvent(tcx,edge,node);fillLeftBelowEdgeEvent(tcx,edge,node)}}}function fillLeftConvexEdgeEvent(tcx,edge,node){if(orient2d(node.prev.point,node.prev.prev.point,node.prev.prev.prev.point)===Orientation.CW){fillLeftConcaveEdgeEvent(tcx,edge,node.prev)}else{if(orient2d(edge.q,node.prev.prev.point,edge.p)===Orientation.CW){fillLeftConvexEdgeEvent(tcx,edge,node.prev)}else{}}}function fillLeftConcaveEdgeEvent(tcx,edge,node){fill(tcx,node.prev);if(node.prev.point!==edge.p){if(orient2d(edge.q,node.prev.point,edge.p)===Orientation.CW){if(orient2d(node.point,node.prev.point,node.prev.prev.point)===Orientation.CW){fillLeftConcaveEdgeEvent(tcx,edge,node)}else{}}}}function flipEdgeEvent(tcx,ep,eq,t,p){var ot=t.neighborAcross(p);assert(ot,"FLIP failed due to missing triangle!");var op=ot.oppositePoint(t,p);if(t.getConstrainedEdgeAcross(p)){var index=t.index(p);throw new PointError("poly2tri Intersecting Constraints",[p,op,t.getPoint((index+1)%3),t.getPoint((index+2)%3)])}if(inScanArea(p,t.pointCCW(p),t.pointCW(p),op)){rotateTrianglePair(t,p,ot,op);tcx.mapTriangleToNodes(t);tcx.mapTriangleToNodes(ot);if(p===eq&&op===ep){if(eq===tcx.edge_event.constrained_edge.q&&ep===tcx.edge_event.constrained_edge.p){t.markConstrainedEdgeByPoints(ep,eq);ot.markConstrainedEdgeByPoints(ep,eq);legalize(tcx,t);legalize(tcx,ot)}else{}}else{var o=orient2d(eq,op,ep);t=nextFlipTriangle(tcx,o,t,ot,p,op);flipEdgeEvent(tcx,ep,eq,t,p)}}else{var newP=nextFlipPoint(ep,eq,ot,op);flipScanEdgeEvent(tcx,ep,eq,t,ot,newP);edgeEventByPoints(tcx,ep,eq,t,p)}}function nextFlipTriangle(tcx,o,t,ot,p,op){var edge_index;if(o===Orientation.CCW){edge_index=ot.edgeIndex(p,op);ot.delaunay_edge[edge_index]=true;legalize(tcx,ot);ot.clearDelaunayEdges();return t}edge_index=t.edgeIndex(p,op);t.delaunay_edge[edge_index]=true;legalize(tcx,t);t.clearDelaunayEdges();return ot}function nextFlipPoint(ep,eq,ot,op){var o2d=orient2d(eq,op,ep);if(o2d===Orientation.CW){return ot.pointCCW(op)}else if(o2d===Orientation.CCW){return ot.pointCW(op)}else{throw new PointError("poly2tri [Unsupported] nextFlipPoint: opposing point on constrained edge!",[eq,op,ep])}}function flipScanEdgeEvent(tcx,ep,eq,flip_triangle,t,p){var ot=t.neighborAcross(p);assert(ot,"FLIP failed due to missing triangle");var op=ot.oppositePoint(t,p);if(inScanArea(eq,flip_triangle.pointCCW(eq),flip_triangle.pointCW(eq),op)){flipEdgeEvent(tcx,eq,op,ot,op)}else{var newP=nextFlipPoint(ep,eq,ot,op);flipScanEdgeEvent(tcx,ep,eq,flip_triangle,ot,newP)}}var kAlpha=.3;var Edge=function(p1,p2){this.p=p1;this.q=p2;if(p1.y>p2.y){this.q=p1;this.p=p2}else if(p1.y===p2.y){if(p1.x>p2.x){this.q=p1;this.p=p2}else if(p1.x===p2.x){throw new PointError("poly2tri Invalid Edge constructor: repeated points!",[p1])}}if(!this.q._p2t_edge_list){this.q._p2t_edge_list=[]}this.q._p2t_edge_list.push(this)};var Basin=function(){this.left_node=null;this.bottom_node=null;this.right_node=null;this.width=0;this.left_highest=false};Basin.prototype.clear=function(){this.left_node=null;this.bottom_node=null;this.right_node=null;this.width=0;this.left_highest=false};var EdgeEvent=function(){this.constrained_edge=null;this.right=false};var SweepContext=function(contour,options){options=options||{};this.triangles_=[];this.map_=[];this.points_=options.cloneArrays?contour.slice(0):contour;this.edge_list=[];this.pmin_=this.pmax_=null;this.front_=null;this.head_=null;this.tail_=null;this.af_head_=null;this.af_middle_=null;this.af_tail_=null;this.basin=new Basin;this.edge_event=new EdgeEvent;this.initEdges(this.points_)};SweepContext.prototype.addHole=function(polyline){this.initEdges(polyline);var i,len=polyline.length;for(i=0;ixmax&&(xmax=p.x);p.xymax&&(ymax=p.y);p.y>>=1;return bit}function tinf_read_bits(d,num,base){if(!num)return base;while(d.bitcount<24){d.tag|=d.source[d.sourceIndex++]<>>16-num;d.tag>>>=num;d.bitcount-=num;return val+base}function tinf_decode_symbol(d,t){while(d.bitcount<24){d.tag|=d.source[d.sourceIndex++]<>>=1;++len;sum+=t.table[len];cur-=t.table[len]}while(cur>=0);d.tag=tag;d.bitcount-=len;return t.trans[sum+cur]}function tinf_decode_trees(d,lt,dt){var hlit,hdist,hclen;var i,num,length;hlit=tinf_read_bits(d,5,257);hdist=tinf_read_bits(d,5,1);hclen=tinf_read_bits(d,4,4);for(i=0;i<19;++i)lengths[i]=0;for(i=0;i8){d.sourceIndex--;d.bitcount-=8}length=d.source[d.sourceIndex+1];length=256*length+d.source[d.sourceIndex];invlength=d.source[d.sourceIndex+3];invlength=256*invlength+d.source[d.sourceIndex+2];if(length!==(~invlength&65535))return TINF_DATA_ERROR;d.sourceIndex+=4;for(i=length;i;--i)d.dest[d.destLen++]=d.source[d.sourceIndex++];d.bitcount=0;return TINF_OK}function tinf_uncompress(source,dest){var d=new Data(source,dest);var bfinal,btype,res;do{bfinal=tinf_getbit(d);btype=tinf_read_bits(d,2,0);switch(btype){case 0:res=tinf_inflate_uncompressed_block(d);break;case 1:res=tinf_inflate_block_data(d,sltree,sdtree);break;case 2:tinf_decode_trees(d,d.ltree,d.dtree);res=tinf_inflate_block_data(d,d.ltree,d.dtree);break;default:res=TINF_DATA_ERROR}if(res!==TINF_OK)throw new Error("Data error")}while(!bfinal);if(d.destLen0,"No English "+name+" specified.")}assertNamePresent("fontFamily");assertNamePresent("weightName");assertNamePresent("manufacturer");assertNamePresent("copyright");assertNamePresent("version");assert(this.unitsPerEm>0,"No unitsPerEm specified.")};Font.prototype.toTables=function(){return sfnt.fontToTable(this)};Font.prototype.toBuffer=function(){console.warn("Font.toBuffer is deprecated. Use Font.toArrayBuffer instead.");return this.toArrayBuffer()};Font.prototype.toArrayBuffer=function(){var sfntTable=this.toTables();var bytes=sfntTable.encode();var buffer=new ArrayBuffer(bytes.length);var intArray=new Uint8Array(buffer);for(var i=0;i=0&&i>0){s+=" "}s+=floatToString(v)}return s}var d="";for(var i=0;i>4;var n2=b&15;if(n1===eof){break}s+=lookup[n1];if(n2===eof){break}s+=lookup[n2]}return parseFloat(s)}function parseOperand(parser,b0){var b1;var b2;var b3;var b4;if(b0===28){b1=parser.parseByte();b2=parser.parseByte();return b1<<8|b2}if(b0===29){b1=parser.parseByte();b2=parser.parseByte();b3=parser.parseByte();b4=parser.parseByte();return b1<<24|b2<<16|b3<<8|b4}if(b0===30){return parseFloatOperand(parser)}if(b0>=32&&b0<=246){return b0-139}if(b0>=247&&b0<=250){b1=parser.parseByte();return(b0-247)*256+b1+108}if(b0>=251&&b0<=254){b1=parser.parseByte();return-(b0-251)*256-b1-108}throw new Error("Invalid b0 "+b0)}function entriesToObject(entries){var o={};for(var i=0;i>1;stack.length=0;haveWidth=true}function parse(code){var b1;var b2;var b3;var b4;var codeIndex;var subrCode;var jpx;var jpy;var c3x;var c3y;var c4x;var c4y;var i=0;while(i1&&!haveWidth){width=stack.shift()+font.nominalWidthX;haveWidth=true}y+=stack.pop();newContour(x,y);break;case 5:while(stack.length>0){x+=stack.shift();y+=stack.shift();p.lineTo(x,y)}break;case 6:while(stack.length>0){x+=stack.shift();p.lineTo(x,y);if(stack.length===0){break}y+=stack.shift();p.lineTo(x,y)}break;case 7:while(stack.length>0){y+=stack.shift();p.lineTo(x,y);if(stack.length===0){break}x+=stack.shift();p.lineTo(x,y)}break;case 8:while(stack.length>0){c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();y=c2y+stack.shift();p.curveTo(c1x,c1y,c2x,c2y,x,y)}break;case 10:codeIndex=stack.pop()+font.subrsBias;subrCode=font.subrs[codeIndex];if(subrCode){parse(subrCode)}break;case 11:return;case 12:v=code[i];i+=1;switch(v){case 35:c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();jpx=c2x+stack.shift();jpy=c2y+stack.shift();c3x=jpx+stack.shift();c3y=jpy+stack.shift();c4x=c3x+stack.shift();c4y=c3y+stack.shift();x=c4x+stack.shift();y=c4y+stack.shift();stack.shift();p.curveTo(c1x,c1y,c2x,c2y,jpx,jpy);p.curveTo(c3x,c3y,c4x,c4y,x,y);break;case 34:c1x=x+stack.shift();c1y=y;c2x=c1x+stack.shift();c2y=c1y+stack.shift();jpx=c2x+stack.shift();jpy=c2y;c3x=jpx+stack.shift();c3y=c2y;c4x=c3x+stack.shift();c4y=y;x=c4x+stack.shift();p.curveTo(c1x,c1y,c2x,c2y,jpx,jpy);p.curveTo(c3x,c3y,c4x,c4y,x,y);break;case 36:c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();jpx=c2x+stack.shift();jpy=c2y;c3x=jpx+stack.shift();c3y=c2y;c4x=c3x+stack.shift();c4y=c3y+stack.shift();x=c4x+stack.shift();p.curveTo(c1x,c1y,c2x,c2y,jpx,jpy);p.curveTo(c3x,c3y,c4x,c4y,x,y);break;case 37:c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();jpx=c2x+stack.shift();jpy=c2y+stack.shift();c3x=jpx+stack.shift();c3y=jpy+stack.shift();c4x=c3x+stack.shift();c4y=c3y+stack.shift();if(Math.abs(c4x-x)>Math.abs(c4y-y)){x=c4x+stack.shift()}else{y=c4y+stack.shift()}p.curveTo(c1x,c1y,c2x,c2y,jpx,jpy);p.curveTo(c3x,c3y,c4x,c4y,x,y);break;default:console.log("Glyph "+glyph.index+": unknown operator "+1200+v);stack.length=0}break;case 14:if(stack.length>0&&!haveWidth){width=stack.shift()+font.nominalWidthX;haveWidth=true}if(open){p.closePath();open=false}break;case 18:parseStems();break;case 19:case 20:parseStems();i+=nStems+7>>3;break;case 21:if(stack.length>2&&!haveWidth){width=stack.shift()+font.nominalWidthX;haveWidth=true}y+=stack.pop();x+=stack.pop();newContour(x,y);break;case 22:if(stack.length>1&&!haveWidth){width=stack.shift()+font.nominalWidthX;haveWidth=true}x+=stack.pop();newContour(x,y);break;case 23:parseStems();break;case 24:while(stack.length>2){c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();y=c2y+stack.shift();p.curveTo(c1x,c1y,c2x,c2y,x,y)}x+=stack.shift();y+=stack.shift();p.lineTo(x,y);break;case 25:while(stack.length>6){x+=stack.shift();y+=stack.shift();p.lineTo(x,y)}c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();y=c2y+stack.shift();p.curveTo(c1x,c1y,c2x,c2y,x,y);break;case 26:if(stack.length%2){x+=stack.shift()}while(stack.length>0){c1x=x;c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x;y=c2y+stack.shift();p.curveTo(c1x,c1y,c2x,c2y,x,y)}break;case 27:if(stack.length%2){y+=stack.shift()}while(stack.length>0){c1x=x+stack.shift();c1y=y;c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();y=c2y;p.curveTo(c1x,c1y,c2x,c2y,x,y)}break;case 28:b1=code[i];b2=code[i+1];stack.push((b1<<24|b2<<16)>>16);i+=2;break;case 29:codeIndex=stack.pop()+font.gsubrsBias;subrCode=font.gsubrs[codeIndex];if(subrCode){parse(subrCode)}break;case 30:while(stack.length>0){c1x=x;c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();y=c2y+(stack.length===1?stack.shift():0);p.curveTo(c1x,c1y,c2x,c2y,x,y);if(stack.length===0){break}c1x=x+stack.shift();c1y=y;c2x=c1x+stack.shift();c2y=c1y+stack.shift();y=c2y+stack.shift();x=c2x+(stack.length===1?stack.shift():0);p.curveTo(c1x,c1y,c2x,c2y,x,y)}break;case 31:while(stack.length>0){c1x=x+stack.shift();c1y=y;c2x=c1x+stack.shift();c2y=c1y+stack.shift();y=c2y+stack.shift();x=c2x+(stack.length===1?stack.shift():0);p.curveTo(c1x,c1y,c2x,c2y,x,y);if(stack.length===0){break}c1x=x;c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();y=c2y+(stack.length===1?stack.shift():0);p.curveTo(c1x,c1y,c2x,c2y,x,y)}break;default:if(v<32){console.log("Glyph "+glyph.index+": unknown operator "+v)}else if(v<247){stack.push(v-139)}else if(v<251){b1=code[i];i+=1;stack.push((v-247)*256+b1+108)}else if(v<255){b1=code[i];i+=1;stack.push(-(v-251)*256-b1-108)}else{b1=code[i];b2=code[i+1];b3=code[i+2];b4=code[i+3];i+=4;stack.push((b1<<24|b2<<16|b3<<8|b4)/65536)}}}}parse(code);glyph.advanceWidth=width;return p}function calcCFFSubroutineBias(subrs){var bias;if(subrs.length<1240){bias=107}else if(subrs.length<33900){bias=1131}else{bias=32768}return bias}function parseCFFTable(data,start,font){font.tables.cff={};var header=parseCFFHeader(data,start);var nameIndex=parseCFFIndex(data,header.endOffset,bytesToString);var topDictIndex=parseCFFIndex(data,nameIndex.endOffset);var stringIndex=parseCFFIndex(data,topDictIndex.endOffset,bytesToString);var globalSubrIndex=parseCFFIndex(data,stringIndex.endOffset);font.gsubrs=globalSubrIndex.objects;font.gsubrsBias=calcCFFSubroutineBias(font.gsubrs);var topDictData=new DataView(new Uint8Array(topDictIndex.objects[0]).buffer);var topDict=parseCFFTopDict(topDictData,stringIndex.objects);font.tables.cff.topDict=topDict;var privateDictOffset=start+topDict["private"][1];var privateDict=parseCFFPrivateDict(data,privateDictOffset,topDict["private"][0],stringIndex.objects);font.defaultWidthX=privateDict.defaultWidthX;font.nominalWidthX=privateDict.nominalWidthX;if(privateDict.subrs!==0){var subrOffset=privateDictOffset+privateDict.subrs;var subrIndex=parseCFFIndex(data,subrOffset);font.subrs=subrIndex.objects;font.subrsBias=calcCFFSubroutineBias(font.subrs)}else{font.subrs=[];font.subrsBias=0}var charStringsIndex=parseCFFIndex(data,start+topDict.charStrings);font.nGlyphs=charStringsIndex.objects.length;var charset=parseCFFCharset(data,start+topDict.charset,font.nGlyphs,stringIndex.objects);if(topDict.encoding===0){font.cffEncoding=new CffEncoding(cffStandardEncoding,charset)}else if(topDict.encoding===1){font.cffEncoding=new CffEncoding(cffExpertEncoding,charset)}else{font.cffEncoding=parseCFFEncoding(data,start+topDict.encoding,charset)}font.encoding=font.encoding||font.cffEncoding;font.glyphs=new GlyphSet(font);for(var i=0;i=0){sid=i}i=strings.indexOf(s);if(i>=0){sid=i+cffStandardStrings.length}else{sid=cffStandardStrings.length+strings.length;strings.push(s)}return sid}function makeHeader(){return new table.Record("Header",[{name:"major",type:"Card8",value:1},{name:"minor",type:"Card8",value:0},{name:"hdrSize",type:"Card8",value:4},{name:"major",type:"Card8",value:1}])}function makeNameIndex(fontNames){var t=new table.Record("Name INDEX",[{name:"names",type:"INDEX",value:[]}]);t.names=[];for(var i=0;i>1;p.skip("uShort",3);cmap.glyphIndexMap={};var endCountParser=new Parser(data,start+offset+14);var startCountParser=new Parser(data,start+offset+16+segCount*2);var idDeltaParser=new Parser(data,start+offset+16+segCount*4);var idRangeOffsetParser=new Parser(data,start+offset+16+segCount*6);var glyphIndexOffset=start+offset+16+segCount*8;for(i=0;i0){v=p.parseByte();if((flag&sameBitMask)===0){v=-v}v=previousValue+v}else{if((flag&sameBitMask)>0){v=previousValue}else{v=previousValue+p.parseShort()}}return v}function parseGlyph(glyph,data,start){var p=new Parser(data,start);glyph.numberOfContours=p.parseShort();glyph.xMin=p.parseShort();glyph.yMin=p.parseShort();glyph.xMax=p.parseShort();glyph.yMax=p.parseShort();var flags;var flag;if(glyph.numberOfContours>0){var i;var endPointIndices=glyph.endPointIndices=[];for(i=0;i0){var repeatCount=p.parseByte();for(var j=0;j0){var points=[];var point;if(numberOfCoordinates>0){for(i=0;i=0;points.push(point)}var px=0;for(i=0;i0){component.dx=p.parseShort();component.dy=p.parseShort()}else{component.dx=p.parseChar();component.dy=p.parseChar()}if((flags&8)>0){component.xScale=component.yScale=p.parseF2Dot14()}else if((flags&64)>0){component.xScale=p.parseF2Dot14();component.yScale=p.parseF2Dot14()}else if((flags&128)>0){component.xScale=p.parseF2Dot14();component.scale01=p.parseF2Dot14();component.scale10=p.parseF2Dot14();component.yScale=p.parseF2Dot14()}glyph.components.push(component);moreComponents=!!(flags&32)}}}function transformPoints(points,transform){var newPoints=[];for(var i=0;i>1;if(glyphID=range.begin&&unicode=1){os2.ulCodePageRange1=p.parseULong();os2.ulCodePageRange2=p.parseULong()}if(os2.version>=2){os2.sxHeight=p.parseShort();os2.sCapHeight=p.parseShort();os2.usDefaultChar=p.parseUShort();os2.usBreakChar=p.parseUShort();os2.usMaxContent=p.parseUShort()}return os2}function makeOS2Table(options){return new table.Table("OS/2",[{name:"version",type:"USHORT",value:3},{name:"xAvgCharWidth",type:"SHORT",value:0},{name:"usWeightClass",type:"USHORT",value:0},{name:"usWidthClass",type:"USHORT",value:0},{name:"fsType",type:"USHORT",value:0},{name:"ySubscriptXSize",type:"SHORT",value:650},{name:"ySubscriptYSize",type:"SHORT",value:699},{name:"ySubscriptXOffset",type:"SHORT",value:0},{name:"ySubscriptYOffset",type:"SHORT",value:140},{name:"ySuperscriptXSize",type:"SHORT",value:650},{name:"ySuperscriptYSize",type:"SHORT",value:699},{name:"ySuperscriptXOffset",type:"SHORT",value:0},{name:"ySuperscriptYOffset",type:"SHORT",value:479},{name:"yStrikeoutSize",type:"SHORT",value:49},{name:"yStrikeoutPosition",type:"SHORT",value:258},{name:"sFamilyClass",type:"SHORT",value:0},{name:"bFamilyType",type:"BYTE",value:0},{name:"bSerifStyle",type:"BYTE",value:0},{name:"bWeight",type:"BYTE",value:0},{name:"bProportion",type:"BYTE",value:0},{name:"bContrast",type:"BYTE",value:0},{name:"bStrokeVariation",type:"BYTE",value:0},{name:"bArmStyle",type:"BYTE",value:0},{name:"bLetterform",type:"BYTE",value:0},{name:"bMidline",type:"BYTE",value:0},{name:"bXHeight",type:"BYTE",value:0},{name:"ulUnicodeRange1",type:"ULONG",value:0},{name:"ulUnicodeRange2",type:"ULONG",value:0},{name:"ulUnicodeRange3",type:"ULONG",value:0},{name:"ulUnicodeRange4",type:"ULONG",value:0},{name:"achVendID",type:"CHARARRAY",value:"XXXX"},{name:"fsSelection",type:"USHORT",value:0},{name:"usFirstCharIndex",type:"USHORT",value:0},{name:"usLastCharIndex",type:"USHORT",value:0},{name:"sTypoAscender",type:"SHORT",value:0},{name:"sTypoDescender",type:"SHORT",value:0},{name:"sTypoLineGap",type:"SHORT",value:0},{name:"usWinAscent",type:"USHORT",value:0},{name:"usWinDescent",type:"USHORT",value:0},{name:"ulCodePageRange1",type:"ULONG",value:0},{name:"ulCodePageRange2",type:"ULONG",value:0},{name:"sxHeight",type:"SHORT",value:0},{name:"sCapHeight",type:"SHORT",value:0},{name:"usDefaultChar",type:"USHORT",value:0},{name:"usBreakChar",type:"USHORT",value:0},{name:"usMaxContext",type:"USHORT",value:0}],options)}function parsePostTable(data,start){var post={};var p=new Parser(data,start);var i;post.version=p.parseVersion();post.italicAngle=p.parseFixed();post.underlinePosition=p.parseShort();post.underlineThickness=p.parseShort();post.isFixedPitch=p.parseULong();post.minMemType42=p.parseULong();post.maxMemType42=p.parseULong();post.minMemType1=p.parseULong();post.maxMemType1=p.parseULong();switch(post.version){case 1:post.names=standardNames.slice();break;case 2:post.numberOfGlyphs=p.parseUShort();post.glyphNameIndex=new Array(post.numberOfGlyphs);for(i=0;i=standardNames.length){var nameLength=p.parseChar();post.names.push(p.parseString(nameLength))}}break;case 2.5:post.numberOfGlyphs=p.parseUShort();post.offset=new Array(post.numberOfGlyphs);for(i=0;ir2.value.tag){return 1}else{return-1}});sfnt.fields=sfnt.fields.concat(recordFields);sfnt.fields=sfnt.fields.concat(tableFields);return sfnt}function metricsForChar(font,chars,notFoundMetrics){for(var i=0;i0){var glyph=font.glyphs.get(glyphIndex);return glyph.getMetrics()}}return notFoundMetrics}function average(vs){var sum=0;for(var i=0;iunicode||firstCharIndex===null){firstCharIndex=unicode}if(lastCharIndex 123 are reserved for internal usage")}if(glyph.name===".notdef")continue;var metrics=glyph.getMetrics();xMins.push(metrics.xMin);yMins.push(metrics.yMin);xMaxs.push(metrics.xMax);yMaxs.push(metrics.yMax);leftSideBearings.push(metrics.leftSideBearing);rightSideBearings.push(metrics.rightSideBearing);advanceWidths.push(glyph.advanceWidth)}var globals={xMin:Math.min.apply(null,xMins),yMin:Math.min.apply(null,yMins),xMax:Math.max.apply(null,xMaxs),yMax:Math.max.apply(null,yMaxs),advanceWidthMax:Math.max.apply(null,advanceWidths),advanceWidthAvg:average(advanceWidths),minLeftSideBearing:Math.min.apply(null,leftSideBearings),maxLeftSideBearing:Math.max.apply(null,leftSideBearings),minRightSideBearing:Math.min.apply(null,rightSideBearings)};globals.ascender=font.ascender;globals.descender=font.descender;var headTable=head.make({flags:3,unitsPerEm:font.unitsPerEm,xMin:globals.xMin,yMin:globals.yMin,xMax:globals.xMax,yMax:globals.yMax,lowestRecPPEM:3});var hheaTable=hhea.make({ascender:globals.ascender,descender:globals.descender,advanceWidthMax:globals.advanceWidthMax,minLeftSideBearing:globals.minLeftSideBearing,minRightSideBearing:globals.minRightSideBearing,xMaxExtent:globals.maxLeftSideBearing+(globals.xMax-globals.xMin),numberOfHMetrics:font.glyphs.length});var maxpTable=maxp.make(font.glyphs.length);var os2Table=os2.make({xAvgCharWidth:Math.round(globals.advanceWidthAvg),usWeightClass:500,usWidthClass:5,usFirstCharIndex:firstCharIndex,usLastCharIndex:lastCharIndex,ulUnicodeRange1:ulUnicodeRange1,ulUnicodeRange2:ulUnicodeRange2,ulUnicodeRange3:ulUnicodeRange3,ulUnicodeRange4:ulUnicodeRange4,fsSelection:64,sTypoAscender:globals.ascender,sTypoDescender:globals.descender,sTypoLineGap:0,usWinAscent:globals.yMax,usWinDescent:Math.abs(globals.yMin),ulCodePageRange1:1,sxHeight:metricsForChar(font,"xyvw",{yMax:Math.round(globals.ascender/2)}).yMax,sCapHeight:metricsForChar(font,"HIKLEFJMNTZBDPRAGOQSUVWXY",globals).yMax,usDefaultChar:font.hasChar(" ")?32:0,usBreakChar:font.hasChar(" ")?32:0});var hmtxTable=hmtx.make(font.glyphs);var cmapTable=cmap.make(font.glyphs);var englishFamilyName=font.getEnglishName("fontFamily");var englishStyleName=font.getEnglishName("fontSubfamily");var englishFullName=englishFamilyName+" "+englishStyleName;var postScriptName=font.getEnglishName("postScriptName");if(!postScriptName){postScriptName=englishFamilyName.replace(/\s/g,"")+"-"+englishStyleName}var names={};for(var n in font.names){names[n]=font.names[n]}if(!names.uniqueID){names.uniqueID={en:font.getEnglishName("manufacturer")+":"+englishFullName}}if(!names.postScriptName){names.postScriptName={en:postScriptName}}if(!names.preferredFamily){names.preferredFamily=font.names.fontFamily}if(!names.preferredSubfamily){names.preferredSubfamily=font.names.fontSubfamily}var languageTags=[];var nameTable=makeNameTable(names,languageTags);var ltagTable=languageTags.length>0?ltag.make(languageTags):undefined;var postTable=post.make();var cffTable=cff.make(font.glyphs,{version:font.getEnglishName("version"),fullName:englishFullName,familyName:englishFamilyName,weightName:englishStyleName,postScriptName:postScriptName,unitsPerEm:font.unitsPerEm,fontBBox:[0,globals.yMin,globals.ascender,globals.advanceWidthMax]});var tables=[headTable,hheaTable,maxpTable,os2Table,nameTable,cmapTable,postTable,cffTable,hmtxTable];if(ltagTable){tables.push(ltagTable)}var sfntTable=makeSfntTable(tables);var bytes=sfntTable.encode();var checkSum=computeCheckSum(bytes);var tableFields=sfntTable.fields;var checkSumAdjusted=false;for(i=0;i=0&&v<=255,"Byte value should be between 0 and 255.");return[v]};sizeOf.BYTE=constant(1);encode.CHAR=function(v){return[v.charCodeAt(0)]};sizeOf.CHAR=constant(1);encode.CHARARRAY=function(v){var b=[];for(var i=0;i>8&255,v&255]};sizeOf.USHORT=constant(2);encode.SHORT=function(v){if(v>=LIMIT16){v=-(2*LIMIT16-v)}return[v>>8&255,v&255]};sizeOf.SHORT=constant(2);encode.UINT24=function(v){return[v>>16&255,v>>8&255,v&255]};sizeOf.UINT24=constant(3);encode.ULONG=function(v){return[v>>24&255,v>>16&255,v>>8&255,v&255]};sizeOf.ULONG=constant(4);encode.LONG=function(v){if(v>=LIMIT32){v=-(2*LIMIT32-v)}return[v>>24&255,v>>16&255,v>>8&255,v&255]};sizeOf.LONG=constant(4);encode.FIXED=encode.ULONG;sizeOf.FIXED=sizeOf.ULONG;encode.FWORD=encode.SHORT;sizeOf.FWORD=sizeOf.SHORT;encode.UFWORD=encode.USHORT;sizeOf.UFWORD=sizeOf.USHORT;encode.LONGDATETIME=function(){return[0,0,0,0,0,0,0,0]};sizeOf.LONGDATETIME=constant(8);encode.TAG=function(v){assert(v.length===4,"Tag should be exactly 4 ASCII characters.");return[v.charCodeAt(0),v.charCodeAt(1),v.charCodeAt(2),v.charCodeAt(3)]};sizeOf.TAG=constant(4);encode.Card8=encode.BYTE;sizeOf.Card8=sizeOf.BYTE;encode.Card16=encode.USHORT;sizeOf.Card16=sizeOf.USHORT;encode.OffSize=encode.BYTE;sizeOf.OffSize=sizeOf.BYTE;encode.SID=encode.USHORT;sizeOf.SID=sizeOf.USHORT;encode.NUMBER=function(v){if(v>=-107&&v<=107){return[v+139]}else if(v>=108&&v<=1131){v=v-108;return[(v>>8)+247,v&255]}else if(v>=-1131&&v<=-108){v=-v-108;return[(v>>8)+251,v&255]}else if(v>=-32768&&v<=32767){return encode.NUMBER16(v)}else{return encode.NUMBER32(v)}};sizeOf.NUMBER=function(v){return encode.NUMBER(v).length};encode.NUMBER16=function(v){return[28,v>>8&255,v&255]};sizeOf.NUMBER16=constant(3);encode.NUMBER32=function(v){return[29,v>>24&255,v>>16&255,v>>8&255,v&255]};sizeOf.NUMBER32=constant(5);encode.REAL=function(v){var value=v.toString();var m=/\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(value);if(m){var epsilon=parseFloat("1e"+((m[2]?+m[2]:0)+m[1].length));value=(Math.round(v*epsilon)/epsilon).toString()}var nibbles="";var i;var ii;for(i=0,ii=value.length;i>8&255);b.push(codepoint&255)}return b};sizeOf.UTF16=function(v){return v.length*2};var eightBitMacEncodings={"x-mac-croatian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø"+"¿¡¬√ƒ≈Ć«Č… ÀÃÕŒœĐ—“”‘’÷◊©⁄€‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ","x-mac-cyrillic":"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњ"+"јЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю","x-mac-gaelic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØḂ±≤≥ḃĊċḊḋḞḟĠġṀæø"+"ṁṖṗɼƒſṠ«»… ÀÃÕŒœ–—“”‘’ṡẛÿŸṪ€‹›Ŷŷṫ·Ỳỳ⁊ÂÊÁËÈÍÎÏÌÓÔ♣ÒÚÛÙıÝýŴŵẄẅẀẁẂẃ","x-mac-greek":"Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦€ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩ"+"άΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ­","x-mac-icelandic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø"+"¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-inuit":"ᐃᐄᐅᐆᐊᐋᐱᐲᐳᐴᐸᐹᑉᑎᑏᑐᑑᑕᑖᑦᑭᑮᑯᑰᑲᑳᒃᒋᒌᒍᒎᒐᒑ°ᒡᒥᒦ•¶ᒧ®©™ᒨᒪᒫᒻᓂᓃᓄᓅᓇᓈᓐᓯᓰᓱᓲᓴᓵᔅᓕᓖᓗ"+"ᓘᓚᓛᓪᔨᔩᔪᔫᔭ… ᔮᔾᕕᕖᕗ–—“”‘’ᕘᕙᕚᕝᕆᕇᕈᕉᕋᕌᕐᕿᖀᖁᖂᖃᖄᖅᖏᖐᖑᖒᖓᖔᖕᙱᙲᙳᙴᙵᙶᖖᖠᖡᖢᖣᖤᖥᖦᕼŁł","x-mac-ce":"ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅ"+"ņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ",macintosh:"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø"+"¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-romanian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂȘ∞±≤≥¥µ∂∑∏π∫ªºΩăș"+"¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›Țț‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-turkish":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø"+"¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙˆ˜¯˘˙˚¸˝˛ˇ"};opentype_decode.MACSTRING=function(dataView,offset,dataLength,encoding){var table=eightBitMacEncodings[encoding];if(table===undefined){return undefined}var result="";for(var i=0;i=128){c=table[c];if(c===undefined){return undefined}}result.push(c)}return result};sizeOf.MACSTRING=function(str,encoding){var b=encode.MACSTRING(str,encoding);if(b!==undefined){return b.length}else{return 0}};encode.INDEX=function(l){var i;var offset=1;var offsets=[offset];var data=[];var dataSize=0;for(i=0;i>8;d[o+1]=offset&255;d=d.concat(subtables[i])}return d};sizeOf.TABLE=function(table){var numBytes=0;var length=table.fields.length;for(var i=0;i=1){if(dest!=quat){dest[0]=quat[0];dest[1]=quat[1];dest[2]=quat[2];dest[3]=quat[3]}return dest}var halfTheta=Math.acos(cosHalfTheta);var sinHalfTheta=Math.sqrt(1-cosHalfTheta*cosHalfTheta);if(Math.abs(sinHalfTheta)<.001){dest[0]=quat[0]*.5+quat2[0]*.5;dest[1]=quat[1]*.5+quat2[1]*.5;dest[2]=quat[2]*.5+quat2[2]*.5;dest[3]=quat[3]*.5+quat2[3]*.5;return dest}var ratioA=Math.sin((1-slerp)*halfTheta)/sinHalfTheta;var ratioB=Math.sin(slerp*halfTheta)/sinHalfTheta;dest[0]=quat[0]*ratioA+quat2[0]*ratioB;dest[1]=quat[1]*ratioA+quat2[1]*ratioB;dest[2]=quat[2]*ratioA+quat2[2]*ratioB;dest[3]=quat[3]*ratioA+quat2[3]*ratioB;return dest};quat4.str=function(quat){return"["+quat[0]+", "+quat[1]+", "+quat[2]+", "+quat[3]+"]"};WebGLUtils=function(){var makeFailHTML=function(msg){return""+''+'
'+'
'+'
'+msg+"
"+"
"+"
"};var GET_A_WEBGL_BROWSER=""+"This page requires a browser that supports WebGL.
"+'Click here to upgrade your browser.';var OTHER_PROBLEM=""+"It doesn't appear your computer can support WebGL.
"+'Click here for more information.';var setupWebGL=function(canvas,opt_attribs){function showLink(str){var container=canvas.parentNode;if(container){container.innerHTML=makeFailHTML(str)}}if(!window.WebGLRenderingContext){showLink(GET_A_WEBGL_BROWSER);return null}var context=create3DContext(canvas,opt_attribs);if(!context){showLink(OTHER_PROBLEM)}return context};var create3DContext=function(canvas,opt_attribs){var names=["webgl","experimental-webgl","webkit-3d","moz-webgl"];var context=null;for(var ii=0;ii1e-6){var rotaxis,newup;if(Math.abs(angle-Math.PI)<1e-6)newup=parent.__up.multiply(-1);else{rotaxis=cross(oldaxis,newaxis);newup=parent.__up.rotate({angle:angle,axis:rotaxis})}parent.__up.__x=newup.x;parent.__up.__y=newup.y;parent.__up.__z=newup.z}}function adjust_axis(parent,oldup,newup){parent.__change();if(newup.mag2===0){if(parent.__oldup===undefined)parent.__oldup=oldup}if(parent.__oldup!==undefined){oldup=parent.__oldup;parent.__oldup=undefined}if(newup.dot(parent.__axis)===0)return;var angle=oldup.diff_angle(newup);if(angle>1e-6){var rotaxis,newaxis;if(Math.abs(angle-Math.PI)<1e-6)newaxis=parent.__axis.multiply(-1);else{rotaxis=cross(oldup,newup);newaxis=parent.__axis.rotate({angle:angle,axis:rotaxis})}parent.__axis.__x=newaxis.x;parent.__axis.__y=newaxis.y;parent.__axis.__z=newaxis.z}}function vec(x,y,z){if(!(this instanceof vec)){if(y===undefined)if(z===undefined)return new vec(x.x,x.y,x.z);return new vec(x,y,z)}if(z===undefined||y===undefined)throw new Error("vector() requires 3 arguments: x, y, and z.");this.x=x;this.y=y;this.z=z}function attributeVector(parent,x,y,z){this.__parent=parent;this.__x=x;this.__y=y;this.__z=z;if(parent){parent.__change()}}attributeVector.prototype=new vec(0,0,0);attributeVector.prototype.constructor=attributeVector;function attributeVectorPos(parent,x,y,z){this.__parent=parent;this.__x=x;this.__y=y;this.__z=z;if(parent){parent.__change();parent._pos_set=true;if(parent.__make_trail)parent.__update_trail(vec(x,y,z))}}attributeVectorPos.prototype=new vec(0,0,0);attributeVectorPos.prototype.constructor=attributeVectorPos;function attributeVectorAxis(parent,x,y,z){var oldaxis;this.__parent=parent;if(parent)oldaxis=norm(parent.__axis);this.__x=x;this.__y=y;this.__z=z;if(parent){if(parent.__sizing)parent.__size.__x=Math.sqrt(x*x+y*y+z*z);if(window.__adjustupaxis)adjust_up(parent,oldaxis,this);parent.__change()}}attributeVectorAxis.prototype=new vec(1,0,0);attributeVectorAxis.prototype.constructor=attributeVectorAxis;function attributeVectorSize(parent,x,y,z){this.__parent=parent;this.__x=x;this.__y=y;this.__z=z;if(parent){if(parent.__sizing){var v=parent.__axis.norm().multiply(x);parent.__axis.__x=v.x;parent.__axis.__y=v.y;parent.__axis.__z=v.z}parent.__change()}}attributeVectorSize.prototype=new vec(1,1,1);attributeVectorSize.prototype.constructor=attributeVectorSize;function attributeVectorUp(parent,x,y,z){var oldup;this.__parent=parent;if(parent)oldup=norm(parent.__up);this.__x=x;this.__y=y;this.__z=z;if(parent){if(window.__adjustupaxis)adjust_axis(parent,oldup,this);parent.__change()}}attributeVectorUp.prototype=new vec(0,1,0);attributeVectorUp.prototype.constructor=attributeVectorUp;Object.defineProperty(attributeVector.prototype,"__x",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVector.prototype,"x",{enumerable:true,get:function(){return this.__x},set:function(value){this.__x=value;this.__parent.__change()}});Object.defineProperty(attributeVector.prototype,"__y",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVector.prototype,"y",{enumerable:true,get:function(){return this.__y},set:function(value){this.__y=value;this.__parent.__change()}});Object.defineProperty(attributeVector.prototype,"__z",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVector.prototype,"z",{enumerable:true,get:function(){return this.__z},set:function(value){this.__z=value;this.__parent.__change()}});Object.defineProperty(attributeVectorPos.prototype,"__x",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVectorPos.prototype,"x",{enumerable:true,get:function(){return this.__x},set:function(value){this.__x=value;this.__parent.__change();this.__parent._pos_set=true;if(this.__parent.__make_trail)this.__parent.__update_trail(vec(this.__x,this.__y,this.__z))}});Object.defineProperty(attributeVectorPos.prototype,"__y",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVectorPos.prototype,"y",{enumerable:true,get:function(){return this.__y},set:function(value){this.__y=value;this.__parent.__change();this.__parent._pos_set=true;if(this.__parent.__make_trail)this.__parent.__update_trail(vec(this.__x,this.__y,this.__z))}});Object.defineProperty(attributeVectorPos.prototype,"__z",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVectorPos.prototype,"z",{enumerable:true,get:function(){return this.__z},set:function(value){this.__z=value;this.__parent.__change();this.__parent._pos_set=true;if(this.__parent.__make_trail)this.__parent.__update_trail(vec(this.__x,this.__y,this.__z))}});Object.defineProperty(attributeVectorAxis.prototype,"__x",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVectorAxis.prototype,"x",{enumerable:true,get:function(){return this.__x},set:function(value){var oldaxis=norm(this.__parent.__axis);this.__x=value;if(this.__parent.__sizing)this.__parent.__size.x=this.mag;adjust_up(this.__parent,oldaxis,this)}});Object.defineProperty(attributeVectorAxis.prototype,"__y",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVectorAxis.prototype,"y",{enumerable:true,get:function(){return this.__y},set:function(value){var oldaxis=norm(this.__parent.__axis);this.__y=value;if(this.__parent.__sizing)this.__parent.__size.x=this.mag;adjust_up(this.__parent,oldaxis,this)}});Object.defineProperty(attributeVectorAxis.prototype,"__z",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVectorAxis.prototype,"z",{enumerable:true,get:function(){return this.__z},set:function(value){var oldaxis=norm(this.__parent.__axis);this.__z=value;if(this.__parent.__sizing)this.__parent.__size.x=this.mag;adjust_up(this.__parent,oldaxis,this)}});Object.defineProperty(attributeVectorSize.prototype,"__x",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVectorSize.prototype,"x",{enumerable:true,get:function(){return this.__x},set:function(value){this.__x=value;if(this.__parent.__sizing){var v=this.__parent.__axis.norm().multiply(value);this.__parent.__axis.__x=v.x;this.__parent.__axis.__y=v.y;this.__parent.__axis.__z=v.z}this.__parent.__change()}});Object.defineProperty(attributeVectorSize.prototype,"__y",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVectorSize.prototype,"y",{enumerable:true,get:function(){return this.__y},set:function(value){this.__y=value;this.__parent.__change()}});Object.defineProperty(attributeVectorSize.prototype,"__z",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVectorSize.prototype,"z",{enumerable:true,get:function(){return this.__z},set:function(value){this.__z=value;this.__parent.__change()}});Object.defineProperty(attributeVectorUp.prototype,"__x",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVectorUp.prototype,"x",{enumerable:true,get:function(){return this.__x},set:function(value){var oldup=norm(this.__parent.__up);this.__x=value;adjust_axis(parent,oldup,this)}});Object.defineProperty(attributeVectorUp.prototype,"__y",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVectorUp.prototype,"y",{enumerable:true,get:function(){return this.__y},set:function(value){var oldup=norm(this.__parent.__up);this.__y=value;adjust_axis(parent,oldup,this)}});Object.defineProperty(attributeVectorUp.prototype,"__z",{enumerable:false,writable:true,value:0});Object.defineProperty(attributeVectorUp.prototype,"z",{enumerable:true,get:function(){return this.__z},set:function(value){var oldup=norm(this.__parent.__up);this.__z=value;adjust_axis(parent,oldup,this)}});vec.prototype.toString=function(){var input=[this.x,this.y,this.z];var output=[];for(var i=0;i<3;i++){output.push(__convert(input[i]))}return"< "+output[0]+", "+output[1]+", "+output[2]+" >"};vec.prototype.add=function(v){return new vec(this.x+v.x,this.y+v.y,this.z+v.z)};vec.prototype.sub=function(v){return new vec(this.x-v.x,this.y-v.y,this.z-v.z)};vec.prototype.multiply=function(r){return new vec(this.x*r,this.y*r,this.z*r)};vec.prototype.divide=function(r){return new vec(this.x/r,this.y/r,this.z/r)};property.declare(vec.prototype,{mag:{get:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},set:function(value){var v=this.norm().multiply(value);this.x=v.x;this.y=v.y;this.z=v.z}},mag2:{get:function(){return this.x*this.x+this.y*this.y+this.z*this.z},set:function(value){var v=this.norm().multiply(Math.sqrt(value));this.x=v.x;this.y=v.y;this.z=v.z}},hat:{get:function(){return this.norm()},set:function(value){var v=value.hat.multiply(this.mag);this.x=v.x;this.y=v.y;this.z=v.z}}});vec.prototype.norm=function(){var r=this.mag;if(r==0)return new vec(0,0,0);return new vec(this.x/r,this.y/r,this.z/r)};vec.prototype.dot=function(v){return this.x*v.x+this.y*v.y+this.z*v.z};vec.prototype.equals=function(v){if(v===null)return false;return this.x===v.x&&this.y===v.y&&this.z===v.z};vec.prototype.proj=function(v){var B=norm(v);return B.multiply(this.dot(B))};vec.prototype.comp=function(v){return this.dot(norm(v))};vec.prototype.cross=function(v){return new vec(this.y*v.z-this.z*v.y,this.z*v.x-this.x*v.z,this.x*v.y-this.y*v.x)};vec.prototype.diff_angle=function(v){var a=this.norm().dot(v.norm());if(a>1)return 0;if(a<-1)return Math.PI;return Math.acos(a)};vec.prototype.rotate=function(args){var angle,axis;if(arguments.length==1){if(args!==null&&args!==undefined){if(typeof args==="number"){angle=args}else{angle=args.angle;axis=args.axis}}}else if(arguments.length==2){angle=arguments[0];axis=arguments[1]}if(angle===undefined)throw new Error("To rotate a vector you must specify an angle.");if(axis===undefined)axis=new vec(0,0,1);if(angle===0)return new vec(this.x,this.y,this.z);var axis=axis.norm();var parallel=axis.multiply(axis.dot(this));var perp=axis.cross(this);var pmag=perp.mag;perp=perp.norm();var y=perp.cross(axis);var rotated=y.multiply(pmag*Math.cos(angle)).add(perp.multiply(pmag*Math.sin(angle)));return parallel.add(rotated)};vec.random=function(){return new vec(-1+2*Math.random(),-1+2*Math.random(),-1+2*Math.random())};var exports={vec:vec,attributeVector:attributeVector,attributeVectorPos:attributeVectorPos,attributeVectorAxis:attributeVectorAxis,attributeVectorSize:attributeVectorSize,attributeVectorUp:attributeVectorUp};Export(exports)})();(function vectorLibraryWrappers(){"use strict";function mag(A){return A.mag}function mag2(A){return A.mag2}function norm(A){return A.norm()}function hat(A){return A.hat}function dot(A,B){return A.dot(B)}function cross(A,B){return A.cross(B)}function proj(A,B){return A.proj(B)}function comp(A,B){return A.comp(B)}function diff_angle(A,B){return A.diff_angle(B)}function rotate(args){var angle,axis;var v=arguments[0];if(arguments.length==2){var args=arguments[1];if(args!==null&&args!==undefined){if(typeof args==="number"){angle=args}else{angle=args.angle;axis=args.axis}}}else if(arguments.length==3){angle=arguments[1];axis=arguments[2]}if(angle===undefined)throw new Error("To rotate a vector you must specify an angle.");if(axis===undefined)axis=new vec(0,0,1);return v.rotate({angle:angle,axis:axis})}function GS_power(x,n){if(x instanceof vec)throw new Error("Cannot raise a vector to a power.");return Math.pow(x,n)}var exports={mag:mag,mag2:mag2,norm:norm,hat:hat,dot:dot,cross:cross,proj:proj,comp:comp,diff_angle:diff_angle,rotate:rotate,GS_power:GS_power};Export(exports)})();(function(){"use strict";function Mesh(){this.pos=[];this.normal=[];this.color=[];this.opacity=[];this.shininess=[];this.emissive=[];this.texpos=[];this.bumpaxis=[];this.index=[];this.model_transparent=false}$.extend(Mesh.prototype,{merge:function merge(otherMesh,object,bias){var xmin=null,xmax=null,ymin=null,ymax=null,zmin=null,zmax=null;var offset=this.pos.length/3;if(object instanceof vertex){if(offset+1>=65536)return null;if(bias<0)this.index.push(offset+bias);else{if(xmin===null||object.__pos.xxmax)xmax=object.__pos.x;if(ymin===null||object.__pos.yymax)ymax=object.__pos.y;if(zmin===null||object.__pos.zzmax)zmax=object.__pos.z;this.pos.push(object.__pos.x,object.__pos.y,object.__pos.z);this.normal.push(object.__normal.x,object.__normal.y,object.__normal.z);this.color.push(object.__color.x,object.__color.y,object.__color.z);if(object.__opacity<1)this.model_transparent=true;this.opacity.push(object.__opacity);this.shininess.push(object.__shininess);this.emissive.push(object.__emissive);this.texpos.push(object.__texpos.x,object.__texpos.y);this.bumpaxis.push(object.__bumpaxis.x,object.__bumpaxis.y,object.__bumpaxis.z);this.index.push(offset)}}else{if(offset+otherMesh.pos.length/3>=65536)return null;var c=[object.__color.x,object.__color.y,object.__color.z];for(var j=0;jxmax)xmax=otherMesh.pos[j]}else if(j%3===1){if(ymin===null||otherMesh.pos[j]ymax)ymax=otherMesh.pos[j]}else if(j%3===2){if(zmin===null||otherMesh.pos[j]zmax)zmax=otherMesh.pos[j]}this.pos.push(otherMesh.pos[j])}for(var j=0;j=Nlong)break;s=i*offset;if(j","?",")","!","@","#","$","%","^","&","*","(",":",":","<","=",">","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","{","|","}","^","_","~","","","","","","","","","","*","+","","","","","f1","f2","f3","f4","f5","f6","f7","f8","f9","f10","","{","|","}","~","delete"];_shifted[187]="+";_shifted[189]="_";_shifted[192]="~";_shifted[219]="{";_shifted[220]="|";_shifted[221]="}";_shifted[186]=":";_shifted[222]='"';_shifted[188]="<";_shifted[190]=">";_shifted[191]="?";var shiftlock=false;var __waitfor;var __waitfor_canvas;var __waitfor__expecting_key;$.fn.extend({gsmenubar:function(cmd){if(!this.is("ul")){alert("MenuBar top level must be unordered list, i.e.
    .");return}this.addClass("gsmenubar");this.children("li").children("ul").each(function(){$(this).menu()})}});$.fn.waitfor=function(eventTypes,callback){var self=this;function cb(ev){self.unbind(eventTypes,cb);__waitfor="";__waitfor_canvas.__expecting_key=__waitfor__expecting_key;callback(null,ev)}this.bind(eventTypes,cb)};$.fn.pause=function(prompt,callback){var self=this;function cb(ev){prompt.visible=false;self.unbind("click",cb);__waitfor="";__waitfor_canvas.__expecting_key=__waitfor__expecting_key;callback(null,ev)}this.bind("click",cb)};window.print_anchor=$("
    ").css("white-space","pre").appendTo($("body"));window.print_anchor.css({float:"left"});var __id=0;function canvas(options){if(!(this instanceof canvas))return new canvas(options);if(!options)options={};canvas.activated=[];canvas.selected=this;canvas.hasmouse=null;this.__title_anchor=$("
    ");this.__caption_anchor=$("
    ");this.__titletext="";this.__captiontext="";if("title"in options){this.__titletext=options.title;delete options.title}if("caption"in options){this.__captiontext=options.caption;delete options.caption}this.__align="none";if("align"in options){this.__align=options.align;delete options.align}this.__lastevent=null;this.__autoscale=true;if("autoscale"in options){this.__autoscale=options.autoscale;delete options.autoscale}this.__range=10;if("width"in options){this.__width=options.width;delete options.width}if("height"in options){this.__height=options.height;delete options.height}for(var id in options)this[id]=options[id];this.hasmouse=false;this.__needs_update=false;this.events=$("
    ");this.wrapper=$("
    ");this.menu=$("
    ");this.__canvas_element=document.createElement("canvas");this.__overlay_element=document.createElement("canvas");this.elements=$([this.__canvas_element,this.__overlay_element]);this.__overlay_objects={objects:[],__changed:false};this.__visiblePrimitives={};this.lights=[];distant_light({direction:vec(.22,.44,.88),color:vec(.8,.8,.8)});distant_light({direction:vec(-.88,-.22,-.44),color:vec(.3,.3,.3)});this.trails=[];this.arrows=[];this.billboards=[];this.update_billboards=false;this.__points_objects=[];this.__opaque_objects={};this.__transparent_objects={};this.vertex_id=1;var N=100;this.__vertices={Nalloc:N,pos:new Float32Array(3*N),normal:new Float32Array(3*N),color:new Float32Array(3*N),opacity:new Float32Array(N),shininess:new Float32Array(N),emissive:new Float32Array(N),texpos:new Float32Array(2*N),bumpaxis:new Float32Array(3*N),index:new Uint16Array(N),model_transparent:false,object_info:{},available:[]};this.__vertices.normal[2]=1;this.__sort_objects={opaque:{plain:{},textures:{},bumpmaps:{},textures_and_bumpmaps:{}},transparent:{plain:{},textures:{},bumpmaps:{},textures_and_bumpmaps:{}}};this.camera=orbital_camera(this);this.mouse=new Mouse(this);this.mouse.pos=vec(0,0,0);this.mouse.ray=vec(0,0,1);this.textures={};this.textures_requested={};this.__changed={};this.__vertex_changed={};this.visible=true;this.waitfor_textures=false;__waitfor="";this.__expecting_key=false;this.center=this.center;this.forward=this.forward;this.up=this.up}property.declare(canvas.prototype,{__activate:function(){this.__activated=true;this.__activate=function(){};this.__id=__id;__id++;var container=canvas.container;this.__title_anchor.css("white-space","pre").appendTo(container);this.menu.css("white-space","pre").appendTo(container);this.wrapper.addClass("glowscript-canvas-wrapper").css("display","inline-block").appendTo(container);this.__caption_anchor.css("white-space","pre").appendTo(container);this.wrapper.css("position","relative");var cv=this.__canvas_element;cv.style.position="absolute";var overlay=this.__overlay_element;overlay.style.position="relative";overlay.style.backgroundColor="transparent";this.width=this.__width;this.height=this.__height;this.wrapper.append(this.__canvas_element);this.wrapper.append(this.__overlay_element);this.wrapper.resizable({alsoResize:[this.__canvas_element,this.__overlay_element],resize:function(ev,ui){this.__canvas_element.width=this.__canvas_element.style.width=this.__overlay_element.width=this.__overlay_element.style.width=this.__width=ui.size.width;this.__canvas_element.height=this.__canvas_element.style.height=this.__overlay_element.height=this.__overlay_element.style.height=this.__height=ui.size.height;this.trigger("resize",{event:"resize"})}.bind(this)});if(!this.resizable)this.wrapper.resizable("disable");this.wrapper.css("float",this.__align);if(this.camera.__activate)this.camera.__activate();this.__handleEvents();if(this.__titletext)this.title=this.__titletext;if(this.__captiontext)this.caption=this.__captiontext;this.__renderer=new WebGLRenderer(this,cv,overlay);canvas.activated.push(this)},remove:function(){for(var id in this.__visiblePrimitives)this.__visiblePrimitives[id].visible=false;for(var id in this.__overlay_objects.objects)this.__overlay_objects.objects[id].visible=false;if(this.__activated)canvas.activated[this.__id]=null;this.wrapper.remove()},__handleEvents:function(){var canvas=this;var elements=canvas.elements;elements.bind("mouseenter mouseleave",function(ev){canvas.trigger("mouse",ev)});var keys={shift:16,ctrl:17,alt:18};$(document).bind("keydown keyup",function(ev){for(var k in keys){if(keys[k]==ev.which){canvas.mouse[k]=ev.type=="keydown";break}}if(!canvas.__expecting_key)return;ev.event=ev.type;if(ev.which==20&&ev.type=="keydown")shiftlock=!shiftlock;ev.shift=canvas.mouse.shift||shiftlock;ev.key=_unshifted[ev.which];if(shiftlock&&(65<=ev.which&&ev.which<=90))ev.key=_shifted[ev.which];else if(canvas.mouse.shift)ev.key=_shifted[ev.which];ev.alt=canvas.mouse.alt;ev.ctrl=canvas.mouse.ctrl;canvas.trigger(ev.type,ev)})},waitfor:function(eventTypes,callback){__waitfor_canvas=this;__waitfor__expecting_key=this.__expecting_key;if(eventTypes.search("key")>=0){__waitfor=eventTypes;this.__expecting_key=true}else{__waitfor="";this.__expecting_key=false}if(eventTypes=="textures")this.waitfor_textures=true;return this.events.waitfor(eventTypes,callback)},pause:function(args){__waitfor_canvas=this;__waitfor__expecting_key=this.__expecting_key;__waitfor="";var prompt="",callback;if(arguments.length==1)callback=arguments[0];else{prompt=arguments[0];callback=arguments[1]}if(prompt.length>0){if(this.__prompt==undefined){this.__prompt=label({canvas:this,align:"right",pixel_pos:true,height:14,color:color.black,background:color.white,opacity:1,box:false})}this.__prompt.pos=vec(this.__width,this.__height-12,0);this.__prompt.text=prompt;this.__prompt.visible=true;this.events.pause(this.__prompt,callback)}else{if(this.__draw==undefined)this.__draw=draw({canvas:this});var x=this.width-5,y=this.height-20;this.__draw.points=[vec(x,y,0),vec(x-30,y-13,0),vec(x-30,y+15,0),vec(x,y,0)];this.__draw.opacity=1;this.__draw.color=color.black;this.__draw.fillcolor=color.white;this.__draw.visible=true;this.events.pause(this.__draw,callback)}},select:function(){window.__context.canvas_selected=this},title_anchor:{get:function(){if(!this.__activated)this.__activate();return this.__title_anchor},set:function(value){throw new Error("Cannot change title_anchor")}},caption_anchor:{get:function(){if(!this.__activated)this.__activate();return this.__caption_anchor},set:function(value){throw new Error("Cannot change caption_anchor")}},title:{get:function(){return this.__titletext},set:function(value){this.__titletext=value;this.__title_anchor.html(value)}},caption:{get:function(){return this.__captiontext},set:function(value){this.__captiontext=value;this.__caption_anchor.html(value)}},append_to_title:function(args){var s="";var L=arguments.length;for(var i=0;i=0)this.__expecting_key=true;return this.events.bind(eventTypes,callback)},unbind:function(eventTypes,callback){if(eventTypes.search("key")>=0)this.__expecting_key=false;return this.events.unbind(eventTypes,callback)},one:function(eventTypes,callback){return this.events.one(eventTypes,callback)},trigger:function(type,ev){if(ev===undefined)ev={type:type,event:event};if(type=="mouse"){type=ev.type;var ev={type:type,pageX:ev.pageX,pageY:ev.pageY,which:1};this.mouse.__update(ev);ev.event=ev.type;ev.pos=this.mouse.pos;if(ev.type=="mousedown"){ev.press="left";ev.release=null}else if(ev.type=="mousemove"){ev.press=null;ev.release=null}else if(ev.type=="mouseup"){ev.press=null;ev.release="left"}else if(ev.type=="mouseenter"||ev.type=="mouseleave"){ev.press=null;ev.release=null}else if(ev.type=="click"){ev.press=null;ev.release="left"}}if(ev!==null)ev.canvas=this;var nev=new $.Event(type,ev);this.events.trigger(nev)},background:new vec(0,0,0),opacity:1,ambient:new vec(.2,.2,.2),__change:function(){if(this.__lastevent!==null&&this.hasmouse)this.mouse.__update(this.__lastevent)},center:new attributeVector(null,0,0,0),forward:new attributeVector(null,0,0,-1),up:new attributeVector(null,0,1,0),__last_forward:null,__last_center:null,__activated:false,userzoom:true,userspin:true,userpan:true,fov:60*Math.PI/180,width:{value:640,onchanged:function(){this.__canvas_element.width=this.__canvas_element.style.width=this.__overlay_element.width=this.__overlay_element.style.width=this.__width}},height:{value:400,onchanged:function(){this.__canvas_element.height=this.__canvas_element.style.height=this.__overlay_element.height=this.__overlay_element.style.height=this.wrapper[0].style.height=this.__height}},align:{get:function(){return this.__align},set:function(value){if(value=="left"||value=="right"||value=="none"){this.__align=value}else throw new Error("align must be 'left', 'right', or 'none' (the default).")}},resizable:{value:true,onchanged:function(){if(this.__activated){this.wrapper.resizable((this.resizable?"en":"dis")+"able")}}},autoscale:{get:function(){return this.__autoscale},set:function(value){if(this.__autoscale&&!value)Autoscale.compute_autoscale(this);this.__autoscale=value}},range:{get:function(){if(this.__autoscale){Autoscale.compute_autoscale(this)}return this.__range},set:function(value){this.__autoscale=false;this.__range=value;if(this.__lastevent!==null)this.mouse.__update(this.__lastevent)}},pixel_to_world:{get:function(){var w=this.__width;var h=this.__height;var d=2*this.range;if(w>=h){return d/h}else{return d/w}},set:function(value){throw new Error("Cannot assign a value to pixel_to_world.")}},objects:{get:function(){var all=[];for(var id in this.__visiblePrimitives){var v=this.__visiblePrimitives[id];if(v.__obj){if(v==v.__obj.__components[0]&&v.__obj.visible)all.push(v.__obj)}else all.push(v)}for(var id in this.__overlay_objects.objects){var obj=this.__overlay_objects.objects[id];if(obj instanceof label)all.push(obj)}return all}}});property.declare(canvas,{selected:{get:function(){return window.__context.canvas_selected||null},set:function(value){window.__context.canvas_selected=value}},get_selected:function(){return window.__context.canvas_selected||null},all:{get:function(){var v=window.__context.canvas_all;if(v===undefined)v=window.__context.canvas_all=[];return v}},container:{get:function(){return window.__context.glowscript_container||null},set:function(value){window.__context.glowscript_container=$(value)}}});function Mouse(canvas){this.canvas=canvas}property.declare(Mouse.prototype,{canvas:null,pos:null,ray:null,__pickx:null,__picky:null,pick:function(){return this.canvas.__renderer.render(1)},project:function(args){if(args.normal===undefined)throw new Error("scene.mouse.project() must specify a normal");var normal=args.normal;var dist;if(args.d===undefined&&args.point===undefined)dist=normal.dot(this.canvas.__center);else if(args.d!==undefined){dist=args.d}else if(args.point!==undefined){dist=normal.dot(args.point)}var ndc=normal.dot(this.canvas.camera.pos)-dist;var ndr=normal.dot(this.ray);if(ndr==0)return null;var t=-ndc/ndr;return this.canvas.camera.pos.add(this.ray.multiply(t))},alt:false,ctrl:false,shift:false,__update:function(ev){var cv=this.canvas,factor;if(cv.__width>cv.__height)factor=2*cv.__range/cv.__height;else factor=2*cv.__range/cv.__width;var o=$(cv.__canvas_element).offset();this.__pickx=ev.pageX-o.left;this.__picky=cv.__height-(ev.pageY-o.top);var mx=(this.__pickx-cv.__width/2)*factor;var my=(this.__picky-cv.__height/2)*factor;var xaxis=cv.__forward.norm().cross(cv.__up).norm();var yaxis=xaxis.cross(cv.__forward.norm());this.pos=cv.__center.add(xaxis.multiply(mx).add(yaxis.multiply(my)));this.ray=this.pos.sub(cv.camera.pos).norm();canvas.hasmouse=cv;cv.__lastevent=ev}});var exports={canvas:canvas};Export(exports)})();(function(){"use strict";function orbital_camera(canvas,args){if(!(this instanceof orbital_camera))return new orbital_camera(canvas,args);this.canvas=canvas;this.follower=null}property.declare(orbital_camera.prototype,{pos:{get:function(){var c=this.canvas;return c.center.sub(c.forward.norm().multiply(c.range/Math.tan(c.fov/2)))},set:function(val){var c=this.canvas;c.center=val.add(this.axis)}},axis:{get:function(){var c=this.canvas;return c.forward.norm().multiply(c.range/Math.tan(c.fov/2))},set:function(val){var c=this.canvas;c.center=this.pos.add(val);c.forward=norm(val);c.range=mag(val)*Math.tan(c.fov/2)}},rotate:function(args){if(args===undefined||args.angle===undefined){throw new Error("object.rotate() requires an angle")}var angle=args.angle;var rotaxis,origin;if(args.axis===undefined){rotaxis=this.axis.norm()}else rotaxis=args.axis.norm();if(args.origin===undefined){origin=this.pos}else origin=args.origin;this.pos=origin.add(this.pos.sub(origin).rotate({angle:angle,axis:rotaxis}));this.axis=this.axis.rotate({angle:angle,axis:rotaxis})},follow:function(objectOrFunction){this.follower=objectOrFunction},__activate:function(){var canvas=this.canvas;var camera=this;var contextMenuDisabled=false;var lastX=[null,null],lastY=[null,null];var downX=[null,null],downY=[null,null];var lastpos=null;var angleX=0,angleY=0;var afterdown=false;var rotating,zrotating,zooming,panning;var leftButton=false,rightButton=false,mouseWheel=false;var lastSep=null;var lastAngle=null;var fingers=0;var nomove=false;var tstart;var zoompos=[null,null];var saveEvent;var zoom=function(delta){var z=Math.exp(-delta*.05);canvas.range=canvas.range*z};var zrotate=function(dtheta){canvas.up=canvas.up.rotate({angle:2*dtheta,axis:canvas.__forward})};var spin=function(ev){var dx=ev.pageX-lastX[0];var dy=ev.pageY-lastY[0];angleX+=dx*.01;angleY+=dy*.01;if(angleY<-1.4)angleY=-1.4;if(angleY>1.4)angleY=1.4;canvas.__forward=canvas.__forward.rotate({angle:-.01*dx,axis:canvas.up});var max_vertical_angle=canvas.up.diff_angle(canvas.__forward.multiply(-1));var vertical_angle=.01*dy;if(!(vertical_angle>=max_vertical_angle||vertical_angle<=max_vertical_angle-Math.PI)){canvas.__forward=canvas.__forward.rotate({angle:-vertical_angle,axis:canvas.__forward.cross(canvas.__up)})}};var pan=function(ev){var csave=vec(canvas.__last_center);canvas.mouse.__update(ev);var c=canvas.mouse.pos;var xaxis=canvas.__forward.cross(canvas.__up).hat;var yaxis=xaxis.cross(canvas.__forward).hat;var d=c.sub(lastpos);var dx=d.dot(xaxis);var dy=d.dot(yaxis);lastpos=c.sub(d);canvas.__center=canvas.__center.sub(xaxis.multiply(dx).add(yaxis.multiply(dy)));canvas.__last_center=csave};$(document).bind("contextmenu",function(e){return!contextMenuDisabled});canvas.elements.mousewheel(function(ev,delta){if(canvas.userzoom)zoom(delta);return false});canvas.elements.mousedown(function(ev){if(ev.which==1)leftButton=true;if(ev.which==3)rightButton=true;rotating=canvas.userspin&&(ev.which==3||ev.which==1&&canvas.mouse.ctrl&&!canvas.mouse.alt);zooming=canvas.userzoom&&(ev.which==2||ev.which==1&&canvas.mouse.alt&&!canvas.mouse.ctrl||leftButton&&rightButton);panning=canvas.userpan&&ev.which==1&&canvas.mouse.shift;if(ev.which==3&&!(rotating||zooming))return;downX[0]=lastX[0]=ev.pageX;downY[0]=lastY[0]=ev.pageY;if(rotating||zooming||panning)contextMenuDisabled=true;else if(ev.which==1)canvas.trigger("mouse",ev);if(panning){canvas.autoscale=false;canvas.mouse.__update(ev);lastpos=canvas.mouse.pos}afterdown=true;ev.preventDefault();ev.stopPropagation();return false});canvas.elements.mousemove(function(ev){if(ev.pageX===lastX[0]&&ev.pageY===lastY[0])return;if(!afterdown){canvas.mouse.__update(ev);return}if(zooming){var dy=lastY[0]-ev.pageY;if(dy!==0)zoom(.1*dy)}else if(rotating){spin(ev)}else if(panning){pan(ev)}else if(ev.which==1)canvas.trigger("mouse",ev);if(!panning){lastX[0]=ev.pageX;lastY[0]=ev.pageY}});canvas.elements.mouseup(function(ev){if(ev.which==1)leftButton=false;if(ev.which==3)rightButton=false;if(!afterdown)return;if(ev.which==3&&contextMenuDisabled)setTimeout(function(){contextMenuDisabled=false},0);if(!(rotating||zooming||panning)){if(ev.which==1){canvas.trigger("mouse",ev);if(abs(ev.pageX-downX[0])<=5&&abs(ev.pageY-downY[0])<=5){ev.type="click";canvas.trigger("mouse",ev)}}else if(ev.which==3){contextMenuDisabled=true;return}}rotating=zooming=panning=afterdown=false;lastX=[null,null];lastY=[null,null]});canvas.elements.bind("touchstart",function(ev){rotating=zooming=nomove=false;lastSep=lastAngle=null;var pt;var data=ev.originalEvent.targetTouches;if(data.length>2)return;if(data.length==2&&!(canvas.userspin||canvas.userzoom))return;fingers++;for(var i=0;i2)return;var pt;var newx=[null,null],newy=[null,null];var relx=[0,0],rely=[0,0];for(var i=0;i15||dzoom[1].mag>15){saveEvent=null;zooming=true;var r=zoompos[1].sub(zoompos[0]).norm();var angmom=r.cross(dzoom[1]).sub(r.cross(dzoom[0])).mag;if(angmom>10){zrotating=canvas.userspin;if(!canvas.userspin)zooming=false}}else return}}if(saveEvent!==null){if(data.length==2){saveEvent=null}else{var near=relx[0]<=5&&rely[0]<=5;if(!rotating&&t>150&&near){canvas.trigger("mouse",saveEvent);saveEvent=null}else if(!near){rotating=canvas.userspin;saveEvent=null}}}else{if(newx[0]===lastX[0]&&newy[0]===lastY[0]&&newx[1]===lastX[1]&&newy[1]===lastY[1])return;ev.pageX=newx[0];ev.pageY=newy[0];ev.type="mousemove";if(rotating)spin(ev);else if(zooming){var xx=newx[1]-newx[0];var yy=newy[1]-newy[0];if(zrotating){var angle=Math.atan2(yy,xx);if(lastAngle!==null){var dangle;var va=vec(Math.cos(lastAngle),Math.sin(lastAngle),0);var vb=vec(Math.cos(angle),Math.sin(angle),0);var vc=va.cross(vb);var amag=Math.abs(Math.asin(vc.mag));if(vc.z>=0)dangle=-amag;else dangle=amag;zrotate(dangle)}lastAngle=angle}else if(canvas.userzoom){var sep=Math.sqrt(xx*xx+yy*yy);if(lastSep!==null&&sep!=lastSep)zoom(.2*(sep-lastSep));lastSep=sep}}else canvas.trigger("mouse",ev)}lastX[0]=newx[0];lastX[1]=newx[1];lastY[0]=newy[0];lastY[1]=newy[1]});canvas.elements.bind("touchend",function(ev){fingers--;if(saveEvent!==null&&!(rotating||zooming)){canvas.trigger("mouse",saveEvent);saveEvent=null}var data=ev.originalEvent.changedTouches;ev.pageX=data[0].clientX;ev.pageY=data[0].clientY;if(!(rotating||zooming)){ev.type="mouseup";canvas.trigger("mouse",ev);if(abs(ev.pageX-downX[0])<=5&&abs(ev.pageY-downY[0])<=5){ev.type="click";canvas.trigger("mouse",ev)}}if(zooming){if(fingers>0)nomove=true;else zooming=nomove=false}rotating=false;lastX=[null,null];lastY=[null,null];lastSep=lastAngle=null})}});var exports={orbital_camera:orbital_camera};Export(exports)})();(function(){"use strict";function extent(){}$.extend(extent.prototype,{xmin:null,ymin:null,zmin:null,xmax:null,ymax:null,zmax:null,zx_camera:0,zy_camera:0,last_zx_camera:-1,last_zy_camera:-1,point_extent:function(obj,p){this.xmin=Math.min(p.x,this.xmin);this.ymin=Math.min(p.y,this.ymin);this.zmin=Math.min(p.z,this.zmin);this.xmax=Math.max(p.x,this.xmax);this.ymax=Math.max(p.y,this.ymax);this.zmax=Math.max(p.z,this.zmax);obj.__xmin=Math.min(p.x,obj.__xmin);obj.__ymin=Math.min(p.y,obj.__ymin);obj.__zmin=Math.min(p.z,obj.__zmin);obj.__xmax=Math.max(p.x,obj.__xmax);obj.__ymax=Math.max(p.y,obj.__ymax);obj.__zmax=Math.max(p.z,obj.__zmax)}});var exports={Autoscale:{compute_autoscale:function compute_autoscale(canvas){var ext=canvas.__extent;if(!ext)ext=canvas.__extent=new extent;var ctrx=canvas.center.x,ctry=canvas.center.y,ctrz=canvas.center.z;var all=canvas.__visiblePrimitives;ext.zx_camera=0;ext.zy_camera=0;var cot_hfov=1/Math.tan(canvas.__fov/2);ext.__cot_hfov=cot_hfov;ext.__centerx=canvas.center.x;ext.__centery=canvas.center.y;ext.__centerz=canvas.center.z;var check=false;var obj;for(var id in all){obj=all[id];if(obj.constructor.name=="point")continue;if(obj.constructor.name=="points")continue;check=true;if(canvas.__changed[obj.__id]||obj.__zx_camera===null||obj.__zy_camera===null){obj.__get_extent(ext);if(obj.__xmin===null)continue;var xx=Math.max(Math.abs(obj.__xmin-ctrx),Math.abs(obj.__xmax-ctrx));var yy=Math.max(Math.abs(obj.__ymin-ctry),Math.abs(obj.__ymax-ctry));var zz=Math.max(Math.abs(obj.__zmin-ctrz),Math.abs(obj.__zmax-ctrz));obj.__zx_camera=xx*cot_hfov+zz;obj.__zy_camera=yy*cot_hfov+zz}ext.zx_camera=Math.max(ext.zx_camera,obj.__zx_camera);ext.zy_camera=Math.max(ext.zy_camera,obj.__zy_camera)}if(check){if(ext.zx_camera>ext.last_zx_camera||ext.zx_cameraext.last_zy_camera||ext.zy_cameraext.zy_camera){if(canvas.__width>=canvas.__height){canvas.__range=1.1*(canvas.__height/canvas.__width)*ext.zx_camera/cot_hfov}else{canvas.__range=1.1*ext.zx_camera/cot_hfov}}else{if(canvas.__width>=canvas.__height){canvas.__range=1.1*ext.zy_camera/cot_hfov}else{canvas.__range=1.1*(canvas.__width/canvas.__height)*ext.zy_camera/cot_hfov}}ext.last_zx_camera=ext.zx_camera;ext.last_zy_camera=ext.zy_camera}}},find_extent:function find_extent(obj,ext){if(obj.constructor.name=="points")return;var size=obj.__size;var sizex=size.x,sizey=size.y,sizez=size.z;var start=obj.__pos;var startx=start.x,starty=start.y,startz=start.z;var center_pos=obj.__hasPosAtCenter;var length;if(center_pos)length=Math.sqrt(sizex*sizex+sizey*sizey+sizez*sizez)/2;else length=Math.sqrt(sizex*sizex+sizey*sizey/4+sizez*sizez/4);var px=startx-ext.__centerx;var py=starty-ext.__centery;var pz=startz-ext.__centerz;var zzx=(Math.abs(px)+length)*ext.__cot_hfov+Math.abs(pz)+length;var zzy=(Math.abs(py)+length)*ext.__cot_hfov+Math.abs(pz)+length;if(zzx>i}return x+1}function handleLoadedTexture(image,obj,bump){var name,t0,ref;if(bump){name=obj.__tex.bumpmap;ref=obj.__tex.bumpmap_ref;t0=obj.__tex.bumpmap_t0}else{name=obj.__tex.file;ref=obj.__tex.texture_ref;t0=obj.__tex.texture_t0}var tf=msclock();tf=tf-t0;if(name in canvas.textures){ref.reference=canvas.textures[name]}else{canvas.textures[name]=ref.reference=gl.createTexture();gl.bindTexture(gl.TEXTURE_2D,ref.reference);gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true);if(!isPowerOfTwo(image.width)||!isPowerOfTwo(image.height)){var c=document.createElement("canvas");c.width=nextHighestPowerOfTwo(image.width);c.height=nextHighestPowerOfTwo(image.height);var ctx=c.getContext("2d");ctx.drawImage(image,0,0,c.width,c.height);image=c}gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,image);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR_MIPMAP_NEAREST);gl.generateMipmap(gl.TEXTURE_2D);gl.bindTexture(gl.TEXTURE_2D,null)}if(name in canvas.textures_requested){var done=canvas.textures_requested[name];while(done.length>0){var data=done.pop();if(data[1]){data[0].__tex.bumpmap_ref.reference=ref.reference}else{data[0].__tex.texture_ref.reference=ref.reference}data[0].__change()}}}this.initTexture=function(name,obj,bump){if(bump)obj.__tex.bumpmap=name;else obj.__tex.file=name;if(name in canvas.textures){if(bump)obj.__tex.bumpmap_ref.reference=canvas.textures[name];else obj.__tex.texture_ref.reference=canvas.textures[name];return}if(name in canvas.textures_requested){canvas.textures_requested[name].push([obj,bump]);return}else canvas.textures_requested[name]=[[obj,bump]];var t0=msclock();if(bump)obj.__tex.bumpmap_t0=t0;else obj.__tex.texture_t0=t0;var image=new Image;image.crossOrigin="anonymous";image.src=name;image.onload=function(){handleLoadedTexture(image,obj,bump)}};var update_vertices=0;canvas.__last_width=-1;canvas.__last_height=-1;canvas.__last_forward=canvas.forward;canvas.__last_up=canvas.up;var ktexture=1;var peels={C0:null,D0:null,C1:null,D1:null,C2:null,D2:null,C3:null,D3:null,C4:null,EXTENT_TEXTURE:null};var fullpeels=gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS)>=16;var textureN={C0:gl.TEXTURE2,D0:gl.TEXTURE3,C1:gl.TEXTURE4,D1:gl.TEXTURE5,C2:gl.TEXTURE6,D2:gl.TEXTURE7,C3:gl.TEXTURE8,D3:gl.TEXTURE9,C4:gl.TEXTURE10,EXTENT_TEXTURE:gl.TEXTURE11};function makeTexture(T){gl.activeTexture(textureN[T]);gl.bindTexture(gl.TEXTURE_2D,peels[T]);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);if(false&&T=="EXTENT_TEXTURE")gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,3,3,0,gl.RGBA,gl.UNSIGNED_BYTE,null);else gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,ktexture*canvas.__width,ktexture*canvas.__height,0,gl.RGBA,gl.UNSIGNED_BYTE,null);gl.bindTexture(gl.TEXTURE_2D,null)}for(var T in peels){peels[T]=gl.createTexture();makeTexture(T)}var peelFramebuffer=gl.createFramebuffer();gl.bindFramebuffer(gl.FRAMEBUFFER,peelFramebuffer);var peelRenderbuffer=gl.createRenderbuffer();gl.bindRenderbuffer(gl.RENDERBUFFER,peelRenderbuffer);gl.renderbufferStorage(gl.RENDERBUFFER,gl.DEPTH_COMPONENT16,ktexture*canvas.__width,ktexture*canvas.__height);gl.framebufferRenderbuffer(gl.FRAMEBUFFER,gl.DEPTH_ATTACHMENT,gl.RENDERBUFFER,peelRenderbuffer);gl.bindRenderbuffer(gl.RENDERBUFFER,null);gl.bindFramebuffer(gl.FRAMEBUFFER,null);var data=new Uint8Array(3);var tex1=gl.createTexture();gl.activeTexture(gl.TEXTURE1);gl.bindTexture(gl.TEXTURE_2D,tex1);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGB,1,1,0,gl.RGB,gl.UNSIGNED_BYTE,data);var tex0=gl.createTexture();gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,tex0);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGB,1,1,0,gl.RGB,gl.UNSIGNED_BYTE,data);this.render=function(mode){if(mode==RENDER){if(canvas.waitfor_textures){var check_objects=canvas.objects;for(var o in check_objects){var obj=check_objects[o];if(obj.__tex===undefined)continue;if(!obj.ready)return}canvas.waitfor_textures=false;canvas.trigger("textures",null)}}if(!canvas.visible){if(mode==RENDER)return;return null}if(canvas.__width!=canvas.__last_width||canvas.__height!=canvas.__last_height){for(var T in peels){makeTexture(T)}gl.bindFramebuffer(gl.FRAMEBUFFER,peelFramebuffer);gl.bindRenderbuffer(gl.RENDERBUFFER,peelRenderbuffer);gl.renderbufferStorage(gl.RENDERBUFFER,gl.DEPTH_COMPONENT16,ktexture*canvas.__width,ktexture*canvas.__height);gl.framebufferRenderbuffer(gl.FRAMEBUFFER,gl.DEPTH_ATTACHMENT,gl.RENDERBUFFER,peelRenderbuffer);gl.bindRenderbuffer(gl.RENDERBUFFER,null);gl.bindFramebuffer(gl.FRAMEBUFFER,null)}if(mode==RENDER){for(var i in canvas.arrows){var pos;var a=canvas.arrows[i];if(!a.run)continue;if(a.obj!==undefined){if(a.obj.pos!==undefined)pos=a.obj.pos;else continue}a.arrow.pos=pos;if(a.obj[a.attr]!==undefined){if(!a.arrow.visible)a.arrow.visible=true;if(window.__GSlang=="vpython")a.arrow.axis=a.obj[a.attr].multiply(a.scale);else a.arrow.axis_and_length=a.obj[a.attr].multiply(a.scale)}}for(var i in canvas.trails){var pos;var a=canvas.trails[i];if(!a.__run)continue;var obj=a.__obj;if(obj===undefined)continue;if(typeof obj==="string"){pos=a[obj];if(pos===undefined)continue}else if(typeof obj!=="function"){if(obj!==undefined&&obj.visible){if(!obj._pos_set)continue;if(obj.__interval>0)continue;if(obj.__pos!==undefined)pos=obj.__pos;else continue}else continue}else pos=obj();if(a.__last_pos!==null&&pos.equals(a.__last_pos))continue;if(a.pps>0){var tnow=msclock();if(a.__last_time===null)a.last_time=tnow;if(tnow-a.__last_time>1e3/a.pps)a.__last_time=tnow;else if(tnow!=a.__last_time)continue}a.__trail.push({pos:pos,color:a.color,radius:a.radius,retain:a.retain});a.__last_pos=vec(pos)}if(canvas.update_billboards||!canvas.__forward.equals(canvas.__last_forward)||!canvas.__up.equals(canvas.__last_up)){canvas.update_billboards=false;for(var i=0;i=canvasElement.clientHeight)camera.distance=canvas.__range/Math.tan(canvas.__fov/2);else camera.distance=canvas.__range*(canvasElement.clientHeight/canvasElement.clientWidth)/Math.tan(canvas.__fov/2);camera.pos=mat4.multiplyVec3(mat4.rotateX(mat4.rotateY(mat4.identity(mat4.create()),-camera.angleX),-camera.angleY),vec3.create([0,0,camera.distance]));camera.pos=vec3.create([canvas.__center.x+camera.pos[0],canvas.__center.y+camera.pos[1],canvas.__center.z+camera.pos[2]]);camera.zNear=camera.distance/100;camera.zFar=camera.distance*10;var projMatrix=mat4.perspective(camera.fovy,canvasElement.clientWidth/canvasElement.clientHeight,camera.zNear,camera.zFar);var viewMatrix=mat4.lookAt(camera.pos,camera.target,camera.up);for(var i=0;i0){var ptsobj=canvas.__points_objects;var scale=2*canvas.__range/canvas.__width;for(var i=0;i0&&(canvas.__overlay_objects.__changed||!(canvas.__forward.equals(canvas.__last_forward)&&canvas.__center.equals(canvas.__last_center)&&canvas.__up.equals(canvas.__last_up)&&canvas.__width==canvas.__last_width&&canvas.__height==canvas.__last_height&&canvas.__range==canvas.__last_range))){canvas.__overlay_objects.__changed=false;var ctx=canvas.overlay_context;ctx.clearRect(0,0,canvas.__width,canvas.__height);for(var i=0;iPEEL_D0)gl.uniform2fv(prog.uniforms.canvas_size,canvas_size);if(minormode!=MERGE){if(mode==RENDER||minormode==PEEL_C0||minormode==PEEL_C1||minormode==PEEL_C2||minormode==PEEL_C3||minormode==PEEL_C4){gl.uniform1i(prog.uniforms.light_count,light_count);gl.uniform4fv(prog.uniforms.light_pos,light_pos);gl.uniform3fv(prog.uniforms.light_color,light_color);gl.uniform3fv(prog.uniforms.light_ambient,light_ambient);gl.enableVertexAttribArray(prog.attributes.normal);if(prog!=curve_program){gl.enableVertexAttribArray(prog.attributes.color);gl.enableVertexAttribArray(prog.attributes.opacity);gl.enableVertexAttribArray(prog.attributes.shininess);gl.enableVertexAttribArray(prog.attributes.emissive);gl.enableVertexAttribArray(prog.attributes.texpos);gl.enableVertexAttribArray(prog.attributes.bumpaxis);gl.uniform1i(prog.uniforms.texmap,0);gl.uniform1i(prog.uniforms.bumpmap,1)}}gl.uniformMatrix4fv(prog.uniforms.viewMatrix,false,viewMatrix);gl.uniformMatrix4fv(prog.uniforms.projMatrix,false,projMatrix)}if(minormode==MERGE){gl.uniform1i(prog.uniforms.C0,2);gl.uniform1i(prog.uniforms.C1,4);if(fullpeels){gl.uniform1i(prog.uniforms.C2,6);gl.uniform1i(prog.uniforms.C3,8);gl.uniform1i(prog.uniforms.C4,10)}}else if(minormode>PEEL_D0){gl.uniform1i(prog.uniforms.D0,3);if(minormode==PEEL_C2||minormode==PEEL_D2)gl.uniform1i(prog.uniforms.D1,5);else if(minormode==PEEL_C3||minormode==PEEL_D3)gl.uniform1i(prog.uniforms.D2,7);else if(minormode==PEEL_C4)gl.uniform1i(prog.uniforms.D3,9)}}function subrender(minormode,T,Trefs){if(mode==RENDER_TEXTURE&&Trefs.length>0){for(var i=0;iPEEL_C0)gl.clearColor(0,0,0,0);else if(mode==EXTENT)gl.clearColor(0,0,0,1);else gl.clearColor(canvas.__background.x,canvas.__background.y,canvas.__background.z,canvas.__opacity);if(mode==EXTENT){gl.depthFunc(gl.GREATER);gl.clearDepth(0)}else{gl.depthFunc(gl.LEQUAL);gl.clearDepth(1)}gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);function render_curves(){var model=object_models.curve;var objs=model.id_object;var elements=model.elementType;var model_length=model.index.length;var setup=true;for(var id in objs){if(!objs[id].visible)break;if(minormode>PEEL_D0)break;if(setup){if(minormode==RENDER||minormode==PEEL_C0){if(curve_program==null)curve_program=shaderProgram(shaders.opaque_render_fragment,shaders.curve_render_vertex,gl);useProgram(curve_program,minormode)}else if(minormode==PEEL_D0){if(curve_peel_depth_programD0==null)curve_peel_depth_programD0=shaderProgram(shaders.peel_depth_fragmentD0,shaders.curve_peel_depth_vertex,gl);useProgram(curve_peel_depth_programD0,minormode)}else if(minormode==PICK){if(curve_pick_program==null)curve_pick_program=shaderProgram(shaders.pick_fragment,shaders.curve_pick_vertex,gl);useProgram(curve_pick_program,minormode)}gl.bindBuffer(gl.ARRAY_BUFFER,model.posBuffer);gl.vertexAttribPointer(program.attributes.pos,4,gl.FLOAT,false,0,0);if(minormode!=PICK&&minormodePEEL_D0){if(op=="opaque")continue}else{if(op=="transparent")continue}var first=true;for(var sort_type in sort[op]){for(var sort_list in sort[op][sort_type]){if(first){first=false;switch(minormode){case RENDER:case PEEL_C0:if(triangle_program===null)triangle_program=shaderProgram(shaders.opaque_render_fragment,shaders.tri_render_vertex,gl);useProgram(triangle_program,minormode);break;case EXTENT:if(extent_program===null)extent_program=shaderProgram(shaders.pick_fragment,shaders.extent_vertex,gl);useProgram(extent_program,minormode);break;case PEEL_D0:if(tri_peel_depth_programD0===null)tri_peel_depth_programD0=shaderProgram(shaders.peel_depth_fragmentD0,shaders.tri_peel_depth_vertex,gl);useProgram(tri_peel_depth_programD0,minormode);break;case PEEL_D1:if(tri_peel_depth_programD1===null)tri_peel_depth_programD1=shaderProgram(shaders.peel_depth_fragmentD1,shaders.tri_peel_depth_vertex,gl);useProgram(tri_peel_depth_programD1,minormode);break;case PEEL_D2:if(tri_peel_depth_programD2===null)tri_peel_depth_programD2=shaderProgram(shaders.peel_depth_fragmentD2,shaders.tri_peel_depth_vertex,gl);useProgram(tri_peel_depth_programD2,minormode);break;case PEEL_D3:if(tri_peel_depth_programD3===null)tri_peel_depth_programD3=shaderProgram(shaders.peel_depth_fragmentD3,shaders.tri_peel_depth_vertex,gl);useProgram(tri_peel_depth_programD3,minormode);break;case PEEL_C1:if(tri_peel_color_programC1===null)tri_peel_color_programC1=shaderProgram(shaders.peel_color_fragmentC1,shaders.tri_render_vertex,gl);useProgram(tri_peel_color_programC1,minormode);break;case PEEL_C2:if(tri_peel_color_programC2===null)tri_peel_color_programC2=shaderProgram(shaders.peel_color_fragmentC2,shaders.tri_render_vertex,gl);useProgram(tri_peel_color_programC2,minormode);break;case PEEL_C3:if(tri_peel_color_programC3===null)tri_peel_color_programC3=shaderProgram(shaders.peel_color_fragmentC3,shaders.tri_render_vertex,gl);useProgram(tri_peel_color_programC3,minormode);break;case PEEL_C4:if(tri_peel_color_programC4===null)tri_peel_color_programC4=shaderProgram(shaders.peel_color_fragmentC4,shaders.tri_render_vertex,gl);useProgram(tri_peel_color_programC4,minormode);break}gl.bindBuffer(gl.ARRAY_BUFFER,model.posBuffer);if(update_vertices)gl.bufferData(gl.ARRAY_BUFFER,model_arrays.pos,gl.DYNAMIC_DRAW);gl.vertexAttribPointer(program.attributes.pos,3,gl.FLOAT,false,0,0);if(mode==RENDER||minormode==PEEL_C0||minormode==PEEL_C1||minormode==PEEL_C2||minormode==PEEL_C3||minormode==PEEL_C4){gl.bindBuffer(gl.ARRAY_BUFFER,model.normalBuffer);if(update_vertices)gl.bufferData(gl.ARRAY_BUFFER,model_arrays.normal,gl.DYNAMIC_DRAW);gl.vertexAttribPointer(program.attributes.normal,3,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,model.colorBuffer);if(update_vertices)gl.bufferData(gl.ARRAY_BUFFER,model_arrays.color,gl.DYNAMIC_DRAW);gl.vertexAttribPointer(program.attributes.color,3,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,model.opacityBuffer);if(update_vertices)gl.bufferData(gl.ARRAY_BUFFER,model_arrays.opacity,gl.DYNAMIC_DRAW);gl.vertexAttribPointer(program.attributes.opacity,1,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,model.shininessBuffer);if(update_vertices)gl.bufferData(gl.ARRAY_BUFFER,model_arrays.shininess,gl.DYNAMIC_DRAW);gl.vertexAttribPointer(program.attributes.shininess,1,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,model.emissiveBuffer);if(update_vertices)gl.bufferData(gl.ARRAY_BUFFER,model_arrays.emissive,gl.DYNAMIC_DRAW);gl.vertexAttribPointer(program.attributes.emissive,1,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,model.texposBuffer);if(update_vertices)gl.bufferData(gl.ARRAY_BUFFER,model_arrays.texpos,gl.DYNAMIC_DRAW);gl.vertexAttribPointer(program.attributes.texpos,2,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,model.bumpaxisBuffer);if(update_vertices)gl.bufferData(gl.ARRAY_BUFFER,model_arrays.bumpaxis,gl.DYNAMIC_DRAW);gl.vertexAttribPointer(program.attributes.bumpaxis,3,gl.FLOAT,false,0,0);update_vertices=0}}var indices=sort[op][sort_type][sort_list];var tbobj=indices[0];var model_index=new Uint16Array(indices.slice(1));var model_length=model_index.length;gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,model.indexBuffer);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,model_index,gl.DYNAMIC_DRAW);if(mode==EXTENT)elements=gl.POINTS;var Tdata=0,Bdata=0;if(sort_type=="textures"){if((mode==RENDER||mode==RENDER_TEXTURE)&&tbobj.__tex.file!==null){if(tbobj.__tex.texture_ref.reference!==null){gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,tbobj.__tex.texture_ref.reference);Tdata=1}else continue}}else if(sort_type=="bumpmaps"){if((mode==RENDER||mode==RENDER_TEXTURE)&&tbobj.__tex.bumpmap!==null){if(tbobj.__tex.bumpmap_ref.reference!==null){gl.activeTexture(gl.TEXTURE1);gl.bindTexture(gl.TEXTURE_2D,tbobj.__tex.bumpmap_ref.reference);Bdata=1}else continue}}else if(sort_type=="textures_and_bumpmaps"){if((mode==RENDER||mode==RENDER_TEXTURE)&&tbobj.__tex.file!==null){if(tbobj.__tex.texture_ref.reference!==null){gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,tbobj.__tex.texture_ref.reference);Tdata=1}else continue}if((mode==RENDER||mode==RENDER_TEXTURE)&&tbobj.__tex.bumpmap!==null){if(tbobj.__tex.bumpmap_ref.reference!==null){gl.activeTexture(gl.TEXTURE1);gl.bindTexture(gl.TEXTURE_2D,tbobj.__tex.bumpmap_ref.reference);Bdata=1}else continue}}gl.uniform1f(program.uniforms.T,Tdata);gl.uniform1f(program.uniforms.B,Bdata);gl.drawElements(elements,model_length,gl.UNSIGNED_SHORT,0)}}}}function render_merge(){var model=object_models.quad;var elements=model.elementType;var model_length=model.index.length;if(fullpeels){if(merge_program==null)merge_program=shaderProgram(shaders.merge_fragment,shaders.merge_vertex,gl);useProgram(merge_program,minormode)}else{if(merge_program2==null)merge_program2=shaderProgram(shaders.merge_fragment2,shaders.merge_vertex,gl);useProgram(merge_program2,minormode)}gl.bindBuffer(gl.ARRAY_BUFFER,model.posBuffer);gl.vertexAttribPointer(program.attributes.pos,3,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,model.indexBuffer);gl.drawElements(elements,model_length,gl.UNSIGNED_SHORT,0)}for(var m in object_models){if(minormode>=MERGE){render_merge();break}if(m=="quad"||m=="triangle"){if(triangles_exist)render_triangles();continue}else if(m=="curve"){render_curves();continue}var model=object_models[m];var elements=model.elementType;var model_length=model.index.length;var objs;if(minormode>PEEL_D0){if(canvas.__transparent_objects[m]===undefined)continue;objs=canvas.__transparent_objects[m]}else{if(canvas.__opaque_objects[m]===undefined)continue;objs=canvas.__opaque_objects[m]}var gotobjects=false;for(var id in objs){gotobjects=true;break}if(!gotobjects)continue;var ringobject=m=="ring"||m=="vp_ring";switch(minormode){case RENDER:case PEEL_C0:if(ringobject){if(ring_program===null)ring_program=shaderProgram(shaders.opaque_render_fragment,shaders.ring_render_vertex,gl);useProgram(ring_program,minormode)}else{if(standard_program===null)standard_program=shaderProgram(shaders.opaque_render_fragment,shaders.render_vertex,gl);useProgram(standard_program,minormode)}break;case PICK:if(ringobject){if(ring_pick_program===null)ring_pick_program=shaderProgram(shaders.pick_fragment,shaders.ring_pick_vertex,gl);useProgram(ring_pick_program,minormode)}else{if(pick_program===null)pick_program=shaderProgram(shaders.pick_fragment,shaders.pick_vertex,gl);useProgram(pick_program,minormode)}break;case EXTENT:if(extent_program===null)extent_program=shaderProgram(shaders.pick_fragment,shaders.extent_vertex,gl);useProgram(extent_program,minormode);break;case PEEL_D0:if(ringobject){if(ring_peel_depth_programD0===null)ring_peel_depth_programD0=shaderProgram(shaders.peel_depth_fragmentD0,shaders.ring_peel_depth_vertex,gl);useProgram(ring_peel_depth_programD0,minormode)}else{if(peel_depth_programD0===null)peel_depth_programD0=shaderProgram(shaders.peel_depth_fragmentD0,shaders.peel_depth_vertex,gl);useProgram(peel_depth_programD0,minormode)}break;case PEEL_D1:if(ringobject){if(ring_peel_depth_programD1===null)ring_peel_depth_programD1=shaderProgram(shaders.peel_depth_fragmentD1,shaders.ring_peel_depth_vertex,gl);useProgram(ring_peel_depth_programD1,minormode)}else{if(peel_depth_programD1===null)peel_depth_programD1=shaderProgram(shaders.peel_depth_fragmentD1,shaders.peel_depth_vertex,gl);useProgram(peel_depth_programD1,minormode)}break;case PEEL_D2:if(ringobject){if(ring_peel_depth_programD2===null)ring_peel_depth_programD2=shaderProgram(shaders.peel_depth_fragmentD2,shaders.ring_peel_depth_vertex,gl);useProgram(ring_peel_depth_programD2,minormode)}else{if(peel_depth_programD2===null)peel_depth_programD2=shaderProgram(shaders.peel_depth_fragmentD2,shaders.peel_depth_vertex,gl);useProgram(peel_depth_programD2,minormode)}break;case PEEL_D3:if(ringobject){if(ring_peel_depth_programD3===null)ring_peel_depth_programD3=shaderProgram(shaders.peel_depth_fragmentD3,shaders.ring_peel_depth_vertex,gl);useProgram(ring_peel_depth_programD3,minormode)}else{if(peel_depth_programD3===null)peel_depth_programD3=shaderProgram(shaders.peel_depth_fragmentD3,shaders.peel_depth_vertex,gl);useProgram(peel_depth_programD3,minormode)}break;case PEEL_C1:if(ringobject){if(ring_peel_color_programC1===null)ring_peel_color_programC1=shaderProgram(shaders.peel_color_fragmentC1,shaders.ring_render_vertex,gl);useProgram(ring_peel_color_programC1,minormode)}else{if(peel_color_programC1===null)peel_color_programC1=shaderProgram(shaders.peel_color_fragmentC1,shaders.render_vertex,gl);useProgram(peel_color_programC1,minormode)}break;case PEEL_C2:if(ringobject){if(ring_peel_color_programC2===null)ring_peel_color_programC2=shaderProgram(shaders.peel_color_fragmentC2,shaders.ring_render_vertex,gl);useProgram(ring_peel_color_programC2,minormode)}else{if(peel_color_programC2===null)peel_color_programC2=shaderProgram(shaders.peel_color_fragmentC2,shaders.render_vertex,gl);useProgram(peel_color_programC2,minormode)}break;case PEEL_C3:if(ringobject){if(ring_peel_color_programC3===null)ring_peel_color_programC3=shaderProgram(shaders.peel_color_fragmentC3,shaders.ring_render_vertex,gl);useProgram(ring_peel_color_programC3,minormode)}else{if(peel_color_programC3===null)peel_color_programC3=shaderProgram(shaders.peel_color_fragmentC3,shaders.render_vertex,gl);useProgram(peel_color_programC3,minormode)}break;case PEEL_C4:if(ringobject){if(ring_peel_color_programC4===null)ring_peel_color_programC4=shaderProgram(shaders.peel_color_fragmentC4,shaders.ring_render_vertex,gl);useProgram(ring_peel_color_programC4,minormode)}else{if(peel_color_programC4===null)peel_color_programC4=shaderProgram(shaders.peel_color_fragmentC4,shaders.render_vertex,gl);useProgram(peel_color_programC4,minormode)}break}gl.bindBuffer(gl.ARRAY_BUFFER,model.posBuffer);gl.vertexAttribPointer(program.attributes.pos,3,gl.FLOAT,false,0,0);if(mode!=PICK&&(mode==RENDER||minormode==PEEL_C0||minormode==PEEL_C1||minormode==PEEL_C2||minormode==PEEL_C3||minormode==PEEL_C4)){gl.bindBuffer(gl.ARRAY_BUFFER,model.normalBuffer);gl.vertexAttribPointer(program.attributes.normal,3,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,model.colorBuffer);gl.vertexAttribPointer(program.attributes.color,3,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,model.opacityBuffer);gl.vertexAttribPointer(program.attributes.opacity,1,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,model.shininessBuffer);gl.vertexAttribPointer(program.attributes.shininess,1,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,model.emissiveBuffer);gl.vertexAttribPointer(program.attributes.emissive,1,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,model.texposBuffer);gl.vertexAttribPointer(program.attributes.texpos,2,gl.FLOAT,false,0,0);gl.bindBuffer(gl.ARRAY_BUFFER,model.bumpaxisBuffer);gl.vertexAttribPointer(program.attributes.bumpaxis,3,gl.FLOAT,false,0,0)}else if(ringobject){gl.bindBuffer(gl.ARRAY_BUFFER,model.normalBuffer);gl.vertexAttribPointer(program.attributes.normal,3,gl.FLOAT,false,0,0)}gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,model.indexBuffer);if(mode==EXTENT)elements=gl.POINTS;for(var id in objs){var obj=objs[id];var data=obj.__data;if(minormode128){exponent=-(exponent-128);mantissa=-mantissa}var extent;if(mantissa==0&&exponent==0)extent=0;else extent=Math.exp(mantissa+exponent);return null}else if(mode==PICK){gl.readPixels(canvas.mouse.__pickx,canvas.mouse.__picky,1,1,gl.RGBA,gl.UNSIGNED_BYTE,pixels);var id=16777216*pixels[0]+65536*pixels[1]+256*pixels[2]+pixels[3];var obj=canvas.__visiblePrimitives[id];if(!obj)return null;else if(obj.__obj&&obj.__obj.pickable)return obj.__obj;else if(obj.constructor.name=="point"){if(!obj.__curve.pickable||!obj.pickable)return null;var pts=obj.__curve.__points;var L=pts.length;for(var i=0;i0;var t=msclock();var elapsed=0;if(doAverage)elapsed=t-lastStartRedraw;lastStartRedraw=t;canvas.trigger("redraw",{dt:elapsed});renderer.render(RENDER);t=msclock();elapsed=0;if(doAverage)elapsed=t-lastEndRedraw;lastEndRedraw=t;if(doAverage){renderMS=renderMS*.95+(t-lastStartRedraw)*.05;fps=fps*.95+1e3/elapsed*.05}else{renderMS=t-lastStartRedraw;fps=0}var total=fps*renderMS;$("#fps").text(fps.toFixed(1)+" renders/s * "+renderMS.toFixed(1)+" ms/render = "+total.toFixed(1)+" ms rendering/s");canvas.trigger("draw_complete",{dt:elapsed});canvas.__last_center=canvas.__center;canvas.__last_forward=canvas.__forward;canvas.__last_range=canvas.__range;canvas.__last_up=canvas.__up;canvas.__last_width=canvas.__width;canvas.__last_height=canvas.__height}this.reset();trigger_render()}var desired_fps=60;var N=0;var enditers;function rate(iters,cb){var dt,timer;if(cb===undefined)throw new Error("rate(iterations_per_second, wait) called without wait");if(N>0){N--;timer=msclock();if(timer>enditers)N=1;if(N>1){cb()}else{N=0;var dt=enditers-Math.ceil(timer);if(dt<5)dt=0;setTimeout(cb,dt)}}else{if(iters<=120){dt=Math.ceil(1e3/iters);setTimeout(cb,dt)}else{timer=msclock();N=Math.ceil(iters/desired_fps);enditers=msclock()+Math.ceil(1e3/desired_fps);cb()}}}var exports={WebGLRenderer:WebGLRenderer,rate:rate};Export(exports)})();(function(){"use strict";function log10(val){return Math.log(val)/Math.LN10}var eformat=false;var nformat=0;var nmax=0;function format_number(val,axis){if(axis.ticks.length==0){var delta=axis.tickSize;var amin=axis.min,amax=axis.max;var nticks=Math.floor((amax-amin)/delta+.5)+1;var vmax,test;for(var i=0;ivmax&&test!=0)vmax=test}nmax=Math.floor(log10(vmax))+1;var n=Math.floor(log10(delta))+1;if(n>3){eformat=true;nformat=n}else if(n>0){eformat=false;nformat=0}else if(n<0){eformat=true;nformat=n;if(nmax>=0){eformat=false;nformat=-n+1}}else{eformat=false;nformat=1}}if(val==0)return"0";if(eformat){var nf,nexp;var mantissa=val*pow(10,-nformat+1);nf=0;nexp=nformat-1;if(nmax>nformat){mantissa*=.1;nf+=1;nexp+=1}return mantissa.toFixed(nf)+"e"+nexp}else{return val.toFixed(nformat)}}var fontsize=16;var graphid=0;function graph(options){graph.activated=[];graph.__selected=null;graph.get_selected=function(){return graph.__selected};if(!(this instanceof graph))return new graph(options);options=options||{};if(options.x!==undefined)delete options.x;if(options.y!==undefined)delete options.y;this.fast=true;if(options.fast!==undefined){this.fast=options.fast;delete options.fast}this.graph_options={};if(this.fast){this.graph_options={series:{shadowSize:0},crosshair:{mode:"xy",color:"rgba(0,0,0,1)"},xaxis:{min:null,max:null,tickFormatter:format_number},yaxis:{min:null,max:null,tickFormatter:format_number}}}this.__lock=false;this.__id="graph"+graphid;graphid++;this.container=$('
    ');this.__activated=false;this.__deleted=false;this.graph_series=[];this.__todo_list=[];graph.__selected=this;this.__width=640;this.__height=400;this.__plot=null;this.__xmin=this.__ymin=null;this.__xmax=this.__ymax=null;this.__xmin_actual=this.__ymin_actual=null;this.__xmax_actual=this.__ymax_actual=null;this.__title=this.__xtitle=this.__ytitle="";this.__made_title=false;this.__made_xtitle=false;this.__made_ytitle=false;if(options.width!==undefined){this.__width=options.width;delete options.width}if(options.height!==undefined){this.__height=options.height;delete options.height}this.__align="none";if(options.align!==undefined){this.__align=options.align;delete options.align}if(options.title!==undefined){this.__title=print_to_string(options.title);delete options.title}if(options.xtitle!==undefined){this.__xtitle=print_to_string(options.xtitle);delete options.xtitle}if(options.ytitle!==undefined){this.__ytitle=print_to_string(options.ytitle);delete options.ytitle}this.__foreground=color.black;this.__background=color.white;if(options.foreground!==undefined){var v=options.foreground;if(!(v instanceof vec))throw new Error("graph foreground must be a vector.");this.__foreground=v;delete options.foreground}if(options.background!==undefined){var v=options.background;if(!(v instanceof vec))throw new Error("graph background must be a vector.");this.__background=v;delete options.background}var minmax=0;if(options.xmin!==undefined){this.__xmin=options.xmin;if(this.fast)this.graph_options.xaxis.min=options.xmin;minmax++;delete options.xmin}if(options.xmax!==undefined){this.__xmax=options.xmax;if(this.fast)this.graph_options.xaxis.max=options.xmax;minmax++;delete options.xmax}if(!this.fast&&minmax==1){if(this.__xmin===null&&this.__xmax>0)this.__xmin=0;else if(this.__xmin<0&&this.__xmax===null)this.__xmax=0;else throw new Error("You must specify both xmin and xmax.")}minmax=0;if(options.ymin!==undefined){this.__ymin=options.ymin;if(this.fast)this.graph_options.yaxis.min=options.ymin;minmax++;delete options.ymin}if(options.ymax!==undefined){this.__ymax=options.ymax;if(this.fast)this.graph_options.yaxis.max=options.ymax;minmax++;delete options.ymax}if(!this.fast&&minmax==1){if(this.__ymin===null&&this.__ymax>0)this.__ymin=0;else if(this.__ymin<0&&this.__ymax===null)this.__ymax=0;else throw new Error("You must specify both ymin and ymax.")}this.__logx=this.__logy=false;if(options.logx!==undefined){this.__logx=this.graph_options.logx=options.logx;delete options.logx}if(options.logy!==undefined){this.__logy=this.graph_options.logy=options.logy;delete options.logy}if(this.fast){if(this.__logx){this.graph_options.xaxis.transform=function(v){return log10(v)};this.graph_options.xaxis.inverseTransform=function(v){return pow(10,v)}}if(this.__logy){this.graph_options.yaxis.transform=function(v){return log10(v)};this.graph_options.yaxis.inverseTransform=function(v){return pow(10,v)}}}var err="",count=0;for(var attr in options){count+=1;err+=attr+", "}if(err.length>0){if(count==1)throw new Error(err.slice(0,err.length-2)+" is not an attribute of a graph");else throw new Error("These are not attributes of a graph: "+err.slice(0,err.length-2))}function compute_offset(T){if(T==null||T=="")return 0;T=T.replace("
    ","\n");T=T.replace("
    ","\n");T=T.split("\n");if(T.length==1)return fontsize;return fontsize+1.3*fontsize*(T.length-1)}if(this.fast){var top=0,left=0,right=0,bottom=0;if(this.__align=="right")right=40;var d=10;if(this.__title!=="")top=d+compute_offset(this.__title);if(this.__ytitle!==""){left=compute_offset(this.__ytitle);if(left>fontsize)throw new Error("graph ytitle must not contain line breaks.");left+=d}if(this.__xtitle!==null&&this.__xtitle!==""){bottom=compute_offset(this.__xtitle);if(bottom>fontsize)throw new Error("graph xtitle must not contain line breaks.");bottom+=d}this.graph_options.grid={color:color.to_html(this.__foreground),backgroundColor:color.to_html(this.__background),offsets:{left:left,right:right,top:top,bottom:bottom}}}}property.declare(graph.prototype,{type:{get:function(){return this.__type},set:function(){throw new Error("Cannot change the type of a graph.")}},select:function(){graph.__selected=this},__todo:function(info,id){if(!this.__lock)Plotly.restyle(this.__id,info,id);else this.__todo_list.push([info,id])},__changed:false,remove:function(){if(this.__activated){if(!this.fast)Plotly.purge(this.__id);this.__deleted=true;this.container.remove()}},title:{get:function(){return this.__title},set:function(value){var m=value.match(/([^\n])*/);value=m[0];this.__title=value;if(this.__activated){if(this.fast){this.make_title(value)}else{Plotly.relayout(this.__id,{title:value})}}}},xtitle:{get:function(){return this.__xtitle},set:function(value){var m=value.match(/([^\n])*/);value=m[0];this.__xtitle=value;if(this.__activated){if(this.fast){this.make_xtitle(value)}else{Plotly.relayout(this.__id,{"xaxis.title":value})}}}},ytitle:{get:function(){return this.__ytitle},set:function(value){var m=value.match(/([^\n])*/);value=m[0];this.__ytitle=value;if(this.__activated){if(this.fast){this.make_ytitle(value)}else{Plotly.relayout(this.__id,{"yaxis.title":value})}}}},width:{get:function(){return this.__width},set:function(value){this.__width=value;if(this.fast){this.container.css("width",value);var plot=$.plot(this.container,[],this.graph_options);plot.resize();plot.setupGrid()}else{if(this.__activated)Plotly.relayout(this.__id,{width:value})}}},height:{get:function(){return this.__height},set:function(value){this.__height=value;if(this.fast){this.container.css("height",value);var plot=$.plot(this.container,[],this.graph_options);plot.resize();plot.setupGrid()}else{if(this.__activated)Plotly.relayout(this.__id,{height:value})}}},align:{get:function(){return this.__align},set:function(value){if(this.__activated)throw new Error("Cannot change align after the graph is activated.");if(value=="left"||value=="right"||value=="none"){this.__align=value}else throw new Error("align must be 'left', 'right', or 'none' (the default).")}},xmin:{get:function(){return this.__xmin},set:function(value){this.__xmin=value;if(this.fast)this.graph_options.xaxis.min=value;else if(this.__activated)Plotly.relayout(this.__id,{"xaxis.range":[value,this.__xmax]})}},xmax:{get:function(){return this.__xmax},set:function(value){this.__xmax=value;if(this.fast)this.graph_options.xaxis.max=value;else if(this.__activated)Plotly.relayout(this.__id,{"xaxis.range":[this.__xmin,value]})}},ymin:{get:function(){return this.__ymin},set:function(value){this.__ymin=value;if(this.fast)this.graph_options.yaxis.min=value;else if(this.__activated)Plotly.relayout(this.__id,{"yaxis.range":[value,this.__ymax]})}},ymax:{get:function(){return this.__ymax},set:function(value){this.__ymax=value;if(this.fast)this.graph_options.yaxis.max=value;else if(this.__activated)Plotly.relayout(this.__id,{"yaxis.range":[this.__ymin,value]})}},logx:{get:function(){return this.__logx},set:function(value){this.__logx=value;if(this.__logx==value)return;if(this.fast){if(value){this.graph_options.xaxis.transform=function(v){return log10(v)};this.graph_options.xaxis.inverseTransform=function(v){return pow(10,v)}}else{delete this.graph_options.xaxis.transform;delete this.graph_options.xaxis.inverseTransform}}else if(this.__activated){if(value)Plotly.relayout(this.__id,{"xaxis.type":"log"});else Plotly.relayout(this.__id,{"xaxis.type":null})}}},logy:{get:function(){return this.__logy},set:function(value){this.__logy=value;if(this.__logy==value)return;if(this.fast){if(value){this.graph_options.yaxis.transform=function(v){return log10(v)};this.graph_options.yaxis.inverseTransform=function(v){return pow(10,v)}}else{delete this.graph_options.yaxis.transform;delete this.graph_options.yaxis.inverseTransform}}else if(this.__activated){if(value)Plotly.relayout(this.__id,{"yaxis.type":"log"});else Plotly.relayout(this.__id,{"yaxis.type":null})}}},foreground:{get:function(){return this.__foreground},set:function(value){if(!(value instanceof vec))throw new Error("graph foreground color must be a vector.");this.__foreground=value;var col=color.to_html(value);if(this.fast)this.graph_options.grid.color=col;else if(this.__activated)Plotly.relayout(this.__id,{paper_bgcolor:col})}},background:{get:function(){return this.__background},set:function(value){if(!(value instanceof vec))throw new Error("graph background color must be a vector.");this.__background=value;var col=color.to_html(value);if(this.fast)this.graph_options.grid.backgroundColor=col;else if(this.__activated)Plotly.relayout(this.__id,{plot_bgcolor:col})}},make_title:function(title){var o=this.graph_options.grid.offsets;if(o.top===0)throw new Error("Cannot change a graph title if it does not already have a title.");var ctx=this.__plot.getCanvas().getContext("2d");ctx.fillStyle=color.to_html_rgba(vec(1,1,1),1);ctx.fillRect(0,0,this.__width,o.top);var font="Arial";if(title!==null&&title!==""){var y0=15;var x0=o.left+(this.__width-o.left-o.right)/2;var info=parse_html({ctx:ctx,text:title.toString(),x:x0,y:y0,align:"center",font:font,fontsize:fontsize,angle:0});display_2D(info)}},make_xtitle:function(title){var o=this.graph_options.grid.offsets;if(o.bottom===0)throw new Error("Cannot change a graph xtitle if it does not already have an xtitle.");var ctx=this.__plot.getCanvas().getContext("2d");ctx.fillStyle=color.to_html_rgba(vec(1,1,1),1);ctx.fillRect(o.left,this.__height-o.bottom,this.__width-o.right,this.__height);var font="Arial";if(title!==null&&title!==""){var x0=o.left+(this.__width-o.left-o.right)/2;var y0=this.__height+o.top-5;var info=parse_html({ctx:ctx,text:title.toString(),x:x0,y:y0,align:"center",font:font,fontsize:fontsize,angle:0});display_2D(info)}},make_ytitle:function(title){var o=this.graph_options.grid.offsets;if(o.left===0)throw new Error("Cannot change a graph ytitle if it does not already have a ytitle.");var ctx=this.__plot.getCanvas().getContext("2d");ctx.fillStyle=color.to_html_rgba(vec(1,1,1),1);ctx.fillRect(0,o.top,o.left,this.__height-o.top-o.bottom);var font="Arial";if(title!==null&&title!==""){var x0=15;var y0=o.top+(this.__height-o.bottom-15)/2;var info=parse_html({ctx:ctx,text:title.toString(),x:x0,y:y0,align:"center",font:font,fontsize:fontsize,angle:-Math.PI/2});display_2D(info)}},add_to_graph:function(obj){obj.__id=this.graph_series.length;obj.__activated=false;this.graph_series.push(obj)},__activate:function(dheight){if(this.__activated)return;if(!this.fast){this.container.addClass("glowscript-graph").css("width",this.__width).css("height",this.__height+dheight).appendTo(canvas.container);if(this.__align!="none")this.container.css("float",this.__align)}else{this.container.addClass("glowscript-graph").css("width",this.__width).css("height",this.__height+this.graph_options.grid.offsets.top).appendTo(canvas.container);this.container.css("float",this.__align)}graph.activated.push(this);this.__activated=true},__update:function(){if(!this.__changed||this.__deleted)return;if(this.__lock)return;var activated=this.__activated;function compute_offset(s){var m=s.match(/
    /g);if(m===null)return 0;return m.length}if(!this.fast){for(var i=0;i0){layout.title=this.title;var n=compute_offset(this.title);t=65;if(n>0)t+=45*(n-1);dh+=45*(n+1);layout.height+=dh}var l=65;if(this.ytitle!==undefined&&this.ytitle.length>0){layout.yaxis.title=this.ytitle;var d=compute_offset(this.ytitle);if(d>0)throw new Error("A ytitle must not contain
    .");l=80}var b=45;if(this.xtitle!==undefined&&this.xtitle.length>0){layout.xaxis.title=this.xtitle;var d=compute_offset(this.xtitle);if(d>0)throw new Error("An xtitle must not contain
    .")}layout.margin={l:l,r:20,b:b,t:t,pad:4};this.__activate(dh);this.__activated=true;var p=s.__realtype;var col=color.to_html(s.__color);if(p=="bar")Plotly.newPlot(this.__id,[{x:[],y:[],type:p,name:s.__label,showlegend:s.__legend,visible:s.__visible,width:s.__delta,orientation:s.__orientation,marker:{color:color.to_html_rgba(s.__color,.5),line:{color:color.to_html_rgba(s.__color,1),width:2}}}],layout);else if(p=="lines"){Plotly.newPlot(this.__id,[{x:[],y:[],mode:p,type:"scatter",name:s.__label,showlegend:s.__legend,visible:s.__visible,line:{color:col,width:s.__width}}],layout)}else if(p=="markers"){Plotly.newPlot(this.__id,[{x:[],y:[],mode:p,type:"scatter",name:s.__label,showlegend:s.__legend,visible:s.__visible,marker:{color:col,size:2*s.__radius}}],layout)}}else if(!s.__activated){s.__activated=true;p=s.__realtype;var col=color.to_html(s.__color);if(p=="bar")Plotly.addTraces(this.__id,{x:[],y:[],type:p,name:s.__label,showlegend:s.__legend,visible:s.__visible,width:s.__delta,orientation:s.__orientation,marker:{color:color.to_html_rgba(s.__color,.5),line:{color:color.to_html_rgba(s.__color,1),width:2}}});else if(p=="lines"){if(s.__markers)p="markers+lines";Plotly.addTraces(this.__id,{x:[],y:[],mode:p,type:"scatter",name:s.__label,showlegend:s.__legend,visible:s.__visible,marker:{color:color.to_html(s.__marker_color),size:2*s.__radius},line:{color:col,width:s.__width}})}else if(p=="markers")Plotly.addTraces(this.__id,{x:[],y:[],mode:p,type:"scatter",name:s.__label,showlegend:s.__legend,visible:s.__visible,marker:{color:col,size:2*s.__radius}})}}if(!this.__lock){this.__lock=true;var self=this;Plotly.extendTraces(this.__id,{x:xs,y:ys},indices).then(function(){self.__lock=false})}}else{var info=[];for(var i=0;i0){var dotdisplay={points:{show:true}};if(s.__dot_radius!==null)dotdisplay.points.radius=s.__dot_radius;else dotdisplay.points.radius=s.__width+1;if(s.__dot_color!==null)dotdisplay.color=color.to_html(s.__dot_color);else dotdisplay.color=color.to_html(s.__color);dotdisplay.points.fillColor=dotdisplay.color;dotdisplay.data=[s.options.data[s.options.data.length-1]];info.push(dotdisplay)}}if(info.length>0){this.__activate(0);this.__plot=$.plot(this.container,info,this.graph_options);this.__plot.draw()}if(!activated){if(this.__title!==null&&this.__title!=="")this.make_title(this.__title);if(this.__xtitle!==null&&this.__xtitle!=="")this.make_xtitle(this.__xtitle);if(this.__ytitle!==null&&this.__ytitle!=="")this.make_ytitle(this.__ytitle)}}this.__changed=false;if(!activated)new render_graph(this)}});var to_slow_type={lines:"lines",scatter:"markers",markers:"markers",bar:"bar"};var to_fast_type={lines:"lines",scatter:"points",markers:"points",bar:"bars"};function gobject(options){options=options||{};this.__data=[];this.__newdata=[];this.__color=vec(0,0,0);this.__marker_color=vec(0,0,0);this.__linemarker=null;this.__lineobj=null;this.__markerobj=null;this.__label=null;this.__save_label=null;this.__delta=1;this.__width=2;this.__radius=3;this.__horizontal=false;this.__dot=false;this.__xmin=null;this.__xmax=null;this.__ymin=null;this.__ymax=null;this.__label="";this.__legend=false;this.__markers=false;this.__interval=-1;var fast=true;if(options.fast!==undefined){fast=options.fast;delete options.fast}if(options.graph!==undefined){this.__graph=options.graph;delete options.graph}else if(options.gdisplay!==undefined){this.__graph=options.gdisplay;delete options.gdisplay}else{try{this.__graph=graph.get_selected()}catch(err){this.__graph=graph({fast:fast})}}this.__type="lines";if(options.type!==undefined){this.__type=options["type"];delete options["type"]}if(this.__graph.fast)this.__realtype=to_fast_type[this.__type];else this.__realtype=to_slow_type[this.__type];if(!this.__realtype)throw new Error("Unknown series type: "+this.__type);this.options={};var ftype=this.__realtype;if(options.data!==undefined){this.__data=options.data;delete options.data}if(options.color!==undefined){var c=options.color;if(!(c instanceof vec))throw new Error("graph color must be a vector.");this.__color=c;this.__marker_color=c;delete options.color}if(this.__graph.fast){if(ftype=="lines")this.options[ftype]={show:true,lineWidth:this.__width};else if(ftype=="points")this.options[ftype]={show:true,radius:this.__radius,fill:true,lineWidth:0};else if(ftype=="bars")this.options[ftype]={show:true,align:"center",horizontal:false,barWidth:1,lineWidth:1,fill:.5}}this.options.color=color.to_html(this.__color);if(this.__graph.fast){if(this.__realtype=="points")this.options[ftype].fillColor=this.options.color;else this.options.fillColor=this.options.color}if(options.marker_color!==undefined){var c=options.marker_color;if(!(c instanceof vec))throw new Error("graph color must be a vector.");this.__marker_color=c;delete options.marker_color}if(options.width!==undefined){this.__width=options.width;if(this.__graph.fast)this.options[ftype].lineWidth=options.width;delete options.width}if(options.markers!==undefined){if(this.__realtype!="lines")throw new Error("One can add markers only to graph curves.");if(options.markers===true){this.__markers=options.markers;var r=this.__width/2+2;if(options.radius!==undefined)r=options.radius;if(this.__graph.fast)this.__linemarker={points:{show:true,radius:r,lineWidth:0,fillColor:color.to_html(this.__marker_color),fill:true}};else this.__radius=r}delete options.markers}if(options.radius!==undefined){this.__radius=options.radius;if(this.__graph.fast)this.options[ftype].radius=options.radius;delete options.radius}if(options.size!==undefined){this.__radius=options.size/2;if(this.__graph.fast)this.options[ftype].radius=options.size/2;delete options.size}if(options.horizontal!==undefined){this.__horizontal=options.horizontal;if(this.__graph.fast)this.options[ftype].horizontal=options.horizontal;delete options.horizontal}if(options.delta!==undefined){this.__delta=options.delta;if(this.__graph.fast)this.options[ftype].barWidth=options.delta;delete options.delta}if(options.label!==undefined){this.__label=options.label;this.__save_label=options.label;if(this.__graph.fast)this.options.label=options.label;if(options.label.length>0)this.__legend=true;delete options.label}if(options.legend!==undefined){this.__legend=options.legend;if(this.__graph.fast&&!options.legend&&this.__label!==null)delete this.options.label;delete options.legend}if(options.__lineobj!==undefined){this.__lineobj=options.__lineobj;delete options.__lineobj}if(options.__markerobj!==undefined){this.__markerobj=options.__markerobj;delete options.__markerobj}if(options.dot!==undefined){if(this.__realtype!="lines")throw new Error('Can add a moving dot only to a gcurve or "lines" object');this.__dot=options.dot;this.__dot_radius=this.__width/2+4;this.__dot_color=this.__color;delete options.dot}if(options.dot_radius!==undefined){this.__dot_radius=options.dot_radius;delete options.dot_radius}this.__dot_color=this.__color;if(options.dot_color!==undefined){var v=options.dot_color;if(!(v instanceof vec))throw new Error("graph dot_color must be a vector.");this.__dot_color=v;delete options.dot_color}if(options.interval!==undefined){this.__interval=options.interval;this.__ninterval=options.interval;delete options.interval}this.__visible=true;if(options.visible!==undefined){this.__visible=options.visible;delete options.visible}var err="",count=0;for(var attr in options){count+=1;err+=attr+", "}if(err.length>0){if(count==1)throw new Error(err.slice(0,err.length-2)+" is not an attribute of a series");else throw new Error("These are not attributes of a graph object: "+err.slice(0,err.length-2))}this.__graph.add_to_graph(this);this.remove=function(){this.data=[]};var toType=function(obj){return{}.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()};var resolveargs=function(args){var v,ret;ret=[];if(toType(arguments[0][0])!="array"){for(var i=0;i0){this.__ninterval++;if(this.__ninterval>=this.__interval)this.__ninterval=0;else continue}if(this.__graph.fast)this.__data.push(data[i]);else this.__newdata.push(data[i]);if(!this.__graph.fast&&this.__realtype=="lines"&&this.__newdata.length>0){var d=this.__newdata[this.__newdata.length-1];if(this.__dot)this.__dotobject.data=[data[i]];if(this.__markers)this.__markerobject.__newdata.push(data[i])}}}else{var x,y,dx,dy,lastx,lasty,dt,xy,wx,wy;var g=this.__graph;var xmin=g.__xmin;var xmax=g.__xmax;var ymin=g.__ymin;var ymax=g.__ymax;var xmin_actual=g.__xmin_actual;var xmax_actual=g.__xmax_actual;var ymin_actual=g.__ymin_actual;var ymax_actual=g.__ymax_actual;dt=Math.floor(msclock()-this.__lasttime);this.__lasttime=msclock();lastx=lasty=null;if(this.__data.length>0){xy=this.__data[this.__data.length-1];lastx=xy[0];lasty=xy[1]}for(var i=0;i0){this.__ninterval++;if(this.__ninterval>=this.__interval)this.__ninterval=0;else continue}xy=data[i];x=xy[0];y=xy[1];checkval(x);checkval(y);if(xmin_actual===null||xxmax_actual)g.__xmax_actual=xmax_actual=x;if(ymin_actual===null||yymax_actual)g.__ymax_actual=ymax_actual=y;if(lastx!==null){wx=xmax_actual-xmin_actual;dx=wx===0?0:Math.abs(x-lastx)/wx;wy=ymax_actual-ymin_actual;dy=wy===0?0:Math.abs(y-lasty)/wy;if(dx<.01&&dy<.01)continue}if(this.__graph.fast)this.__data.push(xy);else this.__newdata.push(xy);lastx=x;lasty=y}if(this.__dot&&!this.__graph.fast&&this.__newdata.length>0){this.__dotobject.data=[this.__newdata[this.__newdata.length-1]]}}this.__graph.__changed=true;if(!this.__graph.__activated)this.__graph.__update()};if(this.__data.length>0)this.plot(this.__data)}property.declare(gobject.prototype,{graph:{get:function(){return this.__graph},set:function(value){throw new Error("Cannot change the choice of graph for an existing graphing object.")}},type:{get:function(){return this.__type},set:function(value){throw new Error("Cannot change the type of an existing graphing object.")}},data:{get:function(){return this.__data.concat(this.__newdata)},set:function(value){this.__data=[];this.options.data=[];this.__newdata=[];if(!this.__graph.fast){if(this.__realtype=="lines"){if(this.__dot){this.__dotobject.__data=[];this.__dotobject.__newdata=[];if(this.__graph.__activated)this.__graph.__todo({x:[[]],y:[[]]},this.__dotobject.__id)}if(this.__markers){this.__markerobject.__data=[];this.__markerobject.__newdata=[];if(this.__graph.__activated)this.__graph.__todo({x:[[]],y:[[]]},this.__markerobject.__id)}}if(this.__graph.__activated)this.__graph.__todo({x:[[]],y:[[]]},this.__id)}this.__graph.__changed=true;if(value.length>0)this.plot(value)}},markers:{get:function(){return this.__markers},set:function(value){if(this.__realtype!="lines")throw new Error("One can add markers only to graph curves.");if(this.__markers===value)return;this.__markers=value;var r=this.__radius+2;if(this.__activated){if(value){var up={};up["marker.color"]=color.to_html(this.__color);if(this.__graph.fast)this.options.points={show:true,radius:r};else this.__graph.__todo(up,this.__markerobject.__id)}else{var up={};up["marker.size"]=.1;if(this.__graph.fast)this.options.points={show:false,radius:r};else this.__graph.__todo(up,this.__markerobject.__id);this.__graph.__changed=true}}}},color:{get:function(){return this.__color},set:function(value){if(!(value instanceof vec))throw new Error("graphing color must be a vector.");if(this.__color.equals(value))return;this.__color=value;var col=color.to_html(value);if(this.__graph.fast)this.options.color=col;if(this.__activated){if(this.__graph.fast){if(this.__realtype=="points")this.options[ftype].fillColor=this.options.color;else this.options.fillColor=this.options.color;this.__graph.__changed=true}else{var up={};if(this.__realtype=="bar"){up["marker.color"]=color.to_html_rgba(value,.5);up["marker.line.color"]=color.to_html_rgba(value,1)}else if(this.__realtype=="markers"){up["marker.color"]=col}else if(this.__realtype=="lines"){up["line.color"]=col;up["marker.color"]=col}this.__graph.__todo(up,this.__id)}}}},marker_color:{get:function(){return this.__marker_color},set:function(value){if(!(value instanceof vec))throw new Error("graphing marker_color must be a vector.");if(this.__marker_color.equals(value))return;this.__marker_color=value;var col=color.to_html(value);if(this.__graph.fast)this.options.marker_color=col;if(this.__activated){if(this.__graph.fast){if(this.__realtype=="lines")this.__linemarker.points.fillColor=col;else this.options.color=col;this.__graph.__changed=true}else{if(this.__markerobject.__activated){var up={};up["marker.color"]=col;this.__graph.__todo(up,this.__markerobject.__id)}}}}},label:{get:function(){if(this.__label===undefined)return"";return this.__label},set:function(value){var m=value.match(/([^\n])*/);value=m[0];if(this.__label==value)return;this.__label=value;if(this.__graph.fast)this.options.label=value;if(value.length>0)this.__legend=true;if(this.__activated){if(this.__graph.fast){this.options.label=value;this.__graph.__changed=true}else this.__graph.__todo({name:value,showlegend:this.__legend},this.__id)}}},legend:{get:function(){return this.__legend},set:function(value){if(this.__legend==value)return;this.__legend=value;if(this.__graph.fast)this.options.legend=value;if(this.__activated){if(this.__graph.fast){if(this.options.label!==null){if(value)this.options.label=this.__save_label;else delete this.options.label}this.options.legend=value;this.__graph.__changed=true}else this.__graph.__todo({showlegend:value},this.__id)}}},delta:{get:function(){return this.__delta},set:function(value){if(this.__delta==value)return;this.__delta=value;if(this.__graph.fast)this.options[this.__realtype].barWidth=value;if(this.__activated){if(this.__graph.fast){this.__graph.__changed=true}else this.__graph.__todo({width:value},this.__id)}}},width:{get:function(){return this.__width},set:function(value){if(this.__width==value)return;this.__width=value;if(this.__graph.fast)this.options[this.__realtype].lineWidth=value;if(this.__activated){if(this.__graph.fast){this.__graph.__changed=true}else{var up={};if(this.__realtype=="bar"){return}else if(this.__realtype=="lines"){up["line.width"]=value}else if(this.__realtype=="markers"){return}this.__graph.__todo(up,this.__id)}}}},radius:{get:function(){return this.__radius},set:function(value){if(this.__radius==value)return;this.__radius=value;if(this.__graph.fast)this.options[this.__realtype].radius=value;if(this.__activated){if(this.__graph.fast){this.__graph.__changed=true}else{var up={};up["marker.size"]=2*value;if(this.__realtype=="lines"){if(!this.__markers)return;this.__graph.__todo(up,this.__markerobject.__id)}else if(this.__realtype=="markers"){this.__graph.__todo(up,this.__id)}}}}},size:{get:function(){return 2*this.__radius},set:function(value){if(2*this.__radius==value)return;this.__radius=value/2;if(this.__graph.fast)this.options[this.__realtype].radius=value/2;if(this.__activated){if(this.__graph.fast){this.__graph.__changed=true}else{var up={};if(this.__realtype=="bar"){return}else if(this.__realtype=="lines"){up["line.width"]=value;up["marker.size"]=value}else if(this.__realtype=="markers"){up["marker.size"]=value}this.__graph.__todo(up,this.__id)}}}},horizontal:{get:function(){return this.__horizontal},set:function(value){if(this.__horizontal==value)return;this.__horizontal=value;if(this.__graph.fast)this.options[this.__realtype].horizontal=value;if(this.__activated){if(this.__graph.fast){this.__graph.__changed=true}else{if(value)this.__graph.__todo({orientation:"h"},this.__id);else this.__graph.__todo({orientation:"v"},this.__id)}}}},orientation:{get:function(){var ret=this.__horizontal?"h":"v";return ret},set:function(value){var m=value.match(/([^\n])*/);value=m[0];this.__orientation=value;if(value=="v")this.__horizontal=false;else if(value=="h")this.__horizontal=true;else throw new Error("orientation must be either 'v' for vertical or 'h' for horizontal");if(this.__activated){if(this.__graph.fast)this.__graph.__changed=true;else this.__graph.__todo({orientation:value},this.__id)}}},dot:{get:function(){return this.__dot},set:function(value){if(this.__activated)throw new Error("Cannot change gcurve dot after the gcurve has been activated.");if(this.__dot==value)return;this.__dot=value}},dot_color:{get:function(){return this.__dot_color},set:function(value){if(!(value instanceof vec))throw new Error("graph dot_color must be a vector.");if(this.__dot_color.equals(value))return;this.__dot_color=value;var col=color.to_html(value);if(this.__graph.fast){this.options.dot_color=col;this.__graph.__changed=true}else if(this.__dotobject.__activated){var up={};up["marker.color"]=col;this.__graph.__todo(up,this.__dotobject.__id)}}},dot_radius:{get:function(){return this.__dot_radius},set:function(value){if(this.__dot_radius==value)return;this.__dot_radius=value;if(this.__graph.fast){this.options.dot_radius=value;this.__graph.__changed=true}else if(this.__dotobject.__activated){var up={};up["marker.size"]=2*value;this.__graph.__todo(up,this.__dotobject.__id)}}},visible:{get:function(){return this.__visible},set:function(value){if(this.__visible==value)return;this.__visible=value;if(this.__activated){if(!this.__graph.fast)this.__graph.__todo({visible:value},this.__id);this.__graph.__changed=true}}}});function render_graph(grf){function grender(){window.requestAnimationFrame(grender);grf.__update()}grender()}function series(options){var ret=new gobject(options);if(ret.dot){options={type:"scatter",color:ret.__dot_color,radius:ret.__dot_radius};ret.__dotobject=new gobject(options)}return ret}function gcurve(options){options=options||{};options.type="lines";if(options.pos!==undefined){options.data=options.pos;delete options.pos}if(options.size!==undefined){options.dot_radius=options.size/2;delete options.size}var ret=new gobject(options);if(!ret.__graph.fast){if(ret.dot)ret.__dotobject=gdots({color:ret.__dot_color,radius:ret.__dot_radius,__lineobj:ret});if(ret.markers)ret.__markerobject=gdots({color:ret.__marker_color,radius:ret.__radius,__markerobj:ret})}return ret}function gdots(options){options=options||{};options.type="scatter";if(options.pos!==undefined){options.data=options.pos;delete options.pos}return new gobject(options)}function gvbars(options){options=options||{};options.type="bar";options.horizontal=false;if(options.pos!==undefined){options.data=options.pos;delete options.pos}return new gobject(options)}function ghbars(options){options=options||{};options.type="bar";options.horizontal=true;if(options.pos!==undefined){options.data=options.pos;delete options.pos}return new gobject(options)}function ghistogram(options){throw new Error("ghistogram is not currently implemented in GlowScript.")}var exports={graph:graph,gdisplay:graph,series:series,gcurve:gcurve,gdots:gdots,gvbars:gvbars,ghbars:ghbars,ghistogram:ghistogram};Export(exports)})();(function(){"use strict";var color={red:vec(1,0,0),green:vec(0,1,0),blue:vec(0,0,1),yellow:vec(1,1,0),orange:vec(1,.6,0),cyan:vec(0,1,1),magenta:vec(1,0,1),purple:vec(.4,.2,.6),white:vec(1,1,1),black:vec(0,0,0),gray:function(g){return vec(g,g,g)},hsv_to_rgb:function(hsv){var h=hsv.x;var s=hsv.y;var v=hsv.z;if(s==0){return vec(v,v,v)}var i=Math.floor(6*h);var f=6*h-i;var p=v*(1-s);var q=v*(1-s*f);var t=v*(1-s*(1-f));var i=i%6;switch(i){case 0:return vec(v,t,p);case 1:return vec(q,v,p);case 2:return vec(p,v,t);case 3:return vec(p,q,v);case 4:return vec(t,p,v);case 5:return vec(v,p,q)}},rgb_to_hsv:function(rgb){var r=rgb.x;var g=rgb.y;var b=rgb.z;var maxc=Math.max(r,g,b);var minc=Math.min(r,g,b);var v=maxc;if(minc==maxc){return vec(0,0,v)}var s=(maxc-minc)/maxc;var rc=(maxc-r)/(maxc-minc);var gc=(maxc-g)/(maxc-minc);var bc=(maxc-b)/(maxc-minc);var h;if(r==maxc){h=bc-gc}else if(g==maxc){h=2+rc-bc}else{h=4+gc-rc}h=h/6;if(h<0)h++;return vec(h,s,v)},to_html:function(color){var r=Math.floor(255*color.x);var g=Math.floor(255*color.y);var b=Math.floor(255*color.z);return"rgb("+r+","+g+","+b+")"},to_html_rgba:function(color,opacity){var r=Math.floor(255*color.x);var g=Math.floor(255*color.y);var b=Math.floor(255*color.z);return"rgba("+r+","+g+","+b+","+opacity+")"}};var exports={color:color};Export(exports)})();(function(){"use strict";var npdefault=64;function shape_object(){}shape_object.prototype.roundc=function roundc(cps,args){var cp=[],i;for(i=0;i0){outer=this.roundc(outer,{roundness:args.roundness,invert:args.invert});inner=this.roundc(inner,{roundness:args.roundness,invert:args.invert})}return[outer,inner]};shape_object.prototype.rectangle=function rectangle(args){args=args||{};if(args.pos===undefined)args.pos=[0,0];if(args.width===undefined)args.width=1;if(args.height===undefined)args.height=null;if(args.rotate===undefined)args.rotate=0;if(args.thickness===undefined)args.thickness=0;if(args.roundness===undefined)args.roundness=0;if(args.invert===undefined)args.invert=false;if(args.scale===undefined)args.scale=1;if(args.xscale===undefined)args.xscale=1;if(args.yscale===undefined)args.yscale=1;var w2,h2,cp;if(args.height===null){args.height=args.width}if(args.thickness===0){cp=[];w2=args.width/2;h2=args.height/2;cp=[[w2,-h2],[w2,h2],[-w2,h2],[-w2,-h2],[w2,-h2]];cp=this.addpos(args.pos,cp);if(args.rotate!==0)cp=this.rotatecp(cp,args.pos,args.rotate);if(args.scale!==1)args.xscale=args.yscale=args.scale;if(args.xscale!==1||args.yscale!==1)cp=this.scale(cp,args.xscale,args.yscale);if(args.roundness>0)cp=this.roundc(cp,{roundness:args.roundness,invert:args.invert})}else{cp=this.rframe(args)}return cp};shape_object.prototype.cross=function cross(args){args=args||{};if(args.pos===undefined)args.pos=[0,0];if(args.width===undefined)args.width=1;if(args.rotate===undefined)args.rotate=0;if(args.thickness===undefined)args.thickness=.2;if(args.roundness===undefined)args.roundness=0;if(args.invert===undefined)args.invert=false;if(args.scale===undefined)args.scale=1;if(args.xscale===undefined)args.xscale=1;if(args.yscale===undefined)args.yscale=1;var wtp,w2,t2,cp;wtp=(args.width+args.thickness)/2;w2=args.width/2;t2=args.thickness/2;cp=[[w2,-t2],[w2,t2],[t2,t2],[t2,w2],[-t2,w2],[-t2,t2],[-w2,t2],[-w2,-t2],[-t2,-t2],[-t2,-w2],[t2,-w2],[t2,-t2],[w2,-t2]];cp=this.addpos(args.pos,cp);if(rotate!==0)cp=this.rotatecp(cp,args.pos,args.rotate);if(args.scale!==1)args.xscale=args.yscale=args.scale;if(args.xscale!==1||args.yscale!==1)cp=this.scale(cp,args.xscale,args.yscale);if(args.roundness>0)cp=this.roundc(cp,{roundness:args.roundness,invert:args.invert});return cp};shape_object.prototype.trframe=function trframe(args){args=args||{};if(args.pos===undefined)args.pos=[0,0];if(args.width===undefined)args.width=2;if(args.height===undefined)args.height=1;if(args.top===undefined)args.top=null;if(args.rotate===undefined)args.rotate=0;if(args.thickness===undefined)args.thickness=0;if(args.roundness===undefined)args.roundness=0;if(args.invert===undefined)args.invert=false;if(args.scale===undefined)args.scale=1;if(args.xscale===undefined)args.xscale=1;if(args.yscale===undefined)args.yscale=1;var angle,db,outer,inner;if(args.top===null){args.top=width/2}if(args.thickness===null){args.thickness=min(args.height,args.top)*.2}else{args.thickness=min(args.height,args.top)*args.thickness*2}outer=this.trapezoid({pos:args.pos,width:args.width,height:args.height,top:args.top});angle=Math.atan((args.width-args.top)/2/args.height);db=args.thickness/Math.cos(angle);inner=this.trapezoid({pos:args.pos,width:args.width-db-args.thickness*Math.tan(angle),height:args.height-args.thickness,top:args.top-(db-args.thickness*Math.tan(angle))});outer=this.addpos(args.pos,outer);inner=this.addpos(args.pos,inner);if(args.rotate!==0){outer=this.rotatecp(outer,args.pos,args.rotate);inner=this.rotatecp(inner,args.pos,args.rotate)}if(args.scale!==1)args.xscale=args.yscale=args.scale;if(args.xscale!==1||args.yscale!==1){outer=this.scale(outer,args.xscale,args.yscale);inner=this.scale(inner,args.xscale,args.yscale)}if(args.roundness>0){outer=this.roundc(outer,{roundness:args.roundness,invert:args.invert});inner=this.roundc(inner,{roundness:args.roundness,invert:args.invert})}return[outer,inner]};shape_object.prototype.trapezoid=function trapezoid(args){args=args||{};if(args.pos===undefined)args.pos=[0,0];if(args.width===undefined)args.width=2;if(args.height===undefined)args.height=1;if(args.top===undefined)args.top=null;if(args.rotate===undefined)args.rotate=0;if(args.thickness===undefined)args.thickness=0;if(args.roundness===undefined)args.roundness=0;if(args.invert===undefined)args.invert=false;if(args.scale===undefined)args.scale=1;if(args.xscale===undefined)args.xscale=1;if(args.yscale===undefined)args.yscale=1;var w2,h2,t2,cp;w2=args.width/2;h2=args.height/2;if(args.top===null){args.top=w2}t2=args.top/2;if(args.thickness===0){cp=[[w2,-h2],[t2,h2],[-t2,h2],[-w2,-h2],[w2,-h2]];cp=this.addpos(args.pos,cp);if(args.rotate!==0)cp=this.rotatecp(cp,args.pos,args.rotate);if(args.scale!==1)args.xscale=args.yscale=args.scale;if(args.xscale!==1||args.yscale!==1)cp=this.scale(cp,args.xscale,args.yscale);if(args.roundness>0)cp=this.roundc(cp,{roundness:args.roundness,invert:args.invert})}else{cp=this.trframe(args)}return cp};shape_object.prototype.circframe=function circframe(args){args=args||{};if(args.pos===undefined)args.pos=[0,0];if(args.radius===undefined)args.radius=.5;if(args.iradius===undefined)args.iradius=null;if(args.np===undefined)args.np=npdefault;if(args.scale===undefined)args.scale=1;if(args.xscale===undefined)args.xscale=1;if(args.yscale===undefined)args.yscale=1;if(args.angle1===undefined)args.angle1=0;if(args.angle2===undefined)args.angle2=2*Math.PI;if(args.rotate===undefined)args.rotate=0;args.thickness=0;var outer,inner;if(args.iradius===null)args.iradius=args.radius*.8;outer=this.circle(args);if(args.angle1===0&&args.angle2==2*Math.PI){args.radius=args.iradius}else{var t=args.radius-args.iradius;var angle=(args.angle1+args.angle2)/2;var offset=t/Math.sin((args.angle2-args.angle1)/2);args.corner=[args.pos[0]+offset*Math.cos(angle),args.pos[1]+offset*Math.sin(angle)];var dangle=Math.asin(t/args.iradius);args.angle1=args.angle1+dangle;args.angle2=args.angle2-dangle;args.radius=args.iradius}inner=this.circle(args);if(args.rotate!==0){outer=this.rotatecp(outer,args.pos,args.rotate);inner=this.rotatecp(inner,args.pos,args.rotate)}if(args.scale!==1)args.xscale=args.yscale=args.scale;if(args.xscale!==1||args.yscale!==1){outer=this.scale(outer,args.xscale,args.yscale);inner=this.scale(inner,args.xscale,args.yscale)}return[outer,inner]};shape_object.prototype.circle=function circle(args){args=args||{};if(args.pos===undefined)args.pos=[0,0];var corner=args.pos;if(args.corner!==undefined)corner=args.corner;if(args.radius===undefined)args.radius=.5;if(args.np===undefined)args.np=npdefault;if(args.scale===undefined)args.scale=1;if(args.xscale===undefined)args.xscale=1;if(args.yscale===undefined)args.yscale=1;if(args.thickness===undefined)args.thickness=0;if(args.angle1===undefined)args.angle1=0;if(args.angle2===undefined)args.angle2=2*Math.PI;if(args.rotate===undefined)args.rotate=0;var seg,nseg,dc,ds,x0,y0,c2,s2,c,s,i,cp;cp=[];if(args.thickness>0){args.iradius=args.radius-args.radius*args.thickness;cp=this.circframe(args)}else{if(args.angle1!==0||args.angle2!==2*Math.PI){cp.push([corner[0],corner[1]])}seg=2*Math.PI/args.np;nseg=Math.floor(Math.abs((args.angle2-args.angle1)/seg+.5));seg=(args.angle2-args.angle1)/nseg;if(args.angle1!==0||args.angle2!==2*Math.PI){nseg+=1}c=args.radius*Math.cos(args.angle1);s=args.radius*Math.sin(args.angle1);dc=Math.cos(seg);ds=Math.sin(seg);x0=args.pos[0];y0=args.pos[1];cp.push([x0+c,y0+s]);for(i=0;i0){outer=this.roundc(outer,{roundness:args.roundness,invert:args.invert});inner=this.roundc(inner,{roundness:args.roundness,invert:args.invert})}return[outer,inner]};shape_object.prototype.ngon=function ngon(args){args=args||{};if(args.thickness===undefined)args.thickness=0;if(args.pos===undefined)args.pos=[0,0];if(args.length===undefined)args.length=1;if(args.rotate===undefined)args.rotate=0;if(args.roundness===undefined)args.roundness=0;if(args.invert===undefined)args.invert=false;if(args.scale===undefined)args.scale=1;if(args.xscale===undefined)args.xscale=1;if(args.yscale===undefined)args.yscale=1;if(args.np===undefined)args.np=3;var seg,x,y,angle,radius,i,cp;cp=[];if(args.np<3)throw Error("number of sides can not be less than 3");angle=2*Math.PI/args.np;radius=args.length/2/Math.sin(angle/2);if(args.thickness===0){seg=2*Math.PI/args.np;angle=0;for(i=0;i0)cp=this.roundc(cp,{roundness:args.roundness,invert:args.invert})}else{cp=this.nframe(args)}return cp};shape_object.prototype.triangle=function triangle(args){args=args||{};if(args.rotate===undefined)args.rotate=0;args.np=3;args.rotate=args.rotate-Math.PI/6;return this.ngon(args)};shape_object.prototype.pentagon=function pentagon(args){args=args||{};if(args.rotate===undefined)args.rotate=0;args.np=5;args.rotate=args.rotate+Math.PI/10;return this.ngon(args)};shape_object.prototype.hexagon=function hexagon(args){args=args||{};if(args.rotate===undefined)args.rotate=0;args.np=6;return this.ngon(args)};shape_object.prototype.octagon=function octagon(args){args=args||{};if(args.rotate===undefined)args.rotate=0;args.np=8;args.rotate=args.rotate+Math.PI/8;return this.ngon(args)};shape_object.prototype.sframe=function sframe(args){args=args||{};if(args.pos===undefined)args.pos=[0,0];if(args.radius===undefined)args.radius=1;if(args.n===undefined)args.n=5;if(args.iradius===undefined)args.iradius=null;if(args.rotate===undefined)args.rotate=0;if(args.thickness===undefined)args.thickness=0;if(args.roundness===undefined)args.roundness=0;if(args.invert===undefined)args.invert=false;if(args.scale===undefined)args.scale=1;if(args.xscale===undefined)args.xscale=1;if(args.yscale===undefined)args.yscale=1;var outer,inner,cp;if(args.iradius===null){args.iradius=.5*args.radius}if(args.thickness===null){args.thickness=.2*args.radius}else{args.thickness=args.thickness*2*args.iradius}outer=this.star({pos:args.pos,n:args.n,radius:args.radius,iradius:args.iradius});inner=this.star({pos:args.pos,n:args.n,radius:args.radius-args.thickness,iradius:(args.radius-args.thickness)*args.iradius/args.radius});if(args.rotate!==0){outer=this.rotatecp(outer,args.pos,args.rotate);inner=this.rotatecp(inner,args.pos,args.rotate)}if(args.scale!==1)args.xscale=args.yscale=args.scale;if(args.xscale!==1||args.yscale!==1){outer=this.scale(outer,args.xscale,args.yscale);inner=this.scale(inner,args.xscale,args.yscale)}if(args.roundness>0){outer=this.roundc(outer,{roundness:args.roundness,invert:args.invert});inner=this.roundc(inner,{roundness:args.roundness,invert:args.invert})}return[outer,inner]};shape_object.prototype.star=function star(args){args=args||{};if(args.pos===undefined)args.pos=[0,0];if(args.radius===undefined)args.radius=1;if(args.n===undefined)args.n=5;if(args.iradius===undefined)args.iradius=null;if(args.rotate===undefined)args.rotate=0;if(args.thickness===undefined)args.thickness=0;if(args.roundness===undefined)args.roundness=0;if(args.invert===undefined)args.invert=false;if(args.scale===undefined)args.scale=1;if(args.xscale===undefined)args.xscale=1;if(args.yscale===undefined)args.yscale=1;var dtheta,theta,i,cp;if(args.iradius===null)args.iradius=args.radius*.5;if(args.thickness===0){cp=[];dtheta=Math.PI/args.n;theta=0;for(i=0;i<2*args.n+1;i++){if(i%2===0){cp.push([-args.radius*Math.sin(theta),args.radius*Math.cos(theta)])}else{cp.push([-args.iradius*Math.sin(theta),args.iradius*Math.cos(theta)])}theta+=dtheta}cp=this.addpos(args.pos,cp);cp[cp.length-1]=cp[0];if(args.rotate!==0)cp=this.rotatecp(cp,args.pos,args.rotate);if(args.scale!==1)args.xscale=args.yscale=args.scale;if(args.xscale!==1||args.yscale!==1)cp=this.scale(cp,args.xscale,args.yscale);if(args.roundness>0)cp=this.roundc(cp,{roundness:args.roundness,invert:args.invert})}else{cp=this.sframe(args)}return cp};shape_object.prototype.points=function points(args){args=args||{};var path=false;if(args.pos===undefined)args.pos=[];if(args.rotate===undefined)args.rotate=0;if(args.roundness===undefined)args.roundness=0;if(args.invert===undefined)args.invert=false;if(args.scale===undefined)args.scale=1;if(args.xscale===undefined)args.xscale=1;if(args.yscale===undefined)args.yscale=1;if(args.path===undefined)path=args.path;var closed,cp;cp=args.pos;closed=cp[cp.length-1][0]===cp[0][0]&&cp[cp.length-1][1]===cp[0][1];if(!closed&&!path)cp.push(cp[0]);if(cp.length&&args.rotate!==0)cp=this.rotatecp(cp,cp[0],args.rotate);if(args.scale!==1)args.xscale=args.yscale=args.scale;if(args.xscale!==1||args.yscale!==1)cp=this.scale(cp,args.xscale,args.yscale);if(args.roundness>0)cp=this.roundc(cp,{roundness:args.roundness,invert:args.invert});return cp};shape_object.prototype.ToothOutline=function ToothOutline(args){args=args||{};if(args.n===undefined)args.n=30;if(args.res===undefined)args.res=1;if(args.phi===undefined)args.phi=20;if(args.radius===undefined)args.radius=50;if(args.addendum===undefined)args.addendum=.4;if(args.dedendum===undefined)args.dedendum=.5;if(args.fradius===undefined)args.fradius=.1;if(args.bevel===undefined)args.bevel=.05;var TOOTHGEO,R,DiametralPitch,ToothThickness,CircularPitch,U1,U2,ThetaA1,ThetaA2,ThetaA3;var A,pts,normals,i,Aw,r,u,xp,yp,auxth,m,rA,xc,yc,P0,Ra,th,N,P,V;TOOTHGEO={PitchRadius:args.radius,TeethN:args.n,PressureAng:args.phi,Addendum:args.addendum,Dedendum:args.dedendum,Fillet:args.fradius,Bevel:args.bevel,Resolution:args.res};R={Bottom:TOOTHGEO["PitchRadius"]-TOOTHGEO["Dedendum"]-TOOTHGEO["Fillet"],Ded:TOOTHGEO["PitchRadius"]-TOOTHGEO["Dedendum"],Base:TOOTHGEO["PitchRadius"]*cos(TOOTHGEO["PressureAng"]*Math.PI/180),Bevel:TOOTHGEO["PitchRadius"]+TOOTHGEO["Addendum"]-TOOTHGEO["Bevel"],Add:TOOTHGEO["PitchRadius"]+TOOTHGEO["Addendum"]};DiametralPitch=TOOTHGEO["TeethN"]/(2*TOOTHGEO["PitchRadius"]);ToothThickness=Math.PI/2/DiametralPitch;CircularPitch=Math.PI/DiametralPitch;U1=sqrt((1-Math.cos(TOOTHGEO["PressureAng"]*Math.PI/1800))/Math.cos(TOOTHGEO["PressureAng"]*Math.PI/180));U2=sqrt(R["Bevel"]*R["Bevel"]/(R["Ded"]*R["Ded"])-1);ThetaA1=Math.atan((sin(U1)-U1*Math.cos(U1))/(Math.cos(U1)+U1*Math.sin(U1)));ThetaA2=Math.atan((sin(U2)-U2*Math.cos(U2))/(Math.cos(U2)+U2*Math.sin(U2)));ThetaA3=ThetaA1+ToothThickness/(TOOTHGEO["PitchRadius"]*2);A={Theta0:CircularPitch/(TOOTHGEO["PitchRadius"]*2),Theta1:ThetaA3+TOOTHGEO["Fillet"]/R["Ded"],Theta2:ThetaA3,Theta3:ThetaA3-ThetaA2,Theta4:ThetaA3-ThetaA2-TOOTHGEO["Bevel"]/R["Add"]};N=TOOTHGEO["Resolution"];pts=[];normals=[];for(i=0;i<2*N;i++){th=(A["Theta1"]-A["Theta0"])*i/(2*N-1)+A["Theta0"];pts.push([R["Bottom"]*Math.cos(th),R["Bottom"]*Math.sin(th)]);normals.push([-Math.cos(th),-Math.sin(th)])}xc=R["Ded"]*Math.cos(A["Theta1"]);yc=R["Ded"]*Math.sin(A["Theta1"]);Aw=Math.PI/2+A["Theta2"]-A["Theta1"];for(i=0;iright)right=x;if(ytop)top=y}center=[(left+right)/2,(bottom+top)/2];dx=args.pos[0]-center[0];dy=args.pos[1]-center[1];gear2=[];for(i=0;i0;axis=up0.cross(args.up);p=[];for(i=0;i=16777216){R=Math.floor(N/16777216);N-=R*16777216}if(N>=65536){G=Math.floor(N/65536);N-=G*65536}if(N>=256){B=Math.floor(N/256);N-=B*256}return[R/255,G/255,B/255,N/255]}function RSdict_to_JSobjectliteral(args){return args}function init(obj,args){if(obj.constructor==text)return;if(window.__GSlang=="vpython"&&args.display!==undefined){args.canvas=args.display;delete args.display}if(args.canvas!==undefined){obj.canvas=args.canvas;delete args.canvas}else{obj.canvas=canvas.selected}if(obj.canvas){if(!(obj.constructor==distant_light||obj.constructor==local_light))obj.canvas.__activate();obj.__model=obj.__get_model()}if(args.__obj){obj.__obj=args.__obj;delete args.__obj}if(args.radius!==undefined){obj.radius=args.radius;delete args.radius}if(args.size_units!==undefined){obj.size_units=args.size_units;delete args.size_units}if(args.axis!==undefined){if(args.axis.mag2===0)obj.__oldaxis=vec(1,0,0);obj.axis=args.axis;delete args.axis}if(args.size!==undefined){obj.size=args.size;delete args.size}if(args.up!==undefined){if(args.up.mag2===0)obj.__oldup=vec(0,1,0);obj.up=args.up;delete args.up}if(args.color!==undefined){obj.color=args.color;delete args.color}obj.__interval=-1;if(obj.constructor!=curve&&obj.constructor!=points&&args.make_trail!==undefined){obj.__make_trail=args.make_trail;delete args.make_trail;obj.__trail_type="curve";if(args.trail_type!==undefined){if(args.trail_type!="curve"&&args.trail_type!="points"&&args.trail_type!="spheres")throw new Error("trail_type = "+args.trail_type+" but must be 'curve' or 'points' (or 'spheres').");obj.__trail_type=args.trail_type;delete args.trail_type}if(args.interval!==undefined){obj.__interval=args.interval;delete args.interval}else if(obj.__trail_type!="curve"){obj.__interval=1}if(args.retain!==undefined){obj.__retain=args.retain;delete args.retain}else obj.__retain=-1;obj.__trail_color=color.white;if(obj.color!==undefined)obj.__trail_color=obj.color;if(args.trail_color!==undefined){obj.__trail_color=args.trail_color;delete args.trail_color}obj.__trail_radius=0;if(args.trail_radius!==undefined){obj.__trail_radius=args.trail_radius;delete args.trail_radius}else{if(obj.__trail_type=="points")obj.__trail_radius=.1*obj.__size.y}obj.__pps=0;if(args.pps!==undefined){if(obj.__interval>0){if(obj.__trail_type!="curve")throw new Error("pps cannot be used with a "+obj.__trail_type+"-type trail");else throw new Error("pps cannot be used with interval > 0")}obj.__pps=args.pps;delete args.pps}obj.__trail_object=attach_trail(obj,{type:obj.__trail_type,color:obj.__trail_color,radius:obj.__trail_radius,pps:obj.__pps,retain:obj.__retain});if(args.pos!==undefined&&obj.__make_trail)obj.__trail_object.__trail.push(args.pos);if(!obj.__make_trail)obj.__trail_object.stop();obj.__ninterval=0}obj._pos_set=args.pos!==undefined;for(var id in args)obj[id]=args[id];if(args.visible===undefined&&obj.canvas!==null)obj.visible=true}function initObject(obj,constructor,args){if(!(obj instanceof constructor))return new constructor(args);args=args||{};obj.__tex={file:null,bumpmap:null,texture_ref:{reference:null},bumpmap_ref:{reference:null},left:false,right:false,sides:false,flipx:false,flipy:false,turn:0,flags:0};if(constructor==curve)obj.origin=obj.origin;if(constructor!=curve&&constructor!=points&&constructor!=text){obj.pos=obj.pos}if(constructor!=points&&constructor!=text){if(constructor==arrow){if(args.axis!==undefined)throw new Error("arrow does not have axis; replace with axis_and_length");else obj.axis_and_length=obj.axis_and_length}else if(constructor==vp_arrow&&args.axis_and_length!==undefined){throw new Error("VPython arrow does not have axis_and_length; replace with axis")}else obj.axis=obj.axis;obj.up=obj.up;obj.size=obj.size;obj.color=obj.color}obj.__sizing=false;if(window.__GSlang=="vpython"&&!(constructor==vp_sphere||constructor==vp_ring||constructor==text||constructor==vp_compound||constructor==compound))obj.__sizing=true;if(args.opacity===undefined)obj.__opacity=1;if(args.make_trail===undefined)obj.__make_trail=false;obj.__opacity_change=true;init(obj,args)}var nextVisibleId=1;var textures={flower:":flower_texture.jpg",granite:":granite_texture.jpg",gravel:":gravel_texture.jpg",earth:":earth_texture.jpg",metal:":metal_texture.jpg",rock:":rock_texture.jpg",rough:":rough_texture.jpg",rug:":rug_texture.jpg",stones:":stones_texture.jpg",stucco:":stucco_texture.jpg",wood:":wood_texture.jpg",wood_old:":wood_old_texture.jpg"};var bumpmaps={gravel:":gravel_bumpmap.jpg",rock:":rock_bumpmap.jpg",stones:":stones_bumpmap.jpg",stucco:":stucco_bumpmap.jpg",wood_old:":wood_old_bumpmap.jpg"};function setup_texture(name,obj,isbump){if(name.slice(0,1)==":"){var jv=window.Jupyter_VPython;if(jv!==undefined){name=jv+name.slice(1)}else{if(navigator.onLine)name="https://s3.amazonaws.com/glowscript/textures/"+name.slice(1);else name="../lib/FilesInAWS/"+name.slice(1)}}obj.canvas.__renderer.initTexture(name,obj,isbump)}function Primitive(){}property.declare(Primitive.prototype,{__id:null,__hasPosAtCenter:false,__deleted:false,__zx_camera:null,__zy_camera:null,__xmin:null,__ymin:null,__zmin:null,__xmax:null,__ymax:null,__zmax:null,pos:new attributeVectorPos(null,0,0,0),size:new attributeVector(null,1,1,1),axis:new attributeVectorAxis(null,1,0,0),up:new attributeVectorUp(null,0,1,0),color:new attributeVector(null,1,1,1),opacity:{get:function(){return this.__opacity},set:function(value){if(value==this.__opacity)return;if(this.__opacity<1&&value==1||this.__opacity==1&&value<1){this.__opacity_change=true}this.__opacity=value;this.__change()}},x:{get:function(){throw new Error('"object.x" is not supported; perhaps you meant "object.pos.x"')},set:function(value){throw new Error('"object.x" is not supported; perhaps you meant "object.pos.x"')}},y:{get:function(){throw new Error('"object.y" is not supported; perhaps you meant "object.pos.y"')},set:function(value){throw new Error('"object.y" is not supported; perhaps you meant "object.pos.y"')}},z:{get:function(){throw new Error('"object.z" is not supported; perhaps you meant "object.pos.z"')},set:function(value){throw new Error('"object.z" is not supported; perhaps you meant "object.pos.z"')}},__opacity_change:false,__prev_opacity:null,shininess:{value:.6,onchanged:function(){this.__change()}},emissive:{value:false,onchanged:function(){this.__change()}},pickable:{value:true,onchanged:function(){this.__change()}},ready:{get:function(){return this.__tex.file===null||this.__tex.texture_ref.reference!==null&&this.__tex.bumpmap===null||this.__tex.bumpmap_ref.reference!==null}},make_trail:{get:function(){return this.__make_trail},set:function(value){if(this.__make_trail!==value){if(value){this.__trail_object.start();this.__trail_object.__trail.push(this.__pos)}else this.__trail_object.stop();this.__make_trail=value}}},retain:{get:function(){return this.__retain},set:function(value){this.__retain=value;if(this.__trail_object!==undefined)this.__trail_object.retain=value}},trail_type:{get:function(){if(this.__trail_type=="curve")return"curve";else if(this.__trail_type=="spheres")return"points";else return this.__trail_type},set:function(value){throw new Error('"trail_type" cannot be changed.')}},trail_color:{get:function(){return this.__color},set:function(value){this.__trail_color=value;if(this.__trail_object!==undefined)this.__trail_object.color=value}},trail_radius:{get:function(){return this.__radius},set:function(value){this.__trail_radius=value;if(this.__trail_object!==undefined)this.__trail_object.radius=value}},pps:{get:function(){return this.__pps},set:function(value){this.__pps=value;if(this.__trail_object!==undefined)this.__trail_object.pps=value}},clear_trail:function(){if(this.__trail_object!==undefined)this.__trail_object.clear()},__update_trail:function(v){if(!this.__trail_object.__run||!this.visible)return;if(this.__interval===-1)return;this.__ninterval++;var update=false;if(this.__ninterval>=this.__interval){this.__ninterval=0;update=true}else if(this.__ninterval==1&&this.__trail_object.__trail.__points.length===0)update=true;if(update){if(this.__retain==-1)this.__trail_object.__trail.push({pos:v,color:this.__trail_color,radius:this.__trail_radius});else this.__trail_object.__trail.push({pos:v,color:this.__trail_color,radius:this.__trail_radius,retain:this.__retain})}},texture:{get:function(){return{file:this.__tex.file,bumpmap:this.__tex.bumpmap,left:this.__tex.left,right:this.__tex.right,sides:this.__tex.sides,flipx:this.__tex.flipx,flipy:this.__tex.flipy,turn:this.__tex.turn}},set:function(args){this.__tex={file:null,bumpmap:null,texture_ref:{reference:null},bumpmap_ref:{reference:null},left:false,right:false,sides:false,flipx:false,flipy:false,turn:0,flags:0};if(args===null){}else if(typeof args==="string"){this.__tex.left=this.__tex.right=this.__tex.sides=true;setup_texture(args,this,false)}else{args=RSdict_to_JSobjectliteral(args);if(args.file!==undefined&&typeof args.file==="string"){setup_texture(args.file,this,false)}else throw new Error("You must specify a file name for a texture.");if(args.bumpmap!==undefined){if(args.bumpmap!==null){if(typeof args.bumpmap!=="string")throw new Error("You must specify a file name for a bumpmap.");setup_texture(args.bumpmap,this,true)}}if(args.flipx!==undefined)this.__tex.flipx=args.flipx;if(args.flipy!==undefined)this.__tex.flipy=args.flipy;if(args.turn!==undefined)this.__tex.turn=Math.round(args.turn);if(args.place!==undefined){if(typeof args.place==="string")args.place=[args.place];for(var i=0;i1e-6){if(isarrow)obj.axis_and_length=obj.axis_and_length.rotate({angle:angle,axis:rotaxis});else obj.axis=obj.__axis.rotate({angle:angle,axis:rotaxis});obj.up=obj.__up.rotate({angle:angle,axis:rotaxis})}else{obj.up=obj.__up.rotate({angle:angle,axis:rotaxis})}window.__adjustupaxis=true},getTransformedMesh:function(){var X=this.__axis.norm();var Y=this.__up.norm();var Z=X.cross(Y);var T=this.__pos;if(this instanceof ring||this instanceof vp_ring){var m=Mesh.makeRing_compound(this.__size);var matrix=[X.x,X.y,X.z,0,Y.x,Y.y,Y.z,0,Z.x,Z.y,Z.z,0,T.x,T.y,T.z,1];return m.transformed(matrix)}else{X=X.multiply(this.__size.x);Y=Y.multiply(this.__size.y);Z=Z.multiply(this.__size.z);var matrix=[X.x,X.y,X.z,0,Y.x,Y.y,Y.z,0,Z.x,Z.y,Z.z,0,T.x,T.y,T.z,1];return this.__model.mesh.transformed(matrix)}}});function box(args){return initObject(this,box,args)}subclass(box,Primitive);box.prototype.__hasPosAtCenter=true;function cylinder(args){return initObject(this,cylinder,args)}subclass(cylinder,Primitive);function cone(args){return initObject(this,cone,args)}subclass(cone,cylinder);function pyramid(args){return initObject(this,pyramid,args)}subclass(pyramid,box);function sphere(args){return initObject(this,sphere,args)}subclass(sphere,Primitive);sphere.prototype.__hasPosAtCenter=true;function simple_sphere(args){return initObject(this,simple_sphere,args)}subclass(simple_sphere,Primitive);simple_sphere.prototype.__hasPosAtCenter=true;property.declare(simple_sphere.prototype,{radius:{get:function(){return this.__radius},set:function(value){this.__radius=value;this.size=vec(2*value,2*value,2*value)}},__get_extent:function(ext){var save=this.__size;if(this.__parent&&this.__parent.__pixels){this.__size=vec(0,0,0)}Autoscale.find_extent(this,ext);this.__size=save}});function vp_box(args){return initObject(this,vp_box,args)}subclass(vp_box,box);property.declare(vp_box.prototype,{size:new attributeVectorSize(null,1,1,1),length:{get:function(){return this.__size.__x},set:function(value){this.axis=this.__axis.norm().multiply(value);this.__change()}},height:{get:function(){return this.__size.__y},set:function(value){this.__size.__y=value;this.__change()}},width:{get:function(){return this.__size.__z},set:function(value){this.__size.__z=value;this.__change()}},red:{get:function(){return this.__color.__x},set:function(value){this.__color.__x=value;this.__change()}},green:{get:function(){return this.__color.__y},set:function(value){this.__color.__y=value;this.__change()}},blue:{get:function(){return this.__color.__z},set:function(value){this.__color.__z=value;this.__change()}}});function vp_pyramid(args){return initObject(this,vp_pyramid,args)}subclass(vp_pyramid,vp_box);function vp_sphere(args){return initObject(this,vp_sphere,args)}subclass(vp_sphere,vp_box);property.declare(vp_sphere.prototype,{axis:new attributeVectorAxis(null,1,0,0),size:new attributeVector(null,2,2,2),radius:{get:function(){return this.__size.__y/2},set:function(value){this.size=vec(2*value,2*value,2*value);this.__change()}}});function vp_ellipsoid(args){return initObject(this,vp_ellipsoid,args)}subclass(vp_ellipsoid,vp_box);property.declare(vp_ellipsoid.prototype,{radius:{get:function(){throw new Error("An ellipsoid does not have a radius attribute.")},set:function(value){throw new Error("An ellipsoid does not have a radius attribute.")}}});function vp_cylinder(args){return initObject(this,vp_cylinder,args)}subclass(vp_cylinder,vp_box);property.declare(vp_cylinder.prototype,{size:new attributeVectorSize(null,1,2,2),radius:{get:function(){return this.__size.__y/2},set:function(value){this.__size.__y=this.__size.__z=2*value;this.__change()}}});function vp_cone(args){return initObject(this,vp_cone,args)}subclass(vp_cone,vp_cylinder);function arrow_update(obj,vp){var pos=obj.__pos;var color=obj.__color;var axis;if(vp)axis=obj.__axis;else axis=obj.__axis_and_length;var L=mag(axis);var A=axis.norm();var sw=obj.__shaftwidth||L*.1;var hw=obj.__headwidth||sw*2;var hl=obj.__headlength||sw*3;if(swL*.5){var scale=L*.5/hl;if(!obj.__shaftwidth)sw*=scale;if(!obj.__headwidth)hw*=scale;if(!obj.__headlength)hl*=scale}var components=obj.__components;if(!components){if(vp)components=obj.__components=[vp_box({canvas:obj.canvas,__obj:obj}),vp_pyramid({canvas:obj.canvas,__obj:obj})];else components=obj.__components=[box({canvas:obj.canvas,__obj:obj}),pyramid({canvas:obj.canvas,__obj:obj})]}var shaft=components[0];var tip=components[1];shaft.pos=pos.add(A.multiply(.5*(L-hl)));tip.pos=pos.add(A.multiply(L-hl));shaft.axis=tip.axis=axis;shaft.size=vec(L-hl,sw,sw);tip.size=vec(hl,hw,hw);shaft.color=tip.color=obj.color;shaft.opacity=tip.opacity=obj.opacity;shaft.pickable=tip.pickable=obj.pickable;obj.size=vec(L,hw,hw);shaft.__update();tip.__update()}function arrow(args){if(!(this instanceof arrow))return new arrow(args);this.__shaftwidth=0;this.__headwidth=0;this.__headlength=0;return initObject(this,arrow,args)}subclass(arrow,box);property.declare(arrow.prototype,{__primitiveCount:2,shaftwidth:{get:function(){return this.__shaftwidth},set:function(value){this.__shaftwidth=value;this.__change()}},headwidth:{get:function(){return this.__headwidth},set:function(value){this.__headwidth=value;this.__change()}},headlength:{get:function(){return this.__headlength},set:function(value){this.__headlength=value;this.__change()}},axis_and_length:new attributeVectorAxis(null,1,0,0),axis:{get:function(){new Error("arrow has an axis_and_length attribute but no axis attribute")},set:function(value){new Error("arrow has an axis_and_length attribute but no axis attribute")}},__change:function(){if(this.__components){this.__components[0].__change();this.__components[1].__change()}},__update:function(){arrow_update(this,false)},__get_extent:function(ext){if(!this.__components)this.__update();Autoscale.find_extent(this.__components[0],ext);Autoscale.find_extent(this.__components[1],ext)}});function vp_arrow(args){if(!(this instanceof vp_arrow))return new vp_arrow(args);this.__shaftwidth=0;this.__headwidth=0;this.__headlength=0;return initObject(this,vp_arrow,args)}subclass(vp_arrow,arrow);property.declare(vp_arrow.prototype,{axis:new attributeVectorAxis(null,1,0,0),axis_and_length:{get:function(){new Error("arrow has an axis attribute but no axis_and_length attribute")},set:function(value){new Error("arrow has an axis attribute but no axis_and_length attribute")}},length:{get:function(){return mag(this.__axis)},set:function(val){this.axis=this.__axis.norm().multiply(val)}},__update:function(){arrow_update(this,true)}});function text(args){if(!(this instanceof text))return new text(args);args=args||{};if(args.canvas===null)return;if(args.text===undefined||args.text.length===0)throw new Error("A text object needs non-empty text.");if(args.length!==undefined)throw new Error("The length cannot be specified when constructing 3D text.");if(args.size!==undefined)throw new Error("A text object does not have a size attribute.");args.text=print_to_string(args.text);this.pos=this.pos;this.axis=this.axis;this.up=this.up;this.color=this.color;var cloning=args.__comp!==undefined;if(!cloning){var ret=text3D(args);this.__id=nextVisibleId;nextVisibleId++;this.__comp=ret[0];args=ret[1]}else{this.__id=nextVisibleId;nextVisibleId++}for(var attr in args)this[attr]=args[attr];if(cloning)this.__comp.__pos=this.__pos.add(this.__offset);this.__pseudosize=vec(this.__comp.size);this.__height_fraction=this.__height/this.__comp.size.y;this.__descender_fraction=this.__descender/this.__comp.size.y;args={};initObject(this,text,{});if(this.__billboard){this.canvas.update_billboards=true;this.canvas.billboards.push(this)}if(!cloning){this.__offset=this.__comp.__pos;this.__offset.x/=this.length;this.__offset.y/=this.height;this.__offset.z/=this.depth}}subclass(text,Primitive);property.declare(text.prototype,{size:{get:function(){throw new Error("A text object does not have a size attribute.")},set:function(value){throw new Error("A text object does not have a size attribute.")}},visible:{get:function(){return this.__comp.visible},set:function(value){this.__comp.visible=value}},__update:function(){window.__adjustupaxis=false;this.__comp.axis=this.axis;this.__comp.up=this.up;window.__adjustupaxis=true;var yheight=this.__pseudosize.y;this.__comp.size=vec(this.length,yheight,Math.abs(this.depth));this.__comp.color=this.color;var dz=cross(this.__axis,this.__up).norm();this.__comp.pos=this.__pos.add(this.__axis.norm().multiply(this.__offset.x*this.length)).add(this.__up.norm().multiply(this.__offset.y*this.height)).add(dz.multiply(this.__offset.z*this.depth))},length:{get:function(){return this.__pseudosize.x},set:function(value){if(value===this.__pseudosize.x)return;this.__pseudosize.x=value;this.__change()}},height:{get:function(){return this.__height_fraction*this.__pseudosize.y},set:function(value){this.__pseudosize.y=value/this.__height_fraction;this.__change()}},depth:{get:function(){if(this.__depth>=0)return this.__pseudosize.z;else return-this.__pseudosize.z},set:function(value){var d=this.__depth;if(Math.abs(value)<.01*d){if(value<0)value=-.01*d;else value=.01*d}this.__depth=value;this.__size.z=Math.abs(value);this.__change()}},descender:{get:function(){return this.__descender_fraction*this.__pseudosize.y},set:function(value){throw new Error("descender is read-only")}},opacity:{get:function(){return this.__opacity},set:function(value){this.__comp.opacity=this.__opacity=value;this.__change()}},shininess:{get:function(){return this.__shininess},set:function(value){this.__shininess=this.__comp.shininess=value;this.__change()}},emissive:{get:function(){return this.__emissive},set:function(value){this.__comp.emissive=this.__emissive=value;this.__change()}},texture:{get:function(){throw new Error("Cannot currently apply a texture to a text object")},set:function(value){throw new Error("Cannot currently apply a texture to a text object")}},text:{get:function(){return this.__text},set:function(value){throw new Error("text is read-only")}},font:{get:function(){return this.__font},set:function(value){throw new Error("font is read-only")}},align:{get:function(){return this.__align},set:function(value){throw new Error("align is read-only")}},billboard:{get:function(){return this.__billboard},set:function(value){throw new Error("billboard is read-only")}},show_start_face:{get:function(){return this.__show_start_face},set:function(value){throw new Error("show_start_face is read-only")}},show_end_face:{get:function(){return this.__show_end_face},set:function(value){throw new Error("show_end_face is read-only")}},start_face_color:{get:function(){return this.__start_face_color},set:function(value){throw new Error("start_face_color is read-only")}},end_face_color:{get:function(){return this.__end_face_color},set:function(value){throw new Error("end_face_color is read-only")}},start:{get:function(){return this.upper_left.sub(this.up.norm().multiply(this.height))},set:function(value){throw new Error("start is read-only")}},end:{get:function(){return this.upper_right.sub(this.up.norm().multiply(this.height))},set:function(value){throw new Error("end is read-only")}},vertical_spacing:{get:function(){return 1.5*this.height},set:function(value){throw new Error("vertical_spacing is read-only")}},upper_left:{get:function(){var dx=0;if(this.__align=="right")dx=-this.length;else if(this.__align=="center")dx=-this.length/2;return this.pos.add(this.up.norm().multiply(this.height)).add(this.axis.norm().multiply(dx))},set:function(value){throw new Error("upper_left is read-only")}},upper_right:{get:function(){return this.upper_left.add(this.axis.norm().multiply(this.length))},set:function(value){throw new Error("upper_right is read-only")}},lower_left:{get:function(){return this.upper_left.add(this.up.norm().multiply(-this.height-this.descender-1.5*this.height*(this.__lines-1)))},set:function(value){throw new Error("lower_left is read-only")}},lower_right:{get:function(){return this.lower_left.add(this.axis.norm().multiply(this.length))},set:function(value){throw new Error("lower_right is read-only")}},lines:{get:function(){return this.__lines},set:function(value){throw new Error("lines is read-only")}}});function vertex(args){if(!(this instanceof vertex)){return new vertex(args)}args=args||{};if(args.canvas!==undefined){this.canvas=args.canvas}else if(args.display!==undefined){this.canvas=args.display}else{this.canvas=canvas.selected}for(var attr in args){if(attr=="canvas"||attr=="display")continue;this[attr]=args[attr]}if(this.opacity===undefined)this.opacity=1;if(this.__texpos.z!==0)throw new Error("In a vertex the z component of texpos must be zero.");if(this.canvas.vertex_id>=65536)throw new Error("Currently the number of vertices is limited to 65536.");var lengths={pos:3,normal:3,color:3,opacity:1,shininess:1,emissive:1,texpos:2,bumpaxis:3};this.__id=this.canvas.__vertices.available.pop();if(this.__id===undefined){this.__id=this.canvas.vertex_id;var c=this.canvas.__vertices;if(this.canvas.vertex_id%c.Nalloc===0){var temp;var L=this.canvas.vertex_id+c.Nalloc;for(var t in lengths){temp=new Float32Array(lengths[t]*L);temp.set(c[t],0);c[t]=temp}}this.canvas.vertex_id++}this.canvas.__vertices.object_info[this.__id]={};this.__change()}property.declare(vertex.prototype,{__id:null,__hasPosAtCenter:true,pos:new attributeVector(null,0,0,0),normal:new attributeVector(null,0,0,1),color:new attributeVector(null,1,1,1),opacity:{get:function(){return this.__opacity},set:function(value){if(value==this.__opacity)return;if(this.__opacity<1&&value==1||this.__opacity==1&&value<1){var users=this.canvas.__vertices.object_info[this.__id];for(var u in users){users[u].__change();users[u].__opacity_change=true}}this.__opacity=value;this.canvas.__vertex_changed[this.__id]=this}},texpos:new attributeVector(null,0,0,0),bumpaxis:new attributeVector(null,1,0,0),shininess:{value:.6,onchanged:function(){this.__change()}},emissive:{value:false,onchanged:function(){this.__change()}},__change:function(){if(this.__id){this.canvas.__vertex_changed[this.__id]=this;if(this.canvas.__autoscale){var users=this.canvas.__vertices.object_info[this.__id];for(var u in users)users[u].__change()}}},rotate:function(args){if(args.angle===undefined){throw new Error("vertex.rotate() requires angle:...")}var angle=args.angle;if(args.axis===undefined){throw new Error("vertex.rotate() requires axis:...")}var axis=args.axis.norm();var origin;if(args.origin===undefined){origin=vec(0,0,0)}else origin=args.origin;this.pos=origin.add(this.__pos.sub(origin).rotate({angle:angle,axis:axis}));this.__change()}});function tri_quad_error(object_type,attribute){throw new Error("A "+object_type+" has no "+attribute+" attribute.")}function triangle(args){if(!(this instanceof triangle))return new triangle(args);args=args||{};var vnames=["v0","v1","v2"];if(args.vs===undefined){for(var i=0;i<3;i++)if(args[vnames[i]]===undefined)throw new Error("A triangle must have a vertex "+vnames[i]+".")}init(this,args);var vtemp=this.vs;for(var i=0;i<3;i++)this.canvas.__vertices.object_info[vtemp[i].__id][this.__id]=this}subclass(triangle,box);property.declare(triangle.prototype,{v0:{get:function(){return this.__v0},set:function(value){if(!(value instanceof vertex))throw new Error("v0 must be a vertex object.");this.__v0=value;this.__change()}},v1:{get:function(){return this.__v1},set:function(value){if(!(value instanceof vertex))throw new Error("v1 must be a vertex object.");this.__v1=value;this.__change()}},v2:{get:function(){return this.__v2},set:function(value){if(!(value instanceof vertex))throw new Error("v2 must be a vertex object.");this.__v2=value;this.__change()}},vs:{get:function(){return[this.__v0,this.__v1,this.__v2]},set:function(value){if(toType(value)!="array"||value.length!=3)throw new Error("triangle.vs must be a list of 3 vertex objects.");for(var i=0;i<3;i++)if(!(value[i]instanceof vertex))throw new Error("triangle.vs must contain vertex objects.");this.__v0=value[0];this.__v1=value[1];this.__v2=value[2];this.__change()}},pos:{get:function(){tri_quad_error("triangle","pos")},set:function(value){tri_quad_error("triangle","pos")}},color:{get:function(){tri_quad_error("triangle","color")},set:function(value){tri_quad_error("triangle","color")}},size:{get:function(){tri_quad_error("triangle","size")},set:function(value){tri_quad_error("triangle","size")}},axis:{get:function(){tri_quad_error("triangle","axis")},set:function(value){tri_quad_error("triangle","axis")}},up:{get:function(){tri_quad_error("triangle","up")},set:function(value){tri_quad_error("triangle","up")}},opacity:{get:function(){tri_quad_error("triangle","opacity")},set:function(value){tri_quad_error("triangle","opacity")}},shininess:{get:function(){tri_quad_error("triangle","shininess")},set:function(value){tri_quad_error("triangle","shininess")}},emissive:{get:function(){tri_quad_error("triangle","emissive")},set:function(value){tri_quad_error("triangle","emissive")}},__prev_texture:null,__prev_bumpmap:null,__update:function(){this.__model.id_object[this.__id]=this},__get_extent:function(ext){var vnames=["__v0","__v1","__v2"];for(var i=0;i<3;i++)ext.point_extent(this,this[vnames[i]].pos)},rotate:function(args){throw new Error("A triangle has no rotate method; rotate the vertices instead.")}});function quad(args){if(!(this instanceof quad))return new quad(args);args=args||{};var vnames=["v0","v1","v2","v3"];if(args.vs===undefined){for(var i=0;i<4;i++)if(args[vnames[i]]===undefined)throw new Error("A quad must have a vertex "+vnames[i]+".")}this.__tex={file:null,bumpmap:null,texture_ref:{reference:null},bumpmap_ref:{reference:null},left:false,right:false,sides:false,flipx:false,flipy:false,turn:0,flags:0};init(this,args);var vtemp=this.vs;for(var i=0;i<4;i++)this.canvas.__vertices.object_info[vtemp[i].__id][this.__id]=this}subclass(quad,box);property.declare(quad.prototype,{v0:{get:function(){return this.__v0},set:function(value){if(!(value instanceof vertex))throw new Error("v0 must be a vertex object.");this.__v0=value;this.__change()}},v1:{get:function(){return this.__v1},set:function(value){if(!(value instanceof vertex))throw new Error("v1 must be a vertex object.");this.__v1=value;this.__change()}},v2:{get:function(){return this.__v2},set:function(value){if(!(value instanceof vertex))throw new Error("v2 must be a vertex object.");this.__v2=value;this.__change()}},v3:{get:function(){return this.__v3},set:function(value){if(!(value instanceof vertex))throw new Error("v3 must be a vertex object.");this.__v3=value;this.__change()}},vs:{get:function(){return[this.__v0,this.__v1,this.__v2,this.__v3]},set:function(value){if(toType(value)!="array"||value.length!=4)throw new Error("quad.vs must be a list of 4 vertex objects.");for(var i=0;i<4;i++)if(!(value[i]instanceof vertex))throw new Error("quad.vs must contain vertex objects.");this.__v0=value[0];this.__v1=value[1];this.__v2=value[2];this.__v3=value[3];this.__change()}},pos:{get:function(){tri_quad_error("quad","pos")},set:function(value){tri_quad_error("quad","pos")}},color:{get:function(){tri_quad_error("quad","color")},set:function(value){tri_quad_error("quad","color")}},size:{get:function(){tri_quad_error("quad","size")},set:function(value){tri_quad_error("quad","size")}},axis:{get:function(){tri_quad_error("quad","axis")},set:function(value){tri_quad_error("quad","axis")}},up:{get:function(){tri_quad_error("quad","up")},set:function(value){tri_quad_error("quad","up")}},opacity:{get:function(){tri_quad_error("quad","opacity")},set:function(value){tri_quad_error("quad","opacity")}},shininess:{get:function(){tri_quad_error("quad","shininess")},set:function(value){tri_quad_error("quad","shininess")}},__prev_texture:null,__prev_bumpmap:null,__update:function(){this.__model.id_object[this.__id]=this},__get_extent:function(ext){var vnames=["__v0","__v1","__v2","__v3"];for(var i=0;i<4;i++)ext.point_extent(this,this[vnames[i]].pos)},rotate:function(args){throw new Error("A quad has no rotate method; rotate the vertices instead.")}});var compound_id=0;function make_compound(objects,parameters){function update_extent(c,extent){if(extent.__xmin===null)return;for(var ext in extent){var value=extent[ext];if(ext.slice(-3)=="min"){if(c[ext]===null||valuec[ext])c[ext]=value}}}function compound_error(n){if(n>0)throw new Error("Compounding objects 0 through "+n+" in the list exceeds the vertex limit.");else throw new Error("The first object in the list exceeds the vertex limit")}var self=parameters.self;delete parameters.self;var mesh=new Mesh;var release=[];var temp;for(var i=0;i0)this.__push_and_append(pos,{})}}subclass(curve,Primitive);property.declare(curve.prototype,{origin:new attributeVectorPos(null,0,0,0),pos:{get:function(){throw new Error("Use methods to read curve or points pos attribute.")},set:function(value){throw new Error("Use methods to change curve or points pos attribute.")}},radius:{get:function(){return this.__radius},set:function(value){this.__radius=value;this.__change()}},retain:{get:function(){return this.__retain},set:function(value){this.__retain=value;this.__change()}},npoints:{get:function(){return this.__points.length},set:function(value){throw new Error("Cannot change curve or points npoints.")}},__no_autoscale:false,__get_extent:function(ext){if(this.__no_autoscale)return;var xmin=null,ymin=null,zmin=null,xmax=null,ymax=null,zmax=null;var length=this.__points.length;var pnt=this.__points;var org=this.__origin;var p;for(var i=0;ixmax)xmax=p.x+org.x;if(ymax===null||p.y+org.y>ymax)ymax=p.y+org.y;if(zmax===null||p.z+org.z>zmax)zmax=p.z+org.z}var center=vec((xmin+xmax)/2,(ymin+ymax)/2,(zmin+zmax)/2);var pseudosize=vec(xmax-xmin,ymax-ymin,zmax-zmin);var savepos=this.__pos,savesize=this.__size;this.__pos=center;this.__size=pseudosize;this.__hasPosAtCenter=true;ext.xmin=xmin;ext.xmax=xmax;ext.ymin=ymin;ext.ymax=ymax;ext.zmin=zmin;ext.zmax=zmax;Autoscale.find_extent(this,ext);this.__pos=savepos;this.__size=savesize},__setup:function(iargs){var pos=[];var specs={};var haspos=false;if(iargs instanceof vec){haspos=true;pos=[iargs]}else if(iargs.length>1){haspos=true;for(var i=0;i-1&&this.__points.length>=retain){var N=this.__points.length-retain;for(var d=0;d-1&&this.__points.length>=retain){var N=this.__points.length-retain;for(var d=0;d=0&&n0){this.__points[n-1].__nextsegment=p.__nextsegment;this.__points[n-1].__change()}if(n0)this.__push_and_append(pos,{});this.canvas.__points_objects.push(this)}}subclass(points,curve);property.declare(points.prototype,{origin:{get:function(){throw new Error("The points object has no origin attribute.")},set:function(value){throw new Error("The points object has no origin attribute.")}},color:{get:function(){return this.__color},set:function(value){this.__color=value;if(!this.__pixels){for(var i=0;i=this.canvas.__height)var factor=2*this.canvas.__range/this.canvas.__height;else var factor=2*this.canvas.__range/this.canvas.__width;var viewMatrix=mat4.lookAt(camera.pos,camera.target,camera.up);var vnew=mat4.multiplyVec3(viewMatrix,vec3.create([this.pos.x,this.pos.y,this.pos.z]));if(vnew[2]>-camera.zNear||vnew[2]<-camera.zFar)return;var d=camera.distance;var k=-d/(vnew[2]*factor);posx=Math.round(k*vnew[0]+this.canvas.__width/2);posy=Math.round(-k*vnew[1]+this.canvas.__height/2)}var h=this.__height;var upperchar=.4*this.__height;var f=this.__font;if(this.__font=="sans")f="Arial";else if(this.__font=="serif")f="Georgia";ctx.textBaseline="middle";ctx.lineWidth=this.__linewidth;var default_color=vec(1,1,1);if(this.canvas.__background.equals(vec(1,1,1)))default_color=vec(0,0,0);ctx.strokeStyle=color.to_html(this.__linecolor||this.__color||default_color);var info=parse_html({ctx:ctx,text:print_to_string(this.__text),x:posx,y:posy,align:this.__align||"center",font:f,fontsize:h,color:this.__color||default_color});var nlines=info.lines.length;var width=info.maxwidth;var dh=1.3*this.__height;var height=this.__height+(nlines-1)*dh;var xbase;var ybase;var border=this.__border;if(xoffset||yoffset){if(Math.abs(yoffset)>Math.abs(xoffset)){if(yoffset>0){xbase=posx+xoffset-width/2;ybase=posy-yoffset-height-border+upperchar}else{xbase=posx+xoffset-width/2;ybase=posy-yoffset+border+upperchar}}else if(Math.abs(xoffset)>0){ybase=posy-yoffset-height/2+upperchar;if(xoffset>0){xbase=posx+xoffset+border}else if(xoffset<0){xbase=posx+xoffset-width-border}}}else{ybase=posy;switch(this.__align){case null:case"center":xbase=posx-width/2;break;case"right":xbase=posx-width;break;case"left":xbase=posx;break}}var bcolor;if(this.__background==null)bcolor=this.canvas.__background;else bcolor=this.__background;ctx.fillStyle=color.to_html_rgba(bcolor,this.__opacity);ctx.fillRect(xbase-border,ybase-upperchar-border,width+2*border,height+2*border);if((xoffset||yoffset)&&this.__line){ctx.beginPath();if(this.space>0){var v=vec(xoffset,-yoffset,0).norm().multiply(this.space);v=v.add(vec(posx,posy,0));ctx.moveTo(v.x,v.y)}else ctx.moveTo(posx,posy);ctx.lineTo(posx+xoffset,posy-yoffset);ctx.stroke()}if(this.__box){ctx.beginPath();ctx.moveTo(xbase-border,ybase-upperchar-border);ctx.lineTo(xbase+width+border,ybase-upperchar-border);ctx.lineTo(xbase+width+border,ybase-upperchar+height+border);ctx.lineTo(xbase-border,ybase-upperchar+height+border);ctx.closePath();ctx.stroke()}info.x=xbase;info.y=ybase;switch(this.__align){case null:case"center":info.x+=width/2;break;case"right":info.x+=width;break;case"left":info.x+=0;break}display_2D(info)},__change:function(){if(this.canvas!==undefined)this.canvas.__overlay_objects.__changed=true}});function attach_trail(objectOrFunction,options){if(!(this instanceof attach_trail))return new attach_trail(objectOrFunction,options);if(options===undefined)options={};this.__options={};this.__obj=objectOrFunction;if(options.canvas!==undefined)this.canvas=options.canvas;else this.canvas=canvas.selected;var radius=0;if(options.type===undefined){this.type="curve"}else{switch(options.type){case"curve":this.type=options.type;break;case"spheres":case"points":this.type="points";this.__options["size_units"]="world";break;default:throw new Error("attach_trail type must be 'curve' or 'points' (or 'spheres')")}}if(typeof objectOrFunction!=="function"&&typeof objectOrFunction!=="string"){this.canvas=objectOrFunction.canvas;this.__options["color"]=objectOrFunction.color;if(options.radius===undefined){if(this.type=="points")radius=.1*objectOrFunction.size.y}else radius=options.radius}else{if(options.radius!==undefined)radius=options.radius}this.__options["radius"]=this.__radius=radius;this.__options["canvas"]=this.canvas;if(options.color!==undefined){this.__options["color"]=options.color}else this.__options["color"]=vec(1,1,1);this.__options["retain"]=-1;if(options.retain!==undefined){this.__options["retain"]=options.retain}this.pps=0;if(options.pps!==undefined){this.pps=options.pps}this.__options["pickable"]=false;var send={};for(var a in this.__options)send[a]=this.__options[a];if(this.type=="curve")this.__trail=curve(send);else this.__trail=points(send);this.__trails=[this.__trail];this.canvas.trails.push(this);this.__last_pos=null;this.__last_time=null;this.__run=true;this.__elements=0}property.declare(attach_trail.prototype,{color:{get:function(){return this.__options.color},set:function(value){this.__options.color=value}},radius:{get:function(){return this.__options.radius},set:function(value){this.__options.radius=value}},retain:{get:function(){return this.__options.retain},set:function(value){this.__options.retain=value}},start:function(){this.__run=true;var send={};for(var a in this.__options)send[a]=this.__options[a];if(this.type==="curve")this.__trail=curve(send);else this.__trail=points(send);this.__trails.push(this.__trail)},stop:function(){this.__run=false},clear:function(){this.__last_pos=null;this.__last_time=null;this.__elements=0;for(var i=0;i').css({width:"16px",height:"16px"}).appendTo(attrs.pos).click(function(){attrs.checked=!attrs.checked;$(attrs.jradio).prop("checked",attrs.checked);attrs.bind(cradio)});$(" "+attrs.text+"").appendTo(attrs.pos);var cradio={get disabled(){return attrs.disabled},set disabled(value){attrs.disabled=value;$(attrs.jradio).attr("disabled",attrs.disabled);if(attrs.disabled)$("#"+attrs._id).css({color:rgb_to_css(vec(.7,.7,.7))});else $("#"+attrs._id).css({color:rgb_to_css(vec(0,0,0))})},get checked(){return attrs.checked},set checked(value){attrs.checked=value;$(attrs.jradio).prop("checked",value)},get text(){return attrs.text},set text(value){attrs.text=value;$("#"+attrs._id).html(" "+value)},remove:function(){$(attrs.jradio).remove();$("#"+attrs._id).remove()}};for(var a in args){cradio[a]=args[a]}cradio.checked=attrs.checked;return cradio}function checkbox(args){if(!(this instanceof checkbox))return new checkbox(args);var cvs=canvas.get_selected();var attrs={pos:cvs.caption_anchor,checked:false,text:""};if(args.bind!==undefined){attrs.bind=args.bind;delete args.bind}else throw new Error("A checkbox must have a bind attribute.");for(a in attrs){if(args[a]!==undefined){attrs[a]=args[a];delete args[a]}}widgetid++;attrs._id=widgetid.toString();attrs.jcheckbox=$('').css({width:"16px",height:"16px"}).appendTo(attrs.pos).click(function(){attrs.checked=!attrs.checked;$(attrs.jcheckbox).prop("checked",attrs.checked);attrs.bind(ccheckbox)});$(" "+attrs.text+"").appendTo(attrs.pos);var ccheckbox={get disabled(){return attrs.disabled},set disabled(value){attrs.disabled=value;$(attrs.jcheckbox).attr("disabled",attrs.disabled);if(attrs.disabled)$("#"+attrs._id).css({color:rgb_to_css(vec(.7,.7,.7))});else $("#"+attrs._id).css({color:rgb_to_css(vec(0,0,0))})},get checked(){return attrs.checked},set checked(value){attrs.checked=value;$(attrs.jcheckbox).prop("checked",value)},get text(){return attrs.text},set text(value){attrs.text=value;$("#"+attrs._id).html(" "+value)},remove:function(){$(attrs.jcheckbox).remove();$("#"+attrs._id).remove()}};for(var a in args){ccheckbox[a]=args[a]}ccheckbox.checked=attrs.checked;return ccheckbox}function wtext(args){if(!(this instanceof wtext))return new wtext(args);args=args||{};var cvs=canvas.get_selected();var attrs={pos:cvs.caption_anchor,text:""};for(var a in attrs){if(args[a]!==undefined){attrs[a]=args[a];delete args[a]}}widgetid++;attrs._id=widgetid.toString();$(""+print_to_string(attrs.text)+"").appendTo(attrs.pos);var cwtext={get text(){return attrs.text},set text(value){attrs.text=value;$("#"+attrs._id).html(print_to_string(value))},remove:function(){$("#"+attrs._id).remove()}};for(var a in args){cwtext[a]=args[a]}return cwtext}function button(args){if(!(this instanceof button))return new button(args);var cvs=canvas.get_selected();var attrs={pos:cvs.caption_anchor,text:" ",color:vec(0,0,0),background:vec(1,1,1),disabled:false};if(args.bind!==undefined){attrs.bind=args.bind;delete args.bind}else throw new Error("A button must have a bind attribute.");for(a in attrs){if(args[a]!==undefined){attrs[a]=args[a];delete args[a]}}attrs.jbutton=$("