/public/js/lib/raphael.js

https://gitlab.com/webster5361/UserFrosting · JavaScript · 8111 lines · 5696 code · 93 blank · 2322 comment · 1780 complexity · c751a1cbe6ccf9aaa97e379046e21555 MD5 · raw file

Large files are truncated click here to view the full file

  1. // ┌────────────────────────────────────────────────────────────────────┐ \\
  2. // │ Raphaël 2.1.1 - JavaScript Vector Library │ \\
  3. // ├────────────────────────────────────────────────────────────────────┤ \\
  4. // │ Copyright © 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com) │ \\
  5. // │ Copyright © 2008-2012 Sencha Labs (http://sencha.com) │ \\
  6. // ├────────────────────────────────────────────────────────────────────┤ \\
  7. // │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\
  8. // └────────────────────────────────────────────────────────────────────┘ \\
  9. // Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
  10. //
  11. // Licensed under the Apache License, Version 2.0 (the "License");
  12. // you may not use this file except in compliance with the License.
  13. // You may obtain a copy of the License at
  14. //
  15. // http://www.apache.org/licenses/LICENSE-2.0
  16. //
  17. // Unless required by applicable law or agreed to in writing, software
  18. // distributed under the License is distributed on an "AS IS" BASIS,
  19. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. // See the License for the specific language governing permissions and
  21. // limitations under the License.
  22. // ┌────────────────────────────────────────────────────────────┐ \\
  23. // │ Eve 0.4.2 - JavaScript Events Library │ \\
  24. // ├────────────────────────────────────────────────────────────┤ \\
  25. // │ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\
  26. // └────────────────────────────────────────────────────────────┘ \\
  27. (function (glob) {
  28. var version = "0.4.2",
  29. has = "hasOwnProperty",
  30. separator = /[\.\/]/,
  31. wildcard = "*",
  32. fun = function () {},
  33. numsort = function (a, b) {
  34. return a - b;
  35. },
  36. current_event,
  37. stop,
  38. events = {n: {}},
  39. /*\
  40. * eve
  41. [ method ]
  42. * Fires event with given `name`, given scope and other parameters.
  43. > Arguments
  44. - name (string) name of the *event*, dot (`.`) or slash (`/`) separated
  45. - scope (object) context for the event handlers
  46. - varargs (...) the rest of arguments will be sent to event handlers
  47. = (object) array of returned values from the listeners
  48. \*/
  49. eve = function (name, scope) {
  50. name = String(name);
  51. var e = events,
  52. oldstop = stop,
  53. args = Array.prototype.slice.call(arguments, 2),
  54. listeners = eve.listeners(name),
  55. z = 0,
  56. f = false,
  57. l,
  58. indexed = [],
  59. queue = {},
  60. out = [],
  61. ce = current_event,
  62. errors = [];
  63. current_event = name;
  64. stop = 0;
  65. for (var i = 0, ii = listeners.length; i < ii; i++) if ("zIndex" in listeners[i]) {
  66. indexed.push(listeners[i].zIndex);
  67. if (listeners[i].zIndex < 0) {
  68. queue[listeners[i].zIndex] = listeners[i];
  69. }
  70. }
  71. indexed.sort(numsort);
  72. while (indexed[z] < 0) {
  73. l = queue[indexed[z++]];
  74. out.push(l.apply(scope, args));
  75. if (stop) {
  76. stop = oldstop;
  77. return out;
  78. }
  79. }
  80. for (i = 0; i < ii; i++) {
  81. l = listeners[i];
  82. if ("zIndex" in l) {
  83. if (l.zIndex == indexed[z]) {
  84. out.push(l.apply(scope, args));
  85. if (stop) {
  86. break;
  87. }
  88. do {
  89. z++;
  90. l = queue[indexed[z]];
  91. l && out.push(l.apply(scope, args));
  92. if (stop) {
  93. break;
  94. }
  95. } while (l)
  96. } else {
  97. queue[l.zIndex] = l;
  98. }
  99. } else {
  100. out.push(l.apply(scope, args));
  101. if (stop) {
  102. break;
  103. }
  104. }
  105. }
  106. stop = oldstop;
  107. current_event = ce;
  108. return out.length ? out : null;
  109. };
  110. // Undocumented. Debug only.
  111. eve._events = events;
  112. /*\
  113. * eve.listeners
  114. [ method ]
  115. * Internal method which gives you array of all event handlers that will be triggered by the given `name`.
  116. > Arguments
  117. - name (string) name of the event, dot (`.`) or slash (`/`) separated
  118. = (array) array of event handlers
  119. \*/
  120. eve.listeners = function (name) {
  121. var names = name.split(separator),
  122. e = events,
  123. item,
  124. items,
  125. k,
  126. i,
  127. ii,
  128. j,
  129. jj,
  130. nes,
  131. es = [e],
  132. out = [];
  133. for (i = 0, ii = names.length; i < ii; i++) {
  134. nes = [];
  135. for (j = 0, jj = es.length; j < jj; j++) {
  136. e = es[j].n;
  137. items = [e[names[i]], e[wildcard]];
  138. k = 2;
  139. while (k--) {
  140. item = items[k];
  141. if (item) {
  142. nes.push(item);
  143. out = out.concat(item.f || []);
  144. }
  145. }
  146. }
  147. es = nes;
  148. }
  149. return out;
  150. };
  151. /*\
  152. * eve.on
  153. [ method ]
  154. **
  155. * Binds given event handler with a given name. You can use wildcards “`*`” for the names:
  156. | eve.on("*.under.*", f);
  157. | eve("mouse.under.floor"); // triggers f
  158. * Use @eve to trigger the listener.
  159. **
  160. > Arguments
  161. **
  162. - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
  163. - f (function) event handler function
  164. **
  165. = (function) returned function accepts a single numeric parameter that represents z-index of the handler. It is an optional feature and only used when you need to ensure that some subset of handlers will be invoked in a given order, despite of the order of assignment.
  166. > Example:
  167. | eve.on("mouse", eatIt)(2);
  168. | eve.on("mouse", scream);
  169. | eve.on("mouse", catchIt)(1);
  170. * This will ensure that `catchIt()` function will be called before `eatIt()`.
  171. *
  172. * If you want to put your handler before non-indexed handlers, specify a negative value.
  173. * Note: I assume most of the time you don’t need to worry about z-index, but it’s nice to have this feature “just in case”.
  174. \*/
  175. eve.on = function (name, f) {
  176. name = String(name);
  177. if (typeof f != "function") {
  178. return function () {};
  179. }
  180. var names = name.split(separator),
  181. e = events;
  182. for (var i = 0, ii = names.length; i < ii; i++) {
  183. e = e.n;
  184. e = e.hasOwnProperty(names[i]) && e[names[i]] || (e[names[i]] = {n: {}});
  185. }
  186. e.f = e.f || [];
  187. for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) {
  188. return fun;
  189. }
  190. e.f.push(f);
  191. return function (zIndex) {
  192. if (+zIndex == +zIndex) {
  193. f.zIndex = +zIndex;
  194. }
  195. };
  196. };
  197. /*\
  198. * eve.f
  199. [ method ]
  200. **
  201. * Returns function that will fire given event with optional arguments.
  202. * Arguments that will be passed to the result function will be also
  203. * concated to the list of final arguments.
  204. | el.onclick = eve.f("click", 1, 2);
  205. | eve.on("click", function (a, b, c) {
  206. | console.log(a, b, c); // 1, 2, [event object]
  207. | });
  208. > Arguments
  209. - event (string) event name
  210. - varargs (…) and any other arguments
  211. = (function) possible event handler function
  212. \*/
  213. eve.f = function (event) {
  214. var attrs = [].slice.call(arguments, 1);
  215. return function () {
  216. eve.apply(null, [event, null].concat(attrs).concat([].slice.call(arguments, 0)));
  217. };
  218. };
  219. /*\
  220. * eve.stop
  221. [ method ]
  222. **
  223. * Is used inside an event handler to stop the event, preventing any subsequent listeners from firing.
  224. \*/
  225. eve.stop = function () {
  226. stop = 1;
  227. };
  228. /*\
  229. * eve.nt
  230. [ method ]
  231. **
  232. * Could be used inside event handler to figure out actual name of the event.
  233. **
  234. > Arguments
  235. **
  236. - subname (string) #optional subname of the event
  237. **
  238. = (string) name of the event, if `subname` is not specified
  239. * or
  240. = (boolean) `true`, if current event’s name contains `subname`
  241. \*/
  242. eve.nt = function (subname) {
  243. if (subname) {
  244. return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(current_event);
  245. }
  246. return current_event;
  247. };
  248. /*\
  249. * eve.nts
  250. [ method ]
  251. **
  252. * Could be used inside event handler to figure out actual name of the event.
  253. **
  254. **
  255. = (array) names of the event
  256. \*/
  257. eve.nts = function () {
  258. return current_event.split(separator);
  259. };
  260. /*\
  261. * eve.off
  262. [ method ]
  263. **
  264. * Removes given function from the list of event listeners assigned to given name.
  265. * If no arguments specified all the events will be cleared.
  266. **
  267. > Arguments
  268. **
  269. - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
  270. - f (function) event handler function
  271. \*/
  272. /*\
  273. * eve.unbind
  274. [ method ]
  275. **
  276. * See @eve.off
  277. \*/
  278. eve.off = eve.unbind = function (name, f) {
  279. if (!name) {
  280. eve._events = events = {n: {}};
  281. return;
  282. }
  283. var names = name.split(separator),
  284. e,
  285. key,
  286. splice,
  287. i, ii, j, jj,
  288. cur = [events];
  289. for (i = 0, ii = names.length; i < ii; i++) {
  290. for (j = 0; j < cur.length; j += splice.length - 2) {
  291. splice = [j, 1];
  292. e = cur[j].n;
  293. if (names[i] != wildcard) {
  294. if (e[names[i]]) {
  295. splice.push(e[names[i]]);
  296. }
  297. } else {
  298. for (key in e) if (e[has](key)) {
  299. splice.push(e[key]);
  300. }
  301. }
  302. cur.splice.apply(cur, splice);
  303. }
  304. }
  305. for (i = 0, ii = cur.length; i < ii; i++) {
  306. e = cur[i];
  307. while (e.n) {
  308. if (f) {
  309. if (e.f) {
  310. for (j = 0, jj = e.f.length; j < jj; j++) if (e.f[j] == f) {
  311. e.f.splice(j, 1);
  312. break;
  313. }
  314. !e.f.length && delete e.f;
  315. }
  316. for (key in e.n) if (e.n[has](key) && e.n[key].f) {
  317. var funcs = e.n[key].f;
  318. for (j = 0, jj = funcs.length; j < jj; j++) if (funcs[j] == f) {
  319. funcs.splice(j, 1);
  320. break;
  321. }
  322. !funcs.length && delete e.n[key].f;
  323. }
  324. } else {
  325. delete e.f;
  326. for (key in e.n) if (e.n[has](key) && e.n[key].f) {
  327. delete e.n[key].f;
  328. }
  329. }
  330. e = e.n;
  331. }
  332. }
  333. };
  334. /*\
  335. * eve.once
  336. [ method ]
  337. **
  338. * Binds given event handler with a given name to only run once then unbind itself.
  339. | eve.once("login", f);
  340. | eve("login"); // triggers f
  341. | eve("login"); // no listeners
  342. * Use @eve to trigger the listener.
  343. **
  344. > Arguments
  345. **
  346. - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards
  347. - f (function) event handler function
  348. **
  349. = (function) same return function as @eve.on
  350. \*/
  351. eve.once = function (name, f) {
  352. var f2 = function () {
  353. eve.unbind(name, f2);
  354. return f.apply(this, arguments);
  355. };
  356. return eve.on(name, f2);
  357. };
  358. /*\
  359. * eve.version
  360. [ property (string) ]
  361. **
  362. * Current version of the library.
  363. \*/
  364. eve.version = version;
  365. eve.toString = function () {
  366. return "You are running Eve " + version;
  367. };
  368. (typeof module != "undefined" && module.exports) ? (module.exports = eve) : (typeof define != "undefined" ? (define("eve", [], function() { return eve; })) : (glob.eve = eve));
  369. })(this);
  370. // ┌─────────────────────────────────────────────────────────────────────┐ \\
  371. // │ "Raphaël 2.1.0" - JavaScript Vector Library │ \\
  372. // ├─────────────────────────────────────────────────────────────────────┤ \\
  373. // │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\
  374. // │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\
  375. // │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\
  376. // └─────────────────────────────────────────────────────────────────────┘ \\
  377. (function (glob, factory) {
  378. // AMD support
  379. if (typeof define === "function" && define.amd) {
  380. // Define as an anonymous module
  381. define(["eve"], function( eve ) {
  382. return factory(glob, eve);
  383. });
  384. } else {
  385. // Browser globals (glob is window)
  386. // Raphael adds itself to window
  387. factory(glob, glob.eve);
  388. }
  389. }(this, function (window, eve) {
  390. /*\
  391. * Raphael
  392. [ method ]
  393. **
  394. * Creates a canvas object on which to draw.
  395. * You must do this first, as all future calls to drawing methods
  396. * from this instance will be bound to this canvas.
  397. > Parameters
  398. **
  399. - container (HTMLElement|string) DOM element or its ID which is going to be a parent for drawing surface
  400. - width (number)
  401. - height (number)
  402. - callback (function) #optional callback function which is going to be executed in the context of newly created paper
  403. * or
  404. - x (number)
  405. - y (number)
  406. - width (number)
  407. - height (number)
  408. - callback (function) #optional callback function which is going to be executed in the context of newly created paper
  409. * or
  410. - all (array) (first 3 or 4 elements in the array are equal to [containerID, width, height] or [x, y, width, height]. The rest are element descriptions in format {type: type, <attributes>}). See @Paper.add.
  411. - callback (function) #optional callback function which is going to be executed in the context of newly created paper
  412. * or
  413. - onReadyCallback (function) function that is going to be called on DOM ready event. You can also subscribe to this event via Eve’s “DOMLoad” event. In this case method returns `undefined`.
  414. = (object) @Paper
  415. > Usage
  416. | // Each of the following examples create a canvas
  417. | // that is 320px wide by 200px high.
  418. | // Canvas is created at the viewport’s 10,50 coordinate.
  419. | var paper = Raphael(10, 50, 320, 200);
  420. | // Canvas is created at the top left corner of the #notepad element
  421. | // (or its top right corner in dir="rtl" elements)
  422. | var paper = Raphael(document.getElementById("notepad"), 320, 200);
  423. | // Same as above
  424. | var paper = Raphael("notepad", 320, 200);
  425. | // Image dump
  426. | var set = Raphael(["notepad", 320, 200, {
  427. | type: "rect",
  428. | x: 10,
  429. | y: 10,
  430. | width: 25,
  431. | height: 25,
  432. | stroke: "#f00"
  433. | }, {
  434. | type: "text",
  435. | x: 30,
  436. | y: 40,
  437. | text: "Dump"
  438. | }]);
  439. \*/
  440. function R(first) {
  441. if (R.is(first, "function")) {
  442. return loaded ? first() : eve.on("raphael.DOMload", first);
  443. } else if (R.is(first, array)) {
  444. return R._engine.create[apply](R, first.splice(0, 3 + R.is(first[0], nu))).add(first);
  445. } else {
  446. var args = Array.prototype.slice.call(arguments, 0);
  447. if (R.is(args[args.length - 1], "function")) {
  448. var f = args.pop();
  449. return loaded ? f.call(R._engine.create[apply](R, args)) : eve.on("raphael.DOMload", function () {
  450. f.call(R._engine.create[apply](R, args));
  451. });
  452. } else {
  453. return R._engine.create[apply](R, arguments);
  454. }
  455. }
  456. }
  457. R.version = "2.1.0";
  458. R.eve = eve;
  459. var loaded,
  460. separator = /[, ]+/,
  461. elements = {circle: 1, rect: 1, path: 1, ellipse: 1, text: 1, image: 1},
  462. formatrg = /\{(\d+)\}/g,
  463. proto = "prototype",
  464. has = "hasOwnProperty",
  465. g = {
  466. doc: document,
  467. win: window
  468. },
  469. oldRaphael = {
  470. was: Object.prototype[has].call(g.win, "Raphael"),
  471. is: g.win.Raphael
  472. },
  473. Paper = function () {
  474. /*\
  475. * Paper.ca
  476. [ property (object) ]
  477. **
  478. * Shortcut for @Paper.customAttributes
  479. \*/
  480. /*\
  481. * Paper.customAttributes
  482. [ property (object) ]
  483. **
  484. * If you have a set of attributes that you would like to represent
  485. * as a function of some number you can do it easily with custom attributes:
  486. > Usage
  487. | paper.customAttributes.hue = function (num) {
  488. | num = num % 1;
  489. | return {fill: "hsb(" + num + ", 0.75, 1)"};
  490. | };
  491. | // Custom attribute “hue” will change fill
  492. | // to be given hue with fixed saturation and brightness.
  493. | // Now you can use it like this:
  494. | var c = paper.circle(10, 10, 10).attr({hue: .45});
  495. | // or even like this:
  496. | c.animate({hue: 1}, 1e3);
  497. |
  498. | // You could also create custom attribute
  499. | // with multiple parameters:
  500. | paper.customAttributes.hsb = function (h, s, b) {
  501. | return {fill: "hsb(" + [h, s, b].join(",") + ")"};
  502. | };
  503. | c.attr({hsb: "0.5 .8 1"});
  504. | c.animate({hsb: [1, 0, 0.5]}, 1e3);
  505. \*/
  506. this.ca = this.customAttributes = {};
  507. },
  508. paperproto,
  509. appendChild = "appendChild",
  510. apply = "apply",
  511. concat = "concat",
  512. supportsTouch = ('ontouchstart' in g.win) || g.win.DocumentTouch && g.doc instanceof DocumentTouch, //taken from Modernizr touch test
  513. E = "",
  514. S = " ",
  515. Str = String,
  516. split = "split",
  517. events = "click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel"[split](S),
  518. touchMap = {
  519. mousedown: "touchstart",
  520. mousemove: "touchmove",
  521. mouseup: "touchend"
  522. },
  523. lowerCase = Str.prototype.toLowerCase,
  524. math = Math,
  525. mmax = math.max,
  526. mmin = math.min,
  527. abs = math.abs,
  528. pow = math.pow,
  529. PI = math.PI,
  530. nu = "number",
  531. string = "string",
  532. array = "array",
  533. toString = "toString",
  534. fillString = "fill",
  535. objectToString = Object.prototype.toString,
  536. paper = {},
  537. push = "push",
  538. ISURL = R._ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i,
  539. colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,
  540. isnan = {"NaN": 1, "Infinity": 1, "-Infinity": 1},
  541. bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
  542. round = math.round,
  543. setAttribute = "setAttribute",
  544. toFloat = parseFloat,
  545. toInt = parseInt,
  546. upperCase = Str.prototype.toUpperCase,
  547. availableAttrs = R._availableAttrs = {
  548. "arrow-end": "none",
  549. "arrow-start": "none",
  550. blur: 0,
  551. "clip-rect": "0 0 1e9 1e9",
  552. cursor: "default",
  553. cx: 0,
  554. cy: 0,
  555. fill: "#fff",
  556. "fill-opacity": 1,
  557. font: '10px "Arial"',
  558. "font-family": '"Arial"',
  559. "font-size": "10",
  560. "font-style": "normal",
  561. "font-weight": 400,
  562. gradient: 0,
  563. height: 0,
  564. href: "http://raphaeljs.com/",
  565. "letter-spacing": 0,
  566. opacity: 1,
  567. path: "M0,0",
  568. r: 0,
  569. rx: 0,
  570. ry: 0,
  571. src: "",
  572. stroke: "#000",
  573. "stroke-dasharray": "",
  574. "stroke-linecap": "butt",
  575. "stroke-linejoin": "butt",
  576. "stroke-miterlimit": 0,
  577. "stroke-opacity": 1,
  578. "stroke-width": 1,
  579. target: "_blank",
  580. "text-anchor": "middle",
  581. title: "Raphael",
  582. transform: "",
  583. width: 0,
  584. x: 0,
  585. y: 0
  586. },
  587. availableAnimAttrs = R._availableAnimAttrs = {
  588. blur: nu,
  589. "clip-rect": "csv",
  590. cx: nu,
  591. cy: nu,
  592. fill: "colour",
  593. "fill-opacity": nu,
  594. "font-size": nu,
  595. height: nu,
  596. opacity: nu,
  597. path: "path",
  598. r: nu,
  599. rx: nu,
  600. ry: nu,
  601. stroke: "colour",
  602. "stroke-opacity": nu,
  603. "stroke-width": nu,
  604. transform: "transform",
  605. width: nu,
  606. x: nu,
  607. y: nu
  608. },
  609. whitespace = /[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]/g,
  610. commaSpaces = /[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/,
  611. hsrg = {hs: 1, rg: 1},
  612. p2s = /,?([achlmqrstvxz]),?/gi,
  613. pathCommand = /([achlmrqstvz])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/ig,
  614. tCommand = /([rstm])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/ig,
  615. pathValues = /(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/ig,
  616. radial_gradient = R._radial_gradient = /^r(?:\(([^,]+?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*([^\)]+?)\))?/,
  617. eldata = {},
  618. sortByKey = function (a, b) {
  619. return a.key - b.key;
  620. },
  621. sortByNumber = function (a, b) {
  622. return toFloat(a) - toFloat(b);
  623. },
  624. fun = function () {},
  625. pipe = function (x) {
  626. return x;
  627. },
  628. rectPath = R._rectPath = function (x, y, w, h, r) {
  629. if (r) {
  630. return [["M", x + r, y], ["l", w - r * 2, 0], ["a", r, r, 0, 0, 1, r, r], ["l", 0, h - r * 2], ["a", r, r, 0, 0, 1, -r, r], ["l", r * 2 - w, 0], ["a", r, r, 0, 0, 1, -r, -r], ["l", 0, r * 2 - h], ["a", r, r, 0, 0, 1, r, -r], ["z"]];
  631. }
  632. return [["M", x, y], ["l", w, 0], ["l", 0, h], ["l", -w, 0], ["z"]];
  633. },
  634. ellipsePath = function (x, y, rx, ry) {
  635. if (ry == null) {
  636. ry = rx;
  637. }
  638. return [["M", x, y], ["m", 0, -ry], ["a", rx, ry, 0, 1, 1, 0, 2 * ry], ["a", rx, ry, 0, 1, 1, 0, -2 * ry], ["z"]];
  639. },
  640. getPath = R._getPath = {
  641. path: function (el) {
  642. return el.attr("path");
  643. },
  644. circle: function (el) {
  645. var a = el.attrs;
  646. return ellipsePath(a.cx, a.cy, a.r);
  647. },
  648. ellipse: function (el) {
  649. var a = el.attrs;
  650. return ellipsePath(a.cx, a.cy, a.rx, a.ry);
  651. },
  652. rect: function (el) {
  653. var a = el.attrs;
  654. return rectPath(a.x, a.y, a.width, a.height, a.r);
  655. },
  656. image: function (el) {
  657. var a = el.attrs;
  658. return rectPath(a.x, a.y, a.width, a.height);
  659. },
  660. text: function (el) {
  661. var bbox = el._getBBox();
  662. return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);
  663. },
  664. set : function(el) {
  665. var bbox = el._getBBox();
  666. return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);
  667. }
  668. },
  669. /*\
  670. * Raphael.mapPath
  671. [ method ]
  672. **
  673. * Transform the path string with given matrix.
  674. > Parameters
  675. - path (string) path string
  676. - matrix (object) see @Matrix
  677. = (string) transformed path string
  678. \*/
  679. mapPath = R.mapPath = function (path, matrix) {
  680. if (!matrix) {
  681. return path;
  682. }
  683. var x, y, i, j, ii, jj, pathi;
  684. path = path2curve(path);
  685. for (i = 0, ii = path.length; i < ii; i++) {
  686. pathi = path[i];
  687. for (j = 1, jj = pathi.length; j < jj; j += 2) {
  688. x = matrix.x(pathi[j], pathi[j + 1]);
  689. y = matrix.y(pathi[j], pathi[j + 1]);
  690. pathi[j] = x;
  691. pathi[j + 1] = y;
  692. }
  693. }
  694. return path;
  695. };
  696. R._g = g;
  697. /*\
  698. * Raphael.type
  699. [ property (string) ]
  700. **
  701. * Can be “SVG”, “VML” or empty, depending on browser support.
  702. \*/
  703. R.type = (g.win.SVGAngle || g.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML");
  704. if (R.type == "VML") {
  705. var d = g.doc.createElement("div"),
  706. b;
  707. d.innerHTML = '<v:shape adj="1"/>';
  708. b = d.firstChild;
  709. b.style.behavior = "url(#default#VML)";
  710. if (!(b && typeof b.adj == "object")) {
  711. return (R.type = E);
  712. }
  713. d = null;
  714. }
  715. /*\
  716. * Raphael.svg
  717. [ property (boolean) ]
  718. **
  719. * `true` if browser supports SVG.
  720. \*/
  721. /*\
  722. * Raphael.vml
  723. [ property (boolean) ]
  724. **
  725. * `true` if browser supports VML.
  726. \*/
  727. R.svg = !(R.vml = R.type == "VML");
  728. R._Paper = Paper;
  729. /*\
  730. * Raphael.fn
  731. [ property (object) ]
  732. **
  733. * You can add your own method to the canvas. For example if you want to draw a pie chart,
  734. * you can create your own pie chart function and ship it as a Raphaël plugin. To do this
  735. * you need to extend the `Raphael.fn` object. You should modify the `fn` object before a
  736. * Raphaël instance is created, otherwise it will take no effect. Please note that the
  737. * ability for namespaced plugins was removed in Raphael 2.0. It is up to the plugin to
  738. * ensure any namespacing ensures proper context.
  739. > Usage
  740. | Raphael.fn.arrow = function (x1, y1, x2, y2, size) {
  741. | return this.path( ... );
  742. | };
  743. | // or create namespace
  744. | Raphael.fn.mystuff = {
  745. | arrow: function () {…},
  746. | star: function () {…},
  747. | // etc…
  748. | };
  749. | var paper = Raphael(10, 10, 630, 480);
  750. | // then use it
  751. | paper.arrow(10, 10, 30, 30, 5).attr({fill: "#f00"});
  752. | paper.mystuff.arrow();
  753. | paper.mystuff.star();
  754. \*/
  755. R.fn = paperproto = Paper.prototype = R.prototype;
  756. R._id = 0;
  757. R._oid = 0;
  758. /*\
  759. * Raphael.is
  760. [ method ]
  761. **
  762. * Handfull replacement for `typeof` operator.
  763. > Parameters
  764. - o (…) any object or primitive
  765. - type (string) name of the type, i.e. “string”, “function”, “number”, etc.
  766. = (boolean) is given value is of given type
  767. \*/
  768. R.is = function (o, type) {
  769. type = lowerCase.call(type);
  770. if (type == "finite") {
  771. return !isnan[has](+o);
  772. }
  773. if (type == "array") {
  774. return o instanceof Array;
  775. }
  776. return (type == "null" && o === null) ||
  777. (type == typeof o && o !== null) ||
  778. (type == "object" && o === Object(o)) ||
  779. (type == "array" && Array.isArray && Array.isArray(o)) ||
  780. objectToString.call(o).slice(8, -1).toLowerCase() == type;
  781. };
  782. function clone(obj) {
  783. if (typeof obj == "function" || Object(obj) !== obj) {
  784. return obj;
  785. }
  786. var res = new obj.constructor;
  787. for (var key in obj) if (obj[has](key)) {
  788. res[key] = clone(obj[key]);
  789. }
  790. return res;
  791. }
  792. /*\
  793. * Raphael.angle
  794. [ method ]
  795. **
  796. * Returns angle between two or three points
  797. > Parameters
  798. - x1 (number) x coord of first point
  799. - y1 (number) y coord of first point
  800. - x2 (number) x coord of second point
  801. - y2 (number) y coord of second point
  802. - x3 (number) #optional x coord of third point
  803. - y3 (number) #optional y coord of third point
  804. = (number) angle in degrees.
  805. \*/
  806. R.angle = function (x1, y1, x2, y2, x3, y3) {
  807. if (x3 == null) {
  808. var x = x1 - x2,
  809. y = y1 - y2;
  810. if (!x && !y) {
  811. return 0;
  812. }
  813. return (180 + math.atan2(-y, -x) * 180 / PI + 360) % 360;
  814. } else {
  815. return R.angle(x1, y1, x3, y3) - R.angle(x2, y2, x3, y3);
  816. }
  817. };
  818. /*\
  819. * Raphael.rad
  820. [ method ]
  821. **
  822. * Transform angle to radians
  823. > Parameters
  824. - deg (number) angle in degrees
  825. = (number) angle in radians.
  826. \*/
  827. R.rad = function (deg) {
  828. return deg % 360 * PI / 180;
  829. };
  830. /*\
  831. * Raphael.deg
  832. [ method ]
  833. **
  834. * Transform angle to degrees
  835. > Parameters
  836. - deg (number) angle in radians
  837. = (number) angle in degrees.
  838. \*/
  839. R.deg = function (rad) {
  840. return rad * 180 / PI % 360;
  841. };
  842. /*\
  843. * Raphael.snapTo
  844. [ method ]
  845. **
  846. * Snaps given value to given grid.
  847. > Parameters
  848. - values (array|number) given array of values or step of the grid
  849. - value (number) value to adjust
  850. - tolerance (number) #optional tolerance for snapping. Default is `10`.
  851. = (number) adjusted value.
  852. \*/
  853. R.snapTo = function (values, value, tolerance) {
  854. tolerance = R.is(tolerance, "finite") ? tolerance : 10;
  855. if (R.is(values, array)) {
  856. var i = values.length;
  857. while (i--) if (abs(values[i] - value) <= tolerance) {
  858. return values[i];
  859. }
  860. } else {
  861. values = +values;
  862. var rem = value % values;
  863. if (rem < tolerance) {
  864. return value - rem;
  865. }
  866. if (rem > values - tolerance) {
  867. return value - rem + values;
  868. }
  869. }
  870. return value;
  871. };
  872. /*\
  873. * Raphael.createUUID
  874. [ method ]
  875. **
  876. * Returns RFC4122, version 4 ID
  877. \*/
  878. var createUUID = R.createUUID = (function (uuidRegEx, uuidReplacer) {
  879. return function () {
  880. return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(uuidRegEx, uuidReplacer).toUpperCase();
  881. };
  882. })(/[xy]/g, function (c) {
  883. var r = math.random() * 16 | 0,
  884. v = c == "x" ? r : (r & 3 | 8);
  885. return v.toString(16);
  886. });
  887. /*\
  888. * Raphael.setWindow
  889. [ method ]
  890. **
  891. * Used when you need to draw in `&lt;iframe>`. Switched window to the iframe one.
  892. > Parameters
  893. - newwin (window) new window object
  894. \*/
  895. R.setWindow = function (newwin) {
  896. eve("raphael.setWindow", R, g.win, newwin);
  897. g.win = newwin;
  898. g.doc = g.win.document;
  899. if (R._engine.initWin) {
  900. R._engine.initWin(g.win);
  901. }
  902. };
  903. var toHex = function (color) {
  904. if (R.vml) {
  905. // http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/
  906. var trim = /^\s+|\s+$/g;
  907. var bod;
  908. try {
  909. var docum = new ActiveXObject("htmlfile");
  910. docum.write("<body>");
  911. docum.close();
  912. bod = docum.body;
  913. } catch(e) {
  914. bod = createPopup().document.body;
  915. }
  916. var range = bod.createTextRange();
  917. toHex = cacher(function (color) {
  918. try {
  919. bod.style.color = Str(color).replace(trim, E);
  920. var value = range.queryCommandValue("ForeColor");
  921. value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16);
  922. return "#" + ("000000" + value.toString(16)).slice(-6);
  923. } catch(e) {
  924. return "none";
  925. }
  926. });
  927. } else {
  928. var i = g.doc.createElement("i");
  929. i.title = "Rapha\xebl Colour Picker";
  930. i.style.display = "none";
  931. g.doc.body.appendChild(i);
  932. toHex = cacher(function (color) {
  933. i.style.color = color;
  934. return g.doc.defaultView.getComputedStyle(i, E).getPropertyValue("color");
  935. });
  936. }
  937. return toHex(color);
  938. },
  939. hsbtoString = function () {
  940. return "hsb(" + [this.h, this.s, this.b] + ")";
  941. },
  942. hsltoString = function () {
  943. return "hsl(" + [this.h, this.s, this.l] + ")";
  944. },
  945. rgbtoString = function () {
  946. return this.hex;
  947. },
  948. prepareRGB = function (r, g, b) {
  949. if (g == null && R.is(r, "object") && "r" in r && "g" in r && "b" in r) {
  950. b = r.b;
  951. g = r.g;
  952. r = r.r;
  953. }
  954. if (g == null && R.is(r, string)) {
  955. var clr = R.getRGB(r);
  956. r = clr.r;
  957. g = clr.g;
  958. b = clr.b;
  959. }
  960. if (r > 1 || g > 1 || b > 1) {
  961. r /= 255;
  962. g /= 255;
  963. b /= 255;
  964. }
  965. return [r, g, b];
  966. },
  967. packageRGB = function (r, g, b, o) {
  968. r *= 255;
  969. g *= 255;
  970. b *= 255;
  971. var rgb = {
  972. r: r,
  973. g: g,
  974. b: b,
  975. hex: R.rgb(r, g, b),
  976. toString: rgbtoString
  977. };
  978. R.is(o, "finite") && (rgb.opacity = o);
  979. return rgb;
  980. };
  981. /*\
  982. * Raphael.color
  983. [ method ]
  984. **
  985. * Parses the color string and returns object with all values for the given color.
  986. > Parameters
  987. - clr (string) color string in one of the supported formats (see @Raphael.getRGB)
  988. = (object) Combined RGB & HSB object in format:
  989. o {
  990. o r (number) red,
  991. o g (number) green,
  992. o b (number) blue,
  993. o hex (string) color in HTML/CSS format: #••••••,
  994. o error (boolean) `true` if string can’t be parsed,
  995. o h (number) hue,
  996. o s (number) saturation,
  997. o v (number) value (brightness),
  998. o l (number) lightness
  999. o }
  1000. \*/
  1001. R.color = function (clr) {
  1002. var rgb;
  1003. if (R.is(clr, "object") && "h" in clr && "s" in clr && "b" in clr) {
  1004. rgb = R.hsb2rgb(clr);
  1005. clr.r = rgb.r;
  1006. clr.g = rgb.g;
  1007. clr.b = rgb.b;
  1008. clr.hex = rgb.hex;
  1009. } else if (R.is(clr, "object") && "h" in clr && "s" in clr && "l" in clr) {
  1010. rgb = R.hsl2rgb(clr);
  1011. clr.r = rgb.r;
  1012. clr.g = rgb.g;
  1013. clr.b = rgb.b;
  1014. clr.hex = rgb.hex;
  1015. } else {
  1016. if (R.is(clr, "string")) {
  1017. clr = R.getRGB(clr);
  1018. }
  1019. if (R.is(clr, "object") && "r" in clr && "g" in clr && "b" in clr) {
  1020. rgb = R.rgb2hsl(clr);
  1021. clr.h = rgb.h;
  1022. clr.s = rgb.s;
  1023. clr.l = rgb.l;
  1024. rgb = R.rgb2hsb(clr);
  1025. clr.v = rgb.b;
  1026. } else {
  1027. clr = {hex: "none"};
  1028. clr.r = clr.g = clr.b = clr.h = clr.s = clr.v = clr.l = -1;
  1029. }
  1030. }
  1031. clr.toString = rgbtoString;
  1032. return clr;
  1033. };
  1034. /*\
  1035. * Raphael.hsb2rgb
  1036. [ method ]
  1037. **
  1038. * Converts HSB values to RGB object.
  1039. > Parameters
  1040. - h (number) hue
  1041. - s (number) saturation
  1042. - v (number) value or brightness
  1043. = (object) RGB object in format:
  1044. o {
  1045. o r (number) red,
  1046. o g (number) green,
  1047. o b (number) blue,
  1048. o hex (string) color in HTML/CSS format: #••••••
  1049. o }
  1050. \*/
  1051. R.hsb2rgb = function (h, s, v, o) {
  1052. if (this.is(h, "object") && "h" in h && "s" in h && "b" in h) {
  1053. v = h.b;
  1054. s = h.s;
  1055. h = h.h;
  1056. o = h.o;
  1057. }
  1058. h *= 360;
  1059. var R, G, B, X, C;
  1060. h = (h % 360) / 60;
  1061. C = v * s;
  1062. X = C * (1 - abs(h % 2 - 1));
  1063. R = G = B = v - C;
  1064. h = ~~h;
  1065. R += [C, X, 0, 0, X, C][h];
  1066. G += [X, C, C, X, 0, 0][h];
  1067. B += [0, 0, X, C, C, X][h];
  1068. return packageRGB(R, G, B, o);
  1069. };
  1070. /*\
  1071. * Raphael.hsl2rgb
  1072. [ method ]
  1073. **
  1074. * Converts HSL values to RGB object.
  1075. > Parameters
  1076. - h (number) hue
  1077. - s (number) saturation
  1078. - l (number) luminosity
  1079. = (object) RGB object in format:
  1080. o {
  1081. o r (number) red,
  1082. o g (number) green,
  1083. o b (number) blue,
  1084. o hex (string) color in HTML/CSS format: #••••••
  1085. o }
  1086. \*/
  1087. R.hsl2rgb = function (h, s, l, o) {
  1088. if (this.is(h, "object") && "h" in h && "s" in h && "l" in h) {
  1089. l = h.l;
  1090. s = h.s;
  1091. h = h.h;
  1092. }
  1093. if (h > 1 || s > 1 || l > 1) {
  1094. h /= 360;
  1095. s /= 100;
  1096. l /= 100;
  1097. }
  1098. h *= 360;
  1099. var R, G, B, X, C;
  1100. h = (h % 360) / 60;
  1101. C = 2 * s * (l < .5 ? l : 1 - l);
  1102. X = C * (1 - abs(h % 2 - 1));
  1103. R = G = B = l - C / 2;
  1104. h = ~~h;
  1105. R += [C, X, 0, 0, X, C][h];
  1106. G += [X, C, C, X, 0, 0][h];
  1107. B += [0, 0, X, C, C, X][h];
  1108. return packageRGB(R, G, B, o);
  1109. };
  1110. /*\
  1111. * Raphael.rgb2hsb
  1112. [ method ]
  1113. **
  1114. * Converts RGB values to HSB object.
  1115. > Parameters
  1116. - r (number) red
  1117. - g (number) green
  1118. - b (number) blue
  1119. = (object) HSB object in format:
  1120. o {
  1121. o h (number) hue
  1122. o s (number) saturation
  1123. o b (number) brightness
  1124. o }
  1125. \*/
  1126. R.rgb2hsb = function (r, g, b) {
  1127. b = prepareRGB(r, g, b);
  1128. r = b[0];
  1129. g = b[1];
  1130. b = b[2];
  1131. var H, S, V, C;
  1132. V = mmax(r, g, b);
  1133. C = V - mmin(r, g, b);
  1134. H = (C == 0 ? null :
  1135. V == r ? (g - b) / C :
  1136. V == g ? (b - r) / C + 2 :
  1137. (r - g) / C + 4
  1138. );
  1139. H = ((H + 360) % 6) * 60 / 360;
  1140. S = C == 0 ? 0 : C / V;
  1141. return {h: H, s: S, b: V, toString: hsbtoString};
  1142. };
  1143. /*\
  1144. * Raphael.rgb2hsl
  1145. [ method ]
  1146. **
  1147. * Converts RGB values to HSL object.
  1148. > Parameters
  1149. - r (number) red
  1150. - g (number) green
  1151. - b (number) blue
  1152. = (object) HSL object in format:
  1153. o {
  1154. o h (number) hue
  1155. o s (number) saturation
  1156. o l (number) luminosity
  1157. o }
  1158. \*/
  1159. R.rgb2hsl = function (r, g, b) {
  1160. b = prepareRGB(r, g, b);
  1161. r = b[0];
  1162. g = b[1];
  1163. b = b[2];
  1164. var H, S, L, M, m, C;
  1165. M = mmax(r, g, b);
  1166. m = mmin(r, g, b);
  1167. C = M - m;
  1168. H = (C == 0 ? null :
  1169. M == r ? (g - b) / C :
  1170. M == g ? (b - r) / C + 2 :
  1171. (r - g) / C + 4);
  1172. H = ((H + 360) % 6) * 60 / 360;
  1173. L = (M + m) / 2;
  1174. S = (C == 0 ? 0 :
  1175. L < .5 ? C / (2 * L) :
  1176. C / (2 - 2 * L));
  1177. return {h: H, s: S, l: L, toString: hsltoString};
  1178. };
  1179. R._path2string = function () {
  1180. return this.join(",").replace(p2s, "$1");
  1181. };
  1182. function repush(array, item) {
  1183. for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) {
  1184. return array.push(array.splice(i, 1)[0]);
  1185. }
  1186. }
  1187. function cacher(f, scope, postprocessor) {
  1188. function newf() {
  1189. var arg = Array.prototype.slice.call(arguments, 0),
  1190. args = arg.join("\u2400"),
  1191. cache = newf.cache = newf.cache || {},
  1192. count = newf.count = newf.count || [];
  1193. if (cache[has](args)) {
  1194. repush(count, args);
  1195. return postprocessor ? postprocessor(cache[args]) : cache[args];
  1196. }
  1197. count.length >= 1e3 && delete cache[count.shift()];
  1198. count.push(args);
  1199. cache[args] = f[apply](scope, arg);
  1200. return postprocessor ? postprocessor(cache[args]) : cache[args];
  1201. }
  1202. return newf;
  1203. }
  1204. var preload = R._preload = function (src, f) {
  1205. var img = g.doc.createElement("img");
  1206. img.style.cssText = "position:absolute;left:-9999em;top:-9999em";
  1207. img.onload = function () {
  1208. f.call(this);
  1209. this.onload = null;
  1210. g.doc.body.removeChild(this);
  1211. };
  1212. img.onerror = function () {
  1213. g.doc.body.removeChild(this);
  1214. };
  1215. g.doc.body.appendChild(img);
  1216. img.src = src;
  1217. };
  1218. function clrToString() {
  1219. return this.hex;
  1220. }
  1221. /*\
  1222. * Raphael.getRGB
  1223. [ method ]
  1224. **
  1225. * Parses colour string as RGB object
  1226. > Parameters
  1227. - colour (string) colour string in one of formats:
  1228. # <ul>
  1229. # <li>Colour name (“<code>red</code>”, “<code>green</code>”, “<code>cornflowerblue</code>”, etc)</li>
  1230. # <li>#••• — shortened HTML colour: (“<code>#000</code>”, “<code>#fc0</code>”, etc)</li>
  1231. # <li>#•••••• — full length HTML colour: (“<code>#000000</code>”, “<code>#bd2300</code>”)</li>
  1232. # <li>rgb(•••, •••, •••) — red, green and blue channels’ values: (“<code>rgb(200,&nbsp;100,&nbsp;0)</code>”)</li>
  1233. # <li>rgb(•••%, •••%, •••%) — same as above, but in %: (“<code>rgb(100%,&nbsp;175%,&nbsp;0%)</code>”)</li>
  1234. # <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (“<code>hsb(0.5,&nbsp;0.25,&nbsp;1)</code>”)</li>
  1235. # <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>
  1236. # <li>hsl(•••, •••, •••) — same as hsb</li>
  1237. # <li>hsl(•••%, •••%, •••%) — same as hsb</li>
  1238. # </ul>
  1239. = (object) RGB object in format:
  1240. o {
  1241. o r (number) red,
  1242. o g (number) green,
  1243. o b (number) blue
  1244. o hex (string) color in HTML/CSS format: #••••••,
  1245. o error (boolean) true if string can’t be parsed
  1246. o }
  1247. \*/
  1248. R.getRGB = cacher(function (colour) {
  1249. if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) {
  1250. return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: clrToString};
  1251. }
  1252. if (colour == "none") {
  1253. return {r: -1, g: -1, b: -1, hex: "none", toString: clrToString};
  1254. }
  1255. !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour));
  1256. var res,
  1257. red,
  1258. green,
  1259. blue,
  1260. opacity,
  1261. t,
  1262. values,
  1263. rgb = colour.match(colourRegExp);
  1264. if (rgb) {
  1265. if (rgb[2]) {
  1266. blue = toInt(rgb[2].substring(5), 16);
  1267. green = toInt(rgb[2].substring(3, 5), 16);
  1268. red = toInt(rgb[2].substring(1, 3), 16);
  1269. }
  1270. if (rgb[3]) {
  1271. blue = toInt((t = rgb[3].charAt(3)) + t, 16);
  1272. green = toInt((t = rgb[3].charAt(2)) + t, 16);
  1273. red = toInt((t = rgb[3].charAt(1)) + t, 16);
  1274. }
  1275. if (rgb[4]) {
  1276. values = rgb[4][split](commaSpaces);
  1277. red = toFloat(values[0]);
  1278. values[0].slice(-1) == "%" && (red *= 2.55);
  1279. green = toFloat(values[1]);
  1280. values[1].slice(-1) == "%" && (green *= 2.55);
  1281. blue = toFloat(values[2]);
  1282. values[2].slice(-1) == "%" && (blue *= 2.55);
  1283. rgb[1].toLowerCase().slice(0, 4) == "rgba" && (opacity = toFloat(values[3]));
  1284. values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
  1285. }
  1286. if (rgb[5]) {
  1287. values = rgb[5][split](commaSpaces);
  1288. red = toFloat(values[0]);
  1289. values[0].slice(-1) == "%" && (red *= 2.55);
  1290. green = toFloat(values[1]);
  1291. values[1].slice(-1) == "%" && (green *= 2.55);
  1292. blue = toFloat(values[2]);
  1293. values[2].slice(-1) == "%" && (blue *= 2.55);
  1294. (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);
  1295. rgb[1].toLowerCase().slice(0, 4) == "hsba" && (opacity = toFloat(values[3]));
  1296. values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
  1297. return R.hsb2rgb(red, green, blue, opacity);
  1298. }
  1299. if (rgb[6]) {
  1300. values = rgb[6][split](commaSpaces);
  1301. red = toFloat(values[0]);
  1302. values[0].slice(-1) == "%" && (red *= 2.55);
  1303. green = toFloat(values[1]);
  1304. values[1].slice(-1) == "%" && (green *= 2.55);
  1305. blue = toFloat(values[2]);
  1306. values[2].slice(-1) == "%" && (blue *= 2.55);
  1307. (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);
  1308. rgb[1].toLowerCase().slice(0, 4) == "hsla" && (opacity = toFloat(values[3]));
  1309. values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
  1310. return R.hsl2rgb(red, green, blue, opacity);
  1311. }
  1312. rgb = {r: red, g: green, b: blue, toString: clrToString};
  1313. rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1);
  1314. R.is(opacity, "finite") && (rgb.opacity = opacity);
  1315. return rgb;
  1316. }
  1317. return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: clrToString};
  1318. }, R);
  1319. /*\
  1320. * Raphael.hsb
  1321. [ method ]
  1322. **
  1323. * Converts HSB values to hex representation of the colour.
  1324. > Parameters
  1325. - h (number) hue
  1326. - s (number) saturation
  1327. - b (number) value or brightness
  1328. = (string) hex representation of the colour.
  1329. \*/
  1330. R.hsb = cacher(function (h, s, b) {
  1331. return R.hsb2rgb(h, s, b).hex;
  1332. });
  1333. /*\
  1334. * Raphael.hsl
  1335. [ method ]
  1336. **
  1337. * Converts HSL values to hex representation of the colour.
  1338. > Parameters
  1339. - h (number) hue…