diff --git a/distrib/aladin-0.5.1.js b/distrib/aladin-0.5.1.js new file mode 100644 index 00000000..976f537e --- /dev/null +++ b/distrib/aladin-0.5.1.js @@ -0,0 +1,6542 @@ +// cds namespace + +var cds = cds || {}; + +var A = A || {}; +/* + json2.js + 2012-10-08 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}());// log +Logger = {}; + +Logger.log = function(action, params) { + try { + var logUrl = "http://alasky.u-strasbg.fr/cgi/AladinLiteLogger/log.py"; + var paramStr = ""; + if (params) { + paramStr = JSON.stringify(params); + } + + $.ajax({ + url: logUrl, + data: {"action": action, "params": paramStr, "pageUrl": window.location.href, "referer": document.referrer ? document.referrer : ""}, + method: 'GET', + dataType: 'json' // as alasky supports CORS, we do not need JSONP any longer + }); + + } + catch(e) { + window.console && console.log('Exception: ' + e); + } + +}; +/*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh) + * Licensed under the MIT License (LICENSE.txt). + * + * Version: 3.1.4 + * + * Requires: 1.2.2+ + */ + +(function (factory) { + if ( typeof define === 'function' && define.amd ) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS style for Browserify + module.exports = factory; + } else { + // Browser globals + factory(jQuery); + } +}(function ($) { + + var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll']; + var toBind = 'onwheel' in document || document.documentMode >= 9 ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll']; + var lowestDelta, lowestDeltaXY; + + if ( $.event.fixHooks ) { + for ( var i = toFix.length; i; ) { + $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks; + } + } + + $.event.special.mousewheel = { + setup: function() { + if ( this.addEventListener ) { + for ( var i = toBind.length; i; ) { + this.addEventListener( toBind[--i], handler, false ); + } + } else { + this.onmousewheel = handler; + } + }, + + teardown: function() { + if ( this.removeEventListener ) { + for ( var i = toBind.length; i; ) { + this.removeEventListener( toBind[--i], handler, false ); + } + } else { + this.onmousewheel = null; + } + } + }; + + $.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, + absDeltaXY = 0, + fn; + event = $.event.fix(orgEvent); + event.type = 'mousewheel'; + + // Old school scrollwheel delta + if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta; } + if ( orgEvent.detail ) { delta = orgEvent.detail * -1; } + + // At a minimum, setup the deltaY to be delta + deltaY = delta; + + // Firefox < 17 related to DOMMouseScroll event + if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { + deltaY = 0; + deltaX = delta * -1; + } + + // New school wheel delta (wheel event) + if ( orgEvent.deltaY ) { + deltaY = orgEvent.deltaY * -1; + delta = deltaY; + } + if ( orgEvent.deltaX ) { + deltaX = orgEvent.deltaX; + delta = deltaX * -1; + } + + // Webkit + if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY; } + if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = orgEvent.wheelDeltaX * -1; } + + // Look for lowest delta to normalize the delta values + absDelta = Math.abs(delta); + if ( !lowestDelta || absDelta < lowestDelta ) { lowestDelta = absDelta; } + absDeltaXY = Math.max(Math.abs(deltaY), Math.abs(deltaX)); + if ( !lowestDeltaXY || absDeltaXY < lowestDeltaXY ) { lowestDeltaXY = absDeltaXY; } + + // Get a whole value for the deltas + fn = delta > 0 ? 'floor' : 'ceil'; + delta = Math[fn](delta / lowestDelta); + deltaX = Math[fn](deltaX / lowestDeltaXY); + deltaY = Math[fn](deltaY / lowestDeltaXY); + + // Add event and delta to the front of the arguments + args.unshift(event, delta, deltaX, deltaY); + + return ($.event.dispatch || $.event.handle).apply(this, args); + } + +}));// requestAnimationFrame() shim by Paul Irish +// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ +window.requestAnimFrame = (function() { + return window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(/* function */ callback, /* DOMElement */ element){ + window.setTimeout(callback, 1000 / 60); + }; +})();// stats.js r6 - http://github.com/mrdoob/stats.js +var Stats=function(){function s(a,g,d){var f,c,e;for(c=0;c<30;c++)for(f=0;f<73;f++)e=(f+c*74)*4,a[e]=a[e+4],a[e+1]=a[e+5],a[e+2]=a[e+6];for(c=0;c<30;c++)e=(73+c*74)*4,c'+n+" MS ("+z+"-"+A+")";o.putImageData(B,0,0);F=j;if(j> +v+1E3){l=Math.round(u*1E3/(j-v));w=Math.min(w,l);x=Math.max(x,l);s(y.data,Math.min(30,30-l/100*30),"fps");d.innerHTML=''+l+" FPS ("+w+"-"+x+")";m.putImageData(y,0,0);if(t==3)p=performance.memory.usedJSHeapSize*9.54E-7,C=Math.min(C,p),D=Math.max(D,p),s(E.data,Math.min(30,30-p/2),"mb"),i.innerHTML=''+Math.round(p)+" MB ("+Math.round(C)+"-"+Math.round(D)+")",q.putImageData(E,0,0);v=j;u=0}}}}; + +Constants={},Constants.PI=Math.PI,Constants.C_PR=Math.PI/180,Constants.VLEV=2,Constants.EPS=1e-7,Constants.c=.105,Constants.LN10=Math.log(10),Constants.PIOVER2=Math.PI/2,Constants.TWOPI=2*Math.PI,Constants.TWOTHIRD=2/3,Constants.ARCSECOND_RADIAN=484813681109536e-20,SpatialVector=function(){function t(t,s,i){"use strict";this.x=t,this.y=s,this.z=i,this.ra_=0,this.dec_=0,this.okRaDec_=!1}return t.prototype.setXYZ=function(t,s,i){this.x=t,this.y=s,this.z=i,this.okRaDec_=!1},t.prototype.length=function(){"use strict";return Math.sqrt(this.lengthSquared())},t.prototype.lengthSquared=function(){"use strict";return this.x*this.x+this.y*this.y+this.z*this.z},t.prototype.normalized=function(){"use strict";var t=this.length();this.x/=t,this.y/=t,this.z/=t},t.prototype.set=function(t,s){"use strict";this.ra_=t,this.dec_=s,this.okRaDec_=!0,this.updateXYZ()},t.prototype.angle=function(t){"use strict";var s=this.y*t.z-this.z*t.y,i=this.z*t.x-this.x*t.z,n=this.x*t.y-this.y*t.x,a=Math.sqrt(s*s+i*i+n*n);return Math.abs(Math.atan2(a,dot(t)))},t.prototype.get=function(){"use strict";return[x,y,z]},t.prototype.toString=function(){"use strict";return"SpatialVector["+this.x+", "+this.y+", "+this.z+"]"},t.prototype.cross=function(s){"use strict";return new t(this.y*s.z-s.y*this.z,this.z*s.x-s.z*this.x,this.x*s.y-s.x()*this.y)},t.prototype.equal=function(t){"use strict";return this.x==t.x&&this.y==t.y&&this.z==t.z()?!0:!1},t.prototype.mult=function(s){"use strict";return new t(s*this.x,s*this.y,s*this.z)},t.prototype.dot=function(t){"use strict";return this.x*t.x+this.y*t.y+this.z*t.z},t.prototype.add=function(s){"use strict";return new t(this.x+s.x,this.y+s.y,this.z+s.z)},t.prototype.sub=function(s){"use strict";return new t(this.x-s.x,this.y-s.y,this.z-s.z)},t.prototype.dec=function(){"use strict";return this.okRaDec_||(this.normalized(),this.updateRaDec()),this.dec_},t.prototype.ra=function(){"use strict";return this.okRaDec_||(this.normalized(),this.updateRaDec()),this.ra_},t.prototype.updateXYZ=function(){"use strict";var t=Math.cos(this.dec_*Constants.C_PR);this.x=Math.cos(this.ra_*Constants.C_PR)*t,this.y=Math.sin(this.ra_*Constants.C_PR)*t,this.z=Math.sin(this.dec_*Constants.C_PR)},t.prototype.updateRaDec=function(){"use strict";this.dec_=Math.asin(this.z)/Constants.C_PR;var t=Math.cos(this.dec_*Constants.C_PR);this.ra_=t>Constants.EPS||-Constants.EPS>t?this.y>Constants.EPS||this.y<-Constants.EPS?0>this.y?360-Math.acos(this.x/t)/Constants.C_PR:Math.acos(this.x/t)/Constants.C_PR:0>this.x?180:0:0,this.okRaDec_=!0},t.prototype.toRaRadians=function(){"use strict";var t=0;return(0!=this.x||0!=this.y)&&(t=Math.atan2(this.y,this.x)),0>t&&(t+=2*Math.PI),t},t.prototype.toDeRadians=function(){var t=z/this.length(),s=Math.acos(t);return Math.PI/2-s},t}(),AngularPosition=function(){return AngularPosition=function(t,s){"use strict";this.theta=t,this.phi=s},AngularPosition.prototype.toString=function(){"use strict";return"theta: "+this.theta+", phi: "+this.phi},AngularPosition}(),LongRangeSetBuilder=function(){function t(){this.items=[]}return t.prototype.appendRange=function(t,s){for(var i=t;s>=i;i++)i in this.items||this.items.push(i)},t}(),HealpixIndex=function(){function t(t){"use strict";this.nside=t}return t.NS_MAX=8192,t.ORDER_MAX=13,t.NSIDELIST=[1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192],t.JRLL=[2,2,2,2,3,3,3,3,4,4,4,4],t.JPLL=[1,3,5,7,0,2,4,6,1,3,5,7],t.XOFFSET=[-1,-1,0,1,1,1,0,-1],t.YOFFSET=[0,1,1,1,0,-1,-1,-1],t.FACEARRAY=[[8,9,10,11,-1,-1,-1,-1,10,11,8,9],[5,6,7,4,8,9,10,11,9,10,11,8],[-1,-1,-1,-1,5,6,7,4,-1,-1,-1,-1],[4,5,6,7,11,8,9,10,11,8,9,10],[0,1,2,3,4,5,6,7,8,9,10,11],[1,2,3,0,0,1,2,3,5,6,7,4],[-1,-1,-1,-1,7,4,5,6,-1,-1,-1,-1],[3,0,1,2,3,0,1,2,4,5,6,7],[2,3,0,1,-1,-1,-1,-1,0,1,2,3]],t.SWAPARRAY=[[0,0,0,0,0,0,0,0,3,3,3,3],[0,0,0,0,0,0,0,0,6,6,6,6],[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,5,5,5,5],[0,0,0,0,0,0,0,0,0,0,0,0],[5,5,5,5,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0],[6,6,6,6,0,0,0,0,0,0,0,0],[3,3,3,3,0,0,0,0,0,0,0,0]],t.Z0=Constants.TWOTHIRD,t.prototype.init=function(){"use strict";var s=256;this.ctab=Array(s),this.utab=Array(s);for(var i=0;256>i;++i)this.ctab[i]=1&i|(2&i)<<7|(4&i)>>1|(8&i)<<6|(16&i)>>2|(32&i)<<5|(64&i)>>3|(128&i)<<4,this.utab[i]=1&i|(2&i)<<1|(4&i)<<2|(8&i)<<3|(16&i)<<4|(32&i)<<5|(64&i)<<6|(128&i)<<7;this.nl2=2*this.nside,this.nl3=3*this.nside,this.nl4=4*this.nside,this.npface=this.nside*this.nside,this.ncap=2*this.nside*(this.nside-1),this.npix=12*this.npface,this.fact2=4/this.npix,this.fact1=(this.nside<<1)*this.fact2,this.order=t.nside2order(this.nside)},t.calculateNSide=function(s){for(var i=0,n=s*s,a=180/Constants.PI,e=3600*3600*4*Constants.PI*a*a,h=Utils.castToInt(e/n),r=h/12,o=Math.sqrt(r),c=t.NS_MAX,u=0,p=0;t.NSIDELIST.length>p;p++)if(c>=Math.abs(o-t.NSIDELIST[p])&&(c=Math.abs(o-t.NSIDELIST[p]),i=t.NSIDELIST[p],u=p),o>i&&t.NS_MAX>o&&(i=t.NSIDELIST[u+1]),o>t.NS_MAX)return console.log("nside cannot be bigger than "+t.NS_MAX),t.NS_MAX;return i},t.nside2order=function(s){"use strict";return(s&s-1)>0?-1:Utils.castToInt(t.log2(s))},t.log2=function(t){"use strict";return Math.log(t)/Math.log(2)},t.prototype.ang2pix_nest=function(s,i){"use strict";var n,a,e,h,r,o,c,u,p,l,d,f,I;if(i>=Constants.TWOPI&&(i-=Constants.TWOPI),0>i&&(i+=Constants.TWOPI),s>Constants.PI||0>s)throw{name:"Illegal argument",message:"theta must be between 0 and "+Constants.PI};if(i>Constants.TWOPI||0>i)throw{name:"Illegal argument",message:"phi must be between 0 and "+Constants.TWOPI};if(a=Math.cos(s),e=Math.abs(a),h=i/Constants.PIOVER2,t.Z0>=e){var M=this.nside*(.5+h),y=this.nside*.75*a,u=M-y,p=M+y;o=u>>this.order,c=p>>this.order,d=o==c?4==o?4:o+4:c>o?o:c+8,f=Utils.castToInt(p&this.nside-1),I=Utils.castToInt(this.nside-(u&this.nside-1)-1)}else{l=Utils.castToInt(h),l>=4&&(l=3),r=h-l;var g=this.nside*Math.sqrt(3*(1-e));u=Utils.castToInt(r*g),p=Utils.castToInt((1-r)*g),u=Math.min(t.NS_MAX-1,u),p=Math.min(t.NS_MAX-1,p),a>=0?(d=l,f=Utils.castToInt(this.nside-p-1),I=Utils.castToInt(this.nside-u-1)):(d=l+8,f=u,I=p)}return n=this.xyf2nest(f,I,d)},t.prototype.xyf2nest=function(t,s,i){"use strict";return(i<<2*this.order)+(this.utab[255&t]|this.utab[255&t>>8]<<16|this.utab[255&t>>16]<<32|this.utab[255&t>>24]<<48|this.utab[255&s]<<1|this.utab[255&s>>8]<<17|this.utab[255&s>>16]<<33|this.utab[255&s>>24]<<49)},t.prototype.nest2xyf=function(t){"use strict";var s={};s.face_num=t>>2*this.order;var i=t&this.npface-1,n=(93823560581120&i)>>16|(614882086624428e4&i)>>31|21845&i|(1431633920&i)>>15;return s.ix=this.ctab[255&n]|this.ctab[255&n>>8]<<4|this.ctab[255&n>>16]<<16|this.ctab[255&n>>24]<<20,i>>=1,n=(93823560581120&i)>>16|(614882086624428e4&i)>>31|21845&i|(1431633920&i)>>15,s.iy=this.ctab[255&n]|this.ctab[255&n>>8]<<4|this.ctab[255&n>>16]<<16|this.ctab[255&n>>24]<<20,s},t.prototype.pix2ang_nest=function(s){"use strict";if(0>s||s>this.npix-1)throw{name:"Illegal argument",message:"ipix out of range"};var i,n,a,e=this.nest2xyf(s),h=e.ix,r=e.iy,o=e.face_num,c=(t.JRLL[o]<c?(i=c,n=1-i*i*this.fact2,a=0):c>this.nl3?(i=this.nl4-c,n=i*i*this.fact2-1,a=0):(i=this.nside,n=(this.nl2-c)*this.fact1,a=1&c-this.nside);var u=Math.acos(n),p=(t.JPLL[o]*i+h-r+1+a)/2;p>this.nl4&&(p-=this.nl4),1>p&&(p+=this.nl4);var l=(p-.5*(a+1))*(Constants.PIOVER2/i);return{theta:u,phi:l}},t.nside2Npix=function(s){"use strict";if(0>this.NSIDELIST.indexOf(s))throw{name:"Illegal argument",message:"nside should be >0, power of 2, <"+t.NS_MAX};var i=12*s*s;return i},t.prototype.xyf2ring=function(s,i,n){"use strict";var a,e,h,r=t.JRLL[n]*this.nside-s-i-1;this.nside>r?(a=r,h=2*a*(a-1),e=0):r>3*this.nside?(a=this.nl4-r,h=this.npix-2*(a+1)*a,e=0):(a=this.nside,h=this.ncap+(r-this.nside)*this.nl4,e=1&r-this.nside);var o=(t.JPLL[n]*a+s-i+1+e)/2;return o>this.nl4?o-=this.nl4:1>o&&(o+=this.nl4),h+o-1},t.prototype.nest2ring=function(t){"use strict";var s=this.nest2xyf(t),i=this.xyf2ring(s.ix,s.iy,s.face_num);return i},t.prototype.corners_nest=function(t,s){"use strict";var i=this.nest2ring(t);return this.corners_ring(i,s)},t.prototype.pix2ang_ring=function(t){"use strict";var s,i,n,a,e,h,r,o,c;if(0>t||t>this.npix-1)throw{name:"Illegal argument",message:"ipix out of range"};return h=t+1,this.ncap>=h?(o=h/2,c=Utils.castToInt(o),n=Utils.castToInt(Math.sqrt(o-Math.sqrt(c)))+1,a=h-2*n*(n-1),s=Math.acos(1-n*n*this.fact2),i=(a-.5)*Constants.PI/(2*n)):this.npix-this.ncap>t?(e=t-this.ncap,n=e/this.nl4+this.nside,a=e%this.nl4+1,r=(1&n+this.nside)>0?1:.5,s=Math.acos((this.nl2-n)*this.fact1),i=(a-r)*Constants.PI/this.nl2):(e=this.npix-t,n=Utils.castToInt(.5*(1+Math.sqrt(2*e-1))),a=4*n+1-(e-2*n*(n-1)),s=Math.acos(-1+Math.pow(n,2)*this.fact2),i=(a-.5)*Constants.PI/(2*n)),[s,i]},t.prototype.ring=function(t){"use strict";var s,i,n=0,a=t+1,e=0;return this.ncap>=a?(i=a/2,e=Utils.castToInt(i),n=Utils.castToInt(Math.sqrt(i-Math.sqrt(e)))+1):this.nl2*(5*this.nside+1)>=a?(s=Utils.castToInt(a-this.ncap-1),n=Utils.castToInt(s/this.nl4+this.nside)):(s=this.npix-a+1,i=s/2,e=Utils.castToInt(i),n=Utils.castToInt(Math.sqrt(i-Math.sqrt(e)))+1,n=this.nl4-n),n},t.prototype.integration_limits_in_costh=function(t){"use strict";var s,i,n,a;return a=1*this.nside,this.nside>=t?(i=1-Math.pow(t,2)/3/this.npface,n=1-Math.pow(t-1,2)/3/this.npface,s=t==this.nside?2*(this.nside-1)/3/a:1-Math.pow(t+1,2)/3/this.npface):this.nl3>t?(i=2*(2*this.nside-t)/3/a,n=2*(2*this.nside-t+1)/3/a,s=2*(2*this.nside-t-1)/3/a):(n=t==this.nl3?2*(-this.nside+1)/3/a:-1+Math.pow(4*this.nside-t+1,2)/3/this.npface,s=-1+Math.pow(this.nl4-t-1,2)/3/this.npface,i=-1+Math.pow(this.nl4-t,2)/3/this.npface),[n,i,s]},t.prototype.pixel_boundaries=function(t,s,i,n){var a,e,h,r,o,c,u,p,l=1*this.nside;if(Math.abs(n)>=1-1/3/this.npface)return u=i*Constants.PIOVER2,p=(i+1)*Constants.PIOVER2,[u,p];if(1.5*n>=1)a=Math.sqrt(3*(1-n)),e=1/l/a,h=s,r=h-1,o=t-s,c=o+1,u=Constants.PIOVER2*(Math.max(r*e,1-c*e)+i),p=Constants.PIOVER2*(Math.min(1-o*e,h*e)+i);else if(1.5*n>-1){var d=.5*(1-1.5*n),f=d+1,I=this.nside+t%2;h=s-(I-t)/2,r=h-1,o=(I+t)/2-s,c=o+1,u=Constants.PIOVER2*(Math.max(f-c/l,-d+r/l)+i),p=Constants.PIOVER2*(Math.min(f-o/l,-d+h/l)+i)}else{a=Math.sqrt(3*(1+n)),e=1/l/a;var M=2*this.nside;h=t-M+s,r=h-1,o=M-s,c=o+1,u=Constants.PIOVER2*(Math.max(1-(M-r)*e,(M-c)*e)+i),p=Constants.PIOVER2*(Math.min(1-(M-h)*e,(M-o)*e)+i)}return[u,p]},t.vector=function(t,s){"use strict";var i=1*Math.sin(t)*Math.cos(s),n=1*Math.sin(t)*Math.sin(s),a=1*Math.cos(t);return new SpatialVector(i,n,a)},t.prototype.corners_ring=function(s,i){"use strict";var n=2*i+2,a=Array(n),e=this.pix2ang_ring(s),h=Math.cos(e[0]),r=e[0],o=e[1],c=Utils.castToInt(o/Constants.PIOVER2),u=this.ring(s),p=Math.min(u,Math.min(this.nside,this.nl4-u)),l=0,d=Constants.PIOVER2/p;l=u>=this.nside&&this.nl3>=u?Utils.castToInt(o/d+u%2/2)+1:Utils.castToInt(o/d)+1,l-=c*p;var f=n/2,I=this.integration_limits_in_costh(u),M=Math.acos(I[0]),y=Math.acos(I[2]),g=this.pixel_boundaries(u,l,c,I[0]);if(a[0]=l>p/2?t.vector(M,g[1]):t.vector(M,g[0]),g=this.pixel_boundaries(u,l,c,I[2]),a[f]=l>p/2?t.vector(y,g[1]):t.vector(y,g[0]),1==i){var x=Math.acos(I[1]);g=this.pixel_boundaries(u,l,c,I[1]),a[1]=t.vector(x,g[0]),a[3]=t.vector(x,g[1])}else for(var P=I[2]-I[0],C=P/(i+1),v=1;i>=v;v++)h=I[0]+C*v,r=Math.acos(h),g=this.pixel_boundaries(u,l,c,h),a[v]=t.vector(r,g[0]),a[n-v]=t.vector(r,g[1]);return a},t.vec2Ang=function(t){"use strict";var s=t.z/t.length(),i=Math.acos(s),n=0;return(0!=t.x||0!=t.y)&&(n=Math.atan2(t.y,t.x)),0>n&&(n+=2*Math.PI),[i,n]},t.prototype.queryDisc=function(s,i,n,a){"use strict";if(0>i||i>Constants.PI)throw{name:"Illegal argument",message:"angular radius is in RADIAN and should be in [0,pi]"};var e,h,r,o,c,u,p,l,d,f,I,M,y,g,x,P,C,v,_,T=new LongRangeSetBuilder,R=null,c=i;if(a&&(c+=Constants.PI/this.nl4),R=t.vec2Ang(s),u=R[0],p=R[1],I=this.fact2,M=this.fact1,o=Math.cos(u),_=1/Math.sqrt((1-o)*(1+o)),g=u-c,x=u+c,l=Math.cos(c),C=Math.cos(g),e=this.ringAbove(C)+1,P=Math.cos(x),h=this.ringAbove(P),e>h&&0==h&&(h=e),0>=g)for(var m=1;e>m;++m)this.inRing(m,0,Math.PI,T);for(r=e;h>=r;++r)v=this.nside>r?1-r*r*I:this.nl3>=r?(this.nl2-r)*M:-1+(this.nl4-r)*(this.nl4-r)*I,d=(l-v*o)*_,f=1-v*v-d*d,y=Math.atan2(Math.sqrt(f),d),isNaN(y)&&(y=c),this.inRing(r,p,y,T);if(x>=Math.PI)for(var m=h+1;this.nl4>m;++m)this.inRing(m,0,Math.PI,T,!1);var b;if(n){for(var S=T.items,U=[],O=0;S.length>O;O++){var A=this.ring2nest(S[O]);U.indexOf(A)>=0||U.push(A)}b=U}else b=T.items;return b},t.prototype.inRing=function(t,s,i,n,a){"use strict";var e,h,r,o,c=!1,u=!1,p=1e-12,l=0,d=0,f=0,I=0,M=(s-i)%Constants.TWOPI-p,y=s+i+p,g=(s+i)%Constants.TWOPI+p;if(p>Math.abs(i-Constants.PI)&&(c=!0),t>=this.nside&&this.nl3>=t?(d=t-this.nside+1,r=this.ncap+this.nl4*(d-1),o=r+this.nl4-1,e=d%2,h=this.nl4):(this.nside>t?(d=t,r=2*d*(d-1),o=r+4*d-1):(d=4*this.nside-t,r=this.npix-2*d*(d+1),o=r+4*d-1),h=4*d,e=1),c)return n.appendRange(r,o),void 0;if(l=e/2,a)f=Math.round(h*M/Constants.TWOPI-l),I=Math.round(h*y/Constants.TWOPI-l),f%=h,I>h&&(I%=h);else{if(f=Math.ceil(h*M/Constants.TWOPI-l),I=Utils.castToInt(h*g/Constants.TWOPI-l),f>I&&1==t&&(I=Utils.castToInt(h*y/Constants.TWOPI-l)),f==I+1&&(f=I),1==f-I&&Constants.PI>i*h)return console.log("the interval is too small and avay from center"),void 0;f=Math.min(f,h-1),I=Math.max(I,0)}if(f>I&&(u=!0),u)f+=r,I+=r,n.appendRange(r,I),n.appendRange(f,o);else{if(0>f)return f=Math.abs(f),n.appendRange(r,r+I),n.appendRange(o-f+1,o),void 0;f+=r,I+=r,n.appendRange(f,I)}},t.prototype.ringAbove=function(t){"use strict";var s=Math.abs(t);if(s>Constants.TWOTHIRD){var i=Utils.castToInt(this.nside*Math.sqrt(3*(1-s)));return t>0?i:4*this.nside-i-1}return Utils.castToInt(this.nside*(2-1.5*t))},t.prototype.ring2nest=function(t){"use strict";var s=this.ring2xyf(t);return this.xyf2nest(s.ix,s.iy,s.face_num)},t.prototype.ring2xyf=function(s){"use strict";var i,n,a,e,h={};if(this.ncap>s){i=Utils.castToInt(.5*(1+Math.sqrt(1+2*s))),n=s+1-2*i*(i-1),a=0,e=i,h.face_num=0;var r=n-1;r>=2*i&&(h.face_num=2,r-=2*i),r>=i&&++h.face_num}else if(this.npix-this.ncap>s){var o=s-this.ncap;this.order>=0?(i=(o>>this.order+2)+this.nside,n=(o&this.nl4-1)+1):(i=o/this.nl4+this.nside,n=o%this.nl4+1),a=1&i+this.nside,e=this.nside;var c,u,p=i-this.nside+1,l=this.nl2+2-p;this.order>=0?(c=n-Utils.castToInt(p/2)+this.nside-1>>this.order,u=n-Utils.castToInt(l/2)+this.nside-1>>this.order):(c=(n-Utils.castToInt(p/2)+this.nside-1)/this.nside,u=(n-Utils.castToInt(l/2)+this.nside-1)/this.nside),h.face_num=u==c?4==u?4:Utils.castToInt(u)+4:c>u?Utils.castToInt(u):Utils.castToInt(c)+8}else{var o=this.npix-s;i=Utils.castToInt(.5*(1+Math.sqrt(2*o-1))),n=4*i+1-(o-2*i*(i-1)),a=0,e=i,i=2*this.nl2-i,h.face_num=8;var r=n-1;r>=2*e&&(h.face_num=10,r-=2*e),r>=e&&++h.face_num}var d=i-t.JRLL[h.face_num]*this.nside+1,f=2*n-t.JPLL[h.face_num]*e-a-1;return f>=this.nl2&&(f-=8*this.nside),h.ix=f-d>>1,h.iy=-(f+d)>>1,h},t}(),Utils=function(){},Utils.radecToPolar=function(t,s){return{theta:Math.PI/2-s/180*Math.PI,phi:t/180*Math.PI}},Utils.polarToRadec=function(t,s){return{ra:180*s/Math.PI,dec:180*(Math.PI/2-t)/Math.PI}},Utils.castToInt=function(t){return t>0?Math.floor(t):Math.ceil(t)};//================================= +// AstroMath +//================================= + +// Class AstroMath having 'static' methods +function AstroMath() {} + +// Constant for conversion Degrees => Radians (rad = deg*AstroMath.D2R) +AstroMath.D2R = Math.PI/180.0; +// Constant for conversion Radians => Degrees (deg = rad*AstroMath.R2D) +AstroMath.R2D = 180.0/Math.PI; +/** + * Function sign + * @param x value for checking the sign + * @return -1, 0, +1 respectively if x < 0, = 0, > 0 + */ +AstroMath.sign = function(x) { return x > 0 ? 1 : (x < 0 ? -1 : 0 ); }; + +/** + * Function cosd(degrees) + * @param x angle in degrees + * @returns the cosine of the angle + */ +AstroMath.cosd = function(x) { + if (x % 90 == 0) { + var i = Math.abs(Math.floor(x / 90 + 0.5)) % 4; + switch (i) { + case 0: return 1; + case 1: return 0; + case 2: return -1; + case 3: return 0; + } + } + return Math.cos(x*AstroMath.D2R); +}; + +/** + * Function sind(degrees) + * @param x angle in degrees + * @returns the sine of the angle + */ +AstroMath.sind = function(x) { + if (x % 90 === 0) { + var i = Math.abs(Math.floor(x / 90 - 0.5)) % 4; + switch (i) { + case 0: return 1; + case 1: return 0; + case 2: return -1; + case 3: return 0; + } + } + + return Math.sin(x*AstroMath.D2R); +}; + +/** + * Function tand(degrees) + * @param x angle in degrees + * @returns the tangent of the angle + */ +AstroMath.tand = function(x) { + var resid; + + resid = x % 360; + if (resid == 0 || Math.abs(resid) == 180) { + return 0; + } else if (resid == 45 || resid == 225) { + return 1; + } else if (resid == -135 || resid == -315) { + return -1 + } + + return Math.tan(x * AstroMath.D2R); +}; + +/** + * Function asin(degrees) + * @param sine value [0,1] + * @return the angle in degrees + */ +AstroMath.asind = function(x) { return Math.asin(x)*AstroMath.R2D; }; + +/** + * Function acos(degrees) + * @param cosine value [0,1] + * @return the angle in degrees + */ +AstroMath.acosd = function(x) { return Math.acos(x)*AstroMath.R2D; }; + +/** + * Function atan(degrees) + * @param tangent value + * @return the angle in degrees + */ +AstroMath.atand = function(x) { return Math.atan(x)*AstroMath.R2D; }; + +/** + * Function atan2(y,x) + * @param y y component of the vector + * @param x x component of the vector + * @return the angle in radians + */ +AstroMath.atan2 = function(y,x) { + if (y != 0.0) { + var sgny = AstroMath.sign(y); + if (x != 0.0) { + var phi = Math.atan(Math.abs(y/x)); + if (x > 0.0) return phi*sgny; + else if (x < 0) return (Math.PI-phi)*sgny; + } else return (Math.PI/2)*sgny; + } else { + return x > 0.0 ? 0.0 : (x < 0 ? Math.PI : 0.0/0.0); + } +} + +/** + * Function atan2d(y,x) + * @param y y component of the vector + * @param x x component of the vector + * @return the angle in degrees + */ +AstroMath.atan2d = function(y,x) { + return AstroMath.atan2(y,x)*AstroMath.R2D; +} + +/*=========================================================================*/ +/** + * Computation of hyperbolic cosine + * @param x argument + */ +AstroMath.cosh = function(x) { + return (Math.exp(x)+Math.exp(-x))/2; +} + +/** + * Computation of hyperbolic sine + * @param x argument + */ +AstroMath.sinh = function(x) { + return (Math.exp(x)-Math.exp(-x))/2; +} + +/** + * Computation of hyperbolic tangent + * @param x argument + */ +AstroMath.tanh = function(x) { + return (Math.exp(x)-Math.exp(-x))/(Math.exp(x)+Math.exp(-x)); +} + +/** + * Computation of Arg cosh + * @param x argument in degrees. Must be in the range [ 1, +infinity ] + */ +AstroMath.acosh = function(x) { + return(Math.log(x+Math.sqrt(x*x-1.0))); +} + +/** + * Computation of Arg sinh + * @param x argument in degrees + */ +AstroMath.asinh = function(x) { + return(Math.log(x+Math.sqrt(x*x+1.0))); +} + +/** + * Computation of Arg tanh + * @param x argument in degrees. Must be in the range ] -1, +1 [ + */ +AstroMath.atanh = function(x) { + return(0.5*Math.log((1.0+x)/(1.0-x))); +} + +//============================================================================= +// Special Functions using trigonometry +//============================================================================= +/** + * Computation of sin(x)/x + * @param x in degrees. + * For small arguments x <= 0.001, use approximation + */ +AstroMath.sinc = function(x) { + var ax = Math.abs(x); + var y; + + if (ax <= 0.001) { + ax *= ax; + y = 1 - ax*(1.0-ax/20.0)/6.0; + } else { + y = Math.sin(ax)/ax; + } + + return y; +} + +/** + * Computes asin(x)/x + * @param x in degrees. + * For small arguments x <= 0.001, use an approximation + */ +AstroMath.asinc = function(x) { + var ax = Math.abs(x); + var y; + + if (ax <= 0.001) { + ax *= ax; + y = 1 + ax*(6.0 + ax*(9.0/20.0))/6.0; + } else { + y = Math.asin(ax)/ax; // ???? radians ??? + } + + return (y); +} + + +//============================================================================= +/** + * Computes the hypotenuse of x and y + * @param x value + * @param y value + * @return sqrt(x*x+y*y) + */ +AstroMath.hypot = function(x,y) { + return Math.sqrt(x*x+y*y); +} + +/** Generate the rotation matrix from the Euler angles + * @param z Euler angle + * @param theta Euler angle + * @param zeta Euler angles + * @return R [3][3] the rotation matrix + * The rotation matrix is defined by:
+ *    R =      R_z(-z)      *        R_y(theta)     *     R_z(-zeta)
+ *   |cos.z -sin.z  0|   |cos.the  0 -sin.the|   |cos.zet -sin.zet 0|
+ * = |sin.z  cos.z  0| x |   0     1     0   | x |sin.zet  cos.zet 0|
+ *   |   0      0   1|   |sin.the  0  cos.the|   |   0        0    1|
+ * 
+ */ +AstroMath.eulerMatrix = function(z, theta, zeta) { + var R = new Array(3); + R[0] = new Array(3); + R[1] = new Array(3); + R[2] = new Array(3); + var cosdZ = AstroMath.cosd(z); + var sindZ = AstroMath.sind(z); + var cosdTheta = AstroMath.cosd(theta); + var w = AstroMath.sind(theta) ; + var cosdZeta = AstroMath.cosd(zeta); + var sindZeta = AstroMath.sind(zeta); + + R[0][0] = cosdZeta*cosdTheta*cosdZ - sindZeta*sindZ; + R[0][1] = -sindZeta*cosdTheta*cosdZ - cosdZeta*sindZ; + R[0][2] = -w*cosdZ; + + R[1][0] = cosdZeta*cosdTheta*sindZ + sindZeta*cosdZ; + R[1][1] = -sindZeta*cosdTheta*sindZ + cosdZeta*cosdZ; + R[1][2] = -w*sindZ; + + R[2][0] = -w*cosdZeta; + R[2][1] = -w*cosdZ; + R[2][2] = cosdTheta; + return R ; +}; + + +AstroMath.displayMatrix = function(m) { + // Number of rows + var nbrows = m.length; + // Max column count + var nbcols = 0 + for (var i=0; i nbcols) nbcols = m[i].length; + } + var str = '\n'; + for (var i=0; i X,Y + * alpha, delta = longitude, lattitude + */ + project: function(alpha, delta) { + var u1 = this.tr_ou(alpha, delta); // u1[3] + var u2 = this.tr_uu(u1, this.ROT); // u2[3] + var P = this.tr_up(this.PROJECTION, u2); // P[2] = [X,Y] + if (P == null) { + return null; + } + + return { X: -P[0], Y: -P[1] }; + }, + + /** + * Computes the coordinates from a projection point : X,Y => ra,dec + * return o = [ ra, dec ] + */ + unproject: function(X,Y) { + X = -X; Y = -Y; + var u1 = this.tr_pu(this.PROJECTION, X, Y); // u1[3] + var u2 = this.tr_uu1(u1, this.ROT); // u2[3] + var o = this.tr_uo(u2); // o[2] + + return { ra: o[0], dec: o[1] }; + }, + + /** + * Compute projections from unit vector + * The center of the projection correspond to u = [1, 0, 0) + * proj = projection system (integer code like _PROJ_MERCATOR_ + * u[3] = unit vector + * return: an array [x,y] or null + */ + tr_up: function(proj, u) { + var x = u[0]; var y = u[1]; var z = u[2]; + var r, den; + var pp; + var X,Y; + + r = AstroMath.hypot(x,y); // r = cos b + if (r == 0.0 && z == 0.0) return null; + + switch(proj) { + default: + pp = null; + break; + + case Projection.PROJ_AITOFF: + den = Math.sqrt(r*(r+x)/2.0); // cos b . cos l/2 + X = Math.sqrt(2.0*r*(r-x)); + den = Math.sqrt((1.0 + den)/2.0); + X = X / den; + Y = z / den; + if (y < 0.0) X = -X; + pp = [ X, Y]; + break; + + case Projection.PROJ_GLS: + Y = Math.asin(z); // sin b + X = (r != 0) ? Math.atan2(y,x)*r : 0.0; + pp = [ X, Y]; + break; + + case Projection.PROJ_MERCATOR: + if (r != 0) { + X = Math.atan2(y,x); + Y = AstroMath.atanh(z); + pp = [ X, Y]; + } else { + pp = null; + } + break; + + case Projection.PROJ_TAN: + if (x > 0.0) { + X = y/x; + Y = z/x; + pp = [ X, Y ]; + } else { + pp = null; + } + break; + + case Projection.PROJ_TAN2: + den = (1.0 + x)/2.0; + if (den > 0.0) { + X = y/den; + Y = z/den; + pp = [ X, Y ]; + } else { + pp = null; + } + break; + + case Projection.PROJ_ARC: + if (x <= -1.0) { + // Distance of 180 degrees + X = Math.PI + Y = 0.0; + } else { + // Arccos(x) = Arcsin(r) + r = AstroMath.hypot(y,z); + if (x > 0.0) den = AstroMath.asinc(r); + else den = Math.acos(x)/r; + X = y * den; + Y = z * den; + } + pp = [ X, Y ]; + break; + + case Projection.PROJ_SIN: + if (x >= 0.0) { + X = y; + Y = z; + pp = [ X, Y ]; + } else { + pp = null; + } + break; + + case Projection.PROJ_SIN2: // Always possible + den = Math.sqrt((1.0 + x)/2.0); + if (den != 0) { + X = y / den; + Y = z / den; + } else { + // For x = -1 + X = 2.0; + Y = 0.0; + } + pp = [ X, Y ]; + break; + + case Projection.PROJ_LAMBERT: // Always possible + Y = z; + X = 0; + if (r != 0) X = Math.atan2(y,x); + pp = [ X, Y ]; + break; + } + return pp; + }, + + /** + * Computes Unit vector from a position in projection centered at position (0,0). + * proj = projection code + * X,Y : coordinates of the point in the projection + * returns : the unit vector u[3] or a face number for cube projection. + * null if the point is outside the limits, or if the projection is unknown. + */ + tr_pu: function( proj, X, Y ) { + var r,s,x,y,z; + + switch(proj) { + default: + return null; + + case Projection.PROJ_AITOFF: + // Limit is ellipse with axises + // a = 2 * sqrt(2) , b = sqrt(2) + // Compute dir l/2, b + r = X*X/8.e0 + Y*Y/2.e0; // 1 - cos b . cos l/2 + if (r > 1.0) { + // Test outside domain */ + return null; + } + x = 1.0 - r ; // cos b . cos l/2 + s = Math.sqrt(1.0 - r/2.0) ; // sqrt(( 1 + cos b . cos l/2)/2) + y = X * s / 2.0; + z = Y * s ; + // From (l/2,b) to (l,b) + r = AstroMath.hypot( x, y ) ; // cos b + if (r != 0.0) { + s = x; + x = (s*s - y*y) /r; + y = 2.0 * s * y/r; + } + break; + + case Projection.PROJ_GLS: + // Limit is |Y| <= pi/2 + z = Math.sin(Y); + r = 1 - z*z; // cos(b) ** 2 + if (r < 0.0) { + return null; + } + r = Math.sqrt(r); // cos b + if (r != 0.0) { + s = X/r; // Longitude + } else { + s = 0.0; // For poles + } + x = r * Math.cos(s); + y = r * Math.sin(s); + break; + + case Projection.PROJ_MERCATOR: + z = AstroMath.tanh(Y); + r = 1.0/AstroMath.cosh(Y); + x = r * Math.cos(X); + y = r * Math.sin(X); + break; + + case Projection.PROJ_LAMBERT: + // Always possible + z = Y; + r = 1 - z*z; // cos(b) ** 2 + if (r < 0.0) { + return null; + } + r = Math.sqrt(r); // cos b + x = r * Math.cos(X); + y = r * Math.sin(X); + break; + + case Projection.PROJ_TAN: + // No limit + x = 1.0 / Math.sqrt(1.0 + X*X + Y*Y); + y = X * x; + z = Y * x; + break; + + case Projection.PROJ_TAN2: + // No limit + r = (X*X + Y*Y)/4.0; + s = 1.0 + r; + x = (1.0 - r)/s; + y = X / s; + z = Y / s; + break; + + case Projection.PROJ_ARC: + // Limit is circle, radius PI + r = AstroMath.hypot(X, Y); + if (r > Math.PI) { + return null; + } + s = AstroMath.sinc(r); + x = Math.cos(r); + y = s * X; + z = s * Y; + break; + + case Projection.PROJ_SIN: + // Limit is circle, radius 1 + s = 1.0 - X*X - Y*Y; + if (s < 0.0) { + return null; + } + x = Math.sqrt(s); + y = X; + z = Y; + break; + + case Projection.PROJ_SIN2: + // Limit is circle, radius 2 */ + r = (X*X + Y*Y)/4.e0; + if (r > 1.0) { + return null; + } + s = Math.sqrt(1.0 - r); + x = 1.0 - 2.0 * r; + y = s * X; + z = s * Y; + break; + } + return [ x,y,z ]; + }, + + /** + * Creates the rotation matrix R[3][3] defined as + * R[0] (first row) = unit vector towards Zenith + * R[1] (second row) = unit vector towards East + * R[2] (third row) = unit vector towards North + * o[2] original angles + * @return rotation matrix + */ + tr_oR: function(lon, lat) { + var R = new Array(3); + R[0] = new Array(3); + R[1] = new Array(3); + R[2] = new Array(3); + R[2][2] = AstroMath.cosd(lat); + R[0][2] = AstroMath.sind(lat); + R[1][1] = AstroMath.cosd(lon); + R[1][0] = -AstroMath.sind(lon); + R[1][2] = 0.0; + R[0][0] = R[2][2] * R[1][1]; + R[0][1] = -R[2][2] * R[1][0]; + R[2][0] = -R[0][2] * R[1][1]; + R[2][1] = R[0][2] * R[1][0]; + return R; + }, + + /** + * Transformation from polar coordinates to Unit vector + * @return U[3] + */ + tr_ou: function(ra, dec) { + var u = new Array(3); + var cosdec = AstroMath.cosd(dec); + + u[0] = cosdec * AstroMath.cosd(ra); + u[1] = cosdec * AstroMath.sind(ra); + u[2] = AstroMath.sind(dec); + + return u; + }, + + /** + * Rotates the unit vector u1 using the rotation matrix + * u1[3] unit vector + * R[3][3] rotation matrix + * return resulting unit vector u2[3] + */ + tr_uu: function( u1, R ) { + var u2 = new Array(3); + var x = u1[0]; + var y = u1[1]; + var z = u1[2]; + + u2[0] = R[0][0]*x + R[0][1]*y + R[0][2]*z ; + u2[1] = R[1][0]*x + R[1][1]*y + R[1][2]*z ; + u2[2] = R[2][0]*x + R[2][1]*y + R[2][2]*z ; + + return u2; + }, + + /** + * reverse rotation the unit vector u1 using the rotation matrix + * u1[3] unit vector + * R[3][3] rotation matrix + * return resulting unit vector u2[3] + */ + tr_uu1: function( u1 , R) { + var u2 = new Array(3); + var x = u1[0]; + var y = u1[1]; + var z = u1[2]; + + u2[0] = R[0][0]*x + R[1][0]*y + R[2][0]*z; + u2[1] = R[0][1]*x + R[1][1]*y + R[2][1]*z; + u2[2] = R[0][2]*x + R[1][2]*y + R[2][2]*z; + + return u2; + }, + + /** + * Computes angles from direction cosines + * u[3] = direction cosines vector + * return o = [ ra, dec ] + */ + tr_uo: function(u) { + var x = u[0]; var y = u[1]; var z = u[2]; + var r2 = x*x + y*y; + var ra, dec; + if (r2 == 0.0) { + // in case of poles + if (z == 0.0) { + return null; + } + ra = 0.0; + dec = z > 0.0 ? 90.0 : -90.0; + } else { + dec = AstroMath.atand( z / Math.sqrt(r2)); + ra = AstroMath.atan2d (y , x ); + if (ra < 0.0) ra += 360.0; + } + + return [ ra, dec ]; + } +}//================================= +// Class Coo +//================================= + +/** + * Constructor + * @param longitude longitude (decimal degrees) + * @param latitude latitude (decimal degrees) + * @param prec precision + * (8: 1/1000th sec, 7: 1/100th sec, 6: 1/10th sec, 5: sec, 4: 1/10th min, 3: min, 2: 1/10th deg, 1: deg + */ +function Coo(longitude, latitude, prec) { + this.lon = longitude; + this.lat = latitude; + this.prec = prec; + this.frame = null; + + this.computeDirCos(); +} + +Coo.factor = [ 3600.0, 60.0, 1.0 ]; + +Coo.prototype = { + /** + * Set the frame for the coordinates + * @param astroframe frame code + */ + setFrame: function(astroframe) { + this.frame = astroframe; + }, + + /** + * Compute the direction cosine of these coordinates + */ + computeDirCos: function() { + var coslat = AstroMath.cosd(this.lat); + + this.x = coslat*AstroMath.cosd(this.lon); + this.y = coslat*AstroMath.sind(this.lon); + this.z = AstroMath.sind(this.lat); + }, + + /** + * Compute the coordinates from the direction cosine + */ + computeLonLat: function() { + var r2 = this.x*this.x+this.y*this.y; + this.lon = 0.0; + if (r2 == 0.0) { + // In case of poles + if (this.z == 0.0) { + this.lon = 0.0/0.0; + this.lat = 0.0/0.0; + } else { + this.lat = (this.z > 0.0) ? 90.0 : -90.0; + } + } else { + this.lon = AstroMath.atan2d(this.y, this.x); + this.lat = AstroMath.atan2d(this.z, Math.sqrt(r2)); + if (this.lon < 0) this.lon += 360.0; + } + }, + + /** + * Distance between 2 points on the sphere. + * @param pos another position on the sphere + * @return distance in degrees in range [0, 180] + **/ + distance: function(pos) { + // Take care of NaN: + if ((pos.x==0)&&(pos.y==0)&&(pos.z==0)) return(0./0.); + if ((this.x==0)&&(this.y==0)&&(this.z==0)) return(0./0.); + return (2. * AstroMath.asind(0.5 * Math.sqrt(this.dist2(pos)))); + }, + + /** + * Squared distance between 2 points (= 4.sin2(r/2)) + * @param pos another position on the sphere + * @return ||pos-this||2 = 4.sin2(r/2) + **/ + dist2: function(pos) { +// if ((this.x==0)&&(this.y==0)&&(this.z==0)) return(0./0.); +// if ((pos.x==0)&&(pos.y==0)&&(pos.z==0)) return(0./0.); + var w = pos.x - this.x; + var r2 = w * w; + w = pos.y - this.y; r2 += w * w; + w = pos.z - this.z; r2 += w * w; + return r2; + }, + + /** + * Transform the position into another frame. + * @param new_frame The frame of the resulting position. + **/ + convertTo: function(new_frame) { + // Verify first if frames identical -- then nothing to do ! + if (this.frame.equals(new_frame)) { + return; + } + + // Move via ICRS + this.frame.toICRS(this.coo); // Position now in ICRS + new_frame.fromICRS(this.coo); // Position now in new_frame + this.frame = new_frame; + this.lon = this.lat = 0./0.; // Actual angles not recomputed + }, + + /** + * Rotate a coordinate (apply a rotation to the position). + * @param R [3][3] Rotation Matrix + */ + rotate: function(R) { + var X, Y, Z; + if (R == Umatrix3) return; + X = R[0][0]*this.x + R[0][1]*this.y + R[0][2]*this.z; + Y = R[1][0]*this.x + R[1][1]*this.y + R[1][2]*this.z; + Z = R[2][0]*this.x + R[2][1]*this.y + R[2][2]*this.z; + // this.set(X, Y, Z); Not necessary to compute positions each time. + this.x = X; this.y = Y; this.z = Z; + this.lon = this.lat = 0./0.; + }, + + /** + * Rotate a coordinate (apply a rotation to the position) in reverse direction. + * The method is the inverse of rotate. + * @param R [3][3] Rotation Matrix + */ + rotate_1: function(R) { + var X, Y, Z; + if (R == Umatrix3) return; + X = R[0][0]*this.x + R[1][0]*this.y + R[2][0]*this.z; + Y = R[0][1]*this.x + R[1][1]*this.y + R[2][1]*this.z; + Z = R[0][2]*this.x + R[1][2]*this.y + R[2][2]*this.z; + // this.set(X, Y, Z); Not necessary to compute positions each time. + this.x = X; this.y = Y; this.z = Z; + this.lon = this.lat = 0./0.; + }, + + + /** + * Test equality of Coo. + * @param coo Second coordinate to compare with + * @return True if the two coordinates are equal + */ + equals: function(coo) { + return this.x == coo.x && this.y == coo.y && this.z == coo.z; + }, + + /** + * parse a coordinate string. The coordinates can be in decimal or sexagesimal + * @param str string to parse + */ + parse: function(str) { + var p = str.indexOf('+'); + if (p < 0) p = str.indexOf('-'); + if (p < 0) { + this.lon = 0.0/0.0; + this.lat = 0.0/0.0; + this.prec = 0; + return; + } + var strlon = str.substring(0,p); + var strlat = str.substring(p); + + this.lon = this.parseLon(strlon); // sets the precision parameter + this.lat = this.parseLat(strlat); // sets the precision parameter + }, + + /** + * Parse a longitude + */ + parseLon: function(str) { + var str = Strings.trim(str, ' '); + if (str.indexOf(' ') < 0) { + // The longitude is a integer or decimal number + var p = str.indexOf('.'); + this.prec = p < 0 ? 0 : str.length - p - 1; + return parseFloat(str); + } else { + var stok = new Tokenizer(str,' '); + var i = 0; + var l = 0; + var pr = 0; + while (stok.hasMore()) { + var tok = stok.nextToken(); + var dec = tok.indexOf('.'); + l += parseFloat(tok)*Coo.factor[i]; +// pr = dec < 0 ? 1 : 2; + switch (i) { + case 0: pr = dec < 0 ? 1 : 2; break; + case 1: pr = dec < 0 ? 3 : 4; break; + case 2: pr = dec < 0 ? 5 : 4+tok.length-dec; + default: break; + } + i++; + } + this.prec = pr; + return l*15/3600.0; + } + }, + + /** + * Parse a latitude + */ + parseLat: function(str) { + var str = Strings.trim(str, ' '); + var sign = str.charAt(0) == '+' ? 1 : -1; + str = str.substring(1); + if (str.indexOf(' ') < 0) { + // The longitude is a integer or decimal number + var p = str.indexOf('.'); + this.prec = p < 0 ? 0 : str.length - p - 1; + return parseFloat(str)*sign; + } else { + var stok = new Tokenizer(str,' '); + var i = 0; + var l = 0; + var pr = 0; + while (stok.hasMore()) { + var tok = stok.nextToken(); + var dec = tok.indexOf('.'); + l += parseFloat(tok)*Coo.factor[i]; + switch (i) { + case 0: pr = dec < 0 ? 1 : 2; break; + case 1: pr = dec < 0 ? 3 : 4; break; + case 2: pr = dec < 0 ? 5 : 4+tok.length-dec; + default: break; + } + i++; + } + this.prec = pr; + return l*sign/3600.0; + } + }, + + /** + * Format coordinates according to the options + * @param options 'd': decimal, 's': sexagésimal, '/': space separated, '2': return [ra,dec] in an array + * @return the formatted coordinates + */ + format: function(options) { + if (isNaN(this.lon)) this.computeLonLat(); + var strlon = "", strlat = ""; + if (options.indexOf('d') >= 0) { + // decimal display + strlon = Numbers.format(this.lon, this.prec); + strlat = Numbers.format(this.lat, this.prec); + } else { + // sexagesimal display + var hlon = this.lon/15.0; + var strlon = Numbers.toSexagesimal(hlon, this.prec, false); + var strlat = Numbers.toSexagesimal(this.lat, this.prec, true); + } + + if (options.indexOf('/') >= 0) { + return strlon+' '+strlat; + } else if (options.indexOf('2') >= 0) { + return [strlon, strlat]; + } + return strlon+strlat; + } + +} + + +//=================================== +// Class Tokenizer (similar to Java) +//=================================== + +/** + * Constructor + * @param str String to tokenize + * @param sep token separator char + */ +function Tokenizer(str, sep) { + this.string = Strings.trim(str, sep); + this.sep = sep; + this.pos = 0; +} + +Tokenizer.prototype = { + /** + * Check if the string has more tokens + * @return true if a token remains (read with nextToken()) + */ + hasMore: function() { + return this.pos < this.string.length; + }, + + /** + * Returns the next token (as long as hasMore() is true) + * @return the token string + */ + nextToken: function() { + // skip all the separator chars + var p0 = this.pos; + while (p0 < this.string.length && this.string.charAt(p0) == this.sep) p0++; + var p1 = p0; + // get the token + while (p1 < this.string.length && this.string.charAt(p1) != this.sep) p1++; + this.pos = p1; + return this.string.substring(p0, p1); + }, +} + +//================================ +// Class Strings (static methods) +//================================ +function Strings() {} + +/** + * Removes a given char at the beginning and the end of a string + * @param str string to trim + * @param c char to remove + * @return the trimmed string + */ + +Strings.trim = function(str, c) { + var p0=0, p1=str.length-1; + while (p0 < str.length && str.charAt(p0) == c) p0++; + if (p0 == str.length) return ""; + while (p1 > p0 && str.charAt(p1) == c) p1--; + return str.substring(p0, p1+1); +} + +//================================ +// Class Numbers (static methods) +//================================ +function Numbers() {} +// 0 1 2 3 4 5 6 7 8 9 +Numbers.pow10 = [ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, +// 10 11 12 13 14 + 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000 ]; +// 0 1 2 3 4 5 6 7 +Numbers.rndval = [ 0.5, 0.05, 0.005, 0.0005, 0.00005, 0.000005, 0.0000005, 0.00000005, +// 8 9 10 11 12 + 0.000000005, 0.0000000005, 0.00000000005, 0.000000000005, 0.0000000000005, +// 13 14 + 0.00000000000005, 0.00000000000005 ]; +/** + * Format a integer or decimal number, adjusting the value with 'prec' decimal digits + * @param num number (integer or decimal) + * @param prec precision (= number of decimal digit to keep or append) + * @return a string with the formatted number + */ +Numbers.format = function(num, prec) { + if (prec <= 0) { + // Return an integer number + return (Math.round(num)).toString(); + } + var str = num.toString(); + var p = str.indexOf('.'); + var nbdec = p >= 0 ? str.length-p-1 : 0; + if (prec >= nbdec) { + if (p < 0) str += '.'; + for (var i=0; i 0 and prec < nbdec + str = (num+Numbers.rndval[prec]).toString(); + return str.substr(0, p+prec+1); +} + + +/** + * Convert a decimal coordinate into sexagesimal string, according to the given precision
+ * 8: 1/1000th sec, 7: 1/100th sec, 6: 1/10th sec, 5: sec, 4: 1/10th min, 3: min, 2: 1/10th deg, 1: deg + * @param num number (integer or decimal) + * @param prec precision (= number of decimal digit to keep or append) + * @param plus if true, the '+' sign is displayed + * @return a string with the formatted sexagesimal number + */ +Numbers.toSexagesimal = function(num, prec, plus) { + var resu = ""; + var sign = num < 0 ? '-' : (plus ? '+' : ''); + var n = Math.abs(num); + + switch (prec) { + case 1: // deg + var n1 = Math.round(n); + return sign+n1.toString(); + case 2: // deg.d + return sign+Numbers.format(n, 1); + case 3: // deg min + var n1 = Math.floor(n); + var n2 = Math.round((n-n1)*60); + return sign+n1+' '+n2; + case 4: // deg min.d + var n1 = Math.floor(n); + var n2 = (n-n1)*60; + return sign+n1+' '+Numbers.format(n2, 1); + case 5: // deg min sec + var n1 = Math.floor(n); // d + var n2 = (n-n1)*60; // M.d + var n3 = Math.floor(n2);// M + var n4 = Math.round((n2-n3)*60); // S + return sign+n1+' '+n3+' '+n4; + case 6: // deg min sec.d + case 7: // deg min sec.dd + case 8: // deg min sec.ddd + var n1 = Math.floor(n); // d + if (n1<10) n1 = '0' + n1; + var n2 = (n-n1)*60; // M.d + var n3 = Math.floor(n2);// M + if (n3<10) n3 = '0' + n3; + var n4 = (n2-n3)*60; // S.ddd + return sign+n1+' '+n3+' '+Numbers.format(n4, prec-5); + default: + return sign+Numbers.format(n, 1); + } +} +CooConversion = (function() { + + var CooConversion = {}; + + CooConversion.GALACTIC_TO_J2000 = [ + -0.0548755604024359, 0.4941094279435681, -0.8676661489811610, + -0.8734370902479237, -0.4448296299195045, -0.1980763734646737, + -0.4838350155267381, 0.7469822444763707, 0.4559837762325372 ]; + + CooConversion.J2000_TO_GALACTIC = [ + -0.0548755604024359, -0.873437090247923, -0.4838350155267381, + 0.4941094279435681, -0.4448296299195045, 0.7469822444763707, + -0.8676661489811610, -0.1980763734646737, 0.4559837762325372 ]; + + // adapted from www.robertmartinayers.org/tools/coordinates.html + // radec : array of ra, dec in degrees + // return coo in degrees + CooConversion.Transform = function( radec, matrix ) {// returns a radec array of two elements + radec[0] = radec[0]*Math.PI/180; + radec[1] = radec[1]*Math.PI/180; + var r0 = new Array ( + Math.cos(radec[0]) * Math.cos(radec[1]), + Math.sin(radec[0]) * Math.cos(radec[1]), + Math.sin(radec[1]) ); + + var s0 = new Array ( + r0[0]*matrix[0] + r0[1]*matrix[1] + r0[2]*matrix[2], + r0[0]*matrix[3] + r0[1]*matrix[4] + r0[2]*matrix[5], + r0[0]*matrix[6] + r0[1]*matrix[7] + r0[2]*matrix[8] ); + + var r = Math.sqrt ( s0[0]*s0[0] + s0[1]*s0[1] + s0[2]*s0[2] ); + + var result = new Array ( 0.0, 0.0 ); + result[1] = Math.asin ( s0[2]/r ); // New dec in range -90.0 -- +90.0 + // or use sin^2 + cos^2 = 1.0 + var cosaa = ( (s0[0]/r) / Math.cos(result[1] ) ); + var sinaa = ( (s0[1]/r) / Math.cos(result[1] ) ); + result[0] = Math.atan2 (sinaa,cosaa); + if ( result[0] < 0.0 ) result[0] = result[0] + 2*Math.PI; + + result[0] = result[0]*180/Math.PI; + result[1] = result[1]*180/Math.PI; + return result; + }; + + // coo : array of lon, lat in degrees + CooConversion.GalacticToJ2000 = function(coo) { + return CooConversion.Transform(coo, CooConversion.GALACTIC_TO_J2000); + }; + // coo : array of lon, lat in degrees + CooConversion.J2000ToGalactic = function(coo) { + return CooConversion.Transform(coo, CooConversion.J2000_TO_GALACTIC); + }; + return CooConversion; +})();/****************************************************************************** + * Aladin HTML5 project + * + * File Sesame.js + * + * Author: Thomas Boch[CDS] + * + *****************************************************************************/ + +Sesame = (function() { + Sesame = {}; + + Sesame.cache = {}; + + Sesame.resolve = function(objectName, callbackFunctionSuccess, callbackFunctionError) { + //var sesameUrl = "http://cdsportal.u-strasbg.fr/services/sesame?format=json"; + var sesameUrl = "http://cds.u-strasbg.fr/cgi-bin/nph-sesame.jsonp?"; + $.ajax({ + url: sesameUrl , + data: {"object": objectName}, + method: 'GET', + dataType: 'jsonp', + success: function(data) { + if (data.Target && data.Target.Resolver && data.Target.Resolver) { + callbackFunctionSuccess(data); + } + else { + callbackFunctionError(data); + } + }, + error: callbackFunctionError + }); + }; + + return Sesame; +})(); + +/****************************************************************************** + * Aladin HTML5 project + * + * File HealpixCache + * + * Author: Thomas Boch[CDS] + * + *****************************************************************************/ + +// class holding some HEALPix computations for better performances +// +// it is made of : +// - a static cache for HEALPix corners at nside=8 +// - a dynamic cache for +HealpixCache = (function() { + + var HealpixCache = {}; + + HealpixCache.staticCache = {corners: {nside8: []}}; + // TODO : utilisation du dynamicCache + HealpixCache.dynamicCache = {}; + + HealpixCache.lastNside = 8; + + HealpixCache.hpxIdxCache = null; + + // TODO : conserver en cache le dernier résultat ? + + HealpixCache.init = function() { + // pre-compute corners position for nside=8 + var hpxIdx = new HealpixIndex(8); + hpxIdx.init(); + var npix = HealpixIndex.nside2Npix(8); + for (var ipix=0; ipix= maxsize) { // remove oldest element when no more room + keys.sort(function (a, b) { + if (expires[a] > expires[b]) return -1; + if (expires[a] < expires[b]) return 1; + return 0; + }); + + size--; + delete expires[keys[size]]; + delete items[keys[size]]; + } + + keys[size] = key; + items[key] = value; + expires[key] = Date.now(); + size++; + + this._keys = keys; + this._items = items; + this._expires = expires; + this._size = size; + }, + + get: function (key) { + var item = this._items[key]; + if (item) this._expires[key] = Date.now(); + return item; + }, + + keys: function() { + return this._keys; + } +}; +/****************************************************************************** + * Aladin HTML5 project + * + * File Color + * + * Author: Thomas Boch[CDS] + * + *****************************************************************************/ + + + Color = {}; + + Color.curIdx = 0; + Color.colors = ['#ff0000', '#0000ff', '#99cc00', '#ffff00','#000066', '#00ffff', '#9900cc', '#0099cc', '#cc9900', '#cc0099', '#00cc99', '#663333', '#ffcc9a', '#ff9acc', '#ccff33', '#660000', '#ffcc33', '#ff00ff', '#00ff00', '#ffffff']; + + + Color.getNextColor = function() { + var c = Color.colors[Color.curIdx % (Color.colors.length)]; + Color.curIdx++; + return c; + }; + + +/****************************************************************************** + * Aladin HTML5 project + * + * File AladinUtils + * + * Author: Thomas Boch[CDS] + * + *****************************************************************************/ +AladinUtils = (function() { + return { + /** + * passage de xy projection à xy dans la vue écran + * @param x + * @param y + * @param width + * @param height + * @param largestDim largest dimension of the view + * @returns position in the view + */ + xyToView: function(x, y, width, height, largestDim, zoomFactor) { + // we round the result for performance gains + return {vx: AladinUtils.myRound(largestDim/2*(1+zoomFactor*x)-(largestDim-width)/2), vy: AladinUtils.myRound(largestDim/2*(1+zoomFactor*y)-(largestDim-height)/2)}; + }, + + /** + * passage de xy dans la vue écran à xy projection + * @param vx + * @param vy + * @param width + * @param height + * @param largestDim + * @param zoomFactor + * @returns position in xy projection + */ + viewToXy: function(vx, vy, width, height, largestDim, zoomFactor) { + return {x: ((2*vx+(largestDim-width))/largestDim-1)/zoomFactor, y: ((2*vy+(largestDim-height))/largestDim-1)/zoomFactor}; + }, + + myRound: function(a) { + if (a<0) { + return -1*( (-a) | 0); + } + else { + return a | 0; + } + }, + + /** + * tests whether a healpix pixel is visible or not + * @param pixCorners array of position (xy view) of the corners of the pixel + * @param viewW + */ + isHpxPixVisible: function(pixCorners, viewWidth, viewHeight) { + for (var i = 0; i=-20 && pixCorners[i].vx<(viewWidth+20) && + pixCorners[i].vy>=-20 && pixCorners[i].vy<(viewHeight+20) ) { + return true; + } + } + return false; + }, + + ipixToIpix: function(npixIn, norderIn, norderOut) { + var npixOut = []; + if (norderIn>=norderOut) { + } + }, + + getZoomFactorForAngle: function(angleInDegrees, projectionMethod) { + var p1 = {ra: 0, dec: 0}; + var p2 = {ra: angleInDegrees, dec: 0}; + var projection = new Projection(angleInDegrees/2, 0); + projection.setProjection(projectionMethod); + var p1Projected = projection.project(p1.ra, p1.dec); + var p2Projected = projection.project(p2.ra, p2.dec); + + var zoomFactor = 1/(p1Projected.X - p2Projected.Y); + return zoomFactor; + } + + }; +})(); + +/****************************************************************************** + * Aladin HTML5 project + * + * File CooFrameEnum + * + * Author: Thomas Boch[CDS] + * + *****************************************************************************/ + + ProjectionEnum = { + SIN: Projection.PROJ_SIN, + AITOFF: Projection.PROJ_AITOFF + };/****************************************************************************** + * Aladin HTML5 project + * + * File CooFrameEnum + * + * Author: Thomas Boch[CDS] + * + *****************************************************************************/ + +CooFrameEnum = (function() { + + return { + J2000: "J2000", + GAL: "Galactic" + }; + +})(); + +// TODO : utiliser cette fonction partout où on reçoit une string frame en entrée +CooFrameEnum.fromString = function(str, defaultValue) { + if (! str) { + return defaultValue ? defaultValue : null; + } + + str = str.toLowerCase().replace(/^\s+|\s+$/g, ''); // convert to lowercase and trim + + if (str.indexOf('j2000')==0 || str.indexOf('icrs')==0) { + return CooFrameEnum.J2000; + } + else if (str.indexOf('g')==0) { + return CooFrameEnum.GAL; + } + else { + return defaultValue ? defaultValue : null; + } +};/****************************************************************************** + * Aladin HTML5 project + * + * File Downloader + * Queue downloading for image elements + * + * Author: Thomas Boch[CDS] + * + *****************************************************************************/ + +Downloader = (function() { + var NB_MAX_SIMULTANEOUS_DL = 4; + // TODO : le fading ne marche pas bien actuellement + var FADING_ENABLED = false; + var FADING_DURATION = 700; // in milliseconds + + + var Downloader = function(view) { + this.view = view; // reference to the view to be able to request redraw + this.nbDownloads = 0; // number of current downloads + this.dlQueue = []; // queue of items being downloaded + this.urlsInQueue = {}; + }; + + Downloader.prototype.requestDownload = function(img, url, cors) { + // first check if url already in queue + if (url in this.urlsInQueue) { + return; + } + // put in queue + this.dlQueue.push({img: img, url: url, cors: cors}); + this.urlsInQueue[url] = 1; + + this.tryDownload(); + }; + + // try to download next items in queue if possible + Downloader.prototype.tryDownload = function() { + //if (this.dlQueue.length>0 && this.nbDownloads0 && this.nbDownloads
'); + this.domEl.appendTo(parentDiv); + + var self = this; + // close popup + this.domEl.find('.aladin-closeBtn').click(function() {self.hide()}); + + }; + + Popup.prototype.hide = function() { + this.domEl.hide(); + }; + + Popup.prototype.show = function() { + this.domEl.show(); + }; + + Popup.prototype.setTitle = function(title) { + this.domEl.find('.aladin-popupTitle').html(title); + }; + + Popup.prototype.setText = function(text) { + this.domEl.find('.aladin-popupText').html(text); + this.w = this.domEl.outerWidth(); + this.h = this.domEl.outerHeight(); + }; + + Popup.prototype.setSource = function(source) { + // remove reference to popup for previous source + if (this.source) { + this.source.popup = null; + } + source.popup = this; + this.source = source; + this.setPosition(source.x, source.y); + }; + + Popup.prototype.setPosition = function(x, y) { + var newX = x - this.w/2; + var newY = y - this.h + this.source.catalog.sourceSize/2; + this.domEl[0].style.left = newX + 'px'; + this.domEl[0].style.top = newY + 'px'; + //this.domEl.css({'left': newX+'px', 'top': newY+'px'}); + }; + + return Popup; +})(); + +/****************************************************************************** + * Aladin HTML5 project + * + * File Overlay + * + * Description: a plane holding overlays (footprints for instance) + * + * Author: Thomas Boch[CDS] + * + *****************************************************************************/ + +Overlay = (function() { + Overlay = function(options) { + options = options || {}; + this.name = options.name || "overlay"; + this.color = options.color || Color.getNextColor(); + + + //this.indexationNorder = 5; // à quel niveau indexe-t-on les overlays + this.overlays = []; + //this.hpxIdx = new HealpixIndex(this.indexationNorder); + //this.hpxIdx.init(); + + + + }; + + + + + // return an array of Footprint from a STC-S string + Overlay.parseSTCS = function(stcs) { + var polygons = []; + var parts = stcs.match(/\S+/g); + var k = 0, len = parts.length; + var curPolygon; + while(k 6, e.g. `E0F` --> `EE00FF` + if(hex.length == 3){ + hex = hex.replace(/(.)/g, '$1$1'); + } + + var r = parseInt(hex.substr(0, 2), 16), + g = parseInt(hex.substr(2, 2), 16), + b = parseInt(hex.substr(4, 2), 16); + + return '#' + + ((0|(1<<8) + r + (256 - r) * percent / 100).toString(16)).substr(1) + + ((0|(1<<8) + g + (256 - g) * percent / 100).toString(16)).substr(1) + + ((0|(1<<8) + b + (256 - b) * percent / 100).toString(16)).substr(1); + } + + + + Overlay.prototype.drawFootprint = function(f, ctx, projection, frame, width, height, largestDim, zoomFactor) { + if (! f.isShowing) { + return null; + } + var xyviewArray = []; + var show = false; + var radecArray = f.polygons; + // for + for (var k=0, len=radecArray.length; k=0 && xyview.vy<=height && xyview.vy>=0) { + show = true; + } + } + + if (show) { + ctx.moveTo(xyviewArray[0].vx, xyviewArray[0].vy); + for (var k=1, len=xyviewArray.length; k(width+sourceSize) || xyview.vx<(0-sourceSize) || + xyview.vy>(height+sourceSize) || xyview.vy<(0-sourceSize)) { + s.x = s.y = undefined; + return; + } + + s.x = xyview.vx; + s.y = xyview.vy; + ctx.drawImage(this.cacheCanvas, s.x-sourceSize/2, s.y-sourceSize/2); + } + } + }, + + deselectAll: function() { + for (var k=0; kthis.maxOrder) { + norder = this.maxOrder; + } + if (norder<=3) { + return; // nothing to do, hurrayh ! + } + var cells = this.view.getVisibleCells(norder, this.frame); + var ipixList, ipix; + for (var curOrder=4; curOrder<=norder; curOrder++) { + ipixList = []; + for (var k=0; k=0 || ucd.indexOf('pos_eq_ra')>=0) { + raFieldIdx = l; + continue; + } + } + } + + if ( ! decFieldIdx) { + if (field.ucd) { + var ucd = field.ucd.toLowerCase(); + if (ucd.indexOf('pos.eq.dec')>=0 || ucd.indexOf('pos_eq_dec')>=0) { + decFieldIdx = l; + continue; + } + } + } + } + var sources = []; + + var coo = new Coo(); + var ra, dec; + $(xml).find("TR").each(function() { + var mesures = {}; + var k = 0; + $(this).find("TD").each(function() { + var key = fields[k].name ? fields[k].name : fields[k].id; + mesures[key] = $(this).text(); + k++; + }); + var keyRa = fields[raFieldIdx].name ? fields[raFieldIdx].name : fields[raFieldIdx].id; + var keyDec = fields[decFieldIdx].name ? fields[decFieldIdx].name : fields[decFieldIdx].id; + + if (Utils.isNumber(mesures[keyRa]) && Utils.isNumber(mesures[keyDec])) { + ra = parseFloat(mesures[keyRa]); + dec = parseFloat(mesures[keyDec]); + } + else { + coo.parse(mesures[keyRa] + " " + mesures[keyDec]); + ra = coo.lon; + dec = coo.lat; + } + sources.push(new cds.Source(ra, dec, mesures)); + }); + if (callback) { + callback(sources); + } + } + + $.ajax({ + url: Aladin.JSONP_PROXY, + data: {"url": url}, + method: 'GET', + dataType: 'jsonp', + success: function(xml) { + doParseVOTable(xml, callback); + }/*, + } + error: callbackFunctionError*/ + }); + }; + + cds.Catalog.prototype.addSources = function(sourcesToAdd) { + this.sources = this.sources.concat(sourcesToAdd); + for (var k=0, len=sourcesToAdd.length; k(width+max) || xyview.vx<(0-max) || + xyview.vy>(height+max) || xyview.vy<(0-max)) { + s.x = s.y = undefined; + return; + } + + s.x = xyview.vx; + s.y = xyview.vy; + + if (s.marker) { + ctx.drawImage(this.cacheMarkerCanvas, s.x-sourceSize/2, s.y-sourceSize/2); + } + else { + ctx.drawImage(this.cacheCanvas, s.x-sourceSize/2, s.y-sourceSize/2); + } + + + // has associated popup ? + if (s.popup) { + s.popup.setPosition(s.x, s.y); + } + +// ctx.moveTo(xyview.vx+sourceSize/2, xyview.vy+sourceSize/2); +// ctx.lineTo(xyview.vx+sourceSize/2, xyview.vy-sourceSize/2); +// ctx.lineTo(xyview.vx-sourceSize/2, xyview.vy-sourceSize/2); +// ctx.lineTo(xyview.vx-sourceSize/2, xyview.vy+sourceSize/2); +// ctx.lineTo(xyview.vx+sourceSize/2, xyview.vy+sourceSize/2); + + } + } + }; + + cds.Catalog.prototype.drawSourceSelection = function(s, ctx) { + if (!s || !s.isShowing || !s.x || !s.y) { + return; + } + var sourceSize = this.selectSize; + + ctx.drawImage(this.cacheSelectCanvas, s.x-sourceSize/2, s.y-sourceSize/2); + +// ctx.moveTo(xyview.vx-sourceSize/2, xyview.vy-sourceSize/2); +// ctx.lineTo(xyview.vx-sourceSize/2, xyview.vy+sourceSize/2); +// ctx.lineTo(xyview.vx+sourceSize/2, xyview.vy+sourceSize/2); +// ctx.lineTo(xyview.vx+sourceSize/2, xyview.vy-sourceSize/2); +// ctx.lineTo(xyview.vx-sourceSize/2, xyview.vy-sourceSize/2); + }; + + + // callback function to be called when the status of one of the sources has changed + cds.Catalog.prototype.reportChange = function() { + this.view.requestRedraw(); + }; + + cds.Catalog.prototype.show = function() { + if (this.isShowing) { + return; + } + this.isShowing = true; + this.reportChange(); + }; + + cds.Catalog.prototype.hide = function() { + if (! this.isShowing) { + return; + } + this.isShowing = false; + if (this.view.popup && this.view.popup.source && this.view.popup.source.catalog==this) { + this.view.popup.hide(); + } + this.reportChange(); + }; + + return cds.Catalog; +})(); +/****************************************************************************** + * Aladin HTML5 project + * + * File Tile + * + * Author: Thomas Boch[CDS] + * + *****************************************************************************/ + +Tile = (function() { + // constructor + function Tile(img, url) { + this.img = img; + this.url = url; + }; + + // check whether the image corresponding to the tile is loaded and ready to be displayed + // + // source : http://www.sajithmr.me/javascript-check-an-image-is-loaded-or-not + Tile.isImageOk = function(img) { + if (img.allSkyTexture) { + return true; + } + + if (!img.src) { + return false; + } + + // During the onload event, IE correctly identifies any images that + // weren’t downloaded as not complete. Others should too. Gecko-based + // browsers act like NS4 in that they report this incorrectly. + if (!img.complete) { + return false; + } + + // However, they do have two very useful properties: naturalWidth and + // naturalHeight. These give the true size of the image. If it failed + // to load, either of these should be zero. + + if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) { + return false; + } + + // No other way of checking: assume it’s ok. + return true; + }; + + + return Tile; +})(); +/****************************************************************************** + * Aladin HTML5 project + * + * File TileBuffer + * + * Author: Thomas Boch[CDS] + * + *****************************************************************************/ + +TileBuffer = (function() { + var NB_MAX_TILES = 800; // buffer size + + // constructor + function TileBuffer() { + this.pointer = 0; + this.tilesMap = {}; + this.tilesArray = new Array(NB_MAX_TILES); + + for (var i=0; i=NB_MAX_TILES) { + this.pointer = 0; + } + + return this.tilesMap[url]; + }; + + TileBuffer.prototype.getTile = function(url) { + return this.tilesMap[url]; + }; + + return TileBuffer; +})(); +/****************************************************************************** + * Aladin HTML5 project + * + * File ColorMap.js + * + * Author: Thomas Boch[CDS] + * + *****************************************************************************/ + +ColorMap = (function() { + + + // constructor + ColorMap = function(view) { + this.view = view; + this.reversed = false; + this.map = 'native'; + this.sig = this.signature(); + }; + +ColorMap.MAPS = {}; + + ColorMap.MAPS['eosb'] = { + name: 'Eos B', + r: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,9,18,27,36,45,49,57,72,81,91,100,109,118,127, + 136,131,139,163,173,182,191,200,209,218,227,213,221,255,255,255,255,255, + 255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,255,255, + 255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255, + 255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229, + 229,255,255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255, + 255,229,229,255,255,255,255,255,255,255,255,229,229,255,253,251,249,247, + 245,243,241,215,214,235,234,232,230,228,226,224,222,198,196,216,215,213, + 211,209,207,205,203,181,179,197,196,194,192,190,188,186,184,164,162,178, + 176,175,173,171,169,167,165,147,145,159,157,156,154,152,150,148,146,130, + 128,140,138,137,135,133,131,129,127,113,111,121,119,117,117], + g: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,15,23,31,39,47,55,57,64,79,87,95, + 103,111,119,127,135,129,136,159,167,175,183,191,199,207,215,200,207,239, + 247,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229, + 229,255,255,255,255,255,255,255,255,229,229,255,250,246,242,238,233,229, + 225,198,195,212,208,204,199,195,191,187,182,160,156,169,165,161,157,153, + 148,144,140,122,118,127,125,123,121,119,116,114,112,99,97,106,104,102, + 99,97,95,93,91,80,78,84,82,80,78,76,74,72,70,61,59,63,61,59,57,55,53,50, + 48,42,40,42,40,38,36,33,31,29,27,22,21,21,19,16,14,12,13,8,6,3,1,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + b: [116,121,127,131,136,140,144,148,153, + 157,145,149,170,174,178,182,187,191,195,199,183,187,212,216,221,225,229, + 233,238,242,221,225,255,247,239,231,223,215,207,199,172,164,175,167,159, + 151,143,135,127,119,100,93,95,87,79,71,63,55,47,39,28,21,15,7,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0] + }; + ColorMap.MAPS['rainbow'] = { + name: 'Rainbow', + r: [0,4,9,13,18,22,27,31,36,40,45,50,54, + 58,61,64,68,69,72,74,77,79,80,82,83,85,84,86,87,88,86,87,87,87,85,84,84, + 84,83,79,78,77,76,71,70,68,66,60,58,55,53,46,43,40,36,33,25,21,16,12,4,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,12,21,25,29,33,42, + 46,51,55,63,67,72,76,80,89,93,97,101,110,114,119,123,131,135,140,144,153, + 157,161,165,169,178,182,187,191,199,203,208,212,221,225,229,233,242,246, + 250,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255], + g: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,4,8,16,21,25,29,38,42,46,51,55,63,67,72,76,84,89,93,97, + 106,110,114,119,127,131,135,140,144,152,157,161,165,174,178,182,187,195, + 199,203,208,216,220,225,229,233,242,246,250,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,250,242,238,233,229,221,216,212,208,199,195,191,187,178,174,170,165, + 161,153,148,144,140,131,127,123,119,110,106,102,97,89,85,80,76,72,63,59, + 55,51,42,38,34,29,21,17,12,8,0], + b: [0,3,7,10,14,19,23,28,32,38,43,48,53, + 59,63,68,72,77,81,86,91,95,100,104,109,113,118,122,127,132,136,141,145, + 150,154,159,163,168,173,177,182,186,191,195,200,204,209,214,218,223,227, + 232,236,241,245,250,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,246,242,238,233,225,220,216,212,203,199,195,191, + 187,178,174,170,165,157,152,148,144,135,131,127,123,114,110,106,102,97, + 89,84,80,76,67,63,59,55,46,42,38,34,25,21,16,12,8,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + }; + + + ColorMap.MAPS_CUSTOM = ['rainbow', 'eosb']; + ColorMap.MAPS_NAMES = ['native', 'grayscale'].concat(ColorMap.MAPS_CUSTOM); + + ColorMap.prototype.reverse = function(val) { + if (val) { + this.reversed = val; + } + else { + this.reversed = ! this.reversed; + } + this.sig = this.signature(); + this.view.requestRedraw(); + }; + + + ColorMap.prototype.signature = function() { + var s = this.map; + + if (this.reversed) { + s += ' reversed'; + } + + return s; + }; + + ColorMap.prototype.update = function(map) { + this.map = map; + this.sig = this.signature(); + this.view.requestRedraw(); + }; + + ColorMap.prototype.apply = function(img) { + if ( this.sig=='native' ) { + return img; + } + + if (img.cmSig==this.sig) { + return img.cmImg; // return cached pixels + } + + var canvas = document.createElement("canvas"); + canvas.width = img.width; + canvas.height = img.height; + var ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0); + + var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); + var pixelData = imageData.data; + var length = pixelData.length; + var a, b, c; + var switchCase = 3; + if (this.map=='grayscale') { + switchCase = 1; + } + else if (ColorMap.MAPS_CUSTOM.indexOf(this.map)>=0) { + switchCase = 2; + } + for (var i = 0; i < length; i+= 4) { + switch(switchCase) { + case 1: + a = b = c = AladinUtils.myRound((pixelData[i]+pixelData[i+1]+pixelData[i+2])/3); + break; + case 2: + if (this.reversed) { + a = ColorMap.MAPS[this.map].r[255-pixelData[i]]; + b = ColorMap.MAPS[this.map].g[255-pixelData[i+1]]; + c = ColorMap.MAPS[this.map].b[255-pixelData[i+2]]; + } + else { + a = ColorMap.MAPS[this.map].r[pixelData[i]]; + b = ColorMap.MAPS[this.map].g[pixelData[i+1]]; + c = ColorMap.MAPS[this.map].b[pixelData[i+2]]; + } + break; + default: + a = pixelData[i]; + b = pixelData[i + 1]; + c = pixelData[i + 2]; + + } + if (switchCase!=2 && this.reversed) { + a = 255-a; + b = 255-b; + c = 255-c; + + } + pixelData[i] = a; + pixelData[i + 1] = b; + pixelData[i + 2] = c; + + } + imageData.data = pixelData; + ctx.putImageData(imageData, 0, 0); + + // cache image with color map applied + img.cmSig = this.sig; + img.cmImg = canvas; + + return img.cmImg; + }; + + return ColorMap; +})(); + +/****************************************************************************** + * Aladin HTML5 project + * + * File HpxImageSurvey + * + * Author: Thomas Boch[CDS] + * + *****************************************************************************/ + +HpxImageSurvey = (function() { + + + var HpxImageSurvey = function(id, name, rootUrl, cooFrame, maxOrder, options) { + this.id = id; + this.name = name; + this.rootUrl = rootUrl; + + options = options || {}; + this.imgFormat = options.imgFormat || 'jpg'; + + // permet de forcer l'affichage d'un certain niveau + this.minOrder = options.minOrder || null; + + if (cooFrame && cooFrame.toLowerCase()=="galactic") { + this.cooFrame = CooFrameEnum.GAL; + } + else { + this.cooFrame = CooFrameEnum.J2000; + } + + this.maxOrder = maxOrder; + + this.allskyTextures = []; + + + this.allskyTextureSize = 0; + + this.lastUpdateDateNeededTiles = 0; + + var found = false; + for (var k=0; k6) { + return; + } + + if ( ! this.allskyTextures ) { + return; + } + + + var cornersXYView; + var coeff = 0; + var center; + var ipix; + for (var k=0, len=cornersXYViewMap.length; k40) { + coeff = 0.02; + center = {x: (cornersXYView[0].vx+cornersXYView[2].vx)/2, y: (cornersXYView[0].vy+cornersXYView[2].vy)/2}; + for (var i=0; i<4; i++) { + var diff = {x: cornersXYView[i].vx-center.x, y: cornersXYView[i].vy-center.y}; + cornersXYView[i].vx += coeff*diff.x; + cornersXYView[i].vy += coeff*diff.y; + } + } + + this.drawOneTile(ctx, this.allskyTextures[ipix], cornersXYView, this.allskyTextureSize); + } + }; + + HpxImageSurvey.prototype.getColorMap = function() { + return this.cm; + }; + + // TODO: avoir un mode où on ne cherche pas à dessiner d'abord les tuiles parentes (pour génération vignettes côté serveur) + HpxImageSurvey.prototype.redrawHighres = function(ctx, cornersXYViewMap, norder) { + var now = new Date().getTime(); + var updateNeededTiles = (now-this.lastUpdateDateNeededTiles) > HpxImageSurvey.UPDATE_NEEDED_TILES_DELAY; + var tile, url, parentTile, parentUrl; + var parentNorder = norder - 1; + var cornersXYView, parentCornersXYView; + var tilesToDraw = []; + var parentTilesToDraw = []; + var parentTilesToDrawIpix = {}; + var missingTiles = false; + + var tilesToDownload = []; + var parentTilesToDownload = []; + + var parentIpix; + var ipix; + + // tri des tuiles selon la distance + if (updateNeededTiles) { + var center = [(cornersXYViewMap[0][0].vx+cornersXYViewMap[0][1].vx)/2, (cornersXYViewMap[0][0].vy+cornersXYViewMap[0][1].vy)/2]; + var newCornersXYViewMap = cornersXYViewMap.sort(function(a, b) { + var cA = [(a[0].vx+a[2].vx)/2, (a[0].vy+a[2].vy)/2]; + var cB = [(b[0].vx+b[2].vx)/2, (b[0].vy+b[2].vy)/2]; + + var distA = (cA[0]-center[0])*(cA[0]-center[0]) + (cA[1]-center[1])*(cA[1]-center[1]); + var distB = (cB[0]-center[0])*(cB[0]-center[0]) + (cB[1]-center[1])*(cB[1]-center[1]); + + return distA-distB; + + }); + cornersXYViewMap = newCornersXYViewMap; + } + + for (var k=0, len=cornersXYViewMap.length; k=3) { + parentTile = this.tileBuffer.addTile(parentUrl); + if (parentTile) { + parentTilesToDownload.push({img: parentTile.img, url: parentUrl}); + //this.view.downloader.requestDownload(parentTile.img, parentUrl); + } + } + + url = this.getTileURL(norder, ipix); + tile = this.tileBuffer.getTile(url); + + if ( ! tile ) { + missingTiles = true; + + if (updateNeededTiles) { + var tile = this.tileBuffer.addTile(url); + if (tile) { + tilesToDownload.push({img: tile.img, url: url}); + //this.view.downloader.requestDownload(tile.img, url); + } + } + + // is the parent tile available ? + if (parentNorder>=3 && ! parentTilesToDrawIpix[parentIpix]) { + parentTile = this.tileBuffer.getTile(parentUrl); + if (parentTile && Tile.isImageOk(parentTile.img)) { + parentCornersXYView = this.view.getPositionsInView(parentIpix, parentNorder); + if (parentCornersXYView) { + parentTilesToDraw.push({img: parentTile.img, corners: parentCornersXYView, ipix: parentIpix}); + } + } + parentTilesToDrawIpix[parentIpix] = 1; + } + + continue; + } + else if ( ! Tile.isImageOk(tile.img)) { + missingTiles = true; + if (updateNeededTiles && ! tile.img.dlError) { + tilesToDownload.push({img: tile.img, url: url}); + //this.view.downloader.requestDownload(tile.img, url); + } + + // is the parent tile available ? + if (parentNorder>=3 && ! parentTilesToDrawIpix[parentIpix]) { + parentTile = this.tileBuffer.getTile(parentUrl); + if (parentTile && Tile.isImageOk(parentTile.img)) { + parentCornersXYView = this.view.getPositionsInView(parentIpix, parentNorder); + if (parentCornersXYView) { + parentTilesToDraw.push({img: parentTile.img, corners: parentCornersXYView, ipix: parentIpix}); + } + } + parentTilesToDrawIpix[parentIpix] = 1; + } + + continue; + } + tilesToDraw.push({img: tile.img, corners: cornersXYView}); + } + + + + // draw parent tiles + for (var k=0, len = parentTilesToDraw.length; k 0); + */ + + ///* + for (var k=0, len = tilesToDraw.length; k").appendTo(this.aladinDiv)[0]; + // canvas to draw the catalogs + this.catalogCanvas = $("").appendTo(this.aladinDiv)[0]; + // canvas to draw the reticle + this.reticleCanvas = $("").appendTo(this.aladinDiv)[0]; + }; + + + // called at startup and when window is resized + View.prototype.fixLayoutDimensions = function() { + Utils.cssScale = undefined; + + this.width = $(this.aladinDiv).width(); + this.height = $(this.aladinDiv).height(); + + + this.cx = this.width/2; + this.cy = this.height/2; + + this.largestDim = Math.max(this.width, this.height); + this.smallestDim = Math.min(this.width, this.height); + this.ratio = this.largestDim/this.smallestDim; + + + this.mouseMoveIncrement = 160/this.largestDim; + + + // reinitialize 2D context + this.imageCtx = this.imageCanvas.getContext("2d"); + this.catalogCtx = this.catalogCanvas.getContext("2d"); + this.reticleCtx = this.reticleCanvas.getContext("2d"); + + this.imageCtx.canvas.width = this.width; + this.catalogCtx.canvas.width = this.width; + this.reticleCtx.canvas.width = this.width; + + + this.imageCtx.canvas.height = this.height; + this.catalogCtx.canvas.height = this.height; + this.reticleCtx.canvas.height = this.height; + + this.computeNorder(); + this.requestRedraw(); + }; + + + View.prototype.setMode = function(mode) { + this.mode = mode; + if (this.mode==View.SELECT) { + this.setCursor('crosshair'); + } + else { + this.setCursor('default'); + } + }; + + View.prototype.setCursor = function(cursor) { + if (this.reticleCanvas.style.cursor==cursor) { + return; + } + this.reticleCanvas.style.cursor = cursor; + }; + + + + /** + * return dataURL string corresponding to the current view + */ + View.prototype.getCanvasDataURL = function() { + var c = document.createElement('canvas'); + c.width = this.width; + c.height = this.height; + var ctx = c.getContext('2d'); + ctx.drawImage(this.imageCanvas, 0, 0); + ctx.drawImage(this.catalogCanvas, 0, 0); + ctx.drawImage(this.reticleCanvas, 0, 0); + + return c.toDataURL("image/png"); + }; + + + /** + * Compute the FoV in degrees of the view and update mouseMoveIncrement + * + * @param view + * @returns FoV (array of 2 elements : width and height) in degrees + */ + computeFov = function(view) { + var fov = doComputeFov(view, view.zoomFactor); + + + view.mouseMoveIncrement = fov/view.imageCanvas.width; + + return fov; + }; + + doComputeFov = function(view, zoomFactor) { + // if zoom factor < 1, we view 180° + if (view.zoomFactor<1) { + fov = 180; + } + else { + // TODO : fov sur les 2 dimensions !! + // to compute FoV, we first retrieve 2 points at coordinates (0, view.cy) and (width-1, view.cy) + var xy1 = AladinUtils.viewToXy(0, view.cy, view.width, view.height, view.largestDim, zoomFactor); + var lonlat1 = view.projection.unproject(xy1.x, xy1.y); + + var xy2 = AladinUtils.viewToXy(view.imageCanvas.width-1, view.cy, view.width, view.height, view.largestDim, zoomFactor); + var lonlat2 = view.projection.unproject(xy2.x, xy2.y); + + + fov = new Coo(lonlat1.ra, lonlat1.dec).distance(new Coo(lonlat2.ra, lonlat2.dec)); + } + + return fov; + }; + + updateFovDiv = function(view) { + if (isNaN(view.fov)) { + view.fovDiv.html("FoV:"); + return; + } + // màj valeur FoV + var fovStr; + if (view.fov>1) { + fovStr = Math.round(view.fov*100)/100 + "°"; + } + else if (view.fov*60>1) { + fovStr = Math.round(view.fov*60*100)/100 + "'"; + } + else { + fovStr = Math.round(view.fov*3600*100)/100 + '"'; + } + view.fovDiv.html("FoV: " + fovStr); + }; + + + createListeners = function(view) { + var hasTouchEvents = false; + if ('ontouchstart' in window) { + hasTouchEvents = true; + } + + // various listeners + onDblClick = function(e) { + var xymouse = view.imageCanvas.relMouseCoords(e); + var xy = AladinUtils.viewToXy(xymouse.x, xymouse.y, view.width, view.height, view.largestDim, view.zoomFactor); + try { + var lonlat = view.projection.unproject(xy.x, xy.y); + } + catch(err) { + return; + } + radec = []; + // convert to J2000 if needed + if (view.cooFrame==CooFrameEnum.GAL) { + radec = CooConversion.GalacticToJ2000([lonlat.ra, lonlat.dec]); + } + else { + radec = [lonlat.ra, lonlat.dec]; + } + + view.pointTo(radec[0], radec[1]); + }; + if (! hasTouchEvents) { + $(view.reticleCanvas).dblclick(onDblClick); + } + + + $(view.reticleCanvas).bind("mousedown touchstart", function(e) { + var xymouse = view.imageCanvas.relMouseCoords(e); + if (e.originalEvent && e.originalEvent.targetTouches) { + view.dragx = e.originalEvent.targetTouches[0].clientX; + view.dragy = e.originalEvent.targetTouches[0].clientY; + } + else { + /* + view.dragx = e.clientX; + view.dragy = e.clientY; + */ + view.dragx = xymouse.x; + view.dragy = xymouse.y; + } + view.dragging = true; + if (view.mode==View.PAN) { + view.setCursor('move'); + } + else if (view.mode==View.SELECT) { + view.selectStartCoo = {x: view.dragx, y: view.dragy}; + } + return false; // to disable text selection + }); + $(view.reticleCanvas).bind("mouseup mouseout touchend", function(e) { + if (view.mode==View.SELECT && view.dragging) { + view.aladin.fire('selectend', + view.getObjectsInBBox(view.selectStartCoo.x, view.selectStartCoo.y, + view.dragx-view.selectStartCoo.x, view.dragy-view.selectStartCoo.y)); + } + if (view.dragging) { + view.setCursor('default'); + view.dragging = false; + + } + view.mustClearCatalog = true; + view.mustRedrawReticle = true; // pour effacer selection bounding box + view.dragx = view.dragy = null; + + + var xymouse = view.imageCanvas.relMouseCoords(e); + // popup to show ? + var objs = view.closestObjects(xymouse.x, xymouse.y, 5); + if (objs) { + var o = objs[0]; + // display marker + if (o.marker) { + view.popup.setTitle(o.popupTitle); + view.popup.setText(o.popupDesc); + view.popup.setSource(o); + view.popup.show(); + } + // show measurements + else { + // TODO: show measurements + if (view.aladin.objClickedFunction) { + var ret = view.aladin.objClickedFunction(o); + } + } + } + + + // TODO : remplacer par mécanisme de listeners + // on avertit les catalogues progressifs + if (e.type!=="mouseout") { + view.refreshProgressiveCats(); + } + view.requestRedraw(); + }); + $(view.reticleCanvas).bind("mousemove touchmove", function(e) { + e.preventDefault(); + var xymouse = view.imageCanvas.relMouseCoords(e); + if (!view.dragging || hasTouchEvents) { + updateLocation(view, xymouse.x, xymouse.y, true); + /* + var xy = AladinUtils.viewToXy(xymouse.x, xymouse.y, view.width, view.height, view.largestDim, view.zoomFactor); + var lonlat; + try { + lonlat = view.projection.unproject(xy.x, xy.y); + } + catch(err) { + } + if (lonlat) { + view.location.update(lonlat.ra, lonlat.dec, view.cooFrame, true); + } + */ + if (!view.dragging && ! view.mode==View.SELECT) { + // objects under the mouse ? + var closest = view.closestObjects(xymouse.x, xymouse.y, 5); + if (closest) { + view.setCursor('pointer'); + if (view.aladin.objHoveredFunction) { + var ret = view.aladin.objHoveredFunction(closest[0]); + } + } + else { + view.setCursor('default'); + } + } + if (!hasTouchEvents) return; + } + + var xoffset, yoffset; + var pos1, pos2; + + if (e.originalEvent && e.originalEvent.targetTouches) { + // ??? + xoffset = e.originalEvent.targetTouches[0].clientX-view.dragx; + yoffset = e.originalEvent.targetTouches[0].clientY-view.dragy; + var xy1 = AladinUtils.viewToXy(e.originalEvent.targetTouches[0].clientX, e.originalEvent.targetTouches[0].clientY, view.width, view.height, view.largestDim, view.zoomFactor); + var xy2 = AladinUtils.viewToXy(view.dragx, view.dragy, view.width, view.height, view.largestDim, view.zoomFactor); + + pos1 = view.projection.unproject(xy1.x, xy1.y); + pos2 = view.projection.unproject(xy2.x, xy2.y); + } + else { + /* + xoffset = e.clientX-view.dragx; + yoffset = e.clientY-view.dragy; + */ + xoffset = xymouse.x-view.dragx; + yoffset = xymouse.y-view.dragy; + + var xy1 = AladinUtils.viewToXy(xymouse.x, xymouse.y, view.width, view.height, view.largestDim, view.zoomFactor); + var xy2 = AladinUtils.viewToXy(view.dragx, view.dragy, view.width, view.height, view.largestDim, view.zoomFactor); + + + pos1 = view.projection.unproject(xy1.x, xy1.y); + pos2 = view.projection.unproject(xy2.x, xy2.y); + + } + + // TODO : faut il faire ce test ?? +// var distSquared = xoffset*xoffset+yoffset*yoffset; +// if (distSquared<3) { +// return; +// } + if (e.originalEvent && e.originalEvent.targetTouches) { + view.dragx = e.originalEvent.targetTouches[0].clientX; + view.dragy = e.originalEvent.targetTouches[0].clientY; + } + else { + view.dragx = xymouse.x; + view.dragy = xymouse.y; + /* + view.dragx = e.clientX; + view.dragy = e.clientY; + */ + } + + if (view.mode==View.SELECT) { + view.requestRedraw(); + return; + } + + //view.viewCenter.lon += xoffset*view.mouseMoveIncrement/Math.cos(view.viewCenter.lat*Math.PI/180.0); + /* + view.viewCenter.lon += xoffset*view.mouseMoveIncrement; + view.viewCenter.lat += yoffset*view.mouseMoveIncrement; + */ + view.viewCenter.lon += pos2.ra - pos1.ra; + view.viewCenter.lat += pos2.dec - pos1.dec; + + + + // can not go beyond poles + if (view.viewCenter.lat>90) { + view.viewCenter.lat = 90; + } + else if (view.viewCenter.lat < -90) { + view.viewCenter.lat = -90; + } + + // limit lon to [0, 360] + if (view.viewCenter.lon < 0) { + view.viewCenter.lon = 360 + view.viewCenter.lon; + } + else if (view.viewCenter.lon > 360) { + view.viewCenter.lon = view.viewCenter.lon % 360; + } + view.requestRedraw(); + }); //// endof mousemove //// + + // disable text selection on IE + $(view.aladinDiv).onselectstart = function () { return false; } + + $(view.reticleCanvas).bind('mousewheel', function(event, delta) { + event.preventDefault(); + event.stopPropagation(); + var level = view.zoomLevel; + if (delta>0) { + level += 1; + } + else { + level -= 1; + } + view.setZoomLevel(level); + + return false; + }); + + }; + + init = function(view) { + + + var stats = new Stats(); + stats.domElement.style.top = '50px'; + if ($('#aladin-statsDiv').length>0) { + $('#aladin-statsDiv')[0].appendChild( stats.domElement ); + } + + view.stats = stats; + + createListeners(view); + + view.displayHpxGrid = false; + view.displaySurvey = true; + view.displayCatalog = false; + view.displayReticle = true; + + // initial draw + view.fov = computeFov(view); + updateFovDiv(view); + + view.redraw(); + }; + + function updateLocation(view, x, y, italic) { + if (!view.projection) { + return; + } + var xy = AladinUtils.viewToXy(x, y, view.width, view.height, view.largestDim, view.zoomFactor); + var lonlat; + try { + lonlat = view.projection.unproject(xy.x, xy.y); + } + catch(err) { + } + if (lonlat) { + view.location.update(lonlat.ra, lonlat.dec, view.cooFrame, italic); + } + } + + View.prototype.requestRedrawAtDate = function(date) { + this.dateRequestDraw = date; + }; + + /** + * redraw the whole view + */ + View.prototype.redraw = function() { + var saveNeedRedraw = this.needRedraw; + requestAnimFrame(this.redraw.bind(this)); + + var now = new Date().getTime(); + if (this.dateRequestDraw && now>this.dateRequestDraw) { + this.dateRequestDraw = null; + } + else if (! this.needRedraw) { + if ( ! this.flagForceRedraw) { + return; + } + else { + this.flagForceRedraw = false; + } + } + this.stats.update(); + + var imageCtx = this.imageCtx; + //////// 1. Draw images //////// + + //// clear canvas //// + // TODO : do not need to clear if fov small enough ? + imageCtx.clearRect(0, 0, this.imageCanvas.width, this.imageCanvas.height); + //////////////////////// + + // black background + if (this.projectionMethod==ProjectionEnum.SIN) { + if (this.fov>80) { + imageCtx.fillStyle = "rgb(0,0,0)"; + imageCtx.beginPath(); + imageCtx.arc(this.cx, this.cy, this.cx*this.zoomFactor, 0, 2*Math.PI, true); + imageCtx.fill(); + } + // pour éviter les losanges blancs qui apparaissent quand les tuiles sont en attente de chargement + else if (this.fov<60) { + imageCtx.fillStyle = "rgb(0,0,0)"; + imageCtx.fillRect(0, 0, this.imageCanvas.width, this.imageCanvas.height); + } + } + + + // TODO : voir si on doit vraiment faire ces vérifs à chaque coup + if (!this.projection) { + this.projection = new Projection(this.viewCenter.lon, this.viewCenter.lat); + } + else { + this.projection.setCenter(this.viewCenter.lon, this.viewCenter.lat); + } + this.projection.setProjection(this.projectionMethod); + + + // ************* Tracé au niveau allsky (faible résolution) ***************** + var cornersXYViewMapAllsky = this.getVisibleCells(3); + var cornersXYViewMapHighres = null; + if (this.curNorder>=3) { + if (this.curNorder==3) { + cornersXYViewMapHighres = cornersXYViewMapAllsky; + } + else { + cornersXYViewMapHighres = this.getVisibleCells(this.curNorder); + } + } + + // redraw image survey + if (this.imageSurvey && this.imageSurvey.isReady && this.displaySurvey) { + // TODO : a t on besoin de dessiner le allsky si norder>=3 ? + // TODO : devrait être une méthode de HpxImageSurvey + this.imageSurvey.redrawAllsky(imageCtx, cornersXYViewMapAllsky, this.fov, this.curNorder); + if (this.curNorder>=3) { + this.imageSurvey.redrawHighres(imageCtx, cornersXYViewMapHighres, this.curNorder); + } + } + + + + + + // redraw grid + if( this.displayHpxGrid) { + if (cornersXYViewMapHighres && this.curNorder>3) { + this.healpixGrid.redraw(imageCtx, cornersXYViewMapHighres, this.fov, this.curNorder); + } + else { + this.healpixGrid.redraw(imageCtx, cornersXYViewMapAllsky, this.fov, 3); + } + } + + + + + ////// 2. Draw catalogues//////// + var catalogCtx = this.catalogCtx; + + var catalogCanvasCleared = false; + if (this.mustClearCatalog) { + catalogCtx.clearRect(0, 0, this.width, this.height); + catalogCanvasCleared = true; + this.mustClearCatalog = false; + } + if (this.catalogs && this.catalogs.length>0 && this.displayCatalog && (! this.dragging || View.DRAW_SOURCES_WHILE_DRAGGING)) { + // TODO : ne pas effacer systématiquement + //// clear canvas //// + if (! catalogCanvasCleared) { + catalogCtx.clearRect(0, 0, this.width, this.height); + catalogCanvasCleared = true; + } + for (var i=0; i0 && (! this.dragging || View.DRAW_SOURCES_WHILE_DRAGGING)) { + if (! catalogCanvasCleared) { + catalogCtx.clearRect(0, 0, this.width, this.height); + catalogCanvasCleared = true; + } + for (var i=0; i mustRedrawReticle + var reticleCtx = this.reticleCtx; + if (this.mustRedrawReticle || this.mode==View.SELECT) { + reticleCtx.clearRect(0, 0, this.width, this.height); + } + if (this.displayReticle) { + + if (! this.reticleCache) { + // build reticle image + var c = document.createElement('canvas'); + var s = this.options.reticleSize; + c.width = s; + c.height = s; + var ctx = c.getContext('2d'); + ctx.lineWidth = 2; + ctx.strokeStyle = this.options.reticleColor; + ctx.beginPath(); + ctx.moveTo(s/2, s/2+(s/2-1)); + ctx.lineTo(s/2, s/2+2); + ctx.moveTo(s/2, s/2-(s/2-1)); + ctx.lineTo(s/2, s/2-2); + + ctx.moveTo(s/2+(s/2-1), s/2); + ctx.lineTo(s/2+2, s/2); + ctx.moveTo(s/2-(s/2-1), s/2); + ctx.lineTo(s/2-2, s/2); + + ctx.stroke(); + + this.reticleCache = c; + } + + reticleCtx.drawImage(this.reticleCache, this.width/2 - this.reticleCache.width/2, this.height/2 - this.reticleCache.height/2); + + + this.mustRedrawReticle = false; + } + + // draw selection box + if (this.mode==View.SELECT && this.dragging) { + reticleCtx.fillStyle = "rgba(100, 240, 110, 0.25)"; + var w = this.dragx - this.selectStartCoo.x; + var h = this.dragy - this.selectStartCoo.y; + + reticleCtx.fillRect(this.selectStartCoo.x, this.selectStartCoo.y, w, h); + } + + + // TODO : est ce la bonne façon de faire ? + if (saveNeedRedraw==this.needRedraw) { + this.needRedraw = false; + } + + + // objects lookup + if (!this.dragging) { + this.updateObjectsLookup(); + } + }; + + View.prototype.forceRedraw = function() { + this.flagForceRedraw = true; + }; + + View.prototype.refreshProgressiveCats = function() { + if (! this.catalogs) { + return; + } + for (var i=0; i80) { + pixList = []; + for (var ipix=0; ipix60) { + radius *= 1.6; + } + else if (this.fov>12) { + radius *=1.45; + } + else { + radius *= 1.1; + } + + + + pixList = hpxIdx.queryDisc(spatialVector, radius*Math.PI/180.0, true, true); + // add central pixel at index 0 + var polar = Utils.radecToPolar(lonlat[0], lonlat[1]); + ipixCenter = hpxIdx.ang2pix_nest(polar.theta, polar.phi); + pixList.unshift(ipixCenter); + } + + + var ipix; + var lon, lat; + for (var ipixIdx=0, len=pixList.length; ipixIdx0) { + continue; + } + var cornersXYView = []; + corners = HealpixCache.corners_nest(ipix, nside); + + for (var k=0; k<4; k++) { + spVec.setXYZ(corners[k].x, corners[k].y, corners[k].z); + + // need for frame transformation ? + if (frameSurvey && frameSurvey != this.cooFrame) { + if (frameSurvey==CooFrameEnum.J2000) { + var radec = CooConversion.J2000ToGalactic([spVec.ra(), spVec.dec()]); + lon = radec[0]; + lat = radec[1]; + } + else if (frameSurvey==CooFrameEnum.GAL) { + var radec = CooConversion.GalacticToJ2000([spVec.ra(), spVec.dec()]); + lon = radec[0]; + lat = radec[1]; + } + } + else { + lon = spVec.ra(); + lat = spVec.dec(); + } + + cornersXY[k] = this.projection.project(lon, lat); + } + + + if (cornersXY[0] == null || cornersXY[1] == null || cornersXY[2] == null || cornersXY[3] == null ) { + continue; + } + + + + for (var k=0; k<4; k++) { + cornersXYView[k] = AladinUtils.xyToView(cornersXY[k].X, cornersXY[k].Y, this.width, this.height, this.largestDim, this.zoomFactor); + } + + var indulge = 10; + // detect pixels outside view. Could be improved ! + // we minimize here the number of cells returned + if( cornersXYView[0].vx<0 && cornersXYView[1].vx<0 && cornersXYView[2].vx<0 &&cornersXYView[3].vx<0) { + continue; + } + if( cornersXYView[0].vy<0 && cornersXYView[1].vy<0 && cornersXYView[2].vy<0 &&cornersXYView[3].vy<0) { + continue; + } + if( cornersXYView[0].vx>=this.width && cornersXYView[1].vx>=this.width && cornersXYView[2].vx>=this.width &&cornersXYView[3].vx>=this.width) { + continue; + } + if( cornersXYView[0].vy>=this.height && cornersXYView[1].vy>=this.height && cornersXYView[2].vy>=this.height &&cornersXYView[3].vy>=this.height) { + continue; + } + + + // check if pixel is visible +// if (this.fov<160) { // don't bother checking if fov is large enough +// if ( ! AladinUtils.isHpxPixVisible(cornersXYView, this.width, this.height) ) { +// continue; +// } +// } + // check if we have a pixel at the edge of the view in AITOFF --> TO BE MODIFIED + if (this.projection.PROJECTION==ProjectionEnum.AITOFF) { + var xdiff = cornersXYView[0].vx-cornersXYView[2].vx; + var ydiff = cornersXYView[0].vy-cornersXYView[2].vy; + var distDiag = Math.sqrt(xdiff*xdiff + ydiff*ydiff); + if (distDiag>this.largestDim/5) { + continue; + } + xdiff = cornersXYView[1].vx-cornersXYView[3].vx; + ydiff = cornersXYView[1].vy-cornersXYView[3].vy; + distDiag = Math.sqrt(xdiff*xdiff + ydiff*ydiff); + if (distDiag>this.largestDim/5) { + continue; + } + } + + cornersXYView.ipix = ipix; + cells.push(cornersXYView); + } + + return cells; + }; + + + + // get position in view for a given HEALPix cell + View.prototype.getPositionsInView = function(ipix, norder) { + var cornersXY = []; + var lon, lat; + var spVec = new SpatialVector(); + var nside = Math.pow(2, norder); // TODO : à changer + + + var cornersXYView = []; // will be returned + var corners = HealpixCache.corners_nest(ipix, nside); + + for (var k=0; k<4; k++) { + spVec.setXYZ(corners[k].x, corners[k].y, corners[k].z); + + // need for frame transformation ? + if (this.imageSurvey && this.imageSurvey.cooFrame != this.cooFrame) { + if (this.imageSurvey.cooFrame==CooFrameEnum.J2000) { + var radec = CooConversion.J2000ToGalactic([spVec.ra(), spVec.dec()]); + lon = radec[0]; + lat = radec[1]; + } + else if (this.imageSurvey.cooFrame==CooFrameEnum.GAL) { + var radec = CooConversion.GalacticToJ2000([spVec.ra(), spVec.dec()]); + lon = radec[0]; + lat = radec[1]; + } + } + else { + lon = spVec.ra(); + lat = spVec.dec(); + } + + cornersXY[k] = this.projection.project(lon, lat); + } + + if (cornersXY[0] == null || cornersXY[1] == null || cornersXY[2] == null || cornersXY[3] == null ) { + return null; + } + + + for (var k=0; k<4; k++) { + cornersXYView[k] = AladinUtils.xyToView(cornersXY[k].X, cornersXY[k].Y, this.width, this.height, this.largestDim, this.zoomFactor); + } + + return cornersXYView; + }; + + + View.prototype.computeZoomFactor = function(level) { + if (level>0) { + return AladinUtils.getZoomFactorForAngle(180/Math.pow(1.15, level), this.projectionMethod); + } + else { + return 1 + 0.1*level; + } + }; + + View.prototype.setZoom = function(fovDegrees) { + if (fovDegrees<0 || fovDegrees>180) { + return; + } + var zoomLevel = Math.log(180/fovDegrees)/Math.log(1.15); + this.setZoomLevel(zoomLevel); + }; + + + View.prototype.setZoomLevel = function(level) { + if (this.minFOV || this.maxFOV) { + var newFov = doComputeFov(this, this.computeZoomFactor(Math.max(-2, level))); + if (this.maxFOV && newFov>this.maxFOV || this.minFOV && newFov2) { + norder = this.imageSurvey.minOrder; + } + + if (this.imageSurvey && norder>this.imageSurvey.maxOrder) { + norder = this.imageSurvey.maxOrder; + } + // should never happen, as calculateNSide will return something <=HealpixIndex.ORDER_MAX + if (norder>HealpixIndex.ORDER_MAX) { + norder = HealpixIndex.ORDER_MAX; + } + + this.curNorder = norder; + }; + + View.prototype.untaintCanvases = function() { + this.createCanvases(); + createListeners(this); + this.fixLayoutDimensions(); + }; + + // @param imageSurvey : HpxImageSurvey object or image survey identifier + View.prototype.setImageSurvey = function(imageSurvey) { + if (! imageSurvey) { + return; + } + + // reset canvas to "untaint" canvas if needed + // we test if the previous base image layer was using CORS or not + if ($.support.cors && this.imageSurvey && ! this.imageSurvey.useCors) { + this.untaintCanvases(); + } + + var newImageSurvey; + if (typeof imageSurvey == "string") { + newImageSurvey = HpxImageSurvey.getSurveyFromId(imageSurvey); + if ( ! newImageSurvey) { + newImageSurvey = HpxImageSurvey.getSurveyFromId(HpxImageSurvey.DEFAULT_SURVEY_ID); + } + } + else { + newImageSurvey = imageSurvey; + } + newImageSurvey.isReady = false; + this.imageSurvey = newImageSurvey; + + var self = this; + newImageSurvey.init(this, function() { + //self.imageSurvey = newImageSurvey; + self.computeNorder(); + newImageSurvey.isReady = true; + self.requestRedraw(); + self.updateObjectsLookup(); + }); + }; + + View.prototype.requestRedraw = function() { + this.needRedraw = true; + //redraw(this); + }; + + View.prototype.changeProjection = function(projectionMethod) { + this.projectionMethod = projectionMethod; + this.requestRedraw(); + }; + + View.prototype.changeFrame = function(cooFrame) { + this.cooFrame = cooFrame; + // recompute viewCenter + if (this.cooFrame==CooFrameEnum.GAL) { + var lb = CooConversion.J2000ToGalactic([this.viewCenter.lon, this.viewCenter.lat]); + this.viewCenter.lon = lb[0]; + this.viewCenter.lat = lb[1]; + } + else if (this.cooFrame==CooFrameEnum.J2000) { + var radec = CooConversion.GalacticToJ2000([this.viewCenter.lon, this.viewCenter.lat]); + this.viewCenter.lon = radec[0]; + this.viewCenter.lat = radec[1]; + } + this.requestRedraw(); + }; + + View.prototype.showHealpixGrid = function(show) { + this.displayHpxGrid = show; + this.requestRedraw(); + }; + + View.prototype.showSurvey = function(show) { + this.displaySurvey = show; + + this.requestRedraw(); + }; + + View.prototype.showCatalog = function(show) { + this.displayCatalog = show; + + if (!this.displayCatalog) { + this.mustClearCatalog = true; + } + this.requestRedraw(); + }; + + View.prototype.showReticle = function(show) { + this.displayReticle = show; + + this.mustRedrawReticle = true; + this.requestRedraw(); + }; + + View.prototype.pointTo = function(ra, dec) { + ra = parseFloat(ra); + dec = parseFloat(dec); + if (isNaN(ra) || isNaN(dec)) { + return; + } + if (this.cooFrame==CooFrameEnum.J2000) { + this.viewCenter.lon = ra; + this.viewCenter.lat = dec; + } + else if (this.cooFrame==CooFrameEnum.GAL) { + var lb = CooConversion.J2000ToGalactic([ra, dec]); + this.viewCenter.lon = lb[0]; + this.viewCenter.lat = lb[1]; + } + + this.forceRedraw(); + this.requestRedraw(); + var self = this; + setTimeout(function() {self.refreshProgressiveCats();}, 1000); + + }; + View.prototype.makeUniqLayerName = function(name) { + if (! this.layerNameExists(name)) { + return name; + } + for (var k=1;;++k) { + var newName = name + '_' + k; + if ( ! this.layerNameExists(newName)) { + return newName; + } + } + }; + View.prototype.layerNameExists = function(name) { + var c = this.catalogs; + for (var k=0; k=x && s.x<=x+w && s.y>=y && s.y<=y+h) { + objList.push(s); + } + } + } + } + return objList; + + }; + + // update objLookup, lookup table + View.prototype.updateObjectsLookup = function() { + this.objLookup = []; + + var cat, sources, s, x, y; + if (this.catalogs) { + for (var k=0; k' + + (options.showFrame ? '' : '') + + '') + .appendTo(aladinDiv); + // div où on écrit la FoV + var fovDiv = $('
').appendTo(aladinDiv); + + // TODO : mettre tous les styles dans un CSS ! + + // zoom control + if (options.showZoomControl) { + $('').appendTo(aladinDiv); + } + + // maximize control + if (options.showFullscreenControl) { + $('
') + .appendTo(aladinDiv); + } + this.fullScreenBtn = $(aladinDiv).find('.aladin-fullscreenControl') + this.fullScreenBtn.click(function() { + self.toggleFullscreen(); + }); + + + + + + // Aladin logo + $("
").appendTo(aladinDiv); + + + // we store the boxes + this.boxes = []; + + + + var location = new Location(locationDiv.find('.aladin-location-text')); + + // set different options + this.view = new View(this, location, fovDiv, cooFrame, options.zoom); + + // layers control panel + // TODO : valeur des checkbox en fonction des options + // TODO : classe LayerBox + if (options.showLayersControl) { + var d = $('
'); + d.appendTo(aladinDiv); + + var layerBox = $('
'); + layerBox.appendTo(aladinDiv); + + this.boxes.push(layerBox); + + // we return false so that the default event is not submitted, and to prevent event bubbling + d.click(function() {self.hideBoxes();self.showLayerBox();return false;}); + + } + + + // goto control panel + if (options.showGotoControl) { + var d = $('
'); + d.appendTo(aladinDiv); + + var gotoBox = + $('
' + + '×' + + '
' + + '
Go to:
'); + gotoBox.appendTo(aladinDiv); + this.boxes.push(gotoBox); + + var input = gotoBox.find('.aladin-target-form input'); + input.on("paste keydown", function() { + $(this).removeClass('aladin-unknownObject'); // remove red border + }); + + // TODO : classe GotoBox + d.click(function() { + self.hideBoxes(); + input.val(''); + input.removeClass('aladin-unknownObject'); + gotoBox.show(); + input.focus(); + + + return false; + }); + gotoBox.find('.aladin-closeBtn').click(function() {self.hideBoxes();return false;}); + } + + // share control panel + if (options.showShareControl) { + var d = $('
'); + d.appendTo(aladinDiv); + + var shareBox = + $('
' + + '×' + + '
' + + 'Share' + + '' + + '
'); + shareBox.appendTo(aladinDiv); + this.boxes.push(shareBox); + + + // TODO : classe GotoBox + d.click(function() { + self.hideBoxes(); + shareBox.show(); + + + return false; + }); + shareBox.find('.aladin-closeBtn').click(function() {self.hideBoxes();return false;}); + } + + + this.gotoObject(options.target); + + if (options.log) { + var params = requestedOptions; + params['version'] = Aladin.VERSION; + Logger.log("startup", params); + } + + this.showReticle(options.showReticle); + + if (options.catalogUrls) { + for (var k=0, len=options.catalogUrls.length; k b.id; + } + return a.order && a.order > b.order ? 1 : -1; + }) + var select = $(this.aladinDiv).find('.aladin-surveySelection'); + select.empty(); + for (var i=0; i").attr("selected", isCurSurvey).val(surveys[i].id).text(surveys[i].name)); + }; + }; + + Aladin.prototype.getOptionsFromQueryString = function() { + var options = {}; + var requestedTarget = $.urlParam('target'); + if (requestedTarget) { + options.target = requestedTarget; + } + var requestedFrame = $.urlParam('frame'); + if (requestedFrame && CooFrameEnum[requestedFrame] ) { + options.frame = requestedFrame; + } + var requestedSurveyId = $.urlParam('survey'); + if (requestedSurveyId && HpxImageSurvey.getSurveyInfoFromId(requestedSurveyId)) { + options.survey = requestedSurveyId; + } + var requestedZoom = $.urlParam('zoom'); + if (requestedZoom && requestedZoom>0 && requestedZoom<180) { + options.zoom = requestedZoom; + } + + var requestedShowreticle = $.urlParam('showReticle'); + if (requestedShowreticle) { + options.showReticle = requestedShowreticle.toLowerCase()=='true'; + } + + var requestedCooFrame = $.urlParam('cooFrame'); + if (requestedCooFrame) { + options.cooFrame = requestedCooFrame; + } + + var requestedFullscreen = $.urlParam('fullScreen'); + if (requestedFullscreen !== undefined) { + options.fullScreen = requestedFullscreen; + } + + return options; + }; + + // TODO: rename to setFoV + Aladin.prototype.setZoom = function(fovDegrees) { + this.view.setZoom(fovDegrees); + }; + + Aladin.prototype.setFrame = function(frameName) { + if (! frameName) { + return; + } + frameName = frameName.toLowerCase(); + if (frameName.indexOf('j2000')==0) { + this.view.changeFrame(CooFrameEnum.J2000); + } + else if (frameName.indexOf('gal')==0) { + this.view.changeFrame(CooFrameEnum.GAL); + } + }; + + Aladin.prototype.setProjection = function(projectionName) { + if (! projectionName) { + return; + } + projectionName = projectionName.toLowerCase(); + switch(projectionName) { + case "aitoff": + this.view.changeProjection(ProjectionEnum.AITOFF); + break; + case "sinus": + default: + this.view.changeProjection(ProjectionEnum.SIN); + } + } + + // point view to a given object (resolved by Sesame) or position + Aladin.prototype.gotoObject = function(targetName, errorCallback) { + var isObjectName = /[a-zA-Z]/.test(targetName); + + // try to parse as a position + if ( ! isObjectName) { + var coo = new Coo(); + + coo.parse(targetName); + var lonlat = [coo.lon, coo.lat]; + if (this.view.cooFrame == CooFrameEnum.GAL) { + lonlat = CooConversion.GalacticToJ2000(lonlat); + } + this.view.pointTo(lonlat[0], lonlat[1]); + } + // ask resolution by Sesame + else { + var self = this; + Sesame.resolve(targetName, + function(data) { + var ra = data.Target.Resolver.jradeg; + var dec = data.Target.Resolver.jdedeg; + self.view.pointTo(ra, dec); + /* + if (data.sesame.error) { + if (console) console.log(data.sesame.error); + } + else { + var radec = data.sesame.decimalPosition.split(" "); + self.view.pointTo(parseFloat(radec[0]), parseFloat(radec[1])); + } + */ + }, + function(data) { + if (console) { + console.log("Could not resolve object name " + targetName); + console.log(data); + } + if (errorCallback) { + errorCallback(); + } + }); + } + }; + + + + // go to a given position, expressed in the current coordinate frame + Aladin.prototype.gotoPosition = function(lon, lat) { + var radec; + // first, convert to J2000 if needed + if (this.view.cooFrame==CooFrameEnum.GAL) { + radec = CooConversion.GalacticToJ2000([lon, lat]); + } + else { + radec = [lon, lat]; + } + this.view.pointTo(radec[0], radec[1]); + }; + + Aladin.prototype.gotoRaDec = function(ra, dec) { + this.view.pointTo(ra, dec); + }; + + Aladin.prototype.showHealpixGrid = function(show) { + this.view.showHealpixGrid(show); + }; + + Aladin.prototype.showSurvey = function(show) { + this.view.showSurvey(show); + }; + Aladin.prototype.showCatalog = function(show) { + this.view.showCatalog(show); + }; + Aladin.prototype.showReticle = function(show) { + this.view.showReticle(show); + $('#displayReticle').attr('checked', show); + }; + Aladin.prototype.removeLayers = function() { + this.view.removeLayers(); + } + Aladin.prototype.addCatalog = function(catalog) { + this.view.addCatalog(catalog); + }; + Aladin.prototype.addOverlay = function(overlay) { + this.view.addOverlay(overlay); + }; + + Aladin.prototype.getBaseImageLayer = function() { + return this.view.imageSurvey; + }; + + // TODO: move to A.imageLayer(...) + Aladin.prototype.createImageSurvey = function(id, name, rootUrl, cooFrame, maxOrder, options) { + return new HpxImageSurvey(id, name, rootUrl, cooFrame, maxOrder, options); + }; + + // @param imageSurvey : HpxImageSurvey object or image survey identifier + Aladin.prototype.setImageSurvey = function(imageSurvey) { + this.view.setImageSurvey(imageSurvey); + this.updateSurveysDropdownList(HpxImageSurvey.getAvailableSurveys()); + if (this.options.log) { + var id = imageSurvey; + if (typeof imageSurvey !== "string") { + id = imageSurvey.rootUrl; + } + + Logger.log("changeImageSurvey", id); + } + }; + + Aladin.prototype.increaseZoom = function(step) { + if (!step) { + step = 5; + } + this.view.setZoomLevel(this.view.zoomLevel+step); + }; + + Aladin.prototype.decreaseZoom = function(step) { + if (!step) { + step = 5; + } + this.view.setZoomLevel(this.view.zoomLevel-step); + }; + + Aladin.prototype.createCatalog = function(options) { + return new cds.Catalog(options); + }; + + Aladin.prototype.createProgressiveCatalog = function(url, frame, maxOrder, options) { + return new ProgressiveCat(url, frame, maxOrder, options); + }; + + Aladin.prototype.createSource = function(ra, dec, data) { + return new cds.Source(ra, dec, data); + }; + Aladin.prototype.createMarker = function(ra, dec, options, data) { + options = options || {}; + options['marker'] = true; + return new cds.Source(ra, dec, data, options); + }; + + Aladin.prototype.createOverlay = function(options) { + return new Overlay(options); + }; + + // API + Aladin.prototype.createFootprintsFromSTCS = function(stcs) { + var polygons = Overlay.parseSTCS(stcs); + var fps = []; + for (var k=0, len=polygons.length; k×' + + '
' + + '
Base image layer
' + + '' + + '
Color map:' + + '
' + + '
' + + '
Overlay layers
'); + + // fill color maps options + var cmSelect = layerBox.find('.aladin-cmSelection'); + for (var k=0; k").text(ColorMap.MAPS_NAMES[k])); + } + cmSelect.val(self.getBaseImageLayer().getColorMap().map); + + + // loop over catalogs + var cats = this.view.catalogs; + var str = '
    '; + for (var k=cats.length-1; k>=0; k--) { + var name = cats[k].name; + var checked = ''; + if (cats[k].isShowing) { + checked = 'checked="checked"'; + } + var nbSources = cats[k].getSources().length; + var title = nbSources + ' source' + ( nbSources>1 ? 's' : ''); + str += '
  • ' + } + str += '
'; + layerBox.append(str); + + layerBox.append('
'); + + // gestion du réticule + var checked = ''; + if (this.view.displayReticle) { + checked = 'checked="checked"'; + } + var reticleCb = $(''); + layerBox.append(reticleCb).append('
'); + reticleCb.change(function() { + self.showReticle($(this).is(':checked')); + }); + + // Gestion grille Healpix + checked = ''; + if (this.view.displayHpxGrid) { + checked = 'checked="checked"'; + } + var hpxGridCb = $(''); + layerBox.append(hpxGridCb).append('
'); + hpxGridCb.change(function() { + self.showHealpixGrid($(this).is(':checked')); + }); + + + layerBox.append('
' + + '
Tools
'); + var exportBtn = $(''); + layerBox.append(exportBtn); + exportBtn.click(function() { + self.exportAsPNG(); + }); + + /* + '
' + + '
Projection
' + + '
' + */ + + layerBox.find('.aladin-closeBtn').click(function() {self.hideBoxes();return false;}); + + // update list of surveys + this.updateSurveysDropdownList(HpxImageSurvey.getAvailableSurveys()); + $(this.aladinDiv).find('.aladin-surveySelection').change(function() { + var survey = HpxImageSurvey.getAvailableSurveys()[$(this)[0].selectedIndex]; + self.setImageSurvey(survey.id); + // update color map list with current value color map + cmSelect.val(self.getBaseImageLayer().getColorMap().map); + }); + + // update color map + layerBox.find('.aladin-cmSelection').change(function() { + var cmName = $(this).find(':selected').val(); + self.getBaseImageLayer().getColorMap().update(cmName); + }); + + // reverse color map + $(layerBox).find('.aladin-reverseCm').click(function() { + self.getBaseImageLayer().getColorMap().reverse(); + }); + + + // handler to hide/show overlays + $(this.aladinDiv).find('.aladin-layerBox ul input').change(function() { + var catName = ($(this).attr('id').substr(12)); + var cat = self.layerByName(catName); + if ($(this).is(':checked')) { + cat.show(); + } + else { + cat.hide(); + } + }); + + // finally show + layerBox.show(); + + }; + + Aladin.prototype.layerByName = function(name) { + var c = this.view.catalogs; + for (var k=0; kmaxFOV) { + var tmp = minFOV; + minFOV = maxFOV; + maxFOV = tmp; + } + + this.view.minFOV = minFOV; + this.view.maxFOV = maxFOV; + + }; + + return Aladin; +})(); + + +A.aladin = function(divSelector, options) { + return new Aladin($(divSelector)[0], options); +}; + +if ($) { + $.aladin = A.aladin; +} + diff --git a/distrib/aladin-0.5.1.min.css b/distrib/aladin-0.5.1.min.css new file mode 100644 index 00000000..13abcbd2 --- /dev/null +++ b/distrib/aladin-0.5.1.min.css @@ -0,0 +1,49 @@ +.aladin-container{position:relative;border:1px solid #ddd;height:100%;} +.aladin-imageCanvas{position:absolute;z-index:1;left:0;top:0;} +.aladin-catalogCanvas{position:absolute;z-index:2;left:0;top:0;} +.aladin-reticleCanvas{position:absolute;z-index:3;left:0;top:0;} +.aladin-logo-container{position:absolute;bottom:5px;right:8px;z-index:20;} +.aladin-logo{width:32px;height:32px;padding:0;background:url(data:image/gif;base64,R0lGODlhIAAgAJEAAJIsLdEwJAdMmP///yH5BAkAAAMALAAAAAAgACAAAAjMAAcIHEiwoMGDCBMqXMiwocOHECMaFCCxYkKKAAoK2MiRo0UBAEKKFOkxYUaCIEMSHBlyo0OQCke6HHDyJEWBKgcG2MlzoEyFMAXyHNqTZsubNFGeHLDT4FCcLREGZUqwaFGRUk82FfqUaQCoSH0OCLqVqlCuX42u9Kl1a1qzXnGGVaozLdG6cpMWxOrVblm4AOYOTNn2L1efYZdu5Eu0cV6cE0fW7QqV4WK+CAMLPnhZMtvAEDmy/CkWMtCOHVFaXC2VtevXsGPLZhgQADs=);} +.aladin-location{z-index:20;position:absolute;padding:2px 4px 2px 4px;background-color:rgba(255, 255, 255, 0.5);font-size:11px;} +.aladin-location-text{font-size:13px;} +.aladin-fov{z-index:20;position:absolute;padding:0;font-size:12px;font-weight:bold;bottom:0px;padding:2px;color:#321bdf;background-color:rgba(255, 255, 255, 0.5);} +.aladin-maximize{position:absolute;top:6px;right:3px;z-index:20;width:30px;height:30px;background-image:url('data:image/gif;base64,R0lGODlhFgAWAOMJAAAAAAEBAQICAgMDAwUFBAUFBQcHBwgICAsLCv///////////////////////////yH5BAEKAA8ALAAAAAAWABYAAARm8MlJabr41i0T+CCQcJz3CYMwklsSEAUhspVnHEYw0x1w558VzYQTBXm24sgjJCUQykmT9dzxWlNq9vrwILYtqe/wRc6SBqszOE6DLZ/AT00FyKNcD4wQeLdQAiB+cCFHVxkZXA8RADs=');background-repeat:no-repeat;background-position:center center;} +.aladin-layersControl-container{position:absolute;top:30px;left:4px;cursor:pointer;z-index:20;background:rgba(250, 250, 250, 0.8);border-radius:4px;} +.aladin-layersControl-container:hover{background:rgba(220, 220, 220, 0.8);} +.aladin-layersControl{width:32px;height:34px;background-image:url('data:image/gif;base64,R0lGODlhGQAcAMIAAAAAADQ0NKahocvFxf///wAAAAAAAAAAACH5BAEKAAcALAAAAAAZABwAAANneLoH/hCwyaJ1dDrCuydY1gBfyYUaaZqosq0r+sKxNNP1pe98Hy2OgXBILLZGxWRSBlA6iZjgczrwWa9WIEDA7Xq/R8d3PGaSz97oFs0WYN9wiDZAr9vvYcB9v2fy/3ZqgIN0cYZYCQA7');background-repeat:no-repeat;background-position:center center;} +.aladin-layerBox{top:30px;padding:4px 4px 10px 10px;} +.aladin-box{display:none;z-index:30;position:absolute;background:#eee;left:4px;border-radius:4px;font-size:14px;font-family:Verdana, Lucida, Arial;line-height:1.3;color:#222;} +.aladin-gotoControl-container{position:absolute;top:68px;left:4px;cursor:pointer;z-index:20;background:rgba(250, 250, 250, 0.8);border-radius:4px;} +.aladin-gotoControl-container:hover{background:rgba(220, 220, 220, 0.8);} +.aladin-gotoControl{width:32px;height:34px;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAASZJREFUeNpiYMAOpIG4GogPAPETIP4PpQ9AxaUZyARsQNwFxN+ghuLC36Dq2EgxXBSITxIwGB2fhOojyuXohl8C4hCk4JCG8i9hsYSgT9qRNPwE4hY8mtig8n+Q9LTjM1waaihMcQ6RQZqD5ig5XAobkRQeJjFRHEbS20iMoigSLYgixnHPkRSRmr6lkfQ+x6UIOfzZyMg3yPFAfx8wAfFNJL49iRYgq7+JS1EFlVJRBS5FcmjxkEak4WnE5gMGaMGFrBhUYjLjUMsMlUd21CJyyqLz0LJHAqpGAso/j6XQ+0NMHiKnNEW3JJyQJZzQ4PpJwLCf0GD5Q44l6DXac6R0jl6jhVBiCbEAlyUh9LDEm9aWPGegMkC35AkDDYAf1OUg7AoQYADEj7juEX/HNAAAAABJRU5ErkJggg==');background-repeat:no-repeat;background-position:center center;} +.aladin-gotoBox{top:68px;padding:4px;} +.aladin-target-form{padding:5px;} +.aladin-shareControl-container{position:absolute;top:106px;left:4px;cursor:pointer;z-index:20;background:rgba(250, 250, 250, 0.8);border-radius:4px;} +.aladin-shareControl-container:hover{background:rgba(220, 220, 220, 0.8);} +.aladin-shareControl{width:32px;height:34px;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA/1BMVEUAAAAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzP////6PkQMAAAAU3RSTlMAAAI2l9TiyXwcBmrj/cEvePX69MD+Vzl06Px5sMgDZPsbOwUfKFGAHVjSEkBgXTcMllbG8rbhdtcm26Ko5/M8F3clPqN1JK+usRpVQdNQBGN9OkYs7f8AAAABYktHRFTkA4ilAAAACXBIWXMAARCQAAEQkAGJrNK4AAABMUlEQVQoz13SeVuCQBAGcAYV5TREEpUQr9TMK9G8Nc/usvn+36VdRFDmz9/uwzuzA8NcFrCRaIyLJ3iAaxdECUnJShKu/UZFTGkyYpoPu67cZows5hKXnif3TfJ5MHS8C9wqcDaaRRILJQ254KBcqd7X6tShYePDmaH52Gp3uq7zacTe+fpTnwQ7gwxJKJqIw4iX++ygW6Ox66oIQf+T6WyOi+WK+osAvptri91sd/tDyF/3u+2GtdZvIT+slgucz6YT3xkQqb/DeHSKd3YnZzpD1wEyA0dHtf9R9h62R5/Snavbabc+m/4mvtBuuF6vfVcrP8EeONRK1MlcNvdrBQdx1A2SwNO58sLF4o45zBp/DUX3+/SKV8iOtRSGnYGkItP+JVEI/RnAH+NSLBphr/0f6ns3OQ1Zz7kAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTMtMTEtMThUMTQ6MzM6NTUrMDE6MDCINg3ZAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDEzLTExLTE4VDE0OjMzOjA0KzAxOjAwF/ywtQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAASUVORK5CYII=');background-repeat:no-repeat;background-position:center center;} +.aladin-shareBox{top:106px;padding:4px;} +.aladin-target-form input{width:140px;margin-left:5px;} +.aladin-cb-list ul{margin:0;padding-left:4px;list-style:none;} +.aladin-cb-list label{display:inline;} +.aladin-cb-list input[type="checkbox"]{margin:3px;} +.aladin-closeBtn{float:right;margin-top:0 0 2px 0;cursor:pointer;color:#605F61;border:1px solid #AEAEAE;border-radius:3px;background:#fff;font-size:15px;font-weight:bold;display:inline-block;line-height:0px;padding:8px 2px;} +.aladin-closeBtn:hover{color:#201F21;} +.aladin-label{font-weight:bold;padding-bottom:4px;} +.aladin-box-separator{height:0;border-top:1px solid #bbb ;margin:5px 0px 5px -4px;} +.aladin-blank-separator{height:10px;} +.aladin-restore{position:absolute;top:6px;right:3px;z-index:20;width:30px;height:30px;background-image:url('data:image/gif;base64,R0lGODlhFgAWAOMJAAAAAAEBAQICAgMDAwUFBAUFBQcHBwgICAsLCv///////////////////////////yH5BAEKAA8ALAAAAAAWABYAAARk8MlJ60zJapsAyhsFPp1xfKHUZeVhAOPWwYD5xjIABDacXrseLtQhFAiBIVEwEOh8P9VzquRgrhgrNhudTaHdJ1NQ1SQCRgL41zIE1sSa6w0361y0eqXtW7EReCNlIgh6XYMbEQA7');background-repeat:no-repeat;background-position:center center;} +.aladin-fullscreen{position:fixed !important;z-index:9999;top:0;left:0;height:100% !important;width:100% !important;border:0 !important;} +.aladin-zoomControl{z-index:20;position:absolute;top:50%;height:48px;right:8px;padding:0;margin:-24px 0 0 0;font-weight:bold;font-size:18px;font-family:Verdana, Lucida, Arial;} +.aladin-zoomControl a{width:20px;height:20px;line-height:18px;display:block;background-color:rgba(250, 250, 250, 0.8);margin:1px;text-align:center;border-radius:4px;border:1px solid #aaa;text-decoration:none;color:#222;} +.aladin-zoomControl a:hover{background-color:rgba(220, 220, 220, 0.8);} +.aladin-surveySelection{width:200px;} +.aladin-cmSelection{width:60px;margin-right:10px;} +.aladin-layerIcon{width:4px;height:12px;background:red;display:inline-block;} +.aladin-btn{display:inline-block;padding:6px 8px;margin-bottom:0;font-size:12px;font-weight:normal;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;border:1px solid transparent;border-radius:3px;color:#ffffff;background-color:#428bca;border-color:#357ebd;} +.aladin-btn-small{font-size:10px;} +.aladin-button:hover{color:#ffffff;background-color:#3276b1;border-color:#285e8e;} +.aladin-unknownObject{border:3px solid red;} +.aladin-popup-container{z-index:18;position:absolute;width:200px;display:none;line-height:1.3;} +.aladin-popup{font-family:Verdana, Lucida, Arial;font-size:13px;background:white;border:1px solid #bbb;border-radius:4px;padding:4px;top:80px;left:110px;} +.aladin-popup-arrow{display:block;border-color:#fff transparent transparent;border-style:solid;border-width:12px;width:0px;height:0px;margin-top:-1px;margin-left:auto;margin-right:auto;} +.aladin-popupTitle{font-weight:bold;} diff --git a/distrib/aladin-0.5.1.min.js b/distrib/aladin-0.5.1.min.js new file mode 100644 index 00000000..c0aa8b60 --- /dev/null +++ b/distrib/aladin-0.5.1.min.js @@ -0,0 +1,4 @@ +function AstroMath(){}function Projection(t,e){this.PROJECTION=Projection.PROJ_TAN,this.ROT=this.tr_oR(t,e)}function Coo(t,e,i){this.lon=t,this.lat=e,this.prec=i,this.frame=null,this.computeDirCos()}function Tokenizer(t,e){this.string=Strings.trim(t,e),this.sep=e,this.pos=0}function Strings(){}function Numbers(){}function relMouseCoords(t){if(t.offsetX)return{x:t.offsetX,y:t.offsetY};if(!Utils.cssScale){var e=window.getComputedStyle(document.body,null),i=e.getPropertyValue("-webkit-transform")||e.getPropertyValue("-moz-transform")||e.getPropertyValue("-ms-transform")||e.getPropertyValue("-o-transform")||e.getPropertyValue("transform"),o=/matrix\((-?\d*\.?\d+),\s*0,\s*0,\s*(-?\d*\.?\d+),\s*0,\s*0\)/,s=i.match(o);Utils.cssScale=s?parseFloat(s[1]):1}var r=t;r.target;var a=r.target||r.srcElement,n=a.currentStyle||window.getComputedStyle(a,null),h=parseInt(n.borderLeftWidth,10),l=parseInt(n.borderTopWidth,10),c=a.getBoundingClientRect(),u=r.clientX-h-c.left,d=r.clientY-l-c.top;return{x:parseInt(u/Utils.cssScale),y:parseInt(d/Utils.cssScale)}}var cds=cds||{},A=A||{};"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(t){return 10>t?"0"+t:t}function quote(t){return escapable.lastIndex=0,escapable.test(t)?'"'+t.replace(escapable,function(t){var e=meta[t];return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}function str(t,e){var i,o,s,r,a,n=gap,h=e[t];switch(h&&"object"==typeof h&&"function"==typeof h.toJSON&&(h=h.toJSON(t)),"function"==typeof rep&&(h=rep.call(e,t,h)),typeof h){case"string":return quote(h);case"number":return isFinite(h)?h+"":"null";case"boolean":case"null":return h+"";case"object":if(!h)return"null";if(gap+=indent,a=[],"[object Array]"===Object.prototype.toString.apply(h)){for(r=h.length,i=0;r>i;i+=1)a[i]=str(i,h)||"null";return s=0===a.length?"[]":gap?"[\n"+gap+a.join(",\n"+gap)+"\n"+n+"]":"["+a.join(",")+"]",gap=n,s}if(rep&&"object"==typeof rep)for(r=rep.length,i=0;r>i;i+=1)"string"==typeof rep[i]&&(o=rep[i],s=str(o,h),s&&a.push(quote(o)+(gap?": ":":")+s));else for(o in h)Object.prototype.hasOwnProperty.call(h,o)&&(s=str(o,h),s&&a.push(quote(o)+(gap?": ":":")+s));return s=0===a.length?"{}":gap?"{\n"+gap+a.join(",\n"+gap)+"\n"+n+"}":"{"+a.join(",")+"}",gap=n,s}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()});var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;"function"!=typeof JSON.stringify&&(JSON.stringify=function(t,e,i){var o;if(gap="",indent="","number"==typeof i)for(o=0;i>o;o+=1)indent+=" ";else"string"==typeof i&&(indent=i);if(rep=e,e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw Error("JSON.stringify");return str("",{"":t})}),"function"!=typeof JSON.parse&&(JSON.parse=function(text,reviver){function walk(t,e){var i,o,s=t[e];if(s&&"object"==typeof s)for(i in s)Object.prototype.hasOwnProperty.call(s,i)&&(o=walk(s,i),void 0!==o?s[i]=o:delete s[i]);return reviver.call(t,e,s)}var j;if(text+="",cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}(),Logger={},Logger.log=function(t,e){try{var i="http://alasky.u-strasbg.fr/cgi/AladinLiteLogger/log.py",o="";e&&(o=JSON.stringify(e)),$.ajax({url:i,data:{action:t,params:o,pageUrl:window.location.href,referer:document.referrer?document.referrer:""},method:"GET",dataType:"json"})}catch(s){window.console&&console.log("Exception: "+s)}},function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof exports?module.exports=t:t(jQuery)}(function(t){function e(e){var s,r=e||window.event,a=[].slice.call(arguments,1),n=0,h=0,l=0,c=0,u=0;return e=t.event.fix(r),e.type="mousewheel",r.wheelDelta&&(n=r.wheelDelta),r.detail&&(n=-1*r.detail),l=n,void 0!==r.axis&&r.axis===r.HORIZONTAL_AXIS&&(l=0,h=-1*n),r.deltaY&&(l=-1*r.deltaY,n=l),r.deltaX&&(h=r.deltaX,n=-1*h),void 0!==r.wheelDeltaY&&(l=r.wheelDeltaY),void 0!==r.wheelDeltaX&&(h=-1*r.wheelDeltaX),c=Math.abs(n),(!i||i>c)&&(i=c),u=Math.max(Math.abs(l),Math.abs(h)),(!o||o>u)&&(o=u),s=n>0?"floor":"ceil",n=Math[s](n/i),h=Math[s](h/o),l=Math[s](l/o),a.unshift(e,n,h,l),(t.event.dispatch||t.event.handle).apply(this,a)}var i,o,s=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],r="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"];if(t.event.fixHooks)for(var a=s.length;a;)t.event.fixHooks[s[--a]]=t.event.mouseHooks;t.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var t=r.length;t;)this.addEventListener(r[--t],e,!1);else this.onmousewheel=e},teardown:function(){if(this.removeEventListener)for(var t=r.length;t;)this.removeEventListener(r[--t],e,!1);else this.onmousewheel=null}},t.fn.extend({mousewheel:function(t){return t?this.bind("mousewheel",t):this.trigger("mousewheel")},unmousewheel:function(t){return this.unbind("mousewheel",t)}})}),window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){window.setTimeout(t,1e3/60)}}();var Stats=function(){function t(t,e,i){var o,s,r;for(s=0;30>s;s++)for(o=0;73>o;o++)r=4*(o+74*s),t[r]=t[r+4],t[r+1]=t[r+5],t[r+2]=t[r+6];for(s=0;30>s;s++)r=4*(73+74*s),e>s?(t[r]=O[i].bg.r,t[r+1]=O[i].bg.g,t[r+2]=O[i].bg.b):(t[r]=O[i].fg.r,t[r+1]=O[i].fg.g,t[r+2]=O[i].fg.b)}var e,i,o,s,r,a,n,h,l,c,u,d,p,f,v=0,g=2,m=0,y=(new Date).getTime(),C=y,w=y,x=0,S=1e3,M=0,b=0,T=1e3,P=0,I=0,R=1e3,A=0,O={fps:{bg:{r:16,g:16,b:48},fg:{r:0,g:255,b:255}},ms:{bg:{r:16,g:48,b:16},fg:{r:0,g:255,b:0}},mb:{bg:{r:48,g:16,b:26},fg:{r:255,g:0,b:128}}};e=document.createElement("div"),e.style.cursor="pointer",e.style.width="80px",e.style.opacity="0.9",e.style.zIndex="10001",e.addEventListener("click",function(){switch(v++,v==g&&(v=0),i.style.display="none",n.style.display="none",u.style.display="none",v){case 0:i.style.display="block";break;case 1:n.style.display="block";break;case 2:u.style.display="block"}},!1),i=document.createElement("div"),i.style.backgroundColor="rgb("+Math.floor(O.fps.bg.r/2)+","+Math.floor(O.fps.bg.g/2)+","+Math.floor(O.fps.bg.b/2)+")",i.style.padding="2px 0px 3px 0px",e.appendChild(i),o=document.createElement("div"),o.style.fontFamily="Helvetica, Arial, sans-serif",o.style.textAlign="left",o.style.fontSize="9px",o.style.color="rgb("+O.fps.fg.r+","+O.fps.fg.g+","+O.fps.fg.b+")",o.style.margin="0px 0px 1px 3px",o.innerHTML='FPS',i.appendChild(o),s=document.createElement("canvas"),s.width=74,s.height=30,s.style.display="block",s.style.marginLeft="3px",i.appendChild(s),r=s.getContext("2d"),r.fillStyle="rgb("+O.fps.bg.r+","+O.fps.bg.g+","+O.fps.bg.b+")",r.fillRect(0,0,s.width,s.height),a=r.getImageData(0,0,s.width,s.height),n=document.createElement("div"),n.style.backgroundColor="rgb("+Math.floor(O.ms.bg.r/2)+","+Math.floor(O.ms.bg.g/2)+","+Math.floor(O.ms.bg.b/2)+")",n.style.padding="2px 0px 3px 0px",n.style.display="none",e.appendChild(n),h=document.createElement("div"),h.style.fontFamily="Helvetica, Arial, sans-serif",h.style.textAlign="left",h.style.fontSize="9px",h.style.color="rgb("+O.ms.fg.r+","+O.ms.fg.g+","+O.ms.fg.b+")",h.style.margin="0px 0px 1px 3px",h.innerHTML='MS',n.appendChild(h),s=document.createElement("canvas"),s.width=74,s.height=30,s.style.display="block",s.style.marginLeft="3px",n.appendChild(s),l=s.getContext("2d"),l.fillStyle="rgb("+O.ms.bg.r+","+O.ms.bg.g+","+O.ms.bg.b+")",l.fillRect(0,0,s.width,s.height),c=l.getImageData(0,0,s.width,s.height);try{performance&&performance.memory&&performance.memory.totalJSHeapSize&&(g=3)}catch(E){}return u=document.createElement("div"),u.style.backgroundColor="rgb("+Math.floor(O.mb.bg.r/2)+","+Math.floor(O.mb.bg.g/2)+","+Math.floor(O.mb.bg.b/2)+")",u.style.padding="2px 0px 3px 0px",u.style.display="none",e.appendChild(u),d=document.createElement("div"),d.style.fontFamily="Helvetica, Arial, sans-serif",d.style.textAlign="left",d.style.fontSize="9px",d.style.color="rgb("+O.mb.fg.r+","+O.mb.fg.g+","+O.mb.fg.b+")",d.style.margin="0px 0px 1px 3px",d.innerHTML='MB',u.appendChild(d),s=document.createElement("canvas"),s.width=74,s.height=30,s.style.display="block",s.style.marginLeft="3px",u.appendChild(s),p=s.getContext("2d"),p.fillStyle="#301010",p.fillRect(0,0,s.width,s.height),f=p.getImageData(0,0,s.width,s.height),{domElement:e,update:function(){m++,y=(new Date).getTime(),b=y-C,T=Math.min(T,b),P=Math.max(P,b),t(c.data,Math.min(30,30-30*(b/200)),"ms"),h.innerHTML=''+b+" MS ("+T+"-"+P+")",l.putImageData(c,0,0),C=y,y>w+1e3&&(x=Math.round(1e3*m/(y-w)),S=Math.min(S,x),M=Math.max(M,x),t(a.data,Math.min(30,30-30*(x/100)),"fps"),o.innerHTML=''+x+" FPS ("+S+"-"+M+")",r.putImageData(a,0,0),3==g&&(I=9.54e-7*performance.memory.usedJSHeapSize,R=Math.min(R,I),A=Math.max(A,I),t(f.data,Math.min(30,30-I/2),"mb"),d.innerHTML=''+Math.round(I)+" MB ("+Math.round(R)+"-"+Math.round(A)+")",p.putImageData(f,0,0)),w=y,m=0)}}};Constants={},Constants.PI=Math.PI,Constants.C_PR=Math.PI/180,Constants.VLEV=2,Constants.EPS=1e-7,Constants.c=.105,Constants.LN10=Math.log(10),Constants.PIOVER2=Math.PI/2,Constants.TWOPI=2*Math.PI,Constants.TWOTHIRD=2/3,Constants.ARCSECOND_RADIAN=484813681109536e-20,SpatialVector=function(){function t(t,e,i){"use strict";this.x=t,this.y=e,this.z=i,this.ra_=0,this.dec_=0,this.okRaDec_=!1}return t.prototype.setXYZ=function(t,e,i){this.x=t,this.y=e,this.z=i,this.okRaDec_=!1},t.prototype.length=function(){"use strict";return Math.sqrt(this.lengthSquared())},t.prototype.lengthSquared=function(){"use strict";return this.x*this.x+this.y*this.y+this.z*this.z},t.prototype.normalized=function(){"use strict";var t=this.length();this.x/=t,this.y/=t,this.z/=t},t.prototype.set=function(t,e){"use strict";this.ra_=t,this.dec_=e,this.okRaDec_=!0,this.updateXYZ()},t.prototype.angle=function(t){"use strict";var e=this.y*t.z-this.z*t.y,i=this.z*t.x-this.x*t.z,o=this.x*t.y-this.y*t.x,s=Math.sqrt(e*e+i*i+o*o);return Math.abs(Math.atan2(s,dot(t)))},t.prototype.get=function(){"use strict";return[x,y,z]},t.prototype.toString=function(){"use strict";return"SpatialVector["+this.x+", "+this.y+", "+this.z+"]"},t.prototype.cross=function(e){"use strict";return new t(this.y*e.z-e.y*this.z,this.z*e.x-e.z*this.x,this.x*e.y-e.x()*this.y)},t.prototype.equal=function(t){"use strict";return this.x==t.x&&this.y==t.y&&this.z==t.z()?!0:!1},t.prototype.mult=function(e){"use strict";return new t(e*this.x,e*this.y,e*this.z)},t.prototype.dot=function(t){"use strict";return this.x*t.x+this.y*t.y+this.z*t.z},t.prototype.add=function(e){"use strict";return new t(this.x+e.x,this.y+e.y,this.z+e.z)},t.prototype.sub=function(e){"use strict";return new t(this.x-e.x,this.y-e.y,this.z-e.z)},t.prototype.dec=function(){"use strict";return this.okRaDec_||(this.normalized(),this.updateRaDec()),this.dec_},t.prototype.ra=function(){"use strict";return this.okRaDec_||(this.normalized(),this.updateRaDec()),this.ra_},t.prototype.updateXYZ=function(){"use strict";var t=Math.cos(this.dec_*Constants.C_PR);this.x=Math.cos(this.ra_*Constants.C_PR)*t,this.y=Math.sin(this.ra_*Constants.C_PR)*t,this.z=Math.sin(this.dec_*Constants.C_PR)},t.prototype.updateRaDec=function(){"use strict";this.dec_=Math.asin(this.z)/Constants.C_PR;var t=Math.cos(this.dec_*Constants.C_PR);this.ra_=t>Constants.EPS||-Constants.EPS>t?this.y>Constants.EPS||this.y<-Constants.EPS?0>this.y?360-Math.acos(this.x/t)/Constants.C_PR:Math.acos(this.x/t)/Constants.C_PR:0>this.x?180:0:0,this.okRaDec_=!0},t.prototype.toRaRadians=function(){"use strict";var t=0;return(0!=this.x||0!=this.y)&&(t=Math.atan2(this.y,this.x)),0>t&&(t+=2*Math.PI),t},t.prototype.toDeRadians=function(){var t=z/this.length(),e=Math.acos(t);return Math.PI/2-e},t}(),AngularPosition=function(){return AngularPosition=function(t,e){"use strict";this.theta=t,this.phi=e},AngularPosition.prototype.toString=function(){"use strict";return"theta: "+this.theta+", phi: "+this.phi},AngularPosition}(),LongRangeSetBuilder=function(){function t(){this.items=[]}return t.prototype.appendRange=function(t,e){for(var i=t;e>=i;i++)i in this.items||this.items.push(i)},t}(),HealpixIndex=function(){function t(t){"use strict";this.nside=t}return t.NS_MAX=8192,t.ORDER_MAX=13,t.NSIDELIST=[1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192],t.JRLL=[2,2,2,2,3,3,3,3,4,4,4,4],t.JPLL=[1,3,5,7,0,2,4,6,1,3,5,7],t.XOFFSET=[-1,-1,0,1,1,1,0,-1],t.YOFFSET=[0,1,1,1,0,-1,-1,-1],t.FACEARRAY=[[8,9,10,11,-1,-1,-1,-1,10,11,8,9],[5,6,7,4,8,9,10,11,9,10,11,8],[-1,-1,-1,-1,5,6,7,4,-1,-1,-1,-1],[4,5,6,7,11,8,9,10,11,8,9,10],[0,1,2,3,4,5,6,7,8,9,10,11],[1,2,3,0,0,1,2,3,5,6,7,4],[-1,-1,-1,-1,7,4,5,6,-1,-1,-1,-1],[3,0,1,2,3,0,1,2,4,5,6,7],[2,3,0,1,-1,-1,-1,-1,0,1,2,3]],t.SWAPARRAY=[[0,0,0,0,0,0,0,0,3,3,3,3],[0,0,0,0,0,0,0,0,6,6,6,6],[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,5,5,5,5],[0,0,0,0,0,0,0,0,0,0,0,0],[5,5,5,5,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0],[6,6,6,6,0,0,0,0,0,0,0,0],[3,3,3,3,0,0,0,0,0,0,0,0]],t.Z0=Constants.TWOTHIRD,t.prototype.init=function(){"use strict";var e=256;this.ctab=Array(e),this.utab=Array(e);for(var i=0;256>i;++i)this.ctab[i]=1&i|(2&i)<<7|(4&i)>>1|(8&i)<<6|(16&i)>>2|(32&i)<<5|(64&i)>>3|(128&i)<<4,this.utab[i]=1&i|(2&i)<<1|(4&i)<<2|(8&i)<<3|(16&i)<<4|(32&i)<<5|(64&i)<<6|(128&i)<<7;this.nl2=2*this.nside,this.nl3=3*this.nside,this.nl4=4*this.nside,this.npface=this.nside*this.nside,this.ncap=2*this.nside*(this.nside-1),this.npix=12*this.npface,this.fact2=4/this.npix,this.fact1=(this.nside<<1)*this.fact2,this.order=t.nside2order(this.nside)},t.calculateNSide=function(e){for(var i=0,o=e*e,s=180/Constants.PI,r=5184e4*Constants.PI*s*s,a=Utils.castToInt(r/o),n=a/12,h=Math.sqrt(n),l=t.NS_MAX,c=0,u=0;t.NSIDELIST.length>u;u++)if(l>=Math.abs(h-t.NSIDELIST[u])&&(l=Math.abs(h-t.NSIDELIST[u]),i=t.NSIDELIST[u],c=u),h>i&&t.NS_MAX>h&&(i=t.NSIDELIST[c+1]),h>t.NS_MAX)return console.log("nside cannot be bigger than "+t.NS_MAX),t.NS_MAX;return i},t.nside2order=function(e){"use strict";return(e&e-1)>0?-1:Utils.castToInt(t.log2(e))},t.log2=function(t){"use strict";return Math.log(t)/Math.log(2)},t.prototype.ang2pix_nest=function(e,i){"use strict";var o,s,r,a,n,h,l,c,u,d,p,f,v;if(i>=Constants.TWOPI&&(i-=Constants.TWOPI),0>i&&(i+=Constants.TWOPI),e>Constants.PI||0>e)throw{name:"Illegal argument",message:"theta must be between 0 and "+Constants.PI};if(i>Constants.TWOPI||0>i)throw{name:"Illegal argument",message:"phi must be between 0 and "+Constants.TWOPI};if(s=Math.cos(e),r=Math.abs(s),a=i/Constants.PIOVER2,t.Z0>=r){var g=this.nside*(.5+a),m=.75*this.nside*s,c=g-m,u=g+m;h=c>>this.order,l=u>>this.order,p=h==l?4==h?4:h+4:l>h?h:l+8,f=Utils.castToInt(u&this.nside-1),v=Utils.castToInt(this.nside-(c&this.nside-1)-1)}else{d=Utils.castToInt(a),d>=4&&(d=3),n=a-d;var y=this.nside*Math.sqrt(3*(1-r));c=Utils.castToInt(n*y),u=Utils.castToInt((1-n)*y),c=Math.min(t.NS_MAX-1,c),u=Math.min(t.NS_MAX-1,u),s>=0?(p=d,f=Utils.castToInt(this.nside-u-1),v=Utils.castToInt(this.nside-c-1)):(p=d+8,f=c,v=u)}return o=this.xyf2nest(f,v,p)},t.prototype.xyf2nest=function(t,e,i){"use strict";return(i<<2*this.order)+(this.utab[255&t]|this.utab[255&t>>8]<<16|this.utab[255&t>>16]<<32|this.utab[255&t>>24]<<48|this.utab[255&e]<<1|this.utab[255&e>>8]<<17|this.utab[255&e>>16]<<33|this.utab[255&e>>24]<<49)},t.prototype.nest2xyf=function(t){"use strict";var e={};e.face_num=t>>2*this.order;var i=t&this.npface-1,o=(93823560581120&i)>>16|(614882086624428e4&i)>>31|21845&i|(1431633920&i)>>15;return e.ix=this.ctab[255&o]|this.ctab[255&o>>8]<<4|this.ctab[255&o>>16]<<16|this.ctab[255&o>>24]<<20,i>>=1,o=(93823560581120&i)>>16|(614882086624428e4&i)>>31|21845&i|(1431633920&i)>>15,e.iy=this.ctab[255&o]|this.ctab[255&o>>8]<<4|this.ctab[255&o>>16]<<16|this.ctab[255&o>>24]<<20,e},t.prototype.pix2ang_nest=function(e){"use strict";if(0>e||e>this.npix-1)throw{name:"Illegal argument",message:"ipix out of range"};var i,o,s,r=this.nest2xyf(e),a=r.ix,n=r.iy,h=r.face_num,l=(t.JRLL[h]<l?(i=l,o=1-i*i*this.fact2,s=0):l>this.nl3?(i=this.nl4-l,o=i*i*this.fact2-1,s=0):(i=this.nside,o=(this.nl2-l)*this.fact1,s=1&l-this.nside);var c=Math.acos(o),u=(t.JPLL[h]*i+a-n+1+s)/2;u>this.nl4&&(u-=this.nl4),1>u&&(u+=this.nl4);var d=(u-.5*(s+1))*(Constants.PIOVER2/i);return{theta:c,phi:d}},t.nside2Npix=function(e){"use strict";if(0>this.NSIDELIST.indexOf(e))throw{name:"Illegal argument",message:"nside should be >0, power of 2, <"+t.NS_MAX};var i=12*e*e;return i},t.prototype.xyf2ring=function(e,i,o){"use strict";var s,r,a,n=t.JRLL[o]*this.nside-e-i-1;this.nside>n?(s=n,a=2*s*(s-1),r=0):n>3*this.nside?(s=this.nl4-n,a=this.npix-2*(s+1)*s,r=0):(s=this.nside,a=this.ncap+(n-this.nside)*this.nl4,r=1&n-this.nside);var h=(t.JPLL[o]*s+e-i+1+r)/2;return h>this.nl4?h-=this.nl4:1>h&&(h+=this.nl4),a+h-1},t.prototype.nest2ring=function(t){"use strict";var e=this.nest2xyf(t),i=this.xyf2ring(e.ix,e.iy,e.face_num);return i},t.prototype.corners_nest=function(t,e){"use strict";var i=this.nest2ring(t);return this.corners_ring(i,e)},t.prototype.pix2ang_ring=function(t){"use strict";var e,i,o,s,r,a,n,h,l;if(0>t||t>this.npix-1)throw{name:"Illegal argument",message:"ipix out of range"};return a=t+1,this.ncap>=a?(h=a/2,l=Utils.castToInt(h),o=Utils.castToInt(Math.sqrt(h-Math.sqrt(l)))+1,s=a-2*o*(o-1),e=Math.acos(1-o*o*this.fact2),i=(s-.5)*Constants.PI/(2*o)):this.npix-this.ncap>t?(r=t-this.ncap,o=r/this.nl4+this.nside,s=r%this.nl4+1,n=(1&o+this.nside)>0?1:.5,e=Math.acos((this.nl2-o)*this.fact1),i=(s-n)*Constants.PI/this.nl2):(r=this.npix-t,o=Utils.castToInt(.5*(1+Math.sqrt(2*r-1))),s=4*o+1-(r-2*o*(o-1)),e=Math.acos(-1+Math.pow(o,2)*this.fact2),i=(s-.5)*Constants.PI/(2*o)),[e,i]},t.prototype.ring=function(t){"use strict";var e,i,o=0,s=t+1,r=0;return this.ncap>=s?(i=s/2,r=Utils.castToInt(i),o=Utils.castToInt(Math.sqrt(i-Math.sqrt(r)))+1):this.nl2*(5*this.nside+1)>=s?(e=Utils.castToInt(s-this.ncap-1),o=Utils.castToInt(e/this.nl4+this.nside)):(e=this.npix-s+1,i=e/2,r=Utils.castToInt(i),o=Utils.castToInt(Math.sqrt(i-Math.sqrt(r)))+1,o=this.nl4-o),o},t.prototype.integration_limits_in_costh=function(t){"use strict";var e,i,o,s;return s=1*this.nside,this.nside>=t?(i=1-Math.pow(t,2)/3/this.npface,o=1-Math.pow(t-1,2)/3/this.npface,e=t==this.nside?2*(this.nside-1)/3/s:1-Math.pow(t+1,2)/3/this.npface):this.nl3>t?(i=2*(2*this.nside-t)/3/s,o=2*(2*this.nside-t+1)/3/s,e=2*(2*this.nside-t-1)/3/s):(o=t==this.nl3?2*(-this.nside+1)/3/s:-1+Math.pow(4*this.nside-t+1,2)/3/this.npface,e=-1+Math.pow(this.nl4-t-1,2)/3/this.npface,i=-1+Math.pow(this.nl4-t,2)/3/this.npface),[o,i,e]},t.prototype.pixel_boundaries=function(t,e,i,o){var s,r,a,n,h,l,c,u,d=1*this.nside;if(Math.abs(o)>=1-1/3/this.npface)return c=i*Constants.PIOVER2,u=(i+1)*Constants.PIOVER2,[c,u];if(1.5*o>=1)s=Math.sqrt(3*(1-o)),r=1/d/s,a=e,n=a-1,h=t-e,l=h+1,c=Constants.PIOVER2*(Math.max(n*r,1-l*r)+i),u=Constants.PIOVER2*(Math.min(1-h*r,a*r)+i);else if(1.5*o>-1){var p=.5*(1-1.5*o),f=p+1,v=this.nside+t%2;a=e-(v-t)/2,n=a-1,h=(v+t)/2-e,l=h+1,c=Constants.PIOVER2*(Math.max(f-l/d,-p+n/d)+i),u=Constants.PIOVER2*(Math.min(f-h/d,-p+a/d)+i)}else{s=Math.sqrt(3*(1+o)),r=1/d/s;var g=2*this.nside;a=t-g+e,n=a-1,h=g-e,l=h+1,c=Constants.PIOVER2*(Math.max(1-(g-n)*r,(g-l)*r)+i),u=Constants.PIOVER2*(Math.min(1-(g-a)*r,(g-h)*r)+i)}return[c,u]},t.vector=function(t,e){"use strict";var i=1*Math.sin(t)*Math.cos(e),o=1*Math.sin(t)*Math.sin(e),s=1*Math.cos(t);return new SpatialVector(i,o,s)},t.prototype.corners_ring=function(e,i){"use strict";var o=2*i+2,s=Array(o),r=this.pix2ang_ring(e),a=Math.cos(r[0]),n=r[0],h=r[1],l=Utils.castToInt(h/Constants.PIOVER2),c=this.ring(e),u=Math.min(c,Math.min(this.nside,this.nl4-c)),d=0,p=Constants.PIOVER2/u;d=c>=this.nside&&this.nl3>=c?Utils.castToInt(h/p+c%2/2)+1:Utils.castToInt(h/p)+1,d-=l*u;var f=o/2,v=this.integration_limits_in_costh(c),g=Math.acos(v[0]),m=Math.acos(v[2]),y=this.pixel_boundaries(c,d,l,v[0]);if(s[0]=d>u/2?t.vector(g,y[1]):t.vector(g,y[0]),y=this.pixel_boundaries(c,d,l,v[2]),s[f]=d>u/2?t.vector(m,y[1]):t.vector(m,y[0]),1==i){var C=Math.acos(v[1]);y=this.pixel_boundaries(c,d,l,v[1]),s[1]=t.vector(C,y[0]),s[3]=t.vector(C,y[1])}else for(var w=v[2]-v[0],x=w/(i+1),S=1;i>=S;S++)a=v[0]+x*S,n=Math.acos(a),y=this.pixel_boundaries(c,d,l,a),s[S]=t.vector(n,y[0]),s[o-S]=t.vector(n,y[1]);return s},t.vec2Ang=function(t){"use strict";var e=t.z/t.length(),i=Math.acos(e),o=0;return(0!=t.x||0!=t.y)&&(o=Math.atan2(t.y,t.x)),0>o&&(o+=2*Math.PI),[i,o]},t.prototype.queryDisc=function(e,i,o,s){"use strict";if(0>i||i>Constants.PI)throw{name:"Illegal argument",message:"angular radius is in RADIAN and should be in [0,pi]"};var r,a,n,h,l,c,u,d,p,f,v,g,m,y,C,w,x,S,M,b=new LongRangeSetBuilder,T=null,l=i;if(s&&(l+=Constants.PI/this.nl4),T=t.vec2Ang(e),c=T[0],u=T[1],v=this.fact2,g=this.fact1,h=Math.cos(c),M=1/Math.sqrt((1-h)*(1+h)),y=c-l,C=c+l,d=Math.cos(l),x=Math.cos(y),r=this.ringAbove(x)+1,w=Math.cos(C),a=this.ringAbove(w),r>a&&0==a&&(a=r),0>=y)for(var P=1;r>P;++P)this.inRing(P,0,Math.PI,b);for(n=r;a>=n;++n)S=this.nside>n?1-n*n*v:this.nl3>=n?(this.nl2-n)*g:-1+(this.nl4-n)*(this.nl4-n)*v,p=(d-S*h)*M,f=1-S*S-p*p,m=Math.atan2(Math.sqrt(f),p),isNaN(m)&&(m=l),this.inRing(n,u,m,b);if(C>=Math.PI)for(var P=a+1;this.nl4>P;++P)this.inRing(P,0,Math.PI,b,!1);var I;if(o){for(var R=b.items,A=[],O=0;R.length>O;O++){var E=this.ring2nest(R[O]);A.indexOf(E)>=0||A.push(E)}I=A}else I=b.items;return I},t.prototype.inRing=function(t,e,i,o,s){"use strict";var r,a,n,h,l=!1,c=!1,u=1e-12,d=0,p=0,f=0,v=0,g=(e-i)%Constants.TWOPI-u,m=e+i+u,y=(e+i)%Constants.TWOPI+u;if(u>Math.abs(i-Constants.PI)&&(l=!0),t>=this.nside&&this.nl3>=t?(p=t-this.nside+1,n=this.ncap+this.nl4*(p-1),h=n+this.nl4-1,r=p%2,a=this.nl4):(this.nside>t?(p=t,n=2*p*(p-1),h=n+4*p-1):(p=4*this.nside-t,n=this.npix-2*p*(p+1),h=n+4*p-1),a=4*p,r=1),l)return o.appendRange(n,h),void 0;if(d=r/2,s)f=Math.round(a*g/Constants.TWOPI-d),v=Math.round(a*m/Constants.TWOPI-d),f%=a,v>a&&(v%=a);else{if(f=Math.ceil(a*g/Constants.TWOPI-d),v=Utils.castToInt(a*y/Constants.TWOPI-d),f>v&&1==t&&(v=Utils.castToInt(a*m/Constants.TWOPI-d)),f==v+1&&(f=v),1==f-v&&Constants.PI>i*a)return console.log("the interval is too small and avay from center"),void 0;f=Math.min(f,a-1),v=Math.max(v,0)}if(f>v&&(c=!0),c)f+=n,v+=n,o.appendRange(n,v),o.appendRange(f,h);else{if(0>f)return f=Math.abs(f),o.appendRange(n,n+v),o.appendRange(h-f+1,h),void 0;f+=n,v+=n,o.appendRange(f,v)}},t.prototype.ringAbove=function(t){"use strict";var e=Math.abs(t);if(e>Constants.TWOTHIRD){var i=Utils.castToInt(this.nside*Math.sqrt(3*(1-e)));return t>0?i:4*this.nside-i-1}return Utils.castToInt(this.nside*(2-1.5*t))},t.prototype.ring2nest=function(t){"use strict";var e=this.ring2xyf(t);return this.xyf2nest(e.ix,e.iy,e.face_num)},t.prototype.ring2xyf=function(e){"use strict";var i,o,s,r,a={};if(this.ncap>e){i=Utils.castToInt(.5*(1+Math.sqrt(1+2*e))),o=e+1-2*i*(i-1),s=0,r=i,a.face_num=0;var n=o-1;n>=2*i&&(a.face_num=2,n-=2*i),n>=i&&++a.face_num}else if(this.npix-this.ncap>e){var h=e-this.ncap;this.order>=0?(i=(h>>this.order+2)+this.nside,o=(h&this.nl4-1)+1):(i=h/this.nl4+this.nside,o=h%this.nl4+1),s=1&i+this.nside,r=this.nside;var l,c,u=i-this.nside+1,d=this.nl2+2-u;this.order>=0?(l=o-Utils.castToInt(u/2)+this.nside-1>>this.order,c=o-Utils.castToInt(d/2)+this.nside-1>>this.order):(l=(o-Utils.castToInt(u/2)+this.nside-1)/this.nside,c=(o-Utils.castToInt(d/2)+this.nside-1)/this.nside),a.face_num=c==l?4==c?4:Utils.castToInt(c)+4:l>c?Utils.castToInt(c):Utils.castToInt(l)+8}else{var h=this.npix-e;i=Utils.castToInt(.5*(1+Math.sqrt(2*h-1))),o=4*i+1-(h-2*i*(i-1)),s=0,r=i,i=2*this.nl2-i,a.face_num=8;var n=o-1;n>=2*r&&(a.face_num=10,n-=2*r),n>=r&&++a.face_num}var p=i-t.JRLL[a.face_num]*this.nside+1,f=2*o-t.JPLL[a.face_num]*r-s-1;return f>=this.nl2&&(f-=8*this.nside),a.ix=f-p>>1,a.iy=-(f+p)>>1,a},t}(),Utils=function(){},Utils.radecToPolar=function(t,e){return{theta:Math.PI/2-e/180*Math.PI,phi:t/180*Math.PI}},Utils.polarToRadec=function(t,e){return{ra:180*e/Math.PI,dec:180*(Math.PI/2-t)/Math.PI}},Utils.castToInt=function(t){return t>0?Math.floor(t):Math.ceil(t)},AstroMath.D2R=Math.PI/180,AstroMath.R2D=180/Math.PI,AstroMath.sign=function(t){return t>0?1:0>t?-1:0},AstroMath.cosd=function(t){if(0==t%90){var e=Math.abs(Math.floor(t/90+.5))%4;switch(e){case 0:return 1;case 1:return 0;case 2:return-1;case 3:return 0}}return Math.cos(t*AstroMath.D2R)},AstroMath.sind=function(t){if(0===t%90){var e=Math.abs(Math.floor(t/90-.5))%4;switch(e){case 0:return 1;case 1:return 0;case 2:return-1;case 3:return 0}}return Math.sin(t*AstroMath.D2R)},AstroMath.tand=function(t){var e;return e=t%360,0==e||180==Math.abs(e)?0:45==e||225==e?1:-135==e||-315==e?-1:Math.tan(t*AstroMath.D2R)},AstroMath.asind=function(t){return Math.asin(t)*AstroMath.R2D},AstroMath.acosd=function(t){return Math.acos(t)*AstroMath.R2D},AstroMath.atand=function(t){return Math.atan(t)*AstroMath.R2D},AstroMath.atan2=function(t,e){if(0==t)return e>0?0:0>e?Math.PI:0/0;var i=AstroMath.sign(t);if(0==e)return Math.PI/2*i;var o=Math.atan(Math.abs(t/e));return e>0?o*i:0>e?(Math.PI-o)*i:void 0},AstroMath.atan2d=function(t,e){return AstroMath.atan2(t,e)*AstroMath.R2D},AstroMath.cosh=function(t){return(Math.exp(t)+Math.exp(-t))/2},AstroMath.sinh=function(t){return(Math.exp(t)-Math.exp(-t))/2},AstroMath.tanh=function(t){return(Math.exp(t)-Math.exp(-t))/(Math.exp(t)+Math.exp(-t))},AstroMath.acosh=function(t){return Math.log(t+Math.sqrt(t*t-1))},AstroMath.asinh=function(t){return Math.log(t+Math.sqrt(t*t+1))},AstroMath.atanh=function(t){return.5*Math.log((1+t)/(1-t))},AstroMath.sinc=function(t){var e,i=Math.abs(t);return.001>=i?(i*=i,e=1-i*(1-i/20)/6):e=Math.sin(i)/i,e},AstroMath.asinc=function(t){var e,i=Math.abs(t);return.001>=i?(i*=i,e=1+i*(6+.45*i)/6):e=Math.asin(i)/i,e},AstroMath.hypot=function(t,e){return Math.sqrt(t*t+e*e)},AstroMath.eulerMatrix=function(t,e,i){var o=Array(3);o[0]=Array(3),o[1]=Array(3),o[2]=Array(3);var s=AstroMath.cosd(t),r=AstroMath.sind(t),a=AstroMath.cosd(e),n=AstroMath.sind(e),h=AstroMath.cosd(i),l=AstroMath.sind(i);return o[0][0]=h*a*s-l*r,o[0][1]=-l*a*s-h*r,o[0][2]=-n*s,o[1][0]=h*a*r+l*s,o[1][1]=-l*a*r+h*s,o[1][2]=-n*r,o[2][0]=-n*h,o[2][1]=-n*s,o[2][2]=a,o},AstroMath.displayMatrix=function(t){for(var e=t.length,i=0,o=0;e>o;o++)t[o].length>i&&(i=t[o].length);for(var s="
\n",o=0;e>o;o++){s+="";for(var r=0;e>r;r++)s+="";s+="\n"}return s+="
",t[o].length>o&&(s+=""+t[o][r]),s+="
\n"},Projection.PROJ_TAN=1,Projection.PROJ_TAN2=2,Projection.PROJ_STG=2,Projection.PROJ_SIN=3,Projection.PROJ_SIN2=4,Projection.PROJ_ZEA=4,Projection.PROJ_ARC=5,Projection.PROJ_SCHMIDT=5,Projection.PROJ_AITOFF=6,Projection.PROJ_AIT=6,Projection.PROJ_GLS=7,Projection.PROJ_MERCATOR=8,Projection.PROJ_MER=8,Projection.PROJ_LAM=9,Projection.PROJ_LAMBERT=9,Projection.PROJ_TSC=10,Projection.PROJ_QSC=11,Projection.PROJ_LIST=["Mercator",Projection.PROJ_MERCATOR,"Gnomonic",Projection.PROJ_TAN,"Stereographic",Projection.PROJ_TAN2,"Orthographic",Projection.PROJ_SIN,"Zenithal",Projection.PROJ_ZEA,"Schmidt",Projection.PROJ_SCHMIDT,"Aitoff",Projection.PROJ_AITOFF,"Lambert",Projection.PROJ_LAMBERT],Projection.PROJ_NAME=["-","Gnomonic","Stereographic","Orthographic","Equal-area","Schmidt plates","Aitoff","Global sin","Mercator","Lambert"],Projection.prototype={setCenter:function(t,e){this.ROT=this.tr_oR(t,e)},setProjection:function(t){this.PROJECTION=t},project:function(t,e){var i=this.tr_ou(t,e),o=this.tr_uu(i,this.ROT),s=this.tr_up(this.PROJECTION,o);return null==s?null:{X:-s[0],Y:-s[1]}},unproject:function(t,e){t=-t,e=-e;var i=this.tr_pu(this.PROJECTION,t,e),o=this.tr_uu1(i,this.ROT),s=this.tr_uo(o);return{ra:s[0],dec:s[1]}},tr_up:function(t,e){var i,o,s,r,a,n=e[0],h=e[1],l=e[2];if(i=AstroMath.hypot(n,h),0==i&&0==l)return null;switch(t){default:s=null;break;case Projection.PROJ_AITOFF:o=Math.sqrt(i*(i+n)/2),r=Math.sqrt(2*i*(i-n)),o=Math.sqrt((1+o)/2),r/=o,a=l/o,0>h&&(r=-r),s=[r,a];break;case Projection.PROJ_GLS:a=Math.asin(l),r=0!=i?Math.atan2(h,n)*i:0,s=[r,a];break;case Projection.PROJ_MERCATOR:0!=i?(r=Math.atan2(h,n),a=AstroMath.atanh(l),s=[r,a]):s=null;break;case Projection.PROJ_TAN:n>0?(r=h/n,a=l/n,s=[r,a]):s=null;break;case Projection.PROJ_TAN2:o=(1+n)/2,o>0?(r=h/o,a=l/o,s=[r,a]):s=null;break;case Projection.PROJ_ARC:-1>=n?(r=Math.PI,a=0):(i=AstroMath.hypot(h,l),o=n>0?AstroMath.asinc(i):Math.acos(n)/i,r=h*o,a=l*o),s=[r,a];break;case Projection.PROJ_SIN:n>=0?(r=h,a=l,s=[r,a]):s=null;break;case Projection.PROJ_SIN2:o=Math.sqrt((1+n)/2),0!=o?(r=h/o,a=l/o):(r=2,a=0),s=[r,a];break;case Projection.PROJ_LAMBERT:a=l,r=0,0!=i&&(r=Math.atan2(h,n)),s=[r,a]}return s},tr_pu:function(t,e,i){var o,s,r,a,n;switch(t){default:return null;case Projection.PROJ_AITOFF:if(o=e*e/8+i*i/2,o>1)return null;r=1-o,s=Math.sqrt(1-o/2),a=e*s/2,n=i*s,o=AstroMath.hypot(r,a),0!=o&&(s=r,r=(s*s-a*a)/o,a=2*s*a/o);break;case Projection.PROJ_GLS:if(n=Math.sin(i),o=1-n*n,0>o)return null;o=Math.sqrt(o),s=0!=o?e/o:0,r=o*Math.cos(s),a=o*Math.sin(s);break;case Projection.PROJ_MERCATOR:n=AstroMath.tanh(i),o=1/AstroMath.cosh(i),r=o*Math.cos(e),a=o*Math.sin(e);break;case Projection.PROJ_LAMBERT:if(n=i,o=1-n*n,0>o)return null;o=Math.sqrt(o),r=o*Math.cos(e),a=o*Math.sin(e);break;case Projection.PROJ_TAN:r=1/Math.sqrt(1+e*e+i*i),a=e*r,n=i*r;break;case Projection.PROJ_TAN2:o=(e*e+i*i)/4,s=1+o,r=(1-o)/s,a=e/s,n=i/s;break;case Projection.PROJ_ARC:if(o=AstroMath.hypot(e,i),o>Math.PI)return null;s=AstroMath.sinc(o),r=Math.cos(o),a=s*e,n=s*i;break;case Projection.PROJ_SIN:if(s=1-e*e-i*i,0>s)return null;r=Math.sqrt(s),a=e,n=i;break;case Projection.PROJ_SIN2:if(o=(e*e+i*i)/4,o>1)return null;s=Math.sqrt(1-o),r=1-2*o,a=s*e,n=s*i}return[r,a,n]},tr_oR:function(t,e){var i=Array(3);return i[0]=Array(3),i[1]=Array(3),i[2]=Array(3),i[2][2]=AstroMath.cosd(e),i[0][2]=AstroMath.sind(e),i[1][1]=AstroMath.cosd(t),i[1][0]=-AstroMath.sind(t),i[1][2]=0,i[0][0]=i[2][2]*i[1][1],i[0][1]=-i[2][2]*i[1][0],i[2][0]=-i[0][2]*i[1][1],i[2][1]=i[0][2]*i[1][0],i},tr_ou:function(t,e){var i=Array(3),o=AstroMath.cosd(e);return i[0]=o*AstroMath.cosd(t),i[1]=o*AstroMath.sind(t),i[2]=AstroMath.sind(e),i},tr_uu:function(t,e){var i=Array(3),o=t[0],s=t[1],r=t[2];return i[0]=e[0][0]*o+e[0][1]*s+e[0][2]*r,i[1]=e[1][0]*o+e[1][1]*s+e[1][2]*r,i[2]=e[2][0]*o+e[2][1]*s+e[2][2]*r,i},tr_uu1:function(t,e){var i=Array(3),o=t[0],s=t[1],r=t[2];return i[0]=e[0][0]*o+e[1][0]*s+e[2][0]*r,i[1]=e[0][1]*o+e[1][1]*s+e[2][1]*r,i[2]=e[0][2]*o+e[1][2]*s+e[2][2]*r,i},tr_uo:function(t){var e,i,o=t[0],s=t[1],r=t[2],a=o*o+s*s;if(0==a){if(0==r)return null;e=0,i=r>0?90:-90}else i=AstroMath.atand(r/Math.sqrt(a)),e=AstroMath.atan2d(s,o),0>e&&(e+=360);return[e,i]}},Coo.factor=[3600,60,1],Coo.prototype={setFrame:function(t){this.frame=t},computeDirCos:function(){var t=AstroMath.cosd(this.lat);this.x=t*AstroMath.cosd(this.lon),this.y=t*AstroMath.sind(this.lon),this.z=AstroMath.sind(this.lat)},computeLonLat:function(){var t=this.x*this.x+this.y*this.y; +this.lon=0,0==t?0==this.z?(this.lon=0/0,this.lat=0/0):this.lat=this.z>0?90:-90:(this.lon=AstroMath.atan2d(this.y,this.x),this.lat=AstroMath.atan2d(this.z,Math.sqrt(t)),0>this.lon&&(this.lon+=360))},distance:function(t){return 0==t.x&&0==t.y&&0==t.z?0/0:0==this.x&&0==this.y&&0==this.z?0/0:2*AstroMath.asind(.5*Math.sqrt(this.dist2(t)))},dist2:function(t){var e=t.x-this.x,i=e*e;return e=t.y-this.y,i+=e*e,e=t.z-this.z,i+=e*e},convertTo:function(t){this.frame.equals(t)||(this.frame.toICRS(this.coo),t.fromICRS(this.coo),this.frame=t,this.lon=this.lat=0/0)},rotate:function(t){var e,i,o;t!=Umatrix3&&(e=t[0][0]*this.x+t[0][1]*this.y+t[0][2]*this.z,i=t[1][0]*this.x+t[1][1]*this.y+t[1][2]*this.z,o=t[2][0]*this.x+t[2][1]*this.y+t[2][2]*this.z,this.x=e,this.y=i,this.z=o,this.lon=this.lat=0/0)},rotate_1:function(t){var e,i,o;t!=Umatrix3&&(e=t[0][0]*this.x+t[1][0]*this.y+t[2][0]*this.z,i=t[0][1]*this.x+t[1][1]*this.y+t[2][1]*this.z,o=t[0][2]*this.x+t[1][2]*this.y+t[2][2]*this.z,this.x=e,this.y=i,this.z=o,this.lon=this.lat=0/0)},equals:function(t){return this.x==t.x&&this.y==t.y&&this.z==t.z},parse:function(t){var e=t.indexOf("+");if(0>e&&(e=t.indexOf("-")),0>e)return this.lon=0/0,this.lat=0/0,this.prec=0,void 0;var i=t.substring(0,e),o=t.substring(e);this.lon=this.parseLon(i),this.lat=this.parseLat(o)},parseLon:function(t){var t=Strings.trim(t," ");if(0>t.indexOf(" ")){var e=t.indexOf(".");return this.prec=0>e?0:t.length-e-1,parseFloat(t)}for(var i=new Tokenizer(t," "),o=0,s=0,r=0;i.hasMore();){var a=i.nextToken(),n=a.indexOf(".");switch(s+=parseFloat(a)*Coo.factor[o],o){case 0:r=0>n?1:2;break;case 1:r=0>n?3:4;break;case 2:r=0>n?5:4+a.length-n;default:}o++}return this.prec=r,15*s/3600},parseLat:function(t){var t=Strings.trim(t," "),e="+"==t.charAt(0)?1:-1;if(t=t.substring(1),0>t.indexOf(" ")){var i=t.indexOf(".");return this.prec=0>i?0:t.length-i-1,parseFloat(t)*e}for(var o=new Tokenizer(t," "),s=0,r=0,a=0;o.hasMore();){var n=o.nextToken(),h=n.indexOf(".");switch(r+=parseFloat(n)*Coo.factor[s],s){case 0:a=0>h?1:2;break;case 1:a=0>h?3:4;break;case 2:a=0>h?5:4+n.length-h;default:}s++}return this.prec=a,r*e/3600},format:function(t){isNaN(this.lon)&&this.computeLonLat();var e="",i="";if(t.indexOf("d")>=0)e=Numbers.format(this.lon,this.prec),i=Numbers.format(this.lat,this.prec);else var o=this.lon/15,e=Numbers.toSexagesimal(o,this.prec,!1),i=Numbers.toSexagesimal(this.lat,this.prec,!0);return t.indexOf("/")>=0?e+" "+i:t.indexOf("2")>=0?[e,i]:e+i}},Tokenizer.prototype={hasMore:function(){return this.post&&this.string.charAt(t)==this.sep;)t++;for(var e=t;this.string.length>e&&this.string.charAt(e)!=this.sep;)e++;return this.pos=e,this.string.substring(t,e)}},Strings.trim=function(t,e){for(var i=0,o=t.length-1;t.length>i&&t.charAt(i)==e;)i++;if(i==t.length)return"";for(;o>i&&t.charAt(o)==e;)o--;return t.substring(i,o+1)},Numbers.pow10=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13,1e14],Numbers.rndval=[.5,.05,.005,5e-4,5e-5,5e-6,5e-7,5e-8,5e-9,5e-10,5e-11,5e-12,5e-13,5e-14,5e-14],Numbers.format=function(t,e){if(0>=e)return""+Math.round(t);var i=""+t,o=i.indexOf("."),s=o>=0?i.length-o-1:0;if(e>=s){0>o&&(i+=".");for(var r=0;e-s>r;r++)i+="0";return i}return i=""+(t+Numbers.rndval[e]),i.substr(0,o+e+1)},Numbers.toSexagesimal=function(t,e,i){var o=0>t?"-":i?"+":"",s=Math.abs(t);switch(e){case 1:var r=Math.round(s);return o+(""+r);case 2:return o+Numbers.format(s,1);case 3:var r=Math.floor(s),a=Math.round(60*(s-r));return o+r+" "+a;case 4:var r=Math.floor(s),a=60*(s-r);return o+r+" "+Numbers.format(a,1);case 5:var r=Math.floor(s),a=60*(s-r),n=Math.floor(a),h=Math.round(60*(a-n));return o+r+" "+n+" "+h;case 6:case 7:case 8:var r=Math.floor(s);10>r&&(r="0"+r);var a=60*(s-r),n=Math.floor(a);10>n&&(n="0"+n);var h=60*(a-n);return o+r+" "+n+" "+Numbers.format(h,e-5);default:return o+Numbers.format(s,1)}},CooConversion=function(){var t={};return t.GALACTIC_TO_J2000=[-.0548755604024359,.4941094279435681,-.867666148981161,-.8734370902479237,-.4448296299195045,-.1980763734646737,-.4838350155267381,.7469822444763707,.4559837762325372],t.J2000_TO_GALACTIC=[-.0548755604024359,-.873437090247923,-.4838350155267381,.4941094279435681,-.4448296299195045,.7469822444763707,-.867666148981161,-.1980763734646737,.4559837762325372],t.Transform=function(t,e){t[0]=t[0]*Math.PI/180,t[1]=t[1]*Math.PI/180;var i=[Math.cos(t[0])*Math.cos(t[1]),Math.sin(t[0])*Math.cos(t[1]),Math.sin(t[1])],o=[i[0]*e[0]+i[1]*e[1]+i[2]*e[2],i[0]*e[3]+i[1]*e[4]+i[2]*e[5],i[0]*e[6]+i[1]*e[7]+i[2]*e[8]],s=Math.sqrt(o[0]*o[0]+o[1]*o[1]+o[2]*o[2]),r=[0,0];r[1]=Math.asin(o[2]/s);var a=o[0]/s/Math.cos(r[1]),n=o[1]/s/Math.cos(r[1]);return r[0]=Math.atan2(n,a),0>r[0]&&(r[0]=r[0]+2*Math.PI),r[0]=180*r[0]/Math.PI,r[1]=180*r[1]/Math.PI,r},t.GalacticToJ2000=function(e){return t.Transform(e,t.GALACTIC_TO_J2000)},t.J2000ToGalactic=function(e){return t.Transform(e,t.J2000_TO_GALACTIC)},t}(),Sesame=function(){return Sesame={},Sesame.cache={},Sesame.resolve=function(t,e,i){var o="http://cds.u-strasbg.fr/cgi-bin/nph-sesame.jsonp?";$.ajax({url:o,data:{object:t},method:"GET",dataType:"jsonp",success:function(t){t.Target&&t.Target.Resolver&&t.Target.Resolver?e(t):i(t)},error:i})},Sesame}(),HealpixCache=function(){var t={};return t.staticCache={corners:{nside8:[]}},t.dynamicCache={},t.lastNside=8,t.hpxIdxCache=null,t.init=function(){var e=new HealpixIndex(8);e.init();for(var i=HealpixIndex.nside2Npix(8),o=0;i>o;o++)t.staticCache.corners.nside8[o]=e.corners_nest(o,1);t.hpxIdxCache=e},t.corners_nest=function(e,i){return 8==i?t.staticCache.corners.nside8[e]:(i!=t.lastNside&&(t.hpxIdxCache=new HealpixIndex(i),t.hpxIdxCache.init(),t.lastNside=i),t.hpxIdxCache.corners_nest(e,1))},t}(),Utils=Utils||{},Utils.cssScale=void 0,HTMLCanvasElement.prototype.relMouseCoords=relMouseCoords,Function.prototype.bind||(Function.prototype.bind=function(t){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var e=[].slice,i=e.call(arguments,1),o=this,s=function(){},r=function(){return o.apply(this instanceof s?this:t||{},i.concat(e.call(arguments)))};return r.prototype=this.prototype,r}),$=$||jQuery,$.urlParam=function(t,e){return void 0===e&&(e=location.search),decodeURIComponent((RegExp("[?|&]"+t+"="+"([^&;]+?)(&|#|;|$)").exec(e)||[,""])[1].replace(/\+/g,"%20"))||null},Utils.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},Utils.debounce=function(t,e){var i=null;return function(){var o=this,s=arguments;clearTimeout(i),i=setTimeout(function(){t.apply(o,s)},e)}},Utils.LRUCache=function(t){this._keys=[],this._items={},this._expires={},this._size=0,this._maxsize=t||1024},Utils.LRUCache.prototype={set:function(t,e){var i=this._keys,o=this._items,s=this._expires,r=this._size,a=this._maxsize;r>=a&&(i.sort(function(t,e){return s[t]>s[e]?-1:s[t]t?-1*(0|-t):0|t},isHpxPixVisible:function(t,e,i){for(var o=0;t.length>o;o++)if(t[o].vx>=-20&&e+20>t[o].vx&&t[o].vy>=-20&&i+20>t[o].vy)return!0;return!1},ipixToIpix:function(t,e,i){},getZoomFactorForAngle:function(t,e){var i={ra:0,dec:0},o={ra:t,dec:0},s=new Projection(t/2,0);s.setProjection(e);var r=s.project(i.ra,i.dec),a=s.project(o.ra,o.dec),n=1/(r.X-a.Y);return n}}}(),ProjectionEnum={SIN:Projection.PROJ_SIN,AITOFF:Projection.PROJ_AITOFF},CooFrameEnum=function(){return{J2000:"J2000",GAL:"Galactic"}}(),CooFrameEnum.fromString=function(t,e){return t?(t=t.toLowerCase().replace(/^\s+|\s+$/g,""),0==t.indexOf("j2000")||0==t.indexOf("icrs")?CooFrameEnum.J2000:0==t.indexOf("g")?CooFrameEnum.GAL:e?e:null):e?e:null},Downloader=function(){var t=4,e=!1,i=700,o=function(t){this.view=t,this.nbDownloads=0,this.dlQueue=[],this.urlsInQueue={}};return o.prototype.requestDownload=function(t,e,i){e in this.urlsInQueue||(this.dlQueue.push({img:t,url:e,cors:i}),this.urlsInQueue[e]=1,this.tryDownload())},o.prototype.tryDownload=function(){for(;this.dlQueue.length>0&&t>this.nbDownloads;)this.startDownloadNext()},o.prototype.startDownloadNext=function(){var t=this.dlQueue.shift();if(t){this.nbDownloads++;var e=this;t.img.onload=function(){e.completeDownload(this,!0)},t.img.onerror=function(){e.completeDownload(this,!1)},t.cors?t.img.crossOrigin="anonymous":void 0!==t.img.crossOrigin&&delete t.img.crossOrigin,t.img.src=t.url}},o.prototype.completeDownload=function(t,o){if(delete this.urlsInQueue[t.src],t.onerror=null,t.onload=null,this.nbDownloads--,o){if(e){var s=(new Date).getTime();t.fadingStart=s,t.fadingEnd=s+i}this.view.requestRedraw()}else t.dlError=!0;this.tryDownload()},o}(),Footprint=function(){return Footprint=function(t){this.polygons=t,this.overlay=null,this.isShowing=!0,this.isSelected=!1},Footprint.prototype.setOverlay=function(t){this.overlay=t},Footprint.prototype.show=function(){this.isShowing||(this.isShowing=!0,this.overlay&&this.overlay.reportChange())},Footprint.prototype.hide=function(){this.isShowing&&(this.isShowing=!1,this.overlay&&this.overlay.reportChange())},Footprint.prototype.select=function(){this.isSelected||(this.isSelected=!0,this.overlay&&this.overlay.reportChange())},Footprint.prototype.deselect=function(){this.isSelected&&(this.isSelected=!1,this.overlay&&this.overlay.reportChange())},Footprint}(),Popup=function(){return Popup=function(t){this.domEl=$(''),this.domEl.appendTo(t);var e=this;this.domEl.find(".aladin-closeBtn").click(function(){e.hide()})},Popup.prototype.hide=function(){this.domEl.hide()},Popup.prototype.show=function(){this.domEl.show()},Popup.prototype.setTitle=function(t){this.domEl.find(".aladin-popupTitle").html(t)},Popup.prototype.setText=function(t){this.domEl.find(".aladin-popupText").html(t),this.w=this.domEl.outerWidth(),this.h=this.domEl.outerHeight()},Popup.prototype.setSource=function(t){this.source&&(this.source.popup=null),t.popup=this,this.source=t,this.setPosition(t.x,t.y)},Popup.prototype.setPosition=function(t,e){var i=t-this.w/2,o=e-this.h+this.source.catalog.sourceSize/2;this.domEl[0].style.left=i+"px",this.domEl[0].style.top=o+"px"},Popup}(),Overlay=function(){return Overlay=function(t){t=t||{},this.name=t.name||"overlay",this.color=t.color||Color.getNextColor(),this.overlays=[]},Overlay.parseSTCS=function(t){for(var e,i=[],o=t.match(/\S+/g),s=0,r=o.length;r>s;){var a=o[s].toLowerCase();if("polygon"==a&&(e=[],s++,frame=o[s].toLowerCase(),"icrs"==frame||"j2000"==frame)){for(;r>s+2;){var n=parseFloat(o[s+1]);if(isNaN(n))break;var h=parseFloat(o[s+2]);e.push([n,h]),s+=2}e.push(e[0]),i.push(e)}s++}return i},Overlay.prototype.addFootprints=function(t){this.overlays=this.overlays.concat(t);for(var e=0,i=t.length;i>e;e++)t[e].setOverlay(this);this.view.requestRedraw()},Overlay.prototype.getFootprint=function(t){return this.footprints.length>t?this.footprints[t]:null},Overlay.prototype.setView=function(t){this.view=t},Overlay.prototype.removeAll=function(){this.overlays=[]},Overlay.prototype.draw=function(t,e,i,o,s,r,a){t.strokeStyle=this.color,t.lineWidth=2,t.beginPath(),xyviews=[];for(var n=0,h=this.overlays.length;h>n;n++)xyviews.push(this.drawFootprint(this.overlays[n],t,e,i,o,s,r,a));t.stroke(),t.strokeStyle=Overlay.increase_brightness(this.color,80),t.beginPath();for(var n=0,h=this.overlays.length;h>n;n++)this.overlays[n].isSelected&&this.drawFootprintSelected(t,xyviews[n]);t.stroke()},Overlay.increase_brightness=function(t,e){t=t.replace(/^\s*#|\s*$/g,""),3==t.length&&(t=t.replace(/(.)/g,"$1$1"));var i=parseInt(t.substr(0,2),16),o=parseInt(t.substr(2,2),16),s=parseInt(t.substr(4,2),16);return"#"+(0|256+i+(256-i)*e/100).toString(16).substr(1)+(0|256+o+(256-o)*e/100).toString(16).substr(1)+(0|256+s+(256-s)*e/100).toString(16).substr(1)},Overlay.prototype.drawFootprint=function(t,e,i,o,s,r,a,n){if(!t.isShowing)return null;for(var h=[],l=!1,c=t.polygons,u=0,d=c.length;d>u;u++){var p;if(o!=CooFrameEnum.J2000){var f=CooConversion.J2000ToGalactic([c[u][0],c[u][1]]);p=i.project(f[0],f[1])}else p=i.project(c[u][0],c[u][1]);if(!p)return null;var v=AladinUtils.xyToView(p.X,p.Y,s,r,a,n);h.push(v),!l&&s>v.vx&&v.vx>=0&&r>=v.vy&&v.vy>=0&&(l=!0)}if(l){e.moveTo(h[0].vx,h[0].vy);for(var u=1,d=h.length;d>u;u++)e.lineTo(h[u].vx,h[u].vy)}return h},Overlay.prototype.drawFootprintSelected=function(t,e){if(e){var i=e;t.moveTo(i[0].vx,i[0].vy);for(var o=1,s=i.length;s>o;o++)t.lineTo(i[o].vx,i[o].vy)}},Overlay.prototype.reportChange=function(){this.view.requestRedraw()},Overlay}(),cds.Source=function(){return cds.Source=function(t,e,i,o){this.ra=t,this.dec=e,this.data=i,this.catalog=null,this.marker=o&&o.marker||!1,this.marker&&(this.popupTitle=o&&o.popupTitle?o.popupTitle:"",this.popupDesc=o&&o.popupDesc?o.popupDesc:""),this.isShowing=!0,this.isSelected=!1},cds.Source.prototype.setCatalog=function(t){this.catalog=t},cds.Source.prototype.show=function(){this.isShowing||(this.isShowing=!0,this.catalog&&this.catalog.reportChange())},cds.Source.prototype.hide=function(){this.isShowing&&(this.isShowing=!1,this.catalog&&this.catalog.reportChange())},cds.Source.prototype.select=function(){this.isSelected||(this.isSelected=!0,this.catalog&&this.catalog.reportChange())},cds.Source.prototype.deselect=function(){this.isSelected&&(this.isSelected=!1,this.catalog&&this.catalog.reportChange())},cds.Source}(),ProgressiveCat=function(){function t(t,e){var i=["name","ID","ucd","utype","unit","datatype","arraysize","width","precision"],o=[],s=0;return t.keyRa=t.keyDec=null,$(e).find("FIELD").each(function(){for(var e={},r=0;i.length>r;r++){var a=i[r];$(this).attr(a)&&(e[a]=$(this).attr(a))}e.ID||(e.ID="col_"+s),t.keyRa||!e.ucd||0!=e.ucd.indexOf("pos.eq.ra")&&0!=e.ucd.indexOf("POS_EQ_RA")||(t.keyRa=e.name?e.name:e.ID),t.keyDec||!e.ucd||0!=e.ucd.indexOf("pos.eq.dec")&&0!=e.ucd.indexOf("POS_EQ_DEC")||(t.keyDec=e.name?e.name:e.ID),o.push(e),s++}),o}function e(t,e,i){if(!t.keyRa||!t.keyDec)return[];lines=e.split("\n");for(var o=[],s=0;i.length>s;s++)i[s].name?o.push(i[s].name):o.push(i[s].ID);for(var r=[],a=new Coo,n=2;lines.length>n;n++){var h={},l=lines[n].split(" ");if(!(l.lengthc;c++)h[o[c]]=l[c];var u,d;Utils.isNumber(h[t.keyRa])&&Utils.isNumber(h[t.keyDec])?(u=parseFloat(h[t.keyRa]),d=parseFloat(h[t.keyDec])):(a.parse(h[t.keyRa]+" "+h[t.keyDec]),u=a.lon,d=a.lat),r.push(new cds.Source(u,d,h))}}return r}return ProgressiveCat=function(t,e,i,o){o=o||{},this.type="progressivecat",this.rootUrl=t,this.frame=CooFrameEnum.fromString(e)||CooFrameEnum.J2000,this.maxOrder=i,this.isShowing=!0,this.name=o.name||"progressive-cat",this.color=o.color||Color.getNextColor(),this.sourceSize=o.sourceSize||10,this.sourcesCache=new Utils.LRUCache(100),this.cacheCanvas=document.createElement("canvas"),this.cacheCanvas.width=this.sourceSize,this.cacheCanvas.height=this.sourceSize;var s=this.cacheCanvas.getContext("2d");s.beginPath(),s.strokeStyle=this.color,s.lineWidth=2,s.moveTo(0,0),s.lineTo(0,this.sourceSize),s.lineTo(this.sourceSize,this.sourceSize),s.lineTo(this.sourceSize,0),s.lineTo(0,0),s.stroke()},ProgressiveCat.prototype={init:function(t){this.view=t,this.level3Sources||this.loadLevel2Sources()},loadLevel2Sources:function(){var i=this;$.ajax({url:i.rootUrl+"/"+"Norder2/Allsky.xml",method:"GET",success:function(o){i.fields=t(i,o),i.level2Sources=e(i,$(o).find("CSV").text(),i.fields),i.loadLevel3Sources()},error:function(t){console.log("Something went wrong: "+t)}})},loadLevel3Sources:function(){var t=this;$.ajax({url:t.rootUrl+"/"+"Norder3/Allsky.xml",method:"GET",success:function(i){t.level3Sources=e(t,$(i).find("CSV").text(),t.fields),t.view.requestRedraw()},error:function(t){console.log("Something went wrong: "+t)}})},draw:function(t,e,i,o,s,r,a){if(this.isShowing&&this.level3Sources&&(this.drawSources(this.level2Sources,t,e,i,o,s,r,a),this.drawSources(this.level3Sources,t,e,i,o,s,r,a),this.tilesInView))for(var n,h,l,c=0;this.tilesInView.length>c;c++)l=this.tilesInView[c],h=l[0]+"-"+l[1],n=this.sourcesCache.get(h),n&&this.drawSources(n,t,e,i,o,s,r,a)},drawSources:function(t,e,i,o,s,r,a,n){for(var h=0,l=t.length;l>h;h++)this.drawSource(t[h],e,i,o,s,r,a,n)},getSources:function(){var t=[];if(this.level2Sources&&(t=t.concat(this.level2Sources)),this.level3Sources&&(t=t.concat(this.level3Sources)),this.tilesInView)for(var e,i,o,s=0;this.tilesInView.length>s;s++)o=this.tilesInView[s],i=o[0]+"-"+o[1],e=this.sourcesCache.get(i),e&&(t=t.concat(e));return t},drawSource:function(t,e,i,o,s,r,a,n){if(t.isShowing){var h,l=this.sourceSize;if(o!=CooFrameEnum.J2000){var c=CooConversion.J2000ToGalactic([t.ra,t.dec]);h=i.project(c[0],c[1])}else h=i.project(t.ra,t.dec);if(h){var u=AladinUtils.xyToView(h.X,h.Y,s,r,a,n);if(u){if(u.vx>s+l||0-l>u.vx||u.vy>r+l||0-l>u.vy)return t.x=t.y=void 0,void 0;t.x=u.vx,t.y=u.vy,e.drawImage(this.cacheCanvas,t.x-l/2,t.y-l/2)}}}},deselectAll:function(){for(var t=0;this.level2Sources.length>t;t++)this.level2Sources[t].deselect();for(var t=0;this.level3Sources.length>t;t++)this.level3Sources[t].deselect();var e=this.sourcesCache.keys();for(key in e)if(this.sourcesCache[key])for(var i=this.sourcesCache[key],t=0;i.length>t;t++)i[t].deselect()},show:function(){this.isShowing||(this.isShowing=!0,this.reportChange())},hide:function(){this.isShowing&&(this.isShowing=!1,this.reportChange())},reportChange:function(){this.view.requestRedraw()},getTileURL:function(t,e){var i=1e4*Math.floor(e/1e4);return this.rootUrl+"/"+"Norder"+t+"/Dir"+i+"/Npix"+e+".tsv"},loadNeededTiles:function(){this.tilesInView=[],this.otherSources=[];var t=this.view.realNorder;if(t>this.maxOrder&&(t=this.maxOrder),!(3>=t)){for(var i,o,s=this.view.getVisibleCells(t,this.frame),r=4;t>=r;r++){i=[];for(var a=0;s.length>a;a++)o=Math.floor(s[a].ipix/Math.pow(4,t-r)),0>i.indexOf(o)&&i.push(o);for(var n=0;i.length>n;n++)this.tilesInView.push([r,i[n]])}for(var h,l,a=0;this.tilesInView.length>a;a++)h=this.tilesInView[a],l=h[0]+"-"+h[1],this.sourcesCache.get(l)||function(t,i,o){var s=i+"-"+o;$.ajax({url:t.getTileURL(i,o),method:"GET",success:function(i){t.sourcesCache.set(s,e(t,i,t.fields)),t.view.requestRedraw()},error:function(){t.sourcesCache.set(s,[])}})}(this,h[0],h[1])}}},ProgressiveCat}(),cds.Catalog=function(){return cds.Catalog=function(t){t=t||{},this.type="catalog",this.name=t.name||"catalog",this.color=t.color||Color.getNextColor(),this.sourceSize=t.sourceSize||6,this.selectSize=this.sourceSize+2,this.isShowing=!0,this.indexationNorder=5,this.sources=[],this.hpxIdx=new HealpixIndex(this.indexationNorder),this.hpxIdx.init(),this.selectionColor="#00ff00",this.cacheCanvas=document.createElement("canvas"),this.cacheCanvas.width=this.sourceSize,this.cacheCanvas.height=this.sourceSize;var e=this.cacheCanvas.getContext("2d");e.beginPath(),e.strokeStyle=this.color,e.lineWidth=2,e.moveTo(0,0),e.lineTo(0,this.sourceSize),e.lineTo(this.sourceSize,this.sourceSize),e.lineTo(this.sourceSize,0),e.lineTo(0,0),e.stroke(),this.cacheMarkerCanvas=document.createElement("canvas"),this.cacheMarkerCanvas.width=this.sourceSize,this.cacheMarkerCanvas.height=this.sourceSize;var i=this.cacheMarkerCanvas.getContext("2d");i.fillStyle=this.color,i.beginPath();var o=this.sourceSize/2;i.arc(o,o,o-2,0,2*Math.PI,!1),i.fill(),i.lineWidth=2,i.strokeStyle="#ccc",i.stroke(),this.cacheSelectCanvas=document.createElement("canvas"),this.cacheSelectCanvas.width=this.selectSize,this.cacheSelectCanvas.height=this.selectSize;var s=this.cacheSelectCanvas.getContext("2d");s.beginPath(),s.strokeStyle=this.selectionColor,s.lineWidth=2,s.moveTo(0,0),s.lineTo(0,this.selectSize),s.lineTo(this.selectSize,this.selectSize),s.lineTo(this.selectSize,0),s.lineTo(0,0),s.stroke()},cds.Catalog.parseVOTable=function(t,e){function i(t,e){t=t.replace(/^\s+/g,"");var i=["name","ID","ucd","utype","unit","datatype","arraysize","width","precision"],o=[],s=0;$(t).find("FIELD").each(function(){for(var t={},e=0;i.length>e;e++){var r=i[e];$(this).attr(r)&&(t[r]=$(this).attr(r))}t.ID||(t.ID="col_"+s),o.push(t),s++});var r,a;r=a=null;for(var n=0,h=o.length;h>n;n++){var l=o[n];if(!r&&l.ucd){var c=l.ucd.toLowerCase();if(c.indexOf("pos.eq.ra")>=0||c.indexOf("pos_eq_ra")>=0){r=n;continue}}if(!a&&l.ucd){var c=l.ucd.toLowerCase();if(c.indexOf("pos.eq.dec")>=0||c.indexOf("pos_eq_dec")>=0){a=n;continue}}}var u,d,p=[],f=new Coo;$(t).find("TR").each(function(){var t={},e=0;$(this).find("TD").each(function(){var i=o[e].name?o[e].name:o[e].id;t[i]=$(this).text(),e++});var i=o[r].name?o[r].name:o[r].id,s=o[a].name?o[a].name:o[a].id;Utils.isNumber(t[i])&&Utils.isNumber(t[s])?(u=parseFloat(t[i]),d=parseFloat(t[s])):(f.parse(t[i]+" "+t[s]),u=f.lon,d=f.lat),p.push(new cds.Source(u,d,t))}),e&&e(p)}$.ajax({url:Aladin.JSONP_PROXY,data:{url:t},method:"GET",dataType:"jsonp",success:function(t){i(t,e)}})},cds.Catalog.prototype.addSources=function(t){this.sources=this.sources.concat(t);for(var e=0,i=t.length;i>e;e++)t[e].setCatalog(this);this.view.requestRedraw()},cds.Catalog.prototype.getSources=function(){return this.sources},cds.Catalog.prototype.selectAll=function(){if(this.sources)for(var t=0;this.sources.length>t;t++)this.sources[t].select()},cds.Catalog.prototype.deselectAll=function(){if(this.sources)for(var t=0;this.sources.length>t;t++)this.sources[t].deselect()},cds.Catalog.prototype.getSource=function(t){return this.sources.length>t?this.sources[t]:null},cds.Catalog.prototype.setView=function(t){this.view=t},cds.Catalog.prototype.removeAll=function(){this.sources=[]},cds.Catalog.prototype.draw=function(t,e,i,o,s,r,a){if(this.isShowing){for(var n=0,h=this.sources.length;h>n;n++)this.drawSource(this.sources[n],t,e,i,o,s,r,a);t.strokeStyle=this.selectionColor,t.beginPath();for(var n=0,h=this.sources.length;h>n;n++)this.sources[n].isSelected&&this.drawSourceSelection(this.sources[n],t);t.stroke()}},cds.Catalog.prototype.drawSource=function(t,e,i,o,s,r,a,n){if(t.isShowing){var h,l=this.sourceSize;if(o!=CooFrameEnum.J2000){var c=CooConversion.J2000ToGalactic([t.ra,t.dec]);h=i.project(c[0],c[1])}else h=i.project(t.ra,t.dec);if(h){var u=AladinUtils.xyToView(h.X,h.Y,s,r,a,n),d=t.popup?100:t.sourceSize;if(u){if(u.vx>s+d||0-d>u.vx||u.vy>r+d||0-d>u.vy)return t.x=t.y=void 0,void 0;t.x=u.vx,t.y=u.vy,t.marker?e.drawImage(this.cacheMarkerCanvas,t.x-l/2,t.y-l/2):e.drawImage(this.cacheCanvas,t.x-l/2,t.y-l/2),t.popup&&t.popup.setPosition(t.x,t.y)}}}},cds.Catalog.prototype.drawSourceSelection=function(t,e){if(t&&t.isShowing&&t.x&&t.y){var i=this.selectSize;e.drawImage(this.cacheSelectCanvas,t.x-i/2,t.y-i/2)}},cds.Catalog.prototype.reportChange=function(){this.view.requestRedraw()},cds.Catalog.prototype.show=function(){this.isShowing||(this.isShowing=!0,this.reportChange())},cds.Catalog.prototype.hide=function(){this.isShowing&&(this.isShowing=!1,this.view.popup&&this.view.popup.source&&this.view.popup.source.catalog==this&&this.view.popup.hide(),this.reportChange())},cds.Catalog}(),Tile=function(){function t(t,e){this.img=t,this.url=e}return t.isImageOk=function(t){return t.allSkyTexture?!0:t.src?t.complete?t.naturalWidth!==void 0&&0==t.naturalWidth?!1:!0:!1:!1},t}(),TileBuffer=function(){function t(){this.pointer=0,this.tilesMap={},this.tilesArray=Array(e);for(var t=0;e>t;t++)this.tilesArray[t]=new Tile(new Image,null,null)}var e=800;return t.prototype.addTile=function(t){if(this.getTile(t))return null;var i=this.tilesArray[this.pointer];return i.img.src=null,delete this.tilesMap[i.url],this.tilesArray[this.pointer].url=t,this.tilesMap[t]=this.tilesArray[this.pointer],this.pointer++,this.pointer>=e&&(this.pointer=0),this.tilesMap[t]},t.prototype.getTile=function(t){return this.tilesMap[t]},t}(),ColorMap=function(){return ColorMap=function(t){this.view=t,this.reversed=!1,this.map="native",this.sig=this.signature()},ColorMap.MAPS={},ColorMap.MAPS.eosb={name:"Eos B",r:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,18,27,36,45,49,57,72,81,91,100,109,118,127,136,131,139,163,173,182,191,200,209,218,227,213,221,255,255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,253,251,249,247,245,243,241,215,214,235,234,232,230,228,226,224,222,198,196,216,215,213,211,209,207,205,203,181,179,197,196,194,192,190,188,186,184,164,162,178,176,175,173,171,169,167,165,147,145,159,157,156,154,152,150,148,146,130,128,140,138,137,135,133,131,129,127,113,111,121,119,117,117],g:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,15,23,31,39,47,55,57,64,79,87,95,103,111,119,127,135,129,136,159,167,175,183,191,199,207,215,200,207,239,247,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,255,255,255,255,255,255,255,229,229,255,250,246,242,238,233,229,225,198,195,212,208,204,199,195,191,187,182,160,156,169,165,161,157,153,148,144,140,122,118,127,125,123,121,119,116,114,112,99,97,106,104,102,99,97,95,93,91,80,78,84,82,80,78,76,74,72,70,61,59,63,61,59,57,55,53,50,48,42,40,42,40,38,36,33,31,29,27,22,21,21,19,16,14,12,13,8,6,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],b:[116,121,127,131,136,140,144,148,153,157,145,149,170,174,178,182,187,191,195,199,183,187,212,216,221,225,229,233,238,242,221,225,255,247,239,231,223,215,207,199,172,164,175,167,159,151,143,135,127,119,100,93,95,87,79,71,63,55,47,39,28,21,15,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},ColorMap.MAPS.rainbow={name:"Rainbow",r:[0,4,9,13,18,22,27,31,36,40,45,50,54,58,61,64,68,69,72,74,77,79,80,82,83,85,84,86,87,88,86,87,87,87,85,84,84,84,83,79,78,77,76,71,70,68,66,60,58,55,53,46,43,40,36,33,25,21,16,12,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,12,21,25,29,33,42,46,51,55,63,67,72,76,80,89,93,97,101,110,114,119,123,131,135,140,144,153,157,161,165,169,178,182,187,191,199,203,208,212,221,225,229,233,242,246,250,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],g:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,16,21,25,29,38,42,46,51,55,63,67,72,76,84,89,93,97,106,110,114,119,127,131,135,140,144,152,157,161,165,174,178,182,187,195,199,203,208,216,220,225,229,233,242,246,250,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,250,242,238,233,229,221,216,212,208,199,195,191,187,178,174,170,165,161,153,148,144,140,131,127,123,119,110,106,102,97,89,85,80,76,72,63,59,55,51,42,38,34,29,21,17,12,8,0],b:[0,3,7,10,14,19,23,28,32,38,43,48,53,59,63,68,72,77,81,86,91,95,100,104,109,113,118,122,127,132,136,141,145,150,154,159,163,168,173,177,182,186,191,195,200,204,209,214,218,223,227,232,236,241,245,250,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,246,242,238,233,225,220,216,212,203,199,195,191,187,178,174,170,165,157,152,148,144,135,131,127,123,114,110,106,102,97,89,84,80,76,67,63,59,55,46,42,38,34,25,21,16,12,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},ColorMap.MAPS_CUSTOM=["rainbow","eosb"],ColorMap.MAPS_NAMES=["native","grayscale"].concat(ColorMap.MAPS_CUSTOM),ColorMap.prototype.reverse=function(t){this.reversed=t?t:!this.reversed,this.sig=this.signature(),this.view.requestRedraw()},ColorMap.prototype.signature=function(){var t=this.map;return this.reversed&&(t+=" reversed"),t},ColorMap.prototype.update=function(t){this.map=t,this.sig=this.signature(),this.view.requestRedraw()},ColorMap.prototype.apply=function(t){if("native"==this.sig)return t;if(t.cmSig==this.sig)return t.cmImg;var e=document.createElement("canvas");e.width=t.width,e.height=t.height;var i=e.getContext("2d");i.drawImage(t,0,0);var o,s,r,a=i.getImageData(0,0,e.width,e.height),n=a.data,h=n.length,l=3;"grayscale"==this.map?l=1:ColorMap.MAPS_CUSTOM.indexOf(this.map)>=0&&(l=2);for(var c=0;h>c;c+=4){switch(l){case 1:o=s=r=AladinUtils.myRound((n[c]+n[c+1]+n[c+2])/3);break;case 2:this.reversed?(o=ColorMap.MAPS[this.map].r[255-n[c]],s=ColorMap.MAPS[this.map].g[255-n[c+1]],r=ColorMap.MAPS[this.map].b[255-n[c+2]]):(o=ColorMap.MAPS[this.map].r[n[c]],s=ColorMap.MAPS[this.map].g[n[c+1]],r=ColorMap.MAPS[this.map].b[n[c+2]]);break;default:o=n[c],s=n[c+1],r=n[c+2]}2!=l&&this.reversed&&(o=255-o,s=255-s,r=255-r),n[c]=o,n[c+1]=s,n[c+2]=r}return a.data=n,i.putImageData(a,0,0),t.cmSig=this.sig,t.cmImg=e,t.cmImg},ColorMap}(),HpxImageSurvey=function(){function t(t,e,i,o,s,r,a,n,h,l,c,u,d,p,f){var v=(i+s+a)/3,g=(o+r+n)/3;t.save(),f&&(t.globalAlpha=f),t.beginPath();var m=.05;t.moveTo((1+m)*i-v*m,(1+m)*o-g*m),t.lineTo((1+m)*s-v*m,(1+m)*r-g*m),t.lineTo((1+m)*a-v*m,(1+m)*n-g*m),t.closePath(),t.clip();var y=1/(h*(p-u)-c*p+d*u+(c-d)*l);t.transform(-(l*(a-s)-u*a+p*s+(u-p)*i)*y,(u*n+l*(r-n)-p*r+(p-u)*o)*y,(h*(a-s)-c*a+d*s+(c-d)*i)*y,-(c*n+h*(r-n)-d*r+(d-c)*o)*y,(h*(p*s-u*a)+l*(c*a-d*s)+(d*u-c*p)*i)*y,(h*(p*r-u*n)+l*(c*n-d*r)+(d*u-c*p)*o)*y),t.drawImage(e,0,0),t.restore()}var e=function(t,i,o,s,r,a){this.id=t,this.name=i,this.rootUrl=o,a=a||{},this.imgFormat=a.imgFormat||"jpg",this.minOrder=a.minOrder||null,this.cooFrame=s&&"galactic"==s.toLowerCase()?CooFrameEnum.GAL:CooFrameEnum.J2000,this.maxOrder=r,this.allskyTextures=[],this.allskyTextureSize=0,this.lastUpdateDateNeededTiles=0;for(var n=!1,h=0;e.SURVEYS.length>h;h++)e.SURVEYS[h].id==this.id&&(n=!0);n||e.SURVEYS.push({id:this.id,url:this.rootUrl,name:this.name,maxOrder:this.maxOrder,frame:this.cooFrame}),e.SURVEYS_OBJECTS[this.id]=this};return e.UPDATE_NEEDED_TILES_DELAY=1e3,e.prototype.init=function(t,e){this.view=t,this.cm||(this.cm=new ColorMap(this.view)),this.tileBuffer=this.view.tileBuffer,this.useCors=!1; +var i=this;$.support.cors?$.ajax({type:"GET",url:this.rootUrl+"/",contentType:"text/plain",xhrFields:{},headers:{},success:function(){i.useCors=!0,i.retrieveAllskyTextures(),e&&e()},error:function(){i.retrieveAllskyTextures(),e&&e()}}):(this.retrieveAllskyTextures(),e())},e.DEFAULT_SURVEY_ID="P/DSS2/color",e.SURVEYS_OBJECTS={},e.SURVEYS=[{id:"P/2MASS/color",url:"http://alasky.u-strasbg.fr/2MASS/Color",name:"2MASS colored",maxOrder:9,frame:"equatorial",format:"jpeg"},{id:"P/DSS2/color",url:"http://alaskybis.u-strasbg.fr/DssColor",name:"DSS colored",maxOrder:9,frame:"equatorial",format:"jpeg"},{id:"P/DSS2/red",url:"http://alaskybis.u-strasbg.fr/DSS/DSS2Merged",name:"DSS2 Red (F+R)",maxOrder:9,frame:"equatorial",format:"jpeg fits"},{id:"P/Fermi/color",url:"http://alasky.u-strasbg.fr/Fermi/Color",name:"Fermi Color",maxOrder:3,frame:"equatorial",format:"jpeg"},{id:"P/Finkbeiner",url:"http://alasky.u-strasbg.fr/FinkbeinerHalpha",maxOrder:3,frame:"galactic",format:"jpeg fits",name:"Halpha"},{id:"P/GALEXGR6/AIS/color",url:"http://alasky.u-strasbg.fr/GALEX/GR6-02-Color",name:"GALEX AIS Colored",maxOrder:8,frame:"equatorial",format:"jpeg"},{id:"P/IRIS/color",url:"http://alaskybis.u-strasbg.fr/IRISColor",name:"IRIS colored",maxOrder:3,frame:"galactic",format:"jpeg"},{id:"P/Mellinger/color",url:"http://alaskybis.u-strasbg.fr/MellingerRGB",name:"Mellinger colored",maxOrder:4,frame:"galactic",format:"jpeg"},{id:"P/SDSS9/color",url:"http://alasky.u-strasbg.fr/SDSS/SDSSDR9",name:"SDSS9 colored",maxOrder:10,frame:"equatorial",format:"jpeg"},{id:"P/SPITZER/color",url:"http://alaskybis.u-strasbg.fr/SpitzerI1I2I4color",name:"IRAC color I1,I2,I4 - (GLIMPSE, SAGE, SAGE-SMC, SINGS)",maxOrder:9,frame:"galactic",format:"jpeg"},{id:"P/VTSS/Ha",url:"http://alasky.u-strasbg.fr/VTSS/Ha",maxOrder:3,frame:"galactic",format:"png jpeg fits",name:"VTSS-Ha"},{id:"P/XMM/EPIC",url:"http://saada.u-strasbg.fr/xmmallsky",name:"XMM-Newton stacked EPIC images (no phot. normalization)",maxOrder:7,frame:"equatorial",format:"png jpeg fits"}],e.getAvailableSurveys=function(){return e.SURVEYS},e.getSurveyInfoFromId=function(t){for(var i=e.getAvailableSurveys(),o=0;i.length>o;o++)if(i[o].id==t)return i[o];return null},e.getSurveyFromId=function(t){if(e.SURVEYS_OBJECTS[t])return e.SURVEYS_OBJECTS[t];var i=e.getSurveyInfoFromId(t);return i?new e(i.id,i.name,i.url,i.frame,i.maxOrder):null},e.prototype.getTileURL=function(t,e){var i=1e4*Math.floor(e/1e4);return this.rootUrl+"/"+"Norder"+t+"/Dir"+i+"/Npix"+e+"."+this.imgFormat},e.prototype.retrieveAllskyTextures=function(){var t=new Image;this.useCors&&(t.crossOrigin="anonymous");var e=this;t.onload=function(){e.allskyTextureSize=t.width/27;for(var i=0;29>i;i++)for(var o=0;27>o;o++){var s=document.createElement("canvas");s.width=s.height=e.allskyTextureSize,s.allSkyTexture=!0;var r=s.getContext("2d");r.drawImage(t,o*e.allskyTextureSize,i*e.allskyTextureSize,e.allskyTextureSize,e.allskyTextureSize,0,0,s.width,s.height),e.allskyTextures.push(s)}e.view.requestRedraw()},t.src=this.rootUrl+"/Norder3/Allsky."+this.imgFormat},e.prototype.redrawAllsky=function(t,e,i){if(!(this.view.curNorder>6)&&this.allskyTextures)for(var o,s,r,a=0,n=0,h=e.length;h>n;n++)if(o=e[n],r=o.ipix,this.allskyTextures[r]&&Tile.isImageOk(this.allskyTextures[r])){if(i>40){a=.02,s={x:(o[0].vx+o[2].vx)/2,y:(o[0].vy+o[2].vy)/2};for(var l=0;4>l;l++){var c={x:o[l].vx-s.x,y:o[l].vy-s.y};o[l].vx+=a*c.x,o[l].vy+=a*c.y}}this.drawOneTile(t,this.allskyTextures[r],o,this.allskyTextureSize)}},e.prototype.getColorMap=function(){return this.cm},e.prototype.redrawHighres=function(t,i,o){var s,r,a,n,h,l,c,u,d=(new Date).getTime(),p=d-this.lastUpdateDateNeededTiles>e.UPDATE_NEEDED_TILES_DELAY,f=o-1,v=[],g=[],m={},y=!1,C=[],w=[];if(p){var x=[(i[0][0].vx+i[0][1].vx)/2,(i[0][0].vy+i[0][1].vy)/2],S=i.sort(function(t,e){var i=[(t[0].vx+t[2].vx)/2,(t[0].vy+t[2].vy)/2],o=[(e[0].vx+e[2].vx)/2,(e[0].vy+e[2].vy)/2],s=(i[0]-x[0])*(i[0]-x[0])+(i[1]-x[1])*(i[1]-x[1]),r=(o[0]-x[0])*(o[0]-x[0])+(o[1]-x[1])*(o[1]-x[1]);return s-r});i=S}for(var M=0,b=i.length;b>M;M++)if(h=i[M],u=h.ipix,c=~~(u/4),n=this.getTileURL(f,c),p&&f>=3&&(a=this.tileBuffer.addTile(n),a&&w.push({img:a.img,url:n})),r=this.getTileURL(o,u),s=this.tileBuffer.getTile(r))Tile.isImageOk(s.img)?v.push({img:s.img,corners:h}):(y=!0,p&&!s.img.dlError&&C.push({img:s.img,url:r}),f>=3&&!m[c]&&(a=this.tileBuffer.getTile(n),a&&Tile.isImageOk(a.img)&&(l=this.view.getPositionsInView(c,f),l&&g.push({img:a.img,corners:l,ipix:c})),m[c]=1));else{if(y=!0,p){var s=this.tileBuffer.addTile(r);s&&C.push({img:s.img,url:r})}f>=3&&!m[c]&&(a=this.tileBuffer.getTile(n),a&&Tile.isImageOk(a.img)&&(l=this.view.getPositionsInView(c,f),l&&g.push({img:a.img,corners:l,ipix:c})),m[c]=1)}for(var M=0,b=g.length;b>M;M++)this.drawOneTile(t,g[M].img,g[M].corners,g[M].img.width);for(var M=0,b=v.length;b>M;M++){var T=null,P=v[M].img;P.fadingStart&&P.fadingEnd&&P.fadingEnd>d&&(T=.2+.8*((d-P.fadingStart)/(P.fadingEnd-P.fadingStart))),this.drawOneTile(t,P,v[M].corners,P.width,T)}if(p){for(var M=0,b=C.length;b>M;M++)this.view.downloader.requestDownload(C[M].img,C[M].url,this.useCors);for(var M=0,b=w.length;b>M;M++)this.view.downloader.requestDownload(w[M].img,w[M].url,this.useCors);this.lastUpdateDateNeededTiles=d}y&&this.view.requestRedrawAtDate(d+e.UPDATE_NEEDED_TILES_DELAY+10)},e.prototype.drawOneTile=function(e,i,o,s,r){var a=this.useCors?this.cm.apply(i):i;t(e,a,o[0].vx,o[0].vy,o[1].vx,o[1].vy,o[3].vx,o[3].vy,s-1,s-1,s-1,0,0,s-1,r),t(e,a,o[1].vx,o[1].vy,o[3].vx,o[3].vy,o[2].vx,o[2].vy,s-1,0,0,s-1,0,0,r)},e}(),HealpixGrid=function(){var t=function(){};return t.prototype.redraw=function(t,e,i,o){t.lineWidth=1,t.strokeStyle="rgb(150,150,220)",t.beginPath();for(var s,r=0,a=e.length;a>r;r++)s=e[r],ipix=s.ipix,t.moveTo(s[0].vx,s[0].vy),t.lineTo(s[1].vx,s[1].vy),t.lineTo(s[2].vx,s[2].vy);t.stroke(),t.strokeStyle="#FFDDDD",t.beginPath();for(var r=0,a=e.length;a>r;r++)s=e[r],ipix=s.ipix,t.strokeText(o+"/"+ipix,(s[0].vx+s[2].vx)/2,(s[0].vy+s[2].vy)/2);t.stroke()},t}(),Location=function(){return Location=function(t){this.div=$(t)},Location.prototype.update=function(t,e,i){var o=new Coo(t,e,7);i==CooFrameEnum.J2000?this.div.html(o.format("s/")):this.div.html(o.format("d/"))},Location}(),View=function(){function t(e,i,o,s,r){this.aladin=e,this.options=e.options,this.aladinDiv=this.aladin.aladinDiv,this.popup=new Popup(this.aladinDiv),this.createCanvases(),this.location=i,this.fovDiv=o,this.mustClearCatalog=!0,this.mustRedrawReticle=!0,this.mode=t.PAN,this.minFOV=this.maxFOV=null,this.healpixGrid=new HealpixGrid(this.imageCanvas),this.cooFrame=s?s:CooFrameEnum.GAL;var a,n;a=n=0,this.projectionMethod=ProjectionEnum.SIN,this.projection=new Projection(a,n),this.projection.setProjection(this.projectionMethod),this.zoomLevel=0,this.zoomFactor=this.computeZoomFactor(this.zoomLevel),this.viewCenter={lon:a,lat:n},r&&this.setZoom(r),this.imageSurvey=null,this.catalogs=[],this.overlays=[],this.tileBuffer=new TileBuffer,this.fixLayoutDimensions(),this.curNorder=1,this.realNorder=1,this.dragging=!1,this.dragx=null,this.dragy=null,this.needRedraw=!0,this.downloader=new Downloader(this),this.flagForceRedraw=!1,this.fadingLatestUpdate=null,this.dateRequestRedraw=null,init(this),this.resizeTimer=null;var h=this;$(window).resize(function(){clearTimeout(h.resizeTimer),h.resizeTimer=setTimeout(function(){h.fixLayoutDimensions(h)},100)})}function e(t,e,i,o){if(t.projection){var s,r=AladinUtils.viewToXy(e,i,t.width,t.height,t.largestDim,t.zoomFactor);try{s=t.projection.unproject(r.x,r.y)}catch(a){}s&&t.location.update(s.ra,s.dec,t.cooFrame,o)}}return t.PAN=0,t.SELECT=1,t.DRAW_SOURCES_WHILE_DRAGGING=!0,t.prototype.createCanvases=function(){var t=$(this.aladinDiv);t.find(".aladin-imageCanvas").remove(),t.find(".aladin-catalogCanvas").remove(),t.find(".aladin-reticleCanvas").remove(),this.imageCanvas=$("").appendTo(this.aladinDiv)[0],this.catalogCanvas=$("").appendTo(this.aladinDiv)[0],this.reticleCanvas=$("").appendTo(this.aladinDiv)[0]},t.prototype.fixLayoutDimensions=function(){Utils.cssScale=void 0,this.width=$(this.aladinDiv).width(),this.height=$(this.aladinDiv).height(),this.cx=this.width/2,this.cy=this.height/2,this.largestDim=Math.max(this.width,this.height),this.smallestDim=Math.min(this.width,this.height),this.ratio=this.largestDim/this.smallestDim,this.mouseMoveIncrement=160/this.largestDim,this.imageCtx=this.imageCanvas.getContext("2d"),this.catalogCtx=this.catalogCanvas.getContext("2d"),this.reticleCtx=this.reticleCanvas.getContext("2d"),this.imageCtx.canvas.width=this.width,this.catalogCtx.canvas.width=this.width,this.reticleCtx.canvas.width=this.width,this.imageCtx.canvas.height=this.height,this.catalogCtx.canvas.height=this.height,this.reticleCtx.canvas.height=this.height,this.computeNorder(),this.requestRedraw()},t.prototype.setMode=function(e){this.mode=e,this.mode==t.SELECT?this.setCursor("crosshair"):this.setCursor("default")},t.prototype.setCursor=function(t){this.reticleCanvas.style.cursor!=t&&(this.reticleCanvas.style.cursor=t)},t.prototype.getCanvasDataURL=function(){var t=document.createElement("canvas");t.width=this.width,t.height=this.height;var e=t.getContext("2d");return e.drawImage(this.imageCanvas,0,0),e.drawImage(this.catalogCanvas,0,0),e.drawImage(this.reticleCanvas,0,0),t.toDataURL("image/png")},computeFov=function(t){var e=doComputeFov(t,t.zoomFactor);return t.mouseMoveIncrement=e/t.imageCanvas.width,e},doComputeFov=function(t,e){if(1>t.zoomFactor)fov=180;else{var i=AladinUtils.viewToXy(0,t.cy,t.width,t.height,t.largestDim,e),o=t.projection.unproject(i.x,i.y),s=AladinUtils.viewToXy(t.imageCanvas.width-1,t.cy,t.width,t.height,t.largestDim,e),r=t.projection.unproject(s.x,s.y);fov=new Coo(o.ra,o.dec).distance(new Coo(r.ra,r.dec))}return fov},updateFovDiv=function(t){if(isNaN(t.fov))return t.fovDiv.html("FoV:"),void 0;var e;e=t.fov>1?Math.round(100*t.fov)/100+"°":60*t.fov>1?Math.round(100*60*t.fov)/100+"'":Math.round(100*3600*t.fov)/100+'"',t.fovDiv.html("FoV: "+e)},createListeners=function(i){var o=!1;"ontouchstart"in window&&(o=!0),onDblClick=function(t){var e=i.imageCanvas.relMouseCoords(t),o=AladinUtils.viewToXy(e.x,e.y,i.width,i.height,i.largestDim,i.zoomFactor);try{var s=i.projection.unproject(o.x,o.y)}catch(r){return}radec=[],radec=i.cooFrame==CooFrameEnum.GAL?CooConversion.GalacticToJ2000([s.ra,s.dec]):[s.ra,s.dec],i.pointTo(radec[0],radec[1])},o||$(i.reticleCanvas).dblclick(onDblClick),$(i.reticleCanvas).bind("mousedown touchstart",function(e){var o=i.imageCanvas.relMouseCoords(e);return e.originalEvent&&e.originalEvent.targetTouches?(i.dragx=e.originalEvent.targetTouches[0].clientX,i.dragy=e.originalEvent.targetTouches[0].clientY):(i.dragx=o.x,i.dragy=o.y),i.dragging=!0,i.mode==t.PAN?i.setCursor("move"):i.mode==t.SELECT&&(i.selectStartCoo={x:i.dragx,y:i.dragy}),!1}),$(i.reticleCanvas).bind("mouseup mouseout touchend",function(e){i.mode==t.SELECT&&i.dragging&&i.aladin.fire("selectend",i.getObjectsInBBox(i.selectStartCoo.x,i.selectStartCoo.y,i.dragx-i.selectStartCoo.x,i.dragy-i.selectStartCoo.y)),i.dragging&&(i.setCursor("default"),i.dragging=!1),i.mustClearCatalog=!0,i.mustRedrawReticle=!0,i.dragx=i.dragy=null;var o=i.imageCanvas.relMouseCoords(e),s=i.closestObjects(o.x,o.y,5);if(s){var r=s[0];r.marker?(i.popup.setTitle(r.popupTitle),i.popup.setText(r.popupDesc),i.popup.setSource(r),i.popup.show()):i.aladin.objClickedFunction&&i.aladin.objClickedFunction(r)}"mouseout"!==e.type&&i.refreshProgressiveCats(),i.requestRedraw()}),$(i.reticleCanvas).bind("mousemove touchmove",function(s){s.preventDefault();var r=i.imageCanvas.relMouseCoords(s);if(!i.dragging||o){if(e(i,r.x,r.y,!0),!i.dragging&&!i.mode==t.SELECT){var a=i.closestObjects(r.x,r.y,5);a?(i.setCursor("pointer"),i.aladin.objHoveredFunction&&i.aladin.objHoveredFunction(a[0])):i.setCursor("default")}if(!o)return}var n,h,l,c;if(s.originalEvent&&s.originalEvent.targetTouches){n=s.originalEvent.targetTouches[0].clientX-i.dragx,h=s.originalEvent.targetTouches[0].clientY-i.dragy;var u=AladinUtils.viewToXy(s.originalEvent.targetTouches[0].clientX,s.originalEvent.targetTouches[0].clientY,i.width,i.height,i.largestDim,i.zoomFactor),d=AladinUtils.viewToXy(i.dragx,i.dragy,i.width,i.height,i.largestDim,i.zoomFactor);l=i.projection.unproject(u.x,u.y),c=i.projection.unproject(d.x,d.y)}else{n=r.x-i.dragx,h=r.y-i.dragy;var u=AladinUtils.viewToXy(r.x,r.y,i.width,i.height,i.largestDim,i.zoomFactor),d=AladinUtils.viewToXy(i.dragx,i.dragy,i.width,i.height,i.largestDim,i.zoomFactor);l=i.projection.unproject(u.x,u.y),c=i.projection.unproject(d.x,d.y)}return s.originalEvent&&s.originalEvent.targetTouches?(i.dragx=s.originalEvent.targetTouches[0].clientX,i.dragy=s.originalEvent.targetTouches[0].clientY):(i.dragx=r.x,i.dragy=r.y),i.mode==t.SELECT?(i.requestRedraw(),void 0):(i.viewCenter.lon+=c.ra-l.ra,i.viewCenter.lat+=c.dec-l.dec,i.viewCenter.lat>90?i.viewCenter.lat=90:-90>i.viewCenter.lat&&(i.viewCenter.lat=-90),0>i.viewCenter.lon?i.viewCenter.lon=360+i.viewCenter.lon:i.viewCenter.lon>360&&(i.viewCenter.lon=i.viewCenter.lon%360),i.requestRedraw(),void 0)}),$(i.aladinDiv).onselectstart=function(){return!1},$(i.reticleCanvas).bind("mousewheel",function(t,e){t.preventDefault(),t.stopPropagation();var o=i.zoomLevel;return e>0?o+=1:o-=1,i.setZoomLevel(o),!1})},init=function(t){var e=new Stats;e.domElement.style.top="50px",$("#aladin-statsDiv").length>0&&$("#aladin-statsDiv")[0].appendChild(e.domElement),t.stats=e,createListeners(t),t.displayHpxGrid=!1,t.displaySurvey=!0,t.displayCatalog=!1,t.displayReticle=!0,t.fov=computeFov(t),updateFovDiv(t),t.redraw()},t.prototype.requestRedrawAtDate=function(t){this.dateRequestDraw=t},t.prototype.redraw=function(){var e=this.needRedraw;requestAnimFrame(this.redraw.bind(this));var i=(new Date).getTime();if(this.dateRequestDraw&&i>this.dateRequestDraw)this.dateRequestDraw=null;else if(!this.needRedraw){if(!this.flagForceRedraw)return;this.flagForceRedraw=!1}this.stats.update();var o=this.imageCtx;o.clearRect(0,0,this.imageCanvas.width,this.imageCanvas.height),this.projectionMethod==ProjectionEnum.SIN&&(this.fov>80?(o.fillStyle="rgb(0,0,0)",o.beginPath(),o.arc(this.cx,this.cy,this.cx*this.zoomFactor,0,2*Math.PI,!0),o.fill()):60>this.fov&&(o.fillStyle="rgb(0,0,0)",o.fillRect(0,0,this.imageCanvas.width,this.imageCanvas.height))),this.projection?this.projection.setCenter(this.viewCenter.lon,this.viewCenter.lat):this.projection=new Projection(this.viewCenter.lon,this.viewCenter.lat),this.projection.setProjection(this.projectionMethod);var s=this.getVisibleCells(3),r=null;this.curNorder>=3&&(r=3==this.curNorder?s:this.getVisibleCells(this.curNorder)),this.imageSurvey&&this.imageSurvey.isReady&&this.displaySurvey&&(this.imageSurvey.redrawAllsky(o,s,this.fov,this.curNorder),this.curNorder>=3&&this.imageSurvey.redrawHighres(o,r,this.curNorder)),this.displayHpxGrid&&(r&&this.curNorder>3?this.healpixGrid.redraw(o,r,this.fov,this.curNorder):this.healpixGrid.redraw(o,s,this.fov,3));var a=this.catalogCtx,n=!1;if(this.mustClearCatalog&&(a.clearRect(0,0,this.width,this.height),n=!0,this.mustClearCatalog=!1),this.catalogs&&this.catalogs.length>0&&this.displayCatalog&&(!this.dragging||t.DRAW_SOURCES_WHILE_DRAGGING)){n||(a.clearRect(0,0,this.width,this.height),n=!0);for(var h=0;this.catalogs.length>h;h++)this.catalogs[h].draw(a,this.projection,this.cooFrame,this.width,this.height,this.largestDim,this.zoomFactor,this.cooFrame)}var l=this.catalogCtx;if(this.overlays&&this.overlays.length>0&&(!this.dragging||t.DRAW_SOURCES_WHILE_DRAGGING)){n||(a.clearRect(0,0,this.width,this.height),n=!0);for(var h=0;this.overlays.length>h;h++)this.overlays[h].draw(l,this.projection,this.cooFrame,this.width,this.height,this.largestDim,this.zoomFactor,this.cooFrame)}this.mode==t.SELECT&&(mustRedrawReticle=!0);var c=this.reticleCtx;if((this.mustRedrawReticle||this.mode==t.SELECT)&&c.clearRect(0,0,this.width,this.height),this.displayReticle){if(!this.reticleCache){var u=document.createElement("canvas"),d=this.options.reticleSize;u.width=d,u.height=d;var p=u.getContext("2d");p.lineWidth=2,p.strokeStyle=this.options.reticleColor,p.beginPath(),p.moveTo(d/2,d/2+(d/2-1)),p.lineTo(d/2,d/2+2),p.moveTo(d/2,d/2-(d/2-1)),p.lineTo(d/2,d/2-2),p.moveTo(d/2+(d/2-1),d/2),p.lineTo(d/2+2,d/2),p.moveTo(d/2-(d/2-1),d/2),p.lineTo(d/2-2,d/2),p.stroke(),this.reticleCache=u}c.drawImage(this.reticleCache,this.width/2-this.reticleCache.width/2,this.height/2-this.reticleCache.height/2),this.mustRedrawReticle=!1}if(this.mode==t.SELECT&&this.dragging){c.fillStyle="rgba(100, 240, 110, 0.25)";var f=this.dragx-this.selectStartCoo.x,v=this.dragy-this.selectStartCoo.y;c.fillRect(this.selectStartCoo.x,this.selectStartCoo.y,f,v)}e==this.needRedraw&&(this.needRedraw=!1),this.dragging||this.updateObjectsLookup()},t.prototype.forceRedraw=function(){this.flagForceRedraw=!0},t.prototype.refreshProgressiveCats=function(){if(this.catalogs)for(var t=0;this.catalogs.length>t;t++)"progressivecat"==this.catalogs[t].type&&this.catalogs[t].loadNeededTiles()},t.prototype.getVisibleCells=function(t,e){!e&&this.imageSurvey&&(e=this.imageSurvey.cooFrame);var i,o=[],s=[],r=new SpatialVector,a=Math.pow(2,t),n=HealpixIndex.nside2Npix(a),h=null;if(this.fov>80){i=[];for(var l=0;n>l;l++)i.push(l)}else{var c=new HealpixIndex(a);c.init();var u=new SpatialVector,d=AladinUtils.viewToXy(this.cx,this.cy,this.width,this.height,this.largestDim,this.zoomFactor),p=this.projection.unproject(d.x,d.y),f=[];e&&e!=this.cooFrame?e==CooFrameEnum.J2000?f=CooConversion.GalacticToJ2000([p.ra,p.dec]):e==CooFrameEnum.GAL&&(f=CooConversion.J2000ToGalactic([p.ra,p.dec])):f=[p.ra,p.dec],u.set(f[0],f[1]);var v=.5*this.fov*this.ratio;v*=this.fov>60?1.6:this.fov>12?1.45:1.1,i=c.queryDisc(u,v*Math.PI/180,!0,!0);var g=Utils.radecToPolar(f[0],f[1]);h=c.ang2pix_nest(g.theta,g.phi),i.unshift(h)}for(var l,m,y,C=0,w=i.length;w>C;C++)if(l=i[C],!(l==h&&C>0)){var x=[];corners=HealpixCache.corners_nest(l,a);for(var S=0;4>S;S++){if(r.setXYZ(corners[S].x,corners[S].y,corners[S].z),e&&e!=this.cooFrame){if(e==CooFrameEnum.J2000){var p=CooConversion.J2000ToGalactic([r.ra(),r.dec()]);m=p[0],y=p[1]}else if(e==CooFrameEnum.GAL){var p=CooConversion.GalacticToJ2000([r.ra(),r.dec()]);m=p[0],y=p[1]}}else m=r.ra(),y=r.dec();s[S]=this.projection.project(m,y)}if(null!=s[0]&&null!=s[1]&&null!=s[2]&&null!=s[3]){for(var S=0;4>S;S++)x[S]=AladinUtils.xyToView(s[S].X,s[S].Y,this.width,this.height,this.largestDim,this.zoomFactor);if(!(0>x[0].vx&&0>x[1].vx&&0>x[2].vx&&0>x[3].vx||0>x[0].vy&&0>x[1].vy&&0>x[2].vy&&0>x[3].vy||x[0].vx>=this.width&&x[1].vx>=this.width&&x[2].vx>=this.width&&x[3].vx>=this.width||x[0].vy>=this.height&&x[1].vy>=this.height&&x[2].vy>=this.height&&x[3].vy>=this.height)){if(this.projection.PROJECTION==ProjectionEnum.AITOFF){var M=x[0].vx-x[2].vx,b=x[0].vy-x[2].vy,T=Math.sqrt(M*M+b*b);if(T>this.largestDim/5)continue;if(M=x[1].vx-x[3].vx,b=x[1].vy-x[3].vy,T=Math.sqrt(M*M+b*b),T>this.largestDim/5)continue}x.ipix=l,o.push(x)}}}return o},t.prototype.getPositionsInView=function(t,e){for(var i,o,s=[],r=new SpatialVector,a=Math.pow(2,e),n=[],h=HealpixCache.corners_nest(t,a),l=0;4>l;l++){if(r.setXYZ(h[l].x,h[l].y,h[l].z),this.imageSurvey&&this.imageSurvey.cooFrame!=this.cooFrame){if(this.imageSurvey.cooFrame==CooFrameEnum.J2000){var c=CooConversion.J2000ToGalactic([r.ra(),r.dec()]);i=c[0],o=c[1]}else if(this.imageSurvey.cooFrame==CooFrameEnum.GAL){var c=CooConversion.GalacticToJ2000([r.ra(),r.dec()]);i=c[0],o=c[1]}}else i=r.ra(),o=r.dec();s[l]=this.projection.project(i,o)}if(null==s[0]||null==s[1]||null==s[2]||null==s[3])return null;for(var l=0;4>l;l++)n[l]=AladinUtils.xyToView(s[l].X,s[l].Y,this.width,this.height,this.largestDim,this.zoomFactor);return n},t.prototype.computeZoomFactor=function(t){return t>0?AladinUtils.getZoomFactorForAngle(180/Math.pow(1.15,t),this.projectionMethod):1+.1*t},t.prototype.setZoom=function(t){if(!(0>t||t>180)){var e=Math.log(180/t)/Math.log(1.15);this.setZoomLevel(e)}},t.prototype.setZoomLevel=function(t){if(this.minFOV||this.maxFOV){var e=doComputeFov(this,this.computeZoomFactor(Math.max(-2,t)));if(this.maxFOV&&e>this.maxFOV||this.minFOV&&this.minFOV>e)return}if(this.zoomLevel=Math.max(-2,t),this.zoomFactor=this.computeZoomFactor(this.zoomLevel),this.fov=computeFov(this),updateFovDiv(this),this.computeNorder(),this.forceRedraw(),this.requestRedraw(),!this.debounceProgCatOnZoom){var i=this;this.debounceProgCatOnZoom=Utils.debounce(function(){i.refreshProgressiveCats()},300)}this.debounceProgCatOnZoom()},t.prototype.computeNorder=function(){var t=this.fov/this.largestDim,e=512,i=HealpixIndex.calculateNSide(3600*e*t),o=Math.log(i)/Math.log(2);o=Math.max(o,1),this.realNorder=o,50>=this.fov&&2>=o&&(o=3),this.imageSurvey&&2>=o&&this.imageSurvey.minOrder>2&&(o=this.imageSurvey.minOrder),this.imageSurvey&&o>this.imageSurvey.maxOrder&&(o=this.imageSurvey.maxOrder),o>HealpixIndex.ORDER_MAX&&(o=HealpixIndex.ORDER_MAX),this.curNorder=o},t.prototype.untaintCanvases=function(){this.createCanvases(),createListeners(this),this.fixLayoutDimensions()},t.prototype.setImageSurvey=function(t){if(t){$.support.cors&&this.imageSurvey&&!this.imageSurvey.useCors&&this.untaintCanvases();var e;"string"==typeof t?(e=HpxImageSurvey.getSurveyFromId(t),e||(e=HpxImageSurvey.getSurveyFromId(HpxImageSurvey.DEFAULT_SURVEY_ID))):e=t,e.isReady=!1,this.imageSurvey=e;var i=this;e.init(this,function(){i.computeNorder(),e.isReady=!0,i.requestRedraw(),i.updateObjectsLookup()})}},t.prototype.requestRedraw=function(){this.needRedraw=!0},t.prototype.changeProjection=function(t){this.projectionMethod=t,this.requestRedraw()},t.prototype.changeFrame=function(t){if(this.cooFrame=t,this.cooFrame==CooFrameEnum.GAL){var e=CooConversion.J2000ToGalactic([this.viewCenter.lon,this.viewCenter.lat]);this.viewCenter.lon=e[0],this.viewCenter.lat=e[1]}else if(this.cooFrame==CooFrameEnum.J2000){var i=CooConversion.GalacticToJ2000([this.viewCenter.lon,this.viewCenter.lat]);this.viewCenter.lon=i[0],this.viewCenter.lat=i[1]}this.requestRedraw()},t.prototype.showHealpixGrid=function(t){this.displayHpxGrid=t,this.requestRedraw()},t.prototype.showSurvey=function(t){this.displaySurvey=t,this.requestRedraw()},t.prototype.showCatalog=function(t){this.displayCatalog=t,this.displayCatalog||(this.mustClearCatalog=!0),this.requestRedraw()},t.prototype.showReticle=function(t){this.displayReticle=t,this.mustRedrawReticle=!0,this.requestRedraw()},t.prototype.pointTo=function(t,e){if(t=parseFloat(t),e=parseFloat(e),!isNaN(t)&&!isNaN(e)){if(this.cooFrame==CooFrameEnum.J2000)this.viewCenter.lon=t,this.viewCenter.lat=e;else if(this.cooFrame==CooFrameEnum.GAL){var i=CooConversion.J2000ToGalactic([t,e]);this.viewCenter.lon=i[0],this.viewCenter.lat=i[1]}this.forceRedraw(),this.requestRedraw();var o=this;setTimeout(function(){o.refreshProgressiveCats()},1e3)}},t.prototype.makeUniqLayerName=function(t){if(!this.layerNameExists(t))return t;for(var e=1;;++e){var i=t+"_"+e;if(!this.layerNameExists(i))return i}},t.prototype.layerNameExists=function(t){for(var e=this.catalogs,i=0;e.length>i;i++)if(t==e[i].name)return!0;return!1},t.prototype.removeLayers=function(){this.catalogs=[],this.overlays=[],this.requestRedraw()},t.prototype.addCatalog=function(t){t.name=this.makeUniqLayerName(t.name),this.catalogs.push(t),"catalog"==t.type?t.setView(this):"progressivecat"==t.type&&t.init(this)},t.prototype.addOverlay=function(t){this.overlays.push(t),t.setView(this)},t.prototype.getObjectsInBBox=function(t,e,i,o){0>i&&(t+=i,i=-i),0>o&&(e+=o,o=-o);var s,r,a,n=[];if(this.catalogs)for(var h=0;this.catalogs.length>h;h++)if(s=this.catalogs[h],s.isShowing){r=s.getSources();for(var l=0;r.length>l;l++)a=r[l],a.isShowing&&a.x&&a.y&&a.x>=t&&t+i>=a.x&&a.y>=e&&e+o>=a.y&&n.push(a)}return n},t.prototype.updateObjectsLookup=function(){this.objLookup=[];var t,e,i,o,s;if(this.catalogs)for(var r=0;this.catalogs.length>r;r++)if(t=this.catalogs[r],t.isShowing){e=t.getSources();for(var a=0;e.length>a;a++)i=e[a],i.isShowing&&i.x&&i.y&&(o=i.x,s=i.y,this.objLookup[o]||(this.objLookup[o]=[]),this.objLookup[o][s]||(this.objLookup[o][s]=[]),this.objLookup[o][s].push(i))}},t.prototype.closestObjects=function(t,e,i){if(!this.objLookup)return null;for(var o,s,r=0;i>=r;r++){o=s=null;for(var a=-i;i>=a;a++)if(this.objLookup[t+a])for(var n=-i;i>=n;n++)if(this.objLookup[t+a][e+n])if(o){var h=a*a+n*n;s>h&&(s=h,o=this.objLookup[t+a][e+n])}else o=this.objLookup[t+a][e+n];if(o)return o}return null},t}(),/** @license CDS - Centre de Données astronomiques de Strasbourg , 2013*/ +Aladin=function(){var t=function(e,i){HealpixCache.init();var o=this;$.ajax({url:"http://aladin.u-strasbg.fr/java/nph-aladin.pl",data:{frame:"aladinLiteDic"},method:"GET",dataType:"jsonp",success:function(t){for(var e={},i=0;t.length>i;i++)e[t[i].id]=!0;for(var i=0;HpxImageSurvey.SURVEYS.length>i;i++)e[HpxImageSurvey.SURVEYS[i].id]||t.push(HpxImageSurvey.SURVEYS[i]);HpxImageSurvey.SURVEYS=t},error:function(){}}),void 0===i&&(i=this.getOptionsFromQueryString()),i=i||{};var s={};for(var r in t.DEFAULT_OPTIONS)s[r]=void 0!==i[r]?i[r]:t.DEFAULT_OPTIONS[r];for(var r in i)void 0===t.DEFAULT_OPTIONS[r]&&(s[r]=i[r]);this.options=s,this.aladinDiv=e,$(e).addClass("aladin-container");var a=CooFrameEnum.fromString(s.cooFrame,CooFrameEnum.J2000),n=a==CooFrameEnum.J2000,h=$('
'+(s.showFrame?'":"")+'
').appendTo(e),l=$('
').appendTo(e);s.showZoomControl&&$('').appendTo(e),s.showFullscreenControl&&$('
').appendTo(e),this.fullScreenBtn=$(e).find(".aladin-fullscreenControl"),this.fullScreenBtn.click(function(){o.toggleFullscreen()}),$("
").appendTo(e),this.boxes=[];var c=new Location(h.find(".aladin-location-text"));if(this.view=new View(this,c,l,a,s.zoom),s.showLayersControl){var u=$('
');u.appendTo(e);var d=$('
');d.appendTo(e),this.boxes.push(d),u.click(function(){return o.hideBoxes(),o.showLayerBox(),!1})}if(s.showGotoControl){var u=$('
');u.appendTo(e);var p=$('
×
Go to:
');p.appendTo(e),this.boxes.push(p);var f=p.find(".aladin-target-form input");f.on("paste keydown",function(){$(this).removeClass("aladin-unknownObject")}),u.click(function(){return o.hideBoxes(),f.val(""),f.removeClass("aladin-unknownObject"),p.show(),f.focus(),!1}),p.find(".aladin-closeBtn").click(function(){return o.hideBoxes(),!1})}if(s.showShareControl){var u=$('
');u.appendTo(e);var v=$('
×
Share
');v.appendTo(e),this.boxes.push(v),u.click(function(){return o.hideBoxes(),v.show(),!1}),v.find(".aladin-closeBtn").click(function(){return o.hideBoxes(),!1})}if(this.gotoObject(s.target),s.log){var g=i;g.version=t.VERSION,Logger.log("startup",g)}if(this.showReticle(s.showReticle),s.catalogUrls)for(var m=0,y=s.catalogUrls.length;y>m;m++)this.createCatalogFromVOTable(s.catalogUrls[m]);this.setImageSurvey(s.survey),this.view.showCatalog(s.showCatalog);var C=this;$(e).find(".aladin-frameChoice").change(function(){C.setFrame($(this).val())}),$("#projectionChoice").change(function(){C.setProjection($(this).val())}),$(e).find(".aladin-target-form").submit(function(){return C.gotoObject($(this).find("input").val(),function(){$(e).find(".aladin-target-form input").addClass("aladin-unknownObject")}),!1});var w=$(e).find(".zoomPlus");w.click(function(){return C.increaseZoom(),!1}),w.bind("mousedown",function(t){t.preventDefault()});var x=$(e).find(".zoomMinus");x.click(function(){return C.decreaseZoom(),!1}),x.bind("mousedown",function(t){t.preventDefault()}),s.fullScreen&&window.setTimeout(function(){o.toggleFullscreen()},1e3)};return t.VERSION="0.5.1",t.JSONP_PROXY="http://alasky.u-strasbg.fr/cgi/JSONProxy",t.DEFAULT_OPTIONS={target:"0 +0",cooFrame:"J2000",survey:"P/DSS2/color",zoom:60,showReticle:!0,showZoomControl:!0,showFullscreenControl:!0,showLayersControl:!0,showGotoControl:!0,showShareControl:!1,showCatalog:!0,showFrame:!0,fullScreen:!1,reticleColor:"rgb(178, 50, 178)",reticleSize:22,log:!0},t.prototype.toggleFullscreen=function(){this.fullScreenBtn.toggleClass("aladin-maximize aladin-restore");var t=this.fullScreenBtn.hasClass("aladin-restore");this.fullScreenBtn.attr("title",t?"Restore original size":"Full screen"),$(this.aladinDiv).toggleClass("aladin-fullscreen"),this.view.fixLayoutDimensions()},t.prototype.updateSurveysDropdownList=function(t){t=t.sort(function(t,e){return t.order?t.order&&t.order>e.order?1:-1:t.id>e.id});var e=$(this.aladinDiv).find(".aladin-surveySelection");e.empty();for(var i=0;t.length>i;i++){var o=this.view.imageSurvey.id==t[i].id;e.append($("