Nuiton-js-commits
Threads by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- 636 discussions
Author: echatellier
Date: 2013-09-09 17:34:38 +0200 (Mon, 09 Sep 2013)
New Revision: 214
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/214
Log:
Prepare next iteration
Modified:
sandbox/nuiton-js-jsplumb/pom.xml
Modified: sandbox/nuiton-js-jsplumb/pom.xml
===================================================================
--- sandbox/nuiton-js-jsplumb/pom.xml 2013-09-09 15:33:49 UTC (rev 213)
+++ sandbox/nuiton-js-jsplumb/pom.xml 2013-09-09 15:34:38 UTC (rev 214)
@@ -14,7 +14,7 @@
</parent>
<artifactId>nuiton-js-jsplumb</artifactId>
- <version>1.5.2-1-SNAPSHOT</version>
+ <version>1.5.2-2-SNAPSHOT</version>
<name>Nuiton JS :: jsPlumb</name>
<description>jsPlumb jar packaging</description>
@@ -29,9 +29,9 @@
</licenses>
<scm>
- <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jsplumb-1.5.2-1</connection>
- <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jsplumb-1.5.2-1</developerConnection>
- <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-jsplumb-…</url>
+ <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jsplumb-1.5.2-2</connection>
+ <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jsplumb-1.5.2-2</developerConnection>
+ <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-jsplumb-…</url>
</scm>
</project>
1
0
Author: echatellier
Date: 2013-09-09 17:33:49 +0200 (Mon, 09 Sep 2013)
New Revision: 213
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/213
Log:
Create tag for release
Added:
tags/nuiton-js-jsplumb-1.5.2-1/
1
0
Author: echatellier
Date: 2013-09-09 17:33:10 +0200 (Mon, 09 Sep 2013)
New Revision: 212
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/212
Log:
Prepare next iteration
Modified:
sandbox/nuiton-js-angular/pom.xml
Modified: sandbox/nuiton-js-angular/pom.xml
===================================================================
--- sandbox/nuiton-js-angular/pom.xml 2013-09-09 15:28:26 UTC (rev 211)
+++ sandbox/nuiton-js-angular/pom.xml 2013-09-09 15:33:10 UTC (rev 212)
@@ -29,9 +29,9 @@
</licenses>
<scm>
- <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</connection>
- <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</developerConnection>
- <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-angular-…</url>
+ <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</connection>
+ <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</developerConnection>
+ <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-angular-…</url>
</scm>
</project>
1
0
Author: echatellier
Date: 2013-09-09 17:28:26 +0200 (Mon, 09 Sep 2013)
New Revision: 211
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/211
Log:
Prepare next iteration
Modified:
sandbox/nuiton-js-angular/pom.xml
Modified: sandbox/nuiton-js-angular/pom.xml
===================================================================
--- sandbox/nuiton-js-angular/pom.xml 2013-09-09 15:26:51 UTC (rev 210)
+++ sandbox/nuiton-js-angular/pom.xml 2013-09-09 15:28:26 UTC (rev 211)
@@ -14,7 +14,7 @@
</parent>
<artifactId>nuiton-js-angular</artifactId>
- <version>1.2.0-rc2-1</version>
+ <version>1.2.0-rc2-2-SNAPSHOT</version>
<name>Nuiton JS :: Angular</name>
<description>Angular jar packaging</description>
1
0
Author: echatellier
Date: 2013-09-09 17:26:51 +0200 (Mon, 09 Sep 2013)
New Revision: 210
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/210
Log:
Create tag for release
Added:
tags/nuiton-js-angular-1.2.0-rc2-1/
1
0
Author: echatellier
Date: 2013-09-09 17:26:07 +0200 (Mon, 09 Sep 2013)
New Revision: 209
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/209
Log:
Prepare release
Modified:
sandbox/nuiton-js-angular/pom.xml
Modified: sandbox/nuiton-js-angular/pom.xml
===================================================================
--- sandbox/nuiton-js-angular/pom.xml 2013-09-09 09:45:27 UTC (rev 208)
+++ sandbox/nuiton-js-angular/pom.xml 2013-09-09 15:26:07 UTC (rev 209)
@@ -14,7 +14,7 @@
</parent>
<artifactId>nuiton-js-angular</artifactId>
- <version>1.2.0-rc2-1-SNAPSHOT</version>
+ <version>1.2.0-rc2-1</version>
<name>Nuiton JS :: Angular</name>
<description>Angular jar packaging</description>
1
0
Author: echatellier
Date: 2013-09-09 11:45:27 +0200 (Mon, 09 Sep 2013)
New Revision: 208
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/208
Log:
svn:ignore
Modified:
sandbox/nuiton-js-jsplumb/
Property changes on: sandbox/nuiton-js-jsplumb
___________________________________________________________________
Added: svn:ignore
+ .settings
.classpath
.project
1
0
r207 - in sandbox: . nuiton-js-jsplumb nuiton-js-jsplumb/src nuiton-js-jsplumb/src/main nuiton-js-jsplumb/src/main/resources nuiton-js-jsplumb/src/main/resources/META-INF nuiton-js-jsplumb/src/main/resources/META-INF/nuiton-js nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb nuiton-js-jsplumb/src/site nuiton-js-jsplumb/src/site/rst
by echatellier@users.nuiton.org Sept. 9, 2013
by echatellier@users.nuiton.org Sept. 9, 2013
Sept. 9, 2013
Author: echatellier
Date: 2013-09-09 11:43:14 +0200 (Mon, 09 Sep 2013)
New Revision: 207
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/207
Log:
Initial import
Added:
sandbox/nuiton-js-jsplumb/
sandbox/nuiton-js-jsplumb/LICENSE.txt
sandbox/nuiton-js-jsplumb/README.txt
sandbox/nuiton-js-jsplumb/pom.xml
sandbox/nuiton-js-jsplumb/src/
sandbox/nuiton-js-jsplumb/src/main/
sandbox/nuiton-js-jsplumb/src/main/resources/
sandbox/nuiton-js-jsplumb/src/main/resources/META-INF/
sandbox/nuiton-js-jsplumb/src/main/resources/META-INF/nuiton-js/
sandbox/nuiton-js-jsplumb/src/main/resources/META-INF/nuiton-js/wro-jsplumb.xml
sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/
sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/jquery.jsPlumb-1.5.2.js
sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/mootools.jsPlumb-1.5.2.js
sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/yui.jsPlumb-1.5.2.js
sandbox/nuiton-js-jsplumb/src/site/
sandbox/nuiton-js-jsplumb/src/site/rst/
sandbox/nuiton-js-jsplumb/src/site/rst/index.rst.vm
sandbox/nuiton-js-jsplumb/src/site/site_en.xml
Added: sandbox/nuiton-js-jsplumb/LICENSE.txt
===================================================================
Added: sandbox/nuiton-js-jsplumb/README.txt
===================================================================
--- sandbox/nuiton-js-jsplumb/README.txt (rev 0)
+++ sandbox/nuiton-js-jsplumb/README.txt 2013-09-09 09:43:14 UTC (rev 207)
@@ -0,0 +1,2 @@
+
+
Added: sandbox/nuiton-js-jsplumb/pom.xml
===================================================================
--- sandbox/nuiton-js-jsplumb/pom.xml (rev 0)
+++ sandbox/nuiton-js-jsplumb/pom.xml 2013-09-09 09:43:14 UTC (rev 207)
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- ************************************************************* -->
+ <!-- *** POM Relationships *************************************** -->
+ <!-- ************************************************************* -->
+
+ <parent>
+ <groupId>org.nuiton.js</groupId>
+ <artifactId>nuiton-js-lib</artifactId>
+ <version>1.0.1</version>
+ </parent>
+
+ <artifactId>nuiton-js-jsplumb</artifactId>
+ <version>1.5.2-1-SNAPSHOT</version>
+
+ <name>Nuiton JS :: jsPlumb</name>
+ <description>jsPlumb jar packaging</description>
+
+ <url>http://jsplumbtoolkit.com/</url>
+
+ <licenses>
+ <license>
+ <name>MIT License</name>
+ <url>https://raw.github.com/sporritt/jsPlumb/master/jsPlumb-MIT-LICENSE.txt</url>
+ </license>
+ </licenses>
+
+ <scm>
+ <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jsplumb-1.5.2-1</connection>
+ <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jsplumb-1.5.2-1</developerConnection>
+ <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-jsplumb-…</url>
+ </scm>
+
+</project>
Property changes on: sandbox/nuiton-js-jsplumb/pom.xml
___________________________________________________________________
Added: svn:mime-type
+ text/xml
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Added: sandbox/nuiton-js-jsplumb/src/main/resources/META-INF/nuiton-js/wro-jsplumb.xml
===================================================================
--- sandbox/nuiton-js-jsplumb/src/main/resources/META-INF/nuiton-js/wro-jsplumb.xml (rev 0)
+++ sandbox/nuiton-js-jsplumb/src/main/resources/META-INF/nuiton-js/wro-jsplumb.xml 2013-09-09 09:43:14 UTC (rev 207)
@@ -0,0 +1,34 @@
+<!--
+ #%L
+ Nuiton JS :: jsPlumb
+ $Id$
+ $HeadURL$
+ %%
+ Copyright (C) 2013 CodeLutin, Chatellier Eric
+ %%
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Lesser Public License for more details.
+
+ You should have received a copy of the GNU General Lesser Public
+ License along with this program. If not, see
+ <http://www.gnu.org/licenses/lgpl-3.0.html>.
+ #L%
+ -->
+<groups xmlns="http://www.isdc.ro/wro">
+ <group name='jsplumb-jquery'>
+ <js>classpath:nuiton-js-jsplumb/jquery.jsPlumb-1.5.2.js</js>
+ </group>
+ <group name='jsplumb-mootools'>
+ <js>classpath:nuiton-js-jsplumb/mootools.jsPlumb-1.5.2.js</js>
+ </group>
+ <group name='jsplumb-yui'>
+ <js>classpath:nuiton-js-jsplumb/yui.jsPlumb-1.5.2.js</js>
+ </group>
+</groups>
Property changes on: sandbox/nuiton-js-jsplumb/src/main/resources/META-INF/nuiton-js/wro-jsplumb.xml
___________________________________________________________________
Added: svn:mime-type
+ text/xml
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Added: sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/jquery.jsPlumb-1.5.2.js
===================================================================
--- sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/jquery.jsPlumb-1.5.2.js (rev 0)
+++ sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/jquery.jsPlumb-1.5.2.js 2013-09-09 09:43:14 UTC (rev 207)
@@ -0,0 +1,10973 @@
+/** %%Ignore-License
+* jsBezier-0.6
+*
+* Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+*
+* licensed under the MIT license.
+*
+* a set of Bezier curve functions that deal with Beziers, used by jsPlumb, and perhaps useful for other people. These functions work with Bezier
+* curves of arbitrary degree.
+*
+* - functions are all in the 'jsBezier' namespace.
+*
+* - all input points should be in the format {x:.., y:..}. all output points are in this format too.
+*
+* - all input curves should be in the format [ {x:.., y:..}, {x:.., y:..}, {x:.., y:..}, {x:.., y:..} ]
+*
+* - 'location' as used as an input here refers to a decimal in the range 0-1 inclusive, which indicates a point some proportion along the length
+* of the curve. location as output has the same format and meaning.
+*
+*
+* Function List:
+* --------------
+*
+* distanceFromCurve(point, curve)
+*
+* Calculates the distance that the given point lies from the given Bezier. Note that it is computed relative to the center of the Bezier,
+* so if you have stroked the curve with a wide pen you may wish to take that into account! The distance returned is relative to the values
+* of the curve and the point - it will most likely be pixels.
+*
+* gradientAtPoint(curve, location)
+*
+* Calculates the gradient to the curve at the given location, as a decimal between 0 and 1 inclusive.
+*
+* gradientAtPointAlongCurveFrom (curve, location)
+*
+* Calculates the gradient at the point on the given curve that is 'distance' units from location.
+*
+* nearestPointOnCurve(point, curve)
+*
+* Calculates the nearest point to the given point on the given curve. The return value of this is a JS object literal, containing both the
+*point's coordinates and also the 'location' of the point (see above), for example: { point:{x:551,y:150}, location:0.263365 }.
+*
+* pointOnCurve(curve, location)
+*
+* Calculates the coordinates of the point on the given Bezier curve at the given location.
+*
+* pointAlongCurveFrom(curve, location, distance)
+*
+* Calculates the coordinates of the point on the given curve that is 'distance' units from location. 'distance' should be in the same coordinate
+* space as that used to construct the Bezier curve. For an HTML Canvas usage, for example, distance would be a measure of pixels.
+*
+* locationAlongCurveFrom(curve, location, distance)
+*
+* Calculates the location on the given curve that is 'distance' units from location. 'distance' should be in the same coordinate
+* space as that used to construct the Bezier curve. For an HTML Canvas usage, for example, distance would be a measure of pixels.
+*
+* perpendicularToCurveAt(curve, location, length, distance)
+*
+* Calculates the perpendicular to the given curve at the given location. length is the length of the line you wish for (it will be centered
+* on the point at 'location'). distance is optional, and allows you to specify a point along the path from the given location as the center of
+* the perpendicular returned. The return value of this is an array of two points: [ {x:...,y:...}, {x:...,y:...} ].
+*
+*
+*/
+
+(function() {
+
+ if(typeof Math.sgn == "undefined") {
+ Math.sgn = function(x) { return x == 0 ? 0 : x > 0 ? 1 :-1; };
+ }
+
+ var Vectors = {
+ subtract : function(v1, v2) { return {x:v1.x - v2.x, y:v1.y - v2.y }; },
+ dotProduct : function(v1, v2) { return (v1.x * v2.x) + (v1.y * v2.y); },
+ square : function(v) { return Math.sqrt((v.x * v.x) + (v.y * v.y)); },
+ scale : function(v, s) { return {x:v.x * s, y:v.y * s }; }
+ },
+
+ maxRecursion = 64,
+ flatnessTolerance = Math.pow(2.0,-maxRecursion-1);
+
+ /**
+ * Calculates the distance that the point lies from the curve.
+ *
+ * @param point a point in the form {x:567, y:3342}
+ * @param curve a Bezier curve in the form [{x:..., y:...}, {x:..., y:...}, {x:..., y:...}, {x:..., y:...}]. note that this is currently
+ * hardcoded to assume cubiz beziers, but would be better off supporting any degree.
+ * @return a JS object literal containing location and distance, for example: {location:0.35, distance:10}. Location is analogous to the location
+ * argument you pass to the pointOnPath function: it is a ratio of distance travelled along the curve. Distance is the distance in pixels from
+ * the point to the curve.
+ */
+ var _distanceFromCurve = function(point, curve) {
+ var candidates = [],
+ w = _convertToBezier(point, curve),
+ degree = curve.length - 1, higherDegree = (2 * degree) - 1,
+ numSolutions = _findRoots(w, higherDegree, candidates, 0),
+ v = Vectors.subtract(point, curve[0]), dist = Vectors.square(v), t = 0.0;
+
+ for (var i = 0; i < numSolutions; i++) {
+ v = Vectors.subtract(point, _bezier(curve, degree, candidates[i], null, null));
+ var newDist = Vectors.square(v);
+ if (newDist < dist) {
+ dist = newDist;
+ t = candidates[i];
+ }
+ }
+ v = Vectors.subtract(point, curve[degree]);
+ newDist = Vectors.square(v);
+ if (newDist < dist) {
+ dist = newDist;
+ t = 1.0;
+ }
+ return {location:t, distance:dist};
+ };
+ /**
+ * finds the nearest point on the curve to the given point.
+ */
+ var _nearestPointOnCurve = function(point, curve) {
+ var td = _distanceFromCurve(point, curve);
+ return {point:_bezier(curve, curve.length - 1, td.location, null, null), location:td.location};
+ };
+ var _convertToBezier = function(point, curve) {
+ var degree = curve.length - 1, higherDegree = (2 * degree) - 1,
+ c = [], d = [], cdTable = [], w = [],
+ z = [ [1.0, 0.6, 0.3, 0.1], [0.4, 0.6, 0.6, 0.4], [0.1, 0.3, 0.6, 1.0] ];
+
+ for (var i = 0; i <= degree; i++) c[i] = Vectors.subtract(curve[i], point);
+ for (var i = 0; i <= degree - 1; i++) {
+ d[i] = Vectors.subtract(curve[i+1], curve[i]);
+ d[i] = Vectors.scale(d[i], 3.0);
+ }
+ for (var row = 0; row <= degree - 1; row++) {
+ for (var column = 0; column <= degree; column++) {
+ if (!cdTable[row]) cdTable[row] = [];
+ cdTable[row][column] = Vectors.dotProduct(d[row], c[column]);
+ }
+ }
+ for (i = 0; i <= higherDegree; i++) {
+ if (!w[i]) w[i] = [];
+ w[i].y = 0.0;
+ w[i].x = parseFloat(i) / higherDegree;
+ }
+ var n = degree, m = degree-1;
+ for (var k = 0; k <= n + m; k++) {
+ var lb = Math.max(0, k - m),
+ ub = Math.min(k, n);
+ for (i = lb; i <= ub; i++) {
+ j = k - i;
+ w[i+j].y += cdTable[j][i] * z[j][i];
+ }
+ }
+ return w;
+ };
+ /**
+ * counts how many roots there are.
+ */
+ var _findRoots = function(w, degree, t, depth) {
+ var left = [], right = [],
+ left_count, right_count,
+ left_t = [], right_t = [];
+
+ switch (_getCrossingCount(w, degree)) {
+ case 0 : {
+ return 0;
+ }
+ case 1 : {
+ if (depth >= maxRecursion) {
+ t[0] = (w[0].x + w[degree].x) / 2.0;
+ return 1;
+ }
+ if (_isFlatEnough(w, degree)) {
+ t[0] = _computeXIntercept(w, degree);
+ return 1;
+ }
+ break;
+ }
+ }
+ _bezier(w, degree, 0.5, left, right);
+ left_count = _findRoots(left, degree, left_t, depth+1);
+ right_count = _findRoots(right, degree, right_t, depth+1);
+ for (var i = 0; i < left_count; i++) t[i] = left_t[i];
+ for (var i = 0; i < right_count; i++) t[i+left_count] = right_t[i];
+ return (left_count+right_count);
+ };
+ var _getCrossingCount = function(curve, degree) {
+ var n_crossings = 0, sign, old_sign;
+ sign = old_sign = Math.sgn(curve[0].y);
+ for (var i = 1; i <= degree; i++) {
+ sign = Math.sgn(curve[i].y);
+ if (sign != old_sign) n_crossings++;
+ old_sign = sign;
+ }
+ return n_crossings;
+ };
+ var _isFlatEnough = function(curve, degree) {
+ var error,
+ intercept_1, intercept_2, left_intercept, right_intercept,
+ a, b, c, det, dInv, a1, b1, c1, a2, b2, c2;
+ a = curve[0].y - curve[degree].y;
+ b = curve[degree].x - curve[0].x;
+ c = curve[0].x * curve[degree].y - curve[degree].x * curve[0].y;
+
+ var max_distance_above = max_distance_below = 0.0;
+
+ for (var i = 1; i < degree; i++) {
+ var value = a * curve[i].x + b * curve[i].y + c;
+ if (value > max_distance_above)
+ max_distance_above = value;
+ else if (value < max_distance_below)
+ max_distance_below = value;
+ }
+
+ a1 = 0.0; b1 = 1.0; c1 = 0.0; a2 = a; b2 = b;
+ c2 = c - max_distance_above;
+ det = a1 * b2 - a2 * b1;
+ dInv = 1.0/det;
+ intercept_1 = (b1 * c2 - b2 * c1) * dInv;
+ a2 = a; b2 = b; c2 = c - max_distance_below;
+ det = a1 * b2 - a2 * b1;
+ dInv = 1.0/det;
+ intercept_2 = (b1 * c2 - b2 * c1) * dInv;
+ left_intercept = Math.min(intercept_1, intercept_2);
+ right_intercept = Math.max(intercept_1, intercept_2);
+ error = right_intercept - left_intercept;
+ return (error < flatnessTolerance)? 1 : 0;
+ };
+ var _computeXIntercept = function(curve, degree) {
+ var XLK = 1.0, YLK = 0.0,
+ XNM = curve[degree].x - curve[0].x, YNM = curve[degree].y - curve[0].y,
+ XMK = curve[0].x - 0.0, YMK = curve[0].y - 0.0,
+ det = XNM*YLK - YNM*XLK, detInv = 1.0/det,
+ S = (XNM*YMK - YNM*XMK) * detInv;
+ return 0.0 + XLK * S;
+ };
+ var _bezier = function(curve, degree, t, left, right) {
+ var temp = [[]];
+ for (var j =0; j <= degree; j++) temp[0][j] = curve[j];
+ for (var i = 1; i <= degree; i++) {
+ for (var j =0 ; j <= degree - i; j++) {
+ if (!temp[i]) temp[i] = [];
+ if (!temp[i][j]) temp[i][j] = {};
+ temp[i][j].x = (1.0 - t) * temp[i-1][j].x + t * temp[i-1][j+1].x;
+ temp[i][j].y = (1.0 - t) * temp[i-1][j].y + t * temp[i-1][j+1].y;
+ }
+ }
+ if (left != null)
+ for (j = 0; j <= degree; j++) left[j] = temp[j][0];
+ if (right != null)
+ for (j = 0; j <= degree; j++) right[j] = temp[degree-j][j];
+
+ return (temp[degree][0]);
+ };
+
+ var _curveFunctionCache = {};
+ var _getCurveFunctions = function(order) {
+ var fns = _curveFunctionCache[order];
+ if (!fns) {
+ fns = [];
+ var f_term = function() { return function(t) { return Math.pow(t, order); }; },
+ l_term = function() { return function(t) { return Math.pow((1-t), order); }; },
+ c_term = function(c) { return function(t) { return c; }; },
+ t_term = function() { return function(t) { return t; }; },
+ one_minus_t_term = function() { return function(t) { return 1-t; }; },
+ _termFunc = function(terms) {
+ return function(t) {
+ var p = 1;
+ for (var i = 0; i < terms.length; i++) p = p * terms[i](t);
+ return p;
+ };
+ };
+
+ fns.push(new f_term()); // first is t to the power of the curve order
+ for (var i = 1; i < order; i++) {
+ var terms = [new c_term(order)];
+ for (var j = 0 ; j < (order - i); j++) terms.push(new t_term());
+ for (var j = 0 ; j < i; j++) terms.push(new one_minus_t_term());
+ fns.push(new _termFunc(terms));
+ }
+ fns.push(new l_term()); // last is (1-t) to the power of the curve order
+
+ _curveFunctionCache[order] = fns;
+ }
+
+ return fns;
+ };
+
+
+ /**
+ * calculates a point on the curve, for a Bezier of arbitrary order.
+ * @param curve an array of control points, eg [{x:10,y:20}, {x:50,y:50}, {x:100,y:100}, {x:120,y:100}]. For a cubic bezier this should have four points.
+ * @param location a decimal indicating the distance along the curve the point should be located at. this is the distance along the curve as it travels, taking the way it bends into account. should be a number from 0 to 1, inclusive.
+ */
+ var _pointOnPath = function(curve, location) {
+ var cc = _getCurveFunctions(curve.length - 1),
+ _x = 0, _y = 0;
+ for (var i = 0; i < curve.length ; i++) {
+ _x = _x + (curve[i].x * cc[i](location));
+ _y = _y + (curve[i].y * cc[i](location));
+ }
+
+ return {x:_x, y:_y};
+ };
+
+ var _dist = function(p1,p2) {
+ return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
+ };
+
+ var _isPoint = function(curve) {
+ return curve[0].x == curve[1].x && curve[0].y == curve[1].y;
+ };
+
+ /**
+ * finds the point that is 'distance' along the path from 'location'. this method returns both the x,y location of the point and also
+ * its 'location' (proportion of travel along the path); the method below - _pointAlongPathFrom - calls this method and just returns the
+ * point.
+ */
+ var _pointAlongPath = function(curve, location, distance) {
+
+ if (_isPoint(curve)) {
+ return {
+ point:curve[0],
+ location:location
+ };
+ }
+
+ var prev = _pointOnPath(curve, location),
+ tally = 0,
+ curLoc = location,
+ direction = distance > 0 ? 1 : -1,
+ cur = null;
+
+ while (tally < Math.abs(distance)) {
+ curLoc += (0.005 * direction);
+ cur = _pointOnPath(curve, curLoc);
+ tally += _dist(cur, prev);
+ prev = cur;
+ }
+ return {point:cur, location:curLoc};
+ };
+
+ var _length = function(curve) {
+ if (_isPoint(curve)) return 0;
+
+ var prev = _pointOnPath(curve, 0),
+ tally = 0,
+ curLoc = 0,
+ direction = 1,
+ cur = null;
+
+ while (curLoc < 1) {
+ curLoc += (0.005 * direction);
+ cur = _pointOnPath(curve, curLoc);
+ tally += _dist(cur, prev);
+ prev = cur;
+ }
+ return tally;
+ };
+
+ /**
+ * finds the point that is 'distance' along the path from 'location'.
+ */
+ var _pointAlongPathFrom = function(curve, location, distance) {
+ return _pointAlongPath(curve, location, distance).point;
+ };
+
+ /**
+ * finds the location that is 'distance' along the path from 'location'.
+ */
+ var _locationAlongPathFrom = function(curve, location, distance) {
+ return _pointAlongPath(curve, location, distance).location;
+ };
+
+ /**
+ * returns the gradient of the curve at the given location, which is a decimal between 0 and 1 inclusive.
+ *
+ * thanks // http://bimixual.org/AnimationLibrary/beziertangents.html
+ */
+ var _gradientAtPoint = function(curve, location) {
+ var p1 = _pointOnPath(curve, location),
+ p2 = _pointOnPath(curve.slice(0, curve.length - 1), location),
+ dy = p2.y - p1.y, dx = p2.x - p1.x;
+ return dy == 0 ? Infinity : Math.atan(dy / dx);
+ };
+
+ /**
+ returns the gradient of the curve at the point which is 'distance' from the given location.
+ if this point is greater than location 1, the gradient at location 1 is returned.
+ if this point is less than location 0, the gradient at location 0 is returned.
+ */
+ var _gradientAtPointAlongPathFrom = function(curve, location, distance) {
+ var p = _pointAlongPath(curve, location, distance);
+ if (p.location > 1) p.location = 1;
+ if (p.location < 0) p.location = 0;
+ return _gradientAtPoint(curve, p.location);
+ };
+
+ /**
+ * calculates a line that is 'length' pixels long, perpendicular to, and centered on, the path at 'distance' pixels from the given location.
+ * if distance is not supplied, the perpendicular for the given location is computed (ie. we set distance to zero).
+ */
+ var _perpendicularToPathAt = function(curve, location, length, distance) {
+ distance = distance == null ? 0 : distance;
+ var p = _pointAlongPath(curve, location, distance),
+ m = _gradientAtPoint(curve, p.location),
+ _theta2 = Math.atan(-1 / m),
+ y = length / 2 * Math.sin(_theta2),
+ x = length / 2 * Math.cos(_theta2);
+ return [{x:p.point.x + x, y:p.point.y + y}, {x:p.point.x - x, y:p.point.y - y}];
+ };
+
+ var jsBezier = window.jsBezier = {
+ distanceFromCurve : _distanceFromCurve,
+ gradientAtPoint : _gradientAtPoint,
+ gradientAtPointAlongCurveFrom : _gradientAtPointAlongPathFrom,
+ nearestPointOnCurve : _nearestPointOnCurve,
+ pointOnCurve : _pointOnPath,
+ pointAlongCurveFrom : _pointAlongPathFrom,
+ perpendicularToCurveAt : _perpendicularToPathAt,
+ locationAlongCurveFrom:_locationAlongPathFrom,
+ getLength:_length
+ };
+})();
+
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG or VML.
+ *
+ * This file contains the util functions
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ var _isa = function(a) { return Object.prototype.toString.call(a) === "[object Array]"; },
+ _isnum = function(n) { return Object.prototype.toString.call(n) === "[object Number]"; },
+ _iss = function(s) { return typeof s === "string"; },
+ _isb = function(s) { return typeof s === "boolean"; },
+ _isnull = function(s) { return s == null; },
+ _iso = function(o) { return o == null ? false : Object.prototype.toString.call(o) === "[object Object]"; },
+ _isd = function(o) { return Object.prototype.toString.call(o) === "[object Date]"; },
+ _isf = function(o) { return Object.prototype.toString.call(o) === "[object Function]"; },
+ _ise = function(o) {
+ for (var i in o) { if (o.hasOwnProperty(i)) return false; }
+ return true;
+ },
+ pointHelper = function(p1, p2, fn) {
+ p1 = _isa(p1) ? p1 : [p1.x, p1.y];
+ p2 = _isa(p2) ? p2 : [p2.x, p2.y];
+ return fn(p1, p2);
+ };
+
+ jsPlumbUtil = {
+ isArray : _isa,
+ isString : _iss,
+ isBoolean: _isb,
+ isNull : _isnull,
+ isObject : _iso,
+ isDate : _isd,
+ isFunction: _isf,
+ isEmpty:_ise,
+ isNumber:_isnum,
+ clone : function(a) {
+ if (_iss(a)) return "" + a;
+ else if (_isb(a)) return !!a;
+ else if (_isd(a)) return new Date(a.getTime());
+ else if (_isf(a)) return a;
+ else if (_isa(a)) {
+ var b = [];
+ for (var i = 0; i < a.length; i++)
+ b.push(this.clone(a[i]));
+ return b;
+ }
+ else if (_iso(a)) {
+ var c = {};
+ for (var j in a)
+ c[j] = this.clone(a[j]);
+ return c;
+ }
+ else return a;
+ },
+ merge : function(a, b) {
+ var c = this.clone(a);
+ for (var i in b) {
+ if (c[i] == null || _iss(b[i]) || _isb(b[i]))
+ c[i] = b[i];
+ else {
+ if (_isa(b[i])/* && this.isArray(c[i])*/) {
+ var ar = [];
+ // if c's object is also an array we can keep its values.
+ if (_isa(c[i])) ar.push.apply(ar, c[i]);
+ ar.push.apply(ar, b[i]);
+ c[i] = ar;
+ }
+ else if(_iso(b[i])) {
+ // overwite c's value with an object if it is not already one.
+ if (!_iso(c[i]))
+ c[i] = {};
+ for (var j in b[i])
+ c[i][j] = b[i][j];
+ }
+ }
+ }
+ return c;
+ },
+ copyValues:function(names, from, to) {
+ for (var i = 0; i < names.length; i++)
+ to[names[i]] = from[names[i]];
+ },
+ //
+ // chain a list of functions, supplied by [ object, method name, args ], and return on the first
+ // one that returns the failValue. if none return the failValue, return the successValue.
+ //
+ functionChain : function(successValue, failValue, fns) {
+ for (var i = 0; i < fns.length; i++) {
+ var o = fns[i][0][fns[i][1]].apply(fns[i][0], fns[i][2]);
+ if (o === failValue) {
+ return o;
+ }
+ }
+ return successValue;
+ },
+ // take the given model and expand out any parameters.
+ populate : function(model, values) {
+ // for a string, see if it has parameter matches, and if so, try to make the substitutions.
+ var getValue = function(fromString) {
+ var matches = fromString.match(/(\${.*?})/g);
+ if (matches != null) {
+ for (var i = 0; i < matches.length; i++) {
+ var val = values[matches[i].substring(2, matches[i].length - 1)];
+ if (val != null) {
+ fromString = fromString.replace(matches[i], val);
+ }
+ }
+ }
+ return fromString;
+ },
+ // process one entry.
+ _one = function(d) {
+ if (d != null) {
+ if (_iss(d)) {
+ return getValue(d);
+ }
+ else if (_isa(d)) {
+ var r = [];
+ for (var i = 0; i < d.length; i++)
+ r.push(_one(d[i]));
+ return r;
+ }
+ else if (_iso(d)) {
+ var s = {};
+ for (var j in d) {
+ s[j] = _one(d[j]);
+ }
+ return s;
+ }
+ else {
+ return d;
+ }
+ }
+ };
+
+ return _one(model);
+ },
+ convertStyle : function(s, ignoreAlpha) {
+ // TODO: jsPlumb should support a separate 'opacity' style member.
+ if ("transparent" === s) return s;
+ var o = s,
+ pad = function(n) { return n.length == 1 ? "0" + n : n; },
+ hex = function(k) { return pad(Number(k).toString(16)); },
+ pattern = /(rgb[a]?\()(.*)(\))/;
+ if (s.match(pattern)) {
+ var parts = s.match(pattern)[2].split(",");
+ o = "#" + hex(parts[0]) + hex(parts[1]) + hex(parts[2]);
+ if (!ignoreAlpha && parts.length == 4)
+ o = o + hex(parts[3]);
+ }
+ return o;
+ },
+ gradient : function(p1, p2) {
+ return pointHelper(p1, p2, function(_p1, _p2) {
+ if (_p2[0] == _p1[0])
+ return _p2[1] > _p1[1] ? Infinity : -Infinity;
+ else if (_p2[1] == _p1[1])
+ return _p2[0] > _p1[0] ? 0 : -0;
+ else
+ return (_p2[1] - _p1[1]) / (_p2[0] - _p1[0]);
+ });
+ },
+ normal : function(p1, p2) {
+ return -1 / this.gradient(p1, p2);
+ },
+ lineLength : function(p1, p2) {
+ return pointHelper(p1, p2, function(_p1, _p2) {
+ return Math.sqrt(Math.pow(_p2[1] - _p1[1], 2) + Math.pow(_p2[0] - _p1[0], 2));
+ });
+ },
+ segment : function(p1, p2) {
+ return pointHelper(p1, p2, function(_p1, _p2) {
+ if (_p2[0] > _p1[0]) {
+ return (_p2[1] > _p1[1]) ? 2 : 1;
+ }
+ else if (_p2[0] == _p1[0]) {
+ return _p2[1] > _p1[1] ? 2 : 1;
+ }
+ else {
+ return (_p2[1] > _p1[1]) ? 3 : 4;
+ }
+ });
+ },
+ theta : function(p1, p2) {
+ return pointHelper(p1, p2, function(_p1, _p2) {
+ var m = jsPlumbUtil.gradient(_p1, _p2),
+ t = Math.atan(m),
+ s = jsPlumbUtil.segment(_p1, _p2);
+ if ((s == 4 || s== 3)) t += Math.PI;
+ if (t < 0) t += (2 * Math.PI);
+
+ return t;
+ });
+ },
+ intersects : function(r1, r2) {
+ var x1 = r1.x, x2 = r1.x + r1.w, y1 = r1.y, y2 = r1.y + r1.h,
+ a1 = r2.x, a2 = r2.x + r2.w, b1 = r2.y, b2 = r2.y + r2.h;
+
+ return ( (x1 <= a1 && a1 <= x2) && (y1 <= b1 && b1 <= y2) ) ||
+ ( (x1 <= a2 && a2 <= x2) && (y1 <= b1 && b1 <= y2) ) ||
+ ( (x1 <= a1 && a1 <= x2) && (y1 <= b2 && b2 <= y2) ) ||
+ ( (x1 <= a2 && a1 <= x2) && (y1 <= b2 && b2 <= y2) ) ||
+ ( (a1 <= x1 && x1 <= a2) && (b1 <= y1 && y1 <= b2) ) ||
+ ( (a1 <= x2 && x2 <= a2) && (b1 <= y1 && y1 <= b2) ) ||
+ ( (a1 <= x1 && x1 <= a2) && (b1 <= y2 && y2 <= b2) ) ||
+ ( (a1 <= x2 && x1 <= a2) && (b1 <= y2 && y2 <= b2) );
+ },
+ segmentMultipliers : [null, [1, -1], [1, 1], [-1, 1], [-1, -1] ],
+ inverseSegmentMultipliers : [null, [-1, -1], [-1, 1], [1, 1], [1, -1] ],
+ pointOnLine : function(fromPoint, toPoint, distance) {
+ var m = jsPlumbUtil.gradient(fromPoint, toPoint),
+ s = jsPlumbUtil.segment(fromPoint, toPoint),
+ segmentMultiplier = distance > 0 ? jsPlumbUtil.segmentMultipliers[s] : jsPlumbUtil.inverseSegmentMultipliers[s],
+ theta = Math.atan(m),
+ y = Math.abs(distance * Math.sin(theta)) * segmentMultiplier[1],
+ x = Math.abs(distance * Math.cos(theta)) * segmentMultiplier[0];
+ return { x:fromPoint.x + x, y:fromPoint.y + y };
+ },
+ perpendicularLineTo : function(fromPoint, toPoint, length) {
+ var m = jsPlumbUtil.gradient(fromPoint, toPoint),
+ theta2 = Math.atan(-1 / m),
+ y = length / 2 * Math.sin(theta2),
+ x = length / 2 * Math.cos(theta2);
+ return [{x:toPoint.x + x, y:toPoint.y + y}, {x:toPoint.x - x, y:toPoint.y - y}];
+ },
+ findWithFunction : function(a, f) {
+ if (a)
+ for (var i = 0; i < a.length; i++) if (f(a[i])) return i;
+ return -1;
+ },
+ clampToGrid : function(x, y, grid, dontClampX, dontClampY) {
+ var _gridClamp = function(n, g) {
+ var e = n % g,
+ f = Math.floor(n / g),
+ inc = e >= (g / 2) ? 1 : 0;
+ return (f + inc) * g;
+ };
+ return [
+ dontClampX || grid == null ? x : _gridClamp(x, grid[0]),
+ dontClampY || grid == null ? y : _gridClamp(y, grid[1])
+ ];
+ },
+ indexOf : function(l, v) {
+ return jsPlumbUtil.findWithFunction(l, function(_v) { return _v == v; });
+ },
+ removeWithFunction : function(a, f) {
+ var idx = jsPlumbUtil.findWithFunction(a, f);
+ if (idx > -1) a.splice(idx, 1);
+ return idx != -1;
+ },
+ remove : function(l, v) {
+ var idx = jsPlumbUtil.indexOf(l, v);
+ if (idx > -1) l.splice(idx, 1);
+ return idx != -1;
+ },
+ // TODO support insert index
+ addWithFunction : function(list, item, hashFunction) {
+ if (jsPlumbUtil.findWithFunction(list, hashFunction) == -1) list.push(item);
+ },
+ addToList : function(map, key, value, insertAtStart) {
+ var l = map[key];
+ if (l == null) {
+ l = [];
+ map[key] = l;
+ }
+ l[insertAtStart ? "unshift" : "push"](value);
+ return l;
+ },
+ //
+ // extends the given obj (which can be an array) with the given constructor function, prototype functions, and
+ // class members, any of which may be null.
+ //
+ extend : function(child, parent, _protoFn, _protoAtts) {
+ _protoFn = _protoFn || {};
+ _protoAtts = _protoAtts || {};
+ parent = _isa(parent) ? parent : [ parent ];
+
+ for (var i = 0; i < parent.length; i++) {
+ for (var j in parent[i].prototype) {
+ if(parent[i].prototype.hasOwnProperty(j)) {
+ child.prototype[j] = parent[i].prototype[j];
+ }
+ }
+ }
+
+ var _makeFn = function(name) {
+ return function() {
+ for (var i = 0; i < parent.length; i++) {
+ if (parent[i].prototype[name])
+ parent[i].prototype[name].apply(this, arguments);
+ }
+ return _protoFn[name].apply(this, arguments);
+ };
+ };
+
+ for (var k in _protoFn) {
+ child.prototype[k] = _makeFn(k);
+ }
+
+ return child;
+ },
+ uuid : function() {
+ return ('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+ var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
+ return v.toString(16);
+ }));
+ },
+ logEnabled : true,
+ log : function() {
+ if (jsPlumbUtil.logEnabled && typeof console != "undefined") {
+ try {
+ var msg = arguments[arguments.length - 1];
+ console.log(msg);
+ }
+ catch (e) {}
+ }
+ },
+ group : function(g) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.group(g); },
+ groupEnd : function(g) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.groupEnd(g); },
+ time : function(t) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.time(t); },
+ timeEnd : function(t) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.timeEnd(t); },
+
+ /**
+ * helper to remove an element from the DOM.
+ */
+ removeElement : function(element) {
+ if (element != null && element.parentNode != null) {
+ element.parentNode.removeChild(element);
+ }
+ },
+ /**
+ * helper to remove a list of elements from the DOM.
+ */
+ removeElements : function(elements) {
+ for ( var i = 0; i < elements.length; i++)
+ jsPlumbUtil.removeElement(elements[i]);
+ },
+ /*
+ * Function: sizeElement
+ * Helper to size and position an element. You would typically use
+ * this when writing your own Connector or Endpoint implementation.
+ *
+ * Parameters:
+ * x - [int] x position for the element origin
+ * y - [int] y position for the element origin
+ * w - [int] width of the element
+ * h - [int] height of the element
+ *
+ */
+ sizeElement : function(el, x, y, w, h) {
+ if (el) {
+ el.style.height = h + "px";
+ el.height = h;
+ el.style.width = w + "px";
+ el.width = w;
+ el.style.left = x + "px";
+ el.style.top = y + "px";
+ }
+ },
+ /**
+ * @name jsPlumbUtil.wrap
+ * @desc Wraps one function with another, creating a placeholder for the
+ * wrapped function if it was null. this is used to wrap the various
+ * drag/drop event functions - to allow jsPlumb to be notified of
+ * important lifecycle events without imposing itself on the user's
+ * drag/drop functionality.
+ * @param {Function} wrappedFunction original function to wrap; may be null.
+ * @param {Function} newFunction function to wrap the original with.
+ * @param {Object} [returnOnThisValue] Optional. Indicates that the wrappedFunction should
+ * not be executed if the newFunction returns a value matching 'returnOnThisValue'.
+ * note that this is a simple comparison and only works for primitives right now.
+ */
+ wrap : function(wrappedFunction, newFunction, returnOnThisValue) {
+ wrappedFunction = wrappedFunction || function() { };
+ newFunction = newFunction || function() { };
+ return function() {
+ var r = null;
+ try {
+ r = newFunction.apply(this, arguments);
+ } catch (e) {
+ jsPlumbUtil.log("jsPlumb function failed : " + e);
+ }
+ if (returnOnThisValue == null || (r !== returnOnThisValue)) {
+ try {
+ r = wrappedFunction.apply(this, arguments);
+ } catch (e) {
+ jsPlumbUtil.log("wrapped function failed : " + e);
+ }
+ }
+ return r;
+ };
+ }
+ };
+
+
+ jsPlumbUtil.EventGenerator = function() {
+ var _listeners = {}, eventsSuspended = false;
+
+ // this is a list of events that should re-throw any errors that occur during their dispatch. as of 1.3.0 this is private to
+ // jsPlumb, but it seems feasible that people might want to manipulate this list. the thinking is that we don't want event
+ // listeners to bring down jsPlumb - or do we. i can't make up my mind about this, but i know i want to hear about it if the "ready"
+ // event fails, because then my page has most likely not initialised. so i have this halfway-house solution. it will be interesting
+ // to hear what other people think.
+ var eventsToDieOn = [ "ready" ];
+
+ this.bind = function(event, listener, insertAtStart) {
+ jsPlumbUtil.addToList(_listeners, event, listener, true);
+ return this;
+ };
+
+ this.fire = function(event, value, originalEvent) {
+ if (!eventsSuspended && _listeners[event]) {
+ // instead of looping through the array we get a counter and a length, because it is possible
+ // that an event fired from here could cause the object to get cleaned up, which would throw
+ // away the listeners. so after each cycle through the loop we check to ensure we haven't
+ // been nuked.
+ var l = _listeners[event].length, i = 0, _gone = false, ret = null;
+ if (!this.shouldFireEvent || this.shouldFireEvent(event, value, originalEvent)) {
+ while (!_gone && i < l && ret !== false) {
+
+ // doing it this way rather than catching and then possibly re-throwing means that an error propagated by this
+ // method will have the whole call stack available in the debugger.
+ if (jsPlumbUtil.findWithFunction(eventsToDieOn, function(e) { return e === event; }) != -1)
+ _listeners[event][i](value, originalEvent);
+ else {
+ // for events we don't want to die on, catch and log.
+ try {
+ ret = _listeners[event][i](value, originalEvent);
+ } catch (e) {
+ jsPlumbUtil.log("jsPlumb: fire failed for event " + event + " : " + e);
+ }
+ }
+ i++;
+ if (_listeners == null || _listeners[event] == null) _gone = true;
+ }
+ }
+ }
+ return this;
+ };
+
+ this.unbind = function(event) {
+ if (event)
+ delete _listeners[event];
+ else {
+ _listeners = {};
+ }
+ return this;
+ };
+
+ this.getListener = function(forEvent) {
+ return _listeners[forEvent];
+ };
+ this.setSuspendEvents = function(val) {
+ eventsSuspended = val;
+ };
+ this.isSuspendEvents = function() {
+ return eventsSuspended;
+ };
+ this.cleanupListeners = function() {
+ for (var i in _listeners) {
+ _listeners[i].splice(0);
+ delete _listeners[i];
+ }
+ };
+ };
+
+
+ jsPlumbUtil.EventGenerator.prototype = {
+ cleanup:function() {
+ this.cleanupListeners();
+ }
+ };
+
+
+ // thanks MDC
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Ob…
+ if (!Function.prototype.bind) {
+ Function.prototype.bind = function (oThis) {
+ if (typeof this !== "function") {
+ // closest thing possible to the ECMAScript 5 internal IsCallable function
+ throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
+ }
+
+ var aArgs = Array.prototype.slice.call(arguments, 1),
+ fToBind = this,
+ fNOP = function () {},
+ fBound = function () {
+ return fToBind.apply(this instanceof fNOP && oThis ? this : oThis,
+ aArgs.concat(Array.prototype.slice.call(arguments)));
+ };
+
+ fNOP.prototype = this.prototype;
+ fBound.prototype = new fNOP();
+
+ return fBound;
+ };
+ }
+
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the base functionality for DOM type adapters.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+;(function() {
+
+ var canvasAvailable = !!document.createElement('canvas').getContext,
+ svgAvailable = !!window.SVGAngle || document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"),
+ // http://stackoverflow.com/questions/654112/how-do-you-detect-support-for-vml…
+ vmlAvailable = function() {
+ if (vmlAvailable.vml === undefined) {
+ var a = document.body.appendChild(document.createElement('div'));
+ a.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
+ var b = a.firstChild;
+ if (b != null && b.style != null) {
+ b.style.behavior = "url(#default#VML)";
+ vmlAvailable.vml = b ? typeof b.adj == "object": true;
+ }
+ else
+ vmlAvailable.vml = false;
+ a.parentNode.removeChild(a);
+ }
+ return vmlAvailable.vml;
+ };
+
+ /**
+ Manages dragging for some instance of jsPlumb.
+ */
+ var DragManager = function(_currentInstance) {
+ var _draggables = {}, _dlist = [], _delements = {}, _elementsWithEndpoints = {},
+ // elementids mapped to the draggable to which they belong.
+ _draggablesForElements = {};
+
+ /**
+ register some element as draggable. right now the drag init stuff is done elsewhere, and it is
+ possible that will continue to be the case.
+ */
+ this.register = function(el) {
+ var jpcl = jsPlumb.CurrentLibrary,
+ _el = jpcl.getElementObject(el),
+ id = _currentInstance.getId(el),
+ parentOffset = jpcl.getOffset(_el);
+
+ if (!_draggables[id]) {
+ _draggables[id] = el;
+ _dlist.push(el);
+ _delements[id] = {};
+ }
+
+ // look for child elements that have endpoints and register them against this draggable.
+ var _oneLevel = function(p, startOffset) {
+ if (p) {
+ for (var i = 0; i < p.childNodes.length; i++) {
+ if (p.childNodes[i].nodeType != 3 && p.childNodes[i].nodeType != 8) {
+ var cEl = jpcl.getElementObject(p.childNodes[i]),
+ cid = _currentInstance.getId(p.childNodes[i], null, true);
+ if (cid && _elementsWithEndpoints[cid] && _elementsWithEndpoints[cid] > 0) {
+ var cOff = jpcl.getOffset(cEl);
+ _delements[id][cid] = {
+ id:cid,
+ offset:{
+ left:cOff.left - parentOffset.left,
+ top:cOff.top - parentOffset.top
+ }
+ };
+ _draggablesForElements[cid] = id;
+ }
+ _oneLevel(p.childNodes[i]);
+ }
+ }
+ }
+ };
+
+ _oneLevel(el);
+ };
+
+ // refresh the offsets for child elements of this element.
+ this.updateOffsets = function(elId) {
+ var jpcl = jsPlumb.CurrentLibrary,
+ el = jpcl.getElementObject(elId),
+ domEl = jpcl.getDOMElement(el),
+ id = _currentInstance.getId(domEl),
+ children = _delements[id],
+ parentOffset = jpcl.getOffset(el);
+
+ if (children) {
+ for (var i in children) {
+ var cel = jpcl.getElementObject(i),
+ cOff = jpcl.getOffset(cel);
+
+ _delements[id][i] = {
+ id:i,
+ offset:{
+ left:cOff.left - parentOffset.left,
+ top:cOff.top - parentOffset.top
+ }
+ };
+ _draggablesForElements[i] = id;
+ }
+ }
+ };
+
+ /**
+ notification that an endpoint was added to the given el. we go up from that el's parent
+ node, looking for a parent that has been registered as a draggable. if we find one, we add this
+ el to that parent's list of elements to update on drag (if it is not there already)
+ */
+ this.endpointAdded = function(el) {
+ var jpcl = jsPlumb.CurrentLibrary, b = document.body, id = _currentInstance.getId(el),
+ c = jpcl.getElementObject(el),
+ cLoc = jsPlumb.CurrentLibrary.getOffset(c),
+ p = el.parentNode, done = p == b;
+
+ _elementsWithEndpoints[id] = _elementsWithEndpoints[id] ? _elementsWithEndpoints[id] + 1 : 1;
+
+ while (p != null && p != b) {
+ var pid = _currentInstance.getId(p, null, true);
+ if (pid && _draggables[pid]) {
+ var idx = -1, pEl = jpcl.getElementObject(p), pLoc = jpcl.getOffset(pEl);
+
+ if (_delements[pid][id] == null) {
+ _delements[pid][id] = {
+ id:id,
+ offset:{
+ left:cLoc.left - pLoc.left,
+ top:cLoc.top - pLoc.top
+ }
+ };
+ _draggablesForElements[id] = pid;
+ }
+ break;
+ }
+ p = p.parentNode;
+ }
+ };
+
+ this.endpointDeleted = function(endpoint) {
+ if (_elementsWithEndpoints[endpoint.elementId]) {
+ _elementsWithEndpoints[endpoint.elementId]--;
+ if (_elementsWithEndpoints[endpoint.elementId] <= 0) {
+ for (var i in _delements) {
+ if (_delements[i]) {
+ delete _delements[i][endpoint.elementId];
+ delete _draggablesForElements[endpoint.elementId];
+ }
+ }
+ }
+ }
+ };
+
+ this.changeId = function(oldId, newId) {
+ _delements[newId] = _delements[oldId];
+ _delements[oldId] = {};
+ _draggablesForElements[newId] = _draggablesForElements[oldId];
+ _draggablesForElements[oldId] = null;
+ };
+
+ this.getElementsForDraggable = function(id) {
+ return _delements[id];
+ };
+
+ this.elementRemoved = function(elementId) {
+ var elId = _draggablesForElements[elementId];
+ if (elId) {
+ delete _delements[elId][elementId];
+ delete _draggablesForElements[elementId];
+ }
+ };
+
+ this.reset = function() {
+ _draggables = {};
+ _dlist = [];
+ _delements = {};
+ _elementsWithEndpoints = {};
+ };
+
+ };
+
+ // for those browsers that dont have it. they still don't have it! but at least they won't crash.
+ if (!window.console)
+ window.console = { time:function(){}, timeEnd:function(){}, group:function(){}, groupEnd:function(){}, log:function(){} };
+
+ window.jsPlumbAdapter = {
+
+ headless:false,
+
+ getAttribute:function(el, attName) {
+ return el.getAttribute(attName);
+ },
+
+ setAttribute:function(el, a, v) {
+ el.setAttribute(a, v);
+ },
+
+ appendToRoot : function(node) {
+ document.body.appendChild(node);
+ },
+ getRenderModes : function() {
+ return [ "canvas", "svg", "vml" ];
+ },
+ isRenderModeAvailable : function(m) {
+ return {
+ "canvas":canvasAvailable,
+ "svg":svgAvailable,
+ "vml":vmlAvailable()
+ }[m];
+ },
+ getDragManager : function(_jsPlumb) {
+ return new DragManager(_jsPlumb);
+ },
+ setRenderMode : function(mode) {
+ var renderMode;
+
+ if (mode) {
+ mode = mode.toLowerCase();
+
+ var canvasAvailable = this.isRenderModeAvailable("canvas"),
+ svgAvailable = this.isRenderModeAvailable("svg"),
+ vmlAvailable = this.isRenderModeAvailable("vml");
+
+ // now test we actually have the capability to do this.
+ if (mode === "svg") {
+ if (svgAvailable) renderMode = "svg";
+ else if (canvasAvailable) renderMode = "canvas";
+ else if (vmlAvailable) renderMode = "vml";
+ }
+ else if (mode === "canvas" && canvasAvailable) renderMode = "canvas";
+ else if (vmlAvailable) renderMode = "vml";
+ }
+
+ return renderMode;
+ }
+ };
+
+
+ /*
+
+ addClass:
+
+ add: function( elem, classNames ) {
+ jQuery.each((classNames || "").split(/\s+/), function(i, className){
+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+ elem.className += (elem.className ? " " : "") + className;
+ });
+ },
+ */
+
+ /*
+
+ removeClass:
+
+ elem.className = classNames !== undefined ?
+ jQuery.grep(elem.className.split(/\s+/), function(className){
+ return !jQuery.className.has( classNames, className );
+ }).join(" ") :
+
+*/
+
+})();
+/**
+ * @module jsPlumb
+ * @description Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * - [Demo Site](http://jsplumb.org)
+ * - [GitHub](http://github.com/sporritt/jsplumb)
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+ */
+;(function() {
+
+ var _ju = jsPlumbUtil,
+ _addClass = function(el, clazz) { jsPlumb.CurrentLibrary.addClass(_gel(el), clazz); },
+ _hasClass = function(el, clazz) { return jsPlumb.CurrentLibrary.hasClass(_gel(el), clazz); },
+ _removeClass = function(el, clazz) { jsPlumb.CurrentLibrary.removeClass(_gel(el), clazz); },
+ _gel = function(el) { return jsPlumb.CurrentLibrary.getElementObject(el); },
+ _dom = function(el) { return jsPlumb.CurrentLibrary.getDOMElement(el); },
+ _getOffset = function(el, _instance) {
+ var o = jsPlumb.CurrentLibrary.getOffset(_gel(el));
+ if (_instance != null) {
+ var z = _instance.getZoom();
+ return {left:o.left / z, top:o.top / z };
+ }
+ else
+ return o;
+ },
+ _getSize = function(el) {
+ return jsPlumb.CurrentLibrary.getSize(_gel(el));
+ },
+
+ /**
+ * creates a timestamp, using milliseconds since 1970, but as a string.
+ */
+ _timestamp = function() { return "" + (new Date()).getTime(); },
+
+ // helper method to update the hover style whenever it, or paintStyle, changes.
+ // we use paintStyle as the foundation and merge hoverPaintStyle over the
+ // top.
+ _updateHoverStyle = function(component) {
+ if (component._jsPlumb.paintStyle && component._jsPlumb.hoverPaintStyle) {
+ var mergedHoverStyle = {};
+ jsPlumb.extend(mergedHoverStyle, component._jsPlumb.paintStyle);
+ jsPlumb.extend(mergedHoverStyle, component._jsPlumb.hoverPaintStyle);
+ delete component._jsPlumb.hoverPaintStyle;
+ // we want the fillStyle of paintStyle to override a gradient, if possible.
+ if (mergedHoverStyle.gradient && component._jsPlumb.paintStyle.fillStyle)
+ delete mergedHoverStyle.gradient;
+ component._jsPlumb.hoverPaintStyle = mergedHoverStyle;
+ }
+ },
+ events = [ "click", "dblclick", "mouseenter", "mouseout", "mousemove", "mousedown", "mouseup", "contextmenu" ],
+ eventFilters = { "mouseout":"mouseexit" },
+ _updateAttachedElements = function(component, state, timestamp, sourceElement) {
+ var affectedElements = component.getAttachedElements();
+ if (affectedElements) {
+ for (var i = 0, j = affectedElements.length; i < j; i++) {
+ if (!sourceElement || sourceElement != affectedElements[i])
+ affectedElements[i].setHover(state, true, timestamp); // tell the attached elements not to inform their own attached elements.
+ }
+ }
+ },
+ _splitType = function(t) { return t == null ? null : t.split(" "); },
+ _applyTypes = function(component, params, doNotRepaint) {
+ if (component.getDefaultType) {
+ var td = component.getTypeDescriptor();
+
+ var o = _ju.merge({}, component.getDefaultType());
+ for (var i = 0, j = component._jsPlumb.types.length; i < j; i++)
+ o = _ju.merge(o, component._jsPlumb.instance.getType(component._jsPlumb.types[i], td));
+
+ if (params) {
+ o = _ju.populate(o, params);
+ }
+
+ component.applyType(o, doNotRepaint);
+ if (!doNotRepaint) component.repaint();
+ }
+ },
+
+// ------------------------------ BEGIN jsPlumbUIComponent --------------------------------------------
+
+ jsPlumbUIComponent = window.jsPlumbUIComponent = function(params) {
+
+ jsPlumbUtil.EventGenerator.apply(this, arguments);
+
+ var self = this,
+ a = arguments,
+ idPrefix = self.idPrefix,
+ id = idPrefix + (new Date()).getTime(),
+ jpcl = jsPlumb.CurrentLibrary;
+
+ this._jsPlumb = {
+ instance: params._jsPlumb,
+ parameters:params.parameters || {},
+ paintStyle:null,
+ hoverPaintStyle:null,
+ paintStyleInUse:null,
+ hover:false,
+ beforeDetach:params.beforeDetach,
+ beforeDrop:params.beforeDrop,
+ overlayPlacements : [],
+ hoverClass: params.hoverClass || params._jsPlumb.Defaults.HoverClass || jsPlumb.Defaults.HoverClass,
+ types:[]
+ };
+
+ this.getId = function() { return id; };
+
+ // all components can generate events
+
+ if (params.events) {
+ for (var i in params.events)
+ self.bind(i, params.events[i]);
+ }
+
+ // all components get this clone function.
+ // TODO issue 116 showed a problem with this - it seems 'a' that is in
+ // the clone function's scope is shared by all invocations of it, the classic
+ // JS closure problem. for now, jsPlumb does a version of this inline where
+ // it used to call clone. but it would be nice to find some time to look
+ // further at this.
+ this.clone = function() {
+ var o = {};//new Object();
+ this.constructor.apply(o, a);
+ return o;
+ }.bind(this);
+
+
+ // user can supply a beforeDetach callback, which will be executed before a detach
+ // is performed; returning false prevents the detach.
+ this.isDetachAllowed = function(connection) {
+ var r = true;
+ if (this._jsPlumb.beforeDetach) {
+ try {
+ r = this._jsPlumb.beforeDetach(connection);
+ }
+ catch (e) { _ju.log("jsPlumb: beforeDetach callback failed", e); }
+ }
+ return r;
+ };
+
+ // user can supply a beforeDrop callback, which will be executed before a dropped
+ // connection is confirmed. user can return false to reject connection.
+ this.isDropAllowed = function(sourceId, targetId, scope, connection, dropEndpoint) {
+ var r = this._jsPlumb.instance.checkCondition("beforeDrop", {
+ sourceId:sourceId,
+ targetId:targetId,
+ scope:scope,
+ connection:connection,
+ dropEndpoint:dropEndpoint
+ });
+ if (this._jsPlumb.beforeDrop) {
+ try {
+ r = this._jsPlumb.beforeDrop({
+ sourceId:sourceId,
+ targetId:targetId,
+ scope:scope,
+ connection:connection,
+ dropEndpoint:dropEndpoint
+ });
+ }
+ catch (e) { _ju.log("jsPlumb: beforeDrop callback failed", e); }
+ }
+ return r;
+ };
+
+ var boundListeners = [],
+ bindAListener = function(obj, type, fn) {
+ boundListeners.push([obj, type, fn]);
+ obj.bind(type, fn);
+ },
+ domListeners = [],
+ bindOne = function(o, c, evt) {
+ var filteredEvent = eventFilters[evt] || evt,
+ fn = function(ee) {
+ c.fire(filteredEvent, c, ee);
+ };
+ domListeners.push([o, evt, fn]);
+ jpcl.bind(o, evt, fn);
+ },
+ unbindOne = function(o, evt, fn) {
+ var filteredEvent = eventFilters[evt] || evt;
+ jpcl.unbind(o, evt, fn);
+ };
+
+ this.bindListeners = function(obj, _self, _hoverFunction) {
+ bindAListener(obj, "click", function(ep, e) { _self.fire("click", _self, e); });
+ bindAListener(obj, "dblclick", function(ep, e) { _self.fire("dblclick", _self, e); });
+ bindAListener(obj, "contextmenu", function(ep, e) { _self.fire("contextmenu", _self, e); });
+ bindAListener(obj, "mouseenter", function(ep, e) {
+ if (!_self.isHover()) {
+ _hoverFunction(true);
+ _self.fire("mouseenter", _self, e);
+ }
+ });
+ bindAListener(obj, "mouseexit", function(ep, e) {
+ if (_self.isHover()) {
+ _hoverFunction(false);
+ _self.fire("mouseexit", _self, e);
+ }
+ });
+ bindAListener(obj, "mousedown", function(ep, e) { _self.fire("mousedown", _self, e); });
+ bindAListener(obj, "mouseup", function(ep, e) { _self.fire("mouseup", _self, e); });
+ };
+
+ this.unbindListeners = function() {
+ for (var i = 0; i < boundListeners.length; i++) {
+ var o = boundListeners[i];
+ o[0].unbind(o[1], o[2]);
+ }
+ boundListeners = null;
+ };
+
+ this.attachListeners = function(o, c) {
+ for (var i = 0, j = events.length; i < j; i++) {
+ bindOne(o, c, events[i]);
+ }
+ };
+ this.detachListeners = function() {
+ for (var i = 0; i < domListeners.length; i++) {
+ unbindOne(domListeners[i][0], domListeners[i][1], domListeners[i][2]);
+ }
+ domListeners = null;
+ };
+
+ this.reattachListenersForElement = function(o) {
+ if (arguments.length > 1) {
+ for (var i = 0, j = events.length; i < j; i++)
+ unbindOne(o, events[i]);
+ for (i = 1, j = arguments.length; i < j; i++)
+ this.attachListeners(o, arguments[i]);
+ }
+ };
+ };
+
+ jsPlumbUtil.extend(jsPlumbUIComponent, jsPlumbUtil.EventGenerator, {
+
+ getParameter : function(name) {
+ return this._jsPlumb.parameters[name];
+ },
+
+ setParameter : function(name, value) {
+ this._jsPlumb.parameters[name] = value;
+ },
+
+ getParameters : function() {
+ return this._jsPlumb.parameters;
+ },
+
+ setParameters : function(p) {
+ this._jsPlumb.parameters = p;
+ },
+
+ addClass : function(clazz) {
+ if (this.canvas != null)
+ _addClass(this.canvas, clazz);
+ },
+
+ removeClass : function(clazz) {
+ if (this.canvas != null)
+ _removeClass(this.canvas, clazz);
+ },
+
+ setType : function(typeId, params, doNotRepaint) {
+ this._jsPlumb.types = _splitType(typeId) || [];
+ _applyTypes(this, params, doNotRepaint);
+ },
+
+ getType : function() {
+ return this._jsPlumb.types;
+ },
+
+ reapplyTypes : function(params, doNotRepaint) {
+ _applyTypes(this, params, doNotRepaint);
+ },
+
+ hasType : function(typeId) {
+ return jsPlumbUtil.indexOf(this._jsPlumb.types, typeId) != -1;
+ },
+
+ addType : function(typeId, params, doNotRepaint) {
+ var t = _splitType(typeId), _cont = false;
+ if (t != null) {
+ for (var i = 0, j = t.length; i < j; i++) {
+ if (!this.hasType(t[i])) {
+ this._jsPlumb.types.push(t[i]);
+ _cont = true;
+ }
+ }
+ if (_cont) _applyTypes(this, params, doNotRepaint);
+ }
+ },
+
+ removeType : function(typeId, doNotRepaint) {
+ var t = _splitType(typeId), _cont = false, _one = function(tt) {
+ var idx = _ju.indexOf(this._jsPlumb.types, tt);
+ if (idx != -1) {
+ this._jsPlumb.types.splice(idx, 1);
+ return true;
+ }
+ return false;
+ }.bind(this);
+
+ if (t != null) {
+ for (var i = 0,j = t.length; i < j; i++) {
+ _cont = _one(t[i]) || _cont;
+ }
+ if (_cont) _applyTypes(this, null, doNotRepaint);
+ }
+ },
+
+ toggleType : function(typeId, params, doNotRepaint) {
+ var t = _splitType(typeId);
+ if (t != null) {
+ for (var i = 0, j = t.length; i < j; i++) {
+ var idx = jsPlumbUtil.indexOf(this._jsPlumb.types, t[i]);
+ if (idx != -1)
+ this._jsPlumb.types.splice(idx, 1);
+ else
+ this._jsPlumb.types.push(t[i]);
+ }
+
+ _applyTypes(this, params, doNotRepaint);
+ }
+ },
+ applyType : function(t, doNotRepaint) {
+ this.setPaintStyle(t.paintStyle, doNotRepaint);
+ this.setHoverPaintStyle(t.hoverPaintStyle, doNotRepaint);
+ if (t.parameters){
+ for (var i in t.parameters)
+ this.setParameter(i, t.parameters[i]);
+ }
+ },
+ setPaintStyle : function(style, doNotRepaint) {
+// this._jsPlumb.paintStyle = jsPlumb.extend({}, style);
+// TODO figure out if we want components to clone paintStyle so as not to share it.
+ this._jsPlumb.paintStyle = style;
+ this._jsPlumb.paintStyleInUse = this._jsPlumb.paintStyle;
+ _updateHoverStyle(this);
+ if (!doNotRepaint) this.repaint();
+ },
+ getPaintStyle : function() {
+ return this._jsPlumb.paintStyle;
+ },
+ setHoverPaintStyle : function(style, doNotRepaint) {
+ //this._jsPlumb.hoverPaintStyle = jsPlumb.extend({}, style);
+// TODO figure out if we want components to clone paintStyle so as not to share it.
+ this._jsPlumb.hoverPaintStyle = style;
+ _updateHoverStyle(this);
+ if (!doNotRepaint) this.repaint();
+ },
+ getHoverPaintStyle : function() {
+ return this._jsPlumb.hoverPaintStyle;
+ },
+ cleanup:function() {
+ this.unbindListeners();
+ this.detachListeners();
+ },
+ destroy:function() {
+ this.cleanupListeners();
+ this.clone = null;
+ this._jsPlumb = null;
+ },
+
+ isHover : function() { return this._jsPlumb.hover; },
+
+ setHover : function(hover, ignoreAttachedElements, timestamp) {
+ var jpcl = jsPlumb.CurrentLibrary;
+ // while dragging, we ignore these events. this keeps the UI from flashing and
+ // swishing and whatevering.
+ if (this._jsPlumb && !this._jsPlumb.instance.currentlyDragging && !this._jsPlumb.instance.isHoverSuspended()) {
+
+ this._jsPlumb.hover = hover;
+
+ if (this.canvas != null) {
+ if (this._jsPlumb.instance.hoverClass != null) {
+ jpcl[hover ? "addClass" : "removeClass"](this.canvas, this._jsPlumb.instance.hoverClass);
+ }
+ }
+ if (this._jsPlumb.hoverPaintStyle != null) {
+ this._jsPlumb.paintStyleInUse = hover ? this._jsPlumb.hoverPaintStyle : this._jsPlumb.paintStyle;
+ if (!this._jsPlumb.instance.isSuspendDrawing()) {
+ timestamp = timestamp || _timestamp();
+ this.repaint({timestamp:timestamp, recalc:false});
+ }
+ }
+ // get the list of other affected elements, if supported by this component.
+ // for a connection, its the endpoints. for an endpoint, its the connections! surprise.
+ if (this.getAttachedElements && !ignoreAttachedElements)
+ _updateAttachedElements(this, hover, _timestamp(), this);
+ }
+ }
+ });
+
+// ------------------------------ END jsPlumbUIComponent --------------------------------------------
+
+// ------------------------------ BEGIN OverlayCapablejsPlumbUIComponent --------------------------------------------
+
+ var _internalLabelOverlayId = "__label",
+ // helper to get the index of some overlay
+ _getOverlayIndex = function(component, id) {
+ var idx = -1;
+ for (var i = 0, j = component._jsPlumb.overlays.length; i < j; i++) {
+ if (id === component._jsPlumb.overlays[i].id) {
+ idx = i;
+ break;
+ }
+ }
+ return idx;
+ },
+ // this is a shortcut helper method to let people add a label as
+ // overlay.
+ _makeLabelOverlay = function(component, params) {
+
+ var _params = {
+ cssClass:params.cssClass,
+ labelStyle : component.labelStyle,
+ id:_internalLabelOverlayId,
+ component:component,
+ _jsPlumb:component._jsPlumb.instance // TODO not necessary, since the instance can be accessed through the component.
+ },
+ mergedParams = jsPlumb.extend(_params, params);
+
+ return new jsPlumb.Overlays[component._jsPlumb.instance.getRenderMode()].Label( mergedParams );
+ },
+ _processOverlay = function(component, o) {
+ var _newOverlay = null;
+ if (_ju.isArray(o)) { // this is for the shorthand ["Arrow", { width:50 }] syntax
+ // there's also a three arg version:
+ // ["Arrow", { width:50 }, {location:0.7}]
+ // which merges the 3rd arg into the 2nd.
+ var type = o[0],
+ // make a copy of the object so as not to mess up anyone else's reference...
+ p = jsPlumb.extend({component:component, _jsPlumb:component._jsPlumb.instance}, o[1]);
+ if (o.length == 3) jsPlumb.extend(p, o[2]);
+ _newOverlay = new jsPlumb.Overlays[component._jsPlumb.instance.getRenderMode()][type](p);
+ } else if (o.constructor == String) {
+ _newOverlay = new jsPlumb.Overlays[component._jsPlumb.instance.getRenderMode()][o]({component:component, _jsPlumb:component._jsPlumb.instance});
+ } else {
+ _newOverlay = o;
+ }
+
+ component._jsPlumb.overlays.push(_newOverlay);
+ },
+ _calculateOverlaysToAdd = function(component, params) {
+ var defaultKeys = component.defaultOverlayKeys || [], o = params.overlays,
+ checkKey = function(k) {
+ return component._jsPlumb.instance.Defaults[k] || jsPlumb.Defaults[k] || [];
+ };
+
+ if (!o) o = [];
+
+ for (var i = 0, j = defaultKeys.length; i < j; i++)
+ o.unshift.apply(o, checkKey(defaultKeys[i]));
+
+ return o;
+ },
+ OverlayCapableJsPlumbUIComponent = window.OverlayCapableJsPlumbUIComponent = function(params) {
+
+ jsPlumbUIComponent.apply(this, arguments);
+ this._jsPlumb.overlays = [];
+
+ var _overlays = _calculateOverlaysToAdd(this, params);
+ if (_overlays) {
+ for (var i = 0, j = _overlays.length; i < j; i++) {
+ _processOverlay(this, _overlays[i]);
+ }
+ }
+
+ if (params.label) {
+ var loc = params.labelLocation || this.defaultLabelLocation || 0.5,
+ labelStyle = params.labelStyle || this._jsPlumb.instance.Defaults.LabelStyle || jsPlumb.Defaults.LabelStyle;
+
+ this._jsPlumb.overlays.push(_makeLabelOverlay(this, {
+ label:params.label,
+ location:loc,
+ labelStyle:labelStyle
+ }));
+ }
+ };
+
+ jsPlumbUtil.extend(OverlayCapableJsPlumbUIComponent, jsPlumbUIComponent, {
+ applyType : function(t, doNotRepaint) {
+ this.removeAllOverlays(doNotRepaint);
+ if (t.overlays) {
+ for (var i = 0, j = t.overlays.length; i < j; i++)
+ this.addOverlay(t.overlays[i], true);
+ }
+ },
+ setHover : function(hover, ignoreAttachedElements, timestamp) {
+ if (this._jsPlumb && !this._jsPlumb.instance.isConnectionBeingDragged()) {
+ for (var i = 0, j = this._jsPlumb.overlays.length; i < j; i++) {
+ this._jsPlumb.overlays[i][hover ? "addClass":"removeClass"](this._jsPlumb.instance.hoverClass);
+ }
+ }
+ },
+ addOverlay : function(overlay, doNotRepaint) {
+ _processOverlay(this, overlay);
+ if (!doNotRepaint) this.repaint();
+ },
+ getOverlay : function(id) {
+ var idx = _getOverlayIndex(this, id);
+ return idx >= 0 ? this._jsPlumb.overlays[idx] : null;
+ },
+ getOverlays : function() {
+ return this._jsPlumb.overlays;
+ },
+ hideOverlay : function(id) {
+ var o = this.getOverlay(id);
+ if (o) o.hide();
+ },
+ hideOverlays : function() {
+ for (var i = 0, j = this._jsPlumb.overlays.length; i < j; i++)
+ this._jsPlumb.overlays[i].hide();
+ },
+ showOverlay : function(id) {
+ var o = this.getOverlay(id);
+ if (o) o.show();
+ },
+ showOverlays : function() {
+ for (var i = 0, j = this._jsPlumb.overlays.length; i < j; i++)
+ this._jsPlumb.overlays[i].show();
+ },
+ removeAllOverlays : function(doNotRepaint) {
+ for (var i = 0, j = this._jsPlumb.overlays.length; i < j; i++) {
+ if (this._jsPlumb.overlays[i].cleanup) this._jsPlumb.overlays[i].cleanup();
+ }
+
+ this._jsPlumb.overlays.splice(0, this._jsPlumb.overlays.length);
+ if (!doNotRepaint)
+ this.repaint();
+ },
+ removeOverlay : function(overlayId) {
+ var idx = _getOverlayIndex(this, overlayId);
+ if (idx != -1) {
+ var o = this._jsPlumb.overlays[idx];
+ if (o.cleanup) o.cleanup();
+ this._jsPlumb.overlays.splice(idx, 1);
+ }
+ },
+ removeOverlays : function() {
+ for (var i = 0, j = arguments.length; i < j; i++)
+ this.removeOverlay(arguments[i]);
+ },
+ getLabel : function() {
+ var lo = this.getOverlay(_internalLabelOverlayId);
+ return lo != null ? lo.getLabel() : null;
+ },
+ getLabelOverlay : function() {
+ return this.getOverlay(_internalLabelOverlayId);
+ },
+ setLabel : function(l) {
+ var lo = this.getOverlay(_internalLabelOverlayId);
+ if (!lo) {
+ var params = l.constructor == String || l.constructor == Function ? { label:l } : l;
+ lo = _makeLabelOverlay(this, params);
+ this._jsPlumb.overlays.push(lo);
+ }
+ else {
+ if (l.constructor == String || l.constructor == Function) lo.setLabel(l);
+ else {
+ if (l.label) lo.setLabel(l.label);
+ if (l.location) lo.setLocation(l.location);
+ }
+ }
+
+ if (!this._jsPlumb.instance.isSuspendDrawing())
+ this.repaint();
+ },
+ cleanup:function() {
+ for (var i = 0; i < this._jsPlumb.overlays.length; i++) {
+ this._jsPlumb.overlays[i].cleanup();
+ this._jsPlumb.overlays[i].destroy();
+ }
+ this._jsPlumb.overlays.splice(0);
+ }
+ });
+
+// ------------------------------ END OverlayCapablejsPlumbUIComponent --------------------------------------------
+
+ var _jsPlumbInstanceIndex = 0,
+ getInstanceIndex = function() {
+ var i = _jsPlumbInstanceIndex + 1;
+ _jsPlumbInstanceIndex++;
+ return i;
+ };
+
+ var jsPlumbInstance = window.jsPlumbInstance = function(_defaults) {
+
+ this.Defaults = {
+ Anchor : "BottomCenter",
+ Anchors : [ null, null ],
+ ConnectionsDetachable : true,
+ ConnectionOverlays : [ ],
+ Connector : "Bezier",
+ Container : null,
+ DoNotThrowErrors:false,
+ DragOptions : { },
+ DropOptions : { },
+ Endpoint : "Dot",
+ EndpointOverlays : [ ],
+ Endpoints : [ null, null ],
+ EndpointStyle : { fillStyle : "#456" },
+ EndpointStyles : [ null, null ],
+ EndpointHoverStyle : null,
+ EndpointHoverStyles : [ null, null ],
+ HoverPaintStyle : null,
+ LabelStyle : { color : "black" },
+ LogEnabled : false,
+ Overlays : [ ],
+ MaxConnections : 1,
+ PaintStyle : { lineWidth : 8, strokeStyle : "#456" },
+ ReattachConnections:false,
+ RenderMode : "svg",
+ Scope : "jsPlumb_DefaultScope"
+ };
+ if (_defaults) jsPlumb.extend(this.Defaults, _defaults);
+
+ this.logEnabled = this.Defaults.LogEnabled;
+ this._connectionTypes = {};
+ this._endpointTypes = {};
+
+ jsPlumbUtil.EventGenerator.apply(this);
+
+ var _currentInstance = this,
+ _instanceIndex = getInstanceIndex(),
+ _bb = _currentInstance.bind,
+ _initialDefaults = {},
+ _zoom = 1,
+ _info = function(el) {
+ var _el = _dom(el);
+ return { el:_el, id:(jsPlumbUtil.isString(el) && _el == null) ? el : _getId(_el) };
+ };
+
+ this.getInstanceIndex = function() { return _instanceIndex; };
+
+ this.setZoom = function(z, repaintEverything) {
+ _zoom = z;
+ if (repaintEverything) _currentInstance.repaintEverything();
+ };
+ this.getZoom = function() { return _zoom; };
+
+ for (var i in this.Defaults)
+ _initialDefaults[i] = this.Defaults[i];
+
+ this.bind = function(event, fn) {
+ if ("ready" === event && initialized) fn();
+ else _bb.apply(_currentInstance,[event, fn]);
+ };
+
+ _currentInstance.importDefaults = function(d) {
+ for (var i in d) {
+ _currentInstance.Defaults[i] = d[i];
+ }
+ return _currentInstance;
+ };
+
+ _currentInstance.restoreDefaults = function() {
+ _currentInstance.Defaults = jsPlumb.extend({}, _initialDefaults);
+ return _currentInstance;
+ };
+
+ var log = null,
+ resizeTimer = null,
+ initialized = false,
+ // TODO remove from window scope
+ connections = [],
+ // map of element id -> endpoint lists. an element can have an arbitrary
+ // number of endpoints on it, and not all of them have to be connected
+ // to anything.
+ endpointsByElement = {},
+ endpointsByUUID = {},
+ offsets = {},
+ offsetTimestamps = {},
+ floatingConnections = {},
+ draggableStates = {},
+ connectionBeingDragged = false,
+ sizes = [],
+ _suspendDrawing = false,
+ _suspendedAt = null,
+ DEFAULT_SCOPE = this.Defaults.Scope,
+ renderMode = null, // will be set in init()
+ _curIdStamp = 1,
+ _idstamp = function() { return "" + _curIdStamp++; },
+
+ //
+ // appends an element to some other element, which is calculated as follows:
+ //
+ // 1. if _currentInstance.Defaults.Container exists, use that element.
+ // 2. if the 'parent' parameter exists, use that.
+ // 3. otherwise just use the root element (for DOM usage, the document body).
+ //
+ //
+ _appendElement = function(el, parent) {
+ if (_currentInstance.Defaults.Container)
+ jsPlumb.CurrentLibrary.appendElement(el, _currentInstance.Defaults.Container);
+ else if (!parent)
+ jsPlumbAdapter.appendToRoot(el);
+ else
+ jsPlumb.CurrentLibrary.appendElement(el, parent);
+ },
+
+ //
+ // YUI, for some reason, put the result of a Y.all call into an object that contains
+ // a '_nodes' array, instead of handing back an array-like object like the other
+ // libraries do.
+ //
+ _convertYUICollection = function(c) {
+ return c._nodes ? c._nodes : c;
+ },
+
+ //
+ // Draws an endpoint and its connections. this is the main entry point into drawing connections as well
+ // as endpoints, since jsPlumb is endpoint-centric under the hood.
+ //
+ // @param element element to draw (of type library specific element object)
+ // @param ui UI object from current library's event system. optional.
+ // @param timestamp timestamp for this paint cycle. used to speed things up a little by cutting down the amount of offset calculations we do.
+ // @param clearEdits defaults to false; indicates that mouse edits for connectors should be cleared
+ ///
+ _draw = function(element, ui, timestamp, clearEdits) {
+
+ // TODO is it correct to filter by headless at this top level? how would a headless adapter ever repaint?
+ if (!jsPlumbAdapter.headless && !_suspendDrawing) {
+ var id = _getId(element),
+ repaintEls = _currentInstance.dragManager.getElementsForDraggable(id);
+
+ if (timestamp == null) timestamp = _timestamp();
+
+ // update the offset of everything _before_ we try to draw anything.
+ var o = _updateOffset( { elId : id, offset : ui, recalc : false, timestamp : timestamp });
+
+ if (repaintEls) {
+ for (var i in repaintEls) {
+ _updateOffset( {
+ elId : repaintEls[i].id,
+ offset : {
+ left:o.o.left + repaintEls[i].offset.left,
+ top:o.o.top + repaintEls[i].offset.top
+ },
+ recalc : false,
+ timestamp : timestamp
+ });
+ }
+ }
+
+
+ _currentInstance.anchorManager.redraw(id, ui, timestamp, null, clearEdits);
+
+ if (repaintEls) {
+ for (var j in repaintEls) {
+ _currentInstance.anchorManager.redraw(repaintEls[j].id, ui, timestamp, repaintEls[j].offset, clearEdits, true);
+ }
+ }
+ }
+ },
+
+ //
+ // executes the given function against the given element if the first
+ // argument is an object, or the list of elements, if the first argument
+ // is a list. the function passed in takes (element, elementId) as
+ // arguments.
+ //
+ _elementProxy = function(element, fn) {
+ var retVal = null, el, id;
+ if (_ju.isArray(element)) {
+ retVal = [];
+ for ( var i = 0, j = element.length; i < j; i++) {
+ el = _gel(element[i]);
+ id = _currentInstance.getAttribute(el, "id");
+ retVal.push(fn(el, id)); // append return values to what we will return
+ }
+ } else {
+ el = _gel(element);
+ id = _currentInstance.getAttribute(el, "id");
+ retVal = fn(el, id);
+ }
+ return retVal;
+ },
+
+ //
+ // gets an Endpoint by uuid.
+ //
+ _getEndpoint = function(uuid) { return endpointsByUUID[uuid]; },
+
+ /**
+ * inits a draggable if it's not already initialised.
+ * TODO: somehow abstract this to the adapter, because the concept of "draggable" has no
+ * place on the server.
+ */
+ _initDraggableIfNecessary = function(element, isDraggable, dragOptions) {
+ // TODO move to DragManager?
+ if (!jsPlumbAdapter.headless) {
+ var _draggable = isDraggable == null ? false : isDraggable, jpcl = jsPlumb.CurrentLibrary;
+ if (_draggable) {
+ if (jpcl.isDragSupported(element) && !jpcl.isAlreadyDraggable(element)) {
+ var options = dragOptions || _currentInstance.Defaults.DragOptions || jsPlumb.Defaults.DragOptions;
+ options = jsPlumb.extend( {}, options); // make a copy.
+ var dragEvent = jpcl.dragEvents.drag,
+ stopEvent = jpcl.dragEvents.stop,
+ startEvent = jpcl.dragEvents.start;
+
+ options[startEvent] = _ju.wrap(options[startEvent], function() {
+ _currentInstance.setHoverSuspended(true);
+ _currentInstance.select({source:element}).addClass(_currentInstance.elementDraggingClass + " " + _currentInstance.sourceElementDraggingClass, true);
+ _currentInstance.select({target:element}).addClass(_currentInstance.elementDraggingClass + " " + _currentInstance.targetElementDraggingClass, true);
+ _currentInstance.setConnectionBeingDragged(true);
+ });
+
+ options[dragEvent] = _ju.wrap(options[dragEvent], function() {
+ var ui = jpcl.getUIPosition(arguments, _currentInstance.getZoom());
+ _draw(element, ui, null, true);
+ _addClass(element, "jsPlumb_dragged");
+ });
+ options[stopEvent] = _ju.wrap(options[stopEvent], function() {
+ var ui = jpcl.getUIPosition(arguments, _currentInstance.getZoom());
+ _draw(element, ui);
+ _removeClass(element, "jsPlumb_dragged");
+ _currentInstance.setHoverSuspended(false);
+ _currentInstance.select({source:element}).removeClass(_currentInstance.elementDraggingClass + " " + _currentInstance.sourceElementDraggingClass, true);
+ _currentInstance.select({target:element}).removeClass(_currentInstance.elementDraggingClass + " " + _currentInstance.targetElementDraggingClass, true);
+ _currentInstance.setConnectionBeingDragged(false);
+ });
+ var elId = _getId(element); // need ID
+ draggableStates[elId] = true;
+ var draggable = draggableStates[elId];
+ options.disabled = draggable == null ? false : !draggable;
+ jpcl.initDraggable(element, options, false, _currentInstance);
+ _currentInstance.dragManager.register(element);
+ }
+ }
+ }
+ },
+
+ /*
+ * prepares a final params object that can be passed to _newConnection, taking into account defaults, events, etc.
+ */
+ _prepareConnectionParams = function(params, referenceParams) {
+ var _p = jsPlumb.extend( { }, params);
+ if (referenceParams) jsPlumb.extend(_p, referenceParams);
+
+ // hotwire endpoints passed as source or target to sourceEndpoint/targetEndpoint, respectively.
+ if (_p.source) {
+ if (_p.source.endpoint)
+ _p.sourceEndpoint = _p.source;
+ else
+ _p.source = _dom(_p.source);
+ }
+ if (_p.target) {
+ if (_p.target.endpoint)
+ _p.targetEndpoint = _p.target;
+ else
+ _p.target = _dom(_p.target);
+ }
+
+ // test for endpoint uuids to connect
+ if (params.uuids) {
+ _p.sourceEndpoint = _getEndpoint(params.uuids[0]);
+ _p.targetEndpoint = _getEndpoint(params.uuids[1]);
+ }
+
+ // now ensure that if we do have Endpoints already, they're not full.
+ // source:
+ if (_p.sourceEndpoint && _p.sourceEndpoint.isFull()) {
+ _ju.log(_currentInstance, "could not add connection; source endpoint is full");
+ return;
+ }
+
+ // target:
+ if (_p.targetEndpoint && _p.targetEndpoint.isFull()) {
+ _ju.log(_currentInstance, "could not add connection; target endpoint is full");
+ return;
+ }
+
+ // if source endpoint mandates connection type and nothing specified in our params, use it.
+ if (!_p.type && _p.sourceEndpoint)
+ _p.type = _p.sourceEndpoint.connectionType;
+
+ // copy in any connectorOverlays that were specified on the source endpoint.
+ // it doesnt copy target endpoint overlays. i'm not sure if we want it to or not.
+ if (_p.sourceEndpoint && _p.sourceEndpoint.connectorOverlays) {
+ _p.overlays = _p.overlays || [];
+ for (var i = 0, j = _p.sourceEndpoint.connectorOverlays.length; i < j; i++) {
+ _p.overlays.push(_p.sourceEndpoint.connectorOverlays[i]);
+ }
+ }
+
+ // pointer events
+ if (!_p["pointer-events"] && _p.sourceEndpoint && _p.sourceEndpoint.connectorPointerEvents)
+ _p["pointer-events"] = _p.sourceEndpoint.connectorPointerEvents;
+
+ // if there's a target specified (which of course there should be), and there is no
+ // target endpoint specified, and 'newConnection' was not set to true, then we check to
+ // see if a prior call to makeTarget has provided us with the specs for the target endpoint, and
+ // we use those if so. additionally, if the makeTarget call was specified with 'uniqueEndpoint' set
+ // to true, then if that target endpoint has already been created, we re-use it.
+
+ var tid, tep, existingUniqueEndpoint, newEndpoint;
+
+ // TODO: this code can be refactored to be a little dry.
+ if (_p.target && !_p.target.endpoint && !_p.targetEndpoint && !_p.newConnection) {
+ tid = _getId(_p.target);
+ tep =_targetEndpointDefinitions[tid];
+ existingUniqueEndpoint = _targetEndpoints[tid];
+
+ if (tep) {
+ // if target not enabled, return.
+ if (!_targetsEnabled[tid]) return;
+
+ tep.isTarget = true;
+ // check for max connections??
+ newEndpoint = existingUniqueEndpoint != null ? existingUniqueEndpoint : _currentInstance.addEndpoint(_p.target, tep);
+ if (_targetEndpointsUnique[tid]) _targetEndpoints[tid] = newEndpoint;
+ _p.targetEndpoint = newEndpoint;
+ // TODO test options to makeTarget to see if we should do this?
+ newEndpoint._doNotDeleteOnDetach = false; // reset.
+ newEndpoint._deleteOnDetach = true;
+ }
+ }
+
+ // same thing, but for source.
+ if (_p.source && !_p.source.endpoint && !_p.sourceEndpoint && !_p.newConnection) {
+ tid = _getId(_p.source);
+ tep = _sourceEndpointDefinitions[tid];
+ existingUniqueEndpoint = _sourceEndpoints[tid];
+
+ if (tep) {
+ // if source not enabled, return.
+ if (!_sourcesEnabled[tid]) return;
+
+ newEndpoint = existingUniqueEndpoint != null ? existingUniqueEndpoint : _currentInstance.addEndpoint(_p.source, tep);
+ if (_sourceEndpointsUnique[tid]) _sourceEndpoints[tid] = newEndpoint;
+ _p.sourceEndpoint = newEndpoint;
+ // TODO test options to makeSource to see if we should do this?
+ newEndpoint._doNotDeleteOnDetach = false; // reset.
+ newEndpoint._deleteOnDetach = true;
+ }
+ }
+
+ return _p;
+ },
+
+ _newConnection = function(params) {
+ var connectionFunc = _currentInstance.Defaults.ConnectionType || _currentInstance.getDefaultConnectionType(),
+ endpointFunc = _currentInstance.Defaults.EndpointType || jsPlumb.Endpoint,
+ parent = jsPlumb.CurrentLibrary.getParent;
+
+ if (params.container)
+ params.parent = params.container;
+ else {
+ if (params.sourceEndpoint)
+ params.parent = params.sourceEndpoint.parent;
+ else if (params.source.constructor == endpointFunc)
+ params.parent = params.source.parent;
+ else params.parent = parent(params.source);
+ }
+
+ params._jsPlumb = _currentInstance;
+ params.newConnection = _newConnection;
+ params.newEndpoint = _newEndpoint;
+ params.endpointsByUUID = endpointsByUUID;
+ params.endpointsByElement = endpointsByElement;
+ params.finaliseConnection = _finaliseConnection;
+ var con = new connectionFunc(params);
+ con.id = "con_" + _idstamp();
+ _eventFireProxy("click", "click", con);
+ _eventFireProxy("dblclick", "dblclick", con);
+ _eventFireProxy("contextmenu", "contextmenu", con);
+ return con;
+ },
+
+ //
+ // adds the connection to the backing model, fires an event if necessary and then redraws
+ //
+ _finaliseConnection = function(jpc, params, originalEvent, doInformAnchorManager) {
+ params = params || {};
+ // add to list of connections (by scope).
+ if (!jpc.suspendedEndpoint)
+ connections.push(jpc);
+
+ // always inform the anchor manager
+ // except that if jpc has a suspended endpoint it's not true to say the
+ // connection is new; it has just (possibly) moved. the question is whether
+ // to make that call here or in the anchor manager. i think perhaps here.
+ if (jpc.suspendedEndpoint == null || doInformAnchorManager)
+ _currentInstance.anchorManager.newConnection(jpc);
+
+ // force a paint
+ _draw(jpc.source);
+
+ // fire an event
+ if (!params.doNotFireConnectionEvent && params.fireEvent !== false) {
+
+ var eventArgs = {
+ connection:jpc,
+ source : jpc.source, target : jpc.target,
+ sourceId : jpc.sourceId, targetId : jpc.targetId,
+ sourceEndpoint : jpc.endpoints[0], targetEndpoint : jpc.endpoints[1]
+ };
+
+ _currentInstance.fire("connection", eventArgs, originalEvent);
+ }
+ },
+
+ _eventFireProxy = function(event, proxyEvent, obj) {
+ obj.bind(event, function(originalObject, originalEvent) {
+ _currentInstance.fire(proxyEvent, obj, originalEvent);
+ });
+ },
+
+ /*
+ * for the given endpoint params, returns an appropriate parent element for the UI elements that will be added.
+ * this function is used by _newEndpoint (directly below), and also in the makeSource function in jsPlumb.
+ *
+ * the logic is to first look for a "container" member of params, and pass that back if found. otherwise we
+ * handoff to the 'getParent' function in the current library.
+ */
+ _getParentFromParams = function(params) {
+ if (params.container)
+ return params.container;
+ else {
+ var tag = jsPlumb.CurrentLibrary.getTagName(params.source),
+ p = jsPlumb.CurrentLibrary.getParent(params.source);
+ if (tag && tag.toLowerCase() === "td")
+ return jsPlumb.CurrentLibrary.getParent(p);
+ else return p;
+ }
+ },
+
+ /*
+ factory method to prepare a new endpoint. this should always be used instead of creating Endpoints
+ manually, since this method attaches event listeners and an id.
+ */
+ _newEndpoint = function(params) {
+ var endpointFunc = _currentInstance.Defaults.EndpointType || jsPlumb.Endpoint;
+ var _p = jsPlumb.extend({}, params);
+ _p.parent = _getParentFromParams(_p);
+ _p._jsPlumb = _currentInstance;
+ _p.newConnection = _newConnection;
+ _p.newEndpoint = _newEndpoint;
+ _p.endpointsByUUID = endpointsByUUID;
+ _p.endpointsByElement = endpointsByElement;
+ _p.finaliseConnection = _finaliseConnection;
+ _p.fireDetachEvent = fireDetachEvent;
+ _p.floatingConnections = floatingConnections;
+ _p.getParentFromParams = _getParentFromParams;
+ _p.elementId = _getId(_p.source);
+ var ep = new endpointFunc(_p);
+ ep.id = "ep_" + _idstamp();
+ _eventFireProxy("click", "endpointClick", ep);
+ _eventFireProxy("dblclick", "endpointDblClick", ep);
+ _eventFireProxy("contextmenu", "contextmenu", ep);
+ if (!jsPlumbAdapter.headless)
+ _currentInstance.dragManager.endpointAdded(_p.source);
+ return ep;
+ },
+
+ /*
+ * performs the given function operation on all the connections found
+ * for the given element id; this means we find all the endpoints for
+ * the given element, and then for each endpoint find the connectors
+ * connected to it. then we pass each connection in to the given
+ * function.
+ */
+ _operation = function(elId, func, endpointFunc) {
+ var endpoints = endpointsByElement[elId];
+ if (endpoints && endpoints.length) {
+ for ( var i = 0, ii = endpoints.length; i < ii; i++) {
+ for ( var j = 0, jj = endpoints[i].connections.length; j < jj; j++) {
+ var retVal = func(endpoints[i].connections[j]);
+ // if the function passed in returns true, we exit.
+ // most functions return false.
+ if (retVal) return;
+ }
+ if (endpointFunc) endpointFunc(endpoints[i]);
+ }
+ }
+ },
+
+ _setDraggable = function(element, draggable) {
+ return _elementProxy(element, function(el, id) {
+ draggableStates[id] = draggable;
+ if (jsPlumb.CurrentLibrary.isDragSupported(el)) {
+ jsPlumb.CurrentLibrary.setDraggable(el, draggable);
+ }
+ });
+ },
+ /*
+ * private method to do the business of hiding/showing.
+ *
+ * @param el
+ * either Id of the element in question or a library specific
+ * object for the element.
+ * @param state
+ * String specifying a value for the css 'display' property
+ * ('block' or 'none').
+ */
+ _setVisible = function(el, state, alsoChangeEndpoints) {
+ state = state === "block";
+ var endpointFunc = null;
+ if (alsoChangeEndpoints) {
+ if (state) endpointFunc = function(ep) {
+ ep.setVisible(true, true, true);
+ };
+ else endpointFunc = function(ep) {
+ ep.setVisible(false, true, true);
+ };
+ }
+ var info = _info(el);
+ _operation(info.id, function(jpc) {
+ if (state && alsoChangeEndpoints) {
+ // this test is necessary because this functionality is new, and i wanted to maintain backwards compatibility.
+ // this block will only set a connection to be visible if the other endpoint in the connection is also visible.
+ var oidx = jpc.sourceId === info.id ? 1 : 0;
+ if (jpc.endpoints[oidx].isVisible()) jpc.setVisible(true);
+ }
+ else // the default behaviour for show, and what always happens for hide, is to just set the visibility without getting clever.
+ jpc.setVisible(state);
+ }, endpointFunc);
+ },
+ /*
+ * toggles the draggable state of the given element(s).
+ * el is either an id, or an element object, or a list of ids/element objects.
+ */
+ _toggleDraggable = function(el) {
+ return _elementProxy(el, function(el, elId) {
+ var state = draggableStates[elId] == null ? false : draggableStates[elId];
+ state = !state;
+ draggableStates[elId] = state;
+ jsPlumb.CurrentLibrary.setDraggable(el, state);
+ return state;
+ });
+ },
+ /**
+ * private method to do the business of toggling hiding/showing.
+ */
+ _toggleVisible = function(elId, changeEndpoints) {
+ var endpointFunc = null;
+ if (changeEndpoints) {
+ endpointFunc = function(ep) {
+ var state = ep.isVisible();
+ ep.setVisible(!state);
+ };
+ }
+ _operation(elId, function(jpc) {
+ var state = jpc.isVisible();
+ jpc.setVisible(!state);
+ }, endpointFunc);
+ // todo this should call _elementProxy, and pass in the
+ // _operation(elId, f) call as a function. cos _toggleDraggable does
+ // that.
+ },
+ /**
+ * updates the offset and size for a given element, and stores the
+ * values. if 'offset' is not null we use that (it would have been
+ * passed in from a drag call) because it's faster; but if it is null,
+ * or if 'recalc' is true in order to force a recalculation, we get the current values.
+ */
+ _updateOffset = function(params) {
+ var timestamp = params.timestamp, recalc = params.recalc, offset = params.offset, elId = params.elId, s;
+ if (_suspendDrawing && !timestamp) timestamp = _suspendedAt;
+ if (!recalc) {
+ if (timestamp && timestamp === offsetTimestamps[elId]) {
+ return {o:params.offset || offsets[elId], s:sizes[elId]};
+ }
+ }
+ if (recalc || !offset) { // if forced repaint or no offset available, we recalculate.
+ // get the current size and offset, and store them
+ s = _gel(elId);
+ if (s != null) {
+ sizes[elId] = _getSize(s);
+ offsets[elId] = _getOffset(s, _currentInstance);
+ offsetTimestamps[elId] = timestamp;
+ }
+ } else {
+ offsets[elId] = offset;
+ if (sizes[elId] == null) {
+ s = _gel(elId);
+ if (s != null) sizes[elId] = _getSize(s);
+ }
+ offsetTimestamps[elId] = timestamp;
+ }
+
+ if(offsets[elId] && !offsets[elId].right) {
+ offsets[elId].right = offsets[elId].left + sizes[elId][0];
+ offsets[elId].bottom = offsets[elId].top + sizes[elId][1];
+ offsets[elId].width = sizes[elId][0];
+ offsets[elId].height = sizes[elId][1];
+ offsets[elId].centerx = offsets[elId].left + (offsets[elId].width / 2);
+ offsets[elId].centery = offsets[elId].top + (offsets[elId].height / 2);
+ }
+ return {o:offsets[elId], s:sizes[elId]};
+ },
+
+ // TODO comparison performance
+ _getCachedData = function(elId) {
+ var o = offsets[elId];
+ if (!o)
+ return _updateOffset({elId:elId});
+ else
+ return {o:o, s:sizes[elId]};
+ },
+
+ /**
+ * gets an id for the given element, creating and setting one if
+ * necessary. the id is of the form
+ *
+ * jsPlumb_<instance index>_<index in instance>
+ *
+ * where "index in instance" is a monotonically increasing integer that starts at 0,
+ * for each instance. this method is used not only to assign ids to elements that do not
+ * have them but also to connections and endpoints.
+ */
+ _getId = function(element, uuid, doNotCreateIfNotFound) {
+ if (jsPlumbUtil.isString(element)) return element;
+ if (element == null) return null;
+ var id = jsPlumbAdapter.getAttribute(element, "id");
+ if (!id || id === "undefined") {
+ // check if fixed uuid parameter is given
+ if (arguments.length == 2 && arguments[1] !== undefined)
+ id = uuid;
+ else if (arguments.length == 1 || (arguments.length == 3 && !arguments[2]))
+ id = "jsPlumb_" + _instanceIndex + "_" + _idstamp();
+
+ if (!doNotCreateIfNotFound) jsPlumbAdapter.setAttribute(element, "id", id);
+ }
+ return id;
+ };
+
+ this.setConnectionBeingDragged = function(v) {
+ connectionBeingDragged = v;
+ };
+ this.isConnectionBeingDragged = function() {
+ return connectionBeingDragged;
+ };
+
+ this.connectorClass = "_jsPlumb_connector";
+ this.hoverClass = "_jsPlumb_hover";
+ this.endpointClass = "_jsPlumb_endpoint";
+ this.endpointConnectedClass = "_jsPlumb_endpoint_connected";
+ this.endpointFullClass = "_jsPlumb_endpoint_full";
+ this.endpointDropAllowedClass = "_jsPlumb_endpoint_drop_allowed";
+ this.endpointDropForbiddenClass = "_jsPlumb_endpoint_drop_forbidden";
+ this.overlayClass = "_jsPlumb_overlay";
+ this.draggingClass = "_jsPlumb_dragging";
+ this.elementDraggingClass = "_jsPlumb_element_dragging";
+ this.sourceElementDraggingClass = "_jsPlumb_source_element_dragging";
+ this.targetElementDraggingClass = "_jsPlumb_target_element_dragging";
+ this.endpointAnchorClassPrefix = "_jsPlumb_endpoint_anchor";
+ this.hoverSourceClass = "_jsPlumb_source_hover";
+ this.hoverTargetClass = "_jsPlumb_target_hover";
+ this.dragSelectClass = "_jsPlumb_drag_select";
+
+ this.Anchors = {};
+ this.Connectors = { "canvas":{}, "svg":{}, "vml":{} };
+ this.Endpoints = { "canvas":{}, "svg":{}, "vml":{} };
+ this.Overlays = { "canvas":{}, "svg":{}, "vml":{}};
+ this.ConnectorRenderers = {};
+ this.SVG = "svg";
+ this.CANVAS = "canvas";
+ this.VML = "vml";
+
+
+// --------------------------- jsPLumbInstance public API ---------------------------------------------------------
+
+
+ this.addEndpoint = function(el, params, referenceParams) {
+ referenceParams = referenceParams || {};
+ var p = jsPlumb.extend({}, referenceParams);
+ jsPlumb.extend(p, params);
+ p.endpoint = p.endpoint || _currentInstance.Defaults.Endpoint || jsPlumb.Defaults.Endpoint;
+ p.paintStyle = p.paintStyle || _currentInstance.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle;
+ // YUI wrapper
+ el = _convertYUICollection(el);
+
+ var results = [],
+ inputs = (_ju.isArray(el) || (el.length != null && !_ju.isString(el))) ? el : [ el ];
+
+ for (var i = 0, j = inputs.length; i < j; i++) {
+ var _el = _dom(inputs[i]), id = _getId(_el);
+ p.source = _el;
+
+ _updateOffset({ elId : id, timestamp:_suspendedAt });
+ var e = _newEndpoint(p);
+ if (p.parentAnchor) e.parentAnchor = p.parentAnchor;
+ _ju.addToList(endpointsByElement, id, e);
+ var myOffset = offsets[id],
+ myWH = sizes[id],
+ anchorLoc = e.anchor.compute( { xy : [ myOffset.left, myOffset.top ], wh : myWH, element : e, timestamp:_suspendedAt }),
+ endpointPaintParams = { anchorLoc : anchorLoc, timestamp:_suspendedAt };
+
+ if (_suspendDrawing) endpointPaintParams.recalc = false;
+ if (!_suspendDrawing) e.paint(endpointPaintParams);
+
+ results.push(e);
+ e._doNotDeleteOnDetach = true; // mark this as being added via addEndpoint.
+ }
+
+ return results.length == 1 ? results[0] : results;
+ };
+
+
+ this.addEndpoints = function(el, endpoints, referenceParams) {
+ var results = [];
+ for ( var i = 0, j = endpoints.length; i < j; i++) {
+ var e = _currentInstance.addEndpoint(el, endpoints[i], referenceParams);
+ if (_ju.isArray(e))
+ Array.prototype.push.apply(results, e);
+ else results.push(e);
+ }
+ return results;
+ };
+
+ this.animate = function(el, properties, options) {
+ options = options || {};
+ var ele = _gel(el),
+ id = _getId(el),
+ stepFunction = jsPlumb.CurrentLibrary.dragEvents.step,
+ completeFunction = jsPlumb.CurrentLibrary.dragEvents.complete;
+
+ options[stepFunction] = _ju.wrap(options[stepFunction], function() {
+ _currentInstance.repaint(id);
+ });
+
+ // onComplete repaints, just to make sure everything looks good at the end of the animation.
+ options[completeFunction] = _ju.wrap(options[completeFunction], function() {
+ _currentInstance.repaint(id);
+ });
+
+ jsPlumb.CurrentLibrary.animate(ele, properties, options);
+ };
+
+ /**
+ * checks for a listener for the given condition, executing it if found, passing in the given value.
+ * condition listeners would have been attached using "bind" (which is, you could argue, now overloaded, since
+ * firing click events etc is a bit different to what this does). i thought about adding a "bindCondition"
+ * or something, but decided against it, for the sake of simplicity. jsPlumb will never fire one of these
+ * condition events anyway.
+ */
+ this.checkCondition = function(conditionName, value) {
+ var l = _currentInstance.getListener(conditionName),
+ r = true;
+
+ if (l && l.length > 0) {
+ try {
+ for (var i = 0, j = l.length; i < j; i++) {
+ r = r && l[i](value);
+ }
+ }
+ catch (e) {
+ _ju.log(_currentInstance, "cannot check condition [" + conditionName + "]" + e);
+ }
+ }
+ return r;
+ };
+
+ /**
+ * checks a condition asynchronously: fires the event handler and passes the handler
+ * a 'proceed' function and a 'stop' function. The handler MUST execute one or other
+ * of these once it has made up its mind.
+ *
+ * Note that although this reads the listener list for the given condition, it
+ * does not loop through and hit each listener, because that, with asynchronous
+ * callbacks, would be messy. so it uses only the first listener registered.
+ */
+ this.checkASyncCondition = function(conditionName, value, proceed, stop) {
+ var l = _currentInstance.getListener(conditionName);
+
+ if (l && l.length > 0) {
+ try {
+ l[0](value, proceed, stop);
+ }
+ catch (e) {
+ _ju.log(_currentInstance, "cannot asynchronously check condition [" + conditionName + "]" + e);
+ }
+ }
+ };
+
+
+ this.connect = function(params, referenceParams) {
+ // prepare a final set of parameters to create connection with
+ var _p = _prepareConnectionParams(params, referenceParams), jpc;
+ // TODO probably a nicer return value if the connection was not made. _prepareConnectionParams
+ // will return null (and log something) if either endpoint was full. what would be nicer is to
+ // create a dedicated 'error' object.
+ if (_p) {
+ // create the connection. it is not yet registered
+ jpc = _newConnection(_p);
+ // now add it the model, fire an event, and redraw
+ _finaliseConnection(jpc, _p);
+ }
+ return jpc;
+ };
+
+ this.deleteEndpoint = function(object, doNotRepaintAfterwards) {
+ var _is = _currentInstance.setSuspendDrawing(true);
+ var endpoint = (typeof object == "string") ? endpointsByUUID[object] : object;
+ if (endpoint) {
+ _currentInstance.deleteObject({endpoint:endpoint});
+ }
+ if(!_is) _currentInstance.setSuspendDrawing(false, doNotRepaintAfterwards);
+ return _currentInstance;
+ };
+
+
+ this.deleteEveryEndpoint = function() {
+ var _is = _currentInstance.setSuspendDrawing(true);
+ for ( var id in endpointsByElement) {
+ var endpoints = endpointsByElement[id];
+ if (endpoints && endpoints.length) {
+ for ( var i = 0, j = endpoints.length; i < j; i++) {
+ _currentInstance.deleteEndpoint(endpoints[i], true);
+ }
+ }
+ }
+ endpointsByElement = {};
+ endpointsByUUID = {};
+ _currentInstance.anchorManager.reset();
+ _currentInstance.dragManager.reset();
+ if(!_is) _currentInstance.setSuspendDrawing(false);
+ return _currentInstance;
+ };
+
+ var fireDetachEvent = function(jpc, doFireEvent, originalEvent) {
+ // may have been given a connection, or in special cases, an object
+ var connType = _currentInstance.Defaults.ConnectionType || _currentInstance.getDefaultConnectionType(),
+ argIsConnection = jpc.constructor == connType,
+ params = argIsConnection ? {
+ connection:jpc,
+ source : jpc.source, target : jpc.target,
+ sourceId : jpc.sourceId, targetId : jpc.targetId,
+ sourceEndpoint : jpc.endpoints[0], targetEndpoint : jpc.endpoints[1]
+ } : jpc;
+
+ if (doFireEvent)
+ _currentInstance.fire("connectionDetached", params, originalEvent);
+
+ _currentInstance.anchorManager.connectionDetached(params);
+ };
+
+ this.unregisterEndpoint = function(endpoint) {
+ if (endpoint._jsPlumb.uuid) endpointsByUUID[endpoint._jsPlumb.uuid] = null;
+ _currentInstance.anchorManager.deleteEndpoint(endpoint);
+ // TODO at least replace this with a removeWithFunction call.
+ for (var e in endpointsByElement) {
+ var endpoints = endpointsByElement[e];
+ if (endpoints) {
+ var newEndpoints = [];
+ for (var i = 0, j = endpoints.length; i < j; i++)
+ if (endpoints[i] != endpoint) newEndpoints.push(endpoints[i]);
+
+ endpointsByElement[e] = newEndpoints;
+ }
+ if(endpointsByElement[e].length <1){
+ delete endpointsByElement[e];
+ }
+ }
+ };
+
+ this.detach = function() {
+
+ if (arguments.length === 0) return;
+ var connType = _currentInstance.Defaults.ConnectionType || _currentInstance.getDefaultConnectionType(),
+ firstArgIsConnection = arguments[0].constructor == connType,
+ params = arguments.length == 2 ? firstArgIsConnection ? (arguments[1] || {}) : arguments[0] : arguments[0],
+ fireEvent = (params.fireEvent !== false),
+ forceDetach = params.forceDetach,
+ conn = firstArgIsConnection ? arguments[0] : params.connection;
+
+ if (conn) {
+ if (forceDetach || jsPlumbUtil.functionChain(true, false, [
+ [ conn.endpoints[0], "isDetachAllowed", [ conn ] ],
+ [ conn.endpoints[1], "isDetachAllowed", [ conn ] ],
+ [ conn, "isDetachAllowed", [ conn ] ],
+ [ _currentInstance, "checkCondition", [ "beforeDetach", conn ] ] ])) {
+
+ conn.endpoints[0].detach(conn, false, true, fireEvent);
+ }
+ }
+ else {
+ var _p = jsPlumb.extend( {}, params); // a backwards compatibility hack: source should be thought of as 'params' in this case.
+ // test for endpoint uuids to detach
+ if (_p.uuids) {
+ _getEndpoint(_p.uuids[0]).detachFrom(_getEndpoint(_p.uuids[1]), fireEvent);
+ } else if (_p.sourceEndpoint && _p.targetEndpoint) {
+ _p.sourceEndpoint.detachFrom(_p.targetEndpoint);
+ } else {
+ var sourceId = _getId(_dom(_p.source)),
+ targetId = _getId(_dom(_p.target));
+ _operation(sourceId, function(jpc) {
+ if ((jpc.sourceId == sourceId && jpc.targetId == targetId) || (jpc.targetId == sourceId && jpc.sourceId == targetId)) {
+ if (_currentInstance.checkCondition("beforeDetach", jpc)) {
+ jpc.endpoints[0].detach(jpc, false, true, fireEvent);
+ }
+ }
+ });
+ }
+ }
+ };
+
+ this.detachAllConnections = function(el, params) {
+ params = params || {};
+ el = _dom(el);
+ var id = _getId(el),
+ endpoints = endpointsByElement[id];
+ if (endpoints && endpoints.length) {
+ for ( var i = 0, j = endpoints.length; i < j; i++) {
+ endpoints[i].detachAll(params.fireEvent !== false);
+ }
+ }
+ return _currentInstance;
+ };
+
+ this.detachEveryConnection = function(params) {
+ params = params || {};
+ _currentInstance.doWhileSuspended(function() {
+ for ( var id in endpointsByElement) {
+ var endpoints = endpointsByElement[id];
+ if (endpoints && endpoints.length) {
+ for ( var i = 0, j = endpoints.length; i < j; i++) {
+ endpoints[i].detachAll(params.fireEvent !== false);
+ }
+ }
+ }
+ connections.splice(0);
+ });
+ return _currentInstance;
+ };
+
+ /// not public. but of course its exposed. how to change this.
+ this.deleteObject = function(params) {
+ var result = {
+ endpoints : {},
+ connections : {},
+ endpointCount:0,
+ connectionCount:0
+ },
+ fireEvent = params.fireEvent !== false,
+ deleteAttachedObjects = params.deleteAttachedObjects !== false;
+
+ var unravelConnection = function(connection) {
+ if(connection != null && result.connections[connection.id] == null) {
+ connection._jsPlumb && connection.setHover(false);
+ result.connections[connection.id] = connection;
+ result.connectionCount++;
+ if (deleteAttachedObjects) {
+ for (var j = 0; j < connection.endpoints.length; j++) {
+ if (connection.endpoints[j]._deleteOnDetach)
+ unravelEndpoint(connection.endpoints[j]);
+ }
+ }
+ }
+ };
+ var unravelEndpoint = function(endpoint) {
+ if(endpoint != null && result.endpoints[endpoint.id] == null) {
+ endpoint._jsPlumb && endpoint.setHover(false);
+ result.endpoints[endpoint.id] = endpoint;
+ result.endpointCount++;
+
+ if (deleteAttachedObjects) {
+ for (var i = 0; i < endpoint.connections.length; i++) {
+ var c = endpoint.connections[i];
+ unravelConnection(c);
+ }
+ }
+ }
+ };
+
+ if (params.connection)
+ unravelConnection(params.connection);
+ else unravelEndpoint(params.endpoint);
+
+ // loop through connections
+ for (var i in result.connections) {
+ var c = result.connections[i];
+ c.endpoints[0].detachFromConnection(c);
+ c.endpoints[1].detachFromConnection(c);
+ //_currentInstance.unregisterConnection(c);
+ jsPlumbUtil.removeWithFunction(connections, function(_c) {
+ return c.id == _c.id;
+ });
+ fireDetachEvent(c, fireEvent, params.originalEvent);
+ c.cleanup();
+ c.destroy();
+ }
+
+ // loop through endpoints
+ for (var j in result.endpoints) {
+ var e = result.endpoints[j];
+ _currentInstance.unregisterEndpoint(e);
+ // FIRE some endpoint deleted event?
+ e.cleanup();
+ e.destroy();
+ }
+
+ return result;
+ };
+
+ this.draggable = function(el, options) {
+ var i,j,ele;
+ // allows for array or jquery/mootools selector
+ if (typeof el == 'object' && el.length) {
+ for (i = 0, j = el.length; i < j; i++) {
+ ele = _dom(el[i]);
+ if (ele) _initDraggableIfNecessary(ele, true, options);
+ }
+ }
+ // allows for YUI selector
+ else if (el._nodes) { // TODO this is YUI specific; really the logic should be forced
+ // into the library adapters (for jquery and mootools aswell)
+ for (i = 0, j = el._nodes.length; i < j; i++) {
+ ele = _dom(el._nodes[i]);
+ if (ele) _initDraggableIfNecessary(ele, true, options);
+ }
+ }
+ else {
+ ele = _dom(el);
+ if (ele) _initDraggableIfNecessary(ele, true, options);
+ }
+ return _currentInstance;
+ };
+
+
+ // just a library-agnostic wrapper.
+ this.extend = function(o1, o2) {
+ return jsPlumb.CurrentLibrary.extend(o1, o2);
+ };
+
+ // helpers for select/selectEndpoints
+ var _setOperation = function(list, func, args, selector) {
+ for (var i = 0, j = list.length; i < j; i++) {
+ list[i][func].apply(list[i], args);
+ }
+ return selector(list);
+ },
+ _getOperation = function(list, func, args) {
+ var out = [];
+ for (var i = 0, j = list.length; i < j; i++) {
+ out.push([ list[i][func].apply(list[i], args), list[i] ]);
+ }
+ return out;
+ },
+ setter = function(list, func, selector) {
+ return function() {
+ return _setOperation(list, func, arguments, selector);
+ };
+ },
+ getter = function(list, func) {
+ return function() {
+ return _getOperation(list, func, arguments);
+ };
+ },
+ prepareList = function(input, doNotGetIds) {
+ var r = [];
+ if (input) {
+ if (typeof input == 'string') {
+ if (input === "*") return input;
+ r.push(input);
+ }
+ else {
+ input = _gel(input);
+ if (doNotGetIds) r = input;
+ else {
+ for (var i = 0, j = input.length; i < j; i++)
+ r.push(_info(input[i]).id);
+ }
+ }
+ }
+ return r;
+ },
+ filterList = function(list, value, missingIsFalse) {
+ if (list === "*") return true;
+ return list.length > 0 ? jsPlumbUtil.indexOf(list, value) != -1 : !missingIsFalse;
+ };
+
+ // get some connections, specifying source/target/scope
+ this.getConnections = function(options, flat) {
+ if (!options) {
+ options = {};
+ } else if (options.constructor == String) {
+ options = { "scope": options };
+ }
+ var scope = options.scope || _currentInstance.getDefaultScope(),
+ scopes = prepareList(scope, true),
+ sources = prepareList(options.source),
+ targets = prepareList(options.target),
+ results = (!flat && scopes.length > 1) ? {} : [],
+ _addOne = function(scope, obj) {
+ if (!flat && scopes.length > 1) {
+ var ss = results[scope];
+ if (ss == null) {
+ ss = results[scope] = [];
+ }
+ ss.push(obj);
+ } else results.push(obj);
+ };
+
+ for ( var j = 0, jj = connections.length; j < jj; j++) {
+ var c = connections[j];
+ if (filterList(scopes, c.scope) && filterList(sources, c.sourceId) && filterList(targets, c.targetId))
+ _addOne(c.scope, c);
+ }
+
+ return results;
+ };
+
+ var _curryEach = function(list, executor) {
+ return function(f) {
+ for (var i = 0, ii = list.length; i < ii; i++) {
+ f(list[i]);
+ }
+ return executor(list);
+ };
+ },
+ _curryGet = function(list) {
+ return function(idx) {
+ return list[idx];
+ };
+ };
+
+ var _makeCommonSelectHandler = function(list, executor) {
+ var out = {
+ length:list.length,
+ each:_curryEach(list, executor),
+ get:_curryGet(list)
+ },
+ setters = ["setHover", "removeAllOverlays", "setLabel", "addClass", "addOverlay", "removeOverlay",
+ "removeOverlays", "showOverlay", "hideOverlay", "showOverlays", "hideOverlays", "setPaintStyle",
+ "setHoverPaintStyle", "setSuspendEvents", "setParameter", "setParameters", "setVisible",
+ "repaint", "addType", "toggleType", "removeType", "removeClass", "setType", "bind", "unbind" ],
+
+ getters = ["getLabel", "getOverlay", "isHover", "getParameter", "getParameters", "getPaintStyle",
+ "getHoverPaintStyle", "isVisible", "hasType", "getType", "isSuspendEvents" ],
+ i, ii;
+
+ for (i = 0, ii = setters.length; i < ii; i++)
+ out[setters[i]] = setter(list, setters[i], executor);
+
+ for (i = 0, ii = getters.length; i < ii; i++)
+ out[getters[i]] = getter(list, getters[i]);
+
+ return out;
+ };
+
+ var _makeConnectionSelectHandler = function(list) {
+ var common = _makeCommonSelectHandler(list, _makeConnectionSelectHandler);
+ return jsPlumb.CurrentLibrary.extend(common, {
+ // setters
+ setDetachable:setter(list, "setDetachable", _makeConnectionSelectHandler),
+ setReattach:setter(list, "setReattach", _makeConnectionSelectHandler),
+ setConnector:setter(list, "setConnector", _makeConnectionSelectHandler),
+ detach:function() {
+ for (var i = 0, ii = list.length; i < ii; i++)
+ _currentInstance.detach(list[i]);
+ },
+ // getters
+ isDetachable:getter(list, "isDetachable"),
+ isReattach:getter(list, "isReattach")
+ });
+ };
+
+ var _makeEndpointSelectHandler = function(list) {
+ var common = _makeCommonSelectHandler(list, _makeEndpointSelectHandler);
+ return jsPlumb.CurrentLibrary.extend(common, {
+ setEnabled:setter(list, "setEnabled", _makeEndpointSelectHandler),
+ setAnchor:setter(list, "setAnchor", _makeEndpointSelectHandler),
+ isEnabled:getter(list, "isEnabled"),
+ detachAll:function() {
+ for (var i = 0, ii = list.length; i < ii; i++)
+ list[i].detachAll();
+ },
+ "remove":function() {
+ for (var i = 0, ii = list.length; i < ii; i++)
+ _currentInstance.deleteObject({endpoint:list[i]});
+ }
+ });
+ };
+
+
+ this.select = function(params) {
+ params = params || {};
+ params.scope = params.scope || "*";
+ return _makeConnectionSelectHandler(params.connections || _currentInstance.getConnections(params, true));
+ };
+
+ this.selectEndpoints = function(params) {
+ params = params || {};
+ params.scope = params.scope || "*";
+ var noElementFilters = !params.element && !params.source && !params.target,
+ elements = noElementFilters ? "*" : prepareList(params.element),
+ sources = noElementFilters ? "*" : prepareList(params.source),
+ targets = noElementFilters ? "*" : prepareList(params.target),
+ scopes = prepareList(params.scope, true);
+
+ var ep = [];
+
+ for (var el in endpointsByElement) {
+ var either = filterList(elements, el, true),
+ source = filterList(sources, el, true),
+ sourceMatchExact = sources != "*",
+ target = filterList(targets, el, true),
+ targetMatchExact = targets != "*";
+
+ // if they requested 'either' then just match scope. otherwise if they requested 'source' (not as a wildcard) then we have to match only endpoints that have isSource set to to true, and the same thing with isTarget.
+ if ( either || source || target ) {
+ inner:
+ for (var i = 0, ii = endpointsByElement[el].length; i < ii; i++) {
+ var _ep = endpointsByElement[el][i];
+ if (filterList(scopes, _ep.scope, true)) {
+
+ var noMatchSource = (sourceMatchExact && sources.length > 0 && !_ep.isSource),
+ noMatchTarget = (targetMatchExact && targets.length > 0 && !_ep.isTarget);
+
+ if (noMatchSource || noMatchTarget)
+ continue inner;
+
+ ep.push(_ep);
+ }
+ }
+ }
+ }
+
+ return _makeEndpointSelectHandler(ep);
+ };
+
+ // get all connections managed by the instance of jsplumb.
+ this.getAllConnections = function() { return connections; };
+ this.getDefaultScope = function() { return DEFAULT_SCOPE; };
+ // get an endpoint by uuid.
+ this.getEndpoint = _getEndpoint;
+ // get endpoints for some element.
+ this.getEndpoints = function(el) { return endpointsByElement[_info(el).id]; };
+ // gets the default endpoint type. used when subclassing. see wiki.
+ this.getDefaultEndpointType = function() { return jsPlumb.Endpoint; };
+ // gets the default connection type. used when subclassing. see wiki.
+ this.getDefaultConnectionType = function() { return jsPlumb.Connection; };
+ /*
+ * Gets an element's id, creating one if necessary. really only exposed
+ * for the lib-specific functionality to access; would be better to pass
+ * the current instance into the lib-specific code (even though this is
+ * a static call. i just don't want to expose it to the public API).
+ */
+ this.getId = _getId;
+ this.getOffset = function(id) {
+ var o = offsets[id];
+ return _updateOffset({elId:id});
+ };
+
+ this.getSelector = function() {
+ return jsPlumb.CurrentLibrary.getSelector.apply(null, arguments);
+ };
+
+ // get the size of the element with the given id, perhaps from cache.
+ this.getSize = function(id) {
+ var s = sizes[id];
+ if (!s) _updateOffset({elId:id});
+ return sizes[id];
+ };
+
+ this.appendElement = _appendElement;
+
+ var _hoverSuspended = false;
+ this.isHoverSuspended = function() { return _hoverSuspended; };
+ this.setHoverSuspended = function(s) { _hoverSuspended = s; };
+
+ var _isAvailable = function(m) {
+ return function() {
+ return jsPlumbAdapter.isRenderModeAvailable(m);
+ };
+ };
+ this.isCanvasAvailable = _isAvailable("canvas");
+ this.isSVGAvailable = _isAvailable("svg");
+ this.isVMLAvailable = _isAvailable("vml");
+
+ // set an element's connections to be hidden
+ this.hide = function(el, changeEndpoints) {
+ _setVisible(el, "none", changeEndpoints);
+ return _currentInstance;
+ };
+
+ // exposed for other objects to use to get a unique id.
+ this.idstamp = _idstamp;
+
+ this.connectorsInitialized = false;
+ var connectorTypes = [], rendererTypes = ["canvas", "svg", "vml"];
+ this.registerConnectorType = function(connector, name) {
+ connectorTypes.push([connector, name]);
+ };
+
+ /**
+ * callback from the current library to tell us to prepare ourselves (attach
+ * mouse listeners etc; can't do that until the library has provided a bind method)
+ */
+ this.init = function() {
+ var _oneType = function(renderer, name, fn) {
+ jsPlumb.Connectors[renderer][name] = function() {
+ fn.apply(this, arguments);
+ jsPlumb.ConnectorRenderers[renderer].apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors[renderer][name], [ fn, jsPlumb.ConnectorRenderers[renderer]]);
+ };
+
+ if (!jsPlumb.connectorsInitialized) {
+ for (var i = 0; i < connectorTypes.length; i++) {
+ for (var j = 0; j < rendererTypes.length; j++) {
+ _oneType(rendererTypes[j], connectorTypes[i][1], connectorTypes[i][0]);
+ }
+
+ }
+ jsPlumb.connectorsInitialized = true;
+ }
+
+ if (!initialized) {
+ _currentInstance.anchorManager = new jsPlumb.AnchorManager({jsPlumbInstance:_currentInstance});
+ _currentInstance.setRenderMode(_currentInstance.Defaults.RenderMode); // calling the method forces the capability logic to be run.
+ initialized = true;
+ _currentInstance.fire("ready", _currentInstance);
+ }
+ }.bind(this);
+
+ this.log = log;
+ this.jsPlumbUIComponent = jsPlumbUIComponent;
+
+ /*
+ * Creates an anchor with the given params.
+ *
+ *
+ * Returns: The newly created Anchor.
+ * Throws: an error if a named anchor was not found.
+ */
+ this.makeAnchor = function() {
+ var _a = function(t, p) {
+ if (jsPlumb.Anchors[t]) return new jsPlumb.Anchors[t](p);
+ if (!_currentInstance.Defaults.DoNotThrowErrors)
+ throw { msg:"jsPlumb: unknown anchor type '" + t + "'" };
+ };
+ if (arguments.length === 0) return null;
+ var specimen = arguments[0], elementId = arguments[1], jsPlumbInstance = arguments[2], newAnchor = null;
+ // if it appears to be an anchor already...
+ if (specimen.compute && specimen.getOrientation) return specimen; //TODO hazy here about whether it should be added or is already added somehow.
+ // is it the name of an anchor type?
+ else if (typeof specimen == "string") {
+ newAnchor = _a(arguments[0], {elementId:elementId, jsPlumbInstance:_currentInstance});
+ }
+ // is it an array? it will be one of:
+ // an array of [name, params] - this defines a single anchor
+ // an array of arrays - this defines some dynamic anchors
+ // an array of numbers - this defines a single anchor.
+ else if (_ju.isArray(specimen)) {
+ if (_ju.isArray(specimen[0]) || _ju.isString(specimen[0])) {
+ if (specimen.length == 2 && _ju.isString(specimen[0]) && _ju.isObject(specimen[1])) {
+ var pp = jsPlumb.extend({elementId:elementId, jsPlumbInstance:_currentInstance}, specimen[1]);
+ newAnchor = _a(specimen[0], pp);
+ }
+ else
+ newAnchor = new jsPlumb.DynamicAnchor({anchors:specimen, selector:null, elementId:elementId, jsPlumbInstance:jsPlumbInstance});
+ }
+ else {
+ var anchorParams = {
+ x:specimen[0], y:specimen[1],
+ orientation : (specimen.length >= 4) ? [ specimen[2], specimen[3] ] : [0,0],
+ offsets : (specimen.length >= 6) ? [ specimen[4], specimen[5] ] : [ 0, 0 ],
+ elementId:elementId,
+ jsPlumbInstance:jsPlumbInstance,
+ cssClass:specimen.length == 7 ? specimen[6] : null
+ };
+ newAnchor = new jsPlumb.Anchor(anchorParams);
+ newAnchor.clone = function() { return new jsPlumb.Anchor(anchorParams); };
+ }
+ }
+
+ if (!newAnchor.id) newAnchor.id = "anchor_" + _idstamp();
+ return newAnchor;
+ };
+
+ /**
+ * makes a list of anchors from the given list of types or coords, eg
+ * ["TopCenter", "RightMiddle", "BottomCenter", [0, 1, -1, -1] ]
+ */
+ this.makeAnchors = function(types, elementId, jsPlumbInstance) {
+ var r = [];
+ for ( var i = 0, ii = types.length; i < ii; i++) {
+ if (typeof types[i] == "string")
+ r.push(jsPlumb.Anchors[types[i]]({elementId:elementId, jsPlumbInstance:jsPlumbInstance}));
+ else if (_ju.isArray(types[i]))
+ r.push(_currentInstance.makeAnchor(types[i], elementId, jsPlumbInstance));
+ }
+ return r;
+ };
+
+ /**
+ * Makes a dynamic anchor from the given list of anchors (which may be in shorthand notation as strings or dimension arrays, or Anchor
+ * objects themselves) and the given, optional, anchorSelector function (jsPlumb uses a default if this is not provided; most people will
+ * not need to provide this - i think).
+ */
+ this.makeDynamicAnchor = function(anchors, anchorSelector) {
+ return new jsPlumb.DynamicAnchor({anchors:anchors, selector:anchorSelector, elementId:null, jsPlumbInstance:_currentInstance});
+ };
+
+// --------------------- makeSource/makeTarget ----------------------------------------------
+
+ var _targetEndpointDefinitions = {},
+ _targetEndpoints = {},
+ _targetEndpointsUnique = {},
+ _targetMaxConnections = {},
+ _setEndpointPaintStylesAndAnchor = function(ep, epIndex) {
+ ep.paintStyle = ep.paintStyle ||
+ _currentInstance.Defaults.EndpointStyles[epIndex] ||
+ _currentInstance.Defaults.EndpointStyle ||
+ jsPlumb.Defaults.EndpointStyles[epIndex] ||
+ jsPlumb.Defaults.EndpointStyle;
+ ep.hoverPaintStyle = ep.hoverPaintStyle ||
+ _currentInstance.Defaults.EndpointHoverStyles[epIndex] ||
+ _currentInstance.Defaults.EndpointHoverStyle ||
+ jsPlumb.Defaults.EndpointHoverStyles[epIndex] ||
+ jsPlumb.Defaults.EndpointHoverStyle;
+
+ ep.anchor = ep.anchor ||
+ _currentInstance.Defaults.Anchors[epIndex] ||
+ _currentInstance.Defaults.Anchor ||
+ jsPlumb.Defaults.Anchors[epIndex] ||
+ jsPlumb.Defaults.Anchor;
+
+ ep.endpoint = ep.endpoint ||
+ _currentInstance.Defaults.Endpoints[epIndex] ||
+ _currentInstance.Defaults.Endpoint ||
+ jsPlumb.Defaults.Endpoints[epIndex] ||
+ jsPlumb.Defaults.Endpoint;
+ },
+ // TODO put all the source stuff inside one parent, keyed by id.
+ _sourceEndpointDefinitions = {},
+ _sourceEndpoints = {},
+ _sourceEndpointsUnique = {},
+ _sourcesEnabled = {},
+ _sourceTriggers = {},
+ _sourceMaxConnections = {},
+ _targetsEnabled = {},
+ selectorFilter = function(evt, _el, selector) {
+ var t = evt.target || evt.srcElement, ok = false,
+ sel = _currentInstance.getSelector(_el, selector);
+ for (var j = 0; j < sel.length; j++) {
+ if (sel[j] == t) {
+ ok = true;
+ break;
+ }
+ }
+ return ok;
+ };
+
+ // see API docs
+ this.makeTarget = function(el, params, referenceParams) {
+
+ // put jsplumb ref into params without altering the params passed in
+ var p = jsPlumb.extend({_jsPlumb:_currentInstance}, referenceParams);
+ jsPlumb.extend(p, params);
+
+ // calculate appropriate paint styles and anchor from the params given
+ _setEndpointPaintStylesAndAnchor(p, 1);
+
+ var jpcl = jsPlumb.CurrentLibrary,
+ targetScope = p.scope || _currentInstance.Defaults.Scope,
+ deleteEndpointsOnDetach = !(p.deleteEndpointsOnDetach === false),
+ maxConnections = p.maxConnections || -1,
+ onMaxConnections = p.onMaxConnections;
+
+ _doOne = function(el) {
+
+ // get the element's id and store the endpoint definition for it. jsPlumb.connect calls will look for one of these,
+ // and use the endpoint definition if found.
+ // decode the info for this element (id and element)
+ var elInfo = _info(el),
+ elid = elInfo.id,
+ proxyComponent = new jsPlumbUIComponent(p),
+ dropOptions = jsPlumb.extend({}, p.dropOptions || {});
+
+ // store the definitions keyed against the element id.
+ _targetEndpointDefinitions[elid] = p;
+ _targetEndpointsUnique[elid] = p.uniqueEndpoint;
+ _targetMaxConnections[elid] = maxConnections;
+ _targetsEnabled[elid] = true;
+
+ var _drop = function() {
+ _currentInstance.currentlyDragging = false;
+ var originalEvent = jsPlumb.CurrentLibrary.getDropEvent(arguments),
+ targetCount = _currentInstance.select({target:elid}).length,
+ draggable = _gel(jpcl.getDragObject(arguments)),
+ id = _currentInstance.getAttribute(draggable, "dragId"),
+ scope = _currentInstance.getAttribute(draggable, "originalScope"),
+ jpc = floatingConnections[id],
+ idx = jpc.endpoints[0].isFloating() ? 0 : 1,
+ // this is not necessarily correct. if the source is being dragged,
+ // then the source endpoint is actually the currently suspended endpoint.
+ source = jpc.endpoints[0],
+ _endpoint = p.endpoint ? jsPlumb.extend({}, p.endpoint) : {};
+
+ if (!_targetsEnabled[elid] || _targetMaxConnections[elid] > 0 && targetCount >= _targetMaxConnections[elid]){
+ if (onMaxConnections) {
+ // TODO here we still have the id of the floating element, not the
+ // actual target.
+ onMaxConnections({
+ element:elInfo.el,
+ connection:jpc
+ }, originalEvent);
+ }
+ return false;
+ }
+
+ // unlock the source anchor to allow it to refresh its position if necessary
+ source.anchor.locked = false;
+
+ // restore the original scope if necessary (issue 57)
+ if (scope) jpcl.setDragScope(draggable, scope);
+
+ // check if drop is allowed here.
+ // if the source is being dragged then in fact
+ // the source and target ids to pass into the drop interceptor are
+ // source - elid
+ // target - jpc's targetId
+ //
+ // otherwise the ids are
+ // source - jpc.sourceId
+ // target - elid
+ //
+ var _continue = proxyComponent.isDropAllowed(idx === 0 ? elid : jpc.sourceId, idx === 0 ? jpc.targetId : elid, jpc.scope, jpc, null);
+
+ // reinstate any suspended endpoint; this just puts the connection back into
+ // a state in which it will report sensible values if someone asks it about
+ // its target. we're going to throw this connection away shortly so it doesnt matter
+ // if we manipulate it a bit.
+ if (jpc.suspendedEndpoint) {
+ jpc[idx ? "targetId" : "sourceId"] = jpc.suspendedEndpoint.elementId;
+ jpc[idx ? "target" : "source"] = jpc.suspendedEndpoint.element;
+ jpc.endpoints[idx] = jpc.suspendedEndpoint;
+ }
+
+ if (_continue) {
+
+ // make a new Endpoint for the target
+ var _el = jpcl.getElementObject(elInfo.el),
+ newEndpoint = _targetEndpoints[elid] || _currentInstance.addEndpoint(_el, p);
+
+ if (p.uniqueEndpoint) _targetEndpoints[elid] = newEndpoint; // may of course just store what it just pulled out. that's ok.
+ // TODO test options to makeTarget to see if we should do this?
+ newEndpoint._doNotDeleteOnDetach = false; // reset.
+ newEndpoint._deleteOnDetach = true;
+
+ // if the anchor has a 'positionFinder' set, then delegate to that function to find
+ // out where to locate the anchor.
+ if (newEndpoint.anchor.positionFinder != null) {
+ var dropPosition = jpcl.getUIPosition(arguments, _currentInstance.getZoom()),
+ elPosition = _getOffset(_el, _currentInstance),
+ elSize = _getSize(_el),
+ ap = newEndpoint.anchor.positionFinder(dropPosition, elPosition, elSize, newEndpoint.anchor.constructorParams);
+ newEndpoint.anchor.x = ap[0];
+ newEndpoint.anchor.y = ap[1];
+ // now figure an orientation for it..kind of hard to know what to do actually. probably the best thing i can do is to
+ // support specifying an orientation in the anchor's spec. if one is not supplied then i will make the orientation
+ // be what will cause the most natural link to the source: it will be pointing at the source, but it needs to be
+ // specified in one axis only, and so how to make that choice? i think i will use whichever axis is the one in which
+ // the target is furthest away from the source.
+ }
+
+ // change the target endpoint and target element information. really this should be
+ // done on a method on connection
+ jpc[idx ? "target" : "source"] = newEndpoint.element;
+ jpc[idx ? "targetId" : "sourceId"] = newEndpoint.elementId;
+ jpc.endpoints[idx].detachFromConnection(jpc);
+ if (jpc.endpoints[idx]._deleteOnDetach)
+ jpc.endpoints[idx].deleteAfterDragStop = true; // tell this endpoint to delet itself after drag stop.
+ // set new endpoint, and configure the settings for endpoints to delete on detach
+ newEndpoint.addConnection(jpc);
+ jpc.endpoints[idx] = newEndpoint;
+ jpc.deleteEndpointsOnDetach = deleteEndpointsOnDetach;
+
+ // inform the anchor manager to update its target endpoint for this connection.
+ // TODO refactor to make this a single method.
+ if (idx == 1)
+ _currentInstance.anchorManager.updateOtherEndpoint(jpc.sourceId, jpc.suspendedElementId, jpc.targetId, jpc);
+ else
+ _currentInstance.anchorManager.sourceChanged(jpc.suspendedEndpoint.elementId, jpc.sourceId, jpc);
+
+ _finaliseConnection(jpc, null, originalEvent);
+
+ }
+ // if not allowed to drop...
+ else {
+ // TODO this code is identical (pretty much) to what happens when a connection
+ // dragged from a normal endpoint is in this situation. refactor.
+ // is this an existing connection, and will we reattach?
+ // TODO also this assumes the source needs to detach - is that always valid?
+ if (jpc.suspendedEndpoint) {
+ if (jpc.isReattach()) {
+ jpc.setHover(false);
+ jpc.floatingAnchorIndex = null;
+ jpc.suspendedEndpoint.addConnection(jpc);
+ _currentInstance.repaint(source.elementId);
+ }
+ else
+ source.detach(jpc, false, true, true, originalEvent); // otherwise, detach the connection and tell everyone about it.
+ }
+
+ }
+ };
+
+ // wrap drop events as needed and initialise droppable
+ var dropEvent = jpcl.dragEvents.drop;
+ dropOptions.scope = dropOptions.scope || targetScope;
+ dropOptions[dropEvent] = _ju.wrap(dropOptions[dropEvent], _drop);
+ jpcl.initDroppable(_gel(elInfo.el), dropOptions, true);
+ };
+
+ // YUI collection fix
+ el = _convertYUICollection(el);
+ // make an array if only given one element
+ var inputs = el.length && el.constructor != String ? el : [ el ];
+
+ // register each one in the list.
+ for (var i = 0, ii = inputs.length; i < ii; i++) {
+ _doOne(inputs[i]);
+ }
+
+ return _currentInstance;
+ };
+
+ // see api docs
+ this.unmakeTarget = function(el, doNotClearArrays) {
+ var info = _info(el);
+
+ jsPlumb.CurrentLibrary.destroyDroppable(info.el);
+ // TODO this is not an exhaustive unmake of a target, since it does not remove the droppable stuff from
+ // the element. the effect will be to prevent it from behaving as a target, but it's not completely purged.
+ if (!doNotClearArrays) {
+ delete _targetEndpointDefinitions[info.id];
+ delete _targetEndpointsUnique[info.id];
+ delete _targetMaxConnections[info.id];
+ delete _targetsEnabled[info.id];
+ }
+
+ return _currentInstance;
+ };
+
+ // see api docs
+ this.makeSource = function(el, params, referenceParams) {
+ var p = jsPlumb.extend({}, referenceParams);
+ jsPlumb.extend(p, params);
+ _setEndpointPaintStylesAndAnchor(p, 0);
+ var jpcl = jsPlumb.CurrentLibrary,
+ maxConnections = p.maxConnections || -1,
+ onMaxConnections = p.onMaxConnections,
+ _doOne = function(elInfo) {
+ // get the element's id and store the endpoint definition for it. jsPlumb.connect calls will look for one of these,
+ // and use the endpoint definition if found.
+ var elid = elInfo.id,
+ _el = _gel(elInfo.el),
+ parentElement = function() {
+ return p.parent == null ? null : p.parent === "parent" ? elInfo.el.parentNode : _dom(p.parent);
+ },
+ idToRegisterAgainst = p.parent != null ? _currentInstance.getId(parentElement()) : elid;
+
+ _sourceEndpointDefinitions[idToRegisterAgainst] = p;
+ _sourceEndpointsUnique[idToRegisterAgainst] = p.uniqueEndpoint;
+ _sourcesEnabled[idToRegisterAgainst] = true;
+
+ var stopEvent = jpcl.dragEvents.stop,
+ dragEvent = jpcl.dragEvents.drag,
+ dragOptions = jsPlumb.extend({ }, p.dragOptions || {}),
+ existingDrag = dragOptions.drag,
+ existingStop = dragOptions.stop,
+ ep = null,
+ endpointAddedButNoDragYet = false;
+
+ _sourceMaxConnections[idToRegisterAgainst] = maxConnections;
+
+ // set scope if its not set in dragOptions but was passed in in params
+ dragOptions.scope = dragOptions.scope || p.scope;
+
+ dragOptions[dragEvent] = _ju.wrap(dragOptions[dragEvent], function() {
+ if (existingDrag) existingDrag.apply(this, arguments);
+ endpointAddedButNoDragYet = false;
+ });
+
+ dragOptions[stopEvent] = _ju.wrap(dragOptions[stopEvent], function() {
+
+ if (existingStop) existingStop.apply(this, arguments);
+ _currentInstance.currentlyDragging = false;
+ if (ep._jsPlumb != null) { // if not cleaned up...
+
+ jpcl.unbind(ep.canvas, "mousedown");
+
+ // reset the anchor to the anchor that was initially provided. the one we were using to drag
+ // the connection was just a placeholder that was located at the place the user pressed the
+ // mouse button to initiate the drag.
+ var anchorDef = p.anchor || _currentInstance.Defaults.Anchor,
+ oldAnchor = ep.anchor,
+ oldConnection = ep.connections[0];
+
+ ep.setAnchor(_currentInstance.makeAnchor(anchorDef, elid, _currentInstance), true);
+
+ if (p.parent) {
+ var parent = parentElement();
+ if (parent) {
+ var currentId = ep.elementId,
+ potentialParent = p.container || _currentInstance.Defaults.Container || jsPlumb.Defaults.Container;
+
+ ep.setElement(parent, potentialParent);
+ ep.endpointWillMoveAfterConnection = false;
+ //_currentInstance.anchorManager.rehomeEndpoint(ep, currentId, parent);
+ oldConnection.previousConnection = null;
+ // remove from connectionsByScope
+ jsPlumbUtil.removeWithFunction(connections, function(c) {
+ return c.id === oldConnection.id;
+ });
+ _currentInstance.anchorManager.connectionDetached({
+ sourceId:oldConnection.sourceId,
+ targetId:oldConnection.targetId,
+ connection:oldConnection
+ });
+ _finaliseConnection(oldConnection);
+ }
+ }
+
+ ep.repaint();
+ _currentInstance.repaint(ep.elementId);
+ _currentInstance.repaint(oldConnection.targetId);
+ }
+ });
+ // when the user presses the mouse, add an Endpoint, if we are enabled.
+ var mouseDownListener = function(e) {
+
+ // if disabled, return.
+ if (!_sourcesEnabled[idToRegisterAgainst]) return;
+
+ // if a filter was given, run it, and return if it says no.
+ if (p.filter) {
+ var evt = jpcl.getOriginalEvent(e),
+ r = jsPlumbUtil.isString(p.filter) ? selectorFilter(evt, _el, p.filter) : p.filter(evt, _el);
+
+ if (r === false) return;
+ }
+
+ // if maxConnections reached
+ var sourceCount = _currentInstance.select({source:idToRegisterAgainst}).length;
+ if (_sourceMaxConnections[idToRegisterAgainst] >= 0 && sourceCount >= _sourceMaxConnections[idToRegisterAgainst]) {
+ if (onMaxConnections) {
+ onMaxConnections({
+ element:_el,
+ maxConnections:maxConnections
+ }, e);
+ }
+ return false;
+ }
+
+ // make sure we have the latest offset for this div
+ var myOffsetInfo = _updateOffset({elId:elid}).o,
+ z = _currentInstance.getZoom(),
+ x = ( ((e.pageX || e.page.x) / z) - myOffsetInfo.left) / myOffsetInfo.width,
+ y = ( ((e.pageY || e.page.y) / z) - myOffsetInfo.top) / myOffsetInfo.height,
+ parentX = x,
+ parentY = y;
+
+ // if there is a parent, the endpoint will actually be added to it now, rather than the div
+ // that was the source. in that case, we have to adjust the anchor position so it refers to
+ // the parent.
+ if (p.parent) {
+ var pEl = parentElement(), pId = _getId(pEl);
+ myOffsetInfo = _updateOffset({elId:pId}).o;
+ parentX = ((e.pageX || e.page.x) - myOffsetInfo.left) / myOffsetInfo.width;
+ parentY = ((e.pageY || e.page.y) - myOffsetInfo.top) / myOffsetInfo.height;
+ }
+
+ // we need to override the anchor in here, and force 'isSource', but we don't want to mess with
+ // the params passed in, because after a connection is established we're going to reset the endpoint
+ // to have the anchor we were given.
+ var tempEndpointParams = {};
+ jsPlumb.extend(tempEndpointParams, p);
+ tempEndpointParams.isSource = true;
+ tempEndpointParams.anchor = [x,y,0,0];
+ tempEndpointParams.parentAnchor = [ parentX, parentY, 0, 0 ];
+ tempEndpointParams.dragOptions = dragOptions;
+ // if a parent was given we need to turn that into a "container" argument. this is, by default,
+ // the parent of the element we will move to, so parent of p.parent in this case. however, if
+ // the user has specified a 'container' on the endpoint definition or on
+ // the defaults, we should use that.
+ if (p.parent) {
+ var potentialParent = tempEndpointParams.container || _currentInstance.Defaults.Container || jsPlumb.Defaults.Container;
+ if (potentialParent)
+ tempEndpointParams.container = potentialParent;
+ else
+ tempEndpointParams.container = jsPlumb.CurrentLibrary.getParent(parentElement());
+ }
+
+ ep = _currentInstance.addEndpoint(elid, tempEndpointParams);
+
+ endpointAddedButNoDragYet = true;
+ // we set this to prevent connections from firing attach events before this function has had a chance
+ // to move the endpoint.
+ ep.endpointWillMoveAfterConnection = p.parent != null;
+ ep.endpointWillMoveTo = p.parent ? parentElement() : null;
+
+ // TODO test options to makeSource to see if we should do this?
+ ep._doNotDeleteOnDetach = false; // reset.
+ ep._deleteOnDetach = true;
+
+ var _delTempEndpoint = function() {
+ // this mouseup event is fired only if no dragging occurred, by jquery and yui, but for mootools
+ // it is fired even if dragging has occurred, in which case we would blow away a perfectly
+ // legitimate endpoint, were it not for this check. the flag is set after adding an
+ // endpoint and cleared in a drag listener we set in the dragOptions above.
+ if(endpointAddedButNoDragYet) {
+ endpointAddedButNoDragYet = false;
+ _currentInstance.deleteEndpoint(ep);
+ }
+ };
+
+ _currentInstance.registerListener(ep.canvas, "mouseup", _delTempEndpoint);
+ _currentInstance.registerListener(_el, "mouseup", _delTempEndpoint);
+
+ // and then trigger its mousedown event, which will kick off a drag, which will start dragging
+ // a new connection from this endpoint.
+ jpcl.trigger(ep.canvas, "mousedown", e);
+
+ };
+
+ // register this on jsPlumb so that it can be cleared by a reset.
+ _currentInstance.registerListener(_el, "mousedown", mouseDownListener);
+ _sourceTriggers[elid] = mouseDownListener;
+
+ // lastly, if a filter was provided, set it as a dragFilter on the element,
+ // to prevent the element drag function from kicking in when we want to
+ // drag a new connection
+ if (p.filter && jsPlumbUtil.isString(p.filter)) {
+ jpcl.setDragFilter(_el, p.filter);
+ }
+ };
+
+ el = _convertYUICollection(el);
+
+ var inputs = el.length && el.constructor != String ? el : [ el ];
+
+ for (var i = 0, ii = inputs.length; i < ii; i++) {
+ _doOne(_info(inputs[i]));
+ }
+
+ return _currentInstance;
+ };
+
+ // see api docs
+ this.unmakeSource = function(el, doNotClearArrays) {
+ var info = _info(el),
+ mouseDownListener = _sourceTriggers[info.id];
+
+ if (mouseDownListener)
+ _currentInstance.unregisterListener(info.el, "mousedown", mouseDownListener);
+
+ if (!doNotClearArrays) {
+ delete _sourceEndpointDefinitions[info.id];
+ delete _sourceEndpointsUnique[info.id];
+ delete _sourcesEnabled[info.id];
+ delete _sourceTriggers[info.id];
+ delete _sourceMaxConnections[info.id];
+ }
+
+ return _currentInstance;
+ };
+
+ // see api docs
+ this.unmakeEverySource = function() {
+ for (var i in _sourcesEnabled)
+ _currentInstance.unmakeSource(i, true);
+
+ _sourceEndpointDefinitions = {};
+ _sourceEndpointsUnique = {};
+ _sourcesEnabled = {};
+ _sourceTriggers = {};
+ };
+
+ // see api docs
+ this.unmakeEveryTarget = function() {
+ for (var i in _targetsEnabled)
+ _currentInstance.unmakeTarget(i, true);
+
+ _targetEndpointDefinitions = {};
+ _targetEndpointsUnique = {};
+ _targetMaxConnections = {};
+ _targetsEnabled = {};
+
+ return _currentInstance;
+ };
+
+ // does the work of setting a source enabled or disabled.
+ var _setEnabled = function(type, el, state, toggle) {
+ var a = type == "source" ? _sourcesEnabled : _targetsEnabled;
+ el = _convertYUICollection(el);
+
+ if (_ju.isString(el)) a[el] = toggle ? !a[el] : state;
+ else if (el.length) {
+ for (var i = 0, ii = el.length; i < ii; i++) {
+ var info = _info(el[i]);
+ a[info.id] = toggle ? !a[info.id] : state;
+ }
+ }
+ return _currentInstance;
+ };
+
+ this.toggleSourceEnabled = function(el) {
+ _setEnabled("source", el, null, true);
+ return _currentInstance.isSourceEnabled(el);
+ };
+
+ this.setSourceEnabled = function(el, state) { return _setEnabled("source", el, state); };
+ this.isSource = function(el) { return _sourcesEnabled[_info(el).id] != null; };
+ this.isSourceEnabled = function(el) { return _sourcesEnabled[_info(el).id] === true; };
+
+ this.toggleTargetEnabled = function(el) {
+ _setEnabled("target", el, null, true);
+ return _currentInstance.isTargetEnabled(el);
+ };
+
+ this.isTarget = function(el) { return _targetsEnabled[_info(el).id] != null; };
+ this.isTargetEnabled = function(el) { return _targetsEnabled[_info(el).id] === true; };
+ this.setTargetEnabled = function(el, state) { return _setEnabled("target", el, state); };
+
+// --------------------- end makeSource/makeTarget ----------------------------------------------
+
+ this.ready = function(fn) {
+ _currentInstance.bind("ready", fn);
+ };
+
+ // repaint some element's endpoints and connections
+ this.repaint = function(el, ui, timestamp) {
+ // support both lists...
+ if (typeof el == 'object' && el.length)
+ for ( var i = 0, ii = el.length; i < ii; i++) {
+ _draw(el[i], ui, timestamp);
+ }
+ else // ...and single strings.
+ _draw(el, ui, timestamp);
+
+ return _currentInstance;
+ };
+
+ // repaint every endpoint and connection.
+ this.repaintEverything = function() {
+ // TODO this timestamp causes continuous anchors to not repaint properly.
+ // fix this. do not just take out the timestamp. it runs a lot faster with
+ // the timestamp included.
+ var timestamp = _timestamp();
+ for ( var elId in endpointsByElement) {
+ _draw(elId, null, timestamp);
+ }
+ return _currentInstance;
+ /*for (var i = 0; i < connections.length; i++)
+ connections[i].repaint({timestamp:timestamp});*/
+ };
+
+
+ this.removeAllEndpoints = function(el, recurse) {
+ var _one = function(_el) {
+ var info = _info(_el),
+ ebe = endpointsByElement[info.id],
+ i, ii;
+
+ if (ebe) {
+ for ( i = 0, ii = ebe.length; i < ii; i++)
+ _currentInstance.deleteEndpoint(ebe[i]);
+ }
+ delete endpointsByElement[info.id];
+
+ if (recurse) {
+ if (info.el && info.el.nodeType != 3 && info.el.nodeType != 8 ) {
+ for ( i = 0, ii = info.el.childNodes.length; i < ii; i++) {
+ _one(info.el.childNodes[i]);
+ }
+ }
+ }
+
+ };
+ _one(el);
+ return _currentInstance;
+ };
+
+ /**
+ * Remove the given element, including cleaning up all endpoints registered for it.
+ * This is exposed in the public API but also used internally by jsPlumb when removing the
+ * element associated with a connection drag.
+ */
+ this.remove = function(el, doNotRepaint) {
+ var info = _info(el);
+ _currentInstance.doWhileSuspended(function() {
+ _currentInstance.removeAllEndpoints(info.id, true);
+ _currentInstance.dragManager.elementRemoved(info.id);
+ delete floatingConnections[info.id];
+ _currentInstance.anchorManager.clearFor(info.id);
+ _currentInstance.anchorManager.removeFloatingConnection(info.id);
+ }, doNotRepaint === false);
+ if(info.el) jsPlumb.CurrentLibrary.removeElement(info.el);
+ };
+
+ var _registeredListeners = {},
+ _unbindRegisteredListeners = function() {
+ for (var i in _registeredListeners) {
+ for (var j = 0, jj = _registeredListeners[i].length; j < jj; j++) {
+ var info = _registeredListeners[i][j];
+ jsPlumb.CurrentLibrary.unbind(info.el, info.event, info.listener);
+ }
+ }
+ _registeredListeners = {};
+ };
+
+ // internal register listener method. gives us a hook to clean things up
+ // with if the user calls jsPlumb.reset.
+ this.registerListener = function(el, type, listener) {
+ jsPlumb.CurrentLibrary.bind(el, type, listener);
+ jsPlumbUtil.addToList(_registeredListeners, type, {el:el, event:type, listener:listener});
+ };
+
+ this.unregisterListener = function(el, type, listener) {
+ jsPlumb.CurrentLibrary.unbind(el, type, listener);
+ jsPlumbUtil.removeWithFunction(_registeredListeners, function(rl) {
+ return rl.type == type && rl.listener == listener;
+ });
+ };
+
+ this.reset = function() {
+ _currentInstance.deleteEveryEndpoint();
+ _currentInstance.unbind();
+ _targetEndpointDefinitions = {};
+ _targetEndpoints = {};
+ _targetEndpointsUnique = {};
+ _targetMaxConnections = {};
+ _sourceEndpointDefinitions = {};
+ _sourceEndpoints = {};
+ _sourceEndpointsUnique = {};
+ _sourceMaxConnections = {};
+ connections.splice(0);
+ _unbindRegisteredListeners();
+ _currentInstance.anchorManager.reset();
+ if (!jsPlumbAdapter.headless)
+ _currentInstance.dragManager.reset();
+ };
+
+
+ this.setDefaultScope = function(scope) {
+ DEFAULT_SCOPE = scope;
+ return _currentInstance;
+ };
+
+ // sets whether or not some element should be currently draggable.
+ this.setDraggable = _setDraggable;
+
+ // sets the id of some element, changing whatever we need to to keep track.
+ this.setId = function(el, newId, doNotSetAttribute) {
+ //
+ var id;
+
+ if (jsPlumbUtil.isString(el)) {
+ id = el;
+ }
+ else {
+ el = _dom(el);
+ id = _currentInstance.getId(el);
+ }
+
+ var sConns = _currentInstance.getConnections({source:id, scope:'*'}, true),
+ tConns = _currentInstance.getConnections({target:id, scope:'*'}, true);
+
+ newId = "" + newId;
+
+ if (!doNotSetAttribute) {
+ el = _dom(id);
+ jsPlumbAdapter.setAttribute(el, "id", newId);
+ }
+ else
+ el = _dom(newId);
+
+ endpointsByElement[newId] = endpointsByElement[id] || [];
+ for (var i = 0, ii = endpointsByElement[newId].length; i < ii; i++) {
+ endpointsByElement[newId][i].setElementId(newId);
+ endpointsByElement[newId][i].setReferenceElement(el);
+ }
+ delete endpointsByElement[id];
+
+ _currentInstance.anchorManager.changeId(id, newId);
+ if (!jsPlumbAdapter.headless)
+ _currentInstance.dragManager.changeId(id, newId);
+
+ var _conns = function(list, epIdx, type) {
+ for (var i = 0, ii = list.length; i < ii; i++) {
+ list[i].endpoints[epIdx].setElementId(newId);
+ list[i].endpoints[epIdx].setReferenceElement(el);
+ list[i][type + "Id"] = newId;
+ list[i][type] = el;
+ }
+ };
+ _conns(sConns, 0, "source");
+ _conns(tConns, 1, "target");
+
+ _currentInstance.repaint(newId);
+ };
+
+ this.setDebugLog = function(debugLog) {
+ log = debugLog;
+ };
+
+ this.setSuspendDrawing = function(val, repaintAfterwards) {
+ var curVal = _suspendDrawing;
+ _suspendDrawing = val;
+ if (val) _suspendedAt = new Date().getTime(); else _suspendedAt = null;
+ if (repaintAfterwards) _currentInstance.repaintEverything();
+ return curVal;
+ };
+
+ // returns whether or not drawing is currently suspended.
+ this.isSuspendDrawing = function() {
+ return _suspendDrawing;
+ };
+
+ // return timestamp for when drawing was suspended.
+ this.getSuspendedAt = function() { return _suspendedAt; };
+
+ /**
+ * @doc function
+ * @name jsPlumb.class:doWhileSuspended
+ * @param {function} fn Function to run while suspended.
+ * @param {boolean} doNotRepaintAfterwards If true, jsPlumb won't run a full repaint. Otherwise it will.
+ * @description Suspends drawing, runs the given function, then re-enables drawing (and repaints, unless you tell it not to)
+ */
+ this.doWhileSuspended = function(fn, doNotRepaintAfterwards) {
+ var _wasSuspended = _currentInstance.isSuspendDrawing();
+ if (!_wasSuspended)
+ _currentInstance.setSuspendDrawing(true);
+ try {
+ fn();
+ }
+ catch (e) {
+ _ju.log("Function run while suspended failed", e);
+ }
+ if (!_wasSuspended)
+ _currentInstance.setSuspendDrawing(false, !doNotRepaintAfterwards);
+ };
+
+ this.updateOffset = _updateOffset;
+ this.getOffset = function(elId) { return offsets[elId]; };
+ this.getSize = function(elId) { return sizes[elId]; };
+ this.getCachedData = _getCachedData;
+ this.timestamp = _timestamp;
+
+
+
+ /**
+ * @doc function
+ * @name jsPlumb.class:setRenderMode
+ * @param {string} mode One of `jsPlumb.SVG, `jsPlumb.VML` or `jsPlumb.CANVAS`.
+ * @description Sets render mode. jsPlumb will fall back to VML if it determines that
+ * what you asked for is not supported (and that VML is). If you asked for VML but the browser does
+ * not support it, jsPlumb uses SVG.
+ * @return {string} The render mode that jsPlumb set, which of course may be different from that requested.
+ */
+ this.setRenderMode = function(mode) {
+ renderMode = jsPlumbAdapter.setRenderMode(mode);
+ var i, ii;
+ // only add this if the renderer is canvas; we dont want these listeners registered on te
+ // entire document otherwise.
+ if (renderMode == jsPlumb.CANVAS) {
+ var bindOne = function(event) {
+ jsPlumb.CurrentLibrary.bind(document, event, function(e) {
+ if (!_currentInstance.currentlyDragging && renderMode == jsPlumb.CANVAS) {
+ // try connections first
+ for (i = 0, ii = connections.length; i < ii; i++ ) {
+ var t = connections[i].getConnector()[event](e);
+ if (t) return;
+ }
+ for (var el in endpointsByElement) {
+ var ee = endpointsByElement[el];
+ for ( i = 0, ii = ee.length; i < ii; i++ ) {
+ if (ee[i].endpoint[event] && ee[i].endpoint[event](e)) return;
+ }
+ }
+ }
+ });
+ };
+ bindOne("click");bindOne("dblclick");bindOne("mousemove");bindOne("mousedown");bindOne("mouseup");bindOne("contextmenu");
+ }
+
+ return renderMode;
+ };
+
+ /**
+ * @doc function
+ * @name jsPlumb.class:getRenderMode
+ * @description Gets the current render mode for this instance of jsPlumb.
+ * @return {string} The current render mode - "canvas", "svg" or "vml".
+ */
+ this.getRenderMode = function() { return renderMode; };
+
+ this.show = function(el, changeEndpoints) {
+ _setVisible(el, "block", changeEndpoints);
+ return _currentInstance;
+ };
+
+ /**
+ * gets some test hooks. nothing writable.
+ */
+ this.getTestHarness = function() {
+ return {
+ endpointsByElement : endpointsByElement,
+ endpointCount : function(elId) {
+ var e = endpointsByElement[elId];
+ return e ? e.length : 0;
+ },
+ connectionCount : function(scope) {
+ scope = scope || DEFAULT_SCOPE;
+ var c = _currentInstance.getConnections({scope:scope});
+ return c ? c.length : 0;
+ },
+ getId : _getId,
+ makeAnchor:self.makeAnchor,
+ makeDynamicAnchor:self.makeDynamicAnchor
+ };
+ };
+
+
+ // TODO: update this method to return the current state.
+ this.toggleVisible = _toggleVisible;
+ this.toggleDraggable = _toggleDraggable;
+ this.addListener = this.bind;
+
+ /*
+ helper method to take an xy location and adjust it for the parent's offset and scroll.
+ */
+ this.adjustForParentOffsetAndScroll = function(xy, el) {
+
+ var offsetParent = null, result = xy;
+ if (el.tagName.toLowerCase() === "svg" && el.parentNode) {
+ offsetParent = el.parentNode;
+ }
+ else if (el.offsetParent) {
+ offsetParent = el.offsetParent;
+ }
+ if (offsetParent != null) {
+ var po = offsetParent.tagName.toLowerCase() === "body" ? {left:0,top:0} : _getOffset(offsetParent, _currentInstance),
+ so = offsetParent.tagName.toLowerCase() === "body" ? {left:0,top:0} : {left:offsetParent.scrollLeft, top:offsetParent.scrollTop};
+
+ // i thought it might be cool to do this:
+ // lastReturnValue[0] = lastReturnValue[0] - offsetParent.offsetLeft + offsetParent.scrollLeft;
+ // lastReturnValue[1] = lastReturnValue[1] - offsetParent.offsetTop + offsetParent.scrollTop;
+ // but i think it ignores margins. my reasoning was that it's quicker to not hand off to some underlying
+ // library.
+
+ result[0] = xy[0] - po.left + so.left;
+ result[1] = xy[1] - po.top + so.top;
+ }
+
+ return result;
+
+ };
+
+ if (!jsPlumbAdapter.headless) {
+ _currentInstance.dragManager = jsPlumbAdapter.getDragManager(_currentInstance);
+ _currentInstance.recalculateOffsets = _currentInstance.dragManager.updateOffsets;
+ }
+
+ };
+
+ jsPlumbUtil.extend(jsPlumbInstance, jsPlumbUtil.EventGenerator, {
+ setAttribute : function(el, a, v) {
+ jsPlumbAdapter.setAttribute(el, a, v);
+ },
+ getAttribute : function(el, a) {
+ return jsPlumbAdapter.getAttribute(jsPlumb.CurrentLibrary.getDOMElement(el), a);
+ },
+ registerConnectionType : function(id, type) {
+ this._connectionTypes[id] = jsPlumb.extend({}, type);
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:registerConnectionTypes
+ * @param {object} types Object containing the type specifications.
+ * @description
+ * Registers all of the given connection types on this instance of jsPlumb. `types` is expected
+ * to contain keys with typeids and values with type specification objects.
+ */
+ registerConnectionTypes : function(types) {
+ for (var i in types)
+ this._connectionTypes[i] = jsPlumb.extend({}, types[i]);
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:registerEndpointType
+ * @param {string} typeId Id of the type
+ * @param {object} type Object containing the type specification.
+ * @description
+ * Registers the given endpoint type on this instance of jsPlumb.
+ */
+ registerEndpointType : function(id, type) {
+ this._endpointTypes[id] = jsPlumb.extend({}, type);
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:registerEndpointTypes
+ * @param {object} types Object containing the type specifications.
+ * @description
+ * Registers all of the given endpoint types on this instance of jsPlumb. `types` is expected
+ * to contain keys with typeids and values with type specification objects.
+ */
+ registerEndpointTypes : function(types) {
+ for (var i in types)
+ this._endpointTypes[i] = jsPlumb.extend({}, types[i]);
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:getType
+ * @param {string} id Id of the type to retrieve
+ * @param {string} typeDescriptor `"connection"` or `"endpoint"` - the type of Type to get.
+ * @description
+ * Returns the given type's specification.
+ * @return {object} Type specification, it if exists, null otherwise.
+ */
+ getType : function(id, typeDescriptor) {
+ return typeDescriptor === "connection" ? this._connectionTypes[id] : this._endpointTypes[id];
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:setIdChanged
+ * @param {oldId} string Previous id
+ * @param {newId} string Element's new id.
+ * @description called to notify us that an id WAS changed, and we should do our changes, but we
+ * dont need to change the element's DOM attribute. note that this does not work if the an element with
+ * the new id is not in the DOM.
+ */
+ setIdChanged : function(oldId, newId) {
+ this.setId(oldId, newId, true);
+ }
+ });
+
+// --------------------- static instance + AMD registration -------------------------------------------
+
+// create static instance and assign to window if window exists.
+ var jsPlumb = new jsPlumbInstance();
+ // register on window if defined (lets us run on server)
+ if (typeof window != 'undefined') window.jsPlumb = jsPlumb;
+ // add 'getInstance' method to static instance
+ /**
+ * @name jsPlumb.getInstance
+ * @param {object} [_defaults] Optional default settings for the new instance.
+ * @desc Gets a new instance of jsPlumb.
+ */
+ jsPlumb.getInstance = function(_defaults) {
+ var j = new jsPlumbInstance(_defaults);
+ j.init();
+ return j;
+ };
+// maybe register static instance as an AMD module, and getInstance method too.
+ if ( typeof define === "function") {
+ define( "jsplumb", [], function () { return jsPlumb; } );
+ define( "jsplumbinstance", [], function () { return jsPlumb.getInstance(); } );
+ }
+ // CommonJS
+ if (typeof exports !== 'undefined') {
+ exports.jsPlumb = jsPlumb;
+ }
+
+
+// --------------------- end static instance + AMD registration -------------------------------------------
+
+})();
+
+
+;(function() {
+
+ // create the drag handler for a connection
+ var _makeConnectionDragHandler = function(placeholder, _jsPlumb) {
+ var stopped = false;
+ return {
+ drag : function() {
+ if (stopped) {
+ stopped = false;
+ return true;
+ }
+ var _ui = jsPlumb.CurrentLibrary.getUIPosition(arguments, _jsPlumb.getZoom());
+
+ if (placeholder.element) {
+ jsPlumb.CurrentLibrary.setOffset(placeholder.element, _ui);
+ _jsPlumb.repaint(placeholder.element, _ui);
+ }
+ },
+ stopDrag : function() {
+ stopped = true;
+ }
+ };
+ };
+
+ // creates a placeholder div for dragging purposes, adds it to the DOM, and pre-computes its offset.
+ var _makeDraggablePlaceholder = function(placeholder, parent, _jsPlumb) {
+ var n = document.createElement("div");
+ n.style.position = "absolute";
+ var placeholderDragElement = jsPlumb.CurrentLibrary.getElementObject(n);
+ jsPlumb.CurrentLibrary.appendElement(n, parent);
+ var id = _jsPlumb.getId(n);
+ _jsPlumb.updateOffset( { elId : id });
+ // create and assign an id, and initialize the offset.
+ placeholder.id = id;
+ placeholder.element = n;//placeholderDragElement;
+ };
+
+ // create a floating endpoint (for drag connections)
+ var _makeFloatingEndpoint = function(paintStyle, referenceAnchor, endpoint, referenceCanvas, sourceElement, _jsPlumb, _newEndpoint) {
+ var floatingAnchor = new jsPlumb.FloatingAnchor( { reference : referenceAnchor, referenceCanvas : referenceCanvas, jsPlumbInstance:_jsPlumb });
+ //setting the scope here should not be the way to fix that mootools issue. it should be fixed by not
+ // adding the floating endpoint as a droppable. that makes more sense anyway!
+ return _newEndpoint({ paintStyle : paintStyle, endpoint : endpoint, anchor : floatingAnchor, source : sourceElement, scope:"__floating" });
+ };
+
+ var typeParameters = [ "connectorStyle", "connectorHoverStyle", "connectorOverlays",
+ "connector", "connectionType", "connectorClass", "connectorHoverClass" ];
+
+ // a helper function that tries to find a connection to the given element, and returns it if so. if elementWithPrecedence is null,
+ // or no connection to it is found, we return the first connection in our list.
+ var findConnectionToUseForDynamicAnchor = function(ep, elementWithPrecedence) {
+ var idx = 0;
+ if (elementWithPrecedence != null) {
+ for (var i = 0; i < ep.connections.length; i++) {
+ if (ep.connections[i].sourceId == elementWithPrecedence || ep.connections[i].targetId == elementWithPrecedence) {
+ idx = i;
+ break;
+ }
+ }
+ }
+
+ return ep.connections[idx];
+ };
+
+ var findConnectionIndex = function(conn, ep) {
+ return jsPlumbUtil.findWithFunction(ep.connections, function(c) { return c.id == conn.id; });
+ };
+
+ jsPlumb.Endpoint = function(params) {
+ var _jsPlumb = params._jsPlumb,
+ jpcl = jsPlumb.CurrentLibrary,
+ _att = jsPlumbAdapter.getAttribute,
+ _gel = jpcl.getElementObject,
+ _dom = jpcl.getDOMElement,
+ _ju = jsPlumbUtil,
+ _newConnection = params.newConnection,
+ _newEndpoint = params.newEndpoint,
+ _finaliseConnection = params.finaliseConnection,
+ _fireDetachEvent = params.fireDetachEvent,
+ floatingConnections = params.floatingConnections;
+
+ this.idPrefix = "_jsplumb_e_";
+ this.defaultLabelLocation = [ 0.5, 0.5 ];
+ this.defaultOverlayKeys = ["Overlays", "EndpointOverlays"];
+ this.parent = params.parent;
+ OverlayCapableJsPlumbUIComponent.apply(this, arguments);
+
+// TYPE
+
+ this.getDefaultType = function() {
+ return {
+ parameters:{},
+ scope:null,
+ maxConnections:this._jsPlumb.instance.Defaults.MaxConnections,
+ paintStyle:this._jsPlumb.instance.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle,
+ endpoint:this._jsPlumb.instance.Defaults.Endpoint || jsPlumb.Defaults.Endpoint,
+ hoverPaintStyle:this._jsPlumb.instance.Defaults.EndpointHoverStyle || jsPlumb.Defaults.EndpointHoverStyle,
+ overlays:this._jsPlumb.instance.Defaults.EndpointOverlays || jsPlumb.Defaults.EndpointOverlays,
+ connectorStyle:params.connectorStyle,
+ connectorHoverStyle:params.connectorHoverStyle,
+ connectorClass:params.connectorClass,
+ connectorHoverClass:params.connectorHoverClass,
+ connectorOverlays:params.connectorOverlays,
+ connector:params.connector,
+ connectorTooltip:params.connectorTooltip
+ };
+ };
+
+// END TYPE
+
+ this._jsPlumb.enabled = !(params.enabled === false);
+ this._jsPlumb.visible = true;
+ this.element = _dom(params.source);
+ this._jsPlumb.uuid = params.uuid;
+ this._jsPlumb.floatingEndpoint = null;
+ var inPlaceCopy = null;
+ if (this._jsPlumb.uuid) params.endpointsByUUID[this._jsPlumb.uuid] = this;
+ this.elementId = params.elementId;
+
+ this._jsPlumb.connectionCost = params.connectionCost;
+ this._jsPlumb.connectionsDirected = params.connectionsDirected;
+ this._jsPlumb.currentAnchorClass = "";
+ this._jsPlumb.events = {};
+
+ var _updateAnchorClass = function() {
+ jpcl.removeClass(this.element, _jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ this.removeClass(_jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ this._jsPlumb.currentAnchorClass = this.anchor.getCssClass();
+ this.addClass(_jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ jpcl.addClass(this.element, _jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ }.bind(this);
+
+ this.setAnchor = function(anchorParams, doNotRepaint) {
+ this._jsPlumb.instance.continuousAnchorFactory.clear(this.elementId);
+ this.anchor = this._jsPlumb.instance.makeAnchor(anchorParams, this.elementId, _jsPlumb);
+ _updateAnchorClass();
+ this.anchor.bind("anchorChanged", function(currentAnchor) {
+ this.fire("anchorChanged", {endpoint:this, anchor:currentAnchor});
+ _updateAnchorClass();
+ }.bind(this));
+ if (!doNotRepaint)
+ this._jsPlumb.instance.repaint(this.elementId);
+ return this;
+ };
+
+ var anchorParamsToUse = params.anchor ? params.anchor : params.anchors ? params.anchors : (_jsPlumb.Defaults.Anchor || "Top");
+ this.setAnchor(anchorParamsToUse, true);
+
+ // endpoint delegates to first connection for hover, if there is one.
+ var internalHover = function(state) {
+ if (this.connections.length > 0)
+ this.connections[0].setHover(state, false);
+ else
+ this.setHover(state);
+ }.bind(this);
+
+ // ANCHOR MANAGER
+ if (!params._transient) // in place copies, for example, are transient. they will never need to be retrieved during a paint cycle, because they dont move, and then they are deleted.
+ this._jsPlumb.instance.anchorManager.add(this, this.elementId);
+
+ this.setEndpoint = function(ep) {
+
+ if (this.endpoint != null) {
+ this.endpoint.cleanup();
+ this.endpoint.destroy();
+ }
+
+ var _e = function(t, p) {
+ var rm = _jsPlumb.getRenderMode();
+ if (jsPlumb.Endpoints[rm][t]) return new jsPlumb.Endpoints[rm][t](p);
+ if (!_jsPlumb.Defaults.DoNotThrowErrors)
+ throw { msg:"jsPlumb: unknown endpoint type '" + t + "'" };
+ };
+
+ var endpointArgs = {
+ _jsPlumb:this._jsPlumb.instance,
+ cssClass:params.cssClass,
+ parent:params.parent,
+ container:params.container,
+ tooltip:params.tooltip,
+ connectorTooltip:params.connectorTooltip,
+ endpoint:this
+ };
+ if (_ju.isString(ep))
+ this.endpoint = _e(ep, endpointArgs);
+ else if (_ju.isArray(ep)) {
+ endpointArgs = _ju.merge(ep[1], endpointArgs);
+ this.endpoint = _e(ep[0], endpointArgs);
+ }
+ else {
+ this.endpoint = ep.clone();
+ }
+
+ // assign a clone function using a copy of endpointArgs. this is used when a drag starts: the endpoint that was dragged is cloned,
+ // and the clone is left in its place while the original one goes off on a magical journey.
+ // the copy is to get around a closure problem, in which endpointArgs ends up getting shared by
+ // the whole world.
+ var argsForClone = jsPlumb.extend({}, endpointArgs);
+ this.endpoint.clone = function() {
+ // TODO this, and the code above, can be refactored to be more dry.
+ if (_ju.isString(ep))
+ return _e(ep, endpointArgs);
+ else if (_ju.isArray(ep)) {
+ endpointArgs = _ju.merge(ep[1], endpointArgs);
+ return _e(ep[0], endpointArgs);
+ }
+ }.bind(this);
+
+ this.type = this.endpoint.type;
+ // bind listeners from endpoint to self, with the internal hover function defined above.
+ this.bindListeners(this.endpoint, this, internalHover);
+ };
+
+ this.setEndpoint(params.endpoint || _jsPlumb.Defaults.Endpoint || jsPlumb.Defaults.Endpoint || "Dot");
+ this.setPaintStyle(params.paintStyle || params.style || _jsPlumb.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle, true);
+ this.setHoverPaintStyle(params.hoverPaintStyle || _jsPlumb.Defaults.EndpointHoverStyle || jsPlumb.Defaults.EndpointHoverStyle, true);
+ this._jsPlumb.paintStyleInUse = this.getPaintStyle();
+
+ _ju.copyValues(typeParameters, params, this);
+
+ this.isSource = params.isSource || false;
+ this.isTarget = params.isTarget || false;
+ this._jsPlumb.maxConnections = params.maxConnections || _jsPlumb.Defaults.MaxConnections; // maximum number of connections this endpoint can be the source of.
+ this.canvas = this.endpoint.canvas;
+ // add anchor class (need to do this on construction because we set anchor first)
+ this.addClass(_jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ jpcl.addClass(this.element, _jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ this.connections = params.connections || [];
+ this.connectorPointerEvents = params["connector-pointer-events"];
+
+ this.scope = params.scope || _jsPlumb.getDefaultScope();
+ this.timestamp = null;
+ this.reattachConnections = params.reattach || _jsPlumb.Defaults.ReattachConnections;
+ this.connectionsDetachable = _jsPlumb.Defaults.ConnectionsDetachable;
+ if (params.connectionsDetachable === false || params.detachable === false)
+ this.connectionsDetachable = false;
+ this.dragAllowedWhenFull = params.dragAllowedWhenFull || true;
+
+ if (params.onMaxConnections)
+ this.bind("maxConnections", params.onMaxConnections);
+
+ //
+ // add a connection. not part of public API.
+ //
+ this.addConnection = function(connection) {
+ this.connections.push(connection);
+ this[(this.connections.length > 0 ? "add" : "remove") + "Class"](_jsPlumb.endpointConnectedClass);
+ this[(this.isFull() ? "add" : "remove") + "Class"](_jsPlumb.endpointFullClass);
+ };
+
+ this.detachFromConnection = function(connection, idx) {
+ idx = idx == null ? findConnectionIndex(connection, this) : idx;
+ if (idx >= 0) {
+ this.connections.splice(idx, 1);
+ this[(this.connections.length > 0 ? "add" : "remove") + "Class"](_jsPlumb.endpointConnectedClass);
+ this[(this.isFull() ? "add" : "remove") + "Class"](_jsPlumb.endpointFullClass);
+ }
+ };
+
+ this.detach = function(connection, ignoreTarget, forceDetach, fireEvent, originalEvent, endpointBeingDeleted, connectionIndex) {
+
+ var idx = connectionIndex == null ? findConnectionIndex(connection, this) : connectionIndex,
+ actuallyDetached = false;
+ fireEvent = (fireEvent !== false);
+
+ if (idx >= 0) {
+ if (forceDetach || connection._forceDetach || (connection.isDetachable() && connection.isDetachAllowed(connection) && this.isDetachAllowed(connection) )) {
+
+ //connection.setHover(false);
+
+ _jsPlumb.deleteObject({
+ connection:connection,
+ fireEvent:(!ignoreTarget && fireEvent),
+ originalEvent:originalEvent
+ });
+ actuallyDetached = true;
+ }
+ }
+ return actuallyDetached;
+ };
+
+ this.detachAll = function(fireEvent, originalEvent) {
+ while (this.connections.length > 0) {
+ // TODO this could pass the index in to the detach method to save some time (index will always be zero in this while loop)
+ // TODO now it defaults to fireEvent true. will that mess with things?
+ this.detach(this.connections[0], false, true, fireEvent !== false, originalEvent, this, 0);
+ }
+ return this;
+ };
+ this.detachFrom = function(targetEndpoint, fireEvent, originalEvent) {
+ var c = [];
+ for ( var i = 0; i < this.connections.length; i++) {
+ if (this.connections[i].endpoints[1] == targetEndpoint || this.connections[i].endpoints[0] == targetEndpoint) {
+ c.push(this.connections[i]);
+ }
+ }
+ for ( var j = 0; j < c.length; j++) {
+ this.detach(c[j], false, true, fireEvent, originalEvent);
+ }
+ return this;
+ };
+
+ this.getElement = function() {
+ return this.element;
+ };
+
+ // container not supported in 1.5.2; you cannot change the container once it is set.
+ // it might come back int a future release.
+ this.setElement = function(el/*, container*/) {
+ var parentId = this._jsPlumb.instance.getId(el),
+ curId = this.elementId;
+ // remove the endpoint from the list for the current endpoint's element
+ _ju.removeWithFunction(params.endpointsByElement[this.elementId], function(e) {
+ return e.id == this.id;
+ }.bind(this));
+ this.element = _dom(el);
+ this.elementId = _jsPlumb.getId(this.element);
+ _jsPlumb.anchorManager.rehomeEndpoint(this, curId, this.element);
+ _jsPlumb.dragManager.endpointAdded(this.element);
+ _ju.addToList(params.endpointsByElement, parentId, this);
+ return this;
+ };
+
+ /**
+ * private but must be exposed.
+ */
+ this.makeInPlaceCopy = function() {
+ var loc = this.anchor.getCurrentLocation({element:this}),
+ o = this.anchor.getOrientation(this),
+ acc = this.anchor.getCssClass(),
+ inPlaceAnchor = {
+ bind:function() { },
+ compute:function() { return [ loc[0], loc[1] ]; },
+ getCurrentLocation : function() { return [ loc[0], loc[1] ]; },
+ getOrientation:function() { return o; },
+ getCssClass:function() { return acc; }
+ };
+
+ return _newEndpoint( {
+ anchor : inPlaceAnchor,
+ source : this.element,
+ paintStyle : this.getPaintStyle(),
+ endpoint : params.hideOnDrag ? "Blank" : this.endpoint,
+ _transient:true,
+ scope:this.scope
+ });
+ };
+
+
+ /**
+ * private but needs to be exposed.
+ */
+ this.isFloating = function() {
+ return this.anchor != null && this.anchor.isFloating;
+ };
+
+ /**
+ * returns a connection from the pool; used when dragging starts. just gets the head of the array if it can.
+ */
+ this.connectorSelector = function() {
+ var candidate = this.connections[0];
+ if (this.isTarget && candidate) return candidate;
+ else {
+ return (this.connections.length < this._jsPlumb.maxConnections) || this._jsPlumb.maxConnections == -1 ? null : candidate;
+ }
+ };
+
+ this.setStyle = this.setPaintStyle;
+
+ this.paint = function(params) {
+ params = params || {};
+ var timestamp = params.timestamp, recalc = !(params.recalc === false);
+ if (!timestamp || this.timestamp !== timestamp) {
+
+ // TODO check: is this is a safe performance enhancement?
+ var info = _jsPlumb.updateOffset({ elId:this.elementId, timestamp:timestamp/*, recalc:recalc*/ });
+ //var info = _jsPlumb.updateOffset({ elId:_elementId, timestamp:timestamp, recalc:recalc });
+
+ var xy = params.offset ? params.offset.o : info.o;
+ if(xy != null) {
+ var ap = params.anchorPoint,connectorPaintStyle = params.connectorPaintStyle;
+ if (ap == null) {
+ var wh = params.dimensions || info.s,
+ anchorParams = { xy : [ xy.left, xy.top ], wh : wh, element : this, timestamp : timestamp };
+ if (recalc && this.anchor.isDynamic && this.connections.length > 0) {
+ var c = findConnectionToUseForDynamicAnchor(this, params.elementWithPrecedence),
+ oIdx = c.endpoints[0] == this ? 1 : 0,
+ oId = oIdx === 0 ? c.sourceId : c.targetId,
+ oInfo = _jsPlumb.getCachedData(oId),
+ oOffset = oInfo.o, oWH = oInfo.s;
+ anchorParams.txy = [ oOffset.left, oOffset.top ];
+ anchorParams.twh = oWH;
+ anchorParams.tElement = c.endpoints[oIdx];
+ }
+ ap = this.anchor.compute(anchorParams);
+ }
+
+ this.endpoint.compute(ap, this.anchor.getOrientation(this), this._jsPlumb.paintStyleInUse, connectorPaintStyle || this.paintStyleInUse);
+ this.endpoint.paint(this._jsPlumb.paintStyleInUse, this.anchor);
+ this.timestamp = timestamp;
+
+ // paint overlays
+ for ( var i = 0; i < this._jsPlumb.overlays.length; i++) {
+ var o = this._jsPlumb.overlays[i];
+ if (o.isVisible()) {
+ this._jsPlumb.overlayPlacements[i] = o.draw(this.endpoint, this._jsPlumb.paintStyleInUse);
+ o.paint(this._jsPlumb.overlayPlacements[i]);
+ }
+ }
+ }
+ }
+ };
+
+ this.repaint = this.paint;
+
+ // is this a connection source? we make it draggable and have the
+ // drag listener maintain a connection with a floating endpoint.
+ if (jpcl.isDragSupported(this.element) && (this.isSource || this.isTarget)) {
+ var placeholderInfo = { id:null, element:null },
+ jpc = null,
+ existingJpc = false,
+ existingJpcParams = null,
+ _dragHandler = _makeConnectionDragHandler(placeholderInfo, _jsPlumb);
+
+ var start = function() {
+ // drag might have started on an endpoint that is not actually a source, but which has
+ // one or more connections.
+ jpc = this.connectorSelector();
+ var _continue = true;
+ // if not enabled, return
+ if (!this.isEnabled()) _continue = false;
+ // if no connection and we're not a source, return.
+ if (jpc == null && !this.isSource) _continue = false;
+ // otherwise if we're full and not allowed to drag, also return false.
+ if (this.isSource && this.isFull() && !this.dragAllowedWhenFull) _continue = false;
+ // if the connection was setup as not detachable or one of its endpoints
+ // was setup as connectionsDetachable = false, or Defaults.ConnectionsDetachable
+ // is set to false...
+ if (jpc != null && !jpc.isDetachable()) _continue = false;
+
+ if (_continue === false) {
+ // this is for mootools and yui. returning false from this causes jquery to stop drag.
+ // the events are wrapped in both mootools and yui anyway, but i don't think returning
+ // false from the start callback would stop a drag.
+ if (jpcl.stopDrag) jpcl.stopDrag();
+ _dragHandler.stopDrag();
+ return false;
+ }
+
+ // clear hover for all connections for this endpoint before continuing.
+ for (var i = 0; i < this.connections.length; i++)
+ this.connections[i].setHover(false);
+
+ this.addClass("endpointDrag");
+ _jsPlumb.setConnectionBeingDragged(true);
+
+ // if we're not full but there was a connection, make it null. we'll create a new one.
+ if (jpc && !this.isFull() && this.isSource) jpc = null;
+
+ _jsPlumb.updateOffset( { elId : this.elementId });
+ inPlaceCopy = this.makeInPlaceCopy();
+ inPlaceCopy.referenceEndpoint = this;
+ inPlaceCopy.paint();
+
+ _makeDraggablePlaceholder(placeholderInfo, this.parent, _jsPlumb);
+
+ // set the offset of this div to be where 'inPlaceCopy' is, to start with.
+ // TODO merge this code with the code in both Anchor and FloatingAnchor, because it
+ // does the same stuff.
+ var ipcoel = _gel(inPlaceCopy.canvas),
+ ipco = jsPlumb.CurrentLibrary.getOffset(ipcoel, _jsPlumb),
+ po = _jsPlumb.adjustForParentOffsetAndScroll([ipco.left, ipco.top], inPlaceCopy.canvas),
+ canvasElement = _gel(this.canvas);
+
+ jpcl.setOffset(placeholderInfo.element, {left:po[0], top:po[1]});
+
+ // when using makeSource and a parent, we first draw the source anchor on the source element, then
+ // move it to the parent. note that this happens after drawing the placeholder for the
+ // first time.
+ if (this.parentAnchor) this.anchor = _jsPlumb.makeAnchor(this.parentAnchor, this.elementId, _jsPlumb);
+
+ // store the id of the dragging div and the source element. the drop function will pick these up.
+ _jsPlumb.setAttribute(this.canvas, "dragId", placeholderInfo.id);
+ _jsPlumb.setAttribute(this.canvas, "elId", this.elementId);
+
+ this._jsPlumb.floatingEndpoint = _makeFloatingEndpoint(this.getPaintStyle(), this.anchor, this.endpoint, this.canvas, placeholderInfo.element, _jsPlumb, _newEndpoint);
+ // TODO we should not know about DOM here. make the library adapter do this (or the
+ // dom adapter)
+ this.canvas.style.visibility = "hidden";
+
+ if (jpc == null) {
+ this.anchor.locked = true;
+ this.setHover(false, false);
+ // create a connection. one end is this endpoint, the other is a floating endpoint.
+ jpc = _newConnection({
+ sourceEndpoint : this,
+ targetEndpoint : this._jsPlumb.floatingEndpoint,
+ source : this.endpointWillMoveTo || this.element, // for makeSource with parent option. ensure source element is represented correctly.
+ target : placeholderInfo.element,
+ anchors : [ this.anchor, this._jsPlumb.floatingEndpoint.anchor ],
+ paintStyle : params.connectorStyle, // this can be null. Connection will use the default.
+ hoverPaintStyle:params.connectorHoverStyle,
+ connector : params.connector, // this can also be null. Connection will use the default.
+ overlays : params.connectorOverlays,
+ type:this.connectionType,
+ cssClass:this.connectorClass,
+ hoverClass:this.connectorHoverClass
+ });
+ jpc.addClass(_jsPlumb.draggingClass);
+ this._jsPlumb.floatingEndpoint.addClass(_jsPlumb.draggingClass);
+ // fire an event that informs that a connection is being dragged
+ _jsPlumb.fire("connectionDrag", jpc);
+
+ } else {
+ existingJpc = true;
+ jpc.setHover(false);
+ // if existing connection, allow to be dropped back on the source endpoint (issue 51).
+ _initDropTarget(ipcoel, false, true);
+ // new anchor idx
+ var anchorIdx = jpc.endpoints[0].id == this.id ? 0 : 1;
+ jpc.floatingAnchorIndex = anchorIdx; // save our anchor index as the connection's floating index.
+ this.detachFromConnection(jpc); // detach from the connection while dragging is occurring.
+
+ // store the original scope (issue 57)
+ var dragScope = jsPlumb.CurrentLibrary.getDragScope(canvasElement);
+ _jsPlumb.setAttribute(this.canvas, "originalScope", dragScope);
+ // now we want to get this endpoint's DROP scope, and set it for now: we can only be dropped on drop zones
+ // that have our drop scope (issue 57).
+ var dropScope = jpcl.getDropScope(canvasElement);
+ jpcl.setDragScope(canvasElement, dropScope);
+
+ // fire an event that informs that a connection is being dragged. we do this before
+ // replacing the original target with the floating element info.
+ _jsPlumb.fire("connectionDrag", jpc);
+
+ // now we replace ourselves with the temporary div we created above:
+ if (anchorIdx === 0) {
+ existingJpcParams = [ jpc.source, jpc.sourceId, canvasElement, dragScope ];
+ jpc.source = placeholderInfo.element;
+ jpc.sourceId = placeholderInfo.id;
+ } else {
+ existingJpcParams = [ jpc.target, jpc.targetId, canvasElement, dragScope ];
+ jpc.target = placeholderInfo.element;
+ jpc.targetId = placeholderInfo.id;
+ }
+
+ // lock the other endpoint; if it is dynamic it will not move while the drag is occurring.
+ jpc.endpoints[anchorIdx === 0 ? 1 : 0].anchor.locked = true;
+ // store the original endpoint and assign the new floating endpoint for the drag.
+ jpc.suspendedEndpoint = jpc.endpoints[anchorIdx];
+
+ // PROVIDE THE SUSPENDED ELEMENT, BE IT A SOURCE OR TARGET (ISSUE 39)
+ jpc.suspendedElement = jpc.endpoints[anchorIdx].getElement();
+ jpc.suspendedElementId = jpc.endpoints[anchorIdx].elementId;
+ jpc.suspendedElementType = anchorIdx === 0 ? "source" : "target";
+
+ jpc.suspendedEndpoint.setHover(false);
+ this._jsPlumb.floatingEndpoint.referenceEndpoint = jpc.suspendedEndpoint;
+ jpc.endpoints[anchorIdx] = this._jsPlumb.floatingEndpoint;
+
+ jpc.addClass(_jsPlumb.draggingClass);
+ this._jsPlumb.floatingEndpoint.addClass(_jsPlumb.draggingClass);
+
+ }
+ // register it and register connection on it.
+ floatingConnections[placeholderInfo.id] = jpc;
+ _jsPlumb.anchorManager.addFloatingConnection(placeholderInfo.id, jpc);
+ // only register for the target endpoint; we will not be dragging the source at any time
+ // before this connection is either discarded or made into a permanent connection.
+ _ju.addToList(params.endpointsByElement, placeholderInfo.id, this._jsPlumb.floatingEndpoint);
+ // tell jsplumb about it
+ _jsPlumb.currentlyDragging = true;
+ }.bind(this);
+
+ var dragOptions = params.dragOptions || {},
+ defaultOpts = jsPlumb.extend( {}, jpcl.defaultDragOptions),
+ startEvent = jpcl.dragEvents.start,
+ stopEvent = jpcl.dragEvents.stop,
+ dragEvent = jpcl.dragEvents.drag;
+
+ dragOptions = jsPlumb.extend(defaultOpts, dragOptions);
+ dragOptions.scope = dragOptions.scope || this.scope;
+ dragOptions[startEvent] = _ju.wrap(dragOptions[startEvent], start, false);
+ // extracted drag handler function so can be used by makeSource
+ dragOptions[dragEvent] = _ju.wrap(dragOptions[dragEvent], _dragHandler.drag);
+ dragOptions[stopEvent] = _ju.wrap(dragOptions[stopEvent],
+ function() {
+
+ _jsPlumb.setConnectionBeingDragged(false);
+ // get the actual drop event (decode from library args to stop function)
+ var originalEvent = jpcl.getDropEvent(arguments);
+ // unlock the other endpoint (if it is dynamic, it would have been locked at drag start)
+ var idx = jpc.floatingAnchorIndex == null ? 1 : jpc.floatingAnchorIndex;
+ jpc.endpoints[idx === 0 ? 1 : 0].anchor.locked = false;
+ // WHY does this need to happen? i suppose because the connection might not get
+ // deleted. TODO: i dont want to know about css classes inside jsplumb, ideally.
+ jpc.removeClass(_jsPlumb.draggingClass);
+
+ // if we have the floating endpoint then the connection has not been dropped
+ // on another endpoint. If it is a new connection we throw it away. If it is an
+ // existing connection we check to see if we should reattach it, throwing it away
+ // if not.
+ if (jpc.endpoints[idx] == this._jsPlumb.floatingEndpoint) {
+ // 6a. if the connection was an existing one...
+ if (existingJpc && jpc.suspendedEndpoint) {
+ // fix for issue35, thanks Sylvain Gizard: when firing the detach event make sure the
+ // floating endpoint has been replaced.
+ if (idx === 0) {
+ jpc.source = existingJpcParams[0];
+ jpc.sourceId = existingJpcParams[1];
+ } else {
+ jpc.target = existingJpcParams[0];
+ jpc.targetId = existingJpcParams[1];
+ }
+
+ // restore the original scope (issue 57)
+ jpcl.setDragScope(existingJpcParams[2], existingJpcParams[3]);
+ jpc.endpoints[idx] = jpc.suspendedEndpoint;
+ // IF the connection should be reattached, or the other endpoint refuses detach, then
+ // reset the connection to its original state
+ if (jpc.isReattach() || jpc._forceReattach || jpc._forceDetach || !jpc.endpoints[idx === 0 ? 1 : 0].detach(jpc, false, false, true, originalEvent)) {
+ jpc.setHover(false);
+ jpc.floatingAnchorIndex = null;
+ jpc._forceDetach = null;
+ jpc._forceReattach = null;
+ this._jsPlumb.floatingEndpoint.detachFromConnection(jpc);
+ jpc.suspendedEndpoint.addConnection(jpc);
+ _jsPlumb.repaint(existingJpcParams[1]);
+ }
+ }
+ }
+
+ // remove the element associated with the floating endpoint
+ // (and its associated floating endpoint and visual artefacts)
+ // TODO we need a way to say that the connection should be kept, if
+ _jsPlumb.remove(placeholderInfo.element, false);
+ // remove the inplace copy
+ _jsPlumb.remove(inPlaceCopy.canvas, false);
+
+ // makeTargets sets this flag, to tell us we have been replaced and should delete ourself.
+ if (this.deleteAfterDragStop) {
+ _jsPlumb.deleteObject({endpoint:this});
+ }
+ else {
+ if (this._jsPlumb) {
+ this._jsPlumb.floatingEndpoint = null;
+ // repaint this endpoint.
+ // make our canvas visible (TODO: hand off to library; we should not know about DOM)
+ this.canvas.style.visibility = "visible";
+ // unlock our anchor
+ this.anchor.locked = false;
+ this.paint({recalc:false});
+ }
+ }
+
+ // TODO can this stay here? the connection is no longer valid.
+ _jsPlumb.fire("connectionDragStop", jpc);
+
+ // tell jsplumb that dragging is finished.
+ _jsPlumb.currentlyDragging = false;
+
+ jpc = null;
+
+ }.bind(this));
+
+ var i = _gel(this.canvas);
+ jpcl.initDraggable(i, dragOptions, true, _jsPlumb);
+ }
+
+ // pulled this out into a function so we can reuse it for the inPlaceCopy canvas; you can now drop detached connections
+ // back onto the endpoint you detached it from.
+ var _initDropTarget = function(canvas, forceInit, isTransient, endpoint) {
+ if ((this.isTarget || forceInit) && jpcl.isDropSupported(this.element)) {
+ var dropOptions = params.dropOptions || _jsPlumb.Defaults.DropOptions || jsPlumb.Defaults.DropOptions;
+ dropOptions = jsPlumb.extend( {}, dropOptions);
+ dropOptions.scope = dropOptions.scope || this.scope;
+ var dropEvent = jpcl.dragEvents.drop,
+ overEvent = jpcl.dragEvents.over,
+ outEvent = jpcl.dragEvents.out,
+ drop = function() {
+
+ this.removeClass(_jsPlumb.endpointDropAllowedClass);
+ this.removeClass(_jsPlumb.endpointDropForbiddenClass);
+
+ var originalEvent = jpcl.getDropEvent(arguments),
+ draggable = _gel(jpcl.getDragObject(arguments)),
+ id = _jsPlumb.getAttribute(draggable, "dragId"),
+ elId = _jsPlumb.getAttribute(draggable, "elId"),
+ scope = _jsPlumb.getAttribute(draggable, "originalScope"),
+ jpc = floatingConnections[id];
+
+ // if this is a drop back where the connection came from, mark it force rettach and
+ // return; the stop handler will reattach. without firing an event.
+ var redrop = jpc.suspendedEndpoint && (jpc.suspendedEndpoint.id == this.id ||
+ this.referenceEndpoint && jpc.suspendedEndpoint.id == this.referenceEndpoint.id) ;
+ if (redrop) {
+ jpc._forceReattach = true;
+ return;
+ }
+
+ if (jpc != null) {
+ var idx = jpc.floatingAnchorIndex == null ? 1 : jpc.floatingAnchorIndex, oidx = idx === 0 ? 1 : 0;
+
+ // restore the original scope if necessary (issue 57)
+ if (scope) jsPlumb.CurrentLibrary.setDragScope(draggable, scope);
+
+ var endpointEnabled = endpoint != null ? endpoint.isEnabled() : true;
+
+ if (this.isFull()) {
+ this.fire("maxConnections", {
+ endpoint:this,
+ connection:jpc,
+ maxConnections:this._jsPlumb.maxConnections
+ }, originalEvent);
+ }
+
+ if (!this.isFull() && !(idx === 0 && !this.isSource) && !(idx == 1 && !this.isTarget) && endpointEnabled) {
+ var _doContinue = true;
+
+ // the second check here is for the case that the user is dropping it back
+ // where it came from.
+ if (jpc.suspendedEndpoint && jpc.suspendedEndpoint.id != this.id) {
+ if (idx === 0) {
+ jpc.source = jpc.suspendedEndpoint.element;
+ jpc.sourceId = jpc.suspendedEndpoint.elementId;
+ } else {
+ jpc.target = jpc.suspendedEndpoint.element;
+ jpc.targetId = jpc.suspendedEndpoint.elementId;
+ }
+
+ if (!jpc.isDetachAllowed(jpc) || !jpc.endpoints[idx].isDetachAllowed(jpc) || !jpc.suspendedEndpoint.isDetachAllowed(jpc) || !_jsPlumb.checkCondition("beforeDetach", jpc))
+ _doContinue = false;
+ }
+
+ // these have to be set before testing for beforeDrop.
+ if (idx === 0) {
+ jpc.source = this.element;
+ jpc.sourceId = this.elementId;
+ } else {
+ jpc.target = this.element;
+ jpc.targetId = this.elementId;
+ }
+
+// ------------ wrap the execution path in a function so we can support asynchronous beforeDrop
+
+ // we want to execute this regardless.
+ var commonFunction = function() {
+ jpc.floatingAnchorIndex = null;
+ };
+
+ var continueFunction = function() {
+
+ // remove this jpc from the current endpoint
+ jpc.endpoints[idx].detachFromConnection(jpc);
+ if (jpc.suspendedEndpoint) jpc.suspendedEndpoint.detachFromConnection(jpc);
+ jpc.endpoints[idx] = this;
+ this.addConnection(jpc);
+
+ // copy our parameters in to the connection:
+ var params = this.getParameters();
+ for (var aParam in params)
+ jpc.setParameter(aParam, params[aParam]);
+
+ if (!jpc.suspendedEndpoint) {
+ if (params.draggable)
+ jsPlumb.CurrentLibrary.initDraggable(this.element, dragOptions, true, _jsPlumb);
+ }
+ else {
+ var suspendedElement = jpc.suspendedEndpoint.getElement(), suspendedElementId = jpc.suspendedEndpoint.elementId;
+ // fire a detach event
+ _fireDetachEvent({
+ source : idx === 0 ? suspendedElement : jpc.source,
+ target : idx == 1 ? suspendedElement : jpc.target,
+ sourceId : idx === 0 ? suspendedElementId : jpc.sourceId,
+ targetId : idx == 1 ? suspendedElementId : jpc.targetId,
+ sourceEndpoint : idx === 0 ? jpc.suspendedEndpoint : jpc.endpoints[0],
+ targetEndpoint : idx == 1 ? jpc.suspendedEndpoint : jpc.endpoints[1],
+ connection : jpc
+ }, true, originalEvent);
+ }
+
+ // TODO this is like the makeTarget drop code.
+ if (idx == 1)
+ _jsPlumb.anchorManager.updateOtherEndpoint(jpc.sourceId, jpc.suspendedElementId, jpc.targetId, jpc);
+ else
+ _jsPlumb.anchorManager.sourceChanged(jpc.suspendedEndpoint.elementId, jpc.sourceId, jpc);
+
+ // finalise will inform the anchor manager and also add to
+ // connectionsByScope if necessary.
+ _finaliseConnection(jpc, null, originalEvent, true);
+
+ commonFunction();
+ }.bind(this);
+
+ var dontContinueFunction = function() {
+ // otherwise just put it back on the endpoint it was on before the drag.
+ if (jpc.suspendedEndpoint) {
+ jpc.endpoints[idx] = jpc.suspendedEndpoint;
+ jpc.setHover(false);
+ jpc._forceDetach = true;
+ if (idx === 0) {
+ jpc.source = jpc.suspendedEndpoint.element;
+ jpc.sourceId = jpc.suspendedEndpoint.elementId;
+ } else {
+ jpc.target = jpc.suspendedEndpoint.element;
+ jpc.targetId = jpc.suspendedEndpoint.elementId;
+ }
+ jpc.suspendedEndpoint.addConnection(jpc);
+
+ jpc.endpoints[0].repaint();
+ jpc.repaint();
+ _jsPlumb.repaint(jpc.sourceId);
+ jpc._forceDetach = false;
+ }
+
+ commonFunction();
+ };
+
+// --------------------------------------
+ // now check beforeDrop. this will be available only on Endpoints that are setup to
+ // have a beforeDrop condition (although, secretly, under the hood all Endpoints and
+ // the Connection have them, because they are on jsPlumbUIComponent. shhh!), because
+ // it only makes sense to have it on a target endpoint.
+ _doContinue = _doContinue && this.isDropAllowed(jpc.sourceId, jpc.targetId, jpc.scope, jpc, this);
+
+ if (_doContinue) {
+ continueFunction();
+ }
+ else {
+ dontContinueFunction();
+ }
+ }
+ _jsPlumb.currentlyDragging = false;
+ }
+ }.bind(this);
+
+ dropOptions[dropEvent] = _ju.wrap(dropOptions[dropEvent], drop);
+ dropOptions[overEvent] = _ju.wrap(dropOptions[overEvent], function() {
+ var draggable = jpcl.getDragObject(arguments),
+ id = _jsPlumb.getAttribute(draggable, "dragId"),
+ _jpc = floatingConnections[id];
+
+ if (_jpc != null) {
+ var idx = _jpc.floatingAnchorIndex == null ? 1 : _jpc.floatingAnchorIndex;
+ // here we should fire the 'over' event if we are a target and this is a new connection,
+ // or we are the same as the floating endpoint.
+ var _cont = (this.isTarget && _jpc.floatingAnchorIndex !== 0) || (_jpc.suspendedEndpoint && this.referenceEndpoint && this.referenceEndpoint.id == _jpc.suspendedEndpoint.id);
+ if (_cont) {
+ var bb = _jsPlumb.checkCondition("checkDropAllowed", {
+ sourceEndpoint:_jpc.endpoints[idx],
+ targetEndpoint:this,
+ connection:_jpc
+ });
+ this[(bb ? "add" : "remove") + "Class"](_jsPlumb.endpointDropAllowedClass);
+ this[(bb ? "remove" : "add") + "Class"](_jsPlumb.endpointDropForbiddenClass);
+ _jpc.endpoints[idx].anchor.over(this.anchor, this);
+ }
+ }
+ }.bind(this));
+
+ dropOptions[outEvent] = _ju.wrap(dropOptions[outEvent], function() {
+ var draggable = jpcl.getDragObject(arguments),
+ id = _jsPlumb.getAttribute( draggable, "dragId"),
+ _jpc = floatingConnections[id];
+
+ if (_jpc != null) {
+ var idx = _jpc.floatingAnchorIndex == null ? 1 : _jpc.floatingAnchorIndex;
+ var _cont = (this.isTarget && _jpc.floatingAnchorIndex !== 0) || (_jpc.suspendedEndpoint && this.referenceEndpoint && this.referenceEndpoint.id == _jpc.suspendedEndpoint.id);
+ if (_cont) {
+ this.removeClass(_jsPlumb.endpointDropAllowedClass);
+ this.removeClass(_jsPlumb.endpointDropForbiddenClass);
+ _jpc.endpoints[idx].anchor.out();
+ }
+ }
+ }.bind(this));
+ jpcl.initDroppable(canvas, dropOptions, true, isTransient);
+ }
+ }.bind(this);
+
+ // initialise the endpoint's canvas as a drop target. this will be ignored if the endpoint is not a target or drag is not supported.
+ _initDropTarget(_gel(this.canvas), true, !(params._transient || this.anchor.isFloating), this);
+
+ // finally, set type if it was provided
+ if (params.type)
+ this.addType(params.type, params.data, _jsPlumb.isSuspendDrawing());
+
+ return this;
+ };
+
+ jsPlumbUtil.extend(jsPlumb.Endpoint, OverlayCapableJsPlumbUIComponent, {
+ getTypeDescriptor : function() { return "endpoint"; },
+ isVisible : function() { return this._jsPlumb.visible; },
+ setVisible : function(v, doNotChangeConnections, doNotNotifyOtherEndpoint) {
+ this._jsPlumb.visible = v;
+ if (this.canvas) this.canvas.style.display = v ? "block" : "none";
+ this[v ? "showOverlays" : "hideOverlays"]();
+ if (!doNotChangeConnections) {
+ for (var i = 0; i < this.connections.length; i++) {
+ this.connections[i].setVisible(v);
+ if (!doNotNotifyOtherEndpoint) {
+ var oIdx = this === this.connections[i].endpoints[0] ? 1 : 0;
+ // only change the other endpoint if this is its only connection.
+ if (this.connections[i].endpoints[oIdx].connections.length == 1) this.connections[i].endpoints[oIdx].setVisible(v, true, true);
+ }
+ }
+ }
+ },
+ getAttachedElements : function() {
+ return this.connections;
+ },
+ applyType : function(t, doNotRepaint) {
+ if (t.maxConnections != null) this._jsPlumb.maxConnections = t.maxConnections;
+ if (t.scope) this.scope = t.scope;
+ jsPlumbUtil.copyValues(typeParameters, t, this);
+ },
+ isEnabled : function() { return this._jsPlumb.enabled; },
+ setEnabled : function(e) { this._jsPlumb.enabled = e; },
+ cleanup : function() {
+ jsPlumb.CurrentLibrary.removeClass(this.element, this._jsPlumb.instance.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ this.anchor = null;
+ this.endpoint.cleanup();
+ this.endpoint.destroy();
+ this.endpoint = null;
+ // drag/drop
+ var i = jsPlumb.CurrentLibrary.getElementObject(this.canvas);
+ jsPlumb.CurrentLibrary.destroyDraggable(i);
+ jsPlumb.CurrentLibrary.destroyDroppable(i);
+ },
+ setHover : function(h) {
+ if (this.endpoint && this._jsPlumb && !this._jsPlumb.instance.isConnectionBeingDragged())
+ this.endpoint.setHover(h);
+ },
+ isFull : function() {
+ return !(this.isFloating() || this._jsPlumb.maxConnections < 1 || this.connections.length < this._jsPlumb.maxConnections);
+ },
+ getConnectionCost : function() { return this._jsPlumb.connectionCost; },
+ setConnectionCost : function(c) {
+ this._jsPlumb.connectionCost = c;
+ },
+ areConnectionsDirected : function() { return this._jsPlumb.connectionsDirected; },
+ setConnectionsDirected : function(b) { this._jsPlumb.connectionsDirected = b; },
+ setElementId : function(_elId) {
+ this.elementId = _elId;
+ this.anchor.elementId = _elId;
+ },
+ setReferenceElement : function(_el) {
+ this.element = jsPlumb.CurrentLibrary.getDOMElement(_el);
+ },
+ setDragAllowedWhenFull : function(allowed) {
+ this.dragAllowedWhenFull = allowed;
+ },
+ equals : function(endpoint) {
+ return this.anchor.equals(endpoint.anchor);
+ },
+ getUuid : function() {
+ return this._jsPlumb.uuid;
+ },
+ computeAnchor : function(params) {
+ return this.anchor.compute(params);
+ }
+ });
+})();
+;(function() {
+
+ var makeConnector = function(_jsPlumb, renderMode, connectorName, connectorArgs) {
+ if (!_jsPlumb.Defaults.DoNotThrowErrors && jsPlumb.Connectors[renderMode][connectorName] == null)
+ throw { msg:"jsPlumb: unknown connector type '" + connectorName + "'" };
+
+ return new jsPlumb.Connectors[renderMode][connectorName](connectorArgs);
+ },
+ _makeAnchor = function(anchorParams, elementId, _jsPlumb) {
+ return (anchorParams) ? _jsPlumb.makeAnchor(anchorParams, elementId, _jsPlumb) : null;
+ },
+ prepareEndpoint = function(_jsPlumb, _newEndpoint, conn, existing, index, params, element, elementId, connectorPaintStyle, connectorHoverPaintStyle) {
+ var e;
+ if (existing) {
+ conn.endpoints[index] = existing;
+ existing.addConnection(conn);
+ } else {
+ if (!params.endpoints) params.endpoints = [ null, null ];
+ var ep = params.endpoints[index] || params.endpoint || _jsPlumb.Defaults.Endpoints[index] || jsPlumb.Defaults.Endpoints[index] || _jsPlumb.Defaults.Endpoint || jsPlumb.Defaults.Endpoint;
+ if (!params.endpointStyles) params.endpointStyles = [ null, null ];
+ if (!params.endpointHoverStyles) params.endpointHoverStyles = [ null, null ];
+ var es = params.endpointStyles[index] || params.endpointStyle || _jsPlumb.Defaults.EndpointStyles[index] || jsPlumb.Defaults.EndpointStyles[index] || _jsPlumb.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle;
+ // Endpoints derive their fillStyle from the connector's strokeStyle, if no fillStyle was specified.
+ if (es.fillStyle == null && connectorPaintStyle != null)
+ es.fillStyle = connectorPaintStyle.strokeStyle;
+
+ // TODO: decide if the endpoint should derive the connection's outline width and color. currently it does:
+ //*
+ if (es.outlineColor == null && connectorPaintStyle != null)
+ es.outlineColor = connectorPaintStyle.outlineColor;
+ if (es.outlineWidth == null && connectorPaintStyle != null)
+ es.outlineWidth = connectorPaintStyle.outlineWidth;
+ //*/
+
+ var ehs = params.endpointHoverStyles[index] || params.endpointHoverStyle || _jsPlumb.Defaults.EndpointHoverStyles[index] || jsPlumb.Defaults.EndpointHoverStyles[index] || _jsPlumb.Defaults.EndpointHoverStyle || jsPlumb.Defaults.EndpointHoverStyle;
+ // endpoint hover fill style is derived from connector's hover stroke style. TODO: do we want to do this by default? for sure?
+ if (connectorHoverPaintStyle != null) {
+ if (ehs == null) ehs = {};
+ if (ehs.fillStyle == null) {
+ ehs.fillStyle = connectorHoverPaintStyle.strokeStyle;
+ }
+ }
+ var a = params.anchors ? params.anchors[index] :
+ params.anchor ? params.anchor :
+ _makeAnchor(_jsPlumb.Defaults.Anchors[index], elementId, _jsPlumb) ||
+ _makeAnchor(jsPlumb.Defaults.Anchors[index], elementId,_jsPlumb) ||
+ _makeAnchor(_jsPlumb.Defaults.Anchor, elementId,_jsPlumb) ||
+ _makeAnchor(jsPlumb.Defaults.Anchor, elementId, _jsPlumb),
+ u = params.uuids ? params.uuids[index] : null;
+ e = _newEndpoint({
+ paintStyle : es, hoverPaintStyle:ehs, endpoint : ep, connections : [ conn ],
+ uuid : u, anchor : a, source : element, scope : params.scope, container:params.container,
+ reattach:params.reattach || _jsPlumb.Defaults.ReattachConnections,
+ detachable:params.detachable || _jsPlumb.Defaults.ConnectionsDetachable
+ });
+ conn.endpoints[index] = e;
+
+ if (params.drawEndpoints === false) e.setVisible(false, true, true);
+
+ }
+ return e;
+ };
+
+ jsPlumb.Connection = function(params) {
+ var _newConnection = params.newConnection,
+ _newEndpoint = params.newEndpoint,
+ jpcl = jsPlumb.CurrentLibrary,
+ _att = jpcl.getAttribute,
+ _gel = jpcl.getElementObject,
+ _dom = jpcl.getDOMElement,
+ _ju = jsPlumbUtil,
+ _getOffset = jpcl.getOffset;
+
+ this.connector = null;
+ this.idPrefix = "_jsplumb_c_";
+ this.defaultLabelLocation = 0.5;
+ this.defaultOverlayKeys = ["Overlays", "ConnectionOverlays"];
+ this.parent = params.parent;
+ // if a new connection is the result of moving some existing connection, params.previousConnection
+ // will have that Connection in it. listeners for the jsPlumbConnection event can look for that
+ // member and take action if they need to.
+ this.previousConnection = params.previousConnection;
+ this.source = _dom(params.source);
+ this.target = _dom(params.target);
+ // sourceEndpoint and targetEndpoint override source/target, if they are present. but
+ // source is not overridden if the Endpoint has declared it is not the final target of a connection;
+ // instead we use the source that the Endpoint declares will be the final source element.
+ if (params.sourceEndpoint) this.source = params.sourceEndpoint.endpointWillMoveTo || params.sourceEndpoint.getElement();
+ if (params.targetEndpoint) this.target = params.targetEndpoint.getElement();
+
+ OverlayCapableJsPlumbUIComponent.apply(this, arguments);
+
+ this.sourceId = this._jsPlumb.instance.getId(this.source);
+ this.targetId = this._jsPlumb.instance.getId(this.target);
+ this.scope = params.scope; // scope may have been passed in to the connect call. if it wasn't, we will pull it from the source endpoint, after having initialised the endpoints.
+ this.endpoints = [];
+ this.endpointStyles = [];
+
+ var _jsPlumb = this._jsPlumb.instance;
+ this._jsPlumb.visible = true;
+ this._jsPlumb.editable = params.editable === true;
+ this._jsPlumb.params = {
+ parent:params.parent,
+ cssClass:params.cssClass,
+ container:params.container,
+ "pointer-events":params["pointer-events"],
+ editorParams:params.editorParams
+ };
+ this._jsPlumb.lastPaintedAt = null;
+ this.getDefaultType = function() {
+ return {
+ parameters:{},
+ scope:null,
+ detachable:this._jsPlumb.instance.Defaults.ConnectionsDetachable,
+ rettach:this._jsPlumb.instance.Defaults.ReattachConnections,
+ paintStyle:this._jsPlumb.instance.Defaults.PaintStyle || jsPlumb.Defaults.PaintStyle,
+ connector:this._jsPlumb.instance.Defaults.Connector || jsPlumb.Defaults.Connector,
+ hoverPaintStyle:this._jsPlumb.instance.Defaults.HoverPaintStyle || jsPlumb.Defaults.HoverPaintStyle,
+ overlays:this._jsPlumb.instance.Defaults.ConnectorOverlays || jsPlumb.Defaults.ConnectorOverlays
+ };
+ };
+
+// INITIALISATION CODE
+
+ // wrapped the main function to return null if no input given. this lets us cascade defaults properly.
+
+ var eS = prepareEndpoint(_jsPlumb, _newEndpoint, this, params.sourceEndpoint, 0, params, this.source, this.sourceId, params.paintStyle, params.hoverPaintStyle);
+ if (eS) _ju.addToList(params.endpointsByElement, this.sourceId, eS);
+ var eT = prepareEndpoint(_jsPlumb, _newEndpoint, this, params.targetEndpoint, 1, params, this.target, this.targetId, params.paintStyle, params.hoverPaintStyle);
+ if (eT) _ju.addToList(params.endpointsByElement, this.targetId, eT);
+ // if scope not set, set it to be the scope for the source endpoint.
+ if (!this.scope) this.scope = this.endpoints[0].scope;
+
+ // if explicitly told to (or not to) delete endpoints on detach, override endpoint's preferences
+ if (params.deleteEndpointsOnDetach != null) {
+ this.endpoints[0]._deleteOnDetach = params.deleteEndpointsOnDetach;
+ this.endpoints[1]._deleteOnDetach = params.deleteEndpointsOnDetach;
+ }
+ else {
+ // otherwise, unless the endpoints say otherwise, mark them for deletion.
+ if (!this.endpoints[0]._doNotDeleteOnDetach) this.endpoints[0]._deleteOnDetach = true;
+ if (!this.endpoints[1]._doNotDeleteOnDetach) this.endpoints[1]._deleteOnDetach = true;
+ }
+
+ // TODO these could surely be refactored into some method that tries them one at a time until something exists
+ this.setConnector(this.endpoints[0].connector ||
+ this.endpoints[1].connector ||
+ params.connector ||
+ _jsPlumb.Defaults.Connector ||
+ jsPlumb.Defaults.Connector, true);
+
+ if (params.path)
+ this.connector.setPath(params.path);
+
+ this.setPaintStyle(this.endpoints[0].connectorStyle ||
+ this.endpoints[1].connectorStyle ||
+ params.paintStyle ||
+ _jsPlumb.Defaults.PaintStyle ||
+ jsPlumb.Defaults.PaintStyle, true);
+
+ this.setHoverPaintStyle(this.endpoints[0].connectorHoverStyle ||
+ this.endpoints[1].connectorHoverStyle ||
+ params.hoverPaintStyle ||
+ _jsPlumb.Defaults.HoverPaintStyle ||
+ jsPlumb.Defaults.HoverPaintStyle, true);
+
+ this._jsPlumb.paintStyleInUse = this.getPaintStyle();
+
+ var _suspendedAt = _jsPlumb.getSuspendedAt();
+ _jsPlumb.updateOffset( { elId : this.sourceId, timestamp:_suspendedAt });
+ _jsPlumb.updateOffset( { elId : this.targetId, timestamp:_suspendedAt });
+
+//*
+ if(!_jsPlumb.isSuspendDrawing()) {
+ // paint the endpoints
+ var myInfo = _jsPlumb.getCachedData(this.sourceId),
+ myOffset = myInfo.o, myWH = myInfo.s,
+ otherInfo = _jsPlumb.getCachedData(this.targetId),
+ otherOffset = otherInfo.o,
+ otherWH = otherInfo.s,
+ initialTimestamp = _suspendedAt || _jsPlumb.timestamp(),
+ anchorLoc = this.endpoints[0].anchor.compute( {
+ xy : [ myOffset.left, myOffset.top ], wh : myWH, element : this.endpoints[0],
+ elementId:this.endpoints[0].elementId,
+ txy : [ otherOffset.left, otherOffset.top ], twh : otherWH, tElement : this.endpoints[1],
+ timestamp:initialTimestamp
+ });
+
+ this.endpoints[0].paint( { anchorLoc : anchorLoc, timestamp:initialTimestamp });
+
+ anchorLoc = this.endpoints[1].anchor.compute( {
+ xy : [ otherOffset.left, otherOffset.top ], wh : otherWH, element : this.endpoints[1],
+ elementId:this.endpoints[1].elementId,
+ txy : [ myOffset.left, myOffset.top ], twh : myWH, tElement : this.endpoints[0],
+ timestamp:initialTimestamp
+ });
+ this.endpoints[1].paint({ anchorLoc : anchorLoc, timestamp:initialTimestamp });
+ }
+ //*/
+
+// END INITIALISATION CODE
+
+// DETACHABLE
+ this._jsPlumb.detachable = _jsPlumb.Defaults.ConnectionsDetachable;
+ if (params.detachable === false) this._jsPlumb.detachable = false;
+ if(this.endpoints[0].connectionsDetachable === false) this._jsPlumb.detachable = false;
+ if(this.endpoints[1].connectionsDetachable === false) this._jsPlumb.detachable = false;
+// REATTACH
+ this._jsPlumb.reattach = params.reattach || this.endpoints[0].reattachConnections || this.endpoints[1].reattachConnections || _jsPlumb.Defaults.ReattachConnections;
+// COST + DIRECTIONALITY
+ // if cost not supplied, try to inherit from source endpoint
+ this._jsPlumb.cost = params.cost || this.endpoints[0].getConnectionCost();
+ this._jsPlumb.directed = params.directed;
+ // inherit directed flag if set no source endpoint
+ if (params.directed == null) this._jsPlumb.directed = this.endpoints[0].areConnectionsDirected();
+// END COST + DIRECTIONALITY
+
+// PARAMETERS
+ // merge all the parameters objects into the connection. parameters set
+ // on the connection take precedence; then source endpoint params, then
+ // finally target endpoint params.
+ // TODO jsPlumb.extend could be made to take more than two args, and it would
+ // apply the second through nth args in order.
+ var _p = jsPlumb.extend({}, this.endpoints[1].getParameters());
+ jsPlumb.extend(_p, this.endpoints[0].getParameters());
+ jsPlumb.extend(_p, this.getParameters());
+ this.setParameters(_p);
+// END PARAMETERS
+
+// PAINTING
+
+ // the very last thing we do is check to see if a 'type' was supplied in the params
+ var _type = params.type || this.endpoints[0].connectionType || this.endpoints[1].connectionType;
+ if (_type)
+ this.addType(_type, params.data, true);
+
+// END PAINTING
+ };
+
+ jsPlumbUtil.extend(jsPlumb.Connection, OverlayCapableJsPlumbUIComponent, {
+ applyType : function(t, doNotRepaint) {
+ if (t.detachable != null) this.setDetachable(t.detachable);
+ if (t.reattach != null) this.setReattach(t.reattach);
+ if (t.scope) this.scope = t.scope;
+ //editable = t.editable; // TODO
+ this.setConnector(t.connector, doNotRepaint);
+ },
+ getTypeDescriptor : function() { return "connection"; },
+ getAttachedElements : function() {
+ return this.endpoints;
+ },
+ addClass : function(c, informEndpoints) {
+ if (informEndpoints) {
+ this.endpoints[0].addClass(c);
+ this.endpoints[1].addClass(c);
+ if (this.suspendedEndpoint) this.suspendedEndpoint.addClass(c);
+ }
+ if (this.connector) {
+ this.connector.addClass(c);
+ }
+ },
+ removeClass : function(c, informEndpoints) {
+ if (informEndpoints) {
+ this.endpoints[0].removeClass(c);
+ this.endpoints[1].removeClass(c);
+ if (this.suspendedEndpoint) this.suspendedEndpoint.removeClass(c);
+ }
+ if (this.connector) {
+ this.connector.removeClass(c);
+ }
+ },
+ isVisible : function() { return this._jsPlumb.visible; },
+ setVisible : function(v) {
+ this._jsPlumb.visible = v;
+ this[v ? "showOverlays" : "hideOverlays"]();
+ if (this.connector && this.connector.canvas) this.connector.canvas.style.display = v ? "block" : "none";
+ this.repaint();
+ },
+ setEditable : function(e) {
+ if (this.connector && this.connector.isEditable())
+ this._jsPlumb.editable = e;
+
+ return this._jsPlumb.editable;
+ },
+ isEditable : function() { return this._jsPlumb.editable; },
+ editStarted : function() {
+ this.setSuspendEvents(true);
+ this.fire("editStarted", {
+ path:this.connector.getPath()
+ });
+ this._jsPlumb.instance.setHoverSuspended(true);
+ },
+ editCompleted : function() {
+ this.fire("editCompleted", {
+ path:this.connector.getPath()
+ });
+ this.setSuspendEvents(false);
+ this.setHover(false);
+ this._jsPlumb.instance.setHoverSuspended(false);
+ },
+ editCanceled : function() {
+ this.fire("editCanceled", {
+ path:this.connector.getPath()
+ });
+ this.setHover(false);
+ this._jsPlumb.instance.setHoverSuspended(false);
+ },
+ cleanup:function() {
+ //this.endpointsToDeleteOnDetach = null;
+ this.endpoints = null;
+ this.source = null;
+ this.target = null;
+ if (this.connector != null) {
+ this.connector.cleanup();
+ this.connector.destroy();
+ }
+ this.connector = null;
+ },
+ isDetachable : function() {
+ return this._jsPlumb.detachable === true;
+ },
+ setDetachable : function(detachable) {
+ this._jsPlumb.detachable = detachable === true;
+ },
+ isReattach : function() {
+ return this._jsPlumb.reattach === true;
+ },
+ setReattach : function(reattach) {
+ this._jsPlumb.reattach = reattach === true;
+ },
+ setHover : function(state) {
+ if (this.connector && this._jsPlumb && !this._jsPlumb.instance.isConnectionBeingDragged()) {
+ this.connector.setHover(state);
+ jsPlumb.CurrentLibrary[state ? "addClass" : "removeClass"](this.source, this._jsPlumb.instance.hoverSourceClass);
+ jsPlumb.CurrentLibrary[state ? "addClass" : "removeClass"](this.target, this._jsPlumb.instance.hoverTargetClass);
+ }
+ },
+ getCost : function() { return this._jsPlumb.cost; },
+ setCost : function(c) { this._jsPlumb.cost = c; },
+ isDirected : function() { return this._jsPlumb.directed === true; },
+ //
+ // changes the parent element of this connection to newParent. not exposed for the public API.
+ //
+ // TODO ensure moveParent method still works (the overlay stuff in particular)
+ moveParent : function(newParent) {
+ var jpcl = jsPlumb.CurrentLibrary, curParent = jpcl.getParent(this.connector.canvas);
+ if (this.connector.bgCanvas) {
+ jpcl.removeElement(this.connector.bgCanvas);
+ jpcl.appendElement(this.connector.bgCanvas, newParent);
+ }
+ jpcl.removeElement(this.connector.canvas);
+ jpcl.appendElement(this.connector.canvas, newParent);
+ // this only applies for DOMOverlays
+ for (var i = 0; i < this._jsPlumb.overlays.length; i++) {
+ if (this._jsPlumb.overlays[i].isAppendedAtTopLevel) {
+ jpcl.removeElement(this._jsPlumb.overlays[i].canvas);
+ jpcl.appendElement(this._jsPlumb.overlays[i].canvas, newParent);
+ if (this._jsPlumb.overlays[i].reattachListeners)
+ this._jsPlumb.overlays[i].reattachListeners(this.connector);
+ }
+ }
+ if (this.connector.reattachListeners) // this is for SVG/VML; change an element's parent and you have to reinit its listeners.
+ this.connector.reattachListeners(); // the Canvas implementation doesn't have to care about this
+ },
+ getConnector : function() { return this.connector; },
+ setConnector : function(connectorSpec, doNotRepaint) {
+ var _ju = jsPlumbUtil;
+ if (this.connector != null) {
+ this.connector.cleanup();
+ this.connector.destroy();
+ }
+
+ var connectorArgs = {
+ _jsPlumb:this._jsPlumb.instance,
+ parent:this._jsPlumb.params.parent,
+ cssClass:this._jsPlumb.params.cssClass,
+ container:this._jsPlumb.params.container,
+ "pointer-events":this._jsPlumb.params["pointer-events"]
+ },
+ renderMode = this._jsPlumb.instance.getRenderMode();
+
+ if (_ju.isString(connectorSpec))
+ this.connector = makeConnector(this._jsPlumb.instance, renderMode, connectorSpec, connectorArgs); // lets you use a string as shorthand.
+ else if (_ju.isArray(connectorSpec)) {
+ if (connectorSpec.length == 1)
+ this.connector = makeConnector(this._jsPlumb.instance, renderMode, connectorSpec[0], connectorArgs);
+ else
+ this.connector = makeConnector(this._jsPlumb.instance, renderMode, connectorSpec[0], _ju.merge(connectorSpec[1], connectorArgs));
+ }
+ // binds mouse listeners to the current connector.
+ this.bindListeners(this.connector, this, function(state) {
+ this.setHover(state, false);
+ }.bind(this));
+
+ this.canvas = this.connector.canvas;
+
+ if (this._jsPlumb.editable && jsPlumb.ConnectorEditors != null && jsPlumb.ConnectorEditors[this.connector.type] && this.connector.isEditable()) {
+ new jsPlumb.ConnectorEditors[this.connector.type]({
+ connector:this.connector,
+ connection:this,
+ params:this._jsPlumb.params.editorParams || { }
+ });
+ }
+ else {
+ editable = false;
+ }
+
+ if (!doNotRepaint) this.repaint();
+ },
+ paint : function(params) {
+
+ if (!this._jsPlumb.instance.isSuspendDrawing() && this._jsPlumb.visible) {
+
+ params = params || {};
+ var elId = params.elId, ui = params.ui, recalc = params.recalc, timestamp = params.timestamp,
+ // if the moving object is not the source we must transpose the two references.
+ swap = false,
+ tId = swap ? this.sourceId : this.targetId, sId = swap ? this.targetId : this.sourceId,
+ tIdx = swap ? 0 : 1, sIdx = swap ? 1 : 0;
+
+ if (timestamp == null || timestamp != this._jsPlumb.lastPaintedAt) {
+ var sourceInfo = this._jsPlumb.instance.updateOffset( { elId : sId, offset : ui, recalc : recalc, timestamp : timestamp }).o,
+ targetInfo = this._jsPlumb.instance.updateOffset( { elId : tId, timestamp : timestamp }).o, // update the target if this is a forced repaint. otherwise, only the source has been moved.
+ sE = this.endpoints[sIdx], tE = this.endpoints[tIdx];
+
+ if (params.clearEdits) {
+ sE.anchor.clearUserDefinedLocation();
+ tE.anchor.clearUserDefinedLocation();
+ this.connector.setEdited(false);
+ }
+
+ var sAnchorP = sE.anchor.getCurrentLocation({xy:[sourceInfo.left,sourceInfo.top], wh:[sourceInfo.width, sourceInfo.height], element:sE, timestamp:timestamp}),
+ tAnchorP = tE.anchor.getCurrentLocation({xy:[targetInfo.left,targetInfo.top], wh:[targetInfo.width, targetInfo.height], element:tE, timestamp:timestamp});
+
+ this.connector.resetBounds();
+
+ this.connector.compute({
+ sourcePos:sAnchorP,
+ targetPos:tAnchorP,
+ sourceEndpoint:this.endpoints[sIdx],
+ targetEndpoint:this.endpoints[tIdx],
+ lineWidth:this._jsPlumb.paintStyleInUse.lineWidth,
+ sourceInfo:sourceInfo,
+ targetInfo:targetInfo,
+ clearEdits:params.clearEdits === true
+ });
+
+ var overlayExtents = { minX:Infinity, minY:Infinity, maxX:-Infinity, maxY:-Infinity };
+
+ // compute overlays. we do this first so we can get their placements, and adjust the
+ // container if needs be (if an overlay would be clipped)
+ for ( var i = 0; i < this._jsPlumb.overlays.length; i++) {
+ var o = this._jsPlumb.overlays[i];
+ if (o.isVisible()) {
+ this._jsPlumb.overlayPlacements[i] = o.draw(this.connector, this._jsPlumb.paintStyleInUse);
+ overlayExtents.minX = Math.min(overlayExtents.minX, this._jsPlumb.overlayPlacements[i].minX);
+ overlayExtents.maxX = Math.max(overlayExtents.maxX, this._jsPlumb.overlayPlacements[i].maxX);
+ overlayExtents.minY = Math.min(overlayExtents.minY, this._jsPlumb.overlayPlacements[i].minY);
+ overlayExtents.maxY = Math.max(overlayExtents.maxY, this._jsPlumb.overlayPlacements[i].maxY);
+ }
+ }
+
+ var lineWidth = parseFloat(this._jsPlumb.paintStyleInUse.lineWidth || 1) / 2,
+ outlineWidth = parseFloat(this._jsPlumb.paintStyleInUse.lineWidth || 0),
+ extents = {
+ xmin : Math.min(this.connector.bounds.minX - (lineWidth + outlineWidth), overlayExtents.minX),
+ ymin : Math.min(this.connector.bounds.minY - (lineWidth + outlineWidth), overlayExtents.minY),
+ xmax : Math.max(this.connector.bounds.maxX + (lineWidth + outlineWidth), overlayExtents.maxX),
+ ymax : Math.max(this.connector.bounds.maxY + (lineWidth + outlineWidth), overlayExtents.maxY)
+ };
+
+ // paint the connector.
+ this.connector.paint(this._jsPlumb.paintStyleInUse, null, extents);
+ // and then the overlays
+ for ( var j = 0; j < this._jsPlumb.overlays.length; j++) {
+ var p = this._jsPlumb.overlays[j];
+ if (p.isVisible()) {
+ p.paint(this._jsPlumb.overlayPlacements[j], extents);
+ }
+ }
+ }
+ this._jsPlumb.lastPaintedAt = timestamp;
+ }
+ },
+ /*
+ * Function: repaint
+ * Repaints the Connection. No parameters exposed to public API.
+ */
+ repaint : function(params) {
+ params = params || {};
+ this.paint({ elId : this.sourceId, recalc : !(params.recalc === false), timestamp:params.timestamp, clearEdits:params.clearEdits });
+ }
+
+ }); // END Connection class
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the code for creating and manipulating anchors.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+;(function() {
+
+ //
+ // manages anchors for all elements.
+ //
+ jsPlumb.AnchorManager = function(params) {
+ var _amEndpoints = {},
+ continuousAnchors = {},
+ continuousAnchorLocations = {},
+ userDefinedContinuousAnchorLocations = {},
+ continuousAnchorOrientations = {},
+ Orientation = { HORIZONTAL : "horizontal", VERTICAL : "vertical", DIAGONAL : "diagonal", IDENTITY:"identity" },
+ connectionsByElementId = {},
+ self = this,
+ anchorLists = {},
+ jsPlumbInstance = params.jsPlumbInstance,
+ jpcl = jsPlumb.CurrentLibrary,
+ floatingConnections = {},
+ // TODO this functions uses a crude method of determining orientation between two elements.
+ // 'diagonal' should be chosen when the angle of the line between the two centers is around
+ // one of 45, 135, 225 and 315 degrees. maybe +- 15 degrees.
+ // used by AnchorManager.redraw
+ calculateOrientation = function(sourceId, targetId, sd, td, sourceAnchor, targetAnchor) {
+
+ if (sourceId === targetId) return {
+ orientation:Orientation.IDENTITY,
+ a:["top", "top"]
+ };
+
+ var theta = Math.atan2((td.centery - sd.centery) , (td.centerx - sd.centerx)),
+ theta2 = Math.atan2((sd.centery - td.centery) , (sd.centerx - td.centerx)),
+ h = ((sd.left <= td.left && sd.right >= td.left) || (sd.left <= td.right && sd.right >= td.right) ||
+ (sd.left <= td.left && sd.right >= td.right) || (td.left <= sd.left && td.right >= sd.right)),
+ v = ((sd.top <= td.top && sd.bottom >= td.top) || (sd.top <= td.bottom && sd.bottom >= td.bottom) ||
+ (sd.top <= td.top && sd.bottom >= td.bottom) || (td.top <= sd.top && td.bottom >= sd.bottom)),
+ possiblyTranslateEdges = function(edges) {
+ // this function checks to see if either anchor is Continuous, and if so, runs the suggested edge
+ // through the anchor: Continuous anchors can say which faces they support, and they get to choose
+ // whether a certain face is honoured, or, if not, which face to replace it with. the behaviour when
+ // choosing an alternate face is to try for the opposite face first, then the next one clockwise, and then
+ // the opposite of that one.
+ return [
+ sourceAnchor.isContinuous ? sourceAnchor.verifyEdge(edges[0]) : edges[0],
+ targetAnchor.isContinuous ? targetAnchor.verifyEdge(edges[1]) : edges[1]
+ ];
+ },
+ out = {
+ orientation:Orientation.DIAGONAL,
+ theta:theta,
+ theta2:theta2
+ };
+
+ if (! (h || v)) {
+ if (td.left > sd.left && td.top > sd.top)
+ out.a = ["right", "top"];
+ else if (td.left > sd.left && sd.top > td.top)
+ out.a = [ "top", "left"];
+ else if (td.left < sd.left && td.top < sd.top)
+ out.a = [ "top", "right"];
+ else if (td.left < sd.left && td.top > sd.top)
+ out.a = ["left", "top" ];
+ }
+ else if (h) {
+ out.orientation = Orientation.HORIZONTAL;
+ out.a = sd.top < td.top ? ["bottom", "top"] : ["top", "bottom"];
+ }
+ else {
+ out.orientation = Orientation.VERTICAL;
+ out.a = sd.left < td.left ? ["right", "left"] : ["left", "right"];
+ }
+
+ out.a = possiblyTranslateEdges(out.a);
+ return out;
+ },
+ // used by placeAnchors function
+ placeAnchorsOnLine = function(desc, elementDimensions, elementPosition,
+ connections, horizontal, otherMultiplier, reverse) {
+ var a = [], step = elementDimensions[horizontal ? 0 : 1] / (connections.length + 1);
+
+ for (var i = 0; i < connections.length; i++) {
+ var val = (i + 1) * step, other = otherMultiplier * elementDimensions[horizontal ? 1 : 0];
+ if (reverse)
+ val = elementDimensions[horizontal ? 0 : 1] - val;
+
+ var dx = (horizontal ? val : other), x = elementPosition[0] + dx, xp = dx / elementDimensions[0],
+ dy = (horizontal ? other : val), y = elementPosition[1] + dy, yp = dy / elementDimensions[1];
+
+ a.push([ x, y, xp, yp, connections[i][1], connections[i][2] ]);
+ }
+
+ return a;
+ },
+ // used by edgeSortFunctions
+ currySort = function(reverseAngles) {
+ return function(a,b) {
+ var r = true;
+ if (reverseAngles) {
+ /*if (a[0][0] < b[0][0])
+ r = true;
+ else
+ r = a[0][1] > b[0][1];*/
+ r = a[0][0] < b[0][0];
+ }
+ else {
+ /*if (a[0][0] > b[0][0])
+ r= true;
+ else
+ r =a[0][1] > b[0][1];
+ */
+ r = a[0][0] > b[0][0];
+ }
+ return r === false ? -1 : 1;
+ };
+ },
+ // used by edgeSortFunctions
+ leftSort = function(a,b) {
+ // first get adjusted values
+ var p1 = a[0][0] < 0 ? -Math.PI - a[0][0] : Math.PI - a[0][0],
+ p2 = b[0][0] < 0 ? -Math.PI - b[0][0] : Math.PI - b[0][0];
+ if (p1 > p2) return 1;
+ else return a[0][1] > b[0][1] ? 1 : -1;
+ },
+ // used by placeAnchors
+ edgeSortFunctions = {
+ "top":function(a, b) { return a[0] > b[0] ? 1 : -1; },
+ "right":currySort(true),
+ "bottom":currySort(true),
+ "left":leftSort
+ },
+ // used by placeAnchors
+ _sortHelper = function(_array, _fn) { return _array.sort(_fn); },
+ // used by AnchorManager.redraw
+ placeAnchors = function(elementId, _anchorLists) {
+ var cd = jsPlumbInstance.getCachedData(elementId), sS = cd.s, sO = cd.o,
+ placeSomeAnchors = function(desc, elementDimensions, elementPosition, unsortedConnections, isHorizontal, otherMultiplier, orientation) {
+ if (unsortedConnections.length > 0) {
+ var sc = _sortHelper(unsortedConnections, edgeSortFunctions[desc]), // puts them in order based on the target element's pos on screen
+ reverse = desc === "right" || desc === "top",
+ anchors = placeAnchorsOnLine(desc, elementDimensions,
+ elementPosition, sc,
+ isHorizontal, otherMultiplier, reverse );
+
+ // takes a computed anchor position and adjusts it for parent offset and scroll, then stores it.
+ var _setAnchorLocation = function(endpoint, anchorPos) {
+ var a = jsPlumbInstance.adjustForParentOffsetAndScroll([anchorPos[0], anchorPos[1]], endpoint.canvas);
+ continuousAnchorLocations[endpoint.id] = [ a[0], a[1], anchorPos[2], anchorPos[3] ];
+ continuousAnchorOrientations[endpoint.id] = orientation;
+ };
+
+ for (var i = 0; i < anchors.length; i++) {
+ var c = anchors[i][4], weAreSource = c.endpoints[0].elementId === elementId, weAreTarget = c.endpoints[1].elementId === elementId;
+ if (weAreSource)
+ _setAnchorLocation(c.endpoints[0], anchors[i]);
+ else if (weAreTarget)
+ _setAnchorLocation(c.endpoints[1], anchors[i]);
+ }
+ }
+ };
+
+ placeSomeAnchors("bottom", sS, [sO.left,sO.top], _anchorLists.bottom, true, 1, [0,1]);
+ placeSomeAnchors("top", sS, [sO.left,sO.top], _anchorLists.top, true, 0, [0,-1]);
+ placeSomeAnchors("left", sS, [sO.left,sO.top], _anchorLists.left, false, 0, [-1,0]);
+ placeSomeAnchors("right", sS, [sO.left,sO.top], _anchorLists.right, false, 1, [1,0]);
+ };
+
+ this.reset = function() {
+ _amEndpoints = {};
+ connectionsByElementId = {};
+ anchorLists = {};
+ };
+ this.addFloatingConnection = function(key, conn) {
+ floatingConnections[key] = conn;
+ };
+ this.removeFloatingConnection = function(key) {
+ delete floatingConnections[key];
+ };
+ this.newConnection = function(conn) {
+ var sourceId = conn.sourceId, targetId = conn.targetId,
+ ep = conn.endpoints,
+ doRegisterTarget = true,
+ registerConnection = function(otherIndex, otherEndpoint, otherAnchor, elId, c) {
+ if ((sourceId == targetId) && otherAnchor.isContinuous){
+ // remove the target endpoint's canvas. we dont need it.
+ jpcl.removeElement(ep[1].canvas);
+ doRegisterTarget = false;
+ }
+ jsPlumbUtil.addToList(connectionsByElementId, elId, [c, otherEndpoint, otherAnchor.constructor == jsPlumb.DynamicAnchor]);
+ };
+
+ registerConnection(0, ep[0], ep[0].anchor, targetId, conn);
+ if (doRegisterTarget)
+ registerConnection(1, ep[1], ep[1].anchor, sourceId, conn);
+ };
+ var removeEndpointFromAnchorLists = function(endpoint) {
+ (function(list, eId) {
+ if (list) { // transient anchors dont get entries in this list.
+ var f = function(e) { return e[4] == eId; };
+ jsPlumbUtil.removeWithFunction(list.top, f);
+ jsPlumbUtil.removeWithFunction(list.left, f);
+ jsPlumbUtil.removeWithFunction(list.bottom, f);
+ jsPlumbUtil.removeWithFunction(list.right, f);
+ }
+ })(anchorLists[endpoint.elementId], endpoint.id);
+ };
+ this.connectionDetached = function(connInfo) {
+ var connection = connInfo.connection || connInfo,
+ sourceId = connInfo.sourceId,
+ targetId = connInfo.targetId,
+ ep = connection.endpoints,
+ removeConnection = function(otherIndex, otherEndpoint, otherAnchor, elId, c) {
+ if (otherAnchor != null && otherAnchor.constructor == jsPlumb.FloatingAnchor) {
+ // no-op
+ }
+ else {
+ jsPlumbUtil.removeWithFunction(connectionsByElementId[elId], function(_c) {
+ return _c[0].id == c.id;
+ });
+ }
+ };
+
+ removeConnection(1, ep[1], ep[1].anchor, sourceId, connection);
+ removeConnection(0, ep[0], ep[0].anchor, targetId, connection);
+
+ // remove from anchorLists
+ removeEndpointFromAnchorLists(connection.endpoints[0]);
+ removeEndpointFromAnchorLists(connection.endpoints[1]);
+
+ self.redraw(connection.sourceId);
+ self.redraw(connection.targetId);
+ };
+ this.add = function(endpoint, elementId) {
+ jsPlumbUtil.addToList(_amEndpoints, elementId, endpoint);
+ };
+ this.changeId = function(oldId, newId) {
+ connectionsByElementId[newId] = connectionsByElementId[oldId];
+ _amEndpoints[newId] = _amEndpoints[oldId];
+ delete connectionsByElementId[oldId];
+ delete _amEndpoints[oldId];
+ };
+ this.getConnectionsFor = function(elementId) {
+ return connectionsByElementId[elementId] || [];
+ };
+ this.getEndpointsFor = function(elementId) {
+ return _amEndpoints[elementId] || [];
+ };
+ this.deleteEndpoint = function(endpoint) {
+ jsPlumbUtil.removeWithFunction(_amEndpoints[endpoint.elementId], function(e) {
+ return e.id == endpoint.id;
+ });
+ removeEndpointFromAnchorLists(endpoint);
+ };
+ this.clearFor = function(elementId) {
+ delete _amEndpoints[elementId];
+ _amEndpoints[elementId] = [];
+ };
+ // updates the given anchor list by either updating an existing anchor's info, or adding it. this function
+ // also removes the anchor from its previous list, if the edge it is on has changed.
+ // all connections found along the way (those that are connected to one of the faces this function
+ // operates on) are added to the connsToPaint list, as are their endpoints. in this way we know to repaint
+ // them wthout having to calculate anything else about them.
+ var _updateAnchorList = function(lists, theta, order, conn, aBoolean, otherElId, idx, reverse, edgeId, elId, connsToPaint, endpointsToPaint) {
+ // first try to find the exact match, but keep track of the first index of a matching element id along the way.s
+ var exactIdx = -1,
+ firstMatchingElIdx = -1,
+ endpoint = conn.endpoints[idx],
+ endpointId = endpoint.id,
+ oIdx = [1,0][idx],
+ values = [ [ theta, order ], conn, aBoolean, otherElId, endpointId ],
+ listToAddTo = lists[edgeId],
+ listToRemoveFrom = endpoint._continuousAnchorEdge ? lists[endpoint._continuousAnchorEdge] : null;
+
+ if (listToRemoveFrom) {
+ var rIdx = jsPlumbUtil.findWithFunction(listToRemoveFrom, function(e) { return e[4] == endpointId; });
+ if (rIdx != -1) {
+ listToRemoveFrom.splice(rIdx, 1);
+ // get all connections from this list
+ for (var i = 0; i < listToRemoveFrom.length; i++) {
+ jsPlumbUtil.addWithFunction(connsToPaint, listToRemoveFrom[i][1], function(c) { return c.id == listToRemoveFrom[i][1].id; });
+ jsPlumbUtil.addWithFunction(endpointsToPaint, listToRemoveFrom[i][1].endpoints[idx], function(e) { return e.id == listToRemoveFrom[i][1].endpoints[idx].id; });
+ jsPlumbUtil.addWithFunction(endpointsToPaint, listToRemoveFrom[i][1].endpoints[oIdx], function(e) { return e.id == listToRemoveFrom[i][1].endpoints[oIdx].id; });
+ }
+ }
+ }
+
+ for (i = 0; i < listToAddTo.length; i++) {
+ if (params.idx == 1 && listToAddTo[i][3] === otherElId && firstMatchingElIdx == -1)
+ firstMatchingElIdx = i;
+ jsPlumbUtil.addWithFunction(connsToPaint, listToAddTo[i][1], function(c) { return c.id == listToAddTo[i][1].id; });
+ jsPlumbUtil.addWithFunction(endpointsToPaint, listToAddTo[i][1].endpoints[idx], function(e) { return e.id == listToAddTo[i][1].endpoints[idx].id; });
+ jsPlumbUtil.addWithFunction(endpointsToPaint, listToAddTo[i][1].endpoints[oIdx], function(e) { return e.id == listToAddTo[i][1].endpoints[oIdx].id; });
+ }
+ if (exactIdx != -1) {
+ listToAddTo[exactIdx] = values;
+ }
+ else {
+ var insertIdx = reverse ? firstMatchingElIdx != -1 ? firstMatchingElIdx : 0 : listToAddTo.length; // of course we will get this from having looked through the array shortly.
+ listToAddTo.splice(insertIdx, 0, values);
+ }
+
+ // store this for next time.
+ endpoint._continuousAnchorEdge = edgeId;
+ };
+
+ //
+ // find the entry in an endpoint's list for this connection and update its target endpoint
+ // with the current target in the connection.
+ //
+ //
+ this.updateOtherEndpoint = function(elId, oldTargetId, newTargetId, connection) {
+ var sIndex = jsPlumbUtil.findWithFunction(connectionsByElementId[elId], function(i) {
+ return i[0].id === connection.id;
+ }),
+ tIndex = jsPlumbUtil.findWithFunction(connectionsByElementId[oldTargetId], function(i) {
+ return i[0].id === connection.id;
+ });
+
+ // update or add data for source
+ if (sIndex != -1) {
+ connectionsByElementId[elId][sIndex][0] = connection;
+ connectionsByElementId[elId][sIndex][1] = connection.endpoints[1];
+ connectionsByElementId[elId][sIndex][2] = connection.endpoints[1].anchor.constructor == jsPlumb.DynamicAnchor;
+ }
+
+ // remove entry for previous target (if there)
+ if (tIndex > -1) {
+
+ connectionsByElementId[oldTargetId].splice(tIndex, 1);
+ // add entry for new target
+ jsPlumbUtil.addToList(connectionsByElementId, newTargetId, [connection, connection.endpoints[0], connection.endpoints[0].anchor.constructor == jsPlumb.DynamicAnchor]);
+ }
+ };
+
+ //
+ // notification that the connection given has changed source from the originalId to the newId.
+ // This involves:
+ // 1. removing the connection from the list of connections stored for the originalId
+ // 2. updating the source information for the target of the connection
+ // 3. re-registering the connection in connectionsByElementId with the newId
+ //
+ this.sourceChanged = function(originalId, newId, connection) {
+ // remove the entry that points from the old source to the target
+ jsPlumbUtil.removeWithFunction(connectionsByElementId[originalId], function(info) {
+ return info[0].id === connection.id;
+ });
+ // find entry for target and update it
+ var tIdx = jsPlumbUtil.findWithFunction(connectionsByElementId[connection.targetId], function(i) {
+ return i[0].id === connection.id;
+ });
+ if (tIdx > -1) {
+ connectionsByElementId[connection.targetId][tIdx][0] = connection;
+ connectionsByElementId[connection.targetId][tIdx][1] = connection.endpoints[0];
+ connectionsByElementId[connection.targetId][tIdx][2] = connection.endpoints[0].anchor.constructor == jsPlumb.DynamicAnchor;
+ }
+ // add entry for new source
+ jsPlumbUtil.addToList(connectionsByElementId, newId, [connection, connection.endpoints[1], connection.endpoints[1].anchor.constructor == jsPlumb.DynamicAnchor]);
+ };
+
+ //
+ // moves the given endpoint from `currentId` to `element`.
+ // This involves:
+ //
+ // 1. changing the key in _amEndpoints under which the endpoint is stored
+ // 2. changing the source or target values in all of the endpoint's connections
+ // 3. changing the array in connectionsByElementId in which the endpoint's connections
+ // are stored (done by either sourceChanged or updateOtherEndpoint)
+ //
+ this.rehomeEndpoint = function(ep, currentId, element) {
+ var eps = _amEndpoints[currentId] || [],
+ elementId = jsPlumbInstance.getId(element);
+
+ if (elementId !== currentId) {
+ var idx = jsPlumbUtil.indexOf(eps, ep);
+ if (idx > -1) {
+ var _ep = eps.splice(idx, 1)[0];
+ self.add(_ep, elementId);
+ }
+ }
+
+ for (var i = 0; i < ep.connections.length; i++) {
+ if (ep.connections[i].sourceId == currentId) {
+ ep.connections[i].sourceId = ep.elementId;
+ ep.connections[i].source = ep.element;
+ self.sourceChanged(currentId, ep.elementId, ep.connections[i]);
+ }
+ else if(ep.connections[i].targetId == currentId) {
+ ep.connections[i].targetId = ep.elementId;
+ ep.connections[i].target = ep.element;
+ self.updateOtherEndpoint(ep.connections[i].sourceId, currentId, ep.elementId, ep.connections[i]);
+ }
+ }
+ };
+
+ this.redraw = function(elementId, ui, timestamp, offsetToUI, clearEdits, doNotRecalcEndpoint) {
+
+ if (!jsPlumbInstance.isSuspendDrawing()) {
+ // get all the endpoints for this element
+ var ep = _amEndpoints[elementId] || [],
+ endpointConnections = connectionsByElementId[elementId] || [],
+ connectionsToPaint = [],
+ endpointsToPaint = [],
+ anchorsToUpdate = [];
+
+ timestamp = timestamp || jsPlumbInstance.timestamp();
+ // offsetToUI are values that would have been calculated in the dragManager when registering
+ // an endpoint for an element that had a parent (somewhere in the hierarchy) that had been
+ // registered as draggable.
+ offsetToUI = offsetToUI || {left:0, top:0};
+ if (ui) {
+ ui = {
+ left:ui.left + offsetToUI.left,
+ top:ui.top + offsetToUI.top
+ };
+ }
+
+ // valid for one paint cycle.
+ var myOffset = jsPlumbInstance.updateOffset( { elId : elementId, offset : ui, recalc : false, timestamp : timestamp }),
+ orientationCache = {};
+
+ // actually, first we should compute the orientation of this element to all other elements to which
+ // this element is connected with a continuous anchor (whether both ends of the connection have
+ // a continuous anchor or just one)
+
+ for (var i = 0; i < endpointConnections.length; i++) {
+ var conn = endpointConnections[i][0],
+ sourceId = conn.sourceId,
+ targetId = conn.targetId,
+ sourceContinuous = conn.endpoints[0].anchor.isContinuous,
+ targetContinuous = conn.endpoints[1].anchor.isContinuous;
+
+ if (sourceContinuous || targetContinuous) {
+ var oKey = sourceId + "_" + targetId,
+ oKey2 = targetId + "_" + sourceId,
+ o = orientationCache[oKey],
+ oIdx = conn.sourceId == elementId ? 1 : 0;
+
+ if (sourceContinuous && !anchorLists[sourceId]) anchorLists[sourceId] = { top:[], right:[], bottom:[], left:[] };
+ if (targetContinuous && !anchorLists[targetId]) anchorLists[targetId] = { top:[], right:[], bottom:[], left:[] };
+
+ if (elementId != targetId) jsPlumbInstance.updateOffset( { elId : targetId, timestamp : timestamp });
+ if (elementId != sourceId) jsPlumbInstance.updateOffset( { elId : sourceId, timestamp : timestamp });
+
+ var td = jsPlumbInstance.getCachedData(targetId),
+ sd = jsPlumbInstance.getCachedData(sourceId);
+
+ if (targetId == sourceId && (sourceContinuous || targetContinuous)) {
+ // here we may want to improve this by somehow determining the face we'd like
+ // to put the connector on. ideally, when drawing, the face should be calculated
+ // by determining which face is closest to the point at which the mouse button
+ // was released. for now, we're putting it on the top face.
+ _updateAnchorList(
+ anchorLists[sourceId],
+ -Math.PI / 2,
+ 0,
+ conn,
+ false,
+ targetId,
+ 0, false, "top", sourceId, connectionsToPaint, endpointsToPaint);
+ }
+ else {
+ if (!o) {
+ o = calculateOrientation(sourceId, targetId, sd.o, td.o, conn.endpoints[0].anchor, conn.endpoints[1].anchor);
+ orientationCache[oKey] = o;
+ // this would be a performance enhancement, but the computed angles need to be clamped to
+ //the (-PI/2 -> PI/2) range in order for the sorting to work properly.
+ /* orientationCache[oKey2] = {
+ orientation:o.orientation,
+ a:[o.a[1], o.a[0]],
+ theta:o.theta + Math.PI,
+ theta2:o.theta2 + Math.PI
+ };*/
+ }
+ if (sourceContinuous) _updateAnchorList(anchorLists[sourceId], o.theta, 0, conn, false, targetId, 0, false, o.a[0], sourceId, connectionsToPaint, endpointsToPaint);
+ if (targetContinuous) _updateAnchorList(anchorLists[targetId], o.theta2, -1, conn, true, sourceId, 1, true, o.a[1], targetId, connectionsToPaint, endpointsToPaint);
+ }
+
+ if (sourceContinuous) jsPlumbUtil.addWithFunction(anchorsToUpdate, sourceId, function(a) { return a === sourceId; });
+ if (targetContinuous) jsPlumbUtil.addWithFunction(anchorsToUpdate, targetId, function(a) { return a === targetId; });
+ jsPlumbUtil.addWithFunction(connectionsToPaint, conn, function(c) { return c.id == conn.id; });
+ if ((sourceContinuous && oIdx === 0) || (targetContinuous && oIdx === 1))
+ jsPlumbUtil.addWithFunction(endpointsToPaint, conn.endpoints[oIdx], function(e) { return e.id == conn.endpoints[oIdx].id; });
+ }
+ }
+ // place Endpoints whose anchors are continuous but have no Connections
+ for (i = 0; i < ep.length; i++) {
+ if (ep[i].connections.length === 0 && ep[i].anchor.isContinuous) {
+ if (!anchorLists[elementId]) anchorLists[elementId] = { top:[], right:[], bottom:[], left:[] };
+ _updateAnchorList(anchorLists[elementId], -Math.PI / 2, 0, {endpoints:[ep[i], ep[i]], paint:function(){}}, false, elementId, 0, false, "top", elementId, connectionsToPaint, endpointsToPaint);
+ jsPlumbUtil.addWithFunction(anchorsToUpdate, elementId, function(a) { return a === elementId; });
+ }
+ }
+ // now place all the continuous anchors we need to;
+ for (i = 0; i < anchorsToUpdate.length; i++) {
+ placeAnchors(anchorsToUpdate[i], anchorLists[anchorsToUpdate[i]]);
+ }
+
+ // now that continuous anchors have been placed, paint all the endpoints for this element
+ // TODO performance: add the endpoint ids to a temp array, and then when iterating in the next
+ // loop, check that we didn't just paint that endpoint. we can probably shave off a few more milliseconds this way.
+ for (i = 0; i < ep.length; i++) {
+ ep[i].paint( { timestamp : timestamp, offset : myOffset, dimensions : myOffset.s, recalc:doNotRecalcEndpoint !== true });
+ }
+ // ... and any other endpoints we came across as a result of the continuous anchors.
+ for (i = 0; i < endpointsToPaint.length; i++) {
+ var cd = jsPlumbInstance.getCachedData(endpointsToPaint[i].elementId);
+ endpointsToPaint[i].paint( { timestamp : timestamp, offset : cd, dimensions : cd.s });
+ }
+
+ // paint all the standard and "dynamic connections", which are connections whose other anchor is
+ // static and therefore does need to be recomputed; we make sure that happens only one time.
+
+ // TODO we could have compiled a list of these in the first pass through connections; might save some time.
+ for (i = 0; i < endpointConnections.length; i++) {
+ var otherEndpoint = endpointConnections[i][1];
+ if (otherEndpoint.anchor.constructor == jsPlumb.DynamicAnchor) {
+ otherEndpoint.paint({ elementWithPrecedence:elementId, timestamp:timestamp });
+ jsPlumbUtil.addWithFunction(connectionsToPaint, endpointConnections[i][0], function(c) { return c.id == endpointConnections[i][0].id; });
+ // all the connections for the other endpoint now need to be repainted
+ for (var k = 0; k < otherEndpoint.connections.length; k++) {
+ if (otherEndpoint.connections[k] !== endpointConnections[i][0])
+ jsPlumbUtil.addWithFunction(connectionsToPaint, otherEndpoint.connections[k], function(c) { return c.id == otherEndpoint.connections[k].id; });
+ }
+ } else if (otherEndpoint.anchor.constructor == jsPlumb.Anchor) {
+ jsPlumbUtil.addWithFunction(connectionsToPaint, endpointConnections[i][0], function(c) { return c.id == endpointConnections[i][0].id; });
+ }
+ }
+ // paint current floating connection for this element, if there is one.
+ var fc = floatingConnections[elementId];
+ if (fc)
+ fc.paint({timestamp:timestamp, recalc:false, elId:elementId});
+
+ // paint all the connections
+ for (i = 0; i < connectionsToPaint.length; i++) {
+ connectionsToPaint[i].paint({elId:elementId, timestamp:timestamp, recalc:false, clearEdits:clearEdits});
+ }
+ }
+ };
+
+ var ContinuousAnchor = function(anchorParams) {
+ jsPlumbUtil.EventGenerator.apply(this);
+ this.type = "Continuous";
+ this.isDynamic = true;
+ this.isContinuous = true;
+ var faces = anchorParams.faces || ["top", "right", "bottom", "left"],
+ clockwise = !(anchorParams.clockwise === false),
+ availableFaces = { },
+ opposites = { "top":"bottom", "right":"left","left":"right","bottom":"top" },
+ clockwiseOptions = { "top":"right", "right":"bottom","left":"top","bottom":"left" },
+ antiClockwiseOptions = { "top":"left", "right":"top","left":"bottom","bottom":"right" },
+ secondBest = clockwise ? clockwiseOptions : antiClockwiseOptions,
+ lastChoice = clockwise ? antiClockwiseOptions : clockwiseOptions,
+ cssClass = anchorParams.cssClass || "";
+
+ for (var i = 0; i < faces.length; i++) { availableFaces[faces[i]] = true; }
+
+ // if the given edge is supported, returns it. otherwise looks for a substitute that _is_
+ // supported. if none supported we also return the request edge.
+ this.verifyEdge = function(edge) {
+ if (availableFaces[edge]) return edge;
+ else if (availableFaces[opposites[edge]]) return opposites[edge];
+ else if (availableFaces[secondBest[edge]]) return secondBest[edge];
+ else if (availableFaces[lastChoice[edge]]) return lastChoice[edge];
+ return edge; // we have to give them something.
+ };
+
+ this.compute = function(params) {
+ return userDefinedContinuousAnchorLocations[params.element.id] || continuousAnchorLocations[params.element.id] || [0,0];
+ };
+ this.getCurrentLocation = function(params) {
+ return userDefinedContinuousAnchorLocations[params.element.id] || continuousAnchorLocations[params.element.id] || [0,0];
+ };
+ this.getOrientation = function(endpoint) {
+ return continuousAnchorOrientations[endpoint.id] || [0,0];
+ };
+ this.clearUserDefinedLocation = function() {
+ delete userDefinedContinuousAnchorLocations[anchorParams.elementId];
+ };
+ this.setUserDefinedLocation = function(loc) {
+ userDefinedContinuousAnchorLocations[anchorParams.elementId] = loc;
+ };
+ this.getCssClass = function() { return cssClass; };
+ this.setCssClass = function(c) { cssClass = c; };
+ };
+
+ // continuous anchors
+ jsPlumbInstance.continuousAnchorFactory = {
+ get:function(params) {
+ var existing = continuousAnchors[params.elementId];
+ if (!existing) {
+ existing = new ContinuousAnchor(params);
+ continuousAnchors[params.elementId] = existing;
+ }
+ return existing;
+ },
+ clear:function(elementId) {
+ delete continuousAnchors[elementId];
+ }
+ };
+ };
+
+ /**
+ * Anchors model a position on some element at which an Endpoint may be located. They began as a first class citizen of jsPlumb, ie. a user
+ * was required to create these themselves, but over time this has been replaced by the concept of referring to them either by name (eg. "TopMiddle"),
+ * or by an array describing their coordinates (eg. [ 0, 0.5, 0, -1 ], which is the same as "TopMiddle"). jsPlumb now handles all of the
+ * creation of Anchors without user intervention.
+ */
+ jsPlumb.Anchor = function(params) {
+ this.x = params.x || 0;
+ this.y = params.y || 0;
+ this.elementId = params.elementId;
+ this.cssClass = params.cssClass || "";
+ this.userDefinedLocation = null;
+ this.orientation = params.orientation || [ 0, 0 ];
+
+ jsPlumbUtil.EventGenerator.apply(this);
+
+ var jsPlumbInstance = params.jsPlumbInstance;//,
+ //lastTimestamp = null;//, lastReturnValue = null;
+
+ this.lastReturnValue = null;
+ this.offsets = params.offsets || [ 0, 0 ];
+ this.timestamp = null;
+ this.compute = function(params) {
+
+ var xy = params.xy, wh = params.wh, element = params.element, timestamp = params.timestamp;
+
+ if(params.clearUserDefinedLocation)
+ this.userDefinedLocation = null;
+
+ if (timestamp && timestamp === self.timestamp)
+ return this.lastReturnValue;
+
+ if (this.userDefinedLocation != null) {
+ this.lastReturnValue = this.userDefinedLocation;
+ }
+ else {
+
+ this.lastReturnValue = [ xy[0] + (this.x * wh[0]) + this.offsets[0], xy[1] + (this.y * wh[1]) + this.offsets[1] ];
+ // adjust loc if there is an offsetParent
+ this.lastReturnValue = jsPlumbInstance.adjustForParentOffsetAndScroll(this.lastReturnValue, element.canvas);
+ }
+
+ this.timestamp = timestamp;
+ return this.lastReturnValue;
+ };
+
+ this.getCurrentLocation = function(params) {
+ return (this.lastReturnValue == null || (params.timestamp != null && this.timestamp != params.timestamp)) ? this.compute(params) : this.lastReturnValue;
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Anchor, jsPlumbUtil.EventGenerator, {
+ equals : function(anchor) {
+ if (!anchor) return false;
+ var ao = anchor.getOrientation(),
+ o = this.getOrientation();
+ return this.x == anchor.x && this.y == anchor.y && this.offsets[0] == anchor.offsets[0] && this.offsets[1] == anchor.offsets[1] && o[0] == ao[0] && o[1] == ao[1];
+ },
+ getUserDefinedLocation : function() {
+ return this.userDefinedLocation;
+ },
+ setUserDefinedLocation : function(l) {
+ this.userDefinedLocation = l;
+ },
+ clearUserDefinedLocation : function() {
+ this.userDefinedLocation = null;
+ },
+ getOrientation : function(_endpoint) { return this.orientation; },
+ getCssClass : function() { return this.cssClass; }
+ });
+
+ /**
+ * An Anchor that floats. its orientation is computed dynamically from
+ * its position relative to the anchor it is floating relative to. It is used when creating
+ * a connection through drag and drop.
+ *
+ * TODO FloatingAnchor could totally be refactored to extend Anchor just slightly.
+ */
+ jsPlumb.FloatingAnchor = function(params) {
+
+ jsPlumb.Anchor.apply(this, arguments);
+
+ // this is the anchor that this floating anchor is referenced to for
+ // purposes of calculating the orientation.
+ var ref = params.reference,
+ jpcl = jsPlumb.CurrentLibrary,
+ jsPlumbInstance = params.jsPlumbInstance,
+ // the canvas this refers to.
+ refCanvas = params.referenceCanvas,
+ size = jpcl.getSize(jpcl.getElementObject(refCanvas)),
+ // these are used to store the current relative position of our
+ // anchor wrt the reference anchor. they only indicate
+ // direction, so have a value of 1 or -1 (or, very rarely, 0). these
+ // values are written by the compute method, and read
+ // by the getOrientation method.
+ xDir = 0, yDir = 0,
+ // temporary member used to store an orientation when the floating
+ // anchor is hovering over another anchor.
+ orientation = null,
+ _lastResult = null;
+
+ // clear from parent. we want floating anchor orientation to always be computed.
+ this.orientation = null;
+
+ // set these to 0 each; they are used by certain types of connectors in the loopback case,
+ // when the connector is trying to clear the element it is on. but for floating anchor it's not
+ // very important.
+ this.x = 0; this.y = 0;
+
+ this.isFloating = true;
+
+ this.compute = function(params) {
+ var xy = params.xy, element = params.element,
+ result = [ xy[0] + (size[0] / 2), xy[1] + (size[1] / 2) ]; // return origin of the element. we may wish to improve this so that any object can be the drag proxy.
+
+ // adjust loc if there is an offsetParent
+ result = jsPlumbInstance.adjustForParentOffsetAndScroll(result, element.canvas);
+
+ _lastResult = result;
+ return result;
+ };
+
+ this.getOrientation = function(_endpoint) {
+ if (orientation) return orientation;
+ else {
+ var o = ref.getOrientation(_endpoint);
+ // here we take into account the orientation of the other
+ // anchor: if it declares zero for some direction, we declare zero too. this might not be the most awesome. perhaps we can come
+ // up with a better way. it's just so that the line we draw looks like it makes sense. maybe this wont make sense.
+ return [ Math.abs(o[0]) * xDir * -1,
+ Math.abs(o[1]) * yDir * -1 ];
+ }
+ };
+
+ /**
+ * notification the endpoint associated with this anchor is hovering
+ * over another anchor; we want to assume that anchor's orientation
+ * for the duration of the hover.
+ */
+ this.over = function(anchor, endpoint) {
+ orientation = anchor.getOrientation(endpoint);
+ };
+
+ /**
+ * notification the endpoint associated with this anchor is no
+ * longer hovering over another anchor; we should resume calculating
+ * orientation as we normally do.
+ */
+ this.out = function() { orientation = null; };
+
+ this.getCurrentLocation = function(params) { return _lastResult == null ? this.compute(params) : _lastResult; };
+ };
+ jsPlumbUtil.extend(jsPlumb.FloatingAnchor, jsPlumb.Anchor);
+
+ var _convertAnchor = function(anchor, jsPlumbInstance, elementId) {
+ return anchor.constructor == jsPlumb.Anchor ? anchor: jsPlumbInstance.makeAnchor(anchor, elementId, jsPlumbInstance);
+ };
+
+ /*
+ * A DynamicAnchor is an Anchor that contains a list of other Anchors, which it cycles
+ * through at compute time to find the one that is located closest to
+ * the center of the target element, and returns that Anchor's compute
+ * method result. this causes endpoints to follow each other with
+ * respect to the orientation of their target elements, which is a useful
+ * feature for some applications.
+ *
+ */
+ jsPlumb.DynamicAnchor = function(params) {
+ jsPlumb.Anchor.apply(this, arguments);
+
+ this.isSelective = true;
+ this.isDynamic = true;
+ this.anchors = [];
+ this.elementId = params.elementId;
+ this.jsPlumbInstance = params.jsPlumbInstance;
+
+ for (var i = 0; i < params.anchors.length; i++)
+ this.anchors[i] = _convertAnchor(params.anchors[i], this.jsPlumbInstance, this.elementId);
+ this.addAnchor = function(anchor) { this.anchors.push(_convertAnchor(anchor, this.jsPlumbInstance, this.elementId)); };
+ this.getAnchors = function() { return this.anchors; };
+ this.locked = false;
+ var _curAnchor = this.anchors.length > 0 ? this.anchors[0] : null,
+ _curIndex = this.anchors.length > 0 ? 0 : -1,
+ _lastAnchor = _curAnchor,
+ self = this,
+
+ // helper method to calculate the distance between the centers of the two elements.
+ _distance = function(anchor, cx, cy, xy, wh) {
+ var ax = xy[0] + (anchor.x * wh[0]), ay = xy[1] + (anchor.y * wh[1]),
+ acx = xy[0] + (wh[0] / 2), acy = xy[1] + (wh[1] / 2);
+ return (Math.sqrt(Math.pow(cx - ax, 2) + Math.pow(cy - ay, 2)) +
+ Math.sqrt(Math.pow(acx - ax, 2) + Math.pow(acy - ay, 2)));
+ },
+ // default method uses distance between element centers. you can provide your own method in the dynamic anchor
+ // constructor (and also to jsPlumb.makeDynamicAnchor). the arguments to it are four arrays:
+ // xy - xy loc of the anchor's element
+ // wh - anchor's element's dimensions
+ // txy - xy loc of the element of the other anchor in the connection
+ // twh - dimensions of the element of the other anchor in the connection.
+ // anchors - the list of selectable anchors
+ _anchorSelector = params.selector || function(xy, wh, txy, twh, anchors) {
+ var cx = txy[0] + (twh[0] / 2), cy = txy[1] + (twh[1] / 2);
+ var minIdx = -1, minDist = Infinity;
+ for ( var i = 0; i < anchors.length; i++) {
+ var d = _distance(anchors[i], cx, cy, xy, wh);
+ if (d < minDist) {
+ minIdx = i + 0;
+ minDist = d;
+ }
+ }
+ return anchors[minIdx];
+ };
+
+ this.compute = function(params) {
+ var xy = params.xy, wh = params.wh, timestamp = params.timestamp, txy = params.txy, twh = params.twh;
+
+ if(params.clearUserDefinedLocation)
+ userDefinedLocation = null;
+
+ this.timestamp = timestamp;
+
+ var udl = self.getUserDefinedLocation();
+ if (udl != null) {
+ return udl;
+ }
+
+ // if anchor is locked or an opposite element was not given, we
+ // maintain our state. anchor will be locked
+ // if it is the source of a drag and drop.
+ if (this.locked || txy == null || twh == null)
+ return _curAnchor.compute(params);
+ else
+ params.timestamp = null; // otherwise clear this, i think. we want the anchor to compute.
+
+ _curAnchor = _anchorSelector(xy, wh, txy, twh, this.anchors);
+ this.x = _curAnchor.x;
+ this.y = _curAnchor.y;
+
+ if (_curAnchor != _lastAnchor)
+ this.fire("anchorChanged", _curAnchor);
+
+ _lastAnchor = _curAnchor;
+
+ return _curAnchor.compute(params);
+ };
+
+ this.getCurrentLocation = function(params) {
+ return this.getUserDefinedLocation() || (_curAnchor != null ? _curAnchor.getCurrentLocation(params) : null);
+ };
+
+ this.getOrientation = function(_endpoint) { return _curAnchor != null ? _curAnchor.getOrientation(_endpoint) : [ 0, 0 ]; };
+ this.over = function(anchor, endpoint) { if (_curAnchor != null) _curAnchor.over(anchor, endpoint); };
+ this.out = function() { if (_curAnchor != null) _curAnchor.out(); };
+
+ this.getCssClass = function() { return (_curAnchor && _curAnchor.getCssClass()) || ""; };
+ };
+ jsPlumbUtil.extend(jsPlumb.DynamicAnchor, jsPlumb.Anchor);
+
+// -------- basic anchors ------------------
+ var _curryAnchor = function(x, y, ox, oy, type, fnInit) {
+ jsPlumb.Anchors[type] = function(params) {
+ var a = params.jsPlumbInstance.makeAnchor([ x, y, ox, oy, 0, 0 ], params.elementId, params.jsPlumbInstance);
+ a.type = type;
+ if (fnInit) fnInit(a, params);
+ return a;
+ };
+ };
+
+ _curryAnchor(0.5, 0, 0,-1, "TopCenter");
+ _curryAnchor(0.5, 1, 0, 1, "BottomCenter");
+ _curryAnchor(0, 0.5, -1, 0, "LeftMiddle");
+ _curryAnchor(1, 0.5, 1, 0, "RightMiddle");
+ // from 1.4.2: Top, Right, Bottom, Left
+ _curryAnchor(0.5, 0, 0,-1, "Top");
+ _curryAnchor(0.5, 1, 0, 1, "Bottom");
+ _curryAnchor(0, 0.5, -1, 0, "Left");
+ _curryAnchor(1, 0.5, 1, 0, "Right");
+ _curryAnchor(0.5, 0.5, 0, 0, "Center");
+ _curryAnchor(1, 0, 0,-1, "TopRight");
+ _curryAnchor(1, 1, 0, 1, "BottomRight");
+ _curryAnchor(0, 0, 0, -1, "TopLeft");
+ _curryAnchor(0, 1, 0, 1, "BottomLeft");
+
+// ------- dynamic anchors -------------------
+
+ // default dynamic anchors chooses from Top, Right, Bottom, Left
+ jsPlumb.Defaults.DynamicAnchors = function(params) {
+ return params.jsPlumbInstance.makeAnchors(["TopCenter", "RightMiddle", "BottomCenter", "LeftMiddle"], params.elementId, params.jsPlumbInstance);
+ };
+
+ // default dynamic anchors bound to name 'AutoDefault'
+ jsPlumb.Anchors.AutoDefault = function(params) {
+ var a = params.jsPlumbInstance.makeDynamicAnchor(jsPlumb.Defaults.DynamicAnchors(params));
+ a.type = "AutoDefault";
+ return a;
+ };
+
+// ------- continuous anchors -------------------
+
+ var _curryContinuousAnchor = function(type, faces) {
+ jsPlumb.Anchors[type] = function(params) {
+ var a = params.jsPlumbInstance.makeAnchor(["Continuous", { faces:faces }], params.elementId, params.jsPlumbInstance);
+ a.type = type;
+ return a;
+ };
+ };
+
+ jsPlumb.Anchors.Continuous = function(params) {
+ return params.jsPlumbInstance.continuousAnchorFactory.get(params);
+ };
+
+ _curryContinuousAnchor("ContinuousLeft", ["left"]);
+ _curryContinuousAnchor("ContinuousTop", ["top"]);
+ _curryContinuousAnchor("ContinuousBottom", ["bottom"]);
+ _curryContinuousAnchor("ContinuousRight", ["right"]);
+
+// ------- position assign anchors -------------------
+
+ // this anchor type lets you assign the position at connection time.
+ jsPlumb.Anchors.Assign = _curryAnchor(0, 0, 0, 0, "Assign", function(anchor, params) {
+ // find what to use as the "position finder". the user may have supplied a String which represents
+ // the id of a position finder in jsPlumb.AnchorPositionFinders, or the user may have supplied the
+ // position finder as a function. we find out what to use and then set it on the anchor.
+ var pf = params.position || "Fixed";
+ anchor.positionFinder = pf.constructor == String ? params.jsPlumbInstance.AnchorPositionFinders[pf] : pf;
+ // always set the constructor params; the position finder might need them later (the Grid one does,
+ // for example)
+ anchor.constructorParams = params;
+ });
+
+ // these are the default anchor positions finders, which are used by the makeTarget function. supplying
+ // a position finder argument to that function allows you to specify where the resulting anchor will
+ // be located
+ jsPlumb.AnchorPositionFinders = {
+ "Fixed": function(dp, ep, es, params) {
+ return [ (dp.left - ep.left) / es[0], (dp.top - ep.top) / es[1] ];
+ },
+ "Grid":function(dp, ep, es, params) {
+ var dx = dp.left - ep.left, dy = dp.top - ep.top,
+ gx = es[0] / (params.grid[0]), gy = es[1] / (params.grid[1]),
+ mx = Math.floor(dx / gx), my = Math.floor(dy / gy);
+ return [ ((mx * gx) + (gx / 2)) / es[0], ((my * gy) + (gy / 2)) / es[1] ];
+ }
+ };
+
+// ------- perimeter anchors -------------------
+
+ jsPlumb.Anchors.Perimeter = function(params) {
+ params = params || {};
+ var anchorCount = params.anchorCount || 60,
+ shape = params.shape;
+
+ if (!shape) throw new Error("no shape supplied to Perimeter Anchor type");
+
+ var _circle = function() {
+ var r = 0.5, step = Math.PI * 2 / anchorCount, current = 0, a = [];
+ for (var i = 0; i < anchorCount; i++) {
+ var x = r + (r * Math.sin(current)),
+ y = r + (r * Math.cos(current));
+ a.push( [ x, y, 0, 0 ] );
+ current += step;
+ }
+ return a;
+ },
+ _path = function(segments) {
+ var anchorsPerFace = anchorCount / segments.length, a = [],
+ _computeFace = function(x1, y1, x2, y2, fractionalLength) {
+ anchorsPerFace = anchorCount * fractionalLength;
+ var dx = (x2 - x1) / anchorsPerFace, dy = (y2 - y1) / anchorsPerFace;
+ for (var i = 0; i < anchorsPerFace; i++) {
+ a.push( [
+ x1 + (dx * i),
+ y1 + (dy * i),
+ 0,
+ 0
+ ]);
+ }
+ };
+
+ for (var i = 0; i < segments.length; i++)
+ _computeFace.apply(null, segments[i]);
+
+ return a;
+ },
+ _shape = function(faces) {
+ var s = [];
+ for (var i = 0; i < faces.length; i++) {
+ s.push([faces[i][0], faces[i][1], faces[i][2], faces[i][3], 1 / faces.length]);
+ }
+ return _path(s);
+ },
+ _rectangle = function() {
+ return _shape([
+ [ 0, 0, 1, 0 ], [ 1, 0, 1, 1 ], [ 1, 1, 0, 1 ], [ 0, 1, 0, 0 ]
+ ]);
+ };
+
+ var _shapes = {
+ "Circle":_circle,
+ "Ellipse":_circle,
+ "Diamond":function() {
+ return _shape([
+ [ 0.5, 0, 1, 0.5 ], [ 1, 0.5, 0.5, 1 ], [ 0.5, 1, 0, 0.5 ], [ 0, 0.5, 0.5, 0 ]
+ ]);
+ },
+ "Rectangle":_rectangle,
+ "Square":_rectangle,
+ "Triangle":function() {
+ return _shape([
+ [ 0.5, 0, 1, 1 ], [ 1, 1, 0, 1 ], [ 0, 1, 0.5, 0]
+ ]);
+ },
+ "Path":function(params) {
+ var points = params.points, p = [], tl = 0;
+ for (var i = 0; i < points.length - 1; i++) {
+ var l = Math.sqrt(Math.pow(points[i][2] - points[i][0]) + Math.pow(points[i][3] - points[i][1]));
+ tl += l;
+ p.push([points[i][0], points[i][1], points[i+1][0], points[i+1][1], l]);
+ }
+ for (var j = 0; j < p.length; j++) {
+ p[j][4] = p[j][4] / tl;
+ }
+ return _path(p);
+ }
+ },
+ _rotate = function(points, amountInDegrees) {
+ var o = [], theta = amountInDegrees / 180 * Math.PI ;
+ for (var i = 0; i < points.length; i++) {
+ var _x = points[i][0] - 0.5,
+ _y = points[i][1] - 0.5;
+
+ o.push([
+ 0.5 + ((_x * Math.cos(theta)) - (_y * Math.sin(theta))),
+ 0.5 + ((_x * Math.sin(theta)) + (_y * Math.cos(theta))),
+ points[i][2],
+ points[i][3]
+ ]);
+ }
+ return o;
+ };
+
+ if (!_shapes[shape]) throw new Error("Shape [" + shape + "] is unknown by Perimeter Anchor type");
+
+ var da = _shapes[shape](params);
+ if (params.rotation) da = _rotate(da, params.rotation);
+ var a = params.jsPlumbInstance.makeDynamicAnchor(da);
+ a.type = "Perimeter";
+ return a;
+ };
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the default Connectors, Endpoint and Overlay definitions.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ /**
+ *
+ * Helper class to consume unused mouse events by components that are DOM elements and
+ * are used by all of the different rendering modes.
+ *
+ */
+ jsPlumb.DOMElementComponent = jsPlumbUtil.extend(jsPlumb.jsPlumbUIComponent, function(params) {
+ // when render mode is canvas, these functions may be called by the canvas mouse handler.
+ // this component is safe to pipe this stuff to /dev/null.
+ this.mousemove =
+ this.dblclick =
+ this.click =
+ this.mousedown =
+ this.mouseup = function(e) { };
+ });
+
+ jsPlumb.Segments = {
+
+ /*
+ * Class: AbstractSegment
+ * A Connector is made up of 1..N Segments, each of which has a Type, such as 'Straight', 'Arc',
+ * 'Bezier'. This is new from 1.4.2, and gives us a lot more flexibility when drawing connections: things such
+ * as rounded corners for flowchart connectors, for example, or a straight line stub for Bezier connections, are
+ * much easier to do now.
+ *
+ * A Segment is responsible for providing coordinates for painting it, and also must be able to report its length.
+ *
+ */
+ AbstractSegment : function(params) {
+ this.params = params;
+
+ /**
+ * Function: findClosestPointOnPath
+ * Finds the closest point on this segment to the given [x, y],
+ * returning both the x and y of the point plus its distance from
+ * the supplied point, and its location along the length of the
+ * path inscribed by the segment. This implementation returns
+ * Infinity for distance and null values for everything else;
+ * subclasses are expected to override.
+ */
+ this.findClosestPointOnPath = function(x, y) {
+ return {
+ d:Infinity,
+ x:null,
+ y:null,
+ l:null
+ };
+ };
+
+ this.getBounds = function() {
+ return {
+ minX:Math.min(params.x1, params.x2),
+ minY:Math.min(params.y1, params.y2),
+ maxX:Math.max(params.x1, params.x2),
+ maxY:Math.max(params.y1, params.y2)
+ };
+ };
+ },
+ Straight : function(params) {
+ var _super = jsPlumb.Segments.AbstractSegment.apply(this, arguments),
+ length, m, m2, x1, x2, y1, y2,
+ _recalc = function() {
+ length = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
+ m = jsPlumbUtil.gradient({x:x1, y:y1}, {x:x2, y:y2});
+ m2 = -1 / m;
+ };
+
+ this.type = "Straight";
+
+ this.getLength = function() { return length; };
+ this.getGradient = function() { return m; };
+
+ this.getCoordinates = function() {
+ return { x1:x1,y1:y1,x2:x2,y2:y2 };
+ };
+ this.setCoordinates = function(coords) {
+ x1 = coords.x1; y1 = coords.y1; x2 = coords.x2; y2 = coords.y2;
+ _recalc();
+ };
+ this.setCoordinates({x1:params.x1, y1:params.y1, x2:params.x2, y2:params.y2});
+
+ this.getBounds = function() {
+ return {
+ minX:Math.min(x1, x2),
+ minY:Math.min(y1, y2),
+ maxX:Math.max(x1, x2),
+ maxY:Math.max(y1, y2)
+ };
+ };
+
+ /**
+ * returns the point on the segment's path that is 'location' along the length of the path, where 'location' is a decimal from
+ * 0 to 1 inclusive. for the straight line segment this is simple maths.
+ */
+ this.pointOnPath = function(location, absolute) {
+ if (location === 0 && !absolute)
+ return { x:x1, y:y1 };
+ else if (location == 1 && !absolute)
+ return { x:x2, y:y2 };
+ else {
+ var l = absolute ? location > 0 ? location : length + location : location * length;
+ return jsPlumbUtil.pointOnLine({x:x1, y:y1}, {x:x2, y:y2}, l);
+ }
+ };
+
+ /**
+ * returns the gradient of the segment at the given point - which for us is constant.
+ */
+ this.gradientAtPoint = function(_) {
+ return m;
+ };
+
+ /**
+ * returns the point on the segment's path that is 'distance' along the length of the path from 'location', where
+ * 'location' is a decimal from 0 to 1 inclusive, and 'distance' is a number of pixels.
+ * this hands off to jsPlumbUtil to do the maths, supplying two points and the distance.
+ */
+ this.pointAlongPathFrom = function(location, distance, absolute) {
+ var p = this.pointOnPath(location, absolute),
+ farAwayPoint = distance <= 0 ? {x:x1, y:y1} : {x:x2, y:y2 };
+
+ /*
+ location == 1 ? {
+ x:x1 + ((x2 - x1) * 10),
+ y:y1 + ((y1 - y2) * 10)
+ } :
+ */
+
+ if (distance <= 0 && Math.abs(distance) > 1) distance *= -1;
+
+ return jsPlumbUtil.pointOnLine(p, farAwayPoint, distance);
+ };
+
+ /**
+ Function: findClosestPointOnPath
+ Finds the closest point on this segment to [x,y]. See
+ notes on this method in AbstractSegment.
+ */
+ this.findClosestPointOnPath = function(x, y) {
+ if (m === 0) {
+ return {
+ x:x,
+ y:y1,
+ d:Math.abs(y - y1)
+ };
+ }
+ else if (m == Infinity || m == -Infinity) {
+ return {
+ x:x1,
+ y:y,
+ d:Math.abs(x - 1)
+ };
+ }
+ else {
+ // closest point lies on normal from given point to this line.
+ var b = y1 - (m * x1),
+ b2 = y - (m2 * x),
+ // y1 = m.x1 + b and y1 = m2.x1 + b2
+ // so m.x1 + b = m2.x1 + b2
+ // x1(m - m2) = b2 - b
+ // x1 = (b2 - b) / (m - m2)
+ _x1 = (b2 -b) / (m - m2),
+ _y1 = (m * _x1) + b,
+ d = jsPlumbUtil.lineLength([ x, y ], [ _x1, _y1 ]),
+ fractionInSegment = jsPlumbUtil.lineLength([ _x1, _y1 ], [ x1, y1 ]);
+
+ return { d:d, x:_x1, y:_y1, l:fractionInSegment / length};
+ }
+ };
+ },
+
+ /*
+ Arc Segment. You need to supply:
+
+ r - radius
+ cx - center x for the arc
+ cy - center y for the arc
+ ac - whether the arc is anticlockwise or not. default is clockwise.
+
+ and then either:
+
+ startAngle - startAngle for the arc.
+ endAngle - endAngle for the arc.
+
+ or:
+
+ x1 - x for start point
+ y1 - y for start point
+ x2 - x for end point
+ y2 - y for end point
+
+ */
+ Arc : function(params) {
+ var _super = jsPlumb.Segments.AbstractSegment.apply(this, arguments),
+ _calcAngle = function(_x, _y) {
+ return jsPlumbUtil.theta([params.cx, params.cy], [_x, _y]);
+ },
+ _calcAngleForLocation = function(segment, location) {
+ if (segment.anticlockwise) {
+ var sa = segment.startAngle < segment.endAngle ? segment.startAngle + TWO_PI : segment.startAngle,
+ s = Math.abs(sa - segment.endAngle);
+ return sa - (s * location);
+ }
+ else {
+ var ea = segment.endAngle < segment.startAngle ? segment.endAngle + TWO_PI : segment.endAngle,
+ ss = Math.abs (ea - segment.startAngle);
+
+ return segment.startAngle + (ss * location);
+ }
+ },
+ TWO_PI = 2 * Math.PI;
+
+ this.radius = params.r;
+ this.anticlockwise = params.ac;
+ this.type = "Arc";
+
+ if (params.startAngle && params.endAngle) {
+ this.startAngle = params.startAngle;
+ this.endAngle = params.endAngle;
+ this.x1 = params.cx + (this.radius * Math.cos(params.startAngle));
+ this.y1 = params.cy + (this.radius * Math.sin(params.startAngle));
+ this.x2 = params.cx + (this.radius * Math.cos(params.endAngle));
+ this.y2 = params.cy + (this.radius * Math.sin(params.endAngle));
+ }
+ else {
+ this.startAngle = _calcAngle(params.x1, params.y1);
+ this.endAngle = _calcAngle(params.x2, params.y2);
+ this.x1 = params.x1;
+ this.y1 = params.y1;
+ this.x2 = params.x2;
+ this.y2 = params.y2;
+ }
+
+ if (this.endAngle < 0) this.endAngle += TWO_PI;
+ if (this.startAngle < 0) this.startAngle += TWO_PI;
+
+ // segment is used by vml
+ this.segment = jsPlumbUtil.segment([this.x1, this.y1], [this.x2, this.y2]);
+
+ // we now have startAngle and endAngle as positive numbers, meaning the
+ // absolute difference (|d|) between them is the sweep (s) of this arc, unless the
+ // arc is 'anticlockwise' in which case 's' is given by 2PI - |d|.
+
+ var ea = this.endAngle < this.startAngle ? this.endAngle + TWO_PI : this.endAngle;
+ this.sweep = Math.abs (ea - this.startAngle);
+ if (this.anticlockwise) this.sweep = TWO_PI - this.sweep;
+ var circumference = 2 * Math.PI * this.radius,
+ frac = this.sweep / TWO_PI,
+ length = circumference * frac;
+
+ this.getLength = function() {
+ return length;
+ };
+
+ this.getBounds = function() {
+ return {
+ minX:params.cx - params.r,
+ maxX:params.cx + params.r,
+ minY:params.cy - params.r,
+ maxY:params.cy + params.r
+ };
+ };
+
+ var VERY_SMALL_VALUE = 0.0000000001,
+ gentleRound = function(n) {
+ var f = Math.floor(n), r = Math.ceil(n);
+ if (n - f < VERY_SMALL_VALUE)
+ return f;
+ else if (r - n < VERY_SMALL_VALUE)
+ return r;
+ return n;
+ };
+
+ /**
+ * returns the point on the segment's path that is 'location' along the length of the path, where 'location' is a decimal from
+ * 0 to 1 inclusive.
+ */
+ this.pointOnPath = function(location, absolute) {
+
+ if (location === 0) {
+ return { x:this.x1, y:this.y1, theta:this.startAngle };
+ }
+ else if (location == 1) {
+ return { x:this.x2, y:this.y2, theta:this.endAngle };
+ }
+
+ if (absolute) {
+ location = location / length;
+ }
+
+ var angle = _calcAngleForLocation(this, location),
+ _x = params.cx + (params.r * Math.cos(angle)),
+ _y = params.cy + (params.r * Math.sin(angle));
+
+ return { x:gentleRound(_x), y:gentleRound(_y), theta:angle };
+ };
+
+ /**
+ * returns the gradient of the segment at the given point.
+ */
+ this.gradientAtPoint = function(location, absolute) {
+ var p = this.pointOnPath(location, absolute);
+ var m = jsPlumbUtil.normal( [ params.cx, params.cy ], [p.x, p.y ] );
+ if (!this.anticlockwise && (m == Infinity || m == -Infinity)) m *= -1;
+ return m;
+ };
+
+ this.pointAlongPathFrom = function(location, distance, absolute) {
+ var p = this.pointOnPath(location, absolute),
+ arcSpan = distance / circumference * 2 * Math.PI,
+ dir = this.anticlockwise ? -1 : 1,
+ startAngle = p.theta + (dir * arcSpan),
+ startX = params.cx + (this.radius * Math.cos(startAngle)),
+ startY = params.cy + (this.radius * Math.sin(startAngle));
+
+ return {x:startX, y:startY};
+ };
+ },
+
+ Bezier : function(params) {
+ var _super = jsPlumb.Segments.AbstractSegment.apply(this, arguments),
+ curve = [
+ { x:params.x1, y:params.y1},
+ { x:params.cp1x, y:params.cp1y },
+ { x:params.cp2x, y:params.cp2y },
+ { x:params.x2, y:params.y2 }
+ ],
+ // although this is not a strictly rigorous determination of bounds
+ // of a bezier curve, it works for the types of curves that this segment
+ // type produces.
+ bounds = {
+ minX:Math.min(params.x1, params.x2, params.cp1x, params.cp2x),
+ minY:Math.min(params.y1, params.y2, params.cp1y, params.cp2y),
+ maxX:Math.max(params.x1, params.x2, params.cp1x, params.cp2x),
+ maxY:Math.max(params.y1, params.y2, params.cp1y, params.cp2y)
+ };
+
+ this.type = "Bezier";
+
+ var _translateLocation = function(_curve, location, absolute) {
+ if (absolute)
+ location = jsBezier.locationAlongCurveFrom(_curve, location > 0 ? 0 : 1, location);
+
+ return location;
+ };
+
+ /**
+ * returns the point on the segment's path that is 'location' along the length of the path, where 'location' is a decimal from
+ * 0 to 1 inclusive.
+ */
+ this.pointOnPath = function(location, absolute) {
+ location = _translateLocation(curve, location, absolute);
+ return jsBezier.pointOnCurve(curve, location);
+ };
+
+ /**
+ * returns the gradient of the segment at the given point.
+ */
+ this.gradientAtPoint = function(location, absolute) {
+ location = _translateLocation(curve, location, absolute);
+ return jsBezier.gradientAtPoint(curve, location);
+ };
+
+ this.pointAlongPathFrom = function(location, distance, absolute) {
+ location = _translateLocation(curve, location, absolute);
+ return jsBezier.pointAlongCurveFrom(curve, location, distance);
+ };
+
+ this.getLength = function() {
+ return jsBezier.getLength(curve);
+ };
+
+ this.getBounds = function() {
+ return bounds;
+ };
+ }
+ };
+
+ /*
+ Class: AbstractComponent
+ Superclass for AbstractConnector and AbstractEndpoint.
+ */
+ var AbstractComponent = function() {
+ this.resetBounds = function() {
+ this.bounds = { minX:Infinity, minY:Infinity, maxX:-Infinity, maxY:-Infinity };
+ };
+ this.resetBounds();
+ };
+
+ /*
+ * Class: AbstractConnector
+ * Superclass for all Connectors; here is where Segments are managed. This is exposed on jsPlumb just so it
+ * can be accessed from other files. You should not try to instantiate one of these directly.
+ *
+ * When this class is asked for a pointOnPath, or gradient etc, it must first figure out which segment to dispatch
+ * that request to. This is done by keeping track of the total connector length as segments are added, and also
+ * their cumulative ratios to the total length. Then when the right segment is found it is a simple case of dispatching
+ * the request to it (and adjusting 'location' so that it is relative to the beginning of that segment.)
+ */
+ jsPlumb.Connectors.AbstractConnector = function(params) {
+
+ AbstractComponent.apply(this, arguments);
+
+ var //self = this,
+ segments = [],
+ editing = false,
+ totalLength = 0,
+ segmentProportions = [],
+ segmentProportionalLengths = [],
+ stub = params.stub || 0,
+ sourceStub = jsPlumbUtil.isArray(stub) ? stub[0] : stub,
+ targetStub = jsPlumbUtil.isArray(stub) ? stub[1] : stub,
+ gap = params.gap || 0,
+ sourceGap = jsPlumbUtil.isArray(gap) ? gap[0] : gap,
+ targetGap = jsPlumbUtil.isArray(gap) ? gap[1] : gap,
+ userProvidedSegments = null,
+ edited = false,
+ paintInfo = null;
+
+ // subclasses should override.
+ this.isEditable = function() { return false; };
+ this.setEdited = function(ed) { edited = ed; };
+
+ // to be overridden by subclasses.
+ this.getPath = function() { };
+ this.setPath = function(path) { };
+
+ /**
+ * Function: findSegmentForPoint
+ * Returns the segment that is closest to the given [x,y],
+ * null if nothing found. This function returns a JS
+ * object with:
+ *
+ * d - distance from segment
+ * l - proportional location in segment
+ * x - x point on the segment
+ * y - y point on the segment
+ * s - the segment itself.
+ */
+ this.findSegmentForPoint = function(x, y) {
+ var out = { d:Infinity, s:null, x:null, y:null, l:null };
+ for (var i = 0; i < segments.length; i++) {
+ var _s = segments[i].findClosestPointOnPath(x, y);
+ if (_s.d < out.d) {
+ out.d = _s.d;
+ out.l = _s.l;
+ out.x = _s.x;
+ out.y = _s.y;
+ out.s = segments[i];
+ }
+ }
+
+ return out;
+ };
+
+ var _updateSegmentProportions = function() {
+ var curLoc = 0;
+ for (var i = 0; i < segments.length; i++) {
+ var sl = segments[i].getLength();
+ segmentProportionalLengths[i] = sl / totalLength;
+ segmentProportions[i] = [curLoc, (curLoc += (sl / totalLength)) ];
+ }
+ },
+
+ /**
+ * returns [segment, proportion of travel in segment, segment index] for the segment
+ * that contains the point which is 'location' distance along the entire path, where
+ * 'location' is a decimal between 0 and 1 inclusive. in this connector type, paths
+ * are made up of a list of segments, each of which contributes some fraction to
+ * the total length.
+ * From 1.3.10 this also supports the 'absolute' property, which lets us specify a location
+ * as the absolute distance in pixels, rather than a proportion of the total path.
+ */
+ _findSegmentForLocation = function(location, absolute) {
+ if (absolute) {
+ location = location > 0 ? location / totalLength : (totalLength + location) / totalLength;
+ }
+
+ var idx = segmentProportions.length - 1, inSegmentProportion = 1;
+ //if (location < 1) {
+ for (var i = 0; i < segmentProportions.length; i++) {
+ if (segmentProportions[i][1] >= location) {
+ idx = i;
+ // todo is this correct for all connector path types?
+ inSegmentProportion = location == 1 ? 1 : location === 0 ? 0 : (location - segmentProportions[i][0]) / segmentProportionalLengths[i];
+ break;
+ }
+ }
+ //}
+ return { segment:segments[idx], proportion:inSegmentProportion, index:idx };
+ },
+ _addSegment = function(conn, type, params) {
+ if (params.x1 == params.x2 && params.y1 == params.y2) return;
+ var s = new jsPlumb.Segments[type](params);
+ segments.push(s);
+ totalLength += s.getLength();
+ conn.updateBounds(s);
+ },
+ _clearSegments = function() {
+ totalLength = 0;
+ segments.splice(0, segments.length);
+ segmentProportions.splice(0, segmentProportions.length);
+ segmentProportionalLengths.splice(0, segmentProportionalLengths.length);
+ };
+
+ this.setSegments = function(_segs) {
+ userProvidedSegments = [];
+ totalLength = 0;
+ for (var i = 0; i < _segs.length; i++) {
+ userProvidedSegments.push(_segs[i]);
+ totalLength += _segs[i].getLength();
+ }
+ };
+
+ var _prepareCompute = function(params) {
+ this.lineWidth = params.lineWidth;
+ var segment = jsPlumbUtil.segment(params.sourcePos, params.targetPos),
+ swapX = params.targetPos[0] < params.sourcePos[0],
+ swapY = params.targetPos[1] < params.sourcePos[1],
+ lw = params.lineWidth || 1,
+ so = params.sourceEndpoint.anchor.orientation || params.sourceEndpoint.anchor.getOrientation(params.sourceEndpoint),
+ to = params.targetEndpoint.anchor.orientation || params.targetEndpoint.anchor.getOrientation(params.targetEndpoint),
+ x = swapX ? params.targetPos[0] : params.sourcePos[0],
+ y = swapY ? params.targetPos[1] : params.sourcePos[1],
+ w = Math.abs(params.targetPos[0] - params.sourcePos[0]),
+ h = Math.abs(params.targetPos[1] - params.sourcePos[1]);
+
+ // if either anchor does not have an orientation set, we derive one from their relative
+ // positions. we fix the axis to be the one in which the two elements are further apart, and
+ // point each anchor at the other element. this is also used when dragging a new connection.
+ if (so[0] === 0 && so[1] === 0 || to[0] === 0 && to[1] === 0) {
+ var index = w > h ? 0 : 1, oIndex = [1,0][index];
+ so = []; to = [];
+ so[index] = params.sourcePos[index] > params.targetPos[index] ? -1 : 1;
+ to[index] = params.sourcePos[index] > params.targetPos[index] ? 1 : -1;
+ so[oIndex] = 0; to[oIndex] = 0;
+ }
+
+ var sx = swapX ? w + (sourceGap * so[0]) : sourceGap * so[0],
+ sy = swapY ? h + (sourceGap * so[1]) : sourceGap * so[1],
+ tx = swapX ? targetGap * to[0] : w + (targetGap * to[0]),
+ ty = swapY ? targetGap * to[1] : h + (targetGap * to[1]),
+ oProduct = ((so[0] * to[0]) + (so[1] * to[1]));
+
+ var result = {
+ sx:sx, sy:sy, tx:tx, ty:ty, lw:lw,
+ xSpan:Math.abs(tx - sx),
+ ySpan:Math.abs(ty - sy),
+ mx:(sx + tx) / 2,
+ my:(sy + ty) / 2,
+ so:so, to:to, x:x, y:y, w:w, h:h,
+ segment : segment,
+ startStubX : sx + (so[0] * sourceStub),
+ startStubY : sy + (so[1] * sourceStub),
+ endStubX : tx + (to[0] * targetStub),
+ endStubY : ty + (to[1] * targetStub),
+ isXGreaterThanStubTimes2 : Math.abs(sx - tx) > (sourceStub + targetStub),
+ isYGreaterThanStubTimes2 : Math.abs(sy - ty) > (sourceStub + targetStub),
+ opposite:oProduct == -1,
+ perpendicular:oProduct === 0,
+ orthogonal:oProduct == 1,
+ sourceAxis : so[0] === 0 ? "y" : "x",
+ points:[x, y, w, h, sx, sy, tx, ty ]
+ };
+ result.anchorOrientation = result.opposite ? "opposite" : result.orthogonal ? "orthogonal" : "perpendicular";
+ return result;
+ };
+
+ this.getSegments = function() { return segments; };
+
+ this.updateBounds = function(segment) {
+ var segBounds = segment.getBounds();
+ this.bounds.minX = Math.min(this.bounds.minX, segBounds.minX);
+ this.bounds.maxX = Math.max(this.bounds.maxX, segBounds.maxX);
+ this.bounds.minY = Math.min(this.bounds.minY, segBounds.minY);
+ this.bounds.maxY = Math.max(this.bounds.maxY, segBounds.maxY);
+ };
+
+ var dumpSegmentsToConsole = function() {
+ console.log("SEGMENTS:");
+ for (var i = 0; i < segments.length; i++) {
+ console.log(segments[i].type, segments[i].getLength(), segmentProportions[i]);
+ }
+ };
+
+ this.pointOnPath = function(location, absolute) {
+ var seg = _findSegmentForLocation(location, absolute);
+ return seg.segment && seg.segment.pointOnPath(seg.proportion, absolute) || [0,0];
+ };
+
+ this.gradientAtPoint = function(location) {
+ var seg = _findSegmentForLocation(location, absolute);
+ return seg.segment && seg.segment.gradientAtPoint(seg.proportion, absolute) || 0;
+ };
+
+ this.pointAlongPathFrom = function(location, distance, absolute) {
+ var seg = _findSegmentForLocation(location, absolute);
+ // TODO what happens if this crosses to the next segment?
+ return seg.segment && seg.segment.pointAlongPathFrom(seg.proportion, distance, false) || [0,0];
+ };
+
+ this.compute = function(params) {
+ if (!edited)
+ paintInfo = _prepareCompute(params);
+
+ _clearSegments();
+ this._compute(paintInfo, params);
+ this.x = paintInfo.points[0];
+ this.y = paintInfo.points[1];
+ this.w = paintInfo.points[2];
+ this.h = paintInfo.points[3];
+ this.segment = paintInfo.segment;
+ _updateSegmentProportions();
+ };
+
+ return {
+ addSegment:_addSegment,
+ prepareCompute:_prepareCompute,
+ sourceStub:sourceStub,
+ targetStub:targetStub,
+ maxStub:Math.max(sourceStub, targetStub),
+ sourceGap:sourceGap,
+ targetGap:targetGap,
+ maxGap:Math.max(sourceGap, targetGap)
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.AbstractConnector, AbstractComponent);
+
+ /**
+ * Class: Connectors.Straight
+ * The Straight connector draws a simple straight line between the two anchor points. It does not have any constructor parameters.
+ */
+ var Straight = function() {
+ this.type = "Straight";
+ var _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments);
+
+ this._compute = function(paintInfo, _) {
+ _super.addSegment(this, "Straight", {x1:paintInfo.sx, y1:paintInfo.sy, x2:paintInfo.startStubX, y2:paintInfo.startStubY});
+ _super.addSegment(this, "Straight", {x1:paintInfo.startStubX, y1:paintInfo.startStubY, x2:paintInfo.endStubX, y2:paintInfo.endStubY});
+ _super.addSegment(this, "Straight", {x1:paintInfo.endStubX, y1:paintInfo.endStubY, x2:paintInfo.tx, y2:paintInfo.ty});
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.Straight, jsPlumb.Connectors.AbstractConnector);
+ jsPlumb.registerConnectorType(Straight, "Straight");
+
+ /**
+ * Class:Connectors.Bezier
+ * This Connector draws a Bezier curve with two control points. You can provide a 'curviness' value which gets applied to jsPlumb's
+ * internal voodoo machine and ends up generating locations for the two control points. See the constructor documentation below.
+ */
+ /**
+ * Function:Constructor
+ *
+ * Parameters:
+ * curviness - How 'curvy' you want the curve to be! This is a directive for the placement of control points, not endpoints of the curve, so your curve does not
+ * actually touch the given point, but it has the tendency to lean towards it. The larger this value, the greater the curve is pulled from a straight line.
+ * Optional; defaults to 150.
+ * stub - optional value for a distance to travel from the connector's endpoint before beginning the Bezier curve. defaults to 0.
+ *
+ */
+ var Bezier = function(params) {
+ params = params || {};
+
+ var _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
+ stub = params.stub || 50,
+ majorAnchor = params.curviness || 150,
+ minorAnchor = 10;
+
+ this.type = "Bezier";
+ this.getCurviness = function() { return majorAnchor; };
+
+ this._findControlPoint = function(point, sourceAnchorPosition, targetAnchorPosition, sourceEndpoint, targetEndpoint) {
+ // determine if the two anchors are perpendicular to each other in their orientation. we swap the control
+ // points around if so (code could be tightened up)
+ var soo = sourceEndpoint.anchor.getOrientation(sourceEndpoint),
+ too = targetEndpoint.anchor.getOrientation(targetEndpoint),
+ perpendicular = soo[0] != too[0] || soo[1] == too[1],
+ p = [];
+
+ if (!perpendicular) {
+ if (soo[0] === 0) // X
+ p.push(sourceAnchorPosition[0] < targetAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
+ else p.push(point[0] - (majorAnchor * soo[0]));
+
+ if (soo[1] === 0) // Y
+ p.push(sourceAnchorPosition[1] < targetAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
+ else p.push(point[1] + (majorAnchor * too[1]));
+ }
+ else {
+ if (too[0] === 0) // X
+ p.push(targetAnchorPosition[0] < sourceAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
+ else p.push(point[0] + (majorAnchor * too[0]));
+
+ if (too[1] === 0) // Y
+ p.push(targetAnchorPosition[1] < sourceAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
+ else p.push(point[1] + (majorAnchor * soo[1]));
+ }
+
+ return p;
+ };
+
+ this._compute = function(paintInfo, p) {
+ var sp = p.sourcePos,
+ tp = p.targetPos,
+ _w = Math.abs(sp[0] - tp[0]),
+ _h = Math.abs(sp[1] - tp[1]),
+ _sx = sp[0] < tp[0] ? _w : 0,
+ _sy = sp[1] < tp[1] ? _h : 0,
+ _tx = sp[0] < tp[0] ? 0 : _w,
+ _ty = sp[1] < tp[1] ? 0 : _h,
+ _CP = this._findControlPoint([_sx, _sy], sp, tp, p.sourceEndpoint, p.targetEndpoint),
+ _CP2 = this._findControlPoint([_tx, _ty], tp, sp, p.targetEndpoint, p.sourceEndpoint);
+
+ _super.addSegment(this, "Bezier", {
+ x1:_sx, y1:_sy, x2:_tx, y2:_ty,
+ cp1x:_CP[0], cp1y:_CP[1], cp2x:_CP2[0], cp2y:_CP2[1]
+ });
+ };
+ };
+ jsPlumbUtil.extend(Bezier, jsPlumb.Connectors.AbstractConnector);
+ jsPlumb.registerConnectorType(Bezier, "Bezier");
+
+ // ********************************* END OF CONNECTOR TYPES *******************************************************************
+
+ // ********************************* ENDPOINT TYPES *******************************************************************
+
+ jsPlumb.Endpoints.AbstractEndpoint = function(params) {
+ AbstractComponent.apply(this, arguments);
+ var compute = this.compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ var out = this._compute.apply(this, arguments);
+ this.x = out[0];
+ this.y = out[1];
+ this.w = out[2];
+ this.h = out[3];
+ this.bounds.minX = this.x;
+ this.bounds.minY = this.y;
+ this.bounds.maxX = this.x + this.w;
+ this.bounds.maxY = this.y + this.h;
+ return out;
+ };
+ return {
+ compute:compute,
+ cssClass:params.cssClass
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.AbstractEndpoint, AbstractComponent);
+
+ /**
+ * Class: Endpoints.Dot
+ * A round endpoint, with default radius 10 pixels.
+ */
+
+ /**
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * radius - radius of the endpoint. defaults to 10 pixels.
+ */
+ jsPlumb.Endpoints.Dot = function(params) {
+ this.type = "Dot";
+ var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+ params = params || {};
+ this.radius = params.radius || 10;
+ this.defaultOffset = 0.5 * this.radius;
+ this.defaultInnerRadius = this.radius / 3;
+
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ this.radius = endpointStyle.radius || this.radius;
+ var x = anchorPoint[0] - this.radius,
+ y = anchorPoint[1] - this.radius,
+ w = this.radius * 2,
+ h = this.radius * 2;
+
+ if (endpointStyle.strokeStyle) {
+ var lw = endpointStyle.lineWidth || 1;
+ x -= lw;
+ y -= lw;
+ w += (lw * 2);
+ h += (lw * 2);
+ }
+ return [ x, y, w, h, this.radius ];
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.Dot, jsPlumb.Endpoints.AbstractEndpoint);
+
+ /**
+ * Class: Endpoints.Rectangle
+ * A Rectangular Endpoint, with default size 20x20.
+ */
+ /**
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * width - width of the endpoint. defaults to 20 pixels.
+ * height - height of the endpoint. defaults to 20 pixels.
+ */
+ jsPlumb.Endpoints.Rectangle = function(params) {
+ this.type = "Rectangle";
+ var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+ params = params || {};
+ this.width = params.width || 20;
+ this.height = params.height || 20;
+
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ var width = endpointStyle.width || this.width,
+ height = endpointStyle.height || this.height,
+ x = anchorPoint[0] - (width/2),
+ y = anchorPoint[1] - (height/2);
+
+ return [ x, y, width, height];
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.Rectangle, jsPlumb.Endpoints.AbstractEndpoint);
+
+
+ var DOMElementEndpoint = function(params) {
+ jsPlumb.DOMElementComponent.apply(this, arguments);
+ this._jsPlumb.displayElements = [ ];
+ };
+ jsPlumbUtil.extend(DOMElementEndpoint, jsPlumb.DOMElementComponent, {
+ // jsPlumb.Endpoints.AbstractEndpoint
+ getDisplayElements : function() {
+ return this._jsPlumb.displayElements;
+ },
+ appendDisplayElement : function(el) {
+ this._jsPlumb.displayElements.push(el);
+ }
+ });
+
+ /**
+ * Class: Endpoints.Image
+ * Draws an image as the Endpoint.
+ */
+ /**
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * src - location of the image to use.
+
+ TODO: multiple references to self. not sure quite how to get rid of them entirely. perhaps self = null in the cleanup
+ function will suffice
+
+ TODO this class still leaks memory.
+
+ */
+ jsPlumb.Endpoints.Image = function(params) {
+
+ this.type = "Image";
+ DOMElementEndpoint.apply(this, arguments);
+ jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+
+ var _onload = params.onload,
+ src = params.src || params.url,
+ parent = params.parent,
+ clazz = params.cssClass ? " " + params.cssClass : "";
+
+ this._jsPlumb.img = new Image();
+ this._jsPlumb.ready = false;
+ this._jsPlumb.initialized = false;
+ this._jsPlumb.deleted = false;
+ this._jsPlumb.widthToUse = params.width;
+ this._jsPlumb.heightToUse = params.height;
+ this._jsPlumb.endpoint = params.endpoint;
+
+ this._jsPlumb.img.onload = function() {
+ // check we weren't actually discarded before use (in fact mostly happens in tests)
+ if (this._jsPlumb != null) {
+ this._jsPlumb.ready = true;
+ this._jsPlumb.widthToUse = this._jsPlumb.widthToUse || this._jsPlumb.img.width;
+ this._jsPlumb.heightToUse = this._jsPlumb.heightToUse || this._jsPlumb.img.height;
+ if (_onload) {
+ _onload(this);
+ }
+ }
+ }.bind(this);
+
+ /*
+ Function: setImage
+ Sets the Image to use in this Endpoint.
+
+ Parameters:
+ img - may be a URL or an Image object
+ onload - optional; a callback to execute once the image has loaded.
+ */
+ this._jsPlumb.endpoint.setImage = function(_img, onload) {
+ var s = _img.constructor == String ? _img : _img.src;
+ _onload = onload;
+ this._jsPlumb.img.src = s;
+
+ if (this.canvas != null)
+ this.canvas.setAttribute("src", this._jsPlumb.img.src);
+ }.bind(this);
+
+ this._jsPlumb.endpoint.setImage(src, _onload);
+ /*
+ var s = src.constructor == String ? src : src.src;
+ //_onload = onload;
+ this._jsPlumb.img.src = src;
+
+ if (this.canvas != null)
+ this.canvas.setAttribute("src", this._jsPlumb.img.src);
+ // }.bind(this);
+
+ //this._jsPlumb.endpoint.setImage(src, _onload);*/
+
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ this.anchorPoint = anchorPoint;
+ if (this._jsPlumb.ready) return [anchorPoint[0] - this._jsPlumb.widthToUse / 2, anchorPoint[1] - this._jsPlumb.heightToUse / 2,
+ this._jsPlumb.widthToUse, this._jsPlumb.heightToUse];
+ else return [0,0,0,0];
+ };
+
+ this.canvas = document.createElement("img");
+ this.canvas.style.margin = 0;
+ this.canvas.style.padding = 0;
+ this.canvas.style.outline = 0;
+ this.canvas.style.position = "absolute";
+ this.canvas.className = this._jsPlumb.instance.endpointClass + clazz;
+ if (this._jsPlumb.widthToUse) this.canvas.setAttribute("width", this._jsPlumb.widthToUse);
+ if (this._jsPlumb.heightToUse) this.canvas.setAttribute("height", this._jsPlumb.heightToUse);
+ this._jsPlumb.instance.appendElement(this.canvas, parent);
+ this.attachListeners(this.canvas, this);
+
+ this.actuallyPaint = function(d, style, anchor) {
+ if (!this._jsPlumb.deleted) {
+ if (!this._jsPlumb.initialized) {
+ this.canvas.setAttribute("src", this._jsPlumb.img.src);
+ this.appendDisplayElement(this.canvas);
+ this._jsPlumb.initialized = true;
+ }
+ var x = this.anchorPoint[0] - (this._jsPlumb.widthToUse / 2),
+ y = this.anchorPoint[1] - (this._jsPlumb.heightToUse / 2);
+ jsPlumbUtil.sizeElement(this.canvas, x, y, this._jsPlumb.widthToUse, this._jsPlumb.heightToUse);
+ }
+ };
+
+ this.paint = function(style, anchor) {
+ if (this._jsPlumb != null) { // may have been deleted
+ if (this._jsPlumb.ready) {
+ this.actuallyPaint(style, anchor);
+ }
+ else {
+ window.setTimeout(function() {
+ this.paint(style, anchor);
+ }.bind(this), 200);
+ }
+ }
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.Image, [ DOMElementEndpoint, jsPlumb.Endpoints.AbstractEndpoint ], {
+ cleanup : function() {
+ this._jsPlumb.deleted = true;
+ jsPlumbUtil.removeElement(this.canvas);
+ this.canvas = null;
+ }
+ });
+
+ /*
+ * Class: Endpoints.Blank
+ * An Endpoint that paints nothing (visible) on the screen. Supports cssClass and hoverClass parameters like all Endpoints.
+ */
+ jsPlumb.Endpoints.Blank = function(params) {
+ var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+ this.type = "Blank";
+ DOMElementEndpoint.apply(this, arguments);
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ return [anchorPoint[0], anchorPoint[1],10,0];
+ };
+
+ this.canvas = document.createElement("div");
+ this.canvas.style.display = "block";
+ this.canvas.style.width = "1px";
+ this.canvas.style.height = "1px";
+ this.canvas.style.background = "transparent";
+ this.canvas.style.position = "absolute";
+ this.canvas.className = this._jsPlumb.endpointClass;
+ jsPlumb.appendElement(this.canvas, params.parent);
+
+ this.paint = function(style, anchor) {
+ jsPlumbUtil.sizeElement(this.canvas, this.x, this.y, this.w, this.h);
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.Blank, [jsPlumb.Endpoints.AbstractEndpoint, DOMElementEndpoint], {
+ cleanup:function() {
+ if (this.canvas) {
+ this.canvas.parentNode.removeChild(this.canvas);
+ }
+ }
+ });
+
+ /*
+ * Class: Endpoints.Triangle
+ * A triangular Endpoint.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * width - width of the triangle's base. defaults to 55 pixels.
+ * height - height of the triangle from base to apex. defaults to 55 pixels.
+ */
+ jsPlumb.Endpoints.Triangle = function(params) {
+ this.type = "Triangle";
+ var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+ params = params || { };
+ params.width = params.width || 55;
+ params.height = params.height || 55;
+ this.width = params.width;
+ this.height = params.height;
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ var width = endpointStyle.width || self.width,
+ height = endpointStyle.height || self.height,
+ x = anchorPoint[0] - (width/2),
+ y = anchorPoint[1] - (height/2);
+ return [ x, y, width, height ];
+ };
+ };
+// ********************************* END OF ENDPOINT TYPES *******************************************************************
+
+
+// ********************************* OVERLAY DEFINITIONS ***********************************************************************
+
+ var AbstractOverlay = jsPlumb.Overlays.AbstractOverlay = function(params) {
+ this.visible = true;
+ this.isAppendedAtTopLevel = true;
+ this.component = params.component;
+ this.loc = params.location == null ? 0.5 : params.location;
+ this.endpointLoc = params.endpointLocation == null ? [ 0.5, 0.5] : params.endpointLocation;
+ //this.;
+ };
+ AbstractOverlay.prototype = {
+ cleanup:function() {
+ this.component = null;
+ this.canvas = null;
+ this.endpointLoc = null;
+ },
+ setVisible : function(val) {
+ this.visible = val;
+ this.component.repaint();
+ },
+ isVisible : function() { return this.visible; },
+ hide : function() { this.setVisible(false); },
+ show : function() { this.setVisible(true); },
+
+ incrementLocation : function(amount) {
+ this.loc += amount;
+ this.component.repaint();
+ },
+ setLocation : function(l) {
+ this.loc = l;
+ this.component.repaint();
+ },
+ getLocation : function() {
+ return this.loc;
+ }
+ };
+
+
+ /*
+ * Class: Overlays.Arrow
+ *
+ * An arrow overlay, defined by four points: the head, the two sides of the tail, and a 'foldback' point at some distance along the length
+ * of the arrow that lines from each tail point converge into. The foldback point is defined using a decimal that indicates some fraction
+ * of the length of the arrow and has a default value of 0.623. A foldback point value of 1 would mean that the arrow had a straight line
+ * across the tail.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * length - distance in pixels from head to tail baseline. default 20.
+ * width - width in pixels of the tail baseline. default 20.
+ * fillStyle - style to use when filling the arrow. defaults to "black".
+ * strokeStyle - style to use when stroking the arrow. defaults to null, which means the arrow is not stroked.
+ * lineWidth - line width to use when stroking the arrow. defaults to 1, but only used if strokeStyle is not null.
+ * foldback - distance (as a decimal from 0 to 1 inclusive) along the length of the arrow marking the point the tail points should fold back to. defaults to 0.623.
+ * location - distance (as a decimal from 0 to 1 inclusive) marking where the arrow should sit on the connector. defaults to 0.5.
+ * direction - indicates the direction the arrow points in. valid values are -1 and 1; 1 is default.
+ */
+ jsPlumb.Overlays.Arrow = function(params) {
+ this.type = "Arrow";
+ AbstractOverlay.apply(this, arguments);
+ this.isAppendedAtTopLevel = false;
+ params = params || {};
+ var _ju = jsPlumbUtil;
+
+ this.length = params.length || 20;
+ this.width = params.width || 20;
+ this.id = params.id;
+ var direction = (params.direction || 1) < 0 ? -1 : 1,
+ paintStyle = params.paintStyle || { lineWidth:1 },
+ // how far along the arrow the lines folding back in come to. default is 62.3%.
+ foldback = params.foldback || 0.623;
+
+ this.computeMaxSize = function() { return self.width * 1.5; };
+ //this.cleanup = function() { }; // nothing to clean up for Arrows
+ this.draw = function(component, currentConnectionPaintStyle) {
+
+ var hxy, mid, txy, tail, cxy;
+ if (component.pointAlongPathFrom) {
+
+ if (_ju.isString(this.loc) || this.loc > 1 || this.loc < 0) {
+ var l = parseInt(this.loc, 10);
+ hxy = component.pointAlongPathFrom(l, direction * this.length / 2, true);
+ mid = component.pointOnPath(l, true);
+ txy = _ju.pointOnLine(hxy, mid, this.length);
+ }
+ else if (this.loc == 1) {
+ hxy = component.pointOnPath(this.loc);
+ mid = component.pointAlongPathFrom(this.loc, -(this.length));
+ txy = _ju.pointOnLine(hxy, mid, this.length);
+
+ if (direction == -1) {
+ var _ = txy;
+ txy = hxy;
+ hxy = _;
+ }
+ }
+ else if (this.loc === 0) {
+ txy = component.pointOnPath(this.loc);
+ mid = component.pointAlongPathFrom(this.loc, this.length);
+ hxy = _ju.pointOnLine(txy, mid, this.length);
+ if (direction == -1) {
+ var __ = txy;
+ txy = hxy;
+ hxy = __;
+ }
+ }
+ else {
+ hxy = component.pointAlongPathFrom(this.loc, direction * this.length / 2);
+ mid = component.pointOnPath(this.loc);
+ txy = _ju.pointOnLine(hxy, mid, this.length);
+ }
+
+ tail = _ju.perpendicularLineTo(hxy, txy, this.width);
+ cxy = _ju.pointOnLine(hxy, txy, foldback * this.length);
+
+ var d = { hxy:hxy, tail:tail, cxy:cxy },
+ strokeStyle = paintStyle.strokeStyle || currentConnectionPaintStyle.strokeStyle,
+ fillStyle = paintStyle.fillStyle || currentConnectionPaintStyle.strokeStyle,
+ lineWidth = paintStyle.lineWidth || currentConnectionPaintStyle.lineWidth,
+ info = {
+ component:component,
+ d:d,
+ lineWidth:lineWidth,
+ strokeStyle:strokeStyle,
+ fillStyle:fillStyle,
+ minX:Math.min(hxy.x, tail[0].x, tail[1].x),
+ maxX:Math.max(hxy.x, tail[0].x, tail[1].x),
+ minY:Math.min(hxy.y, tail[0].y, tail[1].y),
+ maxY:Math.max(hxy.y, tail[0].y, tail[1].y)
+ };
+
+ return info;
+ }
+ else return {component:component, minX:0,maxX:0,minY:0,maxY:0};
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.Arrow, AbstractOverlay);
+
+ /*
+ * Class: Overlays.PlainArrow
+ *
+ * A basic arrow. This is in fact just one instance of the more generic case in which the tail folds back on itself to some
+ * point along the length of the arrow: in this case, that foldback point is the full length of the arrow. so it just does
+ * a 'call' to Arrow with foldback set appropriately.
+ */
+ /*
+ * Function: Constructor
+ * See <Overlays.Arrow> for allowed parameters for this overlay.
+ */
+ jsPlumb.Overlays.PlainArrow = function(params) {
+ params = params || {};
+ var p = jsPlumb.extend(params, {foldback:1});
+ jsPlumb.Overlays.Arrow.call(this, p);
+ this.type = "PlainArrow";
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.PlainArrow, jsPlumb.Overlays.Arrow);
+
+ /*
+ * Class: Overlays.Diamond
+ *
+ * A diamond. Like PlainArrow, this is a concrete case of the more generic case of the tail points converging on some point...it just
+ * happens that in this case, that point is greater than the length of the the arrow.
+ *
+ * this could probably do with some help with positioning...due to the way it reuses the Arrow paint code, what Arrow thinks is the
+ * center is actually 1/4 of the way along for this guy. but we don't have any knowledge of pixels at this point, so we're kind of
+ * stuck when it comes to helping out the Arrow class. possibly we could pass in a 'transpose' parameter or something. the value
+ * would be -l/4 in this case - move along one quarter of the total length.
+ */
+ /*
+ * Function: Constructor
+ * See <Overlays.Arrow> for allowed parameters for this overlay.
+ */
+ jsPlumb.Overlays.Diamond = function(params) {
+ params = params || {};
+ var l = params.length || 40,
+ p = jsPlumb.extend(params, {length:l/2, foldback:2});
+ jsPlumb.Overlays.Arrow.call(this, p);
+ this.type = "Diamond";
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.Diamond, jsPlumb.Overlays.Arrow);
+
+ var _getDimensions = function(component) {
+ if (component._jsPlumb.cachedDimensions == null)
+ component._jsPlumb.cachedDimensions = component.getDimensions();
+ return component._jsPlumb.cachedDimensions;
+ };
+
+ // abstract superclass for overlays that add an element to the DOM.
+ var AbstractDOMOverlay = function(params) {
+ jsPlumb.DOMElementComponent.apply(this, arguments);
+ AbstractOverlay.apply(this, arguments);
+
+ var jpcl = jsPlumb.CurrentLibrary;
+ this.id = params.id;
+ this._jsPlumb.div = null;
+ this._jsPlumb.initialised = false;
+ this._jsPlumb.component = params.component;
+ this._jsPlumb.cachedDimensions = null;
+ this._jsPlumb.create = params.create;
+
+ this.getElement = function() {
+ if (this._jsPlumb.div == null) {
+ var div = this._jsPlumb.div = jpcl.getDOMElement(this._jsPlumb.create(this._jsPlumb.component));
+ div.style.position = "absolute";
+ var clazz = params._jsPlumb.overlayClass + " " +
+ (this.cssClass ? this.cssClass :
+ params.cssClass ? params.cssClass : "");
+ div.className = clazz;
+ this._jsPlumb.instance.appendElement(div, this._jsPlumb.component.parent);
+ this._jsPlumb.instance.getId(div);
+ this.attachListeners(div, this);
+ this.canvas = div;
+ }
+ return this._jsPlumb.div;
+ };
+
+ /*
+ this.paint = function(p, containerExtents) {
+ if (!this._jsPlumb.initialised) {
+ this.getElement();
+ p.component.appendDisplayElement(this._jsPlumb.div);
+ this.attachListeners(this._jsPlumb.div, p.component);
+ this._jsPlumb.initialised = true;
+ }
+ this._jsPlumb.div.style.left = (p.component.x + p.d.minx) + "px";
+ this._jsPlumb.div.style.top = (p.component.y + p.d.miny) + "px";
+ };*/
+
+ this.draw = function(component, currentConnectionPaintStyle) {
+ var td = _getDimensions(this);
+ if (td != null && td.length == 2) {
+ var cxy = {x:0,y:0};
+ if (component.pointOnPath) {
+ var loc = this.loc, absolute = false;
+ if (jsPlumbUtil.isString(this.loc) || this.loc < 0 || this.loc > 1) {
+ loc = parseInt(this.loc, 10);
+ absolute = true;
+ }
+ cxy = component.pointOnPath(loc, absolute); // a connection
+ }
+ else {
+ var locToUse = this.loc.constructor == Array ? this.loc : this.endpointLoc;
+ cxy = { x:locToUse[0] * component.w,
+ y:locToUse[1] * component.h };
+ }
+
+ var minx = cxy.x - (td[0] / 2),
+ miny = cxy.y - (td[1] / 2);
+
+ return {
+ component:component,
+ d:{ minx:minx, miny:miny, td:td, cxy:cxy },
+ minX:minx,
+ maxX:minx + td[0],
+ minY:miny,
+ maxY:miny + td[1]
+ };
+ }
+ else return {minX:0,maxX:0,minY:0,maxY:0};
+ };
+ };
+ jsPlumbUtil.extend(AbstractDOMOverlay, [jsPlumb.DOMElementComponent, AbstractOverlay], {
+ getDimensions : function() {
+ return jsPlumb.CurrentLibrary.getSize(jsPlumb.CurrentLibrary.getElementObject(this.getElement()));
+ },
+ setVisible : function(state) {
+ this._jsPlumb.div.style.display = state ? "block" : "none";
+ },
+ /*
+ * Function: clearCachedDimensions
+ * Clears the cached dimensions for the label. As a performance enhancement, label dimensions are
+ * cached from 1.3.12 onwards. The cache is cleared when you change the label text, of course, but
+ * there are other reasons why the text dimensions might change - if you make a change through CSS, for
+ * example, you might change the font size. in that case you should explicitly call this method.
+ */
+ clearCachedDimensions : function() {
+ this._jsPlumb.cachedDimensions = null;
+ },
+ cleanup : function() {
+ if (this._jsPlumb.div != null)
+ jsPlumb.CurrentLibrary.removeElement(this._jsPlumb.div);
+ },
+ computeMaxSize : function() {
+ var td = _getDimensions(this);
+ return Math.max(td[0], td[1]);
+ },
+ reattachListeners : function(connector) {
+ if (this._jsPlumb.div) {
+ this.reattachListenersForElement(this._jsPlumb.div, this, connector);
+ }
+ },
+ paint : function(p, containerExtents) {
+ if (!this._jsPlumb.initialised) {
+ this.getElement();
+ p.component.appendDisplayElement(this._jsPlumb.div);
+ this.attachListeners(this._jsPlumb.div, p.component);
+ this._jsPlumb.initialised = true;
+ }
+ this._jsPlumb.div.style.left = (p.component.x + p.d.minx) + "px";
+ this._jsPlumb.div.style.top = (p.component.y + p.d.miny) + "px";
+ }
+ });
+
+ /*
+ * Class: Overlays.Custom
+ * A Custom overlay. You supply a 'create' function which returns some DOM element, and jsPlumb positions it.
+ * The 'create' function is passed a Connection or Endpoint.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ * create - function for jsPlumb to call that returns a DOM element.
+ * location - distance (as a decimal from 0 to 1 inclusive) marking where the label should sit on the connector. defaults to 0.5.
+ * id - optional id to use for later retrieval of this overlay.
+ *
+ */
+ jsPlumb.Overlays.Custom = function(params) {
+ this.type = "Custom";
+ AbstractDOMOverlay.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.Custom, AbstractDOMOverlay);
+
+ jsPlumb.Overlays.GuideLines = function() {
+ var self = this;
+ self.length = 50;
+ self.lineWidth = 5;
+ this.type = "GuideLines";
+ AbstractOverlay.apply(this, arguments);
+ jsPlumb.jsPlumbUIComponent.apply(this, arguments);
+ this.draw = function(connector, currentConnectionPaintStyle) {
+
+ var head = connector.pointAlongPathFrom(self.loc, self.length / 2),
+ mid = connector.pointOnPath(self.loc),
+ tail = jsPlumbUtil.pointOnLine(head, mid, self.length),
+ tailLine = jsPlumbUtil.perpendicularLineTo(head, tail, 40),
+ headLine = jsPlumbUtil.perpendicularLineTo(tail, head, 20);
+
+ return {
+ connector:connector,
+ head:head,
+ tail:tail,
+ headLine:headLine,
+ tailLine:tailLine,
+ minX:Math.min(head.x, tail.x, headLine[0].x, headLine[1].x),
+ minY:Math.min(head.y, tail.y, headLine[0].y, headLine[1].y),
+ maxX:Math.max(head.x, tail.x, headLine[0].x, headLine[1].x),
+ maxY:Math.max(head.y, tail.y, headLine[0].y, headLine[1].y)
+ };
+ };
+
+ // this.cleanup = function() { }; // nothing to clean up for GuideLines
+ };
+
+ /*
+ * Class: Overlays.Label
+ * A Label overlay. For all different renderer types (SVG/Canvas/VML), jsPlumb draws a Label overlay as a styled DIV. Version 1.3.0 of jsPlumb
+ * introduced the ability to set css classes on the label; this is now the preferred way for you to style a label. The 'labelStyle' parameter
+ * is still supported in 1.3.0 but its usage is deprecated. Under the hood, jsPlumb just turns that object into a bunch of CSS directive that it
+ * puts on the Label's 'style' attribute, so the end result is the same.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ * cssClass - optional css class string to append to css class. This string is appended "as-is", so you can of course have multiple classes
+ * defined. This parameter is preferred to using labelStyle, borderWidth and borderStyle.
+ * label - the label to paint. May be a string or a function that returns a string. Nothing will be painted if your label is null or your
+ * label function returns null. empty strings _will_ be painted.
+ * location - distance (as a decimal from 0 to 1 inclusive) marking where the label should sit on the connector. defaults to 0.5.
+ * id - optional id to use for later retrieval of this overlay.
+ *
+ */
+ jsPlumb.Overlays.Label = function(params) {
+ this.labelStyle = params.labelStyle || jsPlumb.Defaults.LabelStyle;
+ this.cssClass = this.labelStyle != null ? this.labelStyle.cssClass : null;
+ var p = jsPlumb.extend({
+ create : function() {
+ return document.createElement("div");
+ }}, params);
+ jsPlumb.Overlays.Custom.call(this, p);
+ this.type = "Label";
+ this.label = params.label || "";
+ this.labelText = null;
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.Label, jsPlumb.Overlays.Custom, {
+ cleanup:function() {
+ this.div = null;
+ this.label = null;
+ this.labelText = null;
+ this.cssClass = null;
+ this.labelStyle = null;
+ },
+ getLabel : function() {
+ return this.label;
+ },
+ /*
+ * Function: setLabel
+ * sets the label's, um, label. you would think i'd call this function
+ * 'setText', but you can pass either a Function or a String to this, so
+ * it makes more sense as 'setLabel'. This uses innerHTML on the label div, so keep
+ * that in mind if you need escaped HTML.
+ */
+ setLabel : function(l) {
+ this.label = l;
+ this.labelText = null;
+ this.clearCachedDimensions();
+ this.update();
+ this.component.repaint();
+ },
+ getDimensions : function() {
+ this.update();
+ return AbstractDOMOverlay.prototype.getDimensions.apply(this, arguments);
+ },
+ update : function() {
+ if (typeof this.label == "function") {
+ var lt = this.label(this);
+ this.getElement().innerHTML = lt.replace(/\r\n/g, "<br/>");
+ }
+ else {
+ if (this.labelText == null) {
+ this.labelText = this.label;
+ this.getElement().innerHTML = this.labelText.replace(/\r\n/g, "<br/>");
+ }
+ }
+ }
+ });
+
+ // ********************************* END OF OVERLAY DEFINITIONS ***********************************************************************
+
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the 'flowchart' connectors, consisting of vertical and horizontal line segments.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+;(function() {
+
+ /**
+ * Function: Constructor
+ *
+ * Parameters:
+ * stub - minimum length for the stub at each end of the connector. This can be an integer, giving a value for both ends of the connections,
+ * or an array of two integers, giving separate values for each end. The default is an integer with value 30 (pixels).
+ * gap - gap to leave between the end of the connector and the element on which the endpoint resides. if you make this larger than stub then you will see some odd looking behaviour.
+ Like stub, this can be an array or a single value. defaults to 0 pixels for each end.
+ * cornerRadius - optional, defines the radius of corners between segments. defaults to 0 (hard edged corners).
+ * alwaysRespectStubs - defaults to false. whether or not the connectors should always draw the stub, or, if the two elements
+ are in close proximity to each other (closer than the sum of the two stubs), to adjust the stubs.
+ */
+ var Flowchart = function(params) {
+ this.type = "Flowchart";
+ params = params || {};
+ params.stub = params.stub == null ? 30 : params.stub;
+ var self = this,
+ _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
+ midpoint = params.midpoint == null ? 0.5 : params.midpoint,
+ points = [], segments = [],
+ grid = params.grid,
+ alwaysRespectStubs = params.alwaysRespectStubs,
+ userSuppliedSegments = null,
+ lastx = null, lasty = null, lastOrientation,
+ cornerRadius = params.cornerRadius != null ? params.cornerRadius : 0,
+ sgn = function(n) { return n < 0 ? -1 : n === 0 ? 0 : 1; },
+ /**
+ * helper method to add a segment.
+ */
+ addSegment = function(segments, x, y, paintInfo) {
+ if (lastx == x && lasty == y) return;
+ var lx = lastx == null ? paintInfo.sx : lastx,
+ ly = lasty == null ? paintInfo.sy : lasty,
+ o = lx == x ? "v" : "h",
+ sgnx = sgn(x - lx),
+ sgny = sgn(y - ly);
+
+ lastx = x;
+ lasty = y;
+ segments.push([lx, ly, x, y, o, sgnx, sgny]);
+ },
+ segLength = function(s) {
+ return Math.sqrt(Math.pow(s[0] - s[2], 2) + Math.pow(s[1] - s[3], 2));
+ },
+ _cloneArray = function(a) { var _a = []; _a.push.apply(_a, a); return _a;},
+ updateMinMax = function(a1) {
+ self.bounds.minX = Math.min(self.bounds.minX, a1[2]);
+ self.bounds.maxX = Math.max(self.bounds.maxX, a1[2]);
+ self.bounds.minY = Math.min(self.bounds.minY, a1[3]);
+ self.bounds.maxY = Math.max(self.bounds.maxY, a1[3]);
+ },
+ writeSegments = function(conn, segments, paintInfo) {
+ var current, next;
+ for (var i = 0; i < segments.length - 1; i++) {
+
+ current = current || _cloneArray(segments[i]);
+ next = _cloneArray(segments[i + 1]);
+ if (cornerRadius > 0 && current[4] != next[4]) {
+ var radiusToUse = Math.min(cornerRadius, segLength(current), segLength(next));
+ // right angle. adjust current segment's end point, and next segment's start point.
+ current[2] -= current[5] * radiusToUse;
+ current[3] -= current[6] * radiusToUse;
+ next[0] += next[5] * radiusToUse;
+ next[1] += next[6] * radiusToUse;
+ var ac = (current[6] == next[5] && next[5] == 1) ||
+ ((current[6] == next[5] && next[5] === 0) && current[5] != next[6]) ||
+ (current[6] == next[5] && next[5] == -1),
+ sgny = next[1] > current[3] ? 1 : -1,
+ sgnx = next[0] > current[2] ? 1 : -1,
+ sgnEqual = sgny == sgnx,
+ cx = (sgnEqual && ac || (!sgnEqual && !ac)) ? next[0] : current[2],
+ cy = (sgnEqual && ac || (!sgnEqual && !ac)) ? current[3] : next[1];
+
+ _super.addSegment(conn, "Straight", {
+ x1:current[0], y1:current[1], x2:current[2], y2:current[3]
+ });
+
+ _super.addSegment(conn, "Arc", {
+ r:radiusToUse,
+ x1:current[2],
+ y1:current[3],
+ x2:next[0],
+ y2:next[1],
+ cx:cx,
+ cy:cy,
+ ac:ac
+ });
+ }
+ else {
+ // dx + dy are used to adjust for line width.
+ var dx = (current[2] == current[0]) ? 0 : (current[2] > current[0]) ? (paintInfo.lw / 2) : -(paintInfo.lw / 2),
+ dy = (current[3] == current[1]) ? 0 : (current[3] > current[1]) ? (paintInfo.lw / 2) : -(paintInfo.lw / 2);
+ _super.addSegment(conn, "Straight", {
+ x1:current[0]- dx, y1:current[1]-dy, x2:current[2] + dx, y2:current[3] + dy
+ });
+ }
+ current = next;
+ }
+ // last segment
+ _super.addSegment(conn, "Straight", {
+ x1:next[0], y1:next[1], x2:next[2], y2:next[3]
+ });
+ };
+
+ this.setSegments = function(s) {
+ userSuppliedSegments = s;
+ };
+
+ this.isEditable = function() { return true; };
+
+ /*
+ Function: getOriginalSegments
+ Gets the segments before the addition of rounded corners. This is used by the flowchart
+ connector editor, since it only wants to concern itself with the original segments.
+ */
+ this.getOriginalSegments = function() {
+ return userSuppliedSegments || segments;
+ };
+
+ this._compute = function(paintInfo, params) {
+
+ if (params.clearEdits)
+ userSuppliedSegments = null;
+
+ if (userSuppliedSegments != null) {
+ writeSegments(this, userSuppliedSegments, paintInfo);
+ return;
+ }
+
+ segments = [];
+ lastx = null; lasty = null;
+ lastOrientation = null;
+
+ var midx = paintInfo.startStubX + ((paintInfo.endStubX - paintInfo.startStubX) * midpoint),
+ midy = paintInfo.startStubY + ((paintInfo.endStubY - paintInfo.startStubY) * midpoint);
+
+ var findClearedLine = function(start, mult, anchorPos, dimension) {
+ return start + (mult * (( 1 - anchorPos) * dimension) + _super.maxStub);
+ },
+ orientations = { x:[ 0, 1 ], y:[ 1, 0 ] },
+ commonStubCalculator = function(axis) {
+ return [ paintInfo.startStubX, paintInfo.startStubY, paintInfo.endStubX, paintInfo.endStubY ];
+ },
+ stubCalculators = {
+ perpendicular:commonStubCalculator,
+ orthogonal:commonStubCalculator,
+ opposite:function(axis) {
+ var pi = paintInfo,
+ idx = axis == "x" ? 0 : 1,
+ areInProximity = {
+ "x":function() {
+ return ( (pi.so[idx] == 1 && (
+ ( (pi.startStubX > pi.endStubX) && (pi.tx > pi.startStubX) ) ||
+ ( (pi.sx > pi.endStubX) && (pi.tx > pi.sx))))) ||
+
+ ( (pi.so[idx] == -1 && (
+ ( (pi.startStubX < pi.endStubX) && (pi.tx < pi.startStubX) ) ||
+ ( (pi.sx < pi.endStubX) && (pi.tx < pi.sx)))));
+ },
+ "y":function() {
+ return ( (pi.so[idx] == 1 && (
+ ( (pi.startStubY > pi.endStubY) && (pi.ty > pi.startStubY) ) ||
+ ( (pi.sy > pi.endStubY) && (pi.ty > pi.sy))))) ||
+
+ ( (pi.so[idx] == -1 && (
+ ( (pi.startStubY < pi.endStubY) && (pi.ty < pi.startStubY) ) ||
+ ( (pi.sy < pi.endStubY) && (pi.ty < pi.sy)))));
+ }
+ };
+
+ if (!alwaysRespectStubs && areInProximity[axis]()) {
+ return {
+ "x":[(paintInfo.sx + paintInfo.tx) / 2, paintInfo.startStubY, (paintInfo.sx + paintInfo.tx) / 2, paintInfo.endStubY],
+ "y":[paintInfo.startStubX, (paintInfo.sy + paintInfo.ty) / 2, paintInfo.endStubX, (paintInfo.sy + paintInfo.ty) / 2]
+ }[axis];
+ }
+ else {
+ return [ paintInfo.startStubX, paintInfo.startStubY, paintInfo.endStubX, paintInfo.endStubY ];
+ }
+ }
+ },
+ lineCalculators = {
+ perpendicular : function(axis, ss, oss, es, oes) {
+ var pi = paintInfo,
+ sis = {
+ x:[ [ [ 1,2,3,4 ], null, [ 2,1,4,3 ] ], null, [ [ 4,3,2,1 ], null, [ 3,4,1,2 ] ] ],
+ y:[ [ [ 3,2,1,4 ], null, [ 2,3,4,1 ] ], null, [ [ 4,1,2,3 ], null, [ 1,4,3,2 ] ] ]
+ },
+ stubs = {
+ x:[ [ pi.startStubX, pi.endStubX ] , null, [ pi.endStubX, pi.startStubX ] ],
+ y:[ [ pi.startStubY, pi.endStubY ] , null, [ pi.endStubY, pi.startStubY ] ]
+ },
+ midLines = {
+ x:[ [ midx, pi.startStubY ], [ midx, pi.endStubY ] ],
+ y:[ [ pi.startStubX, midy ], [ pi.endStubX, midy ] ]
+ },
+ linesToEnd = {
+ x:[ [ pi.endStubX, pi.startStubY ] ],
+ y:[ [ pi.startStubX, pi.endStubY ] ]
+ },
+ startToEnd = {
+ x:[ [ pi.startStubX, pi.endStubY ], [ pi.endStubX, pi.endStubY ] ],
+ y:[ [ pi.endStubX, pi.startStubY ], [ pi.endStubX, pi.endStubY ] ]
+ },
+ startToMidToEnd = {
+ x:[ [ pi.startStubX, midy ], [ pi.endStubX, midy ], [ pi.endStubX, pi.endStubY ] ],
+ y:[ [ midx, pi.startStubY ], [ midx, pi.endStubY ], [ pi.endStubX, pi.endStubY ] ]
+ },
+ otherStubs = {
+ x:[ pi.startStubY, pi.endStubY ],
+ y:[ pi.startStubX, pi.endStubX ]
+ },
+ soIdx = orientations[axis][0], toIdx = orientations[axis][1],
+ _so = pi.so[soIdx] + 1,
+ _to = pi.to[toIdx] + 1,
+ otherFlipped = (pi.to[toIdx] == -1 && (otherStubs[axis][1] < otherStubs[axis][0])) || (pi.to[toIdx] == 1 && (otherStubs[axis][1] > otherStubs[axis][0])),
+ stub1 = stubs[axis][_so][0],
+ stub2 = stubs[axis][_so][1],
+ segmentIndexes = sis[axis][_so][_to];
+
+ if (pi.segment == segmentIndexes[3] || (pi.segment == segmentIndexes[2] && otherFlipped)) {
+ return midLines[axis];
+ }
+ else if (pi.segment == segmentIndexes[2] && stub2 < stub1) {
+ return linesToEnd[axis];
+ }
+ else if ((pi.segment == segmentIndexes[2] && stub2 >= stub1) || (pi.segment == segmentIndexes[1] && !otherFlipped)) {
+ return startToMidToEnd[axis];
+ }
+ else if (pi.segment == segmentIndexes[0] || (pi.segment == segmentIndexes[1] && otherFlipped)) {
+ return startToEnd[axis];
+ }
+ },
+ orthogonal : function(axis, startStub, otherStartStub, endStub, otherEndStub) {
+ var pi = paintInfo,
+ extent = {
+ "x":pi.so[0] == -1 ? Math.min(startStub, endStub) : Math.max(startStub, endStub),
+ "y":pi.so[1] == -1 ? Math.min(startStub, endStub) : Math.max(startStub, endStub)
+ }[axis];
+
+ return {
+ "x":[ [ extent, otherStartStub ],[ extent, otherEndStub ], [ endStub, otherEndStub ] ],
+ "y":[ [ otherStartStub, extent ], [ otherEndStub, extent ], [ otherEndStub, endStub ] ]
+ }[axis];
+ },
+ opposite : function(axis, ss, oss, es, oes) {
+ var pi = paintInfo,
+ otherAxis = {"x":"y","y":"x"}[axis],
+ dim = {"x":"height","y":"width"}[axis],
+ comparator = pi["is" + axis.toUpperCase() + "GreaterThanStubTimes2"];
+
+ if (params.sourceEndpoint.elementId == params.targetEndpoint.elementId) {
+ var _val = oss + ((1 - params.sourceEndpoint.anchor[otherAxis]) * params.sourceInfo[dim]) + _super.maxStub;
+ return {
+ "x":[ [ ss, _val ], [ es, _val ] ],
+ "y":[ [ _val, ss ], [ _val, es ] ]
+ }[axis];
+
+ }
+ else if (!comparator || (pi.so[idx] == 1 && ss > es) || (pi.so[idx] == -1 && ss < es)) {
+ return {
+ "x":[[ ss, midy ], [ es, midy ]],
+ "y":[[ midx, ss ], [ midx, es ]]
+ }[axis];
+ }
+ else if ((pi.so[idx] == 1 && ss < es) || (pi.so[idx] == -1 && ss > es)) {
+ return {
+ "x":[[ midx, pi.sy ], [ midx, pi.ty ]],
+ "y":[[ pi.sx, midy ], [ pi.tx, midy ]]
+ }[axis];
+ }
+ }
+ };
+
+ var stubs = stubCalculators[paintInfo.anchorOrientation](paintInfo.sourceAxis),
+ idx = paintInfo.sourceAxis == "x" ? 0 : 1,
+ oidx = paintInfo.sourceAxis == "x" ? 1 : 0,
+ ss = stubs[idx],
+ oss = stubs[oidx],
+ es = stubs[idx + 2],
+ oes = stubs[oidx + 2];
+
+ // add the start stub segment.
+ addSegment(segments, stubs[0], stubs[1], paintInfo);
+
+ // compute the rest of the line
+ var p = lineCalculators[paintInfo.anchorOrientation](paintInfo.sourceAxis, ss, oss, es, oes);
+ if (p) {
+ for (var i = 0; i < p.length; i++) {
+ addSegment(segments, p[i][0], p[i][1], paintInfo);
+ }
+ }
+
+ // line to end stub
+ addSegment(segments, stubs[2], stubs[3], paintInfo);
+
+ // end stub to end
+ addSegment(segments, paintInfo.tx, paintInfo.ty, paintInfo);
+
+ writeSegments(this, segments, paintInfo);
+ };
+
+ this.getPath = function() {
+ var _last = null, _lastAxis = null, s = [], segs = userSuppliedSegments || segments;
+ for (var i = 0; i < segs.length; i++) {
+ var seg = segs[i], axis = seg[4], axisIndex = (axis == "v" ? 3 : 2);
+ if (_last != null && _lastAxis === axis) {
+ _last[axisIndex] = seg[axisIndex];
+ }
+ else {
+ if (seg[0] != seg[2] || seg[1] != seg[3]) {
+ s.push({
+ start:[ seg[0], seg[1] ],
+ end:[ seg[2], seg[3] ]
+ });
+ _last = seg;
+ _lastAxis = seg[4];
+ }
+ }
+ }
+ return s;
+ };
+
+ this.setPath = function(path) {
+ userSuppliedSegments = [];
+ for (var i = 0; i < path.length; i++) {
+ var lx = path[i].start[0],
+ ly = path[i].start[1],
+ x = path[i].end[0],
+ y = path[i].end[1],
+ o = lx == x ? "v" : "h",
+ sgnx = sgn(x - lx),
+ sgny = sgn(y - ly);
+
+ userSuppliedSegments.push([lx, ly, x, y, o, sgnx, sgny]);
+ }
+ };
+ };
+
+ jsPlumbUtil.extend(Flowchart, jsPlumb.Connectors.AbstractConnector);
+ jsPlumb.registerConnectorType(Flowchart, "Flowchart");
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the state machine connectors.
+ *
+ * Thanks to Brainstorm Mobile Solutions for supporting the development of these.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ var Line = function(x1, y1, x2, y2) {
+
+ this.m = (y2 - y1) / (x2 - x1);
+ this.b = -1 * ((this.m * x1) - y1);
+
+ this.rectIntersect = function(x,y,w,h) {
+ var results = [], xInt, yInt;
+
+ // try top face
+ // the equation of the top face is y = (0 * x) + b; y = b.
+ xInt = (y - this.b) / this.m;
+ // test that the X value is in the line's range.
+ if (xInt >= x && xInt <= (x + w)) results.push([ xInt, (this.m * xInt) + this.b ]);
+
+ // try right face
+ yInt = (this.m * (x + w)) + this.b;
+ if (yInt >= y && yInt <= (y + h)) results.push([ (yInt - this.b) / this.m, yInt ]);
+
+ // bottom face
+ xInt = ((y + h) - this.b) / this.m;
+ // test that the X value is in the line's range.
+ if (xInt >= x && xInt <= (x + w)) results.push([ xInt, (this.m * xInt) + this.b ]);
+
+ // try left face
+ yInt = (this.m * x) + this.b;
+ if (yInt >= y && yInt <= (y + h)) results.push([ (yInt - this.b) / this.m, yInt ]);
+
+ if (results.length == 2) {
+ var midx = (results[0][0] + results[1][0]) / 2, midy = (results[0][1] + results[1][1]) / 2;
+ results.push([ midx,midy ]);
+ // now calculate the segment inside the rectangle where the midpoint lies.
+ var xseg = midx <= x + (w / 2) ? -1 : 1,
+ yseg = midy <= y + (h / 2) ? -1 : 1;
+ results.push([xseg, yseg]);
+ return results;
+ }
+
+ return null;
+
+ };
+ },
+ _segment = function(x1, y1, x2, y2) {
+ if (x1 <= x2 && y2 <= y1) return 1;
+ else if (x1 <= x2 && y1 <= y2) return 2;
+ else if (x2 <= x1 && y2 >= y1) return 3;
+ return 4;
+ },
+
+ // the control point we will use depends on the faces to which each end of the connection is assigned, specifically whether or not the
+ // two faces are parallel or perpendicular. if they are parallel then the control point lies on the midpoint of the axis in which they
+ // are parellel and varies only in the other axis; this variation is proportional to the distance that the anchor points lie from the
+ // center of that face. if the two faces are perpendicular then the control point is at some distance from both the midpoints; the amount and
+ // direction are dependent on the orientation of the two elements. 'seg', passed in to this method, tells you which segment the target element
+ // lies in with respect to the source: 1 is top right, 2 is bottom right, 3 is bottom left, 4 is top left.
+ //
+ // sourcePos and targetPos are arrays of info about where on the source and target each anchor is located. their contents are:
+ //
+ // 0 - absolute x
+ // 1 - absolute y
+ // 2 - proportional x in element (0 is left edge, 1 is right edge)
+ // 3 - proportional y in element (0 is top edge, 1 is bottom edge)
+ //
+ _findControlPoint = function(midx, midy, segment, sourceEdge, targetEdge, dx, dy, distance, proximityLimit) {
+ // TODO (maybe)
+ // - if anchor pos is 0.5, make the control point take into account the relative position of the elements.
+ if (distance <= proximityLimit) return [midx, midy];
+
+ if (segment === 1) {
+ if (sourceEdge[3] <= 0 && targetEdge[3] >= 1) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
+ else if (sourceEdge[2] >= 1 && targetEdge[2] <= 0) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
+ else return [ midx + (-1 * dx) , midy + (-1 * dy) ];
+ }
+ else if (segment === 2) {
+ if (sourceEdge[3] >= 1 && targetEdge[3] <= 0) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
+ else if (sourceEdge[2] >= 1 && targetEdge[2] <= 0) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
+ else return [ midx + (1 * dx) , midy + (-1 * dy) ];
+ }
+ else if (segment === 3) {
+ if (sourceEdge[3] >= 1 && targetEdge[3] <= 0) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
+ else if (sourceEdge[2] <= 0 && targetEdge[2] >= 1) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
+ else return [ midx + (-1 * dx) , midy + (-1 * dy) ];
+ }
+ else if (segment === 4) {
+ if (sourceEdge[3] <= 0 && targetEdge[3] >= 1) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
+ else if (sourceEdge[2] <= 0 && targetEdge[2] >= 1) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
+ else return [ midx + (1 * dx) , midy + (-1 * dy) ];
+ }
+
+ };
+
+ /**
+ * Class: Connectors.StateMachine
+ * Provides 'state machine' connectors.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ * curviness - measure of how "curvy" the connectors will be. this is translated as the distance that the
+ * Bezier curve's control point is from the midpoint of the straight line connecting the two
+ * endpoints, and does not mean that the connector is this wide. The Bezier curve never reaches
+ * its control points; they act as gravitational masses. defaults to 10.
+ * margin - distance from element to start and end connectors, in pixels. defaults to 5.
+ * proximityLimit - sets the distance beneath which the elements are consider too close together to bother
+ * with fancy curves. by default this is 80 pixels.
+ * loopbackRadius - the radius of a loopback connector. optional; defaults to 25.
+ * showLoopback - If set to false this tells the connector that it is ok to paint connections whose source and target is the same element with a connector running through the element. The default value for this is true; the connector always makes a loopback connection loop around the element rather than passing through it.
+ */
+ var StateMachine = function(params) {
+ params = params || {};
+ this.type = "StateMachine";
+
+ var self = this,
+ _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
+ curviness = params.curviness || 10,
+ margin = params.margin || 5,
+ proximityLimit = params.proximityLimit || 80,
+ clockwise = params.orientation && params.orientation === "clockwise",
+ loopbackRadius = params.loopbackRadius || 25,
+ showLoopback = params.showLoopback !== false;
+
+ this._compute = function(paintInfo, params) {
+ var w = Math.abs(params.sourcePos[0] - params.targetPos[0]),
+ h = Math.abs(params.sourcePos[1] - params.targetPos[1]),
+ x = Math.min(params.sourcePos[0], params.targetPos[0]),
+ y = Math.min(params.sourcePos[1], params.targetPos[1]);
+
+ if (!showLoopback || (params.sourceEndpoint.elementId !== params.targetEndpoint.elementId)) {
+ var _sx = params.sourcePos[0] < params.targetPos[0] ? 0 : w,
+ _sy = params.sourcePos[1] < params.targetPos[1] ? 0:h,
+ _tx = params.sourcePos[0] < params.targetPos[0] ? w : 0,
+ _ty = params.sourcePos[1] < params.targetPos[1] ? h : 0;
+
+ // now adjust for the margin
+ if (params.sourcePos[2] === 0) _sx -= margin;
+ if (params.sourcePos[2] === 1) _sx += margin;
+ if (params.sourcePos[3] === 0) _sy -= margin;
+ if (params.sourcePos[3] === 1) _sy += margin;
+ if (params.targetPos[2] === 0) _tx -= margin;
+ if (params.targetPos[2] === 1) _tx += margin;
+ if (params.targetPos[3] === 0) _ty -= margin;
+ if (params.targetPos[3] === 1) _ty += margin;
+
+ //
+ // these connectors are quadratic bezier curves, having a single control point. if both anchors
+ // are located at 0.5 on their respective faces, the control point is set to the midpoint and you
+ // get a straight line. this is also the case if the two anchors are within 'proximityLimit', since
+ // it seems to make good aesthetic sense to do that. outside of that, the control point is positioned
+ // at 'curviness' pixels away along the normal to the straight line connecting the two anchors.
+ //
+ // there may be two improvements to this. firstly, we might actually support the notion of avoiding nodes
+ // in the UI, or at least making a good effort at doing so. if a connection would pass underneath some node,
+ // for example, we might increase the distance the control point is away from the midpoint in a bid to
+ // steer it around that node. this will work within limits, but i think those limits would also be the likely
+ // limits for, once again, aesthetic good sense in the layout of a chart using these connectors.
+ //
+ // the second possible change is actually two possible changes: firstly, it is possible we should gradually
+ // decrease the 'curviness' as the distance between the anchors decreases; start tailing it off to 0 at some
+ // point (which should be configurable). secondly, we might slightly increase the 'curviness' for connectors
+ // with respect to how far their anchor is from the center of its respective face. this could either look cool,
+ // or stupid, and may indeed work only in a way that is so subtle as to have been a waste of time.
+ //
+
+ var _midx = (_sx + _tx) / 2, _midy = (_sy + _ty) / 2,
+ m2 = (-1 * _midx) / _midy, theta2 = Math.atan(m2),
+ dy = (m2 == Infinity || m2 == -Infinity) ? 0 : Math.abs(curviness / 2 * Math.sin(theta2)),
+ dx = (m2 == Infinity || m2 == -Infinity) ? 0 : Math.abs(curviness / 2 * Math.cos(theta2)),
+ segment = _segment(_sx, _sy, _tx, _ty),
+ distance = Math.sqrt(Math.pow(_tx - _sx, 2) + Math.pow(_ty - _sy, 2)),
+ // calculate the control point. this code will be where we'll put in a rudimentary element avoidance scheme; it
+ // will work by extending the control point to force the curve to be, um, curvier.
+ _controlPoint = _findControlPoint(_midx,
+ _midy,
+ segment,
+ params.sourcePos,
+ params.targetPos,
+ curviness, curviness,
+ distance,
+ proximityLimit);
+
+ _super.addSegment(this, "Bezier", {
+ x1:_tx, y1:_ty, x2:_sx, y2:_sy,
+ cp1x:_controlPoint[0], cp1y:_controlPoint[1],
+ cp2x:_controlPoint[0], cp2y:_controlPoint[1]
+ });
+ }
+ else {
+ // a loopback connector. draw an arc from one anchor to the other.
+ var x1 = params.sourcePos[0], x2 = params.sourcePos[0], y1 = params.sourcePos[1] - margin, y2 = params.sourcePos[1] - margin,
+ cx = x1, cy = y1 - loopbackRadius,
+ // canvas sizing stuff, to ensure the whole painted area is visible.
+ _w = 2 * loopbackRadius,
+ _h = 2 * loopbackRadius,
+ _x = cx - loopbackRadius,
+ _y = cy - loopbackRadius;
+
+ paintInfo.points[0] = _x;
+ paintInfo.points[1] = _y;
+ paintInfo.points[2] = _w;
+ paintInfo.points[3] = _h;
+
+ // ADD AN ARC SEGMENT.
+ _super.addSegment(this, "Arc", {
+ x1:(x1 - _x) + 4,
+ y1:y1 - _y,
+ startAngle:0,
+ endAngle: 2 * Math.PI,
+ r:loopbackRadius,
+ ac:!clockwise,
+ x2:(x1 - _x) - 4,
+ y2:y1 - _y,
+ cx:cx - _x,
+ cy:cy - _y
+ });
+ }
+ };
+ };
+ jsPlumb.registerConnectorType(StateMachine, "StateMachine");
+})();
+
+/*
+ // a possible rudimentary avoidance scheme, old now, perhaps not useful.
+ // if (avoidSelector) {
+ // var testLine = new Line(sourcePos[0] + _sx,sourcePos[1] + _sy,sourcePos[0] + _tx,sourcePos[1] + _ty);
+ // var sel = jsPlumb.getSelector(avoidSelector);
+ // for (var i = 0; i < sel.length; i++) {
+ // var id = jsPlumb.getId(sel[i]);
+ // if (id != sourceEndpoint.elementId && id != targetEndpoint.elementId) {
+ // o = jsPlumb.getOffset(id), s = jsPlumb.getSize(id);
+//
+// if (o && s) {
+// var collision = testLine.rectIntersect(o.left,o.top,s[0],s[1]);
+// if (collision) {
+ // set the control point to be a certain distance from the midpoint of the two points that
+ // the line crosses on the rectangle.
+ // TODO where will this 75 number come from?
+ // _controlX = collision[2][0] + (75 * collision[3][0]);
+ // / _controlY = collision[2][1] + (75 * collision[3][1]);
+// }
+// }
+ // }
+ // }
+ //}
+ */
+
+;(function() {
+
+ var Bezier = function(params) {
+ params = params || {};
+
+ var self = this,
+ _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
+ stub = params.stub || 50,
+ majorAnchor = params.curviness || 150,
+ minorAnchor = 10;
+
+ this.type = "Bezier";
+ this.getCurviness = function() { return majorAnchor; };
+
+ this._findControlPoint = function(point, sourceAnchorPosition, targetAnchorPosition, sourceEndpoint, targetEndpoint) {
+ // determine if the two anchors are perpendicular to each other in their orientation. we swap the control
+ // points around if so (code could be tightened up)
+ var soo = sourceEndpoint.anchor.getOrientation(sourceEndpoint),
+ too = targetEndpoint.anchor.getOrientation(targetEndpoint),
+ perpendicular = soo[0] != too[0] || soo[1] == too[1],
+ p = [];
+
+ if (!perpendicular) {
+ if (soo[0] === 0) // X
+ p.push(sourceAnchorPosition[0] < targetAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
+ else p.push(point[0] - (majorAnchor * soo[0]));
+
+ if (soo[1] === 0) // Y
+ p.push(sourceAnchorPosition[1] < targetAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
+ else p.push(point[1] + (majorAnchor * too[1]));
+ }
+ else {
+ if (too[0] === 0) // X
+ p.push(targetAnchorPosition[0] < sourceAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
+ else p.push(point[0] + (majorAnchor * too[0]));
+
+ if (too[1] === 0) // Y
+ p.push(targetAnchorPosition[1] < sourceAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
+ else p.push(point[1] + (majorAnchor * soo[1]));
+ }
+
+ return p;
+ };
+
+ this._compute = function(paintInfo, p) {
+ var sp = p.sourcePos,
+ tp = p.targetPos,
+ _w = Math.abs(sp[0] - tp[0]),
+ _h = Math.abs(sp[1] - tp[1]),
+ _sx = sp[0] < tp[0] ? _w : 0,
+ _sy = sp[1] < tp[1] ? _h : 0,
+ _tx = sp[0] < tp[0] ? 0 : _w,
+ _ty = sp[1] < tp[1] ? 0 : _h,
+ _CP = self._findControlPoint([_sx, _sy], sp, tp, p.sourceEndpoint, p.targetEndpoint),
+ _CP2 = self._findControlPoint([_tx, _ty], tp, sp, p.targetEndpoint, p.sourceEndpoint);
+
+ _super.addSegment(this, "Bezier", {
+ x1:_sx, y1:_sy, x2:_tx, y2:_ty,
+ cp1x:_CP[0], cp1y:_CP[1], cp2x:_CP2[0], cp2y:_CP2[1]
+ });
+ };
+ };
+
+ jsPlumb.registerConnectorType(Bezier, "Bezier");
+
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the HTML5 canvas renderers. Support for canvas was dropped in 1.4.2.
+ * This is being kept around because canvas might make a comeback as a single-page solution
+ * that also supports node rendering.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+
+// ********************************* CANVAS RENDERERS FOR CONNECTORS AND ENDPOINTS *******************************************************************
+
+ // TODO refactor to renderer common script. put a ref to jsPlumb.sizeCanvas in there too.
+ var _connectionBeingDragged = null,
+ _hasClass = function(el, clazz) { return jsPlumb.CurrentLibrary.hasClass(_getElementObject(el), clazz); },
+ _getElementObject = function(el) { return jsPlumb.CurrentLibrary.getElementObject(el); },
+ _getOffset = function(el) { return jsPlumb.CurrentLibrary.getOffset(_getElementObject(el)); },
+ _pageXY = function(el) { return jsPlumb.CurrentLibrary.getPageXY(el); },
+ _clientXY = function(el) { return jsPlumb.CurrentLibrary.getClientXY(el); };
+
+ /*
+ * Class:CanvasMouseAdapter
+ * Provides support for mouse events on canvases.
+ */
+ var CanvasMouseAdapter = window.CanvasMouseAdapter = function() {
+ var self = this;
+ self.overlayPlacements = [];
+ jsPlumb.jsPlumbUIComponent.apply(this, arguments);
+ jsPlumbUtil.EventGenerator.apply(this, arguments);
+ /**
+ * returns whether or not the given event is ojver a painted area of the canvas.
+ */
+ this._over = function(e) {
+ var o = _getOffset(_getElementObject(self.canvas)),
+ pageXY = _pageXY(e),
+ x = pageXY[0] - o.left, y = pageXY[1] - o.top;
+ if (x > 0 && y > 0 && x < self.canvas.width && y < self.canvas.height) {
+ // first check overlays
+ for ( var i = 0; i < self.overlayPlacements.length; i++) {
+ var p = self.overlayPlacements[i];
+ if (p && (p[0] <= x && p[1] >= x && p[2] <= y && p[3] >= y))
+ return true;
+ }
+ // then the canvas
+ var d = self.canvas.getContext("2d").getImageData(parseInt(x, 10), parseInt(y, 10), 1, 1);
+ return d.data[0] !== 0 || d.data[1] !== 0 || d.data[2] !== 0 || d.data[3] !== 0;
+ }
+ return false;
+ };
+
+ var _mouseover = false, _mouseDown = false, _posWhenMouseDown = null, _mouseWasDown = false,
+ _nullSafeHasClass = function(el, clazz) {
+ return el !== null && _hasClass(el, clazz);
+ };
+ this.mousemove = function(e) {
+ var pageXY = _pageXY(e), clientXY = _clientXY(e),
+ ee = document.elementFromPoint(clientXY[0], clientXY[1]),
+ eventSourceWasOverlay = _nullSafeHasClass(ee, "_jsPlumb_overlay");
+ var _continue = _connectionBeingDragged === null && (_nullSafeHasClass(ee, "_jsPlumb_endpoint") || _nullSafeHasClass(ee, "_jsPlumb_connector"));
+ if (!_mouseover && _continue && self._over(e)) {
+ _mouseover = true;
+ self.fire("mouseenter", self, e);
+ return true;
+ }
+ // TODO here there is a remote chance that the overlay the mouse moved onto
+ // is actually not an overlay for the current component. a more thorough check would
+ // be to ensure the overlay belonged to the current component.
+ else if (_mouseover && (!self._over(e) || !_continue) && !eventSourceWasOverlay) {
+ _mouseover = false;
+ self.fire("mouseexit", self, e);
+ }
+ self.fire("mousemove", self, e);
+ };
+
+ this.click = function(e) {
+ if (_mouseover && self._over(e) && !_mouseWasDown)
+ self.fire("click", self, e);
+ _mouseWasDown = false;
+ };
+
+ this.dblclick = function(e) {
+ if (_mouseover && self._over(e) && !_mouseWasDown)
+ self.fire("dblclick", self, e);
+ _mouseWasDown = false;
+ };
+
+ this.mousedown = function(e) {
+ if(self._over(e) && !_mouseDown) {
+ _mouseDown = true;
+ _posWhenMouseDown = _getOffset(_getElementObject(self.canvas));
+ self.fire("mousedown", self, e);
+ }
+ };
+
+ this.mouseup = function(e) {
+ _mouseDown = false;
+ self.fire("mouseup", self, e);
+ };
+
+ this.contextmenu = function(e) {
+ if (_mouseover && self._over(e) && !_mouseWasDown)
+ self.fire("contextmenu", self, e);
+ _mouseWasDown = false;
+ };
+ };
+ jsPlumbUtil.extend(CanvasMouseAdapter, [ jsPlumb.jsPlumbUIComponent, jsPlumbUtil.EventGenerator ]);
+
+ var _newCanvas = function(params) {
+ var canvas = document.createElement("canvas");
+ params._jsPlumb.instance.appendElement(canvas, params.parent);
+ canvas.style.position = "absolute";
+ if (params["class"]) canvas.className = params["class"];
+ // set an id. if no id on the element and if uuid was supplied it
+ // will be used, otherwise we'll create one.
+ params._jsPlumb.instance.getId(canvas, params.uuid);
+ if (params.tooltip) canvas.setAttribute("title", params.tooltip);
+
+ return canvas;
+ };
+
+ var CanvasComponent = window.CanvasComponent = function(params) {
+ CanvasMouseAdapter.apply(this, arguments);
+
+ var displayElements = [ ];
+ this.getDisplayElements = function() { return displayElements; };
+ this.appendDisplayElement = function(el) { displayElements.push(el); };
+ };
+ jsPlumbUtil.extend(CanvasComponent, CanvasMouseAdapter);
+
+ var segmentMultipliers = [null, [1, -1], [1, 1], [-1, 1], [-1, -1] ];
+ var maybeMakeGradient = function(ctx, style, gradientFunction) {
+ if (style.gradient) {
+ var g = gradientFunction();
+ for ( var i = 0; i < style.gradient.stops.length; i++)
+ g.addColorStop(style.gradient.stops[i][0], style.gradient.stops[i][1]);
+ ctx.strokeStyle = g;
+ }
+ };
+ var segmentRenderer = function(segment, ctx, style, dx, dy) {
+ ({
+ "Straight":function(segment, ctx, style, dx, dy) {
+ var d = segment.params;
+ ctx.save();
+ maybeMakeGradient(ctx, style, function() { return ctx.createLinearGradient(d.x1, d.y1, d.x2, d.y2); });
+ ctx.beginPath();
+ ctx.translate(dx, dy);
+ if (style.dashstyle && style.dashstyle.split(" ").length === 2) {
+ // only a very simple dashed style is supported - having two values, which define the stroke length
+ // (as a multiple of the stroke width) and then the space length (also as a multiple of stroke width).
+ var ds = style.dashstyle.split(" ");
+ if (ds.length !== 2) ds = [2, 2];
+ var dss = [ ds[0] * style.lineWidth, ds[1] * style.lineWidth ],
+ m = (d.x2- d.x1) / (d.y2 - d.y1),
+ s = jsPlumbUtil.segment([d.x1, d.y1], [ d.x2, d.y2 ]),
+ sm = segmentMultipliers[s],
+ theta = Math.atan(m),
+ l = Math.sqrt(Math.pow(d.x2 - d.x1, 2) + Math.pow(d.y2 - d.y1, 2)),
+ repeats = Math.floor(l / (dss[0] + dss[1])),
+ curPos = [d.x1, d.y1];
+
+
+ // TODO: the question here is why could we not support this in all connector types? it's really
+ // just a case of going along and asking jsPlumb for the next point on the path a few times, until it
+ // reaches the end. every type of connector supports that method, after all. but right now its only the
+ // bezier connector that gives you back the new location on the path along with the x,y coordinates, which
+ // we would need. we'd start out at loc=0 and ask for the point along the path that is dss[0] pixels away.
+ // we then ask for the point that is (dss[0] + dss[1]) pixels away; and from that one we need not just the
+ // x,y but the location, cos we're gonna plug that location back in in order to find where that dash ends.
+ //
+ // it also strikes me that it should be trivial to support arbitrary dash styles (having more or less than two
+ // entries). you'd just iterate that array using a step size of 2, and generify the (rss[0] + rss[1])
+ // computation to be sum(rss[0]..rss[n]).
+
+ for (var i = 0; i < repeats; i++) {
+ ctx.moveTo(curPos[0], curPos[1]);
+
+ var nextEndX = curPos[0] + (Math.abs(Math.sin(theta) * dss[0]) * sm[0]),
+ nextEndY = curPos[1] + (Math.abs(Math.cos(theta) * dss[0]) * sm[1]),
+ nextStartX = curPos[0] + (Math.abs(Math.sin(theta) * (dss[0] + dss[1])) * sm[0]),
+ nextStartY = curPos[1] + (Math.abs(Math.cos(theta) * (dss[0] + dss[1])) * sm[1]);
+
+ ctx.lineTo(nextEndX, nextEndY);
+ curPos = [nextStartX, nextStartY];
+ }
+
+ // now draw the last bit
+ ctx.moveTo(curPos[0], curPos[1]);
+ ctx.lineTo(d.x2, d.y2);
+
+ }
+ else {
+ ctx.moveTo(d.x1, d.y1);
+ ctx.lineTo(d.x2, d.y2);
+ }
+
+ ctx.stroke();
+
+ ctx.restore();
+ },
+ "Bezier":function(segment, ctx, style, dx, dy) {
+ var d = segment.params;
+ ctx.save();
+ maybeMakeGradient(ctx, style, function() { return ctx.createLinearGradient(d.x2 + dx, d.y2 + dy, d.x1 + dx, d.y1 + dy); });
+ ctx.beginPath();
+ ctx.translate(dx, dy);
+ ctx.moveTo(d.x1, d.y1);
+ ctx.bezierCurveTo(d.cp1x, d.cp1y, d.cp2x, d.cp2y, d.x2, d.y2);
+ ctx.stroke();
+ ctx.restore();
+ },
+ "Arc":function(segment, ctx, style, dx, dy) {
+ var d = segment.params;
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(dx, dy);
+ ctx.arc(d.cx, d.cy, d.r, segment.startAngle, segment.endAngle, d.ac);
+ ctx.stroke();
+ ctx.restore();
+ }
+ })[segment.type](segment, ctx, style, dx, dy);
+ };
+
+ /**
+ * Class:CanvasConnector
+ * Superclass for Canvas Connector renderers.
+ */
+ var CanvasConnector = jsPlumb.ConnectorRenderers.canvas = function(params) {
+ CanvasComponent.apply(this, arguments);
+
+ var _paintOneStyle = function(aStyle, dx, dy) {
+ this.ctx.save();
+ jsPlumb.extend(this.ctx, aStyle);
+
+ var segments = this.getSegments();
+ for (var i = 0; i < segments.length; i++) {
+ segmentRenderer(segments[i], this.ctx, aStyle, dx, dy);
+ }
+ this.ctx.restore();
+ }.bind(this);
+
+ var clazz = this._jsPlumb.instance.connectorClass + " " + (params.cssClass || "");
+ this.canvas = _newCanvas({
+ "class":clazz,
+ _jsPlumb:this._jsPlumb,
+ parent:params.parent
+ });
+ this.ctx = this.canvas.getContext("2d");
+
+ this.appendDisplayElement(this.canvas);
+
+ this.paint = function(style, anchor, extents) {
+ if (style != null) {
+
+ var xy = [ this.x, this.y ], wh = [ this.w, this.h ], p,
+ dx = 0, dy = 0;
+
+ if (extents != null) {
+ if (extents.xmin < 0) {
+ xy[0] += extents.xmin;
+ dx = -extents.xmin;
+ }
+ if (extents.ymin < 0) {
+ xy[1] += extents.ymin;
+ dy = -extents.ymin;
+ }
+ wh[0] = extents.xmax + ((extents.xmin < 0) ? -extents.xmin : 0);
+ wh[1] = extents.ymax + ((extents.ymin < 0) ? -extents.ymin : 0);
+ }
+
+ this.translateX = dx;
+ this.translateY = dy;
+
+ jsPlumbUtil.sizeElement(this.canvas, xy[0], xy[1], wh[0], wh[1]);
+
+ if (style.outlineColor != null) {
+ var outlineWidth = style.outlineWidth || 1,
+ outlineStrokeWidth = style.lineWidth + (2 * outlineWidth),
+ outlineStyle = {
+ strokeStyle:style.outlineColor,
+ lineWidth:outlineStrokeWidth
+ };
+ _paintOneStyle(outlineStyle, dx, dy);
+ }
+ _paintOneStyle(style, dx, dy);
+ }
+ };
+ };
+ jsPlumbUtil.extend(CanvasConnector, CanvasComponent);
+
+
+ /**
+ * Class:CanvasEndpoint
+ * Superclass for Canvas Endpoint renderers.
+ */
+ var CanvasEndpoint = function(params) {
+ CanvasComponent.apply(this, arguments);
+ var clazz = this._jsPlumb.instance.endpointClass + " " + (params.cssClass || ""),
+ canvasParams = {
+ "class":clazz,
+ _jsPlumb:this._jsPlumb,
+ parent:params.parent,
+ tooltip:self.tooltip
+ };
+ this.canvas = _newCanvas(canvasParams);
+ this.ctx = this.canvas.getContext("2d");
+
+ this.appendDisplayElement(this.canvas);
+
+ this.paint = function(style, anchor, extents) {
+ jsPlumbUtil.sizeElement(this.canvas, this.x, this.y, this.w, this.h);
+ if (style.outlineColor != null) {
+ var outlineWidth = style.outlineWidth || 1,
+ outlineStrokeWidth = style.lineWidth + (2 * outlineWidth);
+ var outlineStyle = {
+ strokeStyle:style.outlineColor,
+ lineWidth:outlineStrokeWidth
+ };
+ }
+
+ this._paint.apply(this, arguments);
+ };
+ };
+ jsPlumbUtil.extend(CanvasEndpoint, CanvasComponent);
+
+ jsPlumb.Endpoints.canvas.Dot = function(params) {
+ jsPlumb.Endpoints.Dot.apply(this, arguments);
+ CanvasEndpoint.apply(this, arguments);
+ var self = this,
+ parseValue = function(value) {
+ try { return parseInt(value, 10); }
+ catch(e) {
+ if (value.substring(value.length - 1) == '%')
+ return parseInt(value.substring(0, value - 1), 10);
+ }
+ },
+ calculateAdjustments = function(gradient) {
+ var offsetAdjustment = self.defaultOffset, innerRadius = self.defaultInnerRadius;
+ if (gradient.offset) offsetAdjustment = parseValue(gradient.offset);
+ if (gradient.innerRadius) innerRadius = parseValue(gradient.innerRadius);
+ return [offsetAdjustment, innerRadius];
+ };
+ this._paint = function(style) {
+ if (style != null) {
+ var ctx = self.canvas.getContext('2d'),
+ orientation = params.endpoint.anchor.getOrientation(params.endpoint);
+
+ jsPlumb.extend(ctx, style);
+ if (style.gradient) {
+ var adjustments = calculateAdjustments(style.gradient),
+ yAdjust = orientation[1] == 1 ? adjustments[0] * -1 : adjustments[0],
+ xAdjust = orientation[0] == 1 ? adjustments[0] * -1: adjustments[0],
+ g = ctx.createRadialGradient(self.radius, self.radius, self.radius, self.radius + xAdjust, self.radius + yAdjust, adjustments[1]);
+ for (var i = 0; i < style.gradient.stops.length; i++)
+ g.addColorStop(style.gradient.stops[i][0], style.gradient.stops[i][1]);
+ ctx.fillStyle = g;
+ }
+ ctx.beginPath();
+ //ctx.translate(dx, dy);
+ ctx.arc(self.radius, self.radius, self.radius, 0, Math.PI*2, true);
+ ctx.closePath();
+ if (style.fillStyle || style.gradient) ctx.fill();
+ if (style.strokeStyle) ctx.stroke();
+ }
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.canvas.Dot, [ jsPlumb.Endpoints.Dot, CanvasEndpoint ]);
+
+ jsPlumb.Endpoints.canvas.Rectangle = function(params) {
+
+ var self = this;
+ jsPlumb.Endpoints.Rectangle.apply(this, arguments);
+ CanvasEndpoint.apply(this, arguments);
+
+ this._paint = function(style) {
+
+ var ctx = self.canvas.getContext("2d"),
+ orientation = params.endpoint.anchor.getOrientation(params.endpoint);
+
+ jsPlumb.extend(ctx, style);
+
+ /* canvas gradient */
+ if (style.gradient) {
+ // first figure out which direction to run the gradient in (it depends on the orientation of the anchors)
+ var y1 = orientation[1] == 1 ? self.h : orientation[1] === 0 ? self.h / 2 : 0;
+ var y2 = orientation[1] == -1 ? self.h : orientation[1] === 0 ? self.h / 2 : 0;
+ var x1 = orientation[0] == 1 ? self.w : orientation[0] === 0 ? self.w / 2 : 0;
+ var x2 = orientation[0] == -1 ? self.w : orientation[0] === 0 ? self.w / 2 : 0;
+ var g = ctx.createLinearGradient(x1,y1,x2,y2);
+ for (var i = 0; i < style.gradient.stops.length; i++)
+ g.addColorStop(style.gradient.stops[i][0], style.gradient.stops[i][1]);
+ ctx.fillStyle = g;
+ }
+
+ ctx.beginPath();
+ ctx.rect(0, 0, self.w, self.h);
+ ctx.closePath();
+ if (style.fillStyle || style.gradient) ctx.fill();
+ if (style.strokeStyle) ctx.stroke();
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.canvas.Rectangle, [ jsPlumb.Endpoints.Rectangle, CanvasEndpoint ]);
+
+ jsPlumb.Endpoints.canvas.Triangle = function(params) {
+
+ var self = this;
+ jsPlumb.Endpoints.Triangle.apply(this, arguments);
+ CanvasEndpoint.apply(this, arguments);
+
+ this._paint = function(style) {
+ var ctx = self.canvas.getContext('2d'),
+ offsetX = 0, offsetY = 0, angle = 0,
+ orientation = params.endpoint.anchor.getOrientation(params.endpoint);
+
+ if( orientation[0] == 1 ) {
+ offsetX = self.width;
+ offsetY = self.height;
+ angle = 180;
+ }
+ if( orientation[1] == -1 ) {
+ offsetX = self.width;
+ angle = 90;
+ }
+ if( orientation[1] == 1 ) {
+ offsetY = self.height;
+ angle = -90;
+ }
+
+ ctx.fillStyle = style.fillStyle;
+
+ ctx.translate(offsetX, offsetY);
+ ctx.rotate(angle * Math.PI/180);
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(self.width/2, self.height/2);
+ ctx.lineTo(0, self.height);
+ ctx.closePath();
+ if (style.fillStyle || style.gradient) ctx.fill();
+ if (style.strokeStyle) ctx.stroke();
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.canvas.Triangle, [ jsPlumb.Endpoints.Triangle, CanvasEndpoint ]);
+
+ /*
+ * Canvas Image Endpoint: uses the default version, which creates an <img> tag.
+ */
+ jsPlumb.Endpoints.canvas.Image = jsPlumb.Endpoints.Image;
+
+ /*
+ * Blank endpoint in all renderers is just the default Blank endpoint.
+ */
+ jsPlumb.Endpoints.canvas.Blank = jsPlumb.Endpoints.Blank;
+
+ /*
+ * Canvas Bezier Connector. Draws a Bezier curve onto a Canvas element.
+ *
+ jsPlumb.Connectors.canvas.Bezier = function() {
+ jsPlumb.Connectors.Bezier.apply(this, arguments);
+ CanvasConnector.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.canvas.Bezier, [ jsPlumb.Connectors.Bezier, CanvasConnector ]);
+
+ /*
+ * Canvas straight line Connector. Draws a straight line onto a Canvas element.
+ *
+ jsPlumb.Connectors.canvas.Straight = function() {
+ jsPlumb.Connectors.Straight.apply(this, arguments);
+ CanvasConnector.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.canvas.Straight, [ jsPlumb.Connectors.Straight, CanvasConnector ]);
+
+ jsPlumb.Connectors.canvas.Flowchart = function() {
+ jsPlumb.Connectors.Flowchart.apply(this, arguments);
+ CanvasConnector.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.canvas.Flowchart, [ jsPlumb.Connectors.Flowchart, CanvasConnector ]);
+
+ */
+// ********************************* END OF CANVAS RENDERERS *******************************************************************
+
+ jsPlumb.Overlays.canvas.Label = jsPlumb.Overlays.Label;
+ jsPlumb.Overlays.canvas.Custom = jsPlumb.Overlays.Custom;
+
+ /**
+ * a placeholder right now, really just exists to mirror the fact that there are SVG and VML versions of this.
+ */
+ var CanvasOverlay = function() {
+ jsPlumb.jsPlumbUIComponent.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(CanvasOverlay, jsPlumb.jsPlumbUIComponent);
+
+ var AbstractCanvasArrowOverlay = function(superclass, originalArgs) {
+ superclass.apply(this, originalArgs);
+ CanvasOverlay.apply(this, originalArgs);
+ this.paint = function(params, containerExtents) {
+ var ctx = params.component.ctx, d = params.d;
+
+ if (d) {
+ ctx.save();
+ ctx.lineWidth = params.lineWidth;
+ ctx.beginPath();
+ ctx.translate(params.component.translateX, params.component.translateY);
+ ctx.moveTo(d.hxy.x, d.hxy.y);
+ ctx.lineTo(d.tail[0].x, d.tail[0].y);
+ ctx.lineTo(d.cxy.x, d.cxy.y);
+ ctx.lineTo(d.tail[1].x, d.tail[1].y);
+ ctx.lineTo(d.hxy.x, d.hxy.y);
+ ctx.closePath();
+
+ if (params.strokeStyle) {
+ ctx.strokeStyle = params.strokeStyle;
+ ctx.stroke();
+ }
+ if (params.fillStyle) {
+ ctx.fillStyle = params.fillStyle;
+ ctx.fill();
+ }
+ ctx.restore();
+ }
+ };
+ };
+
+ jsPlumb.Overlays.canvas.Arrow = function() {
+ AbstractCanvasArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.canvas.Arrow, [ jsPlumb.Overlays.Arrow, CanvasOverlay ] );
+
+ jsPlumb.Overlays.canvas.PlainArrow = function() {
+ AbstractCanvasArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.canvas.PlainArrow, [ jsPlumb.Overlays.PlainArrow, CanvasOverlay ] );
+
+ jsPlumb.Overlays.canvas.Diamond = function() {
+ AbstractCanvasArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.canvas.Diamond, [ jsPlumb.Overlays.Diamond, CanvasOverlay ] );
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the SVG renderers.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+/**
+ * SVG support for jsPlumb.
+ *
+ * things to investigate:
+ *
+ * gradients: https://developer.mozilla.org/en/svg_in_html_introduction
+ * css:http://tutorials.jenkov.com/svg/svg-and-css.html
+ * text on a path: http://www.w3.org/TR/SVG/text.html#TextOnAPath
+ * pointer events: https://developer.mozilla.org/en/css/pointer-events
+ *
+ * IE9 hover jquery: http://forum.jquery.com/topic/1-6-2-broke-svg-hover-events
+ *
+ */
+;(function() {
+
+// ************************** SVG utility methods ********************************************
+
+ var svgAttributeMap = {
+ "joinstyle":"stroke-linejoin",
+ "stroke-linejoin":"stroke-linejoin",
+ "stroke-dashoffset":"stroke-dashoffset",
+ "stroke-linecap":"stroke-linecap"
+ },
+ STROKE_DASHARRAY = "stroke-dasharray",
+ DASHSTYLE = "dashstyle",
+ LINEAR_GRADIENT = "linearGradient",
+ RADIAL_GRADIENT = "radialGradient",
+ FILL = "fill",
+ STOP = "stop",
+ STROKE = "stroke",
+ STROKE_WIDTH = "stroke-width",
+ STYLE = "style",
+ NONE = "none",
+ JSPLUMB_GRADIENT = "jsplumb_gradient_",
+ LINE_WIDTH = "lineWidth",
+ ns = {
+ svg:"http://www.w3.org/2000/svg",
+ xhtml:"http://www.w3.org/1999/xhtml"
+ },
+ _attr = function(node, attributes) {
+ for (var i in attributes)
+ node.setAttribute(i, "" + attributes[i]);
+ },
+ _node = function(name, attributes) {
+ var n = document.createElementNS(ns.svg, name);
+ attributes = attributes || {};
+ attributes.version = "1.1";
+ attributes.xmlns = ns.xhtml;
+ _attr(n, attributes);
+ return n;
+ },
+ _pos = function(d) { return "position:absolute;left:" + d[0] + "px;top:" + d[1] + "px"; },
+ _clearGradient = function(parent) {
+ for (var i = 0; i < parent.childNodes.length; i++) {
+ if (parent.childNodes[i].tagName == LINEAR_GRADIENT || parent.childNodes[i].tagName == RADIAL_GRADIENT)
+ parent.removeChild(parent.childNodes[i]);
+ }
+ },
+ _updateGradient = function(parent, node, style, dimensions, uiComponent) {
+ var id = JSPLUMB_GRADIENT + uiComponent._jsPlumb.instance.idstamp();
+ // first clear out any existing gradient
+ _clearGradient(parent);
+ // this checks for an 'offset' property in the gradient, and in the absence of it, assumes
+ // we want a linear gradient. if it's there, we create a radial gradient.
+ // it is possible that a more explicit means of defining the gradient type would be
+ // better. relying on 'offset' means that we can never have a radial gradient that uses
+ // some default offset, for instance.
+ // issue 244 suggested the 'gradientUnits' attribute; without this, straight/flowchart connectors with gradients would
+ // not show gradients when the line was perfectly horizontal or vertical.
+ var g;
+ if (!style.gradient.offset) {
+ g = _node(LINEAR_GRADIENT, {id:id, gradientUnits:"userSpaceOnUse"});
+ }
+ else {
+ g = _node(RADIAL_GRADIENT, {
+ id:id
+ });
+ }
+
+ parent.appendChild(g);
+
+ // the svg radial gradient seems to treat stops in the reverse
+ // order to how canvas does it. so we want to keep all the maths the same, but
+ // iterate the actual style declarations in reverse order, if the x indexes are not in order.
+ for (var i = 0; i < style.gradient.stops.length; i++) {
+ var styleToUse = uiComponent.segment == 1 || uiComponent.segment == 2 ? i: style.gradient.stops.length - 1 - i,
+ stopColor = jsPlumbUtil.convertStyle(style.gradient.stops[styleToUse][1], true),
+ s = _node(STOP, {"offset":Math.floor(style.gradient.stops[i][0] * 100) + "%", "stop-color":stopColor});
+
+ g.appendChild(s);
+ }
+ var applyGradientTo = style.strokeStyle ? STROKE : FILL;
+ node.setAttribute(STYLE, applyGradientTo + ":url(#" + id + ")");
+ },
+ _applyStyles = function(parent, node, style, dimensions, uiComponent) {
+
+ if (style.gradient) {
+ _updateGradient(parent, node, style, dimensions, uiComponent);
+ }
+ else {
+ // make sure we clear any existing gradient
+ _clearGradient(parent);
+ node.setAttribute(STYLE, "");
+ }
+
+ node.setAttribute(FILL, style.fillStyle ? jsPlumbUtil.convertStyle(style.fillStyle, true) : NONE);
+ node.setAttribute(STROKE, style.strokeStyle ? jsPlumbUtil.convertStyle(style.strokeStyle, true) : NONE);
+ if (style.lineWidth) {
+ node.setAttribute(STROKE_WIDTH, style.lineWidth);
+ }
+
+ // in SVG there is a stroke-dasharray attribute we can set, and its syntax looks like
+ // the syntax in VML but is actually kind of nasty: values are given in the pixel
+ // coordinate space, whereas in VML they are multiples of the width of the stroked
+ // line, which makes a lot more sense. for that reason, jsPlumb is supporting both
+ // the native svg 'stroke-dasharray' attribute, and also the 'dashstyle' concept from
+ // VML, which will be the preferred method. the code below this converts a dashstyle
+ // attribute given in terms of stroke width into a pixel representation, by using the
+ // stroke's lineWidth.
+ if (style[DASHSTYLE] && style[LINE_WIDTH] && !style[STROKE_DASHARRAY]) {
+ var sep = style[DASHSTYLE].indexOf(",") == -1 ? " " : ",",
+ parts = style[DASHSTYLE].split(sep),
+ styleToUse = "";
+ parts.forEach(function(p) {
+ styleToUse += (Math.floor(p * style.lineWidth) + sep);
+ });
+ node.setAttribute(STROKE_DASHARRAY, styleToUse);
+ }
+ else if(style[STROKE_DASHARRAY]) {
+ node.setAttribute(STROKE_DASHARRAY, style[STROKE_DASHARRAY]);
+ }
+
+ // extra attributes such as join type, dash offset.
+ for (var i in svgAttributeMap) {
+ if (style[i]) {
+ node.setAttribute(svgAttributeMap[i], style[i]);
+ }
+ }
+ },
+ _decodeFont = function(f) {
+ var r = /([0-9].)(p[xt])\s(.*)/,
+ bits = f.match(r);
+
+ return {size:bits[1] + bits[2], font:bits[3]};
+ },
+ _classManip = function(el, add, clazz) {
+ var classesToAddOrRemove = clazz.split(" "),
+ className = el.className,
+ curClasses = className.baseVal.split(" ");
+
+ for (var i = 0; i < classesToAddOrRemove.length; i++) {
+ if (add) {
+ if (curClasses.indexOf(classesToAddOrRemove[i]) == -1)
+ curClasses.push(classesToAddOrRemove[i]);
+ }
+ else {
+ var idx = curClasses.indexOf(classesToAddOrRemove[i]);
+ if (idx != -1)
+ curClasses.splice(idx, 1);
+ }
+ }
+
+ el.className.baseVal = curClasses.join(" ");
+ },
+ _addClass = function(el, clazz) { _classManip(el, true, clazz); },
+ _removeClass = function(el, clazz) { _classManip(el, false, clazz); },
+ _appendAtIndex = function(svg, path, idx) {
+ if (svg.childNodes.length > idx) {
+ svg.insertBefore(path, svg.childNodes[idx]);
+ }
+ else svg.appendChild(path);
+ };
+
+ /**
+ utility methods for other objects to use.
+ */
+ jsPlumbUtil.svg = {
+ addClass:_addClass,
+ removeClass:_removeClass,
+ node:_node,
+ attr:_attr,
+ pos:_pos
+ };
+
+ // ************************** / SVG utility methods ********************************************
+
+ /*
+ * Base class for SVG components.
+ */
+ var SvgComponent = function(params) {
+ var pointerEventsSpec = params.pointerEventsSpec || "all", renderer = {};
+
+ jsPlumb.jsPlumbUIComponent.apply(this, params.originalArgs);
+ this.canvas = null;this.path = null;this.svg = null;
+
+ var clazz = params.cssClass + " " + (params.originalArgs[0].cssClass || ""),
+ svgParams = {
+ "style":"",
+ "width":0,
+ "height":0,
+ "pointer-events":pointerEventsSpec,
+ "position":"absolute"
+ };
+ this.svg = _node("svg", svgParams);
+ if (params.useDivWrapper) {
+ this.canvas = document.createElement("div");
+ this.canvas.style.position = "absolute";
+ jsPlumbUtil.sizeElement(this.canvas,0,0,1,1);
+ this.canvas.className = clazz;
+ }
+ else {
+ _attr(this.svg, { "class":clazz });
+ this.canvas = this.svg;
+ }
+
+ params._jsPlumb.appendElement(this.canvas, params.originalArgs[0].parent);
+ if (params.useDivWrapper) this.canvas.appendChild(this.svg);
+
+ // TODO this displayElement stuff is common between all components, across all
+ // renderers. would be best moved to jsPlumbUIComponent.
+ var displayElements = [ this.canvas ];
+ this.getDisplayElements = function() {
+ return displayElements;
+ };
+
+ this.appendDisplayElement = function(el) {
+ displayElements.push(el);
+ };
+
+ this.paint = function(style, anchor, extents) {
+ if (style != null) {
+
+ var xy = [ this.x, this.y ], wh = [ this.w, this.h ], p;
+ if (extents != null) {
+ if (extents.xmin < 0) xy[0] += extents.xmin;
+ if (extents.ymin < 0) xy[1] += extents.ymin;
+ wh[0] = extents.xmax + ((extents.xmin < 0) ? -extents.xmin : 0);
+ wh[1] = extents.ymax + ((extents.ymin < 0) ? -extents.ymin : 0);
+ }
+
+ if (params.useDivWrapper) {
+ jsPlumbUtil.sizeElement(this.canvas, xy[0], xy[1], wh[0], wh[1]);
+ xy[0] = 0; xy[1] = 0;
+ p = _pos([ 0, 0 ]);
+ }
+ else
+ p = _pos([ xy[0], xy[1] ]);
+
+ renderer.paint.apply(this, arguments);
+
+ _attr(this.svg, {
+ "style":p,
+ "width": wh[0],
+ "height": wh[1]
+ });
+ }
+ };
+
+ return {
+ renderer:renderer
+ };
+ };
+ jsPlumbUtil.extend(SvgComponent, jsPlumb.jsPlumbUIComponent, {
+ cleanup:function() {
+ jsPlumbUtil.removeElement(this.canvas);
+ this.svg = null;
+ this.canvas = null;
+ this.path = null;
+ }
+ });
+
+ /*
+ * Base class for SVG connectors.
+ */
+ var SvgConnector = jsPlumb.ConnectorRenderers.svg = function(params) {
+ var self = this,
+ _super = SvgComponent.apply(this, [ {
+ cssClass:params._jsPlumb.connectorClass,
+ originalArgs:arguments,
+ pointerEventsSpec:"none",
+ _jsPlumb:params._jsPlumb
+ } ]);
+
+ /*this.pointOnPath = function(location, absolute) {
+ if (!self.path) return [0,0];
+ var p = absolute ? location : location * self.path.getTotalLength();
+ return self.path.getPointAtLength(p);
+ };*/
+
+ _super.renderer.paint = function(style, anchor, extents) {
+
+ var segments = self.getSegments(), p = "", offset = [0,0];
+ if (extents.xmin < 0) offset[0] = -extents.xmin;
+ if (extents.ymin < 0) offset[1] = -extents.ymin;
+
+ // create path from segments.
+ for (var i = 0; i < segments.length; i++) {
+ p += jsPlumb.Segments.svg.SegmentRenderer.getPath(segments[i]);
+ p += " ";
+ }
+
+ var a = {
+ d:p,
+ transform:"translate(" + offset[0] + "," + offset[1] + ")",
+ "pointer-events":params["pointer-events"] || "visibleStroke"
+ },
+ outlineStyle = null,
+ d = [self.x,self.y,self.w,self.h];
+
+ // outline style. actually means drawing an svg object underneath the main one.
+ if (style.outlineColor) {
+ var outlineWidth = style.outlineWidth || 1,
+ outlineStrokeWidth = style.lineWidth + (2 * outlineWidth);
+ outlineStyle = jsPlumb.CurrentLibrary.extend({}, style);
+ outlineStyle.strokeStyle = jsPlumbUtil.convertStyle(style.outlineColor);
+ outlineStyle.lineWidth = outlineStrokeWidth;
+
+ if (self.bgPath == null) {
+ self.bgPath = _node("path", a);
+ _appendAtIndex(self.svg, self.bgPath, 0);
+ self.attachListeners(self.bgPath, self);
+ }
+ else {
+ _attr(self.bgPath, a);
+ }
+
+ _applyStyles(self.svg, self.bgPath, outlineStyle, d, self);
+ }
+
+ if (self.path == null) {
+ self.path = _node("path", a);
+ _appendAtIndex(self.svg, self.path, style.outlineColor ? 1 : 0);
+ self.attachListeners(self.path, self);
+ }
+ else {
+ _attr(self.path, a);
+ }
+
+ _applyStyles(self.svg, self.path, style, d, self);
+ };
+
+ this.reattachListeners = function() {
+ if (this.bgPath) this.reattachListenersForElement(this.bgPath, this);
+ if (this.path) this.reattachListenersForElement(this.path, this);
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.ConnectorRenderers.svg, SvgComponent);
+
+// ******************************* svg segment renderer *****************************************************
+
+ jsPlumb.Segments.svg = {
+ SegmentRenderer : {
+ getPath : function(segment) {
+ return ({
+ "Straight":function() {
+ var d = segment.getCoordinates();
+ return "M " + d.x1 + " " + d.y1 + " L " + d.x2 + " " + d.y2;
+ },
+ "Bezier":function() {
+ var d = segment.params;
+ return "M " + d.x1 + " " + d.y1 +
+ " C " + d.cp1x + " " + d.cp1y + " " + d.cp2x + " " + d.cp2y + " " + d.x2 + " " + d.y2;
+ },
+ "Arc":function() {
+ var d = segment.params,
+ laf = segment.sweep > Math.PI ? 1 : 0,
+ sf = segment.anticlockwise ? 0 : 1;
+
+ return "M" + segment.x1 + " " + segment.y1 + " A " + segment.radius + " " + d.r + " 0 " + laf + "," + sf + " " + segment.x2 + " " + segment.y2;
+ }
+ })[segment.type]();
+ }
+ }
+ };
+
+// ******************************* /svg segments *****************************************************
+
+ /*
+ * Base class for SVG endpoints.
+ */
+ var SvgEndpoint = window.SvgEndpoint = function(params) {
+ var _super = SvgComponent.apply(this, [ {
+ cssClass:params._jsPlumb.endpointClass,
+ originalArgs:arguments,
+ pointerEventsSpec:"all",
+ useDivWrapper:true,
+ _jsPlumb:params._jsPlumb
+ } ]);
+
+ _super.renderer.paint = function(style) {
+ var s = jsPlumb.extend({}, style);
+ if (s.outlineColor) {
+ s.strokeWidth = s.outlineWidth;
+ s.strokeStyle = jsPlumbUtil.convertStyle(s.outlineColor, true);
+ }
+
+ if (this.node == null) {
+ this.node = this.makeNode(s);
+ this.svg.appendChild(this.node);
+ this.attachListeners(this.node, this);
+ }
+ else if (this.updateNode != null) {
+ this.updateNode(this.node);
+ }
+ _applyStyles(this.svg, this.node, s, [ this.x, this.y, this.w, this.h ], this);
+ _pos(this.node, [ this.x, this.y ]);
+ }.bind(this);
+
+ };
+ jsPlumbUtil.extend(SvgEndpoint, SvgComponent, {
+ reattachListeners : function() {
+ if (this.node) this.reattachListenersForElement(this.node, this);
+ }
+ });
+
+ /*
+ * SVG Dot Endpoint
+ */
+ jsPlumb.Endpoints.svg.Dot = function() {
+ jsPlumb.Endpoints.Dot.apply(this, arguments);
+ SvgEndpoint.apply(this, arguments);
+ this.makeNode = function(style) {
+ return _node("circle", {
+ "cx" : this.w / 2,
+ "cy" : this.h / 2,
+ "r" : this.radius
+ });
+ };
+ this.updateNode = function(node) {
+ _attr(node, {
+ "cx":this.w / 2,
+ "cy":this.h / 2,
+ "r":this.radius
+ });
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.svg.Dot, [jsPlumb.Endpoints.Dot, SvgEndpoint]);
+
+ /*
+ * SVG Rectangle Endpoint
+ */
+ jsPlumb.Endpoints.svg.Rectangle = function() {
+ jsPlumb.Endpoints.Rectangle.apply(this, arguments);
+ SvgEndpoint.apply(this, arguments);
+ this.makeNode = function(style) {
+ return _node("rect", {
+ "width" : this.w,
+ "height" : this.h
+ });
+ };
+ this.updateNode = function(node) {
+ _attr(node, {
+ "width":this.w,
+ "height":this.h
+ });
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.svg.Rectangle, [jsPlumb.Endpoints.Rectangle, SvgEndpoint]);
+
+ /*
+ * SVG Image Endpoint is the default image endpoint.
+ */
+ jsPlumb.Endpoints.svg.Image = jsPlumb.Endpoints.Image;
+ /*
+ * Blank endpoint in svg renderer is the default Blank endpoint.
+ */
+ jsPlumb.Endpoints.svg.Blank = jsPlumb.Endpoints.Blank;
+ /*
+ * Label overlay in svg renderer is the default Label overlay.
+ */
+ jsPlumb.Overlays.svg.Label = jsPlumb.Overlays.Label;
+ /*
+ * Custom overlay in svg renderer is the default Custom overlay.
+ */
+ jsPlumb.Overlays.svg.Custom = jsPlumb.Overlays.Custom;
+
+ var AbstractSvgArrowOverlay = function(superclass, originalArgs) {
+ superclass.apply(this, originalArgs);
+ jsPlumb.jsPlumbUIComponent.apply(this, originalArgs);
+ this.isAppendedAtTopLevel = false;
+ var self = this;
+ this.path = null;
+ this.paint = function(params, containerExtents) {
+ // only draws on connections, not endpoints.
+ if (params.component.svg && containerExtents) {
+ if (this.path == null) {
+ this.path = _node("path", {
+ "pointer-events":"all"
+ });
+ params.component.svg.appendChild(this.path);
+
+ this.attachListeners(this.path, params.component);
+ this.attachListeners(this.path, this);
+ }
+ var clazz = originalArgs && (originalArgs.length == 1) ? (originalArgs[0].cssClass || "") : "",
+ offset = [0,0];
+
+ if (containerExtents.xmin < 0) offset[0] = -containerExtents.xmin;
+ if (containerExtents.ymin < 0) offset[1] = -containerExtents.ymin;
+
+ _attr(this.path, {
+ "d" : makePath(params.d),
+ "class" : clazz,
+ stroke : params.strokeStyle ? params.strokeStyle : null,
+ fill : params.fillStyle ? params.fillStyle : null,
+ transform : "translate(" + offset[0] + "," + offset[1] + ")"
+ });
+ }
+ };
+ var makePath = function(d) {
+ return "M" + d.hxy.x + "," + d.hxy.y +
+ " L" + d.tail[0].x + "," + d.tail[0].y +
+ " L" + d.cxy.x + "," + d.cxy.y +
+ " L" + d.tail[1].x + "," + d.tail[1].y +
+ " L" + d.hxy.x + "," + d.hxy.y;
+ };
+ this.reattachListeners = function() {
+ if (this.path) this.reattachListenersForElement(this.path, this);
+ };
+ };
+ jsPlumbUtil.extend(AbstractSvgArrowOverlay, jsPlumb.jsPlumbUIComponent, {
+ cleanup : function() {
+ if (this.path != null) jsPlumb.CurrentLibrary.removeElement(this.path);
+ }
+ });
+
+ jsPlumb.Overlays.svg.Arrow = function() {
+ AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.svg.Arrow, [ jsPlumb.Overlays.Arrow, AbstractSvgArrowOverlay ]);
+
+ jsPlumb.Overlays.svg.PlainArrow = function() {
+ AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.svg.PlainArrow, [ jsPlumb.Overlays.PlainArrow, AbstractSvgArrowOverlay ]);
+
+ jsPlumb.Overlays.svg.Diamond = function() {
+ AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.svg.Diamond, [ jsPlumb.Overlays.Diamond, AbstractSvgArrowOverlay ]);
+
+ // a test
+ jsPlumb.Overlays.svg.GuideLines = function() {
+ var path = null, self = this, p1_1, p1_2;
+ jsPlumb.Overlays.GuideLines.apply(this, arguments);
+ this.paint = function(params, containerExtents) {
+ if (path == null) {
+ path = _node("path");
+ params.connector.svg.appendChild(path);
+ self.attachListeners(path, params.connector);
+ self.attachListeners(path, self);
+
+ p1_1 = _node("path");
+ params.connector.svg.appendChild(p1_1);
+ self.attachListeners(p1_1, params.connector);
+ self.attachListeners(p1_1, self);
+
+ p1_2 = _node("path");
+ params.connector.svg.appendChild(p1_2);
+ self.attachListeners(p1_2, params.connector);
+ self.attachListeners(p1_2, self);
+ }
+
+ var offset =[0,0];
+ if (containerExtents.xmin < 0) offset[0] = -containerExtents.xmin;
+ if (containerExtents.ymin < 0) offset[1] = -containerExtents.ymin;
+
+ _attr(path, {
+ "d" : makePath(params.head, params.tail),
+ stroke : "red",
+ fill : null,
+ transform:"translate(" + offset[0] + "," + offset[1] + ")"
+ });
+
+ _attr(p1_1, {
+ "d" : makePath(params.tailLine[0], params.tailLine[1]),
+ stroke : "blue",
+ fill : null,
+ transform:"translate(" + offset[0] + "," + offset[1] + ")"
+ });
+
+ _attr(p1_2, {
+ "d" : makePath(params.headLine[0], params.headLine[1]),
+ stroke : "green",
+ fill : null,
+ transform:"translate(" + offset[0] + "," + offset[1] + ")"
+ });
+ };
+
+ var makePath = function(d1, d2) {
+ return "M " + d1.x + "," + d1.y +
+ " L" + d2.x + "," + d2.y;
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.svg.GuideLines, jsPlumb.Overlays.GuideLines);
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the VML renderers.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ // http://ajaxian.com/archives/the-vml-changes-in-ie-8
+ // http://www.nczonline.net/blog/2010/01/19/internet-explorer-8-document-and-b…
+ // http://www.louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-…
+
+ var vmlAttributeMap = {
+ "stroke-linejoin":"joinstyle",
+ "joinstyle":"joinstyle",
+ "endcap":"endcap",
+ "miterlimit":"miterlimit"
+ },
+ jsPlumbStylesheet = null;
+
+ if (document.createStyleSheet && document.namespaces) {
+
+ var ruleClasses = [
+ ".jsplumb_vml", "jsplumb\\:textbox", "jsplumb\\:oval", "jsplumb\\:rect",
+ "jsplumb\\:stroke", "jsplumb\\:shape", "jsplumb\\:group"
+ ],
+ rule = "behavior:url(#default#VML);position:absolute;";
+
+ jsPlumbStylesheet = document.createStyleSheet();
+
+ for (var i = 0; i < ruleClasses.length; i++)
+ jsPlumbStylesheet.addRule(ruleClasses[i], rule);
+
+ // in this page it is also mentioned that IE requires the extra arg to the namespace
+ // http://www.louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-…
+ // but someone commented saying they didn't need it, and it seems jsPlumb doesnt need it either.
+ // var iev = document.documentMode;
+ //if (!iev || iev < 8)
+ document.namespaces.add("jsplumb", "urn:schemas-microsoft-com:vml");
+ //else
+ // document.namespaces.add("jsplumb", "urn:schemas-microsoft-com:vml", "#default#VML");
+ }
+
+ jsPlumb.vml = {};
+
+ var scale = 1000,
+
+ _groupMap = {},
+ _getGroup = function(container, connectorClass) {
+ var id = jsPlumb.getId(container),
+ g = _groupMap[id];
+ if(!g) {
+ g = _node("group", [0,0,scale, scale], {"class":connectorClass});
+ //g.style.position=absolute;
+ //g["coordsize"] = "1000,1000";
+ g.style.backgroundColor="red";
+ _groupMap[id] = g;
+ //jsPlumb.appendElement(g, container); // todo if this gets reinstated, remember to use the current jsplumb instance.
+ //jsPlumb.CurrentLibrary.getDOMElement(container).appendChild(g);
+ //document.body.appendChild(g);
+ }
+ return g;
+ },
+ _atts = function(o, atts) {
+ for (var i in atts) {
+ // IE8 fix: setattribute does not work after an element has been added to the dom!
+ // http://www.louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-…
+ //o.setAttribute(i, atts[i]);
+
+ /*There is an additional problem when accessing VML elements by using get/setAttribute. The simple solution is following:
+
+ if (document.documentMode==8) {
+ ele.opacity=1;
+ } else {
+ ele.setAttribute(‘opacity’,1);
+ }
+ */
+
+ o[i] = atts[i];
+ }
+ },
+ _node = function(name, d, atts, parent, _jsPlumb, deferToJsPlumbContainer) {
+ atts = atts || {};
+ var o = document.createElement("jsplumb:" + name);
+ if (deferToJsPlumbContainer)
+ _jsPlumb.appendElement(o, parent);
+ else
+ jsPlumb.CurrentLibrary.appendElement(o, parent);
+ o.className = (atts["class"] ? atts["class"] + " " : "") + "jsplumb_vml";
+ _pos(o, d);
+ _atts(o, atts);
+ return o;
+ },
+ _pos = function(o,d, zIndex) {
+ o.style.left = d[0] + "px";
+ o.style.top = d[1] + "px";
+ o.style.width= d[2] + "px";
+ o.style.height= d[3] + "px";
+ o.style.position = "absolute";
+ if (zIndex)
+ o.style.zIndex = zIndex;
+ },
+ _conv = jsPlumb.vml.convertValue = function(v) {
+ return Math.floor(v * scale);
+ },
+ // tests if the given style is "transparent" and then sets the appropriate opacity node to 0 if so,
+ // or 1 if not. TODO in the future, support variable opacity.
+ _maybeSetOpacity = function(styleToWrite, styleToCheck, type, component) {
+ if ("transparent" === styleToCheck)
+ component.setOpacity(type, "0.0");
+ else
+ component.setOpacity(type, "1.0");
+ },
+ _applyStyles = function(node, style, component, _jsPlumb) {
+ var styleToWrite = {};
+ if (style.strokeStyle) {
+ styleToWrite.stroked = "true";
+ var strokeColor = jsPlumbUtil.convertStyle(style.strokeStyle, true);
+ styleToWrite.strokecolor = strokeColor;
+ _maybeSetOpacity(styleToWrite, strokeColor, "stroke", component);
+ styleToWrite.strokeweight = style.lineWidth + "px";
+ }
+ else styleToWrite.stroked = "false";
+
+ if (style.fillStyle) {
+ styleToWrite.filled = "true";
+ var fillColor = jsPlumbUtil.convertStyle(style.fillStyle, true);
+ styleToWrite.fillcolor = fillColor;
+ _maybeSetOpacity(styleToWrite, fillColor, "fill", component);
+ }
+ else styleToWrite.filled = "false";
+
+ if(style.dashstyle) {
+ if (component.strokeNode == null) {
+ component.strokeNode = _node("stroke", [0,0,0,0], { dashstyle:style.dashstyle }, node, _jsPlumb);
+ }
+ else
+ component.strokeNode.dashstyle = style.dashstyle;
+ }
+ else if (style["stroke-dasharray"] && style.lineWidth) {
+ var sep = style["stroke-dasharray"].indexOf(",") == -1 ? " " : ",",
+ parts = style["stroke-dasharray"].split(sep),
+ styleToUse = "";
+ for(var i = 0; i < parts.length; i++) {
+ styleToUse += (Math.floor(parts[i] / style.lineWidth) + sep);
+ }
+ if (component.strokeNode == null) {
+ component.strokeNode = _node("stroke", [0,0,0,0], { dashstyle:styleToUse }, node, _jsPlumb);
+ }
+ else
+ component.strokeNode.dashstyle = styleToUse;
+ }
+
+ _atts(node, styleToWrite);
+ },
+ /*
+ * Base class for Vml endpoints and connectors. Extends jsPlumbUIComponent.
+ */
+ VmlComponent = function() {
+ var self = this, renderer = {};
+ jsPlumb.jsPlumbUIComponent.apply(this, arguments);
+
+ this.opacityNodes = {
+ "stroke":null,
+ "fill":null
+ };
+ this.initOpacityNodes = function(vml) {
+ self.opacityNodes.stroke = _node("stroke", [0,0,1,1], {opacity:"0.0"}, vml, self._jsPlumb.instance);
+ self.opacityNodes.fill = _node("fill", [0,0,1,1], {opacity:"0.0"}, vml, self._jsPlumb.instance);
+ };
+ this.setOpacity = function(type, value) {
+ var node = self.opacityNodes[type];
+ if (node) node.opacity = "" + value;
+ };
+ var displayElements = [ ];
+ this.getDisplayElements = function() {
+ return displayElements;
+ };
+
+ this.appendDisplayElement = function(el, doNotAppendToCanvas) {
+ if (!doNotAppendToCanvas) self.canvas.parentNode.appendChild(el);
+ displayElements.push(el);
+ };
+ };
+ jsPlumbUtil.extend(VmlComponent, jsPlumb.jsPlumbUIComponent, {
+ cleanup:function() {
+ if (this.bgCanvas) jsPlumbUtil.removeElement(this.bgCanvas);
+ jsPlumbUtil.removeElement(this.canvas);
+ }
+ });
+
+ /*
+ * Base class for Vml connectors. extends VmlComponent.
+ */
+ var VmlConnector = jsPlumb.ConnectorRenderers.vml = function(params) {
+ this.strokeNode = null;
+ this.canvas = null;
+ VmlComponent.apply(this, arguments);
+ var clazz = this._jsPlumb.instance.connectorClass + (params.cssClass ? (" " + params.cssClass) : "");
+ this.paint = function(style) {
+ if (style !== null) {
+
+ // we need to be at least 1 pixel in each direction, because otherwise coordsize gets set to
+ // 0 and overlays cannot paint.
+ this.w = Math.max(this.w, 1);
+ this.h = Math.max(this.h, 1);
+
+ var segments = this.getSegments(), p = { "path":"" },
+ d = [this.x, this.y, this.w, this.h];
+
+ // create path from segments.
+ for (var i = 0; i < segments.length; i++) {
+ p.path += jsPlumb.Segments.vml.SegmentRenderer.getPath(segments[i]);
+ p.path += " ";
+ }
+
+ //*
+ if (style.outlineColor) {
+ var outlineWidth = style.outlineWidth || 1,
+ outlineStrokeWidth = style.lineWidth + (2 * outlineWidth),
+ outlineStyle = {
+ strokeStyle : jsPlumbUtil.convertStyle(style.outlineColor),
+ lineWidth : outlineStrokeWidth
+ };
+ for (var aa in vmlAttributeMap) outlineStyle[aa] = style[aa];
+
+ if (this.bgCanvas == null) {
+ p["class"] = clazz;
+ p.coordsize = (d[2] * scale) + "," + (d[3] * scale);
+ this.bgCanvas = _node("shape", d, p, params.parent, this._jsPlumb.instance, true);
+ _pos(this.bgCanvas, d);
+ this.appendDisplayElement(this.bgCanvas, true);
+ this.attachListeners(this.bgCanvas, this);
+ this.initOpacityNodes(this.bgCanvas, ["stroke"]);
+ }
+ else {
+ p.coordsize = (d[2] * scale) + "," + (d[3] * scale);
+ _pos(this.bgCanvas, d);
+ _atts(this.bgCanvas, p);
+ }
+
+ _applyStyles(this.bgCanvas, outlineStyle, this);
+ }
+ //*/
+
+ if (this.canvas == null) {
+ p["class"] = clazz;
+ p.coordsize = (d[2] * scale) + "," + (d[3] * scale);
+ this.canvas = _node("shape", d, p, params.parent, this._jsPlumb.instance, true);
+ //var group = _getGroup(params.parent); // test of append everything to a group
+ //group.appendChild(self.canvas); // sort of works but not exactly;
+ //params["_jsPlumb"].appendElement(self.canvas, params.parent); //before introduction of groups
+
+ this.appendDisplayElement(this.canvas, true);
+ this.attachListeners(this.canvas, this);
+ this.initOpacityNodes(this.canvas, ["stroke"]);
+ }
+ else {
+ p.coordsize = (d[2] * scale) + "," + (d[3] * scale);
+ _pos(this.canvas, d);
+ _atts(this.canvas, p);
+ }
+
+ _applyStyles(this.canvas, style, this, this._jsPlumb.instance);
+ }
+ };
+
+ };
+ jsPlumbUtil.extend(VmlConnector, VmlComponent, {
+ reattachListeners : function() {
+ if (this.canvas) this.reattachListenersForElement(this.canvas, this);
+ }
+ });
+
+ /*
+ *
+ * Base class for Vml Endpoints. extends VmlComponent.
+ *
+ */
+ var VmlEndpoint = window.VmlEndpoint = function(params) {
+ VmlComponent.apply(this, arguments);
+ this._jsPlumb.vml = null;//, opacityStrokeNode = null, opacityFillNode = null;
+ this.canvas = document.createElement("div");
+ this.canvas.style.position = "absolute";
+ this._jsPlumb.clazz = this._jsPlumb.instance.endpointClass + (params.cssClass ? (" " + params.cssClass) : "");
+
+ // TODO vml endpoint adds class to VML at constructor time. but the addClass method adds VML
+ // to the enclosing DIV. what to do? seems like it would be better to just target the div.
+ // HOWEVER...vml connection has no containing div. why not? it feels like it should.
+
+ //var group = _getGroup(params.parent);
+ //group.appendChild(self.canvas);
+ params._jsPlumb.appendElement(this.canvas, params.parent);
+
+ this.paint = function(style, anchor) {
+ var p = { }, vml = this._jsPlumb.vml;
+
+ jsPlumbUtil.sizeElement(this.canvas, this.x, this.y, this.w, this.h);
+ if (this._jsPlumb.vml == null) {
+ p["class"] = this._jsPlumb.clazz;
+ vml = this._jsPlumb.vml = this.getVml([0,0, this.w, this.h], p, anchor, this.canvas, this._jsPlumb.instance);
+ this.attachListeners(vml, this);
+
+ this.appendDisplayElement(vml, true);
+ this.appendDisplayElement(this.canvas, true);
+
+ this.initOpacityNodes(vml, ["fill"]);
+ }
+ else {
+ _pos(vml, [0,0, this.w, this.h]);
+ _atts(vml, p);
+ }
+
+ _applyStyles(vml, style, this);
+ };
+ };
+ jsPlumbUtil.extend(VmlEndpoint, VmlComponent, {
+ reattachListeners : function() {
+ if (this._jsPlumb.vml) this.reattachListenersForElement(this._jsPlumb.vml, this);
+ }
+ });
+
+// ******************************* vml segments *****************************************************
+
+ jsPlumb.Segments.vml = {
+ SegmentRenderer : {
+ getPath : function(segment) {
+ return ({
+ "Straight":function(segment) {
+ var d = segment.params;
+ return "m" + _conv(d.x1) + "," + _conv(d.y1) + " l" + _conv(d.x2) + "," + _conv(d.y2) + " e";
+ },
+ "Bezier":function(segment) {
+ var d = segment.params;
+ return "m" + _conv(d.x1) + "," + _conv(d.y1) +
+ " c" + _conv(d.cp1x) + "," + _conv(d.cp1y) + "," + _conv(d.cp2x) + "," + _conv(d.cp2y) + "," + _conv(d.x2) + "," + _conv(d.y2) + " e";
+ },
+ "Arc":function(segment) {
+ var d = segment.params,
+ xmin = Math.min(d.x1, d.x2),
+ xmax = Math.max(d.x1, d.x2),
+ ymin = Math.min(d.y1, d.y2),
+ ymax = Math.max(d.y1, d.y2),
+ sf = segment.anticlockwise ? 1 : 0,
+ pathType = (segment.anticlockwise ? "at " : "wa "),
+ makePosString = function() {
+ var xy = [
+ null,
+ [ function() { return [xmin, ymin ];}, function() { return [xmin - d.r, ymin - d.r ];}],
+ [ function() { return [xmin - d.r, ymin ];}, function() { return [xmin, ymin - d.r ];}],
+ [ function() { return [xmin - d.r, ymin - d.r ];}, function() { return [xmin, ymin ];}],
+ [ function() { return [xmin, ymin - d.r ];}, function() { return [xmin - d.r, ymin ];}]
+ ][segment.segment][sf]();
+
+ return _conv(xy[0]) + "," + _conv(xy[1]) + "," + _conv(xy[0] + (2*d.r)) + "," + _conv(xy[1] + (2*d.r));
+ };
+
+
+ return pathType + makePosString() + "," + _conv(d.x1) + "," + _conv(d.y1) + "," + _conv(d.x2) + "," + _conv(d.y2) + " e";
+ }
+
+ })[segment.type](segment);
+ }
+ }
+ };
+
+// ******************************* /vml segments *****************************************************
+
+// ******************************* vml endpoints *****************************************************
+
+ jsPlumb.Endpoints.vml.Dot = function() {
+ jsPlumb.Endpoints.Dot.apply(this, arguments);
+ VmlEndpoint.apply(this, arguments);
+ this.getVml = function(d, atts, anchor, parent, _jsPlumb) { return _node("oval", d, atts, parent, _jsPlumb); };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.vml.Dot, VmlEndpoint);
+
+ jsPlumb.Endpoints.vml.Rectangle = function() {
+ jsPlumb.Endpoints.Rectangle.apply(this, arguments);
+ VmlEndpoint.apply(this, arguments);
+ this.getVml = function(d, atts, anchor, parent, _jsPlumb) { return _node("rect", d, atts, parent, _jsPlumb); };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.vml.Rectangle, VmlEndpoint);
+
+ /*
+ * VML Image Endpoint is the same as the default image endpoint.
+ */
+ jsPlumb.Endpoints.vml.Image = jsPlumb.Endpoints.Image;
+
+ /**
+ * placeholder for Blank endpoint in vml renderer.
+ */
+ jsPlumb.Endpoints.vml.Blank = jsPlumb.Endpoints.Blank;
+
+// ******************************* /vml endpoints *****************************************************
+
+// ******************************* vml overlays *****************************************************
+
+ /**
+ * VML Label renderer. uses the default label renderer (which adds an element to the DOM)
+ */
+ jsPlumb.Overlays.vml.Label = jsPlumb.Overlays.Label;
+
+ /**
+ * VML Custom renderer. uses the default Custom renderer (which adds an element to the DOM)
+ */
+ jsPlumb.Overlays.vml.Custom = jsPlumb.Overlays.Custom;
+
+ /**
+ * Abstract VML arrow superclass
+ */
+ var AbstractVmlArrowOverlay = function(superclass, originalArgs) {
+ superclass.apply(this, originalArgs);
+ VmlComponent.apply(this, originalArgs);
+ var self = this, path = null;
+ self.canvas = null;
+ self.isAppendedAtTopLevel = true;
+ var getPath = function(d) {
+ return "m " + _conv(d.hxy.x) + "," + _conv(d.hxy.y) +
+ " l " + _conv(d.tail[0].x) + "," + _conv(d.tail[0].y) +
+ " " + _conv(d.cxy.x) + "," + _conv(d.cxy.y) +
+ " " + _conv(d.tail[1].x) + "," + _conv(d.tail[1].y) +
+ " x e";
+ };
+ this.paint = function(params, containerExtents) {
+ var p = {}, d = params.d, connector = params.component;
+ if (params.strokeStyle) {
+ p.stroked = "true";
+ p.strokecolor = jsPlumbUtil.convertStyle(params.strokeStyle, true);
+ }
+ if (params.lineWidth) p.strokeweight = params.lineWidth + "px";
+ if (params.fillStyle) {
+ p.filled = "true";
+ p.fillcolor = params.fillStyle;
+ }
+
+ var xmin = Math.min(d.hxy.x, d.tail[0].x, d.tail[1].x, d.cxy.x),
+ ymin = Math.min(d.hxy.y, d.tail[0].y, d.tail[1].y, d.cxy.y),
+ xmax = Math.max(d.hxy.x, d.tail[0].x, d.tail[1].x, d.cxy.x),
+ ymax = Math.max(d.hxy.y, d.tail[0].y, d.tail[1].y, d.cxy.y),
+ w = Math.abs(xmax - xmin),
+ h = Math.abs(ymax - ymin),
+ dim = [xmin, ymin, w, h];
+
+ // for VML, we create overlays using shapes that have the same dimensions and
+ // coordsize as their connector - overlays calculate themselves relative to the
+ // connector (it's how it's been done since the original canvas implementation, because
+ // for canvas that makes sense).
+ p.path = getPath(d);
+ p.coordsize = (connector.w * scale) + "," + (connector.h * scale);
+
+ dim[0] = connector.x;
+ dim[1] = connector.y;
+ dim[2] = connector.w;
+ dim[3] = connector.h;
+
+ if (self.canvas == null) {
+ var overlayClass = connector._jsPlumb.overlayClass || "";
+ var clazz = originalArgs && (originalArgs.length == 1) ? (originalArgs[0].cssClass || "") : "";
+ p["class"] = clazz + " " + overlayClass;
+ self.canvas = _node("shape", dim, p, connector.canvas.parentNode, connector._jsPlumb.instance, true);
+ connector.appendDisplayElement(self.canvas, true);
+ self.attachListeners(self.canvas, connector);
+ self.attachListeners(self.canvas, self);
+ }
+ else {
+ _pos(self.canvas, dim);
+ _atts(self.canvas, p);
+ }
+ };
+
+ this.reattachListeners = function() {
+ if (self.canvas) self.reattachListenersForElement(self.canvas, self);
+ };
+
+ this.cleanup = function() {
+ if (self.canvas != null) jsPlumb.CurrentLibrary.removeElement(self.canvas);
+ };
+ };
+ jsPlumbUtil.extend(AbstractVmlArrowOverlay, VmlComponent);
+
+ jsPlumb.Overlays.vml.Arrow = function() {
+ AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.vml.Arrow, [ jsPlumb.Overlays.Arrow, AbstractVmlArrowOverlay ]);
+
+ jsPlumb.Overlays.vml.PlainArrow = function() {
+ AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.vml.PlainArrow, [ jsPlumb.Overlays.PlainArrow, AbstractVmlArrowOverlay ]);
+
+ jsPlumb.Overlays.vml.Diamond = function() {
+ AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.vml.Diamond, [ jsPlumb.Overlays.Diamond, AbstractVmlArrowOverlay ]);
+
+// ******************************* /vml overlays *****************************************************
+
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the jQuery adapter.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+/*
+ * the library specific functions, such as find offset, get id, get attribute, extend etc.
+ * the full list is:
+ *
+ * addClass adds a class to the given element
+ * animate calls the underlying library's animate functionality
+ * appendElement appends a child element to a parent element.
+ * bind binds some event to an element
+ * dragEvents a dictionary of event names
+ * extend extend some js object with another. probably not overly necessary; jsPlumb could just do this internally.
+ * getDragObject gets the object that is being dragged, by extracting it from the arguments passed to a drag callback
+ * getDragScope gets the drag scope for a given element.
+ * getDropScope gets the drop scope for a given element.
+ * getElementObject turns an id or dom element into an element object of the underlying library's type.
+ * getOffset gets an element's offset
+ * getOriginalEvent gets the original browser event from some wrapper event
+ * getPageXY gets the page event's xy location.
+ * getParent gets the parent of some element.
+ * getScrollLeft gets an element's scroll left. TODO: is this actually used? will it be?
+ * getScrollTop gets an element's scroll top. TODO: is this actually used? will it be?
+ * getSize gets an element's size.
+ * getUIPosition gets the position of some element that is currently being dragged, by extracting it from the arguments passed to a drag callback.
+ * hasClass returns whether or not the given element has the given class.
+ * initDraggable initializes an element to be draggable
+ * initDroppable initializes an element to be droppable
+ * isDragSupported returns whether or not drag is supported for some element.
+ * isDropSupported returns whether or not drop is supported for some element.
+ * removeClass removes a class from a given element.
+ * removeElement removes some element completely from the DOM.
+ * setDragFilter sets a filter for some element that indicates areas of the element that should not respond to dragging.
+ * setDraggable sets whether or not some element should be draggable.
+ * setDragScope sets the drag scope for a given element.
+ * setOffset sets the offset of some element.
+ * trigger triggers some event on an element.
+ * unbind unbinds some listener from some element.
+ */
+(function($) {
+
+ //var getBoundingClientRectSupported = "getBoundingClientRect" in document.documentElement;
+
+ var _getElementObject = function(el) {
+ return typeof(el) == "string" ? $("#" + el) : $(el);
+ };
+
+ jsPlumb.CurrentLibrary = {
+
+ /**
+ * adds the given class to the element object.
+ */
+ addClass : function(el, clazz) {
+ el = _getElementObject(el);
+ try {
+ if (el[0].className.constructor == SVGAnimatedString) {
+ jsPlumbUtil.svg.addClass(el[0], clazz);
+ }
+ }
+ catch (e) {
+ // SVGAnimatedString not supported; no problem.
+ }
+ try {
+ el.addClass(clazz);
+ }
+ catch (e) {
+ // you probably have jQuery 1.9 and Firefox.
+ }
+ },
+
+ /**
+ * animates the given element.
+ */
+ animate : function(el, properties, options) {
+ el.animate(properties, options);
+ },
+
+ /**
+ * appends the given child to the given parent.
+
+TODO: REMOVE!
+
+ */
+ appendElement : function(child, parent) {
+ _getElementObject(parent).append(child);
+ },
+
+ /**
+ * executes an ajax call.
+ */
+ ajax : function(params) {
+ params = params || {};
+ params.type = params.type || "get";
+ $.ajax(params);
+ },
+
+ /**
+ * event binding wrapper. it just so happens that jQuery uses 'bind' also. yui3, for example,
+ * uses 'on'.
+ */
+ bind : function(el, event, callback) {
+ el = _getElementObject(el);
+ el.bind(event, callback);
+ },
+
+ destroyDraggable : function(el) {
+ if ($(el).data("draggable"))
+ $(el).draggable("destroy");
+ },
+
+ destroyDroppable : function(el) {
+ if ($(el).data("droppable"))
+ $(el).droppable("destroy");
+ },
+
+ /**
+ * mapping of drag events for jQuery
+ */
+ dragEvents : {
+ 'start':'start', 'stop':'stop', 'drag':'drag', 'step':'step',
+ 'over':'over', 'out':'out', 'drop':'drop', 'complete':'complete'
+ },
+
+ /**
+ * wrapper around the library's 'extend' functionality (which it hopefully has.
+ * otherwise you'll have to do it yourself). perhaps jsPlumb could do this for you
+ * instead. it's not like its hard.
+ */
+ extend : function(o1, o2) {
+ return $.extend(o1, o2);
+ },
+
+ getClientXY : function(eventObject) {
+ return [eventObject.clientX, eventObject.clientY];
+ },
+
+ /**
+ * takes the args passed to an event function and returns you an object representing that which is being dragged.
+ */
+ getDragObject : function(eventArgs) {
+ return eventArgs[1].draggable || eventArgs[1].helper;
+ },
+
+ getDragScope : function(el) {
+ return $(el).draggable("option", "scope");
+ },
+
+ getDropEvent : function(args) {
+ return args[0];
+ },
+
+ getDropScope : function(el) {
+ return $(el).droppable("option", "scope");
+ },
+
+ /**
+ * gets a DOM element from the given input, which might be a string (in which case we just do document.getElementById),
+ * a selector (in which case we return el[0]), or a DOM element already (we assume this if it's not either of the other
+ * two cases). this is the opposite of getElementObject below.
+ */
+ getDOMElement : function(el) {
+ if (el == null) return null;
+ if (typeof(el) == "string") return document.getElementById(el);
+ else if (el.context || el.length != null) return el[0];
+ else return el;
+ },
+
+ /**
+ * gets an "element object" from the given input. this means an object that is used by the
+ * underlying library on which jsPlumb is running. 'el' may already be one of these objects,
+ * in which case it is returned as-is. otherwise, 'el' is a String, the library's lookup
+ * function is used to find the element, using the given String as the element's id.
+ *
+ */
+ getElementObject : _getElementObject,
+
+ /**
+ * gets the offset for the element object. this should return a js object like this:
+ *
+ * { left:xxx, top: xxx }
+ */
+ getOffset : function(el) {
+ return el.offset();
+ },
+
+ getOriginalEvent : function(e) {
+ return e.originalEvent;
+ },
+
+ getPageXY : function(eventObject) {
+ return [eventObject.pageX, eventObject.pageY];
+ },
+
+ getParent : function(el) {
+ return _getElementObject(el).parent();
+ },
+
+ getScrollLeft : function(el) {
+ return el.scrollLeft();
+ },
+
+ getScrollTop : function(el) {
+ return el.scrollTop();
+ },
+
+ getSelector : function(context, spec) {
+ if (arguments.length == 2)
+ return _getElementObject(context).find(spec);
+ else
+ return $(context);
+ },
+
+ /**
+ * gets the size for the element object, in an array : [ width, height ].
+ */
+ getSize : function(el) {
+ el = $(el);
+ return [el.outerWidth(), el.outerHeight()];
+ },
+
+ getTagName : function(el) {
+ var e = _getElementObject(el);
+ return e.length > 0 ? e[0].tagName : null;
+ },
+
+ /**
+ * takes the args passed to an event function and returns you an object that gives the
+ * position of the object being moved, as a js object with the same params as the result of
+ * getOffset, ie: { left: xxx, top: xxx }.
+ *
+ * different libraries have different signatures for their event callbacks.
+ * see getDragObject as well
+ */
+ getUIPosition : function(eventArgs, zoom) {
+
+ zoom = zoom || 1;
+ // this code is a workaround for the case that the element being dragged has a margin set on it. jquery UI passes
+ // in the wrong offset if the element has a margin (it doesn't take the margin into account). the getBoundingClientRect
+ // method, which is in pretty much all browsers now, reports the right numbers. but it introduces a noticeable lag, which
+ // i don't like.
+
+ /*if ( getBoundingClientRectSupported ) {
+ var r = eventArgs[1].helper[0].getBoundingClientRect();
+ return { left : r.left, top: r.top };
+ } else {*/
+ if (eventArgs.length == 1) {
+ ret = { left: eventArgs[0].pageX, top:eventArgs[0].pageY };
+ }
+ else {
+ var ui = eventArgs[1],
+ _offset = ui.offset;
+
+ ret = _offset || ui.absolutePosition;
+
+ // adjust ui position to account for zoom, because jquery ui does not do this.
+ ui.position.left /= zoom;
+ ui.position.top /= zoom;
+ }
+ return { left:ret.left / zoom, top: ret.top / zoom };
+ },
+
+ hasClass : function(el, clazz) {
+ return el.hasClass(clazz);
+ },
+
+ /**
+ * initialises the given element to be draggable.
+ */
+ initDraggable : function(el, options, isPlumbedComponent, _jsPlumb) {
+ options = options || {};
+ el = $(el);
+
+/*
+ // css3 transforms
+ // http://gungfoo.wordpress.com/2013/02/15/jquery-ui-resizabledraggable-with-t…
+ options.start = _jsPlumb.wrap(options["start"], function(e, ui) {
+ // TODO why is this 0?
+ ui.position.left = 0;
+ ui.position.top = 0;
+ });
+
+ options.drag = _jsPlumb.wrap(options["drag"], function(e, ui) {
+
+ console.log("original", ui.originalPosition.left, ui.originalPosition.top);
+ console.log("current", ui.position.left, ui.position.top);
+
+ //var changeLeft = ui.position.left - ui.originalPosition.left; // find change in left
+ //var newLeft = ui.originalPosition.left + (changeLeft * _jsPlumb.getZoom()); // adjust new left by our zoomScale
+
+ //var changeTop = ui.position.top - ui.originalPosition.top; // find change in top
+ //var newTop = ui.originalPosition.top + (changeTop * _jsPlumb.getZoom()); // adjust new top by our zoomScale
+
+ //ui.position.left = newLeft;
+ //ui.position.top = newTop;
+
+ ui.position.left *= _jsPlumb.getZoom();
+ ui.position.top *= _jsPlumb.getZoom();
+
+ });
+*/
+
+ options["start"] = jsPlumbUtil.wrap(options["start"], function() {
+ $("body").addClass(_jsPlumb.dragSelectClass);
+ }, false);
+
+ options["stop"] = jsPlumbUtil.wrap(options["stop"], function() {
+ $("body").removeClass(_jsPlumb.dragSelectClass);
+ });
+
+ // remove helper directive if present and no override
+ if (!options.doNotRemoveHelper)
+ options.helper = null;
+ if (isPlumbedComponent)
+ options.scope = options.scope || jsPlumb.Defaults.Scope;
+ el.draggable(options);
+ },
+
+ /**
+ * initialises the given element to be droppable.
+ */
+ initDroppable : function(el, options) {
+ options.scope = options.scope || jsPlumb.Defaults.Scope;
+ $(el).droppable(options);
+ },
+
+ isAlreadyDraggable : function(el) {
+ return $(el).hasClass("ui-draggable");
+ },
+
+ /**
+ * returns whether or not drag is supported (by the library, not whether or not it is disabled) for the given element.
+ */
+ isDragSupported : function(el, options) {
+ return $(el).draggable;
+ },
+
+ /**
+ * returns whether or not drop is supported (by the library, not whether or not it is disabled) for the given element.
+ */
+ isDropSupported : function(el, options) {
+ return $(el).droppable;
+ },
+
+ /**
+ * removes the given class from the element object.
+ */
+ removeClass : function(el, clazz) {
+ el = _getElementObject(el);
+ try {
+ if (el[0].className.constructor == SVGAnimatedString) {
+ jsPlumbUtil.svg.removeClass(el[0], clazz);
+ return;
+ }
+ }
+ catch (e) {
+ // SVGAnimatedString not supported; no problem.
+ }
+ el.removeClass(clazz);
+ },
+
+ removeElement : function(element) {
+ _getElementObject(element).remove();
+ },
+
+ setDragFilter : function(el, filter) {
+ if (jsPlumb.CurrentLibrary.isAlreadyDraggable(el))
+ el.draggable("option", "cancel", filter);
+ },
+
+ setDraggable : function(el, draggable) {
+ el.draggable("option", "disabled", !draggable);
+ },
+
+ setDragScope : function(el, scope) {
+ el.draggable("option", "scope", scope);
+ },
+
+ setOffset : function(el, o) {
+ _getElementObject(el).offset(o);
+ },
+
+ /**
+ * note that jquery ignores the name of the event you wanted to trigger, and figures it out for itself.
+ * the other libraries do not. yui, in fact, cannot even pass an original event. we have to pull out stuff
+ * from the originalEvent to put in an options object for YUI.
+ * @param el
+ * @param event
+ * @param originalEvent
+ */
+ trigger : function(el, event, originalEvent) {
+ var h = jQuery._data(_getElementObject(el)[0], "handle");
+ h(originalEvent);
+ },
+
+ unbind : function(el, event, callback) {
+ el = _getElementObject(el);
+ el.unbind(event, callback);
+ }
+ };
+
+ $(document).ready(jsPlumb.init);
+
+})(jQuery);
+
Added: sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/mootools.jsPlumb-1.5.2.js
===================================================================
--- sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/mootools.jsPlumb-1.5.2.js (rev 0)
+++ sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/mootools.jsPlumb-1.5.2.js 2013-09-09 09:43:14 UTC (rev 207)
@@ -0,0 +1,11006 @@
+/** %%Ignore-License
+* jsBezier-0.6
+*
+* Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+*
+* licensed under the MIT license.
+*
+* a set of Bezier curve functions that deal with Beziers, used by jsPlumb, and perhaps useful for other people. These functions work with Bezier
+* curves of arbitrary degree.
+*
+* - functions are all in the 'jsBezier' namespace.
+*
+* - all input points should be in the format {x:.., y:..}. all output points are in this format too.
+*
+* - all input curves should be in the format [ {x:.., y:..}, {x:.., y:..}, {x:.., y:..}, {x:.., y:..} ]
+*
+* - 'location' as used as an input here refers to a decimal in the range 0-1 inclusive, which indicates a point some proportion along the length
+* of the curve. location as output has the same format and meaning.
+*
+*
+* Function List:
+* --------------
+*
+* distanceFromCurve(point, curve)
+*
+* Calculates the distance that the given point lies from the given Bezier. Note that it is computed relative to the center of the Bezier,
+* so if you have stroked the curve with a wide pen you may wish to take that into account! The distance returned is relative to the values
+* of the curve and the point - it will most likely be pixels.
+*
+* gradientAtPoint(curve, location)
+*
+* Calculates the gradient to the curve at the given location, as a decimal between 0 and 1 inclusive.
+*
+* gradientAtPointAlongCurveFrom (curve, location)
+*
+* Calculates the gradient at the point on the given curve that is 'distance' units from location.
+*
+* nearestPointOnCurve(point, curve)
+*
+* Calculates the nearest point to the given point on the given curve. The return value of this is a JS object literal, containing both the
+*point's coordinates and also the 'location' of the point (see above), for example: { point:{x:551,y:150}, location:0.263365 }.
+*
+* pointOnCurve(curve, location)
+*
+* Calculates the coordinates of the point on the given Bezier curve at the given location.
+*
+* pointAlongCurveFrom(curve, location, distance)
+*
+* Calculates the coordinates of the point on the given curve that is 'distance' units from location. 'distance' should be in the same coordinate
+* space as that used to construct the Bezier curve. For an HTML Canvas usage, for example, distance would be a measure of pixels.
+*
+* locationAlongCurveFrom(curve, location, distance)
+*
+* Calculates the location on the given curve that is 'distance' units from location. 'distance' should be in the same coordinate
+* space as that used to construct the Bezier curve. For an HTML Canvas usage, for example, distance would be a measure of pixels.
+*
+* perpendicularToCurveAt(curve, location, length, distance)
+*
+* Calculates the perpendicular to the given curve at the given location. length is the length of the line you wish for (it will be centered
+* on the point at 'location'). distance is optional, and allows you to specify a point along the path from the given location as the center of
+* the perpendicular returned. The return value of this is an array of two points: [ {x:...,y:...}, {x:...,y:...} ].
+*
+*
+*/
+
+(function() {
+
+ if(typeof Math.sgn == "undefined") {
+ Math.sgn = function(x) { return x == 0 ? 0 : x > 0 ? 1 :-1; };
+ }
+
+ var Vectors = {
+ subtract : function(v1, v2) { return {x:v1.x - v2.x, y:v1.y - v2.y }; },
+ dotProduct : function(v1, v2) { return (v1.x * v2.x) + (v1.y * v2.y); },
+ square : function(v) { return Math.sqrt((v.x * v.x) + (v.y * v.y)); },
+ scale : function(v, s) { return {x:v.x * s, y:v.y * s }; }
+ },
+
+ maxRecursion = 64,
+ flatnessTolerance = Math.pow(2.0,-maxRecursion-1);
+
+ /**
+ * Calculates the distance that the point lies from the curve.
+ *
+ * @param point a point in the form {x:567, y:3342}
+ * @param curve a Bezier curve in the form [{x:..., y:...}, {x:..., y:...}, {x:..., y:...}, {x:..., y:...}]. note that this is currently
+ * hardcoded to assume cubiz beziers, but would be better off supporting any degree.
+ * @return a JS object literal containing location and distance, for example: {location:0.35, distance:10}. Location is analogous to the location
+ * argument you pass to the pointOnPath function: it is a ratio of distance travelled along the curve. Distance is the distance in pixels from
+ * the point to the curve.
+ */
+ var _distanceFromCurve = function(point, curve) {
+ var candidates = [],
+ w = _convertToBezier(point, curve),
+ degree = curve.length - 1, higherDegree = (2 * degree) - 1,
+ numSolutions = _findRoots(w, higherDegree, candidates, 0),
+ v = Vectors.subtract(point, curve[0]), dist = Vectors.square(v), t = 0.0;
+
+ for (var i = 0; i < numSolutions; i++) {
+ v = Vectors.subtract(point, _bezier(curve, degree, candidates[i], null, null));
+ var newDist = Vectors.square(v);
+ if (newDist < dist) {
+ dist = newDist;
+ t = candidates[i];
+ }
+ }
+ v = Vectors.subtract(point, curve[degree]);
+ newDist = Vectors.square(v);
+ if (newDist < dist) {
+ dist = newDist;
+ t = 1.0;
+ }
+ return {location:t, distance:dist};
+ };
+ /**
+ * finds the nearest point on the curve to the given point.
+ */
+ var _nearestPointOnCurve = function(point, curve) {
+ var td = _distanceFromCurve(point, curve);
+ return {point:_bezier(curve, curve.length - 1, td.location, null, null), location:td.location};
+ };
+ var _convertToBezier = function(point, curve) {
+ var degree = curve.length - 1, higherDegree = (2 * degree) - 1,
+ c = [], d = [], cdTable = [], w = [],
+ z = [ [1.0, 0.6, 0.3, 0.1], [0.4, 0.6, 0.6, 0.4], [0.1, 0.3, 0.6, 1.0] ];
+
+ for (var i = 0; i <= degree; i++) c[i] = Vectors.subtract(curve[i], point);
+ for (var i = 0; i <= degree - 1; i++) {
+ d[i] = Vectors.subtract(curve[i+1], curve[i]);
+ d[i] = Vectors.scale(d[i], 3.0);
+ }
+ for (var row = 0; row <= degree - 1; row++) {
+ for (var column = 0; column <= degree; column++) {
+ if (!cdTable[row]) cdTable[row] = [];
+ cdTable[row][column] = Vectors.dotProduct(d[row], c[column]);
+ }
+ }
+ for (i = 0; i <= higherDegree; i++) {
+ if (!w[i]) w[i] = [];
+ w[i].y = 0.0;
+ w[i].x = parseFloat(i) / higherDegree;
+ }
+ var n = degree, m = degree-1;
+ for (var k = 0; k <= n + m; k++) {
+ var lb = Math.max(0, k - m),
+ ub = Math.min(k, n);
+ for (i = lb; i <= ub; i++) {
+ j = k - i;
+ w[i+j].y += cdTable[j][i] * z[j][i];
+ }
+ }
+ return w;
+ };
+ /**
+ * counts how many roots there are.
+ */
+ var _findRoots = function(w, degree, t, depth) {
+ var left = [], right = [],
+ left_count, right_count,
+ left_t = [], right_t = [];
+
+ switch (_getCrossingCount(w, degree)) {
+ case 0 : {
+ return 0;
+ }
+ case 1 : {
+ if (depth >= maxRecursion) {
+ t[0] = (w[0].x + w[degree].x) / 2.0;
+ return 1;
+ }
+ if (_isFlatEnough(w, degree)) {
+ t[0] = _computeXIntercept(w, degree);
+ return 1;
+ }
+ break;
+ }
+ }
+ _bezier(w, degree, 0.5, left, right);
+ left_count = _findRoots(left, degree, left_t, depth+1);
+ right_count = _findRoots(right, degree, right_t, depth+1);
+ for (var i = 0; i < left_count; i++) t[i] = left_t[i];
+ for (var i = 0; i < right_count; i++) t[i+left_count] = right_t[i];
+ return (left_count+right_count);
+ };
+ var _getCrossingCount = function(curve, degree) {
+ var n_crossings = 0, sign, old_sign;
+ sign = old_sign = Math.sgn(curve[0].y);
+ for (var i = 1; i <= degree; i++) {
+ sign = Math.sgn(curve[i].y);
+ if (sign != old_sign) n_crossings++;
+ old_sign = sign;
+ }
+ return n_crossings;
+ };
+ var _isFlatEnough = function(curve, degree) {
+ var error,
+ intercept_1, intercept_2, left_intercept, right_intercept,
+ a, b, c, det, dInv, a1, b1, c1, a2, b2, c2;
+ a = curve[0].y - curve[degree].y;
+ b = curve[degree].x - curve[0].x;
+ c = curve[0].x * curve[degree].y - curve[degree].x * curve[0].y;
+
+ var max_distance_above = max_distance_below = 0.0;
+
+ for (var i = 1; i < degree; i++) {
+ var value = a * curve[i].x + b * curve[i].y + c;
+ if (value > max_distance_above)
+ max_distance_above = value;
+ else if (value < max_distance_below)
+ max_distance_below = value;
+ }
+
+ a1 = 0.0; b1 = 1.0; c1 = 0.0; a2 = a; b2 = b;
+ c2 = c - max_distance_above;
+ det = a1 * b2 - a2 * b1;
+ dInv = 1.0/det;
+ intercept_1 = (b1 * c2 - b2 * c1) * dInv;
+ a2 = a; b2 = b; c2 = c - max_distance_below;
+ det = a1 * b2 - a2 * b1;
+ dInv = 1.0/det;
+ intercept_2 = (b1 * c2 - b2 * c1) * dInv;
+ left_intercept = Math.min(intercept_1, intercept_2);
+ right_intercept = Math.max(intercept_1, intercept_2);
+ error = right_intercept - left_intercept;
+ return (error < flatnessTolerance)? 1 : 0;
+ };
+ var _computeXIntercept = function(curve, degree) {
+ var XLK = 1.0, YLK = 0.0,
+ XNM = curve[degree].x - curve[0].x, YNM = curve[degree].y - curve[0].y,
+ XMK = curve[0].x - 0.0, YMK = curve[0].y - 0.0,
+ det = XNM*YLK - YNM*XLK, detInv = 1.0/det,
+ S = (XNM*YMK - YNM*XMK) * detInv;
+ return 0.0 + XLK * S;
+ };
+ var _bezier = function(curve, degree, t, left, right) {
+ var temp = [[]];
+ for (var j =0; j <= degree; j++) temp[0][j] = curve[j];
+ for (var i = 1; i <= degree; i++) {
+ for (var j =0 ; j <= degree - i; j++) {
+ if (!temp[i]) temp[i] = [];
+ if (!temp[i][j]) temp[i][j] = {};
+ temp[i][j].x = (1.0 - t) * temp[i-1][j].x + t * temp[i-1][j+1].x;
+ temp[i][j].y = (1.0 - t) * temp[i-1][j].y + t * temp[i-1][j+1].y;
+ }
+ }
+ if (left != null)
+ for (j = 0; j <= degree; j++) left[j] = temp[j][0];
+ if (right != null)
+ for (j = 0; j <= degree; j++) right[j] = temp[degree-j][j];
+
+ return (temp[degree][0]);
+ };
+
+ var _curveFunctionCache = {};
+ var _getCurveFunctions = function(order) {
+ var fns = _curveFunctionCache[order];
+ if (!fns) {
+ fns = [];
+ var f_term = function() { return function(t) { return Math.pow(t, order); }; },
+ l_term = function() { return function(t) { return Math.pow((1-t), order); }; },
+ c_term = function(c) { return function(t) { return c; }; },
+ t_term = function() { return function(t) { return t; }; },
+ one_minus_t_term = function() { return function(t) { return 1-t; }; },
+ _termFunc = function(terms) {
+ return function(t) {
+ var p = 1;
+ for (var i = 0; i < terms.length; i++) p = p * terms[i](t);
+ return p;
+ };
+ };
+
+ fns.push(new f_term()); // first is t to the power of the curve order
+ for (var i = 1; i < order; i++) {
+ var terms = [new c_term(order)];
+ for (var j = 0 ; j < (order - i); j++) terms.push(new t_term());
+ for (var j = 0 ; j < i; j++) terms.push(new one_minus_t_term());
+ fns.push(new _termFunc(terms));
+ }
+ fns.push(new l_term()); // last is (1-t) to the power of the curve order
+
+ _curveFunctionCache[order] = fns;
+ }
+
+ return fns;
+ };
+
+
+ /**
+ * calculates a point on the curve, for a Bezier of arbitrary order.
+ * @param curve an array of control points, eg [{x:10,y:20}, {x:50,y:50}, {x:100,y:100}, {x:120,y:100}]. For a cubic bezier this should have four points.
+ * @param location a decimal indicating the distance along the curve the point should be located at. this is the distance along the curve as it travels, taking the way it bends into account. should be a number from 0 to 1, inclusive.
+ */
+ var _pointOnPath = function(curve, location) {
+ var cc = _getCurveFunctions(curve.length - 1),
+ _x = 0, _y = 0;
+ for (var i = 0; i < curve.length ; i++) {
+ _x = _x + (curve[i].x * cc[i](location));
+ _y = _y + (curve[i].y * cc[i](location));
+ }
+
+ return {x:_x, y:_y};
+ };
+
+ var _dist = function(p1,p2) {
+ return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
+ };
+
+ var _isPoint = function(curve) {
+ return curve[0].x == curve[1].x && curve[0].y == curve[1].y;
+ };
+
+ /**
+ * finds the point that is 'distance' along the path from 'location'. this method returns both the x,y location of the point and also
+ * its 'location' (proportion of travel along the path); the method below - _pointAlongPathFrom - calls this method and just returns the
+ * point.
+ */
+ var _pointAlongPath = function(curve, location, distance) {
+
+ if (_isPoint(curve)) {
+ return {
+ point:curve[0],
+ location:location
+ };
+ }
+
+ var prev = _pointOnPath(curve, location),
+ tally = 0,
+ curLoc = location,
+ direction = distance > 0 ? 1 : -1,
+ cur = null;
+
+ while (tally < Math.abs(distance)) {
+ curLoc += (0.005 * direction);
+ cur = _pointOnPath(curve, curLoc);
+ tally += _dist(cur, prev);
+ prev = cur;
+ }
+ return {point:cur, location:curLoc};
+ };
+
+ var _length = function(curve) {
+ if (_isPoint(curve)) return 0;
+
+ var prev = _pointOnPath(curve, 0),
+ tally = 0,
+ curLoc = 0,
+ direction = 1,
+ cur = null;
+
+ while (curLoc < 1) {
+ curLoc += (0.005 * direction);
+ cur = _pointOnPath(curve, curLoc);
+ tally += _dist(cur, prev);
+ prev = cur;
+ }
+ return tally;
+ };
+
+ /**
+ * finds the point that is 'distance' along the path from 'location'.
+ */
+ var _pointAlongPathFrom = function(curve, location, distance) {
+ return _pointAlongPath(curve, location, distance).point;
+ };
+
+ /**
+ * finds the location that is 'distance' along the path from 'location'.
+ */
+ var _locationAlongPathFrom = function(curve, location, distance) {
+ return _pointAlongPath(curve, location, distance).location;
+ };
+
+ /**
+ * returns the gradient of the curve at the given location, which is a decimal between 0 and 1 inclusive.
+ *
+ * thanks // http://bimixual.org/AnimationLibrary/beziertangents.html
+ */
+ var _gradientAtPoint = function(curve, location) {
+ var p1 = _pointOnPath(curve, location),
+ p2 = _pointOnPath(curve.slice(0, curve.length - 1), location),
+ dy = p2.y - p1.y, dx = p2.x - p1.x;
+ return dy == 0 ? Infinity : Math.atan(dy / dx);
+ };
+
+ /**
+ returns the gradient of the curve at the point which is 'distance' from the given location.
+ if this point is greater than location 1, the gradient at location 1 is returned.
+ if this point is less than location 0, the gradient at location 0 is returned.
+ */
+ var _gradientAtPointAlongPathFrom = function(curve, location, distance) {
+ var p = _pointAlongPath(curve, location, distance);
+ if (p.location > 1) p.location = 1;
+ if (p.location < 0) p.location = 0;
+ return _gradientAtPoint(curve, p.location);
+ };
+
+ /**
+ * calculates a line that is 'length' pixels long, perpendicular to, and centered on, the path at 'distance' pixels from the given location.
+ * if distance is not supplied, the perpendicular for the given location is computed (ie. we set distance to zero).
+ */
+ var _perpendicularToPathAt = function(curve, location, length, distance) {
+ distance = distance == null ? 0 : distance;
+ var p = _pointAlongPath(curve, location, distance),
+ m = _gradientAtPoint(curve, p.location),
+ _theta2 = Math.atan(-1 / m),
+ y = length / 2 * Math.sin(_theta2),
+ x = length / 2 * Math.cos(_theta2);
+ return [{x:p.point.x + x, y:p.point.y + y}, {x:p.point.x - x, y:p.point.y - y}];
+ };
+
+ var jsBezier = window.jsBezier = {
+ distanceFromCurve : _distanceFromCurve,
+ gradientAtPoint : _gradientAtPoint,
+ gradientAtPointAlongCurveFrom : _gradientAtPointAlongPathFrom,
+ nearestPointOnCurve : _nearestPointOnCurve,
+ pointOnCurve : _pointOnPath,
+ pointAlongCurveFrom : _pointAlongPathFrom,
+ perpendicularToCurveAt : _perpendicularToPathAt,
+ locationAlongCurveFrom:_locationAlongPathFrom,
+ getLength:_length
+ };
+})();
+
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG or VML.
+ *
+ * This file contains the util functions
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ var _isa = function(a) { return Object.prototype.toString.call(a) === "[object Array]"; },
+ _isnum = function(n) { return Object.prototype.toString.call(n) === "[object Number]"; },
+ _iss = function(s) { return typeof s === "string"; },
+ _isb = function(s) { return typeof s === "boolean"; },
+ _isnull = function(s) { return s == null; },
+ _iso = function(o) { return o == null ? false : Object.prototype.toString.call(o) === "[object Object]"; },
+ _isd = function(o) { return Object.prototype.toString.call(o) === "[object Date]"; },
+ _isf = function(o) { return Object.prototype.toString.call(o) === "[object Function]"; },
+ _ise = function(o) {
+ for (var i in o) { if (o.hasOwnProperty(i)) return false; }
+ return true;
+ },
+ pointHelper = function(p1, p2, fn) {
+ p1 = _isa(p1) ? p1 : [p1.x, p1.y];
+ p2 = _isa(p2) ? p2 : [p2.x, p2.y];
+ return fn(p1, p2);
+ };
+
+ jsPlumbUtil = {
+ isArray : _isa,
+ isString : _iss,
+ isBoolean: _isb,
+ isNull : _isnull,
+ isObject : _iso,
+ isDate : _isd,
+ isFunction: _isf,
+ isEmpty:_ise,
+ isNumber:_isnum,
+ clone : function(a) {
+ if (_iss(a)) return "" + a;
+ else if (_isb(a)) return !!a;
+ else if (_isd(a)) return new Date(a.getTime());
+ else if (_isf(a)) return a;
+ else if (_isa(a)) {
+ var b = [];
+ for (var i = 0; i < a.length; i++)
+ b.push(this.clone(a[i]));
+ return b;
+ }
+ else if (_iso(a)) {
+ var c = {};
+ for (var j in a)
+ c[j] = this.clone(a[j]);
+ return c;
+ }
+ else return a;
+ },
+ merge : function(a, b) {
+ var c = this.clone(a);
+ for (var i in b) {
+ if (c[i] == null || _iss(b[i]) || _isb(b[i]))
+ c[i] = b[i];
+ else {
+ if (_isa(b[i])/* && this.isArray(c[i])*/) {
+ var ar = [];
+ // if c's object is also an array we can keep its values.
+ if (_isa(c[i])) ar.push.apply(ar, c[i]);
+ ar.push.apply(ar, b[i]);
+ c[i] = ar;
+ }
+ else if(_iso(b[i])) {
+ // overwite c's value with an object if it is not already one.
+ if (!_iso(c[i]))
+ c[i] = {};
+ for (var j in b[i])
+ c[i][j] = b[i][j];
+ }
+ }
+ }
+ return c;
+ },
+ copyValues:function(names, from, to) {
+ for (var i = 0; i < names.length; i++)
+ to[names[i]] = from[names[i]];
+ },
+ //
+ // chain a list of functions, supplied by [ object, method name, args ], and return on the first
+ // one that returns the failValue. if none return the failValue, return the successValue.
+ //
+ functionChain : function(successValue, failValue, fns) {
+ for (var i = 0; i < fns.length; i++) {
+ var o = fns[i][0][fns[i][1]].apply(fns[i][0], fns[i][2]);
+ if (o === failValue) {
+ return o;
+ }
+ }
+ return successValue;
+ },
+ // take the given model and expand out any parameters.
+ populate : function(model, values) {
+ // for a string, see if it has parameter matches, and if so, try to make the substitutions.
+ var getValue = function(fromString) {
+ var matches = fromString.match(/(\${.*?})/g);
+ if (matches != null) {
+ for (var i = 0; i < matches.length; i++) {
+ var val = values[matches[i].substring(2, matches[i].length - 1)];
+ if (val != null) {
+ fromString = fromString.replace(matches[i], val);
+ }
+ }
+ }
+ return fromString;
+ },
+ // process one entry.
+ _one = function(d) {
+ if (d != null) {
+ if (_iss(d)) {
+ return getValue(d);
+ }
+ else if (_isa(d)) {
+ var r = [];
+ for (var i = 0; i < d.length; i++)
+ r.push(_one(d[i]));
+ return r;
+ }
+ else if (_iso(d)) {
+ var s = {};
+ for (var j in d) {
+ s[j] = _one(d[j]);
+ }
+ return s;
+ }
+ else {
+ return d;
+ }
+ }
+ };
+
+ return _one(model);
+ },
+ convertStyle : function(s, ignoreAlpha) {
+ // TODO: jsPlumb should support a separate 'opacity' style member.
+ if ("transparent" === s) return s;
+ var o = s,
+ pad = function(n) { return n.length == 1 ? "0" + n : n; },
+ hex = function(k) { return pad(Number(k).toString(16)); },
+ pattern = /(rgb[a]?\()(.*)(\))/;
+ if (s.match(pattern)) {
+ var parts = s.match(pattern)[2].split(",");
+ o = "#" + hex(parts[0]) + hex(parts[1]) + hex(parts[2]);
+ if (!ignoreAlpha && parts.length == 4)
+ o = o + hex(parts[3]);
+ }
+ return o;
+ },
+ gradient : function(p1, p2) {
+ return pointHelper(p1, p2, function(_p1, _p2) {
+ if (_p2[0] == _p1[0])
+ return _p2[1] > _p1[1] ? Infinity : -Infinity;
+ else if (_p2[1] == _p1[1])
+ return _p2[0] > _p1[0] ? 0 : -0;
+ else
+ return (_p2[1] - _p1[1]) / (_p2[0] - _p1[0]);
+ });
+ },
+ normal : function(p1, p2) {
+ return -1 / this.gradient(p1, p2);
+ },
+ lineLength : function(p1, p2) {
+ return pointHelper(p1, p2, function(_p1, _p2) {
+ return Math.sqrt(Math.pow(_p2[1] - _p1[1], 2) + Math.pow(_p2[0] - _p1[0], 2));
+ });
+ },
+ segment : function(p1, p2) {
+ return pointHelper(p1, p2, function(_p1, _p2) {
+ if (_p2[0] > _p1[0]) {
+ return (_p2[1] > _p1[1]) ? 2 : 1;
+ }
+ else if (_p2[0] == _p1[0]) {
+ return _p2[1] > _p1[1] ? 2 : 1;
+ }
+ else {
+ return (_p2[1] > _p1[1]) ? 3 : 4;
+ }
+ });
+ },
+ theta : function(p1, p2) {
+ return pointHelper(p1, p2, function(_p1, _p2) {
+ var m = jsPlumbUtil.gradient(_p1, _p2),
+ t = Math.atan(m),
+ s = jsPlumbUtil.segment(_p1, _p2);
+ if ((s == 4 || s== 3)) t += Math.PI;
+ if (t < 0) t += (2 * Math.PI);
+
+ return t;
+ });
+ },
+ intersects : function(r1, r2) {
+ var x1 = r1.x, x2 = r1.x + r1.w, y1 = r1.y, y2 = r1.y + r1.h,
+ a1 = r2.x, a2 = r2.x + r2.w, b1 = r2.y, b2 = r2.y + r2.h;
+
+ return ( (x1 <= a1 && a1 <= x2) && (y1 <= b1 && b1 <= y2) ) ||
+ ( (x1 <= a2 && a2 <= x2) && (y1 <= b1 && b1 <= y2) ) ||
+ ( (x1 <= a1 && a1 <= x2) && (y1 <= b2 && b2 <= y2) ) ||
+ ( (x1 <= a2 && a1 <= x2) && (y1 <= b2 && b2 <= y2) ) ||
+ ( (a1 <= x1 && x1 <= a2) && (b1 <= y1 && y1 <= b2) ) ||
+ ( (a1 <= x2 && x2 <= a2) && (b1 <= y1 && y1 <= b2) ) ||
+ ( (a1 <= x1 && x1 <= a2) && (b1 <= y2 && y2 <= b2) ) ||
+ ( (a1 <= x2 && x1 <= a2) && (b1 <= y2 && y2 <= b2) );
+ },
+ segmentMultipliers : [null, [1, -1], [1, 1], [-1, 1], [-1, -1] ],
+ inverseSegmentMultipliers : [null, [-1, -1], [-1, 1], [1, 1], [1, -1] ],
+ pointOnLine : function(fromPoint, toPoint, distance) {
+ var m = jsPlumbUtil.gradient(fromPoint, toPoint),
+ s = jsPlumbUtil.segment(fromPoint, toPoint),
+ segmentMultiplier = distance > 0 ? jsPlumbUtil.segmentMultipliers[s] : jsPlumbUtil.inverseSegmentMultipliers[s],
+ theta = Math.atan(m),
+ y = Math.abs(distance * Math.sin(theta)) * segmentMultiplier[1],
+ x = Math.abs(distance * Math.cos(theta)) * segmentMultiplier[0];
+ return { x:fromPoint.x + x, y:fromPoint.y + y };
+ },
+ perpendicularLineTo : function(fromPoint, toPoint, length) {
+ var m = jsPlumbUtil.gradient(fromPoint, toPoint),
+ theta2 = Math.atan(-1 / m),
+ y = length / 2 * Math.sin(theta2),
+ x = length / 2 * Math.cos(theta2);
+ return [{x:toPoint.x + x, y:toPoint.y + y}, {x:toPoint.x - x, y:toPoint.y - y}];
+ },
+ findWithFunction : function(a, f) {
+ if (a)
+ for (var i = 0; i < a.length; i++) if (f(a[i])) return i;
+ return -1;
+ },
+ clampToGrid : function(x, y, grid, dontClampX, dontClampY) {
+ var _gridClamp = function(n, g) {
+ var e = n % g,
+ f = Math.floor(n / g),
+ inc = e >= (g / 2) ? 1 : 0;
+ return (f + inc) * g;
+ };
+ return [
+ dontClampX || grid == null ? x : _gridClamp(x, grid[0]),
+ dontClampY || grid == null ? y : _gridClamp(y, grid[1])
+ ];
+ },
+ indexOf : function(l, v) {
+ return jsPlumbUtil.findWithFunction(l, function(_v) { return _v == v; });
+ },
+ removeWithFunction : function(a, f) {
+ var idx = jsPlumbUtil.findWithFunction(a, f);
+ if (idx > -1) a.splice(idx, 1);
+ return idx != -1;
+ },
+ remove : function(l, v) {
+ var idx = jsPlumbUtil.indexOf(l, v);
+ if (idx > -1) l.splice(idx, 1);
+ return idx != -1;
+ },
+ // TODO support insert index
+ addWithFunction : function(list, item, hashFunction) {
+ if (jsPlumbUtil.findWithFunction(list, hashFunction) == -1) list.push(item);
+ },
+ addToList : function(map, key, value, insertAtStart) {
+ var l = map[key];
+ if (l == null) {
+ l = [];
+ map[key] = l;
+ }
+ l[insertAtStart ? "unshift" : "push"](value);
+ return l;
+ },
+ //
+ // extends the given obj (which can be an array) with the given constructor function, prototype functions, and
+ // class members, any of which may be null.
+ //
+ extend : function(child, parent, _protoFn, _protoAtts) {
+ _protoFn = _protoFn || {};
+ _protoAtts = _protoAtts || {};
+ parent = _isa(parent) ? parent : [ parent ];
+
+ for (var i = 0; i < parent.length; i++) {
+ for (var j in parent[i].prototype) {
+ if(parent[i].prototype.hasOwnProperty(j)) {
+ child.prototype[j] = parent[i].prototype[j];
+ }
+ }
+ }
+
+ var _makeFn = function(name) {
+ return function() {
+ for (var i = 0; i < parent.length; i++) {
+ if (parent[i].prototype[name])
+ parent[i].prototype[name].apply(this, arguments);
+ }
+ return _protoFn[name].apply(this, arguments);
+ };
+ };
+
+ for (var k in _protoFn) {
+ child.prototype[k] = _makeFn(k);
+ }
+
+ return child;
+ },
+ uuid : function() {
+ return ('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+ var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
+ return v.toString(16);
+ }));
+ },
+ logEnabled : true,
+ log : function() {
+ if (jsPlumbUtil.logEnabled && typeof console != "undefined") {
+ try {
+ var msg = arguments[arguments.length - 1];
+ console.log(msg);
+ }
+ catch (e) {}
+ }
+ },
+ group : function(g) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.group(g); },
+ groupEnd : function(g) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.groupEnd(g); },
+ time : function(t) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.time(t); },
+ timeEnd : function(t) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.timeEnd(t); },
+
+ /**
+ * helper to remove an element from the DOM.
+ */
+ removeElement : function(element) {
+ if (element != null && element.parentNode != null) {
+ element.parentNode.removeChild(element);
+ }
+ },
+ /**
+ * helper to remove a list of elements from the DOM.
+ */
+ removeElements : function(elements) {
+ for ( var i = 0; i < elements.length; i++)
+ jsPlumbUtil.removeElement(elements[i]);
+ },
+ /*
+ * Function: sizeElement
+ * Helper to size and position an element. You would typically use
+ * this when writing your own Connector or Endpoint implementation.
+ *
+ * Parameters:
+ * x - [int] x position for the element origin
+ * y - [int] y position for the element origin
+ * w - [int] width of the element
+ * h - [int] height of the element
+ *
+ */
+ sizeElement : function(el, x, y, w, h) {
+ if (el) {
+ el.style.height = h + "px";
+ el.height = h;
+ el.style.width = w + "px";
+ el.width = w;
+ el.style.left = x + "px";
+ el.style.top = y + "px";
+ }
+ },
+ /**
+ * @name jsPlumbUtil.wrap
+ * @desc Wraps one function with another, creating a placeholder for the
+ * wrapped function if it was null. this is used to wrap the various
+ * drag/drop event functions - to allow jsPlumb to be notified of
+ * important lifecycle events without imposing itself on the user's
+ * drag/drop functionality.
+ * @param {Function} wrappedFunction original function to wrap; may be null.
+ * @param {Function} newFunction function to wrap the original with.
+ * @param {Object} [returnOnThisValue] Optional. Indicates that the wrappedFunction should
+ * not be executed if the newFunction returns a value matching 'returnOnThisValue'.
+ * note that this is a simple comparison and only works for primitives right now.
+ */
+ wrap : function(wrappedFunction, newFunction, returnOnThisValue) {
+ wrappedFunction = wrappedFunction || function() { };
+ newFunction = newFunction || function() { };
+ return function() {
+ var r = null;
+ try {
+ r = newFunction.apply(this, arguments);
+ } catch (e) {
+ jsPlumbUtil.log("jsPlumb function failed : " + e);
+ }
+ if (returnOnThisValue == null || (r !== returnOnThisValue)) {
+ try {
+ r = wrappedFunction.apply(this, arguments);
+ } catch (e) {
+ jsPlumbUtil.log("wrapped function failed : " + e);
+ }
+ }
+ return r;
+ };
+ }
+ };
+
+
+ jsPlumbUtil.EventGenerator = function() {
+ var _listeners = {}, eventsSuspended = false;
+
+ // this is a list of events that should re-throw any errors that occur during their dispatch. as of 1.3.0 this is private to
+ // jsPlumb, but it seems feasible that people might want to manipulate this list. the thinking is that we don't want event
+ // listeners to bring down jsPlumb - or do we. i can't make up my mind about this, but i know i want to hear about it if the "ready"
+ // event fails, because then my page has most likely not initialised. so i have this halfway-house solution. it will be interesting
+ // to hear what other people think.
+ var eventsToDieOn = [ "ready" ];
+
+ this.bind = function(event, listener, insertAtStart) {
+ jsPlumbUtil.addToList(_listeners, event, listener, true);
+ return this;
+ };
+
+ this.fire = function(event, value, originalEvent) {
+ if (!eventsSuspended && _listeners[event]) {
+ // instead of looping through the array we get a counter and a length, because it is possible
+ // that an event fired from here could cause the object to get cleaned up, which would throw
+ // away the listeners. so after each cycle through the loop we check to ensure we haven't
+ // been nuked.
+ var l = _listeners[event].length, i = 0, _gone = false, ret = null;
+ if (!this.shouldFireEvent || this.shouldFireEvent(event, value, originalEvent)) {
+ while (!_gone && i < l && ret !== false) {
+
+ // doing it this way rather than catching and then possibly re-throwing means that an error propagated by this
+ // method will have the whole call stack available in the debugger.
+ if (jsPlumbUtil.findWithFunction(eventsToDieOn, function(e) { return e === event; }) != -1)
+ _listeners[event][i](value, originalEvent);
+ else {
+ // for events we don't want to die on, catch and log.
+ try {
+ ret = _listeners[event][i](value, originalEvent);
+ } catch (e) {
+ jsPlumbUtil.log("jsPlumb: fire failed for event " + event + " : " + e);
+ }
+ }
+ i++;
+ if (_listeners == null || _listeners[event] == null) _gone = true;
+ }
+ }
+ }
+ return this;
+ };
+
+ this.unbind = function(event) {
+ if (event)
+ delete _listeners[event];
+ else {
+ _listeners = {};
+ }
+ return this;
+ };
+
+ this.getListener = function(forEvent) {
+ return _listeners[forEvent];
+ };
+ this.setSuspendEvents = function(val) {
+ eventsSuspended = val;
+ };
+ this.isSuspendEvents = function() {
+ return eventsSuspended;
+ };
+ this.cleanupListeners = function() {
+ for (var i in _listeners) {
+ _listeners[i].splice(0);
+ delete _listeners[i];
+ }
+ };
+ };
+
+
+ jsPlumbUtil.EventGenerator.prototype = {
+ cleanup:function() {
+ this.cleanupListeners();
+ }
+ };
+
+
+ // thanks MDC
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Ob…
+ if (!Function.prototype.bind) {
+ Function.prototype.bind = function (oThis) {
+ if (typeof this !== "function") {
+ // closest thing possible to the ECMAScript 5 internal IsCallable function
+ throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
+ }
+
+ var aArgs = Array.prototype.slice.call(arguments, 1),
+ fToBind = this,
+ fNOP = function () {},
+ fBound = function () {
+ return fToBind.apply(this instanceof fNOP && oThis ? this : oThis,
+ aArgs.concat(Array.prototype.slice.call(arguments)));
+ };
+
+ fNOP.prototype = this.prototype;
+ fBound.prototype = new fNOP();
+
+ return fBound;
+ };
+ }
+
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the base functionality for DOM type adapters.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+;(function() {
+
+ var canvasAvailable = !!document.createElement('canvas').getContext,
+ svgAvailable = !!window.SVGAngle || document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"),
+ // http://stackoverflow.com/questions/654112/how-do-you-detect-support-for-vml…
+ vmlAvailable = function() {
+ if (vmlAvailable.vml === undefined) {
+ var a = document.body.appendChild(document.createElement('div'));
+ a.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
+ var b = a.firstChild;
+ if (b != null && b.style != null) {
+ b.style.behavior = "url(#default#VML)";
+ vmlAvailable.vml = b ? typeof b.adj == "object": true;
+ }
+ else
+ vmlAvailable.vml = false;
+ a.parentNode.removeChild(a);
+ }
+ return vmlAvailable.vml;
+ };
+
+ /**
+ Manages dragging for some instance of jsPlumb.
+ */
+ var DragManager = function(_currentInstance) {
+ var _draggables = {}, _dlist = [], _delements = {}, _elementsWithEndpoints = {},
+ // elementids mapped to the draggable to which they belong.
+ _draggablesForElements = {};
+
+ /**
+ register some element as draggable. right now the drag init stuff is done elsewhere, and it is
+ possible that will continue to be the case.
+ */
+ this.register = function(el) {
+ var jpcl = jsPlumb.CurrentLibrary,
+ _el = jpcl.getElementObject(el),
+ id = _currentInstance.getId(el),
+ parentOffset = jpcl.getOffset(_el);
+
+ if (!_draggables[id]) {
+ _draggables[id] = el;
+ _dlist.push(el);
+ _delements[id] = {};
+ }
+
+ // look for child elements that have endpoints and register them against this draggable.
+ var _oneLevel = function(p, startOffset) {
+ if (p) {
+ for (var i = 0; i < p.childNodes.length; i++) {
+ if (p.childNodes[i].nodeType != 3 && p.childNodes[i].nodeType != 8) {
+ var cEl = jpcl.getElementObject(p.childNodes[i]),
+ cid = _currentInstance.getId(p.childNodes[i], null, true);
+ if (cid && _elementsWithEndpoints[cid] && _elementsWithEndpoints[cid] > 0) {
+ var cOff = jpcl.getOffset(cEl);
+ _delements[id][cid] = {
+ id:cid,
+ offset:{
+ left:cOff.left - parentOffset.left,
+ top:cOff.top - parentOffset.top
+ }
+ };
+ _draggablesForElements[cid] = id;
+ }
+ _oneLevel(p.childNodes[i]);
+ }
+ }
+ }
+ };
+
+ _oneLevel(el);
+ };
+
+ // refresh the offsets for child elements of this element.
+ this.updateOffsets = function(elId) {
+ var jpcl = jsPlumb.CurrentLibrary,
+ el = jpcl.getElementObject(elId),
+ domEl = jpcl.getDOMElement(el),
+ id = _currentInstance.getId(domEl),
+ children = _delements[id],
+ parentOffset = jpcl.getOffset(el);
+
+ if (children) {
+ for (var i in children) {
+ var cel = jpcl.getElementObject(i),
+ cOff = jpcl.getOffset(cel);
+
+ _delements[id][i] = {
+ id:i,
+ offset:{
+ left:cOff.left - parentOffset.left,
+ top:cOff.top - parentOffset.top
+ }
+ };
+ _draggablesForElements[i] = id;
+ }
+ }
+ };
+
+ /**
+ notification that an endpoint was added to the given el. we go up from that el's parent
+ node, looking for a parent that has been registered as a draggable. if we find one, we add this
+ el to that parent's list of elements to update on drag (if it is not there already)
+ */
+ this.endpointAdded = function(el) {
+ var jpcl = jsPlumb.CurrentLibrary, b = document.body, id = _currentInstance.getId(el),
+ c = jpcl.getElementObject(el),
+ cLoc = jsPlumb.CurrentLibrary.getOffset(c),
+ p = el.parentNode, done = p == b;
+
+ _elementsWithEndpoints[id] = _elementsWithEndpoints[id] ? _elementsWithEndpoints[id] + 1 : 1;
+
+ while (p != null && p != b) {
+ var pid = _currentInstance.getId(p, null, true);
+ if (pid && _draggables[pid]) {
+ var idx = -1, pEl = jpcl.getElementObject(p), pLoc = jpcl.getOffset(pEl);
+
+ if (_delements[pid][id] == null) {
+ _delements[pid][id] = {
+ id:id,
+ offset:{
+ left:cLoc.left - pLoc.left,
+ top:cLoc.top - pLoc.top
+ }
+ };
+ _draggablesForElements[id] = pid;
+ }
+ break;
+ }
+ p = p.parentNode;
+ }
+ };
+
+ this.endpointDeleted = function(endpoint) {
+ if (_elementsWithEndpoints[endpoint.elementId]) {
+ _elementsWithEndpoints[endpoint.elementId]--;
+ if (_elementsWithEndpoints[endpoint.elementId] <= 0) {
+ for (var i in _delements) {
+ if (_delements[i]) {
+ delete _delements[i][endpoint.elementId];
+ delete _draggablesForElements[endpoint.elementId];
+ }
+ }
+ }
+ }
+ };
+
+ this.changeId = function(oldId, newId) {
+ _delements[newId] = _delements[oldId];
+ _delements[oldId] = {};
+ _draggablesForElements[newId] = _draggablesForElements[oldId];
+ _draggablesForElements[oldId] = null;
+ };
+
+ this.getElementsForDraggable = function(id) {
+ return _delements[id];
+ };
+
+ this.elementRemoved = function(elementId) {
+ var elId = _draggablesForElements[elementId];
+ if (elId) {
+ delete _delements[elId][elementId];
+ delete _draggablesForElements[elementId];
+ }
+ };
+
+ this.reset = function() {
+ _draggables = {};
+ _dlist = [];
+ _delements = {};
+ _elementsWithEndpoints = {};
+ };
+
+ };
+
+ // for those browsers that dont have it. they still don't have it! but at least they won't crash.
+ if (!window.console)
+ window.console = { time:function(){}, timeEnd:function(){}, group:function(){}, groupEnd:function(){}, log:function(){} };
+
+ window.jsPlumbAdapter = {
+
+ headless:false,
+
+ getAttribute:function(el, attName) {
+ return el.getAttribute(attName);
+ },
+
+ setAttribute:function(el, a, v) {
+ el.setAttribute(a, v);
+ },
+
+ appendToRoot : function(node) {
+ document.body.appendChild(node);
+ },
+ getRenderModes : function() {
+ return [ "canvas", "svg", "vml" ];
+ },
+ isRenderModeAvailable : function(m) {
+ return {
+ "canvas":canvasAvailable,
+ "svg":svgAvailable,
+ "vml":vmlAvailable()
+ }[m];
+ },
+ getDragManager : function(_jsPlumb) {
+ return new DragManager(_jsPlumb);
+ },
+ setRenderMode : function(mode) {
+ var renderMode;
+
+ if (mode) {
+ mode = mode.toLowerCase();
+
+ var canvasAvailable = this.isRenderModeAvailable("canvas"),
+ svgAvailable = this.isRenderModeAvailable("svg"),
+ vmlAvailable = this.isRenderModeAvailable("vml");
+
+ // now test we actually have the capability to do this.
+ if (mode === "svg") {
+ if (svgAvailable) renderMode = "svg";
+ else if (canvasAvailable) renderMode = "canvas";
+ else if (vmlAvailable) renderMode = "vml";
+ }
+ else if (mode === "canvas" && canvasAvailable) renderMode = "canvas";
+ else if (vmlAvailable) renderMode = "vml";
+ }
+
+ return renderMode;
+ }
+ };
+
+
+ /*
+
+ addClass:
+
+ add: function( elem, classNames ) {
+ jQuery.each((classNames || "").split(/\s+/), function(i, className){
+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+ elem.className += (elem.className ? " " : "") + className;
+ });
+ },
+ */
+
+ /*
+
+ removeClass:
+
+ elem.className = classNames !== undefined ?
+ jQuery.grep(elem.className.split(/\s+/), function(className){
+ return !jQuery.className.has( classNames, className );
+ }).join(" ") :
+
+*/
+
+})();
+/**
+ * @module jsPlumb
+ * @description Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * - [Demo Site](http://jsplumb.org)
+ * - [GitHub](http://github.com/sporritt/jsplumb)
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+ */
+;(function() {
+
+ var _ju = jsPlumbUtil,
+ _addClass = function(el, clazz) { jsPlumb.CurrentLibrary.addClass(_gel(el), clazz); },
+ _hasClass = function(el, clazz) { return jsPlumb.CurrentLibrary.hasClass(_gel(el), clazz); },
+ _removeClass = function(el, clazz) { jsPlumb.CurrentLibrary.removeClass(_gel(el), clazz); },
+ _gel = function(el) { return jsPlumb.CurrentLibrary.getElementObject(el); },
+ _dom = function(el) { return jsPlumb.CurrentLibrary.getDOMElement(el); },
+ _getOffset = function(el, _instance) {
+ var o = jsPlumb.CurrentLibrary.getOffset(_gel(el));
+ if (_instance != null) {
+ var z = _instance.getZoom();
+ return {left:o.left / z, top:o.top / z };
+ }
+ else
+ return o;
+ },
+ _getSize = function(el) {
+ return jsPlumb.CurrentLibrary.getSize(_gel(el));
+ },
+
+ /**
+ * creates a timestamp, using milliseconds since 1970, but as a string.
+ */
+ _timestamp = function() { return "" + (new Date()).getTime(); },
+
+ // helper method to update the hover style whenever it, or paintStyle, changes.
+ // we use paintStyle as the foundation and merge hoverPaintStyle over the
+ // top.
+ _updateHoverStyle = function(component) {
+ if (component._jsPlumb.paintStyle && component._jsPlumb.hoverPaintStyle) {
+ var mergedHoverStyle = {};
+ jsPlumb.extend(mergedHoverStyle, component._jsPlumb.paintStyle);
+ jsPlumb.extend(mergedHoverStyle, component._jsPlumb.hoverPaintStyle);
+ delete component._jsPlumb.hoverPaintStyle;
+ // we want the fillStyle of paintStyle to override a gradient, if possible.
+ if (mergedHoverStyle.gradient && component._jsPlumb.paintStyle.fillStyle)
+ delete mergedHoverStyle.gradient;
+ component._jsPlumb.hoverPaintStyle = mergedHoverStyle;
+ }
+ },
+ events = [ "click", "dblclick", "mouseenter", "mouseout", "mousemove", "mousedown", "mouseup", "contextmenu" ],
+ eventFilters = { "mouseout":"mouseexit" },
+ _updateAttachedElements = function(component, state, timestamp, sourceElement) {
+ var affectedElements = component.getAttachedElements();
+ if (affectedElements) {
+ for (var i = 0, j = affectedElements.length; i < j; i++) {
+ if (!sourceElement || sourceElement != affectedElements[i])
+ affectedElements[i].setHover(state, true, timestamp); // tell the attached elements not to inform their own attached elements.
+ }
+ }
+ },
+ _splitType = function(t) { return t == null ? null : t.split(" "); },
+ _applyTypes = function(component, params, doNotRepaint) {
+ if (component.getDefaultType) {
+ var td = component.getTypeDescriptor();
+
+ var o = _ju.merge({}, component.getDefaultType());
+ for (var i = 0, j = component._jsPlumb.types.length; i < j; i++)
+ o = _ju.merge(o, component._jsPlumb.instance.getType(component._jsPlumb.types[i], td));
+
+ if (params) {
+ o = _ju.populate(o, params);
+ }
+
+ component.applyType(o, doNotRepaint);
+ if (!doNotRepaint) component.repaint();
+ }
+ },
+
+// ------------------------------ BEGIN jsPlumbUIComponent --------------------------------------------
+
+ jsPlumbUIComponent = window.jsPlumbUIComponent = function(params) {
+
+ jsPlumbUtil.EventGenerator.apply(this, arguments);
+
+ var self = this,
+ a = arguments,
+ idPrefix = self.idPrefix,
+ id = idPrefix + (new Date()).getTime(),
+ jpcl = jsPlumb.CurrentLibrary;
+
+ this._jsPlumb = {
+ instance: params._jsPlumb,
+ parameters:params.parameters || {},
+ paintStyle:null,
+ hoverPaintStyle:null,
+ paintStyleInUse:null,
+ hover:false,
+ beforeDetach:params.beforeDetach,
+ beforeDrop:params.beforeDrop,
+ overlayPlacements : [],
+ hoverClass: params.hoverClass || params._jsPlumb.Defaults.HoverClass || jsPlumb.Defaults.HoverClass,
+ types:[]
+ };
+
+ this.getId = function() { return id; };
+
+ // all components can generate events
+
+ if (params.events) {
+ for (var i in params.events)
+ self.bind(i, params.events[i]);
+ }
+
+ // all components get this clone function.
+ // TODO issue 116 showed a problem with this - it seems 'a' that is in
+ // the clone function's scope is shared by all invocations of it, the classic
+ // JS closure problem. for now, jsPlumb does a version of this inline where
+ // it used to call clone. but it would be nice to find some time to look
+ // further at this.
+ this.clone = function() {
+ var o = {};//new Object();
+ this.constructor.apply(o, a);
+ return o;
+ }.bind(this);
+
+
+ // user can supply a beforeDetach callback, which will be executed before a detach
+ // is performed; returning false prevents the detach.
+ this.isDetachAllowed = function(connection) {
+ var r = true;
+ if (this._jsPlumb.beforeDetach) {
+ try {
+ r = this._jsPlumb.beforeDetach(connection);
+ }
+ catch (e) { _ju.log("jsPlumb: beforeDetach callback failed", e); }
+ }
+ return r;
+ };
+
+ // user can supply a beforeDrop callback, which will be executed before a dropped
+ // connection is confirmed. user can return false to reject connection.
+ this.isDropAllowed = function(sourceId, targetId, scope, connection, dropEndpoint) {
+ var r = this._jsPlumb.instance.checkCondition("beforeDrop", {
+ sourceId:sourceId,
+ targetId:targetId,
+ scope:scope,
+ connection:connection,
+ dropEndpoint:dropEndpoint
+ });
+ if (this._jsPlumb.beforeDrop) {
+ try {
+ r = this._jsPlumb.beforeDrop({
+ sourceId:sourceId,
+ targetId:targetId,
+ scope:scope,
+ connection:connection,
+ dropEndpoint:dropEndpoint
+ });
+ }
+ catch (e) { _ju.log("jsPlumb: beforeDrop callback failed", e); }
+ }
+ return r;
+ };
+
+ var boundListeners = [],
+ bindAListener = function(obj, type, fn) {
+ boundListeners.push([obj, type, fn]);
+ obj.bind(type, fn);
+ },
+ domListeners = [],
+ bindOne = function(o, c, evt) {
+ var filteredEvent = eventFilters[evt] || evt,
+ fn = function(ee) {
+ c.fire(filteredEvent, c, ee);
+ };
+ domListeners.push([o, evt, fn]);
+ jpcl.bind(o, evt, fn);
+ },
+ unbindOne = function(o, evt, fn) {
+ var filteredEvent = eventFilters[evt] || evt;
+ jpcl.unbind(o, evt, fn);
+ };
+
+ this.bindListeners = function(obj, _self, _hoverFunction) {
+ bindAListener(obj, "click", function(ep, e) { _self.fire("click", _self, e); });
+ bindAListener(obj, "dblclick", function(ep, e) { _self.fire("dblclick", _self, e); });
+ bindAListener(obj, "contextmenu", function(ep, e) { _self.fire("contextmenu", _self, e); });
+ bindAListener(obj, "mouseenter", function(ep, e) {
+ if (!_self.isHover()) {
+ _hoverFunction(true);
+ _self.fire("mouseenter", _self, e);
+ }
+ });
+ bindAListener(obj, "mouseexit", function(ep, e) {
+ if (_self.isHover()) {
+ _hoverFunction(false);
+ _self.fire("mouseexit", _self, e);
+ }
+ });
+ bindAListener(obj, "mousedown", function(ep, e) { _self.fire("mousedown", _self, e); });
+ bindAListener(obj, "mouseup", function(ep, e) { _self.fire("mouseup", _self, e); });
+ };
+
+ this.unbindListeners = function() {
+ for (var i = 0; i < boundListeners.length; i++) {
+ var o = boundListeners[i];
+ o[0].unbind(o[1], o[2]);
+ }
+ boundListeners = null;
+ };
+
+ this.attachListeners = function(o, c) {
+ for (var i = 0, j = events.length; i < j; i++) {
+ bindOne(o, c, events[i]);
+ }
+ };
+ this.detachListeners = function() {
+ for (var i = 0; i < domListeners.length; i++) {
+ unbindOne(domListeners[i][0], domListeners[i][1], domListeners[i][2]);
+ }
+ domListeners = null;
+ };
+
+ this.reattachListenersForElement = function(o) {
+ if (arguments.length > 1) {
+ for (var i = 0, j = events.length; i < j; i++)
+ unbindOne(o, events[i]);
+ for (i = 1, j = arguments.length; i < j; i++)
+ this.attachListeners(o, arguments[i]);
+ }
+ };
+ };
+
+ jsPlumbUtil.extend(jsPlumbUIComponent, jsPlumbUtil.EventGenerator, {
+
+ getParameter : function(name) {
+ return this._jsPlumb.parameters[name];
+ },
+
+ setParameter : function(name, value) {
+ this._jsPlumb.parameters[name] = value;
+ },
+
+ getParameters : function() {
+ return this._jsPlumb.parameters;
+ },
+
+ setParameters : function(p) {
+ this._jsPlumb.parameters = p;
+ },
+
+ addClass : function(clazz) {
+ if (this.canvas != null)
+ _addClass(this.canvas, clazz);
+ },
+
+ removeClass : function(clazz) {
+ if (this.canvas != null)
+ _removeClass(this.canvas, clazz);
+ },
+
+ setType : function(typeId, params, doNotRepaint) {
+ this._jsPlumb.types = _splitType(typeId) || [];
+ _applyTypes(this, params, doNotRepaint);
+ },
+
+ getType : function() {
+ return this._jsPlumb.types;
+ },
+
+ reapplyTypes : function(params, doNotRepaint) {
+ _applyTypes(this, params, doNotRepaint);
+ },
+
+ hasType : function(typeId) {
+ return jsPlumbUtil.indexOf(this._jsPlumb.types, typeId) != -1;
+ },
+
+ addType : function(typeId, params, doNotRepaint) {
+ var t = _splitType(typeId), _cont = false;
+ if (t != null) {
+ for (var i = 0, j = t.length; i < j; i++) {
+ if (!this.hasType(t[i])) {
+ this._jsPlumb.types.push(t[i]);
+ _cont = true;
+ }
+ }
+ if (_cont) _applyTypes(this, params, doNotRepaint);
+ }
+ },
+
+ removeType : function(typeId, doNotRepaint) {
+ var t = _splitType(typeId), _cont = false, _one = function(tt) {
+ var idx = _ju.indexOf(this._jsPlumb.types, tt);
+ if (idx != -1) {
+ this._jsPlumb.types.splice(idx, 1);
+ return true;
+ }
+ return false;
+ }.bind(this);
+
+ if (t != null) {
+ for (var i = 0,j = t.length; i < j; i++) {
+ _cont = _one(t[i]) || _cont;
+ }
+ if (_cont) _applyTypes(this, null, doNotRepaint);
+ }
+ },
+
+ toggleType : function(typeId, params, doNotRepaint) {
+ var t = _splitType(typeId);
+ if (t != null) {
+ for (var i = 0, j = t.length; i < j; i++) {
+ var idx = jsPlumbUtil.indexOf(this._jsPlumb.types, t[i]);
+ if (idx != -1)
+ this._jsPlumb.types.splice(idx, 1);
+ else
+ this._jsPlumb.types.push(t[i]);
+ }
+
+ _applyTypes(this, params, doNotRepaint);
+ }
+ },
+ applyType : function(t, doNotRepaint) {
+ this.setPaintStyle(t.paintStyle, doNotRepaint);
+ this.setHoverPaintStyle(t.hoverPaintStyle, doNotRepaint);
+ if (t.parameters){
+ for (var i in t.parameters)
+ this.setParameter(i, t.parameters[i]);
+ }
+ },
+ setPaintStyle : function(style, doNotRepaint) {
+// this._jsPlumb.paintStyle = jsPlumb.extend({}, style);
+// TODO figure out if we want components to clone paintStyle so as not to share it.
+ this._jsPlumb.paintStyle = style;
+ this._jsPlumb.paintStyleInUse = this._jsPlumb.paintStyle;
+ _updateHoverStyle(this);
+ if (!doNotRepaint) this.repaint();
+ },
+ getPaintStyle : function() {
+ return this._jsPlumb.paintStyle;
+ },
+ setHoverPaintStyle : function(style, doNotRepaint) {
+ //this._jsPlumb.hoverPaintStyle = jsPlumb.extend({}, style);
+// TODO figure out if we want components to clone paintStyle so as not to share it.
+ this._jsPlumb.hoverPaintStyle = style;
+ _updateHoverStyle(this);
+ if (!doNotRepaint) this.repaint();
+ },
+ getHoverPaintStyle : function() {
+ return this._jsPlumb.hoverPaintStyle;
+ },
+ cleanup:function() {
+ this.unbindListeners();
+ this.detachListeners();
+ },
+ destroy:function() {
+ this.cleanupListeners();
+ this.clone = null;
+ this._jsPlumb = null;
+ },
+
+ isHover : function() { return this._jsPlumb.hover; },
+
+ setHover : function(hover, ignoreAttachedElements, timestamp) {
+ var jpcl = jsPlumb.CurrentLibrary;
+ // while dragging, we ignore these events. this keeps the UI from flashing and
+ // swishing and whatevering.
+ if (this._jsPlumb && !this._jsPlumb.instance.currentlyDragging && !this._jsPlumb.instance.isHoverSuspended()) {
+
+ this._jsPlumb.hover = hover;
+
+ if (this.canvas != null) {
+ if (this._jsPlumb.instance.hoverClass != null) {
+ jpcl[hover ? "addClass" : "removeClass"](this.canvas, this._jsPlumb.instance.hoverClass);
+ }
+ }
+ if (this._jsPlumb.hoverPaintStyle != null) {
+ this._jsPlumb.paintStyleInUse = hover ? this._jsPlumb.hoverPaintStyle : this._jsPlumb.paintStyle;
+ if (!this._jsPlumb.instance.isSuspendDrawing()) {
+ timestamp = timestamp || _timestamp();
+ this.repaint({timestamp:timestamp, recalc:false});
+ }
+ }
+ // get the list of other affected elements, if supported by this component.
+ // for a connection, its the endpoints. for an endpoint, its the connections! surprise.
+ if (this.getAttachedElements && !ignoreAttachedElements)
+ _updateAttachedElements(this, hover, _timestamp(), this);
+ }
+ }
+ });
+
+// ------------------------------ END jsPlumbUIComponent --------------------------------------------
+
+// ------------------------------ BEGIN OverlayCapablejsPlumbUIComponent --------------------------------------------
+
+ var _internalLabelOverlayId = "__label",
+ // helper to get the index of some overlay
+ _getOverlayIndex = function(component, id) {
+ var idx = -1;
+ for (var i = 0, j = component._jsPlumb.overlays.length; i < j; i++) {
+ if (id === component._jsPlumb.overlays[i].id) {
+ idx = i;
+ break;
+ }
+ }
+ return idx;
+ },
+ // this is a shortcut helper method to let people add a label as
+ // overlay.
+ _makeLabelOverlay = function(component, params) {
+
+ var _params = {
+ cssClass:params.cssClass,
+ labelStyle : component.labelStyle,
+ id:_internalLabelOverlayId,
+ component:component,
+ _jsPlumb:component._jsPlumb.instance // TODO not necessary, since the instance can be accessed through the component.
+ },
+ mergedParams = jsPlumb.extend(_params, params);
+
+ return new jsPlumb.Overlays[component._jsPlumb.instance.getRenderMode()].Label( mergedParams );
+ },
+ _processOverlay = function(component, o) {
+ var _newOverlay = null;
+ if (_ju.isArray(o)) { // this is for the shorthand ["Arrow", { width:50 }] syntax
+ // there's also a three arg version:
+ // ["Arrow", { width:50 }, {location:0.7}]
+ // which merges the 3rd arg into the 2nd.
+ var type = o[0],
+ // make a copy of the object so as not to mess up anyone else's reference...
+ p = jsPlumb.extend({component:component, _jsPlumb:component._jsPlumb.instance}, o[1]);
+ if (o.length == 3) jsPlumb.extend(p, o[2]);
+ _newOverlay = new jsPlumb.Overlays[component._jsPlumb.instance.getRenderMode()][type](p);
+ } else if (o.constructor == String) {
+ _newOverlay = new jsPlumb.Overlays[component._jsPlumb.instance.getRenderMode()][o]({component:component, _jsPlumb:component._jsPlumb.instance});
+ } else {
+ _newOverlay = o;
+ }
+
+ component._jsPlumb.overlays.push(_newOverlay);
+ },
+ _calculateOverlaysToAdd = function(component, params) {
+ var defaultKeys = component.defaultOverlayKeys || [], o = params.overlays,
+ checkKey = function(k) {
+ return component._jsPlumb.instance.Defaults[k] || jsPlumb.Defaults[k] || [];
+ };
+
+ if (!o) o = [];
+
+ for (var i = 0, j = defaultKeys.length; i < j; i++)
+ o.unshift.apply(o, checkKey(defaultKeys[i]));
+
+ return o;
+ },
+ OverlayCapableJsPlumbUIComponent = window.OverlayCapableJsPlumbUIComponent = function(params) {
+
+ jsPlumbUIComponent.apply(this, arguments);
+ this._jsPlumb.overlays = [];
+
+ var _overlays = _calculateOverlaysToAdd(this, params);
+ if (_overlays) {
+ for (var i = 0, j = _overlays.length; i < j; i++) {
+ _processOverlay(this, _overlays[i]);
+ }
+ }
+
+ if (params.label) {
+ var loc = params.labelLocation || this.defaultLabelLocation || 0.5,
+ labelStyle = params.labelStyle || this._jsPlumb.instance.Defaults.LabelStyle || jsPlumb.Defaults.LabelStyle;
+
+ this._jsPlumb.overlays.push(_makeLabelOverlay(this, {
+ label:params.label,
+ location:loc,
+ labelStyle:labelStyle
+ }));
+ }
+ };
+
+ jsPlumbUtil.extend(OverlayCapableJsPlumbUIComponent, jsPlumbUIComponent, {
+ applyType : function(t, doNotRepaint) {
+ this.removeAllOverlays(doNotRepaint);
+ if (t.overlays) {
+ for (var i = 0, j = t.overlays.length; i < j; i++)
+ this.addOverlay(t.overlays[i], true);
+ }
+ },
+ setHover : function(hover, ignoreAttachedElements, timestamp) {
+ if (this._jsPlumb && !this._jsPlumb.instance.isConnectionBeingDragged()) {
+ for (var i = 0, j = this._jsPlumb.overlays.length; i < j; i++) {
+ this._jsPlumb.overlays[i][hover ? "addClass":"removeClass"](this._jsPlumb.instance.hoverClass);
+ }
+ }
+ },
+ addOverlay : function(overlay, doNotRepaint) {
+ _processOverlay(this, overlay);
+ if (!doNotRepaint) this.repaint();
+ },
+ getOverlay : function(id) {
+ var idx = _getOverlayIndex(this, id);
+ return idx >= 0 ? this._jsPlumb.overlays[idx] : null;
+ },
+ getOverlays : function() {
+ return this._jsPlumb.overlays;
+ },
+ hideOverlay : function(id) {
+ var o = this.getOverlay(id);
+ if (o) o.hide();
+ },
+ hideOverlays : function() {
+ for (var i = 0, j = this._jsPlumb.overlays.length; i < j; i++)
+ this._jsPlumb.overlays[i].hide();
+ },
+ showOverlay : function(id) {
+ var o = this.getOverlay(id);
+ if (o) o.show();
+ },
+ showOverlays : function() {
+ for (var i = 0, j = this._jsPlumb.overlays.length; i < j; i++)
+ this._jsPlumb.overlays[i].show();
+ },
+ removeAllOverlays : function(doNotRepaint) {
+ for (var i = 0, j = this._jsPlumb.overlays.length; i < j; i++) {
+ if (this._jsPlumb.overlays[i].cleanup) this._jsPlumb.overlays[i].cleanup();
+ }
+
+ this._jsPlumb.overlays.splice(0, this._jsPlumb.overlays.length);
+ if (!doNotRepaint)
+ this.repaint();
+ },
+ removeOverlay : function(overlayId) {
+ var idx = _getOverlayIndex(this, overlayId);
+ if (idx != -1) {
+ var o = this._jsPlumb.overlays[idx];
+ if (o.cleanup) o.cleanup();
+ this._jsPlumb.overlays.splice(idx, 1);
+ }
+ },
+ removeOverlays : function() {
+ for (var i = 0, j = arguments.length; i < j; i++)
+ this.removeOverlay(arguments[i]);
+ },
+ getLabel : function() {
+ var lo = this.getOverlay(_internalLabelOverlayId);
+ return lo != null ? lo.getLabel() : null;
+ },
+ getLabelOverlay : function() {
+ return this.getOverlay(_internalLabelOverlayId);
+ },
+ setLabel : function(l) {
+ var lo = this.getOverlay(_internalLabelOverlayId);
+ if (!lo) {
+ var params = l.constructor == String || l.constructor == Function ? { label:l } : l;
+ lo = _makeLabelOverlay(this, params);
+ this._jsPlumb.overlays.push(lo);
+ }
+ else {
+ if (l.constructor == String || l.constructor == Function) lo.setLabel(l);
+ else {
+ if (l.label) lo.setLabel(l.label);
+ if (l.location) lo.setLocation(l.location);
+ }
+ }
+
+ if (!this._jsPlumb.instance.isSuspendDrawing())
+ this.repaint();
+ },
+ cleanup:function() {
+ for (var i = 0; i < this._jsPlumb.overlays.length; i++) {
+ this._jsPlumb.overlays[i].cleanup();
+ this._jsPlumb.overlays[i].destroy();
+ }
+ this._jsPlumb.overlays.splice(0);
+ }
+ });
+
+// ------------------------------ END OverlayCapablejsPlumbUIComponent --------------------------------------------
+
+ var _jsPlumbInstanceIndex = 0,
+ getInstanceIndex = function() {
+ var i = _jsPlumbInstanceIndex + 1;
+ _jsPlumbInstanceIndex++;
+ return i;
+ };
+
+ var jsPlumbInstance = window.jsPlumbInstance = function(_defaults) {
+
+ this.Defaults = {
+ Anchor : "BottomCenter",
+ Anchors : [ null, null ],
+ ConnectionsDetachable : true,
+ ConnectionOverlays : [ ],
+ Connector : "Bezier",
+ Container : null,
+ DoNotThrowErrors:false,
+ DragOptions : { },
+ DropOptions : { },
+ Endpoint : "Dot",
+ EndpointOverlays : [ ],
+ Endpoints : [ null, null ],
+ EndpointStyle : { fillStyle : "#456" },
+ EndpointStyles : [ null, null ],
+ EndpointHoverStyle : null,
+ EndpointHoverStyles : [ null, null ],
+ HoverPaintStyle : null,
+ LabelStyle : { color : "black" },
+ LogEnabled : false,
+ Overlays : [ ],
+ MaxConnections : 1,
+ PaintStyle : { lineWidth : 8, strokeStyle : "#456" },
+ ReattachConnections:false,
+ RenderMode : "svg",
+ Scope : "jsPlumb_DefaultScope"
+ };
+ if (_defaults) jsPlumb.extend(this.Defaults, _defaults);
+
+ this.logEnabled = this.Defaults.LogEnabled;
+ this._connectionTypes = {};
+ this._endpointTypes = {};
+
+ jsPlumbUtil.EventGenerator.apply(this);
+
+ var _currentInstance = this,
+ _instanceIndex = getInstanceIndex(),
+ _bb = _currentInstance.bind,
+ _initialDefaults = {},
+ _zoom = 1,
+ _info = function(el) {
+ var _el = _dom(el);
+ return { el:_el, id:(jsPlumbUtil.isString(el) && _el == null) ? el : _getId(_el) };
+ };
+
+ this.getInstanceIndex = function() { return _instanceIndex; };
+
+ this.setZoom = function(z, repaintEverything) {
+ _zoom = z;
+ if (repaintEverything) _currentInstance.repaintEverything();
+ };
+ this.getZoom = function() { return _zoom; };
+
+ for (var i in this.Defaults)
+ _initialDefaults[i] = this.Defaults[i];
+
+ this.bind = function(event, fn) {
+ if ("ready" === event && initialized) fn();
+ else _bb.apply(_currentInstance,[event, fn]);
+ };
+
+ _currentInstance.importDefaults = function(d) {
+ for (var i in d) {
+ _currentInstance.Defaults[i] = d[i];
+ }
+ return _currentInstance;
+ };
+
+ _currentInstance.restoreDefaults = function() {
+ _currentInstance.Defaults = jsPlumb.extend({}, _initialDefaults);
+ return _currentInstance;
+ };
+
+ var log = null,
+ resizeTimer = null,
+ initialized = false,
+ // TODO remove from window scope
+ connections = [],
+ // map of element id -> endpoint lists. an element can have an arbitrary
+ // number of endpoints on it, and not all of them have to be connected
+ // to anything.
+ endpointsByElement = {},
+ endpointsByUUID = {},
+ offsets = {},
+ offsetTimestamps = {},
+ floatingConnections = {},
+ draggableStates = {},
+ connectionBeingDragged = false,
+ sizes = [],
+ _suspendDrawing = false,
+ _suspendedAt = null,
+ DEFAULT_SCOPE = this.Defaults.Scope,
+ renderMode = null, // will be set in init()
+ _curIdStamp = 1,
+ _idstamp = function() { return "" + _curIdStamp++; },
+
+ //
+ // appends an element to some other element, which is calculated as follows:
+ //
+ // 1. if _currentInstance.Defaults.Container exists, use that element.
+ // 2. if the 'parent' parameter exists, use that.
+ // 3. otherwise just use the root element (for DOM usage, the document body).
+ //
+ //
+ _appendElement = function(el, parent) {
+ if (_currentInstance.Defaults.Container)
+ jsPlumb.CurrentLibrary.appendElement(el, _currentInstance.Defaults.Container);
+ else if (!parent)
+ jsPlumbAdapter.appendToRoot(el);
+ else
+ jsPlumb.CurrentLibrary.appendElement(el, parent);
+ },
+
+ //
+ // YUI, for some reason, put the result of a Y.all call into an object that contains
+ // a '_nodes' array, instead of handing back an array-like object like the other
+ // libraries do.
+ //
+ _convertYUICollection = function(c) {
+ return c._nodes ? c._nodes : c;
+ },
+
+ //
+ // Draws an endpoint and its connections. this is the main entry point into drawing connections as well
+ // as endpoints, since jsPlumb is endpoint-centric under the hood.
+ //
+ // @param element element to draw (of type library specific element object)
+ // @param ui UI object from current library's event system. optional.
+ // @param timestamp timestamp for this paint cycle. used to speed things up a little by cutting down the amount of offset calculations we do.
+ // @param clearEdits defaults to false; indicates that mouse edits for connectors should be cleared
+ ///
+ _draw = function(element, ui, timestamp, clearEdits) {
+
+ // TODO is it correct to filter by headless at this top level? how would a headless adapter ever repaint?
+ if (!jsPlumbAdapter.headless && !_suspendDrawing) {
+ var id = _getId(element),
+ repaintEls = _currentInstance.dragManager.getElementsForDraggable(id);
+
+ if (timestamp == null) timestamp = _timestamp();
+
+ // update the offset of everything _before_ we try to draw anything.
+ var o = _updateOffset( { elId : id, offset : ui, recalc : false, timestamp : timestamp });
+
+ if (repaintEls) {
+ for (var i in repaintEls) {
+ _updateOffset( {
+ elId : repaintEls[i].id,
+ offset : {
+ left:o.o.left + repaintEls[i].offset.left,
+ top:o.o.top + repaintEls[i].offset.top
+ },
+ recalc : false,
+ timestamp : timestamp
+ });
+ }
+ }
+
+
+ _currentInstance.anchorManager.redraw(id, ui, timestamp, null, clearEdits);
+
+ if (repaintEls) {
+ for (var j in repaintEls) {
+ _currentInstance.anchorManager.redraw(repaintEls[j].id, ui, timestamp, repaintEls[j].offset, clearEdits, true);
+ }
+ }
+ }
+ },
+
+ //
+ // executes the given function against the given element if the first
+ // argument is an object, or the list of elements, if the first argument
+ // is a list. the function passed in takes (element, elementId) as
+ // arguments.
+ //
+ _elementProxy = function(element, fn) {
+ var retVal = null, el, id;
+ if (_ju.isArray(element)) {
+ retVal = [];
+ for ( var i = 0, j = element.length; i < j; i++) {
+ el = _gel(element[i]);
+ id = _currentInstance.getAttribute(el, "id");
+ retVal.push(fn(el, id)); // append return values to what we will return
+ }
+ } else {
+ el = _gel(element);
+ id = _currentInstance.getAttribute(el, "id");
+ retVal = fn(el, id);
+ }
+ return retVal;
+ },
+
+ //
+ // gets an Endpoint by uuid.
+ //
+ _getEndpoint = function(uuid) { return endpointsByUUID[uuid]; },
+
+ /**
+ * inits a draggable if it's not already initialised.
+ * TODO: somehow abstract this to the adapter, because the concept of "draggable" has no
+ * place on the server.
+ */
+ _initDraggableIfNecessary = function(element, isDraggable, dragOptions) {
+ // TODO move to DragManager?
+ if (!jsPlumbAdapter.headless) {
+ var _draggable = isDraggable == null ? false : isDraggable, jpcl = jsPlumb.CurrentLibrary;
+ if (_draggable) {
+ if (jpcl.isDragSupported(element) && !jpcl.isAlreadyDraggable(element)) {
+ var options = dragOptions || _currentInstance.Defaults.DragOptions || jsPlumb.Defaults.DragOptions;
+ options = jsPlumb.extend( {}, options); // make a copy.
+ var dragEvent = jpcl.dragEvents.drag,
+ stopEvent = jpcl.dragEvents.stop,
+ startEvent = jpcl.dragEvents.start;
+
+ options[startEvent] = _ju.wrap(options[startEvent], function() {
+ _currentInstance.setHoverSuspended(true);
+ _currentInstance.select({source:element}).addClass(_currentInstance.elementDraggingClass + " " + _currentInstance.sourceElementDraggingClass, true);
+ _currentInstance.select({target:element}).addClass(_currentInstance.elementDraggingClass + " " + _currentInstance.targetElementDraggingClass, true);
+ _currentInstance.setConnectionBeingDragged(true);
+ });
+
+ options[dragEvent] = _ju.wrap(options[dragEvent], function() {
+ var ui = jpcl.getUIPosition(arguments, _currentInstance.getZoom());
+ _draw(element, ui, null, true);
+ _addClass(element, "jsPlumb_dragged");
+ });
+ options[stopEvent] = _ju.wrap(options[stopEvent], function() {
+ var ui = jpcl.getUIPosition(arguments, _currentInstance.getZoom());
+ _draw(element, ui);
+ _removeClass(element, "jsPlumb_dragged");
+ _currentInstance.setHoverSuspended(false);
+ _currentInstance.select({source:element}).removeClass(_currentInstance.elementDraggingClass + " " + _currentInstance.sourceElementDraggingClass, true);
+ _currentInstance.select({target:element}).removeClass(_currentInstance.elementDraggingClass + " " + _currentInstance.targetElementDraggingClass, true);
+ _currentInstance.setConnectionBeingDragged(false);
+ });
+ var elId = _getId(element); // need ID
+ draggableStates[elId] = true;
+ var draggable = draggableStates[elId];
+ options.disabled = draggable == null ? false : !draggable;
+ jpcl.initDraggable(element, options, false, _currentInstance);
+ _currentInstance.dragManager.register(element);
+ }
+ }
+ }
+ },
+
+ /*
+ * prepares a final params object that can be passed to _newConnection, taking into account defaults, events, etc.
+ */
+ _prepareConnectionParams = function(params, referenceParams) {
+ var _p = jsPlumb.extend( { }, params);
+ if (referenceParams) jsPlumb.extend(_p, referenceParams);
+
+ // hotwire endpoints passed as source or target to sourceEndpoint/targetEndpoint, respectively.
+ if (_p.source) {
+ if (_p.source.endpoint)
+ _p.sourceEndpoint = _p.source;
+ else
+ _p.source = _dom(_p.source);
+ }
+ if (_p.target) {
+ if (_p.target.endpoint)
+ _p.targetEndpoint = _p.target;
+ else
+ _p.target = _dom(_p.target);
+ }
+
+ // test for endpoint uuids to connect
+ if (params.uuids) {
+ _p.sourceEndpoint = _getEndpoint(params.uuids[0]);
+ _p.targetEndpoint = _getEndpoint(params.uuids[1]);
+ }
+
+ // now ensure that if we do have Endpoints already, they're not full.
+ // source:
+ if (_p.sourceEndpoint && _p.sourceEndpoint.isFull()) {
+ _ju.log(_currentInstance, "could not add connection; source endpoint is full");
+ return;
+ }
+
+ // target:
+ if (_p.targetEndpoint && _p.targetEndpoint.isFull()) {
+ _ju.log(_currentInstance, "could not add connection; target endpoint is full");
+ return;
+ }
+
+ // if source endpoint mandates connection type and nothing specified in our params, use it.
+ if (!_p.type && _p.sourceEndpoint)
+ _p.type = _p.sourceEndpoint.connectionType;
+
+ // copy in any connectorOverlays that were specified on the source endpoint.
+ // it doesnt copy target endpoint overlays. i'm not sure if we want it to or not.
+ if (_p.sourceEndpoint && _p.sourceEndpoint.connectorOverlays) {
+ _p.overlays = _p.overlays || [];
+ for (var i = 0, j = _p.sourceEndpoint.connectorOverlays.length; i < j; i++) {
+ _p.overlays.push(_p.sourceEndpoint.connectorOverlays[i]);
+ }
+ }
+
+ // pointer events
+ if (!_p["pointer-events"] && _p.sourceEndpoint && _p.sourceEndpoint.connectorPointerEvents)
+ _p["pointer-events"] = _p.sourceEndpoint.connectorPointerEvents;
+
+ // if there's a target specified (which of course there should be), and there is no
+ // target endpoint specified, and 'newConnection' was not set to true, then we check to
+ // see if a prior call to makeTarget has provided us with the specs for the target endpoint, and
+ // we use those if so. additionally, if the makeTarget call was specified with 'uniqueEndpoint' set
+ // to true, then if that target endpoint has already been created, we re-use it.
+
+ var tid, tep, existingUniqueEndpoint, newEndpoint;
+
+ // TODO: this code can be refactored to be a little dry.
+ if (_p.target && !_p.target.endpoint && !_p.targetEndpoint && !_p.newConnection) {
+ tid = _getId(_p.target);
+ tep =_targetEndpointDefinitions[tid];
+ existingUniqueEndpoint = _targetEndpoints[tid];
+
+ if (tep) {
+ // if target not enabled, return.
+ if (!_targetsEnabled[tid]) return;
+
+ tep.isTarget = true;
+ // check for max connections??
+ newEndpoint = existingUniqueEndpoint != null ? existingUniqueEndpoint : _currentInstance.addEndpoint(_p.target, tep);
+ if (_targetEndpointsUnique[tid]) _targetEndpoints[tid] = newEndpoint;
+ _p.targetEndpoint = newEndpoint;
+ // TODO test options to makeTarget to see if we should do this?
+ newEndpoint._doNotDeleteOnDetach = false; // reset.
+ newEndpoint._deleteOnDetach = true;
+ }
+ }
+
+ // same thing, but for source.
+ if (_p.source && !_p.source.endpoint && !_p.sourceEndpoint && !_p.newConnection) {
+ tid = _getId(_p.source);
+ tep = _sourceEndpointDefinitions[tid];
+ existingUniqueEndpoint = _sourceEndpoints[tid];
+
+ if (tep) {
+ // if source not enabled, return.
+ if (!_sourcesEnabled[tid]) return;
+
+ newEndpoint = existingUniqueEndpoint != null ? existingUniqueEndpoint : _currentInstance.addEndpoint(_p.source, tep);
+ if (_sourceEndpointsUnique[tid]) _sourceEndpoints[tid] = newEndpoint;
+ _p.sourceEndpoint = newEndpoint;
+ // TODO test options to makeSource to see if we should do this?
+ newEndpoint._doNotDeleteOnDetach = false; // reset.
+ newEndpoint._deleteOnDetach = true;
+ }
+ }
+
+ return _p;
+ },
+
+ _newConnection = function(params) {
+ var connectionFunc = _currentInstance.Defaults.ConnectionType || _currentInstance.getDefaultConnectionType(),
+ endpointFunc = _currentInstance.Defaults.EndpointType || jsPlumb.Endpoint,
+ parent = jsPlumb.CurrentLibrary.getParent;
+
+ if (params.container)
+ params.parent = params.container;
+ else {
+ if (params.sourceEndpoint)
+ params.parent = params.sourceEndpoint.parent;
+ else if (params.source.constructor == endpointFunc)
+ params.parent = params.source.parent;
+ else params.parent = parent(params.source);
+ }
+
+ params._jsPlumb = _currentInstance;
+ params.newConnection = _newConnection;
+ params.newEndpoint = _newEndpoint;
+ params.endpointsByUUID = endpointsByUUID;
+ params.endpointsByElement = endpointsByElement;
+ params.finaliseConnection = _finaliseConnection;
+ var con = new connectionFunc(params);
+ con.id = "con_" + _idstamp();
+ _eventFireProxy("click", "click", con);
+ _eventFireProxy("dblclick", "dblclick", con);
+ _eventFireProxy("contextmenu", "contextmenu", con);
+ return con;
+ },
+
+ //
+ // adds the connection to the backing model, fires an event if necessary and then redraws
+ //
+ _finaliseConnection = function(jpc, params, originalEvent, doInformAnchorManager) {
+ params = params || {};
+ // add to list of connections (by scope).
+ if (!jpc.suspendedEndpoint)
+ connections.push(jpc);
+
+ // always inform the anchor manager
+ // except that if jpc has a suspended endpoint it's not true to say the
+ // connection is new; it has just (possibly) moved. the question is whether
+ // to make that call here or in the anchor manager. i think perhaps here.
+ if (jpc.suspendedEndpoint == null || doInformAnchorManager)
+ _currentInstance.anchorManager.newConnection(jpc);
+
+ // force a paint
+ _draw(jpc.source);
+
+ // fire an event
+ if (!params.doNotFireConnectionEvent && params.fireEvent !== false) {
+
+ var eventArgs = {
+ connection:jpc,
+ source : jpc.source, target : jpc.target,
+ sourceId : jpc.sourceId, targetId : jpc.targetId,
+ sourceEndpoint : jpc.endpoints[0], targetEndpoint : jpc.endpoints[1]
+ };
+
+ _currentInstance.fire("connection", eventArgs, originalEvent);
+ }
+ },
+
+ _eventFireProxy = function(event, proxyEvent, obj) {
+ obj.bind(event, function(originalObject, originalEvent) {
+ _currentInstance.fire(proxyEvent, obj, originalEvent);
+ });
+ },
+
+ /*
+ * for the given endpoint params, returns an appropriate parent element for the UI elements that will be added.
+ * this function is used by _newEndpoint (directly below), and also in the makeSource function in jsPlumb.
+ *
+ * the logic is to first look for a "container" member of params, and pass that back if found. otherwise we
+ * handoff to the 'getParent' function in the current library.
+ */
+ _getParentFromParams = function(params) {
+ if (params.container)
+ return params.container;
+ else {
+ var tag = jsPlumb.CurrentLibrary.getTagName(params.source),
+ p = jsPlumb.CurrentLibrary.getParent(params.source);
+ if (tag && tag.toLowerCase() === "td")
+ return jsPlumb.CurrentLibrary.getParent(p);
+ else return p;
+ }
+ },
+
+ /*
+ factory method to prepare a new endpoint. this should always be used instead of creating Endpoints
+ manually, since this method attaches event listeners and an id.
+ */
+ _newEndpoint = function(params) {
+ var endpointFunc = _currentInstance.Defaults.EndpointType || jsPlumb.Endpoint;
+ var _p = jsPlumb.extend({}, params);
+ _p.parent = _getParentFromParams(_p);
+ _p._jsPlumb = _currentInstance;
+ _p.newConnection = _newConnection;
+ _p.newEndpoint = _newEndpoint;
+ _p.endpointsByUUID = endpointsByUUID;
+ _p.endpointsByElement = endpointsByElement;
+ _p.finaliseConnection = _finaliseConnection;
+ _p.fireDetachEvent = fireDetachEvent;
+ _p.floatingConnections = floatingConnections;
+ _p.getParentFromParams = _getParentFromParams;
+ _p.elementId = _getId(_p.source);
+ var ep = new endpointFunc(_p);
+ ep.id = "ep_" + _idstamp();
+ _eventFireProxy("click", "endpointClick", ep);
+ _eventFireProxy("dblclick", "endpointDblClick", ep);
+ _eventFireProxy("contextmenu", "contextmenu", ep);
+ if (!jsPlumbAdapter.headless)
+ _currentInstance.dragManager.endpointAdded(_p.source);
+ return ep;
+ },
+
+ /*
+ * performs the given function operation on all the connections found
+ * for the given element id; this means we find all the endpoints for
+ * the given element, and then for each endpoint find the connectors
+ * connected to it. then we pass each connection in to the given
+ * function.
+ */
+ _operation = function(elId, func, endpointFunc) {
+ var endpoints = endpointsByElement[elId];
+ if (endpoints && endpoints.length) {
+ for ( var i = 0, ii = endpoints.length; i < ii; i++) {
+ for ( var j = 0, jj = endpoints[i].connections.length; j < jj; j++) {
+ var retVal = func(endpoints[i].connections[j]);
+ // if the function passed in returns true, we exit.
+ // most functions return false.
+ if (retVal) return;
+ }
+ if (endpointFunc) endpointFunc(endpoints[i]);
+ }
+ }
+ },
+
+ _setDraggable = function(element, draggable) {
+ return _elementProxy(element, function(el, id) {
+ draggableStates[id] = draggable;
+ if (jsPlumb.CurrentLibrary.isDragSupported(el)) {
+ jsPlumb.CurrentLibrary.setDraggable(el, draggable);
+ }
+ });
+ },
+ /*
+ * private method to do the business of hiding/showing.
+ *
+ * @param el
+ * either Id of the element in question or a library specific
+ * object for the element.
+ * @param state
+ * String specifying a value for the css 'display' property
+ * ('block' or 'none').
+ */
+ _setVisible = function(el, state, alsoChangeEndpoints) {
+ state = state === "block";
+ var endpointFunc = null;
+ if (alsoChangeEndpoints) {
+ if (state) endpointFunc = function(ep) {
+ ep.setVisible(true, true, true);
+ };
+ else endpointFunc = function(ep) {
+ ep.setVisible(false, true, true);
+ };
+ }
+ var info = _info(el);
+ _operation(info.id, function(jpc) {
+ if (state && alsoChangeEndpoints) {
+ // this test is necessary because this functionality is new, and i wanted to maintain backwards compatibility.
+ // this block will only set a connection to be visible if the other endpoint in the connection is also visible.
+ var oidx = jpc.sourceId === info.id ? 1 : 0;
+ if (jpc.endpoints[oidx].isVisible()) jpc.setVisible(true);
+ }
+ else // the default behaviour for show, and what always happens for hide, is to just set the visibility without getting clever.
+ jpc.setVisible(state);
+ }, endpointFunc);
+ },
+ /*
+ * toggles the draggable state of the given element(s).
+ * el is either an id, or an element object, or a list of ids/element objects.
+ */
+ _toggleDraggable = function(el) {
+ return _elementProxy(el, function(el, elId) {
+ var state = draggableStates[elId] == null ? false : draggableStates[elId];
+ state = !state;
+ draggableStates[elId] = state;
+ jsPlumb.CurrentLibrary.setDraggable(el, state);
+ return state;
+ });
+ },
+ /**
+ * private method to do the business of toggling hiding/showing.
+ */
+ _toggleVisible = function(elId, changeEndpoints) {
+ var endpointFunc = null;
+ if (changeEndpoints) {
+ endpointFunc = function(ep) {
+ var state = ep.isVisible();
+ ep.setVisible(!state);
+ };
+ }
+ _operation(elId, function(jpc) {
+ var state = jpc.isVisible();
+ jpc.setVisible(!state);
+ }, endpointFunc);
+ // todo this should call _elementProxy, and pass in the
+ // _operation(elId, f) call as a function. cos _toggleDraggable does
+ // that.
+ },
+ /**
+ * updates the offset and size for a given element, and stores the
+ * values. if 'offset' is not null we use that (it would have been
+ * passed in from a drag call) because it's faster; but if it is null,
+ * or if 'recalc' is true in order to force a recalculation, we get the current values.
+ */
+ _updateOffset = function(params) {
+ var timestamp = params.timestamp, recalc = params.recalc, offset = params.offset, elId = params.elId, s;
+ if (_suspendDrawing && !timestamp) timestamp = _suspendedAt;
+ if (!recalc) {
+ if (timestamp && timestamp === offsetTimestamps[elId]) {
+ return {o:params.offset || offsets[elId], s:sizes[elId]};
+ }
+ }
+ if (recalc || !offset) { // if forced repaint or no offset available, we recalculate.
+ // get the current size and offset, and store them
+ s = _gel(elId);
+ if (s != null) {
+ sizes[elId] = _getSize(s);
+ offsets[elId] = _getOffset(s, _currentInstance);
+ offsetTimestamps[elId] = timestamp;
+ }
+ } else {
+ offsets[elId] = offset;
+ if (sizes[elId] == null) {
+ s = _gel(elId);
+ if (s != null) sizes[elId] = _getSize(s);
+ }
+ offsetTimestamps[elId] = timestamp;
+ }
+
+ if(offsets[elId] && !offsets[elId].right) {
+ offsets[elId].right = offsets[elId].left + sizes[elId][0];
+ offsets[elId].bottom = offsets[elId].top + sizes[elId][1];
+ offsets[elId].width = sizes[elId][0];
+ offsets[elId].height = sizes[elId][1];
+ offsets[elId].centerx = offsets[elId].left + (offsets[elId].width / 2);
+ offsets[elId].centery = offsets[elId].top + (offsets[elId].height / 2);
+ }
+ return {o:offsets[elId], s:sizes[elId]};
+ },
+
+ // TODO comparison performance
+ _getCachedData = function(elId) {
+ var o = offsets[elId];
+ if (!o)
+ return _updateOffset({elId:elId});
+ else
+ return {o:o, s:sizes[elId]};
+ },
+
+ /**
+ * gets an id for the given element, creating and setting one if
+ * necessary. the id is of the form
+ *
+ * jsPlumb_<instance index>_<index in instance>
+ *
+ * where "index in instance" is a monotonically increasing integer that starts at 0,
+ * for each instance. this method is used not only to assign ids to elements that do not
+ * have them but also to connections and endpoints.
+ */
+ _getId = function(element, uuid, doNotCreateIfNotFound) {
+ if (jsPlumbUtil.isString(element)) return element;
+ if (element == null) return null;
+ var id = jsPlumbAdapter.getAttribute(element, "id");
+ if (!id || id === "undefined") {
+ // check if fixed uuid parameter is given
+ if (arguments.length == 2 && arguments[1] !== undefined)
+ id = uuid;
+ else if (arguments.length == 1 || (arguments.length == 3 && !arguments[2]))
+ id = "jsPlumb_" + _instanceIndex + "_" + _idstamp();
+
+ if (!doNotCreateIfNotFound) jsPlumbAdapter.setAttribute(element, "id", id);
+ }
+ return id;
+ };
+
+ this.setConnectionBeingDragged = function(v) {
+ connectionBeingDragged = v;
+ };
+ this.isConnectionBeingDragged = function() {
+ return connectionBeingDragged;
+ };
+
+ this.connectorClass = "_jsPlumb_connector";
+ this.hoverClass = "_jsPlumb_hover";
+ this.endpointClass = "_jsPlumb_endpoint";
+ this.endpointConnectedClass = "_jsPlumb_endpoint_connected";
+ this.endpointFullClass = "_jsPlumb_endpoint_full";
+ this.endpointDropAllowedClass = "_jsPlumb_endpoint_drop_allowed";
+ this.endpointDropForbiddenClass = "_jsPlumb_endpoint_drop_forbidden";
+ this.overlayClass = "_jsPlumb_overlay";
+ this.draggingClass = "_jsPlumb_dragging";
+ this.elementDraggingClass = "_jsPlumb_element_dragging";
+ this.sourceElementDraggingClass = "_jsPlumb_source_element_dragging";
+ this.targetElementDraggingClass = "_jsPlumb_target_element_dragging";
+ this.endpointAnchorClassPrefix = "_jsPlumb_endpoint_anchor";
+ this.hoverSourceClass = "_jsPlumb_source_hover";
+ this.hoverTargetClass = "_jsPlumb_target_hover";
+ this.dragSelectClass = "_jsPlumb_drag_select";
+
+ this.Anchors = {};
+ this.Connectors = { "canvas":{}, "svg":{}, "vml":{} };
+ this.Endpoints = { "canvas":{}, "svg":{}, "vml":{} };
+ this.Overlays = { "canvas":{}, "svg":{}, "vml":{}};
+ this.ConnectorRenderers = {};
+ this.SVG = "svg";
+ this.CANVAS = "canvas";
+ this.VML = "vml";
+
+
+// --------------------------- jsPLumbInstance public API ---------------------------------------------------------
+
+
+ this.addEndpoint = function(el, params, referenceParams) {
+ referenceParams = referenceParams || {};
+ var p = jsPlumb.extend({}, referenceParams);
+ jsPlumb.extend(p, params);
+ p.endpoint = p.endpoint || _currentInstance.Defaults.Endpoint || jsPlumb.Defaults.Endpoint;
+ p.paintStyle = p.paintStyle || _currentInstance.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle;
+ // YUI wrapper
+ el = _convertYUICollection(el);
+
+ var results = [],
+ inputs = (_ju.isArray(el) || (el.length != null && !_ju.isString(el))) ? el : [ el ];
+
+ for (var i = 0, j = inputs.length; i < j; i++) {
+ var _el = _dom(inputs[i]), id = _getId(_el);
+ p.source = _el;
+
+ _updateOffset({ elId : id, timestamp:_suspendedAt });
+ var e = _newEndpoint(p);
+ if (p.parentAnchor) e.parentAnchor = p.parentAnchor;
+ _ju.addToList(endpointsByElement, id, e);
+ var myOffset = offsets[id],
+ myWH = sizes[id],
+ anchorLoc = e.anchor.compute( { xy : [ myOffset.left, myOffset.top ], wh : myWH, element : e, timestamp:_suspendedAt }),
+ endpointPaintParams = { anchorLoc : anchorLoc, timestamp:_suspendedAt };
+
+ if (_suspendDrawing) endpointPaintParams.recalc = false;
+ if (!_suspendDrawing) e.paint(endpointPaintParams);
+
+ results.push(e);
+ e._doNotDeleteOnDetach = true; // mark this as being added via addEndpoint.
+ }
+
+ return results.length == 1 ? results[0] : results;
+ };
+
+
+ this.addEndpoints = function(el, endpoints, referenceParams) {
+ var results = [];
+ for ( var i = 0, j = endpoints.length; i < j; i++) {
+ var e = _currentInstance.addEndpoint(el, endpoints[i], referenceParams);
+ if (_ju.isArray(e))
+ Array.prototype.push.apply(results, e);
+ else results.push(e);
+ }
+ return results;
+ };
+
+ this.animate = function(el, properties, options) {
+ options = options || {};
+ var ele = _gel(el),
+ id = _getId(el),
+ stepFunction = jsPlumb.CurrentLibrary.dragEvents.step,
+ completeFunction = jsPlumb.CurrentLibrary.dragEvents.complete;
+
+ options[stepFunction] = _ju.wrap(options[stepFunction], function() {
+ _currentInstance.repaint(id);
+ });
+
+ // onComplete repaints, just to make sure everything looks good at the end of the animation.
+ options[completeFunction] = _ju.wrap(options[completeFunction], function() {
+ _currentInstance.repaint(id);
+ });
+
+ jsPlumb.CurrentLibrary.animate(ele, properties, options);
+ };
+
+ /**
+ * checks for a listener for the given condition, executing it if found, passing in the given value.
+ * condition listeners would have been attached using "bind" (which is, you could argue, now overloaded, since
+ * firing click events etc is a bit different to what this does). i thought about adding a "bindCondition"
+ * or something, but decided against it, for the sake of simplicity. jsPlumb will never fire one of these
+ * condition events anyway.
+ */
+ this.checkCondition = function(conditionName, value) {
+ var l = _currentInstance.getListener(conditionName),
+ r = true;
+
+ if (l && l.length > 0) {
+ try {
+ for (var i = 0, j = l.length; i < j; i++) {
+ r = r && l[i](value);
+ }
+ }
+ catch (e) {
+ _ju.log(_currentInstance, "cannot check condition [" + conditionName + "]" + e);
+ }
+ }
+ return r;
+ };
+
+ /**
+ * checks a condition asynchronously: fires the event handler and passes the handler
+ * a 'proceed' function and a 'stop' function. The handler MUST execute one or other
+ * of these once it has made up its mind.
+ *
+ * Note that although this reads the listener list for the given condition, it
+ * does not loop through and hit each listener, because that, with asynchronous
+ * callbacks, would be messy. so it uses only the first listener registered.
+ */
+ this.checkASyncCondition = function(conditionName, value, proceed, stop) {
+ var l = _currentInstance.getListener(conditionName);
+
+ if (l && l.length > 0) {
+ try {
+ l[0](value, proceed, stop);
+ }
+ catch (e) {
+ _ju.log(_currentInstance, "cannot asynchronously check condition [" + conditionName + "]" + e);
+ }
+ }
+ };
+
+
+ this.connect = function(params, referenceParams) {
+ // prepare a final set of parameters to create connection with
+ var _p = _prepareConnectionParams(params, referenceParams), jpc;
+ // TODO probably a nicer return value if the connection was not made. _prepareConnectionParams
+ // will return null (and log something) if either endpoint was full. what would be nicer is to
+ // create a dedicated 'error' object.
+ if (_p) {
+ // create the connection. it is not yet registered
+ jpc = _newConnection(_p);
+ // now add it the model, fire an event, and redraw
+ _finaliseConnection(jpc, _p);
+ }
+ return jpc;
+ };
+
+ this.deleteEndpoint = function(object, doNotRepaintAfterwards) {
+ var _is = _currentInstance.setSuspendDrawing(true);
+ var endpoint = (typeof object == "string") ? endpointsByUUID[object] : object;
+ if (endpoint) {
+ _currentInstance.deleteObject({endpoint:endpoint});
+ }
+ if(!_is) _currentInstance.setSuspendDrawing(false, doNotRepaintAfterwards);
+ return _currentInstance;
+ };
+
+
+ this.deleteEveryEndpoint = function() {
+ var _is = _currentInstance.setSuspendDrawing(true);
+ for ( var id in endpointsByElement) {
+ var endpoints = endpointsByElement[id];
+ if (endpoints && endpoints.length) {
+ for ( var i = 0, j = endpoints.length; i < j; i++) {
+ _currentInstance.deleteEndpoint(endpoints[i], true);
+ }
+ }
+ }
+ endpointsByElement = {};
+ endpointsByUUID = {};
+ _currentInstance.anchorManager.reset();
+ _currentInstance.dragManager.reset();
+ if(!_is) _currentInstance.setSuspendDrawing(false);
+ return _currentInstance;
+ };
+
+ var fireDetachEvent = function(jpc, doFireEvent, originalEvent) {
+ // may have been given a connection, or in special cases, an object
+ var connType = _currentInstance.Defaults.ConnectionType || _currentInstance.getDefaultConnectionType(),
+ argIsConnection = jpc.constructor == connType,
+ params = argIsConnection ? {
+ connection:jpc,
+ source : jpc.source, target : jpc.target,
+ sourceId : jpc.sourceId, targetId : jpc.targetId,
+ sourceEndpoint : jpc.endpoints[0], targetEndpoint : jpc.endpoints[1]
+ } : jpc;
+
+ if (doFireEvent)
+ _currentInstance.fire("connectionDetached", params, originalEvent);
+
+ _currentInstance.anchorManager.connectionDetached(params);
+ };
+
+ this.unregisterEndpoint = function(endpoint) {
+ if (endpoint._jsPlumb.uuid) endpointsByUUID[endpoint._jsPlumb.uuid] = null;
+ _currentInstance.anchorManager.deleteEndpoint(endpoint);
+ // TODO at least replace this with a removeWithFunction call.
+ for (var e in endpointsByElement) {
+ var endpoints = endpointsByElement[e];
+ if (endpoints) {
+ var newEndpoints = [];
+ for (var i = 0, j = endpoints.length; i < j; i++)
+ if (endpoints[i] != endpoint) newEndpoints.push(endpoints[i]);
+
+ endpointsByElement[e] = newEndpoints;
+ }
+ if(endpointsByElement[e].length <1){
+ delete endpointsByElement[e];
+ }
+ }
+ };
+
+ this.detach = function() {
+
+ if (arguments.length === 0) return;
+ var connType = _currentInstance.Defaults.ConnectionType || _currentInstance.getDefaultConnectionType(),
+ firstArgIsConnection = arguments[0].constructor == connType,
+ params = arguments.length == 2 ? firstArgIsConnection ? (arguments[1] || {}) : arguments[0] : arguments[0],
+ fireEvent = (params.fireEvent !== false),
+ forceDetach = params.forceDetach,
+ conn = firstArgIsConnection ? arguments[0] : params.connection;
+
+ if (conn) {
+ if (forceDetach || jsPlumbUtil.functionChain(true, false, [
+ [ conn.endpoints[0], "isDetachAllowed", [ conn ] ],
+ [ conn.endpoints[1], "isDetachAllowed", [ conn ] ],
+ [ conn, "isDetachAllowed", [ conn ] ],
+ [ _currentInstance, "checkCondition", [ "beforeDetach", conn ] ] ])) {
+
+ conn.endpoints[0].detach(conn, false, true, fireEvent);
+ }
+ }
+ else {
+ var _p = jsPlumb.extend( {}, params); // a backwards compatibility hack: source should be thought of as 'params' in this case.
+ // test for endpoint uuids to detach
+ if (_p.uuids) {
+ _getEndpoint(_p.uuids[0]).detachFrom(_getEndpoint(_p.uuids[1]), fireEvent);
+ } else if (_p.sourceEndpoint && _p.targetEndpoint) {
+ _p.sourceEndpoint.detachFrom(_p.targetEndpoint);
+ } else {
+ var sourceId = _getId(_dom(_p.source)),
+ targetId = _getId(_dom(_p.target));
+ _operation(sourceId, function(jpc) {
+ if ((jpc.sourceId == sourceId && jpc.targetId == targetId) || (jpc.targetId == sourceId && jpc.sourceId == targetId)) {
+ if (_currentInstance.checkCondition("beforeDetach", jpc)) {
+ jpc.endpoints[0].detach(jpc, false, true, fireEvent);
+ }
+ }
+ });
+ }
+ }
+ };
+
+ this.detachAllConnections = function(el, params) {
+ params = params || {};
+ el = _dom(el);
+ var id = _getId(el),
+ endpoints = endpointsByElement[id];
+ if (endpoints && endpoints.length) {
+ for ( var i = 0, j = endpoints.length; i < j; i++) {
+ endpoints[i].detachAll(params.fireEvent !== false);
+ }
+ }
+ return _currentInstance;
+ };
+
+ this.detachEveryConnection = function(params) {
+ params = params || {};
+ _currentInstance.doWhileSuspended(function() {
+ for ( var id in endpointsByElement) {
+ var endpoints = endpointsByElement[id];
+ if (endpoints && endpoints.length) {
+ for ( var i = 0, j = endpoints.length; i < j; i++) {
+ endpoints[i].detachAll(params.fireEvent !== false);
+ }
+ }
+ }
+ connections.splice(0);
+ });
+ return _currentInstance;
+ };
+
+ /// not public. but of course its exposed. how to change this.
+ this.deleteObject = function(params) {
+ var result = {
+ endpoints : {},
+ connections : {},
+ endpointCount:0,
+ connectionCount:0
+ },
+ fireEvent = params.fireEvent !== false,
+ deleteAttachedObjects = params.deleteAttachedObjects !== false;
+
+ var unravelConnection = function(connection) {
+ if(connection != null && result.connections[connection.id] == null) {
+ connection._jsPlumb && connection.setHover(false);
+ result.connections[connection.id] = connection;
+ result.connectionCount++;
+ if (deleteAttachedObjects) {
+ for (var j = 0; j < connection.endpoints.length; j++) {
+ if (connection.endpoints[j]._deleteOnDetach)
+ unravelEndpoint(connection.endpoints[j]);
+ }
+ }
+ }
+ };
+ var unravelEndpoint = function(endpoint) {
+ if(endpoint != null && result.endpoints[endpoint.id] == null) {
+ endpoint._jsPlumb && endpoint.setHover(false);
+ result.endpoints[endpoint.id] = endpoint;
+ result.endpointCount++;
+
+ if (deleteAttachedObjects) {
+ for (var i = 0; i < endpoint.connections.length; i++) {
+ var c = endpoint.connections[i];
+ unravelConnection(c);
+ }
+ }
+ }
+ };
+
+ if (params.connection)
+ unravelConnection(params.connection);
+ else unravelEndpoint(params.endpoint);
+
+ // loop through connections
+ for (var i in result.connections) {
+ var c = result.connections[i];
+ c.endpoints[0].detachFromConnection(c);
+ c.endpoints[1].detachFromConnection(c);
+ //_currentInstance.unregisterConnection(c);
+ jsPlumbUtil.removeWithFunction(connections, function(_c) {
+ return c.id == _c.id;
+ });
+ fireDetachEvent(c, fireEvent, params.originalEvent);
+ c.cleanup();
+ c.destroy();
+ }
+
+ // loop through endpoints
+ for (var j in result.endpoints) {
+ var e = result.endpoints[j];
+ _currentInstance.unregisterEndpoint(e);
+ // FIRE some endpoint deleted event?
+ e.cleanup();
+ e.destroy();
+ }
+
+ return result;
+ };
+
+ this.draggable = function(el, options) {
+ var i,j,ele;
+ // allows for array or jquery/mootools selector
+ if (typeof el == 'object' && el.length) {
+ for (i = 0, j = el.length; i < j; i++) {
+ ele = _dom(el[i]);
+ if (ele) _initDraggableIfNecessary(ele, true, options);
+ }
+ }
+ // allows for YUI selector
+ else if (el._nodes) { // TODO this is YUI specific; really the logic should be forced
+ // into the library adapters (for jquery and mootools aswell)
+ for (i = 0, j = el._nodes.length; i < j; i++) {
+ ele = _dom(el._nodes[i]);
+ if (ele) _initDraggableIfNecessary(ele, true, options);
+ }
+ }
+ else {
+ ele = _dom(el);
+ if (ele) _initDraggableIfNecessary(ele, true, options);
+ }
+ return _currentInstance;
+ };
+
+
+ // just a library-agnostic wrapper.
+ this.extend = function(o1, o2) {
+ return jsPlumb.CurrentLibrary.extend(o1, o2);
+ };
+
+ // helpers for select/selectEndpoints
+ var _setOperation = function(list, func, args, selector) {
+ for (var i = 0, j = list.length; i < j; i++) {
+ list[i][func].apply(list[i], args);
+ }
+ return selector(list);
+ },
+ _getOperation = function(list, func, args) {
+ var out = [];
+ for (var i = 0, j = list.length; i < j; i++) {
+ out.push([ list[i][func].apply(list[i], args), list[i] ]);
+ }
+ return out;
+ },
+ setter = function(list, func, selector) {
+ return function() {
+ return _setOperation(list, func, arguments, selector);
+ };
+ },
+ getter = function(list, func) {
+ return function() {
+ return _getOperation(list, func, arguments);
+ };
+ },
+ prepareList = function(input, doNotGetIds) {
+ var r = [];
+ if (input) {
+ if (typeof input == 'string') {
+ if (input === "*") return input;
+ r.push(input);
+ }
+ else {
+ input = _gel(input);
+ if (doNotGetIds) r = input;
+ else {
+ for (var i = 0, j = input.length; i < j; i++)
+ r.push(_info(input[i]).id);
+ }
+ }
+ }
+ return r;
+ },
+ filterList = function(list, value, missingIsFalse) {
+ if (list === "*") return true;
+ return list.length > 0 ? jsPlumbUtil.indexOf(list, value) != -1 : !missingIsFalse;
+ };
+
+ // get some connections, specifying source/target/scope
+ this.getConnections = function(options, flat) {
+ if (!options) {
+ options = {};
+ } else if (options.constructor == String) {
+ options = { "scope": options };
+ }
+ var scope = options.scope || _currentInstance.getDefaultScope(),
+ scopes = prepareList(scope, true),
+ sources = prepareList(options.source),
+ targets = prepareList(options.target),
+ results = (!flat && scopes.length > 1) ? {} : [],
+ _addOne = function(scope, obj) {
+ if (!flat && scopes.length > 1) {
+ var ss = results[scope];
+ if (ss == null) {
+ ss = results[scope] = [];
+ }
+ ss.push(obj);
+ } else results.push(obj);
+ };
+
+ for ( var j = 0, jj = connections.length; j < jj; j++) {
+ var c = connections[j];
+ if (filterList(scopes, c.scope) && filterList(sources, c.sourceId) && filterList(targets, c.targetId))
+ _addOne(c.scope, c);
+ }
+
+ return results;
+ };
+
+ var _curryEach = function(list, executor) {
+ return function(f) {
+ for (var i = 0, ii = list.length; i < ii; i++) {
+ f(list[i]);
+ }
+ return executor(list);
+ };
+ },
+ _curryGet = function(list) {
+ return function(idx) {
+ return list[idx];
+ };
+ };
+
+ var _makeCommonSelectHandler = function(list, executor) {
+ var out = {
+ length:list.length,
+ each:_curryEach(list, executor),
+ get:_curryGet(list)
+ },
+ setters = ["setHover", "removeAllOverlays", "setLabel", "addClass", "addOverlay", "removeOverlay",
+ "removeOverlays", "showOverlay", "hideOverlay", "showOverlays", "hideOverlays", "setPaintStyle",
+ "setHoverPaintStyle", "setSuspendEvents", "setParameter", "setParameters", "setVisible",
+ "repaint", "addType", "toggleType", "removeType", "removeClass", "setType", "bind", "unbind" ],
+
+ getters = ["getLabel", "getOverlay", "isHover", "getParameter", "getParameters", "getPaintStyle",
+ "getHoverPaintStyle", "isVisible", "hasType", "getType", "isSuspendEvents" ],
+ i, ii;
+
+ for (i = 0, ii = setters.length; i < ii; i++)
+ out[setters[i]] = setter(list, setters[i], executor);
+
+ for (i = 0, ii = getters.length; i < ii; i++)
+ out[getters[i]] = getter(list, getters[i]);
+
+ return out;
+ };
+
+ var _makeConnectionSelectHandler = function(list) {
+ var common = _makeCommonSelectHandler(list, _makeConnectionSelectHandler);
+ return jsPlumb.CurrentLibrary.extend(common, {
+ // setters
+ setDetachable:setter(list, "setDetachable", _makeConnectionSelectHandler),
+ setReattach:setter(list, "setReattach", _makeConnectionSelectHandler),
+ setConnector:setter(list, "setConnector", _makeConnectionSelectHandler),
+ detach:function() {
+ for (var i = 0, ii = list.length; i < ii; i++)
+ _currentInstance.detach(list[i]);
+ },
+ // getters
+ isDetachable:getter(list, "isDetachable"),
+ isReattach:getter(list, "isReattach")
+ });
+ };
+
+ var _makeEndpointSelectHandler = function(list) {
+ var common = _makeCommonSelectHandler(list, _makeEndpointSelectHandler);
+ return jsPlumb.CurrentLibrary.extend(common, {
+ setEnabled:setter(list, "setEnabled", _makeEndpointSelectHandler),
+ setAnchor:setter(list, "setAnchor", _makeEndpointSelectHandler),
+ isEnabled:getter(list, "isEnabled"),
+ detachAll:function() {
+ for (var i = 0, ii = list.length; i < ii; i++)
+ list[i].detachAll();
+ },
+ "remove":function() {
+ for (var i = 0, ii = list.length; i < ii; i++)
+ _currentInstance.deleteObject({endpoint:list[i]});
+ }
+ });
+ };
+
+
+ this.select = function(params) {
+ params = params || {};
+ params.scope = params.scope || "*";
+ return _makeConnectionSelectHandler(params.connections || _currentInstance.getConnections(params, true));
+ };
+
+ this.selectEndpoints = function(params) {
+ params = params || {};
+ params.scope = params.scope || "*";
+ var noElementFilters = !params.element && !params.source && !params.target,
+ elements = noElementFilters ? "*" : prepareList(params.element),
+ sources = noElementFilters ? "*" : prepareList(params.source),
+ targets = noElementFilters ? "*" : prepareList(params.target),
+ scopes = prepareList(params.scope, true);
+
+ var ep = [];
+
+ for (var el in endpointsByElement) {
+ var either = filterList(elements, el, true),
+ source = filterList(sources, el, true),
+ sourceMatchExact = sources != "*",
+ target = filterList(targets, el, true),
+ targetMatchExact = targets != "*";
+
+ // if they requested 'either' then just match scope. otherwise if they requested 'source' (not as a wildcard) then we have to match only endpoints that have isSource set to to true, and the same thing with isTarget.
+ if ( either || source || target ) {
+ inner:
+ for (var i = 0, ii = endpointsByElement[el].length; i < ii; i++) {
+ var _ep = endpointsByElement[el][i];
+ if (filterList(scopes, _ep.scope, true)) {
+
+ var noMatchSource = (sourceMatchExact && sources.length > 0 && !_ep.isSource),
+ noMatchTarget = (targetMatchExact && targets.length > 0 && !_ep.isTarget);
+
+ if (noMatchSource || noMatchTarget)
+ continue inner;
+
+ ep.push(_ep);
+ }
+ }
+ }
+ }
+
+ return _makeEndpointSelectHandler(ep);
+ };
+
+ // get all connections managed by the instance of jsplumb.
+ this.getAllConnections = function() { return connections; };
+ this.getDefaultScope = function() { return DEFAULT_SCOPE; };
+ // get an endpoint by uuid.
+ this.getEndpoint = _getEndpoint;
+ // get endpoints for some element.
+ this.getEndpoints = function(el) { return endpointsByElement[_info(el).id]; };
+ // gets the default endpoint type. used when subclassing. see wiki.
+ this.getDefaultEndpointType = function() { return jsPlumb.Endpoint; };
+ // gets the default connection type. used when subclassing. see wiki.
+ this.getDefaultConnectionType = function() { return jsPlumb.Connection; };
+ /*
+ * Gets an element's id, creating one if necessary. really only exposed
+ * for the lib-specific functionality to access; would be better to pass
+ * the current instance into the lib-specific code (even though this is
+ * a static call. i just don't want to expose it to the public API).
+ */
+ this.getId = _getId;
+ this.getOffset = function(id) {
+ var o = offsets[id];
+ return _updateOffset({elId:id});
+ };
+
+ this.getSelector = function() {
+ return jsPlumb.CurrentLibrary.getSelector.apply(null, arguments);
+ };
+
+ // get the size of the element with the given id, perhaps from cache.
+ this.getSize = function(id) {
+ var s = sizes[id];
+ if (!s) _updateOffset({elId:id});
+ return sizes[id];
+ };
+
+ this.appendElement = _appendElement;
+
+ var _hoverSuspended = false;
+ this.isHoverSuspended = function() { return _hoverSuspended; };
+ this.setHoverSuspended = function(s) { _hoverSuspended = s; };
+
+ var _isAvailable = function(m) {
+ return function() {
+ return jsPlumbAdapter.isRenderModeAvailable(m);
+ };
+ };
+ this.isCanvasAvailable = _isAvailable("canvas");
+ this.isSVGAvailable = _isAvailable("svg");
+ this.isVMLAvailable = _isAvailable("vml");
+
+ // set an element's connections to be hidden
+ this.hide = function(el, changeEndpoints) {
+ _setVisible(el, "none", changeEndpoints);
+ return _currentInstance;
+ };
+
+ // exposed for other objects to use to get a unique id.
+ this.idstamp = _idstamp;
+
+ this.connectorsInitialized = false;
+ var connectorTypes = [], rendererTypes = ["canvas", "svg", "vml"];
+ this.registerConnectorType = function(connector, name) {
+ connectorTypes.push([connector, name]);
+ };
+
+ /**
+ * callback from the current library to tell us to prepare ourselves (attach
+ * mouse listeners etc; can't do that until the library has provided a bind method)
+ */
+ this.init = function() {
+ var _oneType = function(renderer, name, fn) {
+ jsPlumb.Connectors[renderer][name] = function() {
+ fn.apply(this, arguments);
+ jsPlumb.ConnectorRenderers[renderer].apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors[renderer][name], [ fn, jsPlumb.ConnectorRenderers[renderer]]);
+ };
+
+ if (!jsPlumb.connectorsInitialized) {
+ for (var i = 0; i < connectorTypes.length; i++) {
+ for (var j = 0; j < rendererTypes.length; j++) {
+ _oneType(rendererTypes[j], connectorTypes[i][1], connectorTypes[i][0]);
+ }
+
+ }
+ jsPlumb.connectorsInitialized = true;
+ }
+
+ if (!initialized) {
+ _currentInstance.anchorManager = new jsPlumb.AnchorManager({jsPlumbInstance:_currentInstance});
+ _currentInstance.setRenderMode(_currentInstance.Defaults.RenderMode); // calling the method forces the capability logic to be run.
+ initialized = true;
+ _currentInstance.fire("ready", _currentInstance);
+ }
+ }.bind(this);
+
+ this.log = log;
+ this.jsPlumbUIComponent = jsPlumbUIComponent;
+
+ /*
+ * Creates an anchor with the given params.
+ *
+ *
+ * Returns: The newly created Anchor.
+ * Throws: an error if a named anchor was not found.
+ */
+ this.makeAnchor = function() {
+ var _a = function(t, p) {
+ if (jsPlumb.Anchors[t]) return new jsPlumb.Anchors[t](p);
+ if (!_currentInstance.Defaults.DoNotThrowErrors)
+ throw { msg:"jsPlumb: unknown anchor type '" + t + "'" };
+ };
+ if (arguments.length === 0) return null;
+ var specimen = arguments[0], elementId = arguments[1], jsPlumbInstance = arguments[2], newAnchor = null;
+ // if it appears to be an anchor already...
+ if (specimen.compute && specimen.getOrientation) return specimen; //TODO hazy here about whether it should be added or is already added somehow.
+ // is it the name of an anchor type?
+ else if (typeof specimen == "string") {
+ newAnchor = _a(arguments[0], {elementId:elementId, jsPlumbInstance:_currentInstance});
+ }
+ // is it an array? it will be one of:
+ // an array of [name, params] - this defines a single anchor
+ // an array of arrays - this defines some dynamic anchors
+ // an array of numbers - this defines a single anchor.
+ else if (_ju.isArray(specimen)) {
+ if (_ju.isArray(specimen[0]) || _ju.isString(specimen[0])) {
+ if (specimen.length == 2 && _ju.isString(specimen[0]) && _ju.isObject(specimen[1])) {
+ var pp = jsPlumb.extend({elementId:elementId, jsPlumbInstance:_currentInstance}, specimen[1]);
+ newAnchor = _a(specimen[0], pp);
+ }
+ else
+ newAnchor = new jsPlumb.DynamicAnchor({anchors:specimen, selector:null, elementId:elementId, jsPlumbInstance:jsPlumbInstance});
+ }
+ else {
+ var anchorParams = {
+ x:specimen[0], y:specimen[1],
+ orientation : (specimen.length >= 4) ? [ specimen[2], specimen[3] ] : [0,0],
+ offsets : (specimen.length >= 6) ? [ specimen[4], specimen[5] ] : [ 0, 0 ],
+ elementId:elementId,
+ jsPlumbInstance:jsPlumbInstance,
+ cssClass:specimen.length == 7 ? specimen[6] : null
+ };
+ newAnchor = new jsPlumb.Anchor(anchorParams);
+ newAnchor.clone = function() { return new jsPlumb.Anchor(anchorParams); };
+ }
+ }
+
+ if (!newAnchor.id) newAnchor.id = "anchor_" + _idstamp();
+ return newAnchor;
+ };
+
+ /**
+ * makes a list of anchors from the given list of types or coords, eg
+ * ["TopCenter", "RightMiddle", "BottomCenter", [0, 1, -1, -1] ]
+ */
+ this.makeAnchors = function(types, elementId, jsPlumbInstance) {
+ var r = [];
+ for ( var i = 0, ii = types.length; i < ii; i++) {
+ if (typeof types[i] == "string")
+ r.push(jsPlumb.Anchors[types[i]]({elementId:elementId, jsPlumbInstance:jsPlumbInstance}));
+ else if (_ju.isArray(types[i]))
+ r.push(_currentInstance.makeAnchor(types[i], elementId, jsPlumbInstance));
+ }
+ return r;
+ };
+
+ /**
+ * Makes a dynamic anchor from the given list of anchors (which may be in shorthand notation as strings or dimension arrays, or Anchor
+ * objects themselves) and the given, optional, anchorSelector function (jsPlumb uses a default if this is not provided; most people will
+ * not need to provide this - i think).
+ */
+ this.makeDynamicAnchor = function(anchors, anchorSelector) {
+ return new jsPlumb.DynamicAnchor({anchors:anchors, selector:anchorSelector, elementId:null, jsPlumbInstance:_currentInstance});
+ };
+
+// --------------------- makeSource/makeTarget ----------------------------------------------
+
+ var _targetEndpointDefinitions = {},
+ _targetEndpoints = {},
+ _targetEndpointsUnique = {},
+ _targetMaxConnections = {},
+ _setEndpointPaintStylesAndAnchor = function(ep, epIndex) {
+ ep.paintStyle = ep.paintStyle ||
+ _currentInstance.Defaults.EndpointStyles[epIndex] ||
+ _currentInstance.Defaults.EndpointStyle ||
+ jsPlumb.Defaults.EndpointStyles[epIndex] ||
+ jsPlumb.Defaults.EndpointStyle;
+ ep.hoverPaintStyle = ep.hoverPaintStyle ||
+ _currentInstance.Defaults.EndpointHoverStyles[epIndex] ||
+ _currentInstance.Defaults.EndpointHoverStyle ||
+ jsPlumb.Defaults.EndpointHoverStyles[epIndex] ||
+ jsPlumb.Defaults.EndpointHoverStyle;
+
+ ep.anchor = ep.anchor ||
+ _currentInstance.Defaults.Anchors[epIndex] ||
+ _currentInstance.Defaults.Anchor ||
+ jsPlumb.Defaults.Anchors[epIndex] ||
+ jsPlumb.Defaults.Anchor;
+
+ ep.endpoint = ep.endpoint ||
+ _currentInstance.Defaults.Endpoints[epIndex] ||
+ _currentInstance.Defaults.Endpoint ||
+ jsPlumb.Defaults.Endpoints[epIndex] ||
+ jsPlumb.Defaults.Endpoint;
+ },
+ // TODO put all the source stuff inside one parent, keyed by id.
+ _sourceEndpointDefinitions = {},
+ _sourceEndpoints = {},
+ _sourceEndpointsUnique = {},
+ _sourcesEnabled = {},
+ _sourceTriggers = {},
+ _sourceMaxConnections = {},
+ _targetsEnabled = {},
+ selectorFilter = function(evt, _el, selector) {
+ var t = evt.target || evt.srcElement, ok = false,
+ sel = _currentInstance.getSelector(_el, selector);
+ for (var j = 0; j < sel.length; j++) {
+ if (sel[j] == t) {
+ ok = true;
+ break;
+ }
+ }
+ return ok;
+ };
+
+ // see API docs
+ this.makeTarget = function(el, params, referenceParams) {
+
+ // put jsplumb ref into params without altering the params passed in
+ var p = jsPlumb.extend({_jsPlumb:_currentInstance}, referenceParams);
+ jsPlumb.extend(p, params);
+
+ // calculate appropriate paint styles and anchor from the params given
+ _setEndpointPaintStylesAndAnchor(p, 1);
+
+ var jpcl = jsPlumb.CurrentLibrary,
+ targetScope = p.scope || _currentInstance.Defaults.Scope,
+ deleteEndpointsOnDetach = !(p.deleteEndpointsOnDetach === false),
+ maxConnections = p.maxConnections || -1,
+ onMaxConnections = p.onMaxConnections;
+
+ _doOne = function(el) {
+
+ // get the element's id and store the endpoint definition for it. jsPlumb.connect calls will look for one of these,
+ // and use the endpoint definition if found.
+ // decode the info for this element (id and element)
+ var elInfo = _info(el),
+ elid = elInfo.id,
+ proxyComponent = new jsPlumbUIComponent(p),
+ dropOptions = jsPlumb.extend({}, p.dropOptions || {});
+
+ // store the definitions keyed against the element id.
+ _targetEndpointDefinitions[elid] = p;
+ _targetEndpointsUnique[elid] = p.uniqueEndpoint;
+ _targetMaxConnections[elid] = maxConnections;
+ _targetsEnabled[elid] = true;
+
+ var _drop = function() {
+ _currentInstance.currentlyDragging = false;
+ var originalEvent = jsPlumb.CurrentLibrary.getDropEvent(arguments),
+ targetCount = _currentInstance.select({target:elid}).length,
+ draggable = _gel(jpcl.getDragObject(arguments)),
+ id = _currentInstance.getAttribute(draggable, "dragId"),
+ scope = _currentInstance.getAttribute(draggable, "originalScope"),
+ jpc = floatingConnections[id],
+ idx = jpc.endpoints[0].isFloating() ? 0 : 1,
+ // this is not necessarily correct. if the source is being dragged,
+ // then the source endpoint is actually the currently suspended endpoint.
+ source = jpc.endpoints[0],
+ _endpoint = p.endpoint ? jsPlumb.extend({}, p.endpoint) : {};
+
+ if (!_targetsEnabled[elid] || _targetMaxConnections[elid] > 0 && targetCount >= _targetMaxConnections[elid]){
+ if (onMaxConnections) {
+ // TODO here we still have the id of the floating element, not the
+ // actual target.
+ onMaxConnections({
+ element:elInfo.el,
+ connection:jpc
+ }, originalEvent);
+ }
+ return false;
+ }
+
+ // unlock the source anchor to allow it to refresh its position if necessary
+ source.anchor.locked = false;
+
+ // restore the original scope if necessary (issue 57)
+ if (scope) jpcl.setDragScope(draggable, scope);
+
+ // check if drop is allowed here.
+ // if the source is being dragged then in fact
+ // the source and target ids to pass into the drop interceptor are
+ // source - elid
+ // target - jpc's targetId
+ //
+ // otherwise the ids are
+ // source - jpc.sourceId
+ // target - elid
+ //
+ var _continue = proxyComponent.isDropAllowed(idx === 0 ? elid : jpc.sourceId, idx === 0 ? jpc.targetId : elid, jpc.scope, jpc, null);
+
+ // reinstate any suspended endpoint; this just puts the connection back into
+ // a state in which it will report sensible values if someone asks it about
+ // its target. we're going to throw this connection away shortly so it doesnt matter
+ // if we manipulate it a bit.
+ if (jpc.suspendedEndpoint) {
+ jpc[idx ? "targetId" : "sourceId"] = jpc.suspendedEndpoint.elementId;
+ jpc[idx ? "target" : "source"] = jpc.suspendedEndpoint.element;
+ jpc.endpoints[idx] = jpc.suspendedEndpoint;
+ }
+
+ if (_continue) {
+
+ // make a new Endpoint for the target
+ var _el = jpcl.getElementObject(elInfo.el),
+ newEndpoint = _targetEndpoints[elid] || _currentInstance.addEndpoint(_el, p);
+
+ if (p.uniqueEndpoint) _targetEndpoints[elid] = newEndpoint; // may of course just store what it just pulled out. that's ok.
+ // TODO test options to makeTarget to see if we should do this?
+ newEndpoint._doNotDeleteOnDetach = false; // reset.
+ newEndpoint._deleteOnDetach = true;
+
+ // if the anchor has a 'positionFinder' set, then delegate to that function to find
+ // out where to locate the anchor.
+ if (newEndpoint.anchor.positionFinder != null) {
+ var dropPosition = jpcl.getUIPosition(arguments, _currentInstance.getZoom()),
+ elPosition = _getOffset(_el, _currentInstance),
+ elSize = _getSize(_el),
+ ap = newEndpoint.anchor.positionFinder(dropPosition, elPosition, elSize, newEndpoint.anchor.constructorParams);
+ newEndpoint.anchor.x = ap[0];
+ newEndpoint.anchor.y = ap[1];
+ // now figure an orientation for it..kind of hard to know what to do actually. probably the best thing i can do is to
+ // support specifying an orientation in the anchor's spec. if one is not supplied then i will make the orientation
+ // be what will cause the most natural link to the source: it will be pointing at the source, but it needs to be
+ // specified in one axis only, and so how to make that choice? i think i will use whichever axis is the one in which
+ // the target is furthest away from the source.
+ }
+
+ // change the target endpoint and target element information. really this should be
+ // done on a method on connection
+ jpc[idx ? "target" : "source"] = newEndpoint.element;
+ jpc[idx ? "targetId" : "sourceId"] = newEndpoint.elementId;
+ jpc.endpoints[idx].detachFromConnection(jpc);
+ if (jpc.endpoints[idx]._deleteOnDetach)
+ jpc.endpoints[idx].deleteAfterDragStop = true; // tell this endpoint to delet itself after drag stop.
+ // set new endpoint, and configure the settings for endpoints to delete on detach
+ newEndpoint.addConnection(jpc);
+ jpc.endpoints[idx] = newEndpoint;
+ jpc.deleteEndpointsOnDetach = deleteEndpointsOnDetach;
+
+ // inform the anchor manager to update its target endpoint for this connection.
+ // TODO refactor to make this a single method.
+ if (idx == 1)
+ _currentInstance.anchorManager.updateOtherEndpoint(jpc.sourceId, jpc.suspendedElementId, jpc.targetId, jpc);
+ else
+ _currentInstance.anchorManager.sourceChanged(jpc.suspendedEndpoint.elementId, jpc.sourceId, jpc);
+
+ _finaliseConnection(jpc, null, originalEvent);
+
+ }
+ // if not allowed to drop...
+ else {
+ // TODO this code is identical (pretty much) to what happens when a connection
+ // dragged from a normal endpoint is in this situation. refactor.
+ // is this an existing connection, and will we reattach?
+ // TODO also this assumes the source needs to detach - is that always valid?
+ if (jpc.suspendedEndpoint) {
+ if (jpc.isReattach()) {
+ jpc.setHover(false);
+ jpc.floatingAnchorIndex = null;
+ jpc.suspendedEndpoint.addConnection(jpc);
+ _currentInstance.repaint(source.elementId);
+ }
+ else
+ source.detach(jpc, false, true, true, originalEvent); // otherwise, detach the connection and tell everyone about it.
+ }
+
+ }
+ };
+
+ // wrap drop events as needed and initialise droppable
+ var dropEvent = jpcl.dragEvents.drop;
+ dropOptions.scope = dropOptions.scope || targetScope;
+ dropOptions[dropEvent] = _ju.wrap(dropOptions[dropEvent], _drop);
+ jpcl.initDroppable(_gel(elInfo.el), dropOptions, true);
+ };
+
+ // YUI collection fix
+ el = _convertYUICollection(el);
+ // make an array if only given one element
+ var inputs = el.length && el.constructor != String ? el : [ el ];
+
+ // register each one in the list.
+ for (var i = 0, ii = inputs.length; i < ii; i++) {
+ _doOne(inputs[i]);
+ }
+
+ return _currentInstance;
+ };
+
+ // see api docs
+ this.unmakeTarget = function(el, doNotClearArrays) {
+ var info = _info(el);
+
+ jsPlumb.CurrentLibrary.destroyDroppable(info.el);
+ // TODO this is not an exhaustive unmake of a target, since it does not remove the droppable stuff from
+ // the element. the effect will be to prevent it from behaving as a target, but it's not completely purged.
+ if (!doNotClearArrays) {
+ delete _targetEndpointDefinitions[info.id];
+ delete _targetEndpointsUnique[info.id];
+ delete _targetMaxConnections[info.id];
+ delete _targetsEnabled[info.id];
+ }
+
+ return _currentInstance;
+ };
+
+ // see api docs
+ this.makeSource = function(el, params, referenceParams) {
+ var p = jsPlumb.extend({}, referenceParams);
+ jsPlumb.extend(p, params);
+ _setEndpointPaintStylesAndAnchor(p, 0);
+ var jpcl = jsPlumb.CurrentLibrary,
+ maxConnections = p.maxConnections || -1,
+ onMaxConnections = p.onMaxConnections,
+ _doOne = function(elInfo) {
+ // get the element's id and store the endpoint definition for it. jsPlumb.connect calls will look for one of these,
+ // and use the endpoint definition if found.
+ var elid = elInfo.id,
+ _el = _gel(elInfo.el),
+ parentElement = function() {
+ return p.parent == null ? null : p.parent === "parent" ? elInfo.el.parentNode : _dom(p.parent);
+ },
+ idToRegisterAgainst = p.parent != null ? _currentInstance.getId(parentElement()) : elid;
+
+ _sourceEndpointDefinitions[idToRegisterAgainst] = p;
+ _sourceEndpointsUnique[idToRegisterAgainst] = p.uniqueEndpoint;
+ _sourcesEnabled[idToRegisterAgainst] = true;
+
+ var stopEvent = jpcl.dragEvents.stop,
+ dragEvent = jpcl.dragEvents.drag,
+ dragOptions = jsPlumb.extend({ }, p.dragOptions || {}),
+ existingDrag = dragOptions.drag,
+ existingStop = dragOptions.stop,
+ ep = null,
+ endpointAddedButNoDragYet = false;
+
+ _sourceMaxConnections[idToRegisterAgainst] = maxConnections;
+
+ // set scope if its not set in dragOptions but was passed in in params
+ dragOptions.scope = dragOptions.scope || p.scope;
+
+ dragOptions[dragEvent] = _ju.wrap(dragOptions[dragEvent], function() {
+ if (existingDrag) existingDrag.apply(this, arguments);
+ endpointAddedButNoDragYet = false;
+ });
+
+ dragOptions[stopEvent] = _ju.wrap(dragOptions[stopEvent], function() {
+
+ if (existingStop) existingStop.apply(this, arguments);
+ _currentInstance.currentlyDragging = false;
+ if (ep._jsPlumb != null) { // if not cleaned up...
+
+ jpcl.unbind(ep.canvas, "mousedown");
+
+ // reset the anchor to the anchor that was initially provided. the one we were using to drag
+ // the connection was just a placeholder that was located at the place the user pressed the
+ // mouse button to initiate the drag.
+ var anchorDef = p.anchor || _currentInstance.Defaults.Anchor,
+ oldAnchor = ep.anchor,
+ oldConnection = ep.connections[0];
+
+ ep.setAnchor(_currentInstance.makeAnchor(anchorDef, elid, _currentInstance), true);
+
+ if (p.parent) {
+ var parent = parentElement();
+ if (parent) {
+ var currentId = ep.elementId,
+ potentialParent = p.container || _currentInstance.Defaults.Container || jsPlumb.Defaults.Container;
+
+ ep.setElement(parent, potentialParent);
+ ep.endpointWillMoveAfterConnection = false;
+ //_currentInstance.anchorManager.rehomeEndpoint(ep, currentId, parent);
+ oldConnection.previousConnection = null;
+ // remove from connectionsByScope
+ jsPlumbUtil.removeWithFunction(connections, function(c) {
+ return c.id === oldConnection.id;
+ });
+ _currentInstance.anchorManager.connectionDetached({
+ sourceId:oldConnection.sourceId,
+ targetId:oldConnection.targetId,
+ connection:oldConnection
+ });
+ _finaliseConnection(oldConnection);
+ }
+ }
+
+ ep.repaint();
+ _currentInstance.repaint(ep.elementId);
+ _currentInstance.repaint(oldConnection.targetId);
+ }
+ });
+ // when the user presses the mouse, add an Endpoint, if we are enabled.
+ var mouseDownListener = function(e) {
+
+ // if disabled, return.
+ if (!_sourcesEnabled[idToRegisterAgainst]) return;
+
+ // if a filter was given, run it, and return if it says no.
+ if (p.filter) {
+ var evt = jpcl.getOriginalEvent(e),
+ r = jsPlumbUtil.isString(p.filter) ? selectorFilter(evt, _el, p.filter) : p.filter(evt, _el);
+
+ if (r === false) return;
+ }
+
+ // if maxConnections reached
+ var sourceCount = _currentInstance.select({source:idToRegisterAgainst}).length;
+ if (_sourceMaxConnections[idToRegisterAgainst] >= 0 && sourceCount >= _sourceMaxConnections[idToRegisterAgainst]) {
+ if (onMaxConnections) {
+ onMaxConnections({
+ element:_el,
+ maxConnections:maxConnections
+ }, e);
+ }
+ return false;
+ }
+
+ // make sure we have the latest offset for this div
+ var myOffsetInfo = _updateOffset({elId:elid}).o,
+ z = _currentInstance.getZoom(),
+ x = ( ((e.pageX || e.page.x) / z) - myOffsetInfo.left) / myOffsetInfo.width,
+ y = ( ((e.pageY || e.page.y) / z) - myOffsetInfo.top) / myOffsetInfo.height,
+ parentX = x,
+ parentY = y;
+
+ // if there is a parent, the endpoint will actually be added to it now, rather than the div
+ // that was the source. in that case, we have to adjust the anchor position so it refers to
+ // the parent.
+ if (p.parent) {
+ var pEl = parentElement(), pId = _getId(pEl);
+ myOffsetInfo = _updateOffset({elId:pId}).o;
+ parentX = ((e.pageX || e.page.x) - myOffsetInfo.left) / myOffsetInfo.width;
+ parentY = ((e.pageY || e.page.y) - myOffsetInfo.top) / myOffsetInfo.height;
+ }
+
+ // we need to override the anchor in here, and force 'isSource', but we don't want to mess with
+ // the params passed in, because after a connection is established we're going to reset the endpoint
+ // to have the anchor we were given.
+ var tempEndpointParams = {};
+ jsPlumb.extend(tempEndpointParams, p);
+ tempEndpointParams.isSource = true;
+ tempEndpointParams.anchor = [x,y,0,0];
+ tempEndpointParams.parentAnchor = [ parentX, parentY, 0, 0 ];
+ tempEndpointParams.dragOptions = dragOptions;
+ // if a parent was given we need to turn that into a "container" argument. this is, by default,
+ // the parent of the element we will move to, so parent of p.parent in this case. however, if
+ // the user has specified a 'container' on the endpoint definition or on
+ // the defaults, we should use that.
+ if (p.parent) {
+ var potentialParent = tempEndpointParams.container || _currentInstance.Defaults.Container || jsPlumb.Defaults.Container;
+ if (potentialParent)
+ tempEndpointParams.container = potentialParent;
+ else
+ tempEndpointParams.container = jsPlumb.CurrentLibrary.getParent(parentElement());
+ }
+
+ ep = _currentInstance.addEndpoint(elid, tempEndpointParams);
+
+ endpointAddedButNoDragYet = true;
+ // we set this to prevent connections from firing attach events before this function has had a chance
+ // to move the endpoint.
+ ep.endpointWillMoveAfterConnection = p.parent != null;
+ ep.endpointWillMoveTo = p.parent ? parentElement() : null;
+
+ // TODO test options to makeSource to see if we should do this?
+ ep._doNotDeleteOnDetach = false; // reset.
+ ep._deleteOnDetach = true;
+
+ var _delTempEndpoint = function() {
+ // this mouseup event is fired only if no dragging occurred, by jquery and yui, but for mootools
+ // it is fired even if dragging has occurred, in which case we would blow away a perfectly
+ // legitimate endpoint, were it not for this check. the flag is set after adding an
+ // endpoint and cleared in a drag listener we set in the dragOptions above.
+ if(endpointAddedButNoDragYet) {
+ endpointAddedButNoDragYet = false;
+ _currentInstance.deleteEndpoint(ep);
+ }
+ };
+
+ _currentInstance.registerListener(ep.canvas, "mouseup", _delTempEndpoint);
+ _currentInstance.registerListener(_el, "mouseup", _delTempEndpoint);
+
+ // and then trigger its mousedown event, which will kick off a drag, which will start dragging
+ // a new connection from this endpoint.
+ jpcl.trigger(ep.canvas, "mousedown", e);
+
+ };
+
+ // register this on jsPlumb so that it can be cleared by a reset.
+ _currentInstance.registerListener(_el, "mousedown", mouseDownListener);
+ _sourceTriggers[elid] = mouseDownListener;
+
+ // lastly, if a filter was provided, set it as a dragFilter on the element,
+ // to prevent the element drag function from kicking in when we want to
+ // drag a new connection
+ if (p.filter && jsPlumbUtil.isString(p.filter)) {
+ jpcl.setDragFilter(_el, p.filter);
+ }
+ };
+
+ el = _convertYUICollection(el);
+
+ var inputs = el.length && el.constructor != String ? el : [ el ];
+
+ for (var i = 0, ii = inputs.length; i < ii; i++) {
+ _doOne(_info(inputs[i]));
+ }
+
+ return _currentInstance;
+ };
+
+ // see api docs
+ this.unmakeSource = function(el, doNotClearArrays) {
+ var info = _info(el),
+ mouseDownListener = _sourceTriggers[info.id];
+
+ if (mouseDownListener)
+ _currentInstance.unregisterListener(info.el, "mousedown", mouseDownListener);
+
+ if (!doNotClearArrays) {
+ delete _sourceEndpointDefinitions[info.id];
+ delete _sourceEndpointsUnique[info.id];
+ delete _sourcesEnabled[info.id];
+ delete _sourceTriggers[info.id];
+ delete _sourceMaxConnections[info.id];
+ }
+
+ return _currentInstance;
+ };
+
+ // see api docs
+ this.unmakeEverySource = function() {
+ for (var i in _sourcesEnabled)
+ _currentInstance.unmakeSource(i, true);
+
+ _sourceEndpointDefinitions = {};
+ _sourceEndpointsUnique = {};
+ _sourcesEnabled = {};
+ _sourceTriggers = {};
+ };
+
+ // see api docs
+ this.unmakeEveryTarget = function() {
+ for (var i in _targetsEnabled)
+ _currentInstance.unmakeTarget(i, true);
+
+ _targetEndpointDefinitions = {};
+ _targetEndpointsUnique = {};
+ _targetMaxConnections = {};
+ _targetsEnabled = {};
+
+ return _currentInstance;
+ };
+
+ // does the work of setting a source enabled or disabled.
+ var _setEnabled = function(type, el, state, toggle) {
+ var a = type == "source" ? _sourcesEnabled : _targetsEnabled;
+ el = _convertYUICollection(el);
+
+ if (_ju.isString(el)) a[el] = toggle ? !a[el] : state;
+ else if (el.length) {
+ for (var i = 0, ii = el.length; i < ii; i++) {
+ var info = _info(el[i]);
+ a[info.id] = toggle ? !a[info.id] : state;
+ }
+ }
+ return _currentInstance;
+ };
+
+ this.toggleSourceEnabled = function(el) {
+ _setEnabled("source", el, null, true);
+ return _currentInstance.isSourceEnabled(el);
+ };
+
+ this.setSourceEnabled = function(el, state) { return _setEnabled("source", el, state); };
+ this.isSource = function(el) { return _sourcesEnabled[_info(el).id] != null; };
+ this.isSourceEnabled = function(el) { return _sourcesEnabled[_info(el).id] === true; };
+
+ this.toggleTargetEnabled = function(el) {
+ _setEnabled("target", el, null, true);
+ return _currentInstance.isTargetEnabled(el);
+ };
+
+ this.isTarget = function(el) { return _targetsEnabled[_info(el).id] != null; };
+ this.isTargetEnabled = function(el) { return _targetsEnabled[_info(el).id] === true; };
+ this.setTargetEnabled = function(el, state) { return _setEnabled("target", el, state); };
+
+// --------------------- end makeSource/makeTarget ----------------------------------------------
+
+ this.ready = function(fn) {
+ _currentInstance.bind("ready", fn);
+ };
+
+ // repaint some element's endpoints and connections
+ this.repaint = function(el, ui, timestamp) {
+ // support both lists...
+ if (typeof el == 'object' && el.length)
+ for ( var i = 0, ii = el.length; i < ii; i++) {
+ _draw(el[i], ui, timestamp);
+ }
+ else // ...and single strings.
+ _draw(el, ui, timestamp);
+
+ return _currentInstance;
+ };
+
+ // repaint every endpoint and connection.
+ this.repaintEverything = function() {
+ // TODO this timestamp causes continuous anchors to not repaint properly.
+ // fix this. do not just take out the timestamp. it runs a lot faster with
+ // the timestamp included.
+ var timestamp = _timestamp();
+ for ( var elId in endpointsByElement) {
+ _draw(elId, null, timestamp);
+ }
+ return _currentInstance;
+ /*for (var i = 0; i < connections.length; i++)
+ connections[i].repaint({timestamp:timestamp});*/
+ };
+
+
+ this.removeAllEndpoints = function(el, recurse) {
+ var _one = function(_el) {
+ var info = _info(_el),
+ ebe = endpointsByElement[info.id],
+ i, ii;
+
+ if (ebe) {
+ for ( i = 0, ii = ebe.length; i < ii; i++)
+ _currentInstance.deleteEndpoint(ebe[i]);
+ }
+ delete endpointsByElement[info.id];
+
+ if (recurse) {
+ if (info.el && info.el.nodeType != 3 && info.el.nodeType != 8 ) {
+ for ( i = 0, ii = info.el.childNodes.length; i < ii; i++) {
+ _one(info.el.childNodes[i]);
+ }
+ }
+ }
+
+ };
+ _one(el);
+ return _currentInstance;
+ };
+
+ /**
+ * Remove the given element, including cleaning up all endpoints registered for it.
+ * This is exposed in the public API but also used internally by jsPlumb when removing the
+ * element associated with a connection drag.
+ */
+ this.remove = function(el, doNotRepaint) {
+ var info = _info(el);
+ _currentInstance.doWhileSuspended(function() {
+ _currentInstance.removeAllEndpoints(info.id, true);
+ _currentInstance.dragManager.elementRemoved(info.id);
+ delete floatingConnections[info.id];
+ _currentInstance.anchorManager.clearFor(info.id);
+ _currentInstance.anchorManager.removeFloatingConnection(info.id);
+ }, doNotRepaint === false);
+ if(info.el) jsPlumb.CurrentLibrary.removeElement(info.el);
+ };
+
+ var _registeredListeners = {},
+ _unbindRegisteredListeners = function() {
+ for (var i in _registeredListeners) {
+ for (var j = 0, jj = _registeredListeners[i].length; j < jj; j++) {
+ var info = _registeredListeners[i][j];
+ jsPlumb.CurrentLibrary.unbind(info.el, info.event, info.listener);
+ }
+ }
+ _registeredListeners = {};
+ };
+
+ // internal register listener method. gives us a hook to clean things up
+ // with if the user calls jsPlumb.reset.
+ this.registerListener = function(el, type, listener) {
+ jsPlumb.CurrentLibrary.bind(el, type, listener);
+ jsPlumbUtil.addToList(_registeredListeners, type, {el:el, event:type, listener:listener});
+ };
+
+ this.unregisterListener = function(el, type, listener) {
+ jsPlumb.CurrentLibrary.unbind(el, type, listener);
+ jsPlumbUtil.removeWithFunction(_registeredListeners, function(rl) {
+ return rl.type == type && rl.listener == listener;
+ });
+ };
+
+ this.reset = function() {
+ _currentInstance.deleteEveryEndpoint();
+ _currentInstance.unbind();
+ _targetEndpointDefinitions = {};
+ _targetEndpoints = {};
+ _targetEndpointsUnique = {};
+ _targetMaxConnections = {};
+ _sourceEndpointDefinitions = {};
+ _sourceEndpoints = {};
+ _sourceEndpointsUnique = {};
+ _sourceMaxConnections = {};
+ connections.splice(0);
+ _unbindRegisteredListeners();
+ _currentInstance.anchorManager.reset();
+ if (!jsPlumbAdapter.headless)
+ _currentInstance.dragManager.reset();
+ };
+
+
+ this.setDefaultScope = function(scope) {
+ DEFAULT_SCOPE = scope;
+ return _currentInstance;
+ };
+
+ // sets whether or not some element should be currently draggable.
+ this.setDraggable = _setDraggable;
+
+ // sets the id of some element, changing whatever we need to to keep track.
+ this.setId = function(el, newId, doNotSetAttribute) {
+ //
+ var id;
+
+ if (jsPlumbUtil.isString(el)) {
+ id = el;
+ }
+ else {
+ el = _dom(el);
+ id = _currentInstance.getId(el);
+ }
+
+ var sConns = _currentInstance.getConnections({source:id, scope:'*'}, true),
+ tConns = _currentInstance.getConnections({target:id, scope:'*'}, true);
+
+ newId = "" + newId;
+
+ if (!doNotSetAttribute) {
+ el = _dom(id);
+ jsPlumbAdapter.setAttribute(el, "id", newId);
+ }
+ else
+ el = _dom(newId);
+
+ endpointsByElement[newId] = endpointsByElement[id] || [];
+ for (var i = 0, ii = endpointsByElement[newId].length; i < ii; i++) {
+ endpointsByElement[newId][i].setElementId(newId);
+ endpointsByElement[newId][i].setReferenceElement(el);
+ }
+ delete endpointsByElement[id];
+
+ _currentInstance.anchorManager.changeId(id, newId);
+ if (!jsPlumbAdapter.headless)
+ _currentInstance.dragManager.changeId(id, newId);
+
+ var _conns = function(list, epIdx, type) {
+ for (var i = 0, ii = list.length; i < ii; i++) {
+ list[i].endpoints[epIdx].setElementId(newId);
+ list[i].endpoints[epIdx].setReferenceElement(el);
+ list[i][type + "Id"] = newId;
+ list[i][type] = el;
+ }
+ };
+ _conns(sConns, 0, "source");
+ _conns(tConns, 1, "target");
+
+ _currentInstance.repaint(newId);
+ };
+
+ this.setDebugLog = function(debugLog) {
+ log = debugLog;
+ };
+
+ this.setSuspendDrawing = function(val, repaintAfterwards) {
+ var curVal = _suspendDrawing;
+ _suspendDrawing = val;
+ if (val) _suspendedAt = new Date().getTime(); else _suspendedAt = null;
+ if (repaintAfterwards) _currentInstance.repaintEverything();
+ return curVal;
+ };
+
+ // returns whether or not drawing is currently suspended.
+ this.isSuspendDrawing = function() {
+ return _suspendDrawing;
+ };
+
+ // return timestamp for when drawing was suspended.
+ this.getSuspendedAt = function() { return _suspendedAt; };
+
+ /**
+ * @doc function
+ * @name jsPlumb.class:doWhileSuspended
+ * @param {function} fn Function to run while suspended.
+ * @param {boolean} doNotRepaintAfterwards If true, jsPlumb won't run a full repaint. Otherwise it will.
+ * @description Suspends drawing, runs the given function, then re-enables drawing (and repaints, unless you tell it not to)
+ */
+ this.doWhileSuspended = function(fn, doNotRepaintAfterwards) {
+ var _wasSuspended = _currentInstance.isSuspendDrawing();
+ if (!_wasSuspended)
+ _currentInstance.setSuspendDrawing(true);
+ try {
+ fn();
+ }
+ catch (e) {
+ _ju.log("Function run while suspended failed", e);
+ }
+ if (!_wasSuspended)
+ _currentInstance.setSuspendDrawing(false, !doNotRepaintAfterwards);
+ };
+
+ this.updateOffset = _updateOffset;
+ this.getOffset = function(elId) { return offsets[elId]; };
+ this.getSize = function(elId) { return sizes[elId]; };
+ this.getCachedData = _getCachedData;
+ this.timestamp = _timestamp;
+
+
+
+ /**
+ * @doc function
+ * @name jsPlumb.class:setRenderMode
+ * @param {string} mode One of `jsPlumb.SVG, `jsPlumb.VML` or `jsPlumb.CANVAS`.
+ * @description Sets render mode. jsPlumb will fall back to VML if it determines that
+ * what you asked for is not supported (and that VML is). If you asked for VML but the browser does
+ * not support it, jsPlumb uses SVG.
+ * @return {string} The render mode that jsPlumb set, which of course may be different from that requested.
+ */
+ this.setRenderMode = function(mode) {
+ renderMode = jsPlumbAdapter.setRenderMode(mode);
+ var i, ii;
+ // only add this if the renderer is canvas; we dont want these listeners registered on te
+ // entire document otherwise.
+ if (renderMode == jsPlumb.CANVAS) {
+ var bindOne = function(event) {
+ jsPlumb.CurrentLibrary.bind(document, event, function(e) {
+ if (!_currentInstance.currentlyDragging && renderMode == jsPlumb.CANVAS) {
+ // try connections first
+ for (i = 0, ii = connections.length; i < ii; i++ ) {
+ var t = connections[i].getConnector()[event](e);
+ if (t) return;
+ }
+ for (var el in endpointsByElement) {
+ var ee = endpointsByElement[el];
+ for ( i = 0, ii = ee.length; i < ii; i++ ) {
+ if (ee[i].endpoint[event] && ee[i].endpoint[event](e)) return;
+ }
+ }
+ }
+ });
+ };
+ bindOne("click");bindOne("dblclick");bindOne("mousemove");bindOne("mousedown");bindOne("mouseup");bindOne("contextmenu");
+ }
+
+ return renderMode;
+ };
+
+ /**
+ * @doc function
+ * @name jsPlumb.class:getRenderMode
+ * @description Gets the current render mode for this instance of jsPlumb.
+ * @return {string} The current render mode - "canvas", "svg" or "vml".
+ */
+ this.getRenderMode = function() { return renderMode; };
+
+ this.show = function(el, changeEndpoints) {
+ _setVisible(el, "block", changeEndpoints);
+ return _currentInstance;
+ };
+
+ /**
+ * gets some test hooks. nothing writable.
+ */
+ this.getTestHarness = function() {
+ return {
+ endpointsByElement : endpointsByElement,
+ endpointCount : function(elId) {
+ var e = endpointsByElement[elId];
+ return e ? e.length : 0;
+ },
+ connectionCount : function(scope) {
+ scope = scope || DEFAULT_SCOPE;
+ var c = _currentInstance.getConnections({scope:scope});
+ return c ? c.length : 0;
+ },
+ getId : _getId,
+ makeAnchor:self.makeAnchor,
+ makeDynamicAnchor:self.makeDynamicAnchor
+ };
+ };
+
+
+ // TODO: update this method to return the current state.
+ this.toggleVisible = _toggleVisible;
+ this.toggleDraggable = _toggleDraggable;
+ this.addListener = this.bind;
+
+ /*
+ helper method to take an xy location and adjust it for the parent's offset and scroll.
+ */
+ this.adjustForParentOffsetAndScroll = function(xy, el) {
+
+ var offsetParent = null, result = xy;
+ if (el.tagName.toLowerCase() === "svg" && el.parentNode) {
+ offsetParent = el.parentNode;
+ }
+ else if (el.offsetParent) {
+ offsetParent = el.offsetParent;
+ }
+ if (offsetParent != null) {
+ var po = offsetParent.tagName.toLowerCase() === "body" ? {left:0,top:0} : _getOffset(offsetParent, _currentInstance),
+ so = offsetParent.tagName.toLowerCase() === "body" ? {left:0,top:0} : {left:offsetParent.scrollLeft, top:offsetParent.scrollTop};
+
+ // i thought it might be cool to do this:
+ // lastReturnValue[0] = lastReturnValue[0] - offsetParent.offsetLeft + offsetParent.scrollLeft;
+ // lastReturnValue[1] = lastReturnValue[1] - offsetParent.offsetTop + offsetParent.scrollTop;
+ // but i think it ignores margins. my reasoning was that it's quicker to not hand off to some underlying
+ // library.
+
+ result[0] = xy[0] - po.left + so.left;
+ result[1] = xy[1] - po.top + so.top;
+ }
+
+ return result;
+
+ };
+
+ if (!jsPlumbAdapter.headless) {
+ _currentInstance.dragManager = jsPlumbAdapter.getDragManager(_currentInstance);
+ _currentInstance.recalculateOffsets = _currentInstance.dragManager.updateOffsets;
+ }
+
+ };
+
+ jsPlumbUtil.extend(jsPlumbInstance, jsPlumbUtil.EventGenerator, {
+ setAttribute : function(el, a, v) {
+ jsPlumbAdapter.setAttribute(el, a, v);
+ },
+ getAttribute : function(el, a) {
+ return jsPlumbAdapter.getAttribute(jsPlumb.CurrentLibrary.getDOMElement(el), a);
+ },
+ registerConnectionType : function(id, type) {
+ this._connectionTypes[id] = jsPlumb.extend({}, type);
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:registerConnectionTypes
+ * @param {object} types Object containing the type specifications.
+ * @description
+ * Registers all of the given connection types on this instance of jsPlumb. `types` is expected
+ * to contain keys with typeids and values with type specification objects.
+ */
+ registerConnectionTypes : function(types) {
+ for (var i in types)
+ this._connectionTypes[i] = jsPlumb.extend({}, types[i]);
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:registerEndpointType
+ * @param {string} typeId Id of the type
+ * @param {object} type Object containing the type specification.
+ * @description
+ * Registers the given endpoint type on this instance of jsPlumb.
+ */
+ registerEndpointType : function(id, type) {
+ this._endpointTypes[id] = jsPlumb.extend({}, type);
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:registerEndpointTypes
+ * @param {object} types Object containing the type specifications.
+ * @description
+ * Registers all of the given endpoint types on this instance of jsPlumb. `types` is expected
+ * to contain keys with typeids and values with type specification objects.
+ */
+ registerEndpointTypes : function(types) {
+ for (var i in types)
+ this._endpointTypes[i] = jsPlumb.extend({}, types[i]);
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:getType
+ * @param {string} id Id of the type to retrieve
+ * @param {string} typeDescriptor `"connection"` or `"endpoint"` - the type of Type to get.
+ * @description
+ * Returns the given type's specification.
+ * @return {object} Type specification, it if exists, null otherwise.
+ */
+ getType : function(id, typeDescriptor) {
+ return typeDescriptor === "connection" ? this._connectionTypes[id] : this._endpointTypes[id];
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:setIdChanged
+ * @param {oldId} string Previous id
+ * @param {newId} string Element's new id.
+ * @description called to notify us that an id WAS changed, and we should do our changes, but we
+ * dont need to change the element's DOM attribute. note that this does not work if the an element with
+ * the new id is not in the DOM.
+ */
+ setIdChanged : function(oldId, newId) {
+ this.setId(oldId, newId, true);
+ }
+ });
+
+// --------------------- static instance + AMD registration -------------------------------------------
+
+// create static instance and assign to window if window exists.
+ var jsPlumb = new jsPlumbInstance();
+ // register on window if defined (lets us run on server)
+ if (typeof window != 'undefined') window.jsPlumb = jsPlumb;
+ // add 'getInstance' method to static instance
+ /**
+ * @name jsPlumb.getInstance
+ * @param {object} [_defaults] Optional default settings for the new instance.
+ * @desc Gets a new instance of jsPlumb.
+ */
+ jsPlumb.getInstance = function(_defaults) {
+ var j = new jsPlumbInstance(_defaults);
+ j.init();
+ return j;
+ };
+// maybe register static instance as an AMD module, and getInstance method too.
+ if ( typeof define === "function") {
+ define( "jsplumb", [], function () { return jsPlumb; } );
+ define( "jsplumbinstance", [], function () { return jsPlumb.getInstance(); } );
+ }
+ // CommonJS
+ if (typeof exports !== 'undefined') {
+ exports.jsPlumb = jsPlumb;
+ }
+
+
+// --------------------- end static instance + AMD registration -------------------------------------------
+
+})();
+
+
+;(function() {
+
+ // create the drag handler for a connection
+ var _makeConnectionDragHandler = function(placeholder, _jsPlumb) {
+ var stopped = false;
+ return {
+ drag : function() {
+ if (stopped) {
+ stopped = false;
+ return true;
+ }
+ var _ui = jsPlumb.CurrentLibrary.getUIPosition(arguments, _jsPlumb.getZoom());
+
+ if (placeholder.element) {
+ jsPlumb.CurrentLibrary.setOffset(placeholder.element, _ui);
+ _jsPlumb.repaint(placeholder.element, _ui);
+ }
+ },
+ stopDrag : function() {
+ stopped = true;
+ }
+ };
+ };
+
+ // creates a placeholder div for dragging purposes, adds it to the DOM, and pre-computes its offset.
+ var _makeDraggablePlaceholder = function(placeholder, parent, _jsPlumb) {
+ var n = document.createElement("div");
+ n.style.position = "absolute";
+ var placeholderDragElement = jsPlumb.CurrentLibrary.getElementObject(n);
+ jsPlumb.CurrentLibrary.appendElement(n, parent);
+ var id = _jsPlumb.getId(n);
+ _jsPlumb.updateOffset( { elId : id });
+ // create and assign an id, and initialize the offset.
+ placeholder.id = id;
+ placeholder.element = n;//placeholderDragElement;
+ };
+
+ // create a floating endpoint (for drag connections)
+ var _makeFloatingEndpoint = function(paintStyle, referenceAnchor, endpoint, referenceCanvas, sourceElement, _jsPlumb, _newEndpoint) {
+ var floatingAnchor = new jsPlumb.FloatingAnchor( { reference : referenceAnchor, referenceCanvas : referenceCanvas, jsPlumbInstance:_jsPlumb });
+ //setting the scope here should not be the way to fix that mootools issue. it should be fixed by not
+ // adding the floating endpoint as a droppable. that makes more sense anyway!
+ return _newEndpoint({ paintStyle : paintStyle, endpoint : endpoint, anchor : floatingAnchor, source : sourceElement, scope:"__floating" });
+ };
+
+ var typeParameters = [ "connectorStyle", "connectorHoverStyle", "connectorOverlays",
+ "connector", "connectionType", "connectorClass", "connectorHoverClass" ];
+
+ // a helper function that tries to find a connection to the given element, and returns it if so. if elementWithPrecedence is null,
+ // or no connection to it is found, we return the first connection in our list.
+ var findConnectionToUseForDynamicAnchor = function(ep, elementWithPrecedence) {
+ var idx = 0;
+ if (elementWithPrecedence != null) {
+ for (var i = 0; i < ep.connections.length; i++) {
+ if (ep.connections[i].sourceId == elementWithPrecedence || ep.connections[i].targetId == elementWithPrecedence) {
+ idx = i;
+ break;
+ }
+ }
+ }
+
+ return ep.connections[idx];
+ };
+
+ var findConnectionIndex = function(conn, ep) {
+ return jsPlumbUtil.findWithFunction(ep.connections, function(c) { return c.id == conn.id; });
+ };
+
+ jsPlumb.Endpoint = function(params) {
+ var _jsPlumb = params._jsPlumb,
+ jpcl = jsPlumb.CurrentLibrary,
+ _att = jsPlumbAdapter.getAttribute,
+ _gel = jpcl.getElementObject,
+ _dom = jpcl.getDOMElement,
+ _ju = jsPlumbUtil,
+ _newConnection = params.newConnection,
+ _newEndpoint = params.newEndpoint,
+ _finaliseConnection = params.finaliseConnection,
+ _fireDetachEvent = params.fireDetachEvent,
+ floatingConnections = params.floatingConnections;
+
+ this.idPrefix = "_jsplumb_e_";
+ this.defaultLabelLocation = [ 0.5, 0.5 ];
+ this.defaultOverlayKeys = ["Overlays", "EndpointOverlays"];
+ this.parent = params.parent;
+ OverlayCapableJsPlumbUIComponent.apply(this, arguments);
+
+// TYPE
+
+ this.getDefaultType = function() {
+ return {
+ parameters:{},
+ scope:null,
+ maxConnections:this._jsPlumb.instance.Defaults.MaxConnections,
+ paintStyle:this._jsPlumb.instance.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle,
+ endpoint:this._jsPlumb.instance.Defaults.Endpoint || jsPlumb.Defaults.Endpoint,
+ hoverPaintStyle:this._jsPlumb.instance.Defaults.EndpointHoverStyle || jsPlumb.Defaults.EndpointHoverStyle,
+ overlays:this._jsPlumb.instance.Defaults.EndpointOverlays || jsPlumb.Defaults.EndpointOverlays,
+ connectorStyle:params.connectorStyle,
+ connectorHoverStyle:params.connectorHoverStyle,
+ connectorClass:params.connectorClass,
+ connectorHoverClass:params.connectorHoverClass,
+ connectorOverlays:params.connectorOverlays,
+ connector:params.connector,
+ connectorTooltip:params.connectorTooltip
+ };
+ };
+
+// END TYPE
+
+ this._jsPlumb.enabled = !(params.enabled === false);
+ this._jsPlumb.visible = true;
+ this.element = _dom(params.source);
+ this._jsPlumb.uuid = params.uuid;
+ this._jsPlumb.floatingEndpoint = null;
+ var inPlaceCopy = null;
+ if (this._jsPlumb.uuid) params.endpointsByUUID[this._jsPlumb.uuid] = this;
+ this.elementId = params.elementId;
+
+ this._jsPlumb.connectionCost = params.connectionCost;
+ this._jsPlumb.connectionsDirected = params.connectionsDirected;
+ this._jsPlumb.currentAnchorClass = "";
+ this._jsPlumb.events = {};
+
+ var _updateAnchorClass = function() {
+ jpcl.removeClass(this.element, _jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ this.removeClass(_jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ this._jsPlumb.currentAnchorClass = this.anchor.getCssClass();
+ this.addClass(_jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ jpcl.addClass(this.element, _jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ }.bind(this);
+
+ this.setAnchor = function(anchorParams, doNotRepaint) {
+ this._jsPlumb.instance.continuousAnchorFactory.clear(this.elementId);
+ this.anchor = this._jsPlumb.instance.makeAnchor(anchorParams, this.elementId, _jsPlumb);
+ _updateAnchorClass();
+ this.anchor.bind("anchorChanged", function(currentAnchor) {
+ this.fire("anchorChanged", {endpoint:this, anchor:currentAnchor});
+ _updateAnchorClass();
+ }.bind(this));
+ if (!doNotRepaint)
+ this._jsPlumb.instance.repaint(this.elementId);
+ return this;
+ };
+
+ var anchorParamsToUse = params.anchor ? params.anchor : params.anchors ? params.anchors : (_jsPlumb.Defaults.Anchor || "Top");
+ this.setAnchor(anchorParamsToUse, true);
+
+ // endpoint delegates to first connection for hover, if there is one.
+ var internalHover = function(state) {
+ if (this.connections.length > 0)
+ this.connections[0].setHover(state, false);
+ else
+ this.setHover(state);
+ }.bind(this);
+
+ // ANCHOR MANAGER
+ if (!params._transient) // in place copies, for example, are transient. they will never need to be retrieved during a paint cycle, because they dont move, and then they are deleted.
+ this._jsPlumb.instance.anchorManager.add(this, this.elementId);
+
+ this.setEndpoint = function(ep) {
+
+ if (this.endpoint != null) {
+ this.endpoint.cleanup();
+ this.endpoint.destroy();
+ }
+
+ var _e = function(t, p) {
+ var rm = _jsPlumb.getRenderMode();
+ if (jsPlumb.Endpoints[rm][t]) return new jsPlumb.Endpoints[rm][t](p);
+ if (!_jsPlumb.Defaults.DoNotThrowErrors)
+ throw { msg:"jsPlumb: unknown endpoint type '" + t + "'" };
+ };
+
+ var endpointArgs = {
+ _jsPlumb:this._jsPlumb.instance,
+ cssClass:params.cssClass,
+ parent:params.parent,
+ container:params.container,
+ tooltip:params.tooltip,
+ connectorTooltip:params.connectorTooltip,
+ endpoint:this
+ };
+ if (_ju.isString(ep))
+ this.endpoint = _e(ep, endpointArgs);
+ else if (_ju.isArray(ep)) {
+ endpointArgs = _ju.merge(ep[1], endpointArgs);
+ this.endpoint = _e(ep[0], endpointArgs);
+ }
+ else {
+ this.endpoint = ep.clone();
+ }
+
+ // assign a clone function using a copy of endpointArgs. this is used when a drag starts: the endpoint that was dragged is cloned,
+ // and the clone is left in its place while the original one goes off on a magical journey.
+ // the copy is to get around a closure problem, in which endpointArgs ends up getting shared by
+ // the whole world.
+ var argsForClone = jsPlumb.extend({}, endpointArgs);
+ this.endpoint.clone = function() {
+ // TODO this, and the code above, can be refactored to be more dry.
+ if (_ju.isString(ep))
+ return _e(ep, endpointArgs);
+ else if (_ju.isArray(ep)) {
+ endpointArgs = _ju.merge(ep[1], endpointArgs);
+ return _e(ep[0], endpointArgs);
+ }
+ }.bind(this);
+
+ this.type = this.endpoint.type;
+ // bind listeners from endpoint to self, with the internal hover function defined above.
+ this.bindListeners(this.endpoint, this, internalHover);
+ };
+
+ this.setEndpoint(params.endpoint || _jsPlumb.Defaults.Endpoint || jsPlumb.Defaults.Endpoint || "Dot");
+ this.setPaintStyle(params.paintStyle || params.style || _jsPlumb.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle, true);
+ this.setHoverPaintStyle(params.hoverPaintStyle || _jsPlumb.Defaults.EndpointHoverStyle || jsPlumb.Defaults.EndpointHoverStyle, true);
+ this._jsPlumb.paintStyleInUse = this.getPaintStyle();
+
+ _ju.copyValues(typeParameters, params, this);
+
+ this.isSource = params.isSource || false;
+ this.isTarget = params.isTarget || false;
+ this._jsPlumb.maxConnections = params.maxConnections || _jsPlumb.Defaults.MaxConnections; // maximum number of connections this endpoint can be the source of.
+ this.canvas = this.endpoint.canvas;
+ // add anchor class (need to do this on construction because we set anchor first)
+ this.addClass(_jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ jpcl.addClass(this.element, _jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ this.connections = params.connections || [];
+ this.connectorPointerEvents = params["connector-pointer-events"];
+
+ this.scope = params.scope || _jsPlumb.getDefaultScope();
+ this.timestamp = null;
+ this.reattachConnections = params.reattach || _jsPlumb.Defaults.ReattachConnections;
+ this.connectionsDetachable = _jsPlumb.Defaults.ConnectionsDetachable;
+ if (params.connectionsDetachable === false || params.detachable === false)
+ this.connectionsDetachable = false;
+ this.dragAllowedWhenFull = params.dragAllowedWhenFull || true;
+
+ if (params.onMaxConnections)
+ this.bind("maxConnections", params.onMaxConnections);
+
+ //
+ // add a connection. not part of public API.
+ //
+ this.addConnection = function(connection) {
+ this.connections.push(connection);
+ this[(this.connections.length > 0 ? "add" : "remove") + "Class"](_jsPlumb.endpointConnectedClass);
+ this[(this.isFull() ? "add" : "remove") + "Class"](_jsPlumb.endpointFullClass);
+ };
+
+ this.detachFromConnection = function(connection, idx) {
+ idx = idx == null ? findConnectionIndex(connection, this) : idx;
+ if (idx >= 0) {
+ this.connections.splice(idx, 1);
+ this[(this.connections.length > 0 ? "add" : "remove") + "Class"](_jsPlumb.endpointConnectedClass);
+ this[(this.isFull() ? "add" : "remove") + "Class"](_jsPlumb.endpointFullClass);
+ }
+ };
+
+ this.detach = function(connection, ignoreTarget, forceDetach, fireEvent, originalEvent, endpointBeingDeleted, connectionIndex) {
+
+ var idx = connectionIndex == null ? findConnectionIndex(connection, this) : connectionIndex,
+ actuallyDetached = false;
+ fireEvent = (fireEvent !== false);
+
+ if (idx >= 0) {
+ if (forceDetach || connection._forceDetach || (connection.isDetachable() && connection.isDetachAllowed(connection) && this.isDetachAllowed(connection) )) {
+
+ //connection.setHover(false);
+
+ _jsPlumb.deleteObject({
+ connection:connection,
+ fireEvent:(!ignoreTarget && fireEvent),
+ originalEvent:originalEvent
+ });
+ actuallyDetached = true;
+ }
+ }
+ return actuallyDetached;
+ };
+
+ this.detachAll = function(fireEvent, originalEvent) {
+ while (this.connections.length > 0) {
+ // TODO this could pass the index in to the detach method to save some time (index will always be zero in this while loop)
+ // TODO now it defaults to fireEvent true. will that mess with things?
+ this.detach(this.connections[0], false, true, fireEvent !== false, originalEvent, this, 0);
+ }
+ return this;
+ };
+ this.detachFrom = function(targetEndpoint, fireEvent, originalEvent) {
+ var c = [];
+ for ( var i = 0; i < this.connections.length; i++) {
+ if (this.connections[i].endpoints[1] == targetEndpoint || this.connections[i].endpoints[0] == targetEndpoint) {
+ c.push(this.connections[i]);
+ }
+ }
+ for ( var j = 0; j < c.length; j++) {
+ this.detach(c[j], false, true, fireEvent, originalEvent);
+ }
+ return this;
+ };
+
+ this.getElement = function() {
+ return this.element;
+ };
+
+ // container not supported in 1.5.2; you cannot change the container once it is set.
+ // it might come back int a future release.
+ this.setElement = function(el/*, container*/) {
+ var parentId = this._jsPlumb.instance.getId(el),
+ curId = this.elementId;
+ // remove the endpoint from the list for the current endpoint's element
+ _ju.removeWithFunction(params.endpointsByElement[this.elementId], function(e) {
+ return e.id == this.id;
+ }.bind(this));
+ this.element = _dom(el);
+ this.elementId = _jsPlumb.getId(this.element);
+ _jsPlumb.anchorManager.rehomeEndpoint(this, curId, this.element);
+ _jsPlumb.dragManager.endpointAdded(this.element);
+ _ju.addToList(params.endpointsByElement, parentId, this);
+ return this;
+ };
+
+ /**
+ * private but must be exposed.
+ */
+ this.makeInPlaceCopy = function() {
+ var loc = this.anchor.getCurrentLocation({element:this}),
+ o = this.anchor.getOrientation(this),
+ acc = this.anchor.getCssClass(),
+ inPlaceAnchor = {
+ bind:function() { },
+ compute:function() { return [ loc[0], loc[1] ]; },
+ getCurrentLocation : function() { return [ loc[0], loc[1] ]; },
+ getOrientation:function() { return o; },
+ getCssClass:function() { return acc; }
+ };
+
+ return _newEndpoint( {
+ anchor : inPlaceAnchor,
+ source : this.element,
+ paintStyle : this.getPaintStyle(),
+ endpoint : params.hideOnDrag ? "Blank" : this.endpoint,
+ _transient:true,
+ scope:this.scope
+ });
+ };
+
+
+ /**
+ * private but needs to be exposed.
+ */
+ this.isFloating = function() {
+ return this.anchor != null && this.anchor.isFloating;
+ };
+
+ /**
+ * returns a connection from the pool; used when dragging starts. just gets the head of the array if it can.
+ */
+ this.connectorSelector = function() {
+ var candidate = this.connections[0];
+ if (this.isTarget && candidate) return candidate;
+ else {
+ return (this.connections.length < this._jsPlumb.maxConnections) || this._jsPlumb.maxConnections == -1 ? null : candidate;
+ }
+ };
+
+ this.setStyle = this.setPaintStyle;
+
+ this.paint = function(params) {
+ params = params || {};
+ var timestamp = params.timestamp, recalc = !(params.recalc === false);
+ if (!timestamp || this.timestamp !== timestamp) {
+
+ // TODO check: is this is a safe performance enhancement?
+ var info = _jsPlumb.updateOffset({ elId:this.elementId, timestamp:timestamp/*, recalc:recalc*/ });
+ //var info = _jsPlumb.updateOffset({ elId:_elementId, timestamp:timestamp, recalc:recalc });
+
+ var xy = params.offset ? params.offset.o : info.o;
+ if(xy != null) {
+ var ap = params.anchorPoint,connectorPaintStyle = params.connectorPaintStyle;
+ if (ap == null) {
+ var wh = params.dimensions || info.s,
+ anchorParams = { xy : [ xy.left, xy.top ], wh : wh, element : this, timestamp : timestamp };
+ if (recalc && this.anchor.isDynamic && this.connections.length > 0) {
+ var c = findConnectionToUseForDynamicAnchor(this, params.elementWithPrecedence),
+ oIdx = c.endpoints[0] == this ? 1 : 0,
+ oId = oIdx === 0 ? c.sourceId : c.targetId,
+ oInfo = _jsPlumb.getCachedData(oId),
+ oOffset = oInfo.o, oWH = oInfo.s;
+ anchorParams.txy = [ oOffset.left, oOffset.top ];
+ anchorParams.twh = oWH;
+ anchorParams.tElement = c.endpoints[oIdx];
+ }
+ ap = this.anchor.compute(anchorParams);
+ }
+
+ this.endpoint.compute(ap, this.anchor.getOrientation(this), this._jsPlumb.paintStyleInUse, connectorPaintStyle || this.paintStyleInUse);
+ this.endpoint.paint(this._jsPlumb.paintStyleInUse, this.anchor);
+ this.timestamp = timestamp;
+
+ // paint overlays
+ for ( var i = 0; i < this._jsPlumb.overlays.length; i++) {
+ var o = this._jsPlumb.overlays[i];
+ if (o.isVisible()) {
+ this._jsPlumb.overlayPlacements[i] = o.draw(this.endpoint, this._jsPlumb.paintStyleInUse);
+ o.paint(this._jsPlumb.overlayPlacements[i]);
+ }
+ }
+ }
+ }
+ };
+
+ this.repaint = this.paint;
+
+ // is this a connection source? we make it draggable and have the
+ // drag listener maintain a connection with a floating endpoint.
+ if (jpcl.isDragSupported(this.element) && (this.isSource || this.isTarget)) {
+ var placeholderInfo = { id:null, element:null },
+ jpc = null,
+ existingJpc = false,
+ existingJpcParams = null,
+ _dragHandler = _makeConnectionDragHandler(placeholderInfo, _jsPlumb);
+
+ var start = function() {
+ // drag might have started on an endpoint that is not actually a source, but which has
+ // one or more connections.
+ jpc = this.connectorSelector();
+ var _continue = true;
+ // if not enabled, return
+ if (!this.isEnabled()) _continue = false;
+ // if no connection and we're not a source, return.
+ if (jpc == null && !this.isSource) _continue = false;
+ // otherwise if we're full and not allowed to drag, also return false.
+ if (this.isSource && this.isFull() && !this.dragAllowedWhenFull) _continue = false;
+ // if the connection was setup as not detachable or one of its endpoints
+ // was setup as connectionsDetachable = false, or Defaults.ConnectionsDetachable
+ // is set to false...
+ if (jpc != null && !jpc.isDetachable()) _continue = false;
+
+ if (_continue === false) {
+ // this is for mootools and yui. returning false from this causes jquery to stop drag.
+ // the events are wrapped in both mootools and yui anyway, but i don't think returning
+ // false from the start callback would stop a drag.
+ if (jpcl.stopDrag) jpcl.stopDrag();
+ _dragHandler.stopDrag();
+ return false;
+ }
+
+ // clear hover for all connections for this endpoint before continuing.
+ for (var i = 0; i < this.connections.length; i++)
+ this.connections[i].setHover(false);
+
+ this.addClass("endpointDrag");
+ _jsPlumb.setConnectionBeingDragged(true);
+
+ // if we're not full but there was a connection, make it null. we'll create a new one.
+ if (jpc && !this.isFull() && this.isSource) jpc = null;
+
+ _jsPlumb.updateOffset( { elId : this.elementId });
+ inPlaceCopy = this.makeInPlaceCopy();
+ inPlaceCopy.referenceEndpoint = this;
+ inPlaceCopy.paint();
+
+ _makeDraggablePlaceholder(placeholderInfo, this.parent, _jsPlumb);
+
+ // set the offset of this div to be where 'inPlaceCopy' is, to start with.
+ // TODO merge this code with the code in both Anchor and FloatingAnchor, because it
+ // does the same stuff.
+ var ipcoel = _gel(inPlaceCopy.canvas),
+ ipco = jsPlumb.CurrentLibrary.getOffset(ipcoel, _jsPlumb),
+ po = _jsPlumb.adjustForParentOffsetAndScroll([ipco.left, ipco.top], inPlaceCopy.canvas),
+ canvasElement = _gel(this.canvas);
+
+ jpcl.setOffset(placeholderInfo.element, {left:po[0], top:po[1]});
+
+ // when using makeSource and a parent, we first draw the source anchor on the source element, then
+ // move it to the parent. note that this happens after drawing the placeholder for the
+ // first time.
+ if (this.parentAnchor) this.anchor = _jsPlumb.makeAnchor(this.parentAnchor, this.elementId, _jsPlumb);
+
+ // store the id of the dragging div and the source element. the drop function will pick these up.
+ _jsPlumb.setAttribute(this.canvas, "dragId", placeholderInfo.id);
+ _jsPlumb.setAttribute(this.canvas, "elId", this.elementId);
+
+ this._jsPlumb.floatingEndpoint = _makeFloatingEndpoint(this.getPaintStyle(), this.anchor, this.endpoint, this.canvas, placeholderInfo.element, _jsPlumb, _newEndpoint);
+ // TODO we should not know about DOM here. make the library adapter do this (or the
+ // dom adapter)
+ this.canvas.style.visibility = "hidden";
+
+ if (jpc == null) {
+ this.anchor.locked = true;
+ this.setHover(false, false);
+ // create a connection. one end is this endpoint, the other is a floating endpoint.
+ jpc = _newConnection({
+ sourceEndpoint : this,
+ targetEndpoint : this._jsPlumb.floatingEndpoint,
+ source : this.endpointWillMoveTo || this.element, // for makeSource with parent option. ensure source element is represented correctly.
+ target : placeholderInfo.element,
+ anchors : [ this.anchor, this._jsPlumb.floatingEndpoint.anchor ],
+ paintStyle : params.connectorStyle, // this can be null. Connection will use the default.
+ hoverPaintStyle:params.connectorHoverStyle,
+ connector : params.connector, // this can also be null. Connection will use the default.
+ overlays : params.connectorOverlays,
+ type:this.connectionType,
+ cssClass:this.connectorClass,
+ hoverClass:this.connectorHoverClass
+ });
+ jpc.addClass(_jsPlumb.draggingClass);
+ this._jsPlumb.floatingEndpoint.addClass(_jsPlumb.draggingClass);
+ // fire an event that informs that a connection is being dragged
+ _jsPlumb.fire("connectionDrag", jpc);
+
+ } else {
+ existingJpc = true;
+ jpc.setHover(false);
+ // if existing connection, allow to be dropped back on the source endpoint (issue 51).
+ _initDropTarget(ipcoel, false, true);
+ // new anchor idx
+ var anchorIdx = jpc.endpoints[0].id == this.id ? 0 : 1;
+ jpc.floatingAnchorIndex = anchorIdx; // save our anchor index as the connection's floating index.
+ this.detachFromConnection(jpc); // detach from the connection while dragging is occurring.
+
+ // store the original scope (issue 57)
+ var dragScope = jsPlumb.CurrentLibrary.getDragScope(canvasElement);
+ _jsPlumb.setAttribute(this.canvas, "originalScope", dragScope);
+ // now we want to get this endpoint's DROP scope, and set it for now: we can only be dropped on drop zones
+ // that have our drop scope (issue 57).
+ var dropScope = jpcl.getDropScope(canvasElement);
+ jpcl.setDragScope(canvasElement, dropScope);
+
+ // fire an event that informs that a connection is being dragged. we do this before
+ // replacing the original target with the floating element info.
+ _jsPlumb.fire("connectionDrag", jpc);
+
+ // now we replace ourselves with the temporary div we created above:
+ if (anchorIdx === 0) {
+ existingJpcParams = [ jpc.source, jpc.sourceId, canvasElement, dragScope ];
+ jpc.source = placeholderInfo.element;
+ jpc.sourceId = placeholderInfo.id;
+ } else {
+ existingJpcParams = [ jpc.target, jpc.targetId, canvasElement, dragScope ];
+ jpc.target = placeholderInfo.element;
+ jpc.targetId = placeholderInfo.id;
+ }
+
+ // lock the other endpoint; if it is dynamic it will not move while the drag is occurring.
+ jpc.endpoints[anchorIdx === 0 ? 1 : 0].anchor.locked = true;
+ // store the original endpoint and assign the new floating endpoint for the drag.
+ jpc.suspendedEndpoint = jpc.endpoints[anchorIdx];
+
+ // PROVIDE THE SUSPENDED ELEMENT, BE IT A SOURCE OR TARGET (ISSUE 39)
+ jpc.suspendedElement = jpc.endpoints[anchorIdx].getElement();
+ jpc.suspendedElementId = jpc.endpoints[anchorIdx].elementId;
+ jpc.suspendedElementType = anchorIdx === 0 ? "source" : "target";
+
+ jpc.suspendedEndpoint.setHover(false);
+ this._jsPlumb.floatingEndpoint.referenceEndpoint = jpc.suspendedEndpoint;
+ jpc.endpoints[anchorIdx] = this._jsPlumb.floatingEndpoint;
+
+ jpc.addClass(_jsPlumb.draggingClass);
+ this._jsPlumb.floatingEndpoint.addClass(_jsPlumb.draggingClass);
+
+ }
+ // register it and register connection on it.
+ floatingConnections[placeholderInfo.id] = jpc;
+ _jsPlumb.anchorManager.addFloatingConnection(placeholderInfo.id, jpc);
+ // only register for the target endpoint; we will not be dragging the source at any time
+ // before this connection is either discarded or made into a permanent connection.
+ _ju.addToList(params.endpointsByElement, placeholderInfo.id, this._jsPlumb.floatingEndpoint);
+ // tell jsplumb about it
+ _jsPlumb.currentlyDragging = true;
+ }.bind(this);
+
+ var dragOptions = params.dragOptions || {},
+ defaultOpts = jsPlumb.extend( {}, jpcl.defaultDragOptions),
+ startEvent = jpcl.dragEvents.start,
+ stopEvent = jpcl.dragEvents.stop,
+ dragEvent = jpcl.dragEvents.drag;
+
+ dragOptions = jsPlumb.extend(defaultOpts, dragOptions);
+ dragOptions.scope = dragOptions.scope || this.scope;
+ dragOptions[startEvent] = _ju.wrap(dragOptions[startEvent], start, false);
+ // extracted drag handler function so can be used by makeSource
+ dragOptions[dragEvent] = _ju.wrap(dragOptions[dragEvent], _dragHandler.drag);
+ dragOptions[stopEvent] = _ju.wrap(dragOptions[stopEvent],
+ function() {
+
+ _jsPlumb.setConnectionBeingDragged(false);
+ // get the actual drop event (decode from library args to stop function)
+ var originalEvent = jpcl.getDropEvent(arguments);
+ // unlock the other endpoint (if it is dynamic, it would have been locked at drag start)
+ var idx = jpc.floatingAnchorIndex == null ? 1 : jpc.floatingAnchorIndex;
+ jpc.endpoints[idx === 0 ? 1 : 0].anchor.locked = false;
+ // WHY does this need to happen? i suppose because the connection might not get
+ // deleted. TODO: i dont want to know about css classes inside jsplumb, ideally.
+ jpc.removeClass(_jsPlumb.draggingClass);
+
+ // if we have the floating endpoint then the connection has not been dropped
+ // on another endpoint. If it is a new connection we throw it away. If it is an
+ // existing connection we check to see if we should reattach it, throwing it away
+ // if not.
+ if (jpc.endpoints[idx] == this._jsPlumb.floatingEndpoint) {
+ // 6a. if the connection was an existing one...
+ if (existingJpc && jpc.suspendedEndpoint) {
+ // fix for issue35, thanks Sylvain Gizard: when firing the detach event make sure the
+ // floating endpoint has been replaced.
+ if (idx === 0) {
+ jpc.source = existingJpcParams[0];
+ jpc.sourceId = existingJpcParams[1];
+ } else {
+ jpc.target = existingJpcParams[0];
+ jpc.targetId = existingJpcParams[1];
+ }
+
+ // restore the original scope (issue 57)
+ jpcl.setDragScope(existingJpcParams[2], existingJpcParams[3]);
+ jpc.endpoints[idx] = jpc.suspendedEndpoint;
+ // IF the connection should be reattached, or the other endpoint refuses detach, then
+ // reset the connection to its original state
+ if (jpc.isReattach() || jpc._forceReattach || jpc._forceDetach || !jpc.endpoints[idx === 0 ? 1 : 0].detach(jpc, false, false, true, originalEvent)) {
+ jpc.setHover(false);
+ jpc.floatingAnchorIndex = null;
+ jpc._forceDetach = null;
+ jpc._forceReattach = null;
+ this._jsPlumb.floatingEndpoint.detachFromConnection(jpc);
+ jpc.suspendedEndpoint.addConnection(jpc);
+ _jsPlumb.repaint(existingJpcParams[1]);
+ }
+ }
+ }
+
+ // remove the element associated with the floating endpoint
+ // (and its associated floating endpoint and visual artefacts)
+ // TODO we need a way to say that the connection should be kept, if
+ _jsPlumb.remove(placeholderInfo.element, false);
+ // remove the inplace copy
+ _jsPlumb.remove(inPlaceCopy.canvas, false);
+
+ // makeTargets sets this flag, to tell us we have been replaced and should delete ourself.
+ if (this.deleteAfterDragStop) {
+ _jsPlumb.deleteObject({endpoint:this});
+ }
+ else {
+ if (this._jsPlumb) {
+ this._jsPlumb.floatingEndpoint = null;
+ // repaint this endpoint.
+ // make our canvas visible (TODO: hand off to library; we should not know about DOM)
+ this.canvas.style.visibility = "visible";
+ // unlock our anchor
+ this.anchor.locked = false;
+ this.paint({recalc:false});
+ }
+ }
+
+ // TODO can this stay here? the connection is no longer valid.
+ _jsPlumb.fire("connectionDragStop", jpc);
+
+ // tell jsplumb that dragging is finished.
+ _jsPlumb.currentlyDragging = false;
+
+ jpc = null;
+
+ }.bind(this));
+
+ var i = _gel(this.canvas);
+ jpcl.initDraggable(i, dragOptions, true, _jsPlumb);
+ }
+
+ // pulled this out into a function so we can reuse it for the inPlaceCopy canvas; you can now drop detached connections
+ // back onto the endpoint you detached it from.
+ var _initDropTarget = function(canvas, forceInit, isTransient, endpoint) {
+ if ((this.isTarget || forceInit) && jpcl.isDropSupported(this.element)) {
+ var dropOptions = params.dropOptions || _jsPlumb.Defaults.DropOptions || jsPlumb.Defaults.DropOptions;
+ dropOptions = jsPlumb.extend( {}, dropOptions);
+ dropOptions.scope = dropOptions.scope || this.scope;
+ var dropEvent = jpcl.dragEvents.drop,
+ overEvent = jpcl.dragEvents.over,
+ outEvent = jpcl.dragEvents.out,
+ drop = function() {
+
+ this.removeClass(_jsPlumb.endpointDropAllowedClass);
+ this.removeClass(_jsPlumb.endpointDropForbiddenClass);
+
+ var originalEvent = jpcl.getDropEvent(arguments),
+ draggable = _gel(jpcl.getDragObject(arguments)),
+ id = _jsPlumb.getAttribute(draggable, "dragId"),
+ elId = _jsPlumb.getAttribute(draggable, "elId"),
+ scope = _jsPlumb.getAttribute(draggable, "originalScope"),
+ jpc = floatingConnections[id];
+
+ // if this is a drop back where the connection came from, mark it force rettach and
+ // return; the stop handler will reattach. without firing an event.
+ var redrop = jpc.suspendedEndpoint && (jpc.suspendedEndpoint.id == this.id ||
+ this.referenceEndpoint && jpc.suspendedEndpoint.id == this.referenceEndpoint.id) ;
+ if (redrop) {
+ jpc._forceReattach = true;
+ return;
+ }
+
+ if (jpc != null) {
+ var idx = jpc.floatingAnchorIndex == null ? 1 : jpc.floatingAnchorIndex, oidx = idx === 0 ? 1 : 0;
+
+ // restore the original scope if necessary (issue 57)
+ if (scope) jsPlumb.CurrentLibrary.setDragScope(draggable, scope);
+
+ var endpointEnabled = endpoint != null ? endpoint.isEnabled() : true;
+
+ if (this.isFull()) {
+ this.fire("maxConnections", {
+ endpoint:this,
+ connection:jpc,
+ maxConnections:this._jsPlumb.maxConnections
+ }, originalEvent);
+ }
+
+ if (!this.isFull() && !(idx === 0 && !this.isSource) && !(idx == 1 && !this.isTarget) && endpointEnabled) {
+ var _doContinue = true;
+
+ // the second check here is for the case that the user is dropping it back
+ // where it came from.
+ if (jpc.suspendedEndpoint && jpc.suspendedEndpoint.id != this.id) {
+ if (idx === 0) {
+ jpc.source = jpc.suspendedEndpoint.element;
+ jpc.sourceId = jpc.suspendedEndpoint.elementId;
+ } else {
+ jpc.target = jpc.suspendedEndpoint.element;
+ jpc.targetId = jpc.suspendedEndpoint.elementId;
+ }
+
+ if (!jpc.isDetachAllowed(jpc) || !jpc.endpoints[idx].isDetachAllowed(jpc) || !jpc.suspendedEndpoint.isDetachAllowed(jpc) || !_jsPlumb.checkCondition("beforeDetach", jpc))
+ _doContinue = false;
+ }
+
+ // these have to be set before testing for beforeDrop.
+ if (idx === 0) {
+ jpc.source = this.element;
+ jpc.sourceId = this.elementId;
+ } else {
+ jpc.target = this.element;
+ jpc.targetId = this.elementId;
+ }
+
+// ------------ wrap the execution path in a function so we can support asynchronous beforeDrop
+
+ // we want to execute this regardless.
+ var commonFunction = function() {
+ jpc.floatingAnchorIndex = null;
+ };
+
+ var continueFunction = function() {
+
+ // remove this jpc from the current endpoint
+ jpc.endpoints[idx].detachFromConnection(jpc);
+ if (jpc.suspendedEndpoint) jpc.suspendedEndpoint.detachFromConnection(jpc);
+ jpc.endpoints[idx] = this;
+ this.addConnection(jpc);
+
+ // copy our parameters in to the connection:
+ var params = this.getParameters();
+ for (var aParam in params)
+ jpc.setParameter(aParam, params[aParam]);
+
+ if (!jpc.suspendedEndpoint) {
+ if (params.draggable)
+ jsPlumb.CurrentLibrary.initDraggable(this.element, dragOptions, true, _jsPlumb);
+ }
+ else {
+ var suspendedElement = jpc.suspendedEndpoint.getElement(), suspendedElementId = jpc.suspendedEndpoint.elementId;
+ // fire a detach event
+ _fireDetachEvent({
+ source : idx === 0 ? suspendedElement : jpc.source,
+ target : idx == 1 ? suspendedElement : jpc.target,
+ sourceId : idx === 0 ? suspendedElementId : jpc.sourceId,
+ targetId : idx == 1 ? suspendedElementId : jpc.targetId,
+ sourceEndpoint : idx === 0 ? jpc.suspendedEndpoint : jpc.endpoints[0],
+ targetEndpoint : idx == 1 ? jpc.suspendedEndpoint : jpc.endpoints[1],
+ connection : jpc
+ }, true, originalEvent);
+ }
+
+ // TODO this is like the makeTarget drop code.
+ if (idx == 1)
+ _jsPlumb.anchorManager.updateOtherEndpoint(jpc.sourceId, jpc.suspendedElementId, jpc.targetId, jpc);
+ else
+ _jsPlumb.anchorManager.sourceChanged(jpc.suspendedEndpoint.elementId, jpc.sourceId, jpc);
+
+ // finalise will inform the anchor manager and also add to
+ // connectionsByScope if necessary.
+ _finaliseConnection(jpc, null, originalEvent, true);
+
+ commonFunction();
+ }.bind(this);
+
+ var dontContinueFunction = function() {
+ // otherwise just put it back on the endpoint it was on before the drag.
+ if (jpc.suspendedEndpoint) {
+ jpc.endpoints[idx] = jpc.suspendedEndpoint;
+ jpc.setHover(false);
+ jpc._forceDetach = true;
+ if (idx === 0) {
+ jpc.source = jpc.suspendedEndpoint.element;
+ jpc.sourceId = jpc.suspendedEndpoint.elementId;
+ } else {
+ jpc.target = jpc.suspendedEndpoint.element;
+ jpc.targetId = jpc.suspendedEndpoint.elementId;
+ }
+ jpc.suspendedEndpoint.addConnection(jpc);
+
+ jpc.endpoints[0].repaint();
+ jpc.repaint();
+ _jsPlumb.repaint(jpc.sourceId);
+ jpc._forceDetach = false;
+ }
+
+ commonFunction();
+ };
+
+// --------------------------------------
+ // now check beforeDrop. this will be available only on Endpoints that are setup to
+ // have a beforeDrop condition (although, secretly, under the hood all Endpoints and
+ // the Connection have them, because they are on jsPlumbUIComponent. shhh!), because
+ // it only makes sense to have it on a target endpoint.
+ _doContinue = _doContinue && this.isDropAllowed(jpc.sourceId, jpc.targetId, jpc.scope, jpc, this);
+
+ if (_doContinue) {
+ continueFunction();
+ }
+ else {
+ dontContinueFunction();
+ }
+ }
+ _jsPlumb.currentlyDragging = false;
+ }
+ }.bind(this);
+
+ dropOptions[dropEvent] = _ju.wrap(dropOptions[dropEvent], drop);
+ dropOptions[overEvent] = _ju.wrap(dropOptions[overEvent], function() {
+ var draggable = jpcl.getDragObject(arguments),
+ id = _jsPlumb.getAttribute(draggable, "dragId"),
+ _jpc = floatingConnections[id];
+
+ if (_jpc != null) {
+ var idx = _jpc.floatingAnchorIndex == null ? 1 : _jpc.floatingAnchorIndex;
+ // here we should fire the 'over' event if we are a target and this is a new connection,
+ // or we are the same as the floating endpoint.
+ var _cont = (this.isTarget && _jpc.floatingAnchorIndex !== 0) || (_jpc.suspendedEndpoint && this.referenceEndpoint && this.referenceEndpoint.id == _jpc.suspendedEndpoint.id);
+ if (_cont) {
+ var bb = _jsPlumb.checkCondition("checkDropAllowed", {
+ sourceEndpoint:_jpc.endpoints[idx],
+ targetEndpoint:this,
+ connection:_jpc
+ });
+ this[(bb ? "add" : "remove") + "Class"](_jsPlumb.endpointDropAllowedClass);
+ this[(bb ? "remove" : "add") + "Class"](_jsPlumb.endpointDropForbiddenClass);
+ _jpc.endpoints[idx].anchor.over(this.anchor, this);
+ }
+ }
+ }.bind(this));
+
+ dropOptions[outEvent] = _ju.wrap(dropOptions[outEvent], function() {
+ var draggable = jpcl.getDragObject(arguments),
+ id = _jsPlumb.getAttribute( draggable, "dragId"),
+ _jpc = floatingConnections[id];
+
+ if (_jpc != null) {
+ var idx = _jpc.floatingAnchorIndex == null ? 1 : _jpc.floatingAnchorIndex;
+ var _cont = (this.isTarget && _jpc.floatingAnchorIndex !== 0) || (_jpc.suspendedEndpoint && this.referenceEndpoint && this.referenceEndpoint.id == _jpc.suspendedEndpoint.id);
+ if (_cont) {
+ this.removeClass(_jsPlumb.endpointDropAllowedClass);
+ this.removeClass(_jsPlumb.endpointDropForbiddenClass);
+ _jpc.endpoints[idx].anchor.out();
+ }
+ }
+ }.bind(this));
+ jpcl.initDroppable(canvas, dropOptions, true, isTransient);
+ }
+ }.bind(this);
+
+ // initialise the endpoint's canvas as a drop target. this will be ignored if the endpoint is not a target or drag is not supported.
+ _initDropTarget(_gel(this.canvas), true, !(params._transient || this.anchor.isFloating), this);
+
+ // finally, set type if it was provided
+ if (params.type)
+ this.addType(params.type, params.data, _jsPlumb.isSuspendDrawing());
+
+ return this;
+ };
+
+ jsPlumbUtil.extend(jsPlumb.Endpoint, OverlayCapableJsPlumbUIComponent, {
+ getTypeDescriptor : function() { return "endpoint"; },
+ isVisible : function() { return this._jsPlumb.visible; },
+ setVisible : function(v, doNotChangeConnections, doNotNotifyOtherEndpoint) {
+ this._jsPlumb.visible = v;
+ if (this.canvas) this.canvas.style.display = v ? "block" : "none";
+ this[v ? "showOverlays" : "hideOverlays"]();
+ if (!doNotChangeConnections) {
+ for (var i = 0; i < this.connections.length; i++) {
+ this.connections[i].setVisible(v);
+ if (!doNotNotifyOtherEndpoint) {
+ var oIdx = this === this.connections[i].endpoints[0] ? 1 : 0;
+ // only change the other endpoint if this is its only connection.
+ if (this.connections[i].endpoints[oIdx].connections.length == 1) this.connections[i].endpoints[oIdx].setVisible(v, true, true);
+ }
+ }
+ }
+ },
+ getAttachedElements : function() {
+ return this.connections;
+ },
+ applyType : function(t, doNotRepaint) {
+ if (t.maxConnections != null) this._jsPlumb.maxConnections = t.maxConnections;
+ if (t.scope) this.scope = t.scope;
+ jsPlumbUtil.copyValues(typeParameters, t, this);
+ },
+ isEnabled : function() { return this._jsPlumb.enabled; },
+ setEnabled : function(e) { this._jsPlumb.enabled = e; },
+ cleanup : function() {
+ jsPlumb.CurrentLibrary.removeClass(this.element, this._jsPlumb.instance.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ this.anchor = null;
+ this.endpoint.cleanup();
+ this.endpoint.destroy();
+ this.endpoint = null;
+ // drag/drop
+ var i = jsPlumb.CurrentLibrary.getElementObject(this.canvas);
+ jsPlumb.CurrentLibrary.destroyDraggable(i);
+ jsPlumb.CurrentLibrary.destroyDroppable(i);
+ },
+ setHover : function(h) {
+ if (this.endpoint && this._jsPlumb && !this._jsPlumb.instance.isConnectionBeingDragged())
+ this.endpoint.setHover(h);
+ },
+ isFull : function() {
+ return !(this.isFloating() || this._jsPlumb.maxConnections < 1 || this.connections.length < this._jsPlumb.maxConnections);
+ },
+ getConnectionCost : function() { return this._jsPlumb.connectionCost; },
+ setConnectionCost : function(c) {
+ this._jsPlumb.connectionCost = c;
+ },
+ areConnectionsDirected : function() { return this._jsPlumb.connectionsDirected; },
+ setConnectionsDirected : function(b) { this._jsPlumb.connectionsDirected = b; },
+ setElementId : function(_elId) {
+ this.elementId = _elId;
+ this.anchor.elementId = _elId;
+ },
+ setReferenceElement : function(_el) {
+ this.element = jsPlumb.CurrentLibrary.getDOMElement(_el);
+ },
+ setDragAllowedWhenFull : function(allowed) {
+ this.dragAllowedWhenFull = allowed;
+ },
+ equals : function(endpoint) {
+ return this.anchor.equals(endpoint.anchor);
+ },
+ getUuid : function() {
+ return this._jsPlumb.uuid;
+ },
+ computeAnchor : function(params) {
+ return this.anchor.compute(params);
+ }
+ });
+})();
+;(function() {
+
+ var makeConnector = function(_jsPlumb, renderMode, connectorName, connectorArgs) {
+ if (!_jsPlumb.Defaults.DoNotThrowErrors && jsPlumb.Connectors[renderMode][connectorName] == null)
+ throw { msg:"jsPlumb: unknown connector type '" + connectorName + "'" };
+
+ return new jsPlumb.Connectors[renderMode][connectorName](connectorArgs);
+ },
+ _makeAnchor = function(anchorParams, elementId, _jsPlumb) {
+ return (anchorParams) ? _jsPlumb.makeAnchor(anchorParams, elementId, _jsPlumb) : null;
+ },
+ prepareEndpoint = function(_jsPlumb, _newEndpoint, conn, existing, index, params, element, elementId, connectorPaintStyle, connectorHoverPaintStyle) {
+ var e;
+ if (existing) {
+ conn.endpoints[index] = existing;
+ existing.addConnection(conn);
+ } else {
+ if (!params.endpoints) params.endpoints = [ null, null ];
+ var ep = params.endpoints[index] || params.endpoint || _jsPlumb.Defaults.Endpoints[index] || jsPlumb.Defaults.Endpoints[index] || _jsPlumb.Defaults.Endpoint || jsPlumb.Defaults.Endpoint;
+ if (!params.endpointStyles) params.endpointStyles = [ null, null ];
+ if (!params.endpointHoverStyles) params.endpointHoverStyles = [ null, null ];
+ var es = params.endpointStyles[index] || params.endpointStyle || _jsPlumb.Defaults.EndpointStyles[index] || jsPlumb.Defaults.EndpointStyles[index] || _jsPlumb.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle;
+ // Endpoints derive their fillStyle from the connector's strokeStyle, if no fillStyle was specified.
+ if (es.fillStyle == null && connectorPaintStyle != null)
+ es.fillStyle = connectorPaintStyle.strokeStyle;
+
+ // TODO: decide if the endpoint should derive the connection's outline width and color. currently it does:
+ //*
+ if (es.outlineColor == null && connectorPaintStyle != null)
+ es.outlineColor = connectorPaintStyle.outlineColor;
+ if (es.outlineWidth == null && connectorPaintStyle != null)
+ es.outlineWidth = connectorPaintStyle.outlineWidth;
+ //*/
+
+ var ehs = params.endpointHoverStyles[index] || params.endpointHoverStyle || _jsPlumb.Defaults.EndpointHoverStyles[index] || jsPlumb.Defaults.EndpointHoverStyles[index] || _jsPlumb.Defaults.EndpointHoverStyle || jsPlumb.Defaults.EndpointHoverStyle;
+ // endpoint hover fill style is derived from connector's hover stroke style. TODO: do we want to do this by default? for sure?
+ if (connectorHoverPaintStyle != null) {
+ if (ehs == null) ehs = {};
+ if (ehs.fillStyle == null) {
+ ehs.fillStyle = connectorHoverPaintStyle.strokeStyle;
+ }
+ }
+ var a = params.anchors ? params.anchors[index] :
+ params.anchor ? params.anchor :
+ _makeAnchor(_jsPlumb.Defaults.Anchors[index], elementId, _jsPlumb) ||
+ _makeAnchor(jsPlumb.Defaults.Anchors[index], elementId,_jsPlumb) ||
+ _makeAnchor(_jsPlumb.Defaults.Anchor, elementId,_jsPlumb) ||
+ _makeAnchor(jsPlumb.Defaults.Anchor, elementId, _jsPlumb),
+ u = params.uuids ? params.uuids[index] : null;
+ e = _newEndpoint({
+ paintStyle : es, hoverPaintStyle:ehs, endpoint : ep, connections : [ conn ],
+ uuid : u, anchor : a, source : element, scope : params.scope, container:params.container,
+ reattach:params.reattach || _jsPlumb.Defaults.ReattachConnections,
+ detachable:params.detachable || _jsPlumb.Defaults.ConnectionsDetachable
+ });
+ conn.endpoints[index] = e;
+
+ if (params.drawEndpoints === false) e.setVisible(false, true, true);
+
+ }
+ return e;
+ };
+
+ jsPlumb.Connection = function(params) {
+ var _newConnection = params.newConnection,
+ _newEndpoint = params.newEndpoint,
+ jpcl = jsPlumb.CurrentLibrary,
+ _att = jpcl.getAttribute,
+ _gel = jpcl.getElementObject,
+ _dom = jpcl.getDOMElement,
+ _ju = jsPlumbUtil,
+ _getOffset = jpcl.getOffset;
+
+ this.connector = null;
+ this.idPrefix = "_jsplumb_c_";
+ this.defaultLabelLocation = 0.5;
+ this.defaultOverlayKeys = ["Overlays", "ConnectionOverlays"];
+ this.parent = params.parent;
+ // if a new connection is the result of moving some existing connection, params.previousConnection
+ // will have that Connection in it. listeners for the jsPlumbConnection event can look for that
+ // member and take action if they need to.
+ this.previousConnection = params.previousConnection;
+ this.source = _dom(params.source);
+ this.target = _dom(params.target);
+ // sourceEndpoint and targetEndpoint override source/target, if they are present. but
+ // source is not overridden if the Endpoint has declared it is not the final target of a connection;
+ // instead we use the source that the Endpoint declares will be the final source element.
+ if (params.sourceEndpoint) this.source = params.sourceEndpoint.endpointWillMoveTo || params.sourceEndpoint.getElement();
+ if (params.targetEndpoint) this.target = params.targetEndpoint.getElement();
+
+ OverlayCapableJsPlumbUIComponent.apply(this, arguments);
+
+ this.sourceId = this._jsPlumb.instance.getId(this.source);
+ this.targetId = this._jsPlumb.instance.getId(this.target);
+ this.scope = params.scope; // scope may have been passed in to the connect call. if it wasn't, we will pull it from the source endpoint, after having initialised the endpoints.
+ this.endpoints = [];
+ this.endpointStyles = [];
+
+ var _jsPlumb = this._jsPlumb.instance;
+ this._jsPlumb.visible = true;
+ this._jsPlumb.editable = params.editable === true;
+ this._jsPlumb.params = {
+ parent:params.parent,
+ cssClass:params.cssClass,
+ container:params.container,
+ "pointer-events":params["pointer-events"],
+ editorParams:params.editorParams
+ };
+ this._jsPlumb.lastPaintedAt = null;
+ this.getDefaultType = function() {
+ return {
+ parameters:{},
+ scope:null,
+ detachable:this._jsPlumb.instance.Defaults.ConnectionsDetachable,
+ rettach:this._jsPlumb.instance.Defaults.ReattachConnections,
+ paintStyle:this._jsPlumb.instance.Defaults.PaintStyle || jsPlumb.Defaults.PaintStyle,
+ connector:this._jsPlumb.instance.Defaults.Connector || jsPlumb.Defaults.Connector,
+ hoverPaintStyle:this._jsPlumb.instance.Defaults.HoverPaintStyle || jsPlumb.Defaults.HoverPaintStyle,
+ overlays:this._jsPlumb.instance.Defaults.ConnectorOverlays || jsPlumb.Defaults.ConnectorOverlays
+ };
+ };
+
+// INITIALISATION CODE
+
+ // wrapped the main function to return null if no input given. this lets us cascade defaults properly.
+
+ var eS = prepareEndpoint(_jsPlumb, _newEndpoint, this, params.sourceEndpoint, 0, params, this.source, this.sourceId, params.paintStyle, params.hoverPaintStyle);
+ if (eS) _ju.addToList(params.endpointsByElement, this.sourceId, eS);
+ var eT = prepareEndpoint(_jsPlumb, _newEndpoint, this, params.targetEndpoint, 1, params, this.target, this.targetId, params.paintStyle, params.hoverPaintStyle);
+ if (eT) _ju.addToList(params.endpointsByElement, this.targetId, eT);
+ // if scope not set, set it to be the scope for the source endpoint.
+ if (!this.scope) this.scope = this.endpoints[0].scope;
+
+ // if explicitly told to (or not to) delete endpoints on detach, override endpoint's preferences
+ if (params.deleteEndpointsOnDetach != null) {
+ this.endpoints[0]._deleteOnDetach = params.deleteEndpointsOnDetach;
+ this.endpoints[1]._deleteOnDetach = params.deleteEndpointsOnDetach;
+ }
+ else {
+ // otherwise, unless the endpoints say otherwise, mark them for deletion.
+ if (!this.endpoints[0]._doNotDeleteOnDetach) this.endpoints[0]._deleteOnDetach = true;
+ if (!this.endpoints[1]._doNotDeleteOnDetach) this.endpoints[1]._deleteOnDetach = true;
+ }
+
+ // TODO these could surely be refactored into some method that tries them one at a time until something exists
+ this.setConnector(this.endpoints[0].connector ||
+ this.endpoints[1].connector ||
+ params.connector ||
+ _jsPlumb.Defaults.Connector ||
+ jsPlumb.Defaults.Connector, true);
+
+ if (params.path)
+ this.connector.setPath(params.path);
+
+ this.setPaintStyle(this.endpoints[0].connectorStyle ||
+ this.endpoints[1].connectorStyle ||
+ params.paintStyle ||
+ _jsPlumb.Defaults.PaintStyle ||
+ jsPlumb.Defaults.PaintStyle, true);
+
+ this.setHoverPaintStyle(this.endpoints[0].connectorHoverStyle ||
+ this.endpoints[1].connectorHoverStyle ||
+ params.hoverPaintStyle ||
+ _jsPlumb.Defaults.HoverPaintStyle ||
+ jsPlumb.Defaults.HoverPaintStyle, true);
+
+ this._jsPlumb.paintStyleInUse = this.getPaintStyle();
+
+ var _suspendedAt = _jsPlumb.getSuspendedAt();
+ _jsPlumb.updateOffset( { elId : this.sourceId, timestamp:_suspendedAt });
+ _jsPlumb.updateOffset( { elId : this.targetId, timestamp:_suspendedAt });
+
+//*
+ if(!_jsPlumb.isSuspendDrawing()) {
+ // paint the endpoints
+ var myInfo = _jsPlumb.getCachedData(this.sourceId),
+ myOffset = myInfo.o, myWH = myInfo.s,
+ otherInfo = _jsPlumb.getCachedData(this.targetId),
+ otherOffset = otherInfo.o,
+ otherWH = otherInfo.s,
+ initialTimestamp = _suspendedAt || _jsPlumb.timestamp(),
+ anchorLoc = this.endpoints[0].anchor.compute( {
+ xy : [ myOffset.left, myOffset.top ], wh : myWH, element : this.endpoints[0],
+ elementId:this.endpoints[0].elementId,
+ txy : [ otherOffset.left, otherOffset.top ], twh : otherWH, tElement : this.endpoints[1],
+ timestamp:initialTimestamp
+ });
+
+ this.endpoints[0].paint( { anchorLoc : anchorLoc, timestamp:initialTimestamp });
+
+ anchorLoc = this.endpoints[1].anchor.compute( {
+ xy : [ otherOffset.left, otherOffset.top ], wh : otherWH, element : this.endpoints[1],
+ elementId:this.endpoints[1].elementId,
+ txy : [ myOffset.left, myOffset.top ], twh : myWH, tElement : this.endpoints[0],
+ timestamp:initialTimestamp
+ });
+ this.endpoints[1].paint({ anchorLoc : anchorLoc, timestamp:initialTimestamp });
+ }
+ //*/
+
+// END INITIALISATION CODE
+
+// DETACHABLE
+ this._jsPlumb.detachable = _jsPlumb.Defaults.ConnectionsDetachable;
+ if (params.detachable === false) this._jsPlumb.detachable = false;
+ if(this.endpoints[0].connectionsDetachable === false) this._jsPlumb.detachable = false;
+ if(this.endpoints[1].connectionsDetachable === false) this._jsPlumb.detachable = false;
+// REATTACH
+ this._jsPlumb.reattach = params.reattach || this.endpoints[0].reattachConnections || this.endpoints[1].reattachConnections || _jsPlumb.Defaults.ReattachConnections;
+// COST + DIRECTIONALITY
+ // if cost not supplied, try to inherit from source endpoint
+ this._jsPlumb.cost = params.cost || this.endpoints[0].getConnectionCost();
+ this._jsPlumb.directed = params.directed;
+ // inherit directed flag if set no source endpoint
+ if (params.directed == null) this._jsPlumb.directed = this.endpoints[0].areConnectionsDirected();
+// END COST + DIRECTIONALITY
+
+// PARAMETERS
+ // merge all the parameters objects into the connection. parameters set
+ // on the connection take precedence; then source endpoint params, then
+ // finally target endpoint params.
+ // TODO jsPlumb.extend could be made to take more than two args, and it would
+ // apply the second through nth args in order.
+ var _p = jsPlumb.extend({}, this.endpoints[1].getParameters());
+ jsPlumb.extend(_p, this.endpoints[0].getParameters());
+ jsPlumb.extend(_p, this.getParameters());
+ this.setParameters(_p);
+// END PARAMETERS
+
+// PAINTING
+
+ // the very last thing we do is check to see if a 'type' was supplied in the params
+ var _type = params.type || this.endpoints[0].connectionType || this.endpoints[1].connectionType;
+ if (_type)
+ this.addType(_type, params.data, true);
+
+// END PAINTING
+ };
+
+ jsPlumbUtil.extend(jsPlumb.Connection, OverlayCapableJsPlumbUIComponent, {
+ applyType : function(t, doNotRepaint) {
+ if (t.detachable != null) this.setDetachable(t.detachable);
+ if (t.reattach != null) this.setReattach(t.reattach);
+ if (t.scope) this.scope = t.scope;
+ //editable = t.editable; // TODO
+ this.setConnector(t.connector, doNotRepaint);
+ },
+ getTypeDescriptor : function() { return "connection"; },
+ getAttachedElements : function() {
+ return this.endpoints;
+ },
+ addClass : function(c, informEndpoints) {
+ if (informEndpoints) {
+ this.endpoints[0].addClass(c);
+ this.endpoints[1].addClass(c);
+ if (this.suspendedEndpoint) this.suspendedEndpoint.addClass(c);
+ }
+ if (this.connector) {
+ this.connector.addClass(c);
+ }
+ },
+ removeClass : function(c, informEndpoints) {
+ if (informEndpoints) {
+ this.endpoints[0].removeClass(c);
+ this.endpoints[1].removeClass(c);
+ if (this.suspendedEndpoint) this.suspendedEndpoint.removeClass(c);
+ }
+ if (this.connector) {
+ this.connector.removeClass(c);
+ }
+ },
+ isVisible : function() { return this._jsPlumb.visible; },
+ setVisible : function(v) {
+ this._jsPlumb.visible = v;
+ this[v ? "showOverlays" : "hideOverlays"]();
+ if (this.connector && this.connector.canvas) this.connector.canvas.style.display = v ? "block" : "none";
+ this.repaint();
+ },
+ setEditable : function(e) {
+ if (this.connector && this.connector.isEditable())
+ this._jsPlumb.editable = e;
+
+ return this._jsPlumb.editable;
+ },
+ isEditable : function() { return this._jsPlumb.editable; },
+ editStarted : function() {
+ this.setSuspendEvents(true);
+ this.fire("editStarted", {
+ path:this.connector.getPath()
+ });
+ this._jsPlumb.instance.setHoverSuspended(true);
+ },
+ editCompleted : function() {
+ this.fire("editCompleted", {
+ path:this.connector.getPath()
+ });
+ this.setSuspendEvents(false);
+ this.setHover(false);
+ this._jsPlumb.instance.setHoverSuspended(false);
+ },
+ editCanceled : function() {
+ this.fire("editCanceled", {
+ path:this.connector.getPath()
+ });
+ this.setHover(false);
+ this._jsPlumb.instance.setHoverSuspended(false);
+ },
+ cleanup:function() {
+ //this.endpointsToDeleteOnDetach = null;
+ this.endpoints = null;
+ this.source = null;
+ this.target = null;
+ if (this.connector != null) {
+ this.connector.cleanup();
+ this.connector.destroy();
+ }
+ this.connector = null;
+ },
+ isDetachable : function() {
+ return this._jsPlumb.detachable === true;
+ },
+ setDetachable : function(detachable) {
+ this._jsPlumb.detachable = detachable === true;
+ },
+ isReattach : function() {
+ return this._jsPlumb.reattach === true;
+ },
+ setReattach : function(reattach) {
+ this._jsPlumb.reattach = reattach === true;
+ },
+ setHover : function(state) {
+ if (this.connector && this._jsPlumb && !this._jsPlumb.instance.isConnectionBeingDragged()) {
+ this.connector.setHover(state);
+ jsPlumb.CurrentLibrary[state ? "addClass" : "removeClass"](this.source, this._jsPlumb.instance.hoverSourceClass);
+ jsPlumb.CurrentLibrary[state ? "addClass" : "removeClass"](this.target, this._jsPlumb.instance.hoverTargetClass);
+ }
+ },
+ getCost : function() { return this._jsPlumb.cost; },
+ setCost : function(c) { this._jsPlumb.cost = c; },
+ isDirected : function() { return this._jsPlumb.directed === true; },
+ //
+ // changes the parent element of this connection to newParent. not exposed for the public API.
+ //
+ // TODO ensure moveParent method still works (the overlay stuff in particular)
+ moveParent : function(newParent) {
+ var jpcl = jsPlumb.CurrentLibrary, curParent = jpcl.getParent(this.connector.canvas);
+ if (this.connector.bgCanvas) {
+ jpcl.removeElement(this.connector.bgCanvas);
+ jpcl.appendElement(this.connector.bgCanvas, newParent);
+ }
+ jpcl.removeElement(this.connector.canvas);
+ jpcl.appendElement(this.connector.canvas, newParent);
+ // this only applies for DOMOverlays
+ for (var i = 0; i < this._jsPlumb.overlays.length; i++) {
+ if (this._jsPlumb.overlays[i].isAppendedAtTopLevel) {
+ jpcl.removeElement(this._jsPlumb.overlays[i].canvas);
+ jpcl.appendElement(this._jsPlumb.overlays[i].canvas, newParent);
+ if (this._jsPlumb.overlays[i].reattachListeners)
+ this._jsPlumb.overlays[i].reattachListeners(this.connector);
+ }
+ }
+ if (this.connector.reattachListeners) // this is for SVG/VML; change an element's parent and you have to reinit its listeners.
+ this.connector.reattachListeners(); // the Canvas implementation doesn't have to care about this
+ },
+ getConnector : function() { return this.connector; },
+ setConnector : function(connectorSpec, doNotRepaint) {
+ var _ju = jsPlumbUtil;
+ if (this.connector != null) {
+ this.connector.cleanup();
+ this.connector.destroy();
+ }
+
+ var connectorArgs = {
+ _jsPlumb:this._jsPlumb.instance,
+ parent:this._jsPlumb.params.parent,
+ cssClass:this._jsPlumb.params.cssClass,
+ container:this._jsPlumb.params.container,
+ "pointer-events":this._jsPlumb.params["pointer-events"]
+ },
+ renderMode = this._jsPlumb.instance.getRenderMode();
+
+ if (_ju.isString(connectorSpec))
+ this.connector = makeConnector(this._jsPlumb.instance, renderMode, connectorSpec, connectorArgs); // lets you use a string as shorthand.
+ else if (_ju.isArray(connectorSpec)) {
+ if (connectorSpec.length == 1)
+ this.connector = makeConnector(this._jsPlumb.instance, renderMode, connectorSpec[0], connectorArgs);
+ else
+ this.connector = makeConnector(this._jsPlumb.instance, renderMode, connectorSpec[0], _ju.merge(connectorSpec[1], connectorArgs));
+ }
+ // binds mouse listeners to the current connector.
+ this.bindListeners(this.connector, this, function(state) {
+ this.setHover(state, false);
+ }.bind(this));
+
+ this.canvas = this.connector.canvas;
+
+ if (this._jsPlumb.editable && jsPlumb.ConnectorEditors != null && jsPlumb.ConnectorEditors[this.connector.type] && this.connector.isEditable()) {
+ new jsPlumb.ConnectorEditors[this.connector.type]({
+ connector:this.connector,
+ connection:this,
+ params:this._jsPlumb.params.editorParams || { }
+ });
+ }
+ else {
+ editable = false;
+ }
+
+ if (!doNotRepaint) this.repaint();
+ },
+ paint : function(params) {
+
+ if (!this._jsPlumb.instance.isSuspendDrawing() && this._jsPlumb.visible) {
+
+ params = params || {};
+ var elId = params.elId, ui = params.ui, recalc = params.recalc, timestamp = params.timestamp,
+ // if the moving object is not the source we must transpose the two references.
+ swap = false,
+ tId = swap ? this.sourceId : this.targetId, sId = swap ? this.targetId : this.sourceId,
+ tIdx = swap ? 0 : 1, sIdx = swap ? 1 : 0;
+
+ if (timestamp == null || timestamp != this._jsPlumb.lastPaintedAt) {
+ var sourceInfo = this._jsPlumb.instance.updateOffset( { elId : sId, offset : ui, recalc : recalc, timestamp : timestamp }).o,
+ targetInfo = this._jsPlumb.instance.updateOffset( { elId : tId, timestamp : timestamp }).o, // update the target if this is a forced repaint. otherwise, only the source has been moved.
+ sE = this.endpoints[sIdx], tE = this.endpoints[tIdx];
+
+ if (params.clearEdits) {
+ sE.anchor.clearUserDefinedLocation();
+ tE.anchor.clearUserDefinedLocation();
+ this.connector.setEdited(false);
+ }
+
+ var sAnchorP = sE.anchor.getCurrentLocation({xy:[sourceInfo.left,sourceInfo.top], wh:[sourceInfo.width, sourceInfo.height], element:sE, timestamp:timestamp}),
+ tAnchorP = tE.anchor.getCurrentLocation({xy:[targetInfo.left,targetInfo.top], wh:[targetInfo.width, targetInfo.height], element:tE, timestamp:timestamp});
+
+ this.connector.resetBounds();
+
+ this.connector.compute({
+ sourcePos:sAnchorP,
+ targetPos:tAnchorP,
+ sourceEndpoint:this.endpoints[sIdx],
+ targetEndpoint:this.endpoints[tIdx],
+ lineWidth:this._jsPlumb.paintStyleInUse.lineWidth,
+ sourceInfo:sourceInfo,
+ targetInfo:targetInfo,
+ clearEdits:params.clearEdits === true
+ });
+
+ var overlayExtents = { minX:Infinity, minY:Infinity, maxX:-Infinity, maxY:-Infinity };
+
+ // compute overlays. we do this first so we can get their placements, and adjust the
+ // container if needs be (if an overlay would be clipped)
+ for ( var i = 0; i < this._jsPlumb.overlays.length; i++) {
+ var o = this._jsPlumb.overlays[i];
+ if (o.isVisible()) {
+ this._jsPlumb.overlayPlacements[i] = o.draw(this.connector, this._jsPlumb.paintStyleInUse);
+ overlayExtents.minX = Math.min(overlayExtents.minX, this._jsPlumb.overlayPlacements[i].minX);
+ overlayExtents.maxX = Math.max(overlayExtents.maxX, this._jsPlumb.overlayPlacements[i].maxX);
+ overlayExtents.minY = Math.min(overlayExtents.minY, this._jsPlumb.overlayPlacements[i].minY);
+ overlayExtents.maxY = Math.max(overlayExtents.maxY, this._jsPlumb.overlayPlacements[i].maxY);
+ }
+ }
+
+ var lineWidth = parseFloat(this._jsPlumb.paintStyleInUse.lineWidth || 1) / 2,
+ outlineWidth = parseFloat(this._jsPlumb.paintStyleInUse.lineWidth || 0),
+ extents = {
+ xmin : Math.min(this.connector.bounds.minX - (lineWidth + outlineWidth), overlayExtents.minX),
+ ymin : Math.min(this.connector.bounds.minY - (lineWidth + outlineWidth), overlayExtents.minY),
+ xmax : Math.max(this.connector.bounds.maxX + (lineWidth + outlineWidth), overlayExtents.maxX),
+ ymax : Math.max(this.connector.bounds.maxY + (lineWidth + outlineWidth), overlayExtents.maxY)
+ };
+
+ // paint the connector.
+ this.connector.paint(this._jsPlumb.paintStyleInUse, null, extents);
+ // and then the overlays
+ for ( var j = 0; j < this._jsPlumb.overlays.length; j++) {
+ var p = this._jsPlumb.overlays[j];
+ if (p.isVisible()) {
+ p.paint(this._jsPlumb.overlayPlacements[j], extents);
+ }
+ }
+ }
+ this._jsPlumb.lastPaintedAt = timestamp;
+ }
+ },
+ /*
+ * Function: repaint
+ * Repaints the Connection. No parameters exposed to public API.
+ */
+ repaint : function(params) {
+ params = params || {};
+ this.paint({ elId : this.sourceId, recalc : !(params.recalc === false), timestamp:params.timestamp, clearEdits:params.clearEdits });
+ }
+
+ }); // END Connection class
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the code for creating and manipulating anchors.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+;(function() {
+
+ //
+ // manages anchors for all elements.
+ //
+ jsPlumb.AnchorManager = function(params) {
+ var _amEndpoints = {},
+ continuousAnchors = {},
+ continuousAnchorLocations = {},
+ userDefinedContinuousAnchorLocations = {},
+ continuousAnchorOrientations = {},
+ Orientation = { HORIZONTAL : "horizontal", VERTICAL : "vertical", DIAGONAL : "diagonal", IDENTITY:"identity" },
+ connectionsByElementId = {},
+ self = this,
+ anchorLists = {},
+ jsPlumbInstance = params.jsPlumbInstance,
+ jpcl = jsPlumb.CurrentLibrary,
+ floatingConnections = {},
+ // TODO this functions uses a crude method of determining orientation between two elements.
+ // 'diagonal' should be chosen when the angle of the line between the two centers is around
+ // one of 45, 135, 225 and 315 degrees. maybe +- 15 degrees.
+ // used by AnchorManager.redraw
+ calculateOrientation = function(sourceId, targetId, sd, td, sourceAnchor, targetAnchor) {
+
+ if (sourceId === targetId) return {
+ orientation:Orientation.IDENTITY,
+ a:["top", "top"]
+ };
+
+ var theta = Math.atan2((td.centery - sd.centery) , (td.centerx - sd.centerx)),
+ theta2 = Math.atan2((sd.centery - td.centery) , (sd.centerx - td.centerx)),
+ h = ((sd.left <= td.left && sd.right >= td.left) || (sd.left <= td.right && sd.right >= td.right) ||
+ (sd.left <= td.left && sd.right >= td.right) || (td.left <= sd.left && td.right >= sd.right)),
+ v = ((sd.top <= td.top && sd.bottom >= td.top) || (sd.top <= td.bottom && sd.bottom >= td.bottom) ||
+ (sd.top <= td.top && sd.bottom >= td.bottom) || (td.top <= sd.top && td.bottom >= sd.bottom)),
+ possiblyTranslateEdges = function(edges) {
+ // this function checks to see if either anchor is Continuous, and if so, runs the suggested edge
+ // through the anchor: Continuous anchors can say which faces they support, and they get to choose
+ // whether a certain face is honoured, or, if not, which face to replace it with. the behaviour when
+ // choosing an alternate face is to try for the opposite face first, then the next one clockwise, and then
+ // the opposite of that one.
+ return [
+ sourceAnchor.isContinuous ? sourceAnchor.verifyEdge(edges[0]) : edges[0],
+ targetAnchor.isContinuous ? targetAnchor.verifyEdge(edges[1]) : edges[1]
+ ];
+ },
+ out = {
+ orientation:Orientation.DIAGONAL,
+ theta:theta,
+ theta2:theta2
+ };
+
+ if (! (h || v)) {
+ if (td.left > sd.left && td.top > sd.top)
+ out.a = ["right", "top"];
+ else if (td.left > sd.left && sd.top > td.top)
+ out.a = [ "top", "left"];
+ else if (td.left < sd.left && td.top < sd.top)
+ out.a = [ "top", "right"];
+ else if (td.left < sd.left && td.top > sd.top)
+ out.a = ["left", "top" ];
+ }
+ else if (h) {
+ out.orientation = Orientation.HORIZONTAL;
+ out.a = sd.top < td.top ? ["bottom", "top"] : ["top", "bottom"];
+ }
+ else {
+ out.orientation = Orientation.VERTICAL;
+ out.a = sd.left < td.left ? ["right", "left"] : ["left", "right"];
+ }
+
+ out.a = possiblyTranslateEdges(out.a);
+ return out;
+ },
+ // used by placeAnchors function
+ placeAnchorsOnLine = function(desc, elementDimensions, elementPosition,
+ connections, horizontal, otherMultiplier, reverse) {
+ var a = [], step = elementDimensions[horizontal ? 0 : 1] / (connections.length + 1);
+
+ for (var i = 0; i < connections.length; i++) {
+ var val = (i + 1) * step, other = otherMultiplier * elementDimensions[horizontal ? 1 : 0];
+ if (reverse)
+ val = elementDimensions[horizontal ? 0 : 1] - val;
+
+ var dx = (horizontal ? val : other), x = elementPosition[0] + dx, xp = dx / elementDimensions[0],
+ dy = (horizontal ? other : val), y = elementPosition[1] + dy, yp = dy / elementDimensions[1];
+
+ a.push([ x, y, xp, yp, connections[i][1], connections[i][2] ]);
+ }
+
+ return a;
+ },
+ // used by edgeSortFunctions
+ currySort = function(reverseAngles) {
+ return function(a,b) {
+ var r = true;
+ if (reverseAngles) {
+ /*if (a[0][0] < b[0][0])
+ r = true;
+ else
+ r = a[0][1] > b[0][1];*/
+ r = a[0][0] < b[0][0];
+ }
+ else {
+ /*if (a[0][0] > b[0][0])
+ r= true;
+ else
+ r =a[0][1] > b[0][1];
+ */
+ r = a[0][0] > b[0][0];
+ }
+ return r === false ? -1 : 1;
+ };
+ },
+ // used by edgeSortFunctions
+ leftSort = function(a,b) {
+ // first get adjusted values
+ var p1 = a[0][0] < 0 ? -Math.PI - a[0][0] : Math.PI - a[0][0],
+ p2 = b[0][0] < 0 ? -Math.PI - b[0][0] : Math.PI - b[0][0];
+ if (p1 > p2) return 1;
+ else return a[0][1] > b[0][1] ? 1 : -1;
+ },
+ // used by placeAnchors
+ edgeSortFunctions = {
+ "top":function(a, b) { return a[0] > b[0] ? 1 : -1; },
+ "right":currySort(true),
+ "bottom":currySort(true),
+ "left":leftSort
+ },
+ // used by placeAnchors
+ _sortHelper = function(_array, _fn) { return _array.sort(_fn); },
+ // used by AnchorManager.redraw
+ placeAnchors = function(elementId, _anchorLists) {
+ var cd = jsPlumbInstance.getCachedData(elementId), sS = cd.s, sO = cd.o,
+ placeSomeAnchors = function(desc, elementDimensions, elementPosition, unsortedConnections, isHorizontal, otherMultiplier, orientation) {
+ if (unsortedConnections.length > 0) {
+ var sc = _sortHelper(unsortedConnections, edgeSortFunctions[desc]), // puts them in order based on the target element's pos on screen
+ reverse = desc === "right" || desc === "top",
+ anchors = placeAnchorsOnLine(desc, elementDimensions,
+ elementPosition, sc,
+ isHorizontal, otherMultiplier, reverse );
+
+ // takes a computed anchor position and adjusts it for parent offset and scroll, then stores it.
+ var _setAnchorLocation = function(endpoint, anchorPos) {
+ var a = jsPlumbInstance.adjustForParentOffsetAndScroll([anchorPos[0], anchorPos[1]], endpoint.canvas);
+ continuousAnchorLocations[endpoint.id] = [ a[0], a[1], anchorPos[2], anchorPos[3] ];
+ continuousAnchorOrientations[endpoint.id] = orientation;
+ };
+
+ for (var i = 0; i < anchors.length; i++) {
+ var c = anchors[i][4], weAreSource = c.endpoints[0].elementId === elementId, weAreTarget = c.endpoints[1].elementId === elementId;
+ if (weAreSource)
+ _setAnchorLocation(c.endpoints[0], anchors[i]);
+ else if (weAreTarget)
+ _setAnchorLocation(c.endpoints[1], anchors[i]);
+ }
+ }
+ };
+
+ placeSomeAnchors("bottom", sS, [sO.left,sO.top], _anchorLists.bottom, true, 1, [0,1]);
+ placeSomeAnchors("top", sS, [sO.left,sO.top], _anchorLists.top, true, 0, [0,-1]);
+ placeSomeAnchors("left", sS, [sO.left,sO.top], _anchorLists.left, false, 0, [-1,0]);
+ placeSomeAnchors("right", sS, [sO.left,sO.top], _anchorLists.right, false, 1, [1,0]);
+ };
+
+ this.reset = function() {
+ _amEndpoints = {};
+ connectionsByElementId = {};
+ anchorLists = {};
+ };
+ this.addFloatingConnection = function(key, conn) {
+ floatingConnections[key] = conn;
+ };
+ this.removeFloatingConnection = function(key) {
+ delete floatingConnections[key];
+ };
+ this.newConnection = function(conn) {
+ var sourceId = conn.sourceId, targetId = conn.targetId,
+ ep = conn.endpoints,
+ doRegisterTarget = true,
+ registerConnection = function(otherIndex, otherEndpoint, otherAnchor, elId, c) {
+ if ((sourceId == targetId) && otherAnchor.isContinuous){
+ // remove the target endpoint's canvas. we dont need it.
+ jpcl.removeElement(ep[1].canvas);
+ doRegisterTarget = false;
+ }
+ jsPlumbUtil.addToList(connectionsByElementId, elId, [c, otherEndpoint, otherAnchor.constructor == jsPlumb.DynamicAnchor]);
+ };
+
+ registerConnection(0, ep[0], ep[0].anchor, targetId, conn);
+ if (doRegisterTarget)
+ registerConnection(1, ep[1], ep[1].anchor, sourceId, conn);
+ };
+ var removeEndpointFromAnchorLists = function(endpoint) {
+ (function(list, eId) {
+ if (list) { // transient anchors dont get entries in this list.
+ var f = function(e) { return e[4] == eId; };
+ jsPlumbUtil.removeWithFunction(list.top, f);
+ jsPlumbUtil.removeWithFunction(list.left, f);
+ jsPlumbUtil.removeWithFunction(list.bottom, f);
+ jsPlumbUtil.removeWithFunction(list.right, f);
+ }
+ })(anchorLists[endpoint.elementId], endpoint.id);
+ };
+ this.connectionDetached = function(connInfo) {
+ var connection = connInfo.connection || connInfo,
+ sourceId = connInfo.sourceId,
+ targetId = connInfo.targetId,
+ ep = connection.endpoints,
+ removeConnection = function(otherIndex, otherEndpoint, otherAnchor, elId, c) {
+ if (otherAnchor != null && otherAnchor.constructor == jsPlumb.FloatingAnchor) {
+ // no-op
+ }
+ else {
+ jsPlumbUtil.removeWithFunction(connectionsByElementId[elId], function(_c) {
+ return _c[0].id == c.id;
+ });
+ }
+ };
+
+ removeConnection(1, ep[1], ep[1].anchor, sourceId, connection);
+ removeConnection(0, ep[0], ep[0].anchor, targetId, connection);
+
+ // remove from anchorLists
+ removeEndpointFromAnchorLists(connection.endpoints[0]);
+ removeEndpointFromAnchorLists(connection.endpoints[1]);
+
+ self.redraw(connection.sourceId);
+ self.redraw(connection.targetId);
+ };
+ this.add = function(endpoint, elementId) {
+ jsPlumbUtil.addToList(_amEndpoints, elementId, endpoint);
+ };
+ this.changeId = function(oldId, newId) {
+ connectionsByElementId[newId] = connectionsByElementId[oldId];
+ _amEndpoints[newId] = _amEndpoints[oldId];
+ delete connectionsByElementId[oldId];
+ delete _amEndpoints[oldId];
+ };
+ this.getConnectionsFor = function(elementId) {
+ return connectionsByElementId[elementId] || [];
+ };
+ this.getEndpointsFor = function(elementId) {
+ return _amEndpoints[elementId] || [];
+ };
+ this.deleteEndpoint = function(endpoint) {
+ jsPlumbUtil.removeWithFunction(_amEndpoints[endpoint.elementId], function(e) {
+ return e.id == endpoint.id;
+ });
+ removeEndpointFromAnchorLists(endpoint);
+ };
+ this.clearFor = function(elementId) {
+ delete _amEndpoints[elementId];
+ _amEndpoints[elementId] = [];
+ };
+ // updates the given anchor list by either updating an existing anchor's info, or adding it. this function
+ // also removes the anchor from its previous list, if the edge it is on has changed.
+ // all connections found along the way (those that are connected to one of the faces this function
+ // operates on) are added to the connsToPaint list, as are their endpoints. in this way we know to repaint
+ // them wthout having to calculate anything else about them.
+ var _updateAnchorList = function(lists, theta, order, conn, aBoolean, otherElId, idx, reverse, edgeId, elId, connsToPaint, endpointsToPaint) {
+ // first try to find the exact match, but keep track of the first index of a matching element id along the way.s
+ var exactIdx = -1,
+ firstMatchingElIdx = -1,
+ endpoint = conn.endpoints[idx],
+ endpointId = endpoint.id,
+ oIdx = [1,0][idx],
+ values = [ [ theta, order ], conn, aBoolean, otherElId, endpointId ],
+ listToAddTo = lists[edgeId],
+ listToRemoveFrom = endpoint._continuousAnchorEdge ? lists[endpoint._continuousAnchorEdge] : null;
+
+ if (listToRemoveFrom) {
+ var rIdx = jsPlumbUtil.findWithFunction(listToRemoveFrom, function(e) { return e[4] == endpointId; });
+ if (rIdx != -1) {
+ listToRemoveFrom.splice(rIdx, 1);
+ // get all connections from this list
+ for (var i = 0; i < listToRemoveFrom.length; i++) {
+ jsPlumbUtil.addWithFunction(connsToPaint, listToRemoveFrom[i][1], function(c) { return c.id == listToRemoveFrom[i][1].id; });
+ jsPlumbUtil.addWithFunction(endpointsToPaint, listToRemoveFrom[i][1].endpoints[idx], function(e) { return e.id == listToRemoveFrom[i][1].endpoints[idx].id; });
+ jsPlumbUtil.addWithFunction(endpointsToPaint, listToRemoveFrom[i][1].endpoints[oIdx], function(e) { return e.id == listToRemoveFrom[i][1].endpoints[oIdx].id; });
+ }
+ }
+ }
+
+ for (i = 0; i < listToAddTo.length; i++) {
+ if (params.idx == 1 && listToAddTo[i][3] === otherElId && firstMatchingElIdx == -1)
+ firstMatchingElIdx = i;
+ jsPlumbUtil.addWithFunction(connsToPaint, listToAddTo[i][1], function(c) { return c.id == listToAddTo[i][1].id; });
+ jsPlumbUtil.addWithFunction(endpointsToPaint, listToAddTo[i][1].endpoints[idx], function(e) { return e.id == listToAddTo[i][1].endpoints[idx].id; });
+ jsPlumbUtil.addWithFunction(endpointsToPaint, listToAddTo[i][1].endpoints[oIdx], function(e) { return e.id == listToAddTo[i][1].endpoints[oIdx].id; });
+ }
+ if (exactIdx != -1) {
+ listToAddTo[exactIdx] = values;
+ }
+ else {
+ var insertIdx = reverse ? firstMatchingElIdx != -1 ? firstMatchingElIdx : 0 : listToAddTo.length; // of course we will get this from having looked through the array shortly.
+ listToAddTo.splice(insertIdx, 0, values);
+ }
+
+ // store this for next time.
+ endpoint._continuousAnchorEdge = edgeId;
+ };
+
+ //
+ // find the entry in an endpoint's list for this connection and update its target endpoint
+ // with the current target in the connection.
+ //
+ //
+ this.updateOtherEndpoint = function(elId, oldTargetId, newTargetId, connection) {
+ var sIndex = jsPlumbUtil.findWithFunction(connectionsByElementId[elId], function(i) {
+ return i[0].id === connection.id;
+ }),
+ tIndex = jsPlumbUtil.findWithFunction(connectionsByElementId[oldTargetId], function(i) {
+ return i[0].id === connection.id;
+ });
+
+ // update or add data for source
+ if (sIndex != -1) {
+ connectionsByElementId[elId][sIndex][0] = connection;
+ connectionsByElementId[elId][sIndex][1] = connection.endpoints[1];
+ connectionsByElementId[elId][sIndex][2] = connection.endpoints[1].anchor.constructor == jsPlumb.DynamicAnchor;
+ }
+
+ // remove entry for previous target (if there)
+ if (tIndex > -1) {
+
+ connectionsByElementId[oldTargetId].splice(tIndex, 1);
+ // add entry for new target
+ jsPlumbUtil.addToList(connectionsByElementId, newTargetId, [connection, connection.endpoints[0], connection.endpoints[0].anchor.constructor == jsPlumb.DynamicAnchor]);
+ }
+ };
+
+ //
+ // notification that the connection given has changed source from the originalId to the newId.
+ // This involves:
+ // 1. removing the connection from the list of connections stored for the originalId
+ // 2. updating the source information for the target of the connection
+ // 3. re-registering the connection in connectionsByElementId with the newId
+ //
+ this.sourceChanged = function(originalId, newId, connection) {
+ // remove the entry that points from the old source to the target
+ jsPlumbUtil.removeWithFunction(connectionsByElementId[originalId], function(info) {
+ return info[0].id === connection.id;
+ });
+ // find entry for target and update it
+ var tIdx = jsPlumbUtil.findWithFunction(connectionsByElementId[connection.targetId], function(i) {
+ return i[0].id === connection.id;
+ });
+ if (tIdx > -1) {
+ connectionsByElementId[connection.targetId][tIdx][0] = connection;
+ connectionsByElementId[connection.targetId][tIdx][1] = connection.endpoints[0];
+ connectionsByElementId[connection.targetId][tIdx][2] = connection.endpoints[0].anchor.constructor == jsPlumb.DynamicAnchor;
+ }
+ // add entry for new source
+ jsPlumbUtil.addToList(connectionsByElementId, newId, [connection, connection.endpoints[1], connection.endpoints[1].anchor.constructor == jsPlumb.DynamicAnchor]);
+ };
+
+ //
+ // moves the given endpoint from `currentId` to `element`.
+ // This involves:
+ //
+ // 1. changing the key in _amEndpoints under which the endpoint is stored
+ // 2. changing the source or target values in all of the endpoint's connections
+ // 3. changing the array in connectionsByElementId in which the endpoint's connections
+ // are stored (done by either sourceChanged or updateOtherEndpoint)
+ //
+ this.rehomeEndpoint = function(ep, currentId, element) {
+ var eps = _amEndpoints[currentId] || [],
+ elementId = jsPlumbInstance.getId(element);
+
+ if (elementId !== currentId) {
+ var idx = jsPlumbUtil.indexOf(eps, ep);
+ if (idx > -1) {
+ var _ep = eps.splice(idx, 1)[0];
+ self.add(_ep, elementId);
+ }
+ }
+
+ for (var i = 0; i < ep.connections.length; i++) {
+ if (ep.connections[i].sourceId == currentId) {
+ ep.connections[i].sourceId = ep.elementId;
+ ep.connections[i].source = ep.element;
+ self.sourceChanged(currentId, ep.elementId, ep.connections[i]);
+ }
+ else if(ep.connections[i].targetId == currentId) {
+ ep.connections[i].targetId = ep.elementId;
+ ep.connections[i].target = ep.element;
+ self.updateOtherEndpoint(ep.connections[i].sourceId, currentId, ep.elementId, ep.connections[i]);
+ }
+ }
+ };
+
+ this.redraw = function(elementId, ui, timestamp, offsetToUI, clearEdits, doNotRecalcEndpoint) {
+
+ if (!jsPlumbInstance.isSuspendDrawing()) {
+ // get all the endpoints for this element
+ var ep = _amEndpoints[elementId] || [],
+ endpointConnections = connectionsByElementId[elementId] || [],
+ connectionsToPaint = [],
+ endpointsToPaint = [],
+ anchorsToUpdate = [];
+
+ timestamp = timestamp || jsPlumbInstance.timestamp();
+ // offsetToUI are values that would have been calculated in the dragManager when registering
+ // an endpoint for an element that had a parent (somewhere in the hierarchy) that had been
+ // registered as draggable.
+ offsetToUI = offsetToUI || {left:0, top:0};
+ if (ui) {
+ ui = {
+ left:ui.left + offsetToUI.left,
+ top:ui.top + offsetToUI.top
+ };
+ }
+
+ // valid for one paint cycle.
+ var myOffset = jsPlumbInstance.updateOffset( { elId : elementId, offset : ui, recalc : false, timestamp : timestamp }),
+ orientationCache = {};
+
+ // actually, first we should compute the orientation of this element to all other elements to which
+ // this element is connected with a continuous anchor (whether both ends of the connection have
+ // a continuous anchor or just one)
+
+ for (var i = 0; i < endpointConnections.length; i++) {
+ var conn = endpointConnections[i][0],
+ sourceId = conn.sourceId,
+ targetId = conn.targetId,
+ sourceContinuous = conn.endpoints[0].anchor.isContinuous,
+ targetContinuous = conn.endpoints[1].anchor.isContinuous;
+
+ if (sourceContinuous || targetContinuous) {
+ var oKey = sourceId + "_" + targetId,
+ oKey2 = targetId + "_" + sourceId,
+ o = orientationCache[oKey],
+ oIdx = conn.sourceId == elementId ? 1 : 0;
+
+ if (sourceContinuous && !anchorLists[sourceId]) anchorLists[sourceId] = { top:[], right:[], bottom:[], left:[] };
+ if (targetContinuous && !anchorLists[targetId]) anchorLists[targetId] = { top:[], right:[], bottom:[], left:[] };
+
+ if (elementId != targetId) jsPlumbInstance.updateOffset( { elId : targetId, timestamp : timestamp });
+ if (elementId != sourceId) jsPlumbInstance.updateOffset( { elId : sourceId, timestamp : timestamp });
+
+ var td = jsPlumbInstance.getCachedData(targetId),
+ sd = jsPlumbInstance.getCachedData(sourceId);
+
+ if (targetId == sourceId && (sourceContinuous || targetContinuous)) {
+ // here we may want to improve this by somehow determining the face we'd like
+ // to put the connector on. ideally, when drawing, the face should be calculated
+ // by determining which face is closest to the point at which the mouse button
+ // was released. for now, we're putting it on the top face.
+ _updateAnchorList(
+ anchorLists[sourceId],
+ -Math.PI / 2,
+ 0,
+ conn,
+ false,
+ targetId,
+ 0, false, "top", sourceId, connectionsToPaint, endpointsToPaint);
+ }
+ else {
+ if (!o) {
+ o = calculateOrientation(sourceId, targetId, sd.o, td.o, conn.endpoints[0].anchor, conn.endpoints[1].anchor);
+ orientationCache[oKey] = o;
+ // this would be a performance enhancement, but the computed angles need to be clamped to
+ //the (-PI/2 -> PI/2) range in order for the sorting to work properly.
+ /* orientationCache[oKey2] = {
+ orientation:o.orientation,
+ a:[o.a[1], o.a[0]],
+ theta:o.theta + Math.PI,
+ theta2:o.theta2 + Math.PI
+ };*/
+ }
+ if (sourceContinuous) _updateAnchorList(anchorLists[sourceId], o.theta, 0, conn, false, targetId, 0, false, o.a[0], sourceId, connectionsToPaint, endpointsToPaint);
+ if (targetContinuous) _updateAnchorList(anchorLists[targetId], o.theta2, -1, conn, true, sourceId, 1, true, o.a[1], targetId, connectionsToPaint, endpointsToPaint);
+ }
+
+ if (sourceContinuous) jsPlumbUtil.addWithFunction(anchorsToUpdate, sourceId, function(a) { return a === sourceId; });
+ if (targetContinuous) jsPlumbUtil.addWithFunction(anchorsToUpdate, targetId, function(a) { return a === targetId; });
+ jsPlumbUtil.addWithFunction(connectionsToPaint, conn, function(c) { return c.id == conn.id; });
+ if ((sourceContinuous && oIdx === 0) || (targetContinuous && oIdx === 1))
+ jsPlumbUtil.addWithFunction(endpointsToPaint, conn.endpoints[oIdx], function(e) { return e.id == conn.endpoints[oIdx].id; });
+ }
+ }
+ // place Endpoints whose anchors are continuous but have no Connections
+ for (i = 0; i < ep.length; i++) {
+ if (ep[i].connections.length === 0 && ep[i].anchor.isContinuous) {
+ if (!anchorLists[elementId]) anchorLists[elementId] = { top:[], right:[], bottom:[], left:[] };
+ _updateAnchorList(anchorLists[elementId], -Math.PI / 2, 0, {endpoints:[ep[i], ep[i]], paint:function(){}}, false, elementId, 0, false, "top", elementId, connectionsToPaint, endpointsToPaint);
+ jsPlumbUtil.addWithFunction(anchorsToUpdate, elementId, function(a) { return a === elementId; });
+ }
+ }
+ // now place all the continuous anchors we need to;
+ for (i = 0; i < anchorsToUpdate.length; i++) {
+ placeAnchors(anchorsToUpdate[i], anchorLists[anchorsToUpdate[i]]);
+ }
+
+ // now that continuous anchors have been placed, paint all the endpoints for this element
+ // TODO performance: add the endpoint ids to a temp array, and then when iterating in the next
+ // loop, check that we didn't just paint that endpoint. we can probably shave off a few more milliseconds this way.
+ for (i = 0; i < ep.length; i++) {
+ ep[i].paint( { timestamp : timestamp, offset : myOffset, dimensions : myOffset.s, recalc:doNotRecalcEndpoint !== true });
+ }
+ // ... and any other endpoints we came across as a result of the continuous anchors.
+ for (i = 0; i < endpointsToPaint.length; i++) {
+ var cd = jsPlumbInstance.getCachedData(endpointsToPaint[i].elementId);
+ endpointsToPaint[i].paint( { timestamp : timestamp, offset : cd, dimensions : cd.s });
+ }
+
+ // paint all the standard and "dynamic connections", which are connections whose other anchor is
+ // static and therefore does need to be recomputed; we make sure that happens only one time.
+
+ // TODO we could have compiled a list of these in the first pass through connections; might save some time.
+ for (i = 0; i < endpointConnections.length; i++) {
+ var otherEndpoint = endpointConnections[i][1];
+ if (otherEndpoint.anchor.constructor == jsPlumb.DynamicAnchor) {
+ otherEndpoint.paint({ elementWithPrecedence:elementId, timestamp:timestamp });
+ jsPlumbUtil.addWithFunction(connectionsToPaint, endpointConnections[i][0], function(c) { return c.id == endpointConnections[i][0].id; });
+ // all the connections for the other endpoint now need to be repainted
+ for (var k = 0; k < otherEndpoint.connections.length; k++) {
+ if (otherEndpoint.connections[k] !== endpointConnections[i][0])
+ jsPlumbUtil.addWithFunction(connectionsToPaint, otherEndpoint.connections[k], function(c) { return c.id == otherEndpoint.connections[k].id; });
+ }
+ } else if (otherEndpoint.anchor.constructor == jsPlumb.Anchor) {
+ jsPlumbUtil.addWithFunction(connectionsToPaint, endpointConnections[i][0], function(c) { return c.id == endpointConnections[i][0].id; });
+ }
+ }
+ // paint current floating connection for this element, if there is one.
+ var fc = floatingConnections[elementId];
+ if (fc)
+ fc.paint({timestamp:timestamp, recalc:false, elId:elementId});
+
+ // paint all the connections
+ for (i = 0; i < connectionsToPaint.length; i++) {
+ connectionsToPaint[i].paint({elId:elementId, timestamp:timestamp, recalc:false, clearEdits:clearEdits});
+ }
+ }
+ };
+
+ var ContinuousAnchor = function(anchorParams) {
+ jsPlumbUtil.EventGenerator.apply(this);
+ this.type = "Continuous";
+ this.isDynamic = true;
+ this.isContinuous = true;
+ var faces = anchorParams.faces || ["top", "right", "bottom", "left"],
+ clockwise = !(anchorParams.clockwise === false),
+ availableFaces = { },
+ opposites = { "top":"bottom", "right":"left","left":"right","bottom":"top" },
+ clockwiseOptions = { "top":"right", "right":"bottom","left":"top","bottom":"left" },
+ antiClockwiseOptions = { "top":"left", "right":"top","left":"bottom","bottom":"right" },
+ secondBest = clockwise ? clockwiseOptions : antiClockwiseOptions,
+ lastChoice = clockwise ? antiClockwiseOptions : clockwiseOptions,
+ cssClass = anchorParams.cssClass || "";
+
+ for (var i = 0; i < faces.length; i++) { availableFaces[faces[i]] = true; }
+
+ // if the given edge is supported, returns it. otherwise looks for a substitute that _is_
+ // supported. if none supported we also return the request edge.
+ this.verifyEdge = function(edge) {
+ if (availableFaces[edge]) return edge;
+ else if (availableFaces[opposites[edge]]) return opposites[edge];
+ else if (availableFaces[secondBest[edge]]) return secondBest[edge];
+ else if (availableFaces[lastChoice[edge]]) return lastChoice[edge];
+ return edge; // we have to give them something.
+ };
+
+ this.compute = function(params) {
+ return userDefinedContinuousAnchorLocations[params.element.id] || continuousAnchorLocations[params.element.id] || [0,0];
+ };
+ this.getCurrentLocation = function(params) {
+ return userDefinedContinuousAnchorLocations[params.element.id] || continuousAnchorLocations[params.element.id] || [0,0];
+ };
+ this.getOrientation = function(endpoint) {
+ return continuousAnchorOrientations[endpoint.id] || [0,0];
+ };
+ this.clearUserDefinedLocation = function() {
+ delete userDefinedContinuousAnchorLocations[anchorParams.elementId];
+ };
+ this.setUserDefinedLocation = function(loc) {
+ userDefinedContinuousAnchorLocations[anchorParams.elementId] = loc;
+ };
+ this.getCssClass = function() { return cssClass; };
+ this.setCssClass = function(c) { cssClass = c; };
+ };
+
+ // continuous anchors
+ jsPlumbInstance.continuousAnchorFactory = {
+ get:function(params) {
+ var existing = continuousAnchors[params.elementId];
+ if (!existing) {
+ existing = new ContinuousAnchor(params);
+ continuousAnchors[params.elementId] = existing;
+ }
+ return existing;
+ },
+ clear:function(elementId) {
+ delete continuousAnchors[elementId];
+ }
+ };
+ };
+
+ /**
+ * Anchors model a position on some element at which an Endpoint may be located. They began as a first class citizen of jsPlumb, ie. a user
+ * was required to create these themselves, but over time this has been replaced by the concept of referring to them either by name (eg. "TopMiddle"),
+ * or by an array describing their coordinates (eg. [ 0, 0.5, 0, -1 ], which is the same as "TopMiddle"). jsPlumb now handles all of the
+ * creation of Anchors without user intervention.
+ */
+ jsPlumb.Anchor = function(params) {
+ this.x = params.x || 0;
+ this.y = params.y || 0;
+ this.elementId = params.elementId;
+ this.cssClass = params.cssClass || "";
+ this.userDefinedLocation = null;
+ this.orientation = params.orientation || [ 0, 0 ];
+
+ jsPlumbUtil.EventGenerator.apply(this);
+
+ var jsPlumbInstance = params.jsPlumbInstance;//,
+ //lastTimestamp = null;//, lastReturnValue = null;
+
+ this.lastReturnValue = null;
+ this.offsets = params.offsets || [ 0, 0 ];
+ this.timestamp = null;
+ this.compute = function(params) {
+
+ var xy = params.xy, wh = params.wh, element = params.element, timestamp = params.timestamp;
+
+ if(params.clearUserDefinedLocation)
+ this.userDefinedLocation = null;
+
+ if (timestamp && timestamp === self.timestamp)
+ return this.lastReturnValue;
+
+ if (this.userDefinedLocation != null) {
+ this.lastReturnValue = this.userDefinedLocation;
+ }
+ else {
+
+ this.lastReturnValue = [ xy[0] + (this.x * wh[0]) + this.offsets[0], xy[1] + (this.y * wh[1]) + this.offsets[1] ];
+ // adjust loc if there is an offsetParent
+ this.lastReturnValue = jsPlumbInstance.adjustForParentOffsetAndScroll(this.lastReturnValue, element.canvas);
+ }
+
+ this.timestamp = timestamp;
+ return this.lastReturnValue;
+ };
+
+ this.getCurrentLocation = function(params) {
+ return (this.lastReturnValue == null || (params.timestamp != null && this.timestamp != params.timestamp)) ? this.compute(params) : this.lastReturnValue;
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Anchor, jsPlumbUtil.EventGenerator, {
+ equals : function(anchor) {
+ if (!anchor) return false;
+ var ao = anchor.getOrientation(),
+ o = this.getOrientation();
+ return this.x == anchor.x && this.y == anchor.y && this.offsets[0] == anchor.offsets[0] && this.offsets[1] == anchor.offsets[1] && o[0] == ao[0] && o[1] == ao[1];
+ },
+ getUserDefinedLocation : function() {
+ return this.userDefinedLocation;
+ },
+ setUserDefinedLocation : function(l) {
+ this.userDefinedLocation = l;
+ },
+ clearUserDefinedLocation : function() {
+ this.userDefinedLocation = null;
+ },
+ getOrientation : function(_endpoint) { return this.orientation; },
+ getCssClass : function() { return this.cssClass; }
+ });
+
+ /**
+ * An Anchor that floats. its orientation is computed dynamically from
+ * its position relative to the anchor it is floating relative to. It is used when creating
+ * a connection through drag and drop.
+ *
+ * TODO FloatingAnchor could totally be refactored to extend Anchor just slightly.
+ */
+ jsPlumb.FloatingAnchor = function(params) {
+
+ jsPlumb.Anchor.apply(this, arguments);
+
+ // this is the anchor that this floating anchor is referenced to for
+ // purposes of calculating the orientation.
+ var ref = params.reference,
+ jpcl = jsPlumb.CurrentLibrary,
+ jsPlumbInstance = params.jsPlumbInstance,
+ // the canvas this refers to.
+ refCanvas = params.referenceCanvas,
+ size = jpcl.getSize(jpcl.getElementObject(refCanvas)),
+ // these are used to store the current relative position of our
+ // anchor wrt the reference anchor. they only indicate
+ // direction, so have a value of 1 or -1 (or, very rarely, 0). these
+ // values are written by the compute method, and read
+ // by the getOrientation method.
+ xDir = 0, yDir = 0,
+ // temporary member used to store an orientation when the floating
+ // anchor is hovering over another anchor.
+ orientation = null,
+ _lastResult = null;
+
+ // clear from parent. we want floating anchor orientation to always be computed.
+ this.orientation = null;
+
+ // set these to 0 each; they are used by certain types of connectors in the loopback case,
+ // when the connector is trying to clear the element it is on. but for floating anchor it's not
+ // very important.
+ this.x = 0; this.y = 0;
+
+ this.isFloating = true;
+
+ this.compute = function(params) {
+ var xy = params.xy, element = params.element,
+ result = [ xy[0] + (size[0] / 2), xy[1] + (size[1] / 2) ]; // return origin of the element. we may wish to improve this so that any object can be the drag proxy.
+
+ // adjust loc if there is an offsetParent
+ result = jsPlumbInstance.adjustForParentOffsetAndScroll(result, element.canvas);
+
+ _lastResult = result;
+ return result;
+ };
+
+ this.getOrientation = function(_endpoint) {
+ if (orientation) return orientation;
+ else {
+ var o = ref.getOrientation(_endpoint);
+ // here we take into account the orientation of the other
+ // anchor: if it declares zero for some direction, we declare zero too. this might not be the most awesome. perhaps we can come
+ // up with a better way. it's just so that the line we draw looks like it makes sense. maybe this wont make sense.
+ return [ Math.abs(o[0]) * xDir * -1,
+ Math.abs(o[1]) * yDir * -1 ];
+ }
+ };
+
+ /**
+ * notification the endpoint associated with this anchor is hovering
+ * over another anchor; we want to assume that anchor's orientation
+ * for the duration of the hover.
+ */
+ this.over = function(anchor, endpoint) {
+ orientation = anchor.getOrientation(endpoint);
+ };
+
+ /**
+ * notification the endpoint associated with this anchor is no
+ * longer hovering over another anchor; we should resume calculating
+ * orientation as we normally do.
+ */
+ this.out = function() { orientation = null; };
+
+ this.getCurrentLocation = function(params) { return _lastResult == null ? this.compute(params) : _lastResult; };
+ };
+ jsPlumbUtil.extend(jsPlumb.FloatingAnchor, jsPlumb.Anchor);
+
+ var _convertAnchor = function(anchor, jsPlumbInstance, elementId) {
+ return anchor.constructor == jsPlumb.Anchor ? anchor: jsPlumbInstance.makeAnchor(anchor, elementId, jsPlumbInstance);
+ };
+
+ /*
+ * A DynamicAnchor is an Anchor that contains a list of other Anchors, which it cycles
+ * through at compute time to find the one that is located closest to
+ * the center of the target element, and returns that Anchor's compute
+ * method result. this causes endpoints to follow each other with
+ * respect to the orientation of their target elements, which is a useful
+ * feature for some applications.
+ *
+ */
+ jsPlumb.DynamicAnchor = function(params) {
+ jsPlumb.Anchor.apply(this, arguments);
+
+ this.isSelective = true;
+ this.isDynamic = true;
+ this.anchors = [];
+ this.elementId = params.elementId;
+ this.jsPlumbInstance = params.jsPlumbInstance;
+
+ for (var i = 0; i < params.anchors.length; i++)
+ this.anchors[i] = _convertAnchor(params.anchors[i], this.jsPlumbInstance, this.elementId);
+ this.addAnchor = function(anchor) { this.anchors.push(_convertAnchor(anchor, this.jsPlumbInstance, this.elementId)); };
+ this.getAnchors = function() { return this.anchors; };
+ this.locked = false;
+ var _curAnchor = this.anchors.length > 0 ? this.anchors[0] : null,
+ _curIndex = this.anchors.length > 0 ? 0 : -1,
+ _lastAnchor = _curAnchor,
+ self = this,
+
+ // helper method to calculate the distance between the centers of the two elements.
+ _distance = function(anchor, cx, cy, xy, wh) {
+ var ax = xy[0] + (anchor.x * wh[0]), ay = xy[1] + (anchor.y * wh[1]),
+ acx = xy[0] + (wh[0] / 2), acy = xy[1] + (wh[1] / 2);
+ return (Math.sqrt(Math.pow(cx - ax, 2) + Math.pow(cy - ay, 2)) +
+ Math.sqrt(Math.pow(acx - ax, 2) + Math.pow(acy - ay, 2)));
+ },
+ // default method uses distance between element centers. you can provide your own method in the dynamic anchor
+ // constructor (and also to jsPlumb.makeDynamicAnchor). the arguments to it are four arrays:
+ // xy - xy loc of the anchor's element
+ // wh - anchor's element's dimensions
+ // txy - xy loc of the element of the other anchor in the connection
+ // twh - dimensions of the element of the other anchor in the connection.
+ // anchors - the list of selectable anchors
+ _anchorSelector = params.selector || function(xy, wh, txy, twh, anchors) {
+ var cx = txy[0] + (twh[0] / 2), cy = txy[1] + (twh[1] / 2);
+ var minIdx = -1, minDist = Infinity;
+ for ( var i = 0; i < anchors.length; i++) {
+ var d = _distance(anchors[i], cx, cy, xy, wh);
+ if (d < minDist) {
+ minIdx = i + 0;
+ minDist = d;
+ }
+ }
+ return anchors[minIdx];
+ };
+
+ this.compute = function(params) {
+ var xy = params.xy, wh = params.wh, timestamp = params.timestamp, txy = params.txy, twh = params.twh;
+
+ if(params.clearUserDefinedLocation)
+ userDefinedLocation = null;
+
+ this.timestamp = timestamp;
+
+ var udl = self.getUserDefinedLocation();
+ if (udl != null) {
+ return udl;
+ }
+
+ // if anchor is locked or an opposite element was not given, we
+ // maintain our state. anchor will be locked
+ // if it is the source of a drag and drop.
+ if (this.locked || txy == null || twh == null)
+ return _curAnchor.compute(params);
+ else
+ params.timestamp = null; // otherwise clear this, i think. we want the anchor to compute.
+
+ _curAnchor = _anchorSelector(xy, wh, txy, twh, this.anchors);
+ this.x = _curAnchor.x;
+ this.y = _curAnchor.y;
+
+ if (_curAnchor != _lastAnchor)
+ this.fire("anchorChanged", _curAnchor);
+
+ _lastAnchor = _curAnchor;
+
+ return _curAnchor.compute(params);
+ };
+
+ this.getCurrentLocation = function(params) {
+ return this.getUserDefinedLocation() || (_curAnchor != null ? _curAnchor.getCurrentLocation(params) : null);
+ };
+
+ this.getOrientation = function(_endpoint) { return _curAnchor != null ? _curAnchor.getOrientation(_endpoint) : [ 0, 0 ]; };
+ this.over = function(anchor, endpoint) { if (_curAnchor != null) _curAnchor.over(anchor, endpoint); };
+ this.out = function() { if (_curAnchor != null) _curAnchor.out(); };
+
+ this.getCssClass = function() { return (_curAnchor && _curAnchor.getCssClass()) || ""; };
+ };
+ jsPlumbUtil.extend(jsPlumb.DynamicAnchor, jsPlumb.Anchor);
+
+// -------- basic anchors ------------------
+ var _curryAnchor = function(x, y, ox, oy, type, fnInit) {
+ jsPlumb.Anchors[type] = function(params) {
+ var a = params.jsPlumbInstance.makeAnchor([ x, y, ox, oy, 0, 0 ], params.elementId, params.jsPlumbInstance);
+ a.type = type;
+ if (fnInit) fnInit(a, params);
+ return a;
+ };
+ };
+
+ _curryAnchor(0.5, 0, 0,-1, "TopCenter");
+ _curryAnchor(0.5, 1, 0, 1, "BottomCenter");
+ _curryAnchor(0, 0.5, -1, 0, "LeftMiddle");
+ _curryAnchor(1, 0.5, 1, 0, "RightMiddle");
+ // from 1.4.2: Top, Right, Bottom, Left
+ _curryAnchor(0.5, 0, 0,-1, "Top");
+ _curryAnchor(0.5, 1, 0, 1, "Bottom");
+ _curryAnchor(0, 0.5, -1, 0, "Left");
+ _curryAnchor(1, 0.5, 1, 0, "Right");
+ _curryAnchor(0.5, 0.5, 0, 0, "Center");
+ _curryAnchor(1, 0, 0,-1, "TopRight");
+ _curryAnchor(1, 1, 0, 1, "BottomRight");
+ _curryAnchor(0, 0, 0, -1, "TopLeft");
+ _curryAnchor(0, 1, 0, 1, "BottomLeft");
+
+// ------- dynamic anchors -------------------
+
+ // default dynamic anchors chooses from Top, Right, Bottom, Left
+ jsPlumb.Defaults.DynamicAnchors = function(params) {
+ return params.jsPlumbInstance.makeAnchors(["TopCenter", "RightMiddle", "BottomCenter", "LeftMiddle"], params.elementId, params.jsPlumbInstance);
+ };
+
+ // default dynamic anchors bound to name 'AutoDefault'
+ jsPlumb.Anchors.AutoDefault = function(params) {
+ var a = params.jsPlumbInstance.makeDynamicAnchor(jsPlumb.Defaults.DynamicAnchors(params));
+ a.type = "AutoDefault";
+ return a;
+ };
+
+// ------- continuous anchors -------------------
+
+ var _curryContinuousAnchor = function(type, faces) {
+ jsPlumb.Anchors[type] = function(params) {
+ var a = params.jsPlumbInstance.makeAnchor(["Continuous", { faces:faces }], params.elementId, params.jsPlumbInstance);
+ a.type = type;
+ return a;
+ };
+ };
+
+ jsPlumb.Anchors.Continuous = function(params) {
+ return params.jsPlumbInstance.continuousAnchorFactory.get(params);
+ };
+
+ _curryContinuousAnchor("ContinuousLeft", ["left"]);
+ _curryContinuousAnchor("ContinuousTop", ["top"]);
+ _curryContinuousAnchor("ContinuousBottom", ["bottom"]);
+ _curryContinuousAnchor("ContinuousRight", ["right"]);
+
+// ------- position assign anchors -------------------
+
+ // this anchor type lets you assign the position at connection time.
+ jsPlumb.Anchors.Assign = _curryAnchor(0, 0, 0, 0, "Assign", function(anchor, params) {
+ // find what to use as the "position finder". the user may have supplied a String which represents
+ // the id of a position finder in jsPlumb.AnchorPositionFinders, or the user may have supplied the
+ // position finder as a function. we find out what to use and then set it on the anchor.
+ var pf = params.position || "Fixed";
+ anchor.positionFinder = pf.constructor == String ? params.jsPlumbInstance.AnchorPositionFinders[pf] : pf;
+ // always set the constructor params; the position finder might need them later (the Grid one does,
+ // for example)
+ anchor.constructorParams = params;
+ });
+
+ // these are the default anchor positions finders, which are used by the makeTarget function. supplying
+ // a position finder argument to that function allows you to specify where the resulting anchor will
+ // be located
+ jsPlumb.AnchorPositionFinders = {
+ "Fixed": function(dp, ep, es, params) {
+ return [ (dp.left - ep.left) / es[0], (dp.top - ep.top) / es[1] ];
+ },
+ "Grid":function(dp, ep, es, params) {
+ var dx = dp.left - ep.left, dy = dp.top - ep.top,
+ gx = es[0] / (params.grid[0]), gy = es[1] / (params.grid[1]),
+ mx = Math.floor(dx / gx), my = Math.floor(dy / gy);
+ return [ ((mx * gx) + (gx / 2)) / es[0], ((my * gy) + (gy / 2)) / es[1] ];
+ }
+ };
+
+// ------- perimeter anchors -------------------
+
+ jsPlumb.Anchors.Perimeter = function(params) {
+ params = params || {};
+ var anchorCount = params.anchorCount || 60,
+ shape = params.shape;
+
+ if (!shape) throw new Error("no shape supplied to Perimeter Anchor type");
+
+ var _circle = function() {
+ var r = 0.5, step = Math.PI * 2 / anchorCount, current = 0, a = [];
+ for (var i = 0; i < anchorCount; i++) {
+ var x = r + (r * Math.sin(current)),
+ y = r + (r * Math.cos(current));
+ a.push( [ x, y, 0, 0 ] );
+ current += step;
+ }
+ return a;
+ },
+ _path = function(segments) {
+ var anchorsPerFace = anchorCount / segments.length, a = [],
+ _computeFace = function(x1, y1, x2, y2, fractionalLength) {
+ anchorsPerFace = anchorCount * fractionalLength;
+ var dx = (x2 - x1) / anchorsPerFace, dy = (y2 - y1) / anchorsPerFace;
+ for (var i = 0; i < anchorsPerFace; i++) {
+ a.push( [
+ x1 + (dx * i),
+ y1 + (dy * i),
+ 0,
+ 0
+ ]);
+ }
+ };
+
+ for (var i = 0; i < segments.length; i++)
+ _computeFace.apply(null, segments[i]);
+
+ return a;
+ },
+ _shape = function(faces) {
+ var s = [];
+ for (var i = 0; i < faces.length; i++) {
+ s.push([faces[i][0], faces[i][1], faces[i][2], faces[i][3], 1 / faces.length]);
+ }
+ return _path(s);
+ },
+ _rectangle = function() {
+ return _shape([
+ [ 0, 0, 1, 0 ], [ 1, 0, 1, 1 ], [ 1, 1, 0, 1 ], [ 0, 1, 0, 0 ]
+ ]);
+ };
+
+ var _shapes = {
+ "Circle":_circle,
+ "Ellipse":_circle,
+ "Diamond":function() {
+ return _shape([
+ [ 0.5, 0, 1, 0.5 ], [ 1, 0.5, 0.5, 1 ], [ 0.5, 1, 0, 0.5 ], [ 0, 0.5, 0.5, 0 ]
+ ]);
+ },
+ "Rectangle":_rectangle,
+ "Square":_rectangle,
+ "Triangle":function() {
+ return _shape([
+ [ 0.5, 0, 1, 1 ], [ 1, 1, 0, 1 ], [ 0, 1, 0.5, 0]
+ ]);
+ },
+ "Path":function(params) {
+ var points = params.points, p = [], tl = 0;
+ for (var i = 0; i < points.length - 1; i++) {
+ var l = Math.sqrt(Math.pow(points[i][2] - points[i][0]) + Math.pow(points[i][3] - points[i][1]));
+ tl += l;
+ p.push([points[i][0], points[i][1], points[i+1][0], points[i+1][1], l]);
+ }
+ for (var j = 0; j < p.length; j++) {
+ p[j][4] = p[j][4] / tl;
+ }
+ return _path(p);
+ }
+ },
+ _rotate = function(points, amountInDegrees) {
+ var o = [], theta = amountInDegrees / 180 * Math.PI ;
+ for (var i = 0; i < points.length; i++) {
+ var _x = points[i][0] - 0.5,
+ _y = points[i][1] - 0.5;
+
+ o.push([
+ 0.5 + ((_x * Math.cos(theta)) - (_y * Math.sin(theta))),
+ 0.5 + ((_x * Math.sin(theta)) + (_y * Math.cos(theta))),
+ points[i][2],
+ points[i][3]
+ ]);
+ }
+ return o;
+ };
+
+ if (!_shapes[shape]) throw new Error("Shape [" + shape + "] is unknown by Perimeter Anchor type");
+
+ var da = _shapes[shape](params);
+ if (params.rotation) da = _rotate(da, params.rotation);
+ var a = params.jsPlumbInstance.makeDynamicAnchor(da);
+ a.type = "Perimeter";
+ return a;
+ };
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the default Connectors, Endpoint and Overlay definitions.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ /**
+ *
+ * Helper class to consume unused mouse events by components that are DOM elements and
+ * are used by all of the different rendering modes.
+ *
+ */
+ jsPlumb.DOMElementComponent = jsPlumbUtil.extend(jsPlumb.jsPlumbUIComponent, function(params) {
+ // when render mode is canvas, these functions may be called by the canvas mouse handler.
+ // this component is safe to pipe this stuff to /dev/null.
+ this.mousemove =
+ this.dblclick =
+ this.click =
+ this.mousedown =
+ this.mouseup = function(e) { };
+ });
+
+ jsPlumb.Segments = {
+
+ /*
+ * Class: AbstractSegment
+ * A Connector is made up of 1..N Segments, each of which has a Type, such as 'Straight', 'Arc',
+ * 'Bezier'. This is new from 1.4.2, and gives us a lot more flexibility when drawing connections: things such
+ * as rounded corners for flowchart connectors, for example, or a straight line stub for Bezier connections, are
+ * much easier to do now.
+ *
+ * A Segment is responsible for providing coordinates for painting it, and also must be able to report its length.
+ *
+ */
+ AbstractSegment : function(params) {
+ this.params = params;
+
+ /**
+ * Function: findClosestPointOnPath
+ * Finds the closest point on this segment to the given [x, y],
+ * returning both the x and y of the point plus its distance from
+ * the supplied point, and its location along the length of the
+ * path inscribed by the segment. This implementation returns
+ * Infinity for distance and null values for everything else;
+ * subclasses are expected to override.
+ */
+ this.findClosestPointOnPath = function(x, y) {
+ return {
+ d:Infinity,
+ x:null,
+ y:null,
+ l:null
+ };
+ };
+
+ this.getBounds = function() {
+ return {
+ minX:Math.min(params.x1, params.x2),
+ minY:Math.min(params.y1, params.y2),
+ maxX:Math.max(params.x1, params.x2),
+ maxY:Math.max(params.y1, params.y2)
+ };
+ };
+ },
+ Straight : function(params) {
+ var _super = jsPlumb.Segments.AbstractSegment.apply(this, arguments),
+ length, m, m2, x1, x2, y1, y2,
+ _recalc = function() {
+ length = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
+ m = jsPlumbUtil.gradient({x:x1, y:y1}, {x:x2, y:y2});
+ m2 = -1 / m;
+ };
+
+ this.type = "Straight";
+
+ this.getLength = function() { return length; };
+ this.getGradient = function() { return m; };
+
+ this.getCoordinates = function() {
+ return { x1:x1,y1:y1,x2:x2,y2:y2 };
+ };
+ this.setCoordinates = function(coords) {
+ x1 = coords.x1; y1 = coords.y1; x2 = coords.x2; y2 = coords.y2;
+ _recalc();
+ };
+ this.setCoordinates({x1:params.x1, y1:params.y1, x2:params.x2, y2:params.y2});
+
+ this.getBounds = function() {
+ return {
+ minX:Math.min(x1, x2),
+ minY:Math.min(y1, y2),
+ maxX:Math.max(x1, x2),
+ maxY:Math.max(y1, y2)
+ };
+ };
+
+ /**
+ * returns the point on the segment's path that is 'location' along the length of the path, where 'location' is a decimal from
+ * 0 to 1 inclusive. for the straight line segment this is simple maths.
+ */
+ this.pointOnPath = function(location, absolute) {
+ if (location === 0 && !absolute)
+ return { x:x1, y:y1 };
+ else if (location == 1 && !absolute)
+ return { x:x2, y:y2 };
+ else {
+ var l = absolute ? location > 0 ? location : length + location : location * length;
+ return jsPlumbUtil.pointOnLine({x:x1, y:y1}, {x:x2, y:y2}, l);
+ }
+ };
+
+ /**
+ * returns the gradient of the segment at the given point - which for us is constant.
+ */
+ this.gradientAtPoint = function(_) {
+ return m;
+ };
+
+ /**
+ * returns the point on the segment's path that is 'distance' along the length of the path from 'location', where
+ * 'location' is a decimal from 0 to 1 inclusive, and 'distance' is a number of pixels.
+ * this hands off to jsPlumbUtil to do the maths, supplying two points and the distance.
+ */
+ this.pointAlongPathFrom = function(location, distance, absolute) {
+ var p = this.pointOnPath(location, absolute),
+ farAwayPoint = distance <= 0 ? {x:x1, y:y1} : {x:x2, y:y2 };
+
+ /*
+ location == 1 ? {
+ x:x1 + ((x2 - x1) * 10),
+ y:y1 + ((y1 - y2) * 10)
+ } :
+ */
+
+ if (distance <= 0 && Math.abs(distance) > 1) distance *= -1;
+
+ return jsPlumbUtil.pointOnLine(p, farAwayPoint, distance);
+ };
+
+ /**
+ Function: findClosestPointOnPath
+ Finds the closest point on this segment to [x,y]. See
+ notes on this method in AbstractSegment.
+ */
+ this.findClosestPointOnPath = function(x, y) {
+ if (m === 0) {
+ return {
+ x:x,
+ y:y1,
+ d:Math.abs(y - y1)
+ };
+ }
+ else if (m == Infinity || m == -Infinity) {
+ return {
+ x:x1,
+ y:y,
+ d:Math.abs(x - 1)
+ };
+ }
+ else {
+ // closest point lies on normal from given point to this line.
+ var b = y1 - (m * x1),
+ b2 = y - (m2 * x),
+ // y1 = m.x1 + b and y1 = m2.x1 + b2
+ // so m.x1 + b = m2.x1 + b2
+ // x1(m - m2) = b2 - b
+ // x1 = (b2 - b) / (m - m2)
+ _x1 = (b2 -b) / (m - m2),
+ _y1 = (m * _x1) + b,
+ d = jsPlumbUtil.lineLength([ x, y ], [ _x1, _y1 ]),
+ fractionInSegment = jsPlumbUtil.lineLength([ _x1, _y1 ], [ x1, y1 ]);
+
+ return { d:d, x:_x1, y:_y1, l:fractionInSegment / length};
+ }
+ };
+ },
+
+ /*
+ Arc Segment. You need to supply:
+
+ r - radius
+ cx - center x for the arc
+ cy - center y for the arc
+ ac - whether the arc is anticlockwise or not. default is clockwise.
+
+ and then either:
+
+ startAngle - startAngle for the arc.
+ endAngle - endAngle for the arc.
+
+ or:
+
+ x1 - x for start point
+ y1 - y for start point
+ x2 - x for end point
+ y2 - y for end point
+
+ */
+ Arc : function(params) {
+ var _super = jsPlumb.Segments.AbstractSegment.apply(this, arguments),
+ _calcAngle = function(_x, _y) {
+ return jsPlumbUtil.theta([params.cx, params.cy], [_x, _y]);
+ },
+ _calcAngleForLocation = function(segment, location) {
+ if (segment.anticlockwise) {
+ var sa = segment.startAngle < segment.endAngle ? segment.startAngle + TWO_PI : segment.startAngle,
+ s = Math.abs(sa - segment.endAngle);
+ return sa - (s * location);
+ }
+ else {
+ var ea = segment.endAngle < segment.startAngle ? segment.endAngle + TWO_PI : segment.endAngle,
+ ss = Math.abs (ea - segment.startAngle);
+
+ return segment.startAngle + (ss * location);
+ }
+ },
+ TWO_PI = 2 * Math.PI;
+
+ this.radius = params.r;
+ this.anticlockwise = params.ac;
+ this.type = "Arc";
+
+ if (params.startAngle && params.endAngle) {
+ this.startAngle = params.startAngle;
+ this.endAngle = params.endAngle;
+ this.x1 = params.cx + (this.radius * Math.cos(params.startAngle));
+ this.y1 = params.cy + (this.radius * Math.sin(params.startAngle));
+ this.x2 = params.cx + (this.radius * Math.cos(params.endAngle));
+ this.y2 = params.cy + (this.radius * Math.sin(params.endAngle));
+ }
+ else {
+ this.startAngle = _calcAngle(params.x1, params.y1);
+ this.endAngle = _calcAngle(params.x2, params.y2);
+ this.x1 = params.x1;
+ this.y1 = params.y1;
+ this.x2 = params.x2;
+ this.y2 = params.y2;
+ }
+
+ if (this.endAngle < 0) this.endAngle += TWO_PI;
+ if (this.startAngle < 0) this.startAngle += TWO_PI;
+
+ // segment is used by vml
+ this.segment = jsPlumbUtil.segment([this.x1, this.y1], [this.x2, this.y2]);
+
+ // we now have startAngle and endAngle as positive numbers, meaning the
+ // absolute difference (|d|) between them is the sweep (s) of this arc, unless the
+ // arc is 'anticlockwise' in which case 's' is given by 2PI - |d|.
+
+ var ea = this.endAngle < this.startAngle ? this.endAngle + TWO_PI : this.endAngle;
+ this.sweep = Math.abs (ea - this.startAngle);
+ if (this.anticlockwise) this.sweep = TWO_PI - this.sweep;
+ var circumference = 2 * Math.PI * this.radius,
+ frac = this.sweep / TWO_PI,
+ length = circumference * frac;
+
+ this.getLength = function() {
+ return length;
+ };
+
+ this.getBounds = function() {
+ return {
+ minX:params.cx - params.r,
+ maxX:params.cx + params.r,
+ minY:params.cy - params.r,
+ maxY:params.cy + params.r
+ };
+ };
+
+ var VERY_SMALL_VALUE = 0.0000000001,
+ gentleRound = function(n) {
+ var f = Math.floor(n), r = Math.ceil(n);
+ if (n - f < VERY_SMALL_VALUE)
+ return f;
+ else if (r - n < VERY_SMALL_VALUE)
+ return r;
+ return n;
+ };
+
+ /**
+ * returns the point on the segment's path that is 'location' along the length of the path, where 'location' is a decimal from
+ * 0 to 1 inclusive.
+ */
+ this.pointOnPath = function(location, absolute) {
+
+ if (location === 0) {
+ return { x:this.x1, y:this.y1, theta:this.startAngle };
+ }
+ else if (location == 1) {
+ return { x:this.x2, y:this.y2, theta:this.endAngle };
+ }
+
+ if (absolute) {
+ location = location / length;
+ }
+
+ var angle = _calcAngleForLocation(this, location),
+ _x = params.cx + (params.r * Math.cos(angle)),
+ _y = params.cy + (params.r * Math.sin(angle));
+
+ return { x:gentleRound(_x), y:gentleRound(_y), theta:angle };
+ };
+
+ /**
+ * returns the gradient of the segment at the given point.
+ */
+ this.gradientAtPoint = function(location, absolute) {
+ var p = this.pointOnPath(location, absolute);
+ var m = jsPlumbUtil.normal( [ params.cx, params.cy ], [p.x, p.y ] );
+ if (!this.anticlockwise && (m == Infinity || m == -Infinity)) m *= -1;
+ return m;
+ };
+
+ this.pointAlongPathFrom = function(location, distance, absolute) {
+ var p = this.pointOnPath(location, absolute),
+ arcSpan = distance / circumference * 2 * Math.PI,
+ dir = this.anticlockwise ? -1 : 1,
+ startAngle = p.theta + (dir * arcSpan),
+ startX = params.cx + (this.radius * Math.cos(startAngle)),
+ startY = params.cy + (this.radius * Math.sin(startAngle));
+
+ return {x:startX, y:startY};
+ };
+ },
+
+ Bezier : function(params) {
+ var _super = jsPlumb.Segments.AbstractSegment.apply(this, arguments),
+ curve = [
+ { x:params.x1, y:params.y1},
+ { x:params.cp1x, y:params.cp1y },
+ { x:params.cp2x, y:params.cp2y },
+ { x:params.x2, y:params.y2 }
+ ],
+ // although this is not a strictly rigorous determination of bounds
+ // of a bezier curve, it works for the types of curves that this segment
+ // type produces.
+ bounds = {
+ minX:Math.min(params.x1, params.x2, params.cp1x, params.cp2x),
+ minY:Math.min(params.y1, params.y2, params.cp1y, params.cp2y),
+ maxX:Math.max(params.x1, params.x2, params.cp1x, params.cp2x),
+ maxY:Math.max(params.y1, params.y2, params.cp1y, params.cp2y)
+ };
+
+ this.type = "Bezier";
+
+ var _translateLocation = function(_curve, location, absolute) {
+ if (absolute)
+ location = jsBezier.locationAlongCurveFrom(_curve, location > 0 ? 0 : 1, location);
+
+ return location;
+ };
+
+ /**
+ * returns the point on the segment's path that is 'location' along the length of the path, where 'location' is a decimal from
+ * 0 to 1 inclusive.
+ */
+ this.pointOnPath = function(location, absolute) {
+ location = _translateLocation(curve, location, absolute);
+ return jsBezier.pointOnCurve(curve, location);
+ };
+
+ /**
+ * returns the gradient of the segment at the given point.
+ */
+ this.gradientAtPoint = function(location, absolute) {
+ location = _translateLocation(curve, location, absolute);
+ return jsBezier.gradientAtPoint(curve, location);
+ };
+
+ this.pointAlongPathFrom = function(location, distance, absolute) {
+ location = _translateLocation(curve, location, absolute);
+ return jsBezier.pointAlongCurveFrom(curve, location, distance);
+ };
+
+ this.getLength = function() {
+ return jsBezier.getLength(curve);
+ };
+
+ this.getBounds = function() {
+ return bounds;
+ };
+ }
+ };
+
+ /*
+ Class: AbstractComponent
+ Superclass for AbstractConnector and AbstractEndpoint.
+ */
+ var AbstractComponent = function() {
+ this.resetBounds = function() {
+ this.bounds = { minX:Infinity, minY:Infinity, maxX:-Infinity, maxY:-Infinity };
+ };
+ this.resetBounds();
+ };
+
+ /*
+ * Class: AbstractConnector
+ * Superclass for all Connectors; here is where Segments are managed. This is exposed on jsPlumb just so it
+ * can be accessed from other files. You should not try to instantiate one of these directly.
+ *
+ * When this class is asked for a pointOnPath, or gradient etc, it must first figure out which segment to dispatch
+ * that request to. This is done by keeping track of the total connector length as segments are added, and also
+ * their cumulative ratios to the total length. Then when the right segment is found it is a simple case of dispatching
+ * the request to it (and adjusting 'location' so that it is relative to the beginning of that segment.)
+ */
+ jsPlumb.Connectors.AbstractConnector = function(params) {
+
+ AbstractComponent.apply(this, arguments);
+
+ var //self = this,
+ segments = [],
+ editing = false,
+ totalLength = 0,
+ segmentProportions = [],
+ segmentProportionalLengths = [],
+ stub = params.stub || 0,
+ sourceStub = jsPlumbUtil.isArray(stub) ? stub[0] : stub,
+ targetStub = jsPlumbUtil.isArray(stub) ? stub[1] : stub,
+ gap = params.gap || 0,
+ sourceGap = jsPlumbUtil.isArray(gap) ? gap[0] : gap,
+ targetGap = jsPlumbUtil.isArray(gap) ? gap[1] : gap,
+ userProvidedSegments = null,
+ edited = false,
+ paintInfo = null;
+
+ // subclasses should override.
+ this.isEditable = function() { return false; };
+ this.setEdited = function(ed) { edited = ed; };
+
+ // to be overridden by subclasses.
+ this.getPath = function() { };
+ this.setPath = function(path) { };
+
+ /**
+ * Function: findSegmentForPoint
+ * Returns the segment that is closest to the given [x,y],
+ * null if nothing found. This function returns a JS
+ * object with:
+ *
+ * d - distance from segment
+ * l - proportional location in segment
+ * x - x point on the segment
+ * y - y point on the segment
+ * s - the segment itself.
+ */
+ this.findSegmentForPoint = function(x, y) {
+ var out = { d:Infinity, s:null, x:null, y:null, l:null };
+ for (var i = 0; i < segments.length; i++) {
+ var _s = segments[i].findClosestPointOnPath(x, y);
+ if (_s.d < out.d) {
+ out.d = _s.d;
+ out.l = _s.l;
+ out.x = _s.x;
+ out.y = _s.y;
+ out.s = segments[i];
+ }
+ }
+
+ return out;
+ };
+
+ var _updateSegmentProportions = function() {
+ var curLoc = 0;
+ for (var i = 0; i < segments.length; i++) {
+ var sl = segments[i].getLength();
+ segmentProportionalLengths[i] = sl / totalLength;
+ segmentProportions[i] = [curLoc, (curLoc += (sl / totalLength)) ];
+ }
+ },
+
+ /**
+ * returns [segment, proportion of travel in segment, segment index] for the segment
+ * that contains the point which is 'location' distance along the entire path, where
+ * 'location' is a decimal between 0 and 1 inclusive. in this connector type, paths
+ * are made up of a list of segments, each of which contributes some fraction to
+ * the total length.
+ * From 1.3.10 this also supports the 'absolute' property, which lets us specify a location
+ * as the absolute distance in pixels, rather than a proportion of the total path.
+ */
+ _findSegmentForLocation = function(location, absolute) {
+ if (absolute) {
+ location = location > 0 ? location / totalLength : (totalLength + location) / totalLength;
+ }
+
+ var idx = segmentProportions.length - 1, inSegmentProportion = 1;
+ //if (location < 1) {
+ for (var i = 0; i < segmentProportions.length; i++) {
+ if (segmentProportions[i][1] >= location) {
+ idx = i;
+ // todo is this correct for all connector path types?
+ inSegmentProportion = location == 1 ? 1 : location === 0 ? 0 : (location - segmentProportions[i][0]) / segmentProportionalLengths[i];
+ break;
+ }
+ }
+ //}
+ return { segment:segments[idx], proportion:inSegmentProportion, index:idx };
+ },
+ _addSegment = function(conn, type, params) {
+ if (params.x1 == params.x2 && params.y1 == params.y2) return;
+ var s = new jsPlumb.Segments[type](params);
+ segments.push(s);
+ totalLength += s.getLength();
+ conn.updateBounds(s);
+ },
+ _clearSegments = function() {
+ totalLength = 0;
+ segments.splice(0, segments.length);
+ segmentProportions.splice(0, segmentProportions.length);
+ segmentProportionalLengths.splice(0, segmentProportionalLengths.length);
+ };
+
+ this.setSegments = function(_segs) {
+ userProvidedSegments = [];
+ totalLength = 0;
+ for (var i = 0; i < _segs.length; i++) {
+ userProvidedSegments.push(_segs[i]);
+ totalLength += _segs[i].getLength();
+ }
+ };
+
+ var _prepareCompute = function(params) {
+ this.lineWidth = params.lineWidth;
+ var segment = jsPlumbUtil.segment(params.sourcePos, params.targetPos),
+ swapX = params.targetPos[0] < params.sourcePos[0],
+ swapY = params.targetPos[1] < params.sourcePos[1],
+ lw = params.lineWidth || 1,
+ so = params.sourceEndpoint.anchor.orientation || params.sourceEndpoint.anchor.getOrientation(params.sourceEndpoint),
+ to = params.targetEndpoint.anchor.orientation || params.targetEndpoint.anchor.getOrientation(params.targetEndpoint),
+ x = swapX ? params.targetPos[0] : params.sourcePos[0],
+ y = swapY ? params.targetPos[1] : params.sourcePos[1],
+ w = Math.abs(params.targetPos[0] - params.sourcePos[0]),
+ h = Math.abs(params.targetPos[1] - params.sourcePos[1]);
+
+ // if either anchor does not have an orientation set, we derive one from their relative
+ // positions. we fix the axis to be the one in which the two elements are further apart, and
+ // point each anchor at the other element. this is also used when dragging a new connection.
+ if (so[0] === 0 && so[1] === 0 || to[0] === 0 && to[1] === 0) {
+ var index = w > h ? 0 : 1, oIndex = [1,0][index];
+ so = []; to = [];
+ so[index] = params.sourcePos[index] > params.targetPos[index] ? -1 : 1;
+ to[index] = params.sourcePos[index] > params.targetPos[index] ? 1 : -1;
+ so[oIndex] = 0; to[oIndex] = 0;
+ }
+
+ var sx = swapX ? w + (sourceGap * so[0]) : sourceGap * so[0],
+ sy = swapY ? h + (sourceGap * so[1]) : sourceGap * so[1],
+ tx = swapX ? targetGap * to[0] : w + (targetGap * to[0]),
+ ty = swapY ? targetGap * to[1] : h + (targetGap * to[1]),
+ oProduct = ((so[0] * to[0]) + (so[1] * to[1]));
+
+ var result = {
+ sx:sx, sy:sy, tx:tx, ty:ty, lw:lw,
+ xSpan:Math.abs(tx - sx),
+ ySpan:Math.abs(ty - sy),
+ mx:(sx + tx) / 2,
+ my:(sy + ty) / 2,
+ so:so, to:to, x:x, y:y, w:w, h:h,
+ segment : segment,
+ startStubX : sx + (so[0] * sourceStub),
+ startStubY : sy + (so[1] * sourceStub),
+ endStubX : tx + (to[0] * targetStub),
+ endStubY : ty + (to[1] * targetStub),
+ isXGreaterThanStubTimes2 : Math.abs(sx - tx) > (sourceStub + targetStub),
+ isYGreaterThanStubTimes2 : Math.abs(sy - ty) > (sourceStub + targetStub),
+ opposite:oProduct == -1,
+ perpendicular:oProduct === 0,
+ orthogonal:oProduct == 1,
+ sourceAxis : so[0] === 0 ? "y" : "x",
+ points:[x, y, w, h, sx, sy, tx, ty ]
+ };
+ result.anchorOrientation = result.opposite ? "opposite" : result.orthogonal ? "orthogonal" : "perpendicular";
+ return result;
+ };
+
+ this.getSegments = function() { return segments; };
+
+ this.updateBounds = function(segment) {
+ var segBounds = segment.getBounds();
+ this.bounds.minX = Math.min(this.bounds.minX, segBounds.minX);
+ this.bounds.maxX = Math.max(this.bounds.maxX, segBounds.maxX);
+ this.bounds.minY = Math.min(this.bounds.minY, segBounds.minY);
+ this.bounds.maxY = Math.max(this.bounds.maxY, segBounds.maxY);
+ };
+
+ var dumpSegmentsToConsole = function() {
+ console.log("SEGMENTS:");
+ for (var i = 0; i < segments.length; i++) {
+ console.log(segments[i].type, segments[i].getLength(), segmentProportions[i]);
+ }
+ };
+
+ this.pointOnPath = function(location, absolute) {
+ var seg = _findSegmentForLocation(location, absolute);
+ return seg.segment && seg.segment.pointOnPath(seg.proportion, absolute) || [0,0];
+ };
+
+ this.gradientAtPoint = function(location) {
+ var seg = _findSegmentForLocation(location, absolute);
+ return seg.segment && seg.segment.gradientAtPoint(seg.proportion, absolute) || 0;
+ };
+
+ this.pointAlongPathFrom = function(location, distance, absolute) {
+ var seg = _findSegmentForLocation(location, absolute);
+ // TODO what happens if this crosses to the next segment?
+ return seg.segment && seg.segment.pointAlongPathFrom(seg.proportion, distance, false) || [0,0];
+ };
+
+ this.compute = function(params) {
+ if (!edited)
+ paintInfo = _prepareCompute(params);
+
+ _clearSegments();
+ this._compute(paintInfo, params);
+ this.x = paintInfo.points[0];
+ this.y = paintInfo.points[1];
+ this.w = paintInfo.points[2];
+ this.h = paintInfo.points[3];
+ this.segment = paintInfo.segment;
+ _updateSegmentProportions();
+ };
+
+ return {
+ addSegment:_addSegment,
+ prepareCompute:_prepareCompute,
+ sourceStub:sourceStub,
+ targetStub:targetStub,
+ maxStub:Math.max(sourceStub, targetStub),
+ sourceGap:sourceGap,
+ targetGap:targetGap,
+ maxGap:Math.max(sourceGap, targetGap)
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.AbstractConnector, AbstractComponent);
+
+ /**
+ * Class: Connectors.Straight
+ * The Straight connector draws a simple straight line between the two anchor points. It does not have any constructor parameters.
+ */
+ var Straight = function() {
+ this.type = "Straight";
+ var _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments);
+
+ this._compute = function(paintInfo, _) {
+ _super.addSegment(this, "Straight", {x1:paintInfo.sx, y1:paintInfo.sy, x2:paintInfo.startStubX, y2:paintInfo.startStubY});
+ _super.addSegment(this, "Straight", {x1:paintInfo.startStubX, y1:paintInfo.startStubY, x2:paintInfo.endStubX, y2:paintInfo.endStubY});
+ _super.addSegment(this, "Straight", {x1:paintInfo.endStubX, y1:paintInfo.endStubY, x2:paintInfo.tx, y2:paintInfo.ty});
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.Straight, jsPlumb.Connectors.AbstractConnector);
+ jsPlumb.registerConnectorType(Straight, "Straight");
+
+ /**
+ * Class:Connectors.Bezier
+ * This Connector draws a Bezier curve with two control points. You can provide a 'curviness' value which gets applied to jsPlumb's
+ * internal voodoo machine and ends up generating locations for the two control points. See the constructor documentation below.
+ */
+ /**
+ * Function:Constructor
+ *
+ * Parameters:
+ * curviness - How 'curvy' you want the curve to be! This is a directive for the placement of control points, not endpoints of the curve, so your curve does not
+ * actually touch the given point, but it has the tendency to lean towards it. The larger this value, the greater the curve is pulled from a straight line.
+ * Optional; defaults to 150.
+ * stub - optional value for a distance to travel from the connector's endpoint before beginning the Bezier curve. defaults to 0.
+ *
+ */
+ var Bezier = function(params) {
+ params = params || {};
+
+ var _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
+ stub = params.stub || 50,
+ majorAnchor = params.curviness || 150,
+ minorAnchor = 10;
+
+ this.type = "Bezier";
+ this.getCurviness = function() { return majorAnchor; };
+
+ this._findControlPoint = function(point, sourceAnchorPosition, targetAnchorPosition, sourceEndpoint, targetEndpoint) {
+ // determine if the two anchors are perpendicular to each other in their orientation. we swap the control
+ // points around if so (code could be tightened up)
+ var soo = sourceEndpoint.anchor.getOrientation(sourceEndpoint),
+ too = targetEndpoint.anchor.getOrientation(targetEndpoint),
+ perpendicular = soo[0] != too[0] || soo[1] == too[1],
+ p = [];
+
+ if (!perpendicular) {
+ if (soo[0] === 0) // X
+ p.push(sourceAnchorPosition[0] < targetAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
+ else p.push(point[0] - (majorAnchor * soo[0]));
+
+ if (soo[1] === 0) // Y
+ p.push(sourceAnchorPosition[1] < targetAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
+ else p.push(point[1] + (majorAnchor * too[1]));
+ }
+ else {
+ if (too[0] === 0) // X
+ p.push(targetAnchorPosition[0] < sourceAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
+ else p.push(point[0] + (majorAnchor * too[0]));
+
+ if (too[1] === 0) // Y
+ p.push(targetAnchorPosition[1] < sourceAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
+ else p.push(point[1] + (majorAnchor * soo[1]));
+ }
+
+ return p;
+ };
+
+ this._compute = function(paintInfo, p) {
+ var sp = p.sourcePos,
+ tp = p.targetPos,
+ _w = Math.abs(sp[0] - tp[0]),
+ _h = Math.abs(sp[1] - tp[1]),
+ _sx = sp[0] < tp[0] ? _w : 0,
+ _sy = sp[1] < tp[1] ? _h : 0,
+ _tx = sp[0] < tp[0] ? 0 : _w,
+ _ty = sp[1] < tp[1] ? 0 : _h,
+ _CP = this._findControlPoint([_sx, _sy], sp, tp, p.sourceEndpoint, p.targetEndpoint),
+ _CP2 = this._findControlPoint([_tx, _ty], tp, sp, p.targetEndpoint, p.sourceEndpoint);
+
+ _super.addSegment(this, "Bezier", {
+ x1:_sx, y1:_sy, x2:_tx, y2:_ty,
+ cp1x:_CP[0], cp1y:_CP[1], cp2x:_CP2[0], cp2y:_CP2[1]
+ });
+ };
+ };
+ jsPlumbUtil.extend(Bezier, jsPlumb.Connectors.AbstractConnector);
+ jsPlumb.registerConnectorType(Bezier, "Bezier");
+
+ // ********************************* END OF CONNECTOR TYPES *******************************************************************
+
+ // ********************************* ENDPOINT TYPES *******************************************************************
+
+ jsPlumb.Endpoints.AbstractEndpoint = function(params) {
+ AbstractComponent.apply(this, arguments);
+ var compute = this.compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ var out = this._compute.apply(this, arguments);
+ this.x = out[0];
+ this.y = out[1];
+ this.w = out[2];
+ this.h = out[3];
+ this.bounds.minX = this.x;
+ this.bounds.minY = this.y;
+ this.bounds.maxX = this.x + this.w;
+ this.bounds.maxY = this.y + this.h;
+ return out;
+ };
+ return {
+ compute:compute,
+ cssClass:params.cssClass
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.AbstractEndpoint, AbstractComponent);
+
+ /**
+ * Class: Endpoints.Dot
+ * A round endpoint, with default radius 10 pixels.
+ */
+
+ /**
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * radius - radius of the endpoint. defaults to 10 pixels.
+ */
+ jsPlumb.Endpoints.Dot = function(params) {
+ this.type = "Dot";
+ var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+ params = params || {};
+ this.radius = params.radius || 10;
+ this.defaultOffset = 0.5 * this.radius;
+ this.defaultInnerRadius = this.radius / 3;
+
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ this.radius = endpointStyle.radius || this.radius;
+ var x = anchorPoint[0] - this.radius,
+ y = anchorPoint[1] - this.radius,
+ w = this.radius * 2,
+ h = this.radius * 2;
+
+ if (endpointStyle.strokeStyle) {
+ var lw = endpointStyle.lineWidth || 1;
+ x -= lw;
+ y -= lw;
+ w += (lw * 2);
+ h += (lw * 2);
+ }
+ return [ x, y, w, h, this.radius ];
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.Dot, jsPlumb.Endpoints.AbstractEndpoint);
+
+ /**
+ * Class: Endpoints.Rectangle
+ * A Rectangular Endpoint, with default size 20x20.
+ */
+ /**
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * width - width of the endpoint. defaults to 20 pixels.
+ * height - height of the endpoint. defaults to 20 pixels.
+ */
+ jsPlumb.Endpoints.Rectangle = function(params) {
+ this.type = "Rectangle";
+ var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+ params = params || {};
+ this.width = params.width || 20;
+ this.height = params.height || 20;
+
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ var width = endpointStyle.width || this.width,
+ height = endpointStyle.height || this.height,
+ x = anchorPoint[0] - (width/2),
+ y = anchorPoint[1] - (height/2);
+
+ return [ x, y, width, height];
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.Rectangle, jsPlumb.Endpoints.AbstractEndpoint);
+
+
+ var DOMElementEndpoint = function(params) {
+ jsPlumb.DOMElementComponent.apply(this, arguments);
+ this._jsPlumb.displayElements = [ ];
+ };
+ jsPlumbUtil.extend(DOMElementEndpoint, jsPlumb.DOMElementComponent, {
+ // jsPlumb.Endpoints.AbstractEndpoint
+ getDisplayElements : function() {
+ return this._jsPlumb.displayElements;
+ },
+ appendDisplayElement : function(el) {
+ this._jsPlumb.displayElements.push(el);
+ }
+ });
+
+ /**
+ * Class: Endpoints.Image
+ * Draws an image as the Endpoint.
+ */
+ /**
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * src - location of the image to use.
+
+ TODO: multiple references to self. not sure quite how to get rid of them entirely. perhaps self = null in the cleanup
+ function will suffice
+
+ TODO this class still leaks memory.
+
+ */
+ jsPlumb.Endpoints.Image = function(params) {
+
+ this.type = "Image";
+ DOMElementEndpoint.apply(this, arguments);
+ jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+
+ var _onload = params.onload,
+ src = params.src || params.url,
+ parent = params.parent,
+ clazz = params.cssClass ? " " + params.cssClass : "";
+
+ this._jsPlumb.img = new Image();
+ this._jsPlumb.ready = false;
+ this._jsPlumb.initialized = false;
+ this._jsPlumb.deleted = false;
+ this._jsPlumb.widthToUse = params.width;
+ this._jsPlumb.heightToUse = params.height;
+ this._jsPlumb.endpoint = params.endpoint;
+
+ this._jsPlumb.img.onload = function() {
+ // check we weren't actually discarded before use (in fact mostly happens in tests)
+ if (this._jsPlumb != null) {
+ this._jsPlumb.ready = true;
+ this._jsPlumb.widthToUse = this._jsPlumb.widthToUse || this._jsPlumb.img.width;
+ this._jsPlumb.heightToUse = this._jsPlumb.heightToUse || this._jsPlumb.img.height;
+ if (_onload) {
+ _onload(this);
+ }
+ }
+ }.bind(this);
+
+ /*
+ Function: setImage
+ Sets the Image to use in this Endpoint.
+
+ Parameters:
+ img - may be a URL or an Image object
+ onload - optional; a callback to execute once the image has loaded.
+ */
+ this._jsPlumb.endpoint.setImage = function(_img, onload) {
+ var s = _img.constructor == String ? _img : _img.src;
+ _onload = onload;
+ this._jsPlumb.img.src = s;
+
+ if (this.canvas != null)
+ this.canvas.setAttribute("src", this._jsPlumb.img.src);
+ }.bind(this);
+
+ this._jsPlumb.endpoint.setImage(src, _onload);
+ /*
+ var s = src.constructor == String ? src : src.src;
+ //_onload = onload;
+ this._jsPlumb.img.src = src;
+
+ if (this.canvas != null)
+ this.canvas.setAttribute("src", this._jsPlumb.img.src);
+ // }.bind(this);
+
+ //this._jsPlumb.endpoint.setImage(src, _onload);*/
+
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ this.anchorPoint = anchorPoint;
+ if (this._jsPlumb.ready) return [anchorPoint[0] - this._jsPlumb.widthToUse / 2, anchorPoint[1] - this._jsPlumb.heightToUse / 2,
+ this._jsPlumb.widthToUse, this._jsPlumb.heightToUse];
+ else return [0,0,0,0];
+ };
+
+ this.canvas = document.createElement("img");
+ this.canvas.style.margin = 0;
+ this.canvas.style.padding = 0;
+ this.canvas.style.outline = 0;
+ this.canvas.style.position = "absolute";
+ this.canvas.className = this._jsPlumb.instance.endpointClass + clazz;
+ if (this._jsPlumb.widthToUse) this.canvas.setAttribute("width", this._jsPlumb.widthToUse);
+ if (this._jsPlumb.heightToUse) this.canvas.setAttribute("height", this._jsPlumb.heightToUse);
+ this._jsPlumb.instance.appendElement(this.canvas, parent);
+ this.attachListeners(this.canvas, this);
+
+ this.actuallyPaint = function(d, style, anchor) {
+ if (!this._jsPlumb.deleted) {
+ if (!this._jsPlumb.initialized) {
+ this.canvas.setAttribute("src", this._jsPlumb.img.src);
+ this.appendDisplayElement(this.canvas);
+ this._jsPlumb.initialized = true;
+ }
+ var x = this.anchorPoint[0] - (this._jsPlumb.widthToUse / 2),
+ y = this.anchorPoint[1] - (this._jsPlumb.heightToUse / 2);
+ jsPlumbUtil.sizeElement(this.canvas, x, y, this._jsPlumb.widthToUse, this._jsPlumb.heightToUse);
+ }
+ };
+
+ this.paint = function(style, anchor) {
+ if (this._jsPlumb != null) { // may have been deleted
+ if (this._jsPlumb.ready) {
+ this.actuallyPaint(style, anchor);
+ }
+ else {
+ window.setTimeout(function() {
+ this.paint(style, anchor);
+ }.bind(this), 200);
+ }
+ }
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.Image, [ DOMElementEndpoint, jsPlumb.Endpoints.AbstractEndpoint ], {
+ cleanup : function() {
+ this._jsPlumb.deleted = true;
+ jsPlumbUtil.removeElement(this.canvas);
+ this.canvas = null;
+ }
+ });
+
+ /*
+ * Class: Endpoints.Blank
+ * An Endpoint that paints nothing (visible) on the screen. Supports cssClass and hoverClass parameters like all Endpoints.
+ */
+ jsPlumb.Endpoints.Blank = function(params) {
+ var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+ this.type = "Blank";
+ DOMElementEndpoint.apply(this, arguments);
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ return [anchorPoint[0], anchorPoint[1],10,0];
+ };
+
+ this.canvas = document.createElement("div");
+ this.canvas.style.display = "block";
+ this.canvas.style.width = "1px";
+ this.canvas.style.height = "1px";
+ this.canvas.style.background = "transparent";
+ this.canvas.style.position = "absolute";
+ this.canvas.className = this._jsPlumb.endpointClass;
+ jsPlumb.appendElement(this.canvas, params.parent);
+
+ this.paint = function(style, anchor) {
+ jsPlumbUtil.sizeElement(this.canvas, this.x, this.y, this.w, this.h);
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.Blank, [jsPlumb.Endpoints.AbstractEndpoint, DOMElementEndpoint], {
+ cleanup:function() {
+ if (this.canvas) {
+ this.canvas.parentNode.removeChild(this.canvas);
+ }
+ }
+ });
+
+ /*
+ * Class: Endpoints.Triangle
+ * A triangular Endpoint.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * width - width of the triangle's base. defaults to 55 pixels.
+ * height - height of the triangle from base to apex. defaults to 55 pixels.
+ */
+ jsPlumb.Endpoints.Triangle = function(params) {
+ this.type = "Triangle";
+ var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+ params = params || { };
+ params.width = params.width || 55;
+ params.height = params.height || 55;
+ this.width = params.width;
+ this.height = params.height;
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ var width = endpointStyle.width || self.width,
+ height = endpointStyle.height || self.height,
+ x = anchorPoint[0] - (width/2),
+ y = anchorPoint[1] - (height/2);
+ return [ x, y, width, height ];
+ };
+ };
+// ********************************* END OF ENDPOINT TYPES *******************************************************************
+
+
+// ********************************* OVERLAY DEFINITIONS ***********************************************************************
+
+ var AbstractOverlay = jsPlumb.Overlays.AbstractOverlay = function(params) {
+ this.visible = true;
+ this.isAppendedAtTopLevel = true;
+ this.component = params.component;
+ this.loc = params.location == null ? 0.5 : params.location;
+ this.endpointLoc = params.endpointLocation == null ? [ 0.5, 0.5] : params.endpointLocation;
+ //this.;
+ };
+ AbstractOverlay.prototype = {
+ cleanup:function() {
+ this.component = null;
+ this.canvas = null;
+ this.endpointLoc = null;
+ },
+ setVisible : function(val) {
+ this.visible = val;
+ this.component.repaint();
+ },
+ isVisible : function() { return this.visible; },
+ hide : function() { this.setVisible(false); },
+ show : function() { this.setVisible(true); },
+
+ incrementLocation : function(amount) {
+ this.loc += amount;
+ this.component.repaint();
+ },
+ setLocation : function(l) {
+ this.loc = l;
+ this.component.repaint();
+ },
+ getLocation : function() {
+ return this.loc;
+ }
+ };
+
+
+ /*
+ * Class: Overlays.Arrow
+ *
+ * An arrow overlay, defined by four points: the head, the two sides of the tail, and a 'foldback' point at some distance along the length
+ * of the arrow that lines from each tail point converge into. The foldback point is defined using a decimal that indicates some fraction
+ * of the length of the arrow and has a default value of 0.623. A foldback point value of 1 would mean that the arrow had a straight line
+ * across the tail.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * length - distance in pixels from head to tail baseline. default 20.
+ * width - width in pixels of the tail baseline. default 20.
+ * fillStyle - style to use when filling the arrow. defaults to "black".
+ * strokeStyle - style to use when stroking the arrow. defaults to null, which means the arrow is not stroked.
+ * lineWidth - line width to use when stroking the arrow. defaults to 1, but only used if strokeStyle is not null.
+ * foldback - distance (as a decimal from 0 to 1 inclusive) along the length of the arrow marking the point the tail points should fold back to. defaults to 0.623.
+ * location - distance (as a decimal from 0 to 1 inclusive) marking where the arrow should sit on the connector. defaults to 0.5.
+ * direction - indicates the direction the arrow points in. valid values are -1 and 1; 1 is default.
+ */
+ jsPlumb.Overlays.Arrow = function(params) {
+ this.type = "Arrow";
+ AbstractOverlay.apply(this, arguments);
+ this.isAppendedAtTopLevel = false;
+ params = params || {};
+ var _ju = jsPlumbUtil;
+
+ this.length = params.length || 20;
+ this.width = params.width || 20;
+ this.id = params.id;
+ var direction = (params.direction || 1) < 0 ? -1 : 1,
+ paintStyle = params.paintStyle || { lineWidth:1 },
+ // how far along the arrow the lines folding back in come to. default is 62.3%.
+ foldback = params.foldback || 0.623;
+
+ this.computeMaxSize = function() { return self.width * 1.5; };
+ //this.cleanup = function() { }; // nothing to clean up for Arrows
+ this.draw = function(component, currentConnectionPaintStyle) {
+
+ var hxy, mid, txy, tail, cxy;
+ if (component.pointAlongPathFrom) {
+
+ if (_ju.isString(this.loc) || this.loc > 1 || this.loc < 0) {
+ var l = parseInt(this.loc, 10);
+ hxy = component.pointAlongPathFrom(l, direction * this.length / 2, true);
+ mid = component.pointOnPath(l, true);
+ txy = _ju.pointOnLine(hxy, mid, this.length);
+ }
+ else if (this.loc == 1) {
+ hxy = component.pointOnPath(this.loc);
+ mid = component.pointAlongPathFrom(this.loc, -(this.length));
+ txy = _ju.pointOnLine(hxy, mid, this.length);
+
+ if (direction == -1) {
+ var _ = txy;
+ txy = hxy;
+ hxy = _;
+ }
+ }
+ else if (this.loc === 0) {
+ txy = component.pointOnPath(this.loc);
+ mid = component.pointAlongPathFrom(this.loc, this.length);
+ hxy = _ju.pointOnLine(txy, mid, this.length);
+ if (direction == -1) {
+ var __ = txy;
+ txy = hxy;
+ hxy = __;
+ }
+ }
+ else {
+ hxy = component.pointAlongPathFrom(this.loc, direction * this.length / 2);
+ mid = component.pointOnPath(this.loc);
+ txy = _ju.pointOnLine(hxy, mid, this.length);
+ }
+
+ tail = _ju.perpendicularLineTo(hxy, txy, this.width);
+ cxy = _ju.pointOnLine(hxy, txy, foldback * this.length);
+
+ var d = { hxy:hxy, tail:tail, cxy:cxy },
+ strokeStyle = paintStyle.strokeStyle || currentConnectionPaintStyle.strokeStyle,
+ fillStyle = paintStyle.fillStyle || currentConnectionPaintStyle.strokeStyle,
+ lineWidth = paintStyle.lineWidth || currentConnectionPaintStyle.lineWidth,
+ info = {
+ component:component,
+ d:d,
+ lineWidth:lineWidth,
+ strokeStyle:strokeStyle,
+ fillStyle:fillStyle,
+ minX:Math.min(hxy.x, tail[0].x, tail[1].x),
+ maxX:Math.max(hxy.x, tail[0].x, tail[1].x),
+ minY:Math.min(hxy.y, tail[0].y, tail[1].y),
+ maxY:Math.max(hxy.y, tail[0].y, tail[1].y)
+ };
+
+ return info;
+ }
+ else return {component:component, minX:0,maxX:0,minY:0,maxY:0};
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.Arrow, AbstractOverlay);
+
+ /*
+ * Class: Overlays.PlainArrow
+ *
+ * A basic arrow. This is in fact just one instance of the more generic case in which the tail folds back on itself to some
+ * point along the length of the arrow: in this case, that foldback point is the full length of the arrow. so it just does
+ * a 'call' to Arrow with foldback set appropriately.
+ */
+ /*
+ * Function: Constructor
+ * See <Overlays.Arrow> for allowed parameters for this overlay.
+ */
+ jsPlumb.Overlays.PlainArrow = function(params) {
+ params = params || {};
+ var p = jsPlumb.extend(params, {foldback:1});
+ jsPlumb.Overlays.Arrow.call(this, p);
+ this.type = "PlainArrow";
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.PlainArrow, jsPlumb.Overlays.Arrow);
+
+ /*
+ * Class: Overlays.Diamond
+ *
+ * A diamond. Like PlainArrow, this is a concrete case of the more generic case of the tail points converging on some point...it just
+ * happens that in this case, that point is greater than the length of the the arrow.
+ *
+ * this could probably do with some help with positioning...due to the way it reuses the Arrow paint code, what Arrow thinks is the
+ * center is actually 1/4 of the way along for this guy. but we don't have any knowledge of pixels at this point, so we're kind of
+ * stuck when it comes to helping out the Arrow class. possibly we could pass in a 'transpose' parameter or something. the value
+ * would be -l/4 in this case - move along one quarter of the total length.
+ */
+ /*
+ * Function: Constructor
+ * See <Overlays.Arrow> for allowed parameters for this overlay.
+ */
+ jsPlumb.Overlays.Diamond = function(params) {
+ params = params || {};
+ var l = params.length || 40,
+ p = jsPlumb.extend(params, {length:l/2, foldback:2});
+ jsPlumb.Overlays.Arrow.call(this, p);
+ this.type = "Diamond";
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.Diamond, jsPlumb.Overlays.Arrow);
+
+ var _getDimensions = function(component) {
+ if (component._jsPlumb.cachedDimensions == null)
+ component._jsPlumb.cachedDimensions = component.getDimensions();
+ return component._jsPlumb.cachedDimensions;
+ };
+
+ // abstract superclass for overlays that add an element to the DOM.
+ var AbstractDOMOverlay = function(params) {
+ jsPlumb.DOMElementComponent.apply(this, arguments);
+ AbstractOverlay.apply(this, arguments);
+
+ var jpcl = jsPlumb.CurrentLibrary;
+ this.id = params.id;
+ this._jsPlumb.div = null;
+ this._jsPlumb.initialised = false;
+ this._jsPlumb.component = params.component;
+ this._jsPlumb.cachedDimensions = null;
+ this._jsPlumb.create = params.create;
+
+ this.getElement = function() {
+ if (this._jsPlumb.div == null) {
+ var div = this._jsPlumb.div = jpcl.getDOMElement(this._jsPlumb.create(this._jsPlumb.component));
+ div.style.position = "absolute";
+ var clazz = params._jsPlumb.overlayClass + " " +
+ (this.cssClass ? this.cssClass :
+ params.cssClass ? params.cssClass : "");
+ div.className = clazz;
+ this._jsPlumb.instance.appendElement(div, this._jsPlumb.component.parent);
+ this._jsPlumb.instance.getId(div);
+ this.attachListeners(div, this);
+ this.canvas = div;
+ }
+ return this._jsPlumb.div;
+ };
+
+ /*
+ this.paint = function(p, containerExtents) {
+ if (!this._jsPlumb.initialised) {
+ this.getElement();
+ p.component.appendDisplayElement(this._jsPlumb.div);
+ this.attachListeners(this._jsPlumb.div, p.component);
+ this._jsPlumb.initialised = true;
+ }
+ this._jsPlumb.div.style.left = (p.component.x + p.d.minx) + "px";
+ this._jsPlumb.div.style.top = (p.component.y + p.d.miny) + "px";
+ };*/
+
+ this.draw = function(component, currentConnectionPaintStyle) {
+ var td = _getDimensions(this);
+ if (td != null && td.length == 2) {
+ var cxy = {x:0,y:0};
+ if (component.pointOnPath) {
+ var loc = this.loc, absolute = false;
+ if (jsPlumbUtil.isString(this.loc) || this.loc < 0 || this.loc > 1) {
+ loc = parseInt(this.loc, 10);
+ absolute = true;
+ }
+ cxy = component.pointOnPath(loc, absolute); // a connection
+ }
+ else {
+ var locToUse = this.loc.constructor == Array ? this.loc : this.endpointLoc;
+ cxy = { x:locToUse[0] * component.w,
+ y:locToUse[1] * component.h };
+ }
+
+ var minx = cxy.x - (td[0] / 2),
+ miny = cxy.y - (td[1] / 2);
+
+ return {
+ component:component,
+ d:{ minx:minx, miny:miny, td:td, cxy:cxy },
+ minX:minx,
+ maxX:minx + td[0],
+ minY:miny,
+ maxY:miny + td[1]
+ };
+ }
+ else return {minX:0,maxX:0,minY:0,maxY:0};
+ };
+ };
+ jsPlumbUtil.extend(AbstractDOMOverlay, [jsPlumb.DOMElementComponent, AbstractOverlay], {
+ getDimensions : function() {
+ return jsPlumb.CurrentLibrary.getSize(jsPlumb.CurrentLibrary.getElementObject(this.getElement()));
+ },
+ setVisible : function(state) {
+ this._jsPlumb.div.style.display = state ? "block" : "none";
+ },
+ /*
+ * Function: clearCachedDimensions
+ * Clears the cached dimensions for the label. As a performance enhancement, label dimensions are
+ * cached from 1.3.12 onwards. The cache is cleared when you change the label text, of course, but
+ * there are other reasons why the text dimensions might change - if you make a change through CSS, for
+ * example, you might change the font size. in that case you should explicitly call this method.
+ */
+ clearCachedDimensions : function() {
+ this._jsPlumb.cachedDimensions = null;
+ },
+ cleanup : function() {
+ if (this._jsPlumb.div != null)
+ jsPlumb.CurrentLibrary.removeElement(this._jsPlumb.div);
+ },
+ computeMaxSize : function() {
+ var td = _getDimensions(this);
+ return Math.max(td[0], td[1]);
+ },
+ reattachListeners : function(connector) {
+ if (this._jsPlumb.div) {
+ this.reattachListenersForElement(this._jsPlumb.div, this, connector);
+ }
+ },
+ paint : function(p, containerExtents) {
+ if (!this._jsPlumb.initialised) {
+ this.getElement();
+ p.component.appendDisplayElement(this._jsPlumb.div);
+ this.attachListeners(this._jsPlumb.div, p.component);
+ this._jsPlumb.initialised = true;
+ }
+ this._jsPlumb.div.style.left = (p.component.x + p.d.minx) + "px";
+ this._jsPlumb.div.style.top = (p.component.y + p.d.miny) + "px";
+ }
+ });
+
+ /*
+ * Class: Overlays.Custom
+ * A Custom overlay. You supply a 'create' function which returns some DOM element, and jsPlumb positions it.
+ * The 'create' function is passed a Connection or Endpoint.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ * create - function for jsPlumb to call that returns a DOM element.
+ * location - distance (as a decimal from 0 to 1 inclusive) marking where the label should sit on the connector. defaults to 0.5.
+ * id - optional id to use for later retrieval of this overlay.
+ *
+ */
+ jsPlumb.Overlays.Custom = function(params) {
+ this.type = "Custom";
+ AbstractDOMOverlay.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.Custom, AbstractDOMOverlay);
+
+ jsPlumb.Overlays.GuideLines = function() {
+ var self = this;
+ self.length = 50;
+ self.lineWidth = 5;
+ this.type = "GuideLines";
+ AbstractOverlay.apply(this, arguments);
+ jsPlumb.jsPlumbUIComponent.apply(this, arguments);
+ this.draw = function(connector, currentConnectionPaintStyle) {
+
+ var head = connector.pointAlongPathFrom(self.loc, self.length / 2),
+ mid = connector.pointOnPath(self.loc),
+ tail = jsPlumbUtil.pointOnLine(head, mid, self.length),
+ tailLine = jsPlumbUtil.perpendicularLineTo(head, tail, 40),
+ headLine = jsPlumbUtil.perpendicularLineTo(tail, head, 20);
+
+ return {
+ connector:connector,
+ head:head,
+ tail:tail,
+ headLine:headLine,
+ tailLine:tailLine,
+ minX:Math.min(head.x, tail.x, headLine[0].x, headLine[1].x),
+ minY:Math.min(head.y, tail.y, headLine[0].y, headLine[1].y),
+ maxX:Math.max(head.x, tail.x, headLine[0].x, headLine[1].x),
+ maxY:Math.max(head.y, tail.y, headLine[0].y, headLine[1].y)
+ };
+ };
+
+ // this.cleanup = function() { }; // nothing to clean up for GuideLines
+ };
+
+ /*
+ * Class: Overlays.Label
+ * A Label overlay. For all different renderer types (SVG/Canvas/VML), jsPlumb draws a Label overlay as a styled DIV. Version 1.3.0 of jsPlumb
+ * introduced the ability to set css classes on the label; this is now the preferred way for you to style a label. The 'labelStyle' parameter
+ * is still supported in 1.3.0 but its usage is deprecated. Under the hood, jsPlumb just turns that object into a bunch of CSS directive that it
+ * puts on the Label's 'style' attribute, so the end result is the same.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ * cssClass - optional css class string to append to css class. This string is appended "as-is", so you can of course have multiple classes
+ * defined. This parameter is preferred to using labelStyle, borderWidth and borderStyle.
+ * label - the label to paint. May be a string or a function that returns a string. Nothing will be painted if your label is null or your
+ * label function returns null. empty strings _will_ be painted.
+ * location - distance (as a decimal from 0 to 1 inclusive) marking where the label should sit on the connector. defaults to 0.5.
+ * id - optional id to use for later retrieval of this overlay.
+ *
+ */
+ jsPlumb.Overlays.Label = function(params) {
+ this.labelStyle = params.labelStyle || jsPlumb.Defaults.LabelStyle;
+ this.cssClass = this.labelStyle != null ? this.labelStyle.cssClass : null;
+ var p = jsPlumb.extend({
+ create : function() {
+ return document.createElement("div");
+ }}, params);
+ jsPlumb.Overlays.Custom.call(this, p);
+ this.type = "Label";
+ this.label = params.label || "";
+ this.labelText = null;
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.Label, jsPlumb.Overlays.Custom, {
+ cleanup:function() {
+ this.div = null;
+ this.label = null;
+ this.labelText = null;
+ this.cssClass = null;
+ this.labelStyle = null;
+ },
+ getLabel : function() {
+ return this.label;
+ },
+ /*
+ * Function: setLabel
+ * sets the label's, um, label. you would think i'd call this function
+ * 'setText', but you can pass either a Function or a String to this, so
+ * it makes more sense as 'setLabel'. This uses innerHTML on the label div, so keep
+ * that in mind if you need escaped HTML.
+ */
+ setLabel : function(l) {
+ this.label = l;
+ this.labelText = null;
+ this.clearCachedDimensions();
+ this.update();
+ this.component.repaint();
+ },
+ getDimensions : function() {
+ this.update();
+ return AbstractDOMOverlay.prototype.getDimensions.apply(this, arguments);
+ },
+ update : function() {
+ if (typeof this.label == "function") {
+ var lt = this.label(this);
+ this.getElement().innerHTML = lt.replace(/\r\n/g, "<br/>");
+ }
+ else {
+ if (this.labelText == null) {
+ this.labelText = this.label;
+ this.getElement().innerHTML = this.labelText.replace(/\r\n/g, "<br/>");
+ }
+ }
+ }
+ });
+
+ // ********************************* END OF OVERLAY DEFINITIONS ***********************************************************************
+
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the 'flowchart' connectors, consisting of vertical and horizontal line segments.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+;(function() {
+
+ /**
+ * Function: Constructor
+ *
+ * Parameters:
+ * stub - minimum length for the stub at each end of the connector. This can be an integer, giving a value for both ends of the connections,
+ * or an array of two integers, giving separate values for each end. The default is an integer with value 30 (pixels).
+ * gap - gap to leave between the end of the connector and the element on which the endpoint resides. if you make this larger than stub then you will see some odd looking behaviour.
+ Like stub, this can be an array or a single value. defaults to 0 pixels for each end.
+ * cornerRadius - optional, defines the radius of corners between segments. defaults to 0 (hard edged corners).
+ * alwaysRespectStubs - defaults to false. whether or not the connectors should always draw the stub, or, if the two elements
+ are in close proximity to each other (closer than the sum of the two stubs), to adjust the stubs.
+ */
+ var Flowchart = function(params) {
+ this.type = "Flowchart";
+ params = params || {};
+ params.stub = params.stub == null ? 30 : params.stub;
+ var self = this,
+ _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
+ midpoint = params.midpoint == null ? 0.5 : params.midpoint,
+ points = [], segments = [],
+ grid = params.grid,
+ alwaysRespectStubs = params.alwaysRespectStubs,
+ userSuppliedSegments = null,
+ lastx = null, lasty = null, lastOrientation,
+ cornerRadius = params.cornerRadius != null ? params.cornerRadius : 0,
+ sgn = function(n) { return n < 0 ? -1 : n === 0 ? 0 : 1; },
+ /**
+ * helper method to add a segment.
+ */
+ addSegment = function(segments, x, y, paintInfo) {
+ if (lastx == x && lasty == y) return;
+ var lx = lastx == null ? paintInfo.sx : lastx,
+ ly = lasty == null ? paintInfo.sy : lasty,
+ o = lx == x ? "v" : "h",
+ sgnx = sgn(x - lx),
+ sgny = sgn(y - ly);
+
+ lastx = x;
+ lasty = y;
+ segments.push([lx, ly, x, y, o, sgnx, sgny]);
+ },
+ segLength = function(s) {
+ return Math.sqrt(Math.pow(s[0] - s[2], 2) + Math.pow(s[1] - s[3], 2));
+ },
+ _cloneArray = function(a) { var _a = []; _a.push.apply(_a, a); return _a;},
+ updateMinMax = function(a1) {
+ self.bounds.minX = Math.min(self.bounds.minX, a1[2]);
+ self.bounds.maxX = Math.max(self.bounds.maxX, a1[2]);
+ self.bounds.minY = Math.min(self.bounds.minY, a1[3]);
+ self.bounds.maxY = Math.max(self.bounds.maxY, a1[3]);
+ },
+ writeSegments = function(conn, segments, paintInfo) {
+ var current, next;
+ for (var i = 0; i < segments.length - 1; i++) {
+
+ current = current || _cloneArray(segments[i]);
+ next = _cloneArray(segments[i + 1]);
+ if (cornerRadius > 0 && current[4] != next[4]) {
+ var radiusToUse = Math.min(cornerRadius, segLength(current), segLength(next));
+ // right angle. adjust current segment's end point, and next segment's start point.
+ current[2] -= current[5] * radiusToUse;
+ current[3] -= current[6] * radiusToUse;
+ next[0] += next[5] * radiusToUse;
+ next[1] += next[6] * radiusToUse;
+ var ac = (current[6] == next[5] && next[5] == 1) ||
+ ((current[6] == next[5] && next[5] === 0) && current[5] != next[6]) ||
+ (current[6] == next[5] && next[5] == -1),
+ sgny = next[1] > current[3] ? 1 : -1,
+ sgnx = next[0] > current[2] ? 1 : -1,
+ sgnEqual = sgny == sgnx,
+ cx = (sgnEqual && ac || (!sgnEqual && !ac)) ? next[0] : current[2],
+ cy = (sgnEqual && ac || (!sgnEqual && !ac)) ? current[3] : next[1];
+
+ _super.addSegment(conn, "Straight", {
+ x1:current[0], y1:current[1], x2:current[2], y2:current[3]
+ });
+
+ _super.addSegment(conn, "Arc", {
+ r:radiusToUse,
+ x1:current[2],
+ y1:current[3],
+ x2:next[0],
+ y2:next[1],
+ cx:cx,
+ cy:cy,
+ ac:ac
+ });
+ }
+ else {
+ // dx + dy are used to adjust for line width.
+ var dx = (current[2] == current[0]) ? 0 : (current[2] > current[0]) ? (paintInfo.lw / 2) : -(paintInfo.lw / 2),
+ dy = (current[3] == current[1]) ? 0 : (current[3] > current[1]) ? (paintInfo.lw / 2) : -(paintInfo.lw / 2);
+ _super.addSegment(conn, "Straight", {
+ x1:current[0]- dx, y1:current[1]-dy, x2:current[2] + dx, y2:current[3] + dy
+ });
+ }
+ current = next;
+ }
+ // last segment
+ _super.addSegment(conn, "Straight", {
+ x1:next[0], y1:next[1], x2:next[2], y2:next[3]
+ });
+ };
+
+ this.setSegments = function(s) {
+ userSuppliedSegments = s;
+ };
+
+ this.isEditable = function() { return true; };
+
+ /*
+ Function: getOriginalSegments
+ Gets the segments before the addition of rounded corners. This is used by the flowchart
+ connector editor, since it only wants to concern itself with the original segments.
+ */
+ this.getOriginalSegments = function() {
+ return userSuppliedSegments || segments;
+ };
+
+ this._compute = function(paintInfo, params) {
+
+ if (params.clearEdits)
+ userSuppliedSegments = null;
+
+ if (userSuppliedSegments != null) {
+ writeSegments(this, userSuppliedSegments, paintInfo);
+ return;
+ }
+
+ segments = [];
+ lastx = null; lasty = null;
+ lastOrientation = null;
+
+ var midx = paintInfo.startStubX + ((paintInfo.endStubX - paintInfo.startStubX) * midpoint),
+ midy = paintInfo.startStubY + ((paintInfo.endStubY - paintInfo.startStubY) * midpoint);
+
+ var findClearedLine = function(start, mult, anchorPos, dimension) {
+ return start + (mult * (( 1 - anchorPos) * dimension) + _super.maxStub);
+ },
+ orientations = { x:[ 0, 1 ], y:[ 1, 0 ] },
+ commonStubCalculator = function(axis) {
+ return [ paintInfo.startStubX, paintInfo.startStubY, paintInfo.endStubX, paintInfo.endStubY ];
+ },
+ stubCalculators = {
+ perpendicular:commonStubCalculator,
+ orthogonal:commonStubCalculator,
+ opposite:function(axis) {
+ var pi = paintInfo,
+ idx = axis == "x" ? 0 : 1,
+ areInProximity = {
+ "x":function() {
+ return ( (pi.so[idx] == 1 && (
+ ( (pi.startStubX > pi.endStubX) && (pi.tx > pi.startStubX) ) ||
+ ( (pi.sx > pi.endStubX) && (pi.tx > pi.sx))))) ||
+
+ ( (pi.so[idx] == -1 && (
+ ( (pi.startStubX < pi.endStubX) && (pi.tx < pi.startStubX) ) ||
+ ( (pi.sx < pi.endStubX) && (pi.tx < pi.sx)))));
+ },
+ "y":function() {
+ return ( (pi.so[idx] == 1 && (
+ ( (pi.startStubY > pi.endStubY) && (pi.ty > pi.startStubY) ) ||
+ ( (pi.sy > pi.endStubY) && (pi.ty > pi.sy))))) ||
+
+ ( (pi.so[idx] == -1 && (
+ ( (pi.startStubY < pi.endStubY) && (pi.ty < pi.startStubY) ) ||
+ ( (pi.sy < pi.endStubY) && (pi.ty < pi.sy)))));
+ }
+ };
+
+ if (!alwaysRespectStubs && areInProximity[axis]()) {
+ return {
+ "x":[(paintInfo.sx + paintInfo.tx) / 2, paintInfo.startStubY, (paintInfo.sx + paintInfo.tx) / 2, paintInfo.endStubY],
+ "y":[paintInfo.startStubX, (paintInfo.sy + paintInfo.ty) / 2, paintInfo.endStubX, (paintInfo.sy + paintInfo.ty) / 2]
+ }[axis];
+ }
+ else {
+ return [ paintInfo.startStubX, paintInfo.startStubY, paintInfo.endStubX, paintInfo.endStubY ];
+ }
+ }
+ },
+ lineCalculators = {
+ perpendicular : function(axis, ss, oss, es, oes) {
+ var pi = paintInfo,
+ sis = {
+ x:[ [ [ 1,2,3,4 ], null, [ 2,1,4,3 ] ], null, [ [ 4,3,2,1 ], null, [ 3,4,1,2 ] ] ],
+ y:[ [ [ 3,2,1,4 ], null, [ 2,3,4,1 ] ], null, [ [ 4,1,2,3 ], null, [ 1,4,3,2 ] ] ]
+ },
+ stubs = {
+ x:[ [ pi.startStubX, pi.endStubX ] , null, [ pi.endStubX, pi.startStubX ] ],
+ y:[ [ pi.startStubY, pi.endStubY ] , null, [ pi.endStubY, pi.startStubY ] ]
+ },
+ midLines = {
+ x:[ [ midx, pi.startStubY ], [ midx, pi.endStubY ] ],
+ y:[ [ pi.startStubX, midy ], [ pi.endStubX, midy ] ]
+ },
+ linesToEnd = {
+ x:[ [ pi.endStubX, pi.startStubY ] ],
+ y:[ [ pi.startStubX, pi.endStubY ] ]
+ },
+ startToEnd = {
+ x:[ [ pi.startStubX, pi.endStubY ], [ pi.endStubX, pi.endStubY ] ],
+ y:[ [ pi.endStubX, pi.startStubY ], [ pi.endStubX, pi.endStubY ] ]
+ },
+ startToMidToEnd = {
+ x:[ [ pi.startStubX, midy ], [ pi.endStubX, midy ], [ pi.endStubX, pi.endStubY ] ],
+ y:[ [ midx, pi.startStubY ], [ midx, pi.endStubY ], [ pi.endStubX, pi.endStubY ] ]
+ },
+ otherStubs = {
+ x:[ pi.startStubY, pi.endStubY ],
+ y:[ pi.startStubX, pi.endStubX ]
+ },
+ soIdx = orientations[axis][0], toIdx = orientations[axis][1],
+ _so = pi.so[soIdx] + 1,
+ _to = pi.to[toIdx] + 1,
+ otherFlipped = (pi.to[toIdx] == -1 && (otherStubs[axis][1] < otherStubs[axis][0])) || (pi.to[toIdx] == 1 && (otherStubs[axis][1] > otherStubs[axis][0])),
+ stub1 = stubs[axis][_so][0],
+ stub2 = stubs[axis][_so][1],
+ segmentIndexes = sis[axis][_so][_to];
+
+ if (pi.segment == segmentIndexes[3] || (pi.segment == segmentIndexes[2] && otherFlipped)) {
+ return midLines[axis];
+ }
+ else if (pi.segment == segmentIndexes[2] && stub2 < stub1) {
+ return linesToEnd[axis];
+ }
+ else if ((pi.segment == segmentIndexes[2] && stub2 >= stub1) || (pi.segment == segmentIndexes[1] && !otherFlipped)) {
+ return startToMidToEnd[axis];
+ }
+ else if (pi.segment == segmentIndexes[0] || (pi.segment == segmentIndexes[1] && otherFlipped)) {
+ return startToEnd[axis];
+ }
+ },
+ orthogonal : function(axis, startStub, otherStartStub, endStub, otherEndStub) {
+ var pi = paintInfo,
+ extent = {
+ "x":pi.so[0] == -1 ? Math.min(startStub, endStub) : Math.max(startStub, endStub),
+ "y":pi.so[1] == -1 ? Math.min(startStub, endStub) : Math.max(startStub, endStub)
+ }[axis];
+
+ return {
+ "x":[ [ extent, otherStartStub ],[ extent, otherEndStub ], [ endStub, otherEndStub ] ],
+ "y":[ [ otherStartStub, extent ], [ otherEndStub, extent ], [ otherEndStub, endStub ] ]
+ }[axis];
+ },
+ opposite : function(axis, ss, oss, es, oes) {
+ var pi = paintInfo,
+ otherAxis = {"x":"y","y":"x"}[axis],
+ dim = {"x":"height","y":"width"}[axis],
+ comparator = pi["is" + axis.toUpperCase() + "GreaterThanStubTimes2"];
+
+ if (params.sourceEndpoint.elementId == params.targetEndpoint.elementId) {
+ var _val = oss + ((1 - params.sourceEndpoint.anchor[otherAxis]) * params.sourceInfo[dim]) + _super.maxStub;
+ return {
+ "x":[ [ ss, _val ], [ es, _val ] ],
+ "y":[ [ _val, ss ], [ _val, es ] ]
+ }[axis];
+
+ }
+ else if (!comparator || (pi.so[idx] == 1 && ss > es) || (pi.so[idx] == -1 && ss < es)) {
+ return {
+ "x":[[ ss, midy ], [ es, midy ]],
+ "y":[[ midx, ss ], [ midx, es ]]
+ }[axis];
+ }
+ else if ((pi.so[idx] == 1 && ss < es) || (pi.so[idx] == -1 && ss > es)) {
+ return {
+ "x":[[ midx, pi.sy ], [ midx, pi.ty ]],
+ "y":[[ pi.sx, midy ], [ pi.tx, midy ]]
+ }[axis];
+ }
+ }
+ };
+
+ var stubs = stubCalculators[paintInfo.anchorOrientation](paintInfo.sourceAxis),
+ idx = paintInfo.sourceAxis == "x" ? 0 : 1,
+ oidx = paintInfo.sourceAxis == "x" ? 1 : 0,
+ ss = stubs[idx],
+ oss = stubs[oidx],
+ es = stubs[idx + 2],
+ oes = stubs[oidx + 2];
+
+ // add the start stub segment.
+ addSegment(segments, stubs[0], stubs[1], paintInfo);
+
+ // compute the rest of the line
+ var p = lineCalculators[paintInfo.anchorOrientation](paintInfo.sourceAxis, ss, oss, es, oes);
+ if (p) {
+ for (var i = 0; i < p.length; i++) {
+ addSegment(segments, p[i][0], p[i][1], paintInfo);
+ }
+ }
+
+ // line to end stub
+ addSegment(segments, stubs[2], stubs[3], paintInfo);
+
+ // end stub to end
+ addSegment(segments, paintInfo.tx, paintInfo.ty, paintInfo);
+
+ writeSegments(this, segments, paintInfo);
+ };
+
+ this.getPath = function() {
+ var _last = null, _lastAxis = null, s = [], segs = userSuppliedSegments || segments;
+ for (var i = 0; i < segs.length; i++) {
+ var seg = segs[i], axis = seg[4], axisIndex = (axis == "v" ? 3 : 2);
+ if (_last != null && _lastAxis === axis) {
+ _last[axisIndex] = seg[axisIndex];
+ }
+ else {
+ if (seg[0] != seg[2] || seg[1] != seg[3]) {
+ s.push({
+ start:[ seg[0], seg[1] ],
+ end:[ seg[2], seg[3] ]
+ });
+ _last = seg;
+ _lastAxis = seg[4];
+ }
+ }
+ }
+ return s;
+ };
+
+ this.setPath = function(path) {
+ userSuppliedSegments = [];
+ for (var i = 0; i < path.length; i++) {
+ var lx = path[i].start[0],
+ ly = path[i].start[1],
+ x = path[i].end[0],
+ y = path[i].end[1],
+ o = lx == x ? "v" : "h",
+ sgnx = sgn(x - lx),
+ sgny = sgn(y - ly);
+
+ userSuppliedSegments.push([lx, ly, x, y, o, sgnx, sgny]);
+ }
+ };
+ };
+
+ jsPlumbUtil.extend(Flowchart, jsPlumb.Connectors.AbstractConnector);
+ jsPlumb.registerConnectorType(Flowchart, "Flowchart");
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the state machine connectors.
+ *
+ * Thanks to Brainstorm Mobile Solutions for supporting the development of these.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ var Line = function(x1, y1, x2, y2) {
+
+ this.m = (y2 - y1) / (x2 - x1);
+ this.b = -1 * ((this.m * x1) - y1);
+
+ this.rectIntersect = function(x,y,w,h) {
+ var results = [], xInt, yInt;
+
+ // try top face
+ // the equation of the top face is y = (0 * x) + b; y = b.
+ xInt = (y - this.b) / this.m;
+ // test that the X value is in the line's range.
+ if (xInt >= x && xInt <= (x + w)) results.push([ xInt, (this.m * xInt) + this.b ]);
+
+ // try right face
+ yInt = (this.m * (x + w)) + this.b;
+ if (yInt >= y && yInt <= (y + h)) results.push([ (yInt - this.b) / this.m, yInt ]);
+
+ // bottom face
+ xInt = ((y + h) - this.b) / this.m;
+ // test that the X value is in the line's range.
+ if (xInt >= x && xInt <= (x + w)) results.push([ xInt, (this.m * xInt) + this.b ]);
+
+ // try left face
+ yInt = (this.m * x) + this.b;
+ if (yInt >= y && yInt <= (y + h)) results.push([ (yInt - this.b) / this.m, yInt ]);
+
+ if (results.length == 2) {
+ var midx = (results[0][0] + results[1][0]) / 2, midy = (results[0][1] + results[1][1]) / 2;
+ results.push([ midx,midy ]);
+ // now calculate the segment inside the rectangle where the midpoint lies.
+ var xseg = midx <= x + (w / 2) ? -1 : 1,
+ yseg = midy <= y + (h / 2) ? -1 : 1;
+ results.push([xseg, yseg]);
+ return results;
+ }
+
+ return null;
+
+ };
+ },
+ _segment = function(x1, y1, x2, y2) {
+ if (x1 <= x2 && y2 <= y1) return 1;
+ else if (x1 <= x2 && y1 <= y2) return 2;
+ else if (x2 <= x1 && y2 >= y1) return 3;
+ return 4;
+ },
+
+ // the control point we will use depends on the faces to which each end of the connection is assigned, specifically whether or not the
+ // two faces are parallel or perpendicular. if they are parallel then the control point lies on the midpoint of the axis in which they
+ // are parellel and varies only in the other axis; this variation is proportional to the distance that the anchor points lie from the
+ // center of that face. if the two faces are perpendicular then the control point is at some distance from both the midpoints; the amount and
+ // direction are dependent on the orientation of the two elements. 'seg', passed in to this method, tells you which segment the target element
+ // lies in with respect to the source: 1 is top right, 2 is bottom right, 3 is bottom left, 4 is top left.
+ //
+ // sourcePos and targetPos are arrays of info about where on the source and target each anchor is located. their contents are:
+ //
+ // 0 - absolute x
+ // 1 - absolute y
+ // 2 - proportional x in element (0 is left edge, 1 is right edge)
+ // 3 - proportional y in element (0 is top edge, 1 is bottom edge)
+ //
+ _findControlPoint = function(midx, midy, segment, sourceEdge, targetEdge, dx, dy, distance, proximityLimit) {
+ // TODO (maybe)
+ // - if anchor pos is 0.5, make the control point take into account the relative position of the elements.
+ if (distance <= proximityLimit) return [midx, midy];
+
+ if (segment === 1) {
+ if (sourceEdge[3] <= 0 && targetEdge[3] >= 1) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
+ else if (sourceEdge[2] >= 1 && targetEdge[2] <= 0) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
+ else return [ midx + (-1 * dx) , midy + (-1 * dy) ];
+ }
+ else if (segment === 2) {
+ if (sourceEdge[3] >= 1 && targetEdge[3] <= 0) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
+ else if (sourceEdge[2] >= 1 && targetEdge[2] <= 0) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
+ else return [ midx + (1 * dx) , midy + (-1 * dy) ];
+ }
+ else if (segment === 3) {
+ if (sourceEdge[3] >= 1 && targetEdge[3] <= 0) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
+ else if (sourceEdge[2] <= 0 && targetEdge[2] >= 1) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
+ else return [ midx + (-1 * dx) , midy + (-1 * dy) ];
+ }
+ else if (segment === 4) {
+ if (sourceEdge[3] <= 0 && targetEdge[3] >= 1) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
+ else if (sourceEdge[2] <= 0 && targetEdge[2] >= 1) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
+ else return [ midx + (1 * dx) , midy + (-1 * dy) ];
+ }
+
+ };
+
+ /**
+ * Class: Connectors.StateMachine
+ * Provides 'state machine' connectors.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ * curviness - measure of how "curvy" the connectors will be. this is translated as the distance that the
+ * Bezier curve's control point is from the midpoint of the straight line connecting the two
+ * endpoints, and does not mean that the connector is this wide. The Bezier curve never reaches
+ * its control points; they act as gravitational masses. defaults to 10.
+ * margin - distance from element to start and end connectors, in pixels. defaults to 5.
+ * proximityLimit - sets the distance beneath which the elements are consider too close together to bother
+ * with fancy curves. by default this is 80 pixels.
+ * loopbackRadius - the radius of a loopback connector. optional; defaults to 25.
+ * showLoopback - If set to false this tells the connector that it is ok to paint connections whose source and target is the same element with a connector running through the element. The default value for this is true; the connector always makes a loopback connection loop around the element rather than passing through it.
+ */
+ var StateMachine = function(params) {
+ params = params || {};
+ this.type = "StateMachine";
+
+ var self = this,
+ _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
+ curviness = params.curviness || 10,
+ margin = params.margin || 5,
+ proximityLimit = params.proximityLimit || 80,
+ clockwise = params.orientation && params.orientation === "clockwise",
+ loopbackRadius = params.loopbackRadius || 25,
+ showLoopback = params.showLoopback !== false;
+
+ this._compute = function(paintInfo, params) {
+ var w = Math.abs(params.sourcePos[0] - params.targetPos[0]),
+ h = Math.abs(params.sourcePos[1] - params.targetPos[1]),
+ x = Math.min(params.sourcePos[0], params.targetPos[0]),
+ y = Math.min(params.sourcePos[1], params.targetPos[1]);
+
+ if (!showLoopback || (params.sourceEndpoint.elementId !== params.targetEndpoint.elementId)) {
+ var _sx = params.sourcePos[0] < params.targetPos[0] ? 0 : w,
+ _sy = params.sourcePos[1] < params.targetPos[1] ? 0:h,
+ _tx = params.sourcePos[0] < params.targetPos[0] ? w : 0,
+ _ty = params.sourcePos[1] < params.targetPos[1] ? h : 0;
+
+ // now adjust for the margin
+ if (params.sourcePos[2] === 0) _sx -= margin;
+ if (params.sourcePos[2] === 1) _sx += margin;
+ if (params.sourcePos[3] === 0) _sy -= margin;
+ if (params.sourcePos[3] === 1) _sy += margin;
+ if (params.targetPos[2] === 0) _tx -= margin;
+ if (params.targetPos[2] === 1) _tx += margin;
+ if (params.targetPos[3] === 0) _ty -= margin;
+ if (params.targetPos[3] === 1) _ty += margin;
+
+ //
+ // these connectors are quadratic bezier curves, having a single control point. if both anchors
+ // are located at 0.5 on their respective faces, the control point is set to the midpoint and you
+ // get a straight line. this is also the case if the two anchors are within 'proximityLimit', since
+ // it seems to make good aesthetic sense to do that. outside of that, the control point is positioned
+ // at 'curviness' pixels away along the normal to the straight line connecting the two anchors.
+ //
+ // there may be two improvements to this. firstly, we might actually support the notion of avoiding nodes
+ // in the UI, or at least making a good effort at doing so. if a connection would pass underneath some node,
+ // for example, we might increase the distance the control point is away from the midpoint in a bid to
+ // steer it around that node. this will work within limits, but i think those limits would also be the likely
+ // limits for, once again, aesthetic good sense in the layout of a chart using these connectors.
+ //
+ // the second possible change is actually two possible changes: firstly, it is possible we should gradually
+ // decrease the 'curviness' as the distance between the anchors decreases; start tailing it off to 0 at some
+ // point (which should be configurable). secondly, we might slightly increase the 'curviness' for connectors
+ // with respect to how far their anchor is from the center of its respective face. this could either look cool,
+ // or stupid, and may indeed work only in a way that is so subtle as to have been a waste of time.
+ //
+
+ var _midx = (_sx + _tx) / 2, _midy = (_sy + _ty) / 2,
+ m2 = (-1 * _midx) / _midy, theta2 = Math.atan(m2),
+ dy = (m2 == Infinity || m2 == -Infinity) ? 0 : Math.abs(curviness / 2 * Math.sin(theta2)),
+ dx = (m2 == Infinity || m2 == -Infinity) ? 0 : Math.abs(curviness / 2 * Math.cos(theta2)),
+ segment = _segment(_sx, _sy, _tx, _ty),
+ distance = Math.sqrt(Math.pow(_tx - _sx, 2) + Math.pow(_ty - _sy, 2)),
+ // calculate the control point. this code will be where we'll put in a rudimentary element avoidance scheme; it
+ // will work by extending the control point to force the curve to be, um, curvier.
+ _controlPoint = _findControlPoint(_midx,
+ _midy,
+ segment,
+ params.sourcePos,
+ params.targetPos,
+ curviness, curviness,
+ distance,
+ proximityLimit);
+
+ _super.addSegment(this, "Bezier", {
+ x1:_tx, y1:_ty, x2:_sx, y2:_sy,
+ cp1x:_controlPoint[0], cp1y:_controlPoint[1],
+ cp2x:_controlPoint[0], cp2y:_controlPoint[1]
+ });
+ }
+ else {
+ // a loopback connector. draw an arc from one anchor to the other.
+ var x1 = params.sourcePos[0], x2 = params.sourcePos[0], y1 = params.sourcePos[1] - margin, y2 = params.sourcePos[1] - margin,
+ cx = x1, cy = y1 - loopbackRadius,
+ // canvas sizing stuff, to ensure the whole painted area is visible.
+ _w = 2 * loopbackRadius,
+ _h = 2 * loopbackRadius,
+ _x = cx - loopbackRadius,
+ _y = cy - loopbackRadius;
+
+ paintInfo.points[0] = _x;
+ paintInfo.points[1] = _y;
+ paintInfo.points[2] = _w;
+ paintInfo.points[3] = _h;
+
+ // ADD AN ARC SEGMENT.
+ _super.addSegment(this, "Arc", {
+ x1:(x1 - _x) + 4,
+ y1:y1 - _y,
+ startAngle:0,
+ endAngle: 2 * Math.PI,
+ r:loopbackRadius,
+ ac:!clockwise,
+ x2:(x1 - _x) - 4,
+ y2:y1 - _y,
+ cx:cx - _x,
+ cy:cy - _y
+ });
+ }
+ };
+ };
+ jsPlumb.registerConnectorType(StateMachine, "StateMachine");
+})();
+
+/*
+ // a possible rudimentary avoidance scheme, old now, perhaps not useful.
+ // if (avoidSelector) {
+ // var testLine = new Line(sourcePos[0] + _sx,sourcePos[1] + _sy,sourcePos[0] + _tx,sourcePos[1] + _ty);
+ // var sel = jsPlumb.getSelector(avoidSelector);
+ // for (var i = 0; i < sel.length; i++) {
+ // var id = jsPlumb.getId(sel[i]);
+ // if (id != sourceEndpoint.elementId && id != targetEndpoint.elementId) {
+ // o = jsPlumb.getOffset(id), s = jsPlumb.getSize(id);
+//
+// if (o && s) {
+// var collision = testLine.rectIntersect(o.left,o.top,s[0],s[1]);
+// if (collision) {
+ // set the control point to be a certain distance from the midpoint of the two points that
+ // the line crosses on the rectangle.
+ // TODO where will this 75 number come from?
+ // _controlX = collision[2][0] + (75 * collision[3][0]);
+ // / _controlY = collision[2][1] + (75 * collision[3][1]);
+// }
+// }
+ // }
+ // }
+ //}
+ */
+
+;(function() {
+
+ var Bezier = function(params) {
+ params = params || {};
+
+ var self = this,
+ _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
+ stub = params.stub || 50,
+ majorAnchor = params.curviness || 150,
+ minorAnchor = 10;
+
+ this.type = "Bezier";
+ this.getCurviness = function() { return majorAnchor; };
+
+ this._findControlPoint = function(point, sourceAnchorPosition, targetAnchorPosition, sourceEndpoint, targetEndpoint) {
+ // determine if the two anchors are perpendicular to each other in their orientation. we swap the control
+ // points around if so (code could be tightened up)
+ var soo = sourceEndpoint.anchor.getOrientation(sourceEndpoint),
+ too = targetEndpoint.anchor.getOrientation(targetEndpoint),
+ perpendicular = soo[0] != too[0] || soo[1] == too[1],
+ p = [];
+
+ if (!perpendicular) {
+ if (soo[0] === 0) // X
+ p.push(sourceAnchorPosition[0] < targetAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
+ else p.push(point[0] - (majorAnchor * soo[0]));
+
+ if (soo[1] === 0) // Y
+ p.push(sourceAnchorPosition[1] < targetAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
+ else p.push(point[1] + (majorAnchor * too[1]));
+ }
+ else {
+ if (too[0] === 0) // X
+ p.push(targetAnchorPosition[0] < sourceAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
+ else p.push(point[0] + (majorAnchor * too[0]));
+
+ if (too[1] === 0) // Y
+ p.push(targetAnchorPosition[1] < sourceAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
+ else p.push(point[1] + (majorAnchor * soo[1]));
+ }
+
+ return p;
+ };
+
+ this._compute = function(paintInfo, p) {
+ var sp = p.sourcePos,
+ tp = p.targetPos,
+ _w = Math.abs(sp[0] - tp[0]),
+ _h = Math.abs(sp[1] - tp[1]),
+ _sx = sp[0] < tp[0] ? _w : 0,
+ _sy = sp[1] < tp[1] ? _h : 0,
+ _tx = sp[0] < tp[0] ? 0 : _w,
+ _ty = sp[1] < tp[1] ? 0 : _h,
+ _CP = self._findControlPoint([_sx, _sy], sp, tp, p.sourceEndpoint, p.targetEndpoint),
+ _CP2 = self._findControlPoint([_tx, _ty], tp, sp, p.targetEndpoint, p.sourceEndpoint);
+
+ _super.addSegment(this, "Bezier", {
+ x1:_sx, y1:_sy, x2:_tx, y2:_ty,
+ cp1x:_CP[0], cp1y:_CP[1], cp2x:_CP2[0], cp2y:_CP2[1]
+ });
+ };
+ };
+
+ jsPlumb.registerConnectorType(Bezier, "Bezier");
+
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the HTML5 canvas renderers. Support for canvas was dropped in 1.4.2.
+ * This is being kept around because canvas might make a comeback as a single-page solution
+ * that also supports node rendering.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+
+// ********************************* CANVAS RENDERERS FOR CONNECTORS AND ENDPOINTS *******************************************************************
+
+ // TODO refactor to renderer common script. put a ref to jsPlumb.sizeCanvas in there too.
+ var _connectionBeingDragged = null,
+ _hasClass = function(el, clazz) { return jsPlumb.CurrentLibrary.hasClass(_getElementObject(el), clazz); },
+ _getElementObject = function(el) { return jsPlumb.CurrentLibrary.getElementObject(el); },
+ _getOffset = function(el) { return jsPlumb.CurrentLibrary.getOffset(_getElementObject(el)); },
+ _pageXY = function(el) { return jsPlumb.CurrentLibrary.getPageXY(el); },
+ _clientXY = function(el) { return jsPlumb.CurrentLibrary.getClientXY(el); };
+
+ /*
+ * Class:CanvasMouseAdapter
+ * Provides support for mouse events on canvases.
+ */
+ var CanvasMouseAdapter = window.CanvasMouseAdapter = function() {
+ var self = this;
+ self.overlayPlacements = [];
+ jsPlumb.jsPlumbUIComponent.apply(this, arguments);
+ jsPlumbUtil.EventGenerator.apply(this, arguments);
+ /**
+ * returns whether or not the given event is ojver a painted area of the canvas.
+ */
+ this._over = function(e) {
+ var o = _getOffset(_getElementObject(self.canvas)),
+ pageXY = _pageXY(e),
+ x = pageXY[0] - o.left, y = pageXY[1] - o.top;
+ if (x > 0 && y > 0 && x < self.canvas.width && y < self.canvas.height) {
+ // first check overlays
+ for ( var i = 0; i < self.overlayPlacements.length; i++) {
+ var p = self.overlayPlacements[i];
+ if (p && (p[0] <= x && p[1] >= x && p[2] <= y && p[3] >= y))
+ return true;
+ }
+ // then the canvas
+ var d = self.canvas.getContext("2d").getImageData(parseInt(x, 10), parseInt(y, 10), 1, 1);
+ return d.data[0] !== 0 || d.data[1] !== 0 || d.data[2] !== 0 || d.data[3] !== 0;
+ }
+ return false;
+ };
+
+ var _mouseover = false, _mouseDown = false, _posWhenMouseDown = null, _mouseWasDown = false,
+ _nullSafeHasClass = function(el, clazz) {
+ return el !== null && _hasClass(el, clazz);
+ };
+ this.mousemove = function(e) {
+ var pageXY = _pageXY(e), clientXY = _clientXY(e),
+ ee = document.elementFromPoint(clientXY[0], clientXY[1]),
+ eventSourceWasOverlay = _nullSafeHasClass(ee, "_jsPlumb_overlay");
+ var _continue = _connectionBeingDragged === null && (_nullSafeHasClass(ee, "_jsPlumb_endpoint") || _nullSafeHasClass(ee, "_jsPlumb_connector"));
+ if (!_mouseover && _continue && self._over(e)) {
+ _mouseover = true;
+ self.fire("mouseenter", self, e);
+ return true;
+ }
+ // TODO here there is a remote chance that the overlay the mouse moved onto
+ // is actually not an overlay for the current component. a more thorough check would
+ // be to ensure the overlay belonged to the current component.
+ else if (_mouseover && (!self._over(e) || !_continue) && !eventSourceWasOverlay) {
+ _mouseover = false;
+ self.fire("mouseexit", self, e);
+ }
+ self.fire("mousemove", self, e);
+ };
+
+ this.click = function(e) {
+ if (_mouseover && self._over(e) && !_mouseWasDown)
+ self.fire("click", self, e);
+ _mouseWasDown = false;
+ };
+
+ this.dblclick = function(e) {
+ if (_mouseover && self._over(e) && !_mouseWasDown)
+ self.fire("dblclick", self, e);
+ _mouseWasDown = false;
+ };
+
+ this.mousedown = function(e) {
+ if(self._over(e) && !_mouseDown) {
+ _mouseDown = true;
+ _posWhenMouseDown = _getOffset(_getElementObject(self.canvas));
+ self.fire("mousedown", self, e);
+ }
+ };
+
+ this.mouseup = function(e) {
+ _mouseDown = false;
+ self.fire("mouseup", self, e);
+ };
+
+ this.contextmenu = function(e) {
+ if (_mouseover && self._over(e) && !_mouseWasDown)
+ self.fire("contextmenu", self, e);
+ _mouseWasDown = false;
+ };
+ };
+ jsPlumbUtil.extend(CanvasMouseAdapter, [ jsPlumb.jsPlumbUIComponent, jsPlumbUtil.EventGenerator ]);
+
+ var _newCanvas = function(params) {
+ var canvas = document.createElement("canvas");
+ params._jsPlumb.instance.appendElement(canvas, params.parent);
+ canvas.style.position = "absolute";
+ if (params["class"]) canvas.className = params["class"];
+ // set an id. if no id on the element and if uuid was supplied it
+ // will be used, otherwise we'll create one.
+ params._jsPlumb.instance.getId(canvas, params.uuid);
+ if (params.tooltip) canvas.setAttribute("title", params.tooltip);
+
+ return canvas;
+ };
+
+ var CanvasComponent = window.CanvasComponent = function(params) {
+ CanvasMouseAdapter.apply(this, arguments);
+
+ var displayElements = [ ];
+ this.getDisplayElements = function() { return displayElements; };
+ this.appendDisplayElement = function(el) { displayElements.push(el); };
+ };
+ jsPlumbUtil.extend(CanvasComponent, CanvasMouseAdapter);
+
+ var segmentMultipliers = [null, [1, -1], [1, 1], [-1, 1], [-1, -1] ];
+ var maybeMakeGradient = function(ctx, style, gradientFunction) {
+ if (style.gradient) {
+ var g = gradientFunction();
+ for ( var i = 0; i < style.gradient.stops.length; i++)
+ g.addColorStop(style.gradient.stops[i][0], style.gradient.stops[i][1]);
+ ctx.strokeStyle = g;
+ }
+ };
+ var segmentRenderer = function(segment, ctx, style, dx, dy) {
+ ({
+ "Straight":function(segment, ctx, style, dx, dy) {
+ var d = segment.params;
+ ctx.save();
+ maybeMakeGradient(ctx, style, function() { return ctx.createLinearGradient(d.x1, d.y1, d.x2, d.y2); });
+ ctx.beginPath();
+ ctx.translate(dx, dy);
+ if (style.dashstyle && style.dashstyle.split(" ").length === 2) {
+ // only a very simple dashed style is supported - having two values, which define the stroke length
+ // (as a multiple of the stroke width) and then the space length (also as a multiple of stroke width).
+ var ds = style.dashstyle.split(" ");
+ if (ds.length !== 2) ds = [2, 2];
+ var dss = [ ds[0] * style.lineWidth, ds[1] * style.lineWidth ],
+ m = (d.x2- d.x1) / (d.y2 - d.y1),
+ s = jsPlumbUtil.segment([d.x1, d.y1], [ d.x2, d.y2 ]),
+ sm = segmentMultipliers[s],
+ theta = Math.atan(m),
+ l = Math.sqrt(Math.pow(d.x2 - d.x1, 2) + Math.pow(d.y2 - d.y1, 2)),
+ repeats = Math.floor(l / (dss[0] + dss[1])),
+ curPos = [d.x1, d.y1];
+
+
+ // TODO: the question here is why could we not support this in all connector types? it's really
+ // just a case of going along and asking jsPlumb for the next point on the path a few times, until it
+ // reaches the end. every type of connector supports that method, after all. but right now its only the
+ // bezier connector that gives you back the new location on the path along with the x,y coordinates, which
+ // we would need. we'd start out at loc=0 and ask for the point along the path that is dss[0] pixels away.
+ // we then ask for the point that is (dss[0] + dss[1]) pixels away; and from that one we need not just the
+ // x,y but the location, cos we're gonna plug that location back in in order to find where that dash ends.
+ //
+ // it also strikes me that it should be trivial to support arbitrary dash styles (having more or less than two
+ // entries). you'd just iterate that array using a step size of 2, and generify the (rss[0] + rss[1])
+ // computation to be sum(rss[0]..rss[n]).
+
+ for (var i = 0; i < repeats; i++) {
+ ctx.moveTo(curPos[0], curPos[1]);
+
+ var nextEndX = curPos[0] + (Math.abs(Math.sin(theta) * dss[0]) * sm[0]),
+ nextEndY = curPos[1] + (Math.abs(Math.cos(theta) * dss[0]) * sm[1]),
+ nextStartX = curPos[0] + (Math.abs(Math.sin(theta) * (dss[0] + dss[1])) * sm[0]),
+ nextStartY = curPos[1] + (Math.abs(Math.cos(theta) * (dss[0] + dss[1])) * sm[1]);
+
+ ctx.lineTo(nextEndX, nextEndY);
+ curPos = [nextStartX, nextStartY];
+ }
+
+ // now draw the last bit
+ ctx.moveTo(curPos[0], curPos[1]);
+ ctx.lineTo(d.x2, d.y2);
+
+ }
+ else {
+ ctx.moveTo(d.x1, d.y1);
+ ctx.lineTo(d.x2, d.y2);
+ }
+
+ ctx.stroke();
+
+ ctx.restore();
+ },
+ "Bezier":function(segment, ctx, style, dx, dy) {
+ var d = segment.params;
+ ctx.save();
+ maybeMakeGradient(ctx, style, function() { return ctx.createLinearGradient(d.x2 + dx, d.y2 + dy, d.x1 + dx, d.y1 + dy); });
+ ctx.beginPath();
+ ctx.translate(dx, dy);
+ ctx.moveTo(d.x1, d.y1);
+ ctx.bezierCurveTo(d.cp1x, d.cp1y, d.cp2x, d.cp2y, d.x2, d.y2);
+ ctx.stroke();
+ ctx.restore();
+ },
+ "Arc":function(segment, ctx, style, dx, dy) {
+ var d = segment.params;
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(dx, dy);
+ ctx.arc(d.cx, d.cy, d.r, segment.startAngle, segment.endAngle, d.ac);
+ ctx.stroke();
+ ctx.restore();
+ }
+ })[segment.type](segment, ctx, style, dx, dy);
+ };
+
+ /**
+ * Class:CanvasConnector
+ * Superclass for Canvas Connector renderers.
+ */
+ var CanvasConnector = jsPlumb.ConnectorRenderers.canvas = function(params) {
+ CanvasComponent.apply(this, arguments);
+
+ var _paintOneStyle = function(aStyle, dx, dy) {
+ this.ctx.save();
+ jsPlumb.extend(this.ctx, aStyle);
+
+ var segments = this.getSegments();
+ for (var i = 0; i < segments.length; i++) {
+ segmentRenderer(segments[i], this.ctx, aStyle, dx, dy);
+ }
+ this.ctx.restore();
+ }.bind(this);
+
+ var clazz = this._jsPlumb.instance.connectorClass + " " + (params.cssClass || "");
+ this.canvas = _newCanvas({
+ "class":clazz,
+ _jsPlumb:this._jsPlumb,
+ parent:params.parent
+ });
+ this.ctx = this.canvas.getContext("2d");
+
+ this.appendDisplayElement(this.canvas);
+
+ this.paint = function(style, anchor, extents) {
+ if (style != null) {
+
+ var xy = [ this.x, this.y ], wh = [ this.w, this.h ], p,
+ dx = 0, dy = 0;
+
+ if (extents != null) {
+ if (extents.xmin < 0) {
+ xy[0] += extents.xmin;
+ dx = -extents.xmin;
+ }
+ if (extents.ymin < 0) {
+ xy[1] += extents.ymin;
+ dy = -extents.ymin;
+ }
+ wh[0] = extents.xmax + ((extents.xmin < 0) ? -extents.xmin : 0);
+ wh[1] = extents.ymax + ((extents.ymin < 0) ? -extents.ymin : 0);
+ }
+
+ this.translateX = dx;
+ this.translateY = dy;
+
+ jsPlumbUtil.sizeElement(this.canvas, xy[0], xy[1], wh[0], wh[1]);
+
+ if (style.outlineColor != null) {
+ var outlineWidth = style.outlineWidth || 1,
+ outlineStrokeWidth = style.lineWidth + (2 * outlineWidth),
+ outlineStyle = {
+ strokeStyle:style.outlineColor,
+ lineWidth:outlineStrokeWidth
+ };
+ _paintOneStyle(outlineStyle, dx, dy);
+ }
+ _paintOneStyle(style, dx, dy);
+ }
+ };
+ };
+ jsPlumbUtil.extend(CanvasConnector, CanvasComponent);
+
+
+ /**
+ * Class:CanvasEndpoint
+ * Superclass for Canvas Endpoint renderers.
+ */
+ var CanvasEndpoint = function(params) {
+ CanvasComponent.apply(this, arguments);
+ var clazz = this._jsPlumb.instance.endpointClass + " " + (params.cssClass || ""),
+ canvasParams = {
+ "class":clazz,
+ _jsPlumb:this._jsPlumb,
+ parent:params.parent,
+ tooltip:self.tooltip
+ };
+ this.canvas = _newCanvas(canvasParams);
+ this.ctx = this.canvas.getContext("2d");
+
+ this.appendDisplayElement(this.canvas);
+
+ this.paint = function(style, anchor, extents) {
+ jsPlumbUtil.sizeElement(this.canvas, this.x, this.y, this.w, this.h);
+ if (style.outlineColor != null) {
+ var outlineWidth = style.outlineWidth || 1,
+ outlineStrokeWidth = style.lineWidth + (2 * outlineWidth);
+ var outlineStyle = {
+ strokeStyle:style.outlineColor,
+ lineWidth:outlineStrokeWidth
+ };
+ }
+
+ this._paint.apply(this, arguments);
+ };
+ };
+ jsPlumbUtil.extend(CanvasEndpoint, CanvasComponent);
+
+ jsPlumb.Endpoints.canvas.Dot = function(params) {
+ jsPlumb.Endpoints.Dot.apply(this, arguments);
+ CanvasEndpoint.apply(this, arguments);
+ var self = this,
+ parseValue = function(value) {
+ try { return parseInt(value, 10); }
+ catch(e) {
+ if (value.substring(value.length - 1) == '%')
+ return parseInt(value.substring(0, value - 1), 10);
+ }
+ },
+ calculateAdjustments = function(gradient) {
+ var offsetAdjustment = self.defaultOffset, innerRadius = self.defaultInnerRadius;
+ if (gradient.offset) offsetAdjustment = parseValue(gradient.offset);
+ if (gradient.innerRadius) innerRadius = parseValue(gradient.innerRadius);
+ return [offsetAdjustment, innerRadius];
+ };
+ this._paint = function(style) {
+ if (style != null) {
+ var ctx = self.canvas.getContext('2d'),
+ orientation = params.endpoint.anchor.getOrientation(params.endpoint);
+
+ jsPlumb.extend(ctx, style);
+ if (style.gradient) {
+ var adjustments = calculateAdjustments(style.gradient),
+ yAdjust = orientation[1] == 1 ? adjustments[0] * -1 : adjustments[0],
+ xAdjust = orientation[0] == 1 ? adjustments[0] * -1: adjustments[0],
+ g = ctx.createRadialGradient(self.radius, self.radius, self.radius, self.radius + xAdjust, self.radius + yAdjust, adjustments[1]);
+ for (var i = 0; i < style.gradient.stops.length; i++)
+ g.addColorStop(style.gradient.stops[i][0], style.gradient.stops[i][1]);
+ ctx.fillStyle = g;
+ }
+ ctx.beginPath();
+ //ctx.translate(dx, dy);
+ ctx.arc(self.radius, self.radius, self.radius, 0, Math.PI*2, true);
+ ctx.closePath();
+ if (style.fillStyle || style.gradient) ctx.fill();
+ if (style.strokeStyle) ctx.stroke();
+ }
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.canvas.Dot, [ jsPlumb.Endpoints.Dot, CanvasEndpoint ]);
+
+ jsPlumb.Endpoints.canvas.Rectangle = function(params) {
+
+ var self = this;
+ jsPlumb.Endpoints.Rectangle.apply(this, arguments);
+ CanvasEndpoint.apply(this, arguments);
+
+ this._paint = function(style) {
+
+ var ctx = self.canvas.getContext("2d"),
+ orientation = params.endpoint.anchor.getOrientation(params.endpoint);
+
+ jsPlumb.extend(ctx, style);
+
+ /* canvas gradient */
+ if (style.gradient) {
+ // first figure out which direction to run the gradient in (it depends on the orientation of the anchors)
+ var y1 = orientation[1] == 1 ? self.h : orientation[1] === 0 ? self.h / 2 : 0;
+ var y2 = orientation[1] == -1 ? self.h : orientation[1] === 0 ? self.h / 2 : 0;
+ var x1 = orientation[0] == 1 ? self.w : orientation[0] === 0 ? self.w / 2 : 0;
+ var x2 = orientation[0] == -1 ? self.w : orientation[0] === 0 ? self.w / 2 : 0;
+ var g = ctx.createLinearGradient(x1,y1,x2,y2);
+ for (var i = 0; i < style.gradient.stops.length; i++)
+ g.addColorStop(style.gradient.stops[i][0], style.gradient.stops[i][1]);
+ ctx.fillStyle = g;
+ }
+
+ ctx.beginPath();
+ ctx.rect(0, 0, self.w, self.h);
+ ctx.closePath();
+ if (style.fillStyle || style.gradient) ctx.fill();
+ if (style.strokeStyle) ctx.stroke();
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.canvas.Rectangle, [ jsPlumb.Endpoints.Rectangle, CanvasEndpoint ]);
+
+ jsPlumb.Endpoints.canvas.Triangle = function(params) {
+
+ var self = this;
+ jsPlumb.Endpoints.Triangle.apply(this, arguments);
+ CanvasEndpoint.apply(this, arguments);
+
+ this._paint = function(style) {
+ var ctx = self.canvas.getContext('2d'),
+ offsetX = 0, offsetY = 0, angle = 0,
+ orientation = params.endpoint.anchor.getOrientation(params.endpoint);
+
+ if( orientation[0] == 1 ) {
+ offsetX = self.width;
+ offsetY = self.height;
+ angle = 180;
+ }
+ if( orientation[1] == -1 ) {
+ offsetX = self.width;
+ angle = 90;
+ }
+ if( orientation[1] == 1 ) {
+ offsetY = self.height;
+ angle = -90;
+ }
+
+ ctx.fillStyle = style.fillStyle;
+
+ ctx.translate(offsetX, offsetY);
+ ctx.rotate(angle * Math.PI/180);
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(self.width/2, self.height/2);
+ ctx.lineTo(0, self.height);
+ ctx.closePath();
+ if (style.fillStyle || style.gradient) ctx.fill();
+ if (style.strokeStyle) ctx.stroke();
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.canvas.Triangle, [ jsPlumb.Endpoints.Triangle, CanvasEndpoint ]);
+
+ /*
+ * Canvas Image Endpoint: uses the default version, which creates an <img> tag.
+ */
+ jsPlumb.Endpoints.canvas.Image = jsPlumb.Endpoints.Image;
+
+ /*
+ * Blank endpoint in all renderers is just the default Blank endpoint.
+ */
+ jsPlumb.Endpoints.canvas.Blank = jsPlumb.Endpoints.Blank;
+
+ /*
+ * Canvas Bezier Connector. Draws a Bezier curve onto a Canvas element.
+ *
+ jsPlumb.Connectors.canvas.Bezier = function() {
+ jsPlumb.Connectors.Bezier.apply(this, arguments);
+ CanvasConnector.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.canvas.Bezier, [ jsPlumb.Connectors.Bezier, CanvasConnector ]);
+
+ /*
+ * Canvas straight line Connector. Draws a straight line onto a Canvas element.
+ *
+ jsPlumb.Connectors.canvas.Straight = function() {
+ jsPlumb.Connectors.Straight.apply(this, arguments);
+ CanvasConnector.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.canvas.Straight, [ jsPlumb.Connectors.Straight, CanvasConnector ]);
+
+ jsPlumb.Connectors.canvas.Flowchart = function() {
+ jsPlumb.Connectors.Flowchart.apply(this, arguments);
+ CanvasConnector.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.canvas.Flowchart, [ jsPlumb.Connectors.Flowchart, CanvasConnector ]);
+
+ */
+// ********************************* END OF CANVAS RENDERERS *******************************************************************
+
+ jsPlumb.Overlays.canvas.Label = jsPlumb.Overlays.Label;
+ jsPlumb.Overlays.canvas.Custom = jsPlumb.Overlays.Custom;
+
+ /**
+ * a placeholder right now, really just exists to mirror the fact that there are SVG and VML versions of this.
+ */
+ var CanvasOverlay = function() {
+ jsPlumb.jsPlumbUIComponent.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(CanvasOverlay, jsPlumb.jsPlumbUIComponent);
+
+ var AbstractCanvasArrowOverlay = function(superclass, originalArgs) {
+ superclass.apply(this, originalArgs);
+ CanvasOverlay.apply(this, originalArgs);
+ this.paint = function(params, containerExtents) {
+ var ctx = params.component.ctx, d = params.d;
+
+ if (d) {
+ ctx.save();
+ ctx.lineWidth = params.lineWidth;
+ ctx.beginPath();
+ ctx.translate(params.component.translateX, params.component.translateY);
+ ctx.moveTo(d.hxy.x, d.hxy.y);
+ ctx.lineTo(d.tail[0].x, d.tail[0].y);
+ ctx.lineTo(d.cxy.x, d.cxy.y);
+ ctx.lineTo(d.tail[1].x, d.tail[1].y);
+ ctx.lineTo(d.hxy.x, d.hxy.y);
+ ctx.closePath();
+
+ if (params.strokeStyle) {
+ ctx.strokeStyle = params.strokeStyle;
+ ctx.stroke();
+ }
+ if (params.fillStyle) {
+ ctx.fillStyle = params.fillStyle;
+ ctx.fill();
+ }
+ ctx.restore();
+ }
+ };
+ };
+
+ jsPlumb.Overlays.canvas.Arrow = function() {
+ AbstractCanvasArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.canvas.Arrow, [ jsPlumb.Overlays.Arrow, CanvasOverlay ] );
+
+ jsPlumb.Overlays.canvas.PlainArrow = function() {
+ AbstractCanvasArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.canvas.PlainArrow, [ jsPlumb.Overlays.PlainArrow, CanvasOverlay ] );
+
+ jsPlumb.Overlays.canvas.Diamond = function() {
+ AbstractCanvasArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.canvas.Diamond, [ jsPlumb.Overlays.Diamond, CanvasOverlay ] );
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the SVG renderers.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+/**
+ * SVG support for jsPlumb.
+ *
+ * things to investigate:
+ *
+ * gradients: https://developer.mozilla.org/en/svg_in_html_introduction
+ * css:http://tutorials.jenkov.com/svg/svg-and-css.html
+ * text on a path: http://www.w3.org/TR/SVG/text.html#TextOnAPath
+ * pointer events: https://developer.mozilla.org/en/css/pointer-events
+ *
+ * IE9 hover jquery: http://forum.jquery.com/topic/1-6-2-broke-svg-hover-events
+ *
+ */
+;(function() {
+
+// ************************** SVG utility methods ********************************************
+
+ var svgAttributeMap = {
+ "joinstyle":"stroke-linejoin",
+ "stroke-linejoin":"stroke-linejoin",
+ "stroke-dashoffset":"stroke-dashoffset",
+ "stroke-linecap":"stroke-linecap"
+ },
+ STROKE_DASHARRAY = "stroke-dasharray",
+ DASHSTYLE = "dashstyle",
+ LINEAR_GRADIENT = "linearGradient",
+ RADIAL_GRADIENT = "radialGradient",
+ FILL = "fill",
+ STOP = "stop",
+ STROKE = "stroke",
+ STROKE_WIDTH = "stroke-width",
+ STYLE = "style",
+ NONE = "none",
+ JSPLUMB_GRADIENT = "jsplumb_gradient_",
+ LINE_WIDTH = "lineWidth",
+ ns = {
+ svg:"http://www.w3.org/2000/svg",
+ xhtml:"http://www.w3.org/1999/xhtml"
+ },
+ _attr = function(node, attributes) {
+ for (var i in attributes)
+ node.setAttribute(i, "" + attributes[i]);
+ },
+ _node = function(name, attributes) {
+ var n = document.createElementNS(ns.svg, name);
+ attributes = attributes || {};
+ attributes.version = "1.1";
+ attributes.xmlns = ns.xhtml;
+ _attr(n, attributes);
+ return n;
+ },
+ _pos = function(d) { return "position:absolute;left:" + d[0] + "px;top:" + d[1] + "px"; },
+ _clearGradient = function(parent) {
+ for (var i = 0; i < parent.childNodes.length; i++) {
+ if (parent.childNodes[i].tagName == LINEAR_GRADIENT || parent.childNodes[i].tagName == RADIAL_GRADIENT)
+ parent.removeChild(parent.childNodes[i]);
+ }
+ },
+ _updateGradient = function(parent, node, style, dimensions, uiComponent) {
+ var id = JSPLUMB_GRADIENT + uiComponent._jsPlumb.instance.idstamp();
+ // first clear out any existing gradient
+ _clearGradient(parent);
+ // this checks for an 'offset' property in the gradient, and in the absence of it, assumes
+ // we want a linear gradient. if it's there, we create a radial gradient.
+ // it is possible that a more explicit means of defining the gradient type would be
+ // better. relying on 'offset' means that we can never have a radial gradient that uses
+ // some default offset, for instance.
+ // issue 244 suggested the 'gradientUnits' attribute; without this, straight/flowchart connectors with gradients would
+ // not show gradients when the line was perfectly horizontal or vertical.
+ var g;
+ if (!style.gradient.offset) {
+ g = _node(LINEAR_GRADIENT, {id:id, gradientUnits:"userSpaceOnUse"});
+ }
+ else {
+ g = _node(RADIAL_GRADIENT, {
+ id:id
+ });
+ }
+
+ parent.appendChild(g);
+
+ // the svg radial gradient seems to treat stops in the reverse
+ // order to how canvas does it. so we want to keep all the maths the same, but
+ // iterate the actual style declarations in reverse order, if the x indexes are not in order.
+ for (var i = 0; i < style.gradient.stops.length; i++) {
+ var styleToUse = uiComponent.segment == 1 || uiComponent.segment == 2 ? i: style.gradient.stops.length - 1 - i,
+ stopColor = jsPlumbUtil.convertStyle(style.gradient.stops[styleToUse][1], true),
+ s = _node(STOP, {"offset":Math.floor(style.gradient.stops[i][0] * 100) + "%", "stop-color":stopColor});
+
+ g.appendChild(s);
+ }
+ var applyGradientTo = style.strokeStyle ? STROKE : FILL;
+ node.setAttribute(STYLE, applyGradientTo + ":url(#" + id + ")");
+ },
+ _applyStyles = function(parent, node, style, dimensions, uiComponent) {
+
+ if (style.gradient) {
+ _updateGradient(parent, node, style, dimensions, uiComponent);
+ }
+ else {
+ // make sure we clear any existing gradient
+ _clearGradient(parent);
+ node.setAttribute(STYLE, "");
+ }
+
+ node.setAttribute(FILL, style.fillStyle ? jsPlumbUtil.convertStyle(style.fillStyle, true) : NONE);
+ node.setAttribute(STROKE, style.strokeStyle ? jsPlumbUtil.convertStyle(style.strokeStyle, true) : NONE);
+ if (style.lineWidth) {
+ node.setAttribute(STROKE_WIDTH, style.lineWidth);
+ }
+
+ // in SVG there is a stroke-dasharray attribute we can set, and its syntax looks like
+ // the syntax in VML but is actually kind of nasty: values are given in the pixel
+ // coordinate space, whereas in VML they are multiples of the width of the stroked
+ // line, which makes a lot more sense. for that reason, jsPlumb is supporting both
+ // the native svg 'stroke-dasharray' attribute, and also the 'dashstyle' concept from
+ // VML, which will be the preferred method. the code below this converts a dashstyle
+ // attribute given in terms of stroke width into a pixel representation, by using the
+ // stroke's lineWidth.
+ if (style[DASHSTYLE] && style[LINE_WIDTH] && !style[STROKE_DASHARRAY]) {
+ var sep = style[DASHSTYLE].indexOf(",") == -1 ? " " : ",",
+ parts = style[DASHSTYLE].split(sep),
+ styleToUse = "";
+ parts.forEach(function(p) {
+ styleToUse += (Math.floor(p * style.lineWidth) + sep);
+ });
+ node.setAttribute(STROKE_DASHARRAY, styleToUse);
+ }
+ else if(style[STROKE_DASHARRAY]) {
+ node.setAttribute(STROKE_DASHARRAY, style[STROKE_DASHARRAY]);
+ }
+
+ // extra attributes such as join type, dash offset.
+ for (var i in svgAttributeMap) {
+ if (style[i]) {
+ node.setAttribute(svgAttributeMap[i], style[i]);
+ }
+ }
+ },
+ _decodeFont = function(f) {
+ var r = /([0-9].)(p[xt])\s(.*)/,
+ bits = f.match(r);
+
+ return {size:bits[1] + bits[2], font:bits[3]};
+ },
+ _classManip = function(el, add, clazz) {
+ var classesToAddOrRemove = clazz.split(" "),
+ className = el.className,
+ curClasses = className.baseVal.split(" ");
+
+ for (var i = 0; i < classesToAddOrRemove.length; i++) {
+ if (add) {
+ if (curClasses.indexOf(classesToAddOrRemove[i]) == -1)
+ curClasses.push(classesToAddOrRemove[i]);
+ }
+ else {
+ var idx = curClasses.indexOf(classesToAddOrRemove[i]);
+ if (idx != -1)
+ curClasses.splice(idx, 1);
+ }
+ }
+
+ el.className.baseVal = curClasses.join(" ");
+ },
+ _addClass = function(el, clazz) { _classManip(el, true, clazz); },
+ _removeClass = function(el, clazz) { _classManip(el, false, clazz); },
+ _appendAtIndex = function(svg, path, idx) {
+ if (svg.childNodes.length > idx) {
+ svg.insertBefore(path, svg.childNodes[idx]);
+ }
+ else svg.appendChild(path);
+ };
+
+ /**
+ utility methods for other objects to use.
+ */
+ jsPlumbUtil.svg = {
+ addClass:_addClass,
+ removeClass:_removeClass,
+ node:_node,
+ attr:_attr,
+ pos:_pos
+ };
+
+ // ************************** / SVG utility methods ********************************************
+
+ /*
+ * Base class for SVG components.
+ */
+ var SvgComponent = function(params) {
+ var pointerEventsSpec = params.pointerEventsSpec || "all", renderer = {};
+
+ jsPlumb.jsPlumbUIComponent.apply(this, params.originalArgs);
+ this.canvas = null;this.path = null;this.svg = null;
+
+ var clazz = params.cssClass + " " + (params.originalArgs[0].cssClass || ""),
+ svgParams = {
+ "style":"",
+ "width":0,
+ "height":0,
+ "pointer-events":pointerEventsSpec,
+ "position":"absolute"
+ };
+ this.svg = _node("svg", svgParams);
+ if (params.useDivWrapper) {
+ this.canvas = document.createElement("div");
+ this.canvas.style.position = "absolute";
+ jsPlumbUtil.sizeElement(this.canvas,0,0,1,1);
+ this.canvas.className = clazz;
+ }
+ else {
+ _attr(this.svg, { "class":clazz });
+ this.canvas = this.svg;
+ }
+
+ params._jsPlumb.appendElement(this.canvas, params.originalArgs[0].parent);
+ if (params.useDivWrapper) this.canvas.appendChild(this.svg);
+
+ // TODO this displayElement stuff is common between all components, across all
+ // renderers. would be best moved to jsPlumbUIComponent.
+ var displayElements = [ this.canvas ];
+ this.getDisplayElements = function() {
+ return displayElements;
+ };
+
+ this.appendDisplayElement = function(el) {
+ displayElements.push(el);
+ };
+
+ this.paint = function(style, anchor, extents) {
+ if (style != null) {
+
+ var xy = [ this.x, this.y ], wh = [ this.w, this.h ], p;
+ if (extents != null) {
+ if (extents.xmin < 0) xy[0] += extents.xmin;
+ if (extents.ymin < 0) xy[1] += extents.ymin;
+ wh[0] = extents.xmax + ((extents.xmin < 0) ? -extents.xmin : 0);
+ wh[1] = extents.ymax + ((extents.ymin < 0) ? -extents.ymin : 0);
+ }
+
+ if (params.useDivWrapper) {
+ jsPlumbUtil.sizeElement(this.canvas, xy[0], xy[1], wh[0], wh[1]);
+ xy[0] = 0; xy[1] = 0;
+ p = _pos([ 0, 0 ]);
+ }
+ else
+ p = _pos([ xy[0], xy[1] ]);
+
+ renderer.paint.apply(this, arguments);
+
+ _attr(this.svg, {
+ "style":p,
+ "width": wh[0],
+ "height": wh[1]
+ });
+ }
+ };
+
+ return {
+ renderer:renderer
+ };
+ };
+ jsPlumbUtil.extend(SvgComponent, jsPlumb.jsPlumbUIComponent, {
+ cleanup:function() {
+ jsPlumbUtil.removeElement(this.canvas);
+ this.svg = null;
+ this.canvas = null;
+ this.path = null;
+ }
+ });
+
+ /*
+ * Base class for SVG connectors.
+ */
+ var SvgConnector = jsPlumb.ConnectorRenderers.svg = function(params) {
+ var self = this,
+ _super = SvgComponent.apply(this, [ {
+ cssClass:params._jsPlumb.connectorClass,
+ originalArgs:arguments,
+ pointerEventsSpec:"none",
+ _jsPlumb:params._jsPlumb
+ } ]);
+
+ /*this.pointOnPath = function(location, absolute) {
+ if (!self.path) return [0,0];
+ var p = absolute ? location : location * self.path.getTotalLength();
+ return self.path.getPointAtLength(p);
+ };*/
+
+ _super.renderer.paint = function(style, anchor, extents) {
+
+ var segments = self.getSegments(), p = "", offset = [0,0];
+ if (extents.xmin < 0) offset[0] = -extents.xmin;
+ if (extents.ymin < 0) offset[1] = -extents.ymin;
+
+ // create path from segments.
+ for (var i = 0; i < segments.length; i++) {
+ p += jsPlumb.Segments.svg.SegmentRenderer.getPath(segments[i]);
+ p += " ";
+ }
+
+ var a = {
+ d:p,
+ transform:"translate(" + offset[0] + "," + offset[1] + ")",
+ "pointer-events":params["pointer-events"] || "visibleStroke"
+ },
+ outlineStyle = null,
+ d = [self.x,self.y,self.w,self.h];
+
+ // outline style. actually means drawing an svg object underneath the main one.
+ if (style.outlineColor) {
+ var outlineWidth = style.outlineWidth || 1,
+ outlineStrokeWidth = style.lineWidth + (2 * outlineWidth);
+ outlineStyle = jsPlumb.CurrentLibrary.extend({}, style);
+ outlineStyle.strokeStyle = jsPlumbUtil.convertStyle(style.outlineColor);
+ outlineStyle.lineWidth = outlineStrokeWidth;
+
+ if (self.bgPath == null) {
+ self.bgPath = _node("path", a);
+ _appendAtIndex(self.svg, self.bgPath, 0);
+ self.attachListeners(self.bgPath, self);
+ }
+ else {
+ _attr(self.bgPath, a);
+ }
+
+ _applyStyles(self.svg, self.bgPath, outlineStyle, d, self);
+ }
+
+ if (self.path == null) {
+ self.path = _node("path", a);
+ _appendAtIndex(self.svg, self.path, style.outlineColor ? 1 : 0);
+ self.attachListeners(self.path, self);
+ }
+ else {
+ _attr(self.path, a);
+ }
+
+ _applyStyles(self.svg, self.path, style, d, self);
+ };
+
+ this.reattachListeners = function() {
+ if (this.bgPath) this.reattachListenersForElement(this.bgPath, this);
+ if (this.path) this.reattachListenersForElement(this.path, this);
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.ConnectorRenderers.svg, SvgComponent);
+
+// ******************************* svg segment renderer *****************************************************
+
+ jsPlumb.Segments.svg = {
+ SegmentRenderer : {
+ getPath : function(segment) {
+ return ({
+ "Straight":function() {
+ var d = segment.getCoordinates();
+ return "M " + d.x1 + " " + d.y1 + " L " + d.x2 + " " + d.y2;
+ },
+ "Bezier":function() {
+ var d = segment.params;
+ return "M " + d.x1 + " " + d.y1 +
+ " C " + d.cp1x + " " + d.cp1y + " " + d.cp2x + " " + d.cp2y + " " + d.x2 + " " + d.y2;
+ },
+ "Arc":function() {
+ var d = segment.params,
+ laf = segment.sweep > Math.PI ? 1 : 0,
+ sf = segment.anticlockwise ? 0 : 1;
+
+ return "M" + segment.x1 + " " + segment.y1 + " A " + segment.radius + " " + d.r + " 0 " + laf + "," + sf + " " + segment.x2 + " " + segment.y2;
+ }
+ })[segment.type]();
+ }
+ }
+ };
+
+// ******************************* /svg segments *****************************************************
+
+ /*
+ * Base class for SVG endpoints.
+ */
+ var SvgEndpoint = window.SvgEndpoint = function(params) {
+ var _super = SvgComponent.apply(this, [ {
+ cssClass:params._jsPlumb.endpointClass,
+ originalArgs:arguments,
+ pointerEventsSpec:"all",
+ useDivWrapper:true,
+ _jsPlumb:params._jsPlumb
+ } ]);
+
+ _super.renderer.paint = function(style) {
+ var s = jsPlumb.extend({}, style);
+ if (s.outlineColor) {
+ s.strokeWidth = s.outlineWidth;
+ s.strokeStyle = jsPlumbUtil.convertStyle(s.outlineColor, true);
+ }
+
+ if (this.node == null) {
+ this.node = this.makeNode(s);
+ this.svg.appendChild(this.node);
+ this.attachListeners(this.node, this);
+ }
+ else if (this.updateNode != null) {
+ this.updateNode(this.node);
+ }
+ _applyStyles(this.svg, this.node, s, [ this.x, this.y, this.w, this.h ], this);
+ _pos(this.node, [ this.x, this.y ]);
+ }.bind(this);
+
+ };
+ jsPlumbUtil.extend(SvgEndpoint, SvgComponent, {
+ reattachListeners : function() {
+ if (this.node) this.reattachListenersForElement(this.node, this);
+ }
+ });
+
+ /*
+ * SVG Dot Endpoint
+ */
+ jsPlumb.Endpoints.svg.Dot = function() {
+ jsPlumb.Endpoints.Dot.apply(this, arguments);
+ SvgEndpoint.apply(this, arguments);
+ this.makeNode = function(style) {
+ return _node("circle", {
+ "cx" : this.w / 2,
+ "cy" : this.h / 2,
+ "r" : this.radius
+ });
+ };
+ this.updateNode = function(node) {
+ _attr(node, {
+ "cx":this.w / 2,
+ "cy":this.h / 2,
+ "r":this.radius
+ });
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.svg.Dot, [jsPlumb.Endpoints.Dot, SvgEndpoint]);
+
+ /*
+ * SVG Rectangle Endpoint
+ */
+ jsPlumb.Endpoints.svg.Rectangle = function() {
+ jsPlumb.Endpoints.Rectangle.apply(this, arguments);
+ SvgEndpoint.apply(this, arguments);
+ this.makeNode = function(style) {
+ return _node("rect", {
+ "width" : this.w,
+ "height" : this.h
+ });
+ };
+ this.updateNode = function(node) {
+ _attr(node, {
+ "width":this.w,
+ "height":this.h
+ });
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.svg.Rectangle, [jsPlumb.Endpoints.Rectangle, SvgEndpoint]);
+
+ /*
+ * SVG Image Endpoint is the default image endpoint.
+ */
+ jsPlumb.Endpoints.svg.Image = jsPlumb.Endpoints.Image;
+ /*
+ * Blank endpoint in svg renderer is the default Blank endpoint.
+ */
+ jsPlumb.Endpoints.svg.Blank = jsPlumb.Endpoints.Blank;
+ /*
+ * Label overlay in svg renderer is the default Label overlay.
+ */
+ jsPlumb.Overlays.svg.Label = jsPlumb.Overlays.Label;
+ /*
+ * Custom overlay in svg renderer is the default Custom overlay.
+ */
+ jsPlumb.Overlays.svg.Custom = jsPlumb.Overlays.Custom;
+
+ var AbstractSvgArrowOverlay = function(superclass, originalArgs) {
+ superclass.apply(this, originalArgs);
+ jsPlumb.jsPlumbUIComponent.apply(this, originalArgs);
+ this.isAppendedAtTopLevel = false;
+ var self = this;
+ this.path = null;
+ this.paint = function(params, containerExtents) {
+ // only draws on connections, not endpoints.
+ if (params.component.svg && containerExtents) {
+ if (this.path == null) {
+ this.path = _node("path", {
+ "pointer-events":"all"
+ });
+ params.component.svg.appendChild(this.path);
+
+ this.attachListeners(this.path, params.component);
+ this.attachListeners(this.path, this);
+ }
+ var clazz = originalArgs && (originalArgs.length == 1) ? (originalArgs[0].cssClass || "") : "",
+ offset = [0,0];
+
+ if (containerExtents.xmin < 0) offset[0] = -containerExtents.xmin;
+ if (containerExtents.ymin < 0) offset[1] = -containerExtents.ymin;
+
+ _attr(this.path, {
+ "d" : makePath(params.d),
+ "class" : clazz,
+ stroke : params.strokeStyle ? params.strokeStyle : null,
+ fill : params.fillStyle ? params.fillStyle : null,
+ transform : "translate(" + offset[0] + "," + offset[1] + ")"
+ });
+ }
+ };
+ var makePath = function(d) {
+ return "M" + d.hxy.x + "," + d.hxy.y +
+ " L" + d.tail[0].x + "," + d.tail[0].y +
+ " L" + d.cxy.x + "," + d.cxy.y +
+ " L" + d.tail[1].x + "," + d.tail[1].y +
+ " L" + d.hxy.x + "," + d.hxy.y;
+ };
+ this.reattachListeners = function() {
+ if (this.path) this.reattachListenersForElement(this.path, this);
+ };
+ };
+ jsPlumbUtil.extend(AbstractSvgArrowOverlay, jsPlumb.jsPlumbUIComponent, {
+ cleanup : function() {
+ if (this.path != null) jsPlumb.CurrentLibrary.removeElement(this.path);
+ }
+ });
+
+ jsPlumb.Overlays.svg.Arrow = function() {
+ AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.svg.Arrow, [ jsPlumb.Overlays.Arrow, AbstractSvgArrowOverlay ]);
+
+ jsPlumb.Overlays.svg.PlainArrow = function() {
+ AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.svg.PlainArrow, [ jsPlumb.Overlays.PlainArrow, AbstractSvgArrowOverlay ]);
+
+ jsPlumb.Overlays.svg.Diamond = function() {
+ AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.svg.Diamond, [ jsPlumb.Overlays.Diamond, AbstractSvgArrowOverlay ]);
+
+ // a test
+ jsPlumb.Overlays.svg.GuideLines = function() {
+ var path = null, self = this, p1_1, p1_2;
+ jsPlumb.Overlays.GuideLines.apply(this, arguments);
+ this.paint = function(params, containerExtents) {
+ if (path == null) {
+ path = _node("path");
+ params.connector.svg.appendChild(path);
+ self.attachListeners(path, params.connector);
+ self.attachListeners(path, self);
+
+ p1_1 = _node("path");
+ params.connector.svg.appendChild(p1_1);
+ self.attachListeners(p1_1, params.connector);
+ self.attachListeners(p1_1, self);
+
+ p1_2 = _node("path");
+ params.connector.svg.appendChild(p1_2);
+ self.attachListeners(p1_2, params.connector);
+ self.attachListeners(p1_2, self);
+ }
+
+ var offset =[0,0];
+ if (containerExtents.xmin < 0) offset[0] = -containerExtents.xmin;
+ if (containerExtents.ymin < 0) offset[1] = -containerExtents.ymin;
+
+ _attr(path, {
+ "d" : makePath(params.head, params.tail),
+ stroke : "red",
+ fill : null,
+ transform:"translate(" + offset[0] + "," + offset[1] + ")"
+ });
+
+ _attr(p1_1, {
+ "d" : makePath(params.tailLine[0], params.tailLine[1]),
+ stroke : "blue",
+ fill : null,
+ transform:"translate(" + offset[0] + "," + offset[1] + ")"
+ });
+
+ _attr(p1_2, {
+ "d" : makePath(params.headLine[0], params.headLine[1]),
+ stroke : "green",
+ fill : null,
+ transform:"translate(" + offset[0] + "," + offset[1] + ")"
+ });
+ };
+
+ var makePath = function(d1, d2) {
+ return "M " + d1.x + "," + d1.y +
+ " L" + d2.x + "," + d2.y;
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.svg.GuideLines, jsPlumb.Overlays.GuideLines);
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the VML renderers.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ // http://ajaxian.com/archives/the-vml-changes-in-ie-8
+ // http://www.nczonline.net/blog/2010/01/19/internet-explorer-8-document-and-b…
+ // http://www.louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-…
+
+ var vmlAttributeMap = {
+ "stroke-linejoin":"joinstyle",
+ "joinstyle":"joinstyle",
+ "endcap":"endcap",
+ "miterlimit":"miterlimit"
+ },
+ jsPlumbStylesheet = null;
+
+ if (document.createStyleSheet && document.namespaces) {
+
+ var ruleClasses = [
+ ".jsplumb_vml", "jsplumb\\:textbox", "jsplumb\\:oval", "jsplumb\\:rect",
+ "jsplumb\\:stroke", "jsplumb\\:shape", "jsplumb\\:group"
+ ],
+ rule = "behavior:url(#default#VML);position:absolute;";
+
+ jsPlumbStylesheet = document.createStyleSheet();
+
+ for (var i = 0; i < ruleClasses.length; i++)
+ jsPlumbStylesheet.addRule(ruleClasses[i], rule);
+
+ // in this page it is also mentioned that IE requires the extra arg to the namespace
+ // http://www.louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-…
+ // but someone commented saying they didn't need it, and it seems jsPlumb doesnt need it either.
+ // var iev = document.documentMode;
+ //if (!iev || iev < 8)
+ document.namespaces.add("jsplumb", "urn:schemas-microsoft-com:vml");
+ //else
+ // document.namespaces.add("jsplumb", "urn:schemas-microsoft-com:vml", "#default#VML");
+ }
+
+ jsPlumb.vml = {};
+
+ var scale = 1000,
+
+ _groupMap = {},
+ _getGroup = function(container, connectorClass) {
+ var id = jsPlumb.getId(container),
+ g = _groupMap[id];
+ if(!g) {
+ g = _node("group", [0,0,scale, scale], {"class":connectorClass});
+ //g.style.position=absolute;
+ //g["coordsize"] = "1000,1000";
+ g.style.backgroundColor="red";
+ _groupMap[id] = g;
+ //jsPlumb.appendElement(g, container); // todo if this gets reinstated, remember to use the current jsplumb instance.
+ //jsPlumb.CurrentLibrary.getDOMElement(container).appendChild(g);
+ //document.body.appendChild(g);
+ }
+ return g;
+ },
+ _atts = function(o, atts) {
+ for (var i in atts) {
+ // IE8 fix: setattribute does not work after an element has been added to the dom!
+ // http://www.louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-…
+ //o.setAttribute(i, atts[i]);
+
+ /*There is an additional problem when accessing VML elements by using get/setAttribute. The simple solution is following:
+
+ if (document.documentMode==8) {
+ ele.opacity=1;
+ } else {
+ ele.setAttribute(‘opacity’,1);
+ }
+ */
+
+ o[i] = atts[i];
+ }
+ },
+ _node = function(name, d, atts, parent, _jsPlumb, deferToJsPlumbContainer) {
+ atts = atts || {};
+ var o = document.createElement("jsplumb:" + name);
+ if (deferToJsPlumbContainer)
+ _jsPlumb.appendElement(o, parent);
+ else
+ jsPlumb.CurrentLibrary.appendElement(o, parent);
+ o.className = (atts["class"] ? atts["class"] + " " : "") + "jsplumb_vml";
+ _pos(o, d);
+ _atts(o, atts);
+ return o;
+ },
+ _pos = function(o,d, zIndex) {
+ o.style.left = d[0] + "px";
+ o.style.top = d[1] + "px";
+ o.style.width= d[2] + "px";
+ o.style.height= d[3] + "px";
+ o.style.position = "absolute";
+ if (zIndex)
+ o.style.zIndex = zIndex;
+ },
+ _conv = jsPlumb.vml.convertValue = function(v) {
+ return Math.floor(v * scale);
+ },
+ // tests if the given style is "transparent" and then sets the appropriate opacity node to 0 if so,
+ // or 1 if not. TODO in the future, support variable opacity.
+ _maybeSetOpacity = function(styleToWrite, styleToCheck, type, component) {
+ if ("transparent" === styleToCheck)
+ component.setOpacity(type, "0.0");
+ else
+ component.setOpacity(type, "1.0");
+ },
+ _applyStyles = function(node, style, component, _jsPlumb) {
+ var styleToWrite = {};
+ if (style.strokeStyle) {
+ styleToWrite.stroked = "true";
+ var strokeColor = jsPlumbUtil.convertStyle(style.strokeStyle, true);
+ styleToWrite.strokecolor = strokeColor;
+ _maybeSetOpacity(styleToWrite, strokeColor, "stroke", component);
+ styleToWrite.strokeweight = style.lineWidth + "px";
+ }
+ else styleToWrite.stroked = "false";
+
+ if (style.fillStyle) {
+ styleToWrite.filled = "true";
+ var fillColor = jsPlumbUtil.convertStyle(style.fillStyle, true);
+ styleToWrite.fillcolor = fillColor;
+ _maybeSetOpacity(styleToWrite, fillColor, "fill", component);
+ }
+ else styleToWrite.filled = "false";
+
+ if(style.dashstyle) {
+ if (component.strokeNode == null) {
+ component.strokeNode = _node("stroke", [0,0,0,0], { dashstyle:style.dashstyle }, node, _jsPlumb);
+ }
+ else
+ component.strokeNode.dashstyle = style.dashstyle;
+ }
+ else if (style["stroke-dasharray"] && style.lineWidth) {
+ var sep = style["stroke-dasharray"].indexOf(",") == -1 ? " " : ",",
+ parts = style["stroke-dasharray"].split(sep),
+ styleToUse = "";
+ for(var i = 0; i < parts.length; i++) {
+ styleToUse += (Math.floor(parts[i] / style.lineWidth) + sep);
+ }
+ if (component.strokeNode == null) {
+ component.strokeNode = _node("stroke", [0,0,0,0], { dashstyle:styleToUse }, node, _jsPlumb);
+ }
+ else
+ component.strokeNode.dashstyle = styleToUse;
+ }
+
+ _atts(node, styleToWrite);
+ },
+ /*
+ * Base class for Vml endpoints and connectors. Extends jsPlumbUIComponent.
+ */
+ VmlComponent = function() {
+ var self = this, renderer = {};
+ jsPlumb.jsPlumbUIComponent.apply(this, arguments);
+
+ this.opacityNodes = {
+ "stroke":null,
+ "fill":null
+ };
+ this.initOpacityNodes = function(vml) {
+ self.opacityNodes.stroke = _node("stroke", [0,0,1,1], {opacity:"0.0"}, vml, self._jsPlumb.instance);
+ self.opacityNodes.fill = _node("fill", [0,0,1,1], {opacity:"0.0"}, vml, self._jsPlumb.instance);
+ };
+ this.setOpacity = function(type, value) {
+ var node = self.opacityNodes[type];
+ if (node) node.opacity = "" + value;
+ };
+ var displayElements = [ ];
+ this.getDisplayElements = function() {
+ return displayElements;
+ };
+
+ this.appendDisplayElement = function(el, doNotAppendToCanvas) {
+ if (!doNotAppendToCanvas) self.canvas.parentNode.appendChild(el);
+ displayElements.push(el);
+ };
+ };
+ jsPlumbUtil.extend(VmlComponent, jsPlumb.jsPlumbUIComponent, {
+ cleanup:function() {
+ if (this.bgCanvas) jsPlumbUtil.removeElement(this.bgCanvas);
+ jsPlumbUtil.removeElement(this.canvas);
+ }
+ });
+
+ /*
+ * Base class for Vml connectors. extends VmlComponent.
+ */
+ var VmlConnector = jsPlumb.ConnectorRenderers.vml = function(params) {
+ this.strokeNode = null;
+ this.canvas = null;
+ VmlComponent.apply(this, arguments);
+ var clazz = this._jsPlumb.instance.connectorClass + (params.cssClass ? (" " + params.cssClass) : "");
+ this.paint = function(style) {
+ if (style !== null) {
+
+ // we need to be at least 1 pixel in each direction, because otherwise coordsize gets set to
+ // 0 and overlays cannot paint.
+ this.w = Math.max(this.w, 1);
+ this.h = Math.max(this.h, 1);
+
+ var segments = this.getSegments(), p = { "path":"" },
+ d = [this.x, this.y, this.w, this.h];
+
+ // create path from segments.
+ for (var i = 0; i < segments.length; i++) {
+ p.path += jsPlumb.Segments.vml.SegmentRenderer.getPath(segments[i]);
+ p.path += " ";
+ }
+
+ //*
+ if (style.outlineColor) {
+ var outlineWidth = style.outlineWidth || 1,
+ outlineStrokeWidth = style.lineWidth + (2 * outlineWidth),
+ outlineStyle = {
+ strokeStyle : jsPlumbUtil.convertStyle(style.outlineColor),
+ lineWidth : outlineStrokeWidth
+ };
+ for (var aa in vmlAttributeMap) outlineStyle[aa] = style[aa];
+
+ if (this.bgCanvas == null) {
+ p["class"] = clazz;
+ p.coordsize = (d[2] * scale) + "," + (d[3] * scale);
+ this.bgCanvas = _node("shape", d, p, params.parent, this._jsPlumb.instance, true);
+ _pos(this.bgCanvas, d);
+ this.appendDisplayElement(this.bgCanvas, true);
+ this.attachListeners(this.bgCanvas, this);
+ this.initOpacityNodes(this.bgCanvas, ["stroke"]);
+ }
+ else {
+ p.coordsize = (d[2] * scale) + "," + (d[3] * scale);
+ _pos(this.bgCanvas, d);
+ _atts(this.bgCanvas, p);
+ }
+
+ _applyStyles(this.bgCanvas, outlineStyle, this);
+ }
+ //*/
+
+ if (this.canvas == null) {
+ p["class"] = clazz;
+ p.coordsize = (d[2] * scale) + "," + (d[3] * scale);
+ this.canvas = _node("shape", d, p, params.parent, this._jsPlumb.instance, true);
+ //var group = _getGroup(params.parent); // test of append everything to a group
+ //group.appendChild(self.canvas); // sort of works but not exactly;
+ //params["_jsPlumb"].appendElement(self.canvas, params.parent); //before introduction of groups
+
+ this.appendDisplayElement(this.canvas, true);
+ this.attachListeners(this.canvas, this);
+ this.initOpacityNodes(this.canvas, ["stroke"]);
+ }
+ else {
+ p.coordsize = (d[2] * scale) + "," + (d[3] * scale);
+ _pos(this.canvas, d);
+ _atts(this.canvas, p);
+ }
+
+ _applyStyles(this.canvas, style, this, this._jsPlumb.instance);
+ }
+ };
+
+ };
+ jsPlumbUtil.extend(VmlConnector, VmlComponent, {
+ reattachListeners : function() {
+ if (this.canvas) this.reattachListenersForElement(this.canvas, this);
+ }
+ });
+
+ /*
+ *
+ * Base class for Vml Endpoints. extends VmlComponent.
+ *
+ */
+ var VmlEndpoint = window.VmlEndpoint = function(params) {
+ VmlComponent.apply(this, arguments);
+ this._jsPlumb.vml = null;//, opacityStrokeNode = null, opacityFillNode = null;
+ this.canvas = document.createElement("div");
+ this.canvas.style.position = "absolute";
+ this._jsPlumb.clazz = this._jsPlumb.instance.endpointClass + (params.cssClass ? (" " + params.cssClass) : "");
+
+ // TODO vml endpoint adds class to VML at constructor time. but the addClass method adds VML
+ // to the enclosing DIV. what to do? seems like it would be better to just target the div.
+ // HOWEVER...vml connection has no containing div. why not? it feels like it should.
+
+ //var group = _getGroup(params.parent);
+ //group.appendChild(self.canvas);
+ params._jsPlumb.appendElement(this.canvas, params.parent);
+
+ this.paint = function(style, anchor) {
+ var p = { }, vml = this._jsPlumb.vml;
+
+ jsPlumbUtil.sizeElement(this.canvas, this.x, this.y, this.w, this.h);
+ if (this._jsPlumb.vml == null) {
+ p["class"] = this._jsPlumb.clazz;
+ vml = this._jsPlumb.vml = this.getVml([0,0, this.w, this.h], p, anchor, this.canvas, this._jsPlumb.instance);
+ this.attachListeners(vml, this);
+
+ this.appendDisplayElement(vml, true);
+ this.appendDisplayElement(this.canvas, true);
+
+ this.initOpacityNodes(vml, ["fill"]);
+ }
+ else {
+ _pos(vml, [0,0, this.w, this.h]);
+ _atts(vml, p);
+ }
+
+ _applyStyles(vml, style, this);
+ };
+ };
+ jsPlumbUtil.extend(VmlEndpoint, VmlComponent, {
+ reattachListeners : function() {
+ if (this._jsPlumb.vml) this.reattachListenersForElement(this._jsPlumb.vml, this);
+ }
+ });
+
+// ******************************* vml segments *****************************************************
+
+ jsPlumb.Segments.vml = {
+ SegmentRenderer : {
+ getPath : function(segment) {
+ return ({
+ "Straight":function(segment) {
+ var d = segment.params;
+ return "m" + _conv(d.x1) + "," + _conv(d.y1) + " l" + _conv(d.x2) + "," + _conv(d.y2) + " e";
+ },
+ "Bezier":function(segment) {
+ var d = segment.params;
+ return "m" + _conv(d.x1) + "," + _conv(d.y1) +
+ " c" + _conv(d.cp1x) + "," + _conv(d.cp1y) + "," + _conv(d.cp2x) + "," + _conv(d.cp2y) + "," + _conv(d.x2) + "," + _conv(d.y2) + " e";
+ },
+ "Arc":function(segment) {
+ var d = segment.params,
+ xmin = Math.min(d.x1, d.x2),
+ xmax = Math.max(d.x1, d.x2),
+ ymin = Math.min(d.y1, d.y2),
+ ymax = Math.max(d.y1, d.y2),
+ sf = segment.anticlockwise ? 1 : 0,
+ pathType = (segment.anticlockwise ? "at " : "wa "),
+ makePosString = function() {
+ var xy = [
+ null,
+ [ function() { return [xmin, ymin ];}, function() { return [xmin - d.r, ymin - d.r ];}],
+ [ function() { return [xmin - d.r, ymin ];}, function() { return [xmin, ymin - d.r ];}],
+ [ function() { return [xmin - d.r, ymin - d.r ];}, function() { return [xmin, ymin ];}],
+ [ function() { return [xmin, ymin - d.r ];}, function() { return [xmin - d.r, ymin ];}]
+ ][segment.segment][sf]();
+
+ return _conv(xy[0]) + "," + _conv(xy[1]) + "," + _conv(xy[0] + (2*d.r)) + "," + _conv(xy[1] + (2*d.r));
+ };
+
+
+ return pathType + makePosString() + "," + _conv(d.x1) + "," + _conv(d.y1) + "," + _conv(d.x2) + "," + _conv(d.y2) + " e";
+ }
+
+ })[segment.type](segment);
+ }
+ }
+ };
+
+// ******************************* /vml segments *****************************************************
+
+// ******************************* vml endpoints *****************************************************
+
+ jsPlumb.Endpoints.vml.Dot = function() {
+ jsPlumb.Endpoints.Dot.apply(this, arguments);
+ VmlEndpoint.apply(this, arguments);
+ this.getVml = function(d, atts, anchor, parent, _jsPlumb) { return _node("oval", d, atts, parent, _jsPlumb); };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.vml.Dot, VmlEndpoint);
+
+ jsPlumb.Endpoints.vml.Rectangle = function() {
+ jsPlumb.Endpoints.Rectangle.apply(this, arguments);
+ VmlEndpoint.apply(this, arguments);
+ this.getVml = function(d, atts, anchor, parent, _jsPlumb) { return _node("rect", d, atts, parent, _jsPlumb); };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.vml.Rectangle, VmlEndpoint);
+
+ /*
+ * VML Image Endpoint is the same as the default image endpoint.
+ */
+ jsPlumb.Endpoints.vml.Image = jsPlumb.Endpoints.Image;
+
+ /**
+ * placeholder for Blank endpoint in vml renderer.
+ */
+ jsPlumb.Endpoints.vml.Blank = jsPlumb.Endpoints.Blank;
+
+// ******************************* /vml endpoints *****************************************************
+
+// ******************************* vml overlays *****************************************************
+
+ /**
+ * VML Label renderer. uses the default label renderer (which adds an element to the DOM)
+ */
+ jsPlumb.Overlays.vml.Label = jsPlumb.Overlays.Label;
+
+ /**
+ * VML Custom renderer. uses the default Custom renderer (which adds an element to the DOM)
+ */
+ jsPlumb.Overlays.vml.Custom = jsPlumb.Overlays.Custom;
+
+ /**
+ * Abstract VML arrow superclass
+ */
+ var AbstractVmlArrowOverlay = function(superclass, originalArgs) {
+ superclass.apply(this, originalArgs);
+ VmlComponent.apply(this, originalArgs);
+ var self = this, path = null;
+ self.canvas = null;
+ self.isAppendedAtTopLevel = true;
+ var getPath = function(d) {
+ return "m " + _conv(d.hxy.x) + "," + _conv(d.hxy.y) +
+ " l " + _conv(d.tail[0].x) + "," + _conv(d.tail[0].y) +
+ " " + _conv(d.cxy.x) + "," + _conv(d.cxy.y) +
+ " " + _conv(d.tail[1].x) + "," + _conv(d.tail[1].y) +
+ " x e";
+ };
+ this.paint = function(params, containerExtents) {
+ var p = {}, d = params.d, connector = params.component;
+ if (params.strokeStyle) {
+ p.stroked = "true";
+ p.strokecolor = jsPlumbUtil.convertStyle(params.strokeStyle, true);
+ }
+ if (params.lineWidth) p.strokeweight = params.lineWidth + "px";
+ if (params.fillStyle) {
+ p.filled = "true";
+ p.fillcolor = params.fillStyle;
+ }
+
+ var xmin = Math.min(d.hxy.x, d.tail[0].x, d.tail[1].x, d.cxy.x),
+ ymin = Math.min(d.hxy.y, d.tail[0].y, d.tail[1].y, d.cxy.y),
+ xmax = Math.max(d.hxy.x, d.tail[0].x, d.tail[1].x, d.cxy.x),
+ ymax = Math.max(d.hxy.y, d.tail[0].y, d.tail[1].y, d.cxy.y),
+ w = Math.abs(xmax - xmin),
+ h = Math.abs(ymax - ymin),
+ dim = [xmin, ymin, w, h];
+
+ // for VML, we create overlays using shapes that have the same dimensions and
+ // coordsize as their connector - overlays calculate themselves relative to the
+ // connector (it's how it's been done since the original canvas implementation, because
+ // for canvas that makes sense).
+ p.path = getPath(d);
+ p.coordsize = (connector.w * scale) + "," + (connector.h * scale);
+
+ dim[0] = connector.x;
+ dim[1] = connector.y;
+ dim[2] = connector.w;
+ dim[3] = connector.h;
+
+ if (self.canvas == null) {
+ var overlayClass = connector._jsPlumb.overlayClass || "";
+ var clazz = originalArgs && (originalArgs.length == 1) ? (originalArgs[0].cssClass || "") : "";
+ p["class"] = clazz + " " + overlayClass;
+ self.canvas = _node("shape", dim, p, connector.canvas.parentNode, connector._jsPlumb.instance, true);
+ connector.appendDisplayElement(self.canvas, true);
+ self.attachListeners(self.canvas, connector);
+ self.attachListeners(self.canvas, self);
+ }
+ else {
+ _pos(self.canvas, dim);
+ _atts(self.canvas, p);
+ }
+ };
+
+ this.reattachListeners = function() {
+ if (self.canvas) self.reattachListenersForElement(self.canvas, self);
+ };
+
+ this.cleanup = function() {
+ if (self.canvas != null) jsPlumb.CurrentLibrary.removeElement(self.canvas);
+ };
+ };
+ jsPlumbUtil.extend(AbstractVmlArrowOverlay, VmlComponent);
+
+ jsPlumb.Overlays.vml.Arrow = function() {
+ AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.vml.Arrow, [ jsPlumb.Overlays.Arrow, AbstractVmlArrowOverlay ]);
+
+ jsPlumb.Overlays.vml.PlainArrow = function() {
+ AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.vml.PlainArrow, [ jsPlumb.Overlays.PlainArrow, AbstractVmlArrowOverlay ]);
+
+ jsPlumb.Overlays.vml.Diamond = function() {
+ AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.vml.Diamond, [ jsPlumb.Overlays.Diamond, AbstractVmlArrowOverlay ]);
+
+// ******************************* /vml overlays *****************************************************
+
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the MooTools adapter.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ /*
+ * overrides the FX class to inject 'step' functionality, which MooTools does not
+ * offer, and which makes me sad. they don't seem keen to add it, either, despite
+ * the fact that it could be useful:
+ *
+ * https://mootools.lighthouseapp.com/projects/2706/tickets/668
+ *
+ */
+ var jsPlumbMorph = new Class({
+ Extends:Fx.Morph,
+ onStep : null,
+ initialize : function(el, options) {
+ this.parent(el, options);
+ if (options.onStep) {
+ this.onStep = options.onStep;
+ }
+ },
+ step : function(now) {
+ this.parent(now);
+ if (this.onStep) {
+ try { this.onStep(); }
+ catch(e) { }
+ }
+ }
+ });
+
+ var _droppables = {},
+ _droppableOptions = {},
+ _draggablesByScope = {},
+ _draggablesById = {},
+ _droppableScopesById = {};
+ /*
+ *
+ */
+ var _executeDroppableOption = function(el, dr, event, originalEvent) {
+ if (dr) {
+ var id = dr.get("id");
+ if (id) {
+ var options = _droppableOptions[id];
+ if (options) {
+ if (options[event]) {
+ options[event](el, dr, originalEvent);
+ }
+ }
+ }
+ }
+ };
+
+ var _checkHover = function(el, entering) {
+ if (el) {
+ var id = el.get("id");
+ if (id) {
+ var options = _droppableOptions[id];
+ if (options) {
+ if (options.hoverClass) {
+ if (entering) el.addClass(options.hoverClass);
+ else el.removeClass(options.hoverClass);
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * adds the given value to the given list, with the given scope. creates the scoped list
+ * if necessary.
+ * used by initDraggable and initDroppable.
+ */
+ var _add = function(list, _scope, value) {
+ var l = list[_scope];
+ if (!l) {
+ l = [];
+ list[_scope] = l;
+ }
+ l.push(value);
+ };
+
+ /*
+ * gets an "element object" from the given input. this means an object that is used by the
+ * underlying library on which jsPlumb is running. 'el' may already be one of these objects,
+ * in which case it is returned as-is. otherwise, 'el' is a String, the library's lookup
+ * function is used to find the element, using the given String as the element's id.
+ */
+ var _getElementObject = function(el) {
+ return $(el);
+ };
+
+ jsPlumb.CurrentLibrary = {
+
+ /**
+ * adds the given class to the element object.
+ */
+ addClass : function(el, clazz) {
+ el = jsPlumb.CurrentLibrary.getElementObject(el);
+ try {
+ if (el.className.constructor == SVGAnimatedString) {
+ jsPlumbUtil.svg.addClass(el, clazz);
+ }
+ else el.addClass(clazz);
+ }
+ catch (e) {
+ // SVGAnimatedString not supported; no problem.
+ el.addClass(clazz);
+ }
+ },
+
+ animate : function(el, properties, options) {
+ var m = new jsPlumbMorph(el, options);
+ m.start(properties);
+ },
+
+ appendElement : function(child, parent) {
+ _getElementObject(parent).grab(child);
+ },
+
+ bind : function(el, event, callback) {
+ el = _getElementObject(el);
+ el.addEvent(event, callback);
+ },
+
+ destroyDraggable : function(el) {
+ // TODO
+ var id = jsPlumb.getId(el), d = _draggablesById[id];
+ if (d) {
+ for (var i = 0; i < d.length; i++)
+ d[i].detach();
+
+ delete _draggablesById[id];
+ }
+ },
+
+ destroyDroppable : function(el) {
+ // TODO
+ },
+
+ dragEvents : {
+ 'start':'onStart', 'stop':'onComplete', 'drag':'onDrag', 'step':'onStep',
+ 'over':'onEnter', 'out':'onLeave','drop':'onDrop', 'complete':'onComplete'
+ },
+
+ /*
+ * wrapper around the library's 'extend' functionality (which it hopefully has.
+ * otherwise you'll have to do it yourself). perhaps jsPlumb could do this for you
+ * instead. it's not like its hard.
+ */
+ extend : function(o1, o2) {
+ return $extend(o1, o2);
+ },
+
+ getClientXY : function(eventObject) {
+ return [eventObject.event.clientX, eventObject.event.clientY];
+ },
+
+ getDragObject : function(eventArgs) {
+ return eventArgs[0];
+ },
+
+ getDragScope : function(el) {
+ var id = jsPlumb.getId(el),
+ drags = _draggablesById[id];
+ return drags[0].scope;
+ },
+
+ getDropEvent : function(args) {
+ return args[2];
+ },
+
+ getDropScope : function(el) {
+ var id = jsPlumb.getId(el);
+ return _droppableScopesById[id];
+ },
+
+ getDOMElement : function(el) {
+ if (el == null) return null;
+ // MooTools just decorates the DOM elements. so we have either an ID or an Element here.
+ return typeof(el) == "string" ? document.getElementById(el) : el;
+ },
+
+ getElementObject : _getElementObject,
+
+ /*
+ gets the offset for the element object. this should return a js object like this:
+
+ { left:xxx, top: xxx}
+ */
+ getOffset : function(el) {
+ var p = el.getPosition();
+ return { left:p.x, top:p.y };
+ },
+
+ getOriginalEvent : function(e) {
+ return e.event;
+ },
+
+ getPageXY : function(eventObject) {
+ return [eventObject.event.pageX, eventObject.event.pageY];
+ },
+
+ getParent : function(el) {
+ return jsPlumb.CurrentLibrary.getElementObject(el).getParent();
+ },
+
+ getScrollLeft : function(el) {
+ return null;
+ },
+
+ getScrollTop : function(el) {
+ return null;
+ },
+
+ getSelector : function(context, spec) {
+ if (arguments.length == 2) {
+ return jsPlumb.CurrentLibrary.getElementObject(context).getElements(spec);
+ }
+ else
+ return $$(context);
+ },
+
+ getSize : function(el) {
+ var s = el.getSize();
+ return [s.x, s.y];
+ },
+
+ getTagName : function(el) {
+ var e = jsPlumb.CurrentLibrary.getElementObject(el);
+ return e != null ? e.tagName : null;
+ },
+
+ /*
+ * takes the args passed to an event function and returns you an object that gives the
+ * position of the object being moved, as a js object with the same params as the result of
+ * getOffset, ie: { left: xxx, top: xxx }.
+ */
+ getUIPosition : function(eventArgs, zoom) {
+ var ui = eventArgs[0],
+ el = jsPlumb.CurrentLibrary.getElementObject(ui),
+ p = el.getPosition();
+
+ zoom = zoom || 1;
+
+ return { left:p.x / zoom, top:p.y / zoom};
+ },
+
+ hasClass : function(el, clazz) {
+ return el.hasClass(clazz);
+ },
+
+ initDraggable : function(el, options, isPlumbedComponent, _jsPlumb) {
+ var id = jsPlumb.getId(el);
+ var drag = _draggablesById[id];
+ if (!drag) {
+ var originalZIndex = 0,
+ originalCursor = null,
+ dragZIndex = jsPlumb.Defaults.DragOptions.zIndex || 2000;
+
+ options.onStart = jsPlumbUtil.wrap(options.onStart, function() {
+ originalZIndex = this.element.getStyle('z-index');
+ this.element.setStyle('z-index', dragZIndex);
+ drag.originalZIndex = originalZIndex;
+ if (jsPlumb.Defaults.DragOptions.cursor) {
+ originalCursor = this.element.getStyle('cursor');
+ this.element.setStyle('cursor', jsPlumb.Defaults.DragOptions.cursor);
+ }
+ $(document.body).addClass(_jsPlumb.dragSelectClass);
+ });
+
+ options.onComplete = jsPlumbUtil.wrap(options.onComplete, function() {
+ this.element.setStyle('z-index', originalZIndex);
+ if (originalCursor) {
+ this.element.setStyle('cursor', originalCursor);
+ }
+ $(document.body).removeClass(_jsPlumb.dragSelectClass);
+ });
+
+ // DROPPABLES - only relevant if this is a plumbed component, ie. not just the result of the user making some DOM element
+ // draggable. this is the only library adapter that has to care about this parameter.
+ var scope = "" + (options.scope || jsPlumb.Defaults.Scope),
+ filterFunc = function(entry) {
+ return entry.get("id") != el.get("id");
+ },
+ droppables = _droppables[scope] ? _droppables[scope].filter(filterFunc) : [];
+
+ if (isPlumbedComponent) {
+
+ options.droppables = droppables;
+ options.onLeave = jsPlumbUtil.wrap(options.onLeave, function(el, dr) {
+ if (dr) {
+ _checkHover(dr, false);
+ _executeDroppableOption(el, dr, 'onLeave');
+ }
+ });
+ options.onEnter = jsPlumbUtil.wrap(options.onEnter, function(el, dr) {
+ if (dr) {
+ _checkHover(dr, true);
+ _executeDroppableOption(el, dr, 'onEnter');
+ }
+ });
+ options.onDrop = function(el, dr, event) {
+ if (dr) {
+ _checkHover(dr, false);
+ _executeDroppableOption(el, dr, 'onDrop', event);
+ }
+ };
+ }
+ else
+ options.droppables = [];
+
+ drag = new Drag.Move(el, options);
+ drag.scope = scope;
+ drag.originalZIndex = originalZIndex;
+ _add(_draggablesById, el.get("id"), drag);
+ // again, only keep a record of this for scope stuff if this is a plumbed component (an endpoint)
+ if (isPlumbedComponent) {
+ _add(_draggablesByScope, scope, drag);
+ }
+ // test for disabled.
+ if (options.disabled) drag.detach();
+ }
+ return drag;
+ },
+
+ initDroppable : function(el, options, isPlumbedComponent, isPermanent) {
+ var scope = options.scope;
+ _add(_droppables, scope, el);
+ var id = jsPlumb.getId(el);
+
+ el.setAttribute("_isPermanentDroppable", isPermanent); // we use this to clear out droppables on drag complete.
+ _droppableOptions[id] = options;
+ _droppableScopesById[id] = scope;
+ var filterFunc = function(entry) { return entry.element != el; },
+ draggables = _draggablesByScope[scope] ? _draggablesByScope[scope].filter(filterFunc) : [];
+ for (var i = 0; i < draggables.length; i++) {
+ draggables[i].droppables.push(el);
+ }
+ },
+
+ isAlreadyDraggable : function(el) {
+ return _draggablesById[jsPlumb.getId(el)] != null;
+ },
+
+ isDragSupported : function(el, options) {
+ return typeof Drag != 'undefined' ;
+ },
+
+ /*
+ * you need Drag.Move imported to make drop work.
+ */
+ isDropSupported : function(el, options) {
+ return (typeof Drag !== undefined && typeof Drag.Move !== undefined);
+ },
+
+ /**
+ * removes the given class from the element object.
+ */
+ removeClass : function(el, clazz) {
+ el = jsPlumb.CurrentLibrary.getElementObject(el);
+ try {
+ if (el.className.constructor == SVGAnimatedString) {
+ jsPlumbUtil.svg.removeClass(el, clazz);
+ }
+ else el.removeClass(clazz);
+ }
+ catch (e) {
+ // SVGAnimatedString not supported; no problem.
+ el.removeClass(clazz);
+ }
+ },
+
+ removeElement : function(element, parent) {
+ var el = _getElementObject(element);
+ if (el) el.dispose(); // ??
+ },
+
+ setDragFilter : function(el, filter) {
+ jsPlumb.log("NOT IMPLEMENTED: setDragFilter");
+ },
+
+ setDraggable : function(el, draggable) {
+ var draggables = _draggablesById[el.get("id")];
+ if (draggables) {
+ draggables.each(function(d) {
+ if (draggable) d.attach(); else d.detach();
+ });
+ }
+ },
+
+ setDragScope : function(el, scope) {
+ var drag = _draggablesById[el.get("id")];
+ var filterFunc = function(entry) {
+ return entry.get("id") != el.get("id");
+ };
+ var droppables = _droppables[scope] ? _droppables[scope].filter(filterFunc) : [];
+ drag[0].droppables = droppables;
+ },
+
+ setOffset : function(el, o) {
+ _getElementObject(el).setPosition({x:o.left, y:o.top});
+ },
+
+ stopDrag : function() {
+ for (var i in _draggablesById) {
+ for (var j = 0; j < _draggablesById[i].length; j++) {
+ var d = _draggablesById[i][j];
+ d.stop();
+ if (d.originalZIndex !== 0)
+ d.element.setStyle("z-index", d.originalZIndex);
+ }
+ }
+ },
+
+ /**
+ * note that jquery ignores the name of the event you wanted to trigger, and figures it out for itself.
+ * the other libraries do not. yui, in fact, cannot even pass an original event. we have to pull out stuff
+ * from the originalEvent to put in an options object for YUI.
+ * @param el
+ * @param event
+ * @param originalEvent
+ */
+ trigger : function(el, event, originalEvent) {
+ originalEvent.stopPropagation();
+ _getElementObject(el).fireEvent(event, originalEvent);
+ },
+
+ unbind : function(el, event, callback) {
+ el = _getElementObject(el);
+ el.removeEvent(event, callback);
+ }
+ };
+
+ window.addEvent('domready', jsPlumb.init);
+})();
Added: sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/yui.jsPlumb-1.5.2.js
===================================================================
--- sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/yui.jsPlumb-1.5.2.js (rev 0)
+++ sandbox/nuiton-js-jsplumb/src/main/resources/nuiton-js-jsplumb/yui.jsPlumb-1.5.2.js 2013-09-09 09:43:14 UTC (rev 207)
@@ -0,0 +1,10969 @@
+/** %%Ignore-License
+* jsBezier-0.6
+*
+* Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+*
+* licensed under the MIT license.
+*
+* a set of Bezier curve functions that deal with Beziers, used by jsPlumb, and perhaps useful for other people. These functions work with Bezier
+* curves of arbitrary degree.
+*
+* - functions are all in the 'jsBezier' namespace.
+*
+* - all input points should be in the format {x:.., y:..}. all output points are in this format too.
+*
+* - all input curves should be in the format [ {x:.., y:..}, {x:.., y:..}, {x:.., y:..}, {x:.., y:..} ]
+*
+* - 'location' as used as an input here refers to a decimal in the range 0-1 inclusive, which indicates a point some proportion along the length
+* of the curve. location as output has the same format and meaning.
+*
+*
+* Function List:
+* --------------
+*
+* distanceFromCurve(point, curve)
+*
+* Calculates the distance that the given point lies from the given Bezier. Note that it is computed relative to the center of the Bezier,
+* so if you have stroked the curve with a wide pen you may wish to take that into account! The distance returned is relative to the values
+* of the curve and the point - it will most likely be pixels.
+*
+* gradientAtPoint(curve, location)
+*
+* Calculates the gradient to the curve at the given location, as a decimal between 0 and 1 inclusive.
+*
+* gradientAtPointAlongCurveFrom (curve, location)
+*
+* Calculates the gradient at the point on the given curve that is 'distance' units from location.
+*
+* nearestPointOnCurve(point, curve)
+*
+* Calculates the nearest point to the given point on the given curve. The return value of this is a JS object literal, containing both the
+*point's coordinates and also the 'location' of the point (see above), for example: { point:{x:551,y:150}, location:0.263365 }.
+*
+* pointOnCurve(curve, location)
+*
+* Calculates the coordinates of the point on the given Bezier curve at the given location.
+*
+* pointAlongCurveFrom(curve, location, distance)
+*
+* Calculates the coordinates of the point on the given curve that is 'distance' units from location. 'distance' should be in the same coordinate
+* space as that used to construct the Bezier curve. For an HTML Canvas usage, for example, distance would be a measure of pixels.
+*
+* locationAlongCurveFrom(curve, location, distance)
+*
+* Calculates the location on the given curve that is 'distance' units from location. 'distance' should be in the same coordinate
+* space as that used to construct the Bezier curve. For an HTML Canvas usage, for example, distance would be a measure of pixels.
+*
+* perpendicularToCurveAt(curve, location, length, distance)
+*
+* Calculates the perpendicular to the given curve at the given location. length is the length of the line you wish for (it will be centered
+* on the point at 'location'). distance is optional, and allows you to specify a point along the path from the given location as the center of
+* the perpendicular returned. The return value of this is an array of two points: [ {x:...,y:...}, {x:...,y:...} ].
+*
+*
+*/
+
+(function() {
+
+ if(typeof Math.sgn == "undefined") {
+ Math.sgn = function(x) { return x == 0 ? 0 : x > 0 ? 1 :-1; };
+ }
+
+ var Vectors = {
+ subtract : function(v1, v2) { return {x:v1.x - v2.x, y:v1.y - v2.y }; },
+ dotProduct : function(v1, v2) { return (v1.x * v2.x) + (v1.y * v2.y); },
+ square : function(v) { return Math.sqrt((v.x * v.x) + (v.y * v.y)); },
+ scale : function(v, s) { return {x:v.x * s, y:v.y * s }; }
+ },
+
+ maxRecursion = 64,
+ flatnessTolerance = Math.pow(2.0,-maxRecursion-1);
+
+ /**
+ * Calculates the distance that the point lies from the curve.
+ *
+ * @param point a point in the form {x:567, y:3342}
+ * @param curve a Bezier curve in the form [{x:..., y:...}, {x:..., y:...}, {x:..., y:...}, {x:..., y:...}]. note that this is currently
+ * hardcoded to assume cubiz beziers, but would be better off supporting any degree.
+ * @return a JS object literal containing location and distance, for example: {location:0.35, distance:10}. Location is analogous to the location
+ * argument you pass to the pointOnPath function: it is a ratio of distance travelled along the curve. Distance is the distance in pixels from
+ * the point to the curve.
+ */
+ var _distanceFromCurve = function(point, curve) {
+ var candidates = [],
+ w = _convertToBezier(point, curve),
+ degree = curve.length - 1, higherDegree = (2 * degree) - 1,
+ numSolutions = _findRoots(w, higherDegree, candidates, 0),
+ v = Vectors.subtract(point, curve[0]), dist = Vectors.square(v), t = 0.0;
+
+ for (var i = 0; i < numSolutions; i++) {
+ v = Vectors.subtract(point, _bezier(curve, degree, candidates[i], null, null));
+ var newDist = Vectors.square(v);
+ if (newDist < dist) {
+ dist = newDist;
+ t = candidates[i];
+ }
+ }
+ v = Vectors.subtract(point, curve[degree]);
+ newDist = Vectors.square(v);
+ if (newDist < dist) {
+ dist = newDist;
+ t = 1.0;
+ }
+ return {location:t, distance:dist};
+ };
+ /**
+ * finds the nearest point on the curve to the given point.
+ */
+ var _nearestPointOnCurve = function(point, curve) {
+ var td = _distanceFromCurve(point, curve);
+ return {point:_bezier(curve, curve.length - 1, td.location, null, null), location:td.location};
+ };
+ var _convertToBezier = function(point, curve) {
+ var degree = curve.length - 1, higherDegree = (2 * degree) - 1,
+ c = [], d = [], cdTable = [], w = [],
+ z = [ [1.0, 0.6, 0.3, 0.1], [0.4, 0.6, 0.6, 0.4], [0.1, 0.3, 0.6, 1.0] ];
+
+ for (var i = 0; i <= degree; i++) c[i] = Vectors.subtract(curve[i], point);
+ for (var i = 0; i <= degree - 1; i++) {
+ d[i] = Vectors.subtract(curve[i+1], curve[i]);
+ d[i] = Vectors.scale(d[i], 3.0);
+ }
+ for (var row = 0; row <= degree - 1; row++) {
+ for (var column = 0; column <= degree; column++) {
+ if (!cdTable[row]) cdTable[row] = [];
+ cdTable[row][column] = Vectors.dotProduct(d[row], c[column]);
+ }
+ }
+ for (i = 0; i <= higherDegree; i++) {
+ if (!w[i]) w[i] = [];
+ w[i].y = 0.0;
+ w[i].x = parseFloat(i) / higherDegree;
+ }
+ var n = degree, m = degree-1;
+ for (var k = 0; k <= n + m; k++) {
+ var lb = Math.max(0, k - m),
+ ub = Math.min(k, n);
+ for (i = lb; i <= ub; i++) {
+ j = k - i;
+ w[i+j].y += cdTable[j][i] * z[j][i];
+ }
+ }
+ return w;
+ };
+ /**
+ * counts how many roots there are.
+ */
+ var _findRoots = function(w, degree, t, depth) {
+ var left = [], right = [],
+ left_count, right_count,
+ left_t = [], right_t = [];
+
+ switch (_getCrossingCount(w, degree)) {
+ case 0 : {
+ return 0;
+ }
+ case 1 : {
+ if (depth >= maxRecursion) {
+ t[0] = (w[0].x + w[degree].x) / 2.0;
+ return 1;
+ }
+ if (_isFlatEnough(w, degree)) {
+ t[0] = _computeXIntercept(w, degree);
+ return 1;
+ }
+ break;
+ }
+ }
+ _bezier(w, degree, 0.5, left, right);
+ left_count = _findRoots(left, degree, left_t, depth+1);
+ right_count = _findRoots(right, degree, right_t, depth+1);
+ for (var i = 0; i < left_count; i++) t[i] = left_t[i];
+ for (var i = 0; i < right_count; i++) t[i+left_count] = right_t[i];
+ return (left_count+right_count);
+ };
+ var _getCrossingCount = function(curve, degree) {
+ var n_crossings = 0, sign, old_sign;
+ sign = old_sign = Math.sgn(curve[0].y);
+ for (var i = 1; i <= degree; i++) {
+ sign = Math.sgn(curve[i].y);
+ if (sign != old_sign) n_crossings++;
+ old_sign = sign;
+ }
+ return n_crossings;
+ };
+ var _isFlatEnough = function(curve, degree) {
+ var error,
+ intercept_1, intercept_2, left_intercept, right_intercept,
+ a, b, c, det, dInv, a1, b1, c1, a2, b2, c2;
+ a = curve[0].y - curve[degree].y;
+ b = curve[degree].x - curve[0].x;
+ c = curve[0].x * curve[degree].y - curve[degree].x * curve[0].y;
+
+ var max_distance_above = max_distance_below = 0.0;
+
+ for (var i = 1; i < degree; i++) {
+ var value = a * curve[i].x + b * curve[i].y + c;
+ if (value > max_distance_above)
+ max_distance_above = value;
+ else if (value < max_distance_below)
+ max_distance_below = value;
+ }
+
+ a1 = 0.0; b1 = 1.0; c1 = 0.0; a2 = a; b2 = b;
+ c2 = c - max_distance_above;
+ det = a1 * b2 - a2 * b1;
+ dInv = 1.0/det;
+ intercept_1 = (b1 * c2 - b2 * c1) * dInv;
+ a2 = a; b2 = b; c2 = c - max_distance_below;
+ det = a1 * b2 - a2 * b1;
+ dInv = 1.0/det;
+ intercept_2 = (b1 * c2 - b2 * c1) * dInv;
+ left_intercept = Math.min(intercept_1, intercept_2);
+ right_intercept = Math.max(intercept_1, intercept_2);
+ error = right_intercept - left_intercept;
+ return (error < flatnessTolerance)? 1 : 0;
+ };
+ var _computeXIntercept = function(curve, degree) {
+ var XLK = 1.0, YLK = 0.0,
+ XNM = curve[degree].x - curve[0].x, YNM = curve[degree].y - curve[0].y,
+ XMK = curve[0].x - 0.0, YMK = curve[0].y - 0.0,
+ det = XNM*YLK - YNM*XLK, detInv = 1.0/det,
+ S = (XNM*YMK - YNM*XMK) * detInv;
+ return 0.0 + XLK * S;
+ };
+ var _bezier = function(curve, degree, t, left, right) {
+ var temp = [[]];
+ for (var j =0; j <= degree; j++) temp[0][j] = curve[j];
+ for (var i = 1; i <= degree; i++) {
+ for (var j =0 ; j <= degree - i; j++) {
+ if (!temp[i]) temp[i] = [];
+ if (!temp[i][j]) temp[i][j] = {};
+ temp[i][j].x = (1.0 - t) * temp[i-1][j].x + t * temp[i-1][j+1].x;
+ temp[i][j].y = (1.0 - t) * temp[i-1][j].y + t * temp[i-1][j+1].y;
+ }
+ }
+ if (left != null)
+ for (j = 0; j <= degree; j++) left[j] = temp[j][0];
+ if (right != null)
+ for (j = 0; j <= degree; j++) right[j] = temp[degree-j][j];
+
+ return (temp[degree][0]);
+ };
+
+ var _curveFunctionCache = {};
+ var _getCurveFunctions = function(order) {
+ var fns = _curveFunctionCache[order];
+ if (!fns) {
+ fns = [];
+ var f_term = function() { return function(t) { return Math.pow(t, order); }; },
+ l_term = function() { return function(t) { return Math.pow((1-t), order); }; },
+ c_term = function(c) { return function(t) { return c; }; },
+ t_term = function() { return function(t) { return t; }; },
+ one_minus_t_term = function() { return function(t) { return 1-t; }; },
+ _termFunc = function(terms) {
+ return function(t) {
+ var p = 1;
+ for (var i = 0; i < terms.length; i++) p = p * terms[i](t);
+ return p;
+ };
+ };
+
+ fns.push(new f_term()); // first is t to the power of the curve order
+ for (var i = 1; i < order; i++) {
+ var terms = [new c_term(order)];
+ for (var j = 0 ; j < (order - i); j++) terms.push(new t_term());
+ for (var j = 0 ; j < i; j++) terms.push(new one_minus_t_term());
+ fns.push(new _termFunc(terms));
+ }
+ fns.push(new l_term()); // last is (1-t) to the power of the curve order
+
+ _curveFunctionCache[order] = fns;
+ }
+
+ return fns;
+ };
+
+
+ /**
+ * calculates a point on the curve, for a Bezier of arbitrary order.
+ * @param curve an array of control points, eg [{x:10,y:20}, {x:50,y:50}, {x:100,y:100}, {x:120,y:100}]. For a cubic bezier this should have four points.
+ * @param location a decimal indicating the distance along the curve the point should be located at. this is the distance along the curve as it travels, taking the way it bends into account. should be a number from 0 to 1, inclusive.
+ */
+ var _pointOnPath = function(curve, location) {
+ var cc = _getCurveFunctions(curve.length - 1),
+ _x = 0, _y = 0;
+ for (var i = 0; i < curve.length ; i++) {
+ _x = _x + (curve[i].x * cc[i](location));
+ _y = _y + (curve[i].y * cc[i](location));
+ }
+
+ return {x:_x, y:_y};
+ };
+
+ var _dist = function(p1,p2) {
+ return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
+ };
+
+ var _isPoint = function(curve) {
+ return curve[0].x == curve[1].x && curve[0].y == curve[1].y;
+ };
+
+ /**
+ * finds the point that is 'distance' along the path from 'location'. this method returns both the x,y location of the point and also
+ * its 'location' (proportion of travel along the path); the method below - _pointAlongPathFrom - calls this method and just returns the
+ * point.
+ */
+ var _pointAlongPath = function(curve, location, distance) {
+
+ if (_isPoint(curve)) {
+ return {
+ point:curve[0],
+ location:location
+ };
+ }
+
+ var prev = _pointOnPath(curve, location),
+ tally = 0,
+ curLoc = location,
+ direction = distance > 0 ? 1 : -1,
+ cur = null;
+
+ while (tally < Math.abs(distance)) {
+ curLoc += (0.005 * direction);
+ cur = _pointOnPath(curve, curLoc);
+ tally += _dist(cur, prev);
+ prev = cur;
+ }
+ return {point:cur, location:curLoc};
+ };
+
+ var _length = function(curve) {
+ if (_isPoint(curve)) return 0;
+
+ var prev = _pointOnPath(curve, 0),
+ tally = 0,
+ curLoc = 0,
+ direction = 1,
+ cur = null;
+
+ while (curLoc < 1) {
+ curLoc += (0.005 * direction);
+ cur = _pointOnPath(curve, curLoc);
+ tally += _dist(cur, prev);
+ prev = cur;
+ }
+ return tally;
+ };
+
+ /**
+ * finds the point that is 'distance' along the path from 'location'.
+ */
+ var _pointAlongPathFrom = function(curve, location, distance) {
+ return _pointAlongPath(curve, location, distance).point;
+ };
+
+ /**
+ * finds the location that is 'distance' along the path from 'location'.
+ */
+ var _locationAlongPathFrom = function(curve, location, distance) {
+ return _pointAlongPath(curve, location, distance).location;
+ };
+
+ /**
+ * returns the gradient of the curve at the given location, which is a decimal between 0 and 1 inclusive.
+ *
+ * thanks // http://bimixual.org/AnimationLibrary/beziertangents.html
+ */
+ var _gradientAtPoint = function(curve, location) {
+ var p1 = _pointOnPath(curve, location),
+ p2 = _pointOnPath(curve.slice(0, curve.length - 1), location),
+ dy = p2.y - p1.y, dx = p2.x - p1.x;
+ return dy == 0 ? Infinity : Math.atan(dy / dx);
+ };
+
+ /**
+ returns the gradient of the curve at the point which is 'distance' from the given location.
+ if this point is greater than location 1, the gradient at location 1 is returned.
+ if this point is less than location 0, the gradient at location 0 is returned.
+ */
+ var _gradientAtPointAlongPathFrom = function(curve, location, distance) {
+ var p = _pointAlongPath(curve, location, distance);
+ if (p.location > 1) p.location = 1;
+ if (p.location < 0) p.location = 0;
+ return _gradientAtPoint(curve, p.location);
+ };
+
+ /**
+ * calculates a line that is 'length' pixels long, perpendicular to, and centered on, the path at 'distance' pixels from the given location.
+ * if distance is not supplied, the perpendicular for the given location is computed (ie. we set distance to zero).
+ */
+ var _perpendicularToPathAt = function(curve, location, length, distance) {
+ distance = distance == null ? 0 : distance;
+ var p = _pointAlongPath(curve, location, distance),
+ m = _gradientAtPoint(curve, p.location),
+ _theta2 = Math.atan(-1 / m),
+ y = length / 2 * Math.sin(_theta2),
+ x = length / 2 * Math.cos(_theta2);
+ return [{x:p.point.x + x, y:p.point.y + y}, {x:p.point.x - x, y:p.point.y - y}];
+ };
+
+ var jsBezier = window.jsBezier = {
+ distanceFromCurve : _distanceFromCurve,
+ gradientAtPoint : _gradientAtPoint,
+ gradientAtPointAlongCurveFrom : _gradientAtPointAlongPathFrom,
+ nearestPointOnCurve : _nearestPointOnCurve,
+ pointOnCurve : _pointOnPath,
+ pointAlongCurveFrom : _pointAlongPathFrom,
+ perpendicularToCurveAt : _perpendicularToPathAt,
+ locationAlongCurveFrom:_locationAlongPathFrom,
+ getLength:_length
+ };
+})();
+
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG or VML.
+ *
+ * This file contains the util functions
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ var _isa = function(a) { return Object.prototype.toString.call(a) === "[object Array]"; },
+ _isnum = function(n) { return Object.prototype.toString.call(n) === "[object Number]"; },
+ _iss = function(s) { return typeof s === "string"; },
+ _isb = function(s) { return typeof s === "boolean"; },
+ _isnull = function(s) { return s == null; },
+ _iso = function(o) { return o == null ? false : Object.prototype.toString.call(o) === "[object Object]"; },
+ _isd = function(o) { return Object.prototype.toString.call(o) === "[object Date]"; },
+ _isf = function(o) { return Object.prototype.toString.call(o) === "[object Function]"; },
+ _ise = function(o) {
+ for (var i in o) { if (o.hasOwnProperty(i)) return false; }
+ return true;
+ },
+ pointHelper = function(p1, p2, fn) {
+ p1 = _isa(p1) ? p1 : [p1.x, p1.y];
+ p2 = _isa(p2) ? p2 : [p2.x, p2.y];
+ return fn(p1, p2);
+ };
+
+ jsPlumbUtil = {
+ isArray : _isa,
+ isString : _iss,
+ isBoolean: _isb,
+ isNull : _isnull,
+ isObject : _iso,
+ isDate : _isd,
+ isFunction: _isf,
+ isEmpty:_ise,
+ isNumber:_isnum,
+ clone : function(a) {
+ if (_iss(a)) return "" + a;
+ else if (_isb(a)) return !!a;
+ else if (_isd(a)) return new Date(a.getTime());
+ else if (_isf(a)) return a;
+ else if (_isa(a)) {
+ var b = [];
+ for (var i = 0; i < a.length; i++)
+ b.push(this.clone(a[i]));
+ return b;
+ }
+ else if (_iso(a)) {
+ var c = {};
+ for (var j in a)
+ c[j] = this.clone(a[j]);
+ return c;
+ }
+ else return a;
+ },
+ merge : function(a, b) {
+ var c = this.clone(a);
+ for (var i in b) {
+ if (c[i] == null || _iss(b[i]) || _isb(b[i]))
+ c[i] = b[i];
+ else {
+ if (_isa(b[i])/* && this.isArray(c[i])*/) {
+ var ar = [];
+ // if c's object is also an array we can keep its values.
+ if (_isa(c[i])) ar.push.apply(ar, c[i]);
+ ar.push.apply(ar, b[i]);
+ c[i] = ar;
+ }
+ else if(_iso(b[i])) {
+ // overwite c's value with an object if it is not already one.
+ if (!_iso(c[i]))
+ c[i] = {};
+ for (var j in b[i])
+ c[i][j] = b[i][j];
+ }
+ }
+ }
+ return c;
+ },
+ copyValues:function(names, from, to) {
+ for (var i = 0; i < names.length; i++)
+ to[names[i]] = from[names[i]];
+ },
+ //
+ // chain a list of functions, supplied by [ object, method name, args ], and return on the first
+ // one that returns the failValue. if none return the failValue, return the successValue.
+ //
+ functionChain : function(successValue, failValue, fns) {
+ for (var i = 0; i < fns.length; i++) {
+ var o = fns[i][0][fns[i][1]].apply(fns[i][0], fns[i][2]);
+ if (o === failValue) {
+ return o;
+ }
+ }
+ return successValue;
+ },
+ // take the given model and expand out any parameters.
+ populate : function(model, values) {
+ // for a string, see if it has parameter matches, and if so, try to make the substitutions.
+ var getValue = function(fromString) {
+ var matches = fromString.match(/(\${.*?})/g);
+ if (matches != null) {
+ for (var i = 0; i < matches.length; i++) {
+ var val = values[matches[i].substring(2, matches[i].length - 1)];
+ if (val != null) {
+ fromString = fromString.replace(matches[i], val);
+ }
+ }
+ }
+ return fromString;
+ },
+ // process one entry.
+ _one = function(d) {
+ if (d != null) {
+ if (_iss(d)) {
+ return getValue(d);
+ }
+ else if (_isa(d)) {
+ var r = [];
+ for (var i = 0; i < d.length; i++)
+ r.push(_one(d[i]));
+ return r;
+ }
+ else if (_iso(d)) {
+ var s = {};
+ for (var j in d) {
+ s[j] = _one(d[j]);
+ }
+ return s;
+ }
+ else {
+ return d;
+ }
+ }
+ };
+
+ return _one(model);
+ },
+ convertStyle : function(s, ignoreAlpha) {
+ // TODO: jsPlumb should support a separate 'opacity' style member.
+ if ("transparent" === s) return s;
+ var o = s,
+ pad = function(n) { return n.length == 1 ? "0" + n : n; },
+ hex = function(k) { return pad(Number(k).toString(16)); },
+ pattern = /(rgb[a]?\()(.*)(\))/;
+ if (s.match(pattern)) {
+ var parts = s.match(pattern)[2].split(",");
+ o = "#" + hex(parts[0]) + hex(parts[1]) + hex(parts[2]);
+ if (!ignoreAlpha && parts.length == 4)
+ o = o + hex(parts[3]);
+ }
+ return o;
+ },
+ gradient : function(p1, p2) {
+ return pointHelper(p1, p2, function(_p1, _p2) {
+ if (_p2[0] == _p1[0])
+ return _p2[1] > _p1[1] ? Infinity : -Infinity;
+ else if (_p2[1] == _p1[1])
+ return _p2[0] > _p1[0] ? 0 : -0;
+ else
+ return (_p2[1] - _p1[1]) / (_p2[0] - _p1[0]);
+ });
+ },
+ normal : function(p1, p2) {
+ return -1 / this.gradient(p1, p2);
+ },
+ lineLength : function(p1, p2) {
+ return pointHelper(p1, p2, function(_p1, _p2) {
+ return Math.sqrt(Math.pow(_p2[1] - _p1[1], 2) + Math.pow(_p2[0] - _p1[0], 2));
+ });
+ },
+ segment : function(p1, p2) {
+ return pointHelper(p1, p2, function(_p1, _p2) {
+ if (_p2[0] > _p1[0]) {
+ return (_p2[1] > _p1[1]) ? 2 : 1;
+ }
+ else if (_p2[0] == _p1[0]) {
+ return _p2[1] > _p1[1] ? 2 : 1;
+ }
+ else {
+ return (_p2[1] > _p1[1]) ? 3 : 4;
+ }
+ });
+ },
+ theta : function(p1, p2) {
+ return pointHelper(p1, p2, function(_p1, _p2) {
+ var m = jsPlumbUtil.gradient(_p1, _p2),
+ t = Math.atan(m),
+ s = jsPlumbUtil.segment(_p1, _p2);
+ if ((s == 4 || s== 3)) t += Math.PI;
+ if (t < 0) t += (2 * Math.PI);
+
+ return t;
+ });
+ },
+ intersects : function(r1, r2) {
+ var x1 = r1.x, x2 = r1.x + r1.w, y1 = r1.y, y2 = r1.y + r1.h,
+ a1 = r2.x, a2 = r2.x + r2.w, b1 = r2.y, b2 = r2.y + r2.h;
+
+ return ( (x1 <= a1 && a1 <= x2) && (y1 <= b1 && b1 <= y2) ) ||
+ ( (x1 <= a2 && a2 <= x2) && (y1 <= b1 && b1 <= y2) ) ||
+ ( (x1 <= a1 && a1 <= x2) && (y1 <= b2 && b2 <= y2) ) ||
+ ( (x1 <= a2 && a1 <= x2) && (y1 <= b2 && b2 <= y2) ) ||
+ ( (a1 <= x1 && x1 <= a2) && (b1 <= y1 && y1 <= b2) ) ||
+ ( (a1 <= x2 && x2 <= a2) && (b1 <= y1 && y1 <= b2) ) ||
+ ( (a1 <= x1 && x1 <= a2) && (b1 <= y2 && y2 <= b2) ) ||
+ ( (a1 <= x2 && x1 <= a2) && (b1 <= y2 && y2 <= b2) );
+ },
+ segmentMultipliers : [null, [1, -1], [1, 1], [-1, 1], [-1, -1] ],
+ inverseSegmentMultipliers : [null, [-1, -1], [-1, 1], [1, 1], [1, -1] ],
+ pointOnLine : function(fromPoint, toPoint, distance) {
+ var m = jsPlumbUtil.gradient(fromPoint, toPoint),
+ s = jsPlumbUtil.segment(fromPoint, toPoint),
+ segmentMultiplier = distance > 0 ? jsPlumbUtil.segmentMultipliers[s] : jsPlumbUtil.inverseSegmentMultipliers[s],
+ theta = Math.atan(m),
+ y = Math.abs(distance * Math.sin(theta)) * segmentMultiplier[1],
+ x = Math.abs(distance * Math.cos(theta)) * segmentMultiplier[0];
+ return { x:fromPoint.x + x, y:fromPoint.y + y };
+ },
+ perpendicularLineTo : function(fromPoint, toPoint, length) {
+ var m = jsPlumbUtil.gradient(fromPoint, toPoint),
+ theta2 = Math.atan(-1 / m),
+ y = length / 2 * Math.sin(theta2),
+ x = length / 2 * Math.cos(theta2);
+ return [{x:toPoint.x + x, y:toPoint.y + y}, {x:toPoint.x - x, y:toPoint.y - y}];
+ },
+ findWithFunction : function(a, f) {
+ if (a)
+ for (var i = 0; i < a.length; i++) if (f(a[i])) return i;
+ return -1;
+ },
+ clampToGrid : function(x, y, grid, dontClampX, dontClampY) {
+ var _gridClamp = function(n, g) {
+ var e = n % g,
+ f = Math.floor(n / g),
+ inc = e >= (g / 2) ? 1 : 0;
+ return (f + inc) * g;
+ };
+ return [
+ dontClampX || grid == null ? x : _gridClamp(x, grid[0]),
+ dontClampY || grid == null ? y : _gridClamp(y, grid[1])
+ ];
+ },
+ indexOf : function(l, v) {
+ return jsPlumbUtil.findWithFunction(l, function(_v) { return _v == v; });
+ },
+ removeWithFunction : function(a, f) {
+ var idx = jsPlumbUtil.findWithFunction(a, f);
+ if (idx > -1) a.splice(idx, 1);
+ return idx != -1;
+ },
+ remove : function(l, v) {
+ var idx = jsPlumbUtil.indexOf(l, v);
+ if (idx > -1) l.splice(idx, 1);
+ return idx != -1;
+ },
+ // TODO support insert index
+ addWithFunction : function(list, item, hashFunction) {
+ if (jsPlumbUtil.findWithFunction(list, hashFunction) == -1) list.push(item);
+ },
+ addToList : function(map, key, value, insertAtStart) {
+ var l = map[key];
+ if (l == null) {
+ l = [];
+ map[key] = l;
+ }
+ l[insertAtStart ? "unshift" : "push"](value);
+ return l;
+ },
+ //
+ // extends the given obj (which can be an array) with the given constructor function, prototype functions, and
+ // class members, any of which may be null.
+ //
+ extend : function(child, parent, _protoFn, _protoAtts) {
+ _protoFn = _protoFn || {};
+ _protoAtts = _protoAtts || {};
+ parent = _isa(parent) ? parent : [ parent ];
+
+ for (var i = 0; i < parent.length; i++) {
+ for (var j in parent[i].prototype) {
+ if(parent[i].prototype.hasOwnProperty(j)) {
+ child.prototype[j] = parent[i].prototype[j];
+ }
+ }
+ }
+
+ var _makeFn = function(name) {
+ return function() {
+ for (var i = 0; i < parent.length; i++) {
+ if (parent[i].prototype[name])
+ parent[i].prototype[name].apply(this, arguments);
+ }
+ return _protoFn[name].apply(this, arguments);
+ };
+ };
+
+ for (var k in _protoFn) {
+ child.prototype[k] = _makeFn(k);
+ }
+
+ return child;
+ },
+ uuid : function() {
+ return ('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+ var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
+ return v.toString(16);
+ }));
+ },
+ logEnabled : true,
+ log : function() {
+ if (jsPlumbUtil.logEnabled && typeof console != "undefined") {
+ try {
+ var msg = arguments[arguments.length - 1];
+ console.log(msg);
+ }
+ catch (e) {}
+ }
+ },
+ group : function(g) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.group(g); },
+ groupEnd : function(g) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.groupEnd(g); },
+ time : function(t) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.time(t); },
+ timeEnd : function(t) { if (jsPlumbUtil.logEnabled && typeof console != "undefined") console.timeEnd(t); },
+
+ /**
+ * helper to remove an element from the DOM.
+ */
+ removeElement : function(element) {
+ if (element != null && element.parentNode != null) {
+ element.parentNode.removeChild(element);
+ }
+ },
+ /**
+ * helper to remove a list of elements from the DOM.
+ */
+ removeElements : function(elements) {
+ for ( var i = 0; i < elements.length; i++)
+ jsPlumbUtil.removeElement(elements[i]);
+ },
+ /*
+ * Function: sizeElement
+ * Helper to size and position an element. You would typically use
+ * this when writing your own Connector or Endpoint implementation.
+ *
+ * Parameters:
+ * x - [int] x position for the element origin
+ * y - [int] y position for the element origin
+ * w - [int] width of the element
+ * h - [int] height of the element
+ *
+ */
+ sizeElement : function(el, x, y, w, h) {
+ if (el) {
+ el.style.height = h + "px";
+ el.height = h;
+ el.style.width = w + "px";
+ el.width = w;
+ el.style.left = x + "px";
+ el.style.top = y + "px";
+ }
+ },
+ /**
+ * @name jsPlumbUtil.wrap
+ * @desc Wraps one function with another, creating a placeholder for the
+ * wrapped function if it was null. this is used to wrap the various
+ * drag/drop event functions - to allow jsPlumb to be notified of
+ * important lifecycle events without imposing itself on the user's
+ * drag/drop functionality.
+ * @param {Function} wrappedFunction original function to wrap; may be null.
+ * @param {Function} newFunction function to wrap the original with.
+ * @param {Object} [returnOnThisValue] Optional. Indicates that the wrappedFunction should
+ * not be executed if the newFunction returns a value matching 'returnOnThisValue'.
+ * note that this is a simple comparison and only works for primitives right now.
+ */
+ wrap : function(wrappedFunction, newFunction, returnOnThisValue) {
+ wrappedFunction = wrappedFunction || function() { };
+ newFunction = newFunction || function() { };
+ return function() {
+ var r = null;
+ try {
+ r = newFunction.apply(this, arguments);
+ } catch (e) {
+ jsPlumbUtil.log("jsPlumb function failed : " + e);
+ }
+ if (returnOnThisValue == null || (r !== returnOnThisValue)) {
+ try {
+ r = wrappedFunction.apply(this, arguments);
+ } catch (e) {
+ jsPlumbUtil.log("wrapped function failed : " + e);
+ }
+ }
+ return r;
+ };
+ }
+ };
+
+
+ jsPlumbUtil.EventGenerator = function() {
+ var _listeners = {}, eventsSuspended = false;
+
+ // this is a list of events that should re-throw any errors that occur during their dispatch. as of 1.3.0 this is private to
+ // jsPlumb, but it seems feasible that people might want to manipulate this list. the thinking is that we don't want event
+ // listeners to bring down jsPlumb - or do we. i can't make up my mind about this, but i know i want to hear about it if the "ready"
+ // event fails, because then my page has most likely not initialised. so i have this halfway-house solution. it will be interesting
+ // to hear what other people think.
+ var eventsToDieOn = [ "ready" ];
+
+ this.bind = function(event, listener, insertAtStart) {
+ jsPlumbUtil.addToList(_listeners, event, listener, true);
+ return this;
+ };
+
+ this.fire = function(event, value, originalEvent) {
+ if (!eventsSuspended && _listeners[event]) {
+ // instead of looping through the array we get a counter and a length, because it is possible
+ // that an event fired from here could cause the object to get cleaned up, which would throw
+ // away the listeners. so after each cycle through the loop we check to ensure we haven't
+ // been nuked.
+ var l = _listeners[event].length, i = 0, _gone = false, ret = null;
+ if (!this.shouldFireEvent || this.shouldFireEvent(event, value, originalEvent)) {
+ while (!_gone && i < l && ret !== false) {
+
+ // doing it this way rather than catching and then possibly re-throwing means that an error propagated by this
+ // method will have the whole call stack available in the debugger.
+ if (jsPlumbUtil.findWithFunction(eventsToDieOn, function(e) { return e === event; }) != -1)
+ _listeners[event][i](value, originalEvent);
+ else {
+ // for events we don't want to die on, catch and log.
+ try {
+ ret = _listeners[event][i](value, originalEvent);
+ } catch (e) {
+ jsPlumbUtil.log("jsPlumb: fire failed for event " + event + " : " + e);
+ }
+ }
+ i++;
+ if (_listeners == null || _listeners[event] == null) _gone = true;
+ }
+ }
+ }
+ return this;
+ };
+
+ this.unbind = function(event) {
+ if (event)
+ delete _listeners[event];
+ else {
+ _listeners = {};
+ }
+ return this;
+ };
+
+ this.getListener = function(forEvent) {
+ return _listeners[forEvent];
+ };
+ this.setSuspendEvents = function(val) {
+ eventsSuspended = val;
+ };
+ this.isSuspendEvents = function() {
+ return eventsSuspended;
+ };
+ this.cleanupListeners = function() {
+ for (var i in _listeners) {
+ _listeners[i].splice(0);
+ delete _listeners[i];
+ }
+ };
+ };
+
+
+ jsPlumbUtil.EventGenerator.prototype = {
+ cleanup:function() {
+ this.cleanupListeners();
+ }
+ };
+
+
+ // thanks MDC
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Ob…
+ if (!Function.prototype.bind) {
+ Function.prototype.bind = function (oThis) {
+ if (typeof this !== "function") {
+ // closest thing possible to the ECMAScript 5 internal IsCallable function
+ throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
+ }
+
+ var aArgs = Array.prototype.slice.call(arguments, 1),
+ fToBind = this,
+ fNOP = function () {},
+ fBound = function () {
+ return fToBind.apply(this instanceof fNOP && oThis ? this : oThis,
+ aArgs.concat(Array.prototype.slice.call(arguments)));
+ };
+
+ fNOP.prototype = this.prototype;
+ fBound.prototype = new fNOP();
+
+ return fBound;
+ };
+ }
+
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the base functionality for DOM type adapters.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+;(function() {
+
+ var canvasAvailable = !!document.createElement('canvas').getContext,
+ svgAvailable = !!window.SVGAngle || document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"),
+ // http://stackoverflow.com/questions/654112/how-do-you-detect-support-for-vml…
+ vmlAvailable = function() {
+ if (vmlAvailable.vml === undefined) {
+ var a = document.body.appendChild(document.createElement('div'));
+ a.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
+ var b = a.firstChild;
+ if (b != null && b.style != null) {
+ b.style.behavior = "url(#default#VML)";
+ vmlAvailable.vml = b ? typeof b.adj == "object": true;
+ }
+ else
+ vmlAvailable.vml = false;
+ a.parentNode.removeChild(a);
+ }
+ return vmlAvailable.vml;
+ };
+
+ /**
+ Manages dragging for some instance of jsPlumb.
+ */
+ var DragManager = function(_currentInstance) {
+ var _draggables = {}, _dlist = [], _delements = {}, _elementsWithEndpoints = {},
+ // elementids mapped to the draggable to which they belong.
+ _draggablesForElements = {};
+
+ /**
+ register some element as draggable. right now the drag init stuff is done elsewhere, and it is
+ possible that will continue to be the case.
+ */
+ this.register = function(el) {
+ var jpcl = jsPlumb.CurrentLibrary,
+ _el = jpcl.getElementObject(el),
+ id = _currentInstance.getId(el),
+ parentOffset = jpcl.getOffset(_el);
+
+ if (!_draggables[id]) {
+ _draggables[id] = el;
+ _dlist.push(el);
+ _delements[id] = {};
+ }
+
+ // look for child elements that have endpoints and register them against this draggable.
+ var _oneLevel = function(p, startOffset) {
+ if (p) {
+ for (var i = 0; i < p.childNodes.length; i++) {
+ if (p.childNodes[i].nodeType != 3 && p.childNodes[i].nodeType != 8) {
+ var cEl = jpcl.getElementObject(p.childNodes[i]),
+ cid = _currentInstance.getId(p.childNodes[i], null, true);
+ if (cid && _elementsWithEndpoints[cid] && _elementsWithEndpoints[cid] > 0) {
+ var cOff = jpcl.getOffset(cEl);
+ _delements[id][cid] = {
+ id:cid,
+ offset:{
+ left:cOff.left - parentOffset.left,
+ top:cOff.top - parentOffset.top
+ }
+ };
+ _draggablesForElements[cid] = id;
+ }
+ _oneLevel(p.childNodes[i]);
+ }
+ }
+ }
+ };
+
+ _oneLevel(el);
+ };
+
+ // refresh the offsets for child elements of this element.
+ this.updateOffsets = function(elId) {
+ var jpcl = jsPlumb.CurrentLibrary,
+ el = jpcl.getElementObject(elId),
+ domEl = jpcl.getDOMElement(el),
+ id = _currentInstance.getId(domEl),
+ children = _delements[id],
+ parentOffset = jpcl.getOffset(el);
+
+ if (children) {
+ for (var i in children) {
+ var cel = jpcl.getElementObject(i),
+ cOff = jpcl.getOffset(cel);
+
+ _delements[id][i] = {
+ id:i,
+ offset:{
+ left:cOff.left - parentOffset.left,
+ top:cOff.top - parentOffset.top
+ }
+ };
+ _draggablesForElements[i] = id;
+ }
+ }
+ };
+
+ /**
+ notification that an endpoint was added to the given el. we go up from that el's parent
+ node, looking for a parent that has been registered as a draggable. if we find one, we add this
+ el to that parent's list of elements to update on drag (if it is not there already)
+ */
+ this.endpointAdded = function(el) {
+ var jpcl = jsPlumb.CurrentLibrary, b = document.body, id = _currentInstance.getId(el),
+ c = jpcl.getElementObject(el),
+ cLoc = jsPlumb.CurrentLibrary.getOffset(c),
+ p = el.parentNode, done = p == b;
+
+ _elementsWithEndpoints[id] = _elementsWithEndpoints[id] ? _elementsWithEndpoints[id] + 1 : 1;
+
+ while (p != null && p != b) {
+ var pid = _currentInstance.getId(p, null, true);
+ if (pid && _draggables[pid]) {
+ var idx = -1, pEl = jpcl.getElementObject(p), pLoc = jpcl.getOffset(pEl);
+
+ if (_delements[pid][id] == null) {
+ _delements[pid][id] = {
+ id:id,
+ offset:{
+ left:cLoc.left - pLoc.left,
+ top:cLoc.top - pLoc.top
+ }
+ };
+ _draggablesForElements[id] = pid;
+ }
+ break;
+ }
+ p = p.parentNode;
+ }
+ };
+
+ this.endpointDeleted = function(endpoint) {
+ if (_elementsWithEndpoints[endpoint.elementId]) {
+ _elementsWithEndpoints[endpoint.elementId]--;
+ if (_elementsWithEndpoints[endpoint.elementId] <= 0) {
+ for (var i in _delements) {
+ if (_delements[i]) {
+ delete _delements[i][endpoint.elementId];
+ delete _draggablesForElements[endpoint.elementId];
+ }
+ }
+ }
+ }
+ };
+
+ this.changeId = function(oldId, newId) {
+ _delements[newId] = _delements[oldId];
+ _delements[oldId] = {};
+ _draggablesForElements[newId] = _draggablesForElements[oldId];
+ _draggablesForElements[oldId] = null;
+ };
+
+ this.getElementsForDraggable = function(id) {
+ return _delements[id];
+ };
+
+ this.elementRemoved = function(elementId) {
+ var elId = _draggablesForElements[elementId];
+ if (elId) {
+ delete _delements[elId][elementId];
+ delete _draggablesForElements[elementId];
+ }
+ };
+
+ this.reset = function() {
+ _draggables = {};
+ _dlist = [];
+ _delements = {};
+ _elementsWithEndpoints = {};
+ };
+
+ };
+
+ // for those browsers that dont have it. they still don't have it! but at least they won't crash.
+ if (!window.console)
+ window.console = { time:function(){}, timeEnd:function(){}, group:function(){}, groupEnd:function(){}, log:function(){} };
+
+ window.jsPlumbAdapter = {
+
+ headless:false,
+
+ getAttribute:function(el, attName) {
+ return el.getAttribute(attName);
+ },
+
+ setAttribute:function(el, a, v) {
+ el.setAttribute(a, v);
+ },
+
+ appendToRoot : function(node) {
+ document.body.appendChild(node);
+ },
+ getRenderModes : function() {
+ return [ "canvas", "svg", "vml" ];
+ },
+ isRenderModeAvailable : function(m) {
+ return {
+ "canvas":canvasAvailable,
+ "svg":svgAvailable,
+ "vml":vmlAvailable()
+ }[m];
+ },
+ getDragManager : function(_jsPlumb) {
+ return new DragManager(_jsPlumb);
+ },
+ setRenderMode : function(mode) {
+ var renderMode;
+
+ if (mode) {
+ mode = mode.toLowerCase();
+
+ var canvasAvailable = this.isRenderModeAvailable("canvas"),
+ svgAvailable = this.isRenderModeAvailable("svg"),
+ vmlAvailable = this.isRenderModeAvailable("vml");
+
+ // now test we actually have the capability to do this.
+ if (mode === "svg") {
+ if (svgAvailable) renderMode = "svg";
+ else if (canvasAvailable) renderMode = "canvas";
+ else if (vmlAvailable) renderMode = "vml";
+ }
+ else if (mode === "canvas" && canvasAvailable) renderMode = "canvas";
+ else if (vmlAvailable) renderMode = "vml";
+ }
+
+ return renderMode;
+ }
+ };
+
+
+ /*
+
+ addClass:
+
+ add: function( elem, classNames ) {
+ jQuery.each((classNames || "").split(/\s+/), function(i, className){
+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+ elem.className += (elem.className ? " " : "") + className;
+ });
+ },
+ */
+
+ /*
+
+ removeClass:
+
+ elem.className = classNames !== undefined ?
+ jQuery.grep(elem.className.split(/\s+/), function(className){
+ return !jQuery.className.has( classNames, className );
+ }).join(" ") :
+
+*/
+
+})();
+/**
+ * @module jsPlumb
+ * @description Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * - [Demo Site](http://jsplumb.org)
+ * - [GitHub](http://github.com/sporritt/jsplumb)
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+ */
+;(function() {
+
+ var _ju = jsPlumbUtil,
+ _addClass = function(el, clazz) { jsPlumb.CurrentLibrary.addClass(_gel(el), clazz); },
+ _hasClass = function(el, clazz) { return jsPlumb.CurrentLibrary.hasClass(_gel(el), clazz); },
+ _removeClass = function(el, clazz) { jsPlumb.CurrentLibrary.removeClass(_gel(el), clazz); },
+ _gel = function(el) { return jsPlumb.CurrentLibrary.getElementObject(el); },
+ _dom = function(el) { return jsPlumb.CurrentLibrary.getDOMElement(el); },
+ _getOffset = function(el, _instance) {
+ var o = jsPlumb.CurrentLibrary.getOffset(_gel(el));
+ if (_instance != null) {
+ var z = _instance.getZoom();
+ return {left:o.left / z, top:o.top / z };
+ }
+ else
+ return o;
+ },
+ _getSize = function(el) {
+ return jsPlumb.CurrentLibrary.getSize(_gel(el));
+ },
+
+ /**
+ * creates a timestamp, using milliseconds since 1970, but as a string.
+ */
+ _timestamp = function() { return "" + (new Date()).getTime(); },
+
+ // helper method to update the hover style whenever it, or paintStyle, changes.
+ // we use paintStyle as the foundation and merge hoverPaintStyle over the
+ // top.
+ _updateHoverStyle = function(component) {
+ if (component._jsPlumb.paintStyle && component._jsPlumb.hoverPaintStyle) {
+ var mergedHoverStyle = {};
+ jsPlumb.extend(mergedHoverStyle, component._jsPlumb.paintStyle);
+ jsPlumb.extend(mergedHoverStyle, component._jsPlumb.hoverPaintStyle);
+ delete component._jsPlumb.hoverPaintStyle;
+ // we want the fillStyle of paintStyle to override a gradient, if possible.
+ if (mergedHoverStyle.gradient && component._jsPlumb.paintStyle.fillStyle)
+ delete mergedHoverStyle.gradient;
+ component._jsPlumb.hoverPaintStyle = mergedHoverStyle;
+ }
+ },
+ events = [ "click", "dblclick", "mouseenter", "mouseout", "mousemove", "mousedown", "mouseup", "contextmenu" ],
+ eventFilters = { "mouseout":"mouseexit" },
+ _updateAttachedElements = function(component, state, timestamp, sourceElement) {
+ var affectedElements = component.getAttachedElements();
+ if (affectedElements) {
+ for (var i = 0, j = affectedElements.length; i < j; i++) {
+ if (!sourceElement || sourceElement != affectedElements[i])
+ affectedElements[i].setHover(state, true, timestamp); // tell the attached elements not to inform their own attached elements.
+ }
+ }
+ },
+ _splitType = function(t) { return t == null ? null : t.split(" "); },
+ _applyTypes = function(component, params, doNotRepaint) {
+ if (component.getDefaultType) {
+ var td = component.getTypeDescriptor();
+
+ var o = _ju.merge({}, component.getDefaultType());
+ for (var i = 0, j = component._jsPlumb.types.length; i < j; i++)
+ o = _ju.merge(o, component._jsPlumb.instance.getType(component._jsPlumb.types[i], td));
+
+ if (params) {
+ o = _ju.populate(o, params);
+ }
+
+ component.applyType(o, doNotRepaint);
+ if (!doNotRepaint) component.repaint();
+ }
+ },
+
+// ------------------------------ BEGIN jsPlumbUIComponent --------------------------------------------
+
+ jsPlumbUIComponent = window.jsPlumbUIComponent = function(params) {
+
+ jsPlumbUtil.EventGenerator.apply(this, arguments);
+
+ var self = this,
+ a = arguments,
+ idPrefix = self.idPrefix,
+ id = idPrefix + (new Date()).getTime(),
+ jpcl = jsPlumb.CurrentLibrary;
+
+ this._jsPlumb = {
+ instance: params._jsPlumb,
+ parameters:params.parameters || {},
+ paintStyle:null,
+ hoverPaintStyle:null,
+ paintStyleInUse:null,
+ hover:false,
+ beforeDetach:params.beforeDetach,
+ beforeDrop:params.beforeDrop,
+ overlayPlacements : [],
+ hoverClass: params.hoverClass || params._jsPlumb.Defaults.HoverClass || jsPlumb.Defaults.HoverClass,
+ types:[]
+ };
+
+ this.getId = function() { return id; };
+
+ // all components can generate events
+
+ if (params.events) {
+ for (var i in params.events)
+ self.bind(i, params.events[i]);
+ }
+
+ // all components get this clone function.
+ // TODO issue 116 showed a problem with this - it seems 'a' that is in
+ // the clone function's scope is shared by all invocations of it, the classic
+ // JS closure problem. for now, jsPlumb does a version of this inline where
+ // it used to call clone. but it would be nice to find some time to look
+ // further at this.
+ this.clone = function() {
+ var o = {};//new Object();
+ this.constructor.apply(o, a);
+ return o;
+ }.bind(this);
+
+
+ // user can supply a beforeDetach callback, which will be executed before a detach
+ // is performed; returning false prevents the detach.
+ this.isDetachAllowed = function(connection) {
+ var r = true;
+ if (this._jsPlumb.beforeDetach) {
+ try {
+ r = this._jsPlumb.beforeDetach(connection);
+ }
+ catch (e) { _ju.log("jsPlumb: beforeDetach callback failed", e); }
+ }
+ return r;
+ };
+
+ // user can supply a beforeDrop callback, which will be executed before a dropped
+ // connection is confirmed. user can return false to reject connection.
+ this.isDropAllowed = function(sourceId, targetId, scope, connection, dropEndpoint) {
+ var r = this._jsPlumb.instance.checkCondition("beforeDrop", {
+ sourceId:sourceId,
+ targetId:targetId,
+ scope:scope,
+ connection:connection,
+ dropEndpoint:dropEndpoint
+ });
+ if (this._jsPlumb.beforeDrop) {
+ try {
+ r = this._jsPlumb.beforeDrop({
+ sourceId:sourceId,
+ targetId:targetId,
+ scope:scope,
+ connection:connection,
+ dropEndpoint:dropEndpoint
+ });
+ }
+ catch (e) { _ju.log("jsPlumb: beforeDrop callback failed", e); }
+ }
+ return r;
+ };
+
+ var boundListeners = [],
+ bindAListener = function(obj, type, fn) {
+ boundListeners.push([obj, type, fn]);
+ obj.bind(type, fn);
+ },
+ domListeners = [],
+ bindOne = function(o, c, evt) {
+ var filteredEvent = eventFilters[evt] || evt,
+ fn = function(ee) {
+ c.fire(filteredEvent, c, ee);
+ };
+ domListeners.push([o, evt, fn]);
+ jpcl.bind(o, evt, fn);
+ },
+ unbindOne = function(o, evt, fn) {
+ var filteredEvent = eventFilters[evt] || evt;
+ jpcl.unbind(o, evt, fn);
+ };
+
+ this.bindListeners = function(obj, _self, _hoverFunction) {
+ bindAListener(obj, "click", function(ep, e) { _self.fire("click", _self, e); });
+ bindAListener(obj, "dblclick", function(ep, e) { _self.fire("dblclick", _self, e); });
+ bindAListener(obj, "contextmenu", function(ep, e) { _self.fire("contextmenu", _self, e); });
+ bindAListener(obj, "mouseenter", function(ep, e) {
+ if (!_self.isHover()) {
+ _hoverFunction(true);
+ _self.fire("mouseenter", _self, e);
+ }
+ });
+ bindAListener(obj, "mouseexit", function(ep, e) {
+ if (_self.isHover()) {
+ _hoverFunction(false);
+ _self.fire("mouseexit", _self, e);
+ }
+ });
+ bindAListener(obj, "mousedown", function(ep, e) { _self.fire("mousedown", _self, e); });
+ bindAListener(obj, "mouseup", function(ep, e) { _self.fire("mouseup", _self, e); });
+ };
+
+ this.unbindListeners = function() {
+ for (var i = 0; i < boundListeners.length; i++) {
+ var o = boundListeners[i];
+ o[0].unbind(o[1], o[2]);
+ }
+ boundListeners = null;
+ };
+
+ this.attachListeners = function(o, c) {
+ for (var i = 0, j = events.length; i < j; i++) {
+ bindOne(o, c, events[i]);
+ }
+ };
+ this.detachListeners = function() {
+ for (var i = 0; i < domListeners.length; i++) {
+ unbindOne(domListeners[i][0], domListeners[i][1], domListeners[i][2]);
+ }
+ domListeners = null;
+ };
+
+ this.reattachListenersForElement = function(o) {
+ if (arguments.length > 1) {
+ for (var i = 0, j = events.length; i < j; i++)
+ unbindOne(o, events[i]);
+ for (i = 1, j = arguments.length; i < j; i++)
+ this.attachListeners(o, arguments[i]);
+ }
+ };
+ };
+
+ jsPlumbUtil.extend(jsPlumbUIComponent, jsPlumbUtil.EventGenerator, {
+
+ getParameter : function(name) {
+ return this._jsPlumb.parameters[name];
+ },
+
+ setParameter : function(name, value) {
+ this._jsPlumb.parameters[name] = value;
+ },
+
+ getParameters : function() {
+ return this._jsPlumb.parameters;
+ },
+
+ setParameters : function(p) {
+ this._jsPlumb.parameters = p;
+ },
+
+ addClass : function(clazz) {
+ if (this.canvas != null)
+ _addClass(this.canvas, clazz);
+ },
+
+ removeClass : function(clazz) {
+ if (this.canvas != null)
+ _removeClass(this.canvas, clazz);
+ },
+
+ setType : function(typeId, params, doNotRepaint) {
+ this._jsPlumb.types = _splitType(typeId) || [];
+ _applyTypes(this, params, doNotRepaint);
+ },
+
+ getType : function() {
+ return this._jsPlumb.types;
+ },
+
+ reapplyTypes : function(params, doNotRepaint) {
+ _applyTypes(this, params, doNotRepaint);
+ },
+
+ hasType : function(typeId) {
+ return jsPlumbUtil.indexOf(this._jsPlumb.types, typeId) != -1;
+ },
+
+ addType : function(typeId, params, doNotRepaint) {
+ var t = _splitType(typeId), _cont = false;
+ if (t != null) {
+ for (var i = 0, j = t.length; i < j; i++) {
+ if (!this.hasType(t[i])) {
+ this._jsPlumb.types.push(t[i]);
+ _cont = true;
+ }
+ }
+ if (_cont) _applyTypes(this, params, doNotRepaint);
+ }
+ },
+
+ removeType : function(typeId, doNotRepaint) {
+ var t = _splitType(typeId), _cont = false, _one = function(tt) {
+ var idx = _ju.indexOf(this._jsPlumb.types, tt);
+ if (idx != -1) {
+ this._jsPlumb.types.splice(idx, 1);
+ return true;
+ }
+ return false;
+ }.bind(this);
+
+ if (t != null) {
+ for (var i = 0,j = t.length; i < j; i++) {
+ _cont = _one(t[i]) || _cont;
+ }
+ if (_cont) _applyTypes(this, null, doNotRepaint);
+ }
+ },
+
+ toggleType : function(typeId, params, doNotRepaint) {
+ var t = _splitType(typeId);
+ if (t != null) {
+ for (var i = 0, j = t.length; i < j; i++) {
+ var idx = jsPlumbUtil.indexOf(this._jsPlumb.types, t[i]);
+ if (idx != -1)
+ this._jsPlumb.types.splice(idx, 1);
+ else
+ this._jsPlumb.types.push(t[i]);
+ }
+
+ _applyTypes(this, params, doNotRepaint);
+ }
+ },
+ applyType : function(t, doNotRepaint) {
+ this.setPaintStyle(t.paintStyle, doNotRepaint);
+ this.setHoverPaintStyle(t.hoverPaintStyle, doNotRepaint);
+ if (t.parameters){
+ for (var i in t.parameters)
+ this.setParameter(i, t.parameters[i]);
+ }
+ },
+ setPaintStyle : function(style, doNotRepaint) {
+// this._jsPlumb.paintStyle = jsPlumb.extend({}, style);
+// TODO figure out if we want components to clone paintStyle so as not to share it.
+ this._jsPlumb.paintStyle = style;
+ this._jsPlumb.paintStyleInUse = this._jsPlumb.paintStyle;
+ _updateHoverStyle(this);
+ if (!doNotRepaint) this.repaint();
+ },
+ getPaintStyle : function() {
+ return this._jsPlumb.paintStyle;
+ },
+ setHoverPaintStyle : function(style, doNotRepaint) {
+ //this._jsPlumb.hoverPaintStyle = jsPlumb.extend({}, style);
+// TODO figure out if we want components to clone paintStyle so as not to share it.
+ this._jsPlumb.hoverPaintStyle = style;
+ _updateHoverStyle(this);
+ if (!doNotRepaint) this.repaint();
+ },
+ getHoverPaintStyle : function() {
+ return this._jsPlumb.hoverPaintStyle;
+ },
+ cleanup:function() {
+ this.unbindListeners();
+ this.detachListeners();
+ },
+ destroy:function() {
+ this.cleanupListeners();
+ this.clone = null;
+ this._jsPlumb = null;
+ },
+
+ isHover : function() { return this._jsPlumb.hover; },
+
+ setHover : function(hover, ignoreAttachedElements, timestamp) {
+ var jpcl = jsPlumb.CurrentLibrary;
+ // while dragging, we ignore these events. this keeps the UI from flashing and
+ // swishing and whatevering.
+ if (this._jsPlumb && !this._jsPlumb.instance.currentlyDragging && !this._jsPlumb.instance.isHoverSuspended()) {
+
+ this._jsPlumb.hover = hover;
+
+ if (this.canvas != null) {
+ if (this._jsPlumb.instance.hoverClass != null) {
+ jpcl[hover ? "addClass" : "removeClass"](this.canvas, this._jsPlumb.instance.hoverClass);
+ }
+ }
+ if (this._jsPlumb.hoverPaintStyle != null) {
+ this._jsPlumb.paintStyleInUse = hover ? this._jsPlumb.hoverPaintStyle : this._jsPlumb.paintStyle;
+ if (!this._jsPlumb.instance.isSuspendDrawing()) {
+ timestamp = timestamp || _timestamp();
+ this.repaint({timestamp:timestamp, recalc:false});
+ }
+ }
+ // get the list of other affected elements, if supported by this component.
+ // for a connection, its the endpoints. for an endpoint, its the connections! surprise.
+ if (this.getAttachedElements && !ignoreAttachedElements)
+ _updateAttachedElements(this, hover, _timestamp(), this);
+ }
+ }
+ });
+
+// ------------------------------ END jsPlumbUIComponent --------------------------------------------
+
+// ------------------------------ BEGIN OverlayCapablejsPlumbUIComponent --------------------------------------------
+
+ var _internalLabelOverlayId = "__label",
+ // helper to get the index of some overlay
+ _getOverlayIndex = function(component, id) {
+ var idx = -1;
+ for (var i = 0, j = component._jsPlumb.overlays.length; i < j; i++) {
+ if (id === component._jsPlumb.overlays[i].id) {
+ idx = i;
+ break;
+ }
+ }
+ return idx;
+ },
+ // this is a shortcut helper method to let people add a label as
+ // overlay.
+ _makeLabelOverlay = function(component, params) {
+
+ var _params = {
+ cssClass:params.cssClass,
+ labelStyle : component.labelStyle,
+ id:_internalLabelOverlayId,
+ component:component,
+ _jsPlumb:component._jsPlumb.instance // TODO not necessary, since the instance can be accessed through the component.
+ },
+ mergedParams = jsPlumb.extend(_params, params);
+
+ return new jsPlumb.Overlays[component._jsPlumb.instance.getRenderMode()].Label( mergedParams );
+ },
+ _processOverlay = function(component, o) {
+ var _newOverlay = null;
+ if (_ju.isArray(o)) { // this is for the shorthand ["Arrow", { width:50 }] syntax
+ // there's also a three arg version:
+ // ["Arrow", { width:50 }, {location:0.7}]
+ // which merges the 3rd arg into the 2nd.
+ var type = o[0],
+ // make a copy of the object so as not to mess up anyone else's reference...
+ p = jsPlumb.extend({component:component, _jsPlumb:component._jsPlumb.instance}, o[1]);
+ if (o.length == 3) jsPlumb.extend(p, o[2]);
+ _newOverlay = new jsPlumb.Overlays[component._jsPlumb.instance.getRenderMode()][type](p);
+ } else if (o.constructor == String) {
+ _newOverlay = new jsPlumb.Overlays[component._jsPlumb.instance.getRenderMode()][o]({component:component, _jsPlumb:component._jsPlumb.instance});
+ } else {
+ _newOverlay = o;
+ }
+
+ component._jsPlumb.overlays.push(_newOverlay);
+ },
+ _calculateOverlaysToAdd = function(component, params) {
+ var defaultKeys = component.defaultOverlayKeys || [], o = params.overlays,
+ checkKey = function(k) {
+ return component._jsPlumb.instance.Defaults[k] || jsPlumb.Defaults[k] || [];
+ };
+
+ if (!o) o = [];
+
+ for (var i = 0, j = defaultKeys.length; i < j; i++)
+ o.unshift.apply(o, checkKey(defaultKeys[i]));
+
+ return o;
+ },
+ OverlayCapableJsPlumbUIComponent = window.OverlayCapableJsPlumbUIComponent = function(params) {
+
+ jsPlumbUIComponent.apply(this, arguments);
+ this._jsPlumb.overlays = [];
+
+ var _overlays = _calculateOverlaysToAdd(this, params);
+ if (_overlays) {
+ for (var i = 0, j = _overlays.length; i < j; i++) {
+ _processOverlay(this, _overlays[i]);
+ }
+ }
+
+ if (params.label) {
+ var loc = params.labelLocation || this.defaultLabelLocation || 0.5,
+ labelStyle = params.labelStyle || this._jsPlumb.instance.Defaults.LabelStyle || jsPlumb.Defaults.LabelStyle;
+
+ this._jsPlumb.overlays.push(_makeLabelOverlay(this, {
+ label:params.label,
+ location:loc,
+ labelStyle:labelStyle
+ }));
+ }
+ };
+
+ jsPlumbUtil.extend(OverlayCapableJsPlumbUIComponent, jsPlumbUIComponent, {
+ applyType : function(t, doNotRepaint) {
+ this.removeAllOverlays(doNotRepaint);
+ if (t.overlays) {
+ for (var i = 0, j = t.overlays.length; i < j; i++)
+ this.addOverlay(t.overlays[i], true);
+ }
+ },
+ setHover : function(hover, ignoreAttachedElements, timestamp) {
+ if (this._jsPlumb && !this._jsPlumb.instance.isConnectionBeingDragged()) {
+ for (var i = 0, j = this._jsPlumb.overlays.length; i < j; i++) {
+ this._jsPlumb.overlays[i][hover ? "addClass":"removeClass"](this._jsPlumb.instance.hoverClass);
+ }
+ }
+ },
+ addOverlay : function(overlay, doNotRepaint) {
+ _processOverlay(this, overlay);
+ if (!doNotRepaint) this.repaint();
+ },
+ getOverlay : function(id) {
+ var idx = _getOverlayIndex(this, id);
+ return idx >= 0 ? this._jsPlumb.overlays[idx] : null;
+ },
+ getOverlays : function() {
+ return this._jsPlumb.overlays;
+ },
+ hideOverlay : function(id) {
+ var o = this.getOverlay(id);
+ if (o) o.hide();
+ },
+ hideOverlays : function() {
+ for (var i = 0, j = this._jsPlumb.overlays.length; i < j; i++)
+ this._jsPlumb.overlays[i].hide();
+ },
+ showOverlay : function(id) {
+ var o = this.getOverlay(id);
+ if (o) o.show();
+ },
+ showOverlays : function() {
+ for (var i = 0, j = this._jsPlumb.overlays.length; i < j; i++)
+ this._jsPlumb.overlays[i].show();
+ },
+ removeAllOverlays : function(doNotRepaint) {
+ for (var i = 0, j = this._jsPlumb.overlays.length; i < j; i++) {
+ if (this._jsPlumb.overlays[i].cleanup) this._jsPlumb.overlays[i].cleanup();
+ }
+
+ this._jsPlumb.overlays.splice(0, this._jsPlumb.overlays.length);
+ if (!doNotRepaint)
+ this.repaint();
+ },
+ removeOverlay : function(overlayId) {
+ var idx = _getOverlayIndex(this, overlayId);
+ if (idx != -1) {
+ var o = this._jsPlumb.overlays[idx];
+ if (o.cleanup) o.cleanup();
+ this._jsPlumb.overlays.splice(idx, 1);
+ }
+ },
+ removeOverlays : function() {
+ for (var i = 0, j = arguments.length; i < j; i++)
+ this.removeOverlay(arguments[i]);
+ },
+ getLabel : function() {
+ var lo = this.getOverlay(_internalLabelOverlayId);
+ return lo != null ? lo.getLabel() : null;
+ },
+ getLabelOverlay : function() {
+ return this.getOverlay(_internalLabelOverlayId);
+ },
+ setLabel : function(l) {
+ var lo = this.getOverlay(_internalLabelOverlayId);
+ if (!lo) {
+ var params = l.constructor == String || l.constructor == Function ? { label:l } : l;
+ lo = _makeLabelOverlay(this, params);
+ this._jsPlumb.overlays.push(lo);
+ }
+ else {
+ if (l.constructor == String || l.constructor == Function) lo.setLabel(l);
+ else {
+ if (l.label) lo.setLabel(l.label);
+ if (l.location) lo.setLocation(l.location);
+ }
+ }
+
+ if (!this._jsPlumb.instance.isSuspendDrawing())
+ this.repaint();
+ },
+ cleanup:function() {
+ for (var i = 0; i < this._jsPlumb.overlays.length; i++) {
+ this._jsPlumb.overlays[i].cleanup();
+ this._jsPlumb.overlays[i].destroy();
+ }
+ this._jsPlumb.overlays.splice(0);
+ }
+ });
+
+// ------------------------------ END OverlayCapablejsPlumbUIComponent --------------------------------------------
+
+ var _jsPlumbInstanceIndex = 0,
+ getInstanceIndex = function() {
+ var i = _jsPlumbInstanceIndex + 1;
+ _jsPlumbInstanceIndex++;
+ return i;
+ };
+
+ var jsPlumbInstance = window.jsPlumbInstance = function(_defaults) {
+
+ this.Defaults = {
+ Anchor : "BottomCenter",
+ Anchors : [ null, null ],
+ ConnectionsDetachable : true,
+ ConnectionOverlays : [ ],
+ Connector : "Bezier",
+ Container : null,
+ DoNotThrowErrors:false,
+ DragOptions : { },
+ DropOptions : { },
+ Endpoint : "Dot",
+ EndpointOverlays : [ ],
+ Endpoints : [ null, null ],
+ EndpointStyle : { fillStyle : "#456" },
+ EndpointStyles : [ null, null ],
+ EndpointHoverStyle : null,
+ EndpointHoverStyles : [ null, null ],
+ HoverPaintStyle : null,
+ LabelStyle : { color : "black" },
+ LogEnabled : false,
+ Overlays : [ ],
+ MaxConnections : 1,
+ PaintStyle : { lineWidth : 8, strokeStyle : "#456" },
+ ReattachConnections:false,
+ RenderMode : "svg",
+ Scope : "jsPlumb_DefaultScope"
+ };
+ if (_defaults) jsPlumb.extend(this.Defaults, _defaults);
+
+ this.logEnabled = this.Defaults.LogEnabled;
+ this._connectionTypes = {};
+ this._endpointTypes = {};
+
+ jsPlumbUtil.EventGenerator.apply(this);
+
+ var _currentInstance = this,
+ _instanceIndex = getInstanceIndex(),
+ _bb = _currentInstance.bind,
+ _initialDefaults = {},
+ _zoom = 1,
+ _info = function(el) {
+ var _el = _dom(el);
+ return { el:_el, id:(jsPlumbUtil.isString(el) && _el == null) ? el : _getId(_el) };
+ };
+
+ this.getInstanceIndex = function() { return _instanceIndex; };
+
+ this.setZoom = function(z, repaintEverything) {
+ _zoom = z;
+ if (repaintEverything) _currentInstance.repaintEverything();
+ };
+ this.getZoom = function() { return _zoom; };
+
+ for (var i in this.Defaults)
+ _initialDefaults[i] = this.Defaults[i];
+
+ this.bind = function(event, fn) {
+ if ("ready" === event && initialized) fn();
+ else _bb.apply(_currentInstance,[event, fn]);
+ };
+
+ _currentInstance.importDefaults = function(d) {
+ for (var i in d) {
+ _currentInstance.Defaults[i] = d[i];
+ }
+ return _currentInstance;
+ };
+
+ _currentInstance.restoreDefaults = function() {
+ _currentInstance.Defaults = jsPlumb.extend({}, _initialDefaults);
+ return _currentInstance;
+ };
+
+ var log = null,
+ resizeTimer = null,
+ initialized = false,
+ // TODO remove from window scope
+ connections = [],
+ // map of element id -> endpoint lists. an element can have an arbitrary
+ // number of endpoints on it, and not all of them have to be connected
+ // to anything.
+ endpointsByElement = {},
+ endpointsByUUID = {},
+ offsets = {},
+ offsetTimestamps = {},
+ floatingConnections = {},
+ draggableStates = {},
+ connectionBeingDragged = false,
+ sizes = [],
+ _suspendDrawing = false,
+ _suspendedAt = null,
+ DEFAULT_SCOPE = this.Defaults.Scope,
+ renderMode = null, // will be set in init()
+ _curIdStamp = 1,
+ _idstamp = function() { return "" + _curIdStamp++; },
+
+ //
+ // appends an element to some other element, which is calculated as follows:
+ //
+ // 1. if _currentInstance.Defaults.Container exists, use that element.
+ // 2. if the 'parent' parameter exists, use that.
+ // 3. otherwise just use the root element (for DOM usage, the document body).
+ //
+ //
+ _appendElement = function(el, parent) {
+ if (_currentInstance.Defaults.Container)
+ jsPlumb.CurrentLibrary.appendElement(el, _currentInstance.Defaults.Container);
+ else if (!parent)
+ jsPlumbAdapter.appendToRoot(el);
+ else
+ jsPlumb.CurrentLibrary.appendElement(el, parent);
+ },
+
+ //
+ // YUI, for some reason, put the result of a Y.all call into an object that contains
+ // a '_nodes' array, instead of handing back an array-like object like the other
+ // libraries do.
+ //
+ _convertYUICollection = function(c) {
+ return c._nodes ? c._nodes : c;
+ },
+
+ //
+ // Draws an endpoint and its connections. this is the main entry point into drawing connections as well
+ // as endpoints, since jsPlumb is endpoint-centric under the hood.
+ //
+ // @param element element to draw (of type library specific element object)
+ // @param ui UI object from current library's event system. optional.
+ // @param timestamp timestamp for this paint cycle. used to speed things up a little by cutting down the amount of offset calculations we do.
+ // @param clearEdits defaults to false; indicates that mouse edits for connectors should be cleared
+ ///
+ _draw = function(element, ui, timestamp, clearEdits) {
+
+ // TODO is it correct to filter by headless at this top level? how would a headless adapter ever repaint?
+ if (!jsPlumbAdapter.headless && !_suspendDrawing) {
+ var id = _getId(element),
+ repaintEls = _currentInstance.dragManager.getElementsForDraggable(id);
+
+ if (timestamp == null) timestamp = _timestamp();
+
+ // update the offset of everything _before_ we try to draw anything.
+ var o = _updateOffset( { elId : id, offset : ui, recalc : false, timestamp : timestamp });
+
+ if (repaintEls) {
+ for (var i in repaintEls) {
+ _updateOffset( {
+ elId : repaintEls[i].id,
+ offset : {
+ left:o.o.left + repaintEls[i].offset.left,
+ top:o.o.top + repaintEls[i].offset.top
+ },
+ recalc : false,
+ timestamp : timestamp
+ });
+ }
+ }
+
+
+ _currentInstance.anchorManager.redraw(id, ui, timestamp, null, clearEdits);
+
+ if (repaintEls) {
+ for (var j in repaintEls) {
+ _currentInstance.anchorManager.redraw(repaintEls[j].id, ui, timestamp, repaintEls[j].offset, clearEdits, true);
+ }
+ }
+ }
+ },
+
+ //
+ // executes the given function against the given element if the first
+ // argument is an object, or the list of elements, if the first argument
+ // is a list. the function passed in takes (element, elementId) as
+ // arguments.
+ //
+ _elementProxy = function(element, fn) {
+ var retVal = null, el, id;
+ if (_ju.isArray(element)) {
+ retVal = [];
+ for ( var i = 0, j = element.length; i < j; i++) {
+ el = _gel(element[i]);
+ id = _currentInstance.getAttribute(el, "id");
+ retVal.push(fn(el, id)); // append return values to what we will return
+ }
+ } else {
+ el = _gel(element);
+ id = _currentInstance.getAttribute(el, "id");
+ retVal = fn(el, id);
+ }
+ return retVal;
+ },
+
+ //
+ // gets an Endpoint by uuid.
+ //
+ _getEndpoint = function(uuid) { return endpointsByUUID[uuid]; },
+
+ /**
+ * inits a draggable if it's not already initialised.
+ * TODO: somehow abstract this to the adapter, because the concept of "draggable" has no
+ * place on the server.
+ */
+ _initDraggableIfNecessary = function(element, isDraggable, dragOptions) {
+ // TODO move to DragManager?
+ if (!jsPlumbAdapter.headless) {
+ var _draggable = isDraggable == null ? false : isDraggable, jpcl = jsPlumb.CurrentLibrary;
+ if (_draggable) {
+ if (jpcl.isDragSupported(element) && !jpcl.isAlreadyDraggable(element)) {
+ var options = dragOptions || _currentInstance.Defaults.DragOptions || jsPlumb.Defaults.DragOptions;
+ options = jsPlumb.extend( {}, options); // make a copy.
+ var dragEvent = jpcl.dragEvents.drag,
+ stopEvent = jpcl.dragEvents.stop,
+ startEvent = jpcl.dragEvents.start;
+
+ options[startEvent] = _ju.wrap(options[startEvent], function() {
+ _currentInstance.setHoverSuspended(true);
+ _currentInstance.select({source:element}).addClass(_currentInstance.elementDraggingClass + " " + _currentInstance.sourceElementDraggingClass, true);
+ _currentInstance.select({target:element}).addClass(_currentInstance.elementDraggingClass + " " + _currentInstance.targetElementDraggingClass, true);
+ _currentInstance.setConnectionBeingDragged(true);
+ });
+
+ options[dragEvent] = _ju.wrap(options[dragEvent], function() {
+ var ui = jpcl.getUIPosition(arguments, _currentInstance.getZoom());
+ _draw(element, ui, null, true);
+ _addClass(element, "jsPlumb_dragged");
+ });
+ options[stopEvent] = _ju.wrap(options[stopEvent], function() {
+ var ui = jpcl.getUIPosition(arguments, _currentInstance.getZoom());
+ _draw(element, ui);
+ _removeClass(element, "jsPlumb_dragged");
+ _currentInstance.setHoverSuspended(false);
+ _currentInstance.select({source:element}).removeClass(_currentInstance.elementDraggingClass + " " + _currentInstance.sourceElementDraggingClass, true);
+ _currentInstance.select({target:element}).removeClass(_currentInstance.elementDraggingClass + " " + _currentInstance.targetElementDraggingClass, true);
+ _currentInstance.setConnectionBeingDragged(false);
+ });
+ var elId = _getId(element); // need ID
+ draggableStates[elId] = true;
+ var draggable = draggableStates[elId];
+ options.disabled = draggable == null ? false : !draggable;
+ jpcl.initDraggable(element, options, false, _currentInstance);
+ _currentInstance.dragManager.register(element);
+ }
+ }
+ }
+ },
+
+ /*
+ * prepares a final params object that can be passed to _newConnection, taking into account defaults, events, etc.
+ */
+ _prepareConnectionParams = function(params, referenceParams) {
+ var _p = jsPlumb.extend( { }, params);
+ if (referenceParams) jsPlumb.extend(_p, referenceParams);
+
+ // hotwire endpoints passed as source or target to sourceEndpoint/targetEndpoint, respectively.
+ if (_p.source) {
+ if (_p.source.endpoint)
+ _p.sourceEndpoint = _p.source;
+ else
+ _p.source = _dom(_p.source);
+ }
+ if (_p.target) {
+ if (_p.target.endpoint)
+ _p.targetEndpoint = _p.target;
+ else
+ _p.target = _dom(_p.target);
+ }
+
+ // test for endpoint uuids to connect
+ if (params.uuids) {
+ _p.sourceEndpoint = _getEndpoint(params.uuids[0]);
+ _p.targetEndpoint = _getEndpoint(params.uuids[1]);
+ }
+
+ // now ensure that if we do have Endpoints already, they're not full.
+ // source:
+ if (_p.sourceEndpoint && _p.sourceEndpoint.isFull()) {
+ _ju.log(_currentInstance, "could not add connection; source endpoint is full");
+ return;
+ }
+
+ // target:
+ if (_p.targetEndpoint && _p.targetEndpoint.isFull()) {
+ _ju.log(_currentInstance, "could not add connection; target endpoint is full");
+ return;
+ }
+
+ // if source endpoint mandates connection type and nothing specified in our params, use it.
+ if (!_p.type && _p.sourceEndpoint)
+ _p.type = _p.sourceEndpoint.connectionType;
+
+ // copy in any connectorOverlays that were specified on the source endpoint.
+ // it doesnt copy target endpoint overlays. i'm not sure if we want it to or not.
+ if (_p.sourceEndpoint && _p.sourceEndpoint.connectorOverlays) {
+ _p.overlays = _p.overlays || [];
+ for (var i = 0, j = _p.sourceEndpoint.connectorOverlays.length; i < j; i++) {
+ _p.overlays.push(_p.sourceEndpoint.connectorOverlays[i]);
+ }
+ }
+
+ // pointer events
+ if (!_p["pointer-events"] && _p.sourceEndpoint && _p.sourceEndpoint.connectorPointerEvents)
+ _p["pointer-events"] = _p.sourceEndpoint.connectorPointerEvents;
+
+ // if there's a target specified (which of course there should be), and there is no
+ // target endpoint specified, and 'newConnection' was not set to true, then we check to
+ // see if a prior call to makeTarget has provided us with the specs for the target endpoint, and
+ // we use those if so. additionally, if the makeTarget call was specified with 'uniqueEndpoint' set
+ // to true, then if that target endpoint has already been created, we re-use it.
+
+ var tid, tep, existingUniqueEndpoint, newEndpoint;
+
+ // TODO: this code can be refactored to be a little dry.
+ if (_p.target && !_p.target.endpoint && !_p.targetEndpoint && !_p.newConnection) {
+ tid = _getId(_p.target);
+ tep =_targetEndpointDefinitions[tid];
+ existingUniqueEndpoint = _targetEndpoints[tid];
+
+ if (tep) {
+ // if target not enabled, return.
+ if (!_targetsEnabled[tid]) return;
+
+ tep.isTarget = true;
+ // check for max connections??
+ newEndpoint = existingUniqueEndpoint != null ? existingUniqueEndpoint : _currentInstance.addEndpoint(_p.target, tep);
+ if (_targetEndpointsUnique[tid]) _targetEndpoints[tid] = newEndpoint;
+ _p.targetEndpoint = newEndpoint;
+ // TODO test options to makeTarget to see if we should do this?
+ newEndpoint._doNotDeleteOnDetach = false; // reset.
+ newEndpoint._deleteOnDetach = true;
+ }
+ }
+
+ // same thing, but for source.
+ if (_p.source && !_p.source.endpoint && !_p.sourceEndpoint && !_p.newConnection) {
+ tid = _getId(_p.source);
+ tep = _sourceEndpointDefinitions[tid];
+ existingUniqueEndpoint = _sourceEndpoints[tid];
+
+ if (tep) {
+ // if source not enabled, return.
+ if (!_sourcesEnabled[tid]) return;
+
+ newEndpoint = existingUniqueEndpoint != null ? existingUniqueEndpoint : _currentInstance.addEndpoint(_p.source, tep);
+ if (_sourceEndpointsUnique[tid]) _sourceEndpoints[tid] = newEndpoint;
+ _p.sourceEndpoint = newEndpoint;
+ // TODO test options to makeSource to see if we should do this?
+ newEndpoint._doNotDeleteOnDetach = false; // reset.
+ newEndpoint._deleteOnDetach = true;
+ }
+ }
+
+ return _p;
+ },
+
+ _newConnection = function(params) {
+ var connectionFunc = _currentInstance.Defaults.ConnectionType || _currentInstance.getDefaultConnectionType(),
+ endpointFunc = _currentInstance.Defaults.EndpointType || jsPlumb.Endpoint,
+ parent = jsPlumb.CurrentLibrary.getParent;
+
+ if (params.container)
+ params.parent = params.container;
+ else {
+ if (params.sourceEndpoint)
+ params.parent = params.sourceEndpoint.parent;
+ else if (params.source.constructor == endpointFunc)
+ params.parent = params.source.parent;
+ else params.parent = parent(params.source);
+ }
+
+ params._jsPlumb = _currentInstance;
+ params.newConnection = _newConnection;
+ params.newEndpoint = _newEndpoint;
+ params.endpointsByUUID = endpointsByUUID;
+ params.endpointsByElement = endpointsByElement;
+ params.finaliseConnection = _finaliseConnection;
+ var con = new connectionFunc(params);
+ con.id = "con_" + _idstamp();
+ _eventFireProxy("click", "click", con);
+ _eventFireProxy("dblclick", "dblclick", con);
+ _eventFireProxy("contextmenu", "contextmenu", con);
+ return con;
+ },
+
+ //
+ // adds the connection to the backing model, fires an event if necessary and then redraws
+ //
+ _finaliseConnection = function(jpc, params, originalEvent, doInformAnchorManager) {
+ params = params || {};
+ // add to list of connections (by scope).
+ if (!jpc.suspendedEndpoint)
+ connections.push(jpc);
+
+ // always inform the anchor manager
+ // except that if jpc has a suspended endpoint it's not true to say the
+ // connection is new; it has just (possibly) moved. the question is whether
+ // to make that call here or in the anchor manager. i think perhaps here.
+ if (jpc.suspendedEndpoint == null || doInformAnchorManager)
+ _currentInstance.anchorManager.newConnection(jpc);
+
+ // force a paint
+ _draw(jpc.source);
+
+ // fire an event
+ if (!params.doNotFireConnectionEvent && params.fireEvent !== false) {
+
+ var eventArgs = {
+ connection:jpc,
+ source : jpc.source, target : jpc.target,
+ sourceId : jpc.sourceId, targetId : jpc.targetId,
+ sourceEndpoint : jpc.endpoints[0], targetEndpoint : jpc.endpoints[1]
+ };
+
+ _currentInstance.fire("connection", eventArgs, originalEvent);
+ }
+ },
+
+ _eventFireProxy = function(event, proxyEvent, obj) {
+ obj.bind(event, function(originalObject, originalEvent) {
+ _currentInstance.fire(proxyEvent, obj, originalEvent);
+ });
+ },
+
+ /*
+ * for the given endpoint params, returns an appropriate parent element for the UI elements that will be added.
+ * this function is used by _newEndpoint (directly below), and also in the makeSource function in jsPlumb.
+ *
+ * the logic is to first look for a "container" member of params, and pass that back if found. otherwise we
+ * handoff to the 'getParent' function in the current library.
+ */
+ _getParentFromParams = function(params) {
+ if (params.container)
+ return params.container;
+ else {
+ var tag = jsPlumb.CurrentLibrary.getTagName(params.source),
+ p = jsPlumb.CurrentLibrary.getParent(params.source);
+ if (tag && tag.toLowerCase() === "td")
+ return jsPlumb.CurrentLibrary.getParent(p);
+ else return p;
+ }
+ },
+
+ /*
+ factory method to prepare a new endpoint. this should always be used instead of creating Endpoints
+ manually, since this method attaches event listeners and an id.
+ */
+ _newEndpoint = function(params) {
+ var endpointFunc = _currentInstance.Defaults.EndpointType || jsPlumb.Endpoint;
+ var _p = jsPlumb.extend({}, params);
+ _p.parent = _getParentFromParams(_p);
+ _p._jsPlumb = _currentInstance;
+ _p.newConnection = _newConnection;
+ _p.newEndpoint = _newEndpoint;
+ _p.endpointsByUUID = endpointsByUUID;
+ _p.endpointsByElement = endpointsByElement;
+ _p.finaliseConnection = _finaliseConnection;
+ _p.fireDetachEvent = fireDetachEvent;
+ _p.floatingConnections = floatingConnections;
+ _p.getParentFromParams = _getParentFromParams;
+ _p.elementId = _getId(_p.source);
+ var ep = new endpointFunc(_p);
+ ep.id = "ep_" + _idstamp();
+ _eventFireProxy("click", "endpointClick", ep);
+ _eventFireProxy("dblclick", "endpointDblClick", ep);
+ _eventFireProxy("contextmenu", "contextmenu", ep);
+ if (!jsPlumbAdapter.headless)
+ _currentInstance.dragManager.endpointAdded(_p.source);
+ return ep;
+ },
+
+ /*
+ * performs the given function operation on all the connections found
+ * for the given element id; this means we find all the endpoints for
+ * the given element, and then for each endpoint find the connectors
+ * connected to it. then we pass each connection in to the given
+ * function.
+ */
+ _operation = function(elId, func, endpointFunc) {
+ var endpoints = endpointsByElement[elId];
+ if (endpoints && endpoints.length) {
+ for ( var i = 0, ii = endpoints.length; i < ii; i++) {
+ for ( var j = 0, jj = endpoints[i].connections.length; j < jj; j++) {
+ var retVal = func(endpoints[i].connections[j]);
+ // if the function passed in returns true, we exit.
+ // most functions return false.
+ if (retVal) return;
+ }
+ if (endpointFunc) endpointFunc(endpoints[i]);
+ }
+ }
+ },
+
+ _setDraggable = function(element, draggable) {
+ return _elementProxy(element, function(el, id) {
+ draggableStates[id] = draggable;
+ if (jsPlumb.CurrentLibrary.isDragSupported(el)) {
+ jsPlumb.CurrentLibrary.setDraggable(el, draggable);
+ }
+ });
+ },
+ /*
+ * private method to do the business of hiding/showing.
+ *
+ * @param el
+ * either Id of the element in question or a library specific
+ * object for the element.
+ * @param state
+ * String specifying a value for the css 'display' property
+ * ('block' or 'none').
+ */
+ _setVisible = function(el, state, alsoChangeEndpoints) {
+ state = state === "block";
+ var endpointFunc = null;
+ if (alsoChangeEndpoints) {
+ if (state) endpointFunc = function(ep) {
+ ep.setVisible(true, true, true);
+ };
+ else endpointFunc = function(ep) {
+ ep.setVisible(false, true, true);
+ };
+ }
+ var info = _info(el);
+ _operation(info.id, function(jpc) {
+ if (state && alsoChangeEndpoints) {
+ // this test is necessary because this functionality is new, and i wanted to maintain backwards compatibility.
+ // this block will only set a connection to be visible if the other endpoint in the connection is also visible.
+ var oidx = jpc.sourceId === info.id ? 1 : 0;
+ if (jpc.endpoints[oidx].isVisible()) jpc.setVisible(true);
+ }
+ else // the default behaviour for show, and what always happens for hide, is to just set the visibility without getting clever.
+ jpc.setVisible(state);
+ }, endpointFunc);
+ },
+ /*
+ * toggles the draggable state of the given element(s).
+ * el is either an id, or an element object, or a list of ids/element objects.
+ */
+ _toggleDraggable = function(el) {
+ return _elementProxy(el, function(el, elId) {
+ var state = draggableStates[elId] == null ? false : draggableStates[elId];
+ state = !state;
+ draggableStates[elId] = state;
+ jsPlumb.CurrentLibrary.setDraggable(el, state);
+ return state;
+ });
+ },
+ /**
+ * private method to do the business of toggling hiding/showing.
+ */
+ _toggleVisible = function(elId, changeEndpoints) {
+ var endpointFunc = null;
+ if (changeEndpoints) {
+ endpointFunc = function(ep) {
+ var state = ep.isVisible();
+ ep.setVisible(!state);
+ };
+ }
+ _operation(elId, function(jpc) {
+ var state = jpc.isVisible();
+ jpc.setVisible(!state);
+ }, endpointFunc);
+ // todo this should call _elementProxy, and pass in the
+ // _operation(elId, f) call as a function. cos _toggleDraggable does
+ // that.
+ },
+ /**
+ * updates the offset and size for a given element, and stores the
+ * values. if 'offset' is not null we use that (it would have been
+ * passed in from a drag call) because it's faster; but if it is null,
+ * or if 'recalc' is true in order to force a recalculation, we get the current values.
+ */
+ _updateOffset = function(params) {
+ var timestamp = params.timestamp, recalc = params.recalc, offset = params.offset, elId = params.elId, s;
+ if (_suspendDrawing && !timestamp) timestamp = _suspendedAt;
+ if (!recalc) {
+ if (timestamp && timestamp === offsetTimestamps[elId]) {
+ return {o:params.offset || offsets[elId], s:sizes[elId]};
+ }
+ }
+ if (recalc || !offset) { // if forced repaint or no offset available, we recalculate.
+ // get the current size and offset, and store them
+ s = _gel(elId);
+ if (s != null) {
+ sizes[elId] = _getSize(s);
+ offsets[elId] = _getOffset(s, _currentInstance);
+ offsetTimestamps[elId] = timestamp;
+ }
+ } else {
+ offsets[elId] = offset;
+ if (sizes[elId] == null) {
+ s = _gel(elId);
+ if (s != null) sizes[elId] = _getSize(s);
+ }
+ offsetTimestamps[elId] = timestamp;
+ }
+
+ if(offsets[elId] && !offsets[elId].right) {
+ offsets[elId].right = offsets[elId].left + sizes[elId][0];
+ offsets[elId].bottom = offsets[elId].top + sizes[elId][1];
+ offsets[elId].width = sizes[elId][0];
+ offsets[elId].height = sizes[elId][1];
+ offsets[elId].centerx = offsets[elId].left + (offsets[elId].width / 2);
+ offsets[elId].centery = offsets[elId].top + (offsets[elId].height / 2);
+ }
+ return {o:offsets[elId], s:sizes[elId]};
+ },
+
+ // TODO comparison performance
+ _getCachedData = function(elId) {
+ var o = offsets[elId];
+ if (!o)
+ return _updateOffset({elId:elId});
+ else
+ return {o:o, s:sizes[elId]};
+ },
+
+ /**
+ * gets an id for the given element, creating and setting one if
+ * necessary. the id is of the form
+ *
+ * jsPlumb_<instance index>_<index in instance>
+ *
+ * where "index in instance" is a monotonically increasing integer that starts at 0,
+ * for each instance. this method is used not only to assign ids to elements that do not
+ * have them but also to connections and endpoints.
+ */
+ _getId = function(element, uuid, doNotCreateIfNotFound) {
+ if (jsPlumbUtil.isString(element)) return element;
+ if (element == null) return null;
+ var id = jsPlumbAdapter.getAttribute(element, "id");
+ if (!id || id === "undefined") {
+ // check if fixed uuid parameter is given
+ if (arguments.length == 2 && arguments[1] !== undefined)
+ id = uuid;
+ else if (arguments.length == 1 || (arguments.length == 3 && !arguments[2]))
+ id = "jsPlumb_" + _instanceIndex + "_" + _idstamp();
+
+ if (!doNotCreateIfNotFound) jsPlumbAdapter.setAttribute(element, "id", id);
+ }
+ return id;
+ };
+
+ this.setConnectionBeingDragged = function(v) {
+ connectionBeingDragged = v;
+ };
+ this.isConnectionBeingDragged = function() {
+ return connectionBeingDragged;
+ };
+
+ this.connectorClass = "_jsPlumb_connector";
+ this.hoverClass = "_jsPlumb_hover";
+ this.endpointClass = "_jsPlumb_endpoint";
+ this.endpointConnectedClass = "_jsPlumb_endpoint_connected";
+ this.endpointFullClass = "_jsPlumb_endpoint_full";
+ this.endpointDropAllowedClass = "_jsPlumb_endpoint_drop_allowed";
+ this.endpointDropForbiddenClass = "_jsPlumb_endpoint_drop_forbidden";
+ this.overlayClass = "_jsPlumb_overlay";
+ this.draggingClass = "_jsPlumb_dragging";
+ this.elementDraggingClass = "_jsPlumb_element_dragging";
+ this.sourceElementDraggingClass = "_jsPlumb_source_element_dragging";
+ this.targetElementDraggingClass = "_jsPlumb_target_element_dragging";
+ this.endpointAnchorClassPrefix = "_jsPlumb_endpoint_anchor";
+ this.hoverSourceClass = "_jsPlumb_source_hover";
+ this.hoverTargetClass = "_jsPlumb_target_hover";
+ this.dragSelectClass = "_jsPlumb_drag_select";
+
+ this.Anchors = {};
+ this.Connectors = { "canvas":{}, "svg":{}, "vml":{} };
+ this.Endpoints = { "canvas":{}, "svg":{}, "vml":{} };
+ this.Overlays = { "canvas":{}, "svg":{}, "vml":{}};
+ this.ConnectorRenderers = {};
+ this.SVG = "svg";
+ this.CANVAS = "canvas";
+ this.VML = "vml";
+
+
+// --------------------------- jsPLumbInstance public API ---------------------------------------------------------
+
+
+ this.addEndpoint = function(el, params, referenceParams) {
+ referenceParams = referenceParams || {};
+ var p = jsPlumb.extend({}, referenceParams);
+ jsPlumb.extend(p, params);
+ p.endpoint = p.endpoint || _currentInstance.Defaults.Endpoint || jsPlumb.Defaults.Endpoint;
+ p.paintStyle = p.paintStyle || _currentInstance.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle;
+ // YUI wrapper
+ el = _convertYUICollection(el);
+
+ var results = [],
+ inputs = (_ju.isArray(el) || (el.length != null && !_ju.isString(el))) ? el : [ el ];
+
+ for (var i = 0, j = inputs.length; i < j; i++) {
+ var _el = _dom(inputs[i]), id = _getId(_el);
+ p.source = _el;
+
+ _updateOffset({ elId : id, timestamp:_suspendedAt });
+ var e = _newEndpoint(p);
+ if (p.parentAnchor) e.parentAnchor = p.parentAnchor;
+ _ju.addToList(endpointsByElement, id, e);
+ var myOffset = offsets[id],
+ myWH = sizes[id],
+ anchorLoc = e.anchor.compute( { xy : [ myOffset.left, myOffset.top ], wh : myWH, element : e, timestamp:_suspendedAt }),
+ endpointPaintParams = { anchorLoc : anchorLoc, timestamp:_suspendedAt };
+
+ if (_suspendDrawing) endpointPaintParams.recalc = false;
+ if (!_suspendDrawing) e.paint(endpointPaintParams);
+
+ results.push(e);
+ e._doNotDeleteOnDetach = true; // mark this as being added via addEndpoint.
+ }
+
+ return results.length == 1 ? results[0] : results;
+ };
+
+
+ this.addEndpoints = function(el, endpoints, referenceParams) {
+ var results = [];
+ for ( var i = 0, j = endpoints.length; i < j; i++) {
+ var e = _currentInstance.addEndpoint(el, endpoints[i], referenceParams);
+ if (_ju.isArray(e))
+ Array.prototype.push.apply(results, e);
+ else results.push(e);
+ }
+ return results;
+ };
+
+ this.animate = function(el, properties, options) {
+ options = options || {};
+ var ele = _gel(el),
+ id = _getId(el),
+ stepFunction = jsPlumb.CurrentLibrary.dragEvents.step,
+ completeFunction = jsPlumb.CurrentLibrary.dragEvents.complete;
+
+ options[stepFunction] = _ju.wrap(options[stepFunction], function() {
+ _currentInstance.repaint(id);
+ });
+
+ // onComplete repaints, just to make sure everything looks good at the end of the animation.
+ options[completeFunction] = _ju.wrap(options[completeFunction], function() {
+ _currentInstance.repaint(id);
+ });
+
+ jsPlumb.CurrentLibrary.animate(ele, properties, options);
+ };
+
+ /**
+ * checks for a listener for the given condition, executing it if found, passing in the given value.
+ * condition listeners would have been attached using "bind" (which is, you could argue, now overloaded, since
+ * firing click events etc is a bit different to what this does). i thought about adding a "bindCondition"
+ * or something, but decided against it, for the sake of simplicity. jsPlumb will never fire one of these
+ * condition events anyway.
+ */
+ this.checkCondition = function(conditionName, value) {
+ var l = _currentInstance.getListener(conditionName),
+ r = true;
+
+ if (l && l.length > 0) {
+ try {
+ for (var i = 0, j = l.length; i < j; i++) {
+ r = r && l[i](value);
+ }
+ }
+ catch (e) {
+ _ju.log(_currentInstance, "cannot check condition [" + conditionName + "]" + e);
+ }
+ }
+ return r;
+ };
+
+ /**
+ * checks a condition asynchronously: fires the event handler and passes the handler
+ * a 'proceed' function and a 'stop' function. The handler MUST execute one or other
+ * of these once it has made up its mind.
+ *
+ * Note that although this reads the listener list for the given condition, it
+ * does not loop through and hit each listener, because that, with asynchronous
+ * callbacks, would be messy. so it uses only the first listener registered.
+ */
+ this.checkASyncCondition = function(conditionName, value, proceed, stop) {
+ var l = _currentInstance.getListener(conditionName);
+
+ if (l && l.length > 0) {
+ try {
+ l[0](value, proceed, stop);
+ }
+ catch (e) {
+ _ju.log(_currentInstance, "cannot asynchronously check condition [" + conditionName + "]" + e);
+ }
+ }
+ };
+
+
+ this.connect = function(params, referenceParams) {
+ // prepare a final set of parameters to create connection with
+ var _p = _prepareConnectionParams(params, referenceParams), jpc;
+ // TODO probably a nicer return value if the connection was not made. _prepareConnectionParams
+ // will return null (and log something) if either endpoint was full. what would be nicer is to
+ // create a dedicated 'error' object.
+ if (_p) {
+ // create the connection. it is not yet registered
+ jpc = _newConnection(_p);
+ // now add it the model, fire an event, and redraw
+ _finaliseConnection(jpc, _p);
+ }
+ return jpc;
+ };
+
+ this.deleteEndpoint = function(object, doNotRepaintAfterwards) {
+ var _is = _currentInstance.setSuspendDrawing(true);
+ var endpoint = (typeof object == "string") ? endpointsByUUID[object] : object;
+ if (endpoint) {
+ _currentInstance.deleteObject({endpoint:endpoint});
+ }
+ if(!_is) _currentInstance.setSuspendDrawing(false, doNotRepaintAfterwards);
+ return _currentInstance;
+ };
+
+
+ this.deleteEveryEndpoint = function() {
+ var _is = _currentInstance.setSuspendDrawing(true);
+ for ( var id in endpointsByElement) {
+ var endpoints = endpointsByElement[id];
+ if (endpoints && endpoints.length) {
+ for ( var i = 0, j = endpoints.length; i < j; i++) {
+ _currentInstance.deleteEndpoint(endpoints[i], true);
+ }
+ }
+ }
+ endpointsByElement = {};
+ endpointsByUUID = {};
+ _currentInstance.anchorManager.reset();
+ _currentInstance.dragManager.reset();
+ if(!_is) _currentInstance.setSuspendDrawing(false);
+ return _currentInstance;
+ };
+
+ var fireDetachEvent = function(jpc, doFireEvent, originalEvent) {
+ // may have been given a connection, or in special cases, an object
+ var connType = _currentInstance.Defaults.ConnectionType || _currentInstance.getDefaultConnectionType(),
+ argIsConnection = jpc.constructor == connType,
+ params = argIsConnection ? {
+ connection:jpc,
+ source : jpc.source, target : jpc.target,
+ sourceId : jpc.sourceId, targetId : jpc.targetId,
+ sourceEndpoint : jpc.endpoints[0], targetEndpoint : jpc.endpoints[1]
+ } : jpc;
+
+ if (doFireEvent)
+ _currentInstance.fire("connectionDetached", params, originalEvent);
+
+ _currentInstance.anchorManager.connectionDetached(params);
+ };
+
+ this.unregisterEndpoint = function(endpoint) {
+ if (endpoint._jsPlumb.uuid) endpointsByUUID[endpoint._jsPlumb.uuid] = null;
+ _currentInstance.anchorManager.deleteEndpoint(endpoint);
+ // TODO at least replace this with a removeWithFunction call.
+ for (var e in endpointsByElement) {
+ var endpoints = endpointsByElement[e];
+ if (endpoints) {
+ var newEndpoints = [];
+ for (var i = 0, j = endpoints.length; i < j; i++)
+ if (endpoints[i] != endpoint) newEndpoints.push(endpoints[i]);
+
+ endpointsByElement[e] = newEndpoints;
+ }
+ if(endpointsByElement[e].length <1){
+ delete endpointsByElement[e];
+ }
+ }
+ };
+
+ this.detach = function() {
+
+ if (arguments.length === 0) return;
+ var connType = _currentInstance.Defaults.ConnectionType || _currentInstance.getDefaultConnectionType(),
+ firstArgIsConnection = arguments[0].constructor == connType,
+ params = arguments.length == 2 ? firstArgIsConnection ? (arguments[1] || {}) : arguments[0] : arguments[0],
+ fireEvent = (params.fireEvent !== false),
+ forceDetach = params.forceDetach,
+ conn = firstArgIsConnection ? arguments[0] : params.connection;
+
+ if (conn) {
+ if (forceDetach || jsPlumbUtil.functionChain(true, false, [
+ [ conn.endpoints[0], "isDetachAllowed", [ conn ] ],
+ [ conn.endpoints[1], "isDetachAllowed", [ conn ] ],
+ [ conn, "isDetachAllowed", [ conn ] ],
+ [ _currentInstance, "checkCondition", [ "beforeDetach", conn ] ] ])) {
+
+ conn.endpoints[0].detach(conn, false, true, fireEvent);
+ }
+ }
+ else {
+ var _p = jsPlumb.extend( {}, params); // a backwards compatibility hack: source should be thought of as 'params' in this case.
+ // test for endpoint uuids to detach
+ if (_p.uuids) {
+ _getEndpoint(_p.uuids[0]).detachFrom(_getEndpoint(_p.uuids[1]), fireEvent);
+ } else if (_p.sourceEndpoint && _p.targetEndpoint) {
+ _p.sourceEndpoint.detachFrom(_p.targetEndpoint);
+ } else {
+ var sourceId = _getId(_dom(_p.source)),
+ targetId = _getId(_dom(_p.target));
+ _operation(sourceId, function(jpc) {
+ if ((jpc.sourceId == sourceId && jpc.targetId == targetId) || (jpc.targetId == sourceId && jpc.sourceId == targetId)) {
+ if (_currentInstance.checkCondition("beforeDetach", jpc)) {
+ jpc.endpoints[0].detach(jpc, false, true, fireEvent);
+ }
+ }
+ });
+ }
+ }
+ };
+
+ this.detachAllConnections = function(el, params) {
+ params = params || {};
+ el = _dom(el);
+ var id = _getId(el),
+ endpoints = endpointsByElement[id];
+ if (endpoints && endpoints.length) {
+ for ( var i = 0, j = endpoints.length; i < j; i++) {
+ endpoints[i].detachAll(params.fireEvent !== false);
+ }
+ }
+ return _currentInstance;
+ };
+
+ this.detachEveryConnection = function(params) {
+ params = params || {};
+ _currentInstance.doWhileSuspended(function() {
+ for ( var id in endpointsByElement) {
+ var endpoints = endpointsByElement[id];
+ if (endpoints && endpoints.length) {
+ for ( var i = 0, j = endpoints.length; i < j; i++) {
+ endpoints[i].detachAll(params.fireEvent !== false);
+ }
+ }
+ }
+ connections.splice(0);
+ });
+ return _currentInstance;
+ };
+
+ /// not public. but of course its exposed. how to change this.
+ this.deleteObject = function(params) {
+ var result = {
+ endpoints : {},
+ connections : {},
+ endpointCount:0,
+ connectionCount:0
+ },
+ fireEvent = params.fireEvent !== false,
+ deleteAttachedObjects = params.deleteAttachedObjects !== false;
+
+ var unravelConnection = function(connection) {
+ if(connection != null && result.connections[connection.id] == null) {
+ connection._jsPlumb && connection.setHover(false);
+ result.connections[connection.id] = connection;
+ result.connectionCount++;
+ if (deleteAttachedObjects) {
+ for (var j = 0; j < connection.endpoints.length; j++) {
+ if (connection.endpoints[j]._deleteOnDetach)
+ unravelEndpoint(connection.endpoints[j]);
+ }
+ }
+ }
+ };
+ var unravelEndpoint = function(endpoint) {
+ if(endpoint != null && result.endpoints[endpoint.id] == null) {
+ endpoint._jsPlumb && endpoint.setHover(false);
+ result.endpoints[endpoint.id] = endpoint;
+ result.endpointCount++;
+
+ if (deleteAttachedObjects) {
+ for (var i = 0; i < endpoint.connections.length; i++) {
+ var c = endpoint.connections[i];
+ unravelConnection(c);
+ }
+ }
+ }
+ };
+
+ if (params.connection)
+ unravelConnection(params.connection);
+ else unravelEndpoint(params.endpoint);
+
+ // loop through connections
+ for (var i in result.connections) {
+ var c = result.connections[i];
+ c.endpoints[0].detachFromConnection(c);
+ c.endpoints[1].detachFromConnection(c);
+ //_currentInstance.unregisterConnection(c);
+ jsPlumbUtil.removeWithFunction(connections, function(_c) {
+ return c.id == _c.id;
+ });
+ fireDetachEvent(c, fireEvent, params.originalEvent);
+ c.cleanup();
+ c.destroy();
+ }
+
+ // loop through endpoints
+ for (var j in result.endpoints) {
+ var e = result.endpoints[j];
+ _currentInstance.unregisterEndpoint(e);
+ // FIRE some endpoint deleted event?
+ e.cleanup();
+ e.destroy();
+ }
+
+ return result;
+ };
+
+ this.draggable = function(el, options) {
+ var i,j,ele;
+ // allows for array or jquery/mootools selector
+ if (typeof el == 'object' && el.length) {
+ for (i = 0, j = el.length; i < j; i++) {
+ ele = _dom(el[i]);
+ if (ele) _initDraggableIfNecessary(ele, true, options);
+ }
+ }
+ // allows for YUI selector
+ else if (el._nodes) { // TODO this is YUI specific; really the logic should be forced
+ // into the library adapters (for jquery and mootools aswell)
+ for (i = 0, j = el._nodes.length; i < j; i++) {
+ ele = _dom(el._nodes[i]);
+ if (ele) _initDraggableIfNecessary(ele, true, options);
+ }
+ }
+ else {
+ ele = _dom(el);
+ if (ele) _initDraggableIfNecessary(ele, true, options);
+ }
+ return _currentInstance;
+ };
+
+
+ // just a library-agnostic wrapper.
+ this.extend = function(o1, o2) {
+ return jsPlumb.CurrentLibrary.extend(o1, o2);
+ };
+
+ // helpers for select/selectEndpoints
+ var _setOperation = function(list, func, args, selector) {
+ for (var i = 0, j = list.length; i < j; i++) {
+ list[i][func].apply(list[i], args);
+ }
+ return selector(list);
+ },
+ _getOperation = function(list, func, args) {
+ var out = [];
+ for (var i = 0, j = list.length; i < j; i++) {
+ out.push([ list[i][func].apply(list[i], args), list[i] ]);
+ }
+ return out;
+ },
+ setter = function(list, func, selector) {
+ return function() {
+ return _setOperation(list, func, arguments, selector);
+ };
+ },
+ getter = function(list, func) {
+ return function() {
+ return _getOperation(list, func, arguments);
+ };
+ },
+ prepareList = function(input, doNotGetIds) {
+ var r = [];
+ if (input) {
+ if (typeof input == 'string') {
+ if (input === "*") return input;
+ r.push(input);
+ }
+ else {
+ input = _gel(input);
+ if (doNotGetIds) r = input;
+ else {
+ for (var i = 0, j = input.length; i < j; i++)
+ r.push(_info(input[i]).id);
+ }
+ }
+ }
+ return r;
+ },
+ filterList = function(list, value, missingIsFalse) {
+ if (list === "*") return true;
+ return list.length > 0 ? jsPlumbUtil.indexOf(list, value) != -1 : !missingIsFalse;
+ };
+
+ // get some connections, specifying source/target/scope
+ this.getConnections = function(options, flat) {
+ if (!options) {
+ options = {};
+ } else if (options.constructor == String) {
+ options = { "scope": options };
+ }
+ var scope = options.scope || _currentInstance.getDefaultScope(),
+ scopes = prepareList(scope, true),
+ sources = prepareList(options.source),
+ targets = prepareList(options.target),
+ results = (!flat && scopes.length > 1) ? {} : [],
+ _addOne = function(scope, obj) {
+ if (!flat && scopes.length > 1) {
+ var ss = results[scope];
+ if (ss == null) {
+ ss = results[scope] = [];
+ }
+ ss.push(obj);
+ } else results.push(obj);
+ };
+
+ for ( var j = 0, jj = connections.length; j < jj; j++) {
+ var c = connections[j];
+ if (filterList(scopes, c.scope) && filterList(sources, c.sourceId) && filterList(targets, c.targetId))
+ _addOne(c.scope, c);
+ }
+
+ return results;
+ };
+
+ var _curryEach = function(list, executor) {
+ return function(f) {
+ for (var i = 0, ii = list.length; i < ii; i++) {
+ f(list[i]);
+ }
+ return executor(list);
+ };
+ },
+ _curryGet = function(list) {
+ return function(idx) {
+ return list[idx];
+ };
+ };
+
+ var _makeCommonSelectHandler = function(list, executor) {
+ var out = {
+ length:list.length,
+ each:_curryEach(list, executor),
+ get:_curryGet(list)
+ },
+ setters = ["setHover", "removeAllOverlays", "setLabel", "addClass", "addOverlay", "removeOverlay",
+ "removeOverlays", "showOverlay", "hideOverlay", "showOverlays", "hideOverlays", "setPaintStyle",
+ "setHoverPaintStyle", "setSuspendEvents", "setParameter", "setParameters", "setVisible",
+ "repaint", "addType", "toggleType", "removeType", "removeClass", "setType", "bind", "unbind" ],
+
+ getters = ["getLabel", "getOverlay", "isHover", "getParameter", "getParameters", "getPaintStyle",
+ "getHoverPaintStyle", "isVisible", "hasType", "getType", "isSuspendEvents" ],
+ i, ii;
+
+ for (i = 0, ii = setters.length; i < ii; i++)
+ out[setters[i]] = setter(list, setters[i], executor);
+
+ for (i = 0, ii = getters.length; i < ii; i++)
+ out[getters[i]] = getter(list, getters[i]);
+
+ return out;
+ };
+
+ var _makeConnectionSelectHandler = function(list) {
+ var common = _makeCommonSelectHandler(list, _makeConnectionSelectHandler);
+ return jsPlumb.CurrentLibrary.extend(common, {
+ // setters
+ setDetachable:setter(list, "setDetachable", _makeConnectionSelectHandler),
+ setReattach:setter(list, "setReattach", _makeConnectionSelectHandler),
+ setConnector:setter(list, "setConnector", _makeConnectionSelectHandler),
+ detach:function() {
+ for (var i = 0, ii = list.length; i < ii; i++)
+ _currentInstance.detach(list[i]);
+ },
+ // getters
+ isDetachable:getter(list, "isDetachable"),
+ isReattach:getter(list, "isReattach")
+ });
+ };
+
+ var _makeEndpointSelectHandler = function(list) {
+ var common = _makeCommonSelectHandler(list, _makeEndpointSelectHandler);
+ return jsPlumb.CurrentLibrary.extend(common, {
+ setEnabled:setter(list, "setEnabled", _makeEndpointSelectHandler),
+ setAnchor:setter(list, "setAnchor", _makeEndpointSelectHandler),
+ isEnabled:getter(list, "isEnabled"),
+ detachAll:function() {
+ for (var i = 0, ii = list.length; i < ii; i++)
+ list[i].detachAll();
+ },
+ "remove":function() {
+ for (var i = 0, ii = list.length; i < ii; i++)
+ _currentInstance.deleteObject({endpoint:list[i]});
+ }
+ });
+ };
+
+
+ this.select = function(params) {
+ params = params || {};
+ params.scope = params.scope || "*";
+ return _makeConnectionSelectHandler(params.connections || _currentInstance.getConnections(params, true));
+ };
+
+ this.selectEndpoints = function(params) {
+ params = params || {};
+ params.scope = params.scope || "*";
+ var noElementFilters = !params.element && !params.source && !params.target,
+ elements = noElementFilters ? "*" : prepareList(params.element),
+ sources = noElementFilters ? "*" : prepareList(params.source),
+ targets = noElementFilters ? "*" : prepareList(params.target),
+ scopes = prepareList(params.scope, true);
+
+ var ep = [];
+
+ for (var el in endpointsByElement) {
+ var either = filterList(elements, el, true),
+ source = filterList(sources, el, true),
+ sourceMatchExact = sources != "*",
+ target = filterList(targets, el, true),
+ targetMatchExact = targets != "*";
+
+ // if they requested 'either' then just match scope. otherwise if they requested 'source' (not as a wildcard) then we have to match only endpoints that have isSource set to to true, and the same thing with isTarget.
+ if ( either || source || target ) {
+ inner:
+ for (var i = 0, ii = endpointsByElement[el].length; i < ii; i++) {
+ var _ep = endpointsByElement[el][i];
+ if (filterList(scopes, _ep.scope, true)) {
+
+ var noMatchSource = (sourceMatchExact && sources.length > 0 && !_ep.isSource),
+ noMatchTarget = (targetMatchExact && targets.length > 0 && !_ep.isTarget);
+
+ if (noMatchSource || noMatchTarget)
+ continue inner;
+
+ ep.push(_ep);
+ }
+ }
+ }
+ }
+
+ return _makeEndpointSelectHandler(ep);
+ };
+
+ // get all connections managed by the instance of jsplumb.
+ this.getAllConnections = function() { return connections; };
+ this.getDefaultScope = function() { return DEFAULT_SCOPE; };
+ // get an endpoint by uuid.
+ this.getEndpoint = _getEndpoint;
+ // get endpoints for some element.
+ this.getEndpoints = function(el) { return endpointsByElement[_info(el).id]; };
+ // gets the default endpoint type. used when subclassing. see wiki.
+ this.getDefaultEndpointType = function() { return jsPlumb.Endpoint; };
+ // gets the default connection type. used when subclassing. see wiki.
+ this.getDefaultConnectionType = function() { return jsPlumb.Connection; };
+ /*
+ * Gets an element's id, creating one if necessary. really only exposed
+ * for the lib-specific functionality to access; would be better to pass
+ * the current instance into the lib-specific code (even though this is
+ * a static call. i just don't want to expose it to the public API).
+ */
+ this.getId = _getId;
+ this.getOffset = function(id) {
+ var o = offsets[id];
+ return _updateOffset({elId:id});
+ };
+
+ this.getSelector = function() {
+ return jsPlumb.CurrentLibrary.getSelector.apply(null, arguments);
+ };
+
+ // get the size of the element with the given id, perhaps from cache.
+ this.getSize = function(id) {
+ var s = sizes[id];
+ if (!s) _updateOffset({elId:id});
+ return sizes[id];
+ };
+
+ this.appendElement = _appendElement;
+
+ var _hoverSuspended = false;
+ this.isHoverSuspended = function() { return _hoverSuspended; };
+ this.setHoverSuspended = function(s) { _hoverSuspended = s; };
+
+ var _isAvailable = function(m) {
+ return function() {
+ return jsPlumbAdapter.isRenderModeAvailable(m);
+ };
+ };
+ this.isCanvasAvailable = _isAvailable("canvas");
+ this.isSVGAvailable = _isAvailable("svg");
+ this.isVMLAvailable = _isAvailable("vml");
+
+ // set an element's connections to be hidden
+ this.hide = function(el, changeEndpoints) {
+ _setVisible(el, "none", changeEndpoints);
+ return _currentInstance;
+ };
+
+ // exposed for other objects to use to get a unique id.
+ this.idstamp = _idstamp;
+
+ this.connectorsInitialized = false;
+ var connectorTypes = [], rendererTypes = ["canvas", "svg", "vml"];
+ this.registerConnectorType = function(connector, name) {
+ connectorTypes.push([connector, name]);
+ };
+
+ /**
+ * callback from the current library to tell us to prepare ourselves (attach
+ * mouse listeners etc; can't do that until the library has provided a bind method)
+ */
+ this.init = function() {
+ var _oneType = function(renderer, name, fn) {
+ jsPlumb.Connectors[renderer][name] = function() {
+ fn.apply(this, arguments);
+ jsPlumb.ConnectorRenderers[renderer].apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors[renderer][name], [ fn, jsPlumb.ConnectorRenderers[renderer]]);
+ };
+
+ if (!jsPlumb.connectorsInitialized) {
+ for (var i = 0; i < connectorTypes.length; i++) {
+ for (var j = 0; j < rendererTypes.length; j++) {
+ _oneType(rendererTypes[j], connectorTypes[i][1], connectorTypes[i][0]);
+ }
+
+ }
+ jsPlumb.connectorsInitialized = true;
+ }
+
+ if (!initialized) {
+ _currentInstance.anchorManager = new jsPlumb.AnchorManager({jsPlumbInstance:_currentInstance});
+ _currentInstance.setRenderMode(_currentInstance.Defaults.RenderMode); // calling the method forces the capability logic to be run.
+ initialized = true;
+ _currentInstance.fire("ready", _currentInstance);
+ }
+ }.bind(this);
+
+ this.log = log;
+ this.jsPlumbUIComponent = jsPlumbUIComponent;
+
+ /*
+ * Creates an anchor with the given params.
+ *
+ *
+ * Returns: The newly created Anchor.
+ * Throws: an error if a named anchor was not found.
+ */
+ this.makeAnchor = function() {
+ var _a = function(t, p) {
+ if (jsPlumb.Anchors[t]) return new jsPlumb.Anchors[t](p);
+ if (!_currentInstance.Defaults.DoNotThrowErrors)
+ throw { msg:"jsPlumb: unknown anchor type '" + t + "'" };
+ };
+ if (arguments.length === 0) return null;
+ var specimen = arguments[0], elementId = arguments[1], jsPlumbInstance = arguments[2], newAnchor = null;
+ // if it appears to be an anchor already...
+ if (specimen.compute && specimen.getOrientation) return specimen; //TODO hazy here about whether it should be added or is already added somehow.
+ // is it the name of an anchor type?
+ else if (typeof specimen == "string") {
+ newAnchor = _a(arguments[0], {elementId:elementId, jsPlumbInstance:_currentInstance});
+ }
+ // is it an array? it will be one of:
+ // an array of [name, params] - this defines a single anchor
+ // an array of arrays - this defines some dynamic anchors
+ // an array of numbers - this defines a single anchor.
+ else if (_ju.isArray(specimen)) {
+ if (_ju.isArray(specimen[0]) || _ju.isString(specimen[0])) {
+ if (specimen.length == 2 && _ju.isString(specimen[0]) && _ju.isObject(specimen[1])) {
+ var pp = jsPlumb.extend({elementId:elementId, jsPlumbInstance:_currentInstance}, specimen[1]);
+ newAnchor = _a(specimen[0], pp);
+ }
+ else
+ newAnchor = new jsPlumb.DynamicAnchor({anchors:specimen, selector:null, elementId:elementId, jsPlumbInstance:jsPlumbInstance});
+ }
+ else {
+ var anchorParams = {
+ x:specimen[0], y:specimen[1],
+ orientation : (specimen.length >= 4) ? [ specimen[2], specimen[3] ] : [0,0],
+ offsets : (specimen.length >= 6) ? [ specimen[4], specimen[5] ] : [ 0, 0 ],
+ elementId:elementId,
+ jsPlumbInstance:jsPlumbInstance,
+ cssClass:specimen.length == 7 ? specimen[6] : null
+ };
+ newAnchor = new jsPlumb.Anchor(anchorParams);
+ newAnchor.clone = function() { return new jsPlumb.Anchor(anchorParams); };
+ }
+ }
+
+ if (!newAnchor.id) newAnchor.id = "anchor_" + _idstamp();
+ return newAnchor;
+ };
+
+ /**
+ * makes a list of anchors from the given list of types or coords, eg
+ * ["TopCenter", "RightMiddle", "BottomCenter", [0, 1, -1, -1] ]
+ */
+ this.makeAnchors = function(types, elementId, jsPlumbInstance) {
+ var r = [];
+ for ( var i = 0, ii = types.length; i < ii; i++) {
+ if (typeof types[i] == "string")
+ r.push(jsPlumb.Anchors[types[i]]({elementId:elementId, jsPlumbInstance:jsPlumbInstance}));
+ else if (_ju.isArray(types[i]))
+ r.push(_currentInstance.makeAnchor(types[i], elementId, jsPlumbInstance));
+ }
+ return r;
+ };
+
+ /**
+ * Makes a dynamic anchor from the given list of anchors (which may be in shorthand notation as strings or dimension arrays, or Anchor
+ * objects themselves) and the given, optional, anchorSelector function (jsPlumb uses a default if this is not provided; most people will
+ * not need to provide this - i think).
+ */
+ this.makeDynamicAnchor = function(anchors, anchorSelector) {
+ return new jsPlumb.DynamicAnchor({anchors:anchors, selector:anchorSelector, elementId:null, jsPlumbInstance:_currentInstance});
+ };
+
+// --------------------- makeSource/makeTarget ----------------------------------------------
+
+ var _targetEndpointDefinitions = {},
+ _targetEndpoints = {},
+ _targetEndpointsUnique = {},
+ _targetMaxConnections = {},
+ _setEndpointPaintStylesAndAnchor = function(ep, epIndex) {
+ ep.paintStyle = ep.paintStyle ||
+ _currentInstance.Defaults.EndpointStyles[epIndex] ||
+ _currentInstance.Defaults.EndpointStyle ||
+ jsPlumb.Defaults.EndpointStyles[epIndex] ||
+ jsPlumb.Defaults.EndpointStyle;
+ ep.hoverPaintStyle = ep.hoverPaintStyle ||
+ _currentInstance.Defaults.EndpointHoverStyles[epIndex] ||
+ _currentInstance.Defaults.EndpointHoverStyle ||
+ jsPlumb.Defaults.EndpointHoverStyles[epIndex] ||
+ jsPlumb.Defaults.EndpointHoverStyle;
+
+ ep.anchor = ep.anchor ||
+ _currentInstance.Defaults.Anchors[epIndex] ||
+ _currentInstance.Defaults.Anchor ||
+ jsPlumb.Defaults.Anchors[epIndex] ||
+ jsPlumb.Defaults.Anchor;
+
+ ep.endpoint = ep.endpoint ||
+ _currentInstance.Defaults.Endpoints[epIndex] ||
+ _currentInstance.Defaults.Endpoint ||
+ jsPlumb.Defaults.Endpoints[epIndex] ||
+ jsPlumb.Defaults.Endpoint;
+ },
+ // TODO put all the source stuff inside one parent, keyed by id.
+ _sourceEndpointDefinitions = {},
+ _sourceEndpoints = {},
+ _sourceEndpointsUnique = {},
+ _sourcesEnabled = {},
+ _sourceTriggers = {},
+ _sourceMaxConnections = {},
+ _targetsEnabled = {},
+ selectorFilter = function(evt, _el, selector) {
+ var t = evt.target || evt.srcElement, ok = false,
+ sel = _currentInstance.getSelector(_el, selector);
+ for (var j = 0; j < sel.length; j++) {
+ if (sel[j] == t) {
+ ok = true;
+ break;
+ }
+ }
+ return ok;
+ };
+
+ // see API docs
+ this.makeTarget = function(el, params, referenceParams) {
+
+ // put jsplumb ref into params without altering the params passed in
+ var p = jsPlumb.extend({_jsPlumb:_currentInstance}, referenceParams);
+ jsPlumb.extend(p, params);
+
+ // calculate appropriate paint styles and anchor from the params given
+ _setEndpointPaintStylesAndAnchor(p, 1);
+
+ var jpcl = jsPlumb.CurrentLibrary,
+ targetScope = p.scope || _currentInstance.Defaults.Scope,
+ deleteEndpointsOnDetach = !(p.deleteEndpointsOnDetach === false),
+ maxConnections = p.maxConnections || -1,
+ onMaxConnections = p.onMaxConnections;
+
+ _doOne = function(el) {
+
+ // get the element's id and store the endpoint definition for it. jsPlumb.connect calls will look for one of these,
+ // and use the endpoint definition if found.
+ // decode the info for this element (id and element)
+ var elInfo = _info(el),
+ elid = elInfo.id,
+ proxyComponent = new jsPlumbUIComponent(p),
+ dropOptions = jsPlumb.extend({}, p.dropOptions || {});
+
+ // store the definitions keyed against the element id.
+ _targetEndpointDefinitions[elid] = p;
+ _targetEndpointsUnique[elid] = p.uniqueEndpoint;
+ _targetMaxConnections[elid] = maxConnections;
+ _targetsEnabled[elid] = true;
+
+ var _drop = function() {
+ _currentInstance.currentlyDragging = false;
+ var originalEvent = jsPlumb.CurrentLibrary.getDropEvent(arguments),
+ targetCount = _currentInstance.select({target:elid}).length,
+ draggable = _gel(jpcl.getDragObject(arguments)),
+ id = _currentInstance.getAttribute(draggable, "dragId"),
+ scope = _currentInstance.getAttribute(draggable, "originalScope"),
+ jpc = floatingConnections[id],
+ idx = jpc.endpoints[0].isFloating() ? 0 : 1,
+ // this is not necessarily correct. if the source is being dragged,
+ // then the source endpoint is actually the currently suspended endpoint.
+ source = jpc.endpoints[0],
+ _endpoint = p.endpoint ? jsPlumb.extend({}, p.endpoint) : {};
+
+ if (!_targetsEnabled[elid] || _targetMaxConnections[elid] > 0 && targetCount >= _targetMaxConnections[elid]){
+ if (onMaxConnections) {
+ // TODO here we still have the id of the floating element, not the
+ // actual target.
+ onMaxConnections({
+ element:elInfo.el,
+ connection:jpc
+ }, originalEvent);
+ }
+ return false;
+ }
+
+ // unlock the source anchor to allow it to refresh its position if necessary
+ source.anchor.locked = false;
+
+ // restore the original scope if necessary (issue 57)
+ if (scope) jpcl.setDragScope(draggable, scope);
+
+ // check if drop is allowed here.
+ // if the source is being dragged then in fact
+ // the source and target ids to pass into the drop interceptor are
+ // source - elid
+ // target - jpc's targetId
+ //
+ // otherwise the ids are
+ // source - jpc.sourceId
+ // target - elid
+ //
+ var _continue = proxyComponent.isDropAllowed(idx === 0 ? elid : jpc.sourceId, idx === 0 ? jpc.targetId : elid, jpc.scope, jpc, null);
+
+ // reinstate any suspended endpoint; this just puts the connection back into
+ // a state in which it will report sensible values if someone asks it about
+ // its target. we're going to throw this connection away shortly so it doesnt matter
+ // if we manipulate it a bit.
+ if (jpc.suspendedEndpoint) {
+ jpc[idx ? "targetId" : "sourceId"] = jpc.suspendedEndpoint.elementId;
+ jpc[idx ? "target" : "source"] = jpc.suspendedEndpoint.element;
+ jpc.endpoints[idx] = jpc.suspendedEndpoint;
+ }
+
+ if (_continue) {
+
+ // make a new Endpoint for the target
+ var _el = jpcl.getElementObject(elInfo.el),
+ newEndpoint = _targetEndpoints[elid] || _currentInstance.addEndpoint(_el, p);
+
+ if (p.uniqueEndpoint) _targetEndpoints[elid] = newEndpoint; // may of course just store what it just pulled out. that's ok.
+ // TODO test options to makeTarget to see if we should do this?
+ newEndpoint._doNotDeleteOnDetach = false; // reset.
+ newEndpoint._deleteOnDetach = true;
+
+ // if the anchor has a 'positionFinder' set, then delegate to that function to find
+ // out where to locate the anchor.
+ if (newEndpoint.anchor.positionFinder != null) {
+ var dropPosition = jpcl.getUIPosition(arguments, _currentInstance.getZoom()),
+ elPosition = _getOffset(_el, _currentInstance),
+ elSize = _getSize(_el),
+ ap = newEndpoint.anchor.positionFinder(dropPosition, elPosition, elSize, newEndpoint.anchor.constructorParams);
+ newEndpoint.anchor.x = ap[0];
+ newEndpoint.anchor.y = ap[1];
+ // now figure an orientation for it..kind of hard to know what to do actually. probably the best thing i can do is to
+ // support specifying an orientation in the anchor's spec. if one is not supplied then i will make the orientation
+ // be what will cause the most natural link to the source: it will be pointing at the source, but it needs to be
+ // specified in one axis only, and so how to make that choice? i think i will use whichever axis is the one in which
+ // the target is furthest away from the source.
+ }
+
+ // change the target endpoint and target element information. really this should be
+ // done on a method on connection
+ jpc[idx ? "target" : "source"] = newEndpoint.element;
+ jpc[idx ? "targetId" : "sourceId"] = newEndpoint.elementId;
+ jpc.endpoints[idx].detachFromConnection(jpc);
+ if (jpc.endpoints[idx]._deleteOnDetach)
+ jpc.endpoints[idx].deleteAfterDragStop = true; // tell this endpoint to delet itself after drag stop.
+ // set new endpoint, and configure the settings for endpoints to delete on detach
+ newEndpoint.addConnection(jpc);
+ jpc.endpoints[idx] = newEndpoint;
+ jpc.deleteEndpointsOnDetach = deleteEndpointsOnDetach;
+
+ // inform the anchor manager to update its target endpoint for this connection.
+ // TODO refactor to make this a single method.
+ if (idx == 1)
+ _currentInstance.anchorManager.updateOtherEndpoint(jpc.sourceId, jpc.suspendedElementId, jpc.targetId, jpc);
+ else
+ _currentInstance.anchorManager.sourceChanged(jpc.suspendedEndpoint.elementId, jpc.sourceId, jpc);
+
+ _finaliseConnection(jpc, null, originalEvent);
+
+ }
+ // if not allowed to drop...
+ else {
+ // TODO this code is identical (pretty much) to what happens when a connection
+ // dragged from a normal endpoint is in this situation. refactor.
+ // is this an existing connection, and will we reattach?
+ // TODO also this assumes the source needs to detach - is that always valid?
+ if (jpc.suspendedEndpoint) {
+ if (jpc.isReattach()) {
+ jpc.setHover(false);
+ jpc.floatingAnchorIndex = null;
+ jpc.suspendedEndpoint.addConnection(jpc);
+ _currentInstance.repaint(source.elementId);
+ }
+ else
+ source.detach(jpc, false, true, true, originalEvent); // otherwise, detach the connection and tell everyone about it.
+ }
+
+ }
+ };
+
+ // wrap drop events as needed and initialise droppable
+ var dropEvent = jpcl.dragEvents.drop;
+ dropOptions.scope = dropOptions.scope || targetScope;
+ dropOptions[dropEvent] = _ju.wrap(dropOptions[dropEvent], _drop);
+ jpcl.initDroppable(_gel(elInfo.el), dropOptions, true);
+ };
+
+ // YUI collection fix
+ el = _convertYUICollection(el);
+ // make an array if only given one element
+ var inputs = el.length && el.constructor != String ? el : [ el ];
+
+ // register each one in the list.
+ for (var i = 0, ii = inputs.length; i < ii; i++) {
+ _doOne(inputs[i]);
+ }
+
+ return _currentInstance;
+ };
+
+ // see api docs
+ this.unmakeTarget = function(el, doNotClearArrays) {
+ var info = _info(el);
+
+ jsPlumb.CurrentLibrary.destroyDroppable(info.el);
+ // TODO this is not an exhaustive unmake of a target, since it does not remove the droppable stuff from
+ // the element. the effect will be to prevent it from behaving as a target, but it's not completely purged.
+ if (!doNotClearArrays) {
+ delete _targetEndpointDefinitions[info.id];
+ delete _targetEndpointsUnique[info.id];
+ delete _targetMaxConnections[info.id];
+ delete _targetsEnabled[info.id];
+ }
+
+ return _currentInstance;
+ };
+
+ // see api docs
+ this.makeSource = function(el, params, referenceParams) {
+ var p = jsPlumb.extend({}, referenceParams);
+ jsPlumb.extend(p, params);
+ _setEndpointPaintStylesAndAnchor(p, 0);
+ var jpcl = jsPlumb.CurrentLibrary,
+ maxConnections = p.maxConnections || -1,
+ onMaxConnections = p.onMaxConnections,
+ _doOne = function(elInfo) {
+ // get the element's id and store the endpoint definition for it. jsPlumb.connect calls will look for one of these,
+ // and use the endpoint definition if found.
+ var elid = elInfo.id,
+ _el = _gel(elInfo.el),
+ parentElement = function() {
+ return p.parent == null ? null : p.parent === "parent" ? elInfo.el.parentNode : _dom(p.parent);
+ },
+ idToRegisterAgainst = p.parent != null ? _currentInstance.getId(parentElement()) : elid;
+
+ _sourceEndpointDefinitions[idToRegisterAgainst] = p;
+ _sourceEndpointsUnique[idToRegisterAgainst] = p.uniqueEndpoint;
+ _sourcesEnabled[idToRegisterAgainst] = true;
+
+ var stopEvent = jpcl.dragEvents.stop,
+ dragEvent = jpcl.dragEvents.drag,
+ dragOptions = jsPlumb.extend({ }, p.dragOptions || {}),
+ existingDrag = dragOptions.drag,
+ existingStop = dragOptions.stop,
+ ep = null,
+ endpointAddedButNoDragYet = false;
+
+ _sourceMaxConnections[idToRegisterAgainst] = maxConnections;
+
+ // set scope if its not set in dragOptions but was passed in in params
+ dragOptions.scope = dragOptions.scope || p.scope;
+
+ dragOptions[dragEvent] = _ju.wrap(dragOptions[dragEvent], function() {
+ if (existingDrag) existingDrag.apply(this, arguments);
+ endpointAddedButNoDragYet = false;
+ });
+
+ dragOptions[stopEvent] = _ju.wrap(dragOptions[stopEvent], function() {
+
+ if (existingStop) existingStop.apply(this, arguments);
+ _currentInstance.currentlyDragging = false;
+ if (ep._jsPlumb != null) { // if not cleaned up...
+
+ jpcl.unbind(ep.canvas, "mousedown");
+
+ // reset the anchor to the anchor that was initially provided. the one we were using to drag
+ // the connection was just a placeholder that was located at the place the user pressed the
+ // mouse button to initiate the drag.
+ var anchorDef = p.anchor || _currentInstance.Defaults.Anchor,
+ oldAnchor = ep.anchor,
+ oldConnection = ep.connections[0];
+
+ ep.setAnchor(_currentInstance.makeAnchor(anchorDef, elid, _currentInstance), true);
+
+ if (p.parent) {
+ var parent = parentElement();
+ if (parent) {
+ var currentId = ep.elementId,
+ potentialParent = p.container || _currentInstance.Defaults.Container || jsPlumb.Defaults.Container;
+
+ ep.setElement(parent, potentialParent);
+ ep.endpointWillMoveAfterConnection = false;
+ //_currentInstance.anchorManager.rehomeEndpoint(ep, currentId, parent);
+ oldConnection.previousConnection = null;
+ // remove from connectionsByScope
+ jsPlumbUtil.removeWithFunction(connections, function(c) {
+ return c.id === oldConnection.id;
+ });
+ _currentInstance.anchorManager.connectionDetached({
+ sourceId:oldConnection.sourceId,
+ targetId:oldConnection.targetId,
+ connection:oldConnection
+ });
+ _finaliseConnection(oldConnection);
+ }
+ }
+
+ ep.repaint();
+ _currentInstance.repaint(ep.elementId);
+ _currentInstance.repaint(oldConnection.targetId);
+ }
+ });
+ // when the user presses the mouse, add an Endpoint, if we are enabled.
+ var mouseDownListener = function(e) {
+
+ // if disabled, return.
+ if (!_sourcesEnabled[idToRegisterAgainst]) return;
+
+ // if a filter was given, run it, and return if it says no.
+ if (p.filter) {
+ var evt = jpcl.getOriginalEvent(e),
+ r = jsPlumbUtil.isString(p.filter) ? selectorFilter(evt, _el, p.filter) : p.filter(evt, _el);
+
+ if (r === false) return;
+ }
+
+ // if maxConnections reached
+ var sourceCount = _currentInstance.select({source:idToRegisterAgainst}).length;
+ if (_sourceMaxConnections[idToRegisterAgainst] >= 0 && sourceCount >= _sourceMaxConnections[idToRegisterAgainst]) {
+ if (onMaxConnections) {
+ onMaxConnections({
+ element:_el,
+ maxConnections:maxConnections
+ }, e);
+ }
+ return false;
+ }
+
+ // make sure we have the latest offset for this div
+ var myOffsetInfo = _updateOffset({elId:elid}).o,
+ z = _currentInstance.getZoom(),
+ x = ( ((e.pageX || e.page.x) / z) - myOffsetInfo.left) / myOffsetInfo.width,
+ y = ( ((e.pageY || e.page.y) / z) - myOffsetInfo.top) / myOffsetInfo.height,
+ parentX = x,
+ parentY = y;
+
+ // if there is a parent, the endpoint will actually be added to it now, rather than the div
+ // that was the source. in that case, we have to adjust the anchor position so it refers to
+ // the parent.
+ if (p.parent) {
+ var pEl = parentElement(), pId = _getId(pEl);
+ myOffsetInfo = _updateOffset({elId:pId}).o;
+ parentX = ((e.pageX || e.page.x) - myOffsetInfo.left) / myOffsetInfo.width;
+ parentY = ((e.pageY || e.page.y) - myOffsetInfo.top) / myOffsetInfo.height;
+ }
+
+ // we need to override the anchor in here, and force 'isSource', but we don't want to mess with
+ // the params passed in, because after a connection is established we're going to reset the endpoint
+ // to have the anchor we were given.
+ var tempEndpointParams = {};
+ jsPlumb.extend(tempEndpointParams, p);
+ tempEndpointParams.isSource = true;
+ tempEndpointParams.anchor = [x,y,0,0];
+ tempEndpointParams.parentAnchor = [ parentX, parentY, 0, 0 ];
+ tempEndpointParams.dragOptions = dragOptions;
+ // if a parent was given we need to turn that into a "container" argument. this is, by default,
+ // the parent of the element we will move to, so parent of p.parent in this case. however, if
+ // the user has specified a 'container' on the endpoint definition or on
+ // the defaults, we should use that.
+ if (p.parent) {
+ var potentialParent = tempEndpointParams.container || _currentInstance.Defaults.Container || jsPlumb.Defaults.Container;
+ if (potentialParent)
+ tempEndpointParams.container = potentialParent;
+ else
+ tempEndpointParams.container = jsPlumb.CurrentLibrary.getParent(parentElement());
+ }
+
+ ep = _currentInstance.addEndpoint(elid, tempEndpointParams);
+
+ endpointAddedButNoDragYet = true;
+ // we set this to prevent connections from firing attach events before this function has had a chance
+ // to move the endpoint.
+ ep.endpointWillMoveAfterConnection = p.parent != null;
+ ep.endpointWillMoveTo = p.parent ? parentElement() : null;
+
+ // TODO test options to makeSource to see if we should do this?
+ ep._doNotDeleteOnDetach = false; // reset.
+ ep._deleteOnDetach = true;
+
+ var _delTempEndpoint = function() {
+ // this mouseup event is fired only if no dragging occurred, by jquery and yui, but for mootools
+ // it is fired even if dragging has occurred, in which case we would blow away a perfectly
+ // legitimate endpoint, were it not for this check. the flag is set after adding an
+ // endpoint and cleared in a drag listener we set in the dragOptions above.
+ if(endpointAddedButNoDragYet) {
+ endpointAddedButNoDragYet = false;
+ _currentInstance.deleteEndpoint(ep);
+ }
+ };
+
+ _currentInstance.registerListener(ep.canvas, "mouseup", _delTempEndpoint);
+ _currentInstance.registerListener(_el, "mouseup", _delTempEndpoint);
+
+ // and then trigger its mousedown event, which will kick off a drag, which will start dragging
+ // a new connection from this endpoint.
+ jpcl.trigger(ep.canvas, "mousedown", e);
+
+ };
+
+ // register this on jsPlumb so that it can be cleared by a reset.
+ _currentInstance.registerListener(_el, "mousedown", mouseDownListener);
+ _sourceTriggers[elid] = mouseDownListener;
+
+ // lastly, if a filter was provided, set it as a dragFilter on the element,
+ // to prevent the element drag function from kicking in when we want to
+ // drag a new connection
+ if (p.filter && jsPlumbUtil.isString(p.filter)) {
+ jpcl.setDragFilter(_el, p.filter);
+ }
+ };
+
+ el = _convertYUICollection(el);
+
+ var inputs = el.length && el.constructor != String ? el : [ el ];
+
+ for (var i = 0, ii = inputs.length; i < ii; i++) {
+ _doOne(_info(inputs[i]));
+ }
+
+ return _currentInstance;
+ };
+
+ // see api docs
+ this.unmakeSource = function(el, doNotClearArrays) {
+ var info = _info(el),
+ mouseDownListener = _sourceTriggers[info.id];
+
+ if (mouseDownListener)
+ _currentInstance.unregisterListener(info.el, "mousedown", mouseDownListener);
+
+ if (!doNotClearArrays) {
+ delete _sourceEndpointDefinitions[info.id];
+ delete _sourceEndpointsUnique[info.id];
+ delete _sourcesEnabled[info.id];
+ delete _sourceTriggers[info.id];
+ delete _sourceMaxConnections[info.id];
+ }
+
+ return _currentInstance;
+ };
+
+ // see api docs
+ this.unmakeEverySource = function() {
+ for (var i in _sourcesEnabled)
+ _currentInstance.unmakeSource(i, true);
+
+ _sourceEndpointDefinitions = {};
+ _sourceEndpointsUnique = {};
+ _sourcesEnabled = {};
+ _sourceTriggers = {};
+ };
+
+ // see api docs
+ this.unmakeEveryTarget = function() {
+ for (var i in _targetsEnabled)
+ _currentInstance.unmakeTarget(i, true);
+
+ _targetEndpointDefinitions = {};
+ _targetEndpointsUnique = {};
+ _targetMaxConnections = {};
+ _targetsEnabled = {};
+
+ return _currentInstance;
+ };
+
+ // does the work of setting a source enabled or disabled.
+ var _setEnabled = function(type, el, state, toggle) {
+ var a = type == "source" ? _sourcesEnabled : _targetsEnabled;
+ el = _convertYUICollection(el);
+
+ if (_ju.isString(el)) a[el] = toggle ? !a[el] : state;
+ else if (el.length) {
+ for (var i = 0, ii = el.length; i < ii; i++) {
+ var info = _info(el[i]);
+ a[info.id] = toggle ? !a[info.id] : state;
+ }
+ }
+ return _currentInstance;
+ };
+
+ this.toggleSourceEnabled = function(el) {
+ _setEnabled("source", el, null, true);
+ return _currentInstance.isSourceEnabled(el);
+ };
+
+ this.setSourceEnabled = function(el, state) { return _setEnabled("source", el, state); };
+ this.isSource = function(el) { return _sourcesEnabled[_info(el).id] != null; };
+ this.isSourceEnabled = function(el) { return _sourcesEnabled[_info(el).id] === true; };
+
+ this.toggleTargetEnabled = function(el) {
+ _setEnabled("target", el, null, true);
+ return _currentInstance.isTargetEnabled(el);
+ };
+
+ this.isTarget = function(el) { return _targetsEnabled[_info(el).id] != null; };
+ this.isTargetEnabled = function(el) { return _targetsEnabled[_info(el).id] === true; };
+ this.setTargetEnabled = function(el, state) { return _setEnabled("target", el, state); };
+
+// --------------------- end makeSource/makeTarget ----------------------------------------------
+
+ this.ready = function(fn) {
+ _currentInstance.bind("ready", fn);
+ };
+
+ // repaint some element's endpoints and connections
+ this.repaint = function(el, ui, timestamp) {
+ // support both lists...
+ if (typeof el == 'object' && el.length)
+ for ( var i = 0, ii = el.length; i < ii; i++) {
+ _draw(el[i], ui, timestamp);
+ }
+ else // ...and single strings.
+ _draw(el, ui, timestamp);
+
+ return _currentInstance;
+ };
+
+ // repaint every endpoint and connection.
+ this.repaintEverything = function() {
+ // TODO this timestamp causes continuous anchors to not repaint properly.
+ // fix this. do not just take out the timestamp. it runs a lot faster with
+ // the timestamp included.
+ var timestamp = _timestamp();
+ for ( var elId in endpointsByElement) {
+ _draw(elId, null, timestamp);
+ }
+ return _currentInstance;
+ /*for (var i = 0; i < connections.length; i++)
+ connections[i].repaint({timestamp:timestamp});*/
+ };
+
+
+ this.removeAllEndpoints = function(el, recurse) {
+ var _one = function(_el) {
+ var info = _info(_el),
+ ebe = endpointsByElement[info.id],
+ i, ii;
+
+ if (ebe) {
+ for ( i = 0, ii = ebe.length; i < ii; i++)
+ _currentInstance.deleteEndpoint(ebe[i]);
+ }
+ delete endpointsByElement[info.id];
+
+ if (recurse) {
+ if (info.el && info.el.nodeType != 3 && info.el.nodeType != 8 ) {
+ for ( i = 0, ii = info.el.childNodes.length; i < ii; i++) {
+ _one(info.el.childNodes[i]);
+ }
+ }
+ }
+
+ };
+ _one(el);
+ return _currentInstance;
+ };
+
+ /**
+ * Remove the given element, including cleaning up all endpoints registered for it.
+ * This is exposed in the public API but also used internally by jsPlumb when removing the
+ * element associated with a connection drag.
+ */
+ this.remove = function(el, doNotRepaint) {
+ var info = _info(el);
+ _currentInstance.doWhileSuspended(function() {
+ _currentInstance.removeAllEndpoints(info.id, true);
+ _currentInstance.dragManager.elementRemoved(info.id);
+ delete floatingConnections[info.id];
+ _currentInstance.anchorManager.clearFor(info.id);
+ _currentInstance.anchorManager.removeFloatingConnection(info.id);
+ }, doNotRepaint === false);
+ if(info.el) jsPlumb.CurrentLibrary.removeElement(info.el);
+ };
+
+ var _registeredListeners = {},
+ _unbindRegisteredListeners = function() {
+ for (var i in _registeredListeners) {
+ for (var j = 0, jj = _registeredListeners[i].length; j < jj; j++) {
+ var info = _registeredListeners[i][j];
+ jsPlumb.CurrentLibrary.unbind(info.el, info.event, info.listener);
+ }
+ }
+ _registeredListeners = {};
+ };
+
+ // internal register listener method. gives us a hook to clean things up
+ // with if the user calls jsPlumb.reset.
+ this.registerListener = function(el, type, listener) {
+ jsPlumb.CurrentLibrary.bind(el, type, listener);
+ jsPlumbUtil.addToList(_registeredListeners, type, {el:el, event:type, listener:listener});
+ };
+
+ this.unregisterListener = function(el, type, listener) {
+ jsPlumb.CurrentLibrary.unbind(el, type, listener);
+ jsPlumbUtil.removeWithFunction(_registeredListeners, function(rl) {
+ return rl.type == type && rl.listener == listener;
+ });
+ };
+
+ this.reset = function() {
+ _currentInstance.deleteEveryEndpoint();
+ _currentInstance.unbind();
+ _targetEndpointDefinitions = {};
+ _targetEndpoints = {};
+ _targetEndpointsUnique = {};
+ _targetMaxConnections = {};
+ _sourceEndpointDefinitions = {};
+ _sourceEndpoints = {};
+ _sourceEndpointsUnique = {};
+ _sourceMaxConnections = {};
+ connections.splice(0);
+ _unbindRegisteredListeners();
+ _currentInstance.anchorManager.reset();
+ if (!jsPlumbAdapter.headless)
+ _currentInstance.dragManager.reset();
+ };
+
+
+ this.setDefaultScope = function(scope) {
+ DEFAULT_SCOPE = scope;
+ return _currentInstance;
+ };
+
+ // sets whether or not some element should be currently draggable.
+ this.setDraggable = _setDraggable;
+
+ // sets the id of some element, changing whatever we need to to keep track.
+ this.setId = function(el, newId, doNotSetAttribute) {
+ //
+ var id;
+
+ if (jsPlumbUtil.isString(el)) {
+ id = el;
+ }
+ else {
+ el = _dom(el);
+ id = _currentInstance.getId(el);
+ }
+
+ var sConns = _currentInstance.getConnections({source:id, scope:'*'}, true),
+ tConns = _currentInstance.getConnections({target:id, scope:'*'}, true);
+
+ newId = "" + newId;
+
+ if (!doNotSetAttribute) {
+ el = _dom(id);
+ jsPlumbAdapter.setAttribute(el, "id", newId);
+ }
+ else
+ el = _dom(newId);
+
+ endpointsByElement[newId] = endpointsByElement[id] || [];
+ for (var i = 0, ii = endpointsByElement[newId].length; i < ii; i++) {
+ endpointsByElement[newId][i].setElementId(newId);
+ endpointsByElement[newId][i].setReferenceElement(el);
+ }
+ delete endpointsByElement[id];
+
+ _currentInstance.anchorManager.changeId(id, newId);
+ if (!jsPlumbAdapter.headless)
+ _currentInstance.dragManager.changeId(id, newId);
+
+ var _conns = function(list, epIdx, type) {
+ for (var i = 0, ii = list.length; i < ii; i++) {
+ list[i].endpoints[epIdx].setElementId(newId);
+ list[i].endpoints[epIdx].setReferenceElement(el);
+ list[i][type + "Id"] = newId;
+ list[i][type] = el;
+ }
+ };
+ _conns(sConns, 0, "source");
+ _conns(tConns, 1, "target");
+
+ _currentInstance.repaint(newId);
+ };
+
+ this.setDebugLog = function(debugLog) {
+ log = debugLog;
+ };
+
+ this.setSuspendDrawing = function(val, repaintAfterwards) {
+ var curVal = _suspendDrawing;
+ _suspendDrawing = val;
+ if (val) _suspendedAt = new Date().getTime(); else _suspendedAt = null;
+ if (repaintAfterwards) _currentInstance.repaintEverything();
+ return curVal;
+ };
+
+ // returns whether or not drawing is currently suspended.
+ this.isSuspendDrawing = function() {
+ return _suspendDrawing;
+ };
+
+ // return timestamp for when drawing was suspended.
+ this.getSuspendedAt = function() { return _suspendedAt; };
+
+ /**
+ * @doc function
+ * @name jsPlumb.class:doWhileSuspended
+ * @param {function} fn Function to run while suspended.
+ * @param {boolean} doNotRepaintAfterwards If true, jsPlumb won't run a full repaint. Otherwise it will.
+ * @description Suspends drawing, runs the given function, then re-enables drawing (and repaints, unless you tell it not to)
+ */
+ this.doWhileSuspended = function(fn, doNotRepaintAfterwards) {
+ var _wasSuspended = _currentInstance.isSuspendDrawing();
+ if (!_wasSuspended)
+ _currentInstance.setSuspendDrawing(true);
+ try {
+ fn();
+ }
+ catch (e) {
+ _ju.log("Function run while suspended failed", e);
+ }
+ if (!_wasSuspended)
+ _currentInstance.setSuspendDrawing(false, !doNotRepaintAfterwards);
+ };
+
+ this.updateOffset = _updateOffset;
+ this.getOffset = function(elId) { return offsets[elId]; };
+ this.getSize = function(elId) { return sizes[elId]; };
+ this.getCachedData = _getCachedData;
+ this.timestamp = _timestamp;
+
+
+
+ /**
+ * @doc function
+ * @name jsPlumb.class:setRenderMode
+ * @param {string} mode One of `jsPlumb.SVG, `jsPlumb.VML` or `jsPlumb.CANVAS`.
+ * @description Sets render mode. jsPlumb will fall back to VML if it determines that
+ * what you asked for is not supported (and that VML is). If you asked for VML but the browser does
+ * not support it, jsPlumb uses SVG.
+ * @return {string} The render mode that jsPlumb set, which of course may be different from that requested.
+ */
+ this.setRenderMode = function(mode) {
+ renderMode = jsPlumbAdapter.setRenderMode(mode);
+ var i, ii;
+ // only add this if the renderer is canvas; we dont want these listeners registered on te
+ // entire document otherwise.
+ if (renderMode == jsPlumb.CANVAS) {
+ var bindOne = function(event) {
+ jsPlumb.CurrentLibrary.bind(document, event, function(e) {
+ if (!_currentInstance.currentlyDragging && renderMode == jsPlumb.CANVAS) {
+ // try connections first
+ for (i = 0, ii = connections.length; i < ii; i++ ) {
+ var t = connections[i].getConnector()[event](e);
+ if (t) return;
+ }
+ for (var el in endpointsByElement) {
+ var ee = endpointsByElement[el];
+ for ( i = 0, ii = ee.length; i < ii; i++ ) {
+ if (ee[i].endpoint[event] && ee[i].endpoint[event](e)) return;
+ }
+ }
+ }
+ });
+ };
+ bindOne("click");bindOne("dblclick");bindOne("mousemove");bindOne("mousedown");bindOne("mouseup");bindOne("contextmenu");
+ }
+
+ return renderMode;
+ };
+
+ /**
+ * @doc function
+ * @name jsPlumb.class:getRenderMode
+ * @description Gets the current render mode for this instance of jsPlumb.
+ * @return {string} The current render mode - "canvas", "svg" or "vml".
+ */
+ this.getRenderMode = function() { return renderMode; };
+
+ this.show = function(el, changeEndpoints) {
+ _setVisible(el, "block", changeEndpoints);
+ return _currentInstance;
+ };
+
+ /**
+ * gets some test hooks. nothing writable.
+ */
+ this.getTestHarness = function() {
+ return {
+ endpointsByElement : endpointsByElement,
+ endpointCount : function(elId) {
+ var e = endpointsByElement[elId];
+ return e ? e.length : 0;
+ },
+ connectionCount : function(scope) {
+ scope = scope || DEFAULT_SCOPE;
+ var c = _currentInstance.getConnections({scope:scope});
+ return c ? c.length : 0;
+ },
+ getId : _getId,
+ makeAnchor:self.makeAnchor,
+ makeDynamicAnchor:self.makeDynamicAnchor
+ };
+ };
+
+
+ // TODO: update this method to return the current state.
+ this.toggleVisible = _toggleVisible;
+ this.toggleDraggable = _toggleDraggable;
+ this.addListener = this.bind;
+
+ /*
+ helper method to take an xy location and adjust it for the parent's offset and scroll.
+ */
+ this.adjustForParentOffsetAndScroll = function(xy, el) {
+
+ var offsetParent = null, result = xy;
+ if (el.tagName.toLowerCase() === "svg" && el.parentNode) {
+ offsetParent = el.parentNode;
+ }
+ else if (el.offsetParent) {
+ offsetParent = el.offsetParent;
+ }
+ if (offsetParent != null) {
+ var po = offsetParent.tagName.toLowerCase() === "body" ? {left:0,top:0} : _getOffset(offsetParent, _currentInstance),
+ so = offsetParent.tagName.toLowerCase() === "body" ? {left:0,top:0} : {left:offsetParent.scrollLeft, top:offsetParent.scrollTop};
+
+ // i thought it might be cool to do this:
+ // lastReturnValue[0] = lastReturnValue[0] - offsetParent.offsetLeft + offsetParent.scrollLeft;
+ // lastReturnValue[1] = lastReturnValue[1] - offsetParent.offsetTop + offsetParent.scrollTop;
+ // but i think it ignores margins. my reasoning was that it's quicker to not hand off to some underlying
+ // library.
+
+ result[0] = xy[0] - po.left + so.left;
+ result[1] = xy[1] - po.top + so.top;
+ }
+
+ return result;
+
+ };
+
+ if (!jsPlumbAdapter.headless) {
+ _currentInstance.dragManager = jsPlumbAdapter.getDragManager(_currentInstance);
+ _currentInstance.recalculateOffsets = _currentInstance.dragManager.updateOffsets;
+ }
+
+ };
+
+ jsPlumbUtil.extend(jsPlumbInstance, jsPlumbUtil.EventGenerator, {
+ setAttribute : function(el, a, v) {
+ jsPlumbAdapter.setAttribute(el, a, v);
+ },
+ getAttribute : function(el, a) {
+ return jsPlumbAdapter.getAttribute(jsPlumb.CurrentLibrary.getDOMElement(el), a);
+ },
+ registerConnectionType : function(id, type) {
+ this._connectionTypes[id] = jsPlumb.extend({}, type);
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:registerConnectionTypes
+ * @param {object} types Object containing the type specifications.
+ * @description
+ * Registers all of the given connection types on this instance of jsPlumb. `types` is expected
+ * to contain keys with typeids and values with type specification objects.
+ */
+ registerConnectionTypes : function(types) {
+ for (var i in types)
+ this._connectionTypes[i] = jsPlumb.extend({}, types[i]);
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:registerEndpointType
+ * @param {string} typeId Id of the type
+ * @param {object} type Object containing the type specification.
+ * @description
+ * Registers the given endpoint type on this instance of jsPlumb.
+ */
+ registerEndpointType : function(id, type) {
+ this._endpointTypes[id] = jsPlumb.extend({}, type);
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:registerEndpointTypes
+ * @param {object} types Object containing the type specifications.
+ * @description
+ * Registers all of the given endpoint types on this instance of jsPlumb. `types` is expected
+ * to contain keys with typeids and values with type specification objects.
+ */
+ registerEndpointTypes : function(types) {
+ for (var i in types)
+ this._endpointTypes[i] = jsPlumb.extend({}, types[i]);
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:getType
+ * @param {string} id Id of the type to retrieve
+ * @param {string} typeDescriptor `"connection"` or `"endpoint"` - the type of Type to get.
+ * @description
+ * Returns the given type's specification.
+ * @return {object} Type specification, it if exists, null otherwise.
+ */
+ getType : function(id, typeDescriptor) {
+ return typeDescriptor === "connection" ? this._connectionTypes[id] : this._endpointTypes[id];
+ },
+ /**
+ * @doc function
+ * @name jsPlumb.class:setIdChanged
+ * @param {oldId} string Previous id
+ * @param {newId} string Element's new id.
+ * @description called to notify us that an id WAS changed, and we should do our changes, but we
+ * dont need to change the element's DOM attribute. note that this does not work if the an element with
+ * the new id is not in the DOM.
+ */
+ setIdChanged : function(oldId, newId) {
+ this.setId(oldId, newId, true);
+ }
+ });
+
+// --------------------- static instance + AMD registration -------------------------------------------
+
+// create static instance and assign to window if window exists.
+ var jsPlumb = new jsPlumbInstance();
+ // register on window if defined (lets us run on server)
+ if (typeof window != 'undefined') window.jsPlumb = jsPlumb;
+ // add 'getInstance' method to static instance
+ /**
+ * @name jsPlumb.getInstance
+ * @param {object} [_defaults] Optional default settings for the new instance.
+ * @desc Gets a new instance of jsPlumb.
+ */
+ jsPlumb.getInstance = function(_defaults) {
+ var j = new jsPlumbInstance(_defaults);
+ j.init();
+ return j;
+ };
+// maybe register static instance as an AMD module, and getInstance method too.
+ if ( typeof define === "function") {
+ define( "jsplumb", [], function () { return jsPlumb; } );
+ define( "jsplumbinstance", [], function () { return jsPlumb.getInstance(); } );
+ }
+ // CommonJS
+ if (typeof exports !== 'undefined') {
+ exports.jsPlumb = jsPlumb;
+ }
+
+
+// --------------------- end static instance + AMD registration -------------------------------------------
+
+})();
+
+
+;(function() {
+
+ // create the drag handler for a connection
+ var _makeConnectionDragHandler = function(placeholder, _jsPlumb) {
+ var stopped = false;
+ return {
+ drag : function() {
+ if (stopped) {
+ stopped = false;
+ return true;
+ }
+ var _ui = jsPlumb.CurrentLibrary.getUIPosition(arguments, _jsPlumb.getZoom());
+
+ if (placeholder.element) {
+ jsPlumb.CurrentLibrary.setOffset(placeholder.element, _ui);
+ _jsPlumb.repaint(placeholder.element, _ui);
+ }
+ },
+ stopDrag : function() {
+ stopped = true;
+ }
+ };
+ };
+
+ // creates a placeholder div for dragging purposes, adds it to the DOM, and pre-computes its offset.
+ var _makeDraggablePlaceholder = function(placeholder, parent, _jsPlumb) {
+ var n = document.createElement("div");
+ n.style.position = "absolute";
+ var placeholderDragElement = jsPlumb.CurrentLibrary.getElementObject(n);
+ jsPlumb.CurrentLibrary.appendElement(n, parent);
+ var id = _jsPlumb.getId(n);
+ _jsPlumb.updateOffset( { elId : id });
+ // create and assign an id, and initialize the offset.
+ placeholder.id = id;
+ placeholder.element = n;//placeholderDragElement;
+ };
+
+ // create a floating endpoint (for drag connections)
+ var _makeFloatingEndpoint = function(paintStyle, referenceAnchor, endpoint, referenceCanvas, sourceElement, _jsPlumb, _newEndpoint) {
+ var floatingAnchor = new jsPlumb.FloatingAnchor( { reference : referenceAnchor, referenceCanvas : referenceCanvas, jsPlumbInstance:_jsPlumb });
+ //setting the scope here should not be the way to fix that mootools issue. it should be fixed by not
+ // adding the floating endpoint as a droppable. that makes more sense anyway!
+ return _newEndpoint({ paintStyle : paintStyle, endpoint : endpoint, anchor : floatingAnchor, source : sourceElement, scope:"__floating" });
+ };
+
+ var typeParameters = [ "connectorStyle", "connectorHoverStyle", "connectorOverlays",
+ "connector", "connectionType", "connectorClass", "connectorHoverClass" ];
+
+ // a helper function that tries to find a connection to the given element, and returns it if so. if elementWithPrecedence is null,
+ // or no connection to it is found, we return the first connection in our list.
+ var findConnectionToUseForDynamicAnchor = function(ep, elementWithPrecedence) {
+ var idx = 0;
+ if (elementWithPrecedence != null) {
+ for (var i = 0; i < ep.connections.length; i++) {
+ if (ep.connections[i].sourceId == elementWithPrecedence || ep.connections[i].targetId == elementWithPrecedence) {
+ idx = i;
+ break;
+ }
+ }
+ }
+
+ return ep.connections[idx];
+ };
+
+ var findConnectionIndex = function(conn, ep) {
+ return jsPlumbUtil.findWithFunction(ep.connections, function(c) { return c.id == conn.id; });
+ };
+
+ jsPlumb.Endpoint = function(params) {
+ var _jsPlumb = params._jsPlumb,
+ jpcl = jsPlumb.CurrentLibrary,
+ _att = jsPlumbAdapter.getAttribute,
+ _gel = jpcl.getElementObject,
+ _dom = jpcl.getDOMElement,
+ _ju = jsPlumbUtil,
+ _newConnection = params.newConnection,
+ _newEndpoint = params.newEndpoint,
+ _finaliseConnection = params.finaliseConnection,
+ _fireDetachEvent = params.fireDetachEvent,
+ floatingConnections = params.floatingConnections;
+
+ this.idPrefix = "_jsplumb_e_";
+ this.defaultLabelLocation = [ 0.5, 0.5 ];
+ this.defaultOverlayKeys = ["Overlays", "EndpointOverlays"];
+ this.parent = params.parent;
+ OverlayCapableJsPlumbUIComponent.apply(this, arguments);
+
+// TYPE
+
+ this.getDefaultType = function() {
+ return {
+ parameters:{},
+ scope:null,
+ maxConnections:this._jsPlumb.instance.Defaults.MaxConnections,
+ paintStyle:this._jsPlumb.instance.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle,
+ endpoint:this._jsPlumb.instance.Defaults.Endpoint || jsPlumb.Defaults.Endpoint,
+ hoverPaintStyle:this._jsPlumb.instance.Defaults.EndpointHoverStyle || jsPlumb.Defaults.EndpointHoverStyle,
+ overlays:this._jsPlumb.instance.Defaults.EndpointOverlays || jsPlumb.Defaults.EndpointOverlays,
+ connectorStyle:params.connectorStyle,
+ connectorHoverStyle:params.connectorHoverStyle,
+ connectorClass:params.connectorClass,
+ connectorHoverClass:params.connectorHoverClass,
+ connectorOverlays:params.connectorOverlays,
+ connector:params.connector,
+ connectorTooltip:params.connectorTooltip
+ };
+ };
+
+// END TYPE
+
+ this._jsPlumb.enabled = !(params.enabled === false);
+ this._jsPlumb.visible = true;
+ this.element = _dom(params.source);
+ this._jsPlumb.uuid = params.uuid;
+ this._jsPlumb.floatingEndpoint = null;
+ var inPlaceCopy = null;
+ if (this._jsPlumb.uuid) params.endpointsByUUID[this._jsPlumb.uuid] = this;
+ this.elementId = params.elementId;
+
+ this._jsPlumb.connectionCost = params.connectionCost;
+ this._jsPlumb.connectionsDirected = params.connectionsDirected;
+ this._jsPlumb.currentAnchorClass = "";
+ this._jsPlumb.events = {};
+
+ var _updateAnchorClass = function() {
+ jpcl.removeClass(this.element, _jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ this.removeClass(_jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ this._jsPlumb.currentAnchorClass = this.anchor.getCssClass();
+ this.addClass(_jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ jpcl.addClass(this.element, _jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ }.bind(this);
+
+ this.setAnchor = function(anchorParams, doNotRepaint) {
+ this._jsPlumb.instance.continuousAnchorFactory.clear(this.elementId);
+ this.anchor = this._jsPlumb.instance.makeAnchor(anchorParams, this.elementId, _jsPlumb);
+ _updateAnchorClass();
+ this.anchor.bind("anchorChanged", function(currentAnchor) {
+ this.fire("anchorChanged", {endpoint:this, anchor:currentAnchor});
+ _updateAnchorClass();
+ }.bind(this));
+ if (!doNotRepaint)
+ this._jsPlumb.instance.repaint(this.elementId);
+ return this;
+ };
+
+ var anchorParamsToUse = params.anchor ? params.anchor : params.anchors ? params.anchors : (_jsPlumb.Defaults.Anchor || "Top");
+ this.setAnchor(anchorParamsToUse, true);
+
+ // endpoint delegates to first connection for hover, if there is one.
+ var internalHover = function(state) {
+ if (this.connections.length > 0)
+ this.connections[0].setHover(state, false);
+ else
+ this.setHover(state);
+ }.bind(this);
+
+ // ANCHOR MANAGER
+ if (!params._transient) // in place copies, for example, are transient. they will never need to be retrieved during a paint cycle, because they dont move, and then they are deleted.
+ this._jsPlumb.instance.anchorManager.add(this, this.elementId);
+
+ this.setEndpoint = function(ep) {
+
+ if (this.endpoint != null) {
+ this.endpoint.cleanup();
+ this.endpoint.destroy();
+ }
+
+ var _e = function(t, p) {
+ var rm = _jsPlumb.getRenderMode();
+ if (jsPlumb.Endpoints[rm][t]) return new jsPlumb.Endpoints[rm][t](p);
+ if (!_jsPlumb.Defaults.DoNotThrowErrors)
+ throw { msg:"jsPlumb: unknown endpoint type '" + t + "'" };
+ };
+
+ var endpointArgs = {
+ _jsPlumb:this._jsPlumb.instance,
+ cssClass:params.cssClass,
+ parent:params.parent,
+ container:params.container,
+ tooltip:params.tooltip,
+ connectorTooltip:params.connectorTooltip,
+ endpoint:this
+ };
+ if (_ju.isString(ep))
+ this.endpoint = _e(ep, endpointArgs);
+ else if (_ju.isArray(ep)) {
+ endpointArgs = _ju.merge(ep[1], endpointArgs);
+ this.endpoint = _e(ep[0], endpointArgs);
+ }
+ else {
+ this.endpoint = ep.clone();
+ }
+
+ // assign a clone function using a copy of endpointArgs. this is used when a drag starts: the endpoint that was dragged is cloned,
+ // and the clone is left in its place while the original one goes off on a magical journey.
+ // the copy is to get around a closure problem, in which endpointArgs ends up getting shared by
+ // the whole world.
+ var argsForClone = jsPlumb.extend({}, endpointArgs);
+ this.endpoint.clone = function() {
+ // TODO this, and the code above, can be refactored to be more dry.
+ if (_ju.isString(ep))
+ return _e(ep, endpointArgs);
+ else if (_ju.isArray(ep)) {
+ endpointArgs = _ju.merge(ep[1], endpointArgs);
+ return _e(ep[0], endpointArgs);
+ }
+ }.bind(this);
+
+ this.type = this.endpoint.type;
+ // bind listeners from endpoint to self, with the internal hover function defined above.
+ this.bindListeners(this.endpoint, this, internalHover);
+ };
+
+ this.setEndpoint(params.endpoint || _jsPlumb.Defaults.Endpoint || jsPlumb.Defaults.Endpoint || "Dot");
+ this.setPaintStyle(params.paintStyle || params.style || _jsPlumb.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle, true);
+ this.setHoverPaintStyle(params.hoverPaintStyle || _jsPlumb.Defaults.EndpointHoverStyle || jsPlumb.Defaults.EndpointHoverStyle, true);
+ this._jsPlumb.paintStyleInUse = this.getPaintStyle();
+
+ _ju.copyValues(typeParameters, params, this);
+
+ this.isSource = params.isSource || false;
+ this.isTarget = params.isTarget || false;
+ this._jsPlumb.maxConnections = params.maxConnections || _jsPlumb.Defaults.MaxConnections; // maximum number of connections this endpoint can be the source of.
+ this.canvas = this.endpoint.canvas;
+ // add anchor class (need to do this on construction because we set anchor first)
+ this.addClass(_jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ jpcl.addClass(this.element, _jsPlumb.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ this.connections = params.connections || [];
+ this.connectorPointerEvents = params["connector-pointer-events"];
+
+ this.scope = params.scope || _jsPlumb.getDefaultScope();
+ this.timestamp = null;
+ this.reattachConnections = params.reattach || _jsPlumb.Defaults.ReattachConnections;
+ this.connectionsDetachable = _jsPlumb.Defaults.ConnectionsDetachable;
+ if (params.connectionsDetachable === false || params.detachable === false)
+ this.connectionsDetachable = false;
+ this.dragAllowedWhenFull = params.dragAllowedWhenFull || true;
+
+ if (params.onMaxConnections)
+ this.bind("maxConnections", params.onMaxConnections);
+
+ //
+ // add a connection. not part of public API.
+ //
+ this.addConnection = function(connection) {
+ this.connections.push(connection);
+ this[(this.connections.length > 0 ? "add" : "remove") + "Class"](_jsPlumb.endpointConnectedClass);
+ this[(this.isFull() ? "add" : "remove") + "Class"](_jsPlumb.endpointFullClass);
+ };
+
+ this.detachFromConnection = function(connection, idx) {
+ idx = idx == null ? findConnectionIndex(connection, this) : idx;
+ if (idx >= 0) {
+ this.connections.splice(idx, 1);
+ this[(this.connections.length > 0 ? "add" : "remove") + "Class"](_jsPlumb.endpointConnectedClass);
+ this[(this.isFull() ? "add" : "remove") + "Class"](_jsPlumb.endpointFullClass);
+ }
+ };
+
+ this.detach = function(connection, ignoreTarget, forceDetach, fireEvent, originalEvent, endpointBeingDeleted, connectionIndex) {
+
+ var idx = connectionIndex == null ? findConnectionIndex(connection, this) : connectionIndex,
+ actuallyDetached = false;
+ fireEvent = (fireEvent !== false);
+
+ if (idx >= 0) {
+ if (forceDetach || connection._forceDetach || (connection.isDetachable() && connection.isDetachAllowed(connection) && this.isDetachAllowed(connection) )) {
+
+ //connection.setHover(false);
+
+ _jsPlumb.deleteObject({
+ connection:connection,
+ fireEvent:(!ignoreTarget && fireEvent),
+ originalEvent:originalEvent
+ });
+ actuallyDetached = true;
+ }
+ }
+ return actuallyDetached;
+ };
+
+ this.detachAll = function(fireEvent, originalEvent) {
+ while (this.connections.length > 0) {
+ // TODO this could pass the index in to the detach method to save some time (index will always be zero in this while loop)
+ // TODO now it defaults to fireEvent true. will that mess with things?
+ this.detach(this.connections[0], false, true, fireEvent !== false, originalEvent, this, 0);
+ }
+ return this;
+ };
+ this.detachFrom = function(targetEndpoint, fireEvent, originalEvent) {
+ var c = [];
+ for ( var i = 0; i < this.connections.length; i++) {
+ if (this.connections[i].endpoints[1] == targetEndpoint || this.connections[i].endpoints[0] == targetEndpoint) {
+ c.push(this.connections[i]);
+ }
+ }
+ for ( var j = 0; j < c.length; j++) {
+ this.detach(c[j], false, true, fireEvent, originalEvent);
+ }
+ return this;
+ };
+
+ this.getElement = function() {
+ return this.element;
+ };
+
+ // container not supported in 1.5.2; you cannot change the container once it is set.
+ // it might come back int a future release.
+ this.setElement = function(el/*, container*/) {
+ var parentId = this._jsPlumb.instance.getId(el),
+ curId = this.elementId;
+ // remove the endpoint from the list for the current endpoint's element
+ _ju.removeWithFunction(params.endpointsByElement[this.elementId], function(e) {
+ return e.id == this.id;
+ }.bind(this));
+ this.element = _dom(el);
+ this.elementId = _jsPlumb.getId(this.element);
+ _jsPlumb.anchorManager.rehomeEndpoint(this, curId, this.element);
+ _jsPlumb.dragManager.endpointAdded(this.element);
+ _ju.addToList(params.endpointsByElement, parentId, this);
+ return this;
+ };
+
+ /**
+ * private but must be exposed.
+ */
+ this.makeInPlaceCopy = function() {
+ var loc = this.anchor.getCurrentLocation({element:this}),
+ o = this.anchor.getOrientation(this),
+ acc = this.anchor.getCssClass(),
+ inPlaceAnchor = {
+ bind:function() { },
+ compute:function() { return [ loc[0], loc[1] ]; },
+ getCurrentLocation : function() { return [ loc[0], loc[1] ]; },
+ getOrientation:function() { return o; },
+ getCssClass:function() { return acc; }
+ };
+
+ return _newEndpoint( {
+ anchor : inPlaceAnchor,
+ source : this.element,
+ paintStyle : this.getPaintStyle(),
+ endpoint : params.hideOnDrag ? "Blank" : this.endpoint,
+ _transient:true,
+ scope:this.scope
+ });
+ };
+
+
+ /**
+ * private but needs to be exposed.
+ */
+ this.isFloating = function() {
+ return this.anchor != null && this.anchor.isFloating;
+ };
+
+ /**
+ * returns a connection from the pool; used when dragging starts. just gets the head of the array if it can.
+ */
+ this.connectorSelector = function() {
+ var candidate = this.connections[0];
+ if (this.isTarget && candidate) return candidate;
+ else {
+ return (this.connections.length < this._jsPlumb.maxConnections) || this._jsPlumb.maxConnections == -1 ? null : candidate;
+ }
+ };
+
+ this.setStyle = this.setPaintStyle;
+
+ this.paint = function(params) {
+ params = params || {};
+ var timestamp = params.timestamp, recalc = !(params.recalc === false);
+ if (!timestamp || this.timestamp !== timestamp) {
+
+ // TODO check: is this is a safe performance enhancement?
+ var info = _jsPlumb.updateOffset({ elId:this.elementId, timestamp:timestamp/*, recalc:recalc*/ });
+ //var info = _jsPlumb.updateOffset({ elId:_elementId, timestamp:timestamp, recalc:recalc });
+
+ var xy = params.offset ? params.offset.o : info.o;
+ if(xy != null) {
+ var ap = params.anchorPoint,connectorPaintStyle = params.connectorPaintStyle;
+ if (ap == null) {
+ var wh = params.dimensions || info.s,
+ anchorParams = { xy : [ xy.left, xy.top ], wh : wh, element : this, timestamp : timestamp };
+ if (recalc && this.anchor.isDynamic && this.connections.length > 0) {
+ var c = findConnectionToUseForDynamicAnchor(this, params.elementWithPrecedence),
+ oIdx = c.endpoints[0] == this ? 1 : 0,
+ oId = oIdx === 0 ? c.sourceId : c.targetId,
+ oInfo = _jsPlumb.getCachedData(oId),
+ oOffset = oInfo.o, oWH = oInfo.s;
+ anchorParams.txy = [ oOffset.left, oOffset.top ];
+ anchorParams.twh = oWH;
+ anchorParams.tElement = c.endpoints[oIdx];
+ }
+ ap = this.anchor.compute(anchorParams);
+ }
+
+ this.endpoint.compute(ap, this.anchor.getOrientation(this), this._jsPlumb.paintStyleInUse, connectorPaintStyle || this.paintStyleInUse);
+ this.endpoint.paint(this._jsPlumb.paintStyleInUse, this.anchor);
+ this.timestamp = timestamp;
+
+ // paint overlays
+ for ( var i = 0; i < this._jsPlumb.overlays.length; i++) {
+ var o = this._jsPlumb.overlays[i];
+ if (o.isVisible()) {
+ this._jsPlumb.overlayPlacements[i] = o.draw(this.endpoint, this._jsPlumb.paintStyleInUse);
+ o.paint(this._jsPlumb.overlayPlacements[i]);
+ }
+ }
+ }
+ }
+ };
+
+ this.repaint = this.paint;
+
+ // is this a connection source? we make it draggable and have the
+ // drag listener maintain a connection with a floating endpoint.
+ if (jpcl.isDragSupported(this.element) && (this.isSource || this.isTarget)) {
+ var placeholderInfo = { id:null, element:null },
+ jpc = null,
+ existingJpc = false,
+ existingJpcParams = null,
+ _dragHandler = _makeConnectionDragHandler(placeholderInfo, _jsPlumb);
+
+ var start = function() {
+ // drag might have started on an endpoint that is not actually a source, but which has
+ // one or more connections.
+ jpc = this.connectorSelector();
+ var _continue = true;
+ // if not enabled, return
+ if (!this.isEnabled()) _continue = false;
+ // if no connection and we're not a source, return.
+ if (jpc == null && !this.isSource) _continue = false;
+ // otherwise if we're full and not allowed to drag, also return false.
+ if (this.isSource && this.isFull() && !this.dragAllowedWhenFull) _continue = false;
+ // if the connection was setup as not detachable or one of its endpoints
+ // was setup as connectionsDetachable = false, or Defaults.ConnectionsDetachable
+ // is set to false...
+ if (jpc != null && !jpc.isDetachable()) _continue = false;
+
+ if (_continue === false) {
+ // this is for mootools and yui. returning false from this causes jquery to stop drag.
+ // the events are wrapped in both mootools and yui anyway, but i don't think returning
+ // false from the start callback would stop a drag.
+ if (jpcl.stopDrag) jpcl.stopDrag();
+ _dragHandler.stopDrag();
+ return false;
+ }
+
+ // clear hover for all connections for this endpoint before continuing.
+ for (var i = 0; i < this.connections.length; i++)
+ this.connections[i].setHover(false);
+
+ this.addClass("endpointDrag");
+ _jsPlumb.setConnectionBeingDragged(true);
+
+ // if we're not full but there was a connection, make it null. we'll create a new one.
+ if (jpc && !this.isFull() && this.isSource) jpc = null;
+
+ _jsPlumb.updateOffset( { elId : this.elementId });
+ inPlaceCopy = this.makeInPlaceCopy();
+ inPlaceCopy.referenceEndpoint = this;
+ inPlaceCopy.paint();
+
+ _makeDraggablePlaceholder(placeholderInfo, this.parent, _jsPlumb);
+
+ // set the offset of this div to be where 'inPlaceCopy' is, to start with.
+ // TODO merge this code with the code in both Anchor and FloatingAnchor, because it
+ // does the same stuff.
+ var ipcoel = _gel(inPlaceCopy.canvas),
+ ipco = jsPlumb.CurrentLibrary.getOffset(ipcoel, _jsPlumb),
+ po = _jsPlumb.adjustForParentOffsetAndScroll([ipco.left, ipco.top], inPlaceCopy.canvas),
+ canvasElement = _gel(this.canvas);
+
+ jpcl.setOffset(placeholderInfo.element, {left:po[0], top:po[1]});
+
+ // when using makeSource and a parent, we first draw the source anchor on the source element, then
+ // move it to the parent. note that this happens after drawing the placeholder for the
+ // first time.
+ if (this.parentAnchor) this.anchor = _jsPlumb.makeAnchor(this.parentAnchor, this.elementId, _jsPlumb);
+
+ // store the id of the dragging div and the source element. the drop function will pick these up.
+ _jsPlumb.setAttribute(this.canvas, "dragId", placeholderInfo.id);
+ _jsPlumb.setAttribute(this.canvas, "elId", this.elementId);
+
+ this._jsPlumb.floatingEndpoint = _makeFloatingEndpoint(this.getPaintStyle(), this.anchor, this.endpoint, this.canvas, placeholderInfo.element, _jsPlumb, _newEndpoint);
+ // TODO we should not know about DOM here. make the library adapter do this (or the
+ // dom adapter)
+ this.canvas.style.visibility = "hidden";
+
+ if (jpc == null) {
+ this.anchor.locked = true;
+ this.setHover(false, false);
+ // create a connection. one end is this endpoint, the other is a floating endpoint.
+ jpc = _newConnection({
+ sourceEndpoint : this,
+ targetEndpoint : this._jsPlumb.floatingEndpoint,
+ source : this.endpointWillMoveTo || this.element, // for makeSource with parent option. ensure source element is represented correctly.
+ target : placeholderInfo.element,
+ anchors : [ this.anchor, this._jsPlumb.floatingEndpoint.anchor ],
+ paintStyle : params.connectorStyle, // this can be null. Connection will use the default.
+ hoverPaintStyle:params.connectorHoverStyle,
+ connector : params.connector, // this can also be null. Connection will use the default.
+ overlays : params.connectorOverlays,
+ type:this.connectionType,
+ cssClass:this.connectorClass,
+ hoverClass:this.connectorHoverClass
+ });
+ jpc.addClass(_jsPlumb.draggingClass);
+ this._jsPlumb.floatingEndpoint.addClass(_jsPlumb.draggingClass);
+ // fire an event that informs that a connection is being dragged
+ _jsPlumb.fire("connectionDrag", jpc);
+
+ } else {
+ existingJpc = true;
+ jpc.setHover(false);
+ // if existing connection, allow to be dropped back on the source endpoint (issue 51).
+ _initDropTarget(ipcoel, false, true);
+ // new anchor idx
+ var anchorIdx = jpc.endpoints[0].id == this.id ? 0 : 1;
+ jpc.floatingAnchorIndex = anchorIdx; // save our anchor index as the connection's floating index.
+ this.detachFromConnection(jpc); // detach from the connection while dragging is occurring.
+
+ // store the original scope (issue 57)
+ var dragScope = jsPlumb.CurrentLibrary.getDragScope(canvasElement);
+ _jsPlumb.setAttribute(this.canvas, "originalScope", dragScope);
+ // now we want to get this endpoint's DROP scope, and set it for now: we can only be dropped on drop zones
+ // that have our drop scope (issue 57).
+ var dropScope = jpcl.getDropScope(canvasElement);
+ jpcl.setDragScope(canvasElement, dropScope);
+
+ // fire an event that informs that a connection is being dragged. we do this before
+ // replacing the original target with the floating element info.
+ _jsPlumb.fire("connectionDrag", jpc);
+
+ // now we replace ourselves with the temporary div we created above:
+ if (anchorIdx === 0) {
+ existingJpcParams = [ jpc.source, jpc.sourceId, canvasElement, dragScope ];
+ jpc.source = placeholderInfo.element;
+ jpc.sourceId = placeholderInfo.id;
+ } else {
+ existingJpcParams = [ jpc.target, jpc.targetId, canvasElement, dragScope ];
+ jpc.target = placeholderInfo.element;
+ jpc.targetId = placeholderInfo.id;
+ }
+
+ // lock the other endpoint; if it is dynamic it will not move while the drag is occurring.
+ jpc.endpoints[anchorIdx === 0 ? 1 : 0].anchor.locked = true;
+ // store the original endpoint and assign the new floating endpoint for the drag.
+ jpc.suspendedEndpoint = jpc.endpoints[anchorIdx];
+
+ // PROVIDE THE SUSPENDED ELEMENT, BE IT A SOURCE OR TARGET (ISSUE 39)
+ jpc.suspendedElement = jpc.endpoints[anchorIdx].getElement();
+ jpc.suspendedElementId = jpc.endpoints[anchorIdx].elementId;
+ jpc.suspendedElementType = anchorIdx === 0 ? "source" : "target";
+
+ jpc.suspendedEndpoint.setHover(false);
+ this._jsPlumb.floatingEndpoint.referenceEndpoint = jpc.suspendedEndpoint;
+ jpc.endpoints[anchorIdx] = this._jsPlumb.floatingEndpoint;
+
+ jpc.addClass(_jsPlumb.draggingClass);
+ this._jsPlumb.floatingEndpoint.addClass(_jsPlumb.draggingClass);
+
+ }
+ // register it and register connection on it.
+ floatingConnections[placeholderInfo.id] = jpc;
+ _jsPlumb.anchorManager.addFloatingConnection(placeholderInfo.id, jpc);
+ // only register for the target endpoint; we will not be dragging the source at any time
+ // before this connection is either discarded or made into a permanent connection.
+ _ju.addToList(params.endpointsByElement, placeholderInfo.id, this._jsPlumb.floatingEndpoint);
+ // tell jsplumb about it
+ _jsPlumb.currentlyDragging = true;
+ }.bind(this);
+
+ var dragOptions = params.dragOptions || {},
+ defaultOpts = jsPlumb.extend( {}, jpcl.defaultDragOptions),
+ startEvent = jpcl.dragEvents.start,
+ stopEvent = jpcl.dragEvents.stop,
+ dragEvent = jpcl.dragEvents.drag;
+
+ dragOptions = jsPlumb.extend(defaultOpts, dragOptions);
+ dragOptions.scope = dragOptions.scope || this.scope;
+ dragOptions[startEvent] = _ju.wrap(dragOptions[startEvent], start, false);
+ // extracted drag handler function so can be used by makeSource
+ dragOptions[dragEvent] = _ju.wrap(dragOptions[dragEvent], _dragHandler.drag);
+ dragOptions[stopEvent] = _ju.wrap(dragOptions[stopEvent],
+ function() {
+
+ _jsPlumb.setConnectionBeingDragged(false);
+ // get the actual drop event (decode from library args to stop function)
+ var originalEvent = jpcl.getDropEvent(arguments);
+ // unlock the other endpoint (if it is dynamic, it would have been locked at drag start)
+ var idx = jpc.floatingAnchorIndex == null ? 1 : jpc.floatingAnchorIndex;
+ jpc.endpoints[idx === 0 ? 1 : 0].anchor.locked = false;
+ // WHY does this need to happen? i suppose because the connection might not get
+ // deleted. TODO: i dont want to know about css classes inside jsplumb, ideally.
+ jpc.removeClass(_jsPlumb.draggingClass);
+
+ // if we have the floating endpoint then the connection has not been dropped
+ // on another endpoint. If it is a new connection we throw it away. If it is an
+ // existing connection we check to see if we should reattach it, throwing it away
+ // if not.
+ if (jpc.endpoints[idx] == this._jsPlumb.floatingEndpoint) {
+ // 6a. if the connection was an existing one...
+ if (existingJpc && jpc.suspendedEndpoint) {
+ // fix for issue35, thanks Sylvain Gizard: when firing the detach event make sure the
+ // floating endpoint has been replaced.
+ if (idx === 0) {
+ jpc.source = existingJpcParams[0];
+ jpc.sourceId = existingJpcParams[1];
+ } else {
+ jpc.target = existingJpcParams[0];
+ jpc.targetId = existingJpcParams[1];
+ }
+
+ // restore the original scope (issue 57)
+ jpcl.setDragScope(existingJpcParams[2], existingJpcParams[3]);
+ jpc.endpoints[idx] = jpc.suspendedEndpoint;
+ // IF the connection should be reattached, or the other endpoint refuses detach, then
+ // reset the connection to its original state
+ if (jpc.isReattach() || jpc._forceReattach || jpc._forceDetach || !jpc.endpoints[idx === 0 ? 1 : 0].detach(jpc, false, false, true, originalEvent)) {
+ jpc.setHover(false);
+ jpc.floatingAnchorIndex = null;
+ jpc._forceDetach = null;
+ jpc._forceReattach = null;
+ this._jsPlumb.floatingEndpoint.detachFromConnection(jpc);
+ jpc.suspendedEndpoint.addConnection(jpc);
+ _jsPlumb.repaint(existingJpcParams[1]);
+ }
+ }
+ }
+
+ // remove the element associated with the floating endpoint
+ // (and its associated floating endpoint and visual artefacts)
+ // TODO we need a way to say that the connection should be kept, if
+ _jsPlumb.remove(placeholderInfo.element, false);
+ // remove the inplace copy
+ _jsPlumb.remove(inPlaceCopy.canvas, false);
+
+ // makeTargets sets this flag, to tell us we have been replaced and should delete ourself.
+ if (this.deleteAfterDragStop) {
+ _jsPlumb.deleteObject({endpoint:this});
+ }
+ else {
+ if (this._jsPlumb) {
+ this._jsPlumb.floatingEndpoint = null;
+ // repaint this endpoint.
+ // make our canvas visible (TODO: hand off to library; we should not know about DOM)
+ this.canvas.style.visibility = "visible";
+ // unlock our anchor
+ this.anchor.locked = false;
+ this.paint({recalc:false});
+ }
+ }
+
+ // TODO can this stay here? the connection is no longer valid.
+ _jsPlumb.fire("connectionDragStop", jpc);
+
+ // tell jsplumb that dragging is finished.
+ _jsPlumb.currentlyDragging = false;
+
+ jpc = null;
+
+ }.bind(this));
+
+ var i = _gel(this.canvas);
+ jpcl.initDraggable(i, dragOptions, true, _jsPlumb);
+ }
+
+ // pulled this out into a function so we can reuse it for the inPlaceCopy canvas; you can now drop detached connections
+ // back onto the endpoint you detached it from.
+ var _initDropTarget = function(canvas, forceInit, isTransient, endpoint) {
+ if ((this.isTarget || forceInit) && jpcl.isDropSupported(this.element)) {
+ var dropOptions = params.dropOptions || _jsPlumb.Defaults.DropOptions || jsPlumb.Defaults.DropOptions;
+ dropOptions = jsPlumb.extend( {}, dropOptions);
+ dropOptions.scope = dropOptions.scope || this.scope;
+ var dropEvent = jpcl.dragEvents.drop,
+ overEvent = jpcl.dragEvents.over,
+ outEvent = jpcl.dragEvents.out,
+ drop = function() {
+
+ this.removeClass(_jsPlumb.endpointDropAllowedClass);
+ this.removeClass(_jsPlumb.endpointDropForbiddenClass);
+
+ var originalEvent = jpcl.getDropEvent(arguments),
+ draggable = _gel(jpcl.getDragObject(arguments)),
+ id = _jsPlumb.getAttribute(draggable, "dragId"),
+ elId = _jsPlumb.getAttribute(draggable, "elId"),
+ scope = _jsPlumb.getAttribute(draggable, "originalScope"),
+ jpc = floatingConnections[id];
+
+ // if this is a drop back where the connection came from, mark it force rettach and
+ // return; the stop handler will reattach. without firing an event.
+ var redrop = jpc.suspendedEndpoint && (jpc.suspendedEndpoint.id == this.id ||
+ this.referenceEndpoint && jpc.suspendedEndpoint.id == this.referenceEndpoint.id) ;
+ if (redrop) {
+ jpc._forceReattach = true;
+ return;
+ }
+
+ if (jpc != null) {
+ var idx = jpc.floatingAnchorIndex == null ? 1 : jpc.floatingAnchorIndex, oidx = idx === 0 ? 1 : 0;
+
+ // restore the original scope if necessary (issue 57)
+ if (scope) jsPlumb.CurrentLibrary.setDragScope(draggable, scope);
+
+ var endpointEnabled = endpoint != null ? endpoint.isEnabled() : true;
+
+ if (this.isFull()) {
+ this.fire("maxConnections", {
+ endpoint:this,
+ connection:jpc,
+ maxConnections:this._jsPlumb.maxConnections
+ }, originalEvent);
+ }
+
+ if (!this.isFull() && !(idx === 0 && !this.isSource) && !(idx == 1 && !this.isTarget) && endpointEnabled) {
+ var _doContinue = true;
+
+ // the second check here is for the case that the user is dropping it back
+ // where it came from.
+ if (jpc.suspendedEndpoint && jpc.suspendedEndpoint.id != this.id) {
+ if (idx === 0) {
+ jpc.source = jpc.suspendedEndpoint.element;
+ jpc.sourceId = jpc.suspendedEndpoint.elementId;
+ } else {
+ jpc.target = jpc.suspendedEndpoint.element;
+ jpc.targetId = jpc.suspendedEndpoint.elementId;
+ }
+
+ if (!jpc.isDetachAllowed(jpc) || !jpc.endpoints[idx].isDetachAllowed(jpc) || !jpc.suspendedEndpoint.isDetachAllowed(jpc) || !_jsPlumb.checkCondition("beforeDetach", jpc))
+ _doContinue = false;
+ }
+
+ // these have to be set before testing for beforeDrop.
+ if (idx === 0) {
+ jpc.source = this.element;
+ jpc.sourceId = this.elementId;
+ } else {
+ jpc.target = this.element;
+ jpc.targetId = this.elementId;
+ }
+
+// ------------ wrap the execution path in a function so we can support asynchronous beforeDrop
+
+ // we want to execute this regardless.
+ var commonFunction = function() {
+ jpc.floatingAnchorIndex = null;
+ };
+
+ var continueFunction = function() {
+
+ // remove this jpc from the current endpoint
+ jpc.endpoints[idx].detachFromConnection(jpc);
+ if (jpc.suspendedEndpoint) jpc.suspendedEndpoint.detachFromConnection(jpc);
+ jpc.endpoints[idx] = this;
+ this.addConnection(jpc);
+
+ // copy our parameters in to the connection:
+ var params = this.getParameters();
+ for (var aParam in params)
+ jpc.setParameter(aParam, params[aParam]);
+
+ if (!jpc.suspendedEndpoint) {
+ if (params.draggable)
+ jsPlumb.CurrentLibrary.initDraggable(this.element, dragOptions, true, _jsPlumb);
+ }
+ else {
+ var suspendedElement = jpc.suspendedEndpoint.getElement(), suspendedElementId = jpc.suspendedEndpoint.elementId;
+ // fire a detach event
+ _fireDetachEvent({
+ source : idx === 0 ? suspendedElement : jpc.source,
+ target : idx == 1 ? suspendedElement : jpc.target,
+ sourceId : idx === 0 ? suspendedElementId : jpc.sourceId,
+ targetId : idx == 1 ? suspendedElementId : jpc.targetId,
+ sourceEndpoint : idx === 0 ? jpc.suspendedEndpoint : jpc.endpoints[0],
+ targetEndpoint : idx == 1 ? jpc.suspendedEndpoint : jpc.endpoints[1],
+ connection : jpc
+ }, true, originalEvent);
+ }
+
+ // TODO this is like the makeTarget drop code.
+ if (idx == 1)
+ _jsPlumb.anchorManager.updateOtherEndpoint(jpc.sourceId, jpc.suspendedElementId, jpc.targetId, jpc);
+ else
+ _jsPlumb.anchorManager.sourceChanged(jpc.suspendedEndpoint.elementId, jpc.sourceId, jpc);
+
+ // finalise will inform the anchor manager and also add to
+ // connectionsByScope if necessary.
+ _finaliseConnection(jpc, null, originalEvent, true);
+
+ commonFunction();
+ }.bind(this);
+
+ var dontContinueFunction = function() {
+ // otherwise just put it back on the endpoint it was on before the drag.
+ if (jpc.suspendedEndpoint) {
+ jpc.endpoints[idx] = jpc.suspendedEndpoint;
+ jpc.setHover(false);
+ jpc._forceDetach = true;
+ if (idx === 0) {
+ jpc.source = jpc.suspendedEndpoint.element;
+ jpc.sourceId = jpc.suspendedEndpoint.elementId;
+ } else {
+ jpc.target = jpc.suspendedEndpoint.element;
+ jpc.targetId = jpc.suspendedEndpoint.elementId;
+ }
+ jpc.suspendedEndpoint.addConnection(jpc);
+
+ jpc.endpoints[0].repaint();
+ jpc.repaint();
+ _jsPlumb.repaint(jpc.sourceId);
+ jpc._forceDetach = false;
+ }
+
+ commonFunction();
+ };
+
+// --------------------------------------
+ // now check beforeDrop. this will be available only on Endpoints that are setup to
+ // have a beforeDrop condition (although, secretly, under the hood all Endpoints and
+ // the Connection have them, because they are on jsPlumbUIComponent. shhh!), because
+ // it only makes sense to have it on a target endpoint.
+ _doContinue = _doContinue && this.isDropAllowed(jpc.sourceId, jpc.targetId, jpc.scope, jpc, this);
+
+ if (_doContinue) {
+ continueFunction();
+ }
+ else {
+ dontContinueFunction();
+ }
+ }
+ _jsPlumb.currentlyDragging = false;
+ }
+ }.bind(this);
+
+ dropOptions[dropEvent] = _ju.wrap(dropOptions[dropEvent], drop);
+ dropOptions[overEvent] = _ju.wrap(dropOptions[overEvent], function() {
+ var draggable = jpcl.getDragObject(arguments),
+ id = _jsPlumb.getAttribute(draggable, "dragId"),
+ _jpc = floatingConnections[id];
+
+ if (_jpc != null) {
+ var idx = _jpc.floatingAnchorIndex == null ? 1 : _jpc.floatingAnchorIndex;
+ // here we should fire the 'over' event if we are a target and this is a new connection,
+ // or we are the same as the floating endpoint.
+ var _cont = (this.isTarget && _jpc.floatingAnchorIndex !== 0) || (_jpc.suspendedEndpoint && this.referenceEndpoint && this.referenceEndpoint.id == _jpc.suspendedEndpoint.id);
+ if (_cont) {
+ var bb = _jsPlumb.checkCondition("checkDropAllowed", {
+ sourceEndpoint:_jpc.endpoints[idx],
+ targetEndpoint:this,
+ connection:_jpc
+ });
+ this[(bb ? "add" : "remove") + "Class"](_jsPlumb.endpointDropAllowedClass);
+ this[(bb ? "remove" : "add") + "Class"](_jsPlumb.endpointDropForbiddenClass);
+ _jpc.endpoints[idx].anchor.over(this.anchor, this);
+ }
+ }
+ }.bind(this));
+
+ dropOptions[outEvent] = _ju.wrap(dropOptions[outEvent], function() {
+ var draggable = jpcl.getDragObject(arguments),
+ id = _jsPlumb.getAttribute( draggable, "dragId"),
+ _jpc = floatingConnections[id];
+
+ if (_jpc != null) {
+ var idx = _jpc.floatingAnchorIndex == null ? 1 : _jpc.floatingAnchorIndex;
+ var _cont = (this.isTarget && _jpc.floatingAnchorIndex !== 0) || (_jpc.suspendedEndpoint && this.referenceEndpoint && this.referenceEndpoint.id == _jpc.suspendedEndpoint.id);
+ if (_cont) {
+ this.removeClass(_jsPlumb.endpointDropAllowedClass);
+ this.removeClass(_jsPlumb.endpointDropForbiddenClass);
+ _jpc.endpoints[idx].anchor.out();
+ }
+ }
+ }.bind(this));
+ jpcl.initDroppable(canvas, dropOptions, true, isTransient);
+ }
+ }.bind(this);
+
+ // initialise the endpoint's canvas as a drop target. this will be ignored if the endpoint is not a target or drag is not supported.
+ _initDropTarget(_gel(this.canvas), true, !(params._transient || this.anchor.isFloating), this);
+
+ // finally, set type if it was provided
+ if (params.type)
+ this.addType(params.type, params.data, _jsPlumb.isSuspendDrawing());
+
+ return this;
+ };
+
+ jsPlumbUtil.extend(jsPlumb.Endpoint, OverlayCapableJsPlumbUIComponent, {
+ getTypeDescriptor : function() { return "endpoint"; },
+ isVisible : function() { return this._jsPlumb.visible; },
+ setVisible : function(v, doNotChangeConnections, doNotNotifyOtherEndpoint) {
+ this._jsPlumb.visible = v;
+ if (this.canvas) this.canvas.style.display = v ? "block" : "none";
+ this[v ? "showOverlays" : "hideOverlays"]();
+ if (!doNotChangeConnections) {
+ for (var i = 0; i < this.connections.length; i++) {
+ this.connections[i].setVisible(v);
+ if (!doNotNotifyOtherEndpoint) {
+ var oIdx = this === this.connections[i].endpoints[0] ? 1 : 0;
+ // only change the other endpoint if this is its only connection.
+ if (this.connections[i].endpoints[oIdx].connections.length == 1) this.connections[i].endpoints[oIdx].setVisible(v, true, true);
+ }
+ }
+ }
+ },
+ getAttachedElements : function() {
+ return this.connections;
+ },
+ applyType : function(t, doNotRepaint) {
+ if (t.maxConnections != null) this._jsPlumb.maxConnections = t.maxConnections;
+ if (t.scope) this.scope = t.scope;
+ jsPlumbUtil.copyValues(typeParameters, t, this);
+ },
+ isEnabled : function() { return this._jsPlumb.enabled; },
+ setEnabled : function(e) { this._jsPlumb.enabled = e; },
+ cleanup : function() {
+ jsPlumb.CurrentLibrary.removeClass(this.element, this._jsPlumb.instance.endpointAnchorClassPrefix + "_" + this._jsPlumb.currentAnchorClass);
+ this.anchor = null;
+ this.endpoint.cleanup();
+ this.endpoint.destroy();
+ this.endpoint = null;
+ // drag/drop
+ var i = jsPlumb.CurrentLibrary.getElementObject(this.canvas);
+ jsPlumb.CurrentLibrary.destroyDraggable(i);
+ jsPlumb.CurrentLibrary.destroyDroppable(i);
+ },
+ setHover : function(h) {
+ if (this.endpoint && this._jsPlumb && !this._jsPlumb.instance.isConnectionBeingDragged())
+ this.endpoint.setHover(h);
+ },
+ isFull : function() {
+ return !(this.isFloating() || this._jsPlumb.maxConnections < 1 || this.connections.length < this._jsPlumb.maxConnections);
+ },
+ getConnectionCost : function() { return this._jsPlumb.connectionCost; },
+ setConnectionCost : function(c) {
+ this._jsPlumb.connectionCost = c;
+ },
+ areConnectionsDirected : function() { return this._jsPlumb.connectionsDirected; },
+ setConnectionsDirected : function(b) { this._jsPlumb.connectionsDirected = b; },
+ setElementId : function(_elId) {
+ this.elementId = _elId;
+ this.anchor.elementId = _elId;
+ },
+ setReferenceElement : function(_el) {
+ this.element = jsPlumb.CurrentLibrary.getDOMElement(_el);
+ },
+ setDragAllowedWhenFull : function(allowed) {
+ this.dragAllowedWhenFull = allowed;
+ },
+ equals : function(endpoint) {
+ return this.anchor.equals(endpoint.anchor);
+ },
+ getUuid : function() {
+ return this._jsPlumb.uuid;
+ },
+ computeAnchor : function(params) {
+ return this.anchor.compute(params);
+ }
+ });
+})();
+;(function() {
+
+ var makeConnector = function(_jsPlumb, renderMode, connectorName, connectorArgs) {
+ if (!_jsPlumb.Defaults.DoNotThrowErrors && jsPlumb.Connectors[renderMode][connectorName] == null)
+ throw { msg:"jsPlumb: unknown connector type '" + connectorName + "'" };
+
+ return new jsPlumb.Connectors[renderMode][connectorName](connectorArgs);
+ },
+ _makeAnchor = function(anchorParams, elementId, _jsPlumb) {
+ return (anchorParams) ? _jsPlumb.makeAnchor(anchorParams, elementId, _jsPlumb) : null;
+ },
+ prepareEndpoint = function(_jsPlumb, _newEndpoint, conn, existing, index, params, element, elementId, connectorPaintStyle, connectorHoverPaintStyle) {
+ var e;
+ if (existing) {
+ conn.endpoints[index] = existing;
+ existing.addConnection(conn);
+ } else {
+ if (!params.endpoints) params.endpoints = [ null, null ];
+ var ep = params.endpoints[index] || params.endpoint || _jsPlumb.Defaults.Endpoints[index] || jsPlumb.Defaults.Endpoints[index] || _jsPlumb.Defaults.Endpoint || jsPlumb.Defaults.Endpoint;
+ if (!params.endpointStyles) params.endpointStyles = [ null, null ];
+ if (!params.endpointHoverStyles) params.endpointHoverStyles = [ null, null ];
+ var es = params.endpointStyles[index] || params.endpointStyle || _jsPlumb.Defaults.EndpointStyles[index] || jsPlumb.Defaults.EndpointStyles[index] || _jsPlumb.Defaults.EndpointStyle || jsPlumb.Defaults.EndpointStyle;
+ // Endpoints derive their fillStyle from the connector's strokeStyle, if no fillStyle was specified.
+ if (es.fillStyle == null && connectorPaintStyle != null)
+ es.fillStyle = connectorPaintStyle.strokeStyle;
+
+ // TODO: decide if the endpoint should derive the connection's outline width and color. currently it does:
+ //*
+ if (es.outlineColor == null && connectorPaintStyle != null)
+ es.outlineColor = connectorPaintStyle.outlineColor;
+ if (es.outlineWidth == null && connectorPaintStyle != null)
+ es.outlineWidth = connectorPaintStyle.outlineWidth;
+ //*/
+
+ var ehs = params.endpointHoverStyles[index] || params.endpointHoverStyle || _jsPlumb.Defaults.EndpointHoverStyles[index] || jsPlumb.Defaults.EndpointHoverStyles[index] || _jsPlumb.Defaults.EndpointHoverStyle || jsPlumb.Defaults.EndpointHoverStyle;
+ // endpoint hover fill style is derived from connector's hover stroke style. TODO: do we want to do this by default? for sure?
+ if (connectorHoverPaintStyle != null) {
+ if (ehs == null) ehs = {};
+ if (ehs.fillStyle == null) {
+ ehs.fillStyle = connectorHoverPaintStyle.strokeStyle;
+ }
+ }
+ var a = params.anchors ? params.anchors[index] :
+ params.anchor ? params.anchor :
+ _makeAnchor(_jsPlumb.Defaults.Anchors[index], elementId, _jsPlumb) ||
+ _makeAnchor(jsPlumb.Defaults.Anchors[index], elementId,_jsPlumb) ||
+ _makeAnchor(_jsPlumb.Defaults.Anchor, elementId,_jsPlumb) ||
+ _makeAnchor(jsPlumb.Defaults.Anchor, elementId, _jsPlumb),
+ u = params.uuids ? params.uuids[index] : null;
+ e = _newEndpoint({
+ paintStyle : es, hoverPaintStyle:ehs, endpoint : ep, connections : [ conn ],
+ uuid : u, anchor : a, source : element, scope : params.scope, container:params.container,
+ reattach:params.reattach || _jsPlumb.Defaults.ReattachConnections,
+ detachable:params.detachable || _jsPlumb.Defaults.ConnectionsDetachable
+ });
+ conn.endpoints[index] = e;
+
+ if (params.drawEndpoints === false) e.setVisible(false, true, true);
+
+ }
+ return e;
+ };
+
+ jsPlumb.Connection = function(params) {
+ var _newConnection = params.newConnection,
+ _newEndpoint = params.newEndpoint,
+ jpcl = jsPlumb.CurrentLibrary,
+ _att = jpcl.getAttribute,
+ _gel = jpcl.getElementObject,
+ _dom = jpcl.getDOMElement,
+ _ju = jsPlumbUtil,
+ _getOffset = jpcl.getOffset;
+
+ this.connector = null;
+ this.idPrefix = "_jsplumb_c_";
+ this.defaultLabelLocation = 0.5;
+ this.defaultOverlayKeys = ["Overlays", "ConnectionOverlays"];
+ this.parent = params.parent;
+ // if a new connection is the result of moving some existing connection, params.previousConnection
+ // will have that Connection in it. listeners for the jsPlumbConnection event can look for that
+ // member and take action if they need to.
+ this.previousConnection = params.previousConnection;
+ this.source = _dom(params.source);
+ this.target = _dom(params.target);
+ // sourceEndpoint and targetEndpoint override source/target, if they are present. but
+ // source is not overridden if the Endpoint has declared it is not the final target of a connection;
+ // instead we use the source that the Endpoint declares will be the final source element.
+ if (params.sourceEndpoint) this.source = params.sourceEndpoint.endpointWillMoveTo || params.sourceEndpoint.getElement();
+ if (params.targetEndpoint) this.target = params.targetEndpoint.getElement();
+
+ OverlayCapableJsPlumbUIComponent.apply(this, arguments);
+
+ this.sourceId = this._jsPlumb.instance.getId(this.source);
+ this.targetId = this._jsPlumb.instance.getId(this.target);
+ this.scope = params.scope; // scope may have been passed in to the connect call. if it wasn't, we will pull it from the source endpoint, after having initialised the endpoints.
+ this.endpoints = [];
+ this.endpointStyles = [];
+
+ var _jsPlumb = this._jsPlumb.instance;
+ this._jsPlumb.visible = true;
+ this._jsPlumb.editable = params.editable === true;
+ this._jsPlumb.params = {
+ parent:params.parent,
+ cssClass:params.cssClass,
+ container:params.container,
+ "pointer-events":params["pointer-events"],
+ editorParams:params.editorParams
+ };
+ this._jsPlumb.lastPaintedAt = null;
+ this.getDefaultType = function() {
+ return {
+ parameters:{},
+ scope:null,
+ detachable:this._jsPlumb.instance.Defaults.ConnectionsDetachable,
+ rettach:this._jsPlumb.instance.Defaults.ReattachConnections,
+ paintStyle:this._jsPlumb.instance.Defaults.PaintStyle || jsPlumb.Defaults.PaintStyle,
+ connector:this._jsPlumb.instance.Defaults.Connector || jsPlumb.Defaults.Connector,
+ hoverPaintStyle:this._jsPlumb.instance.Defaults.HoverPaintStyle || jsPlumb.Defaults.HoverPaintStyle,
+ overlays:this._jsPlumb.instance.Defaults.ConnectorOverlays || jsPlumb.Defaults.ConnectorOverlays
+ };
+ };
+
+// INITIALISATION CODE
+
+ // wrapped the main function to return null if no input given. this lets us cascade defaults properly.
+
+ var eS = prepareEndpoint(_jsPlumb, _newEndpoint, this, params.sourceEndpoint, 0, params, this.source, this.sourceId, params.paintStyle, params.hoverPaintStyle);
+ if (eS) _ju.addToList(params.endpointsByElement, this.sourceId, eS);
+ var eT = prepareEndpoint(_jsPlumb, _newEndpoint, this, params.targetEndpoint, 1, params, this.target, this.targetId, params.paintStyle, params.hoverPaintStyle);
+ if (eT) _ju.addToList(params.endpointsByElement, this.targetId, eT);
+ // if scope not set, set it to be the scope for the source endpoint.
+ if (!this.scope) this.scope = this.endpoints[0].scope;
+
+ // if explicitly told to (or not to) delete endpoints on detach, override endpoint's preferences
+ if (params.deleteEndpointsOnDetach != null) {
+ this.endpoints[0]._deleteOnDetach = params.deleteEndpointsOnDetach;
+ this.endpoints[1]._deleteOnDetach = params.deleteEndpointsOnDetach;
+ }
+ else {
+ // otherwise, unless the endpoints say otherwise, mark them for deletion.
+ if (!this.endpoints[0]._doNotDeleteOnDetach) this.endpoints[0]._deleteOnDetach = true;
+ if (!this.endpoints[1]._doNotDeleteOnDetach) this.endpoints[1]._deleteOnDetach = true;
+ }
+
+ // TODO these could surely be refactored into some method that tries them one at a time until something exists
+ this.setConnector(this.endpoints[0].connector ||
+ this.endpoints[1].connector ||
+ params.connector ||
+ _jsPlumb.Defaults.Connector ||
+ jsPlumb.Defaults.Connector, true);
+
+ if (params.path)
+ this.connector.setPath(params.path);
+
+ this.setPaintStyle(this.endpoints[0].connectorStyle ||
+ this.endpoints[1].connectorStyle ||
+ params.paintStyle ||
+ _jsPlumb.Defaults.PaintStyle ||
+ jsPlumb.Defaults.PaintStyle, true);
+
+ this.setHoverPaintStyle(this.endpoints[0].connectorHoverStyle ||
+ this.endpoints[1].connectorHoverStyle ||
+ params.hoverPaintStyle ||
+ _jsPlumb.Defaults.HoverPaintStyle ||
+ jsPlumb.Defaults.HoverPaintStyle, true);
+
+ this._jsPlumb.paintStyleInUse = this.getPaintStyle();
+
+ var _suspendedAt = _jsPlumb.getSuspendedAt();
+ _jsPlumb.updateOffset( { elId : this.sourceId, timestamp:_suspendedAt });
+ _jsPlumb.updateOffset( { elId : this.targetId, timestamp:_suspendedAt });
+
+//*
+ if(!_jsPlumb.isSuspendDrawing()) {
+ // paint the endpoints
+ var myInfo = _jsPlumb.getCachedData(this.sourceId),
+ myOffset = myInfo.o, myWH = myInfo.s,
+ otherInfo = _jsPlumb.getCachedData(this.targetId),
+ otherOffset = otherInfo.o,
+ otherWH = otherInfo.s,
+ initialTimestamp = _suspendedAt || _jsPlumb.timestamp(),
+ anchorLoc = this.endpoints[0].anchor.compute( {
+ xy : [ myOffset.left, myOffset.top ], wh : myWH, element : this.endpoints[0],
+ elementId:this.endpoints[0].elementId,
+ txy : [ otherOffset.left, otherOffset.top ], twh : otherWH, tElement : this.endpoints[1],
+ timestamp:initialTimestamp
+ });
+
+ this.endpoints[0].paint( { anchorLoc : anchorLoc, timestamp:initialTimestamp });
+
+ anchorLoc = this.endpoints[1].anchor.compute( {
+ xy : [ otherOffset.left, otherOffset.top ], wh : otherWH, element : this.endpoints[1],
+ elementId:this.endpoints[1].elementId,
+ txy : [ myOffset.left, myOffset.top ], twh : myWH, tElement : this.endpoints[0],
+ timestamp:initialTimestamp
+ });
+ this.endpoints[1].paint({ anchorLoc : anchorLoc, timestamp:initialTimestamp });
+ }
+ //*/
+
+// END INITIALISATION CODE
+
+// DETACHABLE
+ this._jsPlumb.detachable = _jsPlumb.Defaults.ConnectionsDetachable;
+ if (params.detachable === false) this._jsPlumb.detachable = false;
+ if(this.endpoints[0].connectionsDetachable === false) this._jsPlumb.detachable = false;
+ if(this.endpoints[1].connectionsDetachable === false) this._jsPlumb.detachable = false;
+// REATTACH
+ this._jsPlumb.reattach = params.reattach || this.endpoints[0].reattachConnections || this.endpoints[1].reattachConnections || _jsPlumb.Defaults.ReattachConnections;
+// COST + DIRECTIONALITY
+ // if cost not supplied, try to inherit from source endpoint
+ this._jsPlumb.cost = params.cost || this.endpoints[0].getConnectionCost();
+ this._jsPlumb.directed = params.directed;
+ // inherit directed flag if set no source endpoint
+ if (params.directed == null) this._jsPlumb.directed = this.endpoints[0].areConnectionsDirected();
+// END COST + DIRECTIONALITY
+
+// PARAMETERS
+ // merge all the parameters objects into the connection. parameters set
+ // on the connection take precedence; then source endpoint params, then
+ // finally target endpoint params.
+ // TODO jsPlumb.extend could be made to take more than two args, and it would
+ // apply the second through nth args in order.
+ var _p = jsPlumb.extend({}, this.endpoints[1].getParameters());
+ jsPlumb.extend(_p, this.endpoints[0].getParameters());
+ jsPlumb.extend(_p, this.getParameters());
+ this.setParameters(_p);
+// END PARAMETERS
+
+// PAINTING
+
+ // the very last thing we do is check to see if a 'type' was supplied in the params
+ var _type = params.type || this.endpoints[0].connectionType || this.endpoints[1].connectionType;
+ if (_type)
+ this.addType(_type, params.data, true);
+
+// END PAINTING
+ };
+
+ jsPlumbUtil.extend(jsPlumb.Connection, OverlayCapableJsPlumbUIComponent, {
+ applyType : function(t, doNotRepaint) {
+ if (t.detachable != null) this.setDetachable(t.detachable);
+ if (t.reattach != null) this.setReattach(t.reattach);
+ if (t.scope) this.scope = t.scope;
+ //editable = t.editable; // TODO
+ this.setConnector(t.connector, doNotRepaint);
+ },
+ getTypeDescriptor : function() { return "connection"; },
+ getAttachedElements : function() {
+ return this.endpoints;
+ },
+ addClass : function(c, informEndpoints) {
+ if (informEndpoints) {
+ this.endpoints[0].addClass(c);
+ this.endpoints[1].addClass(c);
+ if (this.suspendedEndpoint) this.suspendedEndpoint.addClass(c);
+ }
+ if (this.connector) {
+ this.connector.addClass(c);
+ }
+ },
+ removeClass : function(c, informEndpoints) {
+ if (informEndpoints) {
+ this.endpoints[0].removeClass(c);
+ this.endpoints[1].removeClass(c);
+ if (this.suspendedEndpoint) this.suspendedEndpoint.removeClass(c);
+ }
+ if (this.connector) {
+ this.connector.removeClass(c);
+ }
+ },
+ isVisible : function() { return this._jsPlumb.visible; },
+ setVisible : function(v) {
+ this._jsPlumb.visible = v;
+ this[v ? "showOverlays" : "hideOverlays"]();
+ if (this.connector && this.connector.canvas) this.connector.canvas.style.display = v ? "block" : "none";
+ this.repaint();
+ },
+ setEditable : function(e) {
+ if (this.connector && this.connector.isEditable())
+ this._jsPlumb.editable = e;
+
+ return this._jsPlumb.editable;
+ },
+ isEditable : function() { return this._jsPlumb.editable; },
+ editStarted : function() {
+ this.setSuspendEvents(true);
+ this.fire("editStarted", {
+ path:this.connector.getPath()
+ });
+ this._jsPlumb.instance.setHoverSuspended(true);
+ },
+ editCompleted : function() {
+ this.fire("editCompleted", {
+ path:this.connector.getPath()
+ });
+ this.setSuspendEvents(false);
+ this.setHover(false);
+ this._jsPlumb.instance.setHoverSuspended(false);
+ },
+ editCanceled : function() {
+ this.fire("editCanceled", {
+ path:this.connector.getPath()
+ });
+ this.setHover(false);
+ this._jsPlumb.instance.setHoverSuspended(false);
+ },
+ cleanup:function() {
+ //this.endpointsToDeleteOnDetach = null;
+ this.endpoints = null;
+ this.source = null;
+ this.target = null;
+ if (this.connector != null) {
+ this.connector.cleanup();
+ this.connector.destroy();
+ }
+ this.connector = null;
+ },
+ isDetachable : function() {
+ return this._jsPlumb.detachable === true;
+ },
+ setDetachable : function(detachable) {
+ this._jsPlumb.detachable = detachable === true;
+ },
+ isReattach : function() {
+ return this._jsPlumb.reattach === true;
+ },
+ setReattach : function(reattach) {
+ this._jsPlumb.reattach = reattach === true;
+ },
+ setHover : function(state) {
+ if (this.connector && this._jsPlumb && !this._jsPlumb.instance.isConnectionBeingDragged()) {
+ this.connector.setHover(state);
+ jsPlumb.CurrentLibrary[state ? "addClass" : "removeClass"](this.source, this._jsPlumb.instance.hoverSourceClass);
+ jsPlumb.CurrentLibrary[state ? "addClass" : "removeClass"](this.target, this._jsPlumb.instance.hoverTargetClass);
+ }
+ },
+ getCost : function() { return this._jsPlumb.cost; },
+ setCost : function(c) { this._jsPlumb.cost = c; },
+ isDirected : function() { return this._jsPlumb.directed === true; },
+ //
+ // changes the parent element of this connection to newParent. not exposed for the public API.
+ //
+ // TODO ensure moveParent method still works (the overlay stuff in particular)
+ moveParent : function(newParent) {
+ var jpcl = jsPlumb.CurrentLibrary, curParent = jpcl.getParent(this.connector.canvas);
+ if (this.connector.bgCanvas) {
+ jpcl.removeElement(this.connector.bgCanvas);
+ jpcl.appendElement(this.connector.bgCanvas, newParent);
+ }
+ jpcl.removeElement(this.connector.canvas);
+ jpcl.appendElement(this.connector.canvas, newParent);
+ // this only applies for DOMOverlays
+ for (var i = 0; i < this._jsPlumb.overlays.length; i++) {
+ if (this._jsPlumb.overlays[i].isAppendedAtTopLevel) {
+ jpcl.removeElement(this._jsPlumb.overlays[i].canvas);
+ jpcl.appendElement(this._jsPlumb.overlays[i].canvas, newParent);
+ if (this._jsPlumb.overlays[i].reattachListeners)
+ this._jsPlumb.overlays[i].reattachListeners(this.connector);
+ }
+ }
+ if (this.connector.reattachListeners) // this is for SVG/VML; change an element's parent and you have to reinit its listeners.
+ this.connector.reattachListeners(); // the Canvas implementation doesn't have to care about this
+ },
+ getConnector : function() { return this.connector; },
+ setConnector : function(connectorSpec, doNotRepaint) {
+ var _ju = jsPlumbUtil;
+ if (this.connector != null) {
+ this.connector.cleanup();
+ this.connector.destroy();
+ }
+
+ var connectorArgs = {
+ _jsPlumb:this._jsPlumb.instance,
+ parent:this._jsPlumb.params.parent,
+ cssClass:this._jsPlumb.params.cssClass,
+ container:this._jsPlumb.params.container,
+ "pointer-events":this._jsPlumb.params["pointer-events"]
+ },
+ renderMode = this._jsPlumb.instance.getRenderMode();
+
+ if (_ju.isString(connectorSpec))
+ this.connector = makeConnector(this._jsPlumb.instance, renderMode, connectorSpec, connectorArgs); // lets you use a string as shorthand.
+ else if (_ju.isArray(connectorSpec)) {
+ if (connectorSpec.length == 1)
+ this.connector = makeConnector(this._jsPlumb.instance, renderMode, connectorSpec[0], connectorArgs);
+ else
+ this.connector = makeConnector(this._jsPlumb.instance, renderMode, connectorSpec[0], _ju.merge(connectorSpec[1], connectorArgs));
+ }
+ // binds mouse listeners to the current connector.
+ this.bindListeners(this.connector, this, function(state) {
+ this.setHover(state, false);
+ }.bind(this));
+
+ this.canvas = this.connector.canvas;
+
+ if (this._jsPlumb.editable && jsPlumb.ConnectorEditors != null && jsPlumb.ConnectorEditors[this.connector.type] && this.connector.isEditable()) {
+ new jsPlumb.ConnectorEditors[this.connector.type]({
+ connector:this.connector,
+ connection:this,
+ params:this._jsPlumb.params.editorParams || { }
+ });
+ }
+ else {
+ editable = false;
+ }
+
+ if (!doNotRepaint) this.repaint();
+ },
+ paint : function(params) {
+
+ if (!this._jsPlumb.instance.isSuspendDrawing() && this._jsPlumb.visible) {
+
+ params = params || {};
+ var elId = params.elId, ui = params.ui, recalc = params.recalc, timestamp = params.timestamp,
+ // if the moving object is not the source we must transpose the two references.
+ swap = false,
+ tId = swap ? this.sourceId : this.targetId, sId = swap ? this.targetId : this.sourceId,
+ tIdx = swap ? 0 : 1, sIdx = swap ? 1 : 0;
+
+ if (timestamp == null || timestamp != this._jsPlumb.lastPaintedAt) {
+ var sourceInfo = this._jsPlumb.instance.updateOffset( { elId : sId, offset : ui, recalc : recalc, timestamp : timestamp }).o,
+ targetInfo = this._jsPlumb.instance.updateOffset( { elId : tId, timestamp : timestamp }).o, // update the target if this is a forced repaint. otherwise, only the source has been moved.
+ sE = this.endpoints[sIdx], tE = this.endpoints[tIdx];
+
+ if (params.clearEdits) {
+ sE.anchor.clearUserDefinedLocation();
+ tE.anchor.clearUserDefinedLocation();
+ this.connector.setEdited(false);
+ }
+
+ var sAnchorP = sE.anchor.getCurrentLocation({xy:[sourceInfo.left,sourceInfo.top], wh:[sourceInfo.width, sourceInfo.height], element:sE, timestamp:timestamp}),
+ tAnchorP = tE.anchor.getCurrentLocation({xy:[targetInfo.left,targetInfo.top], wh:[targetInfo.width, targetInfo.height], element:tE, timestamp:timestamp});
+
+ this.connector.resetBounds();
+
+ this.connector.compute({
+ sourcePos:sAnchorP,
+ targetPos:tAnchorP,
+ sourceEndpoint:this.endpoints[sIdx],
+ targetEndpoint:this.endpoints[tIdx],
+ lineWidth:this._jsPlumb.paintStyleInUse.lineWidth,
+ sourceInfo:sourceInfo,
+ targetInfo:targetInfo,
+ clearEdits:params.clearEdits === true
+ });
+
+ var overlayExtents = { minX:Infinity, minY:Infinity, maxX:-Infinity, maxY:-Infinity };
+
+ // compute overlays. we do this first so we can get their placements, and adjust the
+ // container if needs be (if an overlay would be clipped)
+ for ( var i = 0; i < this._jsPlumb.overlays.length; i++) {
+ var o = this._jsPlumb.overlays[i];
+ if (o.isVisible()) {
+ this._jsPlumb.overlayPlacements[i] = o.draw(this.connector, this._jsPlumb.paintStyleInUse);
+ overlayExtents.minX = Math.min(overlayExtents.minX, this._jsPlumb.overlayPlacements[i].minX);
+ overlayExtents.maxX = Math.max(overlayExtents.maxX, this._jsPlumb.overlayPlacements[i].maxX);
+ overlayExtents.minY = Math.min(overlayExtents.minY, this._jsPlumb.overlayPlacements[i].minY);
+ overlayExtents.maxY = Math.max(overlayExtents.maxY, this._jsPlumb.overlayPlacements[i].maxY);
+ }
+ }
+
+ var lineWidth = parseFloat(this._jsPlumb.paintStyleInUse.lineWidth || 1) / 2,
+ outlineWidth = parseFloat(this._jsPlumb.paintStyleInUse.lineWidth || 0),
+ extents = {
+ xmin : Math.min(this.connector.bounds.minX - (lineWidth + outlineWidth), overlayExtents.minX),
+ ymin : Math.min(this.connector.bounds.minY - (lineWidth + outlineWidth), overlayExtents.minY),
+ xmax : Math.max(this.connector.bounds.maxX + (lineWidth + outlineWidth), overlayExtents.maxX),
+ ymax : Math.max(this.connector.bounds.maxY + (lineWidth + outlineWidth), overlayExtents.maxY)
+ };
+
+ // paint the connector.
+ this.connector.paint(this._jsPlumb.paintStyleInUse, null, extents);
+ // and then the overlays
+ for ( var j = 0; j < this._jsPlumb.overlays.length; j++) {
+ var p = this._jsPlumb.overlays[j];
+ if (p.isVisible()) {
+ p.paint(this._jsPlumb.overlayPlacements[j], extents);
+ }
+ }
+ }
+ this._jsPlumb.lastPaintedAt = timestamp;
+ }
+ },
+ /*
+ * Function: repaint
+ * Repaints the Connection. No parameters exposed to public API.
+ */
+ repaint : function(params) {
+ params = params || {};
+ this.paint({ elId : this.sourceId, recalc : !(params.recalc === false), timestamp:params.timestamp, clearEdits:params.clearEdits });
+ }
+
+ }); // END Connection class
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the code for creating and manipulating anchors.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+;(function() {
+
+ //
+ // manages anchors for all elements.
+ //
+ jsPlumb.AnchorManager = function(params) {
+ var _amEndpoints = {},
+ continuousAnchors = {},
+ continuousAnchorLocations = {},
+ userDefinedContinuousAnchorLocations = {},
+ continuousAnchorOrientations = {},
+ Orientation = { HORIZONTAL : "horizontal", VERTICAL : "vertical", DIAGONAL : "diagonal", IDENTITY:"identity" },
+ connectionsByElementId = {},
+ self = this,
+ anchorLists = {},
+ jsPlumbInstance = params.jsPlumbInstance,
+ jpcl = jsPlumb.CurrentLibrary,
+ floatingConnections = {},
+ // TODO this functions uses a crude method of determining orientation between two elements.
+ // 'diagonal' should be chosen when the angle of the line between the two centers is around
+ // one of 45, 135, 225 and 315 degrees. maybe +- 15 degrees.
+ // used by AnchorManager.redraw
+ calculateOrientation = function(sourceId, targetId, sd, td, sourceAnchor, targetAnchor) {
+
+ if (sourceId === targetId) return {
+ orientation:Orientation.IDENTITY,
+ a:["top", "top"]
+ };
+
+ var theta = Math.atan2((td.centery - sd.centery) , (td.centerx - sd.centerx)),
+ theta2 = Math.atan2((sd.centery - td.centery) , (sd.centerx - td.centerx)),
+ h = ((sd.left <= td.left && sd.right >= td.left) || (sd.left <= td.right && sd.right >= td.right) ||
+ (sd.left <= td.left && sd.right >= td.right) || (td.left <= sd.left && td.right >= sd.right)),
+ v = ((sd.top <= td.top && sd.bottom >= td.top) || (sd.top <= td.bottom && sd.bottom >= td.bottom) ||
+ (sd.top <= td.top && sd.bottom >= td.bottom) || (td.top <= sd.top && td.bottom >= sd.bottom)),
+ possiblyTranslateEdges = function(edges) {
+ // this function checks to see if either anchor is Continuous, and if so, runs the suggested edge
+ // through the anchor: Continuous anchors can say which faces they support, and they get to choose
+ // whether a certain face is honoured, or, if not, which face to replace it with. the behaviour when
+ // choosing an alternate face is to try for the opposite face first, then the next one clockwise, and then
+ // the opposite of that one.
+ return [
+ sourceAnchor.isContinuous ? sourceAnchor.verifyEdge(edges[0]) : edges[0],
+ targetAnchor.isContinuous ? targetAnchor.verifyEdge(edges[1]) : edges[1]
+ ];
+ },
+ out = {
+ orientation:Orientation.DIAGONAL,
+ theta:theta,
+ theta2:theta2
+ };
+
+ if (! (h || v)) {
+ if (td.left > sd.left && td.top > sd.top)
+ out.a = ["right", "top"];
+ else if (td.left > sd.left && sd.top > td.top)
+ out.a = [ "top", "left"];
+ else if (td.left < sd.left && td.top < sd.top)
+ out.a = [ "top", "right"];
+ else if (td.left < sd.left && td.top > sd.top)
+ out.a = ["left", "top" ];
+ }
+ else if (h) {
+ out.orientation = Orientation.HORIZONTAL;
+ out.a = sd.top < td.top ? ["bottom", "top"] : ["top", "bottom"];
+ }
+ else {
+ out.orientation = Orientation.VERTICAL;
+ out.a = sd.left < td.left ? ["right", "left"] : ["left", "right"];
+ }
+
+ out.a = possiblyTranslateEdges(out.a);
+ return out;
+ },
+ // used by placeAnchors function
+ placeAnchorsOnLine = function(desc, elementDimensions, elementPosition,
+ connections, horizontal, otherMultiplier, reverse) {
+ var a = [], step = elementDimensions[horizontal ? 0 : 1] / (connections.length + 1);
+
+ for (var i = 0; i < connections.length; i++) {
+ var val = (i + 1) * step, other = otherMultiplier * elementDimensions[horizontal ? 1 : 0];
+ if (reverse)
+ val = elementDimensions[horizontal ? 0 : 1] - val;
+
+ var dx = (horizontal ? val : other), x = elementPosition[0] + dx, xp = dx / elementDimensions[0],
+ dy = (horizontal ? other : val), y = elementPosition[1] + dy, yp = dy / elementDimensions[1];
+
+ a.push([ x, y, xp, yp, connections[i][1], connections[i][2] ]);
+ }
+
+ return a;
+ },
+ // used by edgeSortFunctions
+ currySort = function(reverseAngles) {
+ return function(a,b) {
+ var r = true;
+ if (reverseAngles) {
+ /*if (a[0][0] < b[0][0])
+ r = true;
+ else
+ r = a[0][1] > b[0][1];*/
+ r = a[0][0] < b[0][0];
+ }
+ else {
+ /*if (a[0][0] > b[0][0])
+ r= true;
+ else
+ r =a[0][1] > b[0][1];
+ */
+ r = a[0][0] > b[0][0];
+ }
+ return r === false ? -1 : 1;
+ };
+ },
+ // used by edgeSortFunctions
+ leftSort = function(a,b) {
+ // first get adjusted values
+ var p1 = a[0][0] < 0 ? -Math.PI - a[0][0] : Math.PI - a[0][0],
+ p2 = b[0][0] < 0 ? -Math.PI - b[0][0] : Math.PI - b[0][0];
+ if (p1 > p2) return 1;
+ else return a[0][1] > b[0][1] ? 1 : -1;
+ },
+ // used by placeAnchors
+ edgeSortFunctions = {
+ "top":function(a, b) { return a[0] > b[0] ? 1 : -1; },
+ "right":currySort(true),
+ "bottom":currySort(true),
+ "left":leftSort
+ },
+ // used by placeAnchors
+ _sortHelper = function(_array, _fn) { return _array.sort(_fn); },
+ // used by AnchorManager.redraw
+ placeAnchors = function(elementId, _anchorLists) {
+ var cd = jsPlumbInstance.getCachedData(elementId), sS = cd.s, sO = cd.o,
+ placeSomeAnchors = function(desc, elementDimensions, elementPosition, unsortedConnections, isHorizontal, otherMultiplier, orientation) {
+ if (unsortedConnections.length > 0) {
+ var sc = _sortHelper(unsortedConnections, edgeSortFunctions[desc]), // puts them in order based on the target element's pos on screen
+ reverse = desc === "right" || desc === "top",
+ anchors = placeAnchorsOnLine(desc, elementDimensions,
+ elementPosition, sc,
+ isHorizontal, otherMultiplier, reverse );
+
+ // takes a computed anchor position and adjusts it for parent offset and scroll, then stores it.
+ var _setAnchorLocation = function(endpoint, anchorPos) {
+ var a = jsPlumbInstance.adjustForParentOffsetAndScroll([anchorPos[0], anchorPos[1]], endpoint.canvas);
+ continuousAnchorLocations[endpoint.id] = [ a[0], a[1], anchorPos[2], anchorPos[3] ];
+ continuousAnchorOrientations[endpoint.id] = orientation;
+ };
+
+ for (var i = 0; i < anchors.length; i++) {
+ var c = anchors[i][4], weAreSource = c.endpoints[0].elementId === elementId, weAreTarget = c.endpoints[1].elementId === elementId;
+ if (weAreSource)
+ _setAnchorLocation(c.endpoints[0], anchors[i]);
+ else if (weAreTarget)
+ _setAnchorLocation(c.endpoints[1], anchors[i]);
+ }
+ }
+ };
+
+ placeSomeAnchors("bottom", sS, [sO.left,sO.top], _anchorLists.bottom, true, 1, [0,1]);
+ placeSomeAnchors("top", sS, [sO.left,sO.top], _anchorLists.top, true, 0, [0,-1]);
+ placeSomeAnchors("left", sS, [sO.left,sO.top], _anchorLists.left, false, 0, [-1,0]);
+ placeSomeAnchors("right", sS, [sO.left,sO.top], _anchorLists.right, false, 1, [1,0]);
+ };
+
+ this.reset = function() {
+ _amEndpoints = {};
+ connectionsByElementId = {};
+ anchorLists = {};
+ };
+ this.addFloatingConnection = function(key, conn) {
+ floatingConnections[key] = conn;
+ };
+ this.removeFloatingConnection = function(key) {
+ delete floatingConnections[key];
+ };
+ this.newConnection = function(conn) {
+ var sourceId = conn.sourceId, targetId = conn.targetId,
+ ep = conn.endpoints,
+ doRegisterTarget = true,
+ registerConnection = function(otherIndex, otherEndpoint, otherAnchor, elId, c) {
+ if ((sourceId == targetId) && otherAnchor.isContinuous){
+ // remove the target endpoint's canvas. we dont need it.
+ jpcl.removeElement(ep[1].canvas);
+ doRegisterTarget = false;
+ }
+ jsPlumbUtil.addToList(connectionsByElementId, elId, [c, otherEndpoint, otherAnchor.constructor == jsPlumb.DynamicAnchor]);
+ };
+
+ registerConnection(0, ep[0], ep[0].anchor, targetId, conn);
+ if (doRegisterTarget)
+ registerConnection(1, ep[1], ep[1].anchor, sourceId, conn);
+ };
+ var removeEndpointFromAnchorLists = function(endpoint) {
+ (function(list, eId) {
+ if (list) { // transient anchors dont get entries in this list.
+ var f = function(e) { return e[4] == eId; };
+ jsPlumbUtil.removeWithFunction(list.top, f);
+ jsPlumbUtil.removeWithFunction(list.left, f);
+ jsPlumbUtil.removeWithFunction(list.bottom, f);
+ jsPlumbUtil.removeWithFunction(list.right, f);
+ }
+ })(anchorLists[endpoint.elementId], endpoint.id);
+ };
+ this.connectionDetached = function(connInfo) {
+ var connection = connInfo.connection || connInfo,
+ sourceId = connInfo.sourceId,
+ targetId = connInfo.targetId,
+ ep = connection.endpoints,
+ removeConnection = function(otherIndex, otherEndpoint, otherAnchor, elId, c) {
+ if (otherAnchor != null && otherAnchor.constructor == jsPlumb.FloatingAnchor) {
+ // no-op
+ }
+ else {
+ jsPlumbUtil.removeWithFunction(connectionsByElementId[elId], function(_c) {
+ return _c[0].id == c.id;
+ });
+ }
+ };
+
+ removeConnection(1, ep[1], ep[1].anchor, sourceId, connection);
+ removeConnection(0, ep[0], ep[0].anchor, targetId, connection);
+
+ // remove from anchorLists
+ removeEndpointFromAnchorLists(connection.endpoints[0]);
+ removeEndpointFromAnchorLists(connection.endpoints[1]);
+
+ self.redraw(connection.sourceId);
+ self.redraw(connection.targetId);
+ };
+ this.add = function(endpoint, elementId) {
+ jsPlumbUtil.addToList(_amEndpoints, elementId, endpoint);
+ };
+ this.changeId = function(oldId, newId) {
+ connectionsByElementId[newId] = connectionsByElementId[oldId];
+ _amEndpoints[newId] = _amEndpoints[oldId];
+ delete connectionsByElementId[oldId];
+ delete _amEndpoints[oldId];
+ };
+ this.getConnectionsFor = function(elementId) {
+ return connectionsByElementId[elementId] || [];
+ };
+ this.getEndpointsFor = function(elementId) {
+ return _amEndpoints[elementId] || [];
+ };
+ this.deleteEndpoint = function(endpoint) {
+ jsPlumbUtil.removeWithFunction(_amEndpoints[endpoint.elementId], function(e) {
+ return e.id == endpoint.id;
+ });
+ removeEndpointFromAnchorLists(endpoint);
+ };
+ this.clearFor = function(elementId) {
+ delete _amEndpoints[elementId];
+ _amEndpoints[elementId] = [];
+ };
+ // updates the given anchor list by either updating an existing anchor's info, or adding it. this function
+ // also removes the anchor from its previous list, if the edge it is on has changed.
+ // all connections found along the way (those that are connected to one of the faces this function
+ // operates on) are added to the connsToPaint list, as are their endpoints. in this way we know to repaint
+ // them wthout having to calculate anything else about them.
+ var _updateAnchorList = function(lists, theta, order, conn, aBoolean, otherElId, idx, reverse, edgeId, elId, connsToPaint, endpointsToPaint) {
+ // first try to find the exact match, but keep track of the first index of a matching element id along the way.s
+ var exactIdx = -1,
+ firstMatchingElIdx = -1,
+ endpoint = conn.endpoints[idx],
+ endpointId = endpoint.id,
+ oIdx = [1,0][idx],
+ values = [ [ theta, order ], conn, aBoolean, otherElId, endpointId ],
+ listToAddTo = lists[edgeId],
+ listToRemoveFrom = endpoint._continuousAnchorEdge ? lists[endpoint._continuousAnchorEdge] : null;
+
+ if (listToRemoveFrom) {
+ var rIdx = jsPlumbUtil.findWithFunction(listToRemoveFrom, function(e) { return e[4] == endpointId; });
+ if (rIdx != -1) {
+ listToRemoveFrom.splice(rIdx, 1);
+ // get all connections from this list
+ for (var i = 0; i < listToRemoveFrom.length; i++) {
+ jsPlumbUtil.addWithFunction(connsToPaint, listToRemoveFrom[i][1], function(c) { return c.id == listToRemoveFrom[i][1].id; });
+ jsPlumbUtil.addWithFunction(endpointsToPaint, listToRemoveFrom[i][1].endpoints[idx], function(e) { return e.id == listToRemoveFrom[i][1].endpoints[idx].id; });
+ jsPlumbUtil.addWithFunction(endpointsToPaint, listToRemoveFrom[i][1].endpoints[oIdx], function(e) { return e.id == listToRemoveFrom[i][1].endpoints[oIdx].id; });
+ }
+ }
+ }
+
+ for (i = 0; i < listToAddTo.length; i++) {
+ if (params.idx == 1 && listToAddTo[i][3] === otherElId && firstMatchingElIdx == -1)
+ firstMatchingElIdx = i;
+ jsPlumbUtil.addWithFunction(connsToPaint, listToAddTo[i][1], function(c) { return c.id == listToAddTo[i][1].id; });
+ jsPlumbUtil.addWithFunction(endpointsToPaint, listToAddTo[i][1].endpoints[idx], function(e) { return e.id == listToAddTo[i][1].endpoints[idx].id; });
+ jsPlumbUtil.addWithFunction(endpointsToPaint, listToAddTo[i][1].endpoints[oIdx], function(e) { return e.id == listToAddTo[i][1].endpoints[oIdx].id; });
+ }
+ if (exactIdx != -1) {
+ listToAddTo[exactIdx] = values;
+ }
+ else {
+ var insertIdx = reverse ? firstMatchingElIdx != -1 ? firstMatchingElIdx : 0 : listToAddTo.length; // of course we will get this from having looked through the array shortly.
+ listToAddTo.splice(insertIdx, 0, values);
+ }
+
+ // store this for next time.
+ endpoint._continuousAnchorEdge = edgeId;
+ };
+
+ //
+ // find the entry in an endpoint's list for this connection and update its target endpoint
+ // with the current target in the connection.
+ //
+ //
+ this.updateOtherEndpoint = function(elId, oldTargetId, newTargetId, connection) {
+ var sIndex = jsPlumbUtil.findWithFunction(connectionsByElementId[elId], function(i) {
+ return i[0].id === connection.id;
+ }),
+ tIndex = jsPlumbUtil.findWithFunction(connectionsByElementId[oldTargetId], function(i) {
+ return i[0].id === connection.id;
+ });
+
+ // update or add data for source
+ if (sIndex != -1) {
+ connectionsByElementId[elId][sIndex][0] = connection;
+ connectionsByElementId[elId][sIndex][1] = connection.endpoints[1];
+ connectionsByElementId[elId][sIndex][2] = connection.endpoints[1].anchor.constructor == jsPlumb.DynamicAnchor;
+ }
+
+ // remove entry for previous target (if there)
+ if (tIndex > -1) {
+
+ connectionsByElementId[oldTargetId].splice(tIndex, 1);
+ // add entry for new target
+ jsPlumbUtil.addToList(connectionsByElementId, newTargetId, [connection, connection.endpoints[0], connection.endpoints[0].anchor.constructor == jsPlumb.DynamicAnchor]);
+ }
+ };
+
+ //
+ // notification that the connection given has changed source from the originalId to the newId.
+ // This involves:
+ // 1. removing the connection from the list of connections stored for the originalId
+ // 2. updating the source information for the target of the connection
+ // 3. re-registering the connection in connectionsByElementId with the newId
+ //
+ this.sourceChanged = function(originalId, newId, connection) {
+ // remove the entry that points from the old source to the target
+ jsPlumbUtil.removeWithFunction(connectionsByElementId[originalId], function(info) {
+ return info[0].id === connection.id;
+ });
+ // find entry for target and update it
+ var tIdx = jsPlumbUtil.findWithFunction(connectionsByElementId[connection.targetId], function(i) {
+ return i[0].id === connection.id;
+ });
+ if (tIdx > -1) {
+ connectionsByElementId[connection.targetId][tIdx][0] = connection;
+ connectionsByElementId[connection.targetId][tIdx][1] = connection.endpoints[0];
+ connectionsByElementId[connection.targetId][tIdx][2] = connection.endpoints[0].anchor.constructor == jsPlumb.DynamicAnchor;
+ }
+ // add entry for new source
+ jsPlumbUtil.addToList(connectionsByElementId, newId, [connection, connection.endpoints[1], connection.endpoints[1].anchor.constructor == jsPlumb.DynamicAnchor]);
+ };
+
+ //
+ // moves the given endpoint from `currentId` to `element`.
+ // This involves:
+ //
+ // 1. changing the key in _amEndpoints under which the endpoint is stored
+ // 2. changing the source or target values in all of the endpoint's connections
+ // 3. changing the array in connectionsByElementId in which the endpoint's connections
+ // are stored (done by either sourceChanged or updateOtherEndpoint)
+ //
+ this.rehomeEndpoint = function(ep, currentId, element) {
+ var eps = _amEndpoints[currentId] || [],
+ elementId = jsPlumbInstance.getId(element);
+
+ if (elementId !== currentId) {
+ var idx = jsPlumbUtil.indexOf(eps, ep);
+ if (idx > -1) {
+ var _ep = eps.splice(idx, 1)[0];
+ self.add(_ep, elementId);
+ }
+ }
+
+ for (var i = 0; i < ep.connections.length; i++) {
+ if (ep.connections[i].sourceId == currentId) {
+ ep.connections[i].sourceId = ep.elementId;
+ ep.connections[i].source = ep.element;
+ self.sourceChanged(currentId, ep.elementId, ep.connections[i]);
+ }
+ else if(ep.connections[i].targetId == currentId) {
+ ep.connections[i].targetId = ep.elementId;
+ ep.connections[i].target = ep.element;
+ self.updateOtherEndpoint(ep.connections[i].sourceId, currentId, ep.elementId, ep.connections[i]);
+ }
+ }
+ };
+
+ this.redraw = function(elementId, ui, timestamp, offsetToUI, clearEdits, doNotRecalcEndpoint) {
+
+ if (!jsPlumbInstance.isSuspendDrawing()) {
+ // get all the endpoints for this element
+ var ep = _amEndpoints[elementId] || [],
+ endpointConnections = connectionsByElementId[elementId] || [],
+ connectionsToPaint = [],
+ endpointsToPaint = [],
+ anchorsToUpdate = [];
+
+ timestamp = timestamp || jsPlumbInstance.timestamp();
+ // offsetToUI are values that would have been calculated in the dragManager when registering
+ // an endpoint for an element that had a parent (somewhere in the hierarchy) that had been
+ // registered as draggable.
+ offsetToUI = offsetToUI || {left:0, top:0};
+ if (ui) {
+ ui = {
+ left:ui.left + offsetToUI.left,
+ top:ui.top + offsetToUI.top
+ };
+ }
+
+ // valid for one paint cycle.
+ var myOffset = jsPlumbInstance.updateOffset( { elId : elementId, offset : ui, recalc : false, timestamp : timestamp }),
+ orientationCache = {};
+
+ // actually, first we should compute the orientation of this element to all other elements to which
+ // this element is connected with a continuous anchor (whether both ends of the connection have
+ // a continuous anchor or just one)
+
+ for (var i = 0; i < endpointConnections.length; i++) {
+ var conn = endpointConnections[i][0],
+ sourceId = conn.sourceId,
+ targetId = conn.targetId,
+ sourceContinuous = conn.endpoints[0].anchor.isContinuous,
+ targetContinuous = conn.endpoints[1].anchor.isContinuous;
+
+ if (sourceContinuous || targetContinuous) {
+ var oKey = sourceId + "_" + targetId,
+ oKey2 = targetId + "_" + sourceId,
+ o = orientationCache[oKey],
+ oIdx = conn.sourceId == elementId ? 1 : 0;
+
+ if (sourceContinuous && !anchorLists[sourceId]) anchorLists[sourceId] = { top:[], right:[], bottom:[], left:[] };
+ if (targetContinuous && !anchorLists[targetId]) anchorLists[targetId] = { top:[], right:[], bottom:[], left:[] };
+
+ if (elementId != targetId) jsPlumbInstance.updateOffset( { elId : targetId, timestamp : timestamp });
+ if (elementId != sourceId) jsPlumbInstance.updateOffset( { elId : sourceId, timestamp : timestamp });
+
+ var td = jsPlumbInstance.getCachedData(targetId),
+ sd = jsPlumbInstance.getCachedData(sourceId);
+
+ if (targetId == sourceId && (sourceContinuous || targetContinuous)) {
+ // here we may want to improve this by somehow determining the face we'd like
+ // to put the connector on. ideally, when drawing, the face should be calculated
+ // by determining which face is closest to the point at which the mouse button
+ // was released. for now, we're putting it on the top face.
+ _updateAnchorList(
+ anchorLists[sourceId],
+ -Math.PI / 2,
+ 0,
+ conn,
+ false,
+ targetId,
+ 0, false, "top", sourceId, connectionsToPaint, endpointsToPaint);
+ }
+ else {
+ if (!o) {
+ o = calculateOrientation(sourceId, targetId, sd.o, td.o, conn.endpoints[0].anchor, conn.endpoints[1].anchor);
+ orientationCache[oKey] = o;
+ // this would be a performance enhancement, but the computed angles need to be clamped to
+ //the (-PI/2 -> PI/2) range in order for the sorting to work properly.
+ /* orientationCache[oKey2] = {
+ orientation:o.orientation,
+ a:[o.a[1], o.a[0]],
+ theta:o.theta + Math.PI,
+ theta2:o.theta2 + Math.PI
+ };*/
+ }
+ if (sourceContinuous) _updateAnchorList(anchorLists[sourceId], o.theta, 0, conn, false, targetId, 0, false, o.a[0], sourceId, connectionsToPaint, endpointsToPaint);
+ if (targetContinuous) _updateAnchorList(anchorLists[targetId], o.theta2, -1, conn, true, sourceId, 1, true, o.a[1], targetId, connectionsToPaint, endpointsToPaint);
+ }
+
+ if (sourceContinuous) jsPlumbUtil.addWithFunction(anchorsToUpdate, sourceId, function(a) { return a === sourceId; });
+ if (targetContinuous) jsPlumbUtil.addWithFunction(anchorsToUpdate, targetId, function(a) { return a === targetId; });
+ jsPlumbUtil.addWithFunction(connectionsToPaint, conn, function(c) { return c.id == conn.id; });
+ if ((sourceContinuous && oIdx === 0) || (targetContinuous && oIdx === 1))
+ jsPlumbUtil.addWithFunction(endpointsToPaint, conn.endpoints[oIdx], function(e) { return e.id == conn.endpoints[oIdx].id; });
+ }
+ }
+ // place Endpoints whose anchors are continuous but have no Connections
+ for (i = 0; i < ep.length; i++) {
+ if (ep[i].connections.length === 0 && ep[i].anchor.isContinuous) {
+ if (!anchorLists[elementId]) anchorLists[elementId] = { top:[], right:[], bottom:[], left:[] };
+ _updateAnchorList(anchorLists[elementId], -Math.PI / 2, 0, {endpoints:[ep[i], ep[i]], paint:function(){}}, false, elementId, 0, false, "top", elementId, connectionsToPaint, endpointsToPaint);
+ jsPlumbUtil.addWithFunction(anchorsToUpdate, elementId, function(a) { return a === elementId; });
+ }
+ }
+ // now place all the continuous anchors we need to;
+ for (i = 0; i < anchorsToUpdate.length; i++) {
+ placeAnchors(anchorsToUpdate[i], anchorLists[anchorsToUpdate[i]]);
+ }
+
+ // now that continuous anchors have been placed, paint all the endpoints for this element
+ // TODO performance: add the endpoint ids to a temp array, and then when iterating in the next
+ // loop, check that we didn't just paint that endpoint. we can probably shave off a few more milliseconds this way.
+ for (i = 0; i < ep.length; i++) {
+ ep[i].paint( { timestamp : timestamp, offset : myOffset, dimensions : myOffset.s, recalc:doNotRecalcEndpoint !== true });
+ }
+ // ... and any other endpoints we came across as a result of the continuous anchors.
+ for (i = 0; i < endpointsToPaint.length; i++) {
+ var cd = jsPlumbInstance.getCachedData(endpointsToPaint[i].elementId);
+ endpointsToPaint[i].paint( { timestamp : timestamp, offset : cd, dimensions : cd.s });
+ }
+
+ // paint all the standard and "dynamic connections", which are connections whose other anchor is
+ // static and therefore does need to be recomputed; we make sure that happens only one time.
+
+ // TODO we could have compiled a list of these in the first pass through connections; might save some time.
+ for (i = 0; i < endpointConnections.length; i++) {
+ var otherEndpoint = endpointConnections[i][1];
+ if (otherEndpoint.anchor.constructor == jsPlumb.DynamicAnchor) {
+ otherEndpoint.paint({ elementWithPrecedence:elementId, timestamp:timestamp });
+ jsPlumbUtil.addWithFunction(connectionsToPaint, endpointConnections[i][0], function(c) { return c.id == endpointConnections[i][0].id; });
+ // all the connections for the other endpoint now need to be repainted
+ for (var k = 0; k < otherEndpoint.connections.length; k++) {
+ if (otherEndpoint.connections[k] !== endpointConnections[i][0])
+ jsPlumbUtil.addWithFunction(connectionsToPaint, otherEndpoint.connections[k], function(c) { return c.id == otherEndpoint.connections[k].id; });
+ }
+ } else if (otherEndpoint.anchor.constructor == jsPlumb.Anchor) {
+ jsPlumbUtil.addWithFunction(connectionsToPaint, endpointConnections[i][0], function(c) { return c.id == endpointConnections[i][0].id; });
+ }
+ }
+ // paint current floating connection for this element, if there is one.
+ var fc = floatingConnections[elementId];
+ if (fc)
+ fc.paint({timestamp:timestamp, recalc:false, elId:elementId});
+
+ // paint all the connections
+ for (i = 0; i < connectionsToPaint.length; i++) {
+ connectionsToPaint[i].paint({elId:elementId, timestamp:timestamp, recalc:false, clearEdits:clearEdits});
+ }
+ }
+ };
+
+ var ContinuousAnchor = function(anchorParams) {
+ jsPlumbUtil.EventGenerator.apply(this);
+ this.type = "Continuous";
+ this.isDynamic = true;
+ this.isContinuous = true;
+ var faces = anchorParams.faces || ["top", "right", "bottom", "left"],
+ clockwise = !(anchorParams.clockwise === false),
+ availableFaces = { },
+ opposites = { "top":"bottom", "right":"left","left":"right","bottom":"top" },
+ clockwiseOptions = { "top":"right", "right":"bottom","left":"top","bottom":"left" },
+ antiClockwiseOptions = { "top":"left", "right":"top","left":"bottom","bottom":"right" },
+ secondBest = clockwise ? clockwiseOptions : antiClockwiseOptions,
+ lastChoice = clockwise ? antiClockwiseOptions : clockwiseOptions,
+ cssClass = anchorParams.cssClass || "";
+
+ for (var i = 0; i < faces.length; i++) { availableFaces[faces[i]] = true; }
+
+ // if the given edge is supported, returns it. otherwise looks for a substitute that _is_
+ // supported. if none supported we also return the request edge.
+ this.verifyEdge = function(edge) {
+ if (availableFaces[edge]) return edge;
+ else if (availableFaces[opposites[edge]]) return opposites[edge];
+ else if (availableFaces[secondBest[edge]]) return secondBest[edge];
+ else if (availableFaces[lastChoice[edge]]) return lastChoice[edge];
+ return edge; // we have to give them something.
+ };
+
+ this.compute = function(params) {
+ return userDefinedContinuousAnchorLocations[params.element.id] || continuousAnchorLocations[params.element.id] || [0,0];
+ };
+ this.getCurrentLocation = function(params) {
+ return userDefinedContinuousAnchorLocations[params.element.id] || continuousAnchorLocations[params.element.id] || [0,0];
+ };
+ this.getOrientation = function(endpoint) {
+ return continuousAnchorOrientations[endpoint.id] || [0,0];
+ };
+ this.clearUserDefinedLocation = function() {
+ delete userDefinedContinuousAnchorLocations[anchorParams.elementId];
+ };
+ this.setUserDefinedLocation = function(loc) {
+ userDefinedContinuousAnchorLocations[anchorParams.elementId] = loc;
+ };
+ this.getCssClass = function() { return cssClass; };
+ this.setCssClass = function(c) { cssClass = c; };
+ };
+
+ // continuous anchors
+ jsPlumbInstance.continuousAnchorFactory = {
+ get:function(params) {
+ var existing = continuousAnchors[params.elementId];
+ if (!existing) {
+ existing = new ContinuousAnchor(params);
+ continuousAnchors[params.elementId] = existing;
+ }
+ return existing;
+ },
+ clear:function(elementId) {
+ delete continuousAnchors[elementId];
+ }
+ };
+ };
+
+ /**
+ * Anchors model a position on some element at which an Endpoint may be located. They began as a first class citizen of jsPlumb, ie. a user
+ * was required to create these themselves, but over time this has been replaced by the concept of referring to them either by name (eg. "TopMiddle"),
+ * or by an array describing their coordinates (eg. [ 0, 0.5, 0, -1 ], which is the same as "TopMiddle"). jsPlumb now handles all of the
+ * creation of Anchors without user intervention.
+ */
+ jsPlumb.Anchor = function(params) {
+ this.x = params.x || 0;
+ this.y = params.y || 0;
+ this.elementId = params.elementId;
+ this.cssClass = params.cssClass || "";
+ this.userDefinedLocation = null;
+ this.orientation = params.orientation || [ 0, 0 ];
+
+ jsPlumbUtil.EventGenerator.apply(this);
+
+ var jsPlumbInstance = params.jsPlumbInstance;//,
+ //lastTimestamp = null;//, lastReturnValue = null;
+
+ this.lastReturnValue = null;
+ this.offsets = params.offsets || [ 0, 0 ];
+ this.timestamp = null;
+ this.compute = function(params) {
+
+ var xy = params.xy, wh = params.wh, element = params.element, timestamp = params.timestamp;
+
+ if(params.clearUserDefinedLocation)
+ this.userDefinedLocation = null;
+
+ if (timestamp && timestamp === self.timestamp)
+ return this.lastReturnValue;
+
+ if (this.userDefinedLocation != null) {
+ this.lastReturnValue = this.userDefinedLocation;
+ }
+ else {
+
+ this.lastReturnValue = [ xy[0] + (this.x * wh[0]) + this.offsets[0], xy[1] + (this.y * wh[1]) + this.offsets[1] ];
+ // adjust loc if there is an offsetParent
+ this.lastReturnValue = jsPlumbInstance.adjustForParentOffsetAndScroll(this.lastReturnValue, element.canvas);
+ }
+
+ this.timestamp = timestamp;
+ return this.lastReturnValue;
+ };
+
+ this.getCurrentLocation = function(params) {
+ return (this.lastReturnValue == null || (params.timestamp != null && this.timestamp != params.timestamp)) ? this.compute(params) : this.lastReturnValue;
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Anchor, jsPlumbUtil.EventGenerator, {
+ equals : function(anchor) {
+ if (!anchor) return false;
+ var ao = anchor.getOrientation(),
+ o = this.getOrientation();
+ return this.x == anchor.x && this.y == anchor.y && this.offsets[0] == anchor.offsets[0] && this.offsets[1] == anchor.offsets[1] && o[0] == ao[0] && o[1] == ao[1];
+ },
+ getUserDefinedLocation : function() {
+ return this.userDefinedLocation;
+ },
+ setUserDefinedLocation : function(l) {
+ this.userDefinedLocation = l;
+ },
+ clearUserDefinedLocation : function() {
+ this.userDefinedLocation = null;
+ },
+ getOrientation : function(_endpoint) { return this.orientation; },
+ getCssClass : function() { return this.cssClass; }
+ });
+
+ /**
+ * An Anchor that floats. its orientation is computed dynamically from
+ * its position relative to the anchor it is floating relative to. It is used when creating
+ * a connection through drag and drop.
+ *
+ * TODO FloatingAnchor could totally be refactored to extend Anchor just slightly.
+ */
+ jsPlumb.FloatingAnchor = function(params) {
+
+ jsPlumb.Anchor.apply(this, arguments);
+
+ // this is the anchor that this floating anchor is referenced to for
+ // purposes of calculating the orientation.
+ var ref = params.reference,
+ jpcl = jsPlumb.CurrentLibrary,
+ jsPlumbInstance = params.jsPlumbInstance,
+ // the canvas this refers to.
+ refCanvas = params.referenceCanvas,
+ size = jpcl.getSize(jpcl.getElementObject(refCanvas)),
+ // these are used to store the current relative position of our
+ // anchor wrt the reference anchor. they only indicate
+ // direction, so have a value of 1 or -1 (or, very rarely, 0). these
+ // values are written by the compute method, and read
+ // by the getOrientation method.
+ xDir = 0, yDir = 0,
+ // temporary member used to store an orientation when the floating
+ // anchor is hovering over another anchor.
+ orientation = null,
+ _lastResult = null;
+
+ // clear from parent. we want floating anchor orientation to always be computed.
+ this.orientation = null;
+
+ // set these to 0 each; they are used by certain types of connectors in the loopback case,
+ // when the connector is trying to clear the element it is on. but for floating anchor it's not
+ // very important.
+ this.x = 0; this.y = 0;
+
+ this.isFloating = true;
+
+ this.compute = function(params) {
+ var xy = params.xy, element = params.element,
+ result = [ xy[0] + (size[0] / 2), xy[1] + (size[1] / 2) ]; // return origin of the element. we may wish to improve this so that any object can be the drag proxy.
+
+ // adjust loc if there is an offsetParent
+ result = jsPlumbInstance.adjustForParentOffsetAndScroll(result, element.canvas);
+
+ _lastResult = result;
+ return result;
+ };
+
+ this.getOrientation = function(_endpoint) {
+ if (orientation) return orientation;
+ else {
+ var o = ref.getOrientation(_endpoint);
+ // here we take into account the orientation of the other
+ // anchor: if it declares zero for some direction, we declare zero too. this might not be the most awesome. perhaps we can come
+ // up with a better way. it's just so that the line we draw looks like it makes sense. maybe this wont make sense.
+ return [ Math.abs(o[0]) * xDir * -1,
+ Math.abs(o[1]) * yDir * -1 ];
+ }
+ };
+
+ /**
+ * notification the endpoint associated with this anchor is hovering
+ * over another anchor; we want to assume that anchor's orientation
+ * for the duration of the hover.
+ */
+ this.over = function(anchor, endpoint) {
+ orientation = anchor.getOrientation(endpoint);
+ };
+
+ /**
+ * notification the endpoint associated with this anchor is no
+ * longer hovering over another anchor; we should resume calculating
+ * orientation as we normally do.
+ */
+ this.out = function() { orientation = null; };
+
+ this.getCurrentLocation = function(params) { return _lastResult == null ? this.compute(params) : _lastResult; };
+ };
+ jsPlumbUtil.extend(jsPlumb.FloatingAnchor, jsPlumb.Anchor);
+
+ var _convertAnchor = function(anchor, jsPlumbInstance, elementId) {
+ return anchor.constructor == jsPlumb.Anchor ? anchor: jsPlumbInstance.makeAnchor(anchor, elementId, jsPlumbInstance);
+ };
+
+ /*
+ * A DynamicAnchor is an Anchor that contains a list of other Anchors, which it cycles
+ * through at compute time to find the one that is located closest to
+ * the center of the target element, and returns that Anchor's compute
+ * method result. this causes endpoints to follow each other with
+ * respect to the orientation of their target elements, which is a useful
+ * feature for some applications.
+ *
+ */
+ jsPlumb.DynamicAnchor = function(params) {
+ jsPlumb.Anchor.apply(this, arguments);
+
+ this.isSelective = true;
+ this.isDynamic = true;
+ this.anchors = [];
+ this.elementId = params.elementId;
+ this.jsPlumbInstance = params.jsPlumbInstance;
+
+ for (var i = 0; i < params.anchors.length; i++)
+ this.anchors[i] = _convertAnchor(params.anchors[i], this.jsPlumbInstance, this.elementId);
+ this.addAnchor = function(anchor) { this.anchors.push(_convertAnchor(anchor, this.jsPlumbInstance, this.elementId)); };
+ this.getAnchors = function() { return this.anchors; };
+ this.locked = false;
+ var _curAnchor = this.anchors.length > 0 ? this.anchors[0] : null,
+ _curIndex = this.anchors.length > 0 ? 0 : -1,
+ _lastAnchor = _curAnchor,
+ self = this,
+
+ // helper method to calculate the distance between the centers of the two elements.
+ _distance = function(anchor, cx, cy, xy, wh) {
+ var ax = xy[0] + (anchor.x * wh[0]), ay = xy[1] + (anchor.y * wh[1]),
+ acx = xy[0] + (wh[0] / 2), acy = xy[1] + (wh[1] / 2);
+ return (Math.sqrt(Math.pow(cx - ax, 2) + Math.pow(cy - ay, 2)) +
+ Math.sqrt(Math.pow(acx - ax, 2) + Math.pow(acy - ay, 2)));
+ },
+ // default method uses distance between element centers. you can provide your own method in the dynamic anchor
+ // constructor (and also to jsPlumb.makeDynamicAnchor). the arguments to it are four arrays:
+ // xy - xy loc of the anchor's element
+ // wh - anchor's element's dimensions
+ // txy - xy loc of the element of the other anchor in the connection
+ // twh - dimensions of the element of the other anchor in the connection.
+ // anchors - the list of selectable anchors
+ _anchorSelector = params.selector || function(xy, wh, txy, twh, anchors) {
+ var cx = txy[0] + (twh[0] / 2), cy = txy[1] + (twh[1] / 2);
+ var minIdx = -1, minDist = Infinity;
+ for ( var i = 0; i < anchors.length; i++) {
+ var d = _distance(anchors[i], cx, cy, xy, wh);
+ if (d < minDist) {
+ minIdx = i + 0;
+ minDist = d;
+ }
+ }
+ return anchors[minIdx];
+ };
+
+ this.compute = function(params) {
+ var xy = params.xy, wh = params.wh, timestamp = params.timestamp, txy = params.txy, twh = params.twh;
+
+ if(params.clearUserDefinedLocation)
+ userDefinedLocation = null;
+
+ this.timestamp = timestamp;
+
+ var udl = self.getUserDefinedLocation();
+ if (udl != null) {
+ return udl;
+ }
+
+ // if anchor is locked or an opposite element was not given, we
+ // maintain our state. anchor will be locked
+ // if it is the source of a drag and drop.
+ if (this.locked || txy == null || twh == null)
+ return _curAnchor.compute(params);
+ else
+ params.timestamp = null; // otherwise clear this, i think. we want the anchor to compute.
+
+ _curAnchor = _anchorSelector(xy, wh, txy, twh, this.anchors);
+ this.x = _curAnchor.x;
+ this.y = _curAnchor.y;
+
+ if (_curAnchor != _lastAnchor)
+ this.fire("anchorChanged", _curAnchor);
+
+ _lastAnchor = _curAnchor;
+
+ return _curAnchor.compute(params);
+ };
+
+ this.getCurrentLocation = function(params) {
+ return this.getUserDefinedLocation() || (_curAnchor != null ? _curAnchor.getCurrentLocation(params) : null);
+ };
+
+ this.getOrientation = function(_endpoint) { return _curAnchor != null ? _curAnchor.getOrientation(_endpoint) : [ 0, 0 ]; };
+ this.over = function(anchor, endpoint) { if (_curAnchor != null) _curAnchor.over(anchor, endpoint); };
+ this.out = function() { if (_curAnchor != null) _curAnchor.out(); };
+
+ this.getCssClass = function() { return (_curAnchor && _curAnchor.getCssClass()) || ""; };
+ };
+ jsPlumbUtil.extend(jsPlumb.DynamicAnchor, jsPlumb.Anchor);
+
+// -------- basic anchors ------------------
+ var _curryAnchor = function(x, y, ox, oy, type, fnInit) {
+ jsPlumb.Anchors[type] = function(params) {
+ var a = params.jsPlumbInstance.makeAnchor([ x, y, ox, oy, 0, 0 ], params.elementId, params.jsPlumbInstance);
+ a.type = type;
+ if (fnInit) fnInit(a, params);
+ return a;
+ };
+ };
+
+ _curryAnchor(0.5, 0, 0,-1, "TopCenter");
+ _curryAnchor(0.5, 1, 0, 1, "BottomCenter");
+ _curryAnchor(0, 0.5, -1, 0, "LeftMiddle");
+ _curryAnchor(1, 0.5, 1, 0, "RightMiddle");
+ // from 1.4.2: Top, Right, Bottom, Left
+ _curryAnchor(0.5, 0, 0,-1, "Top");
+ _curryAnchor(0.5, 1, 0, 1, "Bottom");
+ _curryAnchor(0, 0.5, -1, 0, "Left");
+ _curryAnchor(1, 0.5, 1, 0, "Right");
+ _curryAnchor(0.5, 0.5, 0, 0, "Center");
+ _curryAnchor(1, 0, 0,-1, "TopRight");
+ _curryAnchor(1, 1, 0, 1, "BottomRight");
+ _curryAnchor(0, 0, 0, -1, "TopLeft");
+ _curryAnchor(0, 1, 0, 1, "BottomLeft");
+
+// ------- dynamic anchors -------------------
+
+ // default dynamic anchors chooses from Top, Right, Bottom, Left
+ jsPlumb.Defaults.DynamicAnchors = function(params) {
+ return params.jsPlumbInstance.makeAnchors(["TopCenter", "RightMiddle", "BottomCenter", "LeftMiddle"], params.elementId, params.jsPlumbInstance);
+ };
+
+ // default dynamic anchors bound to name 'AutoDefault'
+ jsPlumb.Anchors.AutoDefault = function(params) {
+ var a = params.jsPlumbInstance.makeDynamicAnchor(jsPlumb.Defaults.DynamicAnchors(params));
+ a.type = "AutoDefault";
+ return a;
+ };
+
+// ------- continuous anchors -------------------
+
+ var _curryContinuousAnchor = function(type, faces) {
+ jsPlumb.Anchors[type] = function(params) {
+ var a = params.jsPlumbInstance.makeAnchor(["Continuous", { faces:faces }], params.elementId, params.jsPlumbInstance);
+ a.type = type;
+ return a;
+ };
+ };
+
+ jsPlumb.Anchors.Continuous = function(params) {
+ return params.jsPlumbInstance.continuousAnchorFactory.get(params);
+ };
+
+ _curryContinuousAnchor("ContinuousLeft", ["left"]);
+ _curryContinuousAnchor("ContinuousTop", ["top"]);
+ _curryContinuousAnchor("ContinuousBottom", ["bottom"]);
+ _curryContinuousAnchor("ContinuousRight", ["right"]);
+
+// ------- position assign anchors -------------------
+
+ // this anchor type lets you assign the position at connection time.
+ jsPlumb.Anchors.Assign = _curryAnchor(0, 0, 0, 0, "Assign", function(anchor, params) {
+ // find what to use as the "position finder". the user may have supplied a String which represents
+ // the id of a position finder in jsPlumb.AnchorPositionFinders, or the user may have supplied the
+ // position finder as a function. we find out what to use and then set it on the anchor.
+ var pf = params.position || "Fixed";
+ anchor.positionFinder = pf.constructor == String ? params.jsPlumbInstance.AnchorPositionFinders[pf] : pf;
+ // always set the constructor params; the position finder might need them later (the Grid one does,
+ // for example)
+ anchor.constructorParams = params;
+ });
+
+ // these are the default anchor positions finders, which are used by the makeTarget function. supplying
+ // a position finder argument to that function allows you to specify where the resulting anchor will
+ // be located
+ jsPlumb.AnchorPositionFinders = {
+ "Fixed": function(dp, ep, es, params) {
+ return [ (dp.left - ep.left) / es[0], (dp.top - ep.top) / es[1] ];
+ },
+ "Grid":function(dp, ep, es, params) {
+ var dx = dp.left - ep.left, dy = dp.top - ep.top,
+ gx = es[0] / (params.grid[0]), gy = es[1] / (params.grid[1]),
+ mx = Math.floor(dx / gx), my = Math.floor(dy / gy);
+ return [ ((mx * gx) + (gx / 2)) / es[0], ((my * gy) + (gy / 2)) / es[1] ];
+ }
+ };
+
+// ------- perimeter anchors -------------------
+
+ jsPlumb.Anchors.Perimeter = function(params) {
+ params = params || {};
+ var anchorCount = params.anchorCount || 60,
+ shape = params.shape;
+
+ if (!shape) throw new Error("no shape supplied to Perimeter Anchor type");
+
+ var _circle = function() {
+ var r = 0.5, step = Math.PI * 2 / anchorCount, current = 0, a = [];
+ for (var i = 0; i < anchorCount; i++) {
+ var x = r + (r * Math.sin(current)),
+ y = r + (r * Math.cos(current));
+ a.push( [ x, y, 0, 0 ] );
+ current += step;
+ }
+ return a;
+ },
+ _path = function(segments) {
+ var anchorsPerFace = anchorCount / segments.length, a = [],
+ _computeFace = function(x1, y1, x2, y2, fractionalLength) {
+ anchorsPerFace = anchorCount * fractionalLength;
+ var dx = (x2 - x1) / anchorsPerFace, dy = (y2 - y1) / anchorsPerFace;
+ for (var i = 0; i < anchorsPerFace; i++) {
+ a.push( [
+ x1 + (dx * i),
+ y1 + (dy * i),
+ 0,
+ 0
+ ]);
+ }
+ };
+
+ for (var i = 0; i < segments.length; i++)
+ _computeFace.apply(null, segments[i]);
+
+ return a;
+ },
+ _shape = function(faces) {
+ var s = [];
+ for (var i = 0; i < faces.length; i++) {
+ s.push([faces[i][0], faces[i][1], faces[i][2], faces[i][3], 1 / faces.length]);
+ }
+ return _path(s);
+ },
+ _rectangle = function() {
+ return _shape([
+ [ 0, 0, 1, 0 ], [ 1, 0, 1, 1 ], [ 1, 1, 0, 1 ], [ 0, 1, 0, 0 ]
+ ]);
+ };
+
+ var _shapes = {
+ "Circle":_circle,
+ "Ellipse":_circle,
+ "Diamond":function() {
+ return _shape([
+ [ 0.5, 0, 1, 0.5 ], [ 1, 0.5, 0.5, 1 ], [ 0.5, 1, 0, 0.5 ], [ 0, 0.5, 0.5, 0 ]
+ ]);
+ },
+ "Rectangle":_rectangle,
+ "Square":_rectangle,
+ "Triangle":function() {
+ return _shape([
+ [ 0.5, 0, 1, 1 ], [ 1, 1, 0, 1 ], [ 0, 1, 0.5, 0]
+ ]);
+ },
+ "Path":function(params) {
+ var points = params.points, p = [], tl = 0;
+ for (var i = 0; i < points.length - 1; i++) {
+ var l = Math.sqrt(Math.pow(points[i][2] - points[i][0]) + Math.pow(points[i][3] - points[i][1]));
+ tl += l;
+ p.push([points[i][0], points[i][1], points[i+1][0], points[i+1][1], l]);
+ }
+ for (var j = 0; j < p.length; j++) {
+ p[j][4] = p[j][4] / tl;
+ }
+ return _path(p);
+ }
+ },
+ _rotate = function(points, amountInDegrees) {
+ var o = [], theta = amountInDegrees / 180 * Math.PI ;
+ for (var i = 0; i < points.length; i++) {
+ var _x = points[i][0] - 0.5,
+ _y = points[i][1] - 0.5;
+
+ o.push([
+ 0.5 + ((_x * Math.cos(theta)) - (_y * Math.sin(theta))),
+ 0.5 + ((_x * Math.sin(theta)) + (_y * Math.cos(theta))),
+ points[i][2],
+ points[i][3]
+ ]);
+ }
+ return o;
+ };
+
+ if (!_shapes[shape]) throw new Error("Shape [" + shape + "] is unknown by Perimeter Anchor type");
+
+ var da = _shapes[shape](params);
+ if (params.rotation) da = _rotate(da, params.rotation);
+ var a = params.jsPlumbInstance.makeDynamicAnchor(da);
+ a.type = "Perimeter";
+ return a;
+ };
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the default Connectors, Endpoint and Overlay definitions.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ /**
+ *
+ * Helper class to consume unused mouse events by components that are DOM elements and
+ * are used by all of the different rendering modes.
+ *
+ */
+ jsPlumb.DOMElementComponent = jsPlumbUtil.extend(jsPlumb.jsPlumbUIComponent, function(params) {
+ // when render mode is canvas, these functions may be called by the canvas mouse handler.
+ // this component is safe to pipe this stuff to /dev/null.
+ this.mousemove =
+ this.dblclick =
+ this.click =
+ this.mousedown =
+ this.mouseup = function(e) { };
+ });
+
+ jsPlumb.Segments = {
+
+ /*
+ * Class: AbstractSegment
+ * A Connector is made up of 1..N Segments, each of which has a Type, such as 'Straight', 'Arc',
+ * 'Bezier'. This is new from 1.4.2, and gives us a lot more flexibility when drawing connections: things such
+ * as rounded corners for flowchart connectors, for example, or a straight line stub for Bezier connections, are
+ * much easier to do now.
+ *
+ * A Segment is responsible for providing coordinates for painting it, and also must be able to report its length.
+ *
+ */
+ AbstractSegment : function(params) {
+ this.params = params;
+
+ /**
+ * Function: findClosestPointOnPath
+ * Finds the closest point on this segment to the given [x, y],
+ * returning both the x and y of the point plus its distance from
+ * the supplied point, and its location along the length of the
+ * path inscribed by the segment. This implementation returns
+ * Infinity for distance and null values for everything else;
+ * subclasses are expected to override.
+ */
+ this.findClosestPointOnPath = function(x, y) {
+ return {
+ d:Infinity,
+ x:null,
+ y:null,
+ l:null
+ };
+ };
+
+ this.getBounds = function() {
+ return {
+ minX:Math.min(params.x1, params.x2),
+ minY:Math.min(params.y1, params.y2),
+ maxX:Math.max(params.x1, params.x2),
+ maxY:Math.max(params.y1, params.y2)
+ };
+ };
+ },
+ Straight : function(params) {
+ var _super = jsPlumb.Segments.AbstractSegment.apply(this, arguments),
+ length, m, m2, x1, x2, y1, y2,
+ _recalc = function() {
+ length = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
+ m = jsPlumbUtil.gradient({x:x1, y:y1}, {x:x2, y:y2});
+ m2 = -1 / m;
+ };
+
+ this.type = "Straight";
+
+ this.getLength = function() { return length; };
+ this.getGradient = function() { return m; };
+
+ this.getCoordinates = function() {
+ return { x1:x1,y1:y1,x2:x2,y2:y2 };
+ };
+ this.setCoordinates = function(coords) {
+ x1 = coords.x1; y1 = coords.y1; x2 = coords.x2; y2 = coords.y2;
+ _recalc();
+ };
+ this.setCoordinates({x1:params.x1, y1:params.y1, x2:params.x2, y2:params.y2});
+
+ this.getBounds = function() {
+ return {
+ minX:Math.min(x1, x2),
+ minY:Math.min(y1, y2),
+ maxX:Math.max(x1, x2),
+ maxY:Math.max(y1, y2)
+ };
+ };
+
+ /**
+ * returns the point on the segment's path that is 'location' along the length of the path, where 'location' is a decimal from
+ * 0 to 1 inclusive. for the straight line segment this is simple maths.
+ */
+ this.pointOnPath = function(location, absolute) {
+ if (location === 0 && !absolute)
+ return { x:x1, y:y1 };
+ else if (location == 1 && !absolute)
+ return { x:x2, y:y2 };
+ else {
+ var l = absolute ? location > 0 ? location : length + location : location * length;
+ return jsPlumbUtil.pointOnLine({x:x1, y:y1}, {x:x2, y:y2}, l);
+ }
+ };
+
+ /**
+ * returns the gradient of the segment at the given point - which for us is constant.
+ */
+ this.gradientAtPoint = function(_) {
+ return m;
+ };
+
+ /**
+ * returns the point on the segment's path that is 'distance' along the length of the path from 'location', where
+ * 'location' is a decimal from 0 to 1 inclusive, and 'distance' is a number of pixels.
+ * this hands off to jsPlumbUtil to do the maths, supplying two points and the distance.
+ */
+ this.pointAlongPathFrom = function(location, distance, absolute) {
+ var p = this.pointOnPath(location, absolute),
+ farAwayPoint = distance <= 0 ? {x:x1, y:y1} : {x:x2, y:y2 };
+
+ /*
+ location == 1 ? {
+ x:x1 + ((x2 - x1) * 10),
+ y:y1 + ((y1 - y2) * 10)
+ } :
+ */
+
+ if (distance <= 0 && Math.abs(distance) > 1) distance *= -1;
+
+ return jsPlumbUtil.pointOnLine(p, farAwayPoint, distance);
+ };
+
+ /**
+ Function: findClosestPointOnPath
+ Finds the closest point on this segment to [x,y]. See
+ notes on this method in AbstractSegment.
+ */
+ this.findClosestPointOnPath = function(x, y) {
+ if (m === 0) {
+ return {
+ x:x,
+ y:y1,
+ d:Math.abs(y - y1)
+ };
+ }
+ else if (m == Infinity || m == -Infinity) {
+ return {
+ x:x1,
+ y:y,
+ d:Math.abs(x - 1)
+ };
+ }
+ else {
+ // closest point lies on normal from given point to this line.
+ var b = y1 - (m * x1),
+ b2 = y - (m2 * x),
+ // y1 = m.x1 + b and y1 = m2.x1 + b2
+ // so m.x1 + b = m2.x1 + b2
+ // x1(m - m2) = b2 - b
+ // x1 = (b2 - b) / (m - m2)
+ _x1 = (b2 -b) / (m - m2),
+ _y1 = (m * _x1) + b,
+ d = jsPlumbUtil.lineLength([ x, y ], [ _x1, _y1 ]),
+ fractionInSegment = jsPlumbUtil.lineLength([ _x1, _y1 ], [ x1, y1 ]);
+
+ return { d:d, x:_x1, y:_y1, l:fractionInSegment / length};
+ }
+ };
+ },
+
+ /*
+ Arc Segment. You need to supply:
+
+ r - radius
+ cx - center x for the arc
+ cy - center y for the arc
+ ac - whether the arc is anticlockwise or not. default is clockwise.
+
+ and then either:
+
+ startAngle - startAngle for the arc.
+ endAngle - endAngle for the arc.
+
+ or:
+
+ x1 - x for start point
+ y1 - y for start point
+ x2 - x for end point
+ y2 - y for end point
+
+ */
+ Arc : function(params) {
+ var _super = jsPlumb.Segments.AbstractSegment.apply(this, arguments),
+ _calcAngle = function(_x, _y) {
+ return jsPlumbUtil.theta([params.cx, params.cy], [_x, _y]);
+ },
+ _calcAngleForLocation = function(segment, location) {
+ if (segment.anticlockwise) {
+ var sa = segment.startAngle < segment.endAngle ? segment.startAngle + TWO_PI : segment.startAngle,
+ s = Math.abs(sa - segment.endAngle);
+ return sa - (s * location);
+ }
+ else {
+ var ea = segment.endAngle < segment.startAngle ? segment.endAngle + TWO_PI : segment.endAngle,
+ ss = Math.abs (ea - segment.startAngle);
+
+ return segment.startAngle + (ss * location);
+ }
+ },
+ TWO_PI = 2 * Math.PI;
+
+ this.radius = params.r;
+ this.anticlockwise = params.ac;
+ this.type = "Arc";
+
+ if (params.startAngle && params.endAngle) {
+ this.startAngle = params.startAngle;
+ this.endAngle = params.endAngle;
+ this.x1 = params.cx + (this.radius * Math.cos(params.startAngle));
+ this.y1 = params.cy + (this.radius * Math.sin(params.startAngle));
+ this.x2 = params.cx + (this.radius * Math.cos(params.endAngle));
+ this.y2 = params.cy + (this.radius * Math.sin(params.endAngle));
+ }
+ else {
+ this.startAngle = _calcAngle(params.x1, params.y1);
+ this.endAngle = _calcAngle(params.x2, params.y2);
+ this.x1 = params.x1;
+ this.y1 = params.y1;
+ this.x2 = params.x2;
+ this.y2 = params.y2;
+ }
+
+ if (this.endAngle < 0) this.endAngle += TWO_PI;
+ if (this.startAngle < 0) this.startAngle += TWO_PI;
+
+ // segment is used by vml
+ this.segment = jsPlumbUtil.segment([this.x1, this.y1], [this.x2, this.y2]);
+
+ // we now have startAngle and endAngle as positive numbers, meaning the
+ // absolute difference (|d|) between them is the sweep (s) of this arc, unless the
+ // arc is 'anticlockwise' in which case 's' is given by 2PI - |d|.
+
+ var ea = this.endAngle < this.startAngle ? this.endAngle + TWO_PI : this.endAngle;
+ this.sweep = Math.abs (ea - this.startAngle);
+ if (this.anticlockwise) this.sweep = TWO_PI - this.sweep;
+ var circumference = 2 * Math.PI * this.radius,
+ frac = this.sweep / TWO_PI,
+ length = circumference * frac;
+
+ this.getLength = function() {
+ return length;
+ };
+
+ this.getBounds = function() {
+ return {
+ minX:params.cx - params.r,
+ maxX:params.cx + params.r,
+ minY:params.cy - params.r,
+ maxY:params.cy + params.r
+ };
+ };
+
+ var VERY_SMALL_VALUE = 0.0000000001,
+ gentleRound = function(n) {
+ var f = Math.floor(n), r = Math.ceil(n);
+ if (n - f < VERY_SMALL_VALUE)
+ return f;
+ else if (r - n < VERY_SMALL_VALUE)
+ return r;
+ return n;
+ };
+
+ /**
+ * returns the point on the segment's path that is 'location' along the length of the path, where 'location' is a decimal from
+ * 0 to 1 inclusive.
+ */
+ this.pointOnPath = function(location, absolute) {
+
+ if (location === 0) {
+ return { x:this.x1, y:this.y1, theta:this.startAngle };
+ }
+ else if (location == 1) {
+ return { x:this.x2, y:this.y2, theta:this.endAngle };
+ }
+
+ if (absolute) {
+ location = location / length;
+ }
+
+ var angle = _calcAngleForLocation(this, location),
+ _x = params.cx + (params.r * Math.cos(angle)),
+ _y = params.cy + (params.r * Math.sin(angle));
+
+ return { x:gentleRound(_x), y:gentleRound(_y), theta:angle };
+ };
+
+ /**
+ * returns the gradient of the segment at the given point.
+ */
+ this.gradientAtPoint = function(location, absolute) {
+ var p = this.pointOnPath(location, absolute);
+ var m = jsPlumbUtil.normal( [ params.cx, params.cy ], [p.x, p.y ] );
+ if (!this.anticlockwise && (m == Infinity || m == -Infinity)) m *= -1;
+ return m;
+ };
+
+ this.pointAlongPathFrom = function(location, distance, absolute) {
+ var p = this.pointOnPath(location, absolute),
+ arcSpan = distance / circumference * 2 * Math.PI,
+ dir = this.anticlockwise ? -1 : 1,
+ startAngle = p.theta + (dir * arcSpan),
+ startX = params.cx + (this.radius * Math.cos(startAngle)),
+ startY = params.cy + (this.radius * Math.sin(startAngle));
+
+ return {x:startX, y:startY};
+ };
+ },
+
+ Bezier : function(params) {
+ var _super = jsPlumb.Segments.AbstractSegment.apply(this, arguments),
+ curve = [
+ { x:params.x1, y:params.y1},
+ { x:params.cp1x, y:params.cp1y },
+ { x:params.cp2x, y:params.cp2y },
+ { x:params.x2, y:params.y2 }
+ ],
+ // although this is not a strictly rigorous determination of bounds
+ // of a bezier curve, it works for the types of curves that this segment
+ // type produces.
+ bounds = {
+ minX:Math.min(params.x1, params.x2, params.cp1x, params.cp2x),
+ minY:Math.min(params.y1, params.y2, params.cp1y, params.cp2y),
+ maxX:Math.max(params.x1, params.x2, params.cp1x, params.cp2x),
+ maxY:Math.max(params.y1, params.y2, params.cp1y, params.cp2y)
+ };
+
+ this.type = "Bezier";
+
+ var _translateLocation = function(_curve, location, absolute) {
+ if (absolute)
+ location = jsBezier.locationAlongCurveFrom(_curve, location > 0 ? 0 : 1, location);
+
+ return location;
+ };
+
+ /**
+ * returns the point on the segment's path that is 'location' along the length of the path, where 'location' is a decimal from
+ * 0 to 1 inclusive.
+ */
+ this.pointOnPath = function(location, absolute) {
+ location = _translateLocation(curve, location, absolute);
+ return jsBezier.pointOnCurve(curve, location);
+ };
+
+ /**
+ * returns the gradient of the segment at the given point.
+ */
+ this.gradientAtPoint = function(location, absolute) {
+ location = _translateLocation(curve, location, absolute);
+ return jsBezier.gradientAtPoint(curve, location);
+ };
+
+ this.pointAlongPathFrom = function(location, distance, absolute) {
+ location = _translateLocation(curve, location, absolute);
+ return jsBezier.pointAlongCurveFrom(curve, location, distance);
+ };
+
+ this.getLength = function() {
+ return jsBezier.getLength(curve);
+ };
+
+ this.getBounds = function() {
+ return bounds;
+ };
+ }
+ };
+
+ /*
+ Class: AbstractComponent
+ Superclass for AbstractConnector and AbstractEndpoint.
+ */
+ var AbstractComponent = function() {
+ this.resetBounds = function() {
+ this.bounds = { minX:Infinity, minY:Infinity, maxX:-Infinity, maxY:-Infinity };
+ };
+ this.resetBounds();
+ };
+
+ /*
+ * Class: AbstractConnector
+ * Superclass for all Connectors; here is where Segments are managed. This is exposed on jsPlumb just so it
+ * can be accessed from other files. You should not try to instantiate one of these directly.
+ *
+ * When this class is asked for a pointOnPath, or gradient etc, it must first figure out which segment to dispatch
+ * that request to. This is done by keeping track of the total connector length as segments are added, and also
+ * their cumulative ratios to the total length. Then when the right segment is found it is a simple case of dispatching
+ * the request to it (and adjusting 'location' so that it is relative to the beginning of that segment.)
+ */
+ jsPlumb.Connectors.AbstractConnector = function(params) {
+
+ AbstractComponent.apply(this, arguments);
+
+ var //self = this,
+ segments = [],
+ editing = false,
+ totalLength = 0,
+ segmentProportions = [],
+ segmentProportionalLengths = [],
+ stub = params.stub || 0,
+ sourceStub = jsPlumbUtil.isArray(stub) ? stub[0] : stub,
+ targetStub = jsPlumbUtil.isArray(stub) ? stub[1] : stub,
+ gap = params.gap || 0,
+ sourceGap = jsPlumbUtil.isArray(gap) ? gap[0] : gap,
+ targetGap = jsPlumbUtil.isArray(gap) ? gap[1] : gap,
+ userProvidedSegments = null,
+ edited = false,
+ paintInfo = null;
+
+ // subclasses should override.
+ this.isEditable = function() { return false; };
+ this.setEdited = function(ed) { edited = ed; };
+
+ // to be overridden by subclasses.
+ this.getPath = function() { };
+ this.setPath = function(path) { };
+
+ /**
+ * Function: findSegmentForPoint
+ * Returns the segment that is closest to the given [x,y],
+ * null if nothing found. This function returns a JS
+ * object with:
+ *
+ * d - distance from segment
+ * l - proportional location in segment
+ * x - x point on the segment
+ * y - y point on the segment
+ * s - the segment itself.
+ */
+ this.findSegmentForPoint = function(x, y) {
+ var out = { d:Infinity, s:null, x:null, y:null, l:null };
+ for (var i = 0; i < segments.length; i++) {
+ var _s = segments[i].findClosestPointOnPath(x, y);
+ if (_s.d < out.d) {
+ out.d = _s.d;
+ out.l = _s.l;
+ out.x = _s.x;
+ out.y = _s.y;
+ out.s = segments[i];
+ }
+ }
+
+ return out;
+ };
+
+ var _updateSegmentProportions = function() {
+ var curLoc = 0;
+ for (var i = 0; i < segments.length; i++) {
+ var sl = segments[i].getLength();
+ segmentProportionalLengths[i] = sl / totalLength;
+ segmentProportions[i] = [curLoc, (curLoc += (sl / totalLength)) ];
+ }
+ },
+
+ /**
+ * returns [segment, proportion of travel in segment, segment index] for the segment
+ * that contains the point which is 'location' distance along the entire path, where
+ * 'location' is a decimal between 0 and 1 inclusive. in this connector type, paths
+ * are made up of a list of segments, each of which contributes some fraction to
+ * the total length.
+ * From 1.3.10 this also supports the 'absolute' property, which lets us specify a location
+ * as the absolute distance in pixels, rather than a proportion of the total path.
+ */
+ _findSegmentForLocation = function(location, absolute) {
+ if (absolute) {
+ location = location > 0 ? location / totalLength : (totalLength + location) / totalLength;
+ }
+
+ var idx = segmentProportions.length - 1, inSegmentProportion = 1;
+ //if (location < 1) {
+ for (var i = 0; i < segmentProportions.length; i++) {
+ if (segmentProportions[i][1] >= location) {
+ idx = i;
+ // todo is this correct for all connector path types?
+ inSegmentProportion = location == 1 ? 1 : location === 0 ? 0 : (location - segmentProportions[i][0]) / segmentProportionalLengths[i];
+ break;
+ }
+ }
+ //}
+ return { segment:segments[idx], proportion:inSegmentProportion, index:idx };
+ },
+ _addSegment = function(conn, type, params) {
+ if (params.x1 == params.x2 && params.y1 == params.y2) return;
+ var s = new jsPlumb.Segments[type](params);
+ segments.push(s);
+ totalLength += s.getLength();
+ conn.updateBounds(s);
+ },
+ _clearSegments = function() {
+ totalLength = 0;
+ segments.splice(0, segments.length);
+ segmentProportions.splice(0, segmentProportions.length);
+ segmentProportionalLengths.splice(0, segmentProportionalLengths.length);
+ };
+
+ this.setSegments = function(_segs) {
+ userProvidedSegments = [];
+ totalLength = 0;
+ for (var i = 0; i < _segs.length; i++) {
+ userProvidedSegments.push(_segs[i]);
+ totalLength += _segs[i].getLength();
+ }
+ };
+
+ var _prepareCompute = function(params) {
+ this.lineWidth = params.lineWidth;
+ var segment = jsPlumbUtil.segment(params.sourcePos, params.targetPos),
+ swapX = params.targetPos[0] < params.sourcePos[0],
+ swapY = params.targetPos[1] < params.sourcePos[1],
+ lw = params.lineWidth || 1,
+ so = params.sourceEndpoint.anchor.orientation || params.sourceEndpoint.anchor.getOrientation(params.sourceEndpoint),
+ to = params.targetEndpoint.anchor.orientation || params.targetEndpoint.anchor.getOrientation(params.targetEndpoint),
+ x = swapX ? params.targetPos[0] : params.sourcePos[0],
+ y = swapY ? params.targetPos[1] : params.sourcePos[1],
+ w = Math.abs(params.targetPos[0] - params.sourcePos[0]),
+ h = Math.abs(params.targetPos[1] - params.sourcePos[1]);
+
+ // if either anchor does not have an orientation set, we derive one from their relative
+ // positions. we fix the axis to be the one in which the two elements are further apart, and
+ // point each anchor at the other element. this is also used when dragging a new connection.
+ if (so[0] === 0 && so[1] === 0 || to[0] === 0 && to[1] === 0) {
+ var index = w > h ? 0 : 1, oIndex = [1,0][index];
+ so = []; to = [];
+ so[index] = params.sourcePos[index] > params.targetPos[index] ? -1 : 1;
+ to[index] = params.sourcePos[index] > params.targetPos[index] ? 1 : -1;
+ so[oIndex] = 0; to[oIndex] = 0;
+ }
+
+ var sx = swapX ? w + (sourceGap * so[0]) : sourceGap * so[0],
+ sy = swapY ? h + (sourceGap * so[1]) : sourceGap * so[1],
+ tx = swapX ? targetGap * to[0] : w + (targetGap * to[0]),
+ ty = swapY ? targetGap * to[1] : h + (targetGap * to[1]),
+ oProduct = ((so[0] * to[0]) + (so[1] * to[1]));
+
+ var result = {
+ sx:sx, sy:sy, tx:tx, ty:ty, lw:lw,
+ xSpan:Math.abs(tx - sx),
+ ySpan:Math.abs(ty - sy),
+ mx:(sx + tx) / 2,
+ my:(sy + ty) / 2,
+ so:so, to:to, x:x, y:y, w:w, h:h,
+ segment : segment,
+ startStubX : sx + (so[0] * sourceStub),
+ startStubY : sy + (so[1] * sourceStub),
+ endStubX : tx + (to[0] * targetStub),
+ endStubY : ty + (to[1] * targetStub),
+ isXGreaterThanStubTimes2 : Math.abs(sx - tx) > (sourceStub + targetStub),
+ isYGreaterThanStubTimes2 : Math.abs(sy - ty) > (sourceStub + targetStub),
+ opposite:oProduct == -1,
+ perpendicular:oProduct === 0,
+ orthogonal:oProduct == 1,
+ sourceAxis : so[0] === 0 ? "y" : "x",
+ points:[x, y, w, h, sx, sy, tx, ty ]
+ };
+ result.anchorOrientation = result.opposite ? "opposite" : result.orthogonal ? "orthogonal" : "perpendicular";
+ return result;
+ };
+
+ this.getSegments = function() { return segments; };
+
+ this.updateBounds = function(segment) {
+ var segBounds = segment.getBounds();
+ this.bounds.minX = Math.min(this.bounds.minX, segBounds.minX);
+ this.bounds.maxX = Math.max(this.bounds.maxX, segBounds.maxX);
+ this.bounds.minY = Math.min(this.bounds.minY, segBounds.minY);
+ this.bounds.maxY = Math.max(this.bounds.maxY, segBounds.maxY);
+ };
+
+ var dumpSegmentsToConsole = function() {
+ console.log("SEGMENTS:");
+ for (var i = 0; i < segments.length; i++) {
+ console.log(segments[i].type, segments[i].getLength(), segmentProportions[i]);
+ }
+ };
+
+ this.pointOnPath = function(location, absolute) {
+ var seg = _findSegmentForLocation(location, absolute);
+ return seg.segment && seg.segment.pointOnPath(seg.proportion, absolute) || [0,0];
+ };
+
+ this.gradientAtPoint = function(location) {
+ var seg = _findSegmentForLocation(location, absolute);
+ return seg.segment && seg.segment.gradientAtPoint(seg.proportion, absolute) || 0;
+ };
+
+ this.pointAlongPathFrom = function(location, distance, absolute) {
+ var seg = _findSegmentForLocation(location, absolute);
+ // TODO what happens if this crosses to the next segment?
+ return seg.segment && seg.segment.pointAlongPathFrom(seg.proportion, distance, false) || [0,0];
+ };
+
+ this.compute = function(params) {
+ if (!edited)
+ paintInfo = _prepareCompute(params);
+
+ _clearSegments();
+ this._compute(paintInfo, params);
+ this.x = paintInfo.points[0];
+ this.y = paintInfo.points[1];
+ this.w = paintInfo.points[2];
+ this.h = paintInfo.points[3];
+ this.segment = paintInfo.segment;
+ _updateSegmentProportions();
+ };
+
+ return {
+ addSegment:_addSegment,
+ prepareCompute:_prepareCompute,
+ sourceStub:sourceStub,
+ targetStub:targetStub,
+ maxStub:Math.max(sourceStub, targetStub),
+ sourceGap:sourceGap,
+ targetGap:targetGap,
+ maxGap:Math.max(sourceGap, targetGap)
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.AbstractConnector, AbstractComponent);
+
+ /**
+ * Class: Connectors.Straight
+ * The Straight connector draws a simple straight line between the two anchor points. It does not have any constructor parameters.
+ */
+ var Straight = function() {
+ this.type = "Straight";
+ var _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments);
+
+ this._compute = function(paintInfo, _) {
+ _super.addSegment(this, "Straight", {x1:paintInfo.sx, y1:paintInfo.sy, x2:paintInfo.startStubX, y2:paintInfo.startStubY});
+ _super.addSegment(this, "Straight", {x1:paintInfo.startStubX, y1:paintInfo.startStubY, x2:paintInfo.endStubX, y2:paintInfo.endStubY});
+ _super.addSegment(this, "Straight", {x1:paintInfo.endStubX, y1:paintInfo.endStubY, x2:paintInfo.tx, y2:paintInfo.ty});
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.Straight, jsPlumb.Connectors.AbstractConnector);
+ jsPlumb.registerConnectorType(Straight, "Straight");
+
+ /**
+ * Class:Connectors.Bezier
+ * This Connector draws a Bezier curve with two control points. You can provide a 'curviness' value which gets applied to jsPlumb's
+ * internal voodoo machine and ends up generating locations for the two control points. See the constructor documentation below.
+ */
+ /**
+ * Function:Constructor
+ *
+ * Parameters:
+ * curviness - How 'curvy' you want the curve to be! This is a directive for the placement of control points, not endpoints of the curve, so your curve does not
+ * actually touch the given point, but it has the tendency to lean towards it. The larger this value, the greater the curve is pulled from a straight line.
+ * Optional; defaults to 150.
+ * stub - optional value for a distance to travel from the connector's endpoint before beginning the Bezier curve. defaults to 0.
+ *
+ */
+ var Bezier = function(params) {
+ params = params || {};
+
+ var _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
+ stub = params.stub || 50,
+ majorAnchor = params.curviness || 150,
+ minorAnchor = 10;
+
+ this.type = "Bezier";
+ this.getCurviness = function() { return majorAnchor; };
+
+ this._findControlPoint = function(point, sourceAnchorPosition, targetAnchorPosition, sourceEndpoint, targetEndpoint) {
+ // determine if the two anchors are perpendicular to each other in their orientation. we swap the control
+ // points around if so (code could be tightened up)
+ var soo = sourceEndpoint.anchor.getOrientation(sourceEndpoint),
+ too = targetEndpoint.anchor.getOrientation(targetEndpoint),
+ perpendicular = soo[0] != too[0] || soo[1] == too[1],
+ p = [];
+
+ if (!perpendicular) {
+ if (soo[0] === 0) // X
+ p.push(sourceAnchorPosition[0] < targetAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
+ else p.push(point[0] - (majorAnchor * soo[0]));
+
+ if (soo[1] === 0) // Y
+ p.push(sourceAnchorPosition[1] < targetAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
+ else p.push(point[1] + (majorAnchor * too[1]));
+ }
+ else {
+ if (too[0] === 0) // X
+ p.push(targetAnchorPosition[0] < sourceAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
+ else p.push(point[0] + (majorAnchor * too[0]));
+
+ if (too[1] === 0) // Y
+ p.push(targetAnchorPosition[1] < sourceAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
+ else p.push(point[1] + (majorAnchor * soo[1]));
+ }
+
+ return p;
+ };
+
+ this._compute = function(paintInfo, p) {
+ var sp = p.sourcePos,
+ tp = p.targetPos,
+ _w = Math.abs(sp[0] - tp[0]),
+ _h = Math.abs(sp[1] - tp[1]),
+ _sx = sp[0] < tp[0] ? _w : 0,
+ _sy = sp[1] < tp[1] ? _h : 0,
+ _tx = sp[0] < tp[0] ? 0 : _w,
+ _ty = sp[1] < tp[1] ? 0 : _h,
+ _CP = this._findControlPoint([_sx, _sy], sp, tp, p.sourceEndpoint, p.targetEndpoint),
+ _CP2 = this._findControlPoint([_tx, _ty], tp, sp, p.targetEndpoint, p.sourceEndpoint);
+
+ _super.addSegment(this, "Bezier", {
+ x1:_sx, y1:_sy, x2:_tx, y2:_ty,
+ cp1x:_CP[0], cp1y:_CP[1], cp2x:_CP2[0], cp2y:_CP2[1]
+ });
+ };
+ };
+ jsPlumbUtil.extend(Bezier, jsPlumb.Connectors.AbstractConnector);
+ jsPlumb.registerConnectorType(Bezier, "Bezier");
+
+ // ********************************* END OF CONNECTOR TYPES *******************************************************************
+
+ // ********************************* ENDPOINT TYPES *******************************************************************
+
+ jsPlumb.Endpoints.AbstractEndpoint = function(params) {
+ AbstractComponent.apply(this, arguments);
+ var compute = this.compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ var out = this._compute.apply(this, arguments);
+ this.x = out[0];
+ this.y = out[1];
+ this.w = out[2];
+ this.h = out[3];
+ this.bounds.minX = this.x;
+ this.bounds.minY = this.y;
+ this.bounds.maxX = this.x + this.w;
+ this.bounds.maxY = this.y + this.h;
+ return out;
+ };
+ return {
+ compute:compute,
+ cssClass:params.cssClass
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.AbstractEndpoint, AbstractComponent);
+
+ /**
+ * Class: Endpoints.Dot
+ * A round endpoint, with default radius 10 pixels.
+ */
+
+ /**
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * radius - radius of the endpoint. defaults to 10 pixels.
+ */
+ jsPlumb.Endpoints.Dot = function(params) {
+ this.type = "Dot";
+ var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+ params = params || {};
+ this.radius = params.radius || 10;
+ this.defaultOffset = 0.5 * this.radius;
+ this.defaultInnerRadius = this.radius / 3;
+
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ this.radius = endpointStyle.radius || this.radius;
+ var x = anchorPoint[0] - this.radius,
+ y = anchorPoint[1] - this.radius,
+ w = this.radius * 2,
+ h = this.radius * 2;
+
+ if (endpointStyle.strokeStyle) {
+ var lw = endpointStyle.lineWidth || 1;
+ x -= lw;
+ y -= lw;
+ w += (lw * 2);
+ h += (lw * 2);
+ }
+ return [ x, y, w, h, this.radius ];
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.Dot, jsPlumb.Endpoints.AbstractEndpoint);
+
+ /**
+ * Class: Endpoints.Rectangle
+ * A Rectangular Endpoint, with default size 20x20.
+ */
+ /**
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * width - width of the endpoint. defaults to 20 pixels.
+ * height - height of the endpoint. defaults to 20 pixels.
+ */
+ jsPlumb.Endpoints.Rectangle = function(params) {
+ this.type = "Rectangle";
+ var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+ params = params || {};
+ this.width = params.width || 20;
+ this.height = params.height || 20;
+
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ var width = endpointStyle.width || this.width,
+ height = endpointStyle.height || this.height,
+ x = anchorPoint[0] - (width/2),
+ y = anchorPoint[1] - (height/2);
+
+ return [ x, y, width, height];
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.Rectangle, jsPlumb.Endpoints.AbstractEndpoint);
+
+
+ var DOMElementEndpoint = function(params) {
+ jsPlumb.DOMElementComponent.apply(this, arguments);
+ this._jsPlumb.displayElements = [ ];
+ };
+ jsPlumbUtil.extend(DOMElementEndpoint, jsPlumb.DOMElementComponent, {
+ // jsPlumb.Endpoints.AbstractEndpoint
+ getDisplayElements : function() {
+ return this._jsPlumb.displayElements;
+ },
+ appendDisplayElement : function(el) {
+ this._jsPlumb.displayElements.push(el);
+ }
+ });
+
+ /**
+ * Class: Endpoints.Image
+ * Draws an image as the Endpoint.
+ */
+ /**
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * src - location of the image to use.
+
+ TODO: multiple references to self. not sure quite how to get rid of them entirely. perhaps self = null in the cleanup
+ function will suffice
+
+ TODO this class still leaks memory.
+
+ */
+ jsPlumb.Endpoints.Image = function(params) {
+
+ this.type = "Image";
+ DOMElementEndpoint.apply(this, arguments);
+ jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+
+ var _onload = params.onload,
+ src = params.src || params.url,
+ parent = params.parent,
+ clazz = params.cssClass ? " " + params.cssClass : "";
+
+ this._jsPlumb.img = new Image();
+ this._jsPlumb.ready = false;
+ this._jsPlumb.initialized = false;
+ this._jsPlumb.deleted = false;
+ this._jsPlumb.widthToUse = params.width;
+ this._jsPlumb.heightToUse = params.height;
+ this._jsPlumb.endpoint = params.endpoint;
+
+ this._jsPlumb.img.onload = function() {
+ // check we weren't actually discarded before use (in fact mostly happens in tests)
+ if (this._jsPlumb != null) {
+ this._jsPlumb.ready = true;
+ this._jsPlumb.widthToUse = this._jsPlumb.widthToUse || this._jsPlumb.img.width;
+ this._jsPlumb.heightToUse = this._jsPlumb.heightToUse || this._jsPlumb.img.height;
+ if (_onload) {
+ _onload(this);
+ }
+ }
+ }.bind(this);
+
+ /*
+ Function: setImage
+ Sets the Image to use in this Endpoint.
+
+ Parameters:
+ img - may be a URL or an Image object
+ onload - optional; a callback to execute once the image has loaded.
+ */
+ this._jsPlumb.endpoint.setImage = function(_img, onload) {
+ var s = _img.constructor == String ? _img : _img.src;
+ _onload = onload;
+ this._jsPlumb.img.src = s;
+
+ if (this.canvas != null)
+ this.canvas.setAttribute("src", this._jsPlumb.img.src);
+ }.bind(this);
+
+ this._jsPlumb.endpoint.setImage(src, _onload);
+ /*
+ var s = src.constructor == String ? src : src.src;
+ //_onload = onload;
+ this._jsPlumb.img.src = src;
+
+ if (this.canvas != null)
+ this.canvas.setAttribute("src", this._jsPlumb.img.src);
+ // }.bind(this);
+
+ //this._jsPlumb.endpoint.setImage(src, _onload);*/
+
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ this.anchorPoint = anchorPoint;
+ if (this._jsPlumb.ready) return [anchorPoint[0] - this._jsPlumb.widthToUse / 2, anchorPoint[1] - this._jsPlumb.heightToUse / 2,
+ this._jsPlumb.widthToUse, this._jsPlumb.heightToUse];
+ else return [0,0,0,0];
+ };
+
+ this.canvas = document.createElement("img");
+ this.canvas.style.margin = 0;
+ this.canvas.style.padding = 0;
+ this.canvas.style.outline = 0;
+ this.canvas.style.position = "absolute";
+ this.canvas.className = this._jsPlumb.instance.endpointClass + clazz;
+ if (this._jsPlumb.widthToUse) this.canvas.setAttribute("width", this._jsPlumb.widthToUse);
+ if (this._jsPlumb.heightToUse) this.canvas.setAttribute("height", this._jsPlumb.heightToUse);
+ this._jsPlumb.instance.appendElement(this.canvas, parent);
+ this.attachListeners(this.canvas, this);
+
+ this.actuallyPaint = function(d, style, anchor) {
+ if (!this._jsPlumb.deleted) {
+ if (!this._jsPlumb.initialized) {
+ this.canvas.setAttribute("src", this._jsPlumb.img.src);
+ this.appendDisplayElement(this.canvas);
+ this._jsPlumb.initialized = true;
+ }
+ var x = this.anchorPoint[0] - (this._jsPlumb.widthToUse / 2),
+ y = this.anchorPoint[1] - (this._jsPlumb.heightToUse / 2);
+ jsPlumbUtil.sizeElement(this.canvas, x, y, this._jsPlumb.widthToUse, this._jsPlumb.heightToUse);
+ }
+ };
+
+ this.paint = function(style, anchor) {
+ if (this._jsPlumb != null) { // may have been deleted
+ if (this._jsPlumb.ready) {
+ this.actuallyPaint(style, anchor);
+ }
+ else {
+ window.setTimeout(function() {
+ this.paint(style, anchor);
+ }.bind(this), 200);
+ }
+ }
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.Image, [ DOMElementEndpoint, jsPlumb.Endpoints.AbstractEndpoint ], {
+ cleanup : function() {
+ this._jsPlumb.deleted = true;
+ jsPlumbUtil.removeElement(this.canvas);
+ this.canvas = null;
+ }
+ });
+
+ /*
+ * Class: Endpoints.Blank
+ * An Endpoint that paints nothing (visible) on the screen. Supports cssClass and hoverClass parameters like all Endpoints.
+ */
+ jsPlumb.Endpoints.Blank = function(params) {
+ var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+ this.type = "Blank";
+ DOMElementEndpoint.apply(this, arguments);
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ return [anchorPoint[0], anchorPoint[1],10,0];
+ };
+
+ this.canvas = document.createElement("div");
+ this.canvas.style.display = "block";
+ this.canvas.style.width = "1px";
+ this.canvas.style.height = "1px";
+ this.canvas.style.background = "transparent";
+ this.canvas.style.position = "absolute";
+ this.canvas.className = this._jsPlumb.endpointClass;
+ jsPlumb.appendElement(this.canvas, params.parent);
+
+ this.paint = function(style, anchor) {
+ jsPlumbUtil.sizeElement(this.canvas, this.x, this.y, this.w, this.h);
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.Blank, [jsPlumb.Endpoints.AbstractEndpoint, DOMElementEndpoint], {
+ cleanup:function() {
+ if (this.canvas) {
+ this.canvas.parentNode.removeChild(this.canvas);
+ }
+ }
+ });
+
+ /*
+ * Class: Endpoints.Triangle
+ * A triangular Endpoint.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * width - width of the triangle's base. defaults to 55 pixels.
+ * height - height of the triangle from base to apex. defaults to 55 pixels.
+ */
+ jsPlumb.Endpoints.Triangle = function(params) {
+ this.type = "Triangle";
+ var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
+ params = params || { };
+ params.width = params.width || 55;
+ params.height = params.height || 55;
+ this.width = params.width;
+ this.height = params.height;
+ this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
+ var width = endpointStyle.width || self.width,
+ height = endpointStyle.height || self.height,
+ x = anchorPoint[0] - (width/2),
+ y = anchorPoint[1] - (height/2);
+ return [ x, y, width, height ];
+ };
+ };
+// ********************************* END OF ENDPOINT TYPES *******************************************************************
+
+
+// ********************************* OVERLAY DEFINITIONS ***********************************************************************
+
+ var AbstractOverlay = jsPlumb.Overlays.AbstractOverlay = function(params) {
+ this.visible = true;
+ this.isAppendedAtTopLevel = true;
+ this.component = params.component;
+ this.loc = params.location == null ? 0.5 : params.location;
+ this.endpointLoc = params.endpointLocation == null ? [ 0.5, 0.5] : params.endpointLocation;
+ //this.;
+ };
+ AbstractOverlay.prototype = {
+ cleanup:function() {
+ this.component = null;
+ this.canvas = null;
+ this.endpointLoc = null;
+ },
+ setVisible : function(val) {
+ this.visible = val;
+ this.component.repaint();
+ },
+ isVisible : function() { return this.visible; },
+ hide : function() { this.setVisible(false); },
+ show : function() { this.setVisible(true); },
+
+ incrementLocation : function(amount) {
+ this.loc += amount;
+ this.component.repaint();
+ },
+ setLocation : function(l) {
+ this.loc = l;
+ this.component.repaint();
+ },
+ getLocation : function() {
+ return this.loc;
+ }
+ };
+
+
+ /*
+ * Class: Overlays.Arrow
+ *
+ * An arrow overlay, defined by four points: the head, the two sides of the tail, and a 'foldback' point at some distance along the length
+ * of the arrow that lines from each tail point converge into. The foldback point is defined using a decimal that indicates some fraction
+ * of the length of the arrow and has a default value of 0.623. A foldback point value of 1 would mean that the arrow had a straight line
+ * across the tail.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ *
+ * length - distance in pixels from head to tail baseline. default 20.
+ * width - width in pixels of the tail baseline. default 20.
+ * fillStyle - style to use when filling the arrow. defaults to "black".
+ * strokeStyle - style to use when stroking the arrow. defaults to null, which means the arrow is not stroked.
+ * lineWidth - line width to use when stroking the arrow. defaults to 1, but only used if strokeStyle is not null.
+ * foldback - distance (as a decimal from 0 to 1 inclusive) along the length of the arrow marking the point the tail points should fold back to. defaults to 0.623.
+ * location - distance (as a decimal from 0 to 1 inclusive) marking where the arrow should sit on the connector. defaults to 0.5.
+ * direction - indicates the direction the arrow points in. valid values are -1 and 1; 1 is default.
+ */
+ jsPlumb.Overlays.Arrow = function(params) {
+ this.type = "Arrow";
+ AbstractOverlay.apply(this, arguments);
+ this.isAppendedAtTopLevel = false;
+ params = params || {};
+ var _ju = jsPlumbUtil;
+
+ this.length = params.length || 20;
+ this.width = params.width || 20;
+ this.id = params.id;
+ var direction = (params.direction || 1) < 0 ? -1 : 1,
+ paintStyle = params.paintStyle || { lineWidth:1 },
+ // how far along the arrow the lines folding back in come to. default is 62.3%.
+ foldback = params.foldback || 0.623;
+
+ this.computeMaxSize = function() { return self.width * 1.5; };
+ //this.cleanup = function() { }; // nothing to clean up for Arrows
+ this.draw = function(component, currentConnectionPaintStyle) {
+
+ var hxy, mid, txy, tail, cxy;
+ if (component.pointAlongPathFrom) {
+
+ if (_ju.isString(this.loc) || this.loc > 1 || this.loc < 0) {
+ var l = parseInt(this.loc, 10);
+ hxy = component.pointAlongPathFrom(l, direction * this.length / 2, true);
+ mid = component.pointOnPath(l, true);
+ txy = _ju.pointOnLine(hxy, mid, this.length);
+ }
+ else if (this.loc == 1) {
+ hxy = component.pointOnPath(this.loc);
+ mid = component.pointAlongPathFrom(this.loc, -(this.length));
+ txy = _ju.pointOnLine(hxy, mid, this.length);
+
+ if (direction == -1) {
+ var _ = txy;
+ txy = hxy;
+ hxy = _;
+ }
+ }
+ else if (this.loc === 0) {
+ txy = component.pointOnPath(this.loc);
+ mid = component.pointAlongPathFrom(this.loc, this.length);
+ hxy = _ju.pointOnLine(txy, mid, this.length);
+ if (direction == -1) {
+ var __ = txy;
+ txy = hxy;
+ hxy = __;
+ }
+ }
+ else {
+ hxy = component.pointAlongPathFrom(this.loc, direction * this.length / 2);
+ mid = component.pointOnPath(this.loc);
+ txy = _ju.pointOnLine(hxy, mid, this.length);
+ }
+
+ tail = _ju.perpendicularLineTo(hxy, txy, this.width);
+ cxy = _ju.pointOnLine(hxy, txy, foldback * this.length);
+
+ var d = { hxy:hxy, tail:tail, cxy:cxy },
+ strokeStyle = paintStyle.strokeStyle || currentConnectionPaintStyle.strokeStyle,
+ fillStyle = paintStyle.fillStyle || currentConnectionPaintStyle.strokeStyle,
+ lineWidth = paintStyle.lineWidth || currentConnectionPaintStyle.lineWidth,
+ info = {
+ component:component,
+ d:d,
+ lineWidth:lineWidth,
+ strokeStyle:strokeStyle,
+ fillStyle:fillStyle,
+ minX:Math.min(hxy.x, tail[0].x, tail[1].x),
+ maxX:Math.max(hxy.x, tail[0].x, tail[1].x),
+ minY:Math.min(hxy.y, tail[0].y, tail[1].y),
+ maxY:Math.max(hxy.y, tail[0].y, tail[1].y)
+ };
+
+ return info;
+ }
+ else return {component:component, minX:0,maxX:0,minY:0,maxY:0};
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.Arrow, AbstractOverlay);
+
+ /*
+ * Class: Overlays.PlainArrow
+ *
+ * A basic arrow. This is in fact just one instance of the more generic case in which the tail folds back on itself to some
+ * point along the length of the arrow: in this case, that foldback point is the full length of the arrow. so it just does
+ * a 'call' to Arrow with foldback set appropriately.
+ */
+ /*
+ * Function: Constructor
+ * See <Overlays.Arrow> for allowed parameters for this overlay.
+ */
+ jsPlumb.Overlays.PlainArrow = function(params) {
+ params = params || {};
+ var p = jsPlumb.extend(params, {foldback:1});
+ jsPlumb.Overlays.Arrow.call(this, p);
+ this.type = "PlainArrow";
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.PlainArrow, jsPlumb.Overlays.Arrow);
+
+ /*
+ * Class: Overlays.Diamond
+ *
+ * A diamond. Like PlainArrow, this is a concrete case of the more generic case of the tail points converging on some point...it just
+ * happens that in this case, that point is greater than the length of the the arrow.
+ *
+ * this could probably do with some help with positioning...due to the way it reuses the Arrow paint code, what Arrow thinks is the
+ * center is actually 1/4 of the way along for this guy. but we don't have any knowledge of pixels at this point, so we're kind of
+ * stuck when it comes to helping out the Arrow class. possibly we could pass in a 'transpose' parameter or something. the value
+ * would be -l/4 in this case - move along one quarter of the total length.
+ */
+ /*
+ * Function: Constructor
+ * See <Overlays.Arrow> for allowed parameters for this overlay.
+ */
+ jsPlumb.Overlays.Diamond = function(params) {
+ params = params || {};
+ var l = params.length || 40,
+ p = jsPlumb.extend(params, {length:l/2, foldback:2});
+ jsPlumb.Overlays.Arrow.call(this, p);
+ this.type = "Diamond";
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.Diamond, jsPlumb.Overlays.Arrow);
+
+ var _getDimensions = function(component) {
+ if (component._jsPlumb.cachedDimensions == null)
+ component._jsPlumb.cachedDimensions = component.getDimensions();
+ return component._jsPlumb.cachedDimensions;
+ };
+
+ // abstract superclass for overlays that add an element to the DOM.
+ var AbstractDOMOverlay = function(params) {
+ jsPlumb.DOMElementComponent.apply(this, arguments);
+ AbstractOverlay.apply(this, arguments);
+
+ var jpcl = jsPlumb.CurrentLibrary;
+ this.id = params.id;
+ this._jsPlumb.div = null;
+ this._jsPlumb.initialised = false;
+ this._jsPlumb.component = params.component;
+ this._jsPlumb.cachedDimensions = null;
+ this._jsPlumb.create = params.create;
+
+ this.getElement = function() {
+ if (this._jsPlumb.div == null) {
+ var div = this._jsPlumb.div = jpcl.getDOMElement(this._jsPlumb.create(this._jsPlumb.component));
+ div.style.position = "absolute";
+ var clazz = params._jsPlumb.overlayClass + " " +
+ (this.cssClass ? this.cssClass :
+ params.cssClass ? params.cssClass : "");
+ div.className = clazz;
+ this._jsPlumb.instance.appendElement(div, this._jsPlumb.component.parent);
+ this._jsPlumb.instance.getId(div);
+ this.attachListeners(div, this);
+ this.canvas = div;
+ }
+ return this._jsPlumb.div;
+ };
+
+ /*
+ this.paint = function(p, containerExtents) {
+ if (!this._jsPlumb.initialised) {
+ this.getElement();
+ p.component.appendDisplayElement(this._jsPlumb.div);
+ this.attachListeners(this._jsPlumb.div, p.component);
+ this._jsPlumb.initialised = true;
+ }
+ this._jsPlumb.div.style.left = (p.component.x + p.d.minx) + "px";
+ this._jsPlumb.div.style.top = (p.component.y + p.d.miny) + "px";
+ };*/
+
+ this.draw = function(component, currentConnectionPaintStyle) {
+ var td = _getDimensions(this);
+ if (td != null && td.length == 2) {
+ var cxy = {x:0,y:0};
+ if (component.pointOnPath) {
+ var loc = this.loc, absolute = false;
+ if (jsPlumbUtil.isString(this.loc) || this.loc < 0 || this.loc > 1) {
+ loc = parseInt(this.loc, 10);
+ absolute = true;
+ }
+ cxy = component.pointOnPath(loc, absolute); // a connection
+ }
+ else {
+ var locToUse = this.loc.constructor == Array ? this.loc : this.endpointLoc;
+ cxy = { x:locToUse[0] * component.w,
+ y:locToUse[1] * component.h };
+ }
+
+ var minx = cxy.x - (td[0] / 2),
+ miny = cxy.y - (td[1] / 2);
+
+ return {
+ component:component,
+ d:{ minx:minx, miny:miny, td:td, cxy:cxy },
+ minX:minx,
+ maxX:minx + td[0],
+ minY:miny,
+ maxY:miny + td[1]
+ };
+ }
+ else return {minX:0,maxX:0,minY:0,maxY:0};
+ };
+ };
+ jsPlumbUtil.extend(AbstractDOMOverlay, [jsPlumb.DOMElementComponent, AbstractOverlay], {
+ getDimensions : function() {
+ return jsPlumb.CurrentLibrary.getSize(jsPlumb.CurrentLibrary.getElementObject(this.getElement()));
+ },
+ setVisible : function(state) {
+ this._jsPlumb.div.style.display = state ? "block" : "none";
+ },
+ /*
+ * Function: clearCachedDimensions
+ * Clears the cached dimensions for the label. As a performance enhancement, label dimensions are
+ * cached from 1.3.12 onwards. The cache is cleared when you change the label text, of course, but
+ * there are other reasons why the text dimensions might change - if you make a change through CSS, for
+ * example, you might change the font size. in that case you should explicitly call this method.
+ */
+ clearCachedDimensions : function() {
+ this._jsPlumb.cachedDimensions = null;
+ },
+ cleanup : function() {
+ if (this._jsPlumb.div != null)
+ jsPlumb.CurrentLibrary.removeElement(this._jsPlumb.div);
+ },
+ computeMaxSize : function() {
+ var td = _getDimensions(this);
+ return Math.max(td[0], td[1]);
+ },
+ reattachListeners : function(connector) {
+ if (this._jsPlumb.div) {
+ this.reattachListenersForElement(this._jsPlumb.div, this, connector);
+ }
+ },
+ paint : function(p, containerExtents) {
+ if (!this._jsPlumb.initialised) {
+ this.getElement();
+ p.component.appendDisplayElement(this._jsPlumb.div);
+ this.attachListeners(this._jsPlumb.div, p.component);
+ this._jsPlumb.initialised = true;
+ }
+ this._jsPlumb.div.style.left = (p.component.x + p.d.minx) + "px";
+ this._jsPlumb.div.style.top = (p.component.y + p.d.miny) + "px";
+ }
+ });
+
+ /*
+ * Class: Overlays.Custom
+ * A Custom overlay. You supply a 'create' function which returns some DOM element, and jsPlumb positions it.
+ * The 'create' function is passed a Connection or Endpoint.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ * create - function for jsPlumb to call that returns a DOM element.
+ * location - distance (as a decimal from 0 to 1 inclusive) marking where the label should sit on the connector. defaults to 0.5.
+ * id - optional id to use for later retrieval of this overlay.
+ *
+ */
+ jsPlumb.Overlays.Custom = function(params) {
+ this.type = "Custom";
+ AbstractDOMOverlay.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.Custom, AbstractDOMOverlay);
+
+ jsPlumb.Overlays.GuideLines = function() {
+ var self = this;
+ self.length = 50;
+ self.lineWidth = 5;
+ this.type = "GuideLines";
+ AbstractOverlay.apply(this, arguments);
+ jsPlumb.jsPlumbUIComponent.apply(this, arguments);
+ this.draw = function(connector, currentConnectionPaintStyle) {
+
+ var head = connector.pointAlongPathFrom(self.loc, self.length / 2),
+ mid = connector.pointOnPath(self.loc),
+ tail = jsPlumbUtil.pointOnLine(head, mid, self.length),
+ tailLine = jsPlumbUtil.perpendicularLineTo(head, tail, 40),
+ headLine = jsPlumbUtil.perpendicularLineTo(tail, head, 20);
+
+ return {
+ connector:connector,
+ head:head,
+ tail:tail,
+ headLine:headLine,
+ tailLine:tailLine,
+ minX:Math.min(head.x, tail.x, headLine[0].x, headLine[1].x),
+ minY:Math.min(head.y, tail.y, headLine[0].y, headLine[1].y),
+ maxX:Math.max(head.x, tail.x, headLine[0].x, headLine[1].x),
+ maxY:Math.max(head.y, tail.y, headLine[0].y, headLine[1].y)
+ };
+ };
+
+ // this.cleanup = function() { }; // nothing to clean up for GuideLines
+ };
+
+ /*
+ * Class: Overlays.Label
+ * A Label overlay. For all different renderer types (SVG/Canvas/VML), jsPlumb draws a Label overlay as a styled DIV. Version 1.3.0 of jsPlumb
+ * introduced the ability to set css classes on the label; this is now the preferred way for you to style a label. The 'labelStyle' parameter
+ * is still supported in 1.3.0 but its usage is deprecated. Under the hood, jsPlumb just turns that object into a bunch of CSS directive that it
+ * puts on the Label's 'style' attribute, so the end result is the same.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ * cssClass - optional css class string to append to css class. This string is appended "as-is", so you can of course have multiple classes
+ * defined. This parameter is preferred to using labelStyle, borderWidth and borderStyle.
+ * label - the label to paint. May be a string or a function that returns a string. Nothing will be painted if your label is null or your
+ * label function returns null. empty strings _will_ be painted.
+ * location - distance (as a decimal from 0 to 1 inclusive) marking where the label should sit on the connector. defaults to 0.5.
+ * id - optional id to use for later retrieval of this overlay.
+ *
+ */
+ jsPlumb.Overlays.Label = function(params) {
+ this.labelStyle = params.labelStyle || jsPlumb.Defaults.LabelStyle;
+ this.cssClass = this.labelStyle != null ? this.labelStyle.cssClass : null;
+ var p = jsPlumb.extend({
+ create : function() {
+ return document.createElement("div");
+ }}, params);
+ jsPlumb.Overlays.Custom.call(this, p);
+ this.type = "Label";
+ this.label = params.label || "";
+ this.labelText = null;
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.Label, jsPlumb.Overlays.Custom, {
+ cleanup:function() {
+ this.div = null;
+ this.label = null;
+ this.labelText = null;
+ this.cssClass = null;
+ this.labelStyle = null;
+ },
+ getLabel : function() {
+ return this.label;
+ },
+ /*
+ * Function: setLabel
+ * sets the label's, um, label. you would think i'd call this function
+ * 'setText', but you can pass either a Function or a String to this, so
+ * it makes more sense as 'setLabel'. This uses innerHTML on the label div, so keep
+ * that in mind if you need escaped HTML.
+ */
+ setLabel : function(l) {
+ this.label = l;
+ this.labelText = null;
+ this.clearCachedDimensions();
+ this.update();
+ this.component.repaint();
+ },
+ getDimensions : function() {
+ this.update();
+ return AbstractDOMOverlay.prototype.getDimensions.apply(this, arguments);
+ },
+ update : function() {
+ if (typeof this.label == "function") {
+ var lt = this.label(this);
+ this.getElement().innerHTML = lt.replace(/\r\n/g, "<br/>");
+ }
+ else {
+ if (this.labelText == null) {
+ this.labelText = this.label;
+ this.getElement().innerHTML = this.labelText.replace(/\r\n/g, "<br/>");
+ }
+ }
+ }
+ });
+
+ // ********************************* END OF OVERLAY DEFINITIONS ***********************************************************************
+
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the 'flowchart' connectors, consisting of vertical and horizontal line segments.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+;(function() {
+
+ /**
+ * Function: Constructor
+ *
+ * Parameters:
+ * stub - minimum length for the stub at each end of the connector. This can be an integer, giving a value for both ends of the connections,
+ * or an array of two integers, giving separate values for each end. The default is an integer with value 30 (pixels).
+ * gap - gap to leave between the end of the connector and the element on which the endpoint resides. if you make this larger than stub then you will see some odd looking behaviour.
+ Like stub, this can be an array or a single value. defaults to 0 pixels for each end.
+ * cornerRadius - optional, defines the radius of corners between segments. defaults to 0 (hard edged corners).
+ * alwaysRespectStubs - defaults to false. whether or not the connectors should always draw the stub, or, if the two elements
+ are in close proximity to each other (closer than the sum of the two stubs), to adjust the stubs.
+ */
+ var Flowchart = function(params) {
+ this.type = "Flowchart";
+ params = params || {};
+ params.stub = params.stub == null ? 30 : params.stub;
+ var self = this,
+ _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
+ midpoint = params.midpoint == null ? 0.5 : params.midpoint,
+ points = [], segments = [],
+ grid = params.grid,
+ alwaysRespectStubs = params.alwaysRespectStubs,
+ userSuppliedSegments = null,
+ lastx = null, lasty = null, lastOrientation,
+ cornerRadius = params.cornerRadius != null ? params.cornerRadius : 0,
+ sgn = function(n) { return n < 0 ? -1 : n === 0 ? 0 : 1; },
+ /**
+ * helper method to add a segment.
+ */
+ addSegment = function(segments, x, y, paintInfo) {
+ if (lastx == x && lasty == y) return;
+ var lx = lastx == null ? paintInfo.sx : lastx,
+ ly = lasty == null ? paintInfo.sy : lasty,
+ o = lx == x ? "v" : "h",
+ sgnx = sgn(x - lx),
+ sgny = sgn(y - ly);
+
+ lastx = x;
+ lasty = y;
+ segments.push([lx, ly, x, y, o, sgnx, sgny]);
+ },
+ segLength = function(s) {
+ return Math.sqrt(Math.pow(s[0] - s[2], 2) + Math.pow(s[1] - s[3], 2));
+ },
+ _cloneArray = function(a) { var _a = []; _a.push.apply(_a, a); return _a;},
+ updateMinMax = function(a1) {
+ self.bounds.minX = Math.min(self.bounds.minX, a1[2]);
+ self.bounds.maxX = Math.max(self.bounds.maxX, a1[2]);
+ self.bounds.minY = Math.min(self.bounds.minY, a1[3]);
+ self.bounds.maxY = Math.max(self.bounds.maxY, a1[3]);
+ },
+ writeSegments = function(conn, segments, paintInfo) {
+ var current, next;
+ for (var i = 0; i < segments.length - 1; i++) {
+
+ current = current || _cloneArray(segments[i]);
+ next = _cloneArray(segments[i + 1]);
+ if (cornerRadius > 0 && current[4] != next[4]) {
+ var radiusToUse = Math.min(cornerRadius, segLength(current), segLength(next));
+ // right angle. adjust current segment's end point, and next segment's start point.
+ current[2] -= current[5] * radiusToUse;
+ current[3] -= current[6] * radiusToUse;
+ next[0] += next[5] * radiusToUse;
+ next[1] += next[6] * radiusToUse;
+ var ac = (current[6] == next[5] && next[5] == 1) ||
+ ((current[6] == next[5] && next[5] === 0) && current[5] != next[6]) ||
+ (current[6] == next[5] && next[5] == -1),
+ sgny = next[1] > current[3] ? 1 : -1,
+ sgnx = next[0] > current[2] ? 1 : -1,
+ sgnEqual = sgny == sgnx,
+ cx = (sgnEqual && ac || (!sgnEqual && !ac)) ? next[0] : current[2],
+ cy = (sgnEqual && ac || (!sgnEqual && !ac)) ? current[3] : next[1];
+
+ _super.addSegment(conn, "Straight", {
+ x1:current[0], y1:current[1], x2:current[2], y2:current[3]
+ });
+
+ _super.addSegment(conn, "Arc", {
+ r:radiusToUse,
+ x1:current[2],
+ y1:current[3],
+ x2:next[0],
+ y2:next[1],
+ cx:cx,
+ cy:cy,
+ ac:ac
+ });
+ }
+ else {
+ // dx + dy are used to adjust for line width.
+ var dx = (current[2] == current[0]) ? 0 : (current[2] > current[0]) ? (paintInfo.lw / 2) : -(paintInfo.lw / 2),
+ dy = (current[3] == current[1]) ? 0 : (current[3] > current[1]) ? (paintInfo.lw / 2) : -(paintInfo.lw / 2);
+ _super.addSegment(conn, "Straight", {
+ x1:current[0]- dx, y1:current[1]-dy, x2:current[2] + dx, y2:current[3] + dy
+ });
+ }
+ current = next;
+ }
+ // last segment
+ _super.addSegment(conn, "Straight", {
+ x1:next[0], y1:next[1], x2:next[2], y2:next[3]
+ });
+ };
+
+ this.setSegments = function(s) {
+ userSuppliedSegments = s;
+ };
+
+ this.isEditable = function() { return true; };
+
+ /*
+ Function: getOriginalSegments
+ Gets the segments before the addition of rounded corners. This is used by the flowchart
+ connector editor, since it only wants to concern itself with the original segments.
+ */
+ this.getOriginalSegments = function() {
+ return userSuppliedSegments || segments;
+ };
+
+ this._compute = function(paintInfo, params) {
+
+ if (params.clearEdits)
+ userSuppliedSegments = null;
+
+ if (userSuppliedSegments != null) {
+ writeSegments(this, userSuppliedSegments, paintInfo);
+ return;
+ }
+
+ segments = [];
+ lastx = null; lasty = null;
+ lastOrientation = null;
+
+ var midx = paintInfo.startStubX + ((paintInfo.endStubX - paintInfo.startStubX) * midpoint),
+ midy = paintInfo.startStubY + ((paintInfo.endStubY - paintInfo.startStubY) * midpoint);
+
+ var findClearedLine = function(start, mult, anchorPos, dimension) {
+ return start + (mult * (( 1 - anchorPos) * dimension) + _super.maxStub);
+ },
+ orientations = { x:[ 0, 1 ], y:[ 1, 0 ] },
+ commonStubCalculator = function(axis) {
+ return [ paintInfo.startStubX, paintInfo.startStubY, paintInfo.endStubX, paintInfo.endStubY ];
+ },
+ stubCalculators = {
+ perpendicular:commonStubCalculator,
+ orthogonal:commonStubCalculator,
+ opposite:function(axis) {
+ var pi = paintInfo,
+ idx = axis == "x" ? 0 : 1,
+ areInProximity = {
+ "x":function() {
+ return ( (pi.so[idx] == 1 && (
+ ( (pi.startStubX > pi.endStubX) && (pi.tx > pi.startStubX) ) ||
+ ( (pi.sx > pi.endStubX) && (pi.tx > pi.sx))))) ||
+
+ ( (pi.so[idx] == -1 && (
+ ( (pi.startStubX < pi.endStubX) && (pi.tx < pi.startStubX) ) ||
+ ( (pi.sx < pi.endStubX) && (pi.tx < pi.sx)))));
+ },
+ "y":function() {
+ return ( (pi.so[idx] == 1 && (
+ ( (pi.startStubY > pi.endStubY) && (pi.ty > pi.startStubY) ) ||
+ ( (pi.sy > pi.endStubY) && (pi.ty > pi.sy))))) ||
+
+ ( (pi.so[idx] == -1 && (
+ ( (pi.startStubY < pi.endStubY) && (pi.ty < pi.startStubY) ) ||
+ ( (pi.sy < pi.endStubY) && (pi.ty < pi.sy)))));
+ }
+ };
+
+ if (!alwaysRespectStubs && areInProximity[axis]()) {
+ return {
+ "x":[(paintInfo.sx + paintInfo.tx) / 2, paintInfo.startStubY, (paintInfo.sx + paintInfo.tx) / 2, paintInfo.endStubY],
+ "y":[paintInfo.startStubX, (paintInfo.sy + paintInfo.ty) / 2, paintInfo.endStubX, (paintInfo.sy + paintInfo.ty) / 2]
+ }[axis];
+ }
+ else {
+ return [ paintInfo.startStubX, paintInfo.startStubY, paintInfo.endStubX, paintInfo.endStubY ];
+ }
+ }
+ },
+ lineCalculators = {
+ perpendicular : function(axis, ss, oss, es, oes) {
+ var pi = paintInfo,
+ sis = {
+ x:[ [ [ 1,2,3,4 ], null, [ 2,1,4,3 ] ], null, [ [ 4,3,2,1 ], null, [ 3,4,1,2 ] ] ],
+ y:[ [ [ 3,2,1,4 ], null, [ 2,3,4,1 ] ], null, [ [ 4,1,2,3 ], null, [ 1,4,3,2 ] ] ]
+ },
+ stubs = {
+ x:[ [ pi.startStubX, pi.endStubX ] , null, [ pi.endStubX, pi.startStubX ] ],
+ y:[ [ pi.startStubY, pi.endStubY ] , null, [ pi.endStubY, pi.startStubY ] ]
+ },
+ midLines = {
+ x:[ [ midx, pi.startStubY ], [ midx, pi.endStubY ] ],
+ y:[ [ pi.startStubX, midy ], [ pi.endStubX, midy ] ]
+ },
+ linesToEnd = {
+ x:[ [ pi.endStubX, pi.startStubY ] ],
+ y:[ [ pi.startStubX, pi.endStubY ] ]
+ },
+ startToEnd = {
+ x:[ [ pi.startStubX, pi.endStubY ], [ pi.endStubX, pi.endStubY ] ],
+ y:[ [ pi.endStubX, pi.startStubY ], [ pi.endStubX, pi.endStubY ] ]
+ },
+ startToMidToEnd = {
+ x:[ [ pi.startStubX, midy ], [ pi.endStubX, midy ], [ pi.endStubX, pi.endStubY ] ],
+ y:[ [ midx, pi.startStubY ], [ midx, pi.endStubY ], [ pi.endStubX, pi.endStubY ] ]
+ },
+ otherStubs = {
+ x:[ pi.startStubY, pi.endStubY ],
+ y:[ pi.startStubX, pi.endStubX ]
+ },
+ soIdx = orientations[axis][0], toIdx = orientations[axis][1],
+ _so = pi.so[soIdx] + 1,
+ _to = pi.to[toIdx] + 1,
+ otherFlipped = (pi.to[toIdx] == -1 && (otherStubs[axis][1] < otherStubs[axis][0])) || (pi.to[toIdx] == 1 && (otherStubs[axis][1] > otherStubs[axis][0])),
+ stub1 = stubs[axis][_so][0],
+ stub2 = stubs[axis][_so][1],
+ segmentIndexes = sis[axis][_so][_to];
+
+ if (pi.segment == segmentIndexes[3] || (pi.segment == segmentIndexes[2] && otherFlipped)) {
+ return midLines[axis];
+ }
+ else if (pi.segment == segmentIndexes[2] && stub2 < stub1) {
+ return linesToEnd[axis];
+ }
+ else if ((pi.segment == segmentIndexes[2] && stub2 >= stub1) || (pi.segment == segmentIndexes[1] && !otherFlipped)) {
+ return startToMidToEnd[axis];
+ }
+ else if (pi.segment == segmentIndexes[0] || (pi.segment == segmentIndexes[1] && otherFlipped)) {
+ return startToEnd[axis];
+ }
+ },
+ orthogonal : function(axis, startStub, otherStartStub, endStub, otherEndStub) {
+ var pi = paintInfo,
+ extent = {
+ "x":pi.so[0] == -1 ? Math.min(startStub, endStub) : Math.max(startStub, endStub),
+ "y":pi.so[1] == -1 ? Math.min(startStub, endStub) : Math.max(startStub, endStub)
+ }[axis];
+
+ return {
+ "x":[ [ extent, otherStartStub ],[ extent, otherEndStub ], [ endStub, otherEndStub ] ],
+ "y":[ [ otherStartStub, extent ], [ otherEndStub, extent ], [ otherEndStub, endStub ] ]
+ }[axis];
+ },
+ opposite : function(axis, ss, oss, es, oes) {
+ var pi = paintInfo,
+ otherAxis = {"x":"y","y":"x"}[axis],
+ dim = {"x":"height","y":"width"}[axis],
+ comparator = pi["is" + axis.toUpperCase() + "GreaterThanStubTimes2"];
+
+ if (params.sourceEndpoint.elementId == params.targetEndpoint.elementId) {
+ var _val = oss + ((1 - params.sourceEndpoint.anchor[otherAxis]) * params.sourceInfo[dim]) + _super.maxStub;
+ return {
+ "x":[ [ ss, _val ], [ es, _val ] ],
+ "y":[ [ _val, ss ], [ _val, es ] ]
+ }[axis];
+
+ }
+ else if (!comparator || (pi.so[idx] == 1 && ss > es) || (pi.so[idx] == -1 && ss < es)) {
+ return {
+ "x":[[ ss, midy ], [ es, midy ]],
+ "y":[[ midx, ss ], [ midx, es ]]
+ }[axis];
+ }
+ else if ((pi.so[idx] == 1 && ss < es) || (pi.so[idx] == -1 && ss > es)) {
+ return {
+ "x":[[ midx, pi.sy ], [ midx, pi.ty ]],
+ "y":[[ pi.sx, midy ], [ pi.tx, midy ]]
+ }[axis];
+ }
+ }
+ };
+
+ var stubs = stubCalculators[paintInfo.anchorOrientation](paintInfo.sourceAxis),
+ idx = paintInfo.sourceAxis == "x" ? 0 : 1,
+ oidx = paintInfo.sourceAxis == "x" ? 1 : 0,
+ ss = stubs[idx],
+ oss = stubs[oidx],
+ es = stubs[idx + 2],
+ oes = stubs[oidx + 2];
+
+ // add the start stub segment.
+ addSegment(segments, stubs[0], stubs[1], paintInfo);
+
+ // compute the rest of the line
+ var p = lineCalculators[paintInfo.anchorOrientation](paintInfo.sourceAxis, ss, oss, es, oes);
+ if (p) {
+ for (var i = 0; i < p.length; i++) {
+ addSegment(segments, p[i][0], p[i][1], paintInfo);
+ }
+ }
+
+ // line to end stub
+ addSegment(segments, stubs[2], stubs[3], paintInfo);
+
+ // end stub to end
+ addSegment(segments, paintInfo.tx, paintInfo.ty, paintInfo);
+
+ writeSegments(this, segments, paintInfo);
+ };
+
+ this.getPath = function() {
+ var _last = null, _lastAxis = null, s = [], segs = userSuppliedSegments || segments;
+ for (var i = 0; i < segs.length; i++) {
+ var seg = segs[i], axis = seg[4], axisIndex = (axis == "v" ? 3 : 2);
+ if (_last != null && _lastAxis === axis) {
+ _last[axisIndex] = seg[axisIndex];
+ }
+ else {
+ if (seg[0] != seg[2] || seg[1] != seg[3]) {
+ s.push({
+ start:[ seg[0], seg[1] ],
+ end:[ seg[2], seg[3] ]
+ });
+ _last = seg;
+ _lastAxis = seg[4];
+ }
+ }
+ }
+ return s;
+ };
+
+ this.setPath = function(path) {
+ userSuppliedSegments = [];
+ for (var i = 0; i < path.length; i++) {
+ var lx = path[i].start[0],
+ ly = path[i].start[1],
+ x = path[i].end[0],
+ y = path[i].end[1],
+ o = lx == x ? "v" : "h",
+ sgnx = sgn(x - lx),
+ sgny = sgn(y - ly);
+
+ userSuppliedSegments.push([lx, ly, x, y, o, sgnx, sgny]);
+ }
+ };
+ };
+
+ jsPlumbUtil.extend(Flowchart, jsPlumb.Connectors.AbstractConnector);
+ jsPlumb.registerConnectorType(Flowchart, "Flowchart");
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the state machine connectors.
+ *
+ * Thanks to Brainstorm Mobile Solutions for supporting the development of these.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt(a)gmail.com)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ var Line = function(x1, y1, x2, y2) {
+
+ this.m = (y2 - y1) / (x2 - x1);
+ this.b = -1 * ((this.m * x1) - y1);
+
+ this.rectIntersect = function(x,y,w,h) {
+ var results = [], xInt, yInt;
+
+ // try top face
+ // the equation of the top face is y = (0 * x) + b; y = b.
+ xInt = (y - this.b) / this.m;
+ // test that the X value is in the line's range.
+ if (xInt >= x && xInt <= (x + w)) results.push([ xInt, (this.m * xInt) + this.b ]);
+
+ // try right face
+ yInt = (this.m * (x + w)) + this.b;
+ if (yInt >= y && yInt <= (y + h)) results.push([ (yInt - this.b) / this.m, yInt ]);
+
+ // bottom face
+ xInt = ((y + h) - this.b) / this.m;
+ // test that the X value is in the line's range.
+ if (xInt >= x && xInt <= (x + w)) results.push([ xInt, (this.m * xInt) + this.b ]);
+
+ // try left face
+ yInt = (this.m * x) + this.b;
+ if (yInt >= y && yInt <= (y + h)) results.push([ (yInt - this.b) / this.m, yInt ]);
+
+ if (results.length == 2) {
+ var midx = (results[0][0] + results[1][0]) / 2, midy = (results[0][1] + results[1][1]) / 2;
+ results.push([ midx,midy ]);
+ // now calculate the segment inside the rectangle where the midpoint lies.
+ var xseg = midx <= x + (w / 2) ? -1 : 1,
+ yseg = midy <= y + (h / 2) ? -1 : 1;
+ results.push([xseg, yseg]);
+ return results;
+ }
+
+ return null;
+
+ };
+ },
+ _segment = function(x1, y1, x2, y2) {
+ if (x1 <= x2 && y2 <= y1) return 1;
+ else if (x1 <= x2 && y1 <= y2) return 2;
+ else if (x2 <= x1 && y2 >= y1) return 3;
+ return 4;
+ },
+
+ // the control point we will use depends on the faces to which each end of the connection is assigned, specifically whether or not the
+ // two faces are parallel or perpendicular. if they are parallel then the control point lies on the midpoint of the axis in which they
+ // are parellel and varies only in the other axis; this variation is proportional to the distance that the anchor points lie from the
+ // center of that face. if the two faces are perpendicular then the control point is at some distance from both the midpoints; the amount and
+ // direction are dependent on the orientation of the two elements. 'seg', passed in to this method, tells you which segment the target element
+ // lies in with respect to the source: 1 is top right, 2 is bottom right, 3 is bottom left, 4 is top left.
+ //
+ // sourcePos and targetPos are arrays of info about where on the source and target each anchor is located. their contents are:
+ //
+ // 0 - absolute x
+ // 1 - absolute y
+ // 2 - proportional x in element (0 is left edge, 1 is right edge)
+ // 3 - proportional y in element (0 is top edge, 1 is bottom edge)
+ //
+ _findControlPoint = function(midx, midy, segment, sourceEdge, targetEdge, dx, dy, distance, proximityLimit) {
+ // TODO (maybe)
+ // - if anchor pos is 0.5, make the control point take into account the relative position of the elements.
+ if (distance <= proximityLimit) return [midx, midy];
+
+ if (segment === 1) {
+ if (sourceEdge[3] <= 0 && targetEdge[3] >= 1) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
+ else if (sourceEdge[2] >= 1 && targetEdge[2] <= 0) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
+ else return [ midx + (-1 * dx) , midy + (-1 * dy) ];
+ }
+ else if (segment === 2) {
+ if (sourceEdge[3] >= 1 && targetEdge[3] <= 0) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
+ else if (sourceEdge[2] >= 1 && targetEdge[2] <= 0) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
+ else return [ midx + (1 * dx) , midy + (-1 * dy) ];
+ }
+ else if (segment === 3) {
+ if (sourceEdge[3] >= 1 && targetEdge[3] <= 0) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
+ else if (sourceEdge[2] <= 0 && targetEdge[2] >= 1) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
+ else return [ midx + (-1 * dx) , midy + (-1 * dy) ];
+ }
+ else if (segment === 4) {
+ if (sourceEdge[3] <= 0 && targetEdge[3] >= 1) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ];
+ else if (sourceEdge[2] <= 0 && targetEdge[2] >= 1) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ];
+ else return [ midx + (1 * dx) , midy + (-1 * dy) ];
+ }
+
+ };
+
+ /**
+ * Class: Connectors.StateMachine
+ * Provides 'state machine' connectors.
+ */
+ /*
+ * Function: Constructor
+ *
+ * Parameters:
+ * curviness - measure of how "curvy" the connectors will be. this is translated as the distance that the
+ * Bezier curve's control point is from the midpoint of the straight line connecting the two
+ * endpoints, and does not mean that the connector is this wide. The Bezier curve never reaches
+ * its control points; they act as gravitational masses. defaults to 10.
+ * margin - distance from element to start and end connectors, in pixels. defaults to 5.
+ * proximityLimit - sets the distance beneath which the elements are consider too close together to bother
+ * with fancy curves. by default this is 80 pixels.
+ * loopbackRadius - the radius of a loopback connector. optional; defaults to 25.
+ * showLoopback - If set to false this tells the connector that it is ok to paint connections whose source and target is the same element with a connector running through the element. The default value for this is true; the connector always makes a loopback connection loop around the element rather than passing through it.
+ */
+ var StateMachine = function(params) {
+ params = params || {};
+ this.type = "StateMachine";
+
+ var self = this,
+ _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
+ curviness = params.curviness || 10,
+ margin = params.margin || 5,
+ proximityLimit = params.proximityLimit || 80,
+ clockwise = params.orientation && params.orientation === "clockwise",
+ loopbackRadius = params.loopbackRadius || 25,
+ showLoopback = params.showLoopback !== false;
+
+ this._compute = function(paintInfo, params) {
+ var w = Math.abs(params.sourcePos[0] - params.targetPos[0]),
+ h = Math.abs(params.sourcePos[1] - params.targetPos[1]),
+ x = Math.min(params.sourcePos[0], params.targetPos[0]),
+ y = Math.min(params.sourcePos[1], params.targetPos[1]);
+
+ if (!showLoopback || (params.sourceEndpoint.elementId !== params.targetEndpoint.elementId)) {
+ var _sx = params.sourcePos[0] < params.targetPos[0] ? 0 : w,
+ _sy = params.sourcePos[1] < params.targetPos[1] ? 0:h,
+ _tx = params.sourcePos[0] < params.targetPos[0] ? w : 0,
+ _ty = params.sourcePos[1] < params.targetPos[1] ? h : 0;
+
+ // now adjust for the margin
+ if (params.sourcePos[2] === 0) _sx -= margin;
+ if (params.sourcePos[2] === 1) _sx += margin;
+ if (params.sourcePos[3] === 0) _sy -= margin;
+ if (params.sourcePos[3] === 1) _sy += margin;
+ if (params.targetPos[2] === 0) _tx -= margin;
+ if (params.targetPos[2] === 1) _tx += margin;
+ if (params.targetPos[3] === 0) _ty -= margin;
+ if (params.targetPos[3] === 1) _ty += margin;
+
+ //
+ // these connectors are quadratic bezier curves, having a single control point. if both anchors
+ // are located at 0.5 on their respective faces, the control point is set to the midpoint and you
+ // get a straight line. this is also the case if the two anchors are within 'proximityLimit', since
+ // it seems to make good aesthetic sense to do that. outside of that, the control point is positioned
+ // at 'curviness' pixels away along the normal to the straight line connecting the two anchors.
+ //
+ // there may be two improvements to this. firstly, we might actually support the notion of avoiding nodes
+ // in the UI, or at least making a good effort at doing so. if a connection would pass underneath some node,
+ // for example, we might increase the distance the control point is away from the midpoint in a bid to
+ // steer it around that node. this will work within limits, but i think those limits would also be the likely
+ // limits for, once again, aesthetic good sense in the layout of a chart using these connectors.
+ //
+ // the second possible change is actually two possible changes: firstly, it is possible we should gradually
+ // decrease the 'curviness' as the distance between the anchors decreases; start tailing it off to 0 at some
+ // point (which should be configurable). secondly, we might slightly increase the 'curviness' for connectors
+ // with respect to how far their anchor is from the center of its respective face. this could either look cool,
+ // or stupid, and may indeed work only in a way that is so subtle as to have been a waste of time.
+ //
+
+ var _midx = (_sx + _tx) / 2, _midy = (_sy + _ty) / 2,
+ m2 = (-1 * _midx) / _midy, theta2 = Math.atan(m2),
+ dy = (m2 == Infinity || m2 == -Infinity) ? 0 : Math.abs(curviness / 2 * Math.sin(theta2)),
+ dx = (m2 == Infinity || m2 == -Infinity) ? 0 : Math.abs(curviness / 2 * Math.cos(theta2)),
+ segment = _segment(_sx, _sy, _tx, _ty),
+ distance = Math.sqrt(Math.pow(_tx - _sx, 2) + Math.pow(_ty - _sy, 2)),
+ // calculate the control point. this code will be where we'll put in a rudimentary element avoidance scheme; it
+ // will work by extending the control point to force the curve to be, um, curvier.
+ _controlPoint = _findControlPoint(_midx,
+ _midy,
+ segment,
+ params.sourcePos,
+ params.targetPos,
+ curviness, curviness,
+ distance,
+ proximityLimit);
+
+ _super.addSegment(this, "Bezier", {
+ x1:_tx, y1:_ty, x2:_sx, y2:_sy,
+ cp1x:_controlPoint[0], cp1y:_controlPoint[1],
+ cp2x:_controlPoint[0], cp2y:_controlPoint[1]
+ });
+ }
+ else {
+ // a loopback connector. draw an arc from one anchor to the other.
+ var x1 = params.sourcePos[0], x2 = params.sourcePos[0], y1 = params.sourcePos[1] - margin, y2 = params.sourcePos[1] - margin,
+ cx = x1, cy = y1 - loopbackRadius,
+ // canvas sizing stuff, to ensure the whole painted area is visible.
+ _w = 2 * loopbackRadius,
+ _h = 2 * loopbackRadius,
+ _x = cx - loopbackRadius,
+ _y = cy - loopbackRadius;
+
+ paintInfo.points[0] = _x;
+ paintInfo.points[1] = _y;
+ paintInfo.points[2] = _w;
+ paintInfo.points[3] = _h;
+
+ // ADD AN ARC SEGMENT.
+ _super.addSegment(this, "Arc", {
+ x1:(x1 - _x) + 4,
+ y1:y1 - _y,
+ startAngle:0,
+ endAngle: 2 * Math.PI,
+ r:loopbackRadius,
+ ac:!clockwise,
+ x2:(x1 - _x) - 4,
+ y2:y1 - _y,
+ cx:cx - _x,
+ cy:cy - _y
+ });
+ }
+ };
+ };
+ jsPlumb.registerConnectorType(StateMachine, "StateMachine");
+})();
+
+/*
+ // a possible rudimentary avoidance scheme, old now, perhaps not useful.
+ // if (avoidSelector) {
+ // var testLine = new Line(sourcePos[0] + _sx,sourcePos[1] + _sy,sourcePos[0] + _tx,sourcePos[1] + _ty);
+ // var sel = jsPlumb.getSelector(avoidSelector);
+ // for (var i = 0; i < sel.length; i++) {
+ // var id = jsPlumb.getId(sel[i]);
+ // if (id != sourceEndpoint.elementId && id != targetEndpoint.elementId) {
+ // o = jsPlumb.getOffset(id), s = jsPlumb.getSize(id);
+//
+// if (o && s) {
+// var collision = testLine.rectIntersect(o.left,o.top,s[0],s[1]);
+// if (collision) {
+ // set the control point to be a certain distance from the midpoint of the two points that
+ // the line crosses on the rectangle.
+ // TODO where will this 75 number come from?
+ // _controlX = collision[2][0] + (75 * collision[3][0]);
+ // / _controlY = collision[2][1] + (75 * collision[3][1]);
+// }
+// }
+ // }
+ // }
+ //}
+ */
+
+;(function() {
+
+ var Bezier = function(params) {
+ params = params || {};
+
+ var self = this,
+ _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
+ stub = params.stub || 50,
+ majorAnchor = params.curviness || 150,
+ minorAnchor = 10;
+
+ this.type = "Bezier";
+ this.getCurviness = function() { return majorAnchor; };
+
+ this._findControlPoint = function(point, sourceAnchorPosition, targetAnchorPosition, sourceEndpoint, targetEndpoint) {
+ // determine if the two anchors are perpendicular to each other in their orientation. we swap the control
+ // points around if so (code could be tightened up)
+ var soo = sourceEndpoint.anchor.getOrientation(sourceEndpoint),
+ too = targetEndpoint.anchor.getOrientation(targetEndpoint),
+ perpendicular = soo[0] != too[0] || soo[1] == too[1],
+ p = [];
+
+ if (!perpendicular) {
+ if (soo[0] === 0) // X
+ p.push(sourceAnchorPosition[0] < targetAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
+ else p.push(point[0] - (majorAnchor * soo[0]));
+
+ if (soo[1] === 0) // Y
+ p.push(sourceAnchorPosition[1] < targetAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
+ else p.push(point[1] + (majorAnchor * too[1]));
+ }
+ else {
+ if (too[0] === 0) // X
+ p.push(targetAnchorPosition[0] < sourceAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
+ else p.push(point[0] + (majorAnchor * too[0]));
+
+ if (too[1] === 0) // Y
+ p.push(targetAnchorPosition[1] < sourceAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
+ else p.push(point[1] + (majorAnchor * soo[1]));
+ }
+
+ return p;
+ };
+
+ this._compute = function(paintInfo, p) {
+ var sp = p.sourcePos,
+ tp = p.targetPos,
+ _w = Math.abs(sp[0] - tp[0]),
+ _h = Math.abs(sp[1] - tp[1]),
+ _sx = sp[0] < tp[0] ? _w : 0,
+ _sy = sp[1] < tp[1] ? _h : 0,
+ _tx = sp[0] < tp[0] ? 0 : _w,
+ _ty = sp[1] < tp[1] ? 0 : _h,
+ _CP = self._findControlPoint([_sx, _sy], sp, tp, p.sourceEndpoint, p.targetEndpoint),
+ _CP2 = self._findControlPoint([_tx, _ty], tp, sp, p.targetEndpoint, p.sourceEndpoint);
+
+ _super.addSegment(this, "Bezier", {
+ x1:_sx, y1:_sy, x2:_tx, y2:_ty,
+ cp1x:_CP[0], cp1y:_CP[1], cp2x:_CP2[0], cp2y:_CP2[1]
+ });
+ };
+ };
+
+ jsPlumb.registerConnectorType(Bezier, "Bezier");
+
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the HTML5 canvas renderers. Support for canvas was dropped in 1.4.2.
+ * This is being kept around because canvas might make a comeback as a single-page solution
+ * that also supports node rendering.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+
+// ********************************* CANVAS RENDERERS FOR CONNECTORS AND ENDPOINTS *******************************************************************
+
+ // TODO refactor to renderer common script. put a ref to jsPlumb.sizeCanvas in there too.
+ var _connectionBeingDragged = null,
+ _hasClass = function(el, clazz) { return jsPlumb.CurrentLibrary.hasClass(_getElementObject(el), clazz); },
+ _getElementObject = function(el) { return jsPlumb.CurrentLibrary.getElementObject(el); },
+ _getOffset = function(el) { return jsPlumb.CurrentLibrary.getOffset(_getElementObject(el)); },
+ _pageXY = function(el) { return jsPlumb.CurrentLibrary.getPageXY(el); },
+ _clientXY = function(el) { return jsPlumb.CurrentLibrary.getClientXY(el); };
+
+ /*
+ * Class:CanvasMouseAdapter
+ * Provides support for mouse events on canvases.
+ */
+ var CanvasMouseAdapter = window.CanvasMouseAdapter = function() {
+ var self = this;
+ self.overlayPlacements = [];
+ jsPlumb.jsPlumbUIComponent.apply(this, arguments);
+ jsPlumbUtil.EventGenerator.apply(this, arguments);
+ /**
+ * returns whether or not the given event is ojver a painted area of the canvas.
+ */
+ this._over = function(e) {
+ var o = _getOffset(_getElementObject(self.canvas)),
+ pageXY = _pageXY(e),
+ x = pageXY[0] - o.left, y = pageXY[1] - o.top;
+ if (x > 0 && y > 0 && x < self.canvas.width && y < self.canvas.height) {
+ // first check overlays
+ for ( var i = 0; i < self.overlayPlacements.length; i++) {
+ var p = self.overlayPlacements[i];
+ if (p && (p[0] <= x && p[1] >= x && p[2] <= y && p[3] >= y))
+ return true;
+ }
+ // then the canvas
+ var d = self.canvas.getContext("2d").getImageData(parseInt(x, 10), parseInt(y, 10), 1, 1);
+ return d.data[0] !== 0 || d.data[1] !== 0 || d.data[2] !== 0 || d.data[3] !== 0;
+ }
+ return false;
+ };
+
+ var _mouseover = false, _mouseDown = false, _posWhenMouseDown = null, _mouseWasDown = false,
+ _nullSafeHasClass = function(el, clazz) {
+ return el !== null && _hasClass(el, clazz);
+ };
+ this.mousemove = function(e) {
+ var pageXY = _pageXY(e), clientXY = _clientXY(e),
+ ee = document.elementFromPoint(clientXY[0], clientXY[1]),
+ eventSourceWasOverlay = _nullSafeHasClass(ee, "_jsPlumb_overlay");
+ var _continue = _connectionBeingDragged === null && (_nullSafeHasClass(ee, "_jsPlumb_endpoint") || _nullSafeHasClass(ee, "_jsPlumb_connector"));
+ if (!_mouseover && _continue && self._over(e)) {
+ _mouseover = true;
+ self.fire("mouseenter", self, e);
+ return true;
+ }
+ // TODO here there is a remote chance that the overlay the mouse moved onto
+ // is actually not an overlay for the current component. a more thorough check would
+ // be to ensure the overlay belonged to the current component.
+ else if (_mouseover && (!self._over(e) || !_continue) && !eventSourceWasOverlay) {
+ _mouseover = false;
+ self.fire("mouseexit", self, e);
+ }
+ self.fire("mousemove", self, e);
+ };
+
+ this.click = function(e) {
+ if (_mouseover && self._over(e) && !_mouseWasDown)
+ self.fire("click", self, e);
+ _mouseWasDown = false;
+ };
+
+ this.dblclick = function(e) {
+ if (_mouseover && self._over(e) && !_mouseWasDown)
+ self.fire("dblclick", self, e);
+ _mouseWasDown = false;
+ };
+
+ this.mousedown = function(e) {
+ if(self._over(e) && !_mouseDown) {
+ _mouseDown = true;
+ _posWhenMouseDown = _getOffset(_getElementObject(self.canvas));
+ self.fire("mousedown", self, e);
+ }
+ };
+
+ this.mouseup = function(e) {
+ _mouseDown = false;
+ self.fire("mouseup", self, e);
+ };
+
+ this.contextmenu = function(e) {
+ if (_mouseover && self._over(e) && !_mouseWasDown)
+ self.fire("contextmenu", self, e);
+ _mouseWasDown = false;
+ };
+ };
+ jsPlumbUtil.extend(CanvasMouseAdapter, [ jsPlumb.jsPlumbUIComponent, jsPlumbUtil.EventGenerator ]);
+
+ var _newCanvas = function(params) {
+ var canvas = document.createElement("canvas");
+ params._jsPlumb.instance.appendElement(canvas, params.parent);
+ canvas.style.position = "absolute";
+ if (params["class"]) canvas.className = params["class"];
+ // set an id. if no id on the element and if uuid was supplied it
+ // will be used, otherwise we'll create one.
+ params._jsPlumb.instance.getId(canvas, params.uuid);
+ if (params.tooltip) canvas.setAttribute("title", params.tooltip);
+
+ return canvas;
+ };
+
+ var CanvasComponent = window.CanvasComponent = function(params) {
+ CanvasMouseAdapter.apply(this, arguments);
+
+ var displayElements = [ ];
+ this.getDisplayElements = function() { return displayElements; };
+ this.appendDisplayElement = function(el) { displayElements.push(el); };
+ };
+ jsPlumbUtil.extend(CanvasComponent, CanvasMouseAdapter);
+
+ var segmentMultipliers = [null, [1, -1], [1, 1], [-1, 1], [-1, -1] ];
+ var maybeMakeGradient = function(ctx, style, gradientFunction) {
+ if (style.gradient) {
+ var g = gradientFunction();
+ for ( var i = 0; i < style.gradient.stops.length; i++)
+ g.addColorStop(style.gradient.stops[i][0], style.gradient.stops[i][1]);
+ ctx.strokeStyle = g;
+ }
+ };
+ var segmentRenderer = function(segment, ctx, style, dx, dy) {
+ ({
+ "Straight":function(segment, ctx, style, dx, dy) {
+ var d = segment.params;
+ ctx.save();
+ maybeMakeGradient(ctx, style, function() { return ctx.createLinearGradient(d.x1, d.y1, d.x2, d.y2); });
+ ctx.beginPath();
+ ctx.translate(dx, dy);
+ if (style.dashstyle && style.dashstyle.split(" ").length === 2) {
+ // only a very simple dashed style is supported - having two values, which define the stroke length
+ // (as a multiple of the stroke width) and then the space length (also as a multiple of stroke width).
+ var ds = style.dashstyle.split(" ");
+ if (ds.length !== 2) ds = [2, 2];
+ var dss = [ ds[0] * style.lineWidth, ds[1] * style.lineWidth ],
+ m = (d.x2- d.x1) / (d.y2 - d.y1),
+ s = jsPlumbUtil.segment([d.x1, d.y1], [ d.x2, d.y2 ]),
+ sm = segmentMultipliers[s],
+ theta = Math.atan(m),
+ l = Math.sqrt(Math.pow(d.x2 - d.x1, 2) + Math.pow(d.y2 - d.y1, 2)),
+ repeats = Math.floor(l / (dss[0] + dss[1])),
+ curPos = [d.x1, d.y1];
+
+
+ // TODO: the question here is why could we not support this in all connector types? it's really
+ // just a case of going along and asking jsPlumb for the next point on the path a few times, until it
+ // reaches the end. every type of connector supports that method, after all. but right now its only the
+ // bezier connector that gives you back the new location on the path along with the x,y coordinates, which
+ // we would need. we'd start out at loc=0 and ask for the point along the path that is dss[0] pixels away.
+ // we then ask for the point that is (dss[0] + dss[1]) pixels away; and from that one we need not just the
+ // x,y but the location, cos we're gonna plug that location back in in order to find where that dash ends.
+ //
+ // it also strikes me that it should be trivial to support arbitrary dash styles (having more or less than two
+ // entries). you'd just iterate that array using a step size of 2, and generify the (rss[0] + rss[1])
+ // computation to be sum(rss[0]..rss[n]).
+
+ for (var i = 0; i < repeats; i++) {
+ ctx.moveTo(curPos[0], curPos[1]);
+
+ var nextEndX = curPos[0] + (Math.abs(Math.sin(theta) * dss[0]) * sm[0]),
+ nextEndY = curPos[1] + (Math.abs(Math.cos(theta) * dss[0]) * sm[1]),
+ nextStartX = curPos[0] + (Math.abs(Math.sin(theta) * (dss[0] + dss[1])) * sm[0]),
+ nextStartY = curPos[1] + (Math.abs(Math.cos(theta) * (dss[0] + dss[1])) * sm[1]);
+
+ ctx.lineTo(nextEndX, nextEndY);
+ curPos = [nextStartX, nextStartY];
+ }
+
+ // now draw the last bit
+ ctx.moveTo(curPos[0], curPos[1]);
+ ctx.lineTo(d.x2, d.y2);
+
+ }
+ else {
+ ctx.moveTo(d.x1, d.y1);
+ ctx.lineTo(d.x2, d.y2);
+ }
+
+ ctx.stroke();
+
+ ctx.restore();
+ },
+ "Bezier":function(segment, ctx, style, dx, dy) {
+ var d = segment.params;
+ ctx.save();
+ maybeMakeGradient(ctx, style, function() { return ctx.createLinearGradient(d.x2 + dx, d.y2 + dy, d.x1 + dx, d.y1 + dy); });
+ ctx.beginPath();
+ ctx.translate(dx, dy);
+ ctx.moveTo(d.x1, d.y1);
+ ctx.bezierCurveTo(d.cp1x, d.cp1y, d.cp2x, d.cp2y, d.x2, d.y2);
+ ctx.stroke();
+ ctx.restore();
+ },
+ "Arc":function(segment, ctx, style, dx, dy) {
+ var d = segment.params;
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(dx, dy);
+ ctx.arc(d.cx, d.cy, d.r, segment.startAngle, segment.endAngle, d.ac);
+ ctx.stroke();
+ ctx.restore();
+ }
+ })[segment.type](segment, ctx, style, dx, dy);
+ };
+
+ /**
+ * Class:CanvasConnector
+ * Superclass for Canvas Connector renderers.
+ */
+ var CanvasConnector = jsPlumb.ConnectorRenderers.canvas = function(params) {
+ CanvasComponent.apply(this, arguments);
+
+ var _paintOneStyle = function(aStyle, dx, dy) {
+ this.ctx.save();
+ jsPlumb.extend(this.ctx, aStyle);
+
+ var segments = this.getSegments();
+ for (var i = 0; i < segments.length; i++) {
+ segmentRenderer(segments[i], this.ctx, aStyle, dx, dy);
+ }
+ this.ctx.restore();
+ }.bind(this);
+
+ var clazz = this._jsPlumb.instance.connectorClass + " " + (params.cssClass || "");
+ this.canvas = _newCanvas({
+ "class":clazz,
+ _jsPlumb:this._jsPlumb,
+ parent:params.parent
+ });
+ this.ctx = this.canvas.getContext("2d");
+
+ this.appendDisplayElement(this.canvas);
+
+ this.paint = function(style, anchor, extents) {
+ if (style != null) {
+
+ var xy = [ this.x, this.y ], wh = [ this.w, this.h ], p,
+ dx = 0, dy = 0;
+
+ if (extents != null) {
+ if (extents.xmin < 0) {
+ xy[0] += extents.xmin;
+ dx = -extents.xmin;
+ }
+ if (extents.ymin < 0) {
+ xy[1] += extents.ymin;
+ dy = -extents.ymin;
+ }
+ wh[0] = extents.xmax + ((extents.xmin < 0) ? -extents.xmin : 0);
+ wh[1] = extents.ymax + ((extents.ymin < 0) ? -extents.ymin : 0);
+ }
+
+ this.translateX = dx;
+ this.translateY = dy;
+
+ jsPlumbUtil.sizeElement(this.canvas, xy[0], xy[1], wh[0], wh[1]);
+
+ if (style.outlineColor != null) {
+ var outlineWidth = style.outlineWidth || 1,
+ outlineStrokeWidth = style.lineWidth + (2 * outlineWidth),
+ outlineStyle = {
+ strokeStyle:style.outlineColor,
+ lineWidth:outlineStrokeWidth
+ };
+ _paintOneStyle(outlineStyle, dx, dy);
+ }
+ _paintOneStyle(style, dx, dy);
+ }
+ };
+ };
+ jsPlumbUtil.extend(CanvasConnector, CanvasComponent);
+
+
+ /**
+ * Class:CanvasEndpoint
+ * Superclass for Canvas Endpoint renderers.
+ */
+ var CanvasEndpoint = function(params) {
+ CanvasComponent.apply(this, arguments);
+ var clazz = this._jsPlumb.instance.endpointClass + " " + (params.cssClass || ""),
+ canvasParams = {
+ "class":clazz,
+ _jsPlumb:this._jsPlumb,
+ parent:params.parent,
+ tooltip:self.tooltip
+ };
+ this.canvas = _newCanvas(canvasParams);
+ this.ctx = this.canvas.getContext("2d");
+
+ this.appendDisplayElement(this.canvas);
+
+ this.paint = function(style, anchor, extents) {
+ jsPlumbUtil.sizeElement(this.canvas, this.x, this.y, this.w, this.h);
+ if (style.outlineColor != null) {
+ var outlineWidth = style.outlineWidth || 1,
+ outlineStrokeWidth = style.lineWidth + (2 * outlineWidth);
+ var outlineStyle = {
+ strokeStyle:style.outlineColor,
+ lineWidth:outlineStrokeWidth
+ };
+ }
+
+ this._paint.apply(this, arguments);
+ };
+ };
+ jsPlumbUtil.extend(CanvasEndpoint, CanvasComponent);
+
+ jsPlumb.Endpoints.canvas.Dot = function(params) {
+ jsPlumb.Endpoints.Dot.apply(this, arguments);
+ CanvasEndpoint.apply(this, arguments);
+ var self = this,
+ parseValue = function(value) {
+ try { return parseInt(value, 10); }
+ catch(e) {
+ if (value.substring(value.length - 1) == '%')
+ return parseInt(value.substring(0, value - 1), 10);
+ }
+ },
+ calculateAdjustments = function(gradient) {
+ var offsetAdjustment = self.defaultOffset, innerRadius = self.defaultInnerRadius;
+ if (gradient.offset) offsetAdjustment = parseValue(gradient.offset);
+ if (gradient.innerRadius) innerRadius = parseValue(gradient.innerRadius);
+ return [offsetAdjustment, innerRadius];
+ };
+ this._paint = function(style) {
+ if (style != null) {
+ var ctx = self.canvas.getContext('2d'),
+ orientation = params.endpoint.anchor.getOrientation(params.endpoint);
+
+ jsPlumb.extend(ctx, style);
+ if (style.gradient) {
+ var adjustments = calculateAdjustments(style.gradient),
+ yAdjust = orientation[1] == 1 ? adjustments[0] * -1 : adjustments[0],
+ xAdjust = orientation[0] == 1 ? adjustments[0] * -1: adjustments[0],
+ g = ctx.createRadialGradient(self.radius, self.radius, self.radius, self.radius + xAdjust, self.radius + yAdjust, adjustments[1]);
+ for (var i = 0; i < style.gradient.stops.length; i++)
+ g.addColorStop(style.gradient.stops[i][0], style.gradient.stops[i][1]);
+ ctx.fillStyle = g;
+ }
+ ctx.beginPath();
+ //ctx.translate(dx, dy);
+ ctx.arc(self.radius, self.radius, self.radius, 0, Math.PI*2, true);
+ ctx.closePath();
+ if (style.fillStyle || style.gradient) ctx.fill();
+ if (style.strokeStyle) ctx.stroke();
+ }
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.canvas.Dot, [ jsPlumb.Endpoints.Dot, CanvasEndpoint ]);
+
+ jsPlumb.Endpoints.canvas.Rectangle = function(params) {
+
+ var self = this;
+ jsPlumb.Endpoints.Rectangle.apply(this, arguments);
+ CanvasEndpoint.apply(this, arguments);
+
+ this._paint = function(style) {
+
+ var ctx = self.canvas.getContext("2d"),
+ orientation = params.endpoint.anchor.getOrientation(params.endpoint);
+
+ jsPlumb.extend(ctx, style);
+
+ /* canvas gradient */
+ if (style.gradient) {
+ // first figure out which direction to run the gradient in (it depends on the orientation of the anchors)
+ var y1 = orientation[1] == 1 ? self.h : orientation[1] === 0 ? self.h / 2 : 0;
+ var y2 = orientation[1] == -1 ? self.h : orientation[1] === 0 ? self.h / 2 : 0;
+ var x1 = orientation[0] == 1 ? self.w : orientation[0] === 0 ? self.w / 2 : 0;
+ var x2 = orientation[0] == -1 ? self.w : orientation[0] === 0 ? self.w / 2 : 0;
+ var g = ctx.createLinearGradient(x1,y1,x2,y2);
+ for (var i = 0; i < style.gradient.stops.length; i++)
+ g.addColorStop(style.gradient.stops[i][0], style.gradient.stops[i][1]);
+ ctx.fillStyle = g;
+ }
+
+ ctx.beginPath();
+ ctx.rect(0, 0, self.w, self.h);
+ ctx.closePath();
+ if (style.fillStyle || style.gradient) ctx.fill();
+ if (style.strokeStyle) ctx.stroke();
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.canvas.Rectangle, [ jsPlumb.Endpoints.Rectangle, CanvasEndpoint ]);
+
+ jsPlumb.Endpoints.canvas.Triangle = function(params) {
+
+ var self = this;
+ jsPlumb.Endpoints.Triangle.apply(this, arguments);
+ CanvasEndpoint.apply(this, arguments);
+
+ this._paint = function(style) {
+ var ctx = self.canvas.getContext('2d'),
+ offsetX = 0, offsetY = 0, angle = 0,
+ orientation = params.endpoint.anchor.getOrientation(params.endpoint);
+
+ if( orientation[0] == 1 ) {
+ offsetX = self.width;
+ offsetY = self.height;
+ angle = 180;
+ }
+ if( orientation[1] == -1 ) {
+ offsetX = self.width;
+ angle = 90;
+ }
+ if( orientation[1] == 1 ) {
+ offsetY = self.height;
+ angle = -90;
+ }
+
+ ctx.fillStyle = style.fillStyle;
+
+ ctx.translate(offsetX, offsetY);
+ ctx.rotate(angle * Math.PI/180);
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(self.width/2, self.height/2);
+ ctx.lineTo(0, self.height);
+ ctx.closePath();
+ if (style.fillStyle || style.gradient) ctx.fill();
+ if (style.strokeStyle) ctx.stroke();
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.canvas.Triangle, [ jsPlumb.Endpoints.Triangle, CanvasEndpoint ]);
+
+ /*
+ * Canvas Image Endpoint: uses the default version, which creates an <img> tag.
+ */
+ jsPlumb.Endpoints.canvas.Image = jsPlumb.Endpoints.Image;
+
+ /*
+ * Blank endpoint in all renderers is just the default Blank endpoint.
+ */
+ jsPlumb.Endpoints.canvas.Blank = jsPlumb.Endpoints.Blank;
+
+ /*
+ * Canvas Bezier Connector. Draws a Bezier curve onto a Canvas element.
+ *
+ jsPlumb.Connectors.canvas.Bezier = function() {
+ jsPlumb.Connectors.Bezier.apply(this, arguments);
+ CanvasConnector.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.canvas.Bezier, [ jsPlumb.Connectors.Bezier, CanvasConnector ]);
+
+ /*
+ * Canvas straight line Connector. Draws a straight line onto a Canvas element.
+ *
+ jsPlumb.Connectors.canvas.Straight = function() {
+ jsPlumb.Connectors.Straight.apply(this, arguments);
+ CanvasConnector.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.canvas.Straight, [ jsPlumb.Connectors.Straight, CanvasConnector ]);
+
+ jsPlumb.Connectors.canvas.Flowchart = function() {
+ jsPlumb.Connectors.Flowchart.apply(this, arguments);
+ CanvasConnector.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(jsPlumb.Connectors.canvas.Flowchart, [ jsPlumb.Connectors.Flowchart, CanvasConnector ]);
+
+ */
+// ********************************* END OF CANVAS RENDERERS *******************************************************************
+
+ jsPlumb.Overlays.canvas.Label = jsPlumb.Overlays.Label;
+ jsPlumb.Overlays.canvas.Custom = jsPlumb.Overlays.Custom;
+
+ /**
+ * a placeholder right now, really just exists to mirror the fact that there are SVG and VML versions of this.
+ */
+ var CanvasOverlay = function() {
+ jsPlumb.jsPlumbUIComponent.apply(this, arguments);
+ };
+ jsPlumbUtil.extend(CanvasOverlay, jsPlumb.jsPlumbUIComponent);
+
+ var AbstractCanvasArrowOverlay = function(superclass, originalArgs) {
+ superclass.apply(this, originalArgs);
+ CanvasOverlay.apply(this, originalArgs);
+ this.paint = function(params, containerExtents) {
+ var ctx = params.component.ctx, d = params.d;
+
+ if (d) {
+ ctx.save();
+ ctx.lineWidth = params.lineWidth;
+ ctx.beginPath();
+ ctx.translate(params.component.translateX, params.component.translateY);
+ ctx.moveTo(d.hxy.x, d.hxy.y);
+ ctx.lineTo(d.tail[0].x, d.tail[0].y);
+ ctx.lineTo(d.cxy.x, d.cxy.y);
+ ctx.lineTo(d.tail[1].x, d.tail[1].y);
+ ctx.lineTo(d.hxy.x, d.hxy.y);
+ ctx.closePath();
+
+ if (params.strokeStyle) {
+ ctx.strokeStyle = params.strokeStyle;
+ ctx.stroke();
+ }
+ if (params.fillStyle) {
+ ctx.fillStyle = params.fillStyle;
+ ctx.fill();
+ }
+ ctx.restore();
+ }
+ };
+ };
+
+ jsPlumb.Overlays.canvas.Arrow = function() {
+ AbstractCanvasArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.canvas.Arrow, [ jsPlumb.Overlays.Arrow, CanvasOverlay ] );
+
+ jsPlumb.Overlays.canvas.PlainArrow = function() {
+ AbstractCanvasArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.canvas.PlainArrow, [ jsPlumb.Overlays.PlainArrow, CanvasOverlay ] );
+
+ jsPlumb.Overlays.canvas.Diamond = function() {
+ AbstractCanvasArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.canvas.Diamond, [ jsPlumb.Overlays.Diamond, CanvasOverlay ] );
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the SVG renderers.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+/**
+ * SVG support for jsPlumb.
+ *
+ * things to investigate:
+ *
+ * gradients: https://developer.mozilla.org/en/svg_in_html_introduction
+ * css:http://tutorials.jenkov.com/svg/svg-and-css.html
+ * text on a path: http://www.w3.org/TR/SVG/text.html#TextOnAPath
+ * pointer events: https://developer.mozilla.org/en/css/pointer-events
+ *
+ * IE9 hover jquery: http://forum.jquery.com/topic/1-6-2-broke-svg-hover-events
+ *
+ */
+;(function() {
+
+// ************************** SVG utility methods ********************************************
+
+ var svgAttributeMap = {
+ "joinstyle":"stroke-linejoin",
+ "stroke-linejoin":"stroke-linejoin",
+ "stroke-dashoffset":"stroke-dashoffset",
+ "stroke-linecap":"stroke-linecap"
+ },
+ STROKE_DASHARRAY = "stroke-dasharray",
+ DASHSTYLE = "dashstyle",
+ LINEAR_GRADIENT = "linearGradient",
+ RADIAL_GRADIENT = "radialGradient",
+ FILL = "fill",
+ STOP = "stop",
+ STROKE = "stroke",
+ STROKE_WIDTH = "stroke-width",
+ STYLE = "style",
+ NONE = "none",
+ JSPLUMB_GRADIENT = "jsplumb_gradient_",
+ LINE_WIDTH = "lineWidth",
+ ns = {
+ svg:"http://www.w3.org/2000/svg",
+ xhtml:"http://www.w3.org/1999/xhtml"
+ },
+ _attr = function(node, attributes) {
+ for (var i in attributes)
+ node.setAttribute(i, "" + attributes[i]);
+ },
+ _node = function(name, attributes) {
+ var n = document.createElementNS(ns.svg, name);
+ attributes = attributes || {};
+ attributes.version = "1.1";
+ attributes.xmlns = ns.xhtml;
+ _attr(n, attributes);
+ return n;
+ },
+ _pos = function(d) { return "position:absolute;left:" + d[0] + "px;top:" + d[1] + "px"; },
+ _clearGradient = function(parent) {
+ for (var i = 0; i < parent.childNodes.length; i++) {
+ if (parent.childNodes[i].tagName == LINEAR_GRADIENT || parent.childNodes[i].tagName == RADIAL_GRADIENT)
+ parent.removeChild(parent.childNodes[i]);
+ }
+ },
+ _updateGradient = function(parent, node, style, dimensions, uiComponent) {
+ var id = JSPLUMB_GRADIENT + uiComponent._jsPlumb.instance.idstamp();
+ // first clear out any existing gradient
+ _clearGradient(parent);
+ // this checks for an 'offset' property in the gradient, and in the absence of it, assumes
+ // we want a linear gradient. if it's there, we create a radial gradient.
+ // it is possible that a more explicit means of defining the gradient type would be
+ // better. relying on 'offset' means that we can never have a radial gradient that uses
+ // some default offset, for instance.
+ // issue 244 suggested the 'gradientUnits' attribute; without this, straight/flowchart connectors with gradients would
+ // not show gradients when the line was perfectly horizontal or vertical.
+ var g;
+ if (!style.gradient.offset) {
+ g = _node(LINEAR_GRADIENT, {id:id, gradientUnits:"userSpaceOnUse"});
+ }
+ else {
+ g = _node(RADIAL_GRADIENT, {
+ id:id
+ });
+ }
+
+ parent.appendChild(g);
+
+ // the svg radial gradient seems to treat stops in the reverse
+ // order to how canvas does it. so we want to keep all the maths the same, but
+ // iterate the actual style declarations in reverse order, if the x indexes are not in order.
+ for (var i = 0; i < style.gradient.stops.length; i++) {
+ var styleToUse = uiComponent.segment == 1 || uiComponent.segment == 2 ? i: style.gradient.stops.length - 1 - i,
+ stopColor = jsPlumbUtil.convertStyle(style.gradient.stops[styleToUse][1], true),
+ s = _node(STOP, {"offset":Math.floor(style.gradient.stops[i][0] * 100) + "%", "stop-color":stopColor});
+
+ g.appendChild(s);
+ }
+ var applyGradientTo = style.strokeStyle ? STROKE : FILL;
+ node.setAttribute(STYLE, applyGradientTo + ":url(#" + id + ")");
+ },
+ _applyStyles = function(parent, node, style, dimensions, uiComponent) {
+
+ if (style.gradient) {
+ _updateGradient(parent, node, style, dimensions, uiComponent);
+ }
+ else {
+ // make sure we clear any existing gradient
+ _clearGradient(parent);
+ node.setAttribute(STYLE, "");
+ }
+
+ node.setAttribute(FILL, style.fillStyle ? jsPlumbUtil.convertStyle(style.fillStyle, true) : NONE);
+ node.setAttribute(STROKE, style.strokeStyle ? jsPlumbUtil.convertStyle(style.strokeStyle, true) : NONE);
+ if (style.lineWidth) {
+ node.setAttribute(STROKE_WIDTH, style.lineWidth);
+ }
+
+ // in SVG there is a stroke-dasharray attribute we can set, and its syntax looks like
+ // the syntax in VML but is actually kind of nasty: values are given in the pixel
+ // coordinate space, whereas in VML they are multiples of the width of the stroked
+ // line, which makes a lot more sense. for that reason, jsPlumb is supporting both
+ // the native svg 'stroke-dasharray' attribute, and also the 'dashstyle' concept from
+ // VML, which will be the preferred method. the code below this converts a dashstyle
+ // attribute given in terms of stroke width into a pixel representation, by using the
+ // stroke's lineWidth.
+ if (style[DASHSTYLE] && style[LINE_WIDTH] && !style[STROKE_DASHARRAY]) {
+ var sep = style[DASHSTYLE].indexOf(",") == -1 ? " " : ",",
+ parts = style[DASHSTYLE].split(sep),
+ styleToUse = "";
+ parts.forEach(function(p) {
+ styleToUse += (Math.floor(p * style.lineWidth) + sep);
+ });
+ node.setAttribute(STROKE_DASHARRAY, styleToUse);
+ }
+ else if(style[STROKE_DASHARRAY]) {
+ node.setAttribute(STROKE_DASHARRAY, style[STROKE_DASHARRAY]);
+ }
+
+ // extra attributes such as join type, dash offset.
+ for (var i in svgAttributeMap) {
+ if (style[i]) {
+ node.setAttribute(svgAttributeMap[i], style[i]);
+ }
+ }
+ },
+ _decodeFont = function(f) {
+ var r = /([0-9].)(p[xt])\s(.*)/,
+ bits = f.match(r);
+
+ return {size:bits[1] + bits[2], font:bits[3]};
+ },
+ _classManip = function(el, add, clazz) {
+ var classesToAddOrRemove = clazz.split(" "),
+ className = el.className,
+ curClasses = className.baseVal.split(" ");
+
+ for (var i = 0; i < classesToAddOrRemove.length; i++) {
+ if (add) {
+ if (curClasses.indexOf(classesToAddOrRemove[i]) == -1)
+ curClasses.push(classesToAddOrRemove[i]);
+ }
+ else {
+ var idx = curClasses.indexOf(classesToAddOrRemove[i]);
+ if (idx != -1)
+ curClasses.splice(idx, 1);
+ }
+ }
+
+ el.className.baseVal = curClasses.join(" ");
+ },
+ _addClass = function(el, clazz) { _classManip(el, true, clazz); },
+ _removeClass = function(el, clazz) { _classManip(el, false, clazz); },
+ _appendAtIndex = function(svg, path, idx) {
+ if (svg.childNodes.length > idx) {
+ svg.insertBefore(path, svg.childNodes[idx]);
+ }
+ else svg.appendChild(path);
+ };
+
+ /**
+ utility methods for other objects to use.
+ */
+ jsPlumbUtil.svg = {
+ addClass:_addClass,
+ removeClass:_removeClass,
+ node:_node,
+ attr:_attr,
+ pos:_pos
+ };
+
+ // ************************** / SVG utility methods ********************************************
+
+ /*
+ * Base class for SVG components.
+ */
+ var SvgComponent = function(params) {
+ var pointerEventsSpec = params.pointerEventsSpec || "all", renderer = {};
+
+ jsPlumb.jsPlumbUIComponent.apply(this, params.originalArgs);
+ this.canvas = null;this.path = null;this.svg = null;
+
+ var clazz = params.cssClass + " " + (params.originalArgs[0].cssClass || ""),
+ svgParams = {
+ "style":"",
+ "width":0,
+ "height":0,
+ "pointer-events":pointerEventsSpec,
+ "position":"absolute"
+ };
+ this.svg = _node("svg", svgParams);
+ if (params.useDivWrapper) {
+ this.canvas = document.createElement("div");
+ this.canvas.style.position = "absolute";
+ jsPlumbUtil.sizeElement(this.canvas,0,0,1,1);
+ this.canvas.className = clazz;
+ }
+ else {
+ _attr(this.svg, { "class":clazz });
+ this.canvas = this.svg;
+ }
+
+ params._jsPlumb.appendElement(this.canvas, params.originalArgs[0].parent);
+ if (params.useDivWrapper) this.canvas.appendChild(this.svg);
+
+ // TODO this displayElement stuff is common between all components, across all
+ // renderers. would be best moved to jsPlumbUIComponent.
+ var displayElements = [ this.canvas ];
+ this.getDisplayElements = function() {
+ return displayElements;
+ };
+
+ this.appendDisplayElement = function(el) {
+ displayElements.push(el);
+ };
+
+ this.paint = function(style, anchor, extents) {
+ if (style != null) {
+
+ var xy = [ this.x, this.y ], wh = [ this.w, this.h ], p;
+ if (extents != null) {
+ if (extents.xmin < 0) xy[0] += extents.xmin;
+ if (extents.ymin < 0) xy[1] += extents.ymin;
+ wh[0] = extents.xmax + ((extents.xmin < 0) ? -extents.xmin : 0);
+ wh[1] = extents.ymax + ((extents.ymin < 0) ? -extents.ymin : 0);
+ }
+
+ if (params.useDivWrapper) {
+ jsPlumbUtil.sizeElement(this.canvas, xy[0], xy[1], wh[0], wh[1]);
+ xy[0] = 0; xy[1] = 0;
+ p = _pos([ 0, 0 ]);
+ }
+ else
+ p = _pos([ xy[0], xy[1] ]);
+
+ renderer.paint.apply(this, arguments);
+
+ _attr(this.svg, {
+ "style":p,
+ "width": wh[0],
+ "height": wh[1]
+ });
+ }
+ };
+
+ return {
+ renderer:renderer
+ };
+ };
+ jsPlumbUtil.extend(SvgComponent, jsPlumb.jsPlumbUIComponent, {
+ cleanup:function() {
+ jsPlumbUtil.removeElement(this.canvas);
+ this.svg = null;
+ this.canvas = null;
+ this.path = null;
+ }
+ });
+
+ /*
+ * Base class for SVG connectors.
+ */
+ var SvgConnector = jsPlumb.ConnectorRenderers.svg = function(params) {
+ var self = this,
+ _super = SvgComponent.apply(this, [ {
+ cssClass:params._jsPlumb.connectorClass,
+ originalArgs:arguments,
+ pointerEventsSpec:"none",
+ _jsPlumb:params._jsPlumb
+ } ]);
+
+ /*this.pointOnPath = function(location, absolute) {
+ if (!self.path) return [0,0];
+ var p = absolute ? location : location * self.path.getTotalLength();
+ return self.path.getPointAtLength(p);
+ };*/
+
+ _super.renderer.paint = function(style, anchor, extents) {
+
+ var segments = self.getSegments(), p = "", offset = [0,0];
+ if (extents.xmin < 0) offset[0] = -extents.xmin;
+ if (extents.ymin < 0) offset[1] = -extents.ymin;
+
+ // create path from segments.
+ for (var i = 0; i < segments.length; i++) {
+ p += jsPlumb.Segments.svg.SegmentRenderer.getPath(segments[i]);
+ p += " ";
+ }
+
+ var a = {
+ d:p,
+ transform:"translate(" + offset[0] + "," + offset[1] + ")",
+ "pointer-events":params["pointer-events"] || "visibleStroke"
+ },
+ outlineStyle = null,
+ d = [self.x,self.y,self.w,self.h];
+
+ // outline style. actually means drawing an svg object underneath the main one.
+ if (style.outlineColor) {
+ var outlineWidth = style.outlineWidth || 1,
+ outlineStrokeWidth = style.lineWidth + (2 * outlineWidth);
+ outlineStyle = jsPlumb.CurrentLibrary.extend({}, style);
+ outlineStyle.strokeStyle = jsPlumbUtil.convertStyle(style.outlineColor);
+ outlineStyle.lineWidth = outlineStrokeWidth;
+
+ if (self.bgPath == null) {
+ self.bgPath = _node("path", a);
+ _appendAtIndex(self.svg, self.bgPath, 0);
+ self.attachListeners(self.bgPath, self);
+ }
+ else {
+ _attr(self.bgPath, a);
+ }
+
+ _applyStyles(self.svg, self.bgPath, outlineStyle, d, self);
+ }
+
+ if (self.path == null) {
+ self.path = _node("path", a);
+ _appendAtIndex(self.svg, self.path, style.outlineColor ? 1 : 0);
+ self.attachListeners(self.path, self);
+ }
+ else {
+ _attr(self.path, a);
+ }
+
+ _applyStyles(self.svg, self.path, style, d, self);
+ };
+
+ this.reattachListeners = function() {
+ if (this.bgPath) this.reattachListenersForElement(this.bgPath, this);
+ if (this.path) this.reattachListenersForElement(this.path, this);
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.ConnectorRenderers.svg, SvgComponent);
+
+// ******************************* svg segment renderer *****************************************************
+
+ jsPlumb.Segments.svg = {
+ SegmentRenderer : {
+ getPath : function(segment) {
+ return ({
+ "Straight":function() {
+ var d = segment.getCoordinates();
+ return "M " + d.x1 + " " + d.y1 + " L " + d.x2 + " " + d.y2;
+ },
+ "Bezier":function() {
+ var d = segment.params;
+ return "M " + d.x1 + " " + d.y1 +
+ " C " + d.cp1x + " " + d.cp1y + " " + d.cp2x + " " + d.cp2y + " " + d.x2 + " " + d.y2;
+ },
+ "Arc":function() {
+ var d = segment.params,
+ laf = segment.sweep > Math.PI ? 1 : 0,
+ sf = segment.anticlockwise ? 0 : 1;
+
+ return "M" + segment.x1 + " " + segment.y1 + " A " + segment.radius + " " + d.r + " 0 " + laf + "," + sf + " " + segment.x2 + " " + segment.y2;
+ }
+ })[segment.type]();
+ }
+ }
+ };
+
+// ******************************* /svg segments *****************************************************
+
+ /*
+ * Base class for SVG endpoints.
+ */
+ var SvgEndpoint = window.SvgEndpoint = function(params) {
+ var _super = SvgComponent.apply(this, [ {
+ cssClass:params._jsPlumb.endpointClass,
+ originalArgs:arguments,
+ pointerEventsSpec:"all",
+ useDivWrapper:true,
+ _jsPlumb:params._jsPlumb
+ } ]);
+
+ _super.renderer.paint = function(style) {
+ var s = jsPlumb.extend({}, style);
+ if (s.outlineColor) {
+ s.strokeWidth = s.outlineWidth;
+ s.strokeStyle = jsPlumbUtil.convertStyle(s.outlineColor, true);
+ }
+
+ if (this.node == null) {
+ this.node = this.makeNode(s);
+ this.svg.appendChild(this.node);
+ this.attachListeners(this.node, this);
+ }
+ else if (this.updateNode != null) {
+ this.updateNode(this.node);
+ }
+ _applyStyles(this.svg, this.node, s, [ this.x, this.y, this.w, this.h ], this);
+ _pos(this.node, [ this.x, this.y ]);
+ }.bind(this);
+
+ };
+ jsPlumbUtil.extend(SvgEndpoint, SvgComponent, {
+ reattachListeners : function() {
+ if (this.node) this.reattachListenersForElement(this.node, this);
+ }
+ });
+
+ /*
+ * SVG Dot Endpoint
+ */
+ jsPlumb.Endpoints.svg.Dot = function() {
+ jsPlumb.Endpoints.Dot.apply(this, arguments);
+ SvgEndpoint.apply(this, arguments);
+ this.makeNode = function(style) {
+ return _node("circle", {
+ "cx" : this.w / 2,
+ "cy" : this.h / 2,
+ "r" : this.radius
+ });
+ };
+ this.updateNode = function(node) {
+ _attr(node, {
+ "cx":this.w / 2,
+ "cy":this.h / 2,
+ "r":this.radius
+ });
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.svg.Dot, [jsPlumb.Endpoints.Dot, SvgEndpoint]);
+
+ /*
+ * SVG Rectangle Endpoint
+ */
+ jsPlumb.Endpoints.svg.Rectangle = function() {
+ jsPlumb.Endpoints.Rectangle.apply(this, arguments);
+ SvgEndpoint.apply(this, arguments);
+ this.makeNode = function(style) {
+ return _node("rect", {
+ "width" : this.w,
+ "height" : this.h
+ });
+ };
+ this.updateNode = function(node) {
+ _attr(node, {
+ "width":this.w,
+ "height":this.h
+ });
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.svg.Rectangle, [jsPlumb.Endpoints.Rectangle, SvgEndpoint]);
+
+ /*
+ * SVG Image Endpoint is the default image endpoint.
+ */
+ jsPlumb.Endpoints.svg.Image = jsPlumb.Endpoints.Image;
+ /*
+ * Blank endpoint in svg renderer is the default Blank endpoint.
+ */
+ jsPlumb.Endpoints.svg.Blank = jsPlumb.Endpoints.Blank;
+ /*
+ * Label overlay in svg renderer is the default Label overlay.
+ */
+ jsPlumb.Overlays.svg.Label = jsPlumb.Overlays.Label;
+ /*
+ * Custom overlay in svg renderer is the default Custom overlay.
+ */
+ jsPlumb.Overlays.svg.Custom = jsPlumb.Overlays.Custom;
+
+ var AbstractSvgArrowOverlay = function(superclass, originalArgs) {
+ superclass.apply(this, originalArgs);
+ jsPlumb.jsPlumbUIComponent.apply(this, originalArgs);
+ this.isAppendedAtTopLevel = false;
+ var self = this;
+ this.path = null;
+ this.paint = function(params, containerExtents) {
+ // only draws on connections, not endpoints.
+ if (params.component.svg && containerExtents) {
+ if (this.path == null) {
+ this.path = _node("path", {
+ "pointer-events":"all"
+ });
+ params.component.svg.appendChild(this.path);
+
+ this.attachListeners(this.path, params.component);
+ this.attachListeners(this.path, this);
+ }
+ var clazz = originalArgs && (originalArgs.length == 1) ? (originalArgs[0].cssClass || "") : "",
+ offset = [0,0];
+
+ if (containerExtents.xmin < 0) offset[0] = -containerExtents.xmin;
+ if (containerExtents.ymin < 0) offset[1] = -containerExtents.ymin;
+
+ _attr(this.path, {
+ "d" : makePath(params.d),
+ "class" : clazz,
+ stroke : params.strokeStyle ? params.strokeStyle : null,
+ fill : params.fillStyle ? params.fillStyle : null,
+ transform : "translate(" + offset[0] + "," + offset[1] + ")"
+ });
+ }
+ };
+ var makePath = function(d) {
+ return "M" + d.hxy.x + "," + d.hxy.y +
+ " L" + d.tail[0].x + "," + d.tail[0].y +
+ " L" + d.cxy.x + "," + d.cxy.y +
+ " L" + d.tail[1].x + "," + d.tail[1].y +
+ " L" + d.hxy.x + "," + d.hxy.y;
+ };
+ this.reattachListeners = function() {
+ if (this.path) this.reattachListenersForElement(this.path, this);
+ };
+ };
+ jsPlumbUtil.extend(AbstractSvgArrowOverlay, jsPlumb.jsPlumbUIComponent, {
+ cleanup : function() {
+ if (this.path != null) jsPlumb.CurrentLibrary.removeElement(this.path);
+ }
+ });
+
+ jsPlumb.Overlays.svg.Arrow = function() {
+ AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.svg.Arrow, [ jsPlumb.Overlays.Arrow, AbstractSvgArrowOverlay ]);
+
+ jsPlumb.Overlays.svg.PlainArrow = function() {
+ AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.svg.PlainArrow, [ jsPlumb.Overlays.PlainArrow, AbstractSvgArrowOverlay ]);
+
+ jsPlumb.Overlays.svg.Diamond = function() {
+ AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.svg.Diamond, [ jsPlumb.Overlays.Diamond, AbstractSvgArrowOverlay ]);
+
+ // a test
+ jsPlumb.Overlays.svg.GuideLines = function() {
+ var path = null, self = this, p1_1, p1_2;
+ jsPlumb.Overlays.GuideLines.apply(this, arguments);
+ this.paint = function(params, containerExtents) {
+ if (path == null) {
+ path = _node("path");
+ params.connector.svg.appendChild(path);
+ self.attachListeners(path, params.connector);
+ self.attachListeners(path, self);
+
+ p1_1 = _node("path");
+ params.connector.svg.appendChild(p1_1);
+ self.attachListeners(p1_1, params.connector);
+ self.attachListeners(p1_1, self);
+
+ p1_2 = _node("path");
+ params.connector.svg.appendChild(p1_2);
+ self.attachListeners(p1_2, params.connector);
+ self.attachListeners(p1_2, self);
+ }
+
+ var offset =[0,0];
+ if (containerExtents.xmin < 0) offset[0] = -containerExtents.xmin;
+ if (containerExtents.ymin < 0) offset[1] = -containerExtents.ymin;
+
+ _attr(path, {
+ "d" : makePath(params.head, params.tail),
+ stroke : "red",
+ fill : null,
+ transform:"translate(" + offset[0] + "," + offset[1] + ")"
+ });
+
+ _attr(p1_1, {
+ "d" : makePath(params.tailLine[0], params.tailLine[1]),
+ stroke : "blue",
+ fill : null,
+ transform:"translate(" + offset[0] + "," + offset[1] + ")"
+ });
+
+ _attr(p1_2, {
+ "d" : makePath(params.headLine[0], params.headLine[1]),
+ stroke : "green",
+ fill : null,
+ transform:"translate(" + offset[0] + "," + offset[1] + ")"
+ });
+ };
+
+ var makePath = function(d1, d2) {
+ return "M " + d1.x + "," + d1.y +
+ " L" + d2.x + "," + d2.y;
+ };
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.svg.GuideLines, jsPlumb.Overlays.GuideLines);
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the VML renderers.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+;(function() {
+
+ // http://ajaxian.com/archives/the-vml-changes-in-ie-8
+ // http://www.nczonline.net/blog/2010/01/19/internet-explorer-8-document-and-b…
+ // http://www.louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-…
+
+ var vmlAttributeMap = {
+ "stroke-linejoin":"joinstyle",
+ "joinstyle":"joinstyle",
+ "endcap":"endcap",
+ "miterlimit":"miterlimit"
+ },
+ jsPlumbStylesheet = null;
+
+ if (document.createStyleSheet && document.namespaces) {
+
+ var ruleClasses = [
+ ".jsplumb_vml", "jsplumb\\:textbox", "jsplumb\\:oval", "jsplumb\\:rect",
+ "jsplumb\\:stroke", "jsplumb\\:shape", "jsplumb\\:group"
+ ],
+ rule = "behavior:url(#default#VML);position:absolute;";
+
+ jsPlumbStylesheet = document.createStyleSheet();
+
+ for (var i = 0; i < ruleClasses.length; i++)
+ jsPlumbStylesheet.addRule(ruleClasses[i], rule);
+
+ // in this page it is also mentioned that IE requires the extra arg to the namespace
+ // http://www.louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-…
+ // but someone commented saying they didn't need it, and it seems jsPlumb doesnt need it either.
+ // var iev = document.documentMode;
+ //if (!iev || iev < 8)
+ document.namespaces.add("jsplumb", "urn:schemas-microsoft-com:vml");
+ //else
+ // document.namespaces.add("jsplumb", "urn:schemas-microsoft-com:vml", "#default#VML");
+ }
+
+ jsPlumb.vml = {};
+
+ var scale = 1000,
+
+ _groupMap = {},
+ _getGroup = function(container, connectorClass) {
+ var id = jsPlumb.getId(container),
+ g = _groupMap[id];
+ if(!g) {
+ g = _node("group", [0,0,scale, scale], {"class":connectorClass});
+ //g.style.position=absolute;
+ //g["coordsize"] = "1000,1000";
+ g.style.backgroundColor="red";
+ _groupMap[id] = g;
+ //jsPlumb.appendElement(g, container); // todo if this gets reinstated, remember to use the current jsplumb instance.
+ //jsPlumb.CurrentLibrary.getDOMElement(container).appendChild(g);
+ //document.body.appendChild(g);
+ }
+ return g;
+ },
+ _atts = function(o, atts) {
+ for (var i in atts) {
+ // IE8 fix: setattribute does not work after an element has been added to the dom!
+ // http://www.louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-…
+ //o.setAttribute(i, atts[i]);
+
+ /*There is an additional problem when accessing VML elements by using get/setAttribute. The simple solution is following:
+
+ if (document.documentMode==8) {
+ ele.opacity=1;
+ } else {
+ ele.setAttribute(‘opacity’,1);
+ }
+ */
+
+ o[i] = atts[i];
+ }
+ },
+ _node = function(name, d, atts, parent, _jsPlumb, deferToJsPlumbContainer) {
+ atts = atts || {};
+ var o = document.createElement("jsplumb:" + name);
+ if (deferToJsPlumbContainer)
+ _jsPlumb.appendElement(o, parent);
+ else
+ jsPlumb.CurrentLibrary.appendElement(o, parent);
+ o.className = (atts["class"] ? atts["class"] + " " : "") + "jsplumb_vml";
+ _pos(o, d);
+ _atts(o, atts);
+ return o;
+ },
+ _pos = function(o,d, zIndex) {
+ o.style.left = d[0] + "px";
+ o.style.top = d[1] + "px";
+ o.style.width= d[2] + "px";
+ o.style.height= d[3] + "px";
+ o.style.position = "absolute";
+ if (zIndex)
+ o.style.zIndex = zIndex;
+ },
+ _conv = jsPlumb.vml.convertValue = function(v) {
+ return Math.floor(v * scale);
+ },
+ // tests if the given style is "transparent" and then sets the appropriate opacity node to 0 if so,
+ // or 1 if not. TODO in the future, support variable opacity.
+ _maybeSetOpacity = function(styleToWrite, styleToCheck, type, component) {
+ if ("transparent" === styleToCheck)
+ component.setOpacity(type, "0.0");
+ else
+ component.setOpacity(type, "1.0");
+ },
+ _applyStyles = function(node, style, component, _jsPlumb) {
+ var styleToWrite = {};
+ if (style.strokeStyle) {
+ styleToWrite.stroked = "true";
+ var strokeColor = jsPlumbUtil.convertStyle(style.strokeStyle, true);
+ styleToWrite.strokecolor = strokeColor;
+ _maybeSetOpacity(styleToWrite, strokeColor, "stroke", component);
+ styleToWrite.strokeweight = style.lineWidth + "px";
+ }
+ else styleToWrite.stroked = "false";
+
+ if (style.fillStyle) {
+ styleToWrite.filled = "true";
+ var fillColor = jsPlumbUtil.convertStyle(style.fillStyle, true);
+ styleToWrite.fillcolor = fillColor;
+ _maybeSetOpacity(styleToWrite, fillColor, "fill", component);
+ }
+ else styleToWrite.filled = "false";
+
+ if(style.dashstyle) {
+ if (component.strokeNode == null) {
+ component.strokeNode = _node("stroke", [0,0,0,0], { dashstyle:style.dashstyle }, node, _jsPlumb);
+ }
+ else
+ component.strokeNode.dashstyle = style.dashstyle;
+ }
+ else if (style["stroke-dasharray"] && style.lineWidth) {
+ var sep = style["stroke-dasharray"].indexOf(",") == -1 ? " " : ",",
+ parts = style["stroke-dasharray"].split(sep),
+ styleToUse = "";
+ for(var i = 0; i < parts.length; i++) {
+ styleToUse += (Math.floor(parts[i] / style.lineWidth) + sep);
+ }
+ if (component.strokeNode == null) {
+ component.strokeNode = _node("stroke", [0,0,0,0], { dashstyle:styleToUse }, node, _jsPlumb);
+ }
+ else
+ component.strokeNode.dashstyle = styleToUse;
+ }
+
+ _atts(node, styleToWrite);
+ },
+ /*
+ * Base class for Vml endpoints and connectors. Extends jsPlumbUIComponent.
+ */
+ VmlComponent = function() {
+ var self = this, renderer = {};
+ jsPlumb.jsPlumbUIComponent.apply(this, arguments);
+
+ this.opacityNodes = {
+ "stroke":null,
+ "fill":null
+ };
+ this.initOpacityNodes = function(vml) {
+ self.opacityNodes.stroke = _node("stroke", [0,0,1,1], {opacity:"0.0"}, vml, self._jsPlumb.instance);
+ self.opacityNodes.fill = _node("fill", [0,0,1,1], {opacity:"0.0"}, vml, self._jsPlumb.instance);
+ };
+ this.setOpacity = function(type, value) {
+ var node = self.opacityNodes[type];
+ if (node) node.opacity = "" + value;
+ };
+ var displayElements = [ ];
+ this.getDisplayElements = function() {
+ return displayElements;
+ };
+
+ this.appendDisplayElement = function(el, doNotAppendToCanvas) {
+ if (!doNotAppendToCanvas) self.canvas.parentNode.appendChild(el);
+ displayElements.push(el);
+ };
+ };
+ jsPlumbUtil.extend(VmlComponent, jsPlumb.jsPlumbUIComponent, {
+ cleanup:function() {
+ if (this.bgCanvas) jsPlumbUtil.removeElement(this.bgCanvas);
+ jsPlumbUtil.removeElement(this.canvas);
+ }
+ });
+
+ /*
+ * Base class for Vml connectors. extends VmlComponent.
+ */
+ var VmlConnector = jsPlumb.ConnectorRenderers.vml = function(params) {
+ this.strokeNode = null;
+ this.canvas = null;
+ VmlComponent.apply(this, arguments);
+ var clazz = this._jsPlumb.instance.connectorClass + (params.cssClass ? (" " + params.cssClass) : "");
+ this.paint = function(style) {
+ if (style !== null) {
+
+ // we need to be at least 1 pixel in each direction, because otherwise coordsize gets set to
+ // 0 and overlays cannot paint.
+ this.w = Math.max(this.w, 1);
+ this.h = Math.max(this.h, 1);
+
+ var segments = this.getSegments(), p = { "path":"" },
+ d = [this.x, this.y, this.w, this.h];
+
+ // create path from segments.
+ for (var i = 0; i < segments.length; i++) {
+ p.path += jsPlumb.Segments.vml.SegmentRenderer.getPath(segments[i]);
+ p.path += " ";
+ }
+
+ //*
+ if (style.outlineColor) {
+ var outlineWidth = style.outlineWidth || 1,
+ outlineStrokeWidth = style.lineWidth + (2 * outlineWidth),
+ outlineStyle = {
+ strokeStyle : jsPlumbUtil.convertStyle(style.outlineColor),
+ lineWidth : outlineStrokeWidth
+ };
+ for (var aa in vmlAttributeMap) outlineStyle[aa] = style[aa];
+
+ if (this.bgCanvas == null) {
+ p["class"] = clazz;
+ p.coordsize = (d[2] * scale) + "," + (d[3] * scale);
+ this.bgCanvas = _node("shape", d, p, params.parent, this._jsPlumb.instance, true);
+ _pos(this.bgCanvas, d);
+ this.appendDisplayElement(this.bgCanvas, true);
+ this.attachListeners(this.bgCanvas, this);
+ this.initOpacityNodes(this.bgCanvas, ["stroke"]);
+ }
+ else {
+ p.coordsize = (d[2] * scale) + "," + (d[3] * scale);
+ _pos(this.bgCanvas, d);
+ _atts(this.bgCanvas, p);
+ }
+
+ _applyStyles(this.bgCanvas, outlineStyle, this);
+ }
+ //*/
+
+ if (this.canvas == null) {
+ p["class"] = clazz;
+ p.coordsize = (d[2] * scale) + "," + (d[3] * scale);
+ this.canvas = _node("shape", d, p, params.parent, this._jsPlumb.instance, true);
+ //var group = _getGroup(params.parent); // test of append everything to a group
+ //group.appendChild(self.canvas); // sort of works but not exactly;
+ //params["_jsPlumb"].appendElement(self.canvas, params.parent); //before introduction of groups
+
+ this.appendDisplayElement(this.canvas, true);
+ this.attachListeners(this.canvas, this);
+ this.initOpacityNodes(this.canvas, ["stroke"]);
+ }
+ else {
+ p.coordsize = (d[2] * scale) + "," + (d[3] * scale);
+ _pos(this.canvas, d);
+ _atts(this.canvas, p);
+ }
+
+ _applyStyles(this.canvas, style, this, this._jsPlumb.instance);
+ }
+ };
+
+ };
+ jsPlumbUtil.extend(VmlConnector, VmlComponent, {
+ reattachListeners : function() {
+ if (this.canvas) this.reattachListenersForElement(this.canvas, this);
+ }
+ });
+
+ /*
+ *
+ * Base class for Vml Endpoints. extends VmlComponent.
+ *
+ */
+ var VmlEndpoint = window.VmlEndpoint = function(params) {
+ VmlComponent.apply(this, arguments);
+ this._jsPlumb.vml = null;//, opacityStrokeNode = null, opacityFillNode = null;
+ this.canvas = document.createElement("div");
+ this.canvas.style.position = "absolute";
+ this._jsPlumb.clazz = this._jsPlumb.instance.endpointClass + (params.cssClass ? (" " + params.cssClass) : "");
+
+ // TODO vml endpoint adds class to VML at constructor time. but the addClass method adds VML
+ // to the enclosing DIV. what to do? seems like it would be better to just target the div.
+ // HOWEVER...vml connection has no containing div. why not? it feels like it should.
+
+ //var group = _getGroup(params.parent);
+ //group.appendChild(self.canvas);
+ params._jsPlumb.appendElement(this.canvas, params.parent);
+
+ this.paint = function(style, anchor) {
+ var p = { }, vml = this._jsPlumb.vml;
+
+ jsPlumbUtil.sizeElement(this.canvas, this.x, this.y, this.w, this.h);
+ if (this._jsPlumb.vml == null) {
+ p["class"] = this._jsPlumb.clazz;
+ vml = this._jsPlumb.vml = this.getVml([0,0, this.w, this.h], p, anchor, this.canvas, this._jsPlumb.instance);
+ this.attachListeners(vml, this);
+
+ this.appendDisplayElement(vml, true);
+ this.appendDisplayElement(this.canvas, true);
+
+ this.initOpacityNodes(vml, ["fill"]);
+ }
+ else {
+ _pos(vml, [0,0, this.w, this.h]);
+ _atts(vml, p);
+ }
+
+ _applyStyles(vml, style, this);
+ };
+ };
+ jsPlumbUtil.extend(VmlEndpoint, VmlComponent, {
+ reattachListeners : function() {
+ if (this._jsPlumb.vml) this.reattachListenersForElement(this._jsPlumb.vml, this);
+ }
+ });
+
+// ******************************* vml segments *****************************************************
+
+ jsPlumb.Segments.vml = {
+ SegmentRenderer : {
+ getPath : function(segment) {
+ return ({
+ "Straight":function(segment) {
+ var d = segment.params;
+ return "m" + _conv(d.x1) + "," + _conv(d.y1) + " l" + _conv(d.x2) + "," + _conv(d.y2) + " e";
+ },
+ "Bezier":function(segment) {
+ var d = segment.params;
+ return "m" + _conv(d.x1) + "," + _conv(d.y1) +
+ " c" + _conv(d.cp1x) + "," + _conv(d.cp1y) + "," + _conv(d.cp2x) + "," + _conv(d.cp2y) + "," + _conv(d.x2) + "," + _conv(d.y2) + " e";
+ },
+ "Arc":function(segment) {
+ var d = segment.params,
+ xmin = Math.min(d.x1, d.x2),
+ xmax = Math.max(d.x1, d.x2),
+ ymin = Math.min(d.y1, d.y2),
+ ymax = Math.max(d.y1, d.y2),
+ sf = segment.anticlockwise ? 1 : 0,
+ pathType = (segment.anticlockwise ? "at " : "wa "),
+ makePosString = function() {
+ var xy = [
+ null,
+ [ function() { return [xmin, ymin ];}, function() { return [xmin - d.r, ymin - d.r ];}],
+ [ function() { return [xmin - d.r, ymin ];}, function() { return [xmin, ymin - d.r ];}],
+ [ function() { return [xmin - d.r, ymin - d.r ];}, function() { return [xmin, ymin ];}],
+ [ function() { return [xmin, ymin - d.r ];}, function() { return [xmin - d.r, ymin ];}]
+ ][segment.segment][sf]();
+
+ return _conv(xy[0]) + "," + _conv(xy[1]) + "," + _conv(xy[0] + (2*d.r)) + "," + _conv(xy[1] + (2*d.r));
+ };
+
+
+ return pathType + makePosString() + "," + _conv(d.x1) + "," + _conv(d.y1) + "," + _conv(d.x2) + "," + _conv(d.y2) + " e";
+ }
+
+ })[segment.type](segment);
+ }
+ }
+ };
+
+// ******************************* /vml segments *****************************************************
+
+// ******************************* vml endpoints *****************************************************
+
+ jsPlumb.Endpoints.vml.Dot = function() {
+ jsPlumb.Endpoints.Dot.apply(this, arguments);
+ VmlEndpoint.apply(this, arguments);
+ this.getVml = function(d, atts, anchor, parent, _jsPlumb) { return _node("oval", d, atts, parent, _jsPlumb); };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.vml.Dot, VmlEndpoint);
+
+ jsPlumb.Endpoints.vml.Rectangle = function() {
+ jsPlumb.Endpoints.Rectangle.apply(this, arguments);
+ VmlEndpoint.apply(this, arguments);
+ this.getVml = function(d, atts, anchor, parent, _jsPlumb) { return _node("rect", d, atts, parent, _jsPlumb); };
+ };
+ jsPlumbUtil.extend(jsPlumb.Endpoints.vml.Rectangle, VmlEndpoint);
+
+ /*
+ * VML Image Endpoint is the same as the default image endpoint.
+ */
+ jsPlumb.Endpoints.vml.Image = jsPlumb.Endpoints.Image;
+
+ /**
+ * placeholder for Blank endpoint in vml renderer.
+ */
+ jsPlumb.Endpoints.vml.Blank = jsPlumb.Endpoints.Blank;
+
+// ******************************* /vml endpoints *****************************************************
+
+// ******************************* vml overlays *****************************************************
+
+ /**
+ * VML Label renderer. uses the default label renderer (which adds an element to the DOM)
+ */
+ jsPlumb.Overlays.vml.Label = jsPlumb.Overlays.Label;
+
+ /**
+ * VML Custom renderer. uses the default Custom renderer (which adds an element to the DOM)
+ */
+ jsPlumb.Overlays.vml.Custom = jsPlumb.Overlays.Custom;
+
+ /**
+ * Abstract VML arrow superclass
+ */
+ var AbstractVmlArrowOverlay = function(superclass, originalArgs) {
+ superclass.apply(this, originalArgs);
+ VmlComponent.apply(this, originalArgs);
+ var self = this, path = null;
+ self.canvas = null;
+ self.isAppendedAtTopLevel = true;
+ var getPath = function(d) {
+ return "m " + _conv(d.hxy.x) + "," + _conv(d.hxy.y) +
+ " l " + _conv(d.tail[0].x) + "," + _conv(d.tail[0].y) +
+ " " + _conv(d.cxy.x) + "," + _conv(d.cxy.y) +
+ " " + _conv(d.tail[1].x) + "," + _conv(d.tail[1].y) +
+ " x e";
+ };
+ this.paint = function(params, containerExtents) {
+ var p = {}, d = params.d, connector = params.component;
+ if (params.strokeStyle) {
+ p.stroked = "true";
+ p.strokecolor = jsPlumbUtil.convertStyle(params.strokeStyle, true);
+ }
+ if (params.lineWidth) p.strokeweight = params.lineWidth + "px";
+ if (params.fillStyle) {
+ p.filled = "true";
+ p.fillcolor = params.fillStyle;
+ }
+
+ var xmin = Math.min(d.hxy.x, d.tail[0].x, d.tail[1].x, d.cxy.x),
+ ymin = Math.min(d.hxy.y, d.tail[0].y, d.tail[1].y, d.cxy.y),
+ xmax = Math.max(d.hxy.x, d.tail[0].x, d.tail[1].x, d.cxy.x),
+ ymax = Math.max(d.hxy.y, d.tail[0].y, d.tail[1].y, d.cxy.y),
+ w = Math.abs(xmax - xmin),
+ h = Math.abs(ymax - ymin),
+ dim = [xmin, ymin, w, h];
+
+ // for VML, we create overlays using shapes that have the same dimensions and
+ // coordsize as their connector - overlays calculate themselves relative to the
+ // connector (it's how it's been done since the original canvas implementation, because
+ // for canvas that makes sense).
+ p.path = getPath(d);
+ p.coordsize = (connector.w * scale) + "," + (connector.h * scale);
+
+ dim[0] = connector.x;
+ dim[1] = connector.y;
+ dim[2] = connector.w;
+ dim[3] = connector.h;
+
+ if (self.canvas == null) {
+ var overlayClass = connector._jsPlumb.overlayClass || "";
+ var clazz = originalArgs && (originalArgs.length == 1) ? (originalArgs[0].cssClass || "") : "";
+ p["class"] = clazz + " " + overlayClass;
+ self.canvas = _node("shape", dim, p, connector.canvas.parentNode, connector._jsPlumb.instance, true);
+ connector.appendDisplayElement(self.canvas, true);
+ self.attachListeners(self.canvas, connector);
+ self.attachListeners(self.canvas, self);
+ }
+ else {
+ _pos(self.canvas, dim);
+ _atts(self.canvas, p);
+ }
+ };
+
+ this.reattachListeners = function() {
+ if (self.canvas) self.reattachListenersForElement(self.canvas, self);
+ };
+
+ this.cleanup = function() {
+ if (self.canvas != null) jsPlumb.CurrentLibrary.removeElement(self.canvas);
+ };
+ };
+ jsPlumbUtil.extend(AbstractVmlArrowOverlay, VmlComponent);
+
+ jsPlumb.Overlays.vml.Arrow = function() {
+ AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.vml.Arrow, [ jsPlumb.Overlays.Arrow, AbstractVmlArrowOverlay ]);
+
+ jsPlumb.Overlays.vml.PlainArrow = function() {
+ AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.vml.PlainArrow, [ jsPlumb.Overlays.PlainArrow, AbstractVmlArrowOverlay ]);
+
+ jsPlumb.Overlays.vml.Diamond = function() {
+ AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
+ };
+ jsPlumbUtil.extend(jsPlumb.Overlays.vml.Diamond, [ jsPlumb.Overlays.Diamond, AbstractVmlArrowOverlay ]);
+
+// ******************************* /vml overlays *****************************************************
+
+})();
+/*
+ * jsPlumb
+ *
+ * Title:jsPlumb 1.5.2
+ *
+ * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas
+ * elements, or VML.
+ *
+ * This file contains the YUI3 adapter.
+ *
+ * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org)
+ *
+ * http://jsplumb.org
+ * http://github.com/sporritt/jsplumb
+ * http://code.google.com/p/jsplumb
+ *
+ * Dual licensed under the MIT and GPL2 licenses.
+ */
+
+/**
+ * addClass adds a class to the given element
+ * animate calls the underlying library's animate functionality
+ * appendElement appends a child element to a parent element.
+ * bind binds some event to an element
+ * dragEvents a dictionary of event names
+ * extend extend some js object with another. probably not overly necessary; jsPlumb could just do this internally.
+ * getDragObject gets the object that is being dragged, by extracting it from the arguments passed to a drag callback
+ * getDragScope gets the drag scope for a given element.
+ * getElementObject turns an id or dom element into an element object of the underlying library's type.
+ * getOffset gets an element's offset
+ * getOriginalEvent gets the original browser event from some wrapper event.
+ * getScrollLeft gets an element's scroll left. TODO: is this actually used? will it be?
+ * getScrollTop gets an element's scroll top. TODO: is this actually used? will it be?
+ * getSize gets an element's size.
+ * getUIPosition gets the position of some element that is currently being dragged, by extracting it from the arguments passed to a drag callback.
+ * initDraggable initializes an element to be draggable
+ * initDroppable initializes an element to be droppable
+ * isDragSupported returns whether or not drag is supported for some element.
+ * isDropSupported returns whether or not drop is supported for some element.
+ * removeClass removes a class from a given element.
+ * removeElement removes some element completely from the DOM.
+ * setDraggable sets whether or not some element should be draggable.
+ * setDragScope sets the drag scope for a given element.
+ * setOffset sets the offset of some element.
+ */
+(function() {
+
+ if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function( v, b, s ) {
+ for( var i = +b || 0, l = this.length; i < l; i++ ) {
+ if( this[i]===v || s && this[i]==v ) { return i; }
+ }
+ return -1;
+ };
+ }
+
+ var Y;
+
+ YUI().use('node', 'dd', 'dd-constrain', 'anim', 'node-event-simulate', function(_Y) {
+ Y = _Y;
+ Y.on("domready", function() { jsPlumb.init(); });
+ });
+
+ /**
+ * adds the given value to the given list, with the given scope. creates the scoped list
+ * if necessary.
+ * used by initDraggable and initDroppable.
+ */
+ var _add = function(list, scope, value) {
+ var l = list[scope];
+ if (!l) {
+ l = [];
+ list[scope] = l;
+ }
+ l.push(value);
+ },
+ ddEvents = [ "drag:mouseDown", "drag:afterMouseDown", "drag:mouseup",
+ "drag:align", "drag:removeHandle", "drag:addHandle", "drag:removeInvalid", "drag:addInvalid",
+ "drag:start", "drag:end", "drag:drag", "drag:over", "drag:enter",
+ "drag:exit", "drag:drophit", "drag:dropmiss", "drop:over", "drop:enter", "drop:exit", "drop:hit"
+ ],
+ animEvents = [ "tween" ],
+ /**
+ * helper function to curry callbacks for some element.
+ */
+ _wrapper = function(fn) {
+ return function() {
+ try {
+ return fn.apply(this, arguments);
+ }
+ catch (e) { }
+ };
+ },
+ /**
+ * extracts options from the given options object, leaving out event handlers.
+ */
+ _getDDOptions = function(options) {
+ var o = {};
+ for (var i in options) if (ddEvents.indexOf(i) == -1) o[i] = options[i];
+ return o;
+ },
+ /**
+ * attaches all event handlers found in options to the given dragdrop object, and registering
+ * the given el as the element of interest.
+ */
+ _attachListeners = function(dd, options, eventList) {
+ for (var ev in options) {
+ if (eventList.indexOf(ev) != -1) {
+ var w = _wrapper(options[ev]);
+ dd.on(ev, w);
+ }
+ }
+ },
+ _droppables = {},
+ _droppableOptions = {},
+ _draggablesByScope = {},
+ _draggablesById = {},
+ _droppableScopesById = {},
+ _checkHover = function(el, entering) {
+ if (el) {
+ var id = el.get("id");
+ if (id) {
+ var options = _droppableOptions[id];
+ if (options) {
+ if (options.hoverClass) {
+ if (entering) el.addClass(options.hoverClass);
+ else el.removeClass(options.hoverClass);
+ }
+ }
+ }
+ }
+ },
+ _lastDragObject = null,
+ _extend = function(o1, o2) {
+ for (var i in o2)
+ o1[i] = o2[i];
+ return o1;
+ },
+ _getAttribute = function(el, attributeId) {
+ return el.getAttribute(attributeId);
+ },
+ _getElementObject = function(el) {
+ if (el == null) return null;
+ var eee = null;
+ eee = typeof el == 'string' ? Y.one('#' + el) : el._node ? el : Y.one(el);
+ return eee;
+ };
+
+ jsPlumb.CurrentLibrary = {
+
+ addClass : function(el, clazz) {
+ jsPlumb.CurrentLibrary.getElementObject(el).addClass(clazz);
+ },
+
+ /**
+ * animates the given element.
+ */
+ animate : function(el, properties, options) {
+ var o = _extend({node:el, to:properties}, options),
+ id = _getAttribute(el, "id");
+ o.tween = jsPlumbUtil.wrap(properties.tween, function() {
+ // TODO should use a current instance.
+ jsPlumb.repaint(id);
+ });
+ var a = new Y.Anim(o);
+ _attachListeners(a, o, animEvents);
+ a.run();
+ },
+
+ appendElement : function(child, parent) {
+ _getElementObject (parent).append(child);
+ },
+
+ /**
+ * event binding wrapper.
+ */
+ bind : function(el, event, callback) {
+ _getElementObject(el).on(event, callback);
+ },
+
+ destroyDraggable : function(el) {
+ var id = jsPlumb.getId(el),
+ dd = _draggablesById[id];
+
+ if (dd) {
+ dd.destroy();
+ delete _draggablesById[id];
+ }
+ },
+
+ destroyDroppable : function(el) {
+ // TODO
+ },
+
+ dragEvents : {
+ "start":"drag:start", "stop":"drag:end", "drag":"drag:drag", "step":"step",
+ "over":"drop:enter", "out":"drop:exit", "drop":"drop:hit"
+ },
+
+ extend : _extend,
+
+ getClientXY : function(eventObject) {
+ return [eventObject.clientX, eventObject.clientY];
+ },
+
+ /**
+ * takes the args passed to an event function and returns you an object representing that which is being dragged.
+ */
+ getDragObject : function(eventArgs) {
+ // this is a workaround for the unfortunate fact that in YUI3, the 'drop:exit' event does
+ // not contain a reference to the drag that just exited. single-threaded js to the
+ // rescue: we'll just keep it for ourselves.
+ if (eventArgs[0].drag) _lastDragObject = eventArgs[0].drag.el;
+ return _lastDragObject;
+ },
+
+ getDragScope : function(el) {
+ var id = jsPlumb.getId(el),
+ dd = _draggablesById[id];
+ return dd.scope;
+ },
+
+ getDropEvent : function(args) {
+ return args[0];
+ },
+
+ getDropScope : function(el) {
+ var id = jsPlumb.getId(el);
+ return _droppableScopesById[id];
+ },
+
+ getDOMElement : function(el) {
+ if (el == null) return null;
+ if (typeof(el) == "string")
+ return document.getElementById(el);
+ else if (el._node)
+ return el._node;
+ else return el;
+ },
+
+ getElementObject : _getElementObject,
+
+ getOffset : function(el) {
+ var o = Y.DOM.getXY(el._node);
+ return {left:o[0], top:o[1]};
+ },
+
+ getOriginalEvent : function(e) {
+ return e._event;
+ },
+
+ getPageXY : function(eventObject) {
+ return [eventObject.pageX, eventObject.pageY];
+ },
+
+ getParent : function(el) {
+ return jsPlumb.CurrentLibrary.getElementObject(el).get("parentNode");
+ },
+
+ getScrollLeft : function(el) {
+ return 0;
+ },
+
+ getScrollTop : function(el) {
+ return 0;
+ },
+
+ getSelector : function(context, spec) {
+ var _convert = function(s) { return s && s ._nodes ? s._nodes : []; };
+
+ if (arguments.length == 2) {
+ return _convert(jsPlumb.CurrentLibrary.getElementObject(context).all(spec));
+ }
+ else {
+ return _convert(Y.all(context));
+ }
+ },
+
+ getSize : function(el) {
+ return [ el._node.offsetWidth, el._node.offsetHeight ];
+ },
+
+ getTagName : function(el) {
+ var e = jsPlumb.CurrentLibrary.getElementObject(el);
+ return e != null && e._node != null ? e._node.tagName : null;
+ },
+
+ getUIPosition : function(args, zoom) {
+ zoom = zoom || 1;
+ var el = args[0].currentTarget.el._node || args[0].currentTarget.el;
+ var o = Y.DOM.getXY(el);
+ return {left:o[0] / zoom, top:o[1] / zoom };
+ },
+
+ hasClass : function(el, clazz) {
+ return el.hasClass(clazz);
+ },
+
+ initDraggable : function(el, options, isPlumbedComponent, _jsPlumb) {
+ var _opts = _getDDOptions(options),
+ id = _jsPlumb.getId(el);
+ _opts.node = "#" + id;
+ options["drag:start"] = jsPlumbUtil.wrap(options["drag:start"], function() {
+ Y.one(document.body).addClass(_jsPlumb.dragSelectClass);
+ }, false);
+ options["drag:end"] = jsPlumbUtil.wrap(options["drag:end"], function() {
+ Y.one(document.body).removeClass(_jsPlumb.dragSelectClass);
+ });
+ var dd = new Y.DD.Drag(_opts),
+ containment = options.constrain2node || options.containment;
+
+ dd.el = el;
+
+ if (containment) {
+ dd.plug(Y.Plugin.DDConstrained, {
+ constrain2node: containment
+ });
+ }
+
+ if (isPlumbedComponent) {
+ var scope = options.scope || _jsPlumb.Defaults.Scope;
+ dd.scope = scope;
+ _add(_draggablesByScope, scope, dd);
+ }
+
+ _draggablesById[id] = dd;
+ _attachListeners(dd, options, ddEvents);
+ },
+
+ initDroppable : function(el, options) {
+ var _opts = _getDDOptions(options),
+ id = jsPlumb.getId(el);
+ _opts.node = "#" + id;
+ var dd = new Y.DD.Drop(_opts);
+
+ _droppableOptions[id] = options;
+
+ options = _extend({}, options);
+ var scope = options.scope || jsPlumb.Defaults.Scope;
+ _droppableScopesById[id] = scope;
+
+ options["drop:enter"] = jsPlumbUtil.wrap(options["drop:enter"], function(e) {
+ if (e.drag.scope !== scope) return true;
+ _checkHover(el, true);
+ }, true);
+ options["drop:exit"] = jsPlumbUtil.wrap(options["drop:exit"], function(e) {
+ _checkHover(el, false);
+ });
+ options["drop:hit"] = jsPlumbUtil.wrap(options["drop:hit"], function(e) {
+ if (e.drag.scope !== scope) return true;
+ _checkHover(el, false);
+ }, true);
+
+ _attachListeners(dd, options, ddEvents);
+ },
+
+ isAlreadyDraggable : function(el) {
+ el = _getElementObject(el);
+ return el.hasClass("yui3-dd-draggable");
+ },
+
+ isDragSupported : function(el) { return true; },
+ isDropSupported : function(el) { return true; },
+ removeClass : function(el, clazz) {
+ jsPlumb.CurrentLibrary.getElementObject(el).removeClass(clazz);
+ },
+ removeElement : function(el) { _getElementObject(el).remove(); },
+
+ setDragFilter : function(el, filter) {
+ jsPlumb.log("NOT IMPLEMENTED: setDragFilter");
+ },
+
+ /**
+ * sets the draggable state for the given element
+ */
+ setDraggable : function(el, draggable) {
+ var id = jsPlumb.getId(el),
+ dd = _draggablesById[id];
+ if (dd) dd.set("lock", !draggable);
+ },
+
+ setDragScope : function(el, scope) {
+ var id = jsPlumb.getId(el),
+ dd = _draggablesById[id];
+ if (dd) dd.scope = scope;
+ },
+
+ setOffset : function(el, o) {
+ el = _getElementObject(el);
+ el.set("top", o.top);
+ el.set("left", o.left);
+ },
+
+ stopDrag : function() {
+ Y.DD.DDM.stopDrag();
+ },
+
+ trigger : function(el, event, originalEvent) {
+ originalEvent.stopPropagation();
+ _getElementObject(el).simulate(event, {
+ pageX:originalEvent.pageX,
+ pageY:originalEvent.pageY,
+ clientX:originalEvent.clientX,
+ clientY:originalEvent.clientY
+ });
+ },
+
+ /**
+ * event unbinding wrapper.
+ */
+ unbind : function(el, event, callback) {
+ _getElementObject(el).detach(event, callback);
+ }
+ };
+})();
Added: sandbox/nuiton-js-jsplumb/src/site/rst/index.rst.vm
===================================================================
--- sandbox/nuiton-js-jsplumb/src/site/rst/index.rst.vm (rev 0)
+++ sandbox/nuiton-js-jsplumb/src/site/rst/index.rst.vm 2013-09-09 09:43:14 UTC (rev 207)
@@ -0,0 +1,65 @@
+.. -
+.. * #%L
+.. * Nuiton JS :: jsPlumb
+.. * $Id$
+.. * $HeadURL$
+.. * %%
+.. * Copyright (C) 2012 - 2013 CodeLutin
+.. * %%
+.. * This program is free software: you can redistribute it and/or modify
+.. * it under the terms of the GNU Lesser General Public License as
+.. * published by the Free Software Foundation, either version 3 of the
+.. * License, or (at your option) any later version.
+.. *
+.. * This program is distributed in the hope that it will be useful,
+.. * but WITHOUT ANY WARRANTY; without even the implied warranty of
+.. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.. * GNU General Lesser Public License for more details.
+.. *
+.. * You should have received a copy of the GNU General Lesser Public
+.. * License along with this program. If not, see
+.. * <http://www.gnu.org/licenses/lgpl-3.0.html>.
+.. * #L%
+.. -
+
+jsPlumb
+=======
+
+jsPlumb_ provides a way to connect elements in a UI.
+
+- documentation_
+- demos_
+
+.. _jsPlumb: http://jsplumbtoolkit.com/
+.. _documentation: http://jsplumbtoolkit.com/doc/
+.. _demos: http://jsplumbtoolkit.com/
+
+Use
+---
+
+Maven part::
+
+ <dependency>
+ <groupId>org.nuiton.js</groupId>
+ <artifactId>nuiton-js-jsplumb</artifactId>
+ <version>${project.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+
+JSP part::
+
+ <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+
+ <script language="javascript" type="text/javascript" src="<c:url value="/nuiton-js/jsplumb.js"/>"></script>
+
+Available JS
+------------
+
+- jsplumb-jquery.js
+- jsplumb-mootools.js
+- jsplumb-yui.js
+
+Available CSS
+-------------
+
+*none*
Property changes on: sandbox/nuiton-js-jsplumb/src/site/rst/index.rst.vm
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Added: sandbox/nuiton-js-jsplumb/src/site/site_en.xml
===================================================================
--- sandbox/nuiton-js-jsplumb/src/site/site_en.xml (rev 0)
+++ sandbox/nuiton-js-jsplumb/src/site/site_en.xml 2013-09-09 09:43:14 UTC (rev 207)
@@ -0,0 +1,71 @@
+<!--
+ #%L
+ Nuiton JS :: jsPlumb
+ $Id$
+ $HeadURL$
+ %%
+ Copyright (C) 2013 CodeLutin
+ %%
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Lesser Public License for more details.
+
+ You should have received a copy of the GNU General Lesser Public
+ License along with this program. If not, see
+ <http://www.gnu.org/licenses/lgpl-3.0.html>.
+ #L%
+ -->
+<project name="${project.name}">
+
+ <bannerLeft>
+ <name>${project.name}</name>
+ <href>index.html</href>
+ </bannerLeft>
+
+ <body>
+
+ <head>
+ <script type="text/javascript"
+ src="http://maven-site.nuiton.org/public/js/mavenpom-site.js">
+ </script>
+
+ <link rel="stylesheet" type="text/css"
+ href="http://maven-site.nuiton.org/public/css/mavenpom-site.css"/>
+ </head>
+
+ <breadcrumbs>
+ <item name="${project.name}" href="${project.url}"/>
+ </breadcrumbs>
+
+ <menu ref="parent"/>
+
+ <menu name="Users">
+ <item name="Home" href="index.html"/>
+ </menu>
+
+ <menu ref="reports"/>
+
+ <footer>
+
+ <div id='projectMetas'
+ projectversion='${project.version}'
+ platform='${project.platform}'
+ projectid='${project.projectId}'
+ scm='${project.scm.connection}'
+ scmwebeditorenabled='${project.scmwebeditorEnabled}'
+ scmwebeditorurl='${project.scmwebeditorUrl}'
+ siteSourcesType='${project.siteSourcesType}'
+ piwikEnabled='${project.piwikEnabled}'
+ piwikId='${project.piwikId}'>
+ </div>
+ </footer>
+
+ </body>
+
+</project>
Property changes on: sandbox/nuiton-js-jsplumb/src/site/site_en.xml
___________________________________________________________________
Added: svn:mime-type
+ text/xml
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
1
0
r206 - in sandbox/nuiton-js-angular: . src/main/resources/META-INF/nuiton-js src/main/resources/nuiton-js-angular src/main/resources/nuiton-js-angular/extra src/main/resources/nuiton-js-angular/i18n
by echatellier@users.nuiton.org Sept. 9, 2013
by echatellier@users.nuiton.org Sept. 9, 2013
Sept. 9, 2013
Author: echatellier
Date: 2013-09-09 11:04:12 +0200 (Mon, 09 Sep 2013)
New Revision: 206
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/206
Log:
Update to angularjs-1.2.0-rc2
Removed:
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_chr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cy.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-polyton.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-zz.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-rw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-sn.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-td.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-tg.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_haw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-ch.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln-cg.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mo.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms-bn.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-aw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-be.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-ao.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-gw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-mz.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-st.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro-md.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-md.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-ua.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-ba.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-me.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-ba.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-me.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-rs.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv-fi.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw-ke.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta-lk.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tl-ph.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur-in.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-hk.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-mo.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-sg.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant-hk.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant-mo.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant-tw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant.js
Modified:
sandbox/nuiton-js-angular/pom.xml
sandbox/nuiton-js-angular/src/main/resources/META-INF/nuiton-js/wro-angular.xml
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-animate.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-cookies.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-loader.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-mocks.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-resource.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-route.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-sanitize.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-touch.js
Modified: sandbox/nuiton-js-angular/pom.xml
===================================================================
--- sandbox/nuiton-js-angular/pom.xml 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/pom.xml 2013-09-09 09:04:12 UTC (rev 206)
@@ -14,7 +14,7 @@
</parent>
<artifactId>nuiton-js-angular</artifactId>
- <version>1.2.0-rc1-2-SNAPSHOT</version>
+ <version>1.2.0-rc2-1-SNAPSHOT</version>
<name>Nuiton JS :: Angular</name>
<description>Angular jar packaging</description>
@@ -29,9 +29,9 @@
</licenses>
<scm>
- <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</connection>
- <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</developerConnection>
- <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-angular-…</url>
+ <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</connection>
+ <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</developerConnection>
+ <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-angular-…</url>
</scm>
</project>
Modified: sandbox/nuiton-js-angular/src/main/resources/META-INF/nuiton-js/wro-angular.xml
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/META-INF/nuiton-js/wro-angular.xml 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/META-INF/nuiton-js/wro-angular.xml 2013-09-09 09:04:12 UTC (rev 206)
@@ -186,10 +186,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_ca.js</js>
</group>
- <group name='angular-chr'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_chr.js</js>
- </group>
-
<group name='angular-cs-cz'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_cs-cz.js</js>
</group>
@@ -198,10 +194,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_cs.js</js>
</group>
- <group name='angular-cy'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_cy.js</js>
- </group>
-
<group name='angular-da-dk'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_da-dk.js</js>
</group>
@@ -246,10 +238,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_el-gr.js</js>
</group>
- <group name='angular-el-polyton'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_el-polyton.js</js>
- </group>
-
<group name='angular-el'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_el.js</js>
</group>
@@ -406,10 +394,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_en-zw.js</js>
</group>
- <group name='angular-en-zz'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_en-zz.js</js>
- </group>
-
<group name='angular-en'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_en.js</js>
</group>
@@ -670,22 +654,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_fr-re.js</js>
</group>
- <group name='angular-fr-rw'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_fr-rw.js</js>
- </group>
-
- <group name='angular-fr-sn'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_fr-sn.js</js>
- </group>
-
- <group name='angular-fr-td'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_fr-td.js</js>
- </group>
-
- <group name='angular-fr-tg'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_fr-tg.js</js>
- </group>
-
<group name='angular-fr-yt'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_fr-yt.js</js>
</group>
@@ -718,10 +686,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_gu.js</js>
</group>
- <group name='angular-haw'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_haw.js</js>
- </group>
-
<group name='angular-he-il'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_he-il.js</js>
</group>
@@ -774,10 +738,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_is.js</js>
</group>
- <group name='angular-it-ch'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_it-ch.js</js>
- </group>
-
<group name='angular-it-it'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_it-it.js</js>
</group>
@@ -822,10 +782,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_ln-cd.js</js>
</group>
- <group name='angular-ln-cg'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_ln-cg.js</js>
- </group>
-
<group name='angular-ln'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_ln.js</js>
</group>
@@ -854,10 +810,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_ml.js</js>
</group>
- <group name='angular-mo'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_mo.js</js>
- </group>
-
<group name='angular-mr-in'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_mr-in.js</js>
</group>
@@ -866,10 +818,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_mr.js</js>
</group>
- <group name='angular-ms-bn'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_ms-bn.js</js>
- </group>
-
<group name='angular-ms-my'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_ms-my.js</js>
</group>
@@ -886,14 +834,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_mt.js</js>
</group>
- <group name='angular-nl-aw'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_nl-aw.js</js>
- </group>
-
- <group name='angular-nl-be'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_nl-be.js</js>
- </group>
-
<group name='angular-nl-cw'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_nl-cw.js</js>
</group>
@@ -930,38 +870,18 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_pl.js</js>
</group>
- <group name='angular-pt-ao'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_pt-ao.js</js>
- </group>
-
<group name='angular-pt-br'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_pt-br.js</js>
</group>
- <group name='angular-pt-gw'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_pt-gw.js</js>
- </group>
-
- <group name='angular-pt-mz'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_pt-mz.js</js>
- </group>
-
<group name='angular-pt-pt'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_pt-pt.js</js>
</group>
- <group name='angular-pt-st'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_pt-st.js</js>
- </group>
-
<group name='angular-pt'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_pt.js</js>
</group>
- <group name='angular-ro-md'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_ro-md.js</js>
- </group>
-
<group name='angular-ro-ro'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_ro-ro.js</js>
</group>
@@ -970,18 +890,10 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_ro.js</js>
</group>
- <group name='angular-ru-md'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_ru-md.js</js>
- </group>
-
<group name='angular-ru-ru'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_ru-ru.js</js>
</group>
- <group name='angular-ru-ua'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_ru-ua.js</js>
- </group>
-
<group name='angular-ru'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_ru.js</js>
</group>
@@ -1010,50 +922,18 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_sq.js</js>
</group>
- <group name='angular-sr-cyrl-ba'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_sr-cyrl-ba.js</js>
- </group>
-
- <group name='angular-sr-cyrl-me'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_sr-cyrl-me.js</js>
- </group>
-
<group name='angular-sr-cyrl-rs'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_sr-cyrl-rs.js</js>
</group>
- <group name='angular-sr-cyrl'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_sr-cyrl.js</js>
- </group>
-
- <group name='angular-sr-latn-ba'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_sr-latn-ba.js</js>
- </group>
-
- <group name='angular-sr-latn-me'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_sr-latn-me.js</js>
- </group>
-
<group name='angular-sr-latn-rs'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_sr-latn-rs.js</js>
</group>
- <group name='angular-sr-latn'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_sr-latn.js</js>
- </group>
-
- <group name='angular-sr-rs'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_sr-rs.js</js>
- </group>
-
<group name='angular-sr'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_sr.js</js>
</group>
- <group name='angular-sv-fi'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_sv-fi.js</js>
- </group>
-
<group name='angular-sv-se'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_sv-se.js</js>
</group>
@@ -1062,10 +942,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_sv.js</js>
</group>
- <group name='angular-sw-ke'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_sw-ke.js</js>
- </group>
-
<group name='angular-sw-tz'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_sw-tz.js</js>
</group>
@@ -1078,10 +954,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_ta-in.js</js>
</group>
- <group name='angular-ta-lk'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_ta-lk.js</js>
- </group>
-
<group name='angular-ta'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_ta.js</js>
</group>
@@ -1102,10 +974,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_th.js</js>
</group>
- <group name='angular-tl-ph'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_tl-ph.js</js>
- </group>
-
<group name='angular-tl'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_tl.js</js>
</group>
@@ -1126,10 +994,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_uk.js</js>
</group>
- <group name='angular-ur-in'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_ur-in.js</js>
- </group>
-
<group name='angular-ur-pk'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_ur-pk.js</js>
</group>
@@ -1154,38 +1018,6 @@
<js>classpath:nuiton-js-angular/i18n/angular-locale_zh-hans-cn.js</js>
</group>
- <group name='angular-zh-hans-hk'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_zh-hans-hk.js</js>
- </group>
-
- <group name='angular-zh-hans-mo'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_zh-hans-mo.js</js>
- </group>
-
- <group name='angular-zh-hans-sg'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_zh-hans-sg.js</js>
- </group>
-
- <group name='angular-zh-hans'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_zh-hans.js</js>
- </group>
-
- <group name='angular-zh-hant-hk'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_zh-hant-hk.js</js>
- </group>
-
- <group name='angular-zh-hant-mo'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_zh-hant-mo.js</js>
- </group>
-
- <group name='angular-zh-hant-tw'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_zh-hant-tw.js</js>
- </group>
-
- <group name='angular-zh-hant'>
- <js>classpath:nuiton-js-angular/i18n/angular-locale_zh-hant.js</js>
- </group>
-
<group name='angular-zh-hk'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_zh-hk.js</js>
</group>
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +1,5 @@
/** %%Ignore-License
- * @license AngularJS v1.2.0rc1
+ * @license AngularJS v1.2.0-rc.2
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -35,10 +35,21 @@
function minErr(module) {
return function () {
- var prefix = '[' + (module ? module + ':' : '') + arguments[0] + '] ',
+ var code = arguments[0],
+ prefix = '[' + (module ? module + ':' : '') + code + '] ',
template = arguments[1],
templateArgs = arguments,
- message;
+ stringify = function (obj) {
+ if (isFunction(obj)) {
+ return obj.toString().replace(/ \{[\s\S]*$/, '');
+ } else if (isUndefined(obj)) {
+ return 'undefined';
+ } else if (!isString(obj)) {
+ return JSON.stringify(obj);
+ }
+ return obj;
+ },
+ message, i;
message = prefix + template.replace(/\{\d+\}/g, function (match) {
var index = +match.slice(1, -1), arg;
@@ -57,6 +68,13 @@
return match;
});
+ message = message + '\nhttp://errors.angularjs.org/' + version.full + '/' +
+ (module ? module + '/' : '') + code;
+ for (i = 2; i < arguments.length; i++) {
+ message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
+ encodeURIComponent(stringify(arguments[i]));
+ }
+
return new Error(message);
};
}
@@ -119,7 +137,7 @@
var /** holds major version number for IE or NaN for real browsers */
- msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]),
+ msie,
jqLite, // delay binding since jQuery could be loaded after us.
jQuery, // delay binding
slice = [].slice,
@@ -136,6 +154,16 @@
uid = ['0', '0', '0'];
/**
+ * IE 11 changed the format of the UserAgent string.
+ * See http://msdn.microsoft.com/en-us/library/ms537503.aspx
+ */
+msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);
+if (isNaN(msie)) {
+ msie = int((/trident\/.*; rv:(\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);
+}
+
+
+/**
* @private
* @param {*} obj
* @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
@@ -1249,11 +1277,14 @@
* @name angular.module
* @description
*
- * The `angular.module` is a global place for creating and registering Angular modules. All
- * modules (angular core or 3rd party) that should be available to an application must be
+ * The `angular.module` is a global place for creating, registering and retrieving Angular modules.
+ * All modules (angular core or 3rd party) that should be available to an application must be
* registered using this mechanism.
*
+ * When passed two or more arguments, a new module is created. If passed only one argument, an
+ * existing module (the name passed as the first argument to `module`) is retrieved.
*
+ *
* # Module
*
* A module is a collection of services, directives, filters, and configuration information.
@@ -1523,11 +1554,11 @@
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/
var version = {
- full: '1.2.0rc1', // all of these placeholder strings will be replaced by grunt's
+ full: '1.2.0-rc.2', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task
minor: 2,
dot: 0,
- codeName: 'spooky-giraffe'
+ codeName: 'barehand-atomsplitting'
};
@@ -2590,13 +2621,15 @@
if (typeof fn == 'function') {
if (!($inject = fn.$inject)) {
$inject = [];
- fnText = fn.toString().replace(STRIP_COMMENTS, '');
- argDecl = fnText.match(FN_ARGS);
- forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
- arg.replace(FN_ARG, function(all, underscore, name){
- $inject.push(name);
+ if (fn.length) {
+ fnText = fn.toString().replace(STRIP_COMMENTS, '');
+ argDecl = fnText.match(FN_ARGS);
+ forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
+ arg.replace(FN_ARG, function(all, underscore, name){
+ $inject.push(name);
+ });
});
- });
+ }
fn.$inject = $inject;
}
} else if (isArray(fn)) {
@@ -3320,7 +3353,7 @@
forEach(element, function(node) {
parentNode.insertBefore(node, afterNextSibling);
});
- $timeout(done || noop, 0, false);
+ done && $timeout(done, 0, false);
},
/**
@@ -3337,7 +3370,7 @@
*/
leave : function(element, done) {
element.remove();
- $timeout(done || noop, 0, false);
+ done && $timeout(done, 0, false);
},
/**
@@ -3379,7 +3412,7 @@
className :
isArray(className) ? className.join(' ') : '';
element.addClass(className);
- $timeout(done || noop, 0, false);
+ done && $timeout(done, 0, false);
},
/**
@@ -3400,7 +3433,7 @@
className :
isArray(className) ? className.join(' ') : '';
element.removeClass(className);
- $timeout(done || noop, 0, false);
+ done && $timeout(done, 0, false);
},
enabled : noop
@@ -5699,7 +5732,7 @@
// strip json vulnerability protection prefix
data = data.replace(PROTECTION_PREFIX, '');
if (JSON_START.test(data) && JSON_END.test(data))
- data = fromJson(data, true);
+ data = fromJson(data);
}
return data;
}],
@@ -6015,6 +6048,7 @@
* return function(promise) {
* return promise.then(function(response) {
* // do something on success
+ * return response;
* }, function(response) {
* // do something on error
* if (canRecover(response)) {
@@ -6494,7 +6528,7 @@
if (cache) {
cachedResp = cache.get(url);
- if (cachedResp) {
+ if (isDefined(cachedResp)) {
if (cachedResp.then) {
// cached request has already been sent, but there is no response yet
cachedResp.then(removePendingReq, removePendingReq);
@@ -6514,7 +6548,7 @@
}
// if we won't have the response in cache, send the request to the backend
- if (!cachedResp) {
+ if (isUndefined(cachedResp)) {
$httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
config.withCredentials, config.responseType);
}
@@ -6764,23 +6798,32 @@
* @description
*
* Used for configuring the interpolation markup. Defaults to `{{` and `}}`.
- *
+ *
* @example
- <doc:example>
+ <doc:example module="customInterpolationApp">
<doc:source>
<script>
- var myApp = angular.module('App', [], function($interpolateProvider) {
+ var customInterpolationApp = angular.module('customInterpolationApp', []);
+
+ customInterpolationApp.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('//');
$interpolateProvider.endSymbol('//');
});
- function Controller($scope) {
- $scope.label = "Interpolation Provider Sample";
- }
+
+
+ customInterpolationApp.controller('DemoController', function DemoController() {
+ this.label = "This bindings is brought you you by // interpolation symbols.";
+ });
</script>
- <div ng-app="App" ng-controller="Controller">
- //label//
+ <div ng-app="App" ng-controller="DemoController as demo">
+ //demo.label//
</div>
</doc:source>
+ <doc:scenario>
+ it('should interpolate binding with custom symbols', function() {
+ expect(binding('demo.label')).toBe('This bindings is brought you you by // interpolation symbols.');
+ });
+ </doc:scenario>
</doc:example>
*/
function $InterpolateProvider() {
@@ -7844,7 +7887,6 @@
// access to any member named "constructor".
//
// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor while evaluating
-// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor while evaluating
// the expression, which is a stronger but more expensive test. Since reflective calls are expensive anyway, this is not
// such a big deal compared to static dereferencing.
//
@@ -8518,9 +8560,21 @@
}
var fnPtr = fn(scope, locals, context) || noop;
// IE stupidity!
- return fnPtr.apply
+ var v = fnPtr.apply
? fnPtr.apply(context, args)
: fnPtr(args[0], args[1], args[2], args[3], args[4]);
+
+ // Check for promise
+ if (v && v.then) {
+ var p = v;
+ if (!('$$v' in v)) {
+ p.$$v = undefined;
+ p.then(function(val) { p.$$v = val; });
+ }
+ v = v.$$v;
+ }
+
+ return v;
};
}
@@ -8824,6 +8878,8 @@
* // since this fn executes async in a future turn of the event loop, we need to wrap
* // our code into an $apply call so that the model changes are properly observed.
* scope.$apply(function() {
+ * deferred.notify('About to greet ' + name + '.');
+ *
* if (okToGreet(name)) {
* deferred.resolve('Hello, ' + name + '!');
* } else {
@@ -8840,6 +8896,8 @@
* alert('Success: ' + greeting);
* }, function(reason) {
* alert('Failed: ' + reason);
+ * }, function(update) {
+ * alert('Got notification: ' + update);
* });
* </pre>
*
@@ -8858,7 +8916,8 @@
* A new instance of deferred is constructed by calling `$q.defer()`.
*
* The purpose of the deferred object is to expose the associated Promise instance as well as APIs
- * that can be used for signaling the successful or unsuccessful completion of the task.
+ * that can be used for signaling the successful or unsuccessful completion, as well as the status
+ * of the task.
*
* **Methods**
*
@@ -8866,6 +8925,8 @@
* constructed via `$q.reject`, the promise will be rejected instead.
* - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
* resolving it with a rejection constructed via `$q.reject`.
+ * - `notify(value)` - provides updates on the status of the promises execution. This may be called
+ * multiple times before the promise is either resolved or rejected.
*
* **Properties**
*
@@ -8882,12 +8943,15 @@
*
* **Methods**
*
- * - `then(successCallback, errorCallback)` – regardless of when the promise was or will be resolved
- * or rejected, `then` calls one of the success or error callbacks asynchronously as soon as the result
- * is available. The callbacks are called with a single argument: the result or rejection reason.
+ * - `then(successCallback, errorCallback, notifyCallback)` – regardless of when the promise was or
+ * will be resolved or rejected, `then` calls one of the success or error callbacks asynchronously
+ * as soon as the result is available. The callbacks are called with a single argument: the result
+ * or rejection reason. Additionally, the notify callback may be called zero or more times to
+ * provide a progress indication, before the promise is resolved or rejected.
*
* This method *returns a new promise* which is resolved or rejected via the return value of the
- * `successCallback` or `errorCallback`.
+ * `successCallback`, `errorCallback`. It also notifies via the return value of the `notifyCallback`
+ * method. The promise can not be resolved or rejected from the notifyCallback method.
*
* - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)`
*
@@ -9039,7 +9103,7 @@
var wrappedCallback = function(value) {
try {
- result.resolve((callback || defaultCallback)(value));
+ result.resolve((isFunction(callback) ? callback : defaultCallback)(value));
} catch(e) {
result.reject(e);
exceptionHandler(e);
@@ -9048,7 +9112,7 @@
var wrappedErrback = function(reason) {
try {
- result.resolve((errback || defaultErrback)(reason));
+ result.resolve((isFunction(errback) ? errback : defaultErrback)(reason));
} catch(e) {
result.reject(e);
exceptionHandler(e);
@@ -9057,7 +9121,7 @@
var wrappedProgressback = function(progress) {
try {
- result.notify((progressback || defaultCallback)(progress));
+ result.notify((isFunction(progressback) ? progressback : defaultCallback)(progress));
} catch(e) {
exceptionHandler(e);
}
@@ -9095,7 +9159,7 @@
} catch(e) {
return makePromise(e, false);
}
- if (callbackOutput && callbackOutput.then) {
+ if (callbackOutput && isFunction(callbackOutput.then)) {
return callbackOutput.then(function() {
return makePromise(value, isResolved);
}, function(error) {
@@ -9120,7 +9184,7 @@
var ref = function(value) {
- if (value && value.then) return value;
+ if (value && isFunction(value.then)) return value;
return {
then: function(callback) {
var result = defer();
@@ -9173,7 +9237,12 @@
then: function(callback, errback) {
var result = defer();
nextTick(function() {
- result.resolve((errback || defaultErrback)(reason));
+ try {
+ result.resolve((isFunction(errback) ? errback : defaultErrback)(reason));
+ } catch(e) {
+ result.reject(e);
+ exceptionHandler(e);
+ }
});
return result.promise;
}
@@ -9199,7 +9268,7 @@
var wrappedCallback = function(value) {
try {
- return (callback || defaultCallback)(value);
+ return (isFunction(callback) ? callback : defaultCallback)(value);
} catch (e) {
exceptionHandler(e);
return reject(e);
@@ -9208,7 +9277,7 @@
var wrappedErrback = function(reason) {
try {
- return (errback || defaultErrback)(reason);
+ return (isFunction(errback) ? errback : defaultErrback)(reason);
} catch (e) {
exceptionHandler(e);
return reject(e);
@@ -9217,7 +9286,7 @@
var wrappedProgressback = function(progress) {
try {
- return (progressback || defaultCallback)(progress);
+ return (isFunction(progressback) ? progressback : defaultCallback)(progress);
} catch (e) {
exceptionHandler(e);
}
@@ -9367,8 +9436,8 @@
return TTL;
};
- this.$get = ['$injector', '$exceptionHandler', '$parse',
- function( $injector, $exceptionHandler, $parse) {
+ this.$get = ['$injector', '$exceptionHandler', '$parse', '$browser',
+ function( $injector, $exceptionHandler, $parse, $browser) {
/**
* @ngdoc function
@@ -9417,6 +9486,7 @@
this['this'] = this.$root = this;
this.$$destroyed = false;
this.$$asyncQueue = [];
+ this.$$postDigestQueue = [];
this.$$listeners = {};
this.$$isolateBindings = {};
}
@@ -9431,6 +9501,7 @@
Scope.prototype = {
+ constructor: Scope,
/**
* @ngdoc function
* @name ng.$rootScope.Scope#$new
@@ -9465,6 +9536,7 @@
child.$root = this.$root;
// ensure that there is just one async queue per $rootScope and it's children
child.$$asyncQueue = this.$$asyncQueue;
+ child.$$postDigestQueue = this.$$postDigestQueue;
} else {
Child = function() {}; // should be anonymous; This is so that when the minifier munges
// the name it does not become random set of chars. These will then show up as class
@@ -9792,6 +9864,7 @@
var watch, value, last,
watchers,
asyncQueue = this.$$asyncQueue,
+ postDigestQueue = this.$$postDigestQueue,
length,
dirty, ttl = TTL,
next, current, target = this,
@@ -9864,6 +9937,14 @@
} while (dirty || asyncQueue.length);
clearPhase();
+
+ while(postDigestQueue.length) {
+ try {
+ postDigestQueue.shift()();
+ } catch (e) {
+ $exceptionHandler(e);
+ }
+ }
},
@@ -9964,13 +10045,16 @@
*
* The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only that:
*
- * - it will execute in the current script execution context (before any DOM rendering).
- * - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after
- * `expression` execution.
+ * - it will execute after the function that schedule the evaluation is done running (preferably before DOM rendering).
+ * - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after `expression` execution.
*
* Any exceptions from the execution of the expression are forwarded to the
* {@link ng.$exceptionHandler $exceptionHandler} service.
*
+ * __Note:__ if this function is called outside of `$digest` cycle, a new $digest cycle will be scheduled.
+ * It is however encouraged to always call code that changes the model from withing an `$apply` call.
+ * That includes code evaluated via `$evalAsync`.
+ *
* @param {(string|function())=} expression An angular expression to be executed.
*
* - `string`: execute using the rules as defined in {@link guide/expression expression}.
@@ -9978,9 +10062,23 @@
*
*/
$evalAsync: function(expr) {
+ // if we are outside of an $digest loop and this is the first time we are scheduling async task also schedule
+ // async auto-flush
+ if (!$rootScope.$$phase && !$rootScope.$$asyncQueue.length) {
+ $browser.defer(function() {
+ if ($rootScope.$$asyncQueue.length) {
+ $rootScope.$digest();
+ }
+ });
+ }
+
this.$$asyncQueue.push(expr);
},
+ $$postDigest : function(expr) {
+ this.$$postDigestQueue.push(expr);
+ },
+
/**
* @ngdoc function
* @name ng.$rootScope.Scope#$apply
@@ -10649,7 +10747,7 @@
* {@link ng.$sce#getTrusted $sce.getTrusted} behind the scenes on non-constant literals.
*
* As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link
- * ng.$sce#parseHtml $sce.parseAsHtml(binding expression)}. Here's the actual code (slightly
+ * ng.$sce#parseAsHtml $sce.parseAsHtml(binding expression)}. Here's the actual code (slightly
* simplified):
*
* <pre class="prettyprint">
@@ -10707,7 +10805,7 @@
* ## What trusted context types are supported?<a name="contexts"></a>
*
* | Context | Notes |
- * |=====================|================|
+ * |---------------------|----------------|
* | `$sce.HTML` | For HTML that's safe to source into the application. The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. |
* | `$sce.CSS` | For CSS that's safe to source into the application. Currently unused. Feel free to use it in your own directives. |
* | `$sce.URL` | For URLs that are safe to follow as links. Currently unused (`<a href=` and `<img src=` sanitize their urls and don't consititute an SCE context. |
@@ -11218,6 +11316,7 @@
this.$get = ['$window', '$document', function($window, $document) {
var eventSupport = {},
android = int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
+ boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
document = $document[0] || {},
vendorPrefix,
vendorRegex = /^(Moz|webkit|O|ms)(?=[A-Z])/,
@@ -11234,12 +11333,17 @@
break;
}
}
+
+ if(!vendorPrefix) {
+ vendorPrefix = ('WebkitOpacity' in bodyStyle) && 'webkit';
+ }
+
transitions = !!(('transition' in bodyStyle) || (vendorPrefix + 'Transition' in bodyStyle));
animations = !!(('animation' in bodyStyle) || (vendorPrefix + 'Animation' in bodyStyle));
-
+
if (android && (!transitions||!animations)) {
- transitions = isString(document.body.style.webkitTransition);
- animations = isString(document.body.style.webkitAnimation);
+ transitions = isString(document.body.style.webkitTransition);
+ animations = isString(document.body.style.webkitAnimation);
}
}
@@ -11249,7 +11353,10 @@
// so let's not use the history API at all.
// http://code.google.com/p/android/issues/detail?id=17471
// https://github.com/angular/angular.js/issues/904
- history: !!($window.history && $window.history.pushState && !(android < 4)),
+
+ // older webit browser (533.9) on Boxee box has exactly the same problem as Android has
+ // so let's not use the history API also
+ history: !!($window.history && $window.history.pushState && !(android < 4) && !boxee),
hashchange: 'onhashchange' in $window &&
// IE8 compatible mode lies
(!document.documentMode || document.documentMode > 7),
@@ -11309,7 +11416,7 @@
var deferred = $q.defer(),
promise = deferred.promise,
skipApply = (isDefined(invokeApply) && !invokeApply),
- timeoutId, cleanup;
+ timeoutId;
timeoutId = $browser.defer(function() {
try {
@@ -11318,17 +11425,15 @@
deferred.reject(e);
$exceptionHandler(e);
}
+ finally {
+ delete deferreds[promise.$$timeoutId];
+ }
if (!skipApply) $rootScope.$apply();
}, delay);
- cleanup = function() {
- delete deferreds[promise.$$timeoutId];
- };
-
promise.$$timeoutId = timeoutId;
deferreds[timeoutId] = deferred;
- promise.then(cleanup, cleanup);
return promise;
}
@@ -11350,6 +11455,7 @@
timeout.cancel = function(promise) {
if (promise && promise.$$timeoutId in deferreds) {
deferreds[promise.$$timeoutId].reject('canceled');
+ delete deferreds[promise.$$timeoutId];
return $browser.defer.cancel(promise.$$timeoutId);
}
return false;
@@ -11417,7 +11523,7 @@
* Otherwise, returns an object with the following members.
*
* | member name | Description |
- * |===============|================|
+ * |---------------|----------------|
* | href | A normalized version of the provided URL if it was not an absolute URL |
* | protocol | The protocol including the trailing colon |
* | host | The host and port (if the port is non-default) of the normalizedUrl |
@@ -11425,7 +11531,7 @@
* These fields from the UrlUtils interface are currently not needed and hence not returned.
*
* | member name | Description |
- * |===============|================|
+ * |---------------|----------------|
* | hostname | The host without the port of the normalizedUrl |
* | pathname | The path following the host in the normalizedUrl |
* | hash | The URL hash if present |
@@ -11434,7 +11540,7 @@
*/
function resolve(url, parse) {
var href = url;
- if (msie) {
+ if (msie <= 11) {
// Normalize before parse. Refer Implementation Notes on why this is
// done in two steps on IE.
urlParsingNode.setAttribute("href", href);
@@ -11804,7 +11910,7 @@
})();
} else {
(function() {
- if (!expression[key]) return;
+ if (typeof(expression[key]) == 'undefined') { return; }
var path = key;
predicates.push(function(value) {
return search(getter(value,path), expression[path]);
@@ -12533,8 +12639,10 @@
var t1 = typeof v1;
var t2 = typeof v2;
if (t1 == t2) {
- if (t1 == "string") v1 = v1.toLowerCase();
- if (t1 == "string") v2 = v2.toLowerCase();
+ if (t1 == "string") {
+ v1 = v1.toLowerCase();
+ v2 = v2.toLowerCase();
+ }
if (v1 === v2) return 0;
return v1 < v2 ? -1 : 1;
} else {
@@ -14779,8 +14887,8 @@
var ngBindHtmlDirective = ['$sce', function($sce) {
return function(scope, element, attr) {
element.addClass('ng-binding').data('$binding', attr.ngBindHtml);
- scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function ngBindHtmlWatchAction(value) {
- element.html(value || '');
+ scope.$watch(attr.ngBindHtml, function ngBindHtmlWatchAction(value) {
+ element.html($sce.getTrustedHtml(value) || '');
});
};
}];
@@ -14936,7 +15044,7 @@
## Animations
- Example that demostrates how addition and removal of classes can be animated.
+ The example below demonstrates how to perform animations using ngClass.
<example animations="true">
<file name="index.html">
@@ -14981,6 +15089,14 @@
});
</file>
</example>
+
+
+ ## ngClass and pre-existing CSS3 Transitions/Animations
+ The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure.
+ Therefore, if any CSS3 Transition/Animation styles (outside of ngAnimate) are set on the element, then, if a ngClass animation
+ is triggered, the ngClass animation will be skipped so that ngAnimate can allow for the pre-existing transition or animation to
+ take over. This restriction allows for ngClass to still work with standard CSS3 Transitions/Animations that are defined
+ outside of ngAnimate.
*/
var ngClassDirective = classDirective('', true);
@@ -15899,23 +16015,18 @@
* @description
* Emitted every time the ngInclude content is reloaded.
*/
-var NG_INCLUDE_PRIORITY = 500;
var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile', '$animate', '$sce',
function($http, $templateCache, $anchorScroll, $compile, $animate, $sce) {
return {
restrict: 'ECA',
terminal: true,
- priority: NG_INCLUDE_PRIORITY,
- compile: function(element, attr) {
+ transclude: 'element',
+ compile: function(element, attr, transclusion) {
var srcExp = attr.ngInclude || attr.src,
onloadExp = attr.onload || '',
autoScrollExp = attr.autoscroll;
- element.html('');
- var anchor = jqLite(document.createComment(' ngInclude: ' + srcExp + ' '));
- element.replaceWith(anchor);
-
- return function(scope) {
+ return function(scope, $element) {
var changeCounter = 0,
currentScope,
currentElement;
@@ -15939,21 +16050,23 @@
if (thisChangeId !== changeCounter) return;
var newScope = scope.$new();
- cleanupLastIncludeContent();
+ transclusion(newScope, function(clone) {
+ cleanupLastIncludeContent();
- currentScope = newScope;
- currentElement = element.clone();
- currentElement.html(response);
- $animate.enter(currentElement, null, anchor);
+ currentScope = newScope;
+ currentElement = clone;
- $compile(currentElement, false, NG_INCLUDE_PRIORITY - 1)(currentScope);
+ currentElement.html(response);
+ $animate.enter(currentElement, null, $element);
+ $compile(currentElement.contents())(currentScope);
- if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
- $anchorScroll();
- }
+ if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
+ $anchorScroll();
+ }
- currentScope.$emit('$includeContentLoaded');
- scope.$eval(onloadExp);
+ currentScope.$emit('$includeContentLoaded');
+ scope.$eval(onloadExp);
+ });
}).error(function() {
if (thisChangeId === changeCounter) cleanupLastIncludeContent();
});
@@ -17176,8 +17289,10 @@
* @name ng.directive:ngTransclude
*
* @description
- * Insert the transcluded DOM here.
+ * Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.
*
+ * Any existing content of the element that this directive is placed on will be removed before the transcluded content is inserted.
+ *
* @element ANY
*
* @example
@@ -17220,16 +17335,19 @@
*
*/
var ngTranscludeDirective = ngDirective({
- controller: ['$transclude', '$element', '$scope', function($transclude, $element, $scope) {
- // use evalAsync so that we don't process transclusion before directives on the parent element even when the
- // transclusion replaces the current element. (we can't use priority here because that applies only to compile fns
- // and not controllers
- $scope.$evalAsync(function() {
- $transclude(function(clone) {
- $element.append(clone);
- });
+ controller: ['$transclude', function($transclude) {
+ // remember the transclusion fn but call it during linking so that we don't process transclusion before directives on
+ // the parent element even when the transclusion replaces the current element. (we can't use priority here because
+ // that applies only to compile fns and not controllers
+ this.$transclude = $transclude;
+ }],
+
+ link: function($scope, $element, $attrs, controller) {
+ controller.$transclude(function(clone) {
+ $element.html('');
+ $element.append(clone);
});
- }]
+ }
});
/**
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-animate.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-animate.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-animate.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +1,5 @@
/** %%Ignore-License
- * @license AngularJS v1.2.0rc1
+ * @license AngularJS v1.2.0-rc.2
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -10,20 +10,15 @@
* @name ngAnimate
* @description
*
- * ngAnimate
- * =========
+ * # ngAnimate
*
- * The ngAnimate module is an optional module that comes packed with AngularJS that can be included within an AngularJS
- * application to provide support for CSS and JavaScript animation hooks.
+ * `ngAnimate` is an optional module that provides CSS and JavaScript animation hooks.
*
- * To make use of animations with AngularJS, the `angular-animate.js` JavaScript file must be included into your application
- * and the `ngAnimate` module must be included as a dependency.
+ * {@installModule animate}
*
- * <pre>
- * angular.module('App', ['ngAnimate']);
- * </pre>
+ * # Usage
*
- * Then, to see animations in action, all that is required is to define the appropriate CSS classes
+ * To see animations in action, all that is required is to define the appropriate CSS classes
* or to register a JavaScript animation via the $animation service. The directives that support animation automatically are:
* `ngRepeat`, `ngInclude`, `ngSwitch`, `ngShow`, `ngHide` and `ngView`. Custom directives can take advantage of animation
* by using the `$animate` service.
@@ -53,7 +48,7 @@
* -o-transition:0.5s linear all;
* transition:0.5s linear all;
* }
- *
+ *
* .slide.ng-enter { } /* starting animations for enter */
* .slide.ng-enter-active { } /* terminal animations for enter */
* .slide.ng-leave { } /* starting animations for leave */
@@ -197,12 +192,14 @@
* @name ngAnimate.$animateProvider
* @description
*
- * The $AnimationProvider provider allows developers to register and access custom JavaScript animations directly inside
+ * The `$AnimationProvider` allows developers to register and access custom JavaScript animations directly inside
* of a module. When an animation is triggered, the $animate service will query the $animation function to find any
* animations that match the provided name value.
*
- * Please visit the {@link ngAnimate ngAnimate} module overview page learn more about how to use animations in your application.
+ * Requires the {@link ngAnimate `ngAnimate`} module to be installed.
*
+ * Please visit the {@link ngAnimate `ngAnimate`} module overview page learn more about how to use animations in your application.
+ *
*/
.config(['$provide', '$animateProvider', function($provide, $animateProvider) {
var noop = angular.noop;
@@ -211,8 +208,8 @@
var NG_ANIMATE_STATE = '$$ngAnimateState';
var rootAnimateState = {running:true};
- $provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$timeout',
- function($delegate, $injector, $sniffer, $rootElement, $timeout) {
+ $provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$timeout', '$rootScope',
+ function($delegate, $injector, $sniffer, $rootElement, $timeout, $rootScope) {
$rootElement.data(NG_ANIMATE_STATE, rootAnimateState);
@@ -255,8 +252,10 @@
* The `$animate` service is used behind the scenes with pre-existing directives and animation with these directives
* will work out of the box without any extra configuration.
*
- * Please visit the {@link ngAnimate ngAnimate} module overview page learn more about how to use animations in your application.
+ * Requires the {@link ngAnimate `ngAnimate`} module to be installed.
*
+ * Please visit the {@link ngAnimate `ngAnimate`} module overview page learn more about how to use animations in your application.
+ *
*/
return {
/**
@@ -275,8 +274,8 @@
* |----------------------------------------------------------------------------------------------|-----------------------------------------------|
* | 1. $animate.enter(...) is called | class="my-animation" |
* | 2. element is inserted into the parent element or beside the after element | class="my-animation" |
- * | 3. the .ng-enter class is added to the element | class="my-animation ng-enter" |
- * | 4. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-enter" |
+ * | 3. $animate runs any JavaScript-defined animations on the element | class="my-animation" |
+ * | 4. the .ng-enter class is added to the element | class="my-animation ng-enter" |
* | 5. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-enter" |
* | 6. the .ng-enter-active class is added (this triggers the CSS transition/animation) | class="my-animation ng-enter ng-enter-active" |
* | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-enter ng-enter-active" |
@@ -290,7 +289,11 @@
*/
enter : function(element, parent, after, done) {
$delegate.enter(element, parent, after);
- performAnimation('enter', 'ng-enter', element, parent, after, done);
+ $rootScope.$$postDigest(function() {
+ performAnimation('enter', 'ng-enter', element, parent, after, function() {
+ done && $timeout(done, 0, false);
+ });
+ });
},
/**
@@ -308,8 +311,8 @@
* | Animation Step | What the element class attribute looks like |
* |----------------------------------------------------------------------------------------------|----------------------------------------------|
* | 1. $animate.leave(...) is called | class="my-animation" |
- * | 2. the .ng-leave class is added to the element | class="my-animation ng-leave" |
- * | 3. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-leave" |
+ * | 2. $animate runs any JavaScript-defined animations on the element | class="my-animation" |
+ * | 3. the .ng-leave class is added to the element | class="my-animation ng-leave" |
* | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-leave" |
* | 5. the .ng-leave-active class is added (this triggers the CSS transition/animation) | class="my-animation ng-leave ng-leave-active |
* | 6. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-leave ng-leave-active |
@@ -321,8 +324,10 @@
* @param {function()=} done callback function that will be called once the animation is complete
*/
leave : function(element, done) {
- performAnimation('leave', 'ng-leave', element, null, null, function() {
- $delegate.leave(element, done);
+ $rootScope.$$postDigest(function() {
+ performAnimation('leave', 'ng-leave', element, null, null, function() {
+ $delegate.leave(element, done);
+ });
});
},
@@ -343,8 +348,8 @@
* |----------------------------------------------------------------------------------------------|---------------------------------------------|
* | 1. $animate.move(...) is called | class="my-animation" |
* | 2. element is moved into the parent element or beside the after element | class="my-animation" |
- * | 3. the .ng-move class is added to the element | class="my-animation ng-move" |
- * | 4. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-move" |
+ * | 3. $animate runs any JavaScript-defined animations on the element | class="my-animation" |
+ * | 4. the .ng-move class is added to the element | class="my-animation ng-move" |
* | 5. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-move" |
* | 6. the .ng-move-active class is added (this triggers the CSS transition/animation) | class="my-animation ng-move ng-move-active" |
* | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-move ng-move-active" |
@@ -358,7 +363,11 @@
*/
move : function(element, parent, after, done) {
$delegate.move(element, parent, after);
- performAnimation('move', 'ng-move', element, null, null, done);
+ $rootScope.$$postDigest(function() {
+ performAnimation('move', 'ng-move', element, null, null, function() {
+ done && $timeout(done, 0, false);
+ });
+ });
},
/**
@@ -369,15 +378,16 @@
* @description
* Triggers a custom animation event based off the className variable and then attaches the className value to the element as a CSS class.
* Unlike the other animation methods, the animate service will suffix the className value with {@type -add} in order to provide
- * the animate service the setup and active CSS classes in order to trigger the animation.
+ * the animate service the setup and active CSS classes in order to trigger the animation (this will be skipped if no CSS transitions
+ * or keyframes are defined on the -add CSS class).
*
* Below is a breakdown of each step that occurs during addClass animation:
*
* | Animation Step | What the element class attribute looks like |
* |------------------------------------------------------------------------------------------------|---------------------------------------------|
* | 1. $animate.addClass(element, 'super') is called | class="" |
- * | 2. the .super-add class is added to the element | class="super-add" |
- * | 3. $animate runs any JavaScript-defined animations on the element | class="super-add" |
+ * | 2. $animate runs any JavaScript-defined animations on the element | class="" |
+ * | 3. the .super-add class is added to the element | class="super-add" |
* | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="super-add" |
* | 5. the .super-add-active class is added (this triggers the CSS transition/animation) | class="super-add super-add-active" |
* | 6. $animate waits for X milliseconds for the animation to complete | class="super-add super-add-active" |
@@ -403,15 +413,16 @@
* @description
* Triggers a custom animation event based off the className variable and then removes the CSS class provided by the className value
* from the element. Unlike the other animation methods, the animate service will suffix the className value with {@type -remove} in
- * order to provide the animate service the setup and active CSS classes in order to trigger the animation.
+ * order to provide the animate service the setup and active CSS classes in order to trigger the animation (this will be skipped if
+ * no CSS transitions or keyframes are defined on the -remove CSS class).
*
* Below is a breakdown of each step that occurs during removeClass animation:
*
* | Animation Step | What the element class attribute looks like |
* |-----------------------------------------------------------------------------------------------|-------------------------------------------------|
* | 1. $animate.removeClass(element, 'super') is called | class="super" |
- * | 2. the .super-remove class is added to the element | class="super super-remove" |
- * | 3. $animate runs any JavaScript-defined animations on the element | class="super super-remove" |
+ * | 2. $animate runs any JavaScript-defined animations on the element | class="super" |
+ * | 3. the .super-remove class is added to the element | class="super super-remove" |
* | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="super super-remove" |
* | 5. the .super-remove-active class is added (this triggers the CSS transition/animation) | class="super super-remove super-remove-active" |
* | 6. $animate waits for X milliseconds for the animation to complete | class="super super-remove super-remove-active" |
@@ -496,15 +507,6 @@
done:done
});
- var baseClassName = className;
- if(event == 'addClass') {
- className = suffixClasses(className, '-add');
- } else if(event == 'removeClass') {
- className = suffixClasses(className, '-remove');
- }
-
- element.addClass(className);
-
forEach(animations, function(animation, index) {
var fn = function() {
progress(index);
@@ -512,7 +514,7 @@
if(animation.start) {
if(event == 'addClass' || event == 'removeClass') {
- animation.endFn = animation.start(element, baseClassName, fn);
+ animation.endFn = animation.start(element, className, fn);
} else {
animation.endFn = animation.start(element, fn);
}
@@ -540,7 +542,6 @@
function done() {
if(!done.hasBeenRun) {
done.hasBeenRun = true;
- element.removeClass(className);
element.removeData(NG_ANIMATE_STATE);
(onComplete || noop)();
}
@@ -551,94 +552,125 @@
$animateProvider.register('', ['$window','$sniffer', '$timeout', function($window, $sniffer, $timeout) {
var noop = angular.noop;
var forEach = angular.forEach;
+
+ //one day all browsers will have these properties
+ var w3cAnimationProp = 'animation';
+ var w3cTransitionProp = 'transition';
+
+ //but some still use vendor-prefixed styles
+ var vendorAnimationProp = $sniffer.vendorPrefix + 'Animation';
+ var vendorTransitionProp = $sniffer.vendorPrefix + 'Transition';
+
+ var durationKey = 'Duration',
+ delayKey = 'Delay',
+ propertyKey = 'Property',
+ animationIterationCountKey = 'IterationCount',
+ ELEMENT_NODE = 1;
+
function animate(element, className, done) {
if (!($sniffer.transitions || $sniffer.animations)) {
done();
- } else {
- var activeClassName = '';
- $timeout(startAnimation, 1, false);
-
- //this acts as the cancellation function in case
- //a new animation is triggered while another animation
- //is still going on (otherwise the active className
- //would still hang around until the timer is complete).
- return onEnd;
+ return;
}
-
- function parseMaxTime(str) {
- var total = 0, values = angular.isString(str) ? str.split(/\s*,\s*/) : [];
- forEach(values, function(value) {
- total = Math.max(parseFloat(value) || 0, total);
+ else if(['ng-enter','ng-leave','ng-move'].indexOf(className) == -1) {
+ var existingDuration = 0;
+ forEach(element, function(element) {
+ if (element.nodeType == ELEMENT_NODE) {
+ var elementStyles = $window.getComputedStyle(element) || {};
+ existingDuration = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + durationKey]),
+ parseMaxTime(elementStyles[vendorTransitionProp + durationKey]),
+ existingDuration);
+ }
});
- return total;
+ if(existingDuration > 0) {
+ done();
+ return;
+ }
}
- function startAnimation() {
- var duration = 0;
- forEach(className.split(' '), function(klass, i) {
- activeClassName += (i > 0 ? ' ' : '') + klass + '-active';
- });
+ element.addClass(className);
- element.addClass(activeClassName);
+ //we want all the styles defined before and after
+ var duration = 0;
+ forEach(element, function(element) {
+ if (element.nodeType == ELEMENT_NODE) {
+ var elementStyles = $window.getComputedStyle(element) || {};
- //one day all browsers will have these properties
- var w3cAnimationProp = 'animation';
- var w3cTransitionProp = 'transition';
+ var transitionDelay = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + delayKey]),
+ parseMaxTime(elementStyles[vendorTransitionProp + delayKey]));
- //but some still use vendor-prefixed styles
- var vendorAnimationProp = $sniffer.vendorPrefix + 'Animation';
- var vendorTransitionProp = $sniffer.vendorPrefix + 'Transition';
+ var animationDelay = Math.max(parseMaxTime(elementStyles[w3cAnimationProp + delayKey]),
+ parseMaxTime(elementStyles[vendorAnimationProp + delayKey]));
- var durationKey = 'Duration',
- delayKey = 'Delay',
- animationIterationCountKey = 'IterationCount';
+ var transitionDuration = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + durationKey]),
+ parseMaxTime(elementStyles[vendorTransitionProp + durationKey]));
- //we want all the styles defined before and after
- var ELEMENT_NODE = 1;
- forEach(element, function(element) {
- if (element.nodeType == ELEMENT_NODE) {
- var elementStyles = $window.getComputedStyle(element) || {};
+ var animationDuration = Math.max(parseMaxTime(elementStyles[w3cAnimationProp + durationKey]),
+ parseMaxTime(elementStyles[vendorAnimationProp + durationKey]));
- var transitionDelay = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + delayKey]),
- parseMaxTime(elementStyles[vendorTransitionProp + delayKey]));
+ if(animationDuration > 0) {
+ animationDuration *= Math.max(parseInt(elementStyles[w3cAnimationProp + animationIterationCountKey]) || 0,
+ parseInt(elementStyles[vendorAnimationProp + animationIterationCountKey]) || 0,
+ 1);
+ }
- var animationDelay = Math.max(parseMaxTime(elementStyles[w3cAnimationProp + delayKey]),
- parseMaxTime(elementStyles[vendorAnimationProp + delayKey]));
+ duration = Math.max(animationDelay + animationDuration,
+ transitionDelay + transitionDuration,
+ duration);
+ }
+ });
- var transitionDuration = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + durationKey]),
- parseMaxTime(elementStyles[vendorTransitionProp + durationKey]));
+ /* there is no point in performing a reflow if the animation
+ timeout is empty (this would cause a flicker bug normally
+ in the page */
+ if(duration > 0) {
+ var node = element[0];
- var animationDuration = Math.max(parseMaxTime(elementStyles[w3cAnimationProp + durationKey]),
- parseMaxTime(elementStyles[vendorAnimationProp + durationKey]));
+ //temporarily disable the transition so that the enter styles
+ //don't animate twice (this is here to avoid a bug in Chrome/FF).
+ node.style[w3cTransitionProp + propertyKey] = 'none';
+ node.style[vendorTransitionProp + propertyKey] = 'none';
- if(animationDuration > 0) {
- animationDuration *= Math.max(parseInt(elementStyles[w3cAnimationProp + animationIterationCountKey]) || 0,
- parseInt(elementStyles[vendorAnimationProp + animationIterationCountKey]) || 0,
- 1);
- }
-
- duration = Math.max(animationDelay + animationDuration,
- transitionDelay + transitionDuration,
- duration);
- }
+ var activeClassName = '';
+ forEach(className.split(' '), function(klass, i) {
+ activeClassName += (i > 0 ? ' ' : '') + klass + '-active';
});
+ //this triggers a reflow which allows for the transition animation to kick in
+ element.prop('clientWidth');
+ node.style[w3cTransitionProp + propertyKey] = '';
+ node.style[vendorTransitionProp + propertyKey] = '';
+ element.addClass(activeClassName);
+
$timeout(done, duration * 1000, false);
- }
- //this will automatically be called by $animate so
- //there is no need to attach this internally to the
- //timeout done method
- function onEnd(cancelled) {
- element.removeClass(activeClassName);
+ //this will automatically be called by $animate so
+ //there is no need to attach this internally to the
+ //timeout done method
+ return function onEnd(cancelled) {
+ element.removeClass(className);
+ element.removeClass(activeClassName);
- //only when the animation is cancelled is the done()
- //function not called for this animation therefore
- //this must be also called
- if(cancelled) {
- done();
+ //only when the animation is cancelled is the done()
+ //function not called for this animation therefore
+ //this must be also called
+ if(cancelled) {
+ done();
+ }
}
}
+ else {
+ element.removeClass(className);
+ done();
+ }
+
+ function parseMaxTime(str) {
+ var total = 0, values = angular.isString(str) ? str.split(/\s*,\s*/) : [];
+ forEach(values, function(value) {
+ total = Math.max(parseFloat(value) || 0, total);
+ });
+ return total;
+ }
}
return {
@@ -659,18 +691,17 @@
}
};
+ function suffixClasses(classes, suffix) {
+ var className = '';
+ classes = angular.isArray(classes) ? classes : classes.split(/\s+/);
+ forEach(classes, function(klass, i) {
+ if(klass && klass.length > 0) {
+ className += (i > 0 ? ' ' : '') + klass + suffix;
+ }
+ });
+ return className;
+ }
}]);
-
- function suffixClasses(classes, suffix) {
- var className = '';
- classes = angular.isArray(classes) ? classes : classes.split(/\s+/);
- forEach(classes, function(klass, i) {
- if(klass && klass.length > 0) {
- className += (i > 0 ? ' ' : '') + klass + suffix;
- }
- });
- return className;
- }
}]);
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-cookies.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-cookies.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-cookies.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +1,5 @@
/** %%Ignore-License
- * @license AngularJS v1.2.0rc1
+ * @license AngularJS v1.2.0-rc.2
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -8,6 +8,17 @@
/**
* @ngdoc overview
* @name ngCookies
+ * @description
+ *
+ * # ngCookies
+ *
+ * Provides the {@link ngCookies.$cookies `$cookies`} and
+ * {@link ngCookies.$cookieStore `$cookieStore`} services.
+ *
+ * {@installModule cookies}
+ *
+ * See {@link ngCookies.$cookies `$cookies`} and
+ * {@link ngCookies.$cookieStore `$cookieStore`} for usage.
*/
@@ -23,6 +34,8 @@
* Only a simple Object is exposed and by adding or removing properties to/from
* this object, new cookies are created/deleted at the end of current $eval.
*
+ * Requires the {@link ngCookies `ngCookies`} module to be installed.
+ *
* @example
<doc:example>
<doc:source>
@@ -127,6 +140,9 @@
* Provides a key-value (string-object) storage, that is backed by session cookies.
* Objects put or retrieved from this storage are automatically serialized or
* deserialized by angular's toJson/fromJson.
+ *
+ * Requires the {@link ngCookies `ngCookies`} module to be installed.
+ *
* @example
*/
factory('$cookieStore', ['$cookies', function($cookies) {
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-loader.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-loader.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-loader.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +1,5 @@
/** %%Ignore-License
- * @license AngularJS v1.2.0rc1
+ * @license AngularJS v1.2.0-rc.2
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -29,11 +29,14 @@
* @name angular.module
* @description
*
- * The `angular.module` is a global place for creating and registering Angular modules. All
- * modules (angular core or 3rd party) that should be available to an application must be
+ * The `angular.module` is a global place for creating, registering and retrieving Angular modules.
+ * All modules (angular core or 3rd party) that should be available to an application must be
* registered using this mechanism.
*
+ * When passed two or more arguments, a new module is created. If passed only one argument, an
+ * existing module (the name passed as the first argument to `module`) is retrieved.
*
+ *
* # Module
*
* A module is a collection of services, directives, filters, and configuration information.
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-mocks.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-mocks.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-mocks.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +1,5 @@
/** %%Ignore-License
- * @license AngularJS v1.2.0rc1
+ * @license AngularJS v1.2.0-rc.2
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*
@@ -316,7 +316,7 @@
}
this.debugEnabled = function(flag) {
- if (isDefined(flag)) {
+ if (angular.isDefined(flag)) {
debug = flag;
return this;
} else {
@@ -1851,9 +1851,11 @@
*
* See {@link angular.mock.inject inject} for usage example
*
- * @param {...(string|Function)} fns any number of modules which are represented as string
+ * @param {...(string|Function|Object)} fns any number of modules which are represented as string
* aliases or as anonymous module initialization functions. The modules are used to
- * configure the injector. The 'ng' and 'ngMock' modules are automatically loaded.
+ * configure the injector. The 'ng' and 'ngMock' modules are automatically loaded. If an
+ * object literal is passed they will be register as values in the module, the key being
+ * the module name and the value being what is returned.
*/
window.module = angular.mock.module = function() {
var moduleFns = Array.prototype.slice.call(arguments, 0);
@@ -1865,7 +1867,15 @@
} else {
var modules = currentSpec.$modules || (currentSpec.$modules = []);
angular.forEach(moduleFns, function(module) {
- modules.push(module);
+ if (angular.isObject(module) && !angular.isArray(module)) {
+ modules.push(function($provide) {
+ angular.forEach(module, function(value, key) {
+ $provide.value(key, value);
+ });
+ });
+ } else {
+ modules.push(module);
+ }
});
}
}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-resource.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-resource.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-resource.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +1,5 @@
/** %%Ignore-License
- * @license AngularJS v1.2.0rc1
+ * @license AngularJS v1.2.0-rc.2
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -11,6 +11,16 @@
* @ngdoc overview
* @name ngResource
* @description
+ *
+ * # ngResource
+ *
+ * `ngResource` is the name of the optional Angular module that adds support for interacting with
+ * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.
+ * `ngReource` provides the {@link ngResource.$resource `$resource`} serivce.
+ *
+ * {@installModule resource}
+ *
+ * See {@link ngResource.$resource `$resource`} for usage.
*/
/**
@@ -25,23 +35,14 @@
* The returned resource object has action methods which provide high-level behaviors without
* the need to interact with the low level {@link ng.$http $http} service.
*
- * # Installation
- * To use $resource make sure you have included the `angular-resource.js` that comes in Angular
- * package. You can also find this file on Google CDN, bower as well as at
- * {@link http://code.angularjs.org/ code.angularjs.org}.
+ * Requires the {@link ngResource `ngResource`} module to be installed.
*
- * Finally load the module in your application:
- *
- * angular.module('app', ['ngResource']);
- *
- * and you are ready to get started!
- *
* @param {string} url A parametrized URL template with parameters prefixed by `:` as in
* `/user/:username`. If you are using a URL with a port number (e.g.
* `http://example.com:8080/api`), it will be respected.
*
* If you are using a url with a suffix, just add the suffix, like this:
- * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')
+ * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`
* or even `$resource('http://example.com/resource/:resource_id.:format')`
* If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
* collapsed down to a single `.`. If you need this sequence to appear and not collapse then you
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-route.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-route.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-route.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +1,5 @@
/** %%Ignore-License
- * @license AngularJS v1.2.0rc1
+ * @license AngularJS v1.2.0-rc.2
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -26,7 +26,12 @@
* @name ngRoute
* @description
*
- * Module that provides routing and deeplinking services and directives for angular apps.
+ * # ngRoute
+ *
+ * The `ngRoute` module provides routing and deeplinking services and directives for angular apps.
+ *
+ * {@installModule route}
+ *
*/
var ngRouteModule = angular.module('ngRoute', ['ng']).
@@ -40,6 +45,8 @@
* @description
*
* Used for configuring routes. See {@link ngRoute.$route $route} for an example.
+ *
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
*/
function $RouteProvider(){
var routes = {};
@@ -57,8 +64,8 @@
* * `path` can contain named groups starting with a colon (`:name`). All characters up
* to the next slash are matched and stored in `$routeParams` under the given `name`
* when the route matches.
- * * `path` can contain named groups starting with a colon and ending with a star (`:name*`).
- * All characters are eagerly stored in `$routeParams` under the given `name`
+ * * `path` can contain named groups starting with a colon and ending with a star (`:name*`).
+ * All characters are eagerly stored in `$routeParams` under the given `name`
* when the route matches.
* * `path` can contain optional named groups with a question mark (`:name?`).
*
@@ -149,8 +156,8 @@
// create redirection for trailing slashes
if (path) {
var redirectPath = (path[path.length-1] == '/')
- ? path.substr(0, path.length-1)
- : path +'/';
+ ? path.substr(0, path.length-1)
+ : path +'/';
routes[redirectPath] = extend(
{redirectTo: path},
@@ -241,13 +248,15 @@
* @property {Array.<Object>} routes Array of all configured routes.
*
* @description
- * Is used for deep-linking URLs to controllers and views (HTML partials).
+ * `$route` is used for deep-linking URLs to controllers and views (HTML partials).
* It watches `$location.url()` and tries to map the path to an existing route definition.
*
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
* You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API.
*
- * The `$route` service is typically used in conjunction with {@link ngRoute.directive:ngView ngView}
- * directive and the {@link ngRoute.$routeParams $routeParams} service.
+ * The `$route` service is typically used in conjunction with the {@link ngRoute.directive:ngView `ngView`}
+ * directive and the {@link ngRoute.$routeParams `$routeParams`} service.
*
* @example
This example shows how changing the URL hash causes the `$route` to match a route against the
@@ -449,13 +458,12 @@
var m = route.regexp.exec(on);
if (!m) return null;
- var N = 0;
for (var i = 1, len = m.length; i < len; ++i) {
var key = keys[i - 1];
var val = 'string' == typeof m[i]
- ? decodeURIComponent(m[i])
- : m[i];
+ ? decodeURIComponent(m[i])
+ : m[i];
if (key && val) {
params[key.name] = val;
@@ -562,7 +570,7 @@
function interpolate(string, params) {
var result = [];
forEach((string||'').split(':'), function(segment, i) {
- if (i == 0) {
+ if (i === 0) {
result.push(segment);
} else {
var segmentMatch = segment.match(/(\w+)(.*)/);
@@ -586,10 +594,14 @@
* @requires $route
*
* @description
- * Current set of route parameters. The route parameters are a combination of the
- * {@link ng.$location $location} `search()`, and `path()`. The `path` parameters
- * are extracted when the {@link ngRoute.$route $route} path is matched.
+ * The `$routeParams` service allows you to retrieve the current set of route parameters.
*
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
+ * The route parameters are a combination of {@link ng.$location `$location`}'s
+ * {@link ng.$location#search `search()`} and {@link ng.$location#path `path()`}.
+ * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched.
+ *
* In case of parameter name collision, `path` params take precedence over `search` params.
*
* The service guarantees that the identity of the `$routeParams` object will remain unchanged
@@ -613,6 +625,8 @@
this.$get = function() { return {}; };
}
+ngRouteModule.directive('ngView', ngViewFactory);
+
/**
* @ngdoc directive
* @name ngRoute.directive:ngView
@@ -625,6 +639,8 @@
* Every time the current route changes, the included view changes with it according to the
* configuration of the `$route` service.
*
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
* @animations
* enter - animation is used to bring new content into the browser.
* leave - animation is used to animate existing content away.
@@ -780,23 +796,19 @@
* @description
* Emitted every time the ngView content is reloaded.
*/
-var NG_VIEW_PRIORITY = 500;
-var ngViewDirective = ['$route', '$anchorScroll', '$compile', '$controller', '$animate',
- function($route, $anchorScroll, $compile, $controller, $animate) {
+ngViewFactory.$inject = ['$route', '$anchorScroll', '$compile', '$controller', '$animate'];
+function ngViewFactory( $route, $anchorScroll, $compile, $controller, $animate) {
return {
restrict: 'ECA',
terminal: true,
- priority: NG_VIEW_PRIORITY,
- compile: function(element, attr) {
- var onloadExp = attr.onload || '';
+ priority: 1000,
+ transclude: 'element',
+ compile: function(element, attr, linker) {
+ return function(scope, $element, attr) {
+ var currentScope,
+ currentElement,
+ onloadExp = attr.onload || '';
- element.html('');
- var anchor = jqLite(document.createComment(' ngView '));
- element.replaceWith(anchor);
-
- return function(scope) {
- var currentScope, currentElement;
-
scope.$on('$routeChangeSuccess', update);
update();
@@ -816,35 +828,36 @@
template = locals && locals.$template;
if (template) {
- cleanupLastView();
+ var newScope = scope.$new();
+ linker(newScope, function(clone) {
+ cleanupLastView();
- currentScope = scope.$new();
- currentElement = element.clone();
- currentElement.html(template);
- $animate.enter(currentElement, null, anchor);
+ clone.html(template);
+ $animate.enter(clone, null, $element);
- var link = $compile(currentElement, false, NG_VIEW_PRIORITY - 1),
- current = $route.current;
+ var link = $compile(clone.contents()),
+ current = $route.current;
- if (current.controller) {
- locals.$scope = currentScope;
- var controller = $controller(current.controller, locals);
- if (current.controllerAs) {
- currentScope[current.controllerAs] = controller;
+ currentScope = current.scope = newScope;
+ currentElement = clone;
+
+ if (current.controller) {
+ locals.$scope = currentScope;
+ var controller = $controller(current.controller, locals);
+ if (current.controllerAs) {
+ currentScope[current.controllerAs] = controller;
+ }
+ clone.data('$ngControllerController', controller);
+ clone.contents().data('$ngControllerController', controller);
}
- currentElement.data('$ngControllerController', controller);
- currentElement.children().data('$ngControllerController', controller);
- }
- current.scope = currentScope;
+ link(currentScope);
+ currentScope.$emit('$viewContentLoaded');
+ currentScope.$eval(onloadExp);
- link(currentScope);
-
- currentScope.$emit('$viewContentLoaded');
- currentScope.$eval(onloadExp);
-
- // $anchorScroll might listen on event...
- $anchorScroll();
+ // $anchorScroll might listen on event...
+ $anchorScroll();
+ });
} else {
cleanupLastView();
}
@@ -852,9 +865,7 @@
}
}
};
-}];
+}
-ngRouteModule.directive('ngView', ngViewDirective);
-
})(window, window.angular);
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-sanitize.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-sanitize.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-sanitize.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +1,5 @@
/** %%Ignore-License
- * @license AngularJS v1.2.0rc1
+ * @license AngularJS v1.2.0-rc.2
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -11,25 +11,14 @@
* @ngdoc overview
* @name ngSanitize
* @description
- *
- * The `ngSanitize` module provides functionality to sanitize HTML.
- *
- * # Installation
- * As a separate module, it must be loaded after Angular core is loaded; otherwise, an 'Uncaught Error:
- * No module: ngSanitize' runtime error will occur.
*
- * <pre>
- * <script src="angular.js"></script>
- * <script src="angular-sanitize.js"></script>
- * </pre>
+ * # ngSanitize
*
- * # Usage
- * To make sure the module is available to your application, declare it as a dependency of you application
- * module.
+ * The `ngSanitize` module provides functionality to sanitize HTML.
*
- * <pre>
- * angular.module('app', ['ngSanitize']);
- * </pre>
+ * {@installModule sanitize}
+ *
+ * See {@link ngSanitize.$sanitize `$sanitize`} for usage.
*/
/*
@@ -429,9 +418,11 @@
* @function
*
* @description
- * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
- * plain email address links.
+ * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
+ * plain email address links.
*
+ * Requires the {@link ngSanitize `ngSanitize`} module to be installed.
+ *
* @param {string} text Input text.
* @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in.
* @returns {string} Html-linkified text.
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-touch.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-touch.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-touch.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +1,5 @@
-/** %%Ignore-License
- * @license AngularJS v1.2.0rc1
+/**
+ * @license AngularJS v1.2.0-rc.2
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -9,8 +9,17 @@
* @ngdoc overview
* @name ngTouch
* @description
- * Touch events and other mobile helpers.
- * Based on jQuery Mobile touch event handling (jquerymobile.com)
+ *
+ * # ngTouch
+ *
+ * `ngTouch` is the name of the optional Angular module that provides touch events and other
+ * helpers for touch-enabled devices.
+ * The implementation is based on jQuery Mobile touch event handling
+ * ([jquerymobile.com](http://jquerymobile.com/))
+ *
+ * {@installModule touch}
+ *
+ * See {@link ngTouch.$swipe `$swipe`} for usage.
*/
// define ngTouch module
@@ -24,7 +33,9 @@
* The `$swipe` service is a service that abstracts the messier details of hold-and-drag swipe
* behavior, to make implementing swipe-related directives more convenient.
*
- * It is used by the `ngSwipeLeft` and `ngSwipeRight` directives in `ngTouch`, and by
+ * Requires the {@link ngTouch `ngTouch`} module to be installed.
+ *
+ * `$swipe` is used by the `ngSwipeLeft` and `ngSwipeRight` directives in `ngTouch`, and by
* `ngCarousel` in a separate component.
*
* # Usage
@@ -159,6 +170,8 @@
* the click event. This version handles them immediately, and then prevents the
* following click event from propagating.
*
+ * Requires the {@link ngTouch `ngTouch`} module to be installed.
+ *
* This directive can fall back to using an ordinary click event, and so works on desktop
* browsers as well as mobile.
*
@@ -428,6 +441,8 @@
* A leftward swipe is a quick, right-to-left slide of the finger.
* Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag too.
*
+ * Requires the {@link ngTouch `ngTouch`} module to be installed.
+ *
* @element ANY
* @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate
* upon left swipe. (Event object is available as `$event`)
@@ -455,6 +470,8 @@
* A rightward swipe is a quick, left-to-right slide of the finger.
* Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag too.
*
+ * Requires the {@link ngTouch `ngTouch`} module to be installed.
+ *
* @element ANY
* @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate
* upon right swipe. (Event object is available as `$event`)
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_chr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_chr.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_chr.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {"DATETIME_FORMATS":{"MONTH":["ᎤᏃᎸᏔᏅ","ᎧᎦᎵ","ᎠᏅᏱ","ᎧᏬᏂ","ᎠᏂᏍᎬᏘ","ᏕᎭᎷᏱ","ᎫᏰᏉᏂ","ᎦᎶᏂ","ᏚᎵᏍᏗ","ᏚᏂᏅᏗ","ᏅᏓᏕᏆ","ᎤᏍᎩᏱ"],"SHORTMONTH":["ᎤᏃ","ᎧᎦ","ᎠᏅ","ᎧᏬ","ᎠᏂ","ᏕᎭ","ᎫᏰ","ᎦᎶ","ᏚᎵ","ᏚᏂ","ᏅᏓ","ᎤᏍ"],"DAY":["ᎤᎾᏙᏓᏆᏍᎬ","ᎤᎾᏙᏓᏉᏅᎯ","ᏔᎵᏁᎢᎦ","ᏦᎢᏁᎢᎦ","ᏅᎩᏁᎢᎦ","ᏧᎾᎩᎶᏍᏗ","ᎤᎾᏙᏓᏈᏕᎾ"],"SHORTDAY":["ᏆᏍᎬ","ᏉᏅᎯ","ᏔᎵᏁ","ᏦᎢᏁ","ᏅᎩᏁ","ᏧᎾᎩ","ᏈᏕᎾ"],"AMPMS":["ᏌᎾᎴ","ᏒᎯᏱᎢᏗᏢ"],"medium":"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a","fullDate":"EEEE, MMMM d, y","longDate":"MMMM d, y","mediumDate":"MMM d, y","shortDate":"M/d/yy","mediumTime":"h:mm:ss a","shortTime":"h:mm a"},"pluralCat":function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;},"id":"chr"});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cy.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cy.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cy.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {"DATETIME_FORMATS":{"MONTH":["Ionawr","Chwefror","Mawrth","Ebrill","Mai","Mehefin","Gorffenaf","Awst","Medi","Hydref","Tachwedd","Rhagfyr"],"SHORTMONTH":["Ion","Chwef","Mawrth","Ebrill","Mai","Meh","Gorff","Awst","Medi","Hyd","Tach","Rhag"],"DAY":["Dydd Sul","Dydd Llun","Dydd Mawrth","Dydd Mercher","Dydd Iau","Dydd Gwener","Dydd Sadwrn"],"SHORTDAY":["Sul","Llun","Maw","Mer","Iau","Gwen","Sad"],"AMPMS":["AM","PM"],"medium":"d MMM y HH:mm:ss","short":"dd/MM/yyyy HH:mm","fullDate":"EEEE, d MMMM y","longDate":"d MMMM y","mediumDate":"d MMM y","shortDate":"dd/MM/yyyy","mediumTime":"HH:mm:ss","shortTime":"HH:mm"},"pluralCat":function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;},"id":"cy"});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-polyton.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-polyton.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-polyton.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {"NUMBER_FORMATS":{"DECIMAL_SEP":",","GROUP_SEP":".","PATTERNS":[{"minInt":1,"minFrac":0,"macFrac":0,"posPre":"","posSuf":"","negPre":"-","negSuf":"","gSize":3,"lgSize":3,"maxFrac":3},{"minInt":1,"minFrac":2,"macFrac":0,"posPre":"","posSuf":" \u00A4","negPre":"-","negSuf":" \u00A4","gSize":3,"lgSize":3,"maxFrac":2}],"CURRENCY_SYM":"€"},"pluralCat":function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;},"DATETIME_FORMATS":{"MONTH":["Ιανουαρίου","Φεβρουαρίου","Μαρτίου","Απριλίου","Μαΐου","Ιουνίου","Ιουλίου","Αυγούστου","Σεπτεμβρίου","Οκτωβρίου","Νοεμβρίου","Δεκεμβρίου"],"SHORTMONTH":["Ιαν","Φεβ","Μαρ","Απρ","Μαϊ","Ιουν","Ιουλ","Αυγ","Σεπ","Οκτ","Νοε","Δεκ"],"DAY":["Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Σάββατο"],"SHORTDAY":["Κυρ","Δευ","Τρι","Τετ","Πεμ","Παρ","Σαβ"],"AMPMS":["π.μ.","μ.μ."],"medium":"d MMM y h:mm:ss a","short":"d/M/yy h:mm a","fullDate":"EEEE, d MMMM y","longDate":"d MMMM y","mediumDate":"d MMM y","shortDate":"d/M/yy","mediumTime":"h:mm:ss a","shortTime":"h:mm a"},"id":"el-polyton"});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-zz.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-zz.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-zz.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {"NUMBER_FORMATS":{"DECIMAL_SEP":".","GROUP_SEP":",","PATTERNS":[{"minInt":1,"minFrac":0,"macFrac":0,"posPre":"","posSuf":"","negPre":"-","negSuf":"","gSize":3,"lgSize":3,"maxFrac":3},{"minInt":1,"minFrac":2,"macFrac":0,"posPre":"\u00A4","posSuf":"","negPre":"(\u00A4","negSuf":")","gSize":3,"lgSize":3,"maxFrac":2}],"CURRENCY_SYM":"$"},"pluralCat":function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;},"DATETIME_FORMATS":{"MONTH":["January","February","March","April","May","June","July","August","September","October","November","December"],"SHORTMONTH":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"DAY":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"SHORTDAY":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"AMPMS":["AM","PM"],"medium":"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a","fullDate":"EEEE, MMMM d, y","longDate":"MMMM d, y","mediumDate":"MMM d, y","shortDate":"M/d/yy","mediumTime":"h:mm:ss a","shortTime":"h:mm a"},"id":"en-zz"});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-rw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-rw.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-rw.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
- "fullDate": "EEEE d MMMM y",
- "longDate": "d MMMM y",
- "medium": "d MMM y HH:mm:ss",
- "mediumDate": "d MMM y",
- "mediumTime": "HH:mm:ss",
- "short": "dd/MM/yy HH:mm",
- "shortDate": "dd/MM/yy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "\u20ac",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(",
- "negSuf": "\u00a0\u00a4)",
- "posPre": "",
- "posSuf": "\u00a0\u00a4"
- }
- }
- },
- "id": "fr-rw",
- "pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-sn.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-sn.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-sn.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
- "fullDate": "EEEE d MMMM y",
- "longDate": "d MMMM y",
- "medium": "d MMM y HH:mm:ss",
- "mediumDate": "d MMM y",
- "mediumTime": "HH:mm:ss",
- "short": "dd/MM/yy HH:mm",
- "shortDate": "dd/MM/yy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "\u20ac",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(",
- "negSuf": "\u00a0\u00a4)",
- "posPre": "",
- "posSuf": "\u00a0\u00a4"
- }
- }
- },
- "id": "fr-sn",
- "pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-td.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-td.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-td.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
- "fullDate": "EEEE d MMMM y",
- "longDate": "d MMMM y",
- "medium": "d MMM y HH:mm:ss",
- "mediumDate": "d MMM y",
- "mediumTime": "HH:mm:ss",
- "short": "dd/MM/yy HH:mm",
- "shortDate": "dd/MM/yy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "\u20ac",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(",
- "negSuf": "\u00a0\u00a4)",
- "posPre": "",
- "posSuf": "\u00a0\u00a4"
- }
- }
- },
- "id": "fr-td",
- "pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-tg.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-tg.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-tg.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "février",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "août",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "décembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "févr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "août",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "déc."
- },
- "fullDate": "EEEE d MMMM y",
- "longDate": "d MMMM y",
- "medium": "d MMM y HH:mm:ss",
- "mediumDate": "d MMM y",
- "mediumTime": "HH:mm:ss",
- "short": "dd/MM/yy HH:mm",
- "shortDate": "dd/MM/yy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "€",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": " ",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(",
- "negSuf": " \u00A4)",
- "posPre": "",
- "posSuf": " \u00A4"
- }
- }
- },
- "id": "fr-tg",
- "pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_haw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_haw.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_haw.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {"DATETIME_FORMATS":{"MONTH":["Ianuali","Pepeluali","Malaki","ʻApelila","Mei","Iune","Iulai","ʻAukake","Kepakemapa","ʻOkakopa","Nowemapa","Kekemapa"],"SHORTMONTH":["Ian.","Pep.","Mal.","ʻAp.","Mei","Iun.","Iul.","ʻAu.","Kep.","ʻOk.","Now.","Kek."],"DAY":["Lāpule","Poʻakahi","Poʻalua","Poʻakolu","Poʻahā","Poʻalima","Poʻaono"],"SHORTDAY":["LP","P1","P2","P3","P4","P5","P6"],"AMPMS":["AM","PM"],"medium":"d MMM y h:mm:ss a","short":"d/M/yy h:mm a","fullDate":"EEEE, d MMMM y","longDate":"d MMMM y","mediumDate":"d MMM y","shortDate":"d/M/yy","mediumTime":"h:mm:ss a","shortTime":"h:mm a"},"pluralCat":function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;},"id":"haw"});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-ch.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-ch.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-ch.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "m.",
- "1": "p."
- },
- "DAY": {
- "0": "domenica",
- "1": "lunedì",
- "2": "martedì",
- "3": "mercoledì",
- "4": "giovedì",
- "5": "venerdì",
- "6": "sabato"
- },
- "MONTH": {
- "0": "gennaio",
- "1": "febbraio",
- "2": "marzo",
- "3": "aprile",
- "4": "maggio",
- "5": "giugno",
- "6": "luglio",
- "7": "agosto",
- "8": "settembre",
- "9": "ottobre",
- "10": "novembre",
- "11": "dicembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mer",
- "4": "gio",
- "5": "ven",
- "6": "sab"
- },
- "SHORTMONTH": {
- "0": "gen",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "mag",
- "5": "giu",
- "6": "lug",
- "7": "ago",
- "8": "set",
- "9": "ott",
- "10": "nov",
- "11": "dic"
- },
- "fullDate": "EEEE, d MMMM y",
- "longDate": "d MMMM y",
- "medium": "d-MMM-y HH:mm:ss",
- "mediumDate": "d-MMM-y",
- "mediumTime": "HH:mm:ss",
- "short": "dd.MM.yy HH:mm",
- "shortDate": "dd.MM.yy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "€",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "\u00A4 -",
- "negSuf": "",
- "posPre": "\u00A4 ",
- "posSuf": ""
- }
- }
- },
- "id": "it-ch",
- "pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln-cg.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln-cg.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln-cg.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "ntɔ́ngɔ́",
- "1": "mpókwa"
- },
- "DAY": {
- "0": "eyenga",
- "1": "mokɔlɔ mwa yambo",
- "2": "mokɔlɔ mwa míbalé",
- "3": "mokɔlɔ mwa mísáto",
- "4": "mokɔlɔ ya mínéi",
- "5": "mokɔlɔ ya mítáno",
- "6": "mpɔ́sɔ"
- },
- "MONTH": {
- "0": "sánzá ya yambo",
- "1": "sánzá ya míbalé",
- "2": "sánzá ya mísáto",
- "3": "sánzá ya mínei",
- "4": "sánzá ya mítáno",
- "5": "sánzá ya motóbá",
- "6": "sánzá ya nsambo",
- "7": "sánzá ya mwambe",
- "8": "sánzá ya libwa",
- "9": "sánzá ya zómi",
- "10": "sánzá ya zómi na mɔ̌kɔ́",
- "11": "sánzá ya zómi na míbalé"
- },
- "SHORTDAY": {
- "0": "eye",
- "1": "ybo",
- "2": "mbl",
- "3": "mst",
- "4": "min",
- "5": "mtn",
- "6": "mps"
- },
- "SHORTMONTH": {
- "0": "yan",
- "1": "fbl",
- "2": "msi",
- "3": "apl",
- "4": "mai",
- "5": "yun",
- "6": "yul",
- "7": "agt",
- "8": "stb",
- "9": "ɔtb",
- "10": "nvb",
- "11": "dsb"
- },
- "fullDate": "EEEE d MMMM y",
- "longDate": "d MMMM y",
- "medium": "d MMM y HH:mm:ss",
- "mediumDate": "d MMM y",
- "mediumTime": "HH:mm:ss",
- "short": "d/M/yyyy HH:mm",
- "shortDate": "d/M/yyyy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "FrCD",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "-",
- "negSuf": " \u00A4",
- "posPre": "",
- "posSuf": " \u00A4"
- }
- }
- },
- "id": "ln-cg",
- "pluralCat": function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mo.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mo.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mo.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {"DATETIME_FORMATS":{"MONTH":["ianuarie","februarie","martie","aprilie","mai","iunie","iulie","august","septembrie","octombrie","noiembrie","decembrie"],"SHORTMONTH":["ian.","feb.","mar.","apr.","mai","iun.","iul.","aug.","sept.","oct.","nov.","dec."],"DAY":["duminică","luni","marți","miercuri","joi","vineri","sâmbătă"],"SHORTDAY":["Du","Lu","Ma","Mi","Jo","Vi","Sâ"],"AMPMS":["AM","PM"],"medium":"dd.MM.yyyy HH:mm:ss","short":"dd.MM.yyyy HH:mm","fullDate":"EEEE, d MMMM y","longDate":"d MMMM y","mediumDate":"dd.MM.yyyy","shortDate":"dd.MM.yyyy","mediumTime":"HH:mm:ss","shortTime":"HH:mm"},"NUMBER_FORMATS":{"DECIMAL_SEP":",","GROUP_SEP":".","PATTERNS":[{"minInt":1,"minFrac":0,"macFrac":0,"posPre":"","posSuf":"","negPre":"-","negSuf":"","gSize":3,"lgSize":3,"maxFrac":3},{"minInt":1,"minFrac":2,"macFrac":0,"posPre":"","posSuf":" \u00A4","negPre":"-","negSuf":" \u00A4","gSize":3,"lgSize":3,"maxFrac":2}],"CURRENCY_SYM":"MDL"},"pluralCat":function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 0 || n != 1 && (n % 100) >= 1 && (n % 100) <= 19 && n == Math.floor(n)) { return PLURAL_CATEGORY.FEW; } return PLURAL_CATEGORY.OTHER;},"id":"mo"});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms-bn.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms-bn.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms-bn.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "PG",
- "1": "PTG"
- },
- "DAY": {
- "0": "Ahad",
- "1": "Isnin",
- "2": "Selasa",
- "3": "Rabu",
- "4": "Khamis",
- "5": "Jumaat",
- "6": "Sabtu"
- },
- "MONTH": {
- "0": "Januari",
- "1": "Februari",
- "2": "Mac",
- "3": "April",
- "4": "Mei",
- "5": "Jun",
- "6": "Julai",
- "7": "Ogos",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Disember"
- },
- "SHORTDAY": {
- "0": "Ahd",
- "1": "Isn",
- "2": "Sel",
- "3": "Rab",
- "4": "Kha",
- "5": "Jum",
- "6": "Sab"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mac",
- "3": "Apr",
- "4": "Mei",
- "5": "Jun",
- "6": "Jul",
- "7": "Ogos",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dis"
- },
- "fullDate": "dd MMMM y",
- "longDate": "d MMMM y",
- "medium": "dd/MM/yyyy h:mm:ss a",
- "mediumDate": "dd/MM/yyyy",
- "mediumTime": "h:mm:ss a",
- "short": "d/MM/yy h:mm a",
- "shortDate": "d/MM/yy",
- "shortTime": "h:mm a"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "RM",
- "DECIMAL_SEP": ".",
- "GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "ms-bn",
- "pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-aw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-aw.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-aw.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "zondag",
- "1": "maandag",
- "2": "dinsdag",
- "3": "woensdag",
- "4": "donderdag",
- "5": "vrijdag",
- "6": "zaterdag"
- },
- "MONTH": {
- "0": "januari",
- "1": "februari",
- "2": "maart",
- "3": "april",
- "4": "mei",
- "5": "juni",
- "6": "juli",
- "7": "augustus",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "zo",
- "1": "ma",
- "2": "di",
- "3": "wo",
- "4": "do",
- "5": "vr",
- "6": "za"
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "feb.",
- "2": "mrt.",
- "3": "apr.",
- "4": "mei",
- "5": "jun.",
- "6": "jul.",
- "7": "aug.",
- "8": "sep.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
- "fullDate": "EEEE d MMMM y",
- "longDate": "d MMMM y",
- "medium": "d MMM y HH:mm:ss",
- "mediumDate": "d MMM y",
- "mediumTime": "HH:mm:ss",
- "short": "dd-MM-yy HH:mm",
- "shortDate": "dd-MM-yy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "€",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "\u00A4 ",
- "negSuf": "-",
- "posPre": "\u00A4 ",
- "posSuf": ""
- }
- }
- },
- "id": "nl-aw",
- "pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-be.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-be.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-be.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "zondag",
- "1": "maandag",
- "2": "dinsdag",
- "3": "woensdag",
- "4": "donderdag",
- "5": "vrijdag",
- "6": "zaterdag"
- },
- "MONTH": {
- "0": "januari",
- "1": "februari",
- "2": "maart",
- "3": "april",
- "4": "mei",
- "5": "juni",
- "6": "juli",
- "7": "augustus",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "zo",
- "1": "ma",
- "2": "di",
- "3": "wo",
- "4": "do",
- "5": "vr",
- "6": "za"
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "feb.",
- "2": "mrt.",
- "3": "apr.",
- "4": "mei",
- "5": "jun.",
- "6": "jul.",
- "7": "aug.",
- "8": "sep.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
- "fullDate": "EEEE d MMMM y",
- "longDate": "d MMMM y",
- "medium": "d-MMM-y HH:mm:ss",
- "mediumDate": "d-MMM-y",
- "mediumTime": "HH:mm:ss",
- "short": "d/MM/yy HH:mm",
- "shortDate": "d/MM/yy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "€",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "\u00A4 ",
- "negSuf": "-",
- "posPre": "\u00A4 ",
- "posSuf": ""
- }
- }
- },
- "id": "nl-be",
- "pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-ao.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-ao.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-ao.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "domingo",
- "1": "segunda-feira",
- "2": "terça-feira",
- "3": "quarta-feira",
- "4": "quinta-feira",
- "5": "sexta-feira",
- "6": "sábado"
- },
- "MONTH": {
- "0": "janeiro",
- "1": "fevereiro",
- "2": "março",
- "3": "abril",
- "4": "maio",
- "5": "junho",
- "6": "julho",
- "7": "agosto",
- "8": "setembro",
- "9": "outubro",
- "10": "novembro",
- "11": "dezembro"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "seg",
- "2": "ter",
- "3": "qua",
- "4": "qui",
- "5": "sex",
- "6": "sáb"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "fev",
- "2": "mar",
- "3": "abr",
- "4": "mai",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "set",
- "9": "out",
- "10": "nov",
- "11": "dez"
- },
- "fullDate": "EEEE, d 'de' MMMM 'de' y",
- "longDate": "d 'de' MMMM 'de' y",
- "medium": "dd/MM/yyyy HH:mm:ss",
- "mediumDate": "dd/MM/yyyy",
- "mediumTime": "HH:mm:ss",
- "short": "dd/MM/yy HH:mm",
- "shortDate": "dd/MM/yy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "R$",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "pt-ao",
- "pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-gw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-gw.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-gw.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "domingo",
- "1": "segunda-feira",
- "2": "terça-feira",
- "3": "quarta-feira",
- "4": "quinta-feira",
- "5": "sexta-feira",
- "6": "sábado"
- },
- "MONTH": {
- "0": "janeiro",
- "1": "fevereiro",
- "2": "março",
- "3": "abril",
- "4": "maio",
- "5": "junho",
- "6": "julho",
- "7": "agosto",
- "8": "setembro",
- "9": "outubro",
- "10": "novembro",
- "11": "dezembro"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "seg",
- "2": "ter",
- "3": "qua",
- "4": "qui",
- "5": "sex",
- "6": "sáb"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "fev",
- "2": "mar",
- "3": "abr",
- "4": "mai",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "set",
- "9": "out",
- "10": "nov",
- "11": "dez"
- },
- "fullDate": "EEEE, d 'de' MMMM 'de' y",
- "longDate": "d 'de' MMMM 'de' y",
- "medium": "dd/MM/yyyy HH:mm:ss",
- "mediumDate": "dd/MM/yyyy",
- "mediumTime": "HH:mm:ss",
- "short": "dd/MM/yy HH:mm",
- "shortDate": "dd/MM/yy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "R$",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "pt-gw",
- "pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-mz.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-mz.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-mz.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "domingo",
- "1": "segunda-feira",
- "2": "terça-feira",
- "3": "quarta-feira",
- "4": "quinta-feira",
- "5": "sexta-feira",
- "6": "sábado"
- },
- "MONTH": {
- "0": "janeiro",
- "1": "fevereiro",
- "2": "março",
- "3": "abril",
- "4": "maio",
- "5": "junho",
- "6": "julho",
- "7": "agosto",
- "8": "setembro",
- "9": "outubro",
- "10": "novembro",
- "11": "dezembro"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "seg",
- "2": "ter",
- "3": "qua",
- "4": "qui",
- "5": "sex",
- "6": "sáb"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "fev",
- "2": "mar",
- "3": "abr",
- "4": "mai",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "set",
- "9": "out",
- "10": "nov",
- "11": "dez"
- },
- "fullDate": "EEEE, d 'de' MMMM 'de' y",
- "longDate": "d 'de' MMMM 'de' y",
- "medium": "dd/MM/yyyy HH:mm:ss",
- "mediumDate": "dd/MM/yyyy",
- "mediumTime": "HH:mm:ss",
- "short": "dd/MM/yy HH:mm",
- "shortDate": "dd/MM/yy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "R$",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "pt-mz",
- "pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-st.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-st.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-st.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "domingo",
- "1": "segunda-feira",
- "2": "terça-feira",
- "3": "quarta-feira",
- "4": "quinta-feira",
- "5": "sexta-feira",
- "6": "sábado"
- },
- "MONTH": {
- "0": "janeiro",
- "1": "fevereiro",
- "2": "março",
- "3": "abril",
- "4": "maio",
- "5": "junho",
- "6": "julho",
- "7": "agosto",
- "8": "setembro",
- "9": "outubro",
- "10": "novembro",
- "11": "dezembro"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "seg",
- "2": "ter",
- "3": "qua",
- "4": "qui",
- "5": "sex",
- "6": "sáb"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "fev",
- "2": "mar",
- "3": "abr",
- "4": "mai",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "set",
- "9": "out",
- "10": "nov",
- "11": "dez"
- },
- "fullDate": "EEEE, d 'de' MMMM 'de' y",
- "longDate": "d 'de' MMMM 'de' y",
- "medium": "dd/MM/yyyy HH:mm:ss",
- "mediumDate": "dd/MM/yyyy",
- "mediumTime": "HH:mm:ss",
- "short": "dd/MM/yy HH:mm",
- "shortDate": "dd/MM/yy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "R$",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "pt-st",
- "pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro-md.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro-md.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro-md.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "duminică",
- "1": "luni",
- "2": "marți",
- "3": "miercuri",
- "4": "joi",
- "5": "vineri",
- "6": "sâmbătă"
- },
- "MONTH": {
- "0": "ianuarie",
- "1": "februarie",
- "2": "martie",
- "3": "aprilie",
- "4": "mai",
- "5": "iunie",
- "6": "iulie",
- "7": "august",
- "8": "septembrie",
- "9": "octombrie",
- "10": "noiembrie",
- "11": "decembrie"
- },
- "SHORTDAY": {
- "0": "Du",
- "1": "Lu",
- "2": "Ma",
- "3": "Mi",
- "4": "Jo",
- "5": "Vi",
- "6": "Sâ"
- },
- "SHORTMONTH": {
- "0": "ian.",
- "1": "feb.",
- "2": "mar.",
- "3": "apr.",
- "4": "mai",
- "5": "iun.",
- "6": "iul.",
- "7": "aug.",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "dec."
- },
- "fullDate": "EEEE, d MMMM y",
- "longDate": "d MMMM y",
- "medium": "dd.MM.yyyy HH:mm:ss",
- "mediumDate": "dd.MM.yyyy",
- "mediumTime": "HH:mm:ss",
- "short": "dd.MM.yyyy HH:mm",
- "shortDate": "dd.MM.yyyy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "RON",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "-",
- "negSuf": " \u00A4",
- "posPre": "",
- "posSuf": " \u00A4"
- }
- }
- },
- "id": "ro-md",
- "pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 0 || n != 1 && n == (n | 0) && n % 100 >= 1 && n % 100 <= 19) { return PLURAL_CATEGORY.FEW; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-md.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-md.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-md.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "до полудня",
- "1": "после полудня"
- },
- "DAY": {
- "0": "воскресенье",
- "1": "понедельник",
- "2": "вторник",
- "3": "среда",
- "4": "четверг",
- "5": "пятница",
- "6": "суббота"
- },
- "MONTH": {
- "0": "января",
- "1": "февраля",
- "2": "марта",
- "3": "апреля",
- "4": "мая",
- "5": "июня",
- "6": "июля",
- "7": "августа",
- "8": "сентября",
- "9": "октября",
- "10": "ноября",
- "11": "декабря"
- },
- "SHORTDAY": {
- "0": "вс",
- "1": "пн",
- "2": "вт",
- "3": "ср",
- "4": "чт",
- "5": "пт",
- "6": "сб"
- },
- "SHORTMONTH": {
- "0": "янв.",
- "1": "февр.",
- "2": "марта",
- "3": "апр.",
- "4": "мая",
- "5": "июня",
- "6": "июля",
- "7": "авг.",
- "8": "сент.",
- "9": "окт.",
- "10": "нояб.",
- "11": "дек."
- },
- "fullDate": "EEEE, d MMMM y 'г'.",
- "longDate": "d MMMM y 'г'.",
- "medium": "dd.MM.yyyy H:mm:ss",
- "mediumDate": "dd.MM.yyyy",
- "mediumTime": "H:mm:ss",
- "short": "dd.MM.yy H:mm",
- "shortDate": "dd.MM.yy",
- "shortTime": "H:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "руб.",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": " ",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "-",
- "negSuf": " \u00A4",
- "posPre": "",
- "posSuf": " \u00A4"
- }
- }
- },
- "id": "ru-md",
- "pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-ua.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-ua.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-ua.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "до полудня",
- "1": "после полудня"
- },
- "DAY": {
- "0": "воскресенье",
- "1": "понедельник",
- "2": "вторник",
- "3": "среда",
- "4": "четверг",
- "5": "пятница",
- "6": "суббота"
- },
- "MONTH": {
- "0": "января",
- "1": "февраля",
- "2": "марта",
- "3": "апреля",
- "4": "мая",
- "5": "июня",
- "6": "июля",
- "7": "августа",
- "8": "сентября",
- "9": "октября",
- "10": "ноября",
- "11": "декабря"
- },
- "SHORTDAY": {
- "0": "вс",
- "1": "пн",
- "2": "вт",
- "3": "ср",
- "4": "чт",
- "5": "пт",
- "6": "сб"
- },
- "SHORTMONTH": {
- "0": "янв.",
- "1": "февр.",
- "2": "марта",
- "3": "апр.",
- "4": "мая",
- "5": "июня",
- "6": "июля",
- "7": "авг.",
- "8": "сент.",
- "9": "окт.",
- "10": "нояб.",
- "11": "дек."
- },
- "fullDate": "EEEE, d MMMM y 'г'.",
- "longDate": "d MMMM y",
- "medium": "d MMM y HH:mm:ss",
- "mediumDate": "d MMM y",
- "mediumTime": "HH:mm:ss",
- "short": "dd.MM.yy HH:mm",
- "shortDate": "dd.MM.yy",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "руб.",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": " ",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "-",
- "negSuf": " \u00A4",
- "posPre": "",
- "posSuf": " \u00A4"
- }
- }
- },
- "id": "ru-ua",
- "pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-ba.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-ba.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-ba.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "пре подне",
- "1": "поподне"
- },
- "DAY": {
- "0": "недеља",
- "1": "понедељак",
- "2": "уторак",
- "3": "сриједа",
- "4": "четвртак",
- "5": "петак",
- "6": "субота"
- },
- "MONTH": {
- "0": "јануар",
- "1": "фебруар",
- "2": "март",
- "3": "април",
- "4": "мај",
- "5": "јуни",
- "6": "јули",
- "7": "август",
- "8": "септембар",
- "9": "октобар",
- "10": "новембар",
- "11": "децембар"
- },
- "SHORTDAY": {
- "0": "нед",
- "1": "пон",
- "2": "уто",
- "3": "сри",
- "4": "чет",
- "5": "пет",
- "6": "суб"
- },
- "SHORTMONTH": {
- "0": "јан",
- "1": "феб",
- "2": "мар",
- "3": "апр",
- "4": "мај",
- "5": "јун",
- "6": "јул",
- "7": "авг",
- "8": "сеп",
- "9": "окт",
- "10": "нов",
- "11": "дец"
- },
- "fullDate": "EEEE, dd. MMMM y.",
- "longDate": "dd. MMMM y.",
- "medium": "yyyy-MM-dd HH:mm:ss",
- "mediumDate": "yyyy-MM-dd",
- "mediumTime": "HH:mm:ss",
- "short": "yy-MM-dd HH:mm",
- "shortDate": "yy-MM-dd",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "din",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "-",
- "negSuf": " \u00A4",
- "posPre": "",
- "posSuf": " \u00A4"
- }
- }
- },
- "id": "sr-cyrl-ba",
- "pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-me.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-me.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-me.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "пре подне",
- "1": "поподне"
- },
- "DAY": {
- "0": "недеља",
- "1": "понедељак",
- "2": "уторак",
- "3": "среда",
- "4": "четвртак",
- "5": "петак",
- "6": "субота"
- },
- "MONTH": {
- "0": "јануар",
- "1": "фебруар",
- "2": "март",
- "3": "април",
- "4": "мај",
- "5": "јун",
- "6": "јул",
- "7": "август",
- "8": "септембар",
- "9": "октобар",
- "10": "новембар",
- "11": "децембар"
- },
- "SHORTDAY": {
- "0": "нед",
- "1": "пон",
- "2": "уто",
- "3": "сре",
- "4": "чет",
- "5": "пет",
- "6": "суб"
- },
- "SHORTMONTH": {
- "0": "јан",
- "1": "феб",
- "2": "мар",
- "3": "апр",
- "4": "мај",
- "5": "јун",
- "6": "јул",
- "7": "авг",
- "8": "сеп",
- "9": "окт",
- "10": "нов",
- "11": "дец"
- },
- "fullDate": "EEEE, dd. MMMM y.",
- "longDate": "dd. MMMM y.",
- "medium": "dd.MM.y. HH.mm.ss",
- "mediumDate": "dd.MM.y.",
- "mediumTime": "HH.mm.ss",
- "short": "d.M.yy. HH.mm",
- "shortDate": "d.M.yy.",
- "shortTime": "HH.mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "din",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "-",
- "negSuf": " \u00A4",
- "posPre": "",
- "posSuf": " \u00A4"
- }
- }
- },
- "id": "sr-cyrl-me",
- "pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "пре подне",
- "1": "поподне"
- },
- "DAY": {
- "0": "недеља",
- "1": "понедељак",
- "2": "уторак",
- "3": "среда",
- "4": "четвртак",
- "5": "петак",
- "6": "субота"
- },
- "MONTH": {
- "0": "јануар",
- "1": "фебруар",
- "2": "март",
- "3": "април",
- "4": "мај",
- "5": "јун",
- "6": "јул",
- "7": "август",
- "8": "септембар",
- "9": "октобар",
- "10": "новембар",
- "11": "децембар"
- },
- "SHORTDAY": {
- "0": "нед",
- "1": "пон",
- "2": "уто",
- "3": "сре",
- "4": "чет",
- "5": "пет",
- "6": "суб"
- },
- "SHORTMONTH": {
- "0": "јан",
- "1": "феб",
- "2": "мар",
- "3": "апр",
- "4": "мај",
- "5": "јун",
- "6": "јул",
- "7": "авг",
- "8": "сеп",
- "9": "окт",
- "10": "нов",
- "11": "дец"
- },
- "fullDate": "EEEE, dd. MMMM y.",
- "longDate": "dd. MMMM y.",
- "medium": "dd.MM.y. HH.mm.ss",
- "mediumDate": "dd.MM.y.",
- "mediumTime": "HH.mm.ss",
- "short": "d.M.yy. HH.mm",
- "shortDate": "d.M.yy.",
- "shortTime": "HH.mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "din",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "-",
- "negSuf": " \u00A4",
- "posPre": "",
- "posSuf": " \u00A4"
- }
- }
- },
- "id": "sr-cyrl",
- "pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-ba.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-ba.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-ba.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "pre podne",
- "1": "popodne"
- },
- "DAY": {
- "0": "nedelja",
- "1": "ponedeljak",
- "2": "utorak",
- "3": "sreda",
- "4": "četvrtak",
- "5": "petak",
- "6": "subota"
- },
- "MONTH": {
- "0": "januar",
- "1": "februar",
- "2": "mart",
- "3": "april",
- "4": "maj",
- "5": "jun",
- "6": "jul",
- "7": "avgust",
- "8": "septembar",
- "9": "oktobar",
- "10": "novembar",
- "11": "decembar"
- },
- "SHORTDAY": {
- "0": "ned",
- "1": "pon",
- "2": "uto",
- "3": "sre",
- "4": "čet",
- "5": "pet",
- "6": "sub"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "maj",
- "5": "jun",
- "6": "jul",
- "7": "avg",
- "8": "sep",
- "9": "okt",
- "10": "nov",
- "11": "dec"
- },
- "fullDate": "EEEE, dd. MMMM y.",
- "longDate": "dd. MMMM y.",
- "medium": "dd.MM.y. HH.mm.ss",
- "mediumDate": "dd.MM.y.",
- "mediumTime": "HH.mm.ss",
- "short": "d.M.yy. HH.mm",
- "shortDate": "d.M.yy.",
- "shortTime": "HH.mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "din",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "-",
- "negSuf": " \u00A4",
- "posPre": "",
- "posSuf": " \u00A4"
- }
- }
- },
- "id": "sr-latn-ba",
- "pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-me.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-me.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-me.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "pre podne",
- "1": "popodne"
- },
- "DAY": {
- "0": "nedelja",
- "1": "ponedeljak",
- "2": "utorak",
- "3": "sreda",
- "4": "četvrtak",
- "5": "petak",
- "6": "subota"
- },
- "MONTH": {
- "0": "januar",
- "1": "februar",
- "2": "mart",
- "3": "april",
- "4": "maj",
- "5": "jun",
- "6": "jul",
- "7": "avgust",
- "8": "septembar",
- "9": "oktobar",
- "10": "novembar",
- "11": "decembar"
- },
- "SHORTDAY": {
- "0": "ned",
- "1": "pon",
- "2": "uto",
- "3": "sre",
- "4": "čet",
- "5": "pet",
- "6": "sub"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "maj",
- "5": "jun",
- "6": "jul",
- "7": "avg",
- "8": "sep",
- "9": "okt",
- "10": "nov",
- "11": "dec"
- },
- "fullDate": "EEEE, dd. MMMM y.",
- "longDate": "d.MM.yyyy.",
- "medium": "dd.MM.y. HH.mm.ss",
- "mediumDate": "dd.MM.y.",
- "mediumTime": "HH.mm.ss",
- "short": "d.M.yy. HH.mm",
- "shortDate": "d.M.yy.",
- "shortTime": "HH.mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "din",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "-",
- "negSuf": " \u00A4",
- "posPre": "",
- "posSuf": " \u00A4"
- }
- }
- },
- "id": "sr-latn-me",
- "pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "pre podne",
- "1": "popodne"
- },
- "DAY": {
- "0": "nedelja",
- "1": "ponedeljak",
- "2": "utorak",
- "3": "sreda",
- "4": "četvrtak",
- "5": "petak",
- "6": "subota"
- },
- "MONTH": {
- "0": "januar",
- "1": "februar",
- "2": "mart",
- "3": "april",
- "4": "maj",
- "5": "jun",
- "6": "jul",
- "7": "avgust",
- "8": "septembar",
- "9": "oktobar",
- "10": "novembar",
- "11": "decembar"
- },
- "SHORTDAY": {
- "0": "ned",
- "1": "pon",
- "2": "uto",
- "3": "sre",
- "4": "čet",
- "5": "pet",
- "6": "sub"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "maj",
- "5": "jun",
- "6": "jul",
- "7": "avg",
- "8": "sep",
- "9": "okt",
- "10": "nov",
- "11": "dec"
- },
- "fullDate": "EEEE, dd. MMMM y.",
- "longDate": "dd. MMMM y.",
- "medium": "dd.MM.y. HH.mm.ss",
- "mediumDate": "dd.MM.y.",
- "mediumTime": "HH.mm.ss",
- "short": "d.M.yy. HH.mm",
- "shortDate": "d.M.yy.",
- "shortTime": "HH.mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "din",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "-",
- "negSuf": " \u00A4",
- "posPre": "",
- "posSuf": " \u00A4"
- }
- }
- },
- "id": "sr-latn",
- "pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-rs.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-rs.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-rs.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {"NUMBER_FORMATS":{"DECIMAL_SEP":".","GROUP_SEP":",","PATTERNS":[{"minInt":1,"minFrac":0,"macFrac":0,"posPre":"","posSuf":"","negPre":"-","negSuf":"","gSize":3,"lgSize":3,"maxFrac":3},{"minInt":1,"minFrac":2,"macFrac":0,"posPre":"","posSuf":" \u00A4","negPre":"-","negSuf":" \u00A4","gSize":3,"lgSize":3,"maxFrac":2}],"CURRENCY_SYM":"РСД"},"pluralCat":function (n) { if ((n % 10) == 1 && (n % 100) != 11) { return PLURAL_CATEGORY.ONE; } if ((n % 10) >= 2 && (n % 10) <= 4 && ((n % 100) < 12 || (n % 100) > 14) && n == Math.floor(n)) { return PLURAL_CATEGORY.FEW; } if ((n % 10) == 0 || ((n % 10) >= 5 && (n % 10) <= 9) || ((n % 100) >= 11 && (n % 100) <= 14) && n == Math.floor(n)) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;},"DATETIME_FORMATS":{"MONTH":["јануар","фебруар","март","април","мај","јун","јул","август","септембар","октобар","новембар","децембар"],"SHORTMONTH":["јан","феб","мар","апр","мај","јун","јул","авг","сеп","окт","нов","дец"],"DAY":["недеља","понедељак","уторак","среда","четвртак","петак","субота"],"SHORTDAY":["нед","пон","уто","сре","чет","пет","суб"],"AMPMS":["пре подне","поподне"],"medium":"dd.MM.y. HH.mm.ss","short":"d.M.yy. HH.mm","fullDate":"EEEE, dd. MMMM y.","longDate":"dd. MMMM y.","mediumDate":"dd.MM.y.","shortDate":"d.M.yy.","mediumTime":"HH.mm.ss","shortTime":"HH.mm"},"id":"sr-rs"});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv-fi.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv-fi.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv-fi.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "fm",
- "1": "em"
- },
- "DAY": {
- "0": "söndag",
- "1": "måndag",
- "2": "tisdag",
- "3": "onsdag",
- "4": "torsdag",
- "5": "fredag",
- "6": "lördag"
- },
- "MONTH": {
- "0": "januari",
- "1": "februari",
- "2": "mars",
- "3": "april",
- "4": "maj",
- "5": "juni",
- "6": "juli",
- "7": "augusti",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "sön",
- "1": "mån",
- "2": "tis",
- "3": "ons",
- "4": "tors",
- "5": "fre",
- "6": "lör"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "maj",
- "5": "jun",
- "6": "jul",
- "7": "aug",
- "8": "sep",
- "9": "okt",
- "10": "nov",
- "11": "dec"
- },
- "fullDate": "EEEE'en' 'den' d:'e' MMMM y",
- "longDate": "d MMMM y",
- "medium": "d MMM y HH:mm:ss",
- "mediumDate": "d MMM y",
- "mediumTime": "HH:mm:ss",
- "short": "yyyy-MM-dd HH:mm",
- "shortDate": "yyyy-MM-dd",
- "shortTime": "HH:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "kr",
- "DECIMAL_SEP": ",",
- "GROUP_SEP": " ",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "-",
- "negSuf": " \u00A4",
- "posPre": "",
- "posSuf": " \u00A4"
- }
- }
- },
- "id": "sv-fi",
- "pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw-ke.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw-ke.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw-ke.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "asubuhi",
- "1": "alasiri"
- },
- "DAY": {
- "0": "Jumapili",
- "1": "Jumatatu",
- "2": "Jumanne",
- "3": "Jumatano",
- "4": "Alhamisi",
- "5": "Ijumaa",
- "6": "Jumamosi"
- },
- "MONTH": {
- "0": "Januari",
- "1": "Februari",
- "2": "Machi",
- "3": "Aprili",
- "4": "Mei",
- "5": "Juni",
- "6": "Julai",
- "7": "Agosti",
- "8": "Septemba",
- "9": "Oktoba",
- "10": "Novemba",
- "11": "Desemba"
- },
- "SHORTDAY": {
- "0": "J2",
- "1": "J3",
- "2": "J4",
- "3": "J5",
- "4": "Alh",
- "5": "Ij",
- "6": "J1"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mac",
- "3": "Apr",
- "4": "Mei",
- "5": "Jun",
- "6": "Jul",
- "7": "Ago",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Des"
- },
- "fullDate": "EEEE, d MMMM y",
- "longDate": "d MMMM y",
- "medium": "d MMM y h:mm:ss a",
- "mediumDate": "d MMM y",
- "mediumTime": "h:mm:ss a",
- "short": "dd/MM/yyyy h:mm a",
- "shortDate": "dd/MM/yyyy",
- "shortTime": "h:mm a"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "TSh",
- "DECIMAL_SEP": ".",
- "GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "sw-ke",
- "pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta-lk.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta-lk.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta-lk.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "ஞாயிறு",
- "1": "திங்கள்",
- "2": "செவ்வாய்",
- "3": "புதன்",
- "4": "வியாழன்",
- "5": "வெள்ளி",
- "6": "சனி"
- },
- "MONTH": {
- "0": "ஜனவரி",
- "1": "பிப்ரவரி",
- "2": "மார்ச்",
- "3": "ஏப்ரல்",
- "4": "மே",
- "5": "ஜூன்",
- "6": "ஜூலை",
- "7": "ஆகஸ்ட்",
- "8": "செப்டம்பர்",
- "9": "அக்டோபர்",
- "10": "நவம்பர்",
- "11": "டிசம்பர்"
- },
- "SHORTDAY": {
- "0": "ஞா",
- "1": "தி",
- "2": "செ",
- "3": "பு",
- "4": "வி",
- "5": "வெ",
- "6": "ச"
- },
- "SHORTMONTH": {
- "0": "ஜன.",
- "1": "பிப்.",
- "2": "மார்.",
- "3": "ஏப்.",
- "4": "மே",
- "5": "ஜூன்",
- "6": "ஜூலை",
- "7": "ஆக.",
- "8": "செப்.",
- "9": "அக்.",
- "10": "நவ.",
- "11": "டிச."
- },
- "fullDate": "EEEE, d MMMM, y",
- "longDate": "d MMMM, y",
- "medium": "d MMM, y h:mm:ss a",
- "mediumDate": "d MMM, y",
- "mediumTime": "h:mm:ss a",
- "short": "d-M-yy h:mm a",
- "shortDate": "d-M-yy",
- "shortTime": "h:mm a"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "₹",
- "DECIMAL_SEP": ".",
- "GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
- "gSize": 2,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 2,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "\u00A4 -",
- "negSuf": "",
- "posPre": "\u00A4 ",
- "posSuf": ""
- }
- }
- },
- "id": "ta-lk",
- "pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tl-ph.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tl-ph.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tl-ph.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,5 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {"NUMBER_FORMATS":{"DECIMAL_SEP":".","GROUP_SEP":",","PATTERNS":[{"minInt":1,"minFrac":0,"macFrac":0,"posPre":"","posSuf":"","negPre":"-","negSuf":"","gSize":3,"lgSize":3,"maxFrac":3},{"minInt":1,"minFrac":2,"macFrac":0,"posPre":"\u00A4 ","posSuf":"","negPre":"\u00A4 -","negSuf":"","gSize":3,"lgSize":3,"maxFrac":2}],"CURRENCY_SYM":"P"},"pluralCat":function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;},"DATETIME_FORMATS":{"MONTH":["Enero","Pebrero","Marso","Abril","Mayo","Hunyo","Hulyo","Agosto","Setyembre","Oktubre","Nobyembre","Disyembre"],"SHORTMONTH":["Ene","Peb","Mar","Abr","May","Hun","Hul","Ago","Set","Okt","Nob","Dis"],"DAY":["Linggo","Lunes","Martes","Miyerkules","Huwebes","Biyernes","Sabado"],"SHORTDAY":["Lin","Lun","Mar","Mye","Huw","Bye","Sab"],"AMPMS":["AM","PM"],"medium":"MMM d, y HH:mm:ss","short":"M/d/yy HH:mm","fullDate":"EEEE, MMMM dd y","longDate":"MMMM d, y","mediumDate":"MMM d, y","shortDate":"M/d/yy","mediumTime":"HH:mm:ss","shortTime":"HH:mm"},"id":"tl-ph"});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur-in.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur-in.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur-in.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "دن",
- "1": "رات"
- },
- "DAY": {
- "0": "اتوار",
- "1": "پير",
- "2": "منگل",
- "3": "بده",
- "4": "جمعرات",
- "5": "جمعہ",
- "6": "ہفتہ"
- },
- "MONTH": {
- "0": "جنوری",
- "1": "فروری",
- "2": "مارچ",
- "3": "اپريل",
- "4": "مئ",
- "5": "جون",
- "6": "جولائ",
- "7": "اگست",
- "8": "ستمبر",
- "9": "اکتوبر",
- "10": "نومبر",
- "11": "دسمبر"
- },
- "SHORTDAY": {
- "0": "اتوار",
- "1": "پير",
- "2": "منگل",
- "3": "بده",
- "4": "جمعرات",
- "5": "جمعہ",
- "6": "ہفتہ"
- },
- "SHORTMONTH": {
- "0": "جنوری",
- "1": "فروری",
- "2": "مارچ",
- "3": "اپريل",
- "4": "مئ",
- "5": "جون",
- "6": "جولائ",
- "7": "اگست",
- "8": "ستمبر",
- "9": "اکتوبر",
- "10": "نومبر",
- "11": "دسمبر"
- },
- "fullDate": "EEEE؍ d؍ MMMM y",
- "longDate": "d؍ MMMM y",
- "medium": "d؍ MMM y h:mm:ss a",
- "mediumDate": "d؍ MMM y",
- "mediumTime": "h:mm:ss a",
- "short": "d/M/yy h:mm a",
- "shortDate": "d/M/yy",
- "shortTime": "h:mm a"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "Rs",
- "DECIMAL_SEP": ".",
- "GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "\u00A4-",
- "negSuf": "",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "ur-in",
- "pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-hk.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-hk.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-hk.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "上午",
- "1": "下午"
- },
- "DAY": {
- "0": "星期日",
- "1": "星期一",
- "2": "星期二",
- "3": "星期三",
- "4": "星期四",
- "5": "星期五",
- "6": "星期六"
- },
- "MONTH": {
- "0": "一月",
- "1": "二月",
- "2": "三月",
- "3": "四月",
- "4": "五月",
- "5": "六月",
- "6": "七月",
- "7": "八月",
- "8": "九月",
- "9": "十月",
- "10": "十一月",
- "11": "十二月"
- },
- "SHORTDAY": {
- "0": "周日",
- "1": "周一",
- "2": "周二",
- "3": "周三",
- "4": "周四",
- "5": "周五",
- "6": "周六"
- },
- "SHORTMONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "fullDate": "y年M月d日EEEE",
- "longDate": "y年M月d日",
- "medium": "y年M月d日 ah:mm:ss",
- "mediumDate": "y年M月d日",
- "mediumTime": "ah:mm:ss",
- "short": "d/M/yy ah:mm",
- "shortDate": "d/M/yy",
- "shortTime": "ah:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "¥",
- "DECIMAL_SEP": ".",
- "GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "zh-hans-hk",
- "pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-mo.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-mo.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-mo.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "上午",
- "1": "下午"
- },
- "DAY": {
- "0": "星期日",
- "1": "星期一",
- "2": "星期二",
- "3": "星期三",
- "4": "星期四",
- "5": "星期五",
- "6": "星期六"
- },
- "MONTH": {
- "0": "一月",
- "1": "二月",
- "2": "三月",
- "3": "四月",
- "4": "五月",
- "5": "六月",
- "6": "七月",
- "7": "八月",
- "8": "九月",
- "9": "十月",
- "10": "十一月",
- "11": "十二月"
- },
- "SHORTDAY": {
- "0": "周日",
- "1": "周一",
- "2": "周二",
- "3": "周三",
- "4": "周四",
- "5": "周五",
- "6": "周六"
- },
- "SHORTMONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "fullDate": "y年M月d日EEEE",
- "longDate": "y年M月d日",
- "medium": "y年M月d日 ah:mm:ss",
- "mediumDate": "y年M月d日",
- "mediumTime": "ah:mm:ss",
- "short": "d/M/yy ah:mm",
- "shortDate": "d/M/yy",
- "shortTime": "ah:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "¥",
- "DECIMAL_SEP": ".",
- "GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "zh-hans-mo",
- "pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-sg.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-sg.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-sg.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "上午",
- "1": "下午"
- },
- "DAY": {
- "0": "星期日",
- "1": "星期一",
- "2": "星期二",
- "3": "星期三",
- "4": "星期四",
- "5": "星期五",
- "6": "星期六"
- },
- "MONTH": {
- "0": "一月",
- "1": "二月",
- "2": "三月",
- "3": "四月",
- "4": "五月",
- "5": "六月",
- "6": "七月",
- "7": "八月",
- "8": "九月",
- "9": "十月",
- "10": "十一月",
- "11": "十二月"
- },
- "SHORTDAY": {
- "0": "周日",
- "1": "周一",
- "2": "周二",
- "3": "周三",
- "4": "周四",
- "5": "周五",
- "6": "周六"
- },
- "SHORTMONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "fullDate": "y年M月d日EEEE",
- "longDate": "y年M月d日",
- "medium": "y年M月d日 ah:mm:ss",
- "mediumDate": "y年M月d日",
- "mediumTime": "ah:mm:ss",
- "short": "dd/MM/yy ahh:mm",
- "shortDate": "dd/MM/yy",
- "shortTime": "ahh:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "¥",
- "DECIMAL_SEP": ".",
- "GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "zh-hans-sg",
- "pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "上午",
- "1": "下午"
- },
- "DAY": {
- "0": "星期日",
- "1": "星期一",
- "2": "星期二",
- "3": "星期三",
- "4": "星期四",
- "5": "星期五",
- "6": "星期六"
- },
- "MONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "SHORTDAY": {
- "0": "周日",
- "1": "周一",
- "2": "周二",
- "3": "周三",
- "4": "周四",
- "5": "周五",
- "6": "周六"
- },
- "SHORTMONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "fullDate": "y年M月d日EEEE",
- "longDate": "y年M月d日",
- "medium": "yyyy-M-d ah:mm:ss",
- "mediumDate": "yyyy-M-d",
- "mediumTime": "ah:mm:ss",
- "short": "yy-M-d ah:mm",
- "shortDate": "yy-M-d",
- "shortTime": "ah:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "¥",
- "DECIMAL_SEP": ".",
- "GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "zh-hans",
- "pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant-hk.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant-hk.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant-hk.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "上午",
- "1": "下午"
- },
- "DAY": {
- "0": "星期日",
- "1": "星期一",
- "2": "星期二",
- "3": "星期三",
- "4": "星期四",
- "5": "星期五",
- "6": "星期六"
- },
- "MONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "SHORTDAY": {
- "0": "週日",
- "1": "週一",
- "2": "週二",
- "3": "週三",
- "4": "週四",
- "5": "週五",
- "6": "週六"
- },
- "SHORTMONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "fullDate": "y年M月d日EEEE",
- "longDate": "y年M月d日",
- "medium": "y年M月d日 ahh:mm:ss",
- "mediumDate": "y年M月d日",
- "mediumTime": "ahh:mm:ss",
- "short": "yy年M月d日 ah:mm",
- "shortDate": "yy年M月d日",
- "shortTime": "ah:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "¥",
- "DECIMAL_SEP": ".",
- "GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "zh-hant-hk",
- "pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant-mo.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant-mo.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant-mo.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "上午",
- "1": "下午"
- },
- "DAY": {
- "0": "星期日",
- "1": "星期一",
- "2": "星期二",
- "3": "星期三",
- "4": "星期四",
- "5": "星期五",
- "6": "星期六"
- },
- "MONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "SHORTDAY": {
- "0": "週日",
- "1": "週一",
- "2": "週二",
- "3": "週三",
- "4": "週四",
- "5": "週五",
- "6": "週六"
- },
- "SHORTMONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "fullDate": "y年MM月dd日EEEE",
- "longDate": "y年MM月dd日",
- "medium": "y年M月d日 ahh:mm:ss",
- "mediumDate": "y年M月d日",
- "mediumTime": "ahh:mm:ss",
- "short": "yy年M月d日 ah:mm",
- "shortDate": "yy年M月d日",
- "shortTime": "ah:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "¥",
- "DECIMAL_SEP": ".",
- "GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "zh-hant-mo",
- "pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant-tw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant-tw.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant-tw.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "上午",
- "1": "下午"
- },
- "DAY": {
- "0": "星期日",
- "1": "星期一",
- "2": "星期二",
- "3": "星期三",
- "4": "星期四",
- "5": "星期五",
- "6": "星期六"
- },
- "MONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "SHORTDAY": {
- "0": "週日",
- "1": "週一",
- "2": "週二",
- "3": "週三",
- "4": "週四",
- "5": "週五",
- "6": "週六"
- },
- "SHORTMONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "fullDate": "y年M月d日EEEE",
- "longDate": "y年M月d日",
- "medium": "yyyy/M/d ah:mm:ss",
- "mediumDate": "yyyy/M/d",
- "mediumTime": "ah:mm:ss",
- "short": "y/M/d ah:mm",
- "shortDate": "y/M/d",
- "shortTime": "ah:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "¥",
- "DECIMAL_SEP": ".",
- "GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "zh-hant-tw",
- "pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant.js 2013-08-27 08:38:39 UTC (rev 205)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hant.js 2013-09-09 09:04:12 UTC (rev 206)
@@ -1,99 +0,0 @@
-/* %%Ignore-License */
-angular.module("ngLocale", [], ["$provide", function($provide) {
-var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
-$provide.value("$locale", {
- "DATETIME_FORMATS": {
- "AMPMS": {
- "0": "上午",
- "1": "下午"
- },
- "DAY": {
- "0": "星期日",
- "1": "星期一",
- "2": "星期二",
- "3": "星期三",
- "4": "星期四",
- "5": "星期五",
- "6": "星期六"
- },
- "MONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "SHORTDAY": {
- "0": "週日",
- "1": "週一",
- "2": "週二",
- "3": "週三",
- "4": "週四",
- "5": "週五",
- "6": "週六"
- },
- "SHORTMONTH": {
- "0": "1月",
- "1": "2月",
- "2": "3月",
- "3": "4月",
- "4": "5月",
- "5": "6月",
- "6": "7月",
- "7": "8月",
- "8": "9月",
- "9": "10月",
- "10": "11月",
- "11": "12月"
- },
- "fullDate": "y年M月d日EEEE",
- "longDate": "y年M月d日",
- "medium": "yyyy/M/d ah:mm:ss",
- "mediumDate": "yyyy/M/d",
- "mediumTime": "ah:mm:ss",
- "short": "y/M/d ah:mm",
- "shortDate": "y/M/d",
- "shortTime": "ah:mm"
- },
- "NUMBER_FORMATS": {
- "CURRENCY_SYM": "¥",
- "DECIMAL_SEP": ".",
- "GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 3,
- "minFrac": 0,
- "minInt": 1,
- "negPre": "-",
- "negSuf": "",
- "posPre": "",
- "posSuf": ""
- },
- "1": {
- "gSize": 3,
- "lgSize": 3,
- "macFrac": 0,
- "maxFrac": 2,
- "minFrac": 2,
- "minInt": 1,
- "negPre": "(\u00A4",
- "negSuf": ")",
- "posPre": "\u00A4",
- "posSuf": ""
- }
- }
- },
- "id": "zh-hant",
- "pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
-});
-}]);
\ No newline at end of file
1
0
Author: echatellier
Date: 2013-08-27 10:38:39 +0200 (Tue, 27 Aug 2013)
New Revision: 205
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/205
Log:
Next dev iteration
Modified:
sandbox/nuiton-js-jquery-ui/pom.xml
Modified: sandbox/nuiton-js-jquery-ui/pom.xml
===================================================================
--- sandbox/nuiton-js-jquery-ui/pom.xml 2013-08-27 08:38:05 UTC (rev 204)
+++ sandbox/nuiton-js-jquery-ui/pom.xml 2013-08-27 08:38:39 UTC (rev 205)
@@ -14,7 +14,7 @@
</parent>
<artifactId>nuiton-js-jquery-ui</artifactId>
- <version>1.10.3-1</version>
+ <version>1.10.3-2-SNAPSHOT</version>
<name>Nuiton JS :: JQuery UI</name>
<description>JQuery UI jar packaging</description>
@@ -29,9 +29,9 @@
</licenses>
<scm>
- <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jquery-ui-1.10.3…</connection>
- <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jquery-ui-1.10.3…</developerConnection>
- <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-jquery-u…</url>
+ <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jquery-ui-1.10.3…</connection>
+ <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jquery-ui-1.10.3…</developerConnection>
+ <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-jquery-u…</url>
</scm>
<dependencies>
1
0
Author: echatellier
Date: 2013-08-27 10:38:05 +0200 (Tue, 27 Aug 2013)
New Revision: 204
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/204
Log:
Next dev iteration
Modified:
sandbox/nuiton-js-angular/pom.xml
Modified: sandbox/nuiton-js-angular/pom.xml
===================================================================
--- sandbox/nuiton-js-angular/pom.xml 2013-08-27 08:37:02 UTC (rev 203)
+++ sandbox/nuiton-js-angular/pom.xml 2013-08-27 08:38:05 UTC (rev 204)
@@ -14,7 +14,7 @@
</parent>
<artifactId>nuiton-js-angular</artifactId>
- <version>1.2.0-rc1-1-SNAPSHOT</version>
+ <version>1.2.0-rc1-2-SNAPSHOT</version>
<name>Nuiton JS :: Angular</name>
<description>Angular jar packaging</description>
@@ -29,9 +29,9 @@
</licenses>
<scm>
- <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</connection>
- <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</developerConnection>
- <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-angular-…</url>
+ <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</connection>
+ <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</developerConnection>
+ <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-angular-…</url>
</scm>
</project>
1
0
Author: echatellier
Date: 2013-08-27 10:37:02 +0200 (Tue, 27 Aug 2013)
New Revision: 203
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/203
Log:
Prepare 1.10.3-1 tag
Added:
tags/nuiton-js-jquery-ui-1.10.3-1/
1
0
Author: echatellier
Date: 2013-08-27 10:36:41 +0200 (Tue, 27 Aug 2013)
New Revision: 202
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/202
Log:
Prepare release
Modified:
sandbox/nuiton-js-jquery-ui/pom.xml
Modified: sandbox/nuiton-js-jquery-ui/pom.xml
===================================================================
--- sandbox/nuiton-js-jquery-ui/pom.xml 2013-08-27 08:32:19 UTC (rev 201)
+++ sandbox/nuiton-js-jquery-ui/pom.xml 2013-08-27 08:36:41 UTC (rev 202)
@@ -14,7 +14,7 @@
</parent>
<artifactId>nuiton-js-jquery-ui</artifactId>
- <version>1.10.3-1-SNAPSHOT</version>
+ <version>1.10.3-1</version>
<name>Nuiton JS :: JQuery UI</name>
<description>JQuery UI jar packaging</description>
@@ -29,9 +29,9 @@
</licenses>
<scm>
- <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jquery-ui-1.10.3</connection>
- <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jquery-ui-1.10.3</developerConnection>
- <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-jquery-u…</url>
+ <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jquery-ui-1.10.3…</connection>
+ <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-jquery-ui-1.10.3…</developerConnection>
+ <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-jquery-u…</url>
</scm>
<dependencies>
1
0
Aug. 27, 2013
Author: echatellier
Date: 2013-08-27 10:32:19 +0200 (Tue, 27 Aug 2013)
New Revision: 201
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/201
Log:
Fix version
Modified:
tags/nuiton-js-angular-1.2.0-rc1-1/pom.xml
Modified: tags/nuiton-js-angular-1.2.0-rc1-1/pom.xml
===================================================================
--- tags/nuiton-js-angular-1.2.0-rc1-1/pom.xml 2013-08-27 08:31:23 UTC (rev 200)
+++ tags/nuiton-js-angular-1.2.0-rc1-1/pom.xml 2013-08-27 08:32:19 UTC (rev 201)
@@ -14,7 +14,7 @@
</parent>
<artifactId>nuiton-js-angular</artifactId>
- <version>1.2.0-rc1-1-SNAPSHOT</version>
+ <version>1.2.0-rc1-1</version>
<name>Nuiton JS :: Angular</name>
<description>Angular jar packaging</description>
1
0
Author: echatellier
Date: 2013-08-27 10:31:23 +0200 (Tue, 27 Aug 2013)
New Revision: 200
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/200
Log:
Tag 1.2.0-rc1-1 for release
Added:
tags/nuiton-js-angular-1.2.0-rc1-1/
1
0
r199 - in sandbox/nuiton-js-angular: . src/main/resources/META-INF/nuiton-js src/main/resources/nuiton-js-angular src/main/resources/nuiton-js-angular/extra src/main/resources/nuiton-js-angular/i18n
by echatellier@users.nuiton.org Aug. 14, 2013
by echatellier@users.nuiton.org Aug. 14, 2013
Aug. 14, 2013
Author: echatellier
Date: 2013-08-14 10:20:29 +0200 (Wed, 14 Aug 2013)
New Revision: 199
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/199
Log:
Update to angular 1.2.0-rc1
Added:
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-animate.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-mocks.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-route.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-touch.js
Removed:
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-mobile.js
Modified:
sandbox/nuiton-js-angular/pom.xml
sandbox/nuiton-js-angular/src/main/resources/META-INF/nuiton-js/wro-angular.xml
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-cookies.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-loader.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-resource.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-sanitize.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-na.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-za.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am-et.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-001.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ae.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-bh.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-dz.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-eg.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-iq.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-jo.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-kw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-lb.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ly.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ma.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-om.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-qa.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sa.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sd.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sy.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-tn.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ye.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg-bg.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-bd.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-in.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-ad.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-es.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs-cz.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da-dk.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-at.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-be.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-ch.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-de.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-li.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-lu.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-cy.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-gr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-as.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-au.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bb.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-be.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bm.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bz.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ca.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt-us.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-fm.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gb.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gu.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gy.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-hk.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ie.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-in.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-iso.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-jm.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mh.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mp.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mt.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mu.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-na.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-nz.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ph.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pk.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-sg.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tc.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tt.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-um.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-us.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vg.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vi.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-za.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-zw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-419.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ar.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-bo.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cl.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-co.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-do.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ea.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ec.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-es.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gq.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gt.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-hn.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ic.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-mx.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ni.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pa.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pe.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-py.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-sv.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-us.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-uy.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ve.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et-ee.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu-es.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-af.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-ir.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi-fi.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil-ph.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-be.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bf.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bi.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bj.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bl.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ca.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cd.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cf.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cg.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ch.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ci.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cm.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-dj.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-fr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ga.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gf.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gn.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gp.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gq.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-km.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-lu.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mc.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mf.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mg.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ml.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mq.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ne.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-re.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-yt.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl-es.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw-ch.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu-in.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he-il.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi-in.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr-hr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu-hu.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id-id.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_in.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is-is.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-it.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-sm.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_iw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja-jp.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn-in.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko-kr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln-cd.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt-lt.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv-lv.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml-in.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr-in.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms-my.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt-mt.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-cw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-nl.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-sx.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_no.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or-in.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl-pl.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-br.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-pt.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro-ro.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-ru.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk-sk.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl-si.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq-al.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-rs.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-rs.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv-se.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw-tz.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta-in.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te-in.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th-th.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tl.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr-tr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk-ua.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur-pk.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi-vn.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-cn.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-cn.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hk.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-tw.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu-za.js
sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu.js
Modified: sandbox/nuiton-js-angular/pom.xml
===================================================================
--- sandbox/nuiton-js-angular/pom.xml 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/pom.xml 2013-08-14 08:20:29 UTC (rev 199)
@@ -14,7 +14,7 @@
</parent>
<artifactId>nuiton-js-angular</artifactId>
- <version>1.1.5-2-SNAPSHOT</version>
+ <version>1.2.0-rc1-1-SNAPSHOT</version>
<name>Nuiton JS :: Angular</name>
<description>Angular jar packaging</description>
@@ -29,9 +29,9 @@
</licenses>
<scm>
- <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.1.5-2</connection>
- <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.1.5-2</developerConnection>
- <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-angular-…</url>
+ <connection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</connection>
+ <developerConnection>scm:svn:http://svn.nuiton.org/svn/nuiton-js/tags/nuiton-js-angular-1.2.0-rc…</developerConnection>
+ <url>http://www.nuiton.org/repositories/browse/nuiton-js/tags/nuiton-js-angular-…</url>
</scm>
</project>
Modified: sandbox/nuiton-js-angular/src/main/resources/META-INF/nuiton-js/wro-angular.xml
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/META-INF/nuiton-js/wro-angular.xml 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/META-INF/nuiton-js/wro-angular.xml 2013-08-14 08:20:29 UTC (rev 199)
@@ -26,6 +26,10 @@
<js>classpath:nuiton-js-angular/angular.js</js>
</group>
+ <group name='angular-animate'>
+ <js>classpath:nuiton-js-angular/extra/angular-animate.js</js>
+ </group>
+
<group name='angular-cookies'>
<js>classpath:nuiton-js-angular/extra/angular-cookies.js</js>
</group>
@@ -34,18 +38,26 @@
<js>classpath:nuiton-js-angular/extra/angular-loader.js</js>
</group>
- <group name='angular-mobile'>
- <js>classpath:nuiton-js-angular/extra/angular-mobile.js</js>
+ <group name='angular-mocks'>
+ <js>classpath:nuiton-js-angular/extra/angular-mocks.js</js>
</group>
<group name='angular-resource'>
<js>classpath:nuiton-js-angular/extra/angular-resource.js</js>
</group>
+ <group name='angular-route'>
+ <js>classpath:nuiton-js-angular/extra/angular-route.js</js>
+ </group>
+
<group name='angular-sanitize'>
<js>classpath:nuiton-js-angular/extra/angular-sanitize.js</js>
</group>
+ <group name='angular-touch'>
+ <js>classpath:nuiton-js-angular/extra/angular-touch.js</js>
+ </group>
+
<group name='angular-af-na'>
<js>classpath:nuiton-js-angular/i18n/angular-locale_af-na.js</js>
</group>
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/angular.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -1,14 +1,79 @@
/** %%Ignore-License
- * @license AngularJS v1.1.5
+ * @license AngularJS v1.2.0rc1
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
-(function(window, document, undefined) {
-'use strict';
+(function(window, document, undefined) {'use strict';
+/**
+ * @description
+ *
+ * This object provides a utility for producing rich Error messages within
+ * Angular. It can be called as follows:
+ *
+ * var exampleMinErr = minErr('example');
+ * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
+ *
+ * The above creates an instance of minErr in the example namespace. The
+ * resulting error will have a namespaced error code of example.one. The
+ * resulting error will replace {0} with the value of foo, and {1} with the
+ * value of bar. The object is not restricted in the number of arguments it can
+ * take.
+ *
+ * If fewer arguments are specified than necessary for interpolation, the extra
+ * interpolation markers will be preserved in the final string.
+ *
+ * Since data will be parsed statically during a build step, some restrictions
+ * are applied with respect to how minErr instances are created and called.
+ * Instances should have names of the form namespaceMinErr for a minErr created
+ * using minErr('namespace') . Error codes, namespaces and template strings
+ * should all be static strings, not variables or general expressions.
+ *
+ * @param {string} module The namespace to use for the new minErr instance.
+ * @returns {function(string, string, ...): Error} instance
+ */
+
+function minErr(module) {
+ return function () {
+ var prefix = '[' + (module ? module + ':' : '') + arguments[0] + '] ',
+ template = arguments[1],
+ templateArgs = arguments,
+ message;
+
+ message = prefix + template.replace(/\{\d+\}/g, function (match) {
+ var index = +match.slice(1, -1), arg;
+
+ if (index + 2 < templateArgs.length) {
+ arg = templateArgs[index + 2];
+ if (isFunction(arg)) {
+ return arg.toString().replace(/ ?\{[\s\S]*$/, '');
+ } else if (isUndefined(arg)) {
+ return 'undefined';
+ } else if (!isString(arg)) {
+ return toJson(arg);
+ }
+ return arg;
+ }
+ return match;
+ });
+
+ return new Error(message);
+ };
+}
+
////////////////////////////////////
/**
+ * hasOwnProperty may be overwritten by a property of the same name, or entirely
+ * absent from an object that does not inherit Object.prototype; this copy is
+ * used instead
+ */
+var hasOwnPropertyFn = Object.prototype.hasOwnProperty;
+var hasOwnPropertyLocal = function(obj, key) {
+ return hasOwnPropertyFn.call(obj, key);
+};
+
+/**
* @ngdoc function
* @name angular.lowercase
* @function
@@ -60,6 +125,7 @@
slice = [].slice,
push = [].push,
toString = Object.prototype.toString,
+ ngMinErr = minErr('ng'),
_angular = window.angular,
@@ -70,42 +136,24 @@
uid = ['0', '0', '0'];
/**
- * @ngdoc function
- * @name angular.noConflict
- * @function
- *
- * @description
- * Restores the previous global value of angular and returns the current instance. Other libraries may already use the
- * angular namespace. Or a previous version of angular is already loaded on the page. In these cases you may want to
- * restore the previous namespace and keep a reference to angular.
- *
- * @return {Object} The current angular namespace
- */
-function noConflict() {
- var a = window.angular;
- window.angular = _angular;
- return a;
-}
-
-/**
* @private
* @param {*} obj
* @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
*/
function isArrayLike(obj) {
- if (!obj || (typeof obj.length !== 'number')) return false;
+ if (obj == null || isWindow(obj)) {
+ return false;
+ }
+
+ var length = obj.length;
- // We have on object which has length property. Should we treat it as array?
- if (typeof obj.hasOwnProperty != 'function' &&
- typeof obj.constructor != 'function') {
- // This is here for IE8: it is a bogus object treat it as array;
+ if (obj.nodeType === 1 && length) {
return true;
- } else {
- return obj instanceof JQLite || // JQLite
- (jQuery && obj instanceof jQuery) || // jQuery
- toString.call(obj) !== '[object Object]' || // some browser native object
- typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
}
+
+ return isArray(obj) || !isFunction(obj) && (
+ length === 0 || typeof length === "number" && length > 0 && (length - 1) in obj
+ );
}
/**
@@ -221,7 +269,7 @@
/**
* Set or clear the hashkey for an object.
- * @param obj object
+ * @param obj object
* @param h the hashkey (!truthy to delete the hashkey)
*/
function setHashKey(obj, h) {
@@ -269,12 +317,6 @@
return extend(new (extend(function() {}, {prototype:parent}))(), extra);
}
-var START_SPACE = /^\s*/;
-var END_SPACE = /\s*$/;
-function stripWhitespace(str) {
- return isString(str) ? str.replace(START_SPACE, '').replace(END_SPACE, '') : str;
-}
-
/**
* @ngdoc function
* @name angular.noop
@@ -305,7 +347,7 @@
*
<pre>
function transformer(transformationFn, value) {
- return (transformationFn || identity)(value);
+ return (transformationFn || angular.identity)(value);
};
</pre>
*/
@@ -433,6 +475,18 @@
/**
+ * Determines if a value is a regular expression object.
+ *
+ * @private
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a `RegExp`.
+ */
+function isRegExp(value) {
+ return toString.apply(value) == '[object RegExp]';
+}
+
+
+/**
* Checks if `obj` is a window object.
*
* @private
@@ -459,10 +513,21 @@
}
-function trim(value) {
- return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
-}
+var trim = (function() {
+ // native trim is way faster: http://jsperf.com/angular-trim-test
+ // but IE doesn't have it... :-(
+ // TODO: we should move this into IE/ES5 polyfill
+ if (!String.prototype.trim) {
+ return function(value) {
+ return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
+ };
+ }
+ return function(value) {
+ return isString(value) ? value.trim() : value;
+ };
+})();
+
/**
* @ngdoc function
* @name angular.isElement
@@ -477,7 +542,7 @@
function isElement(node) {
return node &&
(node.nodeName // we are a direct element
- || (node.bind && node.find)); // we have a bind and find method part of jQuery API
+ || (node.on && node.find)); // we have an on and find method part of jQuery API
}
/**
@@ -596,7 +661,10 @@
* @returns {*} The copy or updated `destination`, if `destination` was specified.
*/
function copy(source, destination){
- if (isWindow(source) || isScope(source)) throw Error("Can't copy Window or Scope");
+ if (isWindow(source) || isScope(source)) {
+ throw ngMinErr('cpws', "Can't copy! Making copies of Window or Scope instances is not supported.");
+ }
+
if (!destination) {
destination = source;
if (source) {
@@ -604,12 +672,14 @@
destination = copy(source, []);
} else if (isDate(source)) {
destination = new Date(source.getTime());
+ } else if (isRegExp(source)) {
+ destination = new RegExp(source.source);
} else if (isObject(source)) {
destination = copy(source, {});
}
}
} else {
- if (source === destination) throw Error("Can't copy equivalent objects or arrays");
+ if (source === destination) throw ngMinErr('cpi', "Can't copy! Source and destination are identical.");
if (isArray(source)) {
destination.length = 0;
for ( var i = 0; i < source.length; i++) {
@@ -651,7 +721,7 @@
* @function
*
* @description
- * Determines if two objects or two values are equivalent. Supports value types, arrays and
+ * Determines if two objects or two values are equivalent. Supports value types, regular expressions, arrays and
* objects.
*
* Two objects or values are considered equivalent if at least one of the following is true:
@@ -659,6 +729,9 @@
* * Both objects or values pass `===` comparison.
* * Both objects or values are of the same type and all of their properties pass `===` comparison.
* * Both values are NaN. (In JavasScript, NaN == NaN => false. But we consider two NaN as equal)
+ * * Both values represent the same regular expression (In JavasScript,
+ * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
+ * representation matches).
*
* During a property comparison, properties of `function` type and properties with names
* that begin with `$` are ignored.
@@ -677,6 +750,7 @@
if (t1 == t2) {
if (t1 == 'object') {
if (isArray(o1)) {
+ if (!isArray(o2)) return false;
if ((length = o1.length) == o2.length) {
for(key=0; key<length; key++) {
if (!equals(o1[key], o2[key])) return false;
@@ -685,8 +759,10 @@
}
} else if (isDate(o1)) {
return isDate(o2) && o1.getTime() == o2.getTime();
+ } else if (isRegExp(o1) && isRegExp(o2)) {
+ return o1.toString() == o2.toString();
} else {
- if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
+ if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false;
keySet = {};
for(key in o1) {
if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
@@ -694,7 +770,7 @@
keySet[key] = true;
}
for(key in o2) {
- if (!keySet[key] &&
+ if (!keySet.hasOwnProperty(key) &&
key.charAt(0) !== '$' &&
o2[key] !== undefined &&
!isFunction(o2[key])) return false;
@@ -775,13 +851,15 @@
* @function
*
* @description
- * Serializes input into a JSON-formatted string.
+ * Serializes input into a JSON-formatted string. Properties with leading $ characters will be
+ * stripped since angular uses this notation internally.
*
* @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
* @param {boolean=} pretty If set to true, the JSON output will contain newlines and whitespace.
- * @returns {string} Jsonified string representing `obj`.
+ * @returns {string|undefined} JSON-ified string representing `obj`.
*/
function toJson(obj, pretty) {
+ if (typeof obj === 'undefined') return undefined;
return JSON.stringify(obj, toJsonReplacer, pretty ? ' ' : null);
}
@@ -842,16 +920,42 @@
/////////////////////////////////////////////////
/**
+ * Tries to decode the URI component without throwing an exception.
+ *
+ * @private
+ * @param str value potential URI component to check.
+ * @returns {boolean} True if `value` can be decoded
+ * with the decodeURIComponent function.
+ */
+function tryDecodeURIComponent(value) {
+ try {
+ return decodeURIComponent(value);
+ } catch(e) {
+ // Ignore any invalid uri component
+ }
+}
+
+
+/**
* Parses an escaped url query string into key-value pairs.
* @returns Object.<(string|boolean)>
*/
function parseKeyValue(/**string*/keyValue) {
var obj = {}, key_value, key;
forEach((keyValue || "").split('&'), function(keyValue){
- if (keyValue) {
+ if ( keyValue ) {
key_value = keyValue.split('=');
- key = decodeURIComponent(key_value[0]);
- obj[key] = isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true;
+ key = tryDecodeURIComponent(key_value[0]);
+ if ( isDefined(key) ) {
+ var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
+ if (!obj[key]) {
+ obj[key] = val;
+ } else if(isArray(obj[key])) {
+ obj[key].push(val);
+ } else {
+ obj[key] = [obj[key],val];
+ }
+ }
}
});
return obj;
@@ -860,7 +964,13 @@
function toKeyValue(obj) {
var parts = [];
forEach(obj, function(value, key) {
+ if (isArray(value)) {
+ forEach(value, function(arrayValue) {
+ parts.push(encodeUriQuery(key, true) + (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
+ });
+ } else {
parts.push(encodeUriQuery(key, true) + (value === true ? '' : '=' + encodeUriQuery(value, true)));
+ }
});
return parts.length ? parts.join('&') : '';
}
@@ -917,10 +1027,14 @@
* @description
*
* Use this directive to auto-bootstrap an application. Only
- * one directive can be used per HTML document. The directive
+ * one ngApp directive can be used per HTML document. The directive
* designates the root of the application and is typically placed
* at the root of the page.
*
+ * The first ngApp found in the document will be auto-bootstrapped. To use multiple applications in an
+ * HTML document you must manually bootstrap them using {@link angular.bootstrap}.
+ * Applications cannot be nested.
+ *
* In the example below if the `ngApp` directive would not be placed
* on the `html` element then the document would not be compiled
* and the `{{ 1+2 }}` would not be resolved to `3`.
@@ -986,26 +1100,35 @@
*
* See: {@link guide/bootstrap Bootstrap}
*
+ * Note that ngScenario-based end-to-end tests cannot use this function to bootstrap manually.
+ * They must use {@link api/ng.directive:ngApp ngApp}.
+ *
* @param {Element} element DOM element which is the root of angular application.
* @param {Array<String|Function>=} modules an array of module declarations. See: {@link angular.module modules}
* @returns {AUTO.$injector} Returns the newly created injector for this app.
*/
function bootstrap(element, modules) {
- var resumeBootstrapInternal = function() {
+ var doBootstrap = function() {
element = jqLite(element);
+
+ if (element.injector()) {
+ var tag = (element[0] === document) ? 'document' : startingTag(element);
+ throw ngMinErr('btstrpd', "App Already Bootstrapped with this Element '{0}'", tag);
+ }
+
modules = modules || [];
modules.unshift(['$provide', function($provide) {
$provide.value('$rootElement', element);
}]);
modules.unshift('ng');
var injector = createInjector(modules);
- injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector', '$animator',
- function(scope, element, compile, injector, animator) {
+ injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector', '$animate',
+ function(scope, element, compile, injector, animate) {
scope.$apply(function() {
element.data('$injector', injector);
compile(element)(scope);
});
- animator.enabled(true);
+ animate.enabled(true);
}]
);
return injector;
@@ -1014,7 +1137,7 @@
var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
- return resumeBootstrapInternal();
+ return doBootstrap();
}
window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
@@ -1022,7 +1145,7 @@
forEach(extraModules, function(module) {
modules.push(module);
});
- resumeBootstrapInternal();
+ doBootstrap();
};
}
@@ -1046,9 +1169,10 @@
injector: JQLitePrototype.injector,
inheritedData: JQLitePrototype.inheritedData
});
- JQLitePatchJQueryRemove('remove', true);
- JQLitePatchJQueryRemove('empty');
- JQLitePatchJQueryRemove('html');
+ // Method signature: JQLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments)
+ JQLitePatchJQueryRemove('remove', true, true, false);
+ JQLitePatchJQueryRemove('empty', false, false, false);
+ JQLitePatchJQueryRemove('html', false, false, true);
} else {
jqLite = JQLite;
}
@@ -1060,7 +1184,7 @@
*/
function assertArg(arg, name, reason) {
if (!arg) {
- throw new Error("Argument '" + (name || '?') + "' is " + (reason || "required"));
+ throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required"));
}
return arg;
}
@@ -1076,6 +1200,33 @@
}
/**
+ * Return the value accessible from the object by path. Any undefined traversals are ignored
+ * @param {Object} obj starting object
+ * @param {string} path path to traverse
+ * @param {boolean=true} bindFnToScope
+ * @returns value as accessible by path
+ */
+//TODO(misko): this function needs to be removed
+function getter(obj, path, bindFnToScope) {
+ if (!path) return obj;
+ var keys = path.split('.');
+ var key;
+ var lastInstance = obj;
+ var len = keys.length;
+
+ for (var i = 0; i < len; i++) {
+ key = keys[i];
+ if (obj) {
+ obj = (lastInstance = obj)[key];
+ }
+ }
+ if (!bindFnToScope && isFunction(obj)) {
+ return bind(lastInstance, obj);
+ }
+ return obj;
+}
+
+/**
* @ngdoc interface
* @name angular.Module
* @description
@@ -1105,8 +1256,8 @@
*
* # Module
*
- * A module is a collocation of services, directives, filters, and configuration information. Module
- * is used to configure the {@link AUTO.$injector $injector}.
+ * A module is a collection of services, directives, filters, and configuration information.
+ * `angular.module` is used to configure the {@link AUTO.$injector $injector}.
*
* <pre>
* // Create a new module
@@ -1145,7 +1296,9 @@
}
return ensure(modules, name, function() {
if (!requires) {
- throw Error('No module: ' + name);
+ throw minErr('$injector')('nomod', "Module '{0}' is not available! You either misspelled the module name " +
+ "or forgot to load it. If registering a module ensure that you specify the dependencies as the second " +
+ "argument.", name);
}
/** @type {!Array.<Array.<*>>} */
@@ -1246,24 +1399,30 @@
* @param {Function} animationFactory Factory function for creating new instance of an animation.
* @description
*
- * Defines an animation hook that can be later used with {@link ng.directive:ngAnimate ngAnimate}
- * alongside {@link ng.directive:ngAnimate#Description common ng directives} as well as custom directives.
+ * **NOTE**: animations are take effect only if the **ngAnimate** module is loaded.
+ *
+ *
+ * Defines an animation hook that can be later used with {@link ngAnimate.$animate $animate} service and
+ * directives that use this service.
+ *
* <pre>
- * module.animation('animation-name', function($inject1, $inject2) {
+ * module.animation('.animation-name', function($inject1, $inject2) {
* return {
- * //this gets called in preparation to setup an animation
- * setup : function(element) { ... },
- *
- * //this gets called once the animation is run
- * start : function(element, done, memo) { ... }
+ * eventName : function(element, done) {
+ * //code to run the animation
+ * //once complete, then run done()
+ * return function cancellationFunction(element) {
+ * //code to cancel the animation
+ * }
+ * }
* }
* })
* </pre>
*
- * See {@link ng.$animationProvider#register $animationProvider.register()} and
- * {@link ng.directive:ngAnimate ngAnimate} for more information.
+ * See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and
+ * {@link ngAnimate ngAnimate module} for more information.
*/
- animation: invokeLater('$animationProvider', 'register'),
+ animation: invokeLater('$animateProvider', 'register'),
/**
* @ngdoc method
@@ -1364,11 +1523,11 @@
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/
var version = {
- full: '1.1.5', // all of these placeholder strings will be replaced by grunt's
+ full: '1.2.0rc1', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task
- minor: 1,
- dot: 5,
- codeName: 'triangle-squarification'
+ minor: 2,
+ dot: 0,
+ codeName: 'spooky-giraffe'
};
@@ -1394,12 +1553,12 @@
'isNumber': isNumber,
'isElement': isElement,
'isArray': isArray,
+ '$$minErr': minErr,
'version': version,
'isDate': isDate,
'lowercase': lowercase,
'uppercase': uppercase,
- 'callbacks': {counter: 0},
- 'noConflict': noConflict
+ 'callbacks': {counter: 0}
});
angularModule = setupModuleLoader(window);
@@ -1422,7 +1581,7 @@
style: styleDirective,
option: optionDirective,
ngBind: ngBindDirective,
- ngBindHtmlUnsafe: ngBindHtmlUnsafeDirective,
+ ngBindHtml: ngBindHtmlDirective,
ngBindTemplate: ngBindTemplateDirective,
ngClass: ngClassDirective,
ngClassEven: ngClassEvenDirective,
@@ -1439,13 +1598,11 @@
ngPluralize: ngPluralizeDirective,
ngRepeat: ngRepeatDirective,
ngShow: ngShowDirective,
- ngSubmit: ngSubmitDirective,
ngStyle: ngStyleDirective,
ngSwitch: ngSwitchDirective,
ngSwitchWhen: ngSwitchWhenDirective,
ngSwitchDefault: ngSwitchDefaultDirective,
ngOptions: ngOptionsDirective,
- ngView: ngViewDirective,
ngTransclude: ngTranscludeDirective,
ngModel: ngModelDirective,
ngList: ngListDirective,
@@ -1458,8 +1615,7 @@
directive(ngEventDirectives);
$provide.provider({
$anchorScroll: $AnchorScrollProvider,
- $animation: $AnimationProvider,
- $animator: $AnimatorProvider,
+ $animate: $AnimateProvider,
$browser: $BrowserProvider,
$cacheFactory: $CacheFactoryProvider,
$controller: $ControllerProvider,
@@ -1472,14 +1628,15 @@
$location: $LocationProvider,
$log: $LogProvider,
$parse: $ParseProvider,
- $route: $RouteProvider,
- $routeParams: $RouteParamsProvider,
$rootScope: $RootScopeProvider,
$q: $QProvider,
+ $sce: $SceProvider,
+ $sceDelegate: $SceDelegateProvider,
$sniffer: $SnifferProvider,
$templateCache: $TemplateCacheProvider,
$timeout: $TimeoutProvider,
- $window: $WindowProvider
+ $window: $WindowProvider,
+ $$urlUtils: $$UrlUtilsProvider
});
}
]);
@@ -1511,13 +1668,14 @@
* Note: All element references in Angular are always wrapped with jQuery or jqLite; they are never
* raw DOM references.
*
- * ## Angular's jQuery lite provides the following methods:
+ * ## Angular's jqLite
+ * Angular's lite version of jQuery provides only the following jQuery methods:
*
* - [addClass()](http://api.jquery.com/addClass/)
* - [after()](http://api.jquery.com/after/)
* - [append()](http://api.jquery.com/append/)
* - [attr()](http://api.jquery.com/attr/)
- * - [bind()](http://api.jquery.com/bind/) - Does not support namespaces
+ * - [bind()](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
* - [children()](http://api.jquery.com/children/) - Does not support selectors
* - [clone()](http://api.jquery.com/clone/)
* - [contents()](http://api.jquery.com/contents/)
@@ -1528,6 +1686,8 @@
* - [hasClass()](http://api.jquery.com/hasClass/)
* - [html()](http://api.jquery.com/html/)
* - [next()](http://api.jquery.com/next/) - Does not support selectors
+ * - [on()](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
+ * - [off()](http://api.jquery.com/off/) - Does not support namespaces or selectors
* - [parent()](http://api.jquery.com/parent/) - Does not support selectors
* - [prepend()](http://api.jquery.com/prepend/)
* - [prop()](http://api.jquery.com/prop/)
@@ -1540,12 +1700,18 @@
* - [text()](http://api.jquery.com/text/)
* - [toggleClass()](http://api.jquery.com/toggleClass/)
* - [triggerHandler()](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers.
- * - [unbind()](http://api.jquery.com/unbind/) - Does not support namespaces
+ * - [unbind()](http://api.jquery.com/off/) - Does not support namespaces
* - [val()](http://api.jquery.com/val/)
* - [wrap()](http://api.jquery.com/wrap/)
*
- * ## In addition to the above, Angular provides additional methods to both jQuery and jQuery lite:
+ * ## jQuery/jqLite Extras
+ * Angular also provides the following additional methods and events to both jQuery and jqLite:
*
+ * ### Events
+ * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event
+ * on all DOM nodes being removed. This can be used to clean up and 3rd party bindings to the DOM
+ * element before it is removed.
+ * ### Methods
* - `controller(name)` - retrieves the controller of the current element or its parent. By default
* retrieves controller associated with the `ngController` directive. If `name` is provided as
* camelCase directive name, then the controller for this directive will be retrieved (e.g.
@@ -1575,6 +1741,7 @@
var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
var MOZ_HACK_REGEXP = /^moz([A-Z])/;
+var jqLiteMinErr = minErr('jqLite');
/**
* Converts snake_case to camelCase.
@@ -1592,38 +1759,39 @@
/////////////////////////////////////////////
// jQuery mutation patch
//
-// In conjunction with bindJQuery intercepts all jQuery's DOM destruction apis and fires a
+// In conjunction with bindJQuery intercepts all jQuery's DOM destruction apis and fires a
// $destroy event on all DOM nodes being removed.
//
/////////////////////////////////////////////
-function JQLitePatchJQueryRemove(name, dispatchThis) {
+function JQLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments) {
var originalJqFn = jQuery.fn[name];
originalJqFn = originalJqFn.$original || originalJqFn;
removePatch.$original = originalJqFn;
jQuery.fn[name] = removePatch;
- function removePatch() {
- var list = [this],
+ function removePatch(param) {
+ var list = filterElems && param ? [this.filter(param)] : [this],
fireEvent = dispatchThis,
set, setIndex, setLength,
- element, childIndex, childLength, children,
- fns, events;
+ element, childIndex, childLength, children;
- while(list.length) {
- set = list.shift();
- for(setIndex = 0, setLength = set.length; setIndex < setLength; setIndex++) {
- element = jqLite(set[setIndex]);
- if (fireEvent) {
- element.triggerHandler('$destroy');
- } else {
- fireEvent = !fireEvent;
+ if (!getterIfNoArguments || param != null) {
+ while(list.length) {
+ set = list.shift();
+ for(setIndex = 0, setLength = set.length; setIndex < setLength; setIndex++) {
+ element = jqLite(set[setIndex]);
+ if (fireEvent) {
+ element.triggerHandler('$destroy');
+ } else {
+ fireEvent = !fireEvent;
+ }
+ for(childIndex = 0, childLength = (children = element.children()).length;
+ childIndex < childLength;
+ childIndex++) {
+ list.push(jQuery(children[childIndex]));
+ }
}
- for(childIndex = 0, childLength = (children = element.children()).length;
- childIndex < childLength;
- childIndex++) {
- list.push(jQuery(children[childIndex]));
- }
}
}
return originalJqFn.apply(this, arguments);
@@ -1637,7 +1805,7 @@
}
if (!(this instanceof JQLite)) {
if (isString(element) && element.charAt(0) != '<') {
- throw Error('selectors not implemented');
+ throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
}
return new JQLite(element);
}
@@ -1649,7 +1817,8 @@
div.innerHTML = '<div> </div>' + element; // IE insanity to make NoScope elements work!
div.removeChild(div.firstChild); // remove the superfluous div
JQLiteAddNodes(this, div.childNodes);
- this.remove(); // detach the elements from the temporary DOM div.
+ var fragment = jqLite(document.createDocumentFragment());
+ fragment.append(this); // detach the elements from the temporary DOM div.
} else {
JQLiteAddNodes(this, element);
}
@@ -1666,7 +1835,9 @@
}
}
-function JQLiteUnbind(element, type, fn) {
+function JQLiteOff(element, type, fn, unsupported) {
+ if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument');
+
var events = JQLiteExpandoStore(element, 'events'),
handle = JQLiteExpandoStore(element, 'handle');
@@ -1678,23 +1849,30 @@
delete events[type];
});
} else {
- if (isUndefined(fn)) {
- removeEventListenerFn(element, type, events[type]);
- delete events[type];
- } else {
- arrayRemove(events[type], fn);
- }
+ forEach(type.split(' '), function(type) {
+ if (isUndefined(fn)) {
+ removeEventListenerFn(element, type, events[type]);
+ delete events[type];
+ } else {
+ arrayRemove(events[type] || [], fn);
+ }
+ });
}
}
-function JQLiteRemoveData(element) {
+function JQLiteRemoveData(element, name) {
var expandoId = element[jqName],
expandoStore = jqCache[expandoId];
if (expandoStore) {
+ if (name) {
+ delete jqCache[expandoId].data[name];
+ return;
+ }
+
if (expandoStore.handle) {
expandoStore.events.$destroy && expandoStore.handle({}, '$destroy');
- JQLiteUnbind(element);
+ JQLiteOff(element);
}
delete jqCache[expandoId];
element[jqName] = undefined; // ie does not allow deletion of attributes on elements.
@@ -1794,7 +1972,7 @@
}
while (element.length) {
- if (value = element.data(name)) return value;
+ if ((value = element.data(name)) !== undefined) return value;
element = element.parent();
}
}
@@ -1816,9 +1994,9 @@
if (document.readyState === 'complete'){
setTimeout(trigger);
} else {
- this.bind('DOMContentLoaded', trigger); // works for modern browsers and IE9
+ this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9
// we can not use jqLite since we are not done loading and jQuery could be loaded later.
- JQLite(window).bind('load', trigger); // fallback to window.onload for others
+ JQLite(window).on('load', trigger); // fallback to window.onload for others
}
},
toString: function() {
@@ -1940,27 +2118,38 @@
}
},
- text: extend((msie < 9)
- ? function(element, value) {
- if (element.nodeType == 1 /** Element */) {
- if (isUndefined(value))
- return element.innerText;
- element.innerText = value;
- } else {
- if (isUndefined(value))
- return element.nodeValue;
- element.nodeValue = value;
- }
+ text: (function() {
+ var NODE_TYPE_TEXT_PROPERTY = [];
+ if (msie < 9) {
+ NODE_TYPE_TEXT_PROPERTY[1] = 'innerText'; /** Element **/
+ NODE_TYPE_TEXT_PROPERTY[3] = 'nodeValue'; /** Text **/
+ } else {
+ NODE_TYPE_TEXT_PROPERTY[1] = /** Element **/
+ NODE_TYPE_TEXT_PROPERTY[3] = 'textContent'; /** Text **/
+ }
+ getText.$dv = '';
+ return getText;
+
+ function getText(element, value) {
+ var textProp = NODE_TYPE_TEXT_PROPERTY[element.nodeType]
+ if (isUndefined(value)) {
+ return textProp ? element[textProp] : '';
}
- : function(element, value) {
- if (isUndefined(value)) {
- return element.textContent;
- }
- element.textContent = value;
- }, {$dv:''}),
+ element[textProp] = value;
+ }
+ })(),
val: function(element, value) {
if (isUndefined(value)) {
+ if (nodeName_(element) === 'SELECT' && element.multiple) {
+ var result = [];
+ forEach(element.options, function (option) {
+ if (option.selected) {
+ result.push(option.value || option.text);
+ }
+ });
+ return result.length === 0 ? null : result;
+ }
return element.value;
}
element.value = value;
@@ -2002,8 +2191,14 @@
return this;
} else {
// we are a read, so read the first child.
- if (this.length)
- return fn(this[0], arg1, arg2);
+ var value = fn.$dv;
+ // Only if we have $dv do we iterate over all, otherwise it is just the first element.
+ var jj = value == undefined ? Math.min(this.length, 1) : this.length;
+ for (var j = 0; j < jj; j++) {
+ var nodeValue = fn(this[j], arg1, arg2);
+ value = value ? value + nodeValue : nodeValue;
+ }
+ return value;
}
} else {
// we are a write, so apply to all children
@@ -2013,7 +2208,6 @@
// return self for chaining
return this;
}
- return fn.$dv;
};
});
@@ -2080,7 +2274,9 @@
dealoc: JQLiteDealoc,
- bind: function bindFn(element, type, fn){
+ on: function onFn(element, type, fn, unsupported){
+ if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');
+
var events = JQLiteExpandoStore(element, 'events'),
handle = JQLiteExpandoStore(element, 'handle');
@@ -2111,22 +2307,22 @@
}
}
return false;
- };
+ };
events[type] = [];
-
- // Refer to jQuery's implementation of mouseenter & mouseleave
+
+ // Refer to jQuery's implementation of mouseenter & mouseleave
// Read about mouseenter and mouseleave:
// http://www.quirksmode.org/js/events_mouse.html#link8
- var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"}
- bindFn(element, eventmap[type], function(event) {
- var ret, target = this, related = event.relatedTarget;
+ var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"};
+
+ onFn(element, eventmap[type], function(event) {
+ var target = this, related = event.relatedTarget;
// For mousenter/leave call the handler if related is outside the target.
// NB: No relatedTarget if the mouse left/entered the browser window
if ( !related || (related !== target && !contains(target, related)) ){
handle(event, type);
- }
-
+ }
});
} else {
@@ -2139,7 +2335,7 @@
});
},
- unbind: JQLiteUnbind,
+ off: JQLiteOff,
replaceWith: function(element, replaceNode) {
var index, parent = element.parentNode;
@@ -2179,12 +2375,7 @@
if (element.nodeType === 1) {
var index = element.firstChild;
forEach(new JQLite(node), function(child){
- if (index) {
- element.insertBefore(child, index);
- } else {
- element.appendChild(child);
- index = child;
- }
+ element.insertBefore(child, index);
});
}
},
@@ -2246,33 +2437,40 @@
clone: JQLiteClone,
- triggerHandler: function(element, eventName) {
+ triggerHandler: function(element, eventName, eventData) {
var eventFns = (JQLiteExpandoStore(element, 'events') || {})[eventName];
- var event;
+ eventData = eventData || {
+ preventDefault: noop,
+ stopPropagation: noop
+ };
forEach(eventFns, function(fn) {
- fn.call(element, {preventDefault: noop});
+ fn.call(element, eventData);
});
}
}, function(fn, name){
/**
* chaining functions
*/
- JQLite.prototype[name] = function(arg1, arg2) {
+ JQLite.prototype[name] = function(arg1, arg2, arg3) {
var value;
for(var i=0; i < this.length; i++) {
if (value == undefined) {
- value = fn(this[i], arg1, arg2);
+ value = fn(this[i], arg1, arg2, arg3);
if (value !== undefined) {
// any function which returns a value needs to be wrapped
value = jqLite(value);
}
} else {
- JQLiteAddNodes(value, fn(this[i], arg1, arg2));
+ JQLiteAddNodes(value, fn(this[i], arg1, arg2, arg3));
}
}
return value == undefined ? this : value;
};
+
+ // bind legacy bind/unbind to on/off
+ JQLite.prototype.bind = JQLite.prototype.on;
+ JQLite.prototype.unbind = JQLite.prototype.off;
});
/**
@@ -2382,6 +2580,7 @@
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
+var $injectorMinErr = minErr('$injector');
function annotate(fn) {
var $inject,
fnText,
@@ -2541,7 +2740,7 @@
* expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
* </pre>
*
- * This method does not work with code minfication / obfuscation. For this reason the following annotation strategies
+ * This method does not work with code minification / obfuscation. For this reason the following annotation strategies
* are supported.
*
* # The `$inject` property
@@ -2762,7 +2961,7 @@
},
providerInjector = (providerCache.$injector =
createInternalInjector(providerCache, function() {
- throw Error("Unknown provider: " + path.join(' <- '));
+ throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));
})),
instanceCache = {},
instanceInjector = (instanceCache.$injector =
@@ -2795,7 +2994,7 @@
provider_ = providerInjector.instantiate(provider_);
}
if (!provider_.$get) {
- throw Error('Provider ' + name + ' must define $get factory method.');
+ throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name);
}
return providerCache[name + providerSuffix] = provider_;
}
@@ -2833,37 +3032,36 @@
forEach(modulesToLoad, function(module) {
if (loadedModules.get(module)) return;
loadedModules.put(module, true);
- if (isString(module)) {
- var moduleFn = angularModule(module);
- runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
- try {
+ try {
+ if (isString(module)) {
+ var moduleFn = angularModule(module);
+ runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
+
for(var invokeQueue = moduleFn._invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) {
var invokeArgs = invokeQueue[i],
provider = providerInjector.get(invokeArgs[0]);
provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
}
- } catch (e) {
- if (e.message) e.message += ' from ' + module;
- throw e;
+ } else if (isFunction(module)) {
+ runBlocks.push(providerInjector.invoke(module));
+ } else if (isArray(module)) {
+ runBlocks.push(providerInjector.invoke(module));
+ } else {
+ assertArgFn(module, 'module');
}
- } else if (isFunction(module)) {
- try {
- runBlocks.push(providerInjector.invoke(module));
- } catch (e) {
- if (e.message) e.message += ' from ' + module;
- throw e;
+ } catch (e) {
+ if (isArray(module)) {
+ module = module[module.length - 1];
}
- } else if (isArray(module)) {
- try {
- runBlocks.push(providerInjector.invoke(module));
- } catch (e) {
- if (e.message) e.message += ' from ' + String(module[module.length - 1]);
- throw e;
+ if (e.message && e.stack && e.stack.indexOf(e.message) == -1) {
+ // Safari & FF's stack traces don't contain error.message content unlike those of Chrome and IE
+ // So if stack doesn't contain message, we create a new string that contains both.
+ // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here.
+ e = e.message + '\n' + e.stack;
}
- } else {
- assertArgFn(module, 'module');
+ throw $injectorMinErr('modulerr', "Failed to instantiate module {0} due to:\n{1}", module, e.stack || e.message || e);
}
});
return runBlocks;
@@ -2876,12 +3074,9 @@
function createInternalInjector(cache, factory) {
function getService(serviceName) {
- if (typeof serviceName !== 'string') {
- throw Error('Service name expected');
- }
if (cache.hasOwnProperty(serviceName)) {
if (cache[serviceName] === INSTANTIATING) {
- throw Error('Circular dependency: ' + path.join(' <- '));
+ throw $injectorMinErr('cdep', 'Circular dependency found: {0}', path.join(' <- '));
}
return cache[serviceName];
} else {
@@ -2903,6 +3098,9 @@
for(i = 0, length = $inject.length; i < length; i++) {
key = $inject[i];
+ if (typeof key !== 'string') {
+ throw $injectorMinErr('itkn', 'Incorrect injection token! Expected service name as string, got {0}', key);
+ }
args.push(
locals && locals.hasOwnProperty(key)
? locals[key]
@@ -3024,505 +3222,191 @@
}];
}
+var $animateMinErr = minErr('$animate');
/**
* @ngdoc object
- * @name ng.$animationProvider
+ * @name ng.$animateProvider
+ *
* @description
+ * Default implementation of $animate that doesn't perform any animations, instead just synchronously performs DOM
+ * updates and calls done() callbacks.
*
- * The $AnimationProvider provider allows developers to register and access custom JavaScript animations directly inside
- * of a module.
+ * In order to enable animations the ngAnimate module has to be loaded.
*
+ * To see the functional implementation check out src/ngAnimate/animate.js
*/
-$AnimationProvider.$inject = ['$provide'];
-function $AnimationProvider($provide) {
- var suffix = 'Animation';
+var $AnimateProvider = ['$provide', function($provide) {
+ this.$$selectors = {};
+
+
/**
* @ngdoc function
- * @name ng.$animation#register
- * @methodOf ng.$animationProvider
+ * @name ng.$animateProvider#register
+ * @methodOf ng.$animateProvider
*
* @description
* Registers a new injectable animation factory function. The factory function produces the animation object which
- * has these two properties:
+ * contains callback functions for each event that is expected to be animated.
*
- * * `setup`: `function(Element):*` A function which receives the starting state of the element. The purpose
- * of this function is to get the element ready for animation. Optionally the function returns an memento which
- * is passed to the `start` function.
- * * `start`: `function(Element, doneFunction, *)` The element to animate, the `doneFunction` to be called on
- * element animation completion, and an optional memento from the `setup` function.
+ * * `eventFn`: `function(Element, doneFunction)` The element to animate, the `doneFunction` must be called once the
+ * element animation is complete. If a function is returned then the animation service will use this function to
+ * cancel the animation whenever a cancel event is triggered.
*
+ *
+ *<pre>
+ * return {
+ * eventFn : function(element, done) {
+ * //code to run the animation
+ * //once complete, then run done()
+ * return function cancellationFunction() {
+ * //code to cancel the animation
+ * }
+ * }
+ * }
+ *</pre>
+ *
* @param {string} name The name of the animation.
* @param {function} factory The factory function that will be executed to return the animation object.
- *
*/
this.register = function(name, factory) {
- $provide.factory(camelCase(name) + suffix, factory);
+ var key = name + '-animation';
+ if (name && name.charAt(0) != '.') throw $animateMinErr('notcsel',
+ "Expecting class selector starting with '.' got '{0}'.", name);
+ this.$$selectors[name.substr(1)] = key;
+ $provide.factory(key, factory);
};
- this.$get = ['$injector', function($injector) {
+ this.$get = ['$timeout', function($timeout) {
+
/**
- * @ngdoc function
- * @name ng.$animation
- * @function
+ * @ngdoc object
+ * @name ng.$animate
*
* @description
- * The $animation service is used to retrieve any defined animation functions. When executed, the $animation service
- * will return a object that contains the setup and start functions that were defined for the animation.
+ * The $animate service provides rudimentary DOM manipulation functions to insert, remove, move elements within
+ * the DOM as well as adding and removing classes. This service is the core service used by the ngAnimate $animator
+ * service which provides high-level animation hooks for CSS and JavaScript.
*
- * @param {String} name Name of the animation function to retrieve. Animation functions are registered and stored
- * inside of the AngularJS DI so a call to $animate('custom') is the same as injecting `customAnimation`
- * via dependency injection.
- * @return {Object} the animation object which contains the `setup` and `start` functions that perform the animation.
- */
- return function $animation(name) {
- if (name) {
- var animationName = camelCase(name) + suffix;
- if ($injector.has(animationName)) {
- return $injector.get(animationName);
- }
- }
- };
- }];
-}
-
-// NOTE: this is a pseudo directive.
-
-/**
- * @ngdoc directive
- * @name ng.directive:ngAnimate
- *
- * @description
- * The `ngAnimate` directive works as an attribute that is attached alongside pre-existing directives.
- * It effects how the directive will perform DOM manipulation. This allows for complex animations to take place
- * without burdening the directive which uses the animation with animation details. The built in directives
- * `ngRepeat`, `ngInclude`, `ngSwitch`, `ngShow`, `ngHide` and `ngView` already accept `ngAnimate` directive.
- * Custom directives can take advantage of animation through {@link ng.$animator $animator service}.
- *
- * Below is a more detailed breakdown of the supported callback events provided by pre-exisitng ng directives:
- *
- * | Directive | Supported Animations |
- * |========================================================== |====================================================|
- * | {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave and move |
- * | {@link ng.directive:ngView#animations ngView} | enter and leave |
- * | {@link ng.directive:ngInclude#animations ngInclude} | enter and leave |
- * | {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave |
- * | {@link ng.directive:ngIf#animations ngIf} | enter and leave |
- * | {@link ng.directive:ngShow#animations ngShow & ngHide} | show and hide |
- *
- * You can find out more information about animations upon visiting each directive page.
- *
- * Below is an example of a directive that makes use of the ngAnimate attribute:
- *
- * <pre>
- * <!-- you can also use data-ng-animate, ng:animate or x-ng-animate as well -->
- * <ANY ng-directive ng-animate="{event1: 'animation-name', event2: 'animation-name-2'}"></ANY>
- *
- * <!-- you can also use a short hand -->
- * <ANY ng-directive ng-animate=" 'animation' "></ANY>
- * <!-- which expands to -->
- * <ANY ng-directive ng-animate="{ enter: 'animation-enter', leave: 'animation-leave', ...}"></ANY>
- *
- * <!-- keep in mind that ng-animate can take expressions -->
- * <ANY ng-directive ng-animate=" computeCurrentAnimation() "></ANY>
- * </pre>
- *
- * The `event1` and `event2` attributes refer to the animation events specific to the directive that has been assigned.
- *
- * Keep in mind that if an animation is running, no child element of such animation can also be animated.
- *
- * <h2>CSS-defined Animations</h2>
- * By default, ngAnimate attaches two CSS classes per animation event to the DOM element to achieve the animation.
- * It is up to you, the developer, to ensure that the animations take place using cross-browser CSS3 transitions as
- * well as CSS animations.
- *
- * The following code below demonstrates how to perform animations using **CSS transitions** with ngAnimate:
- *
- * <pre>
- * <style type="text/css">
- * /*
- * The animate-enter CSS class is the event name that you
- * have provided within the ngAnimate attribute.
- * */
- * .animate-enter {
- * -webkit-transition: 1s linear all; /* Safari/Chrome */
- * -moz-transition: 1s linear all; /* Firefox */
- * -o-transition: 1s linear all; /* Opera */
- * transition: 1s linear all; /* IE10+ and Future Browsers */
- *
- * /* The animation preparation code */
- * opacity: 0;
- * }
- *
- * /*
- * Keep in mind that you want to combine both CSS
- * classes together to avoid any CSS-specificity
- * conflicts
- * */
- * .animate-enter.animate-enter-active {
- * /* The animation code itself */
- * opacity: 1;
- * }
- * </style>
- *
- * <div ng-directive ng-animate="{enter: 'animate-enter'}"></div>
- * </pre>
- *
- * The following code below demonstrates how to perform animations using **CSS animations** with ngAnimate:
- *
- * <pre>
- * <style type="text/css">
- * .animate-enter {
- * -webkit-animation: enter_sequence 1s linear; /* Safari/Chrome */
- * -moz-animation: enter_sequence 1s linear; /* Firefox */
- * -o-animation: enter_sequence 1s linear; /* Opera */
- * animation: enter_sequence 1s linear; /* IE10+ and Future Browsers */
- * }
- * @-webkit-keyframes enter_sequence {
- * from { opacity:0; }
- * to { opacity:1; }
- * }
- * @-moz-keyframes enter_sequence {
- * from { opacity:0; }
- * to { opacity:1; }
- * }
- * @-o-keyframes enter_sequence {
- * from { opacity:0; }
- * to { opacity:1; }
- * }
- * @keyframes enter_sequence {
- * from { opacity:0; }
- * to { opacity:1; }
- * }
- * </style>
- *
- * <div ng-directive ng-animate="{enter: 'animate-enter'}"></div>
- * </pre>
- *
- * ngAnimate will first examine any CSS animation code and then fallback to using CSS transitions.
- *
- * Upon DOM mutation, the event class is added first, then the browser is allowed to reflow the content and then,
- * the active class is added to trigger the animation. The ngAnimate directive will automatically extract the duration
- * of the animation to determine when the animation ends. Once the animation is over then both CSS classes will be
- * removed from the DOM. If a browser does not support CSS transitions or CSS animations then the animation will start and end
- * immediately resulting in a DOM element that is at it's final state. This final state is when the DOM element
- * has no CSS transition/animation classes surrounding it.
- *
- * <h2>JavaScript-defined Animations</h2>
- * In the event that you do not want to use CSS3 transitions or CSS3 animations or if you wish to offer animations to browsers that do not
- * yet support them, then you can make use of JavaScript animations defined inside of your AngularJS module.
- *
- * <pre>
- * var ngModule = angular.module('YourApp', []);
- * ngModule.animation('animate-enter', function() {
- * return {
- * setup : function(element) {
- * //prepare the element for animation
- * element.css({ 'opacity': 0 });
- * var memo = "..."; //this value is passed to the start function
- * return memo;
- * },
- * start : function(element, done, memo) {
- * //start the animation
- * element.animate({
- * 'opacity' : 1
- * }, function() {
- * //call when the animation is complete
- * done()
- * });
- * }
- * }
- * });
- * </pre>
- *
- * As you can see, the JavaScript code follows a similar template to the CSS3 animations. Once defined, the animation
- * can be used in the same way with the ngAnimate attribute. Keep in mind that, when using JavaScript-enabled
- * animations, ngAnimate will also add in the same CSS classes that CSS-enabled animations do (even if you're not using
- * CSS animations) to animated the element, but it will not attempt to find any CSS3 transition or animation duration/delay values.
- * It will instead close off the animation once the provided done function is executed. So it's important that you
- * make sure your animations remember to fire off the done function once the animations are complete.
- *
- * @param {expression} ngAnimate Used to configure the DOM manipulation animations.
- *
- */
-
-var $AnimatorProvider = function() {
- var NG_ANIMATE_CONTROLLER = '$ngAnimateController';
- var rootAnimateController = {running:true};
-
- this.$get = ['$animation', '$window', '$sniffer', '$rootElement', '$rootScope',
- function($animation, $window, $sniffer, $rootElement, $rootScope) {
- $rootElement.data(NG_ANIMATE_CONTROLLER, rootAnimateController);
-
- /**
- * @ngdoc function
- * @name ng.$animator
- * @function
+ * $animate is available in the AngularJS core, however, the ngAnimate module must be included to enable full out
+ * animation support. Otherwise, $animate will only perform simple DOM manipulation operations.
*
- * @description
- * The $animator.create service provides the DOM manipulation API which is decorated with animations.
- *
- * @param {Scope} scope the scope for the ng-animate.
- * @param {Attributes} attr the attributes object which contains the ngAnimate key / value pair. (The attributes are
- * passed into the linking function of the directive using the `$animator`.)
- * @return {object} the animator object which contains the enter, leave, move, show, hide and animate methods.
+ * To learn more about enabling animation support, click here to visit the {@link ngAnimate ngAnimate module page}
+ * as well as the {@link ngAnimate.$animate ngAnimate $animate service page}.
*/
- var AnimatorService = function(scope, attrs) {
- var animator = {};
-
- /**
- * @ngdoc function
- * @name ng.animator#enter
- * @methodOf ng.$animator
- * @function
- *
- * @description
- * Injects the element object into the DOM (inside of the parent element) and then runs the enter animation.
- *
- * @param {jQuery/jqLite element} element the element that will be the focus of the enter animation
- * @param {jQuery/jqLite element} parent the parent element of the element that will be the focus of the enter animation
- * @param {jQuery/jqLite element} after the sibling element (which is the previous element) of the element that will be the focus of the enter animation
- */
- animator.enter = animateActionFactory('enter', insert, noop);
-
- /**
- * @ngdoc function
- * @name ng.animator#leave
- * @methodOf ng.$animator
- * @function
- *
- * @description
- * Runs the leave animation operation and, upon completion, removes the element from the DOM.
- *
- * @param {jQuery/jqLite element} element the element that will be the focus of the leave animation
- * @param {jQuery/jqLite element} parent the parent element of the element that will be the focus of the leave animation
- */
- animator.leave = animateActionFactory('leave', noop, remove);
-
- /**
- * @ngdoc function
- * @name ng.animator#move
- * @methodOf ng.$animator
- * @function
- *
- * @description
- * Fires the move DOM operation. Just before the animation starts, the animator will either append it into the parent container or
- * add the element directly after the after element if present. Then the move animation will be run.
- *
- * @param {jQuery/jqLite element} element the element that will be the focus of the move animation
- * @param {jQuery/jqLite element} parent the parent element of the element that will be the focus of the move animation
- * @param {jQuery/jqLite element} after the sibling element (which is the previous element) of the element that will be the focus of the move animation
- */
- animator.move = animateActionFactory('move', move, noop);
-
- /**
- * @ngdoc function
- * @name ng.animator#show
- * @methodOf ng.$animator
- * @function
- *
- * @description
- * Reveals the element by setting the CSS property `display` to `block` and then starts the show animation directly after.
- *
- * @param {jQuery/jqLite element} element the element that will be rendered visible or hidden
- */
- animator.show = animateActionFactory('show', show, noop);
-
- /**
- * @ngdoc function
- * @name ng.animator#hide
- * @methodOf ng.$animator
- *
- * @description
- * Starts the hide animation first and sets the CSS `display` property to `none` upon completion.
- *
- * @param {jQuery/jqLite element} element the element that will be rendered visible or hidden
- */
- animator.hide = animateActionFactory('hide', noop, hide);
+ return {
- /**
- * @ngdoc function
- * @name ng.animator#animate
- * @methodOf ng.$animator
- *
- * @description
- * Triggers a custom animation event to be executed on the given element
- *
- * @param {jQuery/jqLite element} element that will be animated
- */
- animator.animate = function(event, element) {
- animateActionFactory(event, noop, noop)(element);
- }
- return animator;
-
- function animateActionFactory(type, beforeFn, afterFn) {
- return function(element, parent, after) {
- var ngAnimateValue = scope.$eval(attrs.ngAnimate);
- var className = ngAnimateValue
- ? isObject(ngAnimateValue) ? ngAnimateValue[type] : ngAnimateValue + '-' + type
- : '';
- var animationPolyfill = $animation(className);
- var polyfillSetup = animationPolyfill && animationPolyfill.setup;
- var polyfillStart = animationPolyfill && animationPolyfill.start;
- var polyfillCancel = animationPolyfill && animationPolyfill.cancel;
+ /**
+ * @ngdoc function
+ * @name ng.$animate#enter
+ * @methodOf ng.$animate
+ * @function
+ *
+ * @description
+ * Inserts the element into the DOM either after the `after` element or within the `parent` element. Once complete,
+ * the done() callback will be fired (if provided).
+ *
+ * @param {jQuery/jqLite element} element the element which will be inserted into the DOM
+ * @param {jQuery/jqLite element} parent the parent element which will append the element as a child (if the after element is not present)
+ * @param {jQuery/jqLite element} after the sibling element which will append the element after itself
+ * @param {function=} done callback function that will be called after the element has been inserted into the DOM
+ */
+ enter : function(element, parent, after, done) {
+ var afterNode = after && after[after.length - 1];
+ var parentNode = parent && parent[0] || afterNode && afterNode.parentNode;
+ // IE does not like undefined so we have to pass null.
+ var afterNextSibling = (afterNode && afterNode.nextSibling) || null;
+ forEach(element, function(node) {
+ parentNode.insertBefore(node, afterNextSibling);
+ });
+ $timeout(done || noop, 0, false);
+ },
- if (!className) {
- beforeFn(element, parent, after);
- afterFn(element, parent, after);
- } else {
- var activeClassName = className + '-active';
+ /**
+ * @ngdoc function
+ * @name ng.$animate#leave
+ * @methodOf ng.$animate
+ * @function
+ *
+ * @description
+ * Removes the element from the DOM. Once complete, the done() callback will be fired (if provided).
+ *
+ * @param {jQuery/jqLite element} element the element which will be removed from the DOM
+ * @param {function=} done callback function that will be called after the element has been removed from the DOM
+ */
+ leave : function(element, done) {
+ element.remove();
+ $timeout(done || noop, 0, false);
+ },
- if (!parent) {
- parent = after ? after.parent() : element.parent();
- }
- if ((!$sniffer.transitions && !polyfillSetup && !polyfillStart) ||
- (parent.inheritedData(NG_ANIMATE_CONTROLLER) || noop).running) {
- beforeFn(element, parent, after);
- afterFn(element, parent, after);
- return;
- }
+ /**
+ * @ngdoc function
+ * @name ng.$animate#move
+ * @methodOf ng.$animate
+ * @function
+ *
+ * @description
+ * Moves the position of the provided element within the DOM to be placed either after the `after` element or inside of the `parent` element.
+ * Once complete, the done() callback will be fired (if provided).
+ *
+ * @param {jQuery/jqLite element} element the element which will be moved around within the DOM
+ * @param {jQuery/jqLite element} parent the parent element where the element will be inserted into (if the after element is not present)
+ * @param {jQuery/jqLite element} after the sibling element where the element will be positioned next to
+ * @param {function=} done the callback function (if provided) that will be fired after the element has been moved to it's new position
+ */
+ move : function(element, parent, after, done) {
+ // Do not remove element before insert. Removing will cause data associated with the
+ // element to be dropped. Insert will implicitly do the remove.
+ this.enter(element, parent, after, done);
+ },
- var animationData = element.data(NG_ANIMATE_CONTROLLER) || {};
- if(animationData.running) {
- (polyfillCancel || noop)(element);
- animationData.done();
- }
+ /**
+ * @ngdoc function
+ * @name ng.$animate#addClass
+ * @methodOf ng.$animate
+ * @function
+ *
+ * @description
+ * Adds the provided className CSS class value to the provided element. Once complete, the done() callback will be fired (if provided).
+ *
+ * @param {jQuery/jqLite element} element the element which will have the className value added to it
+ * @param {string} className the CSS class which will be added to the element
+ * @param {function=} done the callback function (if provided) that will be fired after the className value has been added to the element
+ */
+ addClass : function(element, className, done) {
+ className = isString(className) ?
+ className :
+ isArray(className) ? className.join(' ') : '';
+ element.addClass(className);
+ $timeout(done || noop, 0, false);
+ },
- element.data(NG_ANIMATE_CONTROLLER, {running:true, done:done});
- element.addClass(className);
- beforeFn(element, parent, after);
- if (element.length == 0) return done();
+ /**
+ * @ngdoc function
+ * @name ng.$animate#removeClass
+ * @methodOf ng.$animate
+ * @function
+ *
+ * @description
+ * Removes the provided className CSS class value from the provided element. Once complete, the done() callback will be fired (if provided).
+ *
+ * @param {jQuery/jqLite element} element the element which will have the className value removed from it
+ * @param {string} className the CSS class which will be removed from the element
+ * @param {function=} done the callback function (if provided) that will be fired after the className value has been removed from the element
+ */
+ removeClass : function(element, className, done) {
+ className = isString(className) ?
+ className :
+ isArray(className) ? className.join(' ') : '';
+ element.removeClass(className);
+ $timeout(done || noop, 0, false);
+ },
- var memento = (polyfillSetup || noop)(element);
-
- // $window.setTimeout(beginAnimation, 0); this was causing the element not to animate
- // keep at 1 for animation dom rerender
- $window.setTimeout(beginAnimation, 1);
- }
-
- function parseMaxTime(str) {
- var total = 0, values = isString(str) ? str.split(/\s*,\s*/) : [];
- forEach(values, function(value) {
- total = Math.max(parseFloat(value) || 0, total);
- });
- return total;
- }
-
- function beginAnimation() {
- element.addClass(activeClassName);
- if (polyfillStart) {
- polyfillStart(element, done, memento);
- } else if (isFunction($window.getComputedStyle)) {
- //one day all browsers will have these properties
- var w3cAnimationProp = 'animation';
- var w3cTransitionProp = 'transition';
-
- //but some still use vendor-prefixed styles
- var vendorAnimationProp = $sniffer.vendorPrefix + 'Animation';
- var vendorTransitionProp = $sniffer.vendorPrefix + 'Transition';
-
- var durationKey = 'Duration',
- delayKey = 'Delay',
- animationIterationCountKey = 'IterationCount',
- duration = 0;
-
- //we want all the styles defined before and after
- var ELEMENT_NODE = 1;
- forEach(element, function(element) {
- if (element.nodeType == ELEMENT_NODE) {
- var w3cProp = w3cTransitionProp,
- vendorProp = vendorTransitionProp,
- iterations = 1,
- elementStyles = $window.getComputedStyle(element) || {};
-
- //use CSS Animations over CSS Transitions
- if(parseFloat(elementStyles[w3cAnimationProp + durationKey]) > 0 ||
- parseFloat(elementStyles[vendorAnimationProp + durationKey]) > 0) {
- w3cProp = w3cAnimationProp;
- vendorProp = vendorAnimationProp;
- iterations = Math.max(parseInt(elementStyles[w3cProp + animationIterationCountKey]) || 0,
- parseInt(elementStyles[vendorProp + animationIterationCountKey]) || 0,
- iterations);
- }
-
- var parsedDelay = Math.max(parseMaxTime(elementStyles[w3cProp + delayKey]),
- parseMaxTime(elementStyles[vendorProp + delayKey]));
-
- var parsedDuration = Math.max(parseMaxTime(elementStyles[w3cProp + durationKey]),
- parseMaxTime(elementStyles[vendorProp + durationKey]));
-
- duration = Math.max(parsedDelay + (iterations * parsedDuration), duration);
- }
- });
- $window.setTimeout(done, duration * 1000);
- } else {
- done();
- }
- }
-
- function done() {
- if(!done.run) {
- done.run = true;
- afterFn(element, parent, after);
- element.removeClass(className);
- element.removeClass(activeClassName);
- element.removeData(NG_ANIMATE_CONTROLLER);
- }
- }
- };
- }
-
- function show(element) {
- element.css('display', '');
- }
-
- function hide(element) {
- element.css('display', 'none');
- }
-
- function insert(element, parent, after) {
- if (after) {
- after.after(element);
- } else {
- parent.append(element);
- }
- }
-
- function remove(element) {
- element.remove();
- }
-
- function move(element, parent, after) {
- // Do not remove element before insert. Removing will cause data associated with the
- // element to be dropped. Insert will implicitly do the remove.
- insert(element, parent, after);
- }
- };
-
- /**
- * @ngdoc function
- * @name ng.animator#enabled
- * @methodOf ng.$animator
- * @function
- *
- * @param {Boolean=} If provided then set the animation on or off.
- * @return {Boolean} Current animation state.
- *
- * @description
- * Globally enables/disables animations.
- *
- */
- AnimatorService.enabled = function(value) {
- if (arguments.length) {
- rootAnimateController.running = !value;
- }
- return !rootAnimateController.running;
+ enabled : noop
};
-
- return AnimatorService;
}];
-};
+}];
/**
* ! This is a private undocumented service !
@@ -3648,7 +3532,8 @@
//////////////////////////////////////////////////////////////
var lastBrowserUrl = location.href,
- baseElement = document.find('base');
+ baseElement = document.find('base'),
+ replacedUrl = null;
/**
* @name ng.$browser#url
@@ -3683,14 +3568,21 @@
baseElement.attr('href', baseElement.attr('href'));
}
} else {
- if (replace) location.replace(url);
- else location.href = url;
+ if (replace) {
+ location.replace(url);
+ replacedUrl = url;
+ } else {
+ location.href = url;
+ replacedUrl = null;
+ }
}
return self;
// getter
} else {
- // the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
- return location.href.replace(/%27/g,"'");
+ // - the replacedUrl is a workaround for an IE8-9 issue with location.replace method that doesn't update
+ // location.href synchronously
+ // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
+ return replacedUrl || location.href.replace(/%27/g,"'");
}
};
@@ -3736,9 +3628,9 @@
// changed by push/replaceState
// html5 history api - popstate event
- if ($sniffer.history) jqLite(window).bind('popstate', fireUrlChange);
+ if ($sniffer.history) jqLite(window).on('popstate', fireUrlChange);
// hashchange event
- if ($sniffer.hashchange) jqLite(window).bind('hashchange', fireUrlChange);
+ if ($sniffer.hashchange) jqLite(window).on('hashchange', fireUrlChange);
// polling
else self.addPollFn(fireUrlChange);
@@ -3839,7 +3731,7 @@
/**
* @name ng.$browser#defer
* @methodOf ng.$browser
- * @param {function()} fn A function, who's execution should be defered.
+ * @param {function()} fn A function, who's execution should be deferred.
* @param {number=} [delay=0] of milliseconds to defer the function execution.
* @returns {*} DeferId that can be used to cancel the task via `$browser.defer.cancel()`.
*
@@ -3868,7 +3760,7 @@
* @methodOf ng.$browser.defer
*
* @description
- * Cancels a defered task identified with `deferId`.
+ * Cancels a deferred task identified with `deferId`.
*
* @param {*} deferId Token returned by the `$browser.defer` function.
* @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully canceled.
@@ -3897,9 +3789,22 @@
* @name ng.$cacheFactory
*
* @description
- * Factory that constructs cache objects.
+ * Factory that constructs cache objects and gives access to them.
+ *
+ * <pre>
+ *
+ * var cache = $cacheFactory('cacheId');
+ * expect($cacheFactory.get('cacheId')).toBe(cache);
+ * expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined();
*
+ * cache.put("key", "value");
+ * cache.put("another key", "another value");
+ *
+ * expect(cache.info()).toEqual({id: 'cacheId', size: 2}); // Since we've specified no options on creation
+ *
+ * </pre>
*
+ *
* @param {string} cacheId Name or id of the newly created cache.
* @param {object=} options Options object that specifies the cache behavior. Properties:
*
@@ -3922,7 +3827,7 @@
function cacheFactory(cacheId, options) {
if (cacheId in caches) {
- throw Error('cacheId ' + cacheId + ' taken');
+ throw minErr('$cacheFactory')('iid', "CacheId '{0}' is already taken!", cacheId);
}
var size = 0,
@@ -4031,6 +3936,16 @@
}
+ /**
+ * @ngdoc method
+ * @name ng.$cacheFactory#info
+ * @methodOf ng.$cacheFactory
+ *
+ * @description
+ * Get information about all the of the caches that have been created
+ *
+ * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info`
+ */
cacheFactory.info = function() {
var info = {};
forEach(caches, function(cache, cacheId) {
@@ -4040,6 +3955,17 @@
};
+ /**
+ * @ngdoc method
+ * @name ng.$cacheFactory#get
+ * @methodOf ng.$cacheFactory
+ *
+ * @description
+ * Get access to a cache object by the `cacheId` used when it was created.
+ *
+ * @param {string} cacheId Name or id of a cache to access.
+ * @returns {object} Cache object identified by the cacheId or undefined if no such cache.
+ */
cacheFactory.get = function(cacheId) {
return caches[cacheId];
};
@@ -4054,8 +3980,44 @@
* @name ng.$templateCache
*
* @description
- * Cache used for storing html templates.
- *
+ * The first time a template is used, it is loaded in the template cache for quick retrieval. You can
+ * load templates directly into the cache in a `script` tag, or by consuming the `$templateCache`
+ * service directly.
+ *
+ * Adding via the `script` tag:
+ * <pre>
+ * <html ng-app>
+ * <head>
+ * <script type="text/ng-template" id="templateId.html">
+ * This is the content of the template
+ * </script>
+ * </head>
+ * ...
+ * </html>
+ * </pre>
+ *
+ * **Note:** the `script` tag containing the template does not need to be included in the `head` of the document, but
+ * it must be below the `ng-app` definition.
+ *
+ * Adding via the $templateCache service:
+ *
+ * <pre>
+ * var myApp = angular.module('myApp', []);
+ * myApp.run(function($templateCache) {
+ * $templateCache.put('templateId.html', 'This is the content of the template');
+ * });
+ * </pre>
+ *
+ * To retrieve the template later, simply use it in your HTML:
+ * <pre>
+ * <div ng-include=" 'templateId.html' "></div>
+ * </pre>
+ *
+ * or get it via Javascript:
+ * <pre>
+ * $templateCache.get('templateId.html')
+ * </pre>
+ *
* See {@link ng.$cacheFactory $cacheFactory}.
*
*/
@@ -4083,9 +4045,6 @@
*/
-var NON_ASSIGNABLE_MODEL_EXPRESSION = 'Non-assignable model expression: ';
-
-
/**
* @ngdoc function
* @name ng.$compile
@@ -4206,6 +4165,7 @@
* {@link guide/compiler Angular HTML Compiler} section of the Developer Guide.
*/
+var $compileMinErr = minErr('$compile');
/**
* @ngdoc service
@@ -4220,9 +4180,13 @@
Suffix = 'Directive',
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/,
- MULTI_ROOT_TEMPLATE_ERROR = 'Template must have exactly one root element. was: ',
- urlSanitizationWhitelist = /^\s*(https?|ftp|mailto|file):/;
+ aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|file):/,
+ imgSrcSanitizationWhitelist = /^\s*(https?|ftp|file):|data:image\//;
+ // Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes
+ // The assumption is that future DOM event attribute names will begin with
+ // 'on' and be composed of only English letters.
+ var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]*|formaction)$/;
/**
* @ngdoc function
@@ -4231,17 +4195,17 @@
* @function
*
* @description
- * Register a new directives with the compiler.
+ * Register a new directive with the compiler.
*
* @param {string} name Name of the directive in camel-case. (ie <code>ngBind</code> which will match as
* <code>ng-bind</code>).
- * @param {function} directiveFactory An injectable directive factory function. See {@link guide/directive} for more
+ * @param {function|Array} directiveFactory An injectable directive factory function. See {@link guide/directive} for more
* info.
* @returns {ng.$compileProvider} Self for chaining.
*/
this.directive = function registerDirective(name, directiveFactory) {
if (isString(name)) {
- assertArg(directiveFactory, 'directive');
+ assertArg(directiveFactory, 'directiveFactory');
if (!hasDirectives.hasOwnProperty(name)) {
hasDirectives[name] = [];
$provide.factory(name + Suffix, ['$injector', '$exceptionHandler',
@@ -4277,7 +4241,7 @@
/**
* @ngdoc function
- * @name ng.$compileProvider#urlSanitizationWhitelist
+ * @name ng.$compileProvider#aHrefSanitizationWhitelist
* @methodOf ng.$compileProvider
* @function
*
@@ -4287,29 +4251,59 @@
*
* The sanitization is a security measure aimed at prevent XSS attacks via html links.
*
- * Any url about to be assigned to a[href] via data-binding is first normalized and turned into an
- * absolute url. Afterwards the url is matched against the `urlSanitizationWhitelist` regular
- * expression. If a match is found the original url is written into the dom. Otherwise the
- * absolute url is prefixed with `'unsafe:'` string and only then it is written into the DOM.
+ * Any url about to be assigned to a[href] via data-binding is first normalized and turned into
+ * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
+ * regular expression. If a match is found, the original url is written into the dom. Otherwise,
+ * the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
*
* @param {RegExp=} regexp New regexp to whitelist urls with.
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
* chaining otherwise.
*/
- this.urlSanitizationWhitelist = function(regexp) {
+ this.aHrefSanitizationWhitelist = function(regexp) {
if (isDefined(regexp)) {
- urlSanitizationWhitelist = regexp;
+ aHrefSanitizationWhitelist = regexp;
return this;
}
- return urlSanitizationWhitelist;
+ return aHrefSanitizationWhitelist;
};
+ /**
+ * @ngdoc function
+ * @name ng.$compileProvider#imgSrcSanitizationWhitelist
+ * @methodOf ng.$compileProvider
+ * @function
+ *
+ * @description
+ * Retrieves or overrides the default regular expression that is used for whitelisting of safe
+ * urls during img[src] sanitization.
+ *
+ * The sanitization is a security measure aimed at prevent XSS attacks via html links.
+ *
+ * Any url about to be assigned to img[src] via data-binding is first normalized and turned into an
+ * absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist` regular
+ * expression. If a match is found, the original url is written into the dom. Otherwise, the
+ * absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
+ *
+ * @param {RegExp=} regexp New regexp to whitelist urls with.
+ * @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
+ * chaining otherwise.
+ */
+ this.imgSrcSanitizationWhitelist = function(regexp) {
+ if (isDefined(regexp)) {
+ imgSrcSanitizationWhitelist = regexp;
+ return this;
+ }
+ return imgSrcSanitizationWhitelist;
+ };
+
+
this.$get = [
'$injector', '$interpolate', '$exceptionHandler', '$http', '$templateCache', '$parse',
- '$controller', '$rootScope', '$document',
+ '$controller', '$rootScope', '$document', '$sce', '$$urlUtils', '$animate',
function($injector, $interpolate, $exceptionHandler, $http, $templateCache, $parse,
- $controller, $rootScope, $document) {
+ $controller, $rootScope, $document, $sce, $$urlUtils, $animate) {
var Attributes = function(element, attr) {
this.$$element = element;
@@ -4321,6 +4315,42 @@
/**
+ * @ngdoc function
+ * @name ng.$compile.directive.Attributes#$addClass
+ * @methodOf ng.$compile.directive.Attributes
+ * @function
+ *
+ * @description
+ * Adds the CSS class value specified by the classVal parameter to the element. If animations
+ * are enabled then an animation will be triggered for the class addition.
+ *
+ * @param {string} classVal The className value that will be added to the element
+ */
+ $addClass : function(classVal) {
+ if(classVal && classVal.length > 0) {
+ $animate.addClass(this.$$element, classVal);
+ }
+ },
+
+ /**
+ * @ngdoc function
+ * @name ng.$compile.directive.Attributes#$removeClass
+ * @methodOf ng.$compile.directive.Attributes
+ * @function
+ *
+ * @description
+ * Removes the CSS class value specified by the classVal parameter from the element. If animations
+ * are enabled then an animation will be triggered for the class removal.
+ *
+ * @param {string} classVal The className value that will be removed from the element
+ */
+ $removeClass : function(classVal) {
+ if(classVal && classVal.length > 0) {
+ $animate.removeClass(this.$$element, classVal);
+ }
+ },
+
+ /**
* Set a normalized attribute on the element in a way such that all directives
* can share the attribute. This function properly handles boolean attributes.
* @param {string} key Normalized key. (ie ngAttribute)
@@ -4330,49 +4360,64 @@
* @param {string=} attrName Optional none normalized name. Defaults to key.
*/
$set: function(key, value, writeAttr, attrName) {
- var booleanKey = getBooleanAttrName(this.$$element[0], key),
- $$observers = this.$$observers,
- normalizedVal;
+ //special case for class attribute addition + removal
+ //so that class changes can tap into the animation
+ //hooks provided by the $animate service
+ if(key == 'class') {
+ value = value || '';
+ var current = this.$$element.attr('class') || '';
+ this.$removeClass(tokenDifference(current, value).join(' '));
+ this.$addClass(tokenDifference(value, current).join(' '));
+ } else {
+ var booleanKey = getBooleanAttrName(this.$$element[0], key),
+ normalizedVal,
+ nodeName;
- if (booleanKey) {
- this.$$element.prop(key, value);
- attrName = booleanKey;
- }
+ if (booleanKey) {
+ this.$$element.prop(key, value);
+ attrName = booleanKey;
+ }
- this[key] = value;
+ this[key] = value;
- // translate normalized key to actual key
- if (attrName) {
- this.$attr[key] = attrName;
- } else {
- attrName = this.$attr[key];
- if (!attrName) {
- this.$attr[key] = attrName = snake_case(key, '-');
+ // translate normalized key to actual key
+ if (attrName) {
+ this.$attr[key] = attrName;
+ } else {
+ attrName = this.$attr[key];
+ if (!attrName) {
+ this.$attr[key] = attrName = snake_case(key, '-');
+ }
}
- }
+ nodeName = nodeName_(this.$$element);
- // sanitize a[href] values
- if (nodeName_(this.$$element[0]) === 'A' && key === 'href') {
- urlSanitizationNode.setAttribute('href', value);
-
- // href property always returns normalized absolute url, so we can match against that
- normalizedVal = urlSanitizationNode.href;
- if (!normalizedVal.match(urlSanitizationWhitelist)) {
- this[key] = value = 'unsafe:' + normalizedVal;
+ // sanitize a[href] and img[src] values
+ if ((nodeName === 'A' && key === 'href') ||
+ (nodeName === 'IMG' && key === 'src')) {
+ // NOTE: $$urlUtils.resolve() doesn't support IE < 8 so we don't sanitize for that case.
+ if (!msie || msie >= 8 ) {
+ normalizedVal = $$urlUtils.resolve(value);
+ if (normalizedVal !== '') {
+ if ((key === 'href' && !normalizedVal.match(aHrefSanitizationWhitelist)) ||
+ (key === 'src' && !normalizedVal.match(imgSrcSanitizationWhitelist))) {
+ this[key] = value = 'unsafe:' + normalizedVal;
+ }
+ }
+ }
}
- }
-
- if (writeAttr !== false) {
- if (value === null || value === undefined) {
- this.$$element.removeAttr(attrName);
- } else {
- this.$$element.attr(attrName, value);
+ if (writeAttr !== false) {
+ if (value === null || value === undefined) {
+ this.$$element.removeAttr(attrName);
+ } else {
+ this.$$element.attr(attrName, value);
+ }
}
}
// fire observers
+ var $$observers = this.$$observers;
$$observers && forEach($$observers[key], function(fn) {
try {
fn(value);
@@ -4380,6 +4425,22 @@
$exceptionHandler(e);
}
});
+
+ function tokenDifference(str1, str2) {
+ var values = [],
+ tokens1 = str1.split(/\s+/),
+ tokens2 = str2.split(/\s+/);
+
+ outer:
+ for(var i=0;i<tokens1.length;i++) {
+ var token = tokens1[i];
+ for(var j=0;j<tokens2.length;j++) {
+ if(token == tokens2[j]) continue outer;
+ }
+ values.push(token);
+ }
+ return values;
+ };
},
@@ -4422,7 +4483,7 @@
//================================
- function compile($compileNodes, transcludeFn, maxPriority) {
+ function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective) {
if (!($compileNodes instanceof jqLite)) {
// jquery always rewraps, whereas we need to preserve the original selector so that we can modify it.
$compileNodes = jqLite($compileNodes);
@@ -4431,10 +4492,10 @@
// not be able to attach scope data to them, so we will wrap them in <span>
forEach($compileNodes, function(node, index){
if (node.nodeType == 3 /* text node */ && node.nodeValue.match(/\S+/) /* non-empty */ ) {
- $compileNodes[index] = jqLite(node).wrap('<span></span>').parent()[0];
+ $compileNodes[index] = node = jqLite(node).wrap('<span></span>').parent()[0];
}
});
- var compositeLinkFn = compileNodes($compileNodes, transcludeFn, $compileNodes, maxPriority);
+ var compositeLinkFn = compileNodes($compileNodes, transcludeFn, $compileNodes, maxPriority, ignoreDirective);
return function publicLinkFn(scope, cloneConnectFn){
assertArg(scope, 'scope');
// important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
@@ -4457,10 +4518,6 @@
};
}
- function wrongMode(localName, mode) {
- throw Error("Unsupported '" + mode + "' for '" + localName + "'.");
- }
-
function safeAddClass($element, className) {
try {
$element.addClass(className);
@@ -4485,7 +4542,7 @@
* @param {number=} max directive priority
* @returns {?function} A composite linking function of all of the matched directives or null.
*/
- function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority) {
+ function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective) {
var linkFns = [],
nodeLinkFn, childLinkFn, directives, attrs, linkFnFound;
@@ -4493,7 +4550,7 @@
attrs = new Attributes();
// we must always refer to nodeList[i] since the nodes can be replaced underneath us.
- directives = collectDirectives(nodeList[i], [], attrs, maxPriority);
+ directives = collectDirectives(nodeList[i], [], attrs, i == 0 ? maxPriority : undefined, ignoreDirective);
nodeLinkFn = (directives.length)
? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement)
@@ -4542,7 +4599,7 @@
transcludeScope.$$transcluded = true;
return transcludeFn(transcludeScope, cloneFn).
- bind('$destroy', bind(transcludeScope, transcludeScope.$destroy));
+ on('$destroy', bind(transcludeScope, transcludeScope.$destroy));
};
})(childTranscludeFn || transcludeFn)
);
@@ -4567,7 +4624,7 @@
* @param attrs The shared attrs object which is used to populate the normalized attributes.
* @param {number=} maxPriority Max directive priority.
*/
- function collectDirectives(node, directives, attrs, maxPriority) {
+ function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) {
var nodeType = node.nodeType,
attrsMap = attrs.$attr,
match,
@@ -4577,19 +4634,28 @@
case 1: /* Element */
// use the node name: <directive>
addDirective(directives,
- directiveNormalize(nodeName_(node).toLowerCase()), 'E', maxPriority);
+ directiveNormalize(nodeName_(node).toLowerCase()), 'E', maxPriority, ignoreDirective);
// iterate over the attributes
for (var attr, name, nName, ngAttrName, value, nAttrs = node.attributes,
j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
+ var attrStartName;
+ var attrEndName;
+ var index;
+
attr = nAttrs[j];
- if (attr.specified) {
+ if (!msie || msie >= 8 || attr.specified) {
name = attr.name;
// support ngAttr attribute binding
ngAttrName = directiveNormalize(name);
if (NG_ATTR_BINDING.test(ngAttrName)) {
name = ngAttrName.substr(6).toLowerCase();
}
+ if ((index = ngAttrName.lastIndexOf('Start')) != -1 && index == ngAttrName.length - 5) {
+ attrStartName = name;
+ attrEndName = name.substr(0, name.length - 5) + 'end';
+ name = name.substr(0, name.length - 6);
+ }
nName = directiveNormalize(name.toLowerCase());
attrsMap[nName] = name;
attrs[nName] = value = trim((msie && name == 'href')
@@ -4599,7 +4665,7 @@
attrs[nName] = true; // presence means true
}
addAttrInterpolateDirective(node, directives, value, nName);
- addDirective(directives, nName, 'A', maxPriority);
+ addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName, attrEndName);
}
}
@@ -4608,7 +4674,7 @@
if (isString(className) && className !== '') {
while (match = CLASS_DIRECTIVE_REGEXP.exec(className)) {
nName = directiveNormalize(match[2]);
- if (addDirective(directives, nName, 'C', maxPriority)) {
+ if (addDirective(directives, nName, 'C', maxPriority, ignoreDirective)) {
attrs[nName] = trim(match[3]);
}
className = className.substr(match.index + match[0].length);
@@ -4623,7 +4689,7 @@
match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue);
if (match) {
nName = directiveNormalize(match[1]);
- if (addDirective(directives, nName, 'M', maxPriority)) {
+ if (addDirective(directives, nName, 'M', maxPriority, ignoreDirective)) {
attrs[nName] = trim(match[2]);
}
}
@@ -4638,8 +4704,51 @@
return directives;
}
+ /**
+ * Given a node with an directive-start it collects all of the siblings until it find directive-end.
+ * @param node
+ * @param attrStart
+ * @param attrEnd
+ * @returns {*}
+ */
+ function groupScan(node, attrStart, attrEnd) {
+ var nodes = [];
+ var depth = 0;
+ if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) {
+ var startNode = node;
+ do {
+ if (!node) {
+ throw $compileMinErr('uterdir', "Unterminated attribute, found '{0}' but no matching '{1}' found.", attrStart, attrEnd);
+ }
+ if (node.nodeType == 1 /** Element **/) {
+ if (node.hasAttribute(attrStart)) depth++;
+ if (node.hasAttribute(attrEnd)) depth--;
+ }
+ nodes.push(node);
+ node = node.nextSibling;
+ } while (depth > 0);
+ } else {
+ nodes.push(node);
+ }
+ return jqLite(nodes);
+ }
/**
+ * Wrapper for linking function which converts normal linking function into a grouped
+ * linking function.
+ * @param linkFn
+ * @param attrStart
+ * @param attrEnd
+ * @returns {Function}
+ */
+ function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {
+ return function(scope, element, attrs, controllers) {
+ element = groupScan(element[0], attrStart, attrEnd);
+ return linkFn(scope, element, attrs, controllers);
+ }
+ }
+
+ /**
* Once the directives have been collected, their compile functions are executed. This method
* is responsible for inlining directive templates as well as terminating the application
* of the directives if the terminal directive has been reached.
@@ -4654,7 +4763,7 @@
* argument has the root jqLite array so that we can replace nodes on it.
* @returns linkFn
*/
- function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, jqCollection) {
+ function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, jqCollection, originalReplaceDirective) {
var terminalPriority = -Number.MAX_VALUE,
preLinkFns = [],
postLinkFns = [],
@@ -4666,6 +4775,7 @@
directiveName,
$template,
transcludeDirective,
+ replaceDirective = originalReplaceDirective,
childTranscludeFn = transcludeFn,
controllerDirectives,
linkFn,
@@ -4674,6 +4784,13 @@
// executes all directives on the current element
for(var i = 0, ii = directives.length; i < ii; i++) {
directive = directives[i];
+ var attrStart = directive.$$start;
+ var attrEnd = directive.$$end;
+
+ // collect multiblock sections
+ if (attrStart) {
+ $compileNode = groupScan(compileNode, attrStart, attrEnd)
+ }
$template = undefined;
if (terminalPriority > directive.priority) {
@@ -4704,12 +4821,14 @@
transcludeDirective = directive;
terminalPriority = directive.priority;
if (directiveValue == 'element') {
- $template = jqLite(compileNode);
+ $template = groupScan(compileNode, attrStart, attrEnd)
$compileNode = templateAttrs.$$element =
jqLite(document.createComment(' ' + directiveName + ': ' + templateAttrs[directiveName] + ' '));
compileNode = $compileNode[0];
- replaceWith(jqCollection, jqLite($template[0]), compileNode);
- childTranscludeFn = compile($template, transcludeFn, terminalPriority);
+ replaceWith(jqCollection, jqLite(sliceArgs($template)), compileNode);
+
+ childTranscludeFn = compile($template, transcludeFn, terminalPriority,
+ replaceDirective && replaceDirective.name);
} else {
$template = jqLite(JQLiteClone(compileNode)).contents();
$compileNode.html(''); // clear contents
@@ -4728,13 +4847,14 @@
directiveValue = denormalizeTemplate(directiveValue);
if (directive.replace) {
+ replaceDirective = directive;
$template = jqLite('<div>' +
trim(directiveValue) +
'</div>').contents();
compileNode = $template[0];
if ($template.length != 1 || compileNode.nodeType !== 1) {
- throw new Error(MULTI_ROOT_TEMPLATE_ERROR + directiveValue);
+ throw $compileMinErr('tplrt', "Template for directive '{0}' must have exactly one root element. {1}", directiveName, '');
}
replaceWith(jqCollection, $compileNode, compileNode);
@@ -4764,17 +4884,20 @@
if (directive.templateUrl) {
assertNoDuplicate('template', templateDirective, directive, $compileNode);
templateDirective = directive;
+
+ if (directive.replace) {
+ replaceDirective = directive;
+ }
nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i),
- nodeLinkFn, $compileNode, templateAttrs, jqCollection, directive.replace,
- childTranscludeFn);
+ nodeLinkFn, $compileNode, templateAttrs, jqCollection, childTranscludeFn);
ii = directives.length;
} else if (directive.compile) {
try {
linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn);
if (isFunction(linkFn)) {
- addLinkFns(null, linkFn);
+ addLinkFns(null, linkFn, attrStart, attrEnd);
} else if (linkFn) {
- addLinkFns(linkFn.pre, linkFn.post);
+ addLinkFns(linkFn.pre, linkFn.post, attrStart, attrEnd);
}
} catch (e) {
$exceptionHandler(e, startingTag($compileNode));
@@ -4796,12 +4919,14 @@
////////////////////
- function addLinkFns(pre, post) {
+ function addLinkFns(pre, post, attrStart, attrEnd) {
if (pre) {
+ if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);
pre.require = directive.require;
preLinkFns.push(pre);
}
if (post) {
+ if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);
post.require = directive.require;
postLinkFns.push(post);
}
@@ -4820,7 +4945,7 @@
}
value = $element[retrievalMethod]('$' + require + 'Controller');
if (!value && !optional) {
- throw Error("No controller: " + require);
+ throw $compileMinErr('ctreq', "Controller '{0}', required by directive '{1}', can't be found!", require, directiveName);
}
return value;
} else if (isArray(require)) {
@@ -4848,8 +4973,8 @@
var parentScope = scope.$parent || scope;
- forEach(newIsolateScopeDirective.scope, function(definiton, scopeName) {
- var match = definiton.match(LOCAL_REGEXP) || [],
+ forEach(newIsolateScopeDirective.scope, function(definition, scopeName) {
+ var match = definition.match(LOCAL_REGEXP) || [],
attrName = match[3] || scopeName,
optional = (match[2] == '?'),
mode = match[1], // @, =, or &
@@ -4880,8 +5005,8 @@
parentSet = parentGet.assign || function() {
// reset the change, or we will throw this exception on every $digest
lastValue = scope[scopeName] = parentGet(parentScope);
- throw Error(NON_ASSIGNABLE_MODEL_EXPRESSION + attrs[attrName] +
- ' (directive: ' + newIsolateScopeDirective.name + ')');
+ throw $compileMinErr('nonassign', "Expression '{0}' used with directive '{1}' is non-assignable!",
+ attrs[attrName], newIsolateScopeDirective.name);
};
lastValue = scope[scopeName] = parentGet(parentScope);
scope.$watch(function parentValueWatch() {
@@ -4911,8 +5036,8 @@
}
default: {
- throw Error('Invalid isolate scope definition for directive ' +
- newIsolateScopeDirective.name + ': ' + definiton);
+ throw $compileMinErr('iscp', "Invalid isolate scope definition for directive '{0}'. Definition: {... {1}: '{2}' ...}",
+ newIsolateScopeDirective.name, scopeName, definition);
}
}
});
@@ -4925,16 +5050,20 @@
$element: $element,
$attrs: attrs,
$transclude: boundTranscludeFn
- };
+ }, controllerInstance;
controller = directive.controller;
if (controller == '@') {
controller = attrs[directive.name];
}
+ controllerInstance = $controller(controller, locals);
$element.data(
'$' + directive.name + 'Controller',
- $controller(controller, locals));
+ controllerInstance);
+ if (directive.controllerAs) {
+ locals.$scope[directive.controllerAs] = controllerInstance;
+ }
});
}
@@ -4980,8 +5109,9 @@
* * `M`: comment
* @returns true if directive was added.
*/
- function addDirective(tDirectives, name, location, maxPriority) {
- var match = false;
+ function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName, endAttrName) {
+ if (name === ignoreDirective) return null;
+ var match = null;
if (hasDirectives.hasOwnProperty(name)) {
for(var directive, directives = $injector.get(name + Suffix),
i = 0, ii = directives.length; i<ii; i++) {
@@ -4989,8 +5119,11 @@
directive = directives[i];
if ( (maxPriority === undefined || maxPriority > directive.priority) &&
directive.restrict.indexOf(location) != -1) {
+ if (startAttrName) {
+ directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});
+ }
tDirectives.push(directive);
- match = true;
+ match = directive;
}
} catch(e) { $exceptionHandler(e); }
}
@@ -5038,7 +5171,7 @@
function compileTemplateUrl(directives, beforeTemplateNodeLinkFn, $compileNode, tAttrs,
- $rootElement, replace, childTranscludeFn) {
+ $rootElement, childTranscludeFn) {
var linkQueue = [],
afterTemplateNodeLinkFn,
afterTemplateChildLinkFn,
@@ -5046,7 +5179,7 @@
origAsyncDirective = directives.shift(),
// The fact that we have to copy and patch the directive seems wrong!
derivedSyncDirective = extend({}, origAsyncDirective, {
- controller: null, templateUrl: null, transclude: null, scope: null
+ controller: null, templateUrl: null, transclude: null, scope: null, replace: null
}),
templateUrl = (isFunction(origAsyncDirective.templateUrl))
? origAsyncDirective.templateUrl($compileNode, tAttrs)
@@ -5054,18 +5187,19 @@
$compileNode.html('');
- $http.get(templateUrl, {cache: $templateCache}).
+ $http.get($sce.getTrustedResourceUrl(templateUrl), {cache: $templateCache}).
success(function(content) {
var compileNode, tempTemplateAttrs, $template;
content = denormalizeTemplate(content);
- if (replace) {
+ if (origAsyncDirective.replace) {
$template = jqLite('<div>' + trim(content) + '</div>').contents();
compileNode = $template[0];
if ($template.length != 1 || compileNode.nodeType !== 1) {
- throw new Error(MULTI_ROOT_TEMPLATE_ERROR + content);
+ throw $compileMinErr('tplrt', "Template for directive '{0}' must have exactly one root element. {1}",
+ origAsyncDirective.name, templateUrl);
}
tempTemplateAttrs = {$attr: {}};
@@ -5078,7 +5212,13 @@
}
directives.unshift(derivedSyncDirective);
- afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs, childTranscludeFn);
+
+ afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs, childTranscludeFn, $compileNode, origAsyncDirective);
+ forEach($rootElement, function(node, i) {
+ if (node == compileNode) {
+ $rootElement[i] = $compileNode[0];
+ }
+ });
afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);
@@ -5087,7 +5227,7 @@
beforeTemplateLinkNode = linkQueue.shift(),
linkRootElement = linkQueue.shift(),
controller = linkQueue.shift(),
- linkNode = compileNode;
+ linkNode = $compileNode[0];
if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
// it was cloned therefore we have to clone as well.
@@ -5095,14 +5235,15 @@
replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
}
- afterTemplateNodeLinkFn(function() {
- beforeTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, controller);
- }, scope, linkNode, $rootElement, controller);
+ afterTemplateNodeLinkFn(
+ beforeTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, controller),
+ scope, linkNode, $rootElement, controller
+ );
}
linkQueue = null;
}).
error(function(response, code, headers, config) {
- throw Error('Failed to load template: ' + config.url);
+ throw $compileMinErr('tpload', 'Failed to load template: {0}', config.url);
});
return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, controller) {
@@ -5130,8 +5271,8 @@
function assertNoDuplicate(what, previousDirective, directive, element) {
if (previousDirective) {
- throw Error('Multiple directives [' + previousDirective.name + ', ' +
- directive.name + '] asking for ' + what + ' on: ' + startingTag(element));
+ throw $compileMinErr('multidir', 'Multiple directives [{0}, {1}] asking for {2} on: {3}',
+ previousDirective.name, directive.name, what, startingTag(element));
}
}
@@ -5155,6 +5296,16 @@
}
+ function getTrustedContext(node, attrNormalizedName) {
+ // maction[xlink:href] can source SVG. It's not limited to <maction>.
+ if (attrNormalizedName == "xlinkHref" ||
+ (nodeName_(node) != "IMG" && (attrNormalizedName == "src" ||
+ attrNormalizedName == "ngSrc"))) {
+ return $sce.RESOURCE_URL;
+ }
+ }
+
+
function addAttrInterpolateDirective(node, directives, value, name) {
var interpolateFn = $interpolate(value, true);
@@ -5162,14 +5313,25 @@
if (!interpolateFn) return;
+ if (name === "multiple" && nodeName_(node) === "SELECT") {
+ throw $compileMinErr("selmulti", "Binding to the 'multiple' attribute is not supported. Element: {0}",
+ startingTag(node));
+ }
+
directives.push({
priority: 100,
compile: valueFn(function attrInterpolateLinkFn(scope, element, attr) {
var $$observers = (attr.$$observers || (attr.$$observers = {}));
+ if (EVENT_HANDLER_ATTR_REGEXP.test(name)) {
+ throw $compileMinErr('nodomevents',
+ "Interpolations for HTML DOM event attributes are disallowed. Please use the ng- " +
+ "versions (such as ng-click instead of onclick) instead.");
+ }
+
// we need to interpolate again, in case the attribute value has been updated
// (e.g. by another directive's compile function)
- interpolateFn = $interpolate(attr[name], true);
+ interpolateFn = $interpolate(attr[name], true, getTrustedContext(node, name));
// if attribute was updated so that there is no interpolation going on we don't want to
// register any observers
@@ -5192,30 +5354,50 @@
*
* @param {JqLite=} $rootElement The root of the compile tree. Used so that we can replace nodes
* in the root of the tree.
- * @param {JqLite} $element The jqLite element which we are going to replace. We keep the shell,
+ * @param {JqLite} elementsToRemove The jqLite element which we are going to replace. We keep the shell,
* but replace its DOM node reference.
* @param {Node} newNode The new DOM node.
*/
- function replaceWith($rootElement, $element, newNode) {
- var oldNode = $element[0],
- parent = oldNode.parentNode,
+ function replaceWith($rootElement, elementsToRemove, newNode) {
+ var firstElementToRemove = elementsToRemove[0],
+ removeCount = elementsToRemove.length,
+ parent = firstElementToRemove.parentNode,
i, ii;
if ($rootElement) {
for(i = 0, ii = $rootElement.length; i < ii; i++) {
- if ($rootElement[i] == oldNode) {
- $rootElement[i] = newNode;
+ if ($rootElement[i] == firstElementToRemove) {
+ $rootElement[i++] = newNode;
+ for (var j = i, j2 = j + removeCount - 1,
+ jj = $rootElement.length;
+ j < jj; j++, j2++) {
+ if (j2 < jj) {
+ $rootElement[j] = $rootElement[j2];
+ } else {
+ delete $rootElement[j];
+ }
+ }
+ $rootElement.length -= removeCount - 1;
break;
}
}
}
if (parent) {
- parent.replaceChild(newNode, oldNode);
+ parent.replaceChild(newNode, firstElementToRemove);
}
+ var fragment = document.createDocumentFragment();
+ fragment.appendChild(firstElementToRemove);
+ newNode[jqLite.expando] = firstElementToRemove[jqLite.expando];
+ for (var k = 1, kk = elementsToRemove.length; k < kk; k++) {
+ var element = elementsToRemove[k];
+ jqLite(element).remove(); // must do this way to clean up expando
+ fragment.appendChild(element);
+ delete elementsToRemove[k];
+ }
- newNode[jqLite.expando] = oldNode[jqLite.expando];
- $element[0] = newNode;
+ elementsToRemove[0] = newNode;
+ elementsToRemove.length = 1
}
}];
}
@@ -5224,7 +5406,7 @@
/**
* Converts all accepted directives format into proper directive name.
* All of these will become 'myDirective':
- * my:DiRective
+ * my:Directive
* my-directive
* x-my-directive
* data-my:directive
@@ -5368,9 +5550,8 @@
instance = $injector.instantiate(expression, locals);
if (identifier) {
- if (typeof locals.$scope !== 'object') {
- throw new Error('Can not export controller as "' + identifier + '". ' +
- 'No scope object provided!');
+ if (!(locals && typeof locals.$scope == 'object')) {
+ throw minErr('$controller')('noscp', "Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.", constructor || expression.name, identifier);
}
locals.$scope[identifier] = instance;
@@ -5423,13 +5604,1184 @@
}
/**
+ * Parse headers into key value object
+ *
+ * @param {string} headers Raw headers as a string
+ * @returns {Object} Parsed headers as key value object
+ */
+function parseHeaders(headers) {
+ var parsed = {}, key, val, i;
+
+ if (!headers) return parsed;
+
+ forEach(headers.split('\n'), function(line) {
+ i = line.indexOf(':');
+ key = lowercase(trim(line.substr(0, i)));
+ val = trim(line.substr(i + 1));
+
+ if (key) {
+ if (parsed[key]) {
+ parsed[key] += ', ' + val;
+ } else {
+ parsed[key] = val;
+ }
+ }
+ });
+
+ return parsed;
+}
+
+
+/**
+ * Returns a function that provides access to parsed headers.
+ *
+ * Headers are lazy parsed when first requested.
+ * @see parseHeaders
+ *
+ * @param {(string|Object)} headers Headers to provide access to.
+ * @returns {function(string=)} Returns a getter function which if called with:
+ *
+ * - if called with single an argument returns a single header value or null
+ * - if called with no arguments returns an object containing all headers.
+ */
+function headersGetter(headers) {
+ var headersObj = isObject(headers) ? headers : undefined;
+
+ return function(name) {
+ if (!headersObj) headersObj = parseHeaders(headers);
+
+ if (name) {
+ return headersObj[lowercase(name)] || null;
+ }
+
+ return headersObj;
+ };
+}
+
+
+/**
+ * Chain all given functions
+ *
+ * This function is used for both request and response transforming
+ *
+ * @param {*} data Data to transform.
+ * @param {function(string=)} headers Http headers getter fn.
+ * @param {(function|Array.<function>)} fns Function or an array of functions.
+ * @returns {*} Transformed data.
+ */
+function transformData(data, headers, fns) {
+ if (isFunction(fns))
+ return fns(data, headers);
+
+ forEach(fns, function(fn) {
+ data = fn(data, headers);
+ });
+
+ return data;
+}
+
+
+function isSuccess(status) {
+ return 200 <= status && status < 300;
+}
+
+
+function $HttpProvider() {
+ var JSON_START = /^\s*(\[|\{[^\{])/,
+ JSON_END = /[\}\]]\s*$/,
+ PROTECTION_PREFIX = /^\)\]\}',?\n/,
+ CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': 'application/json;charset=utf-8'};
+
+ var defaults = this.defaults = {
+ // transform incoming response data
+ transformResponse: [function(data) {
+ if (isString(data)) {
+ // strip json vulnerability protection prefix
+ data = data.replace(PROTECTION_PREFIX, '');
+ if (JSON_START.test(data) && JSON_END.test(data))
+ data = fromJson(data, true);
+ }
+ return data;
+ }],
+
+ // transform outgoing request data
+ transformRequest: [function(d) {
+ return isObject(d) && !isFile(d) ? toJson(d) : d;
+ }],
+
+ // default headers
+ headers: {
+ common: {
+ 'Accept': 'application/json, text/plain, */*'
+ },
+ post: CONTENT_TYPE_APPLICATION_JSON,
+ put: CONTENT_TYPE_APPLICATION_JSON,
+ patch: CONTENT_TYPE_APPLICATION_JSON
+ },
+
+ xsrfCookieName: 'XSRF-TOKEN',
+ xsrfHeaderName: 'X-XSRF-TOKEN'
+ };
+
+ /**
+ * Are order by request. I.E. they are applied in the same order as
+ * array on request, but revers order on response.
+ */
+ var interceptorFactories = this.interceptors = [];
+ /**
+ * For historical reasons, response interceptors ordered by the order in which
+ * they are applied to response. (This is in revers to interceptorFactories)
+ */
+ var responseInterceptorFactories = this.responseInterceptors = [];
+
+ this.$get = ['$httpBackend', '$browser', '$cacheFactory', '$rootScope', '$q', '$injector', '$$urlUtils',
+ function($httpBackend, $browser, $cacheFactory, $rootScope, $q, $injector, $$urlUtils) {
+
+ var defaultCache = $cacheFactory('$http');
+
+ /**
+ * Interceptors stored in reverse order. Inner interceptors before outer interceptors.
+ * The reversal is needed so that we can build up the interception chain around the
+ * server request.
+ */
+ var reversedInterceptors = [];
+
+ forEach(interceptorFactories, function(interceptorFactory) {
+ reversedInterceptors.unshift(isString(interceptorFactory)
+ ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory));
+ });
+
+ forEach(responseInterceptorFactories, function(interceptorFactory, index) {
+ var responseFn = isString(interceptorFactory)
+ ? $injector.get(interceptorFactory)
+ : $injector.invoke(interceptorFactory);
+
+ /**
+ * Response interceptors go before "around" interceptors (no real reason, just
+ * had to pick one.) But they are already reversed, so we can't use unshift, hence
+ * the splice.
+ */
+ reversedInterceptors.splice(index, 0, {
+ response: function(response) {
+ return responseFn($q.when(response));
+ },
+ responseError: function(response) {
+ return responseFn($q.reject(response));
+ }
+ });
+ });
+
+
+ /**
+ * @ngdoc function
+ * @name ng.$http
+ * @requires $httpBackend
+ * @requires $browser
+ * @requires $cacheFactory
+ * @requires $rootScope
+ * @requires $q
+ * @requires $injector
+ *
+ * @description
+ * The `$http` service is a core Angular service that facilitates communication with the remote
+ * HTTP servers via the browser's {@link https://developer.mozilla.org/en/xmlhttprequest
+ * XMLHttpRequest} object or via {@link http://en.wikipedia.org/wiki/JSONP JSONP}.
+ *
+ * For unit testing applications that use `$http` service, see
+ * {@link ngMock.$httpBackend $httpBackend mock}.
+ *
+ * For a higher level of abstraction, please check out the {@link ngResource.$resource
+ * $resource} service.
+ *
+ * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by
+ * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage
+ * it is important to familiarize yourself with these APIs and the guarantees they provide.
+ *
+ *
+ * # General usage
+ * The `$http` service is a function which takes a single argument — a configuration object —
+ * that is used to generate an HTTP request and returns a {@link ng.$q promise}
+ * with two $http specific methods: `success` and `error`.
+ *
+ * <pre>
+ * $http({method: 'GET', url: '/someUrl'}).
+ * success(function(data, status, headers, config) {
+ * // this callback will be called asynchronously
+ * // when the response is available
+ * }).
+ * error(function(data, status, headers, config) {
+ * // called asynchronously if an error occurs
+ * // or server returns response with an error status.
+ * });
+ * </pre>
+ *
+ * Since the returned value of calling the $http function is a `promise`, you can also use
+ * the `then` method to register callbacks, and these callbacks will receive a single argument –
+ * an object representing the response. See the API signature and type info below for more
+ * details.
+ *
+ * A response status code between 200 and 299 is considered a success status and
+ * will result in the success callback being called. Note that if the response is a redirect,
+ * XMLHttpRequest will transparently follow it, meaning that the error callback will not be
+ * called for such responses.
+ *
+ * # Shortcut methods
+ *
+ * Since all invocations of the $http service require passing in an HTTP method and URL, and
+ * POST/PUT requests require request data to be provided as well, shortcut methods
+ * were created:
+ *
+ * <pre>
+ * $http.get('/someUrl').success(successCallback);
+ * $http.post('/someUrl', data).success(successCallback);
+ * </pre>
+ *
+ * Complete list of shortcut methods:
+ *
+ * - {@link ng.$http#get $http.get}
+ * - {@link ng.$http#head $http.head}
+ * - {@link ng.$http#post $http.post}
+ * - {@link ng.$http#put $http.put}
+ * - {@link ng.$http#delete $http.delete}
+ * - {@link ng.$http#jsonp $http.jsonp}
+ *
+ *
+ * # Setting HTTP Headers
+ *
+ * The $http service will automatically add certain HTTP headers to all requests. These defaults
+ * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration
+ * object, which currently contains this default configuration:
+ *
+ * - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
+ * - `Accept: application/json, text/plain, * / *`
+ * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)
+ * - `Content-Type: application/json`
+ * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)
+ * - `Content-Type: application/json`
+ *
+ * To add or overwrite these defaults, simply add or remove a property from these configuration
+ * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
+ * with the lowercased HTTP method name as the key, e.g.
+ * `$httpProvider.defaults.headers.get['My-Header']='value'`.
+ *
+ * Additionally, the defaults can be set at runtime via the `$http.defaults` object in the same
+ * fashion.
+ *
+ *
+ * # Transforming Requests and Responses
+ *
+ * Both requests and responses can be transformed using transform functions. By default, Angular
+ * applies these transformations:
+ *
+ * Request transformations:
+ *
+ * - If the `data` property of the request configuration object contains an object, serialize it into
+ * JSON format.
+ *
+ * Response transformations:
+ *
+ * - If XSRF prefix is detected, strip it (see Security Considerations section below).
+ * - If JSON response is detected, deserialize it using a JSON parser.
+ *
+ * To globally augment or override the default transforms, modify the `$httpProvider.defaults.transformRequest` and
+ * `$httpProvider.defaults.transformResponse` properties. These properties are by default an
+ * array of transform functions, which allows you to `push` or `unshift` a new transformation function into the
+ * transformation chain. You can also decide to completely override any default transformations by assigning your
+ * transformation functions to these properties directly without the array wrapper.
+ *
+ * Similarly, to locally override the request/response transforms, augment the `transformRequest` and/or
+ * `transformResponse` properties of the configuration object passed into `$http`.
+ *
+ *
+ * # Caching
+ *
+ * To enable caching, set the configuration property `cache` to `true`. When the cache is
+ * enabled, `$http` stores the response from the server in local cache. Next time the
+ * response is served from the cache without sending a request to the server.
+ *
+ * Note that even if the response is served from cache, delivery of the data is asynchronous in
+ * the same way that real requests are.
+ *
+ * If there are multiple GET requests for the same URL that should be cached using the same
+ * cache, but the cache is not populated yet, only one request to the server will be made and
+ * the remaining requests will be fulfilled using the response from the first request.
+ *
+ * A custom default cache built with $cacheFactory can be provided in $http.defaults.cache.
+ * To skip it, set configuration property `cache` to `false`.
+ *
+ *
+ * # Interceptors
+ *
+ * Before you start creating interceptors, be sure to understand the
+ * {@link ng.$q $q and deferred/promise APIs}.
+ *
+ * For purposes of global error handling, authentication, or any kind of synchronous or
+ * asynchronous pre-processing of request or postprocessing of responses, it is desirable to be
+ * able to intercept requests before they are handed to the server and
+ * responses before they are handed over to the application code that
+ * initiated these requests. The interceptors leverage the {@link ng.$q
+ * promise APIs} to fulfill this need for both synchronous and asynchronous pre-processing.
+ *
+ * The interceptors are service factories that are registered with the `$httpProvider` by
+ * adding them to the `$httpProvider.interceptors` array. The factory is called and
+ * injected with dependencies (if specified) and returns the interceptor.
+ *
+ * There are two kinds of interceptors (and two kinds of rejection interceptors):
+ *
+ * * `request`: interceptors get called with http `config` object. The function is free to modify
+ * the `config` or create a new one. The function needs to return the `config` directly or as a
+ * promise.
+ * * `requestError`: interceptor gets called when a previous interceptor threw an error or resolved
+ * with a rejection.
+ * * `response`: interceptors get called with http `response` object. The function is free to modify
+ * the `response` or create a new one. The function needs to return the `response` directly or as a
+ * promise.
+ * * `responseError`: interceptor gets called when a previous interceptor threw an error or resolved
+ * with a rejection.
+ *
+ *
+ * <pre>
+ * // register the interceptor as a service
+ * $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
+ * return {
+ * // optional method
+ * 'request': function(config) {
+ * // do something on success
+ * return config || $q.when(config);
+ * },
+ *
+ * // optional method
+ * 'requestError': function(rejection) {
+ * // do something on error
+ * if (canRecover(rejection)) {
+ * return responseOrNewPromise
+ * }
+ * return $q.reject(rejection);
+ * },
+ *
+ *
+ *
+ * // optional method
+ * 'response': function(response) {
+ * // do something on success
+ * return response || $q.when(response);
+ * },
+ *
+ * // optional method
+ * 'responseError': function(rejection) {
+ * // do something on error
+ * if (canRecover(rejection)) {
+ * return responseOrNewPromise
+ * }
+ * return $q.reject(rejection);
+ * };
+ * }
+ * });
+ *
+ * $httpProvider.interceptors.push('myHttpInterceptor');
+ *
+ *
+ * // register the interceptor via an anonymous factory
+ * $httpProvider.interceptors.push(function($q, dependency1, dependency2) {
+ * return {
+ * 'request': function(config) {
+ * // same as above
+ * },
+ * 'response': function(response) {
+ * // same as above
+ * }
+ * });
+ * </pre>
+ *
+ * # Response interceptors (DEPRECATED)
+ *
+ * Before you start creating interceptors, be sure to understand the
+ * {@link ng.$q $q and deferred/promise APIs}.
+ *
+ * For purposes of global error handling, authentication or any kind of synchronous or
+ * asynchronous preprocessing of received responses, it is desirable to be able to intercept
+ * responses for http requests before they are handed over to the application code that
+ * initiated these requests. The response interceptors leverage the {@link ng.$q
+ * promise apis} to fulfil this need for both synchronous and asynchronous preprocessing.
+ *
+ * The interceptors are service factories that are registered with the $httpProvider by
+ * adding them to the `$httpProvider.responseInterceptors` array. The factory is called and
+ * injected with dependencies (if specified) and returns the interceptor — a function that
+ * takes a {@link ng.$q promise} and returns the original or a new promise.
+ *
+ * <pre>
+ * // register the interceptor as a service
+ * $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
+ * return function(promise) {
+ * return promise.then(function(response) {
+ * // do something on success
+ * }, function(response) {
+ * // do something on error
+ * if (canRecover(response)) {
+ * return responseOrNewPromise
+ * }
+ * return $q.reject(response);
+ * });
+ * }
+ * });
+ *
+ * $httpProvider.responseInterceptors.push('myHttpInterceptor');
+ *
+ *
+ * // register the interceptor via an anonymous factory
+ * $httpProvider.responseInterceptors.push(function($q, dependency1, dependency2) {
+ * return function(promise) {
+ * // same as above
+ * }
+ * });
+ * </pre>
+ *
+ *
+ * # Security Considerations
+ *
+ * When designing web applications, consider security threats from:
+ *
+ * - {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerabilit…
+ * JSON vulnerability}
+ * - {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF}
+ *
+ * Both server and the client must cooperate in order to eliminate these threats. Angular comes
+ * pre-configured with strategies that address these issues, but for this to work backend server
+ * cooperation is required.
+ *
+ * ## JSON Vulnerability Protection
+ *
+ * A {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerabilit…
+ * JSON vulnerability} allows third party website to turn your JSON resource URL into
+ * {@link http://en.wikipedia.org/wiki/JSONP JSONP} request under some conditions. To
+ * counter this your server can prefix all JSON requests with following string `")]}',\n"`.
+ * Angular will automatically strip the prefix before processing it as JSON.
+ *
+ * For example if your server needs to return:
+ * <pre>
+ * ['one','two']
+ * </pre>
+ *
+ * which is vulnerable to attack, your server can return:
+ * <pre>
+ * )]}',
+ * ['one','two']
+ * </pre>
+ *
+ * Angular will strip the prefix, before processing the JSON.
+ *
+ *
+ * ## Cross Site Request Forgery (XSRF) Protection
+ *
+ * {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which
+ * an unauthorized site can gain your user's private data. Angular provides a mechanism
+ * to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
+ * (by default, `XSRF-TOKEN`) and sets it as an HTTP header (`X-XSRF-TOKEN`). Since only
+ * JavaScript that runs on your domain could read the cookie, your server can be assured that
+ * the XHR came from JavaScript running on your domain. The header will not be set for
+ * cross-domain requests.
+ *
+ * To take advantage of this, your server needs to set a token in a JavaScript readable session
+ * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the
+ * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure
+ * that only JavaScript running on your domain could have sent the request. The token must be
+ * unique for each user and must be verifiable by the server (to prevent the JavaScript from making
+ * up its own tokens). We recommend that the token is a digest of your site's authentication
+ * cookie with a {@link https://en.wikipedia.org/wiki/Salt_(cryptography) salt} for added security.
+ *
+ * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName
+ * properties of either $httpProvider.defaults, or the per-request config object.
+ *
+ *
+ * @param {object} config Object describing the request to be made and how it should be
+ * processed. The object has following properties:
+ *
+ * - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc)
+ * - **url** – `{string}` – Absolute or relative URL of the resource that is being requested.
+ * - **params** – `{Object.<string|Object>}` – Map of strings or objects which will be turned to
+ * `?key1=value1&key2=value2` after the url. If the value is not a string, it will be JSONified.
+ * - **data** – `{string|Object}` – Data to be sent as the request message data.
+ * - **headers** – `{Object}` – Map of strings or functions which return strings representing
+ * HTTP headers to send to the server. If the return value of a function is null, the header will
+ * not be sent.
+ * - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token.
+ * - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token.
+ * - **transformRequest** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
+ * transform function or an array of such functions. The transform function takes the http
+ * request body and headers and returns its transformed (typically serialized) version.
+ * - **transformResponse** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
+ * transform function or an array of such functions. The transform function takes the http
+ * response body and headers and returns its transformed (typically deserialized) version.
+ * - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
+ * GET request, otherwise if a cache instance built with
+ * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
+ * caching.
+ * - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}
+ * that should abort the request when resolved.
+ * - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the
+ * XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5
+ * requests with credentials} for more information.
+ * - **responseType** - `{string}` - see {@link
+ * https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}.
+ *
+ * @returns {HttpPromise} Returns a {@link ng.$q promise} object with the
+ * standard `then` method and two http specific methods: `success` and `error`. The `then`
+ * method takes two arguments a success and an error callback which will be called with a
+ * response object. The `success` and `error` methods take a single argument - a function that
+ * will be called when the request succeeds or fails respectively. The arguments passed into
+ * these functions are destructured representation of the response object passed into the
+ * `then` method. The response object has these properties:
+ *
+ * - **data** – `{string|Object}` – The response body transformed with the transform functions.
+ * - **status** – `{number}` – HTTP status code of the response.
+ * - **headers** – `{function([headerName])}` – Header getter function.
+ * - **config** – `{Object}` – The configuration object that was used to generate the request.
+ *
+ * @property {Array.<Object>} pendingRequests Array of config objects for currently pending
+ * requests. This is primarily meant to be used for debugging purposes.
+ *
+ *
+ * @example
+ <example>
+ <file name="index.html">
+ <div ng-controller="FetchCtrl">
+ <select ng-model="method">
+ <option>GET</option>
+ <option>JSONP</option>
+ </select>
+ <input type="text" ng-model="url" size="80"/>
+ <button ng-click="fetch()">fetch</button><br>
+ <button ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
+ <button ng-click="updateModel('JSONP', 'http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')">Sample JSONP</button>
+ <button ng-click="updateModel('JSONP', 'http://angularjs.org/doesntexist&callback=JSON_CALLBACK')">Invalid JSONP</button>
+ <pre>http status code: {{status}}</pre>
+ <pre>http response data: {{data}}</pre>
+ </div>
+ </file>
+ <file name="script.js">
+ function FetchCtrl($scope, $http, $templateCache) {
+ $scope.method = 'GET';
+ $scope.url = 'http-hello.html';
+
+ $scope.fetch = function() {
+ $scope.code = null;
+ $scope.response = null;
+
+ $http({method: $scope.method, url: $scope.url, cache: $templateCache}).
+ success(function(data, status) {
+ $scope.status = status;
+ $scope.data = data;
+ }).
+ error(function(data, status) {
+ $scope.data = data || "Request failed";
+ $scope.status = status;
+ });
+ };
+
+ $scope.updateModel = function(method, url) {
+ $scope.method = method;
+ $scope.url = url;
+ };
+ }
+ </file>
+ <file name="http-hello.html">
+ Hello, $http!
+ </file>
+ <file name="scenario.js">
+ it('should make an xhr GET request', function() {
+ element(':button:contains("Sample GET")').click();
+ element(':button:contains("fetch")').click();
+ expect(binding('status')).toBe('200');
+ expect(binding('data')).toMatch(/Hello, \$http!/);
+ });
+
+ it('should make a JSONP request to angularjs.org', function() {
+ element(':button:contains("Sample JSONP")').click();
+ element(':button:contains("fetch")').click();
+ expect(binding('status')).toBe('200');
+ expect(binding('data')).toMatch(/Super Hero!/);
+ });
+
+ it('should make JSONP request to invalid URL and invoke the error handler',
+ function() {
+ element(':button:contains("Invalid JSONP")').click();
+ element(':button:contains("fetch")').click();
+ expect(binding('status')).toBe('0');
+ expect(binding('data')).toBe('Request failed');
+ });
+ </file>
+ </example>
+ */
+ function $http(requestConfig) {
+ var config = {
+ transformRequest: defaults.transformRequest,
+ transformResponse: defaults.transformResponse
+ };
+ var headers = mergeHeaders(requestConfig);
+
+ extend(config, requestConfig);
+ config.headers = headers;
+ config.method = uppercase(config.method);
+
+ var xsrfValue = $$urlUtils.isSameOrigin(config.url)
+ ? $browser.cookies()[config.xsrfCookieName || defaults.xsrfCookieName]
+ : undefined;
+ if (xsrfValue) {
+ headers[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;
+ }
+
+
+ var serverRequest = function(config) {
+ headers = config.headers;
+ var reqData = transformData(config.data, headersGetter(headers), config.transformRequest);
+
+ // strip content-type if data is undefined
+ if (isUndefined(config.data)) {
+ forEach(headers, function(value, header) {
+ if (lowercase(header) === 'content-type') {
+ delete headers[header];
+ }
+ });
+ }
+
+ if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {
+ config.withCredentials = defaults.withCredentials;
+ }
+
+ // send request
+ return sendReq(config, reqData, headers).then(transformResponse, transformResponse);
+ };
+
+ var chain = [serverRequest, undefined];
+ var promise = $q.when(config);
+
+ // apply interceptors
+ forEach(reversedInterceptors, function(interceptor) {
+ if (interceptor.request || interceptor.requestError) {
+ chain.unshift(interceptor.request, interceptor.requestError);
+ }
+ if (interceptor.response || interceptor.responseError) {
+ chain.push(interceptor.response, interceptor.responseError);
+ }
+ });
+
+ while(chain.length) {
+ var thenFn = chain.shift();
+ var rejectFn = chain.shift();
+
+ promise = promise.then(thenFn, rejectFn);
+ }
+
+ promise.success = function(fn) {
+ promise.then(function(response) {
+ fn(response.data, response.status, response.headers, config);
+ });
+ return promise;
+ };
+
+ promise.error = function(fn) {
+ promise.then(null, function(response) {
+ fn(response.data, response.status, response.headers, config);
+ });
+ return promise;
+ };
+
+ return promise;
+
+ function transformResponse(response) {
+ // make a copy since the response must be cacheable
+ var resp = extend({}, response, {
+ data: transformData(response.data, response.headers, config.transformResponse)
+ });
+ return (isSuccess(response.status))
+ ? resp
+ : $q.reject(resp);
+ }
+
+ function mergeHeaders(config) {
+ var defHeaders = defaults.headers,
+ reqHeaders = extend({}, config.headers),
+ defHeaderName, lowercaseDefHeaderName, reqHeaderName;
+
+ defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);
+
+ // execute if header value is function
+ execHeaders(defHeaders);
+ execHeaders(reqHeaders);
+
+ // using for-in instead of forEach to avoid unecessary iteration after header has been found
+ defaultHeadersIteration:
+ for (defHeaderName in defHeaders) {
+ lowercaseDefHeaderName = lowercase(defHeaderName);
+
+ for (reqHeaderName in reqHeaders) {
+ if (lowercase(reqHeaderName) === lowercaseDefHeaderName) {
+ continue defaultHeadersIteration;
+ }
+ }
+
+ reqHeaders[defHeaderName] = defHeaders[defHeaderName];
+ }
+
+ return reqHeaders;
+
+ function execHeaders(headers) {
+ var headerContent;
+
+ forEach(headers, function(headerFn, header) {
+ if (isFunction(headerFn)) {
+ headerContent = headerFn();
+ if (headerContent != null) {
+ headers[header] = headerContent;
+ } else {
+ delete headers[header];
+ }
+ }
+ });
+ }
+ }
+ }
+
+ $http.pendingRequests = [];
+
+ /**
+ * @ngdoc method
+ * @name ng.$http#get
+ * @methodOf ng.$http
+ *
+ * @description
+ * Shortcut method to perform `GET` request.
+ *
+ * @param {string} url Relative or absolute URL specifying the destination of the request
+ * @param {Object=} config Optional configuration object
+ * @returns {HttpPromise} Future object
+ */
+
+ /**
+ * @ngdoc method
+ * @name ng.$http#delete
+ * @methodOf ng.$http
+ *
+ * @description
+ * Shortcut method to perform `DELETE` request.
+ *
+ * @param {string} url Relative or absolute URL specifying the destination of the request
+ * @param {Object=} config Optional configuration object
+ * @returns {HttpPromise} Future object
+ */
+
+ /**
+ * @ngdoc method
+ * @name ng.$http#head
+ * @methodOf ng.$http
+ *
+ * @description
+ * Shortcut method to perform `HEAD` request.
+ *
+ * @param {string} url Relative or absolute URL specifying the destination of the request
+ * @param {Object=} config Optional configuration object
+ * @returns {HttpPromise} Future object
+ */
+
+ /**
+ * @ngdoc method
+ * @name ng.$http#jsonp
+ * @methodOf ng.$http
+ *
+ * @description
+ * Shortcut method to perform `JSONP` request.
+ *
+ * @param {string} url Relative or absolute URL specifying the destination of the request.
+ * Should contain `JSON_CALLBACK` string.
+ * @param {Object=} config Optional configuration object
+ * @returns {HttpPromise} Future object
+ */
+ createShortMethods('get', 'delete', 'head', 'jsonp');
+
+ /**
+ * @ngdoc method
+ * @name ng.$http#post
+ * @methodOf ng.$http
+ *
+ * @description
+ * Shortcut method to perform `POST` request.
+ *
+ * @param {string} url Relative or absolute URL specifying the destination of the request
+ * @param {*} data Request content
+ * @param {Object=} config Optional configuration object
+ * @returns {HttpPromise} Future object
+ */
+
+ /**
+ * @ngdoc method
+ * @name ng.$http#put
+ * @methodOf ng.$http
+ *
+ * @description
+ * Shortcut method to perform `PUT` request.
+ *
+ * @param {string} url Relative or absolute URL specifying the destination of the request
+ * @param {*} data Request content
+ * @param {Object=} config Optional configuration object
+ * @returns {HttpPromise} Future object
+ */
+ createShortMethodsWithData('post', 'put');
+
+ /**
+ * @ngdoc property
+ * @name ng.$http#defaults
+ * @propertyOf ng.$http
+ *
+ * @description
+ * Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of
+ * default headers, withCredentials as well as request and response transformations.
+ *
+ * See "Setting HTTP Headers" and "Transforming Requests and Responses" sections above.
+ */
+ $http.defaults = defaults;
+
+
+ return $http;
+
+
+ function createShortMethods(names) {
+ forEach(arguments, function(name) {
+ $http[name] = function(url, config) {
+ return $http(extend(config || {}, {
+ method: name,
+ url: url
+ }));
+ };
+ });
+ }
+
+
+ function createShortMethodsWithData(name) {
+ forEach(arguments, function(name) {
+ $http[name] = function(url, data, config) {
+ return $http(extend(config || {}, {
+ method: name,
+ url: url,
+ data: data
+ }));
+ };
+ });
+ }
+
+
+ /**
+ * Makes the request.
+ *
+ * !!! ACCESSES CLOSURE VARS:
+ * $httpBackend, defaults, $log, $rootScope, defaultCache, $http.pendingRequests
+ */
+ function sendReq(config, reqData, reqHeaders) {
+ var deferred = $q.defer(),
+ promise = deferred.promise,
+ cache,
+ cachedResp,
+ url = buildUrl(config.url, config.params);
+
+ $http.pendingRequests.push(config);
+ promise.then(removePendingReq, removePendingReq);
+
+
+ if ((config.cache || defaults.cache) && config.cache !== false && config.method == 'GET') {
+ cache = isObject(config.cache) ? config.cache
+ : isObject(defaults.cache) ? defaults.cache
+ : defaultCache;
+ }
+
+ if (cache) {
+ cachedResp = cache.get(url);
+ if (cachedResp) {
+ if (cachedResp.then) {
+ // cached request has already been sent, but there is no response yet
+ cachedResp.then(removePendingReq, removePendingReq);
+ return cachedResp;
+ } else {
+ // serving from cache
+ if (isArray(cachedResp)) {
+ resolvePromise(cachedResp[1], cachedResp[0], copy(cachedResp[2]));
+ } else {
+ resolvePromise(cachedResp, 200, {});
+ }
+ }
+ } else {
+ // put the promise for the non-transformed response into cache as a placeholder
+ cache.put(url, promise);
+ }
+ }
+
+ // if we won't have the response in cache, send the request to the backend
+ if (!cachedResp) {
+ $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
+ config.withCredentials, config.responseType);
+ }
+
+ return promise;
+
+
+ /**
+ * Callback registered to $httpBackend():
+ * - caches the response if desired
+ * - resolves the raw $http promise
+ * - calls $apply
+ */
+ function done(status, response, headersString) {
+ if (cache) {
+ if (isSuccess(status)) {
+ cache.put(url, [status, response, parseHeaders(headersString)]);
+ } else {
+ // remove promise from the cache
+ cache.remove(url);
+ }
+ }
+
+ resolvePromise(response, status, headersString);
+ if (!$rootScope.$$phase) $rootScope.$apply();
+ }
+
+
+ /**
+ * Resolves the raw $http promise.
+ */
+ function resolvePromise(response, status, headers) {
+ // normalize internal statuses to 0
+ status = Math.max(status, 0);
+
+ (isSuccess(status) ? deferred.resolve : deferred.reject)({
+ data: response,
+ status: status,
+ headers: headersGetter(headers),
+ config: config
+ });
+ }
+
+
+ function removePendingReq() {
+ var idx = indexOf($http.pendingRequests, config);
+ if (idx !== -1) $http.pendingRequests.splice(idx, 1);
+ }
+ }
+
+
+ function buildUrl(url, params) {
+ if (!params) return url;
+ var parts = [];
+ forEachSorted(params, function(value, key) {
+ if (value == null || value == undefined) return;
+ if (!isArray(value)) value = [value];
+
+ forEach(value, function(v) {
+ if (isObject(v)) {
+ v = toJson(v);
+ }
+ parts.push(encodeUriQuery(key) + '=' +
+ encodeUriQuery(v));
+ });
+ });
+ return url + ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
+ }
+
+
+ }];
+}
+
+var XHR = window.XMLHttpRequest || function() {
+ try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
+ try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {}
+ try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {}
+ throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest.");
+};
+
+
+/**
* @ngdoc object
+ * @name ng.$httpBackend
+ * @requires $browser
+ * @requires $window
+ * @requires $document
+ *
+ * @description
+ * HTTP backend used by the {@link ng.$http service} that delegates to
+ * XMLHttpRequest object or JSONP and deals with browser incompatibilities.
+ *
+ * You should never need to use this service directly, instead use the higher-level abstractions:
+ * {@link ng.$http $http} or {@link ngResource.$resource $resource}.
+ *
+ * During testing this implementation is swapped with {@link ngMock.$httpBackend mock
+ * $httpBackend} which can be trained with responses.
+ */
+function $HttpBackendProvider() {
+ this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) {
+ return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks,
+ $document[0], $window.location.protocol.replace(':', ''));
+ }];
+}
+
+function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument, locationProtocol) {
+ // TODO(vojta): fix the signature
+ return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
+ var status;
+ $browser.$$incOutstandingRequestCount();
+ url = url || $browser.url();
+
+ if (lowercase(method) == 'jsonp') {
+ var callbackId = '_' + (callbacks.counter++).toString(36);
+ callbacks[callbackId] = function(data) {
+ callbacks[callbackId].data = data;
+ };
+
+ var jsonpDone = jsonpReq(url.replace('JSON_CALLBACK', 'angular.callbacks.' + callbackId),
+ function() {
+ if (callbacks[callbackId].data) {
+ completeRequest(callback, 200, callbacks[callbackId].data);
+ } else {
+ completeRequest(callback, status || -2);
+ }
+ delete callbacks[callbackId];
+ });
+ } else {
+ var xhr = new XHR();
+ xhr.open(method, url, true);
+ forEach(headers, function(value, key) {
+ if (value) xhr.setRequestHeader(key, value);
+ });
+
+ // In IE6 and 7, this might be called synchronously when xhr.send below is called and the
+ // response is in the cache. the promise api will ensure that to the app code the api is
+ // always async
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ var responseHeaders = xhr.getAllResponseHeaders();
+
+ // TODO(vojta): remove once Firefox 21 gets released.
+ // begin: workaround to overcome Firefox CORS http response headers bug
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=608735
+ // Firefox already patched in nightly. Should land in Firefox 21.
+
+ // CORS "simple response headers" http://www.w3.org/TR/cors/
+ var value,
+ simpleHeaders = ["Cache-Control", "Content-Language", "Content-Type",
+ "Expires", "Last-Modified", "Pragma"];
+ if (!responseHeaders) {
+ responseHeaders = "";
+ forEach(simpleHeaders, function (header) {
+ var value = xhr.getResponseHeader(header);
+ if (value) {
+ responseHeaders += header + ": " + value + "\n";
+ }
+ });
+ }
+ // end of the workaround.
+
+ // responseText is the old-school way of retrieving response (supported by IE8 & 9)
+ // response and responseType properties were introduced in XHR Level2 spec (supported by IE10)
+ completeRequest(callback,
+ status || xhr.status,
+ (xhr.responseType ? xhr.response : xhr.responseText),
+ responseHeaders);
+ }
+ };
+
+ if (withCredentials) {
+ xhr.withCredentials = true;
+ }
+
+ if (responseType) {
+ xhr.responseType = responseType;
+ }
+
+ xhr.send(post || '');
+ }
+
+ if (timeout > 0) {
+ var timeoutId = $browserDefer(timeoutRequest, timeout);
+ } else if (timeout && timeout.then) {
+ timeout.then(timeoutRequest);
+ }
+
+
+ function timeoutRequest() {
+ status = -1;
+ jsonpDone && jsonpDone();
+ xhr && xhr.abort();
+ }
+
+ function completeRequest(callback, status, response, headersString) {
+ // URL_MATCH is defined in src/service/location.js
+ var protocol = (url.match(SERVER_MATCH) || ['', locationProtocol])[1];
+
+ // cancel timeout and subsequent timeout promise resolution
+ timeoutId && $browserDefer.cancel(timeoutId);
+ jsonpDone = xhr = null;
+
+ // fix status code for file protocol (it's always 0)
+ status = (protocol == 'file') ? (response ? 200 : 404) : status;
+
+ // normalize IE bug (http://bugs.jquery.com/ticket/1450)
+ status = status == 1223 ? 204 : status;
+
+ callback(status, response, headersString);
+ $browser.$$completeOutstandingRequest(noop);
+ }
+ };
+
+ function jsonpReq(url, done) {
+ // we can't use jQuery/jqLite here because jQuery does crazy shit with script elements, e.g.:
+ // - fetches local scripts via XHR and evals them
+ // - adds and immediately removes script elements from the document
+ var script = rawDocument.createElement('script'),
+ doneWrapper = function() {
+ rawDocument.body.removeChild(script);
+ if (done) done();
+ };
+
+ script.type = 'text/javascript';
+ script.src = url;
+
+ if (msie) {
+ script.onreadystatechange = function() {
+ if (/loaded|complete/.test(script.readyState)) doneWrapper();
+ };
+ } else {
+ script.onload = script.onerror = doneWrapper;
+ }
+
+ rawDocument.body.appendChild(script);
+ return doneWrapper;
+ }
+}
+
+var $interpolateMinErr = minErr('$interpolate');
+
+/**
+ * @ngdoc object
* @name ng.$interpolateProvider
* @function
*
* @description
*
* Used for configuring the interpolation markup. Defaults to `{{` and `}}`.
+ *
+ * @example
+ <doc:example>
+ <doc:source>
+ <script>
+ var myApp = angular.module('App', [], function($interpolateProvider) {
+ $interpolateProvider.startSymbol('//');
+ $interpolateProvider.endSymbol('//');
+ });
+ function Controller($scope) {
+ $scope.label = "Interpolation Provider Sample";
+ }
+ </script>
+ <div ng-app="App" ng-controller="Controller">
+ //label//
+ </div>
+ </doc:source>
+ </doc:example>
*/
function $InterpolateProvider() {
var startSymbol = '{{';
@@ -5474,7 +6826,7 @@
};
- this.$get = ['$parse', '$exceptionHandler', function($parse, $exceptionHandler) {
+ this.$get = ['$parse', '$exceptionHandler', '$sce', function($parse, $exceptionHandler, $sce) {
var startSymbolLength = startSymbol.length,
endSymbolLength = endSymbol.length;
@@ -5484,6 +6836,7 @@
* @function
*
* @requires $parse
+ * @requires $sce
*
* @description
*
@@ -5504,6 +6857,10 @@
* @param {boolean=} mustHaveExpression if set to true then the interpolation string must have
* embedded expression in order to return an interpolation function. Strings with no
* embedded expression will return null for the interpolation function.
+ * @param {string=} trustedContext when provided, the returned function passes the interpolated
+ * result through {@link ng.$sce#getTrusted $sce.getTrusted(interpolatedResult,
+ * trustedContext)} before returning it. Refer to the {@link ng.$sce $sce} service that
+ * provides Strict Contextual Escaping for details.
* @returns {function(context)} an interpolation function which is used to compute the interpolated
* string. The function has these parameters:
*
@@ -5511,7 +6868,7 @@
* against.
*
*/
- function $interpolate(text, mustHaveExpression) {
+ function $interpolate(text, mustHaveExpression, trustedContext) {
var startIndex,
endIndex,
index = 0,
@@ -5543,6 +6900,19 @@
length = 1;
}
+ // Concatenating expressions makes it hard to reason about whether some combination of concatenated
+ // values are unsafe to use and could easily lead to XSS. By requiring that a single
+ // expression be used for iframe[src], object[src], etc., we ensure that the value that's used
+ // is assigned or constructed by some JS code somewhere that is more testable or make it
+ // obvious that you bound the value to some user controlled value. This helps reduce the load
+ // when auditing for XSS issues.
+ if (trustedContext && parts.length > 1) {
+ throw $interpolateMinErr('noconcat',
+ "Error while interpolating: {0}\nStrict Contextual Escaping disallows " +
+ "interpolations that concatenate multiple expressions when a trusted value is " +
+ "required. See http://docs.angularjs.org/api/ng.$sce", text);
+ }
+
if (!mustHaveExpression || hasInterpolation) {
concat.length = length;
fn = function(context) {
@@ -5550,6 +6920,11 @@
for(var i = 0, ii = length, part; i<ii; i++) {
if (typeof (part = parts[i]) == 'function') {
part = part(context);
+ if (trustedContext) {
+ part = $sce.getTrusted(trustedContext, part);
+ } else {
+ part = $sce.valueOf(part);
+ }
if (part == null || part == undefined) {
part = '';
} else if (typeof part != 'string') {
@@ -5561,7 +6936,7 @@
return concat.join('');
}
catch(err) {
- var newErr = new Error('Error while interpolating: ' + text + '\n' + err.toString());
+ var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text, err.toString());
$exceptionHandler(newErr);
}
};
@@ -5609,9 +6984,81 @@
}];
}
+/**
+ * @ngdoc object
+ * @name ng.$locale
+ *
+ * @description
+ * $locale service provides localization rules for various Angular components. As of right now the
+ * only public api is:
+ *
+ * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`)
+ */
+function $LocaleProvider(){
+ this.$get = function() {
+ return {
+ id: 'en-us',
+
+ NUMBER_FORMATS: {
+ DECIMAL_SEP: '.',
+ GROUP_SEP: ',',
+ PATTERNS: [
+ { // Decimal Pattern
+ minInt: 1,
+ minFrac: 0,
+ maxFrac: 3,
+ posPre: '',
+ posSuf: '',
+ negPre: '-',
+ negSuf: '',
+ gSize: 3,
+ lgSize: 3
+ },{ //Currency Pattern
+ minInt: 1,
+ minFrac: 2,
+ maxFrac: 2,
+ posPre: '\u00A4',
+ posSuf: '',
+ negPre: '(\u00A4',
+ negSuf: ')',
+ gSize: 3,
+ lgSize: 3
+ }
+ ],
+ CURRENCY_SYM: '$'
+ },
+
+ DATETIME_FORMATS: {
+ MONTH: 'January,February,March,April,May,June,July,August,September,October,November,December'
+ .split(','),
+ SHORTMONTH: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(','),
+ DAY: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'.split(','),
+ SHORTDAY: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'.split(','),
+ AMPMS: ['AM','PM'],
+ medium: 'MMM d, y h:mm:ss a',
+ short: 'M/d/yy h:mm a',
+ fullDate: 'EEEE, MMMM d, y',
+ longDate: 'MMMM d, y',
+ mediumDate: 'MMM d, y',
+ shortDate: 'M/d/yy',
+ mediumTime: 'h:mm:ss a',
+ shortTime: 'h:mm a'
+ },
+
+ pluralCat: function(num) {
+ if (num === 1) {
+ return 'one';
+ }
+ return 'other';
+ }
+ };
+ };
+}
+
var SERVER_MATCH = /^([^:]+):\/\/(\w+:{0,1}\w*@)?(\{?[\w\.-]*\}?)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,
PATH_MATCH = /^([^\?#]*)(\?([^#]*))?(#(.*))?$/,
DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp': 21};
+var $locationMinErr = minErr('$location');
/**
@@ -5677,7 +7124,7 @@
return url.substr(0, stripHash(url).lastIndexOf('/') + 1);
}
-/* return the server only */
+/* return the server only (scheme://host:port) */
function serverBase(url) {
return url.substring(0, url.indexOf('/', url.indexOf('//') + 2));
}
@@ -5692,6 +7139,7 @@
* @param {string} basePrefix url path prefix
*/
function LocationHtml5Url(appBase, basePrefix) {
+ this.$$html5 = true;
basePrefix = basePrefix || '';
var appBaseNoFile = stripFile(appBase);
/**
@@ -5704,7 +7152,7 @@
matchUrl(url, parsed);
var pathUrl = beginsWith(appBaseNoFile, url);
if (!isString(pathUrl)) {
- throw Error('Invalid url "' + url + '", missing path prefix "' + appBaseNoFile + '".');
+ throw $locationMinErr('ipthprfx', 'Invalid url "{0}", missing path prefix "{1}".', url, appBaseNoFile);
}
matchAppUrl(pathUrl, parsed);
extend(this, parsed);
@@ -5748,7 +7196,8 @@
/**
* LocationHashbangUrl represents url
- * This object is exposed as $location service when html5 history api is disabled or not supported
+ * This object is exposed as $location service when developer doesn't opt into html5 mode.
+ * It also serves as the base class for html5 mode fallback on legacy browsers.
*
* @constructor
* @param {string} appBase application base URL
@@ -5757,20 +7206,24 @@
function LocationHashbangUrl(appBase, hashPrefix) {
var appBaseNoFile = stripFile(appBase);
+ matchUrl(appBase, this);
+
+
/**
* Parse given hashbang url into properties
* @param {string} url Hashbang url
* @private
*/
this.$$parse = function(url) {
- matchUrl(url, this);
var withoutBaseUrl = beginsWith(appBase, url) || beginsWith(appBaseNoFile, url);
- if (!isString(withoutBaseUrl)) {
- throw new Error('Invalid url "' + url + '", does not start with "' + appBase + '".');
- }
- var withoutHashUrl = withoutBaseUrl.charAt(0) == '#' ? beginsWith(hashPrefix, withoutBaseUrl) : withoutBaseUrl;
+ var withoutHashUrl = withoutBaseUrl.charAt(0) == '#'
+ ? beginsWith(hashPrefix, withoutBaseUrl)
+ : (this.$$html5)
+ ? withoutBaseUrl
+ : '';
+
if (!isString(withoutHashUrl)) {
- throw new Error('Invalid url "' + url + '", missing hash prefix "' + hashPrefix + '".');
+ throw $locationMinErr('ihshprfx', 'Invalid url "{0}", missing hash prefix "{1}".', url, hashPrefix);
}
matchAppUrl(withoutHashUrl, this);
this.$$compose();
@@ -5806,6 +7259,7 @@
* @param {string} hashPrefix hashbang prefix
*/
function LocationHashbangInHtml5Url(appBase, hashPrefix) {
+ this.$$html5 = true;
LocationHashbangUrl.apply(this, arguments);
var appBaseNoFile = stripFile(appBase);
@@ -5829,6 +7283,12 @@
LocationHtml5Url.prototype = {
/**
+ * Are we in html5 mode?
+ * @private
+ */
+ $$html5: false,
+
+ /**
* Has any change been replacing ?
* @private
*/
@@ -5862,6 +7322,7 @@
* Change path, search and hash, when called with parameter and return `$location`.
*
* @param {string=} url New url without base prefix (e.g. `/path?a=b#hash`)
+ * @param {string=} replace The path that will be changed
* @return {string} url
*/
url: function(url, replace) {
@@ -5952,24 +7413,32 @@
*
* Change search part when called with parameter and return `$location`.
*
- * @param {string|object<string,string>=} search New search params - string or hash object
+ * @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or hash object. Hash object
+ * may contain an array of values, which will be decoded as duplicates in the url.
* @param {string=} paramValue If `search` is a string, then `paramValue` will override only a
* single search parameter. If the value is `null`, the parameter will be deleted.
*
* @return {string} search
*/
search: function(search, paramValue) {
- if (isUndefined(search))
- return this.$$search;
-
- if (isDefined(paramValue)) {
- if (paramValue === null) {
- delete this.$$search[search];
- } else {
- this.$$search[search] = paramValue;
- }
- } else {
- this.$$search = isString(search) ? parseKeyValue(search) : search;
+ switch (arguments.length) {
+ case 0:
+ return this.$$search;
+ case 1:
+ if (isString(search)) {
+ this.$$search = parseKeyValue(search);
+ } else if (isObject(search)) {
+ this.$$search = search;
+ } else {
+ throw $locationMinErr('isrcharg', 'The first argument of the `$location#search()` call must be a string or an object.');
+ }
+ break;
+ default:
+ if (paramValue == undefined || paramValue == null) {
+ delete this.$$search[search];
+ } else {
+ this.$$search[search] = paramValue;
+ }
}
this.$$compose();
@@ -6105,12 +7574,12 @@
function( $rootScope, $browser, $sniffer, $rootElement) {
var $location,
LocationMode,
- baseHref = $browser.baseHref(),
+ baseHref = $browser.baseHref(), // if base[href] is undefined, it defaults to ''
initialUrl = $browser.url(),
appBase;
if (html5Mode) {
- appBase = baseHref ? serverBase(initialUrl) + baseHref : initialUrl;
+ appBase = serverBase(initialUrl) + (baseHref || '/');
LocationMode = $sniffer.history ? LocationHtml5Url : LocationHashbangInHtml5Url;
} else {
appBase = stripHash(initialUrl);
@@ -6119,7 +7588,7 @@
$location = new LocationMode(appBase, '#' + hashPrefix);
$location.$$parse($location.$$rewrite(initialUrl));
- $rootElement.bind('click', function(event) {
+ $rootElement.on('click', function(event) {
// TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
// currently we open nice url link and redirect then
@@ -6276,23 +7745,23 @@
/**
* @ngdoc method
- * @name ng.$log#warn
+ * @name ng.$log#info
* @methodOf ng.$log
*
* @description
- * Write a warning message
+ * Write an information message
*/
- warn: consoleLog('warn'),
+ info: consoleLog('info'),
/**
* @ngdoc method
- * @name ng.$log#info
+ * @name ng.$log#warn
* @methodOf ng.$log
*
* @description
- * Write an information message
+ * Write a warning message
*/
- info: consoleLog('info'),
+ warn: consoleLog('warn'),
/**
* @ngdoc method
@@ -6359,6 +7828,55 @@
}];
}
+var $parseMinErr = minErr('$parse');
+
+// Sandboxing Angular Expressions
+// ------------------------------
+// Angular expressions are generally considered safe because these expressions only have direct access to $scope and
+// locals. However, one can obtain the ability to execute arbitrary JS code by obtaining a reference to native JS
+// functions such as the Function constructor.
+//
+// As an example, consider the following Angular expression:
+//
+// {}.toString.constructor(alert("evil JS code"))
+//
+// We want to prevent this type of access. For the sake of performance, during the lexing phase we disallow any "dotted"
+// access to any member named "constructor".
+//
+// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor while evaluating
+// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor while evaluating
+// the expression, which is a stronger but more expensive test. Since reflective calls are expensive anyway, this is not
+// such a big deal compared to static dereferencing.
+//
+// This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits against the
+// expression language, but not to prevent exploits that were enabled by exposing sensitive JavaScript or browser apis
+// on Scope. Exposing such objects on a Scope is never a good practice and therefore we are not even trying to protect
+// against interaction with an object explicitly exposed in this way.
+//
+// A developer could foil the name check by aliasing the Function constructor under a different name on the scope.
+//
+// In general, it is not possible to access a Window object from an angular expression unless a window or some DOM
+// object that has a reference to window is published onto a Scope.
+
+function ensureSafeMemberName(name, fullExpression) {
+ if (name === "constructor") {
+ throw $parseMinErr('isecfld',
+ 'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}', fullExpression);
+ }
+ return name;
+};
+
+function ensureSafeObject(obj, fullExpression) {
+ // nifty check if obj is Function that is fast and works across iframes and other contexts
+ if (obj && obj.constructor === obj) {
+ throw $parseMinErr('isecfn',
+ 'Referencing Function in Angular expressions is disallowed! Expression: {0}', fullExpression);
+ } else {
+ return obj;
+ }
+}
+
+
var OPERATORS = {
'null':function(){return null;},
'true':function(){return true;},
@@ -6482,11 +8000,11 @@
function throwError(error, start, end) {
end = end || index;
- throw Error("Lexer Error: " + error + " at column" +
- (isDefined(start)
- ? "s " + start + "-" + index + " [" + text.substring(start, end) + "]"
- : " " + end) +
- " in expression [" + text + "].");
+ var colStr = (isDefined(start) ?
+ "s " + start + "-" + index + " [" + text.substring(start, end) + "]"
+ : " " + end);
+ throw $parseMinErr('lexerr', "Lexer Error: {0} at column{1} in expression [{2}].",
+ error, colStr, text);
}
function readNumber() {
@@ -6562,12 +8080,12 @@
if (OPERATORS.hasOwnProperty(ident)) {
token.fn = token.json = OPERATORS[ident];
} else {
- var getter = getterFn(ident, csp);
+ var getter = getterFn(ident, csp, text);
token.fn = extend(function(self, locals) {
return (getter(self, locals));
}, {
assign: function(self, value) {
- return setter(self, ident, value);
+ return setter(self, ident, value, text);
}
});
}
@@ -6668,15 +8186,14 @@
///////////////////////////////////
function throwError(msg, token) {
- throw Error("Syntax Error: Token '" + token.text +
- "' " + msg + " at column " +
- (token.index + 1) + " of the expression [" +
- text + "] starting at [" + text.substring(token.index) + "].");
+ throw $parseMinErr('syntax',
+ "Syntax Error: Token '{0}' {1} at column {2} of the expression [{3}] starting at [{4}].",
+ token.text, msg, (token.index + 1), text, text.substring(token.index));
}
function peekToken() {
if (tokens.length === 0)
- throw Error("Unexpected end of expression: " + text);
+ throw $parseMinErr('ueoe', "Unexpected end of expression: {0}", text);
return tokens[0];
}
@@ -6725,7 +8242,7 @@
constant: left.constant && middle.constant && right.constant
});
}
-
+
function binaryFn(left, fn, right) {
return extend(function(self, locals) {
return fn(self, locals, left, right);
@@ -6830,7 +8347,7 @@
return left;
}
}
-
+
function logicalOR() {
var left = logicalAND();
var token;
@@ -6942,14 +8459,14 @@
function _fieldAccess(object) {
var field = expect().text;
- var getter = getterFn(field, csp);
+ var getter = getterFn(field, csp, text);
return extend(
function(scope, locals, self) {
return getter(self || object(scope, locals), locals);
},
{
assign:function(scope, value, locals) {
- return setter(object(scope, locals), field, value);
+ return setter(object(scope, locals), field, value, text);
}
}
);
@@ -6965,7 +8482,7 @@
v, p;
if (!o) return undefined;
- v = o[i];
+ v = ensureSafeObject(o[i], text);
if (v && v.then) {
p = v;
if (!('$$v' in v)) {
@@ -6977,7 +8494,9 @@
return v;
}, {
assign:function(self, value, locals){
- return obj(self, locals)[indexFn(self, locals)] = value;
+ var key = indexFn(self, locals);
+ // prevent overwriting of Function.constructor which would break ensureSafeObject check
+ return ensureSafeObject(obj(self, locals), text)[key] = value;
}
});
}
@@ -7065,48 +8584,33 @@
// Parser helper functions
//////////////////////////////////////////////////
-function setter(obj, path, setValue) {
- var element = path.split('.');
+function setter(obj, path, setValue, fullExp) {
+ var element = path.split('.'), key;
for (var i = 0; element.length > 1; i++) {
- var key = element.shift();
+ key = ensureSafeMemberName(element.shift(), fullExp);
var propertyObj = obj[key];
if (!propertyObj) {
propertyObj = {};
obj[key] = propertyObj;
}
obj = propertyObj;
+ if (obj.then) {
+ if (!("$$v" in obj)) {
+ (function(promise) {
+ promise.then(function(val) { promise.$$v = val; }); }
+ )(obj);
+ }
+ if (obj.$$v === undefined) {
+ obj.$$v = {};
+ }
+ obj = obj.$$v;
+ }
}
- obj[element.shift()] = setValue;
+ key = ensureSafeMemberName(element.shift(), fullExp);
+ obj[key] = setValue;
return setValue;
}
-/**
- * Return the value accessible from the object by path. Any undefined traversals are ignored
- * @param {Object} obj starting object
- * @param {string} path path to traverse
- * @param {boolean=true} bindFnToScope
- * @returns value as accessible by path
- */
-//TODO(misko): this function needs to be removed
-function getter(obj, path, bindFnToScope) {
- if (!path) return obj;
- var keys = path.split('.');
- var key;
- var lastInstance = obj;
- var len = keys.length;
-
- for (var i = 0; i < len; i++) {
- key = keys[i];
- if (obj) {
- obj = (lastInstance = obj)[key];
- }
- }
- if (!bindFnToScope && isFunction(obj)) {
- return bind(lastInstance, obj);
- }
- return obj;
-}
-
var getterFnCache = {};
/**
@@ -7114,7 +8618,12 @@
* - http://jsperf.com/angularjs-parse-getter/4
* - http://jsperf.com/path-evaluation-simplified/7
*/
-function cspSafeGetterFn(key0, key1, key2, key3, key4) {
+function cspSafeGetterFn(key0, key1, key2, key3, key4, fullExp) {
+ ensureSafeMemberName(key0, fullExp);
+ ensureSafeMemberName(key1, fullExp);
+ ensureSafeMemberName(key2, fullExp);
+ ensureSafeMemberName(key3, fullExp);
+ ensureSafeMemberName(key4, fullExp);
return function(scope, locals) {
var pathVal = (locals && locals.hasOwnProperty(key0)) ? locals : scope,
promise;
@@ -7178,7 +8687,7 @@
};
}
-function getterFn(path, csp) {
+function getterFn(path, csp, fullExp) {
if (getterFnCache.hasOwnProperty(path)) {
return getterFnCache[path];
}
@@ -7189,12 +8698,12 @@
if (csp) {
fn = (pathKeysLength < 6)
- ? cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4])
+ ? cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4], fullExp)
: function(scope, locals) {
var i = 0, val;
do {
val = cspSafeGetterFn(
- pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++]
+ pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], fullExp
)(scope, locals);
locals = undefined; // clear after first iteration
@@ -7205,6 +8714,7 @@
} else {
var code = 'var l, fn, p;\n';
forEach(pathKeys, function(key, index) {
+ ensureSafeMemberName(key, fullExp);
code += 'if(s === null || s === undefined) return s;\n' +
'l=s;\n' +
's='+ (index
@@ -7373,21 +8883,27 @@
* **Methods**
*
* - `then(successCallback, errorCallback)` – regardless of when the promise was or will be resolved
- * or rejected calls one of the success or error callbacks asynchronously as soon as the result
- * is available. The callbacks are called with a single argument the result or rejection reason.
+ * or rejected, `then` calls one of the success or error callbacks asynchronously as soon as the result
+ * is available. The callbacks are called with a single argument: the result or rejection reason.
*
* This method *returns a new promise* which is resolved or rejected via the return value of the
* `successCallback` or `errorCallback`.
*
- * - `always(callback)` – allows you to observe either the fulfillment or rejection of a promise,
+ * - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)`
+ *
+ * - `finally(callback)` – allows you to observe either the fulfillment or rejection of a promise,
* but to do so without modifying the final value. This is useful to release resources or do some
* clean-up that needs to be done whether the promise was rejected or resolved. See the [full
* specification](https://github.com/kriskowal/q/wiki/API-Reference#promisefin… for
* more information.
*
+ * Because `finally` is a reserved word in JavaScript and reserved keywords are not supported as
+ * property names by ES3, you'll need to invoke the method like `promise['finally'](callback)` to
+ * make your code IE8 compatible.
+ *
* # Chaining promises
*
- * Because calling `then` api of a promise returns a new derived promise, it is easily possible
+ * Because calling the `then` method of a promise returns a new derived promise, it is easily possible
* to create a chain of promises:
*
* <pre>
@@ -7395,13 +8911,13 @@
* return result + 1;
* });
*
- * // promiseB will be resolved immediately after promiseA is resolved and its value will be
- * // the result of promiseA incremented by 1
+ * // promiseB will be resolved immediately after promiseA is resolved and its value
+ * // will be the result of promiseA incremented by 1
* </pre>
*
* It is possible to create chains of any length and since a promise can be resolved with another
* promise (which will defer its resolution further), it is possible to pause/defer resolution of
- * the promises at any point in the chain. This makes it possible to implement powerful apis like
+ * the promises at any point in the chain. This makes it possible to implement powerful APIs like
* $http's response interceptors.
*
*
@@ -7416,25 +8932,25 @@
* you can treat promises attached to a scope as if they were the resulting values.
* - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains
* all the important functionality needed for common async tasks.
- *
+ *
* # Testing
- *
+ *
* <pre>
* it('should simulate promise', inject(function($q, $rootScope) {
* var deferred = $q.defer();
* var promise = deferred.promise;
* var resolvedValue;
- *
+ *
* promise.then(function(value) { resolvedValue = value; });
* expect(resolvedValue).toBeUndefined();
- *
+ *
* // Simulate resolving of promise
* deferred.resolve(123);
* // Note that the 'then' function does not get called synchronously.
* // This is because we want the promise API to always be async, whether or not
* // it got called synchronously or asynchronously.
* expect(resolvedValue).toBeUndefined();
- *
+ *
* // Propagate promise resolution to 'then' functions using $apply().
* $rootScope.$apply();
* expect(resolvedValue).toEqual(123);
@@ -7487,7 +9003,7 @@
var callback;
for (var i = 0, ii = callbacks.length; i < ii; i++) {
callback = callbacks[i];
- value.then(callback[0], callback[1]);
+ value.then(callback[0], callback[1], callback[2]);
}
});
}
@@ -7500,16 +9016,33 @@
},
+ notify: function(progress) {
+ if (pending) {
+ var callbacks = pending;
+
+ if (pending.length) {
+ nextTick(function() {
+ var callback;
+ for (var i = 0, ii = callbacks.length; i < ii; i++) {
+ callback = callbacks[i];
+ callback[2](progress);
+ }
+ });
+ }
+ }
+ },
+
+
promise: {
- then: function(callback, errback) {
+ then: function(callback, errback, progressback) {
var result = defer();
var wrappedCallback = function(value) {
try {
result.resolve((callback || defaultCallback)(value));
} catch(e) {
+ result.reject(e);
exceptionHandler(e);
- result.reject(e);
}
};
@@ -7517,21 +9050,34 @@
try {
result.resolve((errback || defaultErrback)(reason));
} catch(e) {
+ result.reject(e);
exceptionHandler(e);
- result.reject(e);
}
};
+ var wrappedProgressback = function(progress) {
+ try {
+ result.notify((progressback || defaultCallback)(progress));
+ } catch(e) {
+ exceptionHandler(e);
+ }
+ };
+
if (pending) {
- pending.push([wrappedCallback, wrappedErrback]);
+ pending.push([wrappedCallback, wrappedErrback, wrappedProgressback]);
} else {
- value.then(wrappedCallback, wrappedErrback);
+ value.then(wrappedCallback, wrappedErrback, wrappedProgressback);
}
return result.promise;
},
- always: function(callback) {
-
+
+ "catch": function(callback) {
+ return this.then(null, callback);
+ },
+
+ "finally": function(callback) {
+
function makePromise(value, resolved) {
var result = defer();
if (resolved) {
@@ -7541,14 +9087,14 @@
}
return result.promise;
}
-
+
function handleCallback(value, isResolved) {
- var callbackOutput = null;
+ var callbackOutput = null;
try {
callbackOutput = (callback ||defaultCallback)();
} catch(e) {
return makePromise(e, false);
- }
+ }
if (callbackOutput && callbackOutput.then) {
return callbackOutput.then(function() {
return makePromise(value, isResolved);
@@ -7559,7 +9105,7 @@
return makePromise(value, isResolved);
}
}
-
+
return this.then(function(value) {
return handleCallback(value, true);
}, function(error) {
@@ -7647,7 +9193,7 @@
* @param {*} value Value or a promise
* @returns {Promise} Returns a promise of the passed value or promise
*/
- var when = function(value, callback, errback) {
+ var when = function(value, callback, errback, progressback) {
var result = defer(),
done;
@@ -7669,15 +9215,26 @@
}
};
+ var wrappedProgressback = function(progress) {
+ try {
+ return (progressback || defaultCallback)(progress);
+ } catch (e) {
+ exceptionHandler(e);
+ }
+ };
+
nextTick(function() {
ref(value).then(function(value) {
if (done) return;
done = true;
- result.resolve(ref(value).then(wrappedCallback, wrappedErrback));
+ result.resolve(ref(value).then(wrappedCallback, wrappedErrback, wrappedProgressback));
}, function(reason) {
if (done) return;
done = true;
result.resolve(wrappedErrback(reason));
+ }, function(progress) {
+ if (done) return;
+ result.notify(wrappedProgressback(progress));
});
});
@@ -7742,542 +9299,6 @@
}
/**
- * @ngdoc object
- * @name ng.$routeProvider
- * @function
- *
- * @description
- *
- * Used for configuring routes. See {@link ng.$route $route} for an example.
- */
-function $RouteProvider(){
- var routes = {};
-
- /**
- * @ngdoc method
- * @name ng.$routeProvider#when
- * @methodOf ng.$routeProvider
- *
- * @param {string} path Route path (matched against `$location.path`). If `$location.path`
- * contains redundant trailing slash or is missing one, the route will still match and the
- * `$location.path` will be updated to add or drop the trailing slash to exactly match the
- * route definition.
- *
- * * `path` can contain named groups starting with a colon (`:name`). All characters up
- * to the next slash are matched and stored in `$routeParams` under the given `name`
- * when the route matches.
- * * `path` can contain named groups starting with a star (`*name`). All characters are
- * eagerly stored in `$routeParams` under the given `name` when the route matches.
- *
- * For example, routes like `/color/:color/largecode/*largecode/edit` will match
- * `/color/brown/largecode/code/with/slashs/edit` and extract:
- *
- * * `color: brown`
- * * `largecode: code/with/slashs`.
- *
- *
- * @param {Object} route Mapping information to be assigned to `$route.current` on route
- * match.
- *
- * Object properties:
- *
- * - `controller` – `{(string|function()=}` – Controller fn that should be associated with newly
- * created scope or the name of a {@link angular.Module#controller registered controller}
- * if passed as a string.
- * - `controllerAs` – `{string=}` – A controller alias name. If present the controller will be
- * published to scope under the `controllerAs` name.
- * - `template` – `{string=|function()=}` – html template as a string or function that returns
- * an html template as a string which should be used by {@link ng.directive:ngView ngView} or
- * {@link ng.directive:ngInclude ngInclude} directives.
- * This property takes precedence over `templateUrl`.
- *
- * If `template` is a function, it will be called with the following parameters:
- *
- * - `{Array.<Object>}` - route parameters extracted from the current
- * `$location.path()` by applying the current route
- *
- * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
- * template that should be used by {@link ng.directive:ngView ngView}.
- *
- * If `templateUrl` is a function, it will be called with the following parameters:
- *
- * - `{Array.<Object>}` - route parameters extracted from the current
- * `$location.path()` by applying the current route
- *
- * - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
- * be injected into the controller. If any of these dependencies are promises, they will be
- * resolved and converted to a value before the controller is instantiated and the
- * `$routeChangeSuccess` event is fired. The map object is:
- *
- * - `key` – `{string}`: a name of a dependency to be injected into the controller.
- * - `factory` - `{string|function}`: If `string` then it is an alias for a service.
- * Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected}
- * and the return value is treated as the dependency. If the result is a promise, it is resolved
- * before its value is injected into the controller.
- *
- * - `redirectTo` – {(string|function())=} – value to update
- * {@link ng.$location $location} path with and trigger route redirection.
- *
- * If `redirectTo` is a function, it will be called with the following parameters:
- *
- * - `{Object.<string>}` - route parameters extracted from the current
- * `$location.path()` by applying the current route templateUrl.
- * - `{string}` - current `$location.path()`
- * - `{Object}` - current `$location.search()`
- *
- * The custom `redirectTo` function is expected to return a string which will be used
- * to update `$location.path()` and `$location.search()`.
- *
- * - `[reloadOnSearch=true]` - {boolean=} - reload route when only $location.search()
- * changes.
- *
- * If the option is set to `false` and url in the browser changes, then
- * `$routeUpdate` event is broadcasted on the root scope.
- *
- * - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive
- *
- * If the option is set to `true`, then the particular route can be matched without being
- * case sensitive
- *
- * @returns {Object} self
- *
- * @description
- * Adds a new route definition to the `$route` service.
- */
- this.when = function(path, route) {
- routes[path] = extend({reloadOnSearch: true, caseInsensitiveMatch: false}, route);
-
- // create redirection for trailing slashes
- if (path) {
- var redirectPath = (path[path.length-1] == '/')
- ? path.substr(0, path.length-1)
- : path +'/';
-
- routes[redirectPath] = {redirectTo: path};
- }
-
- return this;
- };
-
- /**
- * @ngdoc method
- * @name ng.$routeProvider#otherwise
- * @methodOf ng.$routeProvider
- *
- * @description
- * Sets route definition that will be used on route change when no other route definition
- * is matched.
- *
- * @param {Object} params Mapping information to be assigned to `$route.current`.
- * @returns {Object} self
- */
- this.otherwise = function(params) {
- this.when(null, params);
- return this;
- };
-
-
- this.$get = ['$rootScope', '$location', '$routeParams', '$q', '$injector', '$http', '$templateCache',
- function( $rootScope, $location, $routeParams, $q, $injector, $http, $templateCache) {
-
- /**
- * @ngdoc object
- * @name ng.$route
- * @requires $location
- * @requires $routeParams
- *
- * @property {Object} current Reference to the current route definition.
- * The route definition contains:
- *
- * - `controller`: The controller constructor as define in route definition.
- * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for
- * controller instantiation. The `locals` contain
- * the resolved values of the `resolve` map. Additionally the `locals` also contain:
- *
- * - `$scope` - The current route scope.
- * - `$template` - The current route template HTML.
- *
- * @property {Array.<Object>} routes Array of all configured routes.
- *
- * @description
- * Is used for deep-linking URLs to controllers and views (HTML partials).
- * It watches `$location.url()` and tries to map the path to an existing route definition.
- *
- * You can define routes through {@link ng.$routeProvider $routeProvider}'s API.
- *
- * The `$route` service is typically used in conjunction with {@link ng.directive:ngView ngView}
- * directive and the {@link ng.$routeParams $routeParams} service.
- *
- * @example
- This example shows how changing the URL hash causes the `$route` to match a route against the
- URL, and the `ngView` pulls in the partial.
-
- Note that this example is using {@link ng.directive:script inlined templates}
- to get it working on jsfiddle as well.
-
- <example module="ngView">
- <file name="index.html">
- <div ng-controller="MainCntl">
- Choose:
- <a href="Book/Moby">Moby</a> |
- <a href="Book/Moby/ch/1">Moby: Ch1</a> |
- <a href="Book/Gatsby">Gatsby</a> |
- <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
- <a href="Book/Scarlet">Scarlet Letter</a><br/>
-
- <div ng-view></div>
- <hr />
-
- <pre>$location.path() = {{$location.path()}}</pre>
- <pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre>
- <pre>$route.current.params = {{$route.current.params}}</pre>
- <pre>$route.current.scope.name = {{$route.current.scope.name}}</pre>
- <pre>$routeParams = {{$routeParams}}</pre>
- </div>
- </file>
-
- <file name="book.html">
- controller: {{name}}<br />
- Book Id: {{params.bookId}}<br />
- </file>
-
- <file name="chapter.html">
- controller: {{name}}<br />
- Book Id: {{params.bookId}}<br />
- Chapter Id: {{params.chapterId}}
- </file>
-
- <file name="script.js">
- angular.module('ngView', [], function($routeProvider, $locationProvider) {
- $routeProvider.when('/Book/:bookId', {
- templateUrl: 'book.html',
- controller: BookCntl,
- resolve: {
- // I will cause a 1 second delay
- delay: function($q, $timeout) {
- var delay = $q.defer();
- $timeout(delay.resolve, 1000);
- return delay.promise;
- }
- }
- });
- $routeProvider.when('/Book/:bookId/ch/:chapterId', {
- templateUrl: 'chapter.html',
- controller: ChapterCntl
- });
-
- // configure html5 to get links working on jsfiddle
- $locationProvider.html5Mode(true);
- });
-
- function MainCntl($scope, $route, $routeParams, $location) {
- $scope.$route = $route;
- $scope.$location = $location;
- $scope.$routeParams = $routeParams;
- }
-
- function BookCntl($scope, $routeParams) {
- $scope.name = "BookCntl";
- $scope.params = $routeParams;
- }
-
- function ChapterCntl($scope, $routeParams) {
- $scope.name = "ChapterCntl";
- $scope.params = $routeParams;
- }
- </file>
-
- <file name="scenario.js">
- it('should load and compile correct template', function() {
- element('a:contains("Moby: Ch1")').click();
- var content = element('.doc-example-live [ng-view]').text();
- expect(content).toMatch(/controller\: ChapterCntl/);
- expect(content).toMatch(/Book Id\: Moby/);
- expect(content).toMatch(/Chapter Id\: 1/);
-
- element('a:contains("Scarlet")').click();
- sleep(2); // promises are not part of scenario waiting
- content = element('.doc-example-live [ng-view]').text();
- expect(content).toMatch(/controller\: BookCntl/);
- expect(content).toMatch(/Book Id\: Scarlet/);
- });
- </file>
- </example>
- */
-
- /**
- * @ngdoc event
- * @name ng.$route#$routeChangeStart
- * @eventOf ng.$route
- * @eventType broadcast on root scope
- * @description
- * Broadcasted before a route change. At this point the route services starts
- * resolving all of the dependencies needed for the route change to occurs.
- * Typically this involves fetching the view template as well as any dependencies
- * defined in `resolve` route property. Once all of the dependencies are resolved
- * `$routeChangeSuccess` is fired.
- *
- * @param {Route} next Future route information.
- * @param {Route} current Current route information.
- */
-
- /**
- * @ngdoc event
- * @name ng.$route#$routeChangeSuccess
- * @eventOf ng.$route
- * @eventType broadcast on root scope
- * @description
- * Broadcasted after a route dependencies are resolved.
- * {@link ng.directive:ngView ngView} listens for the directive
- * to instantiate the controller and render the view.
- *
- * @param {Object} angularEvent Synthetic event object.
- * @param {Route} current Current route information.
- * @param {Route|Undefined} previous Previous route information, or undefined if current is first route entered.
- */
-
- /**
- * @ngdoc event
- * @name ng.$route#$routeChangeError
- * @eventOf ng.$route
- * @eventType broadcast on root scope
- * @description
- * Broadcasted if any of the resolve promises are rejected.
- *
- * @param {Route} current Current route information.
- * @param {Route} previous Previous route information.
- * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise.
- */
-
- /**
- * @ngdoc event
- * @name ng.$route#$routeUpdate
- * @eventOf ng.$route
- * @eventType broadcast on root scope
- * @description
- *
- * The `reloadOnSearch` property has been set to false, and we are reusing the same
- * instance of the Controller.
- */
-
- var forceReload = false,
- $route = {
- routes: routes,
-
- /**
- * @ngdoc method
- * @name ng.$route#reload
- * @methodOf ng.$route
- *
- * @description
- * Causes `$route` service to reload the current route even if
- * {@link ng.$location $location} hasn't changed.
- *
- * As a result of that, {@link ng.directive:ngView ngView}
- * creates new scope, reinstantiates the controller.
- */
- reload: function() {
- forceReload = true;
- $rootScope.$evalAsync(updateRoute);
- }
- };
-
- $rootScope.$on('$locationChangeSuccess', updateRoute);
-
- return $route;
-
- /////////////////////////////////////////////////////
-
- /**
- * @param on {string} current url
- * @param when {string} route when template to match the url against
- * @param whenProperties {Object} properties to define when's matching behavior
- * @return {?Object}
- */
- function switchRouteMatcher(on, when, whenProperties) {
- // TODO(i): this code is convoluted and inefficient, we should construct the route matching
- // regex only once and then reuse it
-
- // Escape regexp special characters.
- when = '^' + when.replace(/[-\/\\^$:*+?.()|[\]{}]/g, "\\$&") + '$';
-
- var regex = '',
- params = [],
- dst = {};
-
- var re = /\\([:*])(\w+)/g,
- paramMatch,
- lastMatchedIndex = 0;
-
- while ((paramMatch = re.exec(when)) !== null) {
- // Find each :param in `when` and replace it with a capturing group.
- // Append all other sections of when unchanged.
- regex += when.slice(lastMatchedIndex, paramMatch.index);
- switch(paramMatch[1]) {
- case ':':
- regex += '([^\\/]*)';
- break;
- case '*':
- regex += '(.*)';
- break;
- }
- params.push(paramMatch[2]);
- lastMatchedIndex = re.lastIndex;
- }
- // Append trailing path part.
- regex += when.substr(lastMatchedIndex);
-
- var match = on.match(new RegExp(regex, whenProperties.caseInsensitiveMatch ? 'i' : ''));
- if (match) {
- forEach(params, function(name, index) {
- dst[name] = match[index + 1];
- });
- }
- return match ? dst : null;
- }
-
- function updateRoute() {
- var next = parseRoute(),
- last = $route.current;
-
- if (next && last && next.$$route === last.$$route
- && equals(next.pathParams, last.pathParams) && !next.reloadOnSearch && !forceReload) {
- last.params = next.params;
- copy(last.params, $routeParams);
- $rootScope.$broadcast('$routeUpdate', last);
- } else if (next || last) {
- forceReload = false;
- $rootScope.$broadcast('$routeChangeStart', next, last);
- $route.current = next;
- if (next) {
- if (next.redirectTo) {
- if (isString(next.redirectTo)) {
- $location.path(interpolate(next.redirectTo, next.params)).search(next.params)
- .replace();
- } else {
- $location.url(next.redirectTo(next.pathParams, $location.path(), $location.search()))
- .replace();
- }
- }
- }
-
- $q.when(next).
- then(function() {
- if (next) {
- var locals = extend({}, next.resolve),
- template;
-
- forEach(locals, function(value, key) {
- locals[key] = isString(value) ? $injector.get(value) : $injector.invoke(value);
- });
-
- if (isDefined(template = next.template)) {
- if (isFunction(template)) {
- template = template(next.params);
- }
- } else if (isDefined(template = next.templateUrl)) {
- if (isFunction(template)) {
- template = template(next.params);
- }
- if (isDefined(template)) {
- next.loadedTemplateUrl = template;
- template = $http.get(template, {cache: $templateCache}).
- then(function(response) { return response.data; });
- }
- }
- if (isDefined(template)) {
- locals['$template'] = template;
- }
- return $q.all(locals);
- }
- }).
- // after route change
- then(function(locals) {
- if (next == $route.current) {
- if (next) {
- next.locals = locals;
- copy(next.params, $routeParams);
- }
- $rootScope.$broadcast('$routeChangeSuccess', next, last);
- }
- }, function(error) {
- if (next == $route.current) {
- $rootScope.$broadcast('$routeChangeError', next, last, error);
- }
- });
- }
- }
-
-
- /**
- * @returns the current active route, by matching it against the URL
- */
- function parseRoute() {
- // Match a route
- var params, match;
- forEach(routes, function(route, path) {
- if (!match && (params = switchRouteMatcher($location.path(), path, route))) {
- match = inherit(route, {
- params: extend({}, $location.search(), params),
- pathParams: params});
- match.$$route = route;
- }
- });
- // No route matched; fallback to "otherwise" route
- return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});
- }
-
- /**
- * @returns interpolation of the redirect path with the parameters
- */
- function interpolate(string, params) {
- var result = [];
- forEach((string||'').split(':'), function(segment, i) {
- if (i == 0) {
- result.push(segment);
- } else {
- var segmentMatch = segment.match(/(\w+)(.*)/);
- var key = segmentMatch[1];
- result.push(params[key]);
- result.push(segmentMatch[2] || '');
- delete params[key];
- }
- });
- return result.join('');
- }
- }];
-}
-
-/**
- * @ngdoc object
- * @name ng.$routeParams
- * @requires $route
- *
- * @description
- * Current set of route parameters. The route parameters are a combination of the
- * {@link ng.$location $location} `search()`, and `path()`. The `path` parameters
- * are extracted when the {@link ng.$route $route} path is matched.
- *
- * In case of parameter name collision, `path` params take precedence over `search` params.
- *
- * The service guarantees that the identity of the `$routeParams` object will remain unchanged
- * (but its properties will likely change) even when a route change occurs.
- *
- * @example
- * <pre>
- * // Given:
- * // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
- * // Route: /Chapter/:chapterId/Section/:sectionId
- * //
- * // Then
- * $routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
- * </pre>
- */
-function $RouteParamsProvider() {
- this.$get = valueFn({});
-}
-
-/**
* DESIGN NOTES
*
* The design decisions behind the scope are heavily favored for speed and memory consumption.
@@ -8337,6 +9358,7 @@
*/
function $RootScopeProvider(){
var TTL = 10;
+ var $rootScopeMinErr = minErr('$rootScope');
this.digestTtl = function(value) {
if (arguments.length) {
@@ -8438,13 +9460,11 @@
var Child,
child;
- if (isFunction(isolate)) {
- // TODO: remove at some point
- throw Error('API-CHANGE: Use $controller to instantiate controllers.');
- }
if (isolate) {
child = new Scope();
child.$root = this.$root;
+ // ensure that there is just one async queue per $rootScope and it's children
+ child.$$asyncQueue = this.$$asyncQueue;
} else {
Child = function() {}; // should be anonymous; This is so that when the minifier munges
// the name it does not become random set of chars. These will then show up as class
@@ -8801,7 +9821,7 @@
watch = watchers[length];
// Most common watches are on primitives, in which case we can short
// circuit it with === operator, only when === fails do we use .equals
- if ((value = watch.get(current)) !== (last = watch.last) &&
+ if (watch && (value = watch.get(current)) !== (last = watch.last) &&
!(watch.eq
? equals(value, last)
: (typeof value == 'number' && typeof last == 'number'
@@ -8837,8 +9857,9 @@
if(dirty && !(ttl--)) {
clearPhase();
- throw Error(TTL + ' $digest() iterations reached. Aborting!\n' +
- 'Watchers fired in the last 5 iterations: ' + toJson(watchLog));
+ throw $rootScopeMinErr('infdig',
+ '{0} $digest() iterations reached. Aborting!\nWatchers fired in the last 5 iterations: {1}',
+ TTL, toJson(watchLog));
}
} while (dirty || asyncQueue.length);
@@ -8854,6 +9875,9 @@
*
* @description
* Broadcasted when a scope and its children are being destroyed.
+ *
+ * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
+ * clean up DOM bindings before an element is removed from the DOM.
*/
/**
@@ -8875,6 +9899,9 @@
* Just before a scope is destroyed a `$destroy` event is broadcasted on this scope.
* Application code can register a `$destroy` event handler that will give it chance to
* perform any necessary cleanup.
+ *
+ * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
+ * clean up DOM bindings before an element is removed from the DOM.
*/
$destroy: function() {
// we can't destroy the root scope or a scope that has been already destroyed
@@ -9200,7 +10227,7 @@
function beginPhase(phase) {
if ($rootScope.$$phase) {
- throw Error($rootScope.$$phase + ' already in progress');
+ throw $rootScopeMinErr('inprog', '{0} already in progress', $rootScope.$$phase);
}
$rootScope.$$phase = phase;
@@ -9224,1328 +10251,1027 @@
}];
}
-/**
- * !!! This is an undocumented "private" service !!!
- *
- * @name ng.$sniffer
- * @requires $window
- * @requires $document
- *
- * @property {boolean} history Does the browser support html5 history api ?
- * @property {boolean} hashchange Does the browser support hashchange event ?
- * @property {boolean} transitions Does the browser support CSS transition events ?
- * @property {boolean} animations Does the browser support CSS animation events ?
- *
- * @description
- * This is very simple implementation of testing browser's features.
- */
-function $SnifferProvider() {
- this.$get = ['$window', '$document', function($window, $document) {
- var eventSupport = {},
- android = int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
- document = $document[0] || {},
- vendorPrefix,
- vendorRegex = /^(Moz|webkit|O|ms)(?=[A-Z])/,
- bodyStyle = document.body && document.body.style,
- transitions = false,
- animations = false,
- match;
+var $sceMinErr = minErr('$sce');
- if (bodyStyle) {
- for(var prop in bodyStyle) {
- if(match = vendorRegex.exec(prop)) {
- vendorPrefix = match[0];
- vendorPrefix = vendorPrefix.substr(0, 1).toUpperCase() + vendorPrefix.substr(1);
- break;
- }
- }
- transitions = !!(('transition' in bodyStyle) || (vendorPrefix + 'Transition' in bodyStyle));
- animations = !!(('animation' in bodyStyle) || (vendorPrefix + 'Animation' in bodyStyle));
- }
+var SCE_CONTEXTS = {
+ HTML: 'html',
+ CSS: 'css',
+ URL: 'url',
+ // RESOURCE_URL is a subtype of URL used in contexts where a privileged resource is sourced from a
+ // url. (e.g. ng-include, script src, templateUrl)
+ RESOURCE_URL: 'resourceUrl',
+ JS: 'js'
+};
- return {
- // Android has history.pushState, but it does not update location correctly
- // so let's not use the history API at all.
- // http://code.google.com/p/android/issues/detail?id=17471
- // https://github.com/angular/angular.js/issues/904
- history: !!($window.history && $window.history.pushState && !(android < 4)),
- hashchange: 'onhashchange' in $window &&
- // IE8 compatible mode lies
- (!document.documentMode || document.documentMode > 7),
- hasEvent: function(event) {
- // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
- // it. In particular the event is not fired when backspace or delete key are pressed or
- // when cut operation is performed.
- if (event == 'input' && msie == 9) return false;
-
- if (isUndefined(eventSupport[event])) {
- var divElm = document.createElement('div');
- eventSupport[event] = 'on' + event in divElm;
- }
-
- return eventSupport[event];
- },
- csp: document.securityPolicy ? document.securityPolicy.isActive : false,
- vendorPrefix: vendorPrefix,
- transitions : transitions,
- animations : animations
- };
- }];
-}
-
/**
- * @ngdoc object
- * @name ng.$window
+ * @ngdoc service
+ * @name ng.$sceDelegate
+ * @function
*
* @description
- * A reference to the browser's `window` object. While `window`
- * is globally available in JavaScript, it causes testability problems, because
- * it is a global variable. In angular we always refer to it through the
- * `$window` service, so it may be overridden, removed or mocked for testing.
*
- * All expressions are evaluated with respect to current scope so they don't
- * suffer from window globality.
+ * `$sceDelegate` is a service that is used by the `$sce` service to provide {@link ng.$sce Strict
+ * Contextual Escaping (SCE)} services to AngularJS.
*
- * @example
- <doc:example>
- <doc:source>
- <script>
- function Ctrl($scope, $window) {
- $scope.$window = $window;
- $scope.greeting = 'Hello, World!';
- }
- </script>
- <div ng-controller="Ctrl">
- <input type="text" ng-model="greeting" />
- <button ng-click="$window.alert(greeting)">ALERT</button>
- </div>
- </doc:source>
- <doc:scenario>
- it('should display the greeting in the input box', function() {
- input('greeting').enter('Hello, E2E Tests');
- // If we click the button it will block the test runner
- // element(':button').click();
- });
- </doc:scenario>
- </doc:example>
+ * Typically, you would configure or override the {@link ng.$sceDelegate $sceDelegate} instead of
+ * the `$sce` service to customize the way Strict Contextual Escaping works in AngularJS. This is
+ * because, while the `$sce` provides numerous shorthand methods, etc., you really only need to
+ * override 3 core functions (`trustAs`, `getTrusted` and `valueOf`) to replace the way things
+ * work because `$sce` delegates to `$sceDelegate` for these operations.
+ *
+ * Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} to configure this service.
+ *
+ * The default instance of `$sceDelegate` should work out of the box with little pain. While you
+ * can override it completely to change the behavior of `$sce`, the common case would
+ * involve configuring the {@link ng.$sceDelegateProvider $sceDelegateProvider} instead by setting
+ * your own whitelists and blacklists for trusting URLs used for loading AngularJS resources such as
+ * templates. Refer {@link ng.$sceDelegateProvider#resourceUrlWhitelist
+ * $sceDelegateProvider.resourceUrlWhitelist} and {@link
+ * ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}
*/
-function $WindowProvider(){
- this.$get = valueFn(window);
-}
/**
- * Parse headers into key value object
+ * @ngdoc object
+ * @name ng.$sceDelegateProvider
+ * @description
*
- * @param {string} headers Raw headers as a string
- * @returns {Object} Parsed headers as key value object
+ * The $sceDelegateProvider provider allows developers to configure the {@link ng.$sceDelegate
+ * $sceDelegate} service. This allows one to get/set the whitelists and blacklists used to ensure
+ * that URLs used for sourcing Angular templates are safe. Refer {@link
+ * ng.$sceDelegateProvider#resourceUrlWhitelist $sceDelegateProvider.resourceUrlWhitelist} and
+ * {@link ng.$sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider.resourceUrlBlacklist}
+ *
+ * Read more about {@link ng.$sce Strict Contextual Escaping (SCE)}.
*/
-function parseHeaders(headers) {
- var parsed = {}, key, val, i;
- if (!headers) return parsed;
+function $SceDelegateProvider() {
+ this.SCE_CONTEXTS = SCE_CONTEXTS;
- forEach(headers.split('\n'), function(line) {
- i = line.indexOf(':');
- key = lowercase(trim(line.substr(0, i)));
- val = trim(line.substr(i + 1));
+ // Resource URLs can also be trusted by policy.
+ var resourceUrlWhitelist = ['self'],
+ resourceUrlBlacklist = [];
- if (key) {
- if (parsed[key]) {
- parsed[key] += ', ' + val;
- } else {
- parsed[key] = val;
- }
+ /**
+ * @ngdoc function
+ * @name ng.sceDelegateProvider#resourceUrlWhitelist
+ * @methodOf ng.$sceDelegateProvider
+ * @function
+ *
+ * @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value
+ * provided. This must be an array.
+ *
+ * Each element of this array must either be a regex or the special string `'self'`.
+ *
+ * When a regex is used, it is matched against the normalized / absolute URL of the resource
+ * being tested.
+ *
+ * The **special string** `'self'` can be used to match against all URLs of the same domain as the
+ * application document with the same protocol (allows sourcing https resources from http documents.)
+ *
+ * Please note that **an empty whitelist array will block all URLs**!
+ *
+ * @return {Array} the currently set whitelist array.
+ *
+ * The **default value** when no whitelist has been explicitly set is `['self']`.
+ *
+ * @description
+ * Sets/Gets the whitelist of trusted resource URLs.
+ */
+ this.resourceUrlWhitelist = function (value) {
+ if (arguments.length) {
+ resourceUrlWhitelist = value;
}
- });
+ return resourceUrlWhitelist;
+ };
- return parsed;
-}
+ /**
+ * @ngdoc function
+ * @name ng.sceDelegateProvider#resourceUrlBlacklist
+ * @methodOf ng.$sceDelegateProvider
+ * @function
+ *
+ * @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value
+ * provided. This must be an array.
+ *
+ * Each element of this array must either be a regex or the special string `'self'` (see
+ * `resourceUrlWhitelist` for meaning - it's only really useful there.)
+ *
+ * When a regex is used, it is matched against the normalized / absolute URL of the resource
+ * being tested.
+ *
+ * The typical usage for the blacklist is to **block [open redirects](http://cwe.mitre.org/data/definitions/601.html)**
+ * served by your domain as these would otherwise be trusted but actually return content from the redirected
+ * domain.
+ *
+ * Finally, **the blacklist overrides the whitelist** and has the final say.
+ *
+ * @return {Array} the currently set blacklist array.
+ *
+ * The **default value** when no whitelist has been explicitly set is the empty array (i.e. there is
+ * no blacklist.)
+ *
+ * @description
+ * Sets/Gets the blacklist of trusted resource URLs.
+ */
+ this.resourceUrlBlacklist = function (value) {
+ if (arguments.length) {
+ resourceUrlBlacklist = value;
+ }
+ return resourceUrlBlacklist;
+ };
-var IS_SAME_DOMAIN_URL_MATCH = /^(([^:]+):)?\/\/(\w+:{0,1}\w*@)?([\w\.-]*)?(:([0-9]+))?(.*)$/;
+ // Helper functions for matching resource urls by policy.
+ function isCompatibleProtocol(documentProtocol, resourceProtocol) {
+ return ((documentProtocol === resourceProtocol) ||
+ (documentProtocol === "http:" && resourceProtocol === "https:"));
+ }
+ this.$get = ['$log', '$document', '$injector', '$$urlUtils', function(
+ $log, $document, $injector, $$urlUtils) {
-/**
- * Parse a request and location URL and determine whether this is a same-domain request.
- *
- * @param {string} requestUrl The url of the request.
- * @param {string} locationUrl The current browser location url.
- * @returns {boolean} Whether the request is for the same domain.
- */
-function isSameDomain(requestUrl, locationUrl) {
- var match = IS_SAME_DOMAIN_URL_MATCH.exec(requestUrl);
- // if requestUrl is relative, the regex does not match.
- if (match == null) return true;
-
- var domain1 = {
- protocol: match[2],
- host: match[4],
- port: int(match[6]) || DEFAULT_PORTS[match[2]] || null,
- // IE8 sets unmatched groups to '' instead of undefined.
- relativeProtocol: match[2] === undefined || match[2] === ''
+ var htmlSanitizer = function htmlSanitizer(html) {
+ throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
};
- match = SERVER_MATCH.exec(locationUrl);
- var domain2 = {
- protocol: match[1],
- host: match[3],
- port: int(match[5]) || DEFAULT_PORTS[match[1]] || null
- };
+ if ($injector.has('$sanitize')) {
+ htmlSanitizer = $injector.get('$sanitize');
+ }
- return (domain1.protocol == domain2.protocol || domain1.relativeProtocol) &&
- domain1.host == domain2.host &&
- (domain1.port == domain2.port || (domain1.relativeProtocol &&
- domain2.port == DEFAULT_PORTS[domain2.protocol]));
-}
+ function matchUrl(matcher, parsedUrl) {
+ if (matcher === 'self') {
+ return $$urlUtils.isSameOrigin(parsedUrl);
+ } else {
+ return !!parsedUrl.href.match(matcher);
+ }
+ }
-/**
- * Returns a function that provides access to parsed headers.
- *
- * Headers are lazy parsed when first requested.
- * @see parseHeaders
- *
- * @param {(string|Object)} headers Headers to provide access to.
- * @returns {function(string=)} Returns a getter function which if called with:
- *
- * - if called with single an argument returns a single header value or null
- * - if called with no arguments returns an object containing all headers.
- */
-function headersGetter(headers) {
- var headersObj = isObject(headers) ? headers : undefined;
+ function isResourceUrlAllowedByPolicy(url) {
+ var parsedUrl = $$urlUtils.resolve(url.toString(), true);
+ var i, n, allowed = false;
+ // Ensure that at least one item from the whitelist allows this url.
+ for (i = 0, n = resourceUrlWhitelist.length; i < n; i++) {
+ if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) {
+ allowed = true;
+ break;
+ }
+ }
+ if (allowed) {
+ // Ensure that no item from the blacklist blocked this url.
+ for (i = 0, n = resourceUrlBlacklist.length; i < n; i++) {
+ if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) {
+ allowed = false;
+ break;
+ }
+ }
+ }
+ return allowed;
+ }
- return function(name) {
- if (!headersObj) headersObj = parseHeaders(headers);
+ function generateHolderType(base) {
+ var holderType = function TrustedValueHolderType(trustedValue) {
+ this.$$unwrapTrustedValue = function() {
+ return trustedValue;
+ };
+ };
+ if (base) {
+ holderType.prototype = new base();
+ }
+ holderType.prototype.valueOf = function sceValueOf() {
+ return this.$$unwrapTrustedValue();
+ }
+ holderType.prototype.toString = function sceToString() {
+ return this.$$unwrapTrustedValue().toString();
+ }
+ return holderType;
+ }
- if (name) {
- return headersObj[lowercase(name)] || null;
+ var trustedValueHolderBase = generateHolderType(),
+ byType = {};
+
+ byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase);
+ byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase);
+ byType[SCE_CONTEXTS.URL] = generateHolderType(trustedValueHolderBase);
+ byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase);
+ byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(byType[SCE_CONTEXTS.URL]);
+
+ /**
+ * @ngdoc method
+ * @name ng.$sceDelegate#trustAs
+ * @methodOf ng.$sceDelegate
+ *
+ * @description
+ * Returns an object that is trusted by angular for use in specified strict
+ * contextual escaping contexts (such as ng-html-bind-unsafe, ng-include, any src
+ * attribute interpolation, any dom event binding attribute interpolation
+ * such as for onclick, etc.) that uses the provided value.
+ * See {@link ng.$sce $sce} for enabling strict contextual escaping.
+ *
+ * @param {string} type The kind of context in which this value is safe for use. e.g. url,
+ * resourceUrl, html, js and css.
+ * @param {*} value The value that that should be considered trusted/safe.
+ * @returns {*} A value that can be used to stand in for the provided `value` in places
+ * where Angular expects a $sce.trustAs() return value.
+ */
+ function trustAs(type, trustedValue) {
+ var constructor = (byType.hasOwnProperty(type) ? byType[type] : null);
+ if (!constructor) {
+ throw $sceMinErr('icontext', 'Attempted to trust a value in invalid context. Context: {0}; Value: {1}',
+ type, trustedValue);
+ }
+ if (trustedValue === null || trustedValue === undefined || trustedValue === '') {
+ return trustedValue;
+ }
+ // All the current contexts in SCE_CONTEXTS happen to be strings. In order to avoid trusting
+ // mutable objects, we ensure here that the value passed in is actually a string.
+ if (typeof trustedValue !== 'string') {
+ throw $sceMinErr('itype',
+ 'Attempted to trust a non-string value in a content requiring a string: Context: {0}',
+ type);
+ }
+ return new constructor(trustedValue);
}
- return headersObj;
- };
+ /**
+ * @ngdoc method
+ * @name ng.$sceDelegate#valueOf
+ * @methodOf ng.$sceDelegate
+ *
+ * @description
+ * If the passed parameter had been returned by a prior call to {@link ng.$sceDelegate#trustAs
+ * `$sceDelegate.trustAs`}, returns the value that had been passed to {@link
+ * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}.
+ *
+ * If the passed parameter is not a value that had been returned by {@link
+ * ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}, returns it as-is.
+ *
+ * @param {*} value The result of a prior {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}
+ * call or anything else.
+ * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#trustAs
+ * `$sceDelegate.trustAs`} if `value` is the result of such a call. Otherwise, returns `value`
+ * unchanged.
+ */
+ function valueOf(maybeTrusted) {
+ if (maybeTrusted instanceof trustedValueHolderBase) {
+ return maybeTrusted.$$unwrapTrustedValue();
+ } else {
+ return maybeTrusted;
+ }
+ }
+
+ /**
+ * @ngdoc method
+ * @name ng.$sceDelegate#getTrusted
+ * @methodOf ng.$sceDelegate
+ *
+ * @description
+ * Takes the result of a {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`} call and returns the
+ * originally supplied value if the queried context type is a supertype of the created type. If
+ * this condition isn't satisfied, throws an exception.
+ *
+ * @param {string} type The kind of context in which this value is to be used.
+ * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#trustAs
+ * `$sceDelegate.trustAs`} call.
+ * @returns {*} The value the was originally provided to {@link ng.$sceDelegate#trustAs
+ * `$sceDelegate.trustAs`} if valid in this context. Otherwise, throws an exception.
+ */
+ function getTrusted(type, maybeTrusted) {
+ if (maybeTrusted === null || maybeTrusted === undefined || maybeTrusted === '') {
+ return maybeTrusted;
+ }
+ var constructor = (byType.hasOwnProperty(type) ? byType[type] : null);
+ if (constructor && maybeTrusted instanceof constructor) {
+ return maybeTrusted.$$unwrapTrustedValue();
+ }
+ // If we get here, then we may only take one of two actions.
+ // 1. sanitize the value for the requested type, or
+ // 2. throw an exception.
+ if (type === SCE_CONTEXTS.RESOURCE_URL) {
+ if (isResourceUrlAllowedByPolicy(maybeTrusted)) {
+ return maybeTrusted;
+ } else {
+ throw $sceMinErr('insecurl',
+ 'Blocked loading resource from url not allowed by $sceDelegate policy. URL: {0}', maybeTrusted.toString());
+ }
+ } else if (type === SCE_CONTEXTS.HTML) {
+ return htmlSanitizer(maybeTrusted);
+ }
+ throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
+ }
+
+ return { trustAs: trustAs,
+ getTrusted: getTrusted,
+ valueOf: valueOf };
+ }];
}
/**
- * Chain all given functions
+ * @ngdoc object
+ * @name ng.$sceProvider
+ * @description
*
- * This function is used for both request and response transforming
+ * The $sceProvider provider allows developers to configure the {@link ng.$sce $sce} service.
+ * - enable/disable Strict Contextual Escaping (SCE) in a module
+ * - override the default implementation with a custom delegate
*
- * @param {*} data Data to transform.
- * @param {function(string=)} headers Http headers getter fn.
- * @param {(function|Array.<function>)} fns Function or an array of functions.
- * @returns {*} Transformed data.
+ * Read more about {@link ng.$sce Strict Contextual Escaping (SCE)}.
*/
-function transformData(data, headers, fns) {
- if (isFunction(fns))
- return fns(data, headers);
- forEach(fns, function(fn) {
- data = fn(data, headers);
- });
+/**
+ * @ngdoc service
+ * @name ng.$sce
+ * @function
+ *
+ * @description
+ *
+ * `$sce` is a service that provides Strict Contextual Escaping services to AngularJS.
+ *
+ * # Strict Contextual Escaping
+ *
+ * Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain
+ * contexts to result in a value that is marked as safe to use for that context One example of such
+ * a context is binding arbitrary html controlled by the user via `ng-bind-html`. We refer to these
+ * contexts as privileged or SCE contexts.
+ *
+ * As of version 1.2, Angular ships with SCE enabled by default.
+ *
+ * Note: When enabled (the default), IE8 in quirks mode is not supported. In this mode, IE8 allows
+ * one to execute arbitrary javascript by the use of the expression() syntax. Refer
+ * <http://blogs.msdn.com/b/ie/archive/2008/10/16/ending-expressions.aspx> to learn more about them.
+ * You can ensure your document is in standards mode and not quirks mode by adding `<!doctype html>`
+ * to the top of your HTML document.
+ *
+ * SCE assists in writing code in way that (a) is secure by default and (b) makes auditing for
+ * security vulnerabilities such as XSS, clickjacking, etc. a lot easier.
+ *
+ * Here's an example of a binding in a privileged context:
+ *
+ * <pre class="prettyprint">
+ * <input ng-model="userHtml">
+ * <div ng-bind-html="{{userHtml}}">
+ * </pre>
+ *
+ * Notice that `ng-bind-html` is bound to `{{userHtml}}` controlled by the user. With SCE
+ * disabled, this application allows the user to render arbitrary HTML into the DIV.
+ * In a more realistic example, one may be rendering user comments, blog articles, etc. via
+ * bindings. (HTML is just one example of a context where rendering user controlled input creates
+ * security vulnerabilities.)
+ *
+ * For the case of HTML, you might use a library, either on the client side, or on the server side,
+ * to sanitize unsafe HTML before binding to the value and rendering it in the document.
+ *
+ * How would you ensure that every place that used these types of bindings was bound to a value that
+ * was sanitized by your library (or returned as safe for rendering by your server?) How can you
+ * ensure that you didn't accidentally delete the line that sanitized the value, or renamed some
+ * properties/fields and forgot to update the binding to the sanitized value?
+ *
+ * To be secure by default, you want to ensure that any such bindings are disallowed unless you can
+ * determine that something explicitly says it's safe to use a value for binding in that
+ * context. You can then audit your code (a simple grep would do) to ensure that this is only done
+ * for those values that you can easily tell are safe - because they were received from your server,
+ * sanitized by your library, etc. You can organize your codebase to help with this - perhaps
+ * allowing only the files in a specific directory to do this. Ensuring that the internal API
+ * exposed by that code doesn't markup arbitrary values as safe then becomes a more manageable task.
+ *
+ * In the case of AngularJS' SCE service, one uses {@link ng.$sce#trustAs $sce.trustAs} (and shorthand
+ * methods such as {@link ng.$sce#trustAsHtml $sce.trustAsHtml}, etc.) to obtain values that will be
+ * accepted by SCE / privileged contexts.
+ *
+ *
+ * ## How does it work?
+ *
+ * In privileged contexts, directives and code will bind to the result of {@link ng.$sce#getTrusted
+ * $sce.getTrusted(context, value)} rather than to the value directly. Directives use {@link
+ * ng.$sce#parse $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs the
+ * {@link ng.$sce#getTrusted $sce.getTrusted} behind the scenes on non-constant literals.
+ *
+ * As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link
+ * ng.$sce#parseHtml $sce.parseAsHtml(binding expression)}. Here's the actual code (slightly
+ * simplified):
+ *
+ * <pre class="prettyprint">
+ * var ngBindHtmlDirective = ['$sce', function($sce) {
+ * return function(scope, element, attr) {
+ * scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
+ * element.html(value || '');
+ * });
+ * };
+ * }];
+ * </pre>
+ *
+ * ## Impact on loading templates
+ *
+ * This applies both to the {@link ng.directive:ngInclude `ng-include`} directive as well as
+ * `templateUrl`'s specified by {@link guide/directive directives}.
+ *
+ * By default, Angular only loads templates from the same domain and protocol as the application
+ * document. This is done by calling {@link ng.$sce#getTrustedResourceUrl
+ * $sce.getTrustedResourceUrl} on the template URL. To load templates from other domains and/or
+ * protocols, you may either either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist
+ * them} or {@link ng.$sce#trustAsResourceUrl wrap it} into a trusted value.
+ *
+ * *Please note*:
+ * The browser's
+ * {@link https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLH…
+ * Same Origin Policy} and {@link http://www.w3.org/TR/cors/ Cross-Origin Resource Sharing (CORS)}
+ * policy apply in addition to this and may further restrict whether the template is successfully
+ * loaded. This means that without the right CORS policy, loading templates from a different domain
+ * won't work on all browsers. Also, loading templates from `file://` URL does not work on some
+ * browsers.
+ *
+ * ## This feels like too much overhead for the developer?
+ *
+ * It's important to remember that SCE only applies to interpolation expressions.
+ *
+ * If your expressions are constant literals, they're automatically trusted and you don't need to
+ * call `$sce.trustAs` on them. (e.g.
+ * `<div ng-html-bind-unsafe="'<b>implicitly trusted</b>'"></div>`) just works.
+ *
+ * Additionally, `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them
+ * through {@link ng.$sce#getTrusted $sce.getTrusted}. SCE doesn't play a role here.
+ *
+ * The included {@link ng.$sceDelegate $sceDelegate} comes with sane defaults to allow you to load
+ * templates in `ng-include` from your application's domain without having to even know about SCE.
+ * It blocks loading templates from other domains or loading templates over http from an https
+ * served document. You can change these by setting your own custom {@link
+ * ng.$sceDelegateProvider#resourceUrlWhitelist whitelists} and {@link
+ * ng.$sceDelegateProvider#resourceUrlBlacklist blacklists} for matching such URLs.
+ *
+ * This significantly reduces the overhead. It is far easier to pay the small overhead and have an
+ * application that's secure and can be audited to verify that with much more ease than bolting
+ * security onto an application later.
+ *
+ * ## What trusted context types are supported?<a name="contexts"></a>
+ *
+ * | Context | Notes |
+ * |=====================|================|
+ * | `$sce.HTML` | For HTML that's safe to source into the application. The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. |
+ * | `$sce.CSS` | For CSS that's safe to source into the application. Currently unused. Feel free to use it in your own directives. |
+ * | `$sce.URL` | For URLs that are safe to follow as links. Currently unused (`<a href=` and `<img src=` sanitize their urls and don't consititute an SCE context. |
+ * | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contens are also safe to include in your application. Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG` (e.g. `IFRAME`, `OBJECT`, etc.) <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` does and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` are required. |
+ * | `$sce.JS` | For JavaScript that is safe to execute in your application's context. Currently unused. Feel free to use it in your own directives. |
+ *
+ * ## Show me an example.
+ *
+ *
+ *
+ * @example
+ <example module="mySceApp">
+ <file name="index.html">
+ <div ng-controller="myAppController as myCtrl">
+ <i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br>
+ <b>User comments</b><br>
+ By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when $sanitize is available. If $sanitize isn't available, this results in an error instead of an exploit.
+ <div class="well">
+ <div ng-repeat="userComment in myCtrl.userComments">
+ <b>{{userComment.name}}</b>:
+ <span ng-bind-html="userComment.htmlComment" class="htmlComment"></span>
+ <br>
+ </div>
+ </div>
+ </div>
+ </file>
- return data;
-}
+ <file name="script.js">
+ var mySceApp = angular.module('mySceApp', ['ngSanitize']);
+ mySceApp.controller("myAppController", function myAppController($http, $templateCache, $sce) {
+ var self = this;
+ $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) {
+ self.userComments = userComments;
+ });
+ self.explicitlyTrustedHtml = $sce.trustAsHtml(
+ '<span onmouseover="this.textContent="Explicitly trusted HTML bypasses ' +
+ 'sanitization."">Hover over this text.</span>');
+ });
+ </file>
-function isSuccess(status) {
- return 200 <= status && status < 300;
-}
-
-
-function $HttpProvider() {
- var JSON_START = /^\s*(\[|\{[^\{])/,
- JSON_END = /[\}\]]\s*$/,
- PROTECTION_PREFIX = /^\)\]\}',?\n/,
- CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': 'application/json;charset=utf-8'};
-
- var defaults = this.defaults = {
- // transform incoming response data
- transformResponse: [function(data) {
- if (isString(data)) {
- // strip json vulnerability protection prefix
- data = data.replace(PROTECTION_PREFIX, '');
- if (JSON_START.test(data) && JSON_END.test(data))
- data = fromJson(data, true);
+ <file name="test_data.json">
+ [
+ { "name": "Alice",
+ "htmlComment": "<span onmouseover='this.textContent=\"PWN3D!\"'>Is <i>anyone</i> reading this?</span>"
+ },
+ { "name": "Bob",
+ "htmlComment": "<i>Yes!</i> Am I the only other one?"
}
- return data;
- }],
+ ]
+ </file>
- // transform outgoing request data
- transformRequest: [function(d) {
- return isObject(d) && !isFile(d) ? toJson(d) : d;
- }],
+ <file name="scenario.js">
+ describe('SCE doc demo', function() {
+ it('should sanitize untrusted values', function() {
+ expect(element('.htmlComment').html()).toBe('<span>Is <i>anyone</i> reading this?</span>');
+ });
+ it('should NOT sanitize explicitly trusted values', function() {
+ expect(element('#explicitlyTrustedHtml').html()).toBe(
+ '<span onmouseover="this.textContent="Explicitly trusted HTML bypasses ' +
+ 'sanitization."">Hover over this text.</span>');
+ });
+ });
+ </file>
+ </example>
+ *
+ *
+ *
+ * ## Can I disable SCE completely?
+ *
+ * Yes, you can. However, this is strongly discouraged. SCE gives you a lot of security benefits
+ * for little coding overhead. It will be much harder to take an SCE disabled application and
+ * either secure it on your own or enable SCE at a later stage. It might make sense to disable SCE
+ * for cases where you have a lot of existing code that was written before SCE was introduced and
+ * you're migrating them a module at a time.
+ *
+ * That said, here's how you can completely disable SCE:
+ *
+ * <pre class="prettyprint">
+ * angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
+ * // Completely disable SCE. For demonstration purposes only!
+ * // Do not use in new projects.
+ * $sceProvider.enabled(false);
+ * });
+ * </pre>
+ *
+ */
- // default headers
- headers: {
- common: {
- 'Accept': 'application/json, text/plain, */*'
- },
- post: CONTENT_TYPE_APPLICATION_JSON,
- put: CONTENT_TYPE_APPLICATION_JSON,
- patch: CONTENT_TYPE_APPLICATION_JSON
- },
+function $SceProvider() {
+ var enabled = true;
- xsrfCookieName: 'XSRF-TOKEN',
- xsrfHeaderName: 'X-XSRF-TOKEN'
+ /**
+ * @ngdoc function
+ * @name ng.sceProvider#enabled
+ * @methodOf ng.$sceProvider
+ * @function
+ *
+ * @param {boolean=} value If provided, then enables/disables SCE.
+ * @return {boolean} true if SCE is enabled, false otherwise.
+ *
+ * @description
+ * Enables/disables SCE and returns the current value.
+ */
+ this.enabled = function (value) {
+ if (arguments.length) {
+ enabled = !!value;
+ }
+ return enabled;
};
- /**
- * Are order by request. I.E. they are applied in the same order as
- * array on request, but revers order on response.
+
+ /* Design notes on the default implementation for SCE.
+ *
+ * The API contract for the SCE delegate
+ * -------------------------------------
+ * The SCE delegate object must provide the following 3 methods:
+ *
+ * - trustAs(contextEnum, value)
+ * This method is used to tell the SCE service that the provided value is OK to use in the
+ * contexts specified by contextEnum. It must return an object that will be accepted by
+ * getTrusted() for a compatible contextEnum and return this value.
+ *
+ * - valueOf(value)
+ * For values that were not produced by trustAs(), return them as is. For values that were
+ * produced by trustAs(), return the corresponding input value to trustAs. Basically, if
+ * trustAs is wrapping the given values into some type, this operation unwraps it when given
+ * such a value.
+ *
+ * - getTrusted(contextEnum, value)
+ * This function should return the a value that is safe to use in the context specified by
+ * contextEnum or throw and exception otherwise.
+ *
+ * NOTE: This contract deliberately does NOT state that values returned by trustAs() must be opaque
+ * or wrapped in some holder object. That happens to be an implementation detail. For instance,
+ * an implementation could maintain a registry of all trusted objects by context. In such a case,
+ * trustAs() would return the same object that was passed in. getTrusted() would return the same
+ * object passed in if it was found in the registry under a compatible context or throw an
+ * exception otherwise. An implementation might only wrap values some of the time based on
+ * some criteria. getTrusted() might return a value and not throw an exception for special
+ * constants or objects even if not wrapped. All such implementations fulfill this contract.
+ *
+ *
+ * A note on the inheritance model for SCE contexts
+ * ------------------------------------------------
+ * I've used inheritance and made RESOURCE_URL wrapped types a subtype of URL wrapped types. This
+ * is purely an implementation details.
+ *
+ * The contract is simply this:
+ *
+ * getTrusted($sce.RESOURCE_URL, value) succeeding implies that getTrusted($sce.URL, value)
+ * will also succeed.
+ *
+ * Inheritance happens to capture this in a natural way. In some future, we
+ * may not use inheritance anymore. That is OK because no code outside of
+ * sce.js and sceSpecs.js would need to be aware of this detail.
*/
- var interceptorFactories = this.interceptors = [];
- /**
- * For historical reasons, response interceptors ordered by the order in which
- * they are applied to response. (This is in revers to interceptorFactories)
- */
- var responseInterceptorFactories = this.responseInterceptors = [];
- this.$get = ['$httpBackend', '$browser', '$cacheFactory', '$rootScope', '$q', '$injector',
- function($httpBackend, $browser, $cacheFactory, $rootScope, $q, $injector) {
+ this.$get = ['$parse', '$document', '$sceDelegate', function(
+ $parse, $document, $sceDelegate) {
+ // Prereq: Ensure that we're not running in IE8 quirks mode. In that mode, IE allows
+ // the "expression(javascript expression)" syntax which is insecure.
+ if (enabled && msie) {
+ var documentMode = $document[0].documentMode;
+ if (documentMode !== undefined && documentMode < 8) {
+ throw $sceMinErr('iequirks',
+ 'Strict Contextual Escaping does not support Internet Explorer version < 9 in quirks ' +
+ 'mode. You can fix this by adding the text <!doctype html> to the top of your HTML ' +
+ 'document. See http://docs.angularjs.org/api/ng.$sce for more information.');
+ }
+ }
- var defaultCache = $cacheFactory('$http');
+ var sce = copy(SCE_CONTEXTS);
/**
- * Interceptors stored in reverse order. Inner interceptors before outer interceptors.
- * The reversal is needed so that we can build up the interception chain around the
- * server request.
+ * @ngdoc function
+ * @name ng.sce#isEnabled
+ * @methodOf ng.$sce
+ * @function
+ *
+ * @return {Boolean} true if SCE is enabled, false otherwise. If you want to set the value, you
+ * have to do it at module config time on {@link ng.$sceProvider $sceProvider}.
+ *
+ * @description
+ * Returns a boolean indicating if SCE is enabled.
*/
- var reversedInterceptors = [];
+ sce.isEnabled = function () {
+ return enabled;
+ };
+ sce.trustAs = $sceDelegate.trustAs;
+ sce.getTrusted = $sceDelegate.getTrusted;
+ sce.valueOf = $sceDelegate.valueOf;
- forEach(interceptorFactories, function(interceptorFactory) {
- reversedInterceptors.unshift(isString(interceptorFactory)
- ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory));
- });
+ if (!enabled) {
+ sce.trustAs = sce.getTrusted = function(type, value) { return value; },
+ sce.valueOf = identity
+ }
- forEach(responseInterceptorFactories, function(interceptorFactory, index) {
- var responseFn = isString(interceptorFactory)
- ? $injector.get(interceptorFactory)
- : $injector.invoke(interceptorFactory);
-
- /**
- * Response interceptors go before "around" interceptors (no real reason, just
- * had to pick one.) But they are already revesed, so we can't use unshift, hence
- * the splice.
- */
- reversedInterceptors.splice(index, 0, {
- response: function(response) {
- return responseFn($q.when(response));
- },
- responseError: function(response) {
- return responseFn($q.reject(response));
- }
- });
- });
-
-
/**
- * @ngdoc function
- * @name ng.$http
- * @requires $httpBackend
- * @requires $browser
- * @requires $cacheFactory
- * @requires $rootScope
- * @requires $q
- * @requires $injector
+ * @ngdoc method
+ * @name ng.$sce#parse
+ * @methodOf ng.$sce
*
* @description
- * The `$http` service is a core Angular service that facilitates communication with the remote
- * HTTP servers via the browser's {@link https://developer.mozilla.org/en/xmlhttprequest
- * XMLHttpRequest} object or via {@link http://en.wikipedia.org/wiki/JSONP JSONP}.
+ * Converts Angular {@link guide/expression expression} into a function. This is like {@link
+ * ng.$parse $parse} and is identical when the expression is a literal constant. Otherwise, it
+ * wraps the expression in a call to {@link ng.$sce#getTrusted $sce.getTrusted(*type*,
+ * *result*)}
*
- * For unit testing applications that use `$http` service, see
- * {@link ngMock.$httpBackend $httpBackend mock}.
+ * @param {string} type The kind of SCE context in which this result will be used.
+ * @param {string} expression String expression to compile.
+ * @returns {function(context, locals)} a function which represents the compiled expression:
*
- * For a higher level of abstraction, please check out the {@link ngResource.$resource
- * $resource} service.
+ * * `context` – `{object}` – an object against which any expressions embedded in the strings
+ * are evaluated against (typically a scope object).
+ * * `locals` – `{object=}` – local variables context object, useful for overriding values in
+ * `context`.
+ */
+ sce.parseAs = function sceParseAs(type, expr) {
+ var parsed = $parse(expr);
+ if (parsed.literal && parsed.constant) {
+ return parsed;
+ } else {
+ return function sceParseAsTrusted(self, locals) {
+ return sce.getTrusted(type, parsed(self, locals));
+ }
+ }
+ };
+
+ /**
+ * @ngdoc method
+ * @name ng.$sce#trustAs
+ * @methodOf ng.$sce
*
- * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by
- * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage
- * it is important to familiarize yourself with these APIs and the guarantees they provide.
+ * @description
+ * Delegates to {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs`}. As such, returns an object
+ * that is trusted by angular for use in specified strict contextual escaping contexts (such as
+ * ng-html-bind-unsafe, ng-include, any src attribute interpolation, any dom event binding
+ * attribute interpolation such as for onclick, etc.) that uses the provided value. See *
+ * {@link ng.$sce $sce} for enabling strict contextual escaping.
*
+ * @param {string} type The kind of context in which this value is safe for use. e.g. url,
+ * resource_url, html, js and css.
+ * @param {*} value The value that that should be considered trusted/safe.
+ * @returns {*} A value that can be used to stand in for the provided `value` in places
+ * where Angular expects a $sce.trustAs() return value.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ng.$sce#trustAsHtml
+ * @methodOf ng.$sce
*
- * # General usage
- * The `$http` service is a function which takes a single argument — a configuration object —
- * that is used to generate an HTTP request and returns a {@link ng.$q promise}
- * with two $http specific methods: `success` and `error`.
+ * @description
+ * Shorthand method. `$sce.trustAsHtml(value)` → {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.HTML, value)`}
*
- * <pre>
- * $http({method: 'GET', url: '/someUrl'}).
- * success(function(data, status, headers, config) {
- * // this callback will be called asynchronously
- * // when the response is available
- * }).
- * error(function(data, status, headers, config) {
- * // called asynchronously if an error occurs
- * // or server returns response with an error status.
- * });
- * </pre>
+ * @param {*} value The value to trustAs.
+ * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedHtml
+ * $sce.getTrustedHtml(value)} to obtain the original value. (privileged directives
+ * only accept expressions that are either literal constants or are the
+ * return value of {@link ng.$sce#trustAs $sce.trustAs}.)
+ */
+
+ /**
+ * @ngdoc method
+ * @name ng.$sce#trustAsUrl
+ * @methodOf ng.$sce
*
- * Since the returned value of calling the $http function is a `promise`, you can also use
- * the `then` method to register callbacks, and these callbacks will receive a single argument –
- * an object representing the response. See the API signature and type info below for more
- * details.
+ * @description
+ * Shorthand method. `$sce.trustAsUrl(value)` → {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.URL, value)`}
*
- * A response status code between 200 and 299 is considered a success status and
- * will result in the success callback being called. Note that if the response is a redirect,
- * XMLHttpRequest will transparently follow it, meaning that the error callback will not be
- * called for such responses.
+ * @param {*} value The value to trustAs.
+ * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedUrl
+ * $sce.getTrustedUrl(value)} to obtain the original value. (privileged directives
+ * only accept expressions that are either literal constants or are the
+ * return value of {@link ng.$sce#trustAs $sce.trustAs}.)
+ */
+
+ /**
+ * @ngdoc method
+ * @name ng.$sce#trustAsResourceUrl
+ * @methodOf ng.$sce
*
- * # Shortcut methods
+ * @description
+ * Shorthand method. `$sce.trustAsResourceUrl(value)` → {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.RESOURCE_URL, value)`}
*
- * Since all invocations of the $http service require passing in an HTTP method and URL, and
- * POST/PUT requests require request data to be provided as well, shortcut methods
- * were created:
+ * @param {*} value The value to trustAs.
+ * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedResourceUrl
+ * $sce.getTrustedResourceUrl(value)} to obtain the original value. (privileged directives
+ * only accept expressions that are either literal constants or are the return
+ * value of {@link ng.$sce#trustAs $sce.trustAs}.)
+ */
+
+ /**
+ * @ngdoc method
+ * @name ng.$sce#trustAsJs
+ * @methodOf ng.$sce
*
- * <pre>
- * $http.get('/someUrl').success(successCallback);
- * $http.post('/someUrl', data).success(successCallback);
- * </pre>
+ * @description
+ * Shorthand method. `$sce.trustAsJs(value)` → {@link ng.$sceDelegate#trustAs `$sceDelegate.trustAs($sce.JS, value)`}
*
- * Complete list of shortcut methods:
+ * @param {*} value The value to trustAs.
+ * @returns {*} An object that can be passed to {@link ng.$sce#getTrustedJs
+ * $sce.getTrustedJs(value)} to obtain the original value. (privileged directives
+ * only accept expressions that are either literal constants or are the
+ * return value of {@link ng.$sce#trustAs $sce.trustAs}.)
+ */
+
+ /**
+ * @ngdoc method
+ * @name ng.$sce#getTrusted
+ * @methodOf ng.$sce
*
- * - {@link ng.$http#get $http.get}
- * - {@link ng.$http#head $http.head}
- * - {@link ng.$http#post $http.post}
- * - {@link ng.$http#put $http.put}
- * - {@link ng.$http#delete $http.delete}
- * - {@link ng.$http#jsonp $http.jsonp}
+ * @description
+ * Delegates to {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted`}. As such, takes
+ * the result of a {@link ng.$sce#trustAs `$sce.trustAs`}() call and returns the originally supplied
+ * value if the queried context type is a supertype of the created type. If this condition
+ * isn't satisfied, throws an exception.
*
+ * @param {string} type The kind of context in which this value is to be used.
+ * @param {*} maybeTrusted The result of a prior {@link ng.$sce#trustAs `$sce.trustAs`} call.
+ * @returns {*} The value the was originally provided to {@link ng.$sce#trustAs `$sce.trustAs`} if
+ * valid in this context. Otherwise, throws an exception.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ng.$sce#getTrustedHtml
+ * @methodOf ng.$sce
*
- * # Setting HTTP Headers
+ * @description
+ * Shorthand method. `$sce.getTrustedHtml(value)` → {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.HTML, value)`}
*
- * The $http service will automatically add certain HTTP headers to all requests. These defaults
- * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration
- * object, which currently contains this default configuration:
+ * @param {*} value The value to pass to `$sce.getTrusted`.
+ * @returns {*} The return value of `$sce.getTrusted($sce.HTML, value)`
+ */
+
+ /**
+ * @ngdoc method
+ * @name ng.$sce#getTrustedCss
+ * @methodOf ng.$sce
*
- * - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
- * - `Accept: application/json, text/plain, * / *`
- * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)
- * - `Content-Type: application/json`
- * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)
- * - `Content-Type: application/json`
+ * @description
+ * Shorthand method. `$sce.getTrustedCss(value)` → {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.CSS, value)`}
*
- * To add or overwrite these defaults, simply add or remove a property from these configuration
- * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
- * with the lowercased HTTP method name as the key, e.g.
- * `$httpProvider.defaults.headers.get['My-Header']='value'`.
+ * @param {*} value The value to pass to `$sce.getTrusted`.
+ * @returns {*} The return value of `$sce.getTrusted($sce.CSS, value)`
+ */
+
+ /**
+ * @ngdoc method
+ * @name ng.$sce#getTrustedUrl
+ * @methodOf ng.$sce
*
- * Additionally, the defaults can be set at runtime via the `$http.defaults` object in the same
- * fashion.
+ * @description
+ * Shorthand method. `$sce.getTrustedUrl(value)` → {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.URL, value)`}
*
- *
- * # Transforming Requests and Responses
- *
- * Both requests and responses can be transformed using transform functions. By default, Angular
- * applies these transformations:
- *
- * Request transformations:
- *
- * - If the `data` property of the request configuration object contains an object, serialize it into
- * JSON format.
- *
- * Response transformations:
- *
- * - If XSRF prefix is detected, strip it (see Security Considerations section below).
- * - If JSON response is detected, deserialize it using a JSON parser.
- *
- * To globally augment or override the default transforms, modify the `$httpProvider.defaults.transformRequest` and
- * `$httpProvider.defaults.transformResponse` properties. These properties are by default an
- * array of transform functions, which allows you to `push` or `unshift` a new transformation function into the
- * transformation chain. You can also decide to completely override any default transformations by assigning your
- * transformation functions to these properties directly without the array wrapper.
- *
- * Similarly, to locally override the request/response transforms, augment the `transformRequest` and/or
- * `transformResponse` properties of the configuration object passed into `$http`.
- *
- *
- * # Caching
- *
- * To enable caching, set the configuration property `cache` to `true`. When the cache is
- * enabled, `$http` stores the response from the server in local cache. Next time the
- * response is served from the cache without sending a request to the server.
- *
- * Note that even if the response is served from cache, delivery of the data is asynchronous in
- * the same way that real requests are.
- *
- * If there are multiple GET requests for the same URL that should be cached using the same
- * cache, but the cache is not populated yet, only one request to the server will be made and
- * the remaining requests will be fulfilled using the response from the first request.
- *
- * A custom default cache built with $cacheFactory can be provided in $http.defaults.cache.
- * To skip it, set configuration property `cache` to `false`.
- *
- *
- * # Interceptors
- *
- * Before you start creating interceptors, be sure to understand the
- * {@link ng.$q $q and deferred/promise APIs}.
- *
- * For purposes of global error handling, authentication, or any kind of synchronous or
- * asynchronous pre-processing of request or postprocessing of responses, it is desirable to be
- * able to intercept requests before they are handed to the server and
- * responses before they are handed over to the application code that
- * initiated these requests. The interceptors leverage the {@link ng.$q
- * promise APIs} to fulfill this need for both synchronous and asynchronous pre-processing.
- *
- * The interceptors are service factories that are registered with the `$httpProvider` by
- * adding them to the `$httpProvider.interceptors` array. The factory is called and
- * injected with dependencies (if specified) and returns the interceptor.
- *
- * There are two kinds of interceptors (and two kinds of rejection interceptors):
- *
- * * `request`: interceptors get called with http `config` object. The function is free to modify
- * the `config` or create a new one. The function needs to return the `config` directly or as a
- * promise.
- * * `requestError`: interceptor gets called when a previous interceptor threw an error or resolved
- * with a rejection.
- * * `response`: interceptors get called with http `response` object. The function is free to modify
- * the `response` or create a new one. The function needs to return the `response` directly or as a
- * promise.
- * * `responseError`: interceptor gets called when a previous interceptor threw an error or resolved
- * with a rejection.
- *
- *
- * <pre>
- * // register the interceptor as a service
- * $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
- * return {
- * // optional method
- * 'request': function(config) {
- * // do something on success
- * return config || $q.when(config);
- * },
- *
- * // optional method
- * 'requestError': function(rejection) {
- * // do something on error
- * if (canRecover(rejection)) {
- * return responseOrNewPromise
- * }
- * return $q.reject(rejection);
- * },
- *
- *
- *
- * // optional method
- * 'response': function(response) {
- * // do something on success
- * return response || $q.when(response);
- * },
- *
- * // optional method
- * 'responseError': function(rejection) {
- * // do something on error
- * if (canRecover(rejection)) {
- * return responseOrNewPromise
- * }
- * return $q.reject(rejection);
- * };
- * }
- * });
- *
- * $httpProvider.interceptors.push('myHttpInterceptor');
- *
- *
- * // register the interceptor via an anonymous factory
- * $httpProvider.interceptors.push(function($q, dependency1, dependency2) {
- * return {
- * 'request': function(config) {
- * // same as above
- * },
- * 'response': function(response) {
- * // same as above
- * }
- * });
- * </pre>
- *
- * # Response interceptors (DEPRECATED)
- *
- * Before you start creating interceptors, be sure to understand the
- * {@link ng.$q $q and deferred/promise APIs}.
- *
- * For purposes of global error handling, authentication or any kind of synchronous or
- * asynchronous preprocessing of received responses, it is desirable to be able to intercept
- * responses for http requests before they are handed over to the application code that
- * initiated these requests. The response interceptors leverage the {@link ng.$q
- * promise apis} to fulfil this need for both synchronous and asynchronous preprocessing.
- *
- * The interceptors are service factories that are registered with the $httpProvider by
- * adding them to the `$httpProvider.responseInterceptors` array. The factory is called and
- * injected with dependencies (if specified) and returns the interceptor — a function that
- * takes a {@link ng.$q promise} and returns the original or a new promise.
- *
- * <pre>
- * // register the interceptor as a service
- * $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
- * return function(promise) {
- * return promise.then(function(response) {
- * // do something on success
- * }, function(response) {
- * // do something on error
- * if (canRecover(response)) {
- * return responseOrNewPromise
- * }
- * return $q.reject(response);
- * });
- * }
- * });
- *
- * $httpProvider.responseInterceptors.push('myHttpInterceptor');
- *
- *
- * // register the interceptor via an anonymous factory
- * $httpProvider.responseInterceptors.push(function($q, dependency1, dependency2) {
- * return function(promise) {
- * // same as above
- * }
- * });
- * </pre>
- *
- *
- * # Security Considerations
- *
- * When designing web applications, consider security threats from:
- *
- * - {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerabilit…
- * JSON vulnerability}
- * - {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF}
- *
- * Both server and the client must cooperate in order to eliminate these threats. Angular comes
- * pre-configured with strategies that address these issues, but for this to work backend server
- * cooperation is required.
- *
- * ## JSON Vulnerability Protection
- *
- * A {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerabilit…
- * JSON vulnerability} allows third party website to turn your JSON resource URL into
- * {@link http://en.wikipedia.org/wiki/JSONP JSONP} request under some conditions. To
- * counter this your server can prefix all JSON requests with following string `")]}',\n"`.
- * Angular will automatically strip the prefix before processing it as JSON.
- *
- * For example if your server needs to return:
- * <pre>
- * ['one','two']
- * </pre>
- *
- * which is vulnerable to attack, your server can return:
- * <pre>
- * )]}',
- * ['one','two']
- * </pre>
- *
- * Angular will strip the prefix, before processing the JSON.
- *
- *
- * ## Cross Site Request Forgery (XSRF) Protection
- *
- * {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which
- * an unauthorized site can gain your user's private data. Angular provides a mechanism
- * to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
- * (by default, `XSRF-TOKEN`) and sets it as an HTTP header (`X-XSRF-TOKEN`). Since only
- * JavaScript that runs on your domain could read the cookie, your server can be assured that
- * the XHR came from JavaScript running on your domain. The header will not be set for
- * cross-domain requests.
- *
- * To take advantage of this, your server needs to set a token in a JavaScript readable session
- * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the
- * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure
- * that only JavaScript running on your domain could have sent the request. The token must be
- * unique for each user and must be verifiable by the server (to prevent the JavaScript from making
- * up its own tokens). We recommend that the token is a digest of your site's authentication
- * cookie with a {@link https://en.wikipedia.org/wiki/Salt_(cryptography) salt} for added security.
- *
- * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName
- * properties of either $httpProvider.defaults, or the per-request config object.
- *
- *
- * @param {object} config Object describing the request to be made and how it should be
- * processed. The object has following properties:
- *
- * - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc)
- * - **url** – `{string}` – Absolute or relative URL of the resource that is being requested.
- * - **params** – `{Object.<string|Object>}` – Map of strings or objects which will be turned to
- * `?key1=value1&key2=value2` after the url. If the value is not a string, it will be JSONified.
- * - **data** – `{string|Object}` – Data to be sent as the request message data.
- * - **headers** – `{Object}` – Map of strings representing HTTP headers to send to the server.
- * - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token.
- * - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token.
- * - **transformRequest** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
- * transform function or an array of such functions. The transform function takes the http
- * request body and headers and returns its transformed (typically serialized) version.
- * - **transformResponse** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
- * transform function or an array of such functions. The transform function takes the http
- * response body and headers and returns its transformed (typically deserialized) version.
- * - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
- * GET request, otherwise if a cache instance built with
- * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
- * caching.
- * - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}
- * that should abort the request when resolved.
- * - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the
- * XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5
- * requests with credentials} for more information.
- * - **responseType** - `{string}` - see {@link
- * https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}.
- *
- * @returns {HttpPromise} Returns a {@link ng.$q promise} object with the
- * standard `then` method and two http specific methods: `success` and `error`. The `then`
- * method takes two arguments a success and an error callback which will be called with a
- * response object. The `success` and `error` methods take a single argument - a function that
- * will be called when the request succeeds or fails respectively. The arguments passed into
- * these functions are destructured representation of the response object passed into the
- * `then` method. The response object has these properties:
- *
- * - **data** – `{string|Object}` – The response body transformed with the transform functions.
- * - **status** – `{number}` – HTTP status code of the response.
- * - **headers** – `{function([headerName])}` – Header getter function.
- * - **config** – `{Object}` – The configuration object that was used to generate the request.
- *
- * @property {Array.<Object>} pendingRequests Array of config objects for currently pending
- * requests. This is primarily meant to be used for debugging purposes.
- *
- *
- * @example
- <example>
- <file name="index.html">
- <div ng-controller="FetchCtrl">
- <select ng-model="method">
- <option>GET</option>
- <option>JSONP</option>
- </select>
- <input type="text" ng-model="url" size="80"/>
- <button ng-click="fetch()">fetch</button><br>
- <button ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
- <button ng-click="updateModel('JSONP', 'http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')">Sample JSONP</button>
- <button ng-click="updateModel('JSONP', 'http://angularjs.org/doesntexist&callback=JSON_CALLBACK')">Invalid JSONP</button>
- <pre>http status code: {{status}}</pre>
- <pre>http response data: {{data}}</pre>
- </div>
- </file>
- <file name="script.js">
- function FetchCtrl($scope, $http, $templateCache) {
- $scope.method = 'GET';
- $scope.url = 'http-hello.html';
-
- $scope.fetch = function() {
- $scope.code = null;
- $scope.response = null;
-
- $http({method: $scope.method, url: $scope.url, cache: $templateCache}).
- success(function(data, status) {
- $scope.status = status;
- $scope.data = data;
- }).
- error(function(data, status) {
- $scope.data = data || "Request failed";
- $scope.status = status;
- });
- };
-
- $scope.updateModel = function(method, url) {
- $scope.method = method;
- $scope.url = url;
- };
- }
- </file>
- <file name="http-hello.html">
- Hello, $http!
- </file>
- <file name="scenario.js">
- it('should make an xhr GET request', function() {
- element(':button:contains("Sample GET")').click();
- element(':button:contains("fetch")').click();
- expect(binding('status')).toBe('200');
- expect(binding('data')).toMatch(/Hello, \$http!/);
- });
-
- it('should make a JSONP request to angularjs.org', function() {
- element(':button:contains("Sample JSONP")').click();
- element(':button:contains("fetch")').click();
- expect(binding('status')).toBe('200');
- expect(binding('data')).toMatch(/Super Hero!/);
- });
-
- it('should make JSONP request to invalid URL and invoke the error handler',
- function() {
- element(':button:contains("Invalid JSONP")').click();
- element(':button:contains("fetch")').click();
- expect(binding('status')).toBe('0');
- expect(binding('data')).toBe('Request failed');
- });
- </file>
- </example>
+ * @param {*} value The value to pass to `$sce.getTrusted`.
+ * @returns {*} The return value of `$sce.getTrusted($sce.URL, value)`
*/
- function $http(requestConfig) {
- var config = {
- transformRequest: defaults.transformRequest,
- transformResponse: defaults.transformResponse
- };
- var headers = {};
- extend(config, requestConfig);
- config.headers = headers;
- config.method = uppercase(config.method);
-
- extend(headers,
- defaults.headers.common,
- defaults.headers[lowercase(config.method)],
- requestConfig.headers);
-
- var xsrfValue = isSameDomain(config.url, $browser.url())
- ? $browser.cookies()[config.xsrfCookieName || defaults.xsrfCookieName]
- : undefined;
- if (xsrfValue) {
- headers[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;
- }
-
-
- var serverRequest = function(config) {
- var reqData = transformData(config.data, headersGetter(headers), config.transformRequest);
-
- // strip content-type if data is undefined
- if (isUndefined(config.data)) {
- delete headers['Content-Type'];
- }
-
- if (isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials)) {
- config.withCredentials = defaults.withCredentials;
- }
-
- // send request
- return sendReq(config, reqData, headers).then(transformResponse, transformResponse);
- };
-
- var chain = [serverRequest, undefined];
- var promise = $q.when(config);
-
- // apply interceptors
- forEach(reversedInterceptors, function(interceptor) {
- if (interceptor.request || interceptor.requestError) {
- chain.unshift(interceptor.request, interceptor.requestError);
- }
- if (interceptor.response || interceptor.responseError) {
- chain.push(interceptor.response, interceptor.responseError);
- }
- });
-
- while(chain.length) {
- var thenFn = chain.shift();
- var rejectFn = chain.shift();
-
- promise = promise.then(thenFn, rejectFn);
- }
-
- promise.success = function(fn) {
- promise.then(function(response) {
- fn(response.data, response.status, response.headers, config);
- });
- return promise;
- };
-
- promise.error = function(fn) {
- promise.then(null, function(response) {
- fn(response.data, response.status, response.headers, config);
- });
- return promise;
- };
-
- return promise;
-
- function transformResponse(response) {
- // make a copy since the response must be cacheable
- var resp = extend({}, response, {
- data: transformData(response.data, response.headers, config.transformResponse)
- });
- return (isSuccess(response.status))
- ? resp
- : $q.reject(resp);
- }
- }
-
- $http.pendingRequests = [];
-
/**
* @ngdoc method
- * @name ng.$http#get
- * @methodOf ng.$http
+ * @name ng.$sce#getTrustedResourceUrl
+ * @methodOf ng.$sce
*
* @description
- * Shortcut method to perform `GET` request.
+ * Shorthand method. `$sce.getTrustedResourceUrl(value)` → {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.RESOURCE_URL, value)`}
*
- * @param {string} url Relative or absolute URL specifying the destination of the request
- * @param {Object=} config Optional configuration object
- * @returns {HttpPromise} Future object
+ * @param {*} value The value to pass to `$sceDelegate.getTrusted`.
+ * @returns {*} The return value of `$sce.getTrusted($sce.RESOURCE_URL, value)`
*/
/**
* @ngdoc method
- * @name ng.$http#delete
- * @methodOf ng.$http
+ * @name ng.$sce#getTrustedJs
+ * @methodOf ng.$sce
*
* @description
- * Shortcut method to perform `DELETE` request.
+ * Shorthand method. `$sce.getTrustedJs(value)` → {@link ng.$sceDelegate#getTrusted `$sceDelegate.getTrusted($sce.JS, value)`}
*
- * @param {string} url Relative or absolute URL specifying the destination of the request
- * @param {Object=} config Optional configuration object
- * @returns {HttpPromise} Future object
+ * @param {*} value The value to pass to `$sce.getTrusted`.
+ * @returns {*} The return value of `$sce.getTrusted($sce.JS, value)`
*/
/**
* @ngdoc method
- * @name ng.$http#head
- * @methodOf ng.$http
+ * @name ng.$sce#parseAsHtml
+ * @methodOf ng.$sce
*
* @description
- * Shortcut method to perform `HEAD` request.
+ * Shorthand method. `$sce.parseAsHtml(expression string)` → {@link ng.$sce#parse `$sce.parseAs($sce.HTML, value)`}
*
- * @param {string} url Relative or absolute URL specifying the destination of the request
- * @param {Object=} config Optional configuration object
- * @returns {HttpPromise} Future object
+ * @param {string} expression String expression to compile.
+ * @returns {function(context, locals)} a function which represents the compiled expression:
+ *
+ * * `context` – `{object}` – an object against which any expressions embedded in the strings
+ * are evaluated against (typically a scope object).
+ * * `locals` – `{object=}` – local variables context object, useful for overriding values in
+ * `context`.
*/
/**
* @ngdoc method
- * @name ng.$http#jsonp
- * @methodOf ng.$http
+ * @name ng.$sce#parseAsCss
+ * @methodOf ng.$sce
*
* @description
- * Shortcut method to perform `JSONP` request.
+ * Shorthand method. `$sce.parseAsCss(value)` → {@link ng.$sce#parse `$sce.parseAs($sce.CSS, value)`}
*
- * @param {string} url Relative or absolute URL specifying the destination of the request.
- * Should contain `JSON_CALLBACK` string.
- * @param {Object=} config Optional configuration object
- * @returns {HttpPromise} Future object
+ * @param {string} expression String expression to compile.
+ * @returns {function(context, locals)} a function which represents the compiled expression:
+ *
+ * * `context` – `{object}` – an object against which any expressions embedded in the strings
+ * are evaluated against (typically a scope object).
+ * * `locals` – `{object=}` – local variables context object, useful for overriding values in
+ * `context`.
*/
- createShortMethods('get', 'delete', 'head', 'jsonp');
/**
* @ngdoc method
- * @name ng.$http#post
- * @methodOf ng.$http
+ * @name ng.$sce#parseAsUrl
+ * @methodOf ng.$sce
*
* @description
- * Shortcut method to perform `POST` request.
+ * Shorthand method. `$sce.parseAsUrl(value)` → {@link ng.$sce#parse `$sce.parseAs($sce.URL, value)`}
*
- * @param {string} url Relative or absolute URL specifying the destination of the request
- * @param {*} data Request content
- * @param {Object=} config Optional configuration object
- * @returns {HttpPromise} Future object
+ * @param {string} expression String expression to compile.
+ * @returns {function(context, locals)} a function which represents the compiled expression:
+ *
+ * * `context` – `{object}` – an object against which any expressions embedded in the strings
+ * are evaluated against (typically a scope object).
+ * * `locals` – `{object=}` – local variables context object, useful for overriding values in
+ * `context`.
*/
/**
* @ngdoc method
- * @name ng.$http#put
- * @methodOf ng.$http
+ * @name ng.$sce#parseAsResourceUrl
+ * @methodOf ng.$sce
*
* @description
- * Shortcut method to perform `PUT` request.
+ * Shorthand method. `$sce.parseAsResourceUrl(value)` → {@link ng.$sce#parse `$sce.parseAs($sce.RESOURCE_URL, value)`}
*
- * @param {string} url Relative or absolute URL specifying the destination of the request
- * @param {*} data Request content
- * @param {Object=} config Optional configuration object
- * @returns {HttpPromise} Future object
+ * @param {string} expression String expression to compile.
+ * @returns {function(context, locals)} a function which represents the compiled expression:
+ *
+ * * `context` – `{object}` – an object against which any expressions embedded in the strings
+ * are evaluated against (typically a scope object).
+ * * `locals` – `{object=}` – local variables context object, useful for overriding values in
+ * `context`.
*/
- createShortMethodsWithData('post', 'put');
- /**
- * @ngdoc property
- * @name ng.$http#defaults
- * @propertyOf ng.$http
- *
- * @description
- * Runtime equivalent of the `$httpProvider.defaults` property. Allows configuration of
- * default headers, withCredentials as well as request and response transformations.
- *
- * See "Setting HTTP Headers" and "Transforming Requests and Responses" sections above.
- */
- $http.defaults = defaults;
-
-
- return $http;
-
-
- function createShortMethods(names) {
- forEach(arguments, function(name) {
- $http[name] = function(url, config) {
- return $http(extend(config || {}, {
- method: name,
- url: url
- }));
- };
- });
- }
-
-
- function createShortMethodsWithData(name) {
- forEach(arguments, function(name) {
- $http[name] = function(url, data, config) {
- return $http(extend(config || {}, {
- method: name,
- url: url,
- data: data
- }));
- };
- });
- }
-
-
/**
- * Makes the request.
+ * @ngdoc method
+ * @name ng.$sce#parseAsJs
+ * @methodOf ng.$sce
*
- * !!! ACCESSES CLOSURE VARS:
- * $httpBackend, defaults, $log, $rootScope, defaultCache, $http.pendingRequests
+ * @description
+ * Shorthand method. `$sce.parseAsJs(value)` → {@link ng.$sce#parse `$sce.parseAs($sce.JS, value)`}
+ *
+ * @param {string} expression String expression to compile.
+ * @returns {function(context, locals)} a function which represents the compiled expression:
+ *
+ * * `context` – `{object}` – an object against which any expressions embedded in the strings
+ * are evaluated against (typically a scope object).
+ * * `locals` – `{object=}` – local variables context object, useful for overriding values in
+ * `context`.
*/
- function sendReq(config, reqData, reqHeaders) {
- var deferred = $q.defer(),
- promise = deferred.promise,
- cache,
- cachedResp,
- url = buildUrl(config.url, config.params);
- $http.pendingRequests.push(config);
- promise.then(removePendingReq, removePendingReq);
+ // Shorthand delegations.
+ var parse = sce.parseAs,
+ getTrusted = sce.getTrusted,
+ trustAs = sce.trustAs;
-
- if ((config.cache || defaults.cache) && config.cache !== false && config.method == 'GET') {
- cache = isObject(config.cache) ? config.cache
- : isObject(defaults.cache) ? defaults.cache
- : defaultCache;
+ angular.forEach(SCE_CONTEXTS, function (enumValue, name) {
+ var lName = lowercase(name);
+ sce[camelCase("parse_as_" + lName)] = function (expr) {
+ return parse(enumValue, expr);
}
-
- if (cache) {
- cachedResp = cache.get(url);
- if (cachedResp) {
- if (cachedResp.then) {
- // cached request has already been sent, but there is no response yet
- cachedResp.then(removePendingReq, removePendingReq);
- return cachedResp;
- } else {
- // serving from cache
- if (isArray(cachedResp)) {
- resolvePromise(cachedResp[1], cachedResp[0], copy(cachedResp[2]));
- } else {
- resolvePromise(cachedResp, 200, {});
- }
- }
- } else {
- // put the promise for the non-transformed response into cache as a placeholder
- cache.put(url, promise);
- }
+ sce[camelCase("get_trusted_" + lName)] = function (value) {
+ return getTrusted(enumValue, value);
}
-
- // if we won't have the response in cache, send the request to the backend
- if (!cachedResp) {
- $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
- config.withCredentials, config.responseType);
+ sce[camelCase("trust_as_" + lName)] = function (value) {
+ return trustAs(enumValue, value);
}
+ });
- return promise;
-
-
- /**
- * Callback registered to $httpBackend():
- * - caches the response if desired
- * - resolves the raw $http promise
- * - calls $apply
- */
- function done(status, response, headersString) {
- if (cache) {
- if (isSuccess(status)) {
- cache.put(url, [status, response, parseHeaders(headersString)]);
- } else {
- // remove promise from the cache
- cache.remove(url);
- }
- }
-
- resolvePromise(response, status, headersString);
- if (!$rootScope.$$phase) $rootScope.$apply();
- }
-
-
- /**
- * Resolves the raw $http promise.
- */
- function resolvePromise(response, status, headers) {
- // normalize internal statuses to 0
- status = Math.max(status, 0);
-
- (isSuccess(status) ? deferred.resolve : deferred.reject)({
- data: response,
- status: status,
- headers: headersGetter(headers),
- config: config
- });
- }
-
-
- function removePendingReq() {
- var idx = indexOf($http.pendingRequests, config);
- if (idx !== -1) $http.pendingRequests.splice(idx, 1);
- }
- }
-
-
- function buildUrl(url, params) {
- if (!params) return url;
- var parts = [];
- forEachSorted(params, function(value, key) {
- if (value == null || value == undefined) return;
- if (!isArray(value)) value = [value];
-
- forEach(value, function(v) {
- if (isObject(v)) {
- v = toJson(v);
- }
- parts.push(encodeUriQuery(key) + '=' +
- encodeUriQuery(v));
- });
- });
- return url + ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
- }
-
-
+ return sce;
}];
}
-var XHR = window.XMLHttpRequest || function() {
- try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
- try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {}
- try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {}
- throw new Error("This browser does not support XMLHttpRequest.");
-};
-
-
/**
- * @ngdoc object
- * @name ng.$httpBackend
- * @requires $browser
+ * !!! This is an undocumented "private" service !!!
+ *
+ * @name ng.$sniffer
* @requires $window
* @requires $document
*
+ * @property {boolean} history Does the browser support html5 history api ?
+ * @property {boolean} hashchange Does the browser support hashchange event ?
+ * @property {boolean} transitions Does the browser support CSS transition events ?
+ * @property {boolean} animations Does the browser support CSS animation events ?
+ *
* @description
- * HTTP backend used by the {@link ng.$http service} that delegates to
- * XMLHttpRequest object or JSONP and deals with browser incompatibilities.
- *
- * You should never need to use this service directly, instead use the higher-level abstractions:
- * {@link ng.$http $http} or {@link ngResource.$resource $resource}.
- *
- * During testing this implementation is swapped with {@link ngMock.$httpBackend mock
- * $httpBackend} which can be trained with responses.
+ * This is very simple implementation of testing browser's features.
*/
-function $HttpBackendProvider() {
- this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) {
- return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks,
- $document[0], $window.location.protocol.replace(':', ''));
- }];
-}
+function $SnifferProvider() {
+ this.$get = ['$window', '$document', function($window, $document) {
+ var eventSupport = {},
+ android = int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
+ document = $document[0] || {},
+ vendorPrefix,
+ vendorRegex = /^(Moz|webkit|O|ms)(?=[A-Z])/,
+ bodyStyle = document.body && document.body.style,
+ transitions = false,
+ animations = false,
+ match;
-function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument, locationProtocol) {
- // TODO(vojta): fix the signature
- return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
- var status;
- $browser.$$incOutstandingRequestCount();
- url = url || $browser.url();
-
- if (lowercase(method) == 'jsonp') {
- var callbackId = '_' + (callbacks.counter++).toString(36);
- callbacks[callbackId] = function(data) {
- callbacks[callbackId].data = data;
- };
-
- var jsonpDone = jsonpReq(url.replace('JSON_CALLBACK', 'angular.callbacks.' + callbackId),
- function() {
- if (callbacks[callbackId].data) {
- completeRequest(callback, 200, callbacks[callbackId].data);
- } else {
- completeRequest(callback, status || -2);
+ if (bodyStyle) {
+ for(var prop in bodyStyle) {
+ if(match = vendorRegex.exec(prop)) {
+ vendorPrefix = match[0];
+ vendorPrefix = vendorPrefix.substr(0, 1).toUpperCase() + vendorPrefix.substr(1);
+ break;
}
- delete callbacks[callbackId];
- });
- } else {
- var xhr = new XHR();
- xhr.open(method, url, true);
- forEach(headers, function(value, key) {
- if (value) xhr.setRequestHeader(key, value);
- });
-
- // In IE6 and 7, this might be called synchronously when xhr.send below is called and the
- // response is in the cache. the promise api will ensure that to the app code the api is
- // always async
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4) {
- var responseHeaders = xhr.getAllResponseHeaders();
-
- // TODO(vojta): remove once Firefox 21 gets released.
- // begin: workaround to overcome Firefox CORS http response headers bug
- // https://bugzilla.mozilla.org/show_bug.cgi?id=608735
- // Firefox already patched in nightly. Should land in Firefox 21.
-
- // CORS "simple response headers" http://www.w3.org/TR/cors/
- var value,
- simpleHeaders = ["Cache-Control", "Content-Language", "Content-Type",
- "Expires", "Last-Modified", "Pragma"];
- if (!responseHeaders) {
- responseHeaders = "";
- forEach(simpleHeaders, function (header) {
- var value = xhr.getResponseHeader(header);
- if (value) {
- responseHeaders += header + ": " + value + "\n";
- }
- });
- }
- // end of the workaround.
-
- // responseText is the old-school way of retrieving response (supported by IE8 & 9)
- // response and responseType properties were introduced in XHR Level2 spec (supported by IE10)
- completeRequest(callback,
- status || xhr.status,
- (xhr.responseType ? xhr.response : xhr.responseText),
- responseHeaders);
- }
- };
-
- if (withCredentials) {
- xhr.withCredentials = true;
}
-
- if (responseType) {
- xhr.responseType = responseType;
+ transitions = !!(('transition' in bodyStyle) || (vendorPrefix + 'Transition' in bodyStyle));
+ animations = !!(('animation' in bodyStyle) || (vendorPrefix + 'Animation' in bodyStyle));
+
+ if (android && (!transitions||!animations)) {
+ transitions = isString(document.body.style.webkitTransition);
+ animations = isString(document.body.style.webkitAnimation);
}
-
- xhr.send(post || '');
}
- if (timeout > 0) {
- var timeoutId = $browserDefer(timeoutRequest, timeout);
- } else if (timeout && timeout.then) {
- timeout.then(timeoutRequest);
- }
-
- function timeoutRequest() {
- status = -1;
- jsonpDone && jsonpDone();
- xhr && xhr.abort();
- }
-
- function completeRequest(callback, status, response, headersString) {
- // URL_MATCH is defined in src/service/location.js
- var protocol = (url.match(SERVER_MATCH) || ['', locationProtocol])[1];
-
- // cancel timeout and subsequent timeout promise resolution
- timeoutId && $browserDefer.cancel(timeoutId);
- jsonpDone = xhr = null;
-
- // fix status code for file protocol (it's always 0)
- status = (protocol == 'file') ? (response ? 200 : 404) : status;
-
- // normalize IE bug (http://bugs.jquery.com/ticket/1450)
- status = status == 1223 ? 204 : status;
-
- callback(status, response, headersString);
- $browser.$$completeOutstandingRequest(noop);
- }
- };
-
- function jsonpReq(url, done) {
- // we can't use jQuery/jqLite here because jQuery does crazy shit with script elements, e.g.:
- // - fetches local scripts via XHR and evals them
- // - adds and immediately removes script elements from the document
- var script = rawDocument.createElement('script'),
- doneWrapper = function() {
- rawDocument.body.removeChild(script);
- if (done) done();
- };
-
- script.type = 'text/javascript';
- script.src = url;
-
- if (msie) {
- script.onreadystatechange = function() {
- if (/loaded|complete/.test(script.readyState)) doneWrapper();
- };
- } else {
- script.onload = script.onerror = doneWrapper;
- }
-
- rawDocument.body.appendChild(script);
- return doneWrapper;
- }
-}
-
-/**
- * @ngdoc object
- * @name ng.$locale
- *
- * @description
- * $locale service provides localization rules for various Angular components. As of right now the
- * only public api is:
- *
- * * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`)
- */
-function $LocaleProvider(){
- this.$get = function() {
return {
- id: 'en-us',
+ // Android has history.pushState, but it does not update location correctly
+ // so let's not use the history API at all.
+ // http://code.google.com/p/android/issues/detail?id=17471
+ // https://github.com/angular/angular.js/issues/904
+ history: !!($window.history && $window.history.pushState && !(android < 4)),
+ hashchange: 'onhashchange' in $window &&
+ // IE8 compatible mode lies
+ (!document.documentMode || document.documentMode > 7),
+ hasEvent: function(event) {
+ // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
+ // it. In particular the event is not fired when backspace or delete key are pressed or
+ // when cut operation is performed.
+ if (event == 'input' && msie == 9) return false;
- NUMBER_FORMATS: {
- DECIMAL_SEP: '.',
- GROUP_SEP: ',',
- PATTERNS: [
- { // Decimal Pattern
- minInt: 1,
- minFrac: 0,
- maxFrac: 3,
- posPre: '',
- posSuf: '',
- negPre: '-',
- negSuf: '',
- gSize: 3,
- lgSize: 3
- },{ //Currency Pattern
- minInt: 1,
- minFrac: 2,
- maxFrac: 2,
- posPre: '\u00A4',
- posSuf: '',
- negPre: '(\u00A4',
- negSuf: ')',
- gSize: 3,
- lgSize: 3
- }
- ],
- CURRENCY_SYM: '$'
- },
+ if (isUndefined(eventSupport[event])) {
+ var divElm = document.createElement('div');
+ eventSupport[event] = 'on' + event in divElm;
+ }
- DATETIME_FORMATS: {
- MONTH: 'January,February,March,April,May,June,July,August,September,October,November,December'
- .split(','),
- SHORTMONTH: 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(','),
- DAY: 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'.split(','),
- SHORTDAY: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'.split(','),
- AMPMS: ['AM','PM'],
- medium: 'MMM d, y h:mm:ss a',
- short: 'M/d/yy h:mm a',
- fullDate: 'EEEE, MMMM d, y',
- longDate: 'MMMM d, y',
- mediumDate: 'MMM d, y',
- shortDate: 'M/d/yy',
- mediumTime: 'h:mm:ss a',
- shortTime: 'h:mm a'
+ return eventSupport[event];
},
-
- pluralCat: function(num) {
- if (num === 1) {
- return 'one';
- }
- return 'other';
- }
+ csp: document.securityPolicy ? document.securityPolicy.isActive : false,
+ vendorPrefix: vendorPrefix,
+ transitions : transitions,
+ animations : animations
};
- };
+ }];
}
function $TimeoutProvider() {
@@ -10633,8 +11359,168 @@
}];
}
+function $$UrlUtilsProvider() {
+ this.$get = [function() {
+ var urlParsingNode = document.createElement("a"),
+ // NOTE: The usage of window and document instead of $window and $document here is
+ // deliberate. This service depends on the specific behavior of anchor nodes created by the
+ // browser (resolving and parsing URLs) that is unlikely to be provided by mock objects and
+ // cause us to break tests. In addition, when the browser resolves a URL for XHR, it
+ // doesn't know about mocked locations and resolves URLs to the real document - which is
+ // exactly the behavior needed here. There is little value is mocking these our for this
+ // service.
+ originUrl = resolve(window.location.href, true);
+
+ /**
+ * @description
+ * Normalizes and optionally parses a URL.
+ *
+ * NOTE: This is a private service. The API is subject to change unpredictably in any commit.
+ *
+ * Implementation Notes for non-IE browsers
+ * ----------------------------------------
+ * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM,
+ * results both in the normalizing and parsing of the URL. Normalizing means that a relative
+ * URL will be resolved into an absolute URL in the context of the application document.
+ * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related
+ * properties are all populated to reflect the normalized URL. This approach has wide
+ * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc. See
+ * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html
+ *
+ * Implementation Notes for IE
+ * ---------------------------
+ * IE >= 8 and <= 10 normalizes the URL when assigned to the anchor node similar to the other
+ * browsers. However, the parsed components will not be set if the URL assigned did not specify
+ * them. (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.) We
+ * work around that by performing the parsing in a 2nd step by taking a previously normalized
+ * URL (e.g. by assining to a.href) and assigning it a.href again. This correctly populates the
+ * properties such as protocol, hostname, port, etc.
+ *
+ * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one
+ * uses the inner HTML approach to assign the URL as part of an HTML snippet -
+ * http://stackoverflow.com/a/472729) However, setting img[src] does normalize the URL.
+ * Unfortunately, setting img[src] to something like "javascript:foo" on IE throws an exception.
+ * Since the primary usage for normalizing URLs is to sanitize such URLs, we can't use that
+ * method and IE < 8 is unsupported.
+ *
+ * References:
+ * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement
+ * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html
+ * http://url.spec.whatwg.org/#urlutils
+ * https://github.com/angular/angular.js/pull/2902
+ * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
+ *
+ * @param {string} url The URL to be parsed.
+ * @param {boolean=} parse When true, returns an object for the parsed URL. Otherwise, returns
+ * a single string that is the normalized URL.
+ * @returns {object|string} When parse is true, returns the normalized URL as a string.
+ * Otherwise, returns an object with the following members.
+ *
+ * | member name | Description |
+ * |===============|================|
+ * | href | A normalized version of the provided URL if it was not an absolute URL |
+ * | protocol | The protocol including the trailing colon |
+ * | host | The host and port (if the port is non-default) of the normalizedUrl |
+ *
+ * These fields from the UrlUtils interface are currently not needed and hence not returned.
+ *
+ * | member name | Description |
+ * |===============|================|
+ * | hostname | The host without the port of the normalizedUrl |
+ * | pathname | The path following the host in the normalizedUrl |
+ * | hash | The URL hash if present |
+ * | search | The query string |
+ *
+ */
+ function resolve(url, parse) {
+ var href = url;
+ if (msie) {
+ // Normalize before parse. Refer Implementation Notes on why this is
+ // done in two steps on IE.
+ urlParsingNode.setAttribute("href", href);
+ href = urlParsingNode.href;
+ }
+ urlParsingNode.setAttribute('href', href);
+
+ if (!parse) {
+ return urlParsingNode.href;
+ }
+ // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
+ return {
+ href: urlParsingNode.href,
+ protocol: urlParsingNode.protocol,
+ host: urlParsingNode.host
+ // Currently unused and hence commented out.
+ // hostname: urlParsingNode.hostname,
+ // port: urlParsingNode.port,
+ // pathname: urlParsingNode.pathname,
+ // hash: urlParsingNode.hash,
+ // search: urlParsingNode.search
+ };
+ }
+
+ return {
+ resolve: resolve,
+ /**
+ * Parse a request URL and determine whether this is a same-origin request as the application document.
+ *
+ * @param {string|object} requestUrl The url of the request as a string that will be resolved
+ * or a parsed URL object.
+ * @returns {boolean} Whether the request is for the same origin as the application document.
+ */
+ isSameOrigin: function isSameOrigin(requestUrl) {
+ var parsed = (typeof requestUrl === 'string') ? resolve(requestUrl, true) : requestUrl;
+ return (parsed.protocol === originUrl.protocol &&
+ parsed.host === originUrl.host);
+ }
+ };
+ }];
+}
+
/**
* @ngdoc object
+ * @name ng.$window
+ *
+ * @description
+ * A reference to the browser's `window` object. While `window`
+ * is globally available in JavaScript, it causes testability problems, because
+ * it is a global variable. In angular we always refer to it through the
+ * `$window` service, so it may be overridden, removed or mocked for testing.
+ *
+ * Expressions, like the one defined for the `ngClick` directive in the example
+ * below, are evaluated with respect to the current scope. Therefore, there is
+ * no risk of inadvertently coding in a dependency on a global value in such an
+ * expression.
+ *
+ * @example
+ <doc:example>
+ <doc:source>
+ <script>
+ function Ctrl($scope, $window) {
+ $scope.$window = $window;
+ $scope.greeting = 'Hello, World!';
+ }
+ </script>
+ <div ng-controller="Ctrl">
+ <input type="text" ng-model="greeting" />
+ <button ng-click="$window.alert(greeting)">ALERT</button>
+ </div>
+ </doc:source>
+ <doc:scenario>
+ it('should display the greeting in the input box', function() {
+ input('greeting').enter('Hello, E2E Tests');
+ // If we click the button it will block the test runner
+ // element(':button').click();
+ });
+ </doc:scenario>
+ </doc:example>
+ */
+function $WindowProvider(){
+ this.$get = valueFn(window);
+}
+
+/**
+ * @ngdoc object
* @name ng.$filterProvider
* @description
*
@@ -10663,7 +11549,7 @@
* }
* </pre>
*
- * The filter function is registered with the `$injector` under the filter name suffixe with `Filter`.
+ * The filter function is registered with the `$injector` under the filter name suffix with `Filter`.
* <pre>
* it('should be the same instance', inject(
* function($filterProvider) {
@@ -11006,7 +11892,9 @@
* If the input is not a number an empty string is returned.
*
* @param {number|string} number Number to format.
- * @param {(number|string)=} [fractionSize=2] Number of decimal places to round the number to.
+ * @param {(number|string)=} fractionSize Number of decimal places to round the number to.
+ * If this is not provided then the fraction size is computed from the current locale's number
+ * formatting pattern. In the case of the default locale, it will be 3.
* @returns {string} Number rounded to decimalPlaces and places a “,” after each third digit.
*
* @example
@@ -11113,6 +12001,11 @@
}
if (fractionSize && fractionSize !== "0") formatedText += decimalSep + fraction.substr(0, fractionSize);
+ } else {
+
+ if (fractionSize > 0 && number > -1 && number < 1) {
+ formatedText = number.toFixed(fractionSize);
+ }
}
parts.push(isNegative ? pattern.negPre : pattern.posPre);
@@ -11187,7 +12080,7 @@
m: dateGetter('Minutes', 1),
ss: dateGetter('Seconds', 2),
s: dateGetter('Seconds', 1),
- // while ISO 8601 requires fractions to be prefixed with `.` or `,`
+ // while ISO 8601 requires fractions to be prefixed with `.` or `,`
// we can be just safely rely on using `sss` since we currently don't support single or two digit fractions
sss: dateGetter('Milliseconds', 3),
EEEE: dateStrGetter('Day'),
@@ -11240,7 +12133,7 @@
* * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US locale (e.g. 9/3/10 12:05 pm)
* * `'fullDate'`: equivalent to `'EEEE, MMMM d,y'` for en_US locale
* (e.g. Friday, September 3, 2010)
- * * `'longDate'`: equivalent to `'MMMM d, y'` for en_US locale (e.g. September 3, 2010
+ * * `'longDate'`: equivalent to `'MMMM d, y'` for en_US locale (e.g. September 3, 2010)
* * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US locale (e.g. Sep 3, 2010)
* * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10)
* * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 pm)
@@ -11248,7 +12141,7 @@
*
* `format` string can contain literal values. These need to be quoted with single quotes (e.g.
* `"h 'in the morning'"`). In order to output single quote, use two single quotes in a sequence
- * (e.g. `"h o''clock"`).
+ * (e.g. `"h 'o''clock'"`).
*
* @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
* number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and its
@@ -11694,7 +12587,7 @@
}
return function(scope, element) {
- element.bind('click', function(event){
+ element.on('click', function(event){
// if we have no href url, then don't navigate anywhere.
if (!element.attr('href')) {
event.preventDefault();
@@ -11905,42 +12798,6 @@
/**
* @ngdoc directive
- * @name ng.directive:ngMultiple
- * @restrict A
- *
- * @description
- * The HTML specs do not require browsers to preserve the special attributes such as multiple.
- * (The presence of them means true and absence means false)
- * This prevents the angular compiler from correctly retrieving the binding expression.
- * To solve this problem, we introduce the `ngMultiple` directive.
- *
- * @example
- <doc:example>
- <doc:source>
- Check me check multiple: <input type="checkbox" ng-model="checked"><br/>
- <select id="select" ng-multiple="checked">
- <option>Misko</option>
- <option>Igor</option>
- <option>Vojta</option>
- <option>Di</option>
- </select>
- </doc:source>
- <doc:scenario>
- it('should toggle multiple', function() {
- expect(element('.doc-example-live #select').prop('multiple')).toBeFalsy();
- input('checked').check();
- expect(element('.doc-example-live #select').prop('multiple')).toBeTruthy();
- });
- </doc:scenario>
- </doc:example>
- *
- * @element SELECT
- * @param {expression} ngMultiple Angular expression that will be evaluated.
- */
-
-
-/**
- * @ngdoc directive
* @name ng.directive:ngReadonly
* @restrict A
*
@@ -12038,6 +12895,9 @@
// boolean attrs are evaluated
forEach(BOOLEAN_ATTR, function(propName, attrName) {
+ // binding to multiple is not supported
+ if (propName == "multiple") return;
+
var normalized = directiveNormalize('ng-' + attrName);
ngAttributeAliasDirectives[normalized] = function() {
return {
@@ -12119,7 +12979,7 @@
controls = [];
// init state
- form.$name = attrs.name;
+ form.$name = attrs.name || attrs.ngForm;
form.$dirty = false;
form.$pristine = true;
form.$valid = true;
@@ -12139,6 +12999,16 @@
addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey);
}
+ /**
+ * @ngdoc function
+ * @name ng.directive:form.FormController#$addControl
+ * @methodOf ng.directive:form.FormController
+ *
+ * @description
+ * Register a control with the form.
+ *
+ * Input elements using ngModelController do this automatically when they are linked.
+ */
form.$addControl = function(control) {
controls.push(control);
@@ -12147,6 +13017,16 @@
}
};
+ /**
+ * @ngdoc function
+ * @name ng.directive:form.FormController#$removeControl
+ * @methodOf ng.directive:form.FormController
+ *
+ * @description
+ * Deregister a control from the form.
+ *
+ * Input elements using ngModelController do this automatically when they are destroyed.
+ */
form.$removeControl = function(control) {
if (control.$name && form[control.$name] === control) {
delete form[control.$name];
@@ -12158,6 +13038,16 @@
arrayRemove(controls, control);
};
+ /**
+ * @ngdoc function
+ * @name ng.directive:form.FormController#$setValidity
+ * @methodOf ng.directive:form.FormController
+ *
+ * @description
+ * Sets the validity of a form control.
+ *
+ * This method will also propagate to parent forms.
+ */
form.$setValidity = function(validationToken, isValid, control) {
var queue = errors[validationToken];
@@ -12196,6 +13086,17 @@
}
};
+ /**
+ * @ngdoc function
+ * @name ng.directive:form.FormController#$setDirty
+ * @methodOf ng.directive:form.FormController
+ *
+ * @description
+ * Sets the form to a dirty state.
+ *
+ * This method can be called to add the 'ng-dirty' class and set the form to a dirty
+ * state (ng-dirty class). This method will also propagate to parent forms.
+ */
form.$setDirty = function() {
element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS);
form.$dirty = true;
@@ -12360,7 +13261,7 @@
// unregister the preventDefault listener so that we don't not leak memory but in a
// way that will achieve the prevention of the default action.
- formElement.bind('$destroy', function() {
+ formElement.on('$destroy', function() {
$timeout(function() {
removeEventListenerFn(formElement[0], 'submit', preventDefaultListener);
}, 0, false);
@@ -12371,13 +13272,13 @@
alias = attr.name || attr.ngForm;
if (alias) {
- scope[alias] = controller;
+ setter(scope, alias, controller, alias);
}
if (parentFormCtrl) {
- formElement.bind('$destroy', function() {
+ formElement.on('$destroy', function() {
parentFormCtrl.$removeControl(controller);
if (alias) {
- scope[alias] = undefined;
+ setter(scope, alias, undefined, alias);
}
extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards
});
@@ -12395,7 +13296,7 @@
var ngFormDirective = formDirectiveFactory(true);
var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
-var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+(a)[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/;
+var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+(a)[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$/;
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
var inputType = {
@@ -12514,9 +13415,9 @@
<form name="myForm" ng-controller="Ctrl">
Number: <input type="number" name="input" ng-model="value"
min="0" max="99" required>
- <span class="error" ng-show="myForm.list.$error.required">
+ <span class="error" ng-show="myForm.input.$error.required">
Required!</span>
- <span class="error" ng-show="myForm.list.$error.number">
+ <span class="error" ng-show="myForm.input.$error.number">
Not valid number!</span>
<tt>value = {{value}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
@@ -12637,6 +13538,8 @@
* @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
* RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
* patterns defined as scope expressions.
+ * @param {string=} ngChange Angular expression to be executed when input changes due to user
+ * interaction with the input element.
*
* @example
<doc:example>
@@ -12803,7 +13706,7 @@
// if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the
// input event on backspace, delete or cut
if ($sniffer.hasEvent('input')) {
- element.bind('input', listener);
+ element.on('input', listener);
} else {
var timeout;
@@ -12816,7 +13719,7 @@
}
};
- element.bind('keydown', function(event) {
+ element.on('keydown', function(event) {
var key = event.keyCode;
// ignore
@@ -12827,11 +13730,11 @@
});
// if user paste into input using mouse, we need "change" event to catch it
- element.bind('change', listener);
+ element.on('change', listener);
// if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
if ($sniffer.hasEvent('paste')) {
- element.bind('paste cut', deferListener);
+ element.on('paste cut', deferListener);
}
}
@@ -12867,7 +13770,9 @@
var patternObj = scope.$eval(pattern);
if (!patternObj || !patternObj.test) {
- throw new Error('Expected ' + pattern + ' to be a RegExp but was ' + patternObj);
+ throw minErr('ngPattern')('noregexp',
+ 'Expected {0} to be a RegExp but was {1}. Element: {2}', pattern,
+ patternObj, startingTag(element));
}
return validate(patternObj, value);
};
@@ -13014,7 +13919,7 @@
element.attr('name', nextUid());
}
- element.bind('click', function() {
+ element.on('click', function() {
if (element[0].checked) {
scope.$apply(function() {
ctrl.$setViewValue(attr.value);
@@ -13037,7 +13942,7 @@
if (!isString(trueValue)) trueValue = true;
if (!isString(falseValue)) falseValue = false;
- element.bind('click', function() {
+ element.on('click', function() {
scope.$apply(function() {
ctrl.$setViewValue(element[0].checked);
});
@@ -13204,12 +14109,25 @@
*
* @property {string} $viewValue Actual string value in the view.
* @property {*} $modelValue The value in the model, that the control is bound to.
- * @property {Array.<Function>} $parsers Whenever the control reads value from the DOM, it executes
- * all of these functions to sanitize / convert the value as well as validate.
+ * @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever
+ the control reads value from the DOM. Each function is called, in turn, passing the value
+ through to the next. Used to sanitize / convert the value as well as validation.
+ For validation, the parsers should update the validity state using
+ {@link ng.directive:ngModel.NgModelController#$setValidity $setValidity()},
+ and return `undefined` for invalid values.
+
*
- * @property {Array.<Function>} $formatters Whenever the model value changes, it executes all of
- * these functions to convert the value as well as validate.
- *
+ * @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever
+ the model value changes. Each function is called, in turn, passing the value through to the
+ next. Used to format / convert values for display in the control and validation.
+ * <pre>
+ * function formatter(value) {
+ * if (value) {
+ * return value.toUpperCase();
+ * }
+ * }
+ * ngModel.$formatters.push(formatter);
+ * </pre>
* @property {Object} $error An object hash with all errors as keys.
*
* @property {boolean} $pristine True if user has not interacted with the control yet.
@@ -13224,7 +14142,11 @@
* specifically does not contain any logic which deals with DOM rendering or listening to
* DOM events. The `NgModelController` is meant to be extended by other directives where, the
* directive provides DOM manipulation and the `NgModelController` provides the data-binding.
+ * Note that you cannot use `NgModelController` in a directive with an isolated scope,
+ * as, in that case, the `ng-model` value gets put into the isolated scope and does not get
+ * propogated to the parent scope.
*
+ *
* This example shows how to use `NgModelController` with a custom control to achieve
* data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`)
* collaborate together to achieve the desired result.
@@ -13257,14 +14179,20 @@
};
// Listen for change events to enable binding
- element.bind('blur keyup change', function() {
+ element.on('blur keyup change', function() {
scope.$apply(read);
});
read(); // initialize
// Write data to the model
function read() {
- ngModel.$setViewValue(element.html());
+ var html = element.html();
+ // When we clear the content editable the browser leaves a <br> behind
+ // If strip-br attribute is provided then we strip this out
+ if( attrs.stripBr && html == '<br>' ) {
+ html = '';
+ }
+ ngModel.$setViewValue(html);
}
}
};
@@ -13274,6 +14202,7 @@
<form name="myForm">
<div contenteditable
name="myWidget" ng-model="userContent"
+ strip-br="true"
required>Change me!</div>
<span ng-show="myForm.myWidget.$error.required">Required!</span>
<hr>
@@ -13310,8 +14239,8 @@
ngModelSet = ngModelGet.assign;
if (!ngModelSet) {
- throw Error(NON_ASSIGNABLE_MODEL_EXPRESSION + $attr.ngModel +
- ' (' + startingTag($element) + ')');
+ throw minErr('ngModel')('nonassign', "Expression '{0}' is non-assignable. Element: {1}",
+ $attr.ngModel, startingTag($element));
}
/**
@@ -13412,8 +14341,8 @@
* For example {@link ng.directive:input input} or
* {@link ng.directive:select select} directives call it.
*
- * It internally calls all `parsers` and if resulted value is valid, updates the model and
- * calls all registered change listeners.
+ * It internally calls all `$parsers` (including validators) and updates the `$modelValue` and the actual model path.
+ * Lastly it calls all registered change listeners.
*
* @param {string} value Value from the view.
*/
@@ -13478,8 +14407,9 @@
* @element input
*
* @description
- * Is directive that tells Angular to do two-way data binding. It works together with `input`,
- * `select`, `textarea`. You can easily write your own directives to use `ngModel` as well.
+ * Is a directive that tells Angular to do two-way data binding. It works together with `input`,
+ * `select`, `textarea` and even custom form controls that use {@link ng.directive:ngModel.NgModelController
+ * NgModelController} exposed by this directive.
*
* `ngModel` is responsible for:
*
@@ -13490,6 +14420,10 @@
* - setting related css class onto the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`),
* - register the control with parent {@link ng.directive:form form}.
*
+ * Note: `ngModel` will try to bind to the property given by evaluating the expression on the
+ * current scope. If the property doesn't already exist on this scope, it will be created
+ * implicitly and added to the scope.
+ *
* For basic examples, how to use `ngModel`, see:
*
* - {@link ng.directive:input input}
@@ -13515,7 +14449,7 @@
formCtrl.$addControl(modelCtrl);
- element.bind('$destroy', function() {
+ element.on('$destroy', function() {
formCtrl.$removeControl(modelCtrl);
});
}
@@ -13630,8 +14564,9 @@
</script>
<form name="myForm" ng-controller="Ctrl">
List: <input name="namesInput" ng-model="names" ng-list required>
- <span class="error" ng-show="myForm.list.$error.required">
+ <span class="error" ng-show="myForm.namesInput.$error.required">
Required!</span>
+ <br>
<tt>names = {{names}}</tt><br/>
<tt>myForm.namesInput.$valid = {{myForm.namesInput.$valid}}</tt><br/>
<tt>myForm.namesInput.$error = {{myForm.namesInput.$error}}</tt><br/>
@@ -13643,12 +14578,14 @@
it('should initialize to model', function() {
expect(binding('names')).toEqual('["igor","misko","vojta"]');
expect(binding('myForm.namesInput.$valid')).toEqual('true');
+ expect(element('span.error').css('display')).toBe('none');
});
it('should be invalid if empty', function() {
input('names').enter('');
expect(binding('names')).toEqual('[]');
expect(binding('myForm.namesInput.$valid')).toEqual('false');
+ expect(element('span.error').css('display')).not().toBe('none');
});
</doc:scenario>
</doc:example>
@@ -13698,7 +14635,7 @@
} else {
return function(scope, elm, attr) {
scope.$watch(attr.ngValue, function valueWatchAction(value) {
- attr.$set('value', value, false);
+ attr.$set('value', value);
});
};
}
@@ -13718,10 +14655,9 @@
* Typically, you don't use `ngBind` directly, but instead you use the double curly markup like
* `{{ expression }}` which is similar but less verbose.
*
- * One scenario in which the use of `ngBind` is preferred over `{{ expression }}` binding is when
- * it's desirable to put bindings into template that is momentarily displayed by the browser in its
- * raw state before Angular compiles it. Since `ngBind` is an element attribute, it makes the
- * bindings invisible to the user while the page is loading.
+ * It is preferrable to use `ngBind` instead of `{{ expression }}` when a template is momentarily
+ * displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an
+ * element attribute, it makes the bindings invisible to the user while the page is loading.
*
* An alternative solution to this problem would be using the
* {@link ng.directive:ngCloak ngCloak} directive.
@@ -13767,10 +14703,11 @@
*
* @description
* The `ngBindTemplate` directive specifies that the element
- * text should be replaced with the template in ngBindTemplate.
- * Unlike ngBind the ngBindTemplate can contain multiple `{{` `}}`
- * expressions. (This is required since some HTML elements
- * can not have SPAN elements such as TITLE, or OPTION to name a few.)
+ * text content should be replaced with the interpolation of the template
+ * in the `ngBindTemplate` attribute.
+ * Unlike `ngBind`, the `ngBindTemplate` can contain multiple `{{` `}}`
+ * expressions. This directive is needed since some HTML elements
+ * (such as TITLE and OPTION) cannot contain SPAN elements.
*
* @element ANY
* @param {string} ngBindTemplate template of form
@@ -13822,23 +14759,27 @@
/**
* @ngdoc directive
- * @name ng.directive:ngBindHtmlUnsafe
+ * @name ng.directive:ngBindHtml
*
* @description
* Creates a binding that will innerHTML the result of evaluating the `expression` into the current
- * element. *The innerHTML-ed content will not be sanitized!* You should use this directive only if
- * {@link ngSanitize.directive:ngBindHtml ngBindHtml} directive is too
- * restrictive and when you absolutely trust the source of the content you are binding to.
+ * element in a secure way. By default, the innerHTML-ed content will be sanitized using the {@link
+ * ngSanitize.$sanitize $sanitize} service. To utilize this functionality, ensure that `$sanitize`
+ * is available, for example, by including {@link ngSanitize} in your module's dependencies (not in
+ * core Angular.) You may also bypass sanitization for values you know are safe. To do so, bind to
+ * an explicitly trusted value via {@link ng.$sce#trustAsHtml $sce.trustAsHtml}. See the example
+ * under {@link ng.$sce#Example Strict Contextual Escaping (SCE)}.
*
- * See {@link ngSanitize.$sanitize $sanitize} docs for examples.
+ * Note: If a `$sanitize` service is unavailable and the bound value isn't explicitly trusted, you
+ * will have an exception (instead of an exploit.)
*
* @element ANY
- * @param {expression} ngBindHtmlUnsafe {@link guide/expression Expression} to evaluate.
+ * @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate.
*/
-var ngBindHtmlUnsafeDirective = [function() {
+var ngBindHtmlDirective = ['$sce', function($sce) {
return function(scope, element, attr) {
- element.addClass('ng-binding').data('$binding', attr.ngBindHtmlUnsafe);
- scope.$watch(attr.ngBindHtmlUnsafe, function ngBindHtmlUnsafeWatchAction(value) {
+ element.addClass('ng-binding').data('$binding', attr.ngBindHtml);
+ scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function ngBindHtmlWatchAction(value) {
element.html(value || '');
});
};
@@ -13846,59 +14787,71 @@
function classDirective(name, selector) {
name = 'ngClass' + name;
- return ngDirective(function(scope, element, attr) {
- var oldVal = undefined;
+ return function() {
+ return {
+ restrict: 'AC',
+ link: function(scope, element, attr) {
+ var oldVal = undefined;
- scope.$watch(attr[name], ngClassWatchAction, true);
+ scope.$watch(attr[name], ngClassWatchAction, true);
- attr.$observe('class', function(value) {
- var ngClass = scope.$eval(attr[name]);
- ngClassWatchAction(ngClass, ngClass);
- });
+ attr.$observe('class', function(value) {
+ ngClassWatchAction(scope.$eval(attr[name]));
+ });
- if (name !== 'ngClass') {
- scope.$watch('$index', function($index, old$index) {
- var mod = $index & 1;
- if (mod !== old$index & 1) {
- if (mod === selector) {
- addClass(scope.$eval(attr[name]));
- } else {
- removeClass(scope.$eval(attr[name]));
+ if (name !== 'ngClass') {
+ scope.$watch('$index', function($index, old$index) {
+ var mod = $index & 1;
+ if (mod !== old$index & 1) {
+ if (mod === selector) {
+ addClass(scope.$eval(attr[name]));
+ } else {
+ removeClass(scope.$eval(attr[name]));
+ }
+ }
+ });
+ }
+
+
+ function ngClassWatchAction(newVal) {
+ if (selector === true || scope.$index % 2 === selector) {
+ if (oldVal && !equals(newVal,oldVal)) {
+ removeClass(oldVal);
+ }
+ addClass(newVal);
}
+ oldVal = copy(newVal);
}
- });
- }
- function ngClassWatchAction(newVal) {
- if (selector === true || scope.$index % 2 === selector) {
- if (oldVal && !equals(newVal,oldVal)) {
- removeClass(oldVal);
+ function removeClass(classVal) {
+ attr.$removeClass(flattenClasses(classVal));
}
- addClass(newVal);
- }
- oldVal = copy(newVal);
- }
- function removeClass(classVal) {
- if (isObject(classVal) && !isArray(classVal)) {
- classVal = map(classVal, function(v, k) { if (v) return k });
- }
- element.removeClass(isArray(classVal) ? classVal.join(' ') : classVal);
- }
+ function addClass(classVal) {
+ attr.$addClass(flattenClasses(classVal));
+ }
+ function flattenClasses(classVal) {
+ if(isArray(classVal)) {
+ return classVal.join(' ');
+ } else if (isObject(classVal)) {
+ var classes = [], i = 0;
+ forEach(classVal, function(v, k) {
+ if (v) {
+ classes.push(k);
+ }
+ });
+ return classes.join(' ');
+ }
- function addClass(classVal) {
- if (isObject(classVal) && !isArray(classVal)) {
- classVal = map(classVal, function(v, k) { if (v) return k });
+ return classVal;
+ };
}
- if (classVal) {
- element.addClass(isArray(classVal) ? classVal.join(' ') : classVal);
- }
- }
- });
+ };
+ };
}
/**
@@ -13906,31 +14859,110 @@
* @name ng.directive:ngClass
*
* @description
- * The `ngClass` allows you to set CSS class on HTML element dynamically by databinding an
- * expression that represents all classes to be added.
+ * The `ngClass` allows you to set CSS classes on HTML an element, dynamically, by databinding
+ * an expression that represents all classes to be added.
*
* The directive won't add duplicate classes if a particular class was already set.
*
* When the expression changes, the previously added classes are removed and only then the
* new classes are added.
*
+ * @animations
+ * add - happens just before the class is applied to the element
+ * remove - happens just before the class is removed from the element
+ *
* @element ANY
* @param {expression} ngClass {@link guide/expression Expression} to eval. The result
* of the evaluation can be a string representing space delimited class
- * names, an array, or a map of class names to boolean values.
+ * names, an array, or a map of class names to boolean values. In the case of a map, the
+ * names of the properties whose values are truthy will be added as css classes to the
+ * element.
*
- * @example
+ * @example Example that demostrates basic bindings via ngClass directive.
<example>
<file name="index.html">
+ <p ng-class="{strike: strike, bold: bold, red: red}">Map Syntax Example</p>
+ <input type="checkbox" ng-model="bold"> bold
+ <input type="checkbox" ng-model="strike"> strike
+ <input type="checkbox" ng-model="red"> red
+ <hr>
+ <p ng-class="style">Using String Syntax</p>
+ <input type="text" ng-model="style" placeholder="Type: bold strike red">
+ <hr>
+ <p ng-class="[style1, style2, style3]">Using Array Syntax</p>
+ <input ng-model="style1" placeholder="Type: bold"><br>
+ <input ng-model="style2" placeholder="Type: strike"><br>
+ <input ng-model="style3" placeholder="Type: red"><br>
+ </file>
+ <file name="style.css">
+ .strike {
+ text-decoration: line-through;
+ }
+ .bold {
+ font-weight: bold;
+ }
+ .red {
+ color: red;
+ }
+ </file>
+ <file name="scenario.js">
+ it('should let you toggle the class', function() {
+
+ expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/bold/);
+ expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/red/);
+
+ input('bold').check();
+ expect(element('.doc-example-live p:first').prop('className')).toMatch(/bold/);
+
+ input('red').check();
+ expect(element('.doc-example-live p:first').prop('className')).toMatch(/red/);
+ });
+
+ it('should let you toggle string example', function() {
+ expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe('');
+ input('style').enter('red');
+ expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe('red');
+ });
+
+ it('array example should have 3 classes', function() {
+ expect(element('.doc-example-live p:last').prop('className')).toBe('');
+ input('style1').enter('bold');
+ input('style2').enter('strike');
+ input('style3').enter('red');
+ expect(element('.doc-example-live p:last').prop('className')).toBe('bold strike red');
+ });
+ </file>
+ </example>
+
+ ## Animations
+
+ Example that demostrates how addition and removal of classes can be animated.
+
+ <example animations="true">
+ <file name="index.html">
<input type="button" value="set" ng-click="myVar='my-class'">
<input type="button" value="clear" ng-click="myVar=''">
<br>
<span ng-class="myVar">Sample Text</span>
</file>
<file name="style.css">
- .my-class {
+ .my-class-add, .my-class-remove {
+ -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
+ -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
+ -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
+ transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
+ }
+
+ .my-class,
+ .my-class-add.my-class-add-active {
color: red;
+ font-size:3em;
}
+
+ .my-class-remove.my-class-remove-active {
+ font-size:1.0em;
+ color:black;
+ }
</file>
<file name="scenario.js">
it('should check ng-class', function() {
@@ -14063,7 +15095,7 @@
*
* <pre>
* [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
- * display: none;
+ * display: none !important;
* }
* </pre>
*
@@ -14121,7 +15153,7 @@
* * Controller — The `ngController` directive specifies a Controller class; the class has
* methods that typically express the business logic behind the application.
*
- * Note that an alternative way to define controllers is via the {@link ng.$route $route} service.
+ * Note that an alternative way to define controllers is via the {@link ngRoute.$route $route} service.
*
* @element ANY
* @scope
@@ -14141,32 +15173,32 @@
<doc:example>
<doc:source>
<script>
- function SettingsController() {
+ function SettingsController1() {
this.name = "John Smith";
this.contacts = [
{type: 'phone', value: '408 555 1212'},
{type: 'email', value: 'john.smith(a)example.org'} ];
};
- SettingsController.prototype.greet = function() {
+ SettingsController1.prototype.greet = function() {
alert(this.name);
};
- SettingsController.prototype.addContact = function() {
+ SettingsController1.prototype.addContact = function() {
this.contacts.push({type: 'email', value: 'yourname(a)example.org'});
};
- SettingsController.prototype.removeContact = function(contactToRemove) {
+ SettingsController1.prototype.removeContact = function(contactToRemove) {
var index = this.contacts.indexOf(contactToRemove);
this.contacts.splice(index, 1);
};
- SettingsController.prototype.clearContact = function(contact) {
+ SettingsController1.prototype.clearContact = function(contact) {
contact.type = 'phone';
contact.value = '';
};
</script>
- <div ng-controller="SettingsController as settings">
+ <div id="ctrl-as-exmpl" ng-controller="SettingsController1 as settings">
Name: <input type="text" ng-model="settings.name"/>
[ <a href="" ng-click="settings.greet()">greet</a> ]<br/>
Contact:
@@ -14185,29 +15217,26 @@
</div>
</doc:source>
<doc:scenario>
- it('should check controller', function() {
- expect(element('.doc-example-live div>:input').val()).toBe('John Smith');
- expect(element('.doc-example-live li:nth-child(1) input').val())
+ it('should check controller as', function() {
+ expect(element('#ctrl-as-exmpl>:input').val()).toBe('John Smith');
+ expect(element('#ctrl-as-exmpl li:nth-child(1) input').val())
.toBe('408 555 1212');
- expect(element('.doc-example-live li:nth-child(2) input').val())
+ expect(element('#ctrl-as-exmpl li:nth-child(2) input').val())
.toBe('john.smith(a)example.org');
- element('.doc-example-live li:first a:contains("clear")').click();
- expect(element('.doc-example-live li:first input').val()).toBe('');
+ element('#ctrl-as-exmpl li:first a:contains("clear")').click();
+ expect(element('#ctrl-as-exmpl li:first input').val()).toBe('');
- element('.doc-example-live li:last a:contains("add")').click();
- expect(element('.doc-example-live li:nth-child(3) input').val())
+ element('#ctrl-as-exmpl li:last a:contains("add")').click();
+ expect(element('#ctrl-as-exmpl li:nth-child(3) input').val())
.toBe('yourname(a)example.org');
});
</doc:scenario>
</doc:example>
-
-
-
<doc:example>
<doc:source>
<script>
- function SettingsController($scope) {
+ function SettingsController2($scope) {
$scope.name = "John Smith";
$scope.contacts = [
{type:'phone', value:'408 555 1212'},
@@ -14232,7 +15261,7 @@
};
}
</script>
- <div ng-controller="SettingsController">
+ <div id="ctrl-exmpl" ng-controller="SettingsController2">
Name: <input type="text" ng-model="name"/>
[ <a href="" ng-click="greet()">greet</a> ]<br/>
Contact:
@@ -14252,17 +15281,17 @@
</doc:source>
<doc:scenario>
it('should check controller', function() {
- expect(element('.doc-example-live div>:input').val()).toBe('John Smith');
- expect(element('.doc-example-live li:nth-child(1) input').val())
+ expect(element('#ctrl-exmpl>:input').val()).toBe('John Smith');
+ expect(element('#ctrl-exmpl li:nth-child(1) input').val())
.toBe('408 555 1212');
- expect(element('.doc-example-live li:nth-child(2) input').val())
+ expect(element('#ctrl-exmpl li:nth-child(2) input').val())
.toBe('john.smith(a)example.org');
- element('.doc-example-live li:first a:contains("clear")').click();
- expect(element('.doc-example-live li:first input').val()).toBe('');
+ element('#ctrl-exmpl li:first a:contains("clear")').click();
+ expect(element('#ctrl-exmpl li:first input').val()).toBe('');
- element('.doc-example-live li:last a:contains("add")').click();
- expect(element('.doc-example-live li:nth-child(3) input').val())
+ element('#ctrl-exmpl li:last a:contains("add")').click();
+ expect(element('#ctrl-exmpl li:nth-child(3) input').val())
.toBe('yourname(a)example.org');
});
</doc:scenario>
@@ -14355,13 +15384,13 @@
*/
var ngEventDirectives = {};
forEach(
- 'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress'.split(' '),
+ 'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur'.split(' '),
function(name) {
var directiveName = directiveNormalize('ng-' + name);
ngEventDirectives[directiveName] = ['$parse', function($parse) {
return function(scope, element, attr) {
var fn = $parse(attr[directiveName]);
- element.bind(lowercase(name), function(event) {
+ element.on(lowercase(name), function(event) {
scope.$apply(function() {
fn(scope, {$event:event});
});
@@ -14538,10 +15567,11 @@
* Enables binding angular expressions to onsubmit events.
*
* Additionally it prevents the default action (which for form means sending the request to the
- * server and reloading the current page).
+ * server and reloading the current page) **but only if the form does not contain an `action`
+ * attribute**.
*
* @element form
- * @param {expression} ngSubmit {@link guide/expression Expression} to eval.
+ * @param {expression} ngSubmit {@link guide/expression Expression} to eval. (Event object is available as `$event`)
*
* @example
<doc:example>
@@ -14581,14 +15611,39 @@
</doc:scenario>
</doc:example>
*/
-var ngSubmitDirective = ngDirective(function(scope, element, attrs) {
- element.bind('submit', function() {
- scope.$apply(attrs.ngSubmit);
- });
-});
/**
* @ngdoc directive
+ * @name ng.directive:ngFocus
+ *
+ * @description
+ * Specify custom behavior on focus event.
+ *
+ * @element window, input, select, textarea, a
+ * @param {expression} ngFocus {@link guide/expression Expression} to evaluate upon
+ * focus. (Event object is available as `$event`)
+ *
+ * @example
+ * See {@link ng.directive:ngClick ngClick}
+ */
+
+/**
+ * @ngdoc directive
+ * @name ng.directive:ngBlur
+ *
+ * @description
+ * Specify custom behavior on blur event.
+ *
+ * @element window, input, select, textarea, a
+ * @param {expression} ngBlur {@link guide/expression Expression} to evaluate upon
+ * blur. (Event object is available as `$event`)
+ *
+ * @example
+ * See {@link ng.directive:ngClick ngClick}
+ */
+
+/**
+ * @ngdoc directive
* @name ng.directive:ngIf
* @restrict A
*
@@ -14617,7 +15672,7 @@
* jQuery's `.addClass()` method, and the element is later removed. When `ngIf` recreates the element
* the added class will be lost because the original compiled state is used to regenerate the element.
*
- * Additionally, you can provide animations via the ngAnimate attribute to animate the **enter**
+ * Additionally, you can provide animations via the ngAnimate module to animate the **enter**
* and **leave** effects.
*
* @animations
@@ -14634,36 +15689,37 @@
<file name="index.html">
Click me: <input type="checkbox" ng-model="checked" ng-init="checked=true" /><br/>
Show when checked:
- <span ng-if="checked" ng-animate="'example'">
+ <span ng-if="checked" class="animate-if">
I'm removed when the checkbox is unchecked.
</span>
</file>
<file name="animations.css">
- .example-leave, .example-enter {
+ .animate-if {
+ background:white;
+ border:1px solid black;
+ padding:10px;
+ }
+
+ .animate-if.ng-enter, .animate-if.ng-leave {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
- -ms-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
}
- .example-enter {
+ .animate-if.ng-enter,
+ .animate-if.ng-leave.ng-leave-active {
opacity:0;
}
- .example-enter.example-enter-active {
- opacity:1;
- }
- .example-leave {
+ .animate-if.ng-enter.ng-enter-active,
+ .animate-if.ng-leave {
opacity:1;
}
- .example-leave.example-leave-active {
- opacity:0;
- }
</file>
</example>
*/
-var ngIfDirective = ['$animator', function($animator) {
+var ngIfDirective = ['$animate', function($animate) {
return {
transclude: 'element',
priority: 1000,
@@ -14671,11 +15727,10 @@
restrict: 'A',
compile: function (element, attr, transclude) {
return function ($scope, $element, $attr) {
- var animate = $animator($scope, $attr);
var childElement, childScope;
$scope.$watch($attr.ngIf, function ngIfWatchAction(value) {
if (childElement) {
- animate.leave(childElement);
+ $animate.leave(childElement);
childElement = undefined;
}
if (childScope) {
@@ -14686,7 +15741,7 @@
childScope = $scope.$new();
transclude(childScope, function (clone) {
childElement = clone;
- animate.enter(clone, $element.parent(), $element);
+ $animate.enter(clone, $element.parent(), $element);
});
}
});
@@ -14703,17 +15758,27 @@
* @description
* Fetches, compiles and includes an external HTML fragment.
*
- * Keep in mind that Same Origin Policy applies to included resources
- * (e.g. ngInclude won't work for cross-domain requests on all browsers and for
- * file:// access on some browsers).
+ * Keep in mind that:
*
- * Additionally, you can also provide animations via the ngAnimate attribute to animate the **enter**
- * and **leave** effects.
+ * - by default, the template URL is restricted to the same domain and protocol as the
+ * application document. This is done by calling {@link ng.$sce#getTrustedResourceUrl
+ * $sce.getTrustedResourceUrl} on it. To load templates from other domains and/or protocols,
+ * you may either either {@link ng.$sceDelegateProvider#resourceUrlWhitelist whitelist them} or
+ * {@link ng.$sce#trustAsResourceUrl wrap it} into a trusted value. Refer Angular's {@link
+ * ng.$sce Strict Contextual Escaping}.
+ * - in addition, the browser's
+ * {@link https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLH…
+ * Same Origin Policy} and {@link http://www.w3.org/TR/cors/ Cross-Origin Resource Sharing
+ * (CORS)} policy apply that may further restrict whether the template is successfully loaded.
+ * (e.g. ngInclude won't work for cross-domain requests on all browsers and for `file://`
+ * access on some browsers)
*
* @animations
- * enter - happens just after the ngInclude contents change and a new DOM element is created and injected into the ngInclude container
- * leave - happens just after the ngInclude contents change and just before the former contents are removed from the DOM
+ * enter - animation is used to bring new content into the browser.
+ * leave - animation is used to animate existing content away.
*
+ * The enter and leave animation occur concurrently.
+ *
* @scope
*
* @param {string} ngInclude|src angular expression evaluating to URL. If the source is a string constant,
@@ -14736,9 +15801,9 @@
</select>
url of the template: <tt>{{template.url}}</tt>
<hr/>
- <div class="example-animate-container"
- ng-include="template.url"
- ng-animate="{enter: 'example-enter', leave: 'example-leave'}"></div>
+ <div class="example-animate-container">
+ <div class="include-example" ng-include="template.url"></div>
+ </div>
</div>
</file>
<file name="script.js">
@@ -14750,17 +15815,27 @@
}
</file>
<file name="template1.html">
- <div>Content of template1.html</div>
+ Content of template1.html
</file>
<file name="template2.html">
- <div>Content of template2.html</div>
+ Content of template2.html
</file>
<file name="animations.css">
- .example-leave,
- .example-enter {
+ .example-animate-container {
+ position:relative;
+ background:white;
+ border:1px solid black;
+ height:40px;
+ overflow:hidden;
+ }
+
+ .example-animate-container > div {
+ padding:10px;
+ }
+
+ .include-example.ng-enter, .include-example.ng-leave {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
- -ms-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
@@ -14769,24 +15844,21 @@
left:0;
right:0;
bottom:0;
- }
-
- .example-animate-container > * {
display:block;
padding:10px;
}
- .example-enter {
+ .include-example.ng-enter {
top:-50px;
}
- .example-enter.example-enter-active {
+ .include-example.ng-enter.ng-enter-active {
top:0;
}
- .example-leave {
+ .include-example.ng-leave {
top:0;
}
- .example-leave.example-leave-active {
+ .include-example.ng-leave.ng-leave-active {
top:50px;
}
</file>
@@ -14802,7 +15874,7 @@
});
it('should change to blank', function() {
select('template').option('');
- expect(element('.doc-example-live [ng-include]').text()).toEqual('');
+ expect(element('.doc-example-live [ng-include]')).toBe(undefined);
});
</file>
</example>
@@ -14827,57 +15899,67 @@
* @description
* Emitted every time the ngInclude content is reloaded.
*/
-var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile', '$animator',
- function($http, $templateCache, $anchorScroll, $compile, $animator) {
+var NG_INCLUDE_PRIORITY = 500;
+var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile', '$animate', '$sce',
+ function($http, $templateCache, $anchorScroll, $compile, $animate, $sce) {
return {
restrict: 'ECA',
terminal: true,
+ priority: NG_INCLUDE_PRIORITY,
compile: function(element, attr) {
var srcExp = attr.ngInclude || attr.src,
onloadExp = attr.onload || '',
autoScrollExp = attr.autoscroll;
- return function(scope, element, attr) {
- var animate = $animator(scope, attr);
+ element.html('');
+ var anchor = jqLite(document.createComment(' ngInclude: ' + srcExp + ' '));
+ element.replaceWith(anchor);
+
+ return function(scope) {
var changeCounter = 0,
- childScope;
+ currentScope,
+ currentElement;
- var clearContent = function() {
- if (childScope) {
- childScope.$destroy();
- childScope = null;
+ var cleanupLastIncludeContent = function() {
+ if (currentScope) {
+ currentScope.$destroy();
+ currentScope = null;
}
- animate.leave(element.contents(), element);
+ if(currentElement) {
+ $animate.leave(currentElement);
+ currentElement = null;
+ }
};
- scope.$watch(srcExp, function ngIncludeWatchAction(src) {
+ scope.$watch($sce.parseAsResourceUrl(srcExp), function ngIncludeWatchAction(src) {
var thisChangeId = ++changeCounter;
if (src) {
$http.get(src, {cache: $templateCache}).success(function(response) {
if (thisChangeId !== changeCounter) return;
+ var newScope = scope.$new();
- if (childScope) childScope.$destroy();
- childScope = scope.$new();
- animate.leave(element.contents(), element);
+ cleanupLastIncludeContent();
- var contents = jqLite('<div/>').html(response).contents();
+ currentScope = newScope;
+ currentElement = element.clone();
+ currentElement.html(response);
+ $animate.enter(currentElement, null, anchor);
- animate.enter(contents, element);
- $compile(contents)(childScope);
+ $compile(currentElement, false, NG_INCLUDE_PRIORITY - 1)(currentScope);
if (isDefined(autoScrollExp) && (!autoScrollExp || scope.$eval(autoScrollExp))) {
$anchorScroll();
}
- childScope.$emit('$includeContentLoaded');
+ currentScope.$emit('$includeContentLoaded');
scope.$eval(onloadExp);
}).error(function() {
- if (thisChangeId === changeCounter) clearContent();
+ if (thisChangeId === changeCounter) cleanupLastIncludeContent();
});
scope.$emit('$includeContentRequested');
} else {
- clearContent();
+ cleanupLastIncludeContent();
}
});
};
@@ -14961,7 +16043,7 @@
* @description
* # Overview
* `ngPluralize` is a directive that displays messages according to en-US localization rules.
- * These rules are bundled with angular.js and the rules can be overridden
+ * These rules are bundled with angular.js, but can be overridden
* (see {@link guide/i18n Angular i18n} dev guide). You configure ngPluralize directive
* by specifying the mappings between
* {@link http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_r…
@@ -14974,8 +16056,8 @@
*
* While a plural category may match many numbers (for example, in en-US locale, "other" can match
* any number that is not 1), an explicit number rule can only match one number. For example, the
- * explicit number rule for "3" matches the number 3. You will see the use of plural categories
- * and explicit number rules throughout later parts of this documentation.
+ * explicit number rule for "3" matches the number 3. There are examples of plural categories
+ * and explicit number rules throughout the rest of this documentation.
*
* # Configuring ngPluralize
* You configure ngPluralize by providing 2 attributes: `count` and `when`.
@@ -14985,8 +16067,7 @@
* Angular expression}; these are evaluated on the current scope for its bound value.
*
* The `when` attribute specifies the mappings between plural categories and the actual
- * string to be displayed. The value of the attribute should be a JSON object so that Angular
- * can interpret it correctly.
+ * string to be displayed. The value of the attribute should be a JSON object.
*
* The following example shows how to configure ngPluralize:
*
@@ -15128,13 +16209,20 @@
restrict: 'EA',
link: function(scope, element, attr) {
var numberExp = attr.count,
- whenExp = element.attr(attr.$attr.when), // this is because we have {{}} in attrs
+ whenExp = attr.$attr.when && element.attr(attr.$attr.when), // we have {{}} in attrs
offset = attr.offset || 0,
- whens = scope.$eval(whenExp),
+ whens = scope.$eval(whenExp) || {},
whensExpFns = {},
startSymbol = $interpolate.startSymbol(),
- endSymbol = $interpolate.endSymbol();
+ endSymbol = $interpolate.endSymbol(),
+ isWhen = /^when(Minus)?(.+)$/;
+ forEach(attr, function(expression, attributeName) {
+ if (isWhen.test(attributeName)) {
+ whens[lowercase(attributeName.replace('when', '').replace('Minus', '-'))] =
+ element.attr(attr.$attr[attributeName]);
+ }
+ });
forEach(whens, function(expression, key) {
whensExpFns[key] =
$interpolate(expression.replace(BRACE, startSymbol + numberExp + '-' +
@@ -15170,14 +16258,60 @@
*
* Special properties are exposed on the local scope of each template instance, including:
*
- * * `$index` – `{number}` – iterator offset of the repeated element (0..length-1)
- * * `$first` – `{boolean}` – true if the repeated element is first in the iterator.
- * * `$middle` – `{boolean}` – true if the repeated element is between the first and last in the iterator.
- * * `$last` – `{boolean}` – true if the repeated element is last in the iterator.
+ * | Variable | Type | Details |
+ * |-----------|-----------------|-----------------------------------------------------------------------------|
+ * | `$index` | {@type number} | iterator offset of the repeated element (0..length-1) |
+ * | `$first` | {@type boolean} | true if the repeated element is first in the iterator. |
+ * | `$middle` | {@type boolean} | true if the repeated element is between the first and last in the iterator. |
+ * | `$last` | {@type boolean} | true if the repeated element is last in the iterator. |
+ * | `$even` | {@type boolean} | true if the iterator position `$index` is even (otherwise false). |
+ * | `$odd` | {@type boolean} | true if the iterator position `$index` is odd (otherwise false). |
*
- * Additionally, you can also provide animations via the ngAnimate attribute to animate the **enter**,
- * **leave** and **move** effects.
*
+ * # Special repeat start and end points
+ * To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending
+ * the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively.
+ * The **ng-repeat-start** directive works the same as **ng-repeat**, but will repeat all the HTML code (including the tag it's defined on)
+ * up to and including the ending HTML tag where **ng-repeat-end** is placed.
+ *
+ * The example below makes use of this feature:
+ * <pre>
+ * <header ng-repeat-start="item in items">
+ * Header {{ item }}
+ * </header>
+ * <div class="body">
+ * Body {{ item }}
+ * </div>
+ * <footer ng-repeat-end>
+ * Footer {{ item }}
+ * </footer>
+ * </pre>
+ *
+ * And with an input of {@type ['A','B']} for the items variable in the example above, the output will evaluate to:
+ * <pre>
+ * <header>
+ * Header A
+ * </header>
+ * <div class="body">
+ * Body A
+ * </div>
+ * <footer>
+ * Footer A
+ * </footer>
+ * <header>
+ * Header B
+ * </header>
+ * <div class="body">
+ * Body B
+ * </div>
+ * <footer>
+ * Footer B
+ * </footer>
+ * </pre>
+ *
+ * The custom start and end points for ngRepeat also support all other HTML directive syntax flavors provided in AngularJS (such
+ * as **data-ng-repeat-start**, **x-ng-repeat-start** and **ng:repeat-start**).
+ *
* @animations
* enter - when a new item is added to the list or when an item is revealed after a filter
* leave - when an item is removed from the list or when an item is filtered out
@@ -15192,7 +16326,7 @@
* * `variable in expression` – where variable is the user defined loop variable and `expression`
* is a scope expression giving the collection to enumerate.
*
- * For example: `track in cd.tracks`.
+ * For example: `album in artist.albums`.
*
* * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers,
* and `expression` is the scope expression giving the collection to enumerate.
@@ -15200,10 +16334,11 @@
* For example: `(name, age) in {'adam':10, 'amalie':12}`.
*
* * `variable in expression track by tracking_expression` – You can also provide an optional tracking function
- * which can be used to associate the objects in the collection with the DOM elements. If no tractking function
+ * which can be used to associate the objects in the collection with the DOM elements. If no tracking function
* is specified the ng-repeat associates elements by identity in the collection. It is an error to have
- * more then one tractking function to resolve to the same key. (This would mean that two distinct objects are
- * mapped to the same DOM element, which is not possible.)
+ * more than one tracking function to resolve to the same key. (This would mean that two distinct objects are
+ * mapped to the same DOM element, which is not possible.) Filters should be applied to the expression,
+ * before specifying a tracking expression.
*
* For example: `item in items` is equivalent to `item in items track by $id(item)'. This implies that the DOM elements
* will be associated by item identity in the array.
@@ -15213,10 +16348,13 @@
* with the corresponding item in the array by identity. Moving the same object in array would move the DOM
* element in the same way ian the DOM.
*
- * For example: `item in items track by item.id` Is a typical pattern when the items come from the database. In this
+ * For example: `item in items track by item.id` is a typical pattern when the items come from the database. In this
* case the object identity does not matter. Two objects are considered equivalent as long as their `id`
* property is same.
*
+ * For example: `item in items | filter:searchText track by item.id` is a pattern that might be used to apply a filter
+ * to items in conjunction with a tracking expression.
+ *
* @example
* This example initializes the scope to a list of names and
* then uses `ngRepeat` to display every person:
@@ -15236,47 +16374,62 @@
]">
I have {{friends.length}} friends. They are:
<input type="search" ng-model="q" placeholder="filter friends..." />
- <ul>
- <li ng-repeat="friend in friends | filter:q"
- ng-animate="{enter: 'example-repeat-enter',
- leave: 'example-repeat-leave',
- move: 'example-repeat-move'}">
+ <ul class="example-animate-container">
+ <li class="animate-repeat" ng-repeat="friend in friends | filter:q">
[{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
</li>
</ul>
</div>
</file>
<file name="animations.css">
- .example-repeat-enter,
- .example-repeat-leave,
- .example-repeat-move {
+ .example-animate-container {
+ background:white;
+ border:1px solid black;
+ list-style:none;
+ margin:0;
+ padding:0;
+ }
+
+ .example-animate-container > li {
+ padding:10px;
+ list-style:none;
+ }
+
+ .animate-repeat.ng-enter,
+ .animate-repeat.ng-leave,
+ .animate-repeat.ng-move {
-webkit-transition:all linear 0.5s;
-moz-transition:all linear 0.5s;
- -ms-transition:all linear 0.5s;
-o-transition:all linear 0.5s;
transition:all linear 0.5s;
}
- .example-repeat-enter {
+ .animate-repeat.ng-enter {
line-height:0;
opacity:0;
+ padding-top:0;
+ padding-bottom:0;
}
- .example-repeat-enter.example-repeat-enter-active {
+ .animate-repeat.ng-enter.ng-enter-active {
line-height:20px;
opacity:1;
+ padding:10px;
}
- .example-repeat-leave {
+ .animate-repeat.ng-leave {
opacity:1;
line-height:20px;
+ padding:10px;
}
- .example-repeat-leave.example-repeat-leave-active {
+ .animate-repeat.ng-leave.ng-leave-active {
opacity:0;
line-height:0;
+ padding-top:0;
+ padding-bottom:0;
}
- .example-repeat-move { }
- .example-repeat-move.example-repeat-move-active { }
+ .animate-repeat.ng-move { }
+ .animate-repeat.ng-move.ng-move-active { }
</file>
<file name="scenario.js">
it('should render initial data set', function() {
@@ -15301,23 +16454,23 @@
</file>
</example>
*/
-var ngRepeatDirective = ['$parse', '$animator', function($parse, $animator) {
+var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
var NG_REMOVED = '$$NG_REMOVED';
+ var ngRepeatMinErr = minErr('ngRepeat');
return {
transclude: 'element',
priority: 1000,
terminal: true,
compile: function(element, attr, linker) {
return function($scope, $element, $attr){
- var animate = $animator($scope, $attr);
var expression = $attr.ngRepeat;
var match = expression.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),
- trackByExp, trackByExpGetter, trackByIdFn, lhs, rhs, valueIdentifier, keyIdentifier,
+ trackByExp, trackByExpGetter, trackByIdFn, trackByIdArrayFn, trackByIdObjFn, lhs, rhs, valueIdentifier, keyIdentifier,
hashFnLocals = {$id: hashKey};
if (!match) {
- throw Error("Expected ngRepeat in form of '_item_ in _collection_[ track by _id_]' but got '" +
- expression + "'.");
+ throw ngRepeatMinErr('iexp', "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.",
+ expression);
}
lhs = match[1];
@@ -15334,15 +16487,18 @@
return trackByExpGetter($scope, hashFnLocals);
};
} else {
- trackByIdFn = function(key, value) {
+ trackByIdArrayFn = function(key, value) {
return hashKey(value);
}
+ trackByIdObjFn = function(key) {
+ return key;
+ }
}
match = lhs.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);
if (!match) {
- throw Error("'item' in 'item in collection' should be identifier or (key, value) but got '" +
- lhs + "'.");
+ throw ngRepeatMinErr('iidexp', "'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'.",
+ lhs);
}
valueIdentifier = match[3] || match[1];
keyIdentifier = match[2];
@@ -15357,8 +16513,8 @@
//watch props
$scope.$watchCollection(rhs, function ngRepeatAction(collection){
var index, length,
- cursor = $element, // current position of the node
- nextCursor,
+ previousNode = $element[0], // current position of the node
+ nextNode,
// Same as lastBlockMap but it has the current state. It will become the
// lastBlockMap on the next iteration.
nextBlockMap = {},
@@ -15373,7 +16529,9 @@
if (isArrayLike(collection)) {
collectionKeys = collection;
+ trackByIdFn = trackByIdFn || trackByIdArrayFn;
} else {
+ trackByIdFn = trackByIdFn || trackByIdObjFn;
// if object, extract keys, sort them and use to determine order of iteration over obj props
collectionKeys = [];
for (key in collection) {
@@ -15400,11 +16558,11 @@
} else if (nextBlockMap.hasOwnProperty(trackById)) {
// restore lastBlockMap
forEach(nextBlockOrder, function(block) {
- if (block && block.element) lastBlockMap[block.id] = block;
+ if (block && block.startNode) lastBlockMap[block.id] = block;
});
// This is a duplicate and we need to throw an error
- throw new Error('Duplicates in a repeater are not allowed. Repeater: ' + expression +
- ' key: ' + trackById);
+ throw ngRepeatMinErr('dupes', "Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}",
+ expression, trackById);
} else {
// new never before seen block
nextBlockOrder[index] = { id: trackById };
@@ -15416,8 +16574,8 @@
for (key in lastBlockMap) {
if (lastBlockMap.hasOwnProperty(key)) {
block = lastBlockMap[key];
- animate.leave(block.element);
- block.element[0][NG_REMOVED] = true;
+ $animate.leave(block.elements);
+ forEach(block.elements, function(element) { element[NG_REMOVED] = true});
block.scope.$destroy();
}
}
@@ -15428,24 +16586,23 @@
value = collection[key];
block = nextBlockOrder[index];
- if (block.element) {
+ if (block.startNode) {
// if we have already seen this object, then we need to reuse the
// associated scope/element
childScope = block.scope;
- nextCursor = cursor[0];
+ nextNode = previousNode;
do {
- nextCursor = nextCursor.nextSibling;
- } while(nextCursor && nextCursor[NG_REMOVED]);
+ nextNode = nextNode.nextSibling;
+ } while(nextNode && nextNode[NG_REMOVED]);
- if (block.element[0] == nextCursor) {
+ if (block.startNode == nextNode) {
// do nothing
- cursor = block.element;
} else {
// existing item which got moved
- animate.move(block.element, null, cursor);
- cursor = block.element;
+ $animate.move(block.elements, null, jqLite(previousNode));
}
+ previousNode = block.endNode;
} else {
// new item which we don't know about
childScope = $scope.$new();
@@ -15457,13 +16614,16 @@
childScope.$first = (index === 0);
childScope.$last = (index === (arrayLength - 1));
childScope.$middle = !(childScope.$first || childScope.$last);
+ childScope.$odd = !(childScope.$even = index%2==0);
- if (!block.element) {
+ if (!block.startNode) {
linker(childScope, function(clone) {
- animate.enter(clone, null, cursor);
- cursor = clone;
+ $animate.enter(clone, null, jqLite(previousNode));
+ previousNode = clone;
block.scope = childScope;
- block.element = clone;
+ block.startNode = clone[0];
+ block.elements = clone;
+ block.endNode = clone[clone.length - 1];
nextBlockMap[block.id] = block;
});
}
@@ -15480,19 +16640,77 @@
* @name ng.directive:ngShow
*
* @description
- * The `ngShow` and `ngHide` directives show or hide a portion of the DOM tree (HTML)
- * conditionally based on **"truthy"** values evaluated within an {expression}. In other
- * words, if the expression assigned to **ngShow evaluates to a true value** then **the element is set to visible**
- * (via `display:block` in css) and **if false** then **the element is set to hidden** (so display:none).
- * With ngHide this is the reverse whereas true values cause the element itself to become
- * hidden.
+ * The `ngShow` directive shows and hides the given HTML element conditionally based on the expression
+ * provided to the ngShow attribute. The show and hide mechanism is a achieved by removing and adding
+ * the `ng-hide` CSS class onto the element. The `.ng-hide` CSS class is a predefined CSS class present
+ * in AngularJS which sets the display style to none (using an !important flag).
*
- * Additionally, you can also provide animations via the ngAnimate attribute to animate the **show**
- * and **hide** effects.
+ * <pre>
+ * <!-- when $scope.myValue is truthy (element is visible) -->
+ * <div ng-show="myValue"></div>
*
+ * <!-- when $scope.myValue is falsy (element is hidden) -->
+ * <div ng-show="myValue" class="ng-hide"></div>
+ * </pre>
+ *
+ * When the ngShow expression evaluates to false then the ng-hide CSS class is added to the class attribute
+ * on the element causing it to become hidden. When true, the ng-hide CSS class is removed
+ * from the element causing the element not to appear hidden.
+ *
+ * ## Why is !important used?
+ *
+ * You may be wondering why !important is used for the .ng-hide CSS class. This is because the `.ng-hide` selector
+ * can be easily overridden by heavier selectors. For example, something as simple
+ * as changing the display style on a HTML list item would make hidden elements appear visible.
+ * This also becomes a bigger issue when dealing with CSS frameworks.
+ *
+ * By using !important, the show and hide behavior will work as expected despite any clash between CSS selector
+ * specificity (when !important isn't used with any conflicting styles). If a developer chooses to override the
+ * styling to change how to hide an element then it is just a matter of using !important in their own CSS code.
+ *
+ * ### Overriding .ng-hide
+ *
+ * If you wish to change the hide behavior with ngShow/ngHide then this can be achieved by
+ * restating the styles for the .ng-hide class in CSS:
+ * <pre>
+ * .ng-hide {
+ * //!annotate CSS Specificity|Not to worry, this will override the AngularJS default...
+ * display:block!important;
+ *
+ * //this is just another form of hiding an element
+ * position:absolute;
+ * top:-9999px;
+ * left:-9999px;
+ * }
+ * </pre>
+ *
+ * Just remember to include the important flag so the CSS override will function.
+ *
+ * ## A note about animations with ngShow
+ *
+ * Animations in ngShow/ngHide work with the show and hide events that are triggered when the directive expression
+ * is true and false. This system works similar to the animation system present with ngClass, however, the
+ * only difference is that you must also include the !important flag to override the display property so
+ * that you can perform an animation when the element is hidden during the time of the animation.
+ *
+ * <pre>
+ * //
+ * //a working example can be found at the bottom of this page
+ * //
+ * .my-element.ng-hide-add, .my-element.ng-hide-remove {
+ * transition:0.5s linear all;
+ * display:block!important;
+ * }
+ *
+ * .my-element.ng-hide-add { ... }
+ * .my-element.ng-hide-add.ng-hide-add-active { ... }
+ * .my-element.ng-hide-remove { ... }
+ * .my-element.ng-hide-remove.ng-hide-remove-active { ... }
+ * </pre>
+ *
* @animations
- * show - happens after the ngShow expression evaluates to a truthy value and the contents are set to visible
- * hide - happens before the ngShow expression evaluates to a non truthy value and just before the contents are set to hidden
+ * addClass: .ng-hide - happens after the ngShow expression evaluates to a truthy value and the just before contents are set to visible
+ * removeClass: .ng-hide - happens after the ngShow expression evaluates to a non truthy value and just before the contents are set to hidden
*
* @element ANY
* @param {expression} ngShow If the {@link guide/expression expression} is truthy
@@ -15504,55 +16722,42 @@
Click me: <input type="checkbox" ng-model="checked"><br/>
<div>
Show:
- <span class="check-element"
- ng-show="checked"
- ng-animate="{show: 'example-show', hide: 'example-hide'}">
+ <div class="check-element animate-show" ng-show="checked">
<span class="icon-thumbs-up"></span> I show up when your checkbox is checked.
- </span>
+ </div>
</div>
<div>
Hide:
- <span class="check-element"
- ng-hide="checked"
- ng-animate="{show: 'example-show', hide: 'example-hide'}">
+ <div class="check-element animate-show" ng-hide="checked">
<span class="icon-thumbs-down"></span> I hide when your checkbox is checked.
- </span>
+ </div>
</div>
</file>
<file name="animations.css">
- .example-show, .example-hide {
+ .animate-show.ng-hide-add,
+ .animate-show.ng-hide-remove {
-webkit-transition:all linear 0.5s;
-moz-transition:all linear 0.5s;
- -ms-transition:all linear 0.5s;
-o-transition:all linear 0.5s;
transition:all linear 0.5s;
+ display:block!important;
}
- .example-show {
+ .animate-show.ng-hide-add.ng-hide-add-active,
+ .animate-show.ng-hide-remove {
line-height:0;
opacity:0;
padding:0 10px;
}
- .example-show-active.example-show-active {
- line-height:20px;
- opacity:1;
- padding:10px;
- border:1px solid black;
- background:white;
- }
- .example-hide {
+ .animate-show.ng-hide-add,
+ .animate-show.ng-hide-remove.ng-hide-remove-active {
line-height:20px;
opacity:1;
padding:10px;
border:1px solid black;
background:white;
}
- .example-hide-active.example-hide-active {
- line-height:0;
- opacity:0;
- padding:0 10px;
- }
.check-element {
padding:10px;
@@ -15573,12 +16778,10 @@
</file>
</example>
*/
-//TODO(misko): refactor to remove element from the DOM
-var ngShowDirective = ['$animator', function($animator) {
+var ngShowDirective = ['$animate', function($animate) {
return function(scope, element, attr) {
- var animate = $animator(scope, attr);
scope.$watch(attr.ngShow, function ngShowWatchAction(value){
- animate[toBoolean(value) ? 'show' : 'hide'](element);
+ $animate[toBoolean(value) ? 'removeClass' : 'addClass'](element, 'ng-hide');
});
};
}];
@@ -15589,19 +16792,77 @@
* @name ng.directive:ngHide
*
* @description
- * The `ngShow` and `ngHide` directives show or hide a portion of the DOM tree (HTML)
- * conditionally based on **"truthy"** values evaluated within an {expression}. In other
- * words, if the expression assigned to **ngShow evaluates to a true value** then **the element is set to visible**
- * (via `display:block` in css) and **if false** then **the element is set to hidden** (so display:none).
- * With ngHide this is the reverse whereas true values cause the element itself to become
- * hidden.
+ * The `ngHide` directive shows and hides the given HTML element conditionally based on the expression
+ * provided to the ngHide attribute. The show and hide mechanism is a achieved by removing and adding
+ * the `ng-hide` CSS class onto the element. The `.ng-hide` CSS class is a predefined CSS class present
+ * in AngularJS which sets the display style to none (using an !important flag).
*
- * Additionally, you can also provide animations via the ngAnimate attribute to animate the **show**
- * and **hide** effects.
+ * <pre>
+ * <!-- when $scope.myValue is truthy (element is hidden) -->
+ * <div ng-hide="myValue"></div>
*
+ * <!-- when $scope.myValue is falsy (element is visible) -->
+ * <div ng-hide="myValue" class="ng-hide"></div>
+ * </pre>
+ *
+ * When the ngHide expression evaluates to true then the .ng-hide CSS class is added to the class attribute
+ * on the element causing it to become hidden. When false, the ng-hide CSS class is removed
+ * from the element causing the element not to appear hidden.
+ *
+ * ## Why is !important used?
+ *
+ * You may be wondering why !important is used for the .ng-hide CSS class. This is because the `.ng-hide` selector
+ * can be easily overridden by heavier selectors. For example, something as simple
+ * as changing the display style on a HTML list item would make hidden elements appear visible.
+ * This also becomes a bigger issue when dealing with CSS frameworks.
+ *
+ * By using !important, the show and hide behavior will work as expected despite any clash between CSS selector
+ * specificity (when !important isn't used with any conflicting styles). If a developer chooses to override the
+ * styling to change how to hide an element then it is just a matter of using !important in their own CSS code.
+ *
+ * ### Overriding .ng-hide
+ *
+ * If you wish to change the hide behavior with ngShow/ngHide then this can be achieved by
+ * restating the styles for the .ng-hide class in CSS:
+ * <pre>
+ * .ng-hide {
+ * //!annotate CSS Specificity|Not to worry, this will override the AngularJS default...
+ * display:block!important;
+ *
+ * //this is just another form of hiding an element
+ * position:absolute;
+ * top:-9999px;
+ * left:-9999px;
+ * }
+ * </pre>
+ *
+ * Just remember to include the important flag so the CSS override will function.
+ *
+ * ## A note about animations with ngHide
+ *
+ * Animations in ngShow/ngHide work with the show and hide events that are triggered when the directive expression
+ * is true and false. This system works similar to the animation system present with ngClass, however, the
+ * only difference is that you must also include the !important flag to override the display property so
+ * that you can perform an animation when the element is hidden during the time of the animation.
+ *
+ * <pre>
+ * //
+ * //a working example can be found at the bottom of this page
+ * //
+ * .my-element.ng-hide-add, .my-element.ng-hide-remove {
+ * transition:0.5s linear all;
+ * display:block!important;
+ * }
+ *
+ * .my-element.ng-hide-add { ... }
+ * .my-element.ng-hide-add.ng-hide-add-active { ... }
+ * .my-element.ng-hide-remove { ... }
+ * .my-element.ng-hide-remove.ng-hide-remove-active { ... }
+ * </pre>
+ *
* @animations
- * show - happens after the ngHide expression evaluates to a non truthy value and the contents are set to visible
- * hide - happens after the ngHide expression evaluates to a truthy value and just before the contents are set to hidden
+ * removeClass: .ng-hide - happens after the ngHide expression evaluates to a truthy value and just before the contents are set to hidden
+ * addClass: .ng-hide - happens after the ngHide expression evaluates to a non truthy value and just before the contents are set to visible
*
* @element ANY
* @param {expression} ngHide If the {@link guide/expression expression} is truthy then
@@ -15613,55 +16874,42 @@
Click me: <input type="checkbox" ng-model="checked"><br/>
<div>
Show:
- <span class="check-element"
- ng-show="checked"
- ng-animate="{show: 'example-show', hide: 'example-hide'}">
+ <div class="check-element animate-hide" ng-show="checked">
<span class="icon-thumbs-up"></span> I show up when your checkbox is checked.
- </span>
+ </div>
</div>
<div>
Hide:
- <span class="check-element"
- ng-hide="checked"
- ng-animate="{show: 'example-show', hide: 'example-hide'}">
+ <div class="check-element animate-hide" ng-hide="checked">
<span class="icon-thumbs-down"></span> I hide when your checkbox is checked.
- </span>
+ </div>
</div>
</file>
<file name="animations.css">
- .example-show, .example-hide {
+ .animate-hide.ng-hide-add,
+ .animate-hide.ng-hide-remove {
-webkit-transition:all linear 0.5s;
-moz-transition:all linear 0.5s;
- -ms-transition:all linear 0.5s;
-o-transition:all linear 0.5s;
transition:all linear 0.5s;
+ display:block!important;
}
- .example-show {
+ .animate-hide.ng-hide-add.ng-hide-add-active,
+ .animate-hide.ng-hide-remove {
line-height:0;
opacity:0;
padding:0 10px;
}
- .example-show.example-show-active {
- line-height:20px;
- opacity:1;
- padding:10px;
- border:1px solid black;
- background:white;
- }
- .example-hide {
+ .animate-hide.ng-hide-add,
+ .animate-hide.ng-hide-remove.ng-hide-remove-active {
line-height:20px;
opacity:1;
padding:10px;
border:1px solid black;
background:white;
}
- .example-hide.example-hide-active {
- line-height:0;
- opacity:0;
- padding:0 10px;
- }
.check-element {
padding:10px;
@@ -15682,12 +16930,10 @@
</file>
</example>
*/
-//TODO(misko): refactor to remove element from the DOM
-var ngHideDirective = ['$animator', function($animator) {
+var ngHideDirective = ['$animate', function($animate) {
return function(scope, element, attr) {
- var animate = $animator(scope, attr);
scope.$watch(attr.ngHide, function ngHideWatchAction(value){
- animate[toBoolean(value) ? 'hide' : 'show'](element);
+ $animate[toBoolean(value) ? 'addClass' : 'removeClass'](element, 'ng-hide');
});
};
}];
@@ -15757,9 +17003,6 @@
* expression is evaluated. If a matching expression is not found via a when attribute then an element with the default
* attribute is displayed.
*
- * Additionally, you can also provide animations via the ngAnimate attribute to animate the **enter**
- * and **leave** effects.
- *
* @animations
* enter - happens after the ngSwtich contents change and the matched child element is placed inside the container
* leave - happens just after the ngSwitch contents change and just before the former contents are removed from the DOM
@@ -15792,10 +17035,8 @@
</select>
<tt>selection={{selection}}</tt>
<hr/>
- <div
- class="example-animate-container"
- ng-switch on="selection"
- ng-animate="{enter: 'example-enter', leave: 'example-leave'}">
+ <div class="animate-switch-container"
+ ng-switch on="selection">
<div ng-switch-when="settings">Settings Div</div>
<div ng-switch-when="home">Home Span</div>
<div ng-switch-default>default</div>
@@ -15809,10 +17050,22 @@
}
</file>
<file name="animations.css">
- .example-leave, .example-enter {
+ .animate-switch-container {
+ position:relative;
+ background:white;
+ border:1px solid black;
+ height:40px;
+ overflow:hidden;
+ }
+
+ .animate-switch-container > div {
+ padding:10px;
+ }
+
+ .animate-switch-container > .ng-enter,
+ .animate-switch-container > .ng-leave {
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
- -ms-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
@@ -15823,22 +17076,17 @@
bottom:0;
}
- .example-animate-container > * {
- display:block;
- padding:10px;
- }
-
- .example-enter {
+ .animate-switch-container > .ng-enter {
top:-50px;
}
- .example-enter.example-enter-active {
+ .animate-switch-container > .ng-enter.ng-enter-active {
top:0;
}
- .example-leave {
+ .animate-switch-container > .ng-leave {
top:0;
}
- .example-leave.example-leave-active {
+ .animate-switch-container > .ng-leave.ng-leave-active {
top:50px;
}
</file>
@@ -15857,7 +17105,7 @@
</file>
</example>
*/
-var ngSwitchDirective = ['$animator', function($animator) {
+var ngSwitchDirective = ['$animate', function($animate) {
return {
restrict: 'EA',
require: 'ngSwitch',
@@ -15867,7 +17115,6 @@
this.cases = {};
}],
link: function(scope, element, attr, ngSwitchController) {
- var animate = $animator(scope, attr);
var watchExpr = attr.ngSwitch || attr.on,
selectedTranscludes,
selectedElements,
@@ -15876,7 +17123,7 @@
scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
for (var i= 0, ii=selectedScopes.length; i<ii; i++) {
selectedScopes[i].$destroy();
- animate.leave(selectedElements[i]);
+ $animate.leave(selectedElements[i]);
}
selectedElements = [];
@@ -15891,7 +17138,7 @@
var anchor = selectedTransclude.element;
selectedElements.push(caseElement);
- animate.enter(caseElement, anchor.parent(), anchor);
+ $animate.enter(caseElement, anchor.parent(), anchor);
});
});
}
@@ -15947,8 +17194,7 @@
return {
restrict: 'E',
transclude: true,
- scope: 'isolate',
- locals: { title:'bind' },
+ scope: { title:'@' },
template: '<div style="border: 1px solid black;">' +
'<div style="background-color: gray">{{title}}</div>' +
'<div ng-transclude></div>' +
@@ -15974,240 +17220,20 @@
*
*/
var ngTranscludeDirective = ngDirective({
- controller: ['$transclude', '$element', function($transclude, $element) {
- $transclude(function(clone) {
- $element.append(clone);
+ controller: ['$transclude', '$element', '$scope', function($transclude, $element, $scope) {
+ // use evalAsync so that we don't process transclusion before directives on the parent element even when the
+ // transclusion replaces the current element. (we can't use priority here because that applies only to compile fns
+ // and not controllers
+ $scope.$evalAsync(function() {
+ $transclude(function(clone) {
+ $element.append(clone);
+ });
});
}]
});
/**
* @ngdoc directive
- * @name ng.directive:ngView
- * @restrict ECA
- *
- * @description
- * # Overview
- * `ngView` is a directive that complements the {@link ng.$route $route} service by
- * including the rendered template of the current route into the main layout (`index.html`) file.
- * Every time the current route changes, the included view changes with it according to the
- * configuration of the `$route` service.
- *
- * Additionally, you can also provide animations via the ngAnimate attribute to animate the **enter**
- * and **leave** effects.
- *
- * @animations
- * enter - happens just after the ngView contents are changed (when the new view DOM element is inserted into the DOM)
- * leave - happens just after the current ngView contents change and just before the former contents are removed from the DOM
- *
- * @scope
- * @example
- <example module="ngView" animations="true">
- <file name="index.html">
- <div ng-controller="MainCntl as main">
- Choose:
- <a href="Book/Moby">Moby</a> |
- <a href="Book/Moby/ch/1">Moby: Ch1</a> |
- <a href="Book/Gatsby">Gatsby</a> |
- <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
- <a href="Book/Scarlet">Scarlet Letter</a><br/>
-
- <div
- ng-view
- class="example-animate-container"
- ng-animate="{enter: 'example-enter', leave: 'example-leave'}"></div>
- <hr />
-
- <pre>$location.path() = {{main.$location.path()}}</pre>
- <pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre>
- <pre>$route.current.params = {{main.$route.current.params}}</pre>
- <pre>$route.current.scope.name = {{main.$route.current.scope.name}}</pre>
- <pre>$routeParams = {{main.$routeParams}}</pre>
- </div>
- </file>
-
- <file name="book.html">
- <div>
- controller: {{book.name}}<br />
- Book Id: {{book.params.bookId}}<br />
- </div>
- </file>
-
- <file name="chapter.html">
- <div>
- controller: {{chapter.name}}<br />
- Book Id: {{chapter.params.bookId}}<br />
- Chapter Id: {{chapter.params.chapterId}}
- </div>
- </file>
-
- <file name="animations.css">
- .example-leave, .example-enter {
- -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
- -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
- -ms-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
- -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
- transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
- }
-
- .example-animate-container {
- position:relative;
- height:100px;
- }
-
- .example-animate-container > * {
- display:block;
- width:100%;
- border-left:1px solid black;
-
- position:absolute;
- top:0;
- left:0;
- right:0;
- bottom:0;
- padding:10px;
- }
-
- .example-enter {
- left:100%;
- }
- .example-enter.example-enter-active {
- left:0;
- }
-
- .example-leave { }
- .example-leave.example-leave-active {
- left:-100%;
- }
- </file>
-
- <file name="script.js">
- angular.module('ngView', [], function($routeProvider, $locationProvider) {
- $routeProvider.when('/Book/:bookId', {
- templateUrl: 'book.html',
- controller: BookCntl,
- controllerAs: 'book'
- });
- $routeProvider.when('/Book/:bookId/ch/:chapterId', {
- templateUrl: 'chapter.html',
- controller: ChapterCntl,
- controllerAs: 'chapter'
- });
-
- // configure html5 to get links working on jsfiddle
- $locationProvider.html5Mode(true);
- });
-
- function MainCntl($route, $routeParams, $location) {
- this.$route = $route;
- this.$location = $location;
- this.$routeParams = $routeParams;
- }
-
- function BookCntl($routeParams) {
- this.name = "BookCntl";
- this.params = $routeParams;
- }
-
- function ChapterCntl($routeParams) {
- this.name = "ChapterCntl";
- this.params = $routeParams;
- }
- </file>
-
- <file name="scenario.js">
- it('should load and compile correct template', function() {
- element('a:contains("Moby: Ch1")').click();
- var content = element('.doc-example-live [ng-view]').text();
- expect(content).toMatch(/controller\: ChapterCntl/);
- expect(content).toMatch(/Book Id\: Moby/);
- expect(content).toMatch(/Chapter Id\: 1/);
-
- element('a:contains("Scarlet")').click();
- content = element('.doc-example-live [ng-view]').text();
- expect(content).toMatch(/controller\: BookCntl/);
- expect(content).toMatch(/Book Id\: Scarlet/);
- });
- </file>
- </example>
- */
-
-
-/**
- * @ngdoc event
- * @name ng.directive:ngView#$viewContentLoaded
- * @eventOf ng.directive:ngView
- * @eventType emit on the current ngView scope
- * @description
- * Emitted every time the ngView content is reloaded.
- */
-var ngViewDirective = ['$http', '$templateCache', '$route', '$anchorScroll', '$compile',
- '$controller', '$animator',
- function($http, $templateCache, $route, $anchorScroll, $compile,
- $controller, $animator) {
- return {
- restrict: 'ECA',
- terminal: true,
- link: function(scope, element, attr) {
- var lastScope,
- onloadExp = attr.onload || '',
- animate = $animator(scope, attr);
-
- scope.$on('$routeChangeSuccess', update);
- update();
-
-
- function destroyLastScope() {
- if (lastScope) {
- lastScope.$destroy();
- lastScope = null;
- }
- }
-
- function clearContent() {
- animate.leave(element.contents(), element);
- destroyLastScope();
- }
-
- function update() {
- var locals = $route.current && $route.current.locals,
- template = locals && locals.$template;
-
- if (template) {
- clearContent();
- var enterElements = jqLite('<div></div>').html(template).contents();
- animate.enter(enterElements, element);
-
- var link = $compile(enterElements),
- current = $route.current,
- controller;
-
- lastScope = current.scope = scope.$new();
- if (current.controller) {
- locals.$scope = lastScope;
- controller = $controller(current.controller, locals);
- if (current.controllerAs) {
- lastScope[current.controllerAs] = controller;
- }
- element.children().data('$ngControllerController', controller);
- }
-
- link(lastScope);
- lastScope.$emit('$viewContentLoaded');
- lastScope.$eval(onloadExp);
-
- // $anchorScroll might listen on event...
- $anchorScroll();
- } else {
- clearContent();
- }
- }
- }
- };
-}];
-
-/**
- * @ngdoc directive
* @name ng.directive:script
*
* @description
@@ -16264,8 +17290,8 @@
* Optionally `ngOptions` attribute can be used to dynamically generate a list of `<option>`
* elements for a `<select>` element using an array or an object obtained by evaluating the
* `ngOptions` expression.
- *˝˝
- * When an item in the select menu is select, the value of array element or object property
+ *
+ * When an item in the `<select>` menu is selected, the value of array element or object property
* represented by the selected option will be bound to the model identified by the `ngModel`
* directive of the parent select element.
*
@@ -16508,7 +17534,7 @@
}
};
- selectElement.bind('change', function() {
+ selectElement.on('change', function() {
scope.$apply(function() {
if (unknownOption.parent()) unknownOption.remove();
ngModelCtrl.$setViewValue(selectElement.val());
@@ -16534,7 +17560,7 @@
}
});
- selectElement.bind('change', function() {
+ selectElement.on('change', function() {
scope.$apply(function() {
var array = [];
forEach(selectElement.find('option'), function(option) {
@@ -16551,9 +17577,9 @@
var match;
if (! (match = optionsExp.match(NG_OPTIONS_REGEXP))) {
- throw Error(
- "Expected ngOptions in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_ (track by _expr_)?'" +
- " but got '" + optionsExp + "'.");
+ throw minErr('ngOptions')('iexp',
+ "Expected expression in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '{0}'. Element: {1}",
+ optionsExp, startingTag(selectElement));
}
var displayFn = $parse(match[2] || match[1]),
@@ -16585,7 +17611,7 @@
// clear contents, we'll add what's needed based on the model
selectElement.html('');
- selectElement.bind('change', function() {
+ selectElement.on('change', function() {
scope.$apply(function() {
var optionGroup,
collection = valuesFn(scope) || [],
@@ -16608,7 +17634,7 @@
for (var trackIndex = 0; trackIndex < collection.length; trackIndex++) {
locals[valueName] = collection[trackIndex];
if (trackFn(scope, locals) == key) break;
- }
+ }
} else {
locals[valueName] = collection[key];
}
@@ -16849,7 +17875,7 @@
selectCtrl.addOption(attr.value);
}
- element.bind('$destroy', function() {
+ element.on('$destroy', function() {
selectCtrl.removeOption(attr.value);
});
};
@@ -16873,4 +17899,4 @@
});
})(window, document);
-angular.element(document).find('head').append('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak{display:none;}ng\\:form{display:block;}</style>');
\ No newline at end of file
+angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}</style>');
\ No newline at end of file
Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-animate.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-animate.js (rev 0)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-animate.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -0,0 +1,677 @@
+/** %%Ignore-License
+ * @license AngularJS v1.2.0rc1
+ * (c) 2010-2012 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+/**
+ * @ngdoc overview
+ * @name ngAnimate
+ * @description
+ *
+ * ngAnimate
+ * =========
+ *
+ * The ngAnimate module is an optional module that comes packed with AngularJS that can be included within an AngularJS
+ * application to provide support for CSS and JavaScript animation hooks.
+ *
+ * To make use of animations with AngularJS, the `angular-animate.js` JavaScript file must be included into your application
+ * and the `ngAnimate` module must be included as a dependency.
+ *
+ * <pre>
+ * angular.module('App', ['ngAnimate']);
+ * </pre>
+ *
+ * Then, to see animations in action, all that is required is to define the appropriate CSS classes
+ * or to register a JavaScript animation via the $animation service. The directives that support animation automatically are:
+ * `ngRepeat`, `ngInclude`, `ngSwitch`, `ngShow`, `ngHide` and `ngView`. Custom directives can take advantage of animation
+ * by using the `$animate` service.
+ *
+ * Below is a more detailed breakdown of the supported animation events provided by pre-existing ng directives:
+ *
+ * | Directive | Supported Animations |
+ * |---------------------------------------------------------- |----------------------------------------------------|
+ * | {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave and move |
+ * | {@link ngRoute.directive:ngView#animations ngView} | enter and leave |
+ * | {@link ng.directive:ngInclude#animations ngInclude} | enter and leave |
+ * | {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave |
+ * | {@link ng.directive:ngIf#animations ngIf} | enter and leave |
+ * | {@link ng.directive:ngShow#animations ngClass} | add and remove |
+ * | {@link ng.directive:ngShow#animations ngShow & ngHide} | add and remove (the ng-hide class value) |
+ *
+ * You can find out more information about animations upon visiting each directive page.
+ *
+ * Below is an example of how to apply animations to a directive that supports animation hooks:
+ *
+ * <pre>
+ * <style type="text/css">
+ * .slide.ng-enter > div,
+ * .slide.ng-leave > div {
+ * -webkit-transition:0.5s linear all;
+ * -moz-transition:0.5s linear all;
+ * -o-transition:0.5s linear all;
+ * transition:0.5s linear all;
+ * }
+ *
+ * .slide.ng-enter { } /* starting animations for enter */
+ * .slide.ng-enter-active { } /* terminal animations for enter */
+ * .slide.ng-leave { } /* starting animations for leave */
+ * .slide.ng-leave-active { } /* terminal animations for leave */
+ * </style>
+ *
+ * <!--
+ * the animate service will automatically add .ng-enter and .ng-leave to the element
+ * to trigger the CSS transition/animations
+ * -->
+ * <ANY class="slide" ng-include="..."></ANY>
+ * </pre>
+ *
+ * Keep in mind that if an animation is running, any child elements cannot be animated until the parent element's
+ * animation has completed.
+ *
+ * <h2>CSS-defined Animations</h2>
+ * The animate service will automatically apply two CSS classes to the animated element and these two CSS classes
+ * are designed to contain the start and end CSS styling. Both CSS transitions and keyframe animations are supported
+ * and can be used to play along with this naming structure.
+ *
+ * The following code below demonstrates how to perform animations using **CSS transitions** with Angular:
+ *
+ * <pre>
+ * <style type="text/css">
+ * /*
+ * The animate class is apart of the element and the ng-enter class
+ * is attached to the element once the enter animation event is triggered
+ * */
+ * .reveal-animation.ng-enter {
+ * -webkit-transition: 1s linear all; /* Safari/Chrome */
+ * -moz-transition: 1s linear all; /* Firefox */
+ * -o-transition: 1s linear all; /* Opera */
+ * transition: 1s linear all; /* IE10+ and Future Browsers */
+ *
+ * /* The animation preparation code */
+ * opacity: 0;
+ * }
+ *
+ * /*
+ * Keep in mind that you want to combine both CSS
+ * classes together to avoid any CSS-specificity
+ * conflicts
+ * */
+ * .reveal-animation.ng-enter.ng-enter-active {
+ * /* The animation code itself */
+ * opacity: 1;
+ * }
+ * </style>
+ *
+ * <div class="view-container">
+ * <div ng-view class="reveal-animation"></div>
+ * </div>
+ * </pre>
+ *
+ * The following code below demonstrates how to perform animations using **CSS animations** with Angular:
+ *
+ * <pre>
+ * <style type="text/css">
+ * .reveal-animation.ng-enter {
+ * -webkit-animation: enter_sequence 1s linear; /* Safari/Chrome */
+ * -moz-animation: enter_sequence 1s linear; /* Firefox */
+ * -o-animation: enter_sequence 1s linear; /* Opera */
+ * animation: enter_sequence 1s linear; /* IE10+ and Future Browsers */
+ * }
+ * @-webkit-keyframes enter_sequence {
+ * from { opacity:0; }
+ * to { opacity:1; }
+ * }
+ * @-moz-keyframes enter_sequence {
+ * from { opacity:0; }
+ * to { opacity:1; }
+ * }
+ * @-o-keyframes enter_sequence {
+ * from { opacity:0; }
+ * to { opacity:1; }
+ * }
+ * @keyframes enter_sequence {
+ * from { opacity:0; }
+ * to { opacity:1; }
+ * }
+ * </style>
+ *
+ * <div class="view-container">
+ * <div ng-view class="reveal-animation"></div>
+ * </div>
+ * </pre>
+ *
+ * Both CSS3 animations and transitions can be used together and the animate service will figure out the correct duration and delay timing.
+ *
+ * Upon DOM mutation, the event class is added first (something like `ng-enter`), then the browser prepares itself to add
+ * the active class (in this case `ng-enter-active`) which then triggers the animation. The animation module will automatically
+ * detect the CSS code to determine when the animation ends. Once the animation is over then both CSS classes will be
+ * removed from the DOM. If a browser does not support CSS transitions or CSS animations then the animation will start and end
+ * immediately resulting in a DOM element that is at its final state. This final state is when the DOM element
+ * has no CSS transition/animation classes applied to it.
+ *
+ * <h2>JavaScript-defined Animations</h2>
+ * In the event that you do not want to use CSS3 transitions or CSS3 animations or if you wish to offer animations on browsers that do not
+ * yet support CSS transitions/animations, then you can make use of JavaScript animations defined inside of your AngularJS module.
+ *
+ * <pre>
+ * //!annotate="YourApp" Your AngularJS Module|Replace this or ngModule with the module that you used to define your application.
+ * var ngModule = angular.module('YourApp', []);
+ * ngModule.animation('.my-crazy-animation', function() {
+ * return {
+ * enter: function(element, done) {
+ * //run the animation
+ * //!annotate Cancel Animation|This function (if provided) will perform the cancellation of the animation when another is triggered
+ * return function(element, done) {
+ * //cancel the animation
+ * }
+ * }
+ * leave: function(element, done) { },
+ * move: function(element, done) { },
+ * show: function(element, done) { },
+ * hide: function(element, done) { },
+ * addClass: function(element, className, done) { },
+ * removeClass: function(element, className, done) { },
+ * }
+ * });
+ * </pre>
+ *
+ * JavaScript-defined animations are created with a CSS-like class selector and a collection of events which are set to run
+ * a javascript callback function. When an animation is triggered, $animate will look for a matching animation which fits
+ * the element's CSS class attribute value and then run the matching animation event function (if found).
+ * In other words, if the CSS classes present on the animated element match any of the JavaScript animations then the callback function
+ * be executed. It should be also noted that only simple class selectors are allowed.
+ *
+ * Within a JavaScript animation, an object containing various event callback animation functions is expected to be returned.
+ * As explained above, these callbacks are triggered based on the animation event. Therefore if an enter animation is run,
+ * and the JavaScript animation is found, then the enter callback will handle that animation (in addition to the CSS keyframe animation
+ * or transition code that is defined via a stylesheet).
+ *
+ */
+
+angular.module('ngAnimate', ['ng'])
+
+ /**
+ * @ngdoc object
+ * @name ngAnimate.$animateProvider
+ * @description
+ *
+ * The $AnimationProvider provider allows developers to register and access custom JavaScript animations directly inside
+ * of a module. When an animation is triggered, the $animate service will query the $animation function to find any
+ * animations that match the provided name value.
+ *
+ * Please visit the {@link ngAnimate ngAnimate} module overview page learn more about how to use animations in your application.
+ *
+ */
+ .config(['$provide', '$animateProvider', function($provide, $animateProvider) {
+ var noop = angular.noop;
+ var forEach = angular.forEach;
+ var selectors = $animateProvider.$$selectors;
+
+ var NG_ANIMATE_STATE = '$$ngAnimateState';
+ var rootAnimateState = {running:true};
+ $provide.decorator('$animate', ['$delegate', '$injector', '$sniffer', '$rootElement', '$timeout',
+ function($delegate, $injector, $sniffer, $rootElement, $timeout) {
+
+ $rootElement.data(NG_ANIMATE_STATE, rootAnimateState);
+
+ function lookup(name) {
+ if (name) {
+ var matches = [],
+ flagMap = {},
+ classes = name.substr(1).split('.');
+
+ //the empty string value is the default animation
+ //operation which performs CSS transition and keyframe
+ //animations sniffing. This is always included for each
+ //element animation procedure
+ classes.push('');
+
+ for(var i=0; i < classes.length; i++) {
+ var klass = classes[i],
+ selectorFactoryName = selectors[klass];
+ if(selectorFactoryName && !flagMap[klass]) {
+ matches.push($injector.get(selectorFactoryName));
+ flagMap[klass] = true;
+ }
+ }
+ return matches;
+ }
+ }
+
+ /**
+ * @ngdoc object
+ * @name ngAnimate.$animate
+ * @requires $timeout, $sniffer, $rootElement
+ * @function
+ *
+ * @description
+ * The `$animate` service provides animation detection support while performing DOM operations (enter, leave and move)
+ * as well as during addClass and removeClass operations. When any of these operations are run, the $animate service
+ * will examine any JavaScript-defined animations (which are defined by using the $animateProvider provider object)
+ * as well as any CSS-defined animations against the CSS classes present on the element once the DOM operation is run.
+ *
+ * The `$animate` service is used behind the scenes with pre-existing directives and animation with these directives
+ * will work out of the box without any extra configuration.
+ *
+ * Please visit the {@link ngAnimate ngAnimate} module overview page learn more about how to use animations in your application.
+ *
+ */
+ return {
+ /**
+ * @ngdoc function
+ * @name ngAnimate.$animate#enter
+ * @methodOf ngAnimate.$animate
+ * @function
+ *
+ * @description
+ * Appends the element to the parent element that resides in the document and then runs the enter animation. Once
+ * the animation is started, the following CSS classes will be present on the element for the duration of the animation:
+ *
+ * Below is a breakdown of each step that occurs during enter animation:
+ *
+ * | Animation Step | What the element class attribute looks like |
+ * |----------------------------------------------------------------------------------------------|-----------------------------------------------|
+ * | 1. $animate.enter(...) is called | class="my-animation" |
+ * | 2. element is inserted into the parent element or beside the after element | class="my-animation" |
+ * | 3. the .ng-enter class is added to the element | class="my-animation ng-enter" |
+ * | 4. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-enter" |
+ * | 5. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-enter" |
+ * | 6. the .ng-enter-active class is added (this triggers the CSS transition/animation) | class="my-animation ng-enter ng-enter-active" |
+ * | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-enter ng-enter-active" |
+ * | 8. The animation ends and both CSS classes are removed from the element | class="my-animation" |
+ * | 9. The done() callback is fired (if provided) | class="my-animation" |
+ *
+ * @param {jQuery/jqLite element} element the element that will be the focus of the enter animation
+ * @param {jQuery/jqLite element} parent the parent element of the element that will be the focus of the enter animation
+ * @param {jQuery/jqLite element} after the sibling element (which is the previous element) of the element that will be the focus of the enter animation
+ * @param {function()=} done callback function that will be called once the animation is complete
+ */
+ enter : function(element, parent, after, done) {
+ $delegate.enter(element, parent, after);
+ performAnimation('enter', 'ng-enter', element, parent, after, done);
+ },
+
+ /**
+ * @ngdoc function
+ * @name ngAnimate.$animate#leave
+ * @methodOf ngAnimate.$animate
+ * @function
+ *
+ * @description
+ * Runs the leave animation operation and, upon completion, removes the element from the DOM. Once
+ * the animation is started, the following CSS classes will be added for the duration of the animation:
+ *
+ * Below is a breakdown of each step that occurs during enter animation:
+ *
+ * | Animation Step | What the element class attribute looks like |
+ * |----------------------------------------------------------------------------------------------|----------------------------------------------|
+ * | 1. $animate.leave(...) is called | class="my-animation" |
+ * | 2. the .ng-leave class is added to the element | class="my-animation ng-leave" |
+ * | 3. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-leave" |
+ * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-leave" |
+ * | 5. the .ng-leave-active class is added (this triggers the CSS transition/animation) | class="my-animation ng-leave ng-leave-active |
+ * | 6. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-leave ng-leave-active |
+ * | 7. The animation ends and both CSS classes are removed from the element | class="my-animation" |
+ * | 8. The element is removed from the DOM | ... |
+ * | 9. The done() callback is fired (if provided) | ... |
+ *
+ * @param {jQuery/jqLite element} element the element that will be the focus of the leave animation
+ * @param {function()=} done callback function that will be called once the animation is complete
+ */
+ leave : function(element, done) {
+ performAnimation('leave', 'ng-leave', element, null, null, function() {
+ $delegate.leave(element, done);
+ });
+ },
+
+ /**
+ * @ngdoc function
+ * @name ngAnimate.$animate#move
+ * @methodOf ngAnimate.$animate
+ * @function
+ *
+ * @description
+ * Fires the move DOM operation. Just before the animation starts, the animate service will either append it into the parent container or
+ * add the element directly after the after element if present. Then the move animation will be run. Once
+ * the animation is started, the following CSS classes will be added for the duration of the animation:
+ *
+ * Below is a breakdown of each step that occurs during move animation:
+ *
+ * | Animation Step | What the element class attribute looks like |
+ * |----------------------------------------------------------------------------------------------|---------------------------------------------|
+ * | 1. $animate.move(...) is called | class="my-animation" |
+ * | 2. element is moved into the parent element or beside the after element | class="my-animation" |
+ * | 3. the .ng-move class is added to the element | class="my-animation ng-move" |
+ * | 4. $animate runs any JavaScript-defined animations on the element | class="my-animation ng-move" |
+ * | 5. $animate scans the element styles to get the CSS transition/animation duration and delay | class="my-animation ng-move" |
+ * | 6. the .ng-move-active class is added (this triggers the CSS transition/animation) | class="my-animation ng-move ng-move-active" |
+ * | 7. $animate waits for X milliseconds for the animation to complete | class="my-animation ng-move ng-move-active" |
+ * | 8. The animation ends and both CSS classes are removed from the element | class="my-animation" |
+ * | 9. The done() callback is fired (if provided) | class="my-animation" |
+ *
+ * @param {jQuery/jqLite element} element the element that will be the focus of the move animation
+ * @param {jQuery/jqLite element} parent the parent element of the element that will be the focus of the move animation
+ * @param {jQuery/jqLite element} after the sibling element (which is the previous element) of the element that will be the focus of the move animation
+ * @param {function()=} done callback function that will be called once the animation is complete
+ */
+ move : function(element, parent, after, done) {
+ $delegate.move(element, parent, after);
+ performAnimation('move', 'ng-move', element, null, null, done);
+ },
+
+ /**
+ * @ngdoc function
+ * @name ngAnimate.$animate#addClass
+ * @methodOf ngAnimate.$animate
+ *
+ * @description
+ * Triggers a custom animation event based off the className variable and then attaches the className value to the element as a CSS class.
+ * Unlike the other animation methods, the animate service will suffix the className value with {@type -add} in order to provide
+ * the animate service the setup and active CSS classes in order to trigger the animation.
+ *
+ * Below is a breakdown of each step that occurs during addClass animation:
+ *
+ * | Animation Step | What the element class attribute looks like |
+ * |------------------------------------------------------------------------------------------------|---------------------------------------------|
+ * | 1. $animate.addClass(element, 'super') is called | class="" |
+ * | 2. the .super-add class is added to the element | class="super-add" |
+ * | 3. $animate runs any JavaScript-defined animations on the element | class="super-add" |
+ * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="super-add" |
+ * | 5. the .super-add-active class is added (this triggers the CSS transition/animation) | class="super-add super-add-active" |
+ * | 6. $animate waits for X milliseconds for the animation to complete | class="super-add super-add-active" |
+ * | 7. The animation ends and both CSS classes are removed from the element | class="" |
+ * | 8. The super class is added to the element | class="super" |
+ * | 9. The done() callback is fired (if provided) | class="super" |
+ *
+ * @param {jQuery/jqLite element} element the element that will be animated
+ * @param {string} className the CSS class that will be animated and then attached to the element
+ * @param {function()=} done callback function that will be called once the animation is complete
+ */
+ addClass : function(element, className, done) {
+ performAnimation('addClass', className, element, null, null, function() {
+ $delegate.addClass(element, className, done);
+ });
+ },
+
+ /**
+ * @ngdoc function
+ * @name ngAnimate.$animate#removeClass
+ * @methodOf ngAnimate.$animate
+ *
+ * @description
+ * Triggers a custom animation event based off the className variable and then removes the CSS class provided by the className value
+ * from the element. Unlike the other animation methods, the animate service will suffix the className value with {@type -remove} in
+ * order to provide the animate service the setup and active CSS classes in order to trigger the animation.
+ *
+ * Below is a breakdown of each step that occurs during removeClass animation:
+ *
+ * | Animation Step | What the element class attribute looks like |
+ * |-----------------------------------------------------------------------------------------------|-------------------------------------------------|
+ * | 1. $animate.removeClass(element, 'super') is called | class="super" |
+ * | 2. the .super-remove class is added to the element | class="super super-remove" |
+ * | 3. $animate runs any JavaScript-defined animations on the element | class="super super-remove" |
+ * | 4. $animate scans the element styles to get the CSS transition/animation duration and delay | class="super super-remove" |
+ * | 5. the .super-remove-active class is added (this triggers the CSS transition/animation) | class="super super-remove super-remove-active" |
+ * | 6. $animate waits for X milliseconds for the animation to complete | class="super super-remove super-remove-active" |
+ * | 7. The animation ends and both CSS all three classes are removed from the element | class="" |
+ * | 8. The done() callback is fired (if provided) | class="" |
+ *
+ * @param {jQuery/jqLite element} element the element that will be animated
+ * @param {string} className the CSS class that will be animated and then removed from the element
+ * @param {function()=} done callback function that will be called once the animation is complete
+ */
+ removeClass : function(element, className, done) {
+ performAnimation('removeClass', className, element, null, null, function() {
+ $delegate.removeClass(element, className, done);
+ });
+ },
+
+ /**
+ * @ngdoc function
+ * @name ngAnimate.$animate#enabled
+ * @methodOf ngAnimate.$animate
+ * @function
+ *
+ * @param {boolean=} value If provided then set the animation on or off.
+ * @return {boolean} Current animation state.
+ *
+ * @description
+ * Globally enables/disables animations.
+ *
+ */
+ enabled : function(value) {
+ if (arguments.length) {
+ rootAnimateState.running = !value;
+ }
+ return !rootAnimateState.running;
+ }
+ };
+
+ /*
+ all animations call this shared animation triggering function internally.
+ The event variable refers to the JavaScript animation event that will be triggered
+ and the className value is the name of the animation that will be applied within the
+ CSS code. Element, parent and after are provided DOM elements for the animation
+ and the onComplete callback will be fired once the animation is fully complete.
+ */
+ function performAnimation(event, className, element, parent, after, onComplete) {
+ var classes = (element.attr('class') || '') + ' ' + className;
+ var animationLookup = (' ' + classes).replace(/\s+/g,'.'),
+ animations = [];
+ forEach(lookup(animationLookup), function(animation, index) {
+ animations.push({
+ start : animation[event]
+ });
+ });
+
+ if (!parent) {
+ parent = after ? after.parent() : element.parent();
+ }
+ var disabledAnimation = { running : true };
+
+ //skip the animation if animations are disabled, a parent is already being animated
+ //or the element is not currently attached to the document body.
+ if ((parent.inheritedData(NG_ANIMATE_STATE) || disabledAnimation).running) {
+ //avoid calling done() since there is no need to remove any
+ //data or className values since this happens earlier than that
+ //and also use a timeout so that it won't be asynchronous
+ $timeout(onComplete || noop, 0, false);
+ return;
+ }
+
+ var ngAnimateState = element.data(NG_ANIMATE_STATE) || {};
+
+ //if an animation is currently running on the element then lets take the steps
+ //to cancel that animation and fire any required callbacks
+ if(ngAnimateState.running) {
+ cancelAnimations(ngAnimateState.animations);
+ ngAnimateState.done();
+ }
+
+ element.data(NG_ANIMATE_STATE, {
+ running:true,
+ animations:animations,
+ done:done
+ });
+
+ var baseClassName = className;
+ if(event == 'addClass') {
+ className = suffixClasses(className, '-add');
+ } else if(event == 'removeClass') {
+ className = suffixClasses(className, '-remove');
+ }
+
+ element.addClass(className);
+
+ forEach(animations, function(animation, index) {
+ var fn = function() {
+ progress(index);
+ };
+
+ if(animation.start) {
+ if(event == 'addClass' || event == 'removeClass') {
+ animation.endFn = animation.start(element, baseClassName, fn);
+ } else {
+ animation.endFn = animation.start(element, fn);
+ }
+ } else {
+ fn();
+ }
+ });
+
+ function cancelAnimations(animations) {
+ var isCancelledFlag = true;
+ forEach(animations, function(animation) {
+ (animation.endFn || noop)(isCancelledFlag);
+ });
+ }
+
+ function progress(index) {
+ animations[index].done = true;
+ (animations[index].endFn || noop)();
+ for(var i=0;i<animations.length;i++) {
+ if(!animations[i].done) return;
+ }
+ done();
+ }
+
+ function done() {
+ if(!done.hasBeenRun) {
+ done.hasBeenRun = true;
+ element.removeClass(className);
+ element.removeData(NG_ANIMATE_STATE);
+ (onComplete || noop)();
+ }
+ }
+ }
+ }]);
+
+ $animateProvider.register('', ['$window','$sniffer', '$timeout', function($window, $sniffer, $timeout) {
+ var noop = angular.noop;
+ var forEach = angular.forEach;
+ function animate(element, className, done) {
+ if (!($sniffer.transitions || $sniffer.animations)) {
+ done();
+ } else {
+ var activeClassName = '';
+ $timeout(startAnimation, 1, false);
+
+ //this acts as the cancellation function in case
+ //a new animation is triggered while another animation
+ //is still going on (otherwise the active className
+ //would still hang around until the timer is complete).
+ return onEnd;
+ }
+
+ function parseMaxTime(str) {
+ var total = 0, values = angular.isString(str) ? str.split(/\s*,\s*/) : [];
+ forEach(values, function(value) {
+ total = Math.max(parseFloat(value) || 0, total);
+ });
+ return total;
+ }
+
+ function startAnimation() {
+ var duration = 0;
+ forEach(className.split(' '), function(klass, i) {
+ activeClassName += (i > 0 ? ' ' : '') + klass + '-active';
+ });
+
+ element.addClass(activeClassName);
+
+ //one day all browsers will have these properties
+ var w3cAnimationProp = 'animation';
+ var w3cTransitionProp = 'transition';
+
+ //but some still use vendor-prefixed styles
+ var vendorAnimationProp = $sniffer.vendorPrefix + 'Animation';
+ var vendorTransitionProp = $sniffer.vendorPrefix + 'Transition';
+
+ var durationKey = 'Duration',
+ delayKey = 'Delay',
+ animationIterationCountKey = 'IterationCount';
+
+ //we want all the styles defined before and after
+ var ELEMENT_NODE = 1;
+ forEach(element, function(element) {
+ if (element.nodeType == ELEMENT_NODE) {
+ var elementStyles = $window.getComputedStyle(element) || {};
+
+ var transitionDelay = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + delayKey]),
+ parseMaxTime(elementStyles[vendorTransitionProp + delayKey]));
+
+ var animationDelay = Math.max(parseMaxTime(elementStyles[w3cAnimationProp + delayKey]),
+ parseMaxTime(elementStyles[vendorAnimationProp + delayKey]));
+
+ var transitionDuration = Math.max(parseMaxTime(elementStyles[w3cTransitionProp + durationKey]),
+ parseMaxTime(elementStyles[vendorTransitionProp + durationKey]));
+
+ var animationDuration = Math.max(parseMaxTime(elementStyles[w3cAnimationProp + durationKey]),
+ parseMaxTime(elementStyles[vendorAnimationProp + durationKey]));
+
+ if(animationDuration > 0) {
+ animationDuration *= Math.max(parseInt(elementStyles[w3cAnimationProp + animationIterationCountKey]) || 0,
+ parseInt(elementStyles[vendorAnimationProp + animationIterationCountKey]) || 0,
+ 1);
+ }
+
+ duration = Math.max(animationDelay + animationDuration,
+ transitionDelay + transitionDuration,
+ duration);
+ }
+ });
+
+ $timeout(done, duration * 1000, false);
+ }
+
+ //this will automatically be called by $animate so
+ //there is no need to attach this internally to the
+ //timeout done method
+ function onEnd(cancelled) {
+ element.removeClass(activeClassName);
+
+ //only when the animation is cancelled is the done()
+ //function not called for this animation therefore
+ //this must be also called
+ if(cancelled) {
+ done();
+ }
+ }
+ }
+
+ return {
+ enter : function(element, done) {
+ return animate(element, 'ng-enter', done);
+ },
+ leave : function(element, done) {
+ return animate(element, 'ng-leave', done);
+ },
+ move : function(element, done) {
+ return animate(element, 'ng-move', done);
+ },
+ addClass : function(element, className, done) {
+ return animate(element, suffixClasses(className, '-add'), done);
+ },
+ removeClass : function(element, className, done) {
+ return animate(element, suffixClasses(className, '-remove'), done);
+ }
+ };
+
+ }]);
+
+ function suffixClasses(classes, suffix) {
+ var className = '';
+ classes = angular.isArray(classes) ? classes : classes.split(/\s+/);
+ forEach(classes, function(klass, i) {
+ if(klass && klass.length > 0) {
+ className += (i > 0 ? ' ' : '') + klass + suffix;
+ }
+ });
+ return className;
+ }
+ }]);
+
+
+})(window, window.angular);
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-cookies.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-cookies.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-cookies.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -1,10 +1,9 @@
/** %%Ignore-License
- * @license AngularJS v1.1.5
+ * @license AngularJS v1.2.0rc1
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
-(function(window, angular, undefined) {
-'use strict';
+(function(window, angular, undefined) {'use strict';
/**
* @ngdoc overview
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-loader.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-loader.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-loader.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -1,5 +1,5 @@
/** %%Ignore-License
- * @license AngularJS v1.1.5
+ * @license AngularJS v1.2.0rc1
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
@@ -36,8 +36,8 @@
*
* # Module
*
- * A module is a collocation of services, directives, filters, and configuration information. Module
- * is used to configure the {@link AUTO.$injector $injector}.
+ * A module is a collection of services, directives, filters, and configuration information.
+ * `angular.module` is used to configure the {@link AUTO.$injector $injector}.
*
* <pre>
* // Create a new module
@@ -47,8 +47,7 @@
* myModule.value('appName', 'MyCoolApp');
*
* // configure existing services inside initialization blocks.
- * myModule.config(function($locationProvider) {
-'use strict';
+ * myModule.config(function($locationProvider) {'use strict';
* // Configure existing providers
* $locationProvider.hashPrefix('!');
* });
@@ -77,7 +76,9 @@
}
return ensure(modules, name, function() {
if (!requires) {
- throw Error('No module: ' + name);
+ throw minErr('$injector')('nomod', "Module '{0}' is not available! You either misspelled the module name " +
+ "or forgot to load it. If registering a module ensure that you specify the dependencies as the second " +
+ "argument.", name);
}
/** @type {!Array.<Array.<*>>} */
@@ -178,24 +179,30 @@
* @param {Function} animationFactory Factory function for creating new instance of an animation.
* @description
*
- * Defines an animation hook that can be later used with {@link ng.directive:ngAnimate ngAnimate}
- * alongside {@link ng.directive:ngAnimate#Description common ng directives} as well as custom directives.
+ * **NOTE**: animations are take effect only if the **ngAnimate** module is loaded.
+ *
+ *
+ * Defines an animation hook that can be later used with {@link ngAnimate.$animate $animate} service and
+ * directives that use this service.
+ *
* <pre>
- * module.animation('animation-name', function($inject1, $inject2) {
+ * module.animation('.animation-name', function($inject1, $inject2) {
* return {
- * //this gets called in preparation to setup an animation
- * setup : function(element) { ... },
- *
- * //this gets called once the animation is run
- * start : function(element, done, memo) { ... }
+ * eventName : function(element, done) {
+ * //code to run the animation
+ * //once complete, then run done()
+ * return function cancellationFunction(element) {
+ * //code to cancel the animation
+ * }
+ * }
* }
* })
* </pre>
*
- * See {@link ng.$animationProvider#register $animationProvider.register()} and
- * {@link ng.directive:ngAnimate ngAnimate} for more information.
+ * See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and
+ * {@link ngAnimate ngAnimate module} for more information.
*/
- animation: invokeLater('$animationProvider', 'register'),
+ animation: invokeLater('$animateProvider', 'register'),
/**
* @ngdoc method
Deleted: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-mobile.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-mobile.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-mobile.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -1,460 +0,0 @@
-/** %%Ignore-License
- * @license AngularJS v1.1.5
- * (c) 2010-2012 Google, Inc. http://angularjs.org
- * License: MIT
- */
-(function(window, angular, undefined) {
-'use strict';
-
-/**
- * @ngdoc overview
- * @name ngMobile
- * @description
- * Touch events and other mobile helpers.
- * Based on jQuery Mobile touch event handling (jquerymobile.com)
- */
-
-// define ngMobile module
-var ngMobile = angular.module('ngMobile', []);
-
-/**
- * @ngdoc directive
- * @name ngMobile.directive:ngClick
- *
- * @description
- * A more powerful replacement for the default ngClick designed to be used on touchscreen
- * devices. Most mobile browsers wait about 300ms after a tap-and-release before sending
- * the click event. This version handles them immediately, and then prevents the
- * following click event from propagating.
- *
- * This directive can fall back to using an ordinary click event, and so works on desktop
- * browsers as well as mobile.
- *
- * This directive also sets the CSS class `ng-click-active` while the element is being held
- * down (by a mouse click or touch) so you can restyle the depressed element if you wish.
- *
- * @element ANY
- * @param {expression} ngClick {@link guide/expression Expression} to evaluate
- * upon tap. (Event object is available as `$event`)
- *
- * @example
- <doc:example>
- <doc:source>
- <button ng-click="count = count + 1" ng-init="count=0">
- Increment
- </button>
- count: {{ count }}
- </doc:source>
- </doc:example>
- */
-
-ngMobile.config(['$provide', function($provide) {
- $provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
- // drop the default ngClick directive
- $delegate.shift();
- return $delegate;
- }]);
-}]);
-
-ngMobile.directive('ngClick', ['$parse', '$timeout', '$rootElement',
- function($parse, $timeout, $rootElement) {
- var TAP_DURATION = 750; // Shorter than 750ms is a tap, longer is a taphold or drag.
- var MOVE_TOLERANCE = 12; // 12px seems to work in most mobile browsers.
- var PREVENT_DURATION = 2500; // 2.5 seconds maximum from preventGhostClick call to click
- var CLICKBUSTER_THRESHOLD = 25; // 25 pixels in any dimension is the limit for busting clicks.
-
- var ACTIVE_CLASS_NAME = 'ng-click-active';
- var lastPreventedTime;
- var touchCoordinates;
-
-
- // TAP EVENTS AND GHOST CLICKS
- //
- // Why tap events?
- // Mobile browsers detect a tap, then wait a moment (usually ~300ms) to see if you're
- // double-tapping, and then fire a click event.
- //
- // This delay sucks and makes mobile apps feel unresponsive.
- // So we detect touchstart, touchmove, touchcancel and touchend ourselves and determine when
- // the user has tapped on something.
- //
- // What happens when the browser then generates a click event?
- // The browser, of course, also detects the tap and fires a click after a delay. This results in
- // tapping/clicking twice. So we do "clickbusting" to prevent it.
- //
- // How does it work?
- // We attach global touchstart and click handlers, that run during the capture (early) phase.
- // So the sequence for a tap is:
- // - global touchstart: Sets an "allowable region" at the point touched.
- // - element's touchstart: Starts a touch
- // (- touchmove or touchcancel ends the touch, no click follows)
- // - element's touchend: Determines if the tap is valid (didn't move too far away, didn't hold
- // too long) and fires the user's tap handler. The touchend also calls preventGhostClick().
- // - preventGhostClick() removes the allowable region the global touchstart created.
- // - The browser generates a click event.
- // - The global click handler catches the click, and checks whether it was in an allowable region.
- // - If preventGhostClick was called, the region will have been removed, the click is busted.
- // - If the region is still there, the click proceeds normally. Therefore clicks on links and
- // other elements without ngTap on them work normally.
- //
- // This is an ugly, terrible hack!
- // Yeah, tell me about it. The alternatives are using the slow click events, or making our users
- // deal with the ghost clicks, so I consider this the least of evils. Fortunately Angular
- // encapsulates this ugly logic away from the user.
- //
- // Why not just put click handlers on the element?
- // We do that too, just to be sure. The problem is that the tap event might have caused the DOM
- // to change, so that the click fires in the same position but something else is there now. So
- // the handlers are global and care only about coordinates and not elements.
-
- // Checks if the coordinates are close enough to be within the region.
- function hit(x1, y1, x2, y2) {
- return Math.abs(x1 - x2) < CLICKBUSTER_THRESHOLD && Math.abs(y1 - y2) < CLICKBUSTER_THRESHOLD;
- }
-
- // Checks a list of allowable regions against a click location.
- // Returns true if the click should be allowed.
- // Splices out the allowable region from the list after it has been used.
- function checkAllowableRegions(touchCoordinates, x, y) {
- for (var i = 0; i < touchCoordinates.length; i += 2) {
- if (hit(touchCoordinates[i], touchCoordinates[i+1], x, y)) {
- touchCoordinates.splice(i, i + 2);
- return true; // allowable region
- }
- }
- return false; // No allowable region; bust it.
- }
-
- // Global click handler that prevents the click if it's in a bustable zone and preventGhostClick
- // was called recently.
- function onClick(event) {
- if (Date.now() - lastPreventedTime > PREVENT_DURATION) {
- return; // Too old.
- }
-
- var touches = event.touches && event.touches.length ? event.touches : [event];
- var x = touches[0].clientX;
- var y = touches[0].clientY;
- // Work around desktop Webkit quirk where clicking a label will fire two clicks (on the label
- // and on the input element). Depending on the exact browser, this second click we don't want
- // to bust has either (0,0) or negative coordinates.
- if (x < 1 && y < 1) {
- return; // offscreen
- }
-
- // Look for an allowable region containing this click.
- // If we find one, that means it was created by touchstart and not removed by
- // preventGhostClick, so we don't bust it.
- if (checkAllowableRegions(touchCoordinates, x, y)) {
- return;
- }
-
- // If we didn't find an allowable region, bust the click.
- event.stopPropagation();
- event.preventDefault();
- }
-
-
- // Global touchstart handler that creates an allowable region for a click event.
- // This allowable region can be removed by preventGhostClick if we want to bust it.
- function onTouchStart(event) {
- var touches = event.touches && event.touches.length ? event.touches : [event];
- var x = touches[0].clientX;
- var y = touches[0].clientY;
- touchCoordinates.push(x, y);
-
- $timeout(function() {
- // Remove the allowable region.
- for (var i = 0; i < touchCoordinates.length; i += 2) {
- if (touchCoordinates[i] == x && touchCoordinates[i+1] == y) {
- touchCoordinates.splice(i, i + 2);
- return;
- }
- }
- }, PREVENT_DURATION, false);
- }
-
- // On the first call, attaches some event handlers. Then whenever it gets called, it creates a
- // zone around the touchstart where clicks will get busted.
- function preventGhostClick(x, y) {
- if (!touchCoordinates) {
- $rootElement[0].addEventListener('click', onClick, true);
- $rootElement[0].addEventListener('touchstart', onTouchStart, true);
- touchCoordinates = [];
- }
-
- lastPreventedTime = Date.now();
-
- checkAllowableRegions(touchCoordinates, x, y);
- }
-
- // Actual linking function.
- return function(scope, element, attr) {
- var clickHandler = $parse(attr.ngClick),
- tapping = false,
- tapElement, // Used to blur the element after a tap.
- startTime, // Used to check if the tap was held too long.
- touchStartX,
- touchStartY;
-
- function resetState() {
- tapping = false;
- element.removeClass(ACTIVE_CLASS_NAME);
- }
-
- element.bind('touchstart', function(event) {
- tapping = true;
- tapElement = event.target ? event.target : event.srcElement; // IE uses srcElement.
- // Hack for Safari, which can target text nodes instead of containers.
- if(tapElement.nodeType == 3) {
- tapElement = tapElement.parentNode;
- }
-
- element.addClass(ACTIVE_CLASS_NAME);
-
- startTime = Date.now();
-
- var touches = event.touches && event.touches.length ? event.touches : [event];
- var e = touches[0].originalEvent || touches[0];
- touchStartX = e.clientX;
- touchStartY = e.clientY;
- });
-
- element.bind('touchmove', function(event) {
- resetState();
- });
-
- element.bind('touchcancel', function(event) {
- resetState();
- });
-
- element.bind('touchend', function(event) {
- var diff = Date.now() - startTime;
-
- var touches = (event.changedTouches && event.changedTouches.length) ? event.changedTouches :
- ((event.touches && event.touches.length) ? event.touches : [event]);
- var e = touches[0].originalEvent || touches[0];
- var x = e.clientX;
- var y = e.clientY;
- var dist = Math.sqrt( Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2) );
-
- if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) {
- // Call preventGhostClick so the clickbuster will catch the corresponding click.
- preventGhostClick(x, y);
-
- // Blur the focused element (the button, probably) before firing the callback.
- // This doesn't work perfectly on Android Chrome, but seems to work elsewhere.
- // I couldn't get anything to work reliably on Android Chrome.
- if (tapElement) {
- tapElement.blur();
- }
-
- scope.$apply(function() {
- // TODO(braden): This is sending the touchend, not a tap or click. Is that kosher?
- clickHandler(scope, {$event: event});
- });
- }
-
- resetState();
- });
-
- // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click
- // something else nearby.
- element.onclick = function(event) { };
-
- // Fallback click handler.
- // Busted clicks don't get this far, and adding this handler allows ng-tap to be used on
- // desktop as well, to allow more portable sites.
- element.bind('click', function(event) {
- scope.$apply(function() {
- clickHandler(scope, {$event: event});
- });
- });
-
- element.bind('mousedown', function(event) {
- element.addClass(ACTIVE_CLASS_NAME);
- });
-
- element.bind('mousemove mouseup', function(event) {
- element.removeClass(ACTIVE_CLASS_NAME);
- });
-
- };
-}]);
-
-/**
- * @ngdoc directive
- * @name ngMobile.directive:ngSwipeLeft
- *
- * @description
- * Specify custom behavior when an element is swiped to the left on a touchscreen device.
- * A leftward swipe is a quick, right-to-left slide of the finger.
- * Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag too.
- *
- * @element ANY
- * @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate
- * upon left swipe. (Event object is available as `$event`)
- *
- * @example
- <doc:example>
- <doc:source>
- <div ng-show="!showActions" ng-swipe-left="showActions = true">
- Some list content, like an email in the inbox
- </div>
- <div ng-show="showActions" ng-swipe-right="showActions = false">
- <button ng-click="reply()">Reply</button>
- <button ng-click="delete()">Delete</button>
- </div>
- </doc:source>
- </doc:example>
- */
-
-/**
- * @ngdoc directive
- * @name ngMobile.directive:ngSwipeRight
- *
- * @description
- * Specify custom behavior when an element is swiped to the right on a touchscreen device.
- * A rightward swipe is a quick, left-to-right slide of the finger.
- * Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag too.
- *
- * @element ANY
- * @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate
- * upon right swipe. (Event object is available as `$event`)
- *
- * @example
- <doc:example>
- <doc:source>
- <div ng-show="!showActions" ng-swipe-left="showActions = true">
- Some list content, like an email in the inbox
- </div>
- <div ng-show="showActions" ng-swipe-right="showActions = false">
- <button ng-click="reply()">Reply</button>
- <button ng-click="delete()">Delete</button>
- </div>
- </doc:source>
- </doc:example>
- */
-
-function makeSwipeDirective(directiveName, direction) {
- ngMobile.directive(directiveName, ['$parse', function($parse) {
- // The maximum vertical delta for a swipe should be less than 75px.
- var MAX_VERTICAL_DISTANCE = 75;
- // Vertical distance should not be more than a fraction of the horizontal distance.
- var MAX_VERTICAL_RATIO = 0.3;
- // At least a 30px lateral motion is necessary for a swipe.
- var MIN_HORIZONTAL_DISTANCE = 30;
- // The total distance in any direction before we make the call on swipe vs. scroll.
- var MOVE_BUFFER_RADIUS = 10;
-
- function getCoordinates(event) {
- var touches = event.touches && event.touches.length ? event.touches : [event];
- var e = (event.changedTouches && event.changedTouches[0]) ||
- (event.originalEvent && event.originalEvent.changedTouches &&
- event.originalEvent.changedTouches[0]) ||
- touches[0].originalEvent || touches[0];
-
- return {
- x: e.clientX,
- y: e.clientY
- };
- }
-
- return function(scope, element, attr) {
- var swipeHandler = $parse(attr[directiveName]);
- var startCoords, valid;
- var totalX, totalY;
- var lastX, lastY;
-
- function validSwipe(event) {
- // Check that it's within the coordinates.
- // Absolute vertical distance must be within tolerances.
- // Horizontal distance, we take the current X - the starting X.
- // This is negative for leftward swipes and positive for rightward swipes.
- // After multiplying by the direction (-1 for left, +1 for right), legal swipes
- // (ie. same direction as the directive wants) will have a positive delta and
- // illegal ones a negative delta.
- // Therefore this delta must be positive, and larger than the minimum.
- if (!startCoords) return false;
- var coords = getCoordinates(event);
- var deltaY = Math.abs(coords.y - startCoords.y);
- var deltaX = (coords.x - startCoords.x) * direction;
- return valid && // Short circuit for already-invalidated swipes.
- deltaY < MAX_VERTICAL_DISTANCE &&
- deltaX > 0 &&
- deltaX > MIN_HORIZONTAL_DISTANCE &&
- deltaY / deltaX < MAX_VERTICAL_RATIO;
- }
-
- element.bind('touchstart mousedown', function(event) {
- startCoords = getCoordinates(event);
- valid = true;
- totalX = 0;
- totalY = 0;
- lastX = startCoords.x;
- lastY = startCoords.y;
- });
-
- element.bind('touchcancel', function(event) {
- valid = false;
- });
-
- element.bind('touchmove mousemove', function(event) {
- if (!valid) return;
-
- // Android will send a touchcancel if it thinks we're starting to scroll.
- // So when the total distance (+ or - or both) exceeds 10px in either direction,
- // we either:
- // - On totalX > totalY, we send preventDefault() and treat this as a swipe.
- // - On totalY > totalX, we let the browser handle it as a scroll.
-
- // Invalidate a touch while it's in progress if it strays too far away vertically.
- // We don't want a scroll down and back up while drifting sideways to be a swipe just
- // because you happened to end up vertically close in the end.
- if (!startCoords) return;
- var coords = getCoordinates(event);
-
- if (Math.abs(coords.y - startCoords.y) > MAX_VERTICAL_DISTANCE) {
- valid = false;
- return;
- }
-
- totalX += Math.abs(coords.x - lastX);
- totalY += Math.abs(coords.y - lastY);
-
- lastX = coords.x;
- lastY = coords.y;
-
- if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) {
- return;
- }
-
- // One of totalX or totalY has exceeded the buffer, so decide on swipe vs. scroll.
- if (totalY > totalX) {
- valid = false;
- return;
- } else {
- event.preventDefault();
- }
- });
-
- element.bind('touchend mouseup', function(event) {
- if (validSwipe(event)) {
- // Prevent this swipe from bubbling up to any other elements with ngSwipes.
- event.stopPropagation();
- scope.$apply(function() {
- swipeHandler(scope, {$event:event});
- });
- }
- });
- };
- }]);
-}
-
-// Left is negative X-coordinate, right is positive.
-makeSwipeDirective('ngSwipeLeft', -1);
-makeSwipeDirective('ngSwipeRight', 1);
-
-
-
-})(window, window.angular);
Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-mocks.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-mocks.js (rev 0)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-mocks.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -0,0 +1,1952 @@
+/** %%Ignore-License
+ * @license AngularJS v1.2.0rc1
+ * (c) 2010-2012 Google, Inc. http://angularjs.org
+ * License: MIT
+ *
+ * TODO(vojta): wrap whole file into closure during build
+ */
+
+/**
+ * @ngdoc overview
+ * @name angular.mock
+ * @description
+ *
+ * Namespace from 'angular-mocks.js' which contains testing related code.
+ */
+angular.mock = {};
+
+/**
+ * ! This is a private undocumented service !
+ *
+ * @name ngMock.$browser
+ *
+ * @description
+ * This service is a mock implementation of {@link ng.$browser}. It provides fake
+ * implementation for commonly used browser apis that are hard to test, e.g. setTimeout, xhr,
+ * cookies, etc...
+ *
+ * The api of this service is the same as that of the real {@link ng.$browser $browser}, except
+ * that there are several helper methods available which can be used in tests.
+ */
+angular.mock.$BrowserProvider = function() {
+ this.$get = function() {
+ return new angular.mock.$Browser();
+ };
+};
+
+angular.mock.$Browser = function() {
+ var self = this;
+
+ this.isMock = true;
+ self.$$url = "http://server/";
+ self.$$lastUrl = self.$$url; // used by url polling fn
+ self.pollFns = [];
+
+ // TODO(vojta): remove this temporary api
+ self.$$completeOutstandingRequest = angular.noop;
+ self.$$incOutstandingRequestCount = angular.noop;
+
+
+ // register url polling fn
+
+ self.onUrlChange = function(listener) {
+ self.pollFns.push(
+ function() {
+ if (self.$$lastUrl != self.$$url) {
+ self.$$lastUrl = self.$$url;
+ listener(self.$$url);
+ }
+ }
+ );
+
+ return listener;
+ };
+
+ self.cookieHash = {};
+ self.lastCookieHash = {};
+ self.deferredFns = [];
+ self.deferredNextId = 0;
+
+ self.defer = function(fn, delay) {
+ delay = delay || 0;
+ self.deferredFns.push({time:(self.defer.now + delay), fn:fn, id: self.deferredNextId});
+ self.deferredFns.sort(function(a,b){ return a.time - b.time;});
+ return self.deferredNextId++;
+ };
+
+
+ self.defer.now = 0;
+
+
+ self.defer.cancel = function(deferId) {
+ var fnIndex;
+
+ angular.forEach(self.deferredFns, function(fn, index) {
+ if (fn.id === deferId) fnIndex = index;
+ });
+
+ if (fnIndex !== undefined) {
+ self.deferredFns.splice(fnIndex, 1);
+ return true;
+ }
+
+ return false;
+ };
+
+
+ /**
+ * @name ngMock.$browser#defer.flush
+ * @methodOf ngMock.$browser
+ *
+ * @description
+ * Flushes all pending requests and executes the defer callbacks.
+ *
+ * @param {number=} number of milliseconds to flush. See {@link #defer.now}
+ */
+ self.defer.flush = function(delay) {
+ if (angular.isDefined(delay)) {
+ self.defer.now += delay;
+ } else {
+ if (self.deferredFns.length) {
+ self.defer.now = self.deferredFns[self.deferredFns.length-1].time;
+ } else {
+ throw Error('No deferred tasks to be flushed');
+ }
+ }
+
+ while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) {
+ self.deferredFns.shift().fn();
+ }
+ };
+
+ /**
+ * @name ngMock.$browser#defer.flushNext
+ * @methodOf ngMock.$browser
+ *
+ * @description
+ * Flushes next pending request and compares it to the provided delay
+ *
+ * @param {number=} expectedDelay the delay value that will be asserted against the delay of the next timeout function
+ */
+ self.defer.flushNext = function(expectedDelay) {
+ var tick = self.deferredFns.shift();
+ expect(tick.time).toEqual(expectedDelay);
+ tick.fn();
+ };
+
+ /**
+ * @name ngMock.$browser#defer.now
+ * @propertyOf ngMock.$browser
+ *
+ * @description
+ * Current milliseconds mock time.
+ */
+
+ self.$$baseHref = '';
+ self.baseHref = function() {
+ return this.$$baseHref;
+ };
+};
+angular.mock.$Browser.prototype = {
+
+/**
+ * @name ngMock.$browser#poll
+ * @methodOf ngMock.$browser
+ *
+ * @description
+ * run all fns in pollFns
+ */
+ poll: function poll() {
+ angular.forEach(this.pollFns, function(pollFn){
+ pollFn();
+ });
+ },
+
+ addPollFn: function(pollFn) {
+ this.pollFns.push(pollFn);
+ return pollFn;
+ },
+
+ url: function(url, replace) {
+ if (url) {
+ this.$$url = url;
+ return this;
+ }
+
+ return this.$$url;
+ },
+
+ cookies: function(name, value) {
+ if (name) {
+ if (value == undefined) {
+ delete this.cookieHash[name];
+ } else {
+ if (angular.isString(value) && //strings only
+ value.length <= 4096) { //strict cookie storage limits
+ this.cookieHash[name] = value;
+ }
+ }
+ } else {
+ if (!angular.equals(this.cookieHash, this.lastCookieHash)) {
+ this.lastCookieHash = angular.copy(this.cookieHash);
+ this.cookieHash = angular.copy(this.cookieHash);
+ }
+ return this.cookieHash;
+ }
+ },
+
+ notifyWhenNoOutstandingRequests: function(fn) {
+ fn();
+ }
+};
+
+
+/**
+ * @ngdoc object
+ * @name ngMock.$exceptionHandlerProvider
+ *
+ * @description
+ * Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors passed
+ * into the `$exceptionHandler`.
+ */
+
+/**
+ * @ngdoc object
+ * @name ngMock.$exceptionHandler
+ *
+ * @description
+ * Mock implementation of {@link ng.$exceptionHandler} that rethrows or logs errors passed
+ * into it. See {@link ngMock.$exceptionHandlerProvider $exceptionHandlerProvider} for configuration
+ * information.
+ *
+ *
+ * <pre>
+ * describe('$exceptionHandlerProvider', function() {
+ *
+ * it('should capture log messages and exceptions', function() {
+ *
+ * module(function($exceptionHandlerProvider) {
+ * $exceptionHandlerProvider.mode('log');
+ * });
+ *
+ * inject(function($log, $exceptionHandler, $timeout) {
+ * $timeout(function() { $log.log(1); });
+ * $timeout(function() { $log.log(2); throw 'banana peel'; });
+ * $timeout(function() { $log.log(3); });
+ * expect($exceptionHandler.errors).toEqual([]);
+ * expect($log.assertEmpty());
+ * $timeout.flush();
+ * expect($exceptionHandler.errors).toEqual(['banana peel']);
+ * expect($log.log.logs).toEqual([[1], [2], [3]]);
+ * });
+ * });
+ * });
+ * </pre>
+ */
+
+angular.mock.$ExceptionHandlerProvider = function() {
+ var handler;
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$exceptionHandlerProvider#mode
+ * @methodOf ngMock.$exceptionHandlerProvider
+ *
+ * @description
+ * Sets the logging mode.
+ *
+ * @param {string} mode Mode of operation, defaults to `rethrow`.
+ *
+ * - `rethrow`: If any errors are passed into the handler in tests, it typically
+ * means that there is a bug in the application or test, so this mock will
+ * make these tests fail.
+ * - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log` mode stores an
+ * array of errors in `$exceptionHandler.errors`, to allow later assertion of them.
+ * See {@link ngMock.$log#assertEmpty assertEmpty()} and
+ * {@link ngMock.$log#reset reset()}
+ */
+ this.mode = function(mode) {
+ switch(mode) {
+ case 'rethrow':
+ handler = function(e) {
+ throw e;
+ };
+ break;
+ case 'log':
+ var errors = [];
+
+ handler = function(e) {
+ if (arguments.length == 1) {
+ errors.push(e);
+ } else {
+ errors.push([].slice.call(arguments, 0));
+ }
+ };
+
+ handler.errors = errors;
+ break;
+ default:
+ throw Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!");
+ }
+ };
+
+ this.$get = function() {
+ return handler;
+ };
+
+ this.mode('rethrow');
+};
+
+
+/**
+ * @ngdoc service
+ * @name ngMock.$log
+ *
+ * @description
+ * Mock implementation of {@link ng.$log} that gathers all logged messages in arrays
+ * (one array per logging level). These arrays are exposed as `logs` property of each of the
+ * level-specific log function, e.g. for level `error` the array is exposed as `$log.error.logs`.
+ *
+ */
+angular.mock.$LogProvider = function() {
+ var debug = true;
+
+ function concat(array1, array2, index) {
+ return array1.concat(Array.prototype.slice.call(array2, index));
+ }
+
+ this.debugEnabled = function(flag) {
+ if (isDefined(flag)) {
+ debug = flag;
+ return this;
+ } else {
+ return debug;
+ }
+ };
+
+ this.$get = function () {
+ var $log = {
+ log: function() { $log.log.logs.push(concat([], arguments, 0)); },
+ warn: function() { $log.warn.logs.push(concat([], arguments, 0)); },
+ info: function() { $log.info.logs.push(concat([], arguments, 0)); },
+ error: function() { $log.error.logs.push(concat([], arguments, 0)); },
+ debug: function() {
+ if (debug) {
+ $log.debug.logs.push(concat([], arguments, 0));
+ }
+ }
+ };
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$log#reset
+ * @methodOf ngMock.$log
+ *
+ * @description
+ * Reset all of the logging arrays to empty.
+ */
+ $log.reset = function () {
+ /**
+ * @ngdoc property
+ * @name ngMock.$log#log.logs
+ * @propertyOf ngMock.$log
+ *
+ * @description
+ * Array of messages logged using {@link ngMock.$log#log}.
+ *
+ * @example
+ * <pre>
+ * $log.log('Some Log');
+ * var first = $log.log.logs.unshift();
+ * </pre>
+ */
+ $log.log.logs = [];
+ /**
+ * @ngdoc property
+ * @name ngMock.$log#info.logs
+ * @propertyOf ngMock.$log
+ *
+ * @description
+ * Array of messages logged using {@link ngMock.$log#info}.
+ *
+ * @example
+ * <pre>
+ * $log.info('Some Info');
+ * var first = $log.info.logs.unshift();
+ * </pre>
+ */
+ $log.info.logs = [];
+ /**
+ * @ngdoc property
+ * @name ngMock.$log#warn.logs
+ * @propertyOf ngMock.$log
+ *
+ * @description
+ * Array of messages logged using {@link ngMock.$log#warn}.
+ *
+ * @example
+ * <pre>
+ * $log.warn('Some Warning');
+ * var first = $log.warn.logs.unshift();
+ * </pre>
+ */
+ $log.warn.logs = [];
+ /**
+ * @ngdoc property
+ * @name ngMock.$log#error.logs
+ * @propertyOf ngMock.$log
+ *
+ * @description
+ * Array of messages logged using {@link ngMock.$log#error}.
+ *
+ * @example
+ * <pre>
+ * $log.log('Some Error');
+ * var first = $log.error.logs.unshift();
+ * </pre>
+ */
+ $log.error.logs = [];
+ /**
+ * @ngdoc property
+ * @name ngMock.$log#debug.logs
+ * @propertyOf ngMock.$log
+ *
+ * @description
+ * Array of messages logged using {@link ngMock.$log#debug}.
+ *
+ * @example
+ * <pre>
+ * $log.debug('Some Error');
+ * var first = $log.debug.logs.unshift();
+ * </pre>
+ */
+ $log.debug.logs = []
+ };
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$log#assertEmpty
+ * @methodOf ngMock.$log
+ *
+ * @description
+ * Assert that the all of the logging methods have no logged messages. If messages present, an exception is thrown.
+ */
+ $log.assertEmpty = function() {
+ var errors = [];
+ angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) {
+ angular.forEach($log[logLevel].logs, function(log) {
+ angular.forEach(log, function (logItem) {
+ errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' + (logItem.stack || ''));
+ });
+ });
+ });
+ if (errors.length) {
+ errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or an expected " +
+ "log message was not checked and removed:");
+ errors.push('');
+ throw new Error(errors.join('\n---------\n'));
+ }
+ };
+
+ $log.reset();
+ return $log;
+ };
+};
+
+
+(function() {
+ var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/;
+
+ function jsonStringToDate(string) {
+ var match;
+ if (match = string.match(R_ISO8061_STR)) {
+ var date = new Date(0),
+ tzHour = 0,
+ tzMin = 0;
+ if (match[9]) {
+ tzHour = int(match[9] + match[10]);
+ tzMin = int(match[9] + match[11]);
+ }
+ date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3]));
+ date.setUTCHours(int(match[4]||0) - tzHour, int(match[5]||0) - tzMin, int(match[6]||0), int(match[7]||0));
+ return date;
+ }
+ return string;
+ }
+
+ function int(str) {
+ return parseInt(str, 10);
+ }
+
+ function padNumber(num, digits, trim) {
+ var neg = '';
+ if (num < 0) {
+ neg = '-';
+ num = -num;
+ }
+ num = '' + num;
+ while(num.length < digits) num = '0' + num;
+ if (trim)
+ num = num.substr(num.length - digits);
+ return neg + num;
+ }
+
+
+ /**
+ * @ngdoc object
+ * @name angular.mock.TzDate
+ * @description
+ *
+ * *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`.
+ *
+ * Mock of the Date type which has its timezone specified via constructor arg.
+ *
+ * The main purpose is to create Date-like instances with timezone fixed to the specified timezone
+ * offset, so that we can test code that depends on local timezone settings without dependency on
+ * the time zone settings of the machine where the code is running.
+ *
+ * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored)
+ * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
+ *
+ * @example
+ * !!!! WARNING !!!!!
+ * This is not a complete Date object so only methods that were implemented can be called safely.
+ * To make matters worse, TzDate instances inherit stuff from Date via a prototype.
+ *
+ * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
+ * incomplete we might be missing some non-standard methods. This can result in errors like:
+ * "Date.prototype.foo called on incompatible Object".
+ *
+ * <pre>
+ * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
+ * newYearInBratislava.getTimezoneOffset() => -60;
+ * newYearInBratislava.getFullYear() => 2010;
+ * newYearInBratislava.getMonth() => 0;
+ * newYearInBratislava.getDate() => 1;
+ * newYearInBratislava.getHours() => 0;
+ * newYearInBratislava.getMinutes() => 0;
+ * newYearInBratislava.getSeconds() => 0;
+ * </pre>
+ *
+ */
+ angular.mock.TzDate = function (offset, timestamp) {
+ var self = new Date(0);
+ if (angular.isString(timestamp)) {
+ var tsStr = timestamp;
+
+ self.origDate = jsonStringToDate(timestamp);
+
+ timestamp = self.origDate.getTime();
+ if (isNaN(timestamp))
+ throw {
+ name: "Illegal Argument",
+ message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
+ };
+ } else {
+ self.origDate = new Date(timestamp);
+ }
+
+ var localOffset = new Date(timestamp).getTimezoneOffset();
+ self.offsetDiff = localOffset*60*1000 - offset*1000*60*60;
+ self.date = new Date(timestamp + self.offsetDiff);
+
+ self.getTime = function() {
+ return self.date.getTime() - self.offsetDiff;
+ };
+
+ self.toLocaleDateString = function() {
+ return self.date.toLocaleDateString();
+ };
+
+ self.getFullYear = function() {
+ return self.date.getFullYear();
+ };
+
+ self.getMonth = function() {
+ return self.date.getMonth();
+ };
+
+ self.getDate = function() {
+ return self.date.getDate();
+ };
+
+ self.getHours = function() {
+ return self.date.getHours();
+ };
+
+ self.getMinutes = function() {
+ return self.date.getMinutes();
+ };
+
+ self.getSeconds = function() {
+ return self.date.getSeconds();
+ };
+
+ self.getMilliseconds = function() {
+ return self.date.getMilliseconds();
+ };
+
+ self.getTimezoneOffset = function() {
+ return offset * 60;
+ };
+
+ self.getUTCFullYear = function() {
+ return self.origDate.getUTCFullYear();
+ };
+
+ self.getUTCMonth = function() {
+ return self.origDate.getUTCMonth();
+ };
+
+ self.getUTCDate = function() {
+ return self.origDate.getUTCDate();
+ };
+
+ self.getUTCHours = function() {
+ return self.origDate.getUTCHours();
+ };
+
+ self.getUTCMinutes = function() {
+ return self.origDate.getUTCMinutes();
+ };
+
+ self.getUTCSeconds = function() {
+ return self.origDate.getUTCSeconds();
+ };
+
+ self.getUTCMilliseconds = function() {
+ return self.origDate.getUTCMilliseconds();
+ };
+
+ self.getDay = function() {
+ return self.date.getDay();
+ };
+
+ // provide this method only on browsers that already have it
+ if (self.toISOString) {
+ self.toISOString = function() {
+ return padNumber(self.origDate.getUTCFullYear(), 4) + '-' +
+ padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' +
+ padNumber(self.origDate.getUTCDate(), 2) + 'T' +
+ padNumber(self.origDate.getUTCHours(), 2) + ':' +
+ padNumber(self.origDate.getUTCMinutes(), 2) + ':' +
+ padNumber(self.origDate.getUTCSeconds(), 2) + '.' +
+ padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z'
+ }
+ }
+
+ //hide all methods not implemented in this mock that the Date prototype exposes
+ var unimplementedMethods = ['getUTCDay',
+ 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',
+ 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
+ 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
+ 'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString',
+ 'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];
+
+ angular.forEach(unimplementedMethods, function(methodName) {
+ self[methodName] = function() {
+ throw Error("Method '" + methodName + "' is not implemented in the TzDate mock");
+ };
+ });
+
+ return self;
+ };
+
+ //make "tzDateInstance instanceof Date" return true
+ angular.mock.TzDate.prototype = Date.prototype;
+})();
+
+angular.mock.animate = angular.module('mock.animate', ['ng'])
+
+ .config(['$provide', function($provide) {
+
+ $provide.decorator('$animate', function($delegate) {
+ var animate = {
+ queue : [],
+ enabled : $delegate.enabled,
+ flushNext : function(name) {
+ var tick = animate.queue.shift();
+ expect(tick.method).toBe(name);
+ tick.fn();
+ return tick;
+ }
+ };
+
+ forEach(['enter','leave','move','addClass','removeClass'], function(method) {
+ animate[method] = function() {
+ var params = arguments;
+ animate.queue.push({
+ method : method,
+ params : params,
+ element : angular.isElement(params[0]) && params[0],
+ parent : angular.isElement(params[1]) && params[1],
+ after : angular.isElement(params[2]) && params[2],
+ fn : function() {
+ $delegate[method].apply($delegate, params);
+ }
+ });
+ };
+ });
+
+ return animate;
+ });
+
+ }]);
+
+
+/**
+ * @ngdoc function
+ * @name angular.mock.dump
+ * @description
+ *
+ * *NOTE*: this is not an injectable instance, just a globally available function.
+ *
+ * Method for serializing common angular objects (scope, elements, etc..) into strings, useful for debugging.
+ *
+ * This method is also available on window, where it can be used to display objects on debug console.
+ *
+ * @param {*} object - any object to turn into string.
+ * @return {string} a serialized string of the argument
+ */
+angular.mock.dump = function(object) {
+ return serialize(object);
+
+ function serialize(object) {
+ var out;
+
+ if (angular.isElement(object)) {
+ object = angular.element(object);
+ out = angular.element('<div></div>');
+ angular.forEach(object, function(element) {
+ out.append(angular.element(element).clone());
+ });
+ out = out.html();
+ } else if (angular.isArray(object)) {
+ out = [];
+ angular.forEach(object, function(o) {
+ out.push(serialize(o));
+ });
+ out = '[ ' + out.join(', ') + ' ]';
+ } else if (angular.isObject(object)) {
+ if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) {
+ out = serializeScope(object);
+ } else if (object instanceof Error) {
+ out = object.stack || ('' + object.name + ': ' + object.message);
+ } else {
+ // TODO(i): this prevents methods to be logged, we should have a better way to serialize objects
+ out = angular.toJson(object, true);
+ }
+ } else {
+ out = String(object);
+ }
+
+ return out;
+ }
+
+ function serializeScope(scope, offset) {
+ offset = offset || ' ';
+ var log = [offset + 'Scope(' + scope.$id + '): {'];
+ for ( var key in scope ) {
+ if (scope.hasOwnProperty(key) && !key.match(/^(\$|this)/)) {
+ log.push(' ' + key + ': ' + angular.toJson(scope[key]));
+ }
+ }
+ var child = scope.$$childHead;
+ while(child) {
+ log.push(serializeScope(child, offset + ' '));
+ child = child.$$nextSibling;
+ }
+ log.push('}');
+ return log.join('\n' + offset);
+ }
+};
+
+/**
+ * @ngdoc object
+ * @name ngMock.$httpBackend
+ * @description
+ * Fake HTTP backend implementation suitable for unit testing applications that use the
+ * {@link ng.$http $http service}.
+ *
+ * *Note*: For fake HTTP backend implementation suitable for end-to-end testing or backend-less
+ * development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}.
+ *
+ * During unit testing, we want our unit tests to run quickly and have no external dependencies so
+ * we don’t want to send {@link https://developer.mozilla.org/en/xmlhttprequest XHR} or
+ * {@link http://en.wikipedia.org/wiki/JSONP JSONP} requests to a real server. All we really need is
+ * to verify whether a certain request has been sent or not, or alternatively just let the
+ * application make requests, respond with pre-trained responses and assert that the end result is
+ * what we expect it to be.
+ *
+ * This mock implementation can be used to respond with static or dynamic responses via the
+ * `expect` and `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc).
+ *
+ * When an Angular application needs some data from a server, it calls the $http service, which
+ * sends the request to a real server using $httpBackend service. With dependency injection, it is
+ * easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify
+ * the requests and respond with some testing data without sending a request to real server.
+ *
+ * There are two ways to specify what test data should be returned as http responses by the mock
+ * backend when the code under test makes http requests:
+ *
+ * - `$httpBackend.expect` - specifies a request expectation
+ * - `$httpBackend.when` - specifies a backend definition
+ *
+ *
+ * # Request Expectations vs Backend Definitions
+ *
+ * Request expectations provide a way to make assertions about requests made by the application and
+ * to define responses for those requests. The test will fail if the expected requests are not made
+ * or they are made in the wrong order.
+ *
+ * Backend definitions allow you to define a fake backend for your application which doesn't assert
+ * if a particular request was made or not, it just returns a trained response if a request is made.
+ * The test will pass whether or not the request gets made during testing.
+ *
+ *
+ * <table class="table">
+ * <tr><th width="220px"></th><th>Request expectations</th><th>Backend definitions</th></tr>
+ * <tr>
+ * <th>Syntax</th>
+ * <td>.expect(...).respond(...)</td>
+ * <td>.when(...).respond(...)</td>
+ * </tr>
+ * <tr>
+ * <th>Typical usage</th>
+ * <td>strict unit tests</td>
+ * <td>loose (black-box) unit testing</td>
+ * </tr>
+ * <tr>
+ * <th>Fulfills multiple requests</th>
+ * <td>NO</td>
+ * <td>YES</td>
+ * </tr>
+ * <tr>
+ * <th>Order of requests matters</th>
+ * <td>YES</td>
+ * <td>NO</td>
+ * </tr>
+ * <tr>
+ * <th>Request required</th>
+ * <td>YES</td>
+ * <td>NO</td>
+ * </tr>
+ * <tr>
+ * <th>Response required</th>
+ * <td>optional (see below)</td>
+ * <td>YES</td>
+ * </tr>
+ * </table>
+ *
+ * In cases where both backend definitions and request expectations are specified during unit
+ * testing, the request expectations are evaluated first.
+ *
+ * If a request expectation has no response specified, the algorithm will search your backend
+ * definitions for an appropriate response.
+ *
+ * If a request didn't match any expectation or if the expectation doesn't have the response
+ * defined, the backend definitions are evaluated in sequential order to see if any of them match
+ * the request. The response from the first matched definition is returned.
+ *
+ *
+ * # Flushing HTTP requests
+ *
+ * The $httpBackend used in production, always responds to requests with responses asynchronously.
+ * If we preserved this behavior in unit testing, we'd have to create async unit tests, which are
+ * hard to write, follow and maintain. At the same time the testing mock, can't respond
+ * synchronously because that would change the execution of the code under test. For this reason the
+ * mock $httpBackend has a `flush()` method, which allows the test to explicitly flush pending
+ * requests and thus preserving the async api of the backend, while allowing the test to execute
+ * synchronously.
+ *
+ *
+ * # Unit testing with mock $httpBackend
+ * The following code shows how to setup and use the mock backend in unit testing a controller.
+ * First we create the controller under test
+ *
+ <pre>
+ // The controller code
+ function MyController($scope, $http) {
+ var authToken;
+
+ $http.get('/auth.py').success(function(data, status, headers) {
+ authToken = headers('A-Token');
+ $scope.user = data;
+ });
+
+ $scope.saveMessage = function(message) {
+ var headers = { 'Authorization': authToken };
+ $scope.status = 'Saving...';
+
+ $http.post('/add-msg.py', message, { headers: headers } ).success(function(response) {
+ $scope.status = '';
+ }).error(function() {
+ $scope.status = 'ERROR!';
+ });
+ };
+ }
+ </pre>
+ *
+ * Now we setup the mock backend and create the test specs.
+ *
+ <pre>
+ // testing controller
+ describe('MyController', function() {
+ var $httpBackend, $rootScope, createController;
+
+ beforeEach(inject(function($injector) {
+ // Set up the mock http service responses
+ $httpBackend = $injector.get('$httpBackend');
+ // backend definition common for all tests
+ $httpBackend.when('GET', '/auth.py').respond({userId: 'userX'}, {'A-Token': 'xxx'});
+
+ // Get hold of a scope (i.e. the root scope)
+ $rootScope = $injector.get('$rootScope');
+ // The $controller service is used to create instances of controllers
+ var $controller = $injector.get('$controller');
+
+ createController = function() {
+ return $controller('MyController', {'$scope' : $rootScope });
+ };
+ }));
+
+
+ afterEach(function() {
+ $httpBackend.verifyNoOutstandingExpectation();
+ $httpBackend.verifyNoOutstandingRequest();
+ });
+
+
+ it('should fetch authentication token', function() {
+ $httpBackend.expectGET('/auth.py');
+ var controller = createController();
+ $httpBackend.flush();
+ });
+
+
+ it('should send msg to server', function() {
+ var controller = createController();
+ $httpBackend.flush();
+
+ // now you don’t care about the authentication, but
+ // the controller will still send the request and
+ // $httpBackend will respond without you having to
+ // specify the expectation and response for this request
+
+ $httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, '');
+ $rootScope.saveMessage('message content');
+ expect($rootScope.status).toBe('Saving...');
+ $httpBackend.flush();
+ expect($rootScope.status).toBe('');
+ });
+
+
+ it('should send auth header', function() {
+ var controller = createController();
+ $httpBackend.flush();
+
+ $httpBackend.expectPOST('/add-msg.py', undefined, function(headers) {
+ // check if the header was send, if it wasn't the expectation won't
+ // match the request and the test will fail
+ return headers['Authorization'] == 'xxx';
+ }).respond(201, '');
+
+ $rootScope.saveMessage('whatever');
+ $httpBackend.flush();
+ });
+ });
+ </pre>
+ */
+angular.mock.$HttpBackendProvider = function() {
+ this.$get = ['$rootScope', createHttpBackendMock];
+};
+
+/**
+ * General factory function for $httpBackend mock.
+ * Returns instance for unit testing (when no arguments specified):
+ * - passing through is disabled
+ * - auto flushing is disabled
+ *
+ * Returns instance for e2e testing (when `$delegate` and `$browser` specified):
+ * - passing through (delegating request to real backend) is enabled
+ * - auto flushing is enabled
+ *
+ * @param {Object=} $delegate Real $httpBackend instance (allow passing through if specified)
+ * @param {Object=} $browser Auto-flushing enabled if specified
+ * @return {Object} Instance of $httpBackend mock
+ */
+function createHttpBackendMock($rootScope, $delegate, $browser) {
+ var definitions = [],
+ expectations = [],
+ responses = [],
+ responsesPush = angular.bind(responses, responses.push);
+
+ function createResponse(status, data, headers) {
+ if (angular.isFunction(status)) return status;
+
+ return function() {
+ return angular.isNumber(status)
+ ? [status, data, headers]
+ : [200, status, data];
+ };
+ }
+
+ // TODO(vojta): change params to: method, url, data, headers, callback
+ function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) {
+ var xhr = new MockXhr(),
+ expectation = expectations[0],
+ wasExpected = false;
+
+ function prettyPrint(data) {
+ return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp)
+ ? data
+ : angular.toJson(data);
+ }
+
+ function wrapResponse(wrapped) {
+ if (!$browser && timeout && timeout.then) timeout.then(handleTimeout);
+
+ return handleResponse;
+
+ function handleResponse() {
+ var response = wrapped.response(method, url, data, headers);
+ xhr.$$respHeaders = response[2];
+ callback(response[0], response[1], xhr.getAllResponseHeaders());
+ }
+
+ function handleTimeout() {
+ for (var i = 0, ii = responses.length; i < ii; i++) {
+ if (responses[i] === handleResponse) {
+ responses.splice(i, 1);
+ callback(-1, undefined, '');
+ break;
+ }
+ }
+ }
+ }
+
+ if (expectation && expectation.match(method, url)) {
+ if (!expectation.matchData(data))
+ throw new Error('Expected ' + expectation + ' with different data\n' +
+ 'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data);
+
+ if (!expectation.matchHeaders(headers))
+ throw new Error('Expected ' + expectation + ' with different headers\n' +
+ 'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' + prettyPrint(headers));
+
+ expectations.shift();
+
+ if (expectation.response) {
+ responses.push(wrapResponse(expectation));
+ return;
+ }
+ wasExpected = true;
+ }
+
+ var i = -1, definition;
+ while ((definition = definitions[++i])) {
+ if (definition.match(method, url, data, headers || {})) {
+ if (definition.response) {
+ // if $browser specified, we do auto flush all requests
+ ($browser ? $browser.defer : responsesPush)(wrapResponse(definition));
+ } else if (definition.passThrough) {
+ $delegate(method, url, data, callback, headers, timeout, withCredentials);
+ } else throw Error('No response defined !');
+ return;
+ }
+ }
+ throw wasExpected ?
+ new Error('No response defined !') :
+ new Error('Unexpected request: ' + method + ' ' + url + '\n' +
+ (expectation ? 'Expected ' + expectation : 'No more request expected'));
+ }
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#when
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new backend definition.
+ *
+ * @param {string} method HTTP method.
+ * @param {string|RegExp} url HTTP url.
+ * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
+ * data string and returns true if the data is as expected.
+ * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
+ * object and returns true if the headers match the current definition.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ *
+ * - respond – `{function([status,] data[, headers])|function(function(method, url, data, headers)}`
+ * – The respond method takes a set of static data to be returned or a function that can return
+ * an array containing response status (number), response data (string) and response headers
+ * (Object).
+ */
+ $httpBackend.when = function(method, url, data, headers) {
+ var definition = new MockHttpExpectation(method, url, data, headers),
+ chain = {
+ respond: function(status, data, headers) {
+ definition.response = createResponse(status, data, headers);
+ }
+ };
+
+ if ($browser) {
+ chain.passThrough = function() {
+ definition.passThrough = true;
+ };
+ }
+
+ definitions.push(definition);
+ return chain;
+ };
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#whenGET
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new backend definition for GET requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(Object|function(Object))=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#whenHEAD
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new backend definition for HEAD requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(Object|function(Object))=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#whenDELETE
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new backend definition for DELETE requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(Object|function(Object))=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#whenPOST
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new backend definition for POST requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
+ * data string and returns true if the data is as expected.
+ * @param {(Object|function(Object))=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#whenPUT
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new backend definition for PUT requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
+ * data string and returns true if the data is as expected.
+ * @param {(Object|function(Object))=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#whenJSONP
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new backend definition for JSONP requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ */
+ createShortMethods('when');
+
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#expect
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new request expectation.
+ *
+ * @param {string} method HTTP method.
+ * @param {string|RegExp} url HTTP url.
+ * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
+ * receives data string and returns true if the data is as expected, or Object if request body
+ * is in JSON format.
+ * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
+ * object and returns true if the headers match the current expectation.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ *
+ * - respond – `{function([status,] data[, headers])|function(function(method, url, data, headers)}`
+ * – The respond method takes a set of static data to be returned or a function that can return
+ * an array containing response status (number), response data (string) and response headers
+ * (Object).
+ */
+ $httpBackend.expect = function(method, url, data, headers) {
+ var expectation = new MockHttpExpectation(method, url, data, headers);
+ expectations.push(expectation);
+ return {
+ respond: function(status, data, headers) {
+ expectation.response = createResponse(status, data, headers);
+ }
+ };
+ };
+
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#expectGET
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new request expectation for GET requests. For more info see `expect()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {Object=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled. See #expect for more info.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#expectHEAD
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new request expectation for HEAD requests. For more info see `expect()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {Object=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#expectDELETE
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new request expectation for DELETE requests. For more info see `expect()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {Object=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#expectPOST
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new request expectation for POST requests. For more info see `expect()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
+ * receives data string and returns true if the data is as expected, or Object if request body
+ * is in JSON format.
+ * @param {Object=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#expectPUT
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new request expectation for PUT requests. For more info see `expect()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
+ * receives data string and returns true if the data is as expected, or Object if request body
+ * is in JSON format.
+ * @param {Object=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#expectPATCH
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new request expectation for PATCH requests. For more info see `expect()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
+ * receives data string and returns true if the data is as expected, or Object if request body
+ * is in JSON format.
+ * @param {Object=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ */
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#expectJSONP
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Creates a new request expectation for JSONP requests. For more info see `expect()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @returns {requestHandler} Returns an object with `respond` method that control how a matched
+ * request is handled.
+ */
+ createShortMethods('expect');
+
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#flush
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Flushes all pending requests using the trained responses.
+ *
+ * @param {number=} count Number of responses to flush (in the order they arrived). If undefined,
+ * all pending requests will be flushed. If there are no pending requests when the flush method
+ * is called an exception is thrown (as this typically a sign of programming error).
+ */
+ $httpBackend.flush = function(count) {
+ $rootScope.$digest();
+ if (!responses.length) throw Error('No pending request to flush !');
+
+ if (angular.isDefined(count)) {
+ while (count--) {
+ if (!responses.length) throw Error('No more pending request to flush !');
+ responses.shift()();
+ }
+ } else {
+ while (responses.length) {
+ responses.shift()();
+ }
+ }
+ $httpBackend.verifyNoOutstandingExpectation();
+ };
+
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#verifyNoOutstandingExpectation
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Verifies that all of the requests defined via the `expect` api were made. If any of the
+ * requests were not made, verifyNoOutstandingExpectation throws an exception.
+ *
+ * Typically, you would call this method following each test case that asserts requests using an
+ * "afterEach" clause.
+ *
+ * <pre>
+ * afterEach($httpBackend.verifyNoOutstandingExpectation);
+ * </pre>
+ */
+ $httpBackend.verifyNoOutstandingExpectation = function() {
+ $rootScope.$digest();
+ if (expectations.length) {
+ throw new Error('Unsatisfied requests: ' + expectations.join(', '));
+ }
+ };
+
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#verifyNoOutstandingRequest
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Verifies that there are no outstanding requests that need to be flushed.
+ *
+ * Typically, you would call this method following each test case that asserts requests using an
+ * "afterEach" clause.
+ *
+ * <pre>
+ * afterEach($httpBackend.verifyNoOutstandingRequest);
+ * </pre>
+ */
+ $httpBackend.verifyNoOutstandingRequest = function() {
+ if (responses.length) {
+ throw Error('Unflushed requests: ' + responses.length);
+ }
+ };
+
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$httpBackend#resetExpectations
+ * @methodOf ngMock.$httpBackend
+ * @description
+ * Resets all request expectations, but preserves all backend definitions. Typically, you would
+ * call resetExpectations during a multiple-phase test when you want to reuse the same instance of
+ * $httpBackend mock.
+ */
+ $httpBackend.resetExpectations = function() {
+ expectations.length = 0;
+ responses.length = 0;
+ };
+
+ return $httpBackend;
+
+
+ function createShortMethods(prefix) {
+ angular.forEach(['GET', 'DELETE', 'JSONP'], function(method) {
+ $httpBackend[prefix + method] = function(url, headers) {
+ return $httpBackend[prefix](method, url, undefined, headers)
+ }
+ });
+
+ angular.forEach(['PUT', 'POST', 'PATCH'], function(method) {
+ $httpBackend[prefix + method] = function(url, data, headers) {
+ return $httpBackend[prefix](method, url, data, headers)
+ }
+ });
+ }
+}
+
+function MockHttpExpectation(method, url, data, headers) {
+
+ this.data = data;
+ this.headers = headers;
+
+ this.match = function(m, u, d, h) {
+ if (method != m) return false;
+ if (!this.matchUrl(u)) return false;
+ if (angular.isDefined(d) && !this.matchData(d)) return false;
+ if (angular.isDefined(h) && !this.matchHeaders(h)) return false;
+ return true;
+ };
+
+ this.matchUrl = function(u) {
+ if (!url) return true;
+ if (angular.isFunction(url.test)) return url.test(u);
+ return url == u;
+ };
+
+ this.matchHeaders = function(h) {
+ if (angular.isUndefined(headers)) return true;
+ if (angular.isFunction(headers)) return headers(h);
+ return angular.equals(headers, h);
+ };
+
+ this.matchData = function(d) {
+ if (angular.isUndefined(data)) return true;
+ if (data && angular.isFunction(data.test)) return data.test(d);
+ if (data && angular.isFunction(data)) return data(d);
+ if (data && !angular.isString(data)) return angular.toJson(data) == d;
+ return data == d;
+ };
+
+ this.toString = function() {
+ return method + ' ' + url;
+ };
+}
+
+function MockXhr() {
+
+ // hack for testing $http, $httpBackend
+ MockXhr.$$lastInstance = this;
+
+ this.open = function(method, url, async) {
+ this.$$method = method;
+ this.$$url = url;
+ this.$$async = async;
+ this.$$reqHeaders = {};
+ this.$$respHeaders = {};
+ };
+
+ this.send = function(data) {
+ this.$$data = data;
+ };
+
+ this.setRequestHeader = function(key, value) {
+ this.$$reqHeaders[key] = value;
+ };
+
+ this.getResponseHeader = function(name) {
+ // the lookup must be case insensitive, that's why we try two quick lookups and full scan at last
+ var header = this.$$respHeaders[name];
+ if (header) return header;
+
+ name = angular.lowercase(name);
+ header = this.$$respHeaders[name];
+ if (header) return header;
+
+ header = undefined;
+ angular.forEach(this.$$respHeaders, function(headerVal, headerName) {
+ if (!header && angular.lowercase(headerName) == name) header = headerVal;
+ });
+ return header;
+ };
+
+ this.getAllResponseHeaders = function() {
+ var lines = [];
+
+ angular.forEach(this.$$respHeaders, function(value, key) {
+ lines.push(key + ': ' + value);
+ });
+ return lines.join('\n');
+ };
+
+ this.abort = angular.noop;
+}
+
+
+/**
+ * @ngdoc function
+ * @name ngMock.$timeout
+ * @description
+ *
+ * This service is just a simple decorator for {@link ng.$timeout $timeout} service
+ * that adds a "flush" and "verifyNoPendingTasks" methods.
+ */
+
+angular.mock.$TimeoutDecorator = function($delegate, $browser) {
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$timeout#flush
+ * @methodOf ngMock.$timeout
+ * @description
+ *
+ * Flushes the queue of pending tasks.
+ *
+ * @param {number=} delay maximum timeout amount to flush up until
+ */
+ $delegate.flush = function(delay) {
+ $browser.defer.flush(delay);
+ };
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$timeout#flushNext
+ * @methodOf ngMock.$timeout
+ * @description
+ *
+ * Flushes the next timeout in the queue and compares it to the provided delay
+ *
+ * @param {number=} expectedDelay the delay value that will be asserted against the delay of the next timeout function
+ */
+ $delegate.flushNext = function(expectedDelay) {
+ $browser.defer.flushNext(expectedDelay);
+ };
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$timeout#verifyNoPendingTasks
+ * @methodOf ngMock.$timeout
+ * @description
+ *
+ * Verifies that there are no pending tasks that need to be flushed.
+ */
+ $delegate.verifyNoPendingTasks = function() {
+ if ($browser.deferredFns.length) {
+ throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' +
+ formatPendingTasksAsString($browser.deferredFns));
+ }
+ };
+
+ function formatPendingTasksAsString(tasks) {
+ var result = [];
+ angular.forEach(tasks, function(task) {
+ result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}');
+ });
+
+ return result.join(', ');
+ }
+
+ return $delegate;
+};
+
+/**
+ *
+ */
+angular.mock.$RootElementProvider = function() {
+ this.$get = function() {
+ return angular.element('<div ng-app></div>');
+ }
+};
+
+/**
+ * @ngdoc overview
+ * @name ngMock
+ * @description
+ *
+ * The `ngMock` is an angular module which is used with `ng` module and adds unit-test configuration as well as useful
+ * mocks to the {@link AUTO.$injector $injector}.
+ */
+angular.module('ngMock', ['ng']).provider({
+ $browser: angular.mock.$BrowserProvider,
+ $exceptionHandler: angular.mock.$ExceptionHandlerProvider,
+ $log: angular.mock.$LogProvider,
+ $httpBackend: angular.mock.$HttpBackendProvider,
+ $rootElement: angular.mock.$RootElementProvider
+}).config(function($provide) {
+ $provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
+});
+
+/**
+ * @ngdoc overview
+ * @name ngMockE2E
+ * @description
+ *
+ * The `ngMockE2E` is an angular module which contains mocks suitable for end-to-end testing.
+ * Currently there is only one mock present in this module -
+ * the {@link ngMockE2E.$httpBackend e2e $httpBackend} mock.
+ */
+angular.module('ngMockE2E', ['ng']).config(function($provide) {
+ $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
+});
+
+/**
+ * @ngdoc object
+ * @name ngMockE2E.$httpBackend
+ * @description
+ * Fake HTTP backend implementation suitable for end-to-end testing or backend-less development of
+ * applications that use the {@link ng.$http $http service}.
+ *
+ * *Note*: For fake http backend implementation suitable for unit testing please see
+ * {@link ngMock.$httpBackend unit-testing $httpBackend mock}.
+ *
+ * This implementation can be used to respond with static or dynamic responses via the `when` api
+ * and its shortcuts (`whenGET`, `whenPOST`, etc) and optionally pass through requests to the
+ * real $httpBackend for specific requests (e.g. to interact with certain remote apis or to fetch
+ * templates from a webserver).
+ *
+ * As opposed to unit-testing, in an end-to-end testing scenario or in scenario when an application
+ * is being developed with the real backend api replaced with a mock, it is often desirable for
+ * certain category of requests to bypass the mock and issue a real http request (e.g. to fetch
+ * templates or static files from the webserver). To configure the backend with this behavior
+ * use the `passThrough` request handler of `when` instead of `respond`.
+ *
+ * Additionally, we don't want to manually have to flush mocked out requests like we do during unit
+ * testing. For this reason the e2e $httpBackend automatically flushes mocked out requests
+ * automatically, closely simulating the behavior of the XMLHttpRequest object.
+ *
+ * To setup the application to run with this http backend, you have to create a module that depends
+ * on the `ngMockE2E` and your application modules and defines the fake backend:
+ *
+ * <pre>
+ * myAppDev = angular.module('myAppDev', ['myApp', 'ngMockE2E']);
+ * myAppDev.run(function($httpBackend) {
+ * phones = [{name: 'phone1'}, {name: 'phone2'}];
+ *
+ * // returns the current list of phones
+ * $httpBackend.whenGET('/phones').respond(phones);
+ *
+ * // adds a new phone to the phones array
+ * $httpBackend.whenPOST('/phones').respond(function(method, url, data) {
+ * phones.push(angular.fromJson(data));
+ * });
+ * $httpBackend.whenGET(/^\/templates\//).passThrough();
+ * //...
+ * });
+ * </pre>
+ *
+ * Afterwards, bootstrap your app with this new module.
+ */
+
+/**
+ * @ngdoc method
+ * @name ngMockE2E.$httpBackend#when
+ * @methodOf ngMockE2E.$httpBackend
+ * @description
+ * Creates a new backend definition.
+ *
+ * @param {string} method HTTP method.
+ * @param {string|RegExp} url HTTP url.
+ * @param {(string|RegExp)=} data HTTP request body.
+ * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
+ * object and returns true if the headers match the current definition.
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
+ * control how a matched request is handled.
+ *
+ * - respond – `{function([status,] data[, headers])|function(function(method, url, data, headers)}`
+ * – The respond method takes a set of static data to be returned or a function that can return
+ * an array containing response status (number), response data (string) and response headers
+ * (Object).
+ * - passThrough – `{function()}` – Any request matching a backend definition with `passThrough`
+ * handler, will be pass through to the real backend (an XHR request will be made to the
+ * server.
+ */
+
+/**
+ * @ngdoc method
+ * @name ngMockE2E.$httpBackend#whenGET
+ * @methodOf ngMockE2E.$httpBackend
+ * @description
+ * Creates a new backend definition for GET requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(Object|function(Object))=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
+ * control how a matched request is handled.
+ */
+
+/**
+ * @ngdoc method
+ * @name ngMockE2E.$httpBackend#whenHEAD
+ * @methodOf ngMockE2E.$httpBackend
+ * @description
+ * Creates a new backend definition for HEAD requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(Object|function(Object))=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
+ * control how a matched request is handled.
+ */
+
+/**
+ * @ngdoc method
+ * @name ngMockE2E.$httpBackend#whenDELETE
+ * @methodOf ngMockE2E.$httpBackend
+ * @description
+ * Creates a new backend definition for DELETE requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(Object|function(Object))=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
+ * control how a matched request is handled.
+ */
+
+/**
+ * @ngdoc method
+ * @name ngMockE2E.$httpBackend#whenPOST
+ * @methodOf ngMockE2E.$httpBackend
+ * @description
+ * Creates a new backend definition for POST requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(string|RegExp)=} data HTTP request body.
+ * @param {(Object|function(Object))=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
+ * control how a matched request is handled.
+ */
+
+/**
+ * @ngdoc method
+ * @name ngMockE2E.$httpBackend#whenPUT
+ * @methodOf ngMockE2E.$httpBackend
+ * @description
+ * Creates a new backend definition for PUT requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(string|RegExp)=} data HTTP request body.
+ * @param {(Object|function(Object))=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
+ * control how a matched request is handled.
+ */
+
+/**
+ * @ngdoc method
+ * @name ngMockE2E.$httpBackend#whenPATCH
+ * @methodOf ngMockE2E.$httpBackend
+ * @description
+ * Creates a new backend definition for PATCH requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @param {(string|RegExp)=} data HTTP request body.
+ * @param {(Object|function(Object))=} headers HTTP headers.
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
+ * control how a matched request is handled.
+ */
+
+/**
+ * @ngdoc method
+ * @name ngMockE2E.$httpBackend#whenJSONP
+ * @methodOf ngMockE2E.$httpBackend
+ * @description
+ * Creates a new backend definition for JSONP requests. For more info see `when()`.
+ *
+ * @param {string|RegExp} url HTTP url.
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
+ * control how a matched request is handled.
+ */
+angular.mock.e2e = {};
+angular.mock.e2e.$httpBackendDecorator = ['$rootScope', '$delegate', '$browser', createHttpBackendMock];
+
+
+angular.mock.clearDataCache = function() {
+ var key,
+ cache = angular.element.cache;
+
+ for(key in cache) {
+ if (cache.hasOwnProperty(key)) {
+ var handle = cache[key].handle;
+
+ handle && angular.element(handle.elem).off();
+ delete cache[key];
+ }
+ }
+};
+
+
+
+(window.jasmine || window.mocha) && (function(window) {
+
+ var currentSpec = null;
+
+ beforeEach(function() {
+ currentSpec = this;
+ });
+
+ afterEach(function() {
+ var injector = currentSpec.$injector;
+
+ currentSpec.$injector = null;
+ currentSpec.$modules = null;
+ currentSpec = null;
+
+ if (injector) {
+ injector.get('$rootElement').off();
+ injector.get('$browser').pollFns.length = 0;
+ }
+
+ angular.mock.clearDataCache();
+
+ // clean up jquery's fragment cache
+ angular.forEach(angular.element.fragments, function(val, key) {
+ delete angular.element.fragments[key];
+ });
+
+ MockXhr.$$lastInstance = null;
+
+ angular.forEach(angular.callbacks, function(val, key) {
+ delete angular.callbacks[key];
+ });
+ angular.callbacks.counter = 0;
+ });
+
+ function isSpecRunning() {
+ return currentSpec && (window.mocha || currentSpec.queue.running);
+ }
+
+ /**
+ * @ngdoc function
+ * @name angular.mock.module
+ * @description
+ *
+ * *NOTE*: This function is also published on window for easy access.<br>
+ *
+ * This function registers a module configuration code. It collects the configuration information
+ * which will be used when the injector is created by {@link angular.mock.inject inject}.
+ *
+ * See {@link angular.mock.inject inject} for usage example
+ *
+ * @param {...(string|Function)} fns any number of modules which are represented as string
+ * aliases or as anonymous module initialization functions. The modules are used to
+ * configure the injector. The 'ng' and 'ngMock' modules are automatically loaded.
+ */
+ window.module = angular.mock.module = function() {
+ var moduleFns = Array.prototype.slice.call(arguments, 0);
+ return isSpecRunning() ? workFn() : workFn;
+ /////////////////////
+ function workFn() {
+ if (currentSpec.$injector) {
+ throw Error('Injector already created, can not register a module!');
+ } else {
+ var modules = currentSpec.$modules || (currentSpec.$modules = []);
+ angular.forEach(moduleFns, function(module) {
+ modules.push(module);
+ });
+ }
+ }
+ };
+
+ /**
+ * @ngdoc function
+ * @name angular.mock.inject
+ * @description
+ *
+ * *NOTE*: This function is also published on window for easy access.<br>
+ *
+ * The inject function wraps a function into an injectable function. The inject() creates new
+ * instance of {@link AUTO.$injector $injector} per test, which is then used for
+ * resolving references.
+ *
+ * See also {@link angular.mock.module module}
+ *
+ * Example of what a typical jasmine tests looks like with the inject method.
+ * <pre>
+ *
+ * angular.module('myApplicationModule', [])
+ * .value('mode', 'app')
+ * .value('version', 'v1.0.1');
+ *
+ *
+ * describe('MyApp', function() {
+ *
+ * // You need to load modules that you want to test,
+ * // it loads only the "ng" module by default.
+ * beforeEach(module('myApplicationModule'));
+ *
+ *
+ * // inject() is used to inject arguments of all given functions
+ * it('should provide a version', inject(function(mode, version) {
+ * expect(version).toEqual('v1.0.1');
+ * expect(mode).toEqual('app');
+ * }));
+ *
+ *
+ * // The inject and module method can also be used inside of the it or beforeEach
+ * it('should override a version and test the new version is injected', function() {
+ * // module() takes functions or strings (module aliases)
+ * module(function($provide) {
+ * $provide.value('version', 'overridden'); // override version here
+ * });
+ *
+ * inject(function(version) {
+ * expect(version).toEqual('overridden');
+ * });
+ * ));
+ * });
+ *
+ * </pre>
+ *
+ * @param {...Function} fns any number of functions which will be injected using the injector.
+ */
+ window.inject = angular.mock.inject = function() {
+ var blockFns = Array.prototype.slice.call(arguments, 0);
+ var errorForStack = new Error('Declaration Location');
+ return isSpecRunning() ? workFn() : workFn;
+ /////////////////////
+ function workFn() {
+ var modules = currentSpec.$modules || [];
+
+ modules.unshift('ngMock');
+ modules.unshift('ng');
+ var injector = currentSpec.$injector;
+ if (!injector) {
+ injector = currentSpec.$injector = angular.injector(modules);
+ }
+ for(var i = 0, ii = blockFns.length; i < ii; i++) {
+ try {
+ injector.invoke(blockFns[i] || angular.noop, this);
+ } catch (e) {
+ if(e.stack && errorForStack) e.stack += '\n' + errorForStack.stack;
+ throw e;
+ } finally {
+ errorForStack = null;
+ }
+ }
+ }
+ };
+})(window);
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-resource.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-resource.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-resource.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -1,11 +1,12 @@
/** %%Ignore-License
- * @license AngularJS v1.1.5
+ * @license AngularJS v1.2.0rc1
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
-(function(window, angular, undefined) {
-'use strict';
+(function(window, angular, undefined) {'use strict';
+var $resourceMinErr = angular.$$minErr('$resource');
+
/**
* @ngdoc overview
* @name ngResource
@@ -37,12 +38,11 @@
*
* @param {string} url A parametrized URL template with parameters prefixed by `:` as in
* `/user/:username`. If you are using a URL with a port number (e.g.
- * `http://example.com:8080/api`), you'll need to escape the colon character before the port
- * number, like this: `$resource('http://example.com\\:8080/api')`.
+ * `http://example.com:8080/api`), it will be respected.
*
- * If you are using a url with a suffix, just add the suffix, like this:
+ * If you are using a url with a suffix, just add the suffix, like this:
* `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')
- * or even `$resource('http://example.com/resource/:resource_id.:format')`
+ * or even `$resource('http://example.com/resource/:resource_id.:format')`
* If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
* collapsed down to a single `.`. If you need this sequence to appear and not collapse then you
* can escape it with `/\.`.
@@ -98,6 +98,9 @@
* requests with credentials} for more information.
* - **`responseType`** - `{string}` - see {@link
* https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}.
+ * - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods -
+ * `response` and `responseError`. Both `response` and `responseError` interceptors get called
+ * with `http response` object. See {@link ng.$http $http interceptors}.
*
* @returns {Object} A resource "class" object with methods for the default set of resource actions
* optionally extended with custom `actions`. The default set contains these actions:
@@ -136,25 +139,28 @@
* - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])`
* - non-GET instance actions: `instance.$action([parameters], [success], [error])`
*
+ * Success callback is called with (value, responseHeaders) arguments. Error callback is called
+ * with (httpResponse) argument.
*
+ * Class actions return empty instance (with additional properties below).
+ * Instance actions return promise of the action.
+ *
* The Resource instances and collection have these additional properties:
*
- * - `$then`: the `then` method of a {@link ng.$q promise} derived from the underlying
- * {@link ng.$http $http} call.
+ * - `$promise`: the {@link ng.$q promise} of the original server interaction that created this
+ * instance or collection.
*
- * The success callback for the `$then` method will be resolved if the underlying `$http` requests
- * succeeds.
+ * On success, the promise is resolved with the same resource instance or collection object,
+ * updated with data from server. This makes it easy to use in
+ * {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view rendering
+ * until the resource(s) are loaded.
*
- * The success callback is called with a single object which is the {@link ng.$http http response}
- * object extended with a new property `resource`. This `resource` property is a reference to the
- * result of the resource action — resource object or array of resources.
+ * On failure, the promise is resolved with the {@link ng.$http http response} object,
+ * without the `resource` property.
*
- * The error callback is called with the {@link ng.$http http response} object when an http
- * error occurs.
+ * - `$resolved`: `true` after first server interaction is completed (either with success or rejection),
+ * `false` before that. Knowing if the Resource has been resolved is useful in data-binding.
*
- * - `$resolved`: true if the promise has been resolved (either with success or rejection);
- * Knowing if the Resource has been resolved is useful in data-binding.
- *
* @example
*
* # Credit card resource
@@ -274,7 +280,7 @@
</doc:example>
*/
angular.module('ngResource', ['ng']).
- factory('$resource', ['$http', '$parse', function($http, $parse) {
+ factory('$resource', ['$http', '$parse', '$q', function($http, $parse, $q) {
var DEFAULT_ACTIONS = {
'get': {method:'GET'},
'save': {method:'POST'},
@@ -345,7 +351,7 @@
var urlParams = self.urlParams = {};
forEach(url.split(/\W/), function(param){
- if (param && (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
+ if (!(new RegExp("^\\d+$").test(param)) && param && (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
urlParams[param] = true;
}
});
@@ -376,8 +382,8 @@
url = url.replace(/\/\.(?=\w+($|\?))/, '.');
// replace escaped `/\.` with `/.`
config.url = url.replace(/\/\\\./, '/.');
-
+
// set params - delegate param encoding to $http
forEach(params, function(value, key){
if (!self.urlParams[key]) {
@@ -404,19 +410,19 @@
return ids;
}
+ function defaultResponseInterceptor(response) {
+ return response.resource;
+ }
+
function Resource(value){
copy(value || {}, this);
}
forEach(actions, function(action, name) {
- action.method = angular.uppercase(action.method);
- var hasBody = action.method == 'POST' || action.method == 'PUT' || action.method == 'PATCH';
+ var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method);
+
Resource[name] = function(a1, a2, a3, a4) {
- var params = {};
- var data;
- var success = noop;
- var error = null;
- var promise;
+ var params = {}, data, success, error;
switch(arguments.length) {
case 4:
@@ -448,33 +454,35 @@
break;
case 0: break;
default:
- throw "Expected between 0-4 arguments [params, data, success, error], got " +
- arguments.length + " arguments.";
+ throw $resourceMinErr('badargs',
+ "Expected up to 4 arguments [params, data, success, error], got {0} arguments", arguments.length);
}
- var value = this instanceof Resource ? this : (action.isArray ? [] : new Resource(data));
- var httpConfig = {},
- promise;
+ var isInstanceCall = data instanceof Resource;
+ var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data));
+ var httpConfig = {};
+ var responseInterceptor = action.interceptor && action.interceptor.response || defaultResponseInterceptor;
+ var responseErrorInterceptor = action.interceptor && action.interceptor.responseError || undefined;
forEach(action, function(value, key) {
- if (key != 'params' && key != 'isArray' ) {
+ if (key != 'params' && key != 'isArray' && key != 'interceptor') {
httpConfig[key] = copy(value);
}
});
+
httpConfig.data = data;
route.setUrlParams(httpConfig, extend({}, extractParams(data, action.params || {}), params), action.url);
- function markResolved() { value.$resolved = true; }
+ var promise = $http(httpConfig).then(function(response) {
+ var data = response.data,
+ promise = value.$promise;
- promise = $http(httpConfig);
- value.$resolved = false;
-
- promise.then(markResolved, markResolved);
- value.$then = promise.then(function(response) {
- var data = response.data;
- var then = value.$then, resolved = value.$resolved;
-
if (data) {
+ if ( angular.isArray(data) != !!action.isArray ) {
+ throw $resourceMinErr('badcfg', 'Error in resource configuration. Expected response' +
+ ' to contain an {0} but got an {1}',
+ action.isArray?'array':'object', angular.isArray(data)?'array':'object');
+ }
if (action.isArray) {
value.length = 0;
forEach(data, function(item) {
@@ -482,45 +490,48 @@
});
} else {
copy(data, value);
- value.$then = then;
- value.$resolved = resolved;
+ value.$promise = promise;
}
}
+ value.$resolved = true;
+
(success||noop)(value, response.headers);
response.resource = value;
+
return response;
- }, error).then;
+ }, function(response) {
+ value.$resolved = true;
- return value;
- };
+ (error||noop)(response);
+ return $q.reject(response);
+ }).then(responseInterceptor, responseErrorInterceptor);
- Resource.prototype['$' + name] = function(a1, a2, a3) {
- var params = extractParams(this),
- success = noop,
- error;
- switch(arguments.length) {
- case 3: params = a1; success = a2; error = a3; break;
- case 2:
- case 1:
- if (isFunction(a1)) {
- success = a1;
- error = a2;
- } else {
- params = a1;
- success = a2 || noop;
- }
- case 0: break;
- default:
- throw "Expected between 1-3 arguments [params, success, error], got " +
- arguments.length + " arguments.";
+ if (!isInstanceCall) {
+ // we are creating instance / collection
+ // - set the initial promise
+ // - return the instance / collection
+ value.$promise = promise;
+ value.$resolved = false;
+
+ return value;
}
- var data = hasBody ? this : undefined;
- Resource[name].call(this, params, data, success, error);
+
+ // instance call
+ return promise;
};
+
+
+ Resource.prototype['$' + name] = function(params, success, error) {
+ if (isFunction(params)) {
+ error = success; success = params; params = {};
+ }
+ var result = Resource[name](params, this, success, error);
+ return result.$promise || result;
+ };
});
Resource.bind = function(additionalParamDefaults){
Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-route.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-route.js (rev 0)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-route.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -0,0 +1,860 @@
+/** %%Ignore-License
+ * @license AngularJS v1.2.0rc1
+ * (c) 2010-2012 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+var copy = angular.copy,
+ equals = angular.equals,
+ extend = angular.extend,
+ forEach = angular.forEach,
+ isDefined = angular.isDefined,
+ isFunction = angular.isFunction,
+ isString = angular.isString,
+ jqLite = angular.element,
+ noop = angular.noop,
+ toJson = angular.toJson;
+
+
+function inherit(parent, extra) {
+ return extend(new (extend(function() {}, {prototype:parent}))(), extra);
+}
+
+/**
+ * @ngdoc overview
+ * @name ngRoute
+ * @description
+ *
+ * Module that provides routing and deeplinking services and directives for angular apps.
+ */
+
+var ngRouteModule = angular.module('ngRoute', ['ng']).
+ provider('$route', $RouteProvider);
+
+/**
+ * @ngdoc object
+ * @name ngRoute.$routeProvider
+ * @function
+ *
+ * @description
+ *
+ * Used for configuring routes. See {@link ngRoute.$route $route} for an example.
+ */
+function $RouteProvider(){
+ var routes = {};
+
+ /**
+ * @ngdoc method
+ * @name ngRoute.$routeProvider#when
+ * @methodOf ngRoute.$routeProvider
+ *
+ * @param {string} path Route path (matched against `$location.path`). If `$location.path`
+ * contains redundant trailing slash or is missing one, the route will still match and the
+ * `$location.path` will be updated to add or drop the trailing slash to exactly match the
+ * route definition.
+ *
+ * * `path` can contain named groups starting with a colon (`:name`). All characters up
+ * to the next slash are matched and stored in `$routeParams` under the given `name`
+ * when the route matches.
+ * * `path` can contain named groups starting with a colon and ending with a star (`:name*`).
+ * All characters are eagerly stored in `$routeParams` under the given `name`
+ * when the route matches.
+ * * `path` can contain optional named groups with a question mark (`:name?`).
+ *
+ * For example, routes like `/color/:color/largecode/:largecode*\/edit` will match
+ * `/color/brown/largecode/code/with/slashs/edit` and extract:
+ *
+ * * `color: brown`
+ * * `largecode: code/with/slashs`.
+ *
+ *
+ * @param {Object} route Mapping information to be assigned to `$route.current` on route
+ * match.
+ *
+ * Object properties:
+ *
+ * - `controller` – `{(string|function()=}` – Controller fn that should be associated with newly
+ * created scope or the name of a {@link angular.Module#controller registered controller}
+ * if passed as a string.
+ * - `controllerAs` – `{string=}` – A controller alias name. If present the controller will be
+ * published to scope under the `controllerAs` name.
+ * - `template` – `{string=|function()=}` – html template as a string or a function that
+ * returns an html template as a string which should be used by {@link
+ * ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives.
+ * This property takes precedence over `templateUrl`.
+ *
+ * If `template` is a function, it will be called with the following parameters:
+ *
+ * - `{Array.<Object>}` - route parameters extracted from the current
+ * `$location.path()` by applying the current route
+ *
+ * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
+ * template that should be used by {@link ngRoute.directive:ngView ngView}.
+ *
+ * If `templateUrl` is a function, it will be called with the following parameters:
+ *
+ * - `{Array.<Object>}` - route parameters extracted from the current
+ * `$location.path()` by applying the current route
+ *
+ * - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
+ * be injected into the controller. If any of these dependencies are promises, they will be
+ * resolved and converted to a value before the controller is instantiated and the
+ * `$routeChangeSuccess` event is fired. The map object is:
+ *
+ * - `key` – `{string}`: a name of a dependency to be injected into the controller.
+ * - `factory` - `{string|function}`: If `string` then it is an alias for a service.
+ * Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected}
+ * and the return value is treated as the dependency. If the result is a promise, it is resolved
+ * before its value is injected into the controller. Be aware that `ngRoute.$routeParams` will
+ * still refer to the previous route within these resolve functions. Use `$route.current.params`
+ * to access the new route parameters, instead.
+ *
+ * - `redirectTo` – {(string|function())=} – value to update
+ * {@link ng.$location $location} path with and trigger route redirection.
+ *
+ * If `redirectTo` is a function, it will be called with the following parameters:
+ *
+ * - `{Object.<string>}` - route parameters extracted from the current
+ * `$location.path()` by applying the current route templateUrl.
+ * - `{string}` - current `$location.path()`
+ * - `{Object}` - current `$location.search()`
+ *
+ * The custom `redirectTo` function is expected to return a string which will be used
+ * to update `$location.path()` and `$location.search()`.
+ *
+ * - `[reloadOnSearch=true]` - {boolean=} - reload route when only $location.search()
+ * changes.
+ *
+ * If the option is set to `false` and url in the browser changes, then
+ * `$routeUpdate` event is broadcasted on the root scope.
+ *
+ * - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive
+ *
+ * If the option is set to `true`, then the particular route can be matched without being
+ * case sensitive
+ *
+ * @returns {Object} self
+ *
+ * @description
+ * Adds a new route definition to the `$route` service.
+ */
+ this.when = function(path, route) {
+ routes[path] = extend(
+ {reloadOnSearch: true},
+ route,
+ path && pathRegExp(path, route)
+ );
+
+ // create redirection for trailing slashes
+ if (path) {
+ var redirectPath = (path[path.length-1] == '/')
+ ? path.substr(0, path.length-1)
+ : path +'/';
+
+ routes[redirectPath] = extend(
+ {redirectTo: path},
+ pathRegExp(redirectPath, route)
+ );
+ }
+
+ return this;
+ };
+
+ /**
+ * @param path {string} path
+ * @param opts {Object} options
+ * @return {?Object}
+ *
+ * @description
+ * Normalizes the given path, returning a regular expression
+ * and the original path.
+ *
+ * Inspired by pathRexp in visionmedia/express/lib/utils.js.
+ */
+ function pathRegExp(path, opts) {
+ var insensitive = opts.caseInsensitiveMatch,
+ ret = {
+ originalPath: path,
+ regexp: path
+ },
+ keys = ret.keys = [];
+
+ path = path
+ .replace(/([().])/g, '\\$1')
+ .replace(/(\/)?:(\w+)([\?|\*])?/g, function(_, slash, key, option){
+ var optional = option === '?' ? option : null;
+ var star = option === '*' ? option : null;
+ keys.push({ name: key, optional: !!optional });
+ slash = slash || '';
+ return ''
+ + (optional ? '' : slash)
+ + '(?:'
+ + (optional ? slash : '')
+ + (star && '(.+)?' || '([^/]+)?') + ')'
+ + (optional || '');
+ })
+ .replace(/([\/$\*])/g, '\\$1');
+
+ ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');
+ return ret;
+ }
+
+ /**
+ * @ngdoc method
+ * @name ngRoute.$routeProvider#otherwise
+ * @methodOf ngRoute.$routeProvider
+ *
+ * @description
+ * Sets route definition that will be used on route change when no other route definition
+ * is matched.
+ *
+ * @param {Object} params Mapping information to be assigned to `$route.current`.
+ * @returns {Object} self
+ */
+ this.otherwise = function(params) {
+ this.when(null, params);
+ return this;
+ };
+
+
+ this.$get = ['$rootScope', '$location', '$routeParams', '$q', '$injector', '$http', '$templateCache', '$sce',
+ function( $rootScope, $location, $routeParams, $q, $injector, $http, $templateCache, $sce) {
+
+ /**
+ * @ngdoc object
+ * @name ngRoute.$route
+ * @requires $location
+ * @requires $routeParams
+ *
+ * @property {Object} current Reference to the current route definition.
+ * The route definition contains:
+ *
+ * - `controller`: The controller constructor as define in route definition.
+ * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for
+ * controller instantiation. The `locals` contain
+ * the resolved values of the `resolve` map. Additionally the `locals` also contain:
+ *
+ * - `$scope` - The current route scope.
+ * - `$template` - The current route template HTML.
+ *
+ * @property {Array.<Object>} routes Array of all configured routes.
+ *
+ * @description
+ * Is used for deep-linking URLs to controllers and views (HTML partials).
+ * It watches `$location.url()` and tries to map the path to an existing route definition.
+ *
+ * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API.
+ *
+ * The `$route` service is typically used in conjunction with {@link ngRoute.directive:ngView ngView}
+ * directive and the {@link ngRoute.$routeParams $routeParams} service.
+ *
+ * @example
+ This example shows how changing the URL hash causes the `$route` to match a route against the
+ URL, and the `ngView` pulls in the partial.
+
+ Note that this example is using {@link ng.directive:script inlined templates}
+ to get it working on jsfiddle as well.
+
+ <example module="ngView" deps="angular-route.js">
+ <file name="index.html">
+ <div ng-controller="MainCntl">
+ Choose:
+ <a href="Book/Moby">Moby</a> |
+ <a href="Book/Moby/ch/1">Moby: Ch1</a> |
+ <a href="Book/Gatsby">Gatsby</a> |
+ <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
+ <a href="Book/Scarlet">Scarlet Letter</a><br/>
+
+ <div ng-view></div>
+ <hr />
+
+ <pre>$location.path() = {{$location.path()}}</pre>
+ <pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre>
+ <pre>$route.current.params = {{$route.current.params}}</pre>
+ <pre>$route.current.scope.name = {{$route.current.scope.name}}</pre>
+ <pre>$routeParams = {{$routeParams}}</pre>
+ </div>
+ </file>
+
+ <file name="book.html">
+ controller: {{name}}<br />
+ Book Id: {{params.bookId}}<br />
+ </file>
+
+ <file name="chapter.html">
+ controller: {{name}}<br />
+ Book Id: {{params.bookId}}<br />
+ Chapter Id: {{params.chapterId}}
+ </file>
+
+ <file name="script.js">
+ angular.module('ngView', ['ngRoute']).config(function($routeProvider, $locationProvider) {
+ $routeProvider.when('/Book/:bookId', {
+ templateUrl: 'book.html',
+ controller: BookCntl,
+ resolve: {
+ // I will cause a 1 second delay
+ delay: function($q, $timeout) {
+ var delay = $q.defer();
+ $timeout(delay.resolve, 1000);
+ return delay.promise;
+ }
+ }
+ });
+ $routeProvider.when('/Book/:bookId/ch/:chapterId', {
+ templateUrl: 'chapter.html',
+ controller: ChapterCntl
+ });
+
+ // configure html5 to get links working on jsfiddle
+ $locationProvider.html5Mode(true);
+ });
+
+ function MainCntl($scope, $route, $routeParams, $location) {
+ $scope.$route = $route;
+ $scope.$location = $location;
+ $scope.$routeParams = $routeParams;
+ }
+
+ function BookCntl($scope, $routeParams) {
+ $scope.name = "BookCntl";
+ $scope.params = $routeParams;
+ }
+
+ function ChapterCntl($scope, $routeParams) {
+ $scope.name = "ChapterCntl";
+ $scope.params = $routeParams;
+ }
+ </file>
+
+ <file name="scenario.js">
+ it('should load and compile correct template', function() {
+ element('a:contains("Moby: Ch1")').click();
+ var content = element('.doc-example-live [ng-view]').text();
+ expect(content).toMatch(/controller\: ChapterCntl/);
+ expect(content).toMatch(/Book Id\: Moby/);
+ expect(content).toMatch(/Chapter Id\: 1/);
+
+ element('a:contains("Scarlet")').click();
+ sleep(2); // promises are not part of scenario waiting
+ content = element('.doc-example-live [ng-view]').text();
+ expect(content).toMatch(/controller\: BookCntl/);
+ expect(content).toMatch(/Book Id\: Scarlet/);
+ });
+ </file>
+ </example>
+ */
+
+ /**
+ * @ngdoc event
+ * @name ngRoute.$route#$routeChangeStart
+ * @eventOf ngRoute.$route
+ * @eventType broadcast on root scope
+ * @description
+ * Broadcasted before a route change. At this point the route services starts
+ * resolving all of the dependencies needed for the route change to occurs.
+ * Typically this involves fetching the view template as well as any dependencies
+ * defined in `resolve` route property. Once all of the dependencies are resolved
+ * `$routeChangeSuccess` is fired.
+ *
+ * @param {Route} next Future route information.
+ * @param {Route} current Current route information.
+ */
+
+ /**
+ * @ngdoc event
+ * @name ngRoute.$route#$routeChangeSuccess
+ * @eventOf ngRoute.$route
+ * @eventType broadcast on root scope
+ * @description
+ * Broadcasted after a route dependencies are resolved.
+ * {@link ngRoute.directive:ngView ngView} listens for the directive
+ * to instantiate the controller and render the view.
+ *
+ * @param {Object} angularEvent Synthetic event object.
+ * @param {Route} current Current route information.
+ * @param {Route|Undefined} previous Previous route information, or undefined if current is first route entered.
+ */
+
+ /**
+ * @ngdoc event
+ * @name ngRoute.$route#$routeChangeError
+ * @eventOf ngRoute.$route
+ * @eventType broadcast on root scope
+ * @description
+ * Broadcasted if any of the resolve promises are rejected.
+ *
+ * @param {Route} current Current route information.
+ * @param {Route} previous Previous route information.
+ * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise.
+ */
+
+ /**
+ * @ngdoc event
+ * @name ngRoute.$route#$routeUpdate
+ * @eventOf ngRoute.$route
+ * @eventType broadcast on root scope
+ * @description
+ *
+ * The `reloadOnSearch` property has been set to false, and we are reusing the same
+ * instance of the Controller.
+ */
+
+ var forceReload = false,
+ $route = {
+ routes: routes,
+
+ /**
+ * @ngdoc method
+ * @name ngRoute.$route#reload
+ * @methodOf ngRoute.$route
+ *
+ * @description
+ * Causes `$route` service to reload the current route even if
+ * {@link ng.$location $location} hasn't changed.
+ *
+ * As a result of that, {@link ngRoute.directive:ngView ngView}
+ * creates new scope, reinstantiates the controller.
+ */
+ reload: function() {
+ forceReload = true;
+ $rootScope.$evalAsync(updateRoute);
+ }
+ };
+
+ $rootScope.$on('$locationChangeSuccess', updateRoute);
+
+ return $route;
+
+ /////////////////////////////////////////////////////
+
+ /**
+ * @param on {string} current url
+ * @param route {Object} route regexp to match the url against
+ * @return {?Object}
+ *
+ * @description
+ * Check if the route matches the current url.
+ *
+ * Inspired by match in
+ * visionmedia/express/lib/router/router.js.
+ */
+ function switchRouteMatcher(on, route) {
+ var keys = route.keys,
+ params = {};
+
+ if (!route.regexp) return null;
+
+ var m = route.regexp.exec(on);
+ if (!m) return null;
+
+ var N = 0;
+ for (var i = 1, len = m.length; i < len; ++i) {
+ var key = keys[i - 1];
+
+ var val = 'string' == typeof m[i]
+ ? decodeURIComponent(m[i])
+ : m[i];
+
+ if (key && val) {
+ params[key.name] = val;
+ }
+ }
+ return params;
+ }
+
+ function updateRoute() {
+ var next = parseRoute(),
+ last = $route.current;
+
+ if (next && last && next.$$route === last.$$route
+ && equals(next.pathParams, last.pathParams) && !next.reloadOnSearch && !forceReload) {
+ last.params = next.params;
+ copy(last.params, $routeParams);
+ $rootScope.$broadcast('$routeUpdate', last);
+ } else if (next || last) {
+ forceReload = false;
+ $rootScope.$broadcast('$routeChangeStart', next, last);
+ $route.current = next;
+ if (next) {
+ if (next.redirectTo) {
+ if (isString(next.redirectTo)) {
+ $location.path(interpolate(next.redirectTo, next.params)).search(next.params)
+ .replace();
+ } else {
+ $location.url(next.redirectTo(next.pathParams, $location.path(), $location.search()))
+ .replace();
+ }
+ }
+ }
+
+ $q.when(next).
+ then(function() {
+ if (next) {
+ var locals = extend({}, next.resolve),
+ template, templateUrl;
+
+ forEach(locals, function(value, key) {
+ locals[key] = isString(value) ? $injector.get(value) : $injector.invoke(value);
+ });
+
+ if (isDefined(template = next.template)) {
+ if (isFunction(template)) {
+ template = template(next.params);
+ }
+ } else if (isDefined(templateUrl = next.templateUrl)) {
+ if (isFunction(templateUrl)) {
+ templateUrl = templateUrl(next.params);
+ }
+ templateUrl = $sce.getTrustedResourceUrl(templateUrl);
+ if (isDefined(templateUrl)) {
+ next.loadedTemplateUrl = templateUrl;
+ template = $http.get(templateUrl, {cache: $templateCache}).
+ then(function(response) { return response.data; });
+ }
+ }
+ if (isDefined(template)) {
+ locals['$template'] = template;
+ }
+ return $q.all(locals);
+ }
+ }).
+ // after route change
+ then(function(locals) {
+ if (next == $route.current) {
+ if (next) {
+ next.locals = locals;
+ copy(next.params, $routeParams);
+ }
+ $rootScope.$broadcast('$routeChangeSuccess', next, last);
+ }
+ }, function(error) {
+ if (next == $route.current) {
+ $rootScope.$broadcast('$routeChangeError', next, last, error);
+ }
+ });
+ }
+ }
+
+
+ /**
+ * @returns the current active route, by matching it against the URL
+ */
+ function parseRoute() {
+ // Match a route
+ var params, match;
+ forEach(routes, function(route, path) {
+ if (!match && (params = switchRouteMatcher($location.path(), route))) {
+ match = inherit(route, {
+ params: extend({}, $location.search(), params),
+ pathParams: params});
+ match.$$route = route;
+ }
+ });
+ // No route matched; fallback to "otherwise" route
+ return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});
+ }
+
+ /**
+ * @returns interpolation of the redirect path with the parameters
+ */
+ function interpolate(string, params) {
+ var result = [];
+ forEach((string||'').split(':'), function(segment, i) {
+ if (i == 0) {
+ result.push(segment);
+ } else {
+ var segmentMatch = segment.match(/(\w+)(.*)/);
+ var key = segmentMatch[1];
+ result.push(params[key]);
+ result.push(segmentMatch[2] || '');
+ delete params[key];
+ }
+ });
+ return result.join('');
+ }
+ }];
+}
+
+ngRouteModule.provider('$routeParams', $RouteParamsProvider);
+
+
+/**
+ * @ngdoc object
+ * @name ngRoute.$routeParams
+ * @requires $route
+ *
+ * @description
+ * Current set of route parameters. The route parameters are a combination of the
+ * {@link ng.$location $location} `search()`, and `path()`. The `path` parameters
+ * are extracted when the {@link ngRoute.$route $route} path is matched.
+ *
+ * In case of parameter name collision, `path` params take precedence over `search` params.
+ *
+ * The service guarantees that the identity of the `$routeParams` object will remain unchanged
+ * (but its properties will likely change) even when a route change occurs.
+ *
+ * Note that the `$routeParams` are only updated *after* a route change completes successfully.
+ * This means that you cannot rely on `$routeParams` being correct in route resolve functions.
+ * Instead you can use `$route.current.params` to access the new route's parameters.
+ *
+ * @example
+ * <pre>
+ * // Given:
+ * // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
+ * // Route: /Chapter/:chapterId/Section/:sectionId
+ * //
+ * // Then
+ * $routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
+ * </pre>
+ */
+function $RouteParamsProvider() {
+ this.$get = function() { return {}; };
+}
+
+/**
+ * @ngdoc directive
+ * @name ngRoute.directive:ngView
+ * @restrict ECA
+ *
+ * @description
+ * # Overview
+ * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by
+ * including the rendered template of the current route into the main layout (`index.html`) file.
+ * Every time the current route changes, the included view changes with it according to the
+ * configuration of the `$route` service.
+ *
+ * @animations
+ * enter - animation is used to bring new content into the browser.
+ * leave - animation is used to animate existing content away.
+ *
+ * The enter and leave animation occur concurrently.
+ *
+ * @scope
+ * @example
+ <example module="ngViewExample" deps="angular-route.js" animations="true">
+ <file name="index.html">
+ <div ng-controller="MainCntl as main">
+ Choose:
+ <a href="Book/Moby">Moby</a> |
+ <a href="Book/Moby/ch/1">Moby: Ch1</a> |
+ <a href="Book/Gatsby">Gatsby</a> |
+ <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
+ <a href="Book/Scarlet">Scarlet Letter</a><br/>
+
+ <div class="example-animate-container">
+ <div ng-view class="view-example"></div>
+ </div>
+ <hr />
+
+ <pre>$location.path() = {{main.$location.path()}}</pre>
+ <pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre>
+ <pre>$route.current.params = {{main.$route.current.params}}</pre>
+ <pre>$route.current.scope.name = {{main.$route.current.scope.name}}</pre>
+ <pre>$routeParams = {{main.$routeParams}}</pre>
+ </div>
+ </file>
+
+ <file name="book.html">
+ <div>
+ controller: {{book.name}}<br />
+ Book Id: {{book.params.bookId}}<br />
+ </div>
+ </file>
+
+ <file name="chapter.html">
+ <div>
+ controller: {{chapter.name}}<br />
+ Book Id: {{chapter.params.bookId}}<br />
+ Chapter Id: {{chapter.params.chapterId}}
+ </div>
+ </file>
+
+ <file name="animations.css">
+ .example-animate-container {
+ position:relative;
+ background:white;
+ border:1px solid black;
+ height:40px;
+ overflow:hidden;
+ }
+
+ .example-animate-container > div {
+ padding:10px;
+ }
+
+ .view-example.ng-enter, .view-example.ng-leave {
+ -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
+ -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
+ -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
+ transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
+
+ display:block;
+ width:100%;
+ border-left:1px solid black;
+
+ position:absolute;
+ top:0;
+ left:0;
+ right:0;
+ bottom:0;
+ padding:10px;
+ }
+
+ .example-animate-container {
+ position:relative;
+ height:100px;
+ }
+
+ .view-example.ng-enter {
+ left:100%;
+ }
+ .view-example.ng-enter.ng-enter-active {
+ left:0;
+ }
+
+ .view-example.ng-leave { }
+ .view-example.ng-leave.ng-leave-active {
+ left:-100%;
+ }
+ </file>
+
+ <file name="script.js">
+ angular.module('ngViewExample', ['ngRoute', 'ngAnimate'], function($routeProvider, $locationProvider) {
+ $routeProvider.when('/Book/:bookId', {
+ templateUrl: 'book.html',
+ controller: BookCntl,
+ controllerAs: 'book'
+ });
+ $routeProvider.when('/Book/:bookId/ch/:chapterId', {
+ templateUrl: 'chapter.html',
+ controller: ChapterCntl,
+ controllerAs: 'chapter'
+ });
+
+ // configure html5 to get links working on jsfiddle
+ $locationProvider.html5Mode(true);
+ });
+
+ function MainCntl($route, $routeParams, $location) {
+ this.$route = $route;
+ this.$location = $location;
+ this.$routeParams = $routeParams;
+ }
+
+ function BookCntl($routeParams) {
+ this.name = "BookCntl";
+ this.params = $routeParams;
+ }
+
+ function ChapterCntl($routeParams) {
+ this.name = "ChapterCntl";
+ this.params = $routeParams;
+ }
+ </file>
+
+ <file name="scenario.js">
+ it('should load and compile correct template', function() {
+ element('a:contains("Moby: Ch1")').click();
+ var content = element('.doc-example-live [ng-view]').text();
+ expect(content).toMatch(/controller\: ChapterCntl/);
+ expect(content).toMatch(/Book Id\: Moby/);
+ expect(content).toMatch(/Chapter Id\: 1/);
+
+ element('a:contains("Scarlet")').click();
+ content = element('.doc-example-live [ng-view]').text();
+ expect(content).toMatch(/controller\: BookCntl/);
+ expect(content).toMatch(/Book Id\: Scarlet/);
+ });
+ </file>
+ </example>
+ */
+
+
+/**
+ * @ngdoc event
+ * @name ngRoute.directive:ngView#$viewContentLoaded
+ * @eventOf ngRoute.directive:ngView
+ * @eventType emit on the current ngView scope
+ * @description
+ * Emitted every time the ngView content is reloaded.
+ */
+var NG_VIEW_PRIORITY = 500;
+var ngViewDirective = ['$route', '$anchorScroll', '$compile', '$controller', '$animate',
+ function($route, $anchorScroll, $compile, $controller, $animate) {
+ return {
+ restrict: 'ECA',
+ terminal: true,
+ priority: NG_VIEW_PRIORITY,
+ compile: function(element, attr) {
+ var onloadExp = attr.onload || '';
+
+ element.html('');
+ var anchor = jqLite(document.createComment(' ngView '));
+ element.replaceWith(anchor);
+
+ return function(scope) {
+ var currentScope, currentElement;
+
+ scope.$on('$routeChangeSuccess', update);
+ update();
+
+ function cleanupLastView() {
+ if (currentScope) {
+ currentScope.$destroy();
+ currentScope = null;
+ }
+ if(currentElement) {
+ $animate.leave(currentElement);
+ currentElement = null;
+ }
+ }
+
+ function update() {
+ var locals = $route.current && $route.current.locals,
+ template = locals && locals.$template;
+
+ if (template) {
+ cleanupLastView();
+
+ currentScope = scope.$new();
+ currentElement = element.clone();
+ currentElement.html(template);
+ $animate.enter(currentElement, null, anchor);
+
+ var link = $compile(currentElement, false, NG_VIEW_PRIORITY - 1),
+ current = $route.current;
+
+ if (current.controller) {
+ locals.$scope = currentScope;
+ var controller = $controller(current.controller, locals);
+ if (current.controllerAs) {
+ currentScope[current.controllerAs] = controller;
+ }
+ currentElement.data('$ngControllerController', controller);
+ currentElement.children().data('$ngControllerController', controller);
+ }
+
+ current.scope = currentScope;
+
+ link(currentScope);
+
+ currentScope.$emit('$viewContentLoaded');
+ currentScope.$eval(onloadExp);
+
+ // $anchorScroll might listen on event...
+ $anchorScroll();
+ } else {
+ cleanupLastView();
+ }
+ }
+ }
+ }
+ };
+}];
+
+ngRouteModule.directive('ngView', ngViewDirective);
+
+
+})(window, window.angular);
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-sanitize.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-sanitize.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-sanitize.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -1,15 +1,35 @@
/** %%Ignore-License
- * @license AngularJS v1.1.5
+ * @license AngularJS v1.2.0rc1
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
-(function(window, angular, undefined) {
-'use strict';
+(function(window, angular, undefined) {'use strict';
+var $sanitizeMinErr = angular.$$minErr('$sanitize');
+
/**
* @ngdoc overview
* @name ngSanitize
* @description
+ *
+ * The `ngSanitize` module provides functionality to sanitize HTML.
+ *
+ * # Installation
+ * As a separate module, it must be loaded after Angular core is loaded; otherwise, an 'Uncaught Error:
+ * No module: ngSanitize' runtime error will occur.
+ *
+ * <pre>
+ * <script src="angular.js"></script>
+ * <script src="angular-sanitize.js"></script>
+ * </pre>
+ *
+ * # Usage
+ * To make sure the module is available to your application, declare it as a dependency of you application
+ * module.
+ *
+ * <pre>
+ * angular.module('app', ['ngSanitize']);
+ * </pre>
*/
/*
@@ -48,68 +68,71 @@
<doc:example module="ngSanitize">
<doc:source>
<script>
- function Ctrl($scope) {
+ function Ctrl($scope, $sce) {
$scope.snippet =
'<p style="color:blue">an html\n' +
'<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
'snippet</p>';
+ $scope.deliberatelyTrustDangerousSnippet = function() {
+ return $sce.trustAsHtml($scope.snippet);
+ };
}
</script>
<div ng-controller="Ctrl">
Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
<table>
<tr>
- <td>Filter</td>
+ <td>Directive</td>
+ <td>How</td>
<td>Source</td>
<td>Rendered</td>
</tr>
- <tr id="html-filter">
- <td>html filter</td>
- <td>
- <pre><div ng-bind-html="snippet"><br/></div></pre>
- </td>
- <td>
- <div ng-bind-html="snippet"></div>
- </td>
+ <tr id="bind-html-with-sanitize">
+ <td>ng-bind-html</td>
+ <td>Automatically uses $sanitize</td>
+ <td><pre><div ng-bind-html="snippet"><br/></div></pre></td>
+ <td><div ng-bind-html="snippet"></div></td>
</tr>
- <tr id="escaped-html">
- <td>no filter</td>
+ <tr id="bind-html-with-trust">
+ <td>ng-bind-html</td>
+ <td>Bypass $sanitize by explicitly trusting the dangerous value</td>
+ <td><pre><div ng-bind-html="deliberatelyTrustDangerousSnippet()"><br/></div></pre></td>
+ <td><div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div></td>
+ </tr>
+ <tr id="bind-default">
+ <td>ng-bind</td>
+ <td>Automatically escapes</td>
<td><pre><div ng-bind="snippet"><br/></div></pre></td>
<td><div ng-bind="snippet"></div></td>
</tr>
- <tr id="html-unsafe-filter">
- <td>unsafe html filter</td>
- <td><pre><div ng-bind-html-unsafe="snippet"><br/></div></pre></td>
- <td><div ng-bind-html-unsafe="snippet"></div></td>
- </tr>
</table>
</div>
</doc:source>
<doc:scenario>
- it('should sanitize the html snippet ', function() {
- expect(using('#html-filter').element('div').html()).
+ it('should sanitize the html snippet by default', function() {
+ expect(using('#bind-html-with-sanitize').element('div').html()).
toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
});
+ it('should inline raw snippet if bound to a trusted value', function() {
+ expect(using('#bind-html-with-trust').element("div").html()).
+ toBe("<p style=\"color:blue\">an html\n" +
+ "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
+ "snippet</p>");
+ });
+
it('should escape snippet without any filter', function() {
- expect(using('#escaped-html').element('div').html()).
+ expect(using('#bind-default').element('div').html()).
toBe("<p style=\"color:blue\">an html\n" +
"<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
"snippet</p>");
});
- it('should inline raw snippet if filtered as unsafe', function() {
- expect(using('#html-unsafe-filter').element("div").html()).
- toBe("<p style=\"color:blue\">an html\n" +
- "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
- "snippet</p>");
- });
-
it('should update', function() {
- input('snippet').enter('new <b>text</b>');
- expect(using('#html-filter').binding('snippet')).toBe('new <b>text</b>');
- expect(using('#escaped-html').element('div').html()).toBe("new <b>text</b>");
- expect(using('#html-unsafe-filter').binding("snippet")).toBe('new <b>text</b>');
+ input('snippet').enter('new <b onclick="alert(1)">text</b>');
+ expect(using('#bind-html-with-sanitize').element('div').html()).toBe('new <b>text</b>');
+ expect(using('#bind-html-with-trust').element('div').html()).toBe('new <b onclick="alert(1)">text</b>');
+ expect(using('#bind-default').element('div').html()).toBe("new <b onclick=\"alert(1)\">text</b>");
});
</doc:scenario>
</doc:example>
@@ -129,7 +152,7 @@
BEGING_END_TAGE_REGEXP = /^<\s*\//,
COMMENT_REGEXP = /<!--(.*?)-->/g,
CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
- URI_REGEXP = /^((ftp|https?):\/\/|mailto:|tel:|#)/,
+ URI_REGEXP = /^((ftp|https?):\/\/|mailto:|tel:|#)/i,
NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; // Match everything outside of normal chars and " (quote character)
@@ -256,7 +279,7 @@
}
if ( html == last ) {
- throw "Parse Error: " + html;
+ throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block of html: {0}", html);
}
last = html;
}
@@ -283,10 +306,10 @@
var attrs = {};
- rest.replace(ATTR_REGEXP, function(match, name, doubleQuotedValue, singleQoutedValue, unqoutedValue) {
+ rest.replace(ATTR_REGEXP, function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {
var value = doubleQuotedValue
- || singleQoutedValue
- || unqoutedValue
+ || singleQuotedValue
+ || unquotedValue
|| '';
attrs[name] = decodeEntities(value);
@@ -401,29 +424,6 @@
angular.module('ngSanitize', []).value('$sanitize', $sanitize);
/**
- * @ngdoc directive
- * @name ngSanitize.directive:ngBindHtml
- *
- * @description
- * Creates a binding that will sanitize the result of evaluating the `expression` with the
- * {@link ngSanitize.$sanitize $sanitize} service and innerHTML the result into the current element.
- *
- * See {@link ngSanitize.$sanitize $sanitize} docs for examples.
- *
- * @element ANY
- * @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate.
- */
-angular.module('ngSanitize').directive('ngBindHtml', ['$sanitize', function($sanitize) {
- return function(scope, element, attr) {
- element.addClass('ng-binding').data('$binding', attr.ngBindHtml);
- scope.$watch(attr.ngBindHtml, function ngBindHtmlWatchAction(value) {
- value = $sanitize(value);
- element.html(value || '');
- });
- };
-}]);
-
-/**
* @ngdoc filter
* @name ngSanitize.filter:linky
* @function
Added: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-touch.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-touch.js (rev 0)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/extra/angular-touch.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -0,0 +1,536 @@
+/** %%Ignore-License
+ * @license AngularJS v1.2.0rc1
+ * (c) 2010-2012 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+/**
+ * @ngdoc overview
+ * @name ngTouch
+ * @description
+ * Touch events and other mobile helpers.
+ * Based on jQuery Mobile touch event handling (jquerymobile.com)
+ */
+
+// define ngTouch module
+var ngTouch = angular.module('ngTouch', []);
+
+/**
+ * @ngdoc object
+ * @name ngTouch.$swipe
+ *
+ * @description
+ * The `$swipe` service is a service that abstracts the messier details of hold-and-drag swipe
+ * behavior, to make implementing swipe-related directives more convenient.
+ *
+ * It is used by the `ngSwipeLeft` and `ngSwipeRight` directives in `ngTouch`, and by
+ * `ngCarousel` in a separate component.
+ *
+ * # Usage
+ * The `$swipe` service is an object with a single method: `bind`. `bind` takes an element
+ * which is to be watched for swipes, and an object with four handler functions. See the
+ * documentation for `bind` below.
+ */
+
+ngTouch.factory('$swipe', [function() {
+ // The total distance in any direction before we make the call on swipe vs. scroll.
+ var MOVE_BUFFER_RADIUS = 10;
+
+ function getCoordinates(event) {
+ var touches = event.touches && event.touches.length ? event.touches : [event];
+ var e = (event.changedTouches && event.changedTouches[0]) ||
+ (event.originalEvent && event.originalEvent.changedTouches &&
+ event.originalEvent.changedTouches[0]) ||
+ touches[0].originalEvent || touches[0];
+
+ return {
+ x: e.clientX,
+ y: e.clientY
+ };
+ }
+
+ return {
+ /**
+ * @ngdoc method
+ * @name ngTouch.$swipe#bind
+ * @methodOf ngTouch.$swipe
+ *
+ * @description
+ * The main method of `$swipe`. It takes an element to be watched for swipe motions, and an
+ * object containing event handlers.
+ *
+ * The four events are `start`, `move`, `end`, and `cancel`. `start`, `move`, and `end`
+ * receive as a parameter a coordinates object of the form `{ x: 150, y: 310 }`.
+ *
+ * `start` is called on either `mousedown` or `touchstart`. After this event, `$swipe` is
+ * watching for `touchmove` or `mousemove` events. These events are ignored until the total
+ * distance moved in either dimension exceeds a small threshold.
+ *
+ * Once this threshold is exceeded, either the horizontal or vertical delta is greater.
+ * - If the horizontal distance is greater, this is a swipe and `move` and `end` events follow.
+ * - If the vertical distance is greater, this is a scroll, and we let the browser take over.
+ * A `cancel` event is sent.
+ *
+ * `move` is called on `mousemove` and `touchmove` after the above logic has determined that
+ * a swipe is in progress.
+ *
+ * `end` is called when a swipe is successfully completed with a `touchend` or `mouseup`.
+ *
+ * `cancel` is called either on a `touchcancel` from the browser, or when we begin scrolling
+ * as described above.
+ *
+ */
+ bind: function(element, eventHandlers) {
+ // Absolute total movement, used to control swipe vs. scroll.
+ var totalX, totalY;
+ // Coordinates of the start position.
+ var startCoords;
+ // Last event's position.
+ var lastPos;
+ // Whether a swipe is active.
+ var active = false;
+
+ element.on('touchstart mousedown', function(event) {
+ startCoords = getCoordinates(event);
+ active = true;
+ totalX = 0;
+ totalY = 0;
+ lastPos = startCoords;
+ eventHandlers['start'] && eventHandlers['start'](startCoords);
+ });
+
+ element.on('touchcancel', function(event) {
+ active = false;
+ eventHandlers['cancel'] && eventHandlers['cancel']();
+ });
+
+ element.on('touchmove mousemove', function(event) {
+ if (!active) return;
+
+ // Android will send a touchcancel if it thinks we're starting to scroll.
+ // So when the total distance (+ or - or both) exceeds 10px in either direction,
+ // we either:
+ // - On totalX > totalY, we send preventDefault() and treat this as a swipe.
+ // - On totalY > totalX, we let the browser handle it as a scroll.
+
+ if (!startCoords) return;
+ var coords = getCoordinates(event);
+
+ totalX += Math.abs(coords.x - lastPos.x);
+ totalY += Math.abs(coords.y - lastPos.y);
+
+ lastPos = coords;
+
+ if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) {
+ return;
+ }
+
+ // One of totalX or totalY has exceeded the buffer, so decide on swipe vs. scroll.
+ if (totalY > totalX) {
+ // Allow native scrolling to take over.
+ active = false;
+ eventHandlers['cancel'] && eventHandlers['cancel']();
+ return;
+ } else {
+ // Prevent the browser from scrolling.
+ event.preventDefault();
+
+ eventHandlers['move'] && eventHandlers['move'](coords);
+ }
+ });
+
+ element.on('touchend mouseup', function(event) {
+ if (!active) return;
+ active = false;
+ eventHandlers['end'] && eventHandlers['end'](getCoordinates(event));
+ });
+ }
+ };
+}]);
+
+/**
+ * @ngdoc directive
+ * @name ngTouch.directive:ngClick
+ *
+ * @description
+ * A more powerful replacement for the default ngClick designed to be used on touchscreen
+ * devices. Most mobile browsers wait about 300ms after a tap-and-release before sending
+ * the click event. This version handles them immediately, and then prevents the
+ * following click event from propagating.
+ *
+ * This directive can fall back to using an ordinary click event, and so works on desktop
+ * browsers as well as mobile.
+ *
+ * This directive also sets the CSS class `ng-click-active` while the element is being held
+ * down (by a mouse click or touch) so you can restyle the depressed element if you wish.
+ *
+ * @element ANY
+ * @param {expression} ngClick {@link guide/expression Expression} to evaluate
+ * upon tap. (Event object is available as `$event`)
+ *
+ * @example
+ <doc:example>
+ <doc:source>
+ <button ng-click="count = count + 1" ng-init="count=0">
+ Increment
+ </button>
+ count: {{ count }}
+ </doc:source>
+ </doc:example>
+ */
+
+ngTouch.config(['$provide', function($provide) {
+ $provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
+ // drop the default ngClick directive
+ $delegate.shift();
+ return $delegate;
+ }]);
+}]);
+
+ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
+ function($parse, $timeout, $rootElement) {
+ var TAP_DURATION = 750; // Shorter than 750ms is a tap, longer is a taphold or drag.
+ var MOVE_TOLERANCE = 12; // 12px seems to work in most mobile browsers.
+ var PREVENT_DURATION = 2500; // 2.5 seconds maximum from preventGhostClick call to click
+ var CLICKBUSTER_THRESHOLD = 25; // 25 pixels in any dimension is the limit for busting clicks.
+
+ var ACTIVE_CLASS_NAME = 'ng-click-active';
+ var lastPreventedTime;
+ var touchCoordinates;
+
+
+ // TAP EVENTS AND GHOST CLICKS
+ //
+ // Why tap events?
+ // Mobile browsers detect a tap, then wait a moment (usually ~300ms) to see if you're
+ // double-tapping, and then fire a click event.
+ //
+ // This delay sucks and makes mobile apps feel unresponsive.
+ // So we detect touchstart, touchmove, touchcancel and touchend ourselves and determine when
+ // the user has tapped on something.
+ //
+ // What happens when the browser then generates a click event?
+ // The browser, of course, also detects the tap and fires a click after a delay. This results in
+ // tapping/clicking twice. So we do "clickbusting" to prevent it.
+ //
+ // How does it work?
+ // We attach global touchstart and click handlers, that run during the capture (early) phase.
+ // So the sequence for a tap is:
+ // - global touchstart: Sets an "allowable region" at the point touched.
+ // - element's touchstart: Starts a touch
+ // (- touchmove or touchcancel ends the touch, no click follows)
+ // - element's touchend: Determines if the tap is valid (didn't move too far away, didn't hold
+ // too long) and fires the user's tap handler. The touchend also calls preventGhostClick().
+ // - preventGhostClick() removes the allowable region the global touchstart created.
+ // - The browser generates a click event.
+ // - The global click handler catches the click, and checks whether it was in an allowable region.
+ // - If preventGhostClick was called, the region will have been removed, the click is busted.
+ // - If the region is still there, the click proceeds normally. Therefore clicks on links and
+ // other elements without ngTap on them work normally.
+ //
+ // This is an ugly, terrible hack!
+ // Yeah, tell me about it. The alternatives are using the slow click events, or making our users
+ // deal with the ghost clicks, so I consider this the least of evils. Fortunately Angular
+ // encapsulates this ugly logic away from the user.
+ //
+ // Why not just put click handlers on the element?
+ // We do that too, just to be sure. The problem is that the tap event might have caused the DOM
+ // to change, so that the click fires in the same position but something else is there now. So
+ // the handlers are global and care only about coordinates and not elements.
+
+ // Checks if the coordinates are close enough to be within the region.
+ function hit(x1, y1, x2, y2) {
+ return Math.abs(x1 - x2) < CLICKBUSTER_THRESHOLD && Math.abs(y1 - y2) < CLICKBUSTER_THRESHOLD;
+ }
+
+ // Checks a list of allowable regions against a click location.
+ // Returns true if the click should be allowed.
+ // Splices out the allowable region from the list after it has been used.
+ function checkAllowableRegions(touchCoordinates, x, y) {
+ for (var i = 0; i < touchCoordinates.length; i += 2) {
+ if (hit(touchCoordinates[i], touchCoordinates[i+1], x, y)) {
+ touchCoordinates.splice(i, i + 2);
+ return true; // allowable region
+ }
+ }
+ return false; // No allowable region; bust it.
+ }
+
+ // Global click handler that prevents the click if it's in a bustable zone and preventGhostClick
+ // was called recently.
+ function onClick(event) {
+ if (Date.now() - lastPreventedTime > PREVENT_DURATION) {
+ return; // Too old.
+ }
+
+ var touches = event.touches && event.touches.length ? event.touches : [event];
+ var x = touches[0].clientX;
+ var y = touches[0].clientY;
+ // Work around desktop Webkit quirk where clicking a label will fire two clicks (on the label
+ // and on the input element). Depending on the exact browser, this second click we don't want
+ // to bust has either (0,0) or negative coordinates.
+ if (x < 1 && y < 1) {
+ return; // offscreen
+ }
+
+ // Look for an allowable region containing this click.
+ // If we find one, that means it was created by touchstart and not removed by
+ // preventGhostClick, so we don't bust it.
+ if (checkAllowableRegions(touchCoordinates, x, y)) {
+ return;
+ }
+
+ // If we didn't find an allowable region, bust the click.
+ event.stopPropagation();
+ event.preventDefault();
+
+ // Blur focused form elements
+ event.target && event.target.blur();
+ }
+
+
+ // Global touchstart handler that creates an allowable region for a click event.
+ // This allowable region can be removed by preventGhostClick if we want to bust it.
+ function onTouchStart(event) {
+ var touches = event.touches && event.touches.length ? event.touches : [event];
+ var x = touches[0].clientX;
+ var y = touches[0].clientY;
+ touchCoordinates.push(x, y);
+
+ $timeout(function() {
+ // Remove the allowable region.
+ for (var i = 0; i < touchCoordinates.length; i += 2) {
+ if (touchCoordinates[i] == x && touchCoordinates[i+1] == y) {
+ touchCoordinates.splice(i, i + 2);
+ return;
+ }
+ }
+ }, PREVENT_DURATION, false);
+ }
+
+ // On the first call, attaches some event handlers. Then whenever it gets called, it creates a
+ // zone around the touchstart where clicks will get busted.
+ function preventGhostClick(x, y) {
+ if (!touchCoordinates) {
+ $rootElement[0].addEventListener('click', onClick, true);
+ $rootElement[0].addEventListener('touchstart', onTouchStart, true);
+ touchCoordinates = [];
+ }
+
+ lastPreventedTime = Date.now();
+
+ checkAllowableRegions(touchCoordinates, x, y);
+ }
+
+ // Actual linking function.
+ return function(scope, element, attr) {
+ var clickHandler = $parse(attr.ngClick),
+ tapping = false,
+ tapElement, // Used to blur the element after a tap.
+ startTime, // Used to check if the tap was held too long.
+ touchStartX,
+ touchStartY;
+
+ function resetState() {
+ tapping = false;
+ element.removeClass(ACTIVE_CLASS_NAME);
+ }
+
+ element.on('touchstart', function(event) {
+ tapping = true;
+ tapElement = event.target ? event.target : event.srcElement; // IE uses srcElement.
+ // Hack for Safari, which can target text nodes instead of containers.
+ if(tapElement.nodeType == 3) {
+ tapElement = tapElement.parentNode;
+ }
+
+ element.addClass(ACTIVE_CLASS_NAME);
+
+ startTime = Date.now();
+
+ var touches = event.touches && event.touches.length ? event.touches : [event];
+ var e = touches[0].originalEvent || touches[0];
+ touchStartX = e.clientX;
+ touchStartY = e.clientY;
+ });
+
+ element.on('touchmove', function(event) {
+ resetState();
+ });
+
+ element.on('touchcancel', function(event) {
+ resetState();
+ });
+
+ element.on('touchend', function(event) {
+ var diff = Date.now() - startTime;
+
+ var touches = (event.changedTouches && event.changedTouches.length) ? event.changedTouches :
+ ((event.touches && event.touches.length) ? event.touches : [event]);
+ var e = touches[0].originalEvent || touches[0];
+ var x = e.clientX;
+ var y = e.clientY;
+ var dist = Math.sqrt( Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2) );
+
+ if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) {
+ // Call preventGhostClick so the clickbuster will catch the corresponding click.
+ preventGhostClick(x, y);
+
+ // Blur the focused element (the button, probably) before firing the callback.
+ // This doesn't work perfectly on Android Chrome, but seems to work elsewhere.
+ // I couldn't get anything to work reliably on Android Chrome.
+ if (tapElement) {
+ tapElement.blur();
+ }
+
+ if (!angular.isDefined(attr.disabled) || attr.disabled === false) {
+ element.triggerHandler('click', event);
+ }
+ }
+
+ resetState();
+ });
+
+ // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click
+ // something else nearby.
+ element.onclick = function(event) { };
+
+ // Actual click handler.
+ // There are three different kinds of clicks, only two of which reach this point.
+ // - On desktop browsers without touch events, their clicks will always come here.
+ // - On mobile browsers, the simulated "fast" click will call this.
+ // - But the browser's follow-up slow click will be "busted" before it reaches this handler.
+ // Therefore it's safe to use this directive on both mobile and desktop.
+ element.on('click', function(event) {
+ scope.$apply(function() {
+ clickHandler(scope, {$event: event});
+ });
+ });
+
+ element.on('mousedown', function(event) {
+ element.addClass(ACTIVE_CLASS_NAME);
+ });
+
+ element.on('mousemove mouseup', function(event) {
+ element.removeClass(ACTIVE_CLASS_NAME);
+ });
+
+ };
+}]);
+
+/**
+ * @ngdoc directive
+ * @name ngTouch.directive:ngSwipeLeft
+ *
+ * @description
+ * Specify custom behavior when an element is swiped to the left on a touchscreen device.
+ * A leftward swipe is a quick, right-to-left slide of the finger.
+ * Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag too.
+ *
+ * @element ANY
+ * @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate
+ * upon left swipe. (Event object is available as `$event`)
+ *
+ * @example
+ <doc:example>
+ <doc:source>
+ <div ng-show="!showActions" ng-swipe-left="showActions = true">
+ Some list content, like an email in the inbox
+ </div>
+ <div ng-show="showActions" ng-swipe-right="showActions = false">
+ <button ng-click="reply()">Reply</button>
+ <button ng-click="delete()">Delete</button>
+ </div>
+ </doc:source>
+ </doc:example>
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngTouch.directive:ngSwipeRight
+ *
+ * @description
+ * Specify custom behavior when an element is swiped to the right on a touchscreen device.
+ * A rightward swipe is a quick, left-to-right slide of the finger.
+ * Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag too.
+ *
+ * @element ANY
+ * @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate
+ * upon right swipe. (Event object is available as `$event`)
+ *
+ * @example
+ <doc:example>
+ <doc:source>
+ <div ng-show="!showActions" ng-swipe-left="showActions = true">
+ Some list content, like an email in the inbox
+ </div>
+ <div ng-show="showActions" ng-swipe-right="showActions = false">
+ <button ng-click="reply()">Reply</button>
+ <button ng-click="delete()">Delete</button>
+ </div>
+ </doc:source>
+ </doc:example>
+ */
+
+function makeSwipeDirective(directiveName, direction, eventName) {
+ ngTouch.directive(directiveName, ['$parse', '$swipe', function($parse, $swipe) {
+ // The maximum vertical delta for a swipe should be less than 75px.
+ var MAX_VERTICAL_DISTANCE = 75;
+ // Vertical distance should not be more than a fraction of the horizontal distance.
+ var MAX_VERTICAL_RATIO = 0.3;
+ // At least a 30px lateral motion is necessary for a swipe.
+ var MIN_HORIZONTAL_DISTANCE = 30;
+
+ return function(scope, element, attr) {
+ var swipeHandler = $parse(attr[directiveName]);
+
+ var startCoords, valid;
+
+ function validSwipe(coords) {
+ // Check that it's within the coordinates.
+ // Absolute vertical distance must be within tolerances.
+ // Horizontal distance, we take the current X - the starting X.
+ // This is negative for leftward swipes and positive for rightward swipes.
+ // After multiplying by the direction (-1 for left, +1 for right), legal swipes
+ // (ie. same direction as the directive wants) will have a positive delta and
+ // illegal ones a negative delta.
+ // Therefore this delta must be positive, and larger than the minimum.
+ if (!startCoords) return false;
+ var deltaY = Math.abs(coords.y - startCoords.y);
+ var deltaX = (coords.x - startCoords.x) * direction;
+ return valid && // Short circuit for already-invalidated swipes.
+ deltaY < MAX_VERTICAL_DISTANCE &&
+ deltaX > 0 &&
+ deltaX > MIN_HORIZONTAL_DISTANCE &&
+ deltaY / deltaX < MAX_VERTICAL_RATIO;
+ }
+
+ $swipe.bind(element, {
+ 'start': function(coords) {
+ startCoords = coords;
+ valid = true;
+ },
+ 'cancel': function() {
+ valid = false;
+ },
+ 'end': function(coords) {
+ if (validSwipe(coords)) {
+ scope.$apply(function() {
+ element.triggerHandler(eventName);
+ swipeHandler(scope);
+ });
+ }
+ }
+ });
+ };
+ }]);
+}
+
+// Left is negative X-coordinate, right is positive.
+makeSwipeDirective('ngSwipeLeft', -1, 'swipeleft');
+makeSwipeDirective('ngSwipeRight', 1, 'swiperight');
+
+
+
+})(window, window.angular);
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-na.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-na.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-na.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "vm.",
- "1": "nm."
- },
- "DAY": {
- "0": "Sondag",
- "1": "Maandag",
- "2": "Dinsdag",
- "3": "Woensdag",
- "4": "Donderdag",
- "5": "Vrydag",
- "6": "Saterdag"
- },
- "MONTH": {
- "0": "Januarie",
- "1": "Februarie",
- "2": "Maart",
- "3": "April",
- "4": "Mei",
- "5": "Junie",
- "6": "Julie",
- "7": "Augustus",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Desember"
- },
- "SHORTDAY": {
- "0": "So",
- "1": "Ma",
- "2": "Di",
- "3": "Wo",
- "4": "Do",
- "5": "Vr",
- "6": "Sa"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "Mei",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Des"
- },
+ "AMPMS": [
+ "vm.",
+ "nm."
+ ],
+ "DAY": [
+ "Sondag",
+ "Maandag",
+ "Dinsdag",
+ "Woensdag",
+ "Donderdag",
+ "Vrydag",
+ "Saterdag"
+ ],
+ "MONTH": [
+ "Januarie",
+ "Februarie",
+ "Maart",
+ "April",
+ "Mei",
+ "Junie",
+ "Julie",
+ "Augustus",
+ "September",
+ "Oktober",
+ "November",
+ "Desember"
+ ],
+ "SHORTDAY": [
+ "So",
+ "Ma",
+ "Di",
+ "Wo",
+ "Do",
+ "Vr",
+ "Sa"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Des"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "R",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "af-na",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-za.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-za.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af-za.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "vm.",
- "1": "nm."
- },
- "DAY": {
- "0": "Sondag",
- "1": "Maandag",
- "2": "Dinsdag",
- "3": "Woensdag",
- "4": "Donderdag",
- "5": "Vrydag",
- "6": "Saterdag"
- },
- "MONTH": {
- "0": "Januarie",
- "1": "Februarie",
- "2": "Maart",
- "3": "April",
- "4": "Mei",
- "5": "Junie",
- "6": "Julie",
- "7": "Augustus",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Desember"
- },
- "SHORTDAY": {
- "0": "So",
- "1": "Ma",
- "2": "Di",
- "3": "Wo",
- "4": "Do",
- "5": "Vr",
- "6": "Sa"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "Mei",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Des"
- },
+ "AMPMS": [
+ "vm.",
+ "nm."
+ ],
+ "DAY": [
+ "Sondag",
+ "Maandag",
+ "Dinsdag",
+ "Woensdag",
+ "Donderdag",
+ "Vrydag",
+ "Saterdag"
+ ],
+ "MONTH": [
+ "Januarie",
+ "Februarie",
+ "Maart",
+ "April",
+ "Mei",
+ "Junie",
+ "Julie",
+ "Augustus",
+ "September",
+ "Oktober",
+ "November",
+ "Desember"
+ ],
+ "SHORTDAY": [
+ "So",
+ "Ma",
+ "Di",
+ "Wo",
+ "Do",
+ "Vr",
+ "Sa"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Des"
+ ],
"fullDate": "EEEE dd MMMM y",
"longDate": "dd MMMM y",
"medium": "dd MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "R",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "af-za",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_af.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "vm.",
- "1": "nm."
- },
- "DAY": {
- "0": "Sondag",
- "1": "Maandag",
- "2": "Dinsdag",
- "3": "Woensdag",
- "4": "Donderdag",
- "5": "Vrydag",
- "6": "Saterdag"
- },
- "MONTH": {
- "0": "Januarie",
- "1": "Februarie",
- "2": "Maart",
- "3": "April",
- "4": "Mei",
- "5": "Junie",
- "6": "Julie",
- "7": "Augustus",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Desember"
- },
- "SHORTDAY": {
- "0": "So",
- "1": "Ma",
- "2": "Di",
- "3": "Wo",
- "4": "Do",
- "5": "Vr",
- "6": "Sa"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "Mei",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Des"
- },
+ "AMPMS": [
+ "vm.",
+ "nm."
+ ],
+ "DAY": [
+ "Sondag",
+ "Maandag",
+ "Dinsdag",
+ "Woensdag",
+ "Donderdag",
+ "Vrydag",
+ "Saterdag"
+ ],
+ "MONTH": [
+ "Januarie",
+ "Februarie",
+ "Maart",
+ "April",
+ "Mei",
+ "Junie",
+ "Julie",
+ "Augustus",
+ "September",
+ "Oktober",
+ "November",
+ "Desember"
+ ],
+ "SHORTDAY": [
+ "So",
+ "Ma",
+ "Di",
+ "Wo",
+ "Do",
+ "Vr",
+ "Sa"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Des"
+ ],
"fullDate": "EEEE dd MMMM y",
"longDate": "dd MMMM y",
"medium": "dd MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "R",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "af",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am-et.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am-et.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am-et.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u1321\u12cb\u1275",
- "1": "\u12a8\u1233\u12d3\u1275"
- },
- "DAY": {
- "0": "\u12a5\u1211\u12f5",
- "1": "\u1230\u129e",
- "2": "\u121b\u12ad\u1230\u129e",
- "3": "\u1228\u1261\u12d5",
- "4": "\u1210\u1219\u1235",
- "5": "\u12d3\u122d\u1265",
- "6": "\u1245\u12f3\u121c"
- },
- "MONTH": {
- "0": "\u1303\u1295\u12e9\u12c8\u122a",
- "1": "\u134c\u1265\u1229\u12c8\u122a",
- "2": "\u121b\u122d\u127d",
- "3": "\u12a4\u1355\u1228\u120d",
- "4": "\u121c\u12ed",
- "5": "\u1301\u1295",
- "6": "\u1301\u120b\u12ed",
- "7": "\u12a6\u1308\u1235\u1275",
- "8": "\u1234\u1355\u1274\u121d\u1260\u122d",
- "9": "\u12a6\u12ad\u1270\u12cd\u1260\u122d",
- "10": "\u1296\u126c\u121d\u1260\u122d",
- "11": "\u12f2\u1234\u121d\u1260\u122d"
- },
- "SHORTDAY": {
- "0": "\u12a5\u1211\u12f5",
- "1": "\u1230\u129e",
- "2": "\u121b\u12ad\u1230",
- "3": "\u1228\u1261\u12d5",
- "4": "\u1210\u1219\u1235",
- "5": "\u12d3\u122d\u1265",
- "6": "\u1245\u12f3\u121c"
- },
- "SHORTMONTH": {
- "0": "\u1303\u1295\u12e9",
- "1": "\u134c\u1265\u1229",
- "2": "\u121b\u122d\u127d",
- "3": "\u12a4\u1355\u1228",
- "4": "\u121c\u12ed",
- "5": "\u1301\u1295",
- "6": "\u1301\u120b\u12ed",
- "7": "\u12a6\u1308\u1235",
- "8": "\u1234\u1355\u1274",
- "9": "\u12a6\u12ad\u1270",
- "10": "\u1296\u126c\u121d",
- "11": "\u12f2\u1234\u121d"
- },
+ "AMPMS": [
+ "\u1321\u12cb\u1275",
+ "\u12a8\u1233\u12d3\u1275"
+ ],
+ "DAY": [
+ "\u12a5\u1211\u12f5",
+ "\u1230\u129e",
+ "\u121b\u12ad\u1230\u129e",
+ "\u1228\u1261\u12d5",
+ "\u1210\u1219\u1235",
+ "\u12d3\u122d\u1265",
+ "\u1245\u12f3\u121c"
+ ],
+ "MONTH": [
+ "\u1303\u1295\u12e9\u12c8\u122a",
+ "\u134c\u1265\u1229\u12c8\u122a",
+ "\u121b\u122d\u127d",
+ "\u12a4\u1355\u1228\u120d",
+ "\u121c\u12ed",
+ "\u1301\u1295",
+ "\u1301\u120b\u12ed",
+ "\u12a6\u1308\u1235\u1275",
+ "\u1234\u1355\u1274\u121d\u1260\u122d",
+ "\u12a6\u12ad\u1270\u12cd\u1260\u122d",
+ "\u1296\u126c\u121d\u1260\u122d",
+ "\u12f2\u1234\u121d\u1260\u122d"
+ ],
+ "SHORTDAY": [
+ "\u12a5\u1211\u12f5",
+ "\u1230\u129e",
+ "\u121b\u12ad\u1230",
+ "\u1228\u1261\u12d5",
+ "\u1210\u1219\u1235",
+ "\u12d3\u122d\u1265",
+ "\u1245\u12f3\u121c"
+ ],
+ "SHORTMONTH": [
+ "\u1303\u1295\u12e9",
+ "\u134c\u1265\u1229",
+ "\u121b\u122d\u127d",
+ "\u12a4\u1355\u1228",
+ "\u121c\u12ed",
+ "\u1301\u1295",
+ "\u1301\u120b\u12ed",
+ "\u12a6\u1308\u1235",
+ "\u1234\u1355\u1274",
+ "\u12a6\u12ad\u1270",
+ "\u1296\u126c\u121d",
+ "\u12f2\u1234\u121d"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Birr",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "am-et",
"pluralCat": function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_am.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u1321\u12cb\u1275",
- "1": "\u12a8\u1233\u12d3\u1275"
- },
- "DAY": {
- "0": "\u12a5\u1211\u12f5",
- "1": "\u1230\u129e",
- "2": "\u121b\u12ad\u1230\u129e",
- "3": "\u1228\u1261\u12d5",
- "4": "\u1210\u1219\u1235",
- "5": "\u12d3\u122d\u1265",
- "6": "\u1245\u12f3\u121c"
- },
- "MONTH": {
- "0": "\u1303\u1295\u12e9\u12c8\u122a",
- "1": "\u134c\u1265\u1229\u12c8\u122a",
- "2": "\u121b\u122d\u127d",
- "3": "\u12a4\u1355\u1228\u120d",
- "4": "\u121c\u12ed",
- "5": "\u1301\u1295",
- "6": "\u1301\u120b\u12ed",
- "7": "\u12a6\u1308\u1235\u1275",
- "8": "\u1234\u1355\u1274\u121d\u1260\u122d",
- "9": "\u12a6\u12ad\u1270\u12cd\u1260\u122d",
- "10": "\u1296\u126c\u121d\u1260\u122d",
- "11": "\u12f2\u1234\u121d\u1260\u122d"
- },
- "SHORTDAY": {
- "0": "\u12a5\u1211\u12f5",
- "1": "\u1230\u129e",
- "2": "\u121b\u12ad\u1230",
- "3": "\u1228\u1261\u12d5",
- "4": "\u1210\u1219\u1235",
- "5": "\u12d3\u122d\u1265",
- "6": "\u1245\u12f3\u121c"
- },
- "SHORTMONTH": {
- "0": "\u1303\u1295\u12e9",
- "1": "\u134c\u1265\u1229",
- "2": "\u121b\u122d\u127d",
- "3": "\u12a4\u1355\u1228",
- "4": "\u121c\u12ed",
- "5": "\u1301\u1295",
- "6": "\u1301\u120b\u12ed",
- "7": "\u12a6\u1308\u1235",
- "8": "\u1234\u1355\u1274",
- "9": "\u12a6\u12ad\u1270",
- "10": "\u1296\u126c\u121d",
- "11": "\u12f2\u1234\u121d"
- },
+ "AMPMS": [
+ "\u1321\u12cb\u1275",
+ "\u12a8\u1233\u12d3\u1275"
+ ],
+ "DAY": [
+ "\u12a5\u1211\u12f5",
+ "\u1230\u129e",
+ "\u121b\u12ad\u1230\u129e",
+ "\u1228\u1261\u12d5",
+ "\u1210\u1219\u1235",
+ "\u12d3\u122d\u1265",
+ "\u1245\u12f3\u121c"
+ ],
+ "MONTH": [
+ "\u1303\u1295\u12e9\u12c8\u122a",
+ "\u134c\u1265\u1229\u12c8\u122a",
+ "\u121b\u122d\u127d",
+ "\u12a4\u1355\u1228\u120d",
+ "\u121c\u12ed",
+ "\u1301\u1295",
+ "\u1301\u120b\u12ed",
+ "\u12a6\u1308\u1235\u1275",
+ "\u1234\u1355\u1274\u121d\u1260\u122d",
+ "\u12a6\u12ad\u1270\u12cd\u1260\u122d",
+ "\u1296\u126c\u121d\u1260\u122d",
+ "\u12f2\u1234\u121d\u1260\u122d"
+ ],
+ "SHORTDAY": [
+ "\u12a5\u1211\u12f5",
+ "\u1230\u129e",
+ "\u121b\u12ad\u1230",
+ "\u1228\u1261\u12d5",
+ "\u1210\u1219\u1235",
+ "\u12d3\u122d\u1265",
+ "\u1245\u12f3\u121c"
+ ],
+ "SHORTMONTH": [
+ "\u1303\u1295\u12e9",
+ "\u134c\u1265\u1229",
+ "\u121b\u122d\u127d",
+ "\u12a4\u1355\u1228",
+ "\u121c\u12ed",
+ "\u1301\u1295",
+ "\u1301\u120b\u12ed",
+ "\u12a6\u1308\u1235",
+ "\u1234\u1355\u1274",
+ "\u12a6\u12ad\u1270",
+ "\u1296\u126c\u121d",
+ "\u12f2\u1234\u121d"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Birr",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "am",
"pluralCat": function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-001.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-001.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-001.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-001",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ae.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ae.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ae.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-ae",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-bh.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-bh.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-bh.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-bh",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-dz.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-dz.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-dz.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "yyyy/MM/dd h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-dz",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-eg.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-eg.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-eg.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-eg",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-iq.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-iq.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-iq.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-iq",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-jo.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-jo.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-jo.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
- "1": "\u0634\u0628\u0627\u0637",
- "2": "\u0622\u0630\u0627\u0631",
- "3": "\u0646\u064a\u0633\u0627\u0646",
- "4": "\u0623\u064a\u0627\u0631",
- "5": "\u062d\u0632\u064a\u0631\u0627\u0646",
- "6": "\u062a\u0645\u0648\u0632",
- "7": "\u0622\u0628",
- "8": "\u0623\u064a\u0644\u0648\u0644",
- "9": "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644",
- "10": "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
- "11": "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
- "1": "\u0634\u0628\u0627\u0637",
- "2": "\u0622\u0630\u0627\u0631",
- "3": "\u0646\u064a\u0633\u0627\u0646",
- "4": "\u0623\u064a\u0627\u0631",
- "5": "\u062d\u0632\u064a\u0631\u0627\u0646",
- "6": "\u062a\u0645\u0648\u0632",
- "7": "\u0622\u0628",
- "8": "\u0623\u064a\u0644\u0648\u0644",
- "9": "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644",
- "10": "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
- "11": "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
+ "\u0634\u0628\u0627\u0637",
+ "\u0622\u0630\u0627\u0631",
+ "\u0646\u064a\u0633\u0627\u0646",
+ "\u0623\u064a\u0627\u0631",
+ "\u062d\u0632\u064a\u0631\u0627\u0646",
+ "\u062a\u0645\u0648\u0632",
+ "\u0622\u0628",
+ "\u0623\u064a\u0644\u0648\u0644",
+ "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644",
+ "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
+ "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
+ "\u0634\u0628\u0627\u0637",
+ "\u0622\u0630\u0627\u0631",
+ "\u0646\u064a\u0633\u0627\u0646",
+ "\u0623\u064a\u0627\u0631",
+ "\u062d\u0632\u064a\u0631\u0627\u0646",
+ "\u062a\u0645\u0648\u0632",
+ "\u0622\u0628",
+ "\u0623\u064a\u0644\u0648\u0644",
+ "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644",
+ "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
+ "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-jo",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-kw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-kw.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-kw.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-kw",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-lb.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-lb.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-lb.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
- "1": "\u0634\u0628\u0627\u0637",
- "2": "\u0622\u0630\u0627\u0631",
- "3": "\u0646\u064a\u0633\u0627\u0646",
- "4": "\u0623\u064a\u0627\u0631",
- "5": "\u062d\u0632\u064a\u0631\u0627\u0646",
- "6": "\u062a\u0645\u0648\u0632",
- "7": "\u0622\u0628",
- "8": "\u0623\u064a\u0644\u0648\u0644",
- "9": "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644",
- "10": "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
- "11": "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
- "1": "\u0634\u0628\u0627\u0637",
- "2": "\u0622\u0630\u0627\u0631",
- "3": "\u0646\u064a\u0633\u0627\u0646",
- "4": "\u0623\u064a\u0627\u0631",
- "5": "\u062d\u0632\u064a\u0631\u0627\u0646",
- "6": "\u062a\u0645\u0648\u0632",
- "7": "\u0622\u0628",
- "8": "\u0623\u064a\u0644\u0648\u0644",
- "9": "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644",
- "10": "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
- "11": "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
+ "\u0634\u0628\u0627\u0637",
+ "\u0622\u0630\u0627\u0631",
+ "\u0646\u064a\u0633\u0627\u0646",
+ "\u0623\u064a\u0627\u0631",
+ "\u062d\u0632\u064a\u0631\u0627\u0646",
+ "\u062a\u0645\u0648\u0632",
+ "\u0622\u0628",
+ "\u0623\u064a\u0644\u0648\u0644",
+ "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644",
+ "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
+ "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
+ "\u0634\u0628\u0627\u0637",
+ "\u0622\u0630\u0627\u0631",
+ "\u0646\u064a\u0633\u0627\u0646",
+ "\u0623\u064a\u0627\u0631",
+ "\u062d\u0632\u064a\u0631\u0627\u0646",
+ "\u062a\u0645\u0648\u0632",
+ "\u0622\u0628",
+ "\u0623\u064a\u0644\u0648\u0644",
+ "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644",
+ "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
+ "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-lb",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ly.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ly.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ly.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-ly",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ma.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ma.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ma.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "yyyy/MM/dd h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-ma",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-om.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-om.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-om.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-om",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-qa.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-qa.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-qa.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-qa",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sa.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sa.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sa.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-sa",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sd.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sd.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sd.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-sd",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sy.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sy.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-sy.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
- "1": "\u0634\u0628\u0627\u0637",
- "2": "\u0622\u0630\u0627\u0631",
- "3": "\u0646\u064a\u0633\u0627\u0646",
- "4": "\u0623\u064a\u0627\u0631",
- "5": "\u062d\u0632\u064a\u0631\u0627\u0646",
- "6": "\u062a\u0645\u0648\u0632",
- "7": "\u0622\u0628",
- "8": "\u0623\u064a\u0644\u0648\u0644",
- "9": "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644",
- "10": "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
- "11": "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
- "1": "\u0634\u0628\u0627\u0637",
- "2": "\u0622\u0630\u0627\u0631",
- "3": "\u0646\u064a\u0633\u0627\u0646",
- "4": "\u0623\u064a\u0627\u0631",
- "5": "\u062d\u0632\u064a\u0631\u0627\u0646",
- "6": "\u062a\u0645\u0648\u0632",
- "7": "\u0622\u0628",
- "8": "\u0623\u064a\u0644\u0648\u0644",
- "9": "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644",
- "10": "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
- "11": "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
+ "\u0634\u0628\u0627\u0637",
+ "\u0622\u0630\u0627\u0631",
+ "\u0646\u064a\u0633\u0627\u0646",
+ "\u0623\u064a\u0627\u0631",
+ "\u062d\u0632\u064a\u0631\u0627\u0646",
+ "\u062a\u0645\u0648\u0632",
+ "\u0622\u0628",
+ "\u0623\u064a\u0644\u0648\u0644",
+ "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644",
+ "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
+ "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
+ "\u0634\u0628\u0627\u0637",
+ "\u0622\u0630\u0627\u0631",
+ "\u0646\u064a\u0633\u0627\u0646",
+ "\u0623\u064a\u0627\u0631",
+ "\u062d\u0632\u064a\u0631\u0627\u0646",
+ "\u062a\u0645\u0648\u0632",
+ "\u0622\u0628",
+ "\u0623\u064a\u0644\u0648\u0644",
+ "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644",
+ "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a",
+ "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-sy",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-tn.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-tn.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-tn.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "yyyy/MM/dd h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-tn",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ye.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ye.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar-ye.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar-ye",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ar.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0635",
- "1": "\u0645"
- },
- "DAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "MONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u0644\u0623\u062d\u062f",
- "1": "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
- "2": "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
- "3": "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
- "4": "\u0627\u0644\u062e\u0645\u064a\u0633",
- "5": "\u0627\u0644\u062c\u0645\u0639\u0629",
- "6": "\u0627\u0644\u0633\u0628\u062a"
- },
- "SHORTMONTH": {
- "0": "\u064a\u0646\u0627\u064a\u0631",
- "1": "\u0641\u0628\u0631\u0627\u064a\u0631",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0623\u0628\u0631\u064a\u0644",
- "4": "\u0645\u0627\u064a\u0648",
- "5": "\u064a\u0648\u0646\u064a\u0648",
- "6": "\u064a\u0648\u0644\u064a\u0648",
- "7": "\u0623\u063a\u0633\u0637\u0633",
- "8": "\u0633\u0628\u062a\u0645\u0628\u0631",
- "9": "\u0623\u0643\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0641\u0645\u0628\u0631",
- "11": "\u062f\u064a\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0635",
+ "\u0645"
+ ],
+ "DAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "MONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u0644\u0623\u062d\u062f",
+ "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
+ "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
+ "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
+ "\u0627\u0644\u062e\u0645\u064a\u0633",
+ "\u0627\u0644\u062c\u0645\u0639\u0629",
+ "\u0627\u0644\u0633\u0628\u062a"
+ ],
+ "SHORTMONTH": [
+ "\u064a\u0646\u0627\u064a\u0631",
+ "\u0641\u0628\u0631\u0627\u064a\u0631",
+ "\u0645\u0627\u0631\u0633",
+ "\u0623\u0628\u0631\u064a\u0644",
+ "\u0645\u0627\u064a\u0648",
+ "\u064a\u0648\u0646\u064a\u0648",
+ "\u064a\u0648\u0644\u064a\u0648",
+ "\u0623\u063a\u0633\u0637\u0633",
+ "\u0633\u0628\u062a\u0645\u0628\u0631",
+ "\u0623\u0643\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0641\u0645\u0628\u0631",
+ "\u062f\u064a\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060c d MMMM\u060c y",
"longDate": "d MMMM\u060c y",
"medium": "dd\u200f/MM\u200f/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ar",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n == (n | 0) && n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg-bg.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg-bg.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg-bg.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u043f\u0440. \u043e\u0431.",
- "1": "\u0441\u043b. \u043e\u0431."
- },
- "DAY": {
- "0": "\u043d\u0435\u0434\u0435\u043b\u044f",
- "1": "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a",
- "2": "\u0432\u0442\u043e\u0440\u043d\u0438\u043a",
- "3": "\u0441\u0440\u044f\u0434\u0430",
- "4": "\u0447\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a",
- "5": "\u043f\u0435\u0442\u044a\u043a",
- "6": "\u0441\u044a\u0431\u043e\u0442\u0430"
- },
- "MONTH": {
- "0": "\u044f\u043d\u0443\u0430\u0440\u0438",
- "1": "\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438",
- "2": "\u043c\u0430\u0440\u0442",
- "3": "\u0430\u043f\u0440\u0438\u043b",
- "4": "\u043c\u0430\u0439",
- "5": "\u044e\u043d\u0438",
- "6": "\u044e\u043b\u0438",
- "7": "\u0430\u0432\u0433\u0443\u0441\u0442",
- "8": "\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438",
- "9": "\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438",
- "10": "\u043d\u043e\u0435\u043c\u0432\u0440\u0438",
- "11": "\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438"
- },
- "SHORTDAY": {
- "0": "\u043d\u0434",
- "1": "\u043f\u043d",
- "2": "\u0432\u0442",
- "3": "\u0441\u0440",
- "4": "\u0447\u0442",
- "5": "\u043f\u0442",
- "6": "\u0441\u0431"
- },
- "SHORTMONTH": {
- "0": "\u044f\u043d.",
- "1": "\u0444\u0435\u0432\u0440.",
- "2": "\u043c\u0430\u0440\u0442",
- "3": "\u0430\u043f\u0440.",
- "4": "\u043c\u0430\u0439",
- "5": "\u044e\u043d\u0438",
- "6": "\u044e\u043b\u0438",
- "7": "\u0430\u0432\u0433.",
- "8": "\u0441\u0435\u043f\u0442.",
- "9": "\u043e\u043a\u0442.",
- "10": "\u043d\u043e\u0435\u043c.",
- "11": "\u0434\u0435\u043a."
- },
+ "AMPMS": [
+ "\u043f\u0440. \u043e\u0431.",
+ "\u0441\u043b. \u043e\u0431."
+ ],
+ "DAY": [
+ "\u043d\u0435\u0434\u0435\u043b\u044f",
+ "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a",
+ "\u0432\u0442\u043e\u0440\u043d\u0438\u043a",
+ "\u0441\u0440\u044f\u0434\u0430",
+ "\u0447\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a",
+ "\u043f\u0435\u0442\u044a\u043a",
+ "\u0441\u044a\u0431\u043e\u0442\u0430"
+ ],
+ "MONTH": [
+ "\u044f\u043d\u0443\u0430\u0440\u0438",
+ "\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438",
+ "\u043c\u0430\u0440\u0442",
+ "\u0430\u043f\u0440\u0438\u043b",
+ "\u043c\u0430\u0439",
+ "\u044e\u043d\u0438",
+ "\u044e\u043b\u0438",
+ "\u0430\u0432\u0433\u0443\u0441\u0442",
+ "\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438",
+ "\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438",
+ "\u043d\u043e\u0435\u043c\u0432\u0440\u0438",
+ "\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438"
+ ],
+ "SHORTDAY": [
+ "\u043d\u0434",
+ "\u043f\u043d",
+ "\u0432\u0442",
+ "\u0441\u0440",
+ "\u0447\u0442",
+ "\u043f\u0442",
+ "\u0441\u0431"
+ ],
+ "SHORTMONTH": [
+ "\u044f\u043d.",
+ "\u0444\u0435\u0432\u0440.",
+ "\u043c\u0430\u0440\u0442",
+ "\u0430\u043f\u0440.",
+ "\u043c\u0430\u0439",
+ "\u044e\u043d\u0438",
+ "\u044e\u043b\u0438",
+ "\u0430\u0432\u0433.",
+ "\u0441\u0435\u043f\u0442.",
+ "\u043e\u043a\u0442.",
+ "\u043d\u043e\u0435\u043c.",
+ "\u0434\u0435\u043a."
+ ],
"fullDate": "dd MMMM y, EEEE",
"longDate": "dd MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "lev",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "bg-bg",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bg.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u043f\u0440. \u043e\u0431.",
- "1": "\u0441\u043b. \u043e\u0431."
- },
- "DAY": {
- "0": "\u043d\u0435\u0434\u0435\u043b\u044f",
- "1": "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a",
- "2": "\u0432\u0442\u043e\u0440\u043d\u0438\u043a",
- "3": "\u0441\u0440\u044f\u0434\u0430",
- "4": "\u0447\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a",
- "5": "\u043f\u0435\u0442\u044a\u043a",
- "6": "\u0441\u044a\u0431\u043e\u0442\u0430"
- },
- "MONTH": {
- "0": "\u044f\u043d\u0443\u0430\u0440\u0438",
- "1": "\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438",
- "2": "\u043c\u0430\u0440\u0442",
- "3": "\u0430\u043f\u0440\u0438\u043b",
- "4": "\u043c\u0430\u0439",
- "5": "\u044e\u043d\u0438",
- "6": "\u044e\u043b\u0438",
- "7": "\u0430\u0432\u0433\u0443\u0441\u0442",
- "8": "\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438",
- "9": "\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438",
- "10": "\u043d\u043e\u0435\u043c\u0432\u0440\u0438",
- "11": "\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438"
- },
- "SHORTDAY": {
- "0": "\u043d\u0434",
- "1": "\u043f\u043d",
- "2": "\u0432\u0442",
- "3": "\u0441\u0440",
- "4": "\u0447\u0442",
- "5": "\u043f\u0442",
- "6": "\u0441\u0431"
- },
- "SHORTMONTH": {
- "0": "\u044f\u043d.",
- "1": "\u0444\u0435\u0432\u0440.",
- "2": "\u043c\u0430\u0440\u0442",
- "3": "\u0430\u043f\u0440.",
- "4": "\u043c\u0430\u0439",
- "5": "\u044e\u043d\u0438",
- "6": "\u044e\u043b\u0438",
- "7": "\u0430\u0432\u0433.",
- "8": "\u0441\u0435\u043f\u0442.",
- "9": "\u043e\u043a\u0442.",
- "10": "\u043d\u043e\u0435\u043c.",
- "11": "\u0434\u0435\u043a."
- },
+ "AMPMS": [
+ "\u043f\u0440. \u043e\u0431.",
+ "\u0441\u043b. \u043e\u0431."
+ ],
+ "DAY": [
+ "\u043d\u0435\u0434\u0435\u043b\u044f",
+ "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a",
+ "\u0432\u0442\u043e\u0440\u043d\u0438\u043a",
+ "\u0441\u0440\u044f\u0434\u0430",
+ "\u0447\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a",
+ "\u043f\u0435\u0442\u044a\u043a",
+ "\u0441\u044a\u0431\u043e\u0442\u0430"
+ ],
+ "MONTH": [
+ "\u044f\u043d\u0443\u0430\u0440\u0438",
+ "\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438",
+ "\u043c\u0430\u0440\u0442",
+ "\u0430\u043f\u0440\u0438\u043b",
+ "\u043c\u0430\u0439",
+ "\u044e\u043d\u0438",
+ "\u044e\u043b\u0438",
+ "\u0430\u0432\u0433\u0443\u0441\u0442",
+ "\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438",
+ "\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438",
+ "\u043d\u043e\u0435\u043c\u0432\u0440\u0438",
+ "\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438"
+ ],
+ "SHORTDAY": [
+ "\u043d\u0434",
+ "\u043f\u043d",
+ "\u0432\u0442",
+ "\u0441\u0440",
+ "\u0447\u0442",
+ "\u043f\u0442",
+ "\u0441\u0431"
+ ],
+ "SHORTMONTH": [
+ "\u044f\u043d.",
+ "\u0444\u0435\u0432\u0440.",
+ "\u043c\u0430\u0440\u0442",
+ "\u0430\u043f\u0440.",
+ "\u043c\u0430\u0439",
+ "\u044e\u043d\u0438",
+ "\u044e\u043b\u0438",
+ "\u0430\u0432\u0433.",
+ "\u0441\u0435\u043f\u0442.",
+ "\u043e\u043a\u0442.",
+ "\u043d\u043e\u0435\u043c.",
+ "\u0434\u0435\u043a."
+ ],
"fullDate": "dd MMMM y, EEEE",
"longDate": "dd MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "lev",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "bg",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-bd.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-bd.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-bd.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u09b0\u09ac\u09bf\u09ac\u09be\u09b0",
- "1": "\u09b8\u09cb\u09ae\u09ac\u09be\u09b0",
- "2": "\u09ae\u0999\u09cd\u0997\u09b2\u09ac\u09be\u09b0",
- "3": "\u09ac\u09c1\u09a7\u09ac\u09be\u09b0",
- "4": "\u09ac\u09c3\u09b9\u09b7\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0",
- "5": "\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0",
- "6": "\u09b6\u09a8\u09bf\u09ac\u09be\u09b0"
- },
- "MONTH": {
- "0": "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
- "1": "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
- "2": "\u09ae\u09be\u09b0\u09cd\u099a",
- "3": "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2",
- "4": "\u09ae\u09c7",
- "5": "\u099c\u09c1\u09a8",
- "6": "\u099c\u09c1\u09b2\u09be\u0987",
- "7": "\u0986\u0997\u09b8\u09cd\u099f",
- "8": "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
- "9": "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
- "10": "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
- "11": "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"
- },
- "SHORTDAY": {
- "0": "\u09b0\u09ac\u09bf",
- "1": "\u09b8\u09cb\u09ae",
- "2": "\u09ae\u0999\u09cd\u0997\u09b2",
- "3": "\u09ac\u09c1\u09a7",
- "4": "\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf",
- "5": "\u09b6\u09c1\u0995\u09cd\u09b0",
- "6": "\u09b6\u09a8\u09bf"
- },
- "SHORTMONTH": {
- "0": "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
- "1": "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
- "2": "\u09ae\u09be\u09b0\u09cd\u099a",
- "3": "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2",
- "4": "\u09ae\u09c7",
- "5": "\u099c\u09c1\u09a8",
- "6": "\u099c\u09c1\u09b2\u09be\u0987",
- "7": "\u0986\u0997\u09b8\u09cd\u099f",
- "8": "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
- "9": "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
- "10": "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
- "11": "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u09b0\u09ac\u09bf\u09ac\u09be\u09b0",
+ "\u09b8\u09cb\u09ae\u09ac\u09be\u09b0",
+ "\u09ae\u0999\u09cd\u0997\u09b2\u09ac\u09be\u09b0",
+ "\u09ac\u09c1\u09a7\u09ac\u09be\u09b0",
+ "\u09ac\u09c3\u09b9\u09b7\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0",
+ "\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0",
+ "\u09b6\u09a8\u09bf\u09ac\u09be\u09b0"
+ ],
+ "MONTH": [
+ "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
+ "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
+ "\u09ae\u09be\u09b0\u09cd\u099a",
+ "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2",
+ "\u09ae\u09c7",
+ "\u099c\u09c1\u09a8",
+ "\u099c\u09c1\u09b2\u09be\u0987",
+ "\u0986\u0997\u09b8\u09cd\u099f",
+ "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
+ "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
+ "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
+ "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"
+ ],
+ "SHORTDAY": [
+ "\u09b0\u09ac\u09bf",
+ "\u09b8\u09cb\u09ae",
+ "\u09ae\u0999\u09cd\u0997\u09b2",
+ "\u09ac\u09c1\u09a7",
+ "\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf",
+ "\u09b6\u09c1\u0995\u09cd\u09b0",
+ "\u09b6\u09a8\u09bf"
+ ],
+ "SHORTMONTH": [
+ "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
+ "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
+ "\u09ae\u09be\u09b0\u09cd\u099a",
+ "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2",
+ "\u09ae\u09c7",
+ "\u099c\u09c1\u09a8",
+ "\u099c\u09c1\u09b2\u09be\u0987",
+ "\u0986\u0997\u09b8\u09cd\u099f",
+ "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
+ "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
+ "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
+ "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"
+ ],
"fullDate": "EEEE, d MMMM, y",
"longDate": "d MMMM, y",
"medium": "d MMM, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u09f3",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a4"
}
- }
+ ]
},
"id": "bn-bd",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-in.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-in.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn-in.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u09b0\u09ac\u09bf\u09ac\u09be\u09b0",
- "1": "\u09b8\u09cb\u09ae\u09ac\u09be\u09b0",
- "2": "\u09ae\u0999\u09cd\u0997\u09b2\u09ac\u09be\u09b0",
- "3": "\u09ac\u09c1\u09a7\u09ac\u09be\u09b0",
- "4": "\u09ac\u09c3\u09b9\u09b7\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0",
- "5": "\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0",
- "6": "\u09b6\u09a8\u09bf\u09ac\u09be\u09b0"
- },
- "MONTH": {
- "0": "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
- "1": "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
- "2": "\u09ae\u09be\u09b0\u09cd\u099a",
- "3": "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2",
- "4": "\u09ae\u09c7",
- "5": "\u099c\u09c1\u09a8",
- "6": "\u099c\u09c1\u09b2\u09be\u0987",
- "7": "\u0986\u0997\u09b8\u09cd\u099f",
- "8": "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
- "9": "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
- "10": "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
- "11": "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"
- },
- "SHORTDAY": {
- "0": "\u09b0\u09ac\u09bf",
- "1": "\u09b8\u09cb\u09ae",
- "2": "\u09ae\u0999\u09cd\u0997\u09b2",
- "3": "\u09ac\u09c1\u09a7",
- "4": "\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf",
- "5": "\u09b6\u09c1\u0995\u09cd\u09b0",
- "6": "\u09b6\u09a8\u09bf"
- },
- "SHORTMONTH": {
- "0": "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
- "1": "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
- "2": "\u09ae\u09be\u09b0\u09cd\u099a",
- "3": "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2",
- "4": "\u09ae\u09c7",
- "5": "\u099c\u09c1\u09a8",
- "6": "\u099c\u09c1\u09b2\u09be\u0987",
- "7": "\u0986\u0997\u09b8\u09cd\u099f",
- "8": "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
- "9": "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
- "10": "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
- "11": "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u09b0\u09ac\u09bf\u09ac\u09be\u09b0",
+ "\u09b8\u09cb\u09ae\u09ac\u09be\u09b0",
+ "\u09ae\u0999\u09cd\u0997\u09b2\u09ac\u09be\u09b0",
+ "\u09ac\u09c1\u09a7\u09ac\u09be\u09b0",
+ "\u09ac\u09c3\u09b9\u09b7\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0",
+ "\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0",
+ "\u09b6\u09a8\u09bf\u09ac\u09be\u09b0"
+ ],
+ "MONTH": [
+ "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
+ "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
+ "\u09ae\u09be\u09b0\u09cd\u099a",
+ "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2",
+ "\u09ae\u09c7",
+ "\u099c\u09c1\u09a8",
+ "\u099c\u09c1\u09b2\u09be\u0987",
+ "\u0986\u0997\u09b8\u09cd\u099f",
+ "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
+ "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
+ "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
+ "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"
+ ],
+ "SHORTDAY": [
+ "\u09b0\u09ac\u09bf",
+ "\u09b8\u09cb\u09ae",
+ "\u09ae\u0999\u09cd\u0997\u09b2",
+ "\u09ac\u09c1\u09a7",
+ "\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf",
+ "\u09b6\u09c1\u0995\u09cd\u09b0",
+ "\u09b6\u09a8\u09bf"
+ ],
+ "SHORTMONTH": [
+ "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
+ "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
+ "\u09ae\u09be\u09b0\u09cd\u099a",
+ "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2",
+ "\u09ae\u09c7",
+ "\u099c\u09c1\u09a8",
+ "\u099c\u09c1\u09b2\u09be\u0987",
+ "\u0986\u0997\u09b8\u09cd\u099f",
+ "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
+ "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
+ "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
+ "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"
+ ],
"fullDate": "EEEE, d MMMM, y",
"longDate": "d MMMM, y",
"medium": "d MMM, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u09f3",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a4"
}
- }
+ ]
},
"id": "bn-in",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_bn.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u09b0\u09ac\u09bf\u09ac\u09be\u09b0",
- "1": "\u09b8\u09cb\u09ae\u09ac\u09be\u09b0",
- "2": "\u09ae\u0999\u09cd\u0997\u09b2\u09ac\u09be\u09b0",
- "3": "\u09ac\u09c1\u09a7\u09ac\u09be\u09b0",
- "4": "\u09ac\u09c3\u09b9\u09b7\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0",
- "5": "\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0",
- "6": "\u09b6\u09a8\u09bf\u09ac\u09be\u09b0"
- },
- "MONTH": {
- "0": "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
- "1": "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
- "2": "\u09ae\u09be\u09b0\u09cd\u099a",
- "3": "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2",
- "4": "\u09ae\u09c7",
- "5": "\u099c\u09c1\u09a8",
- "6": "\u099c\u09c1\u09b2\u09be\u0987",
- "7": "\u0986\u0997\u09b8\u09cd\u099f",
- "8": "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
- "9": "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
- "10": "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
- "11": "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"
- },
- "SHORTDAY": {
- "0": "\u09b0\u09ac\u09bf",
- "1": "\u09b8\u09cb\u09ae",
- "2": "\u09ae\u0999\u09cd\u0997\u09b2",
- "3": "\u09ac\u09c1\u09a7",
- "4": "\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf",
- "5": "\u09b6\u09c1\u0995\u09cd\u09b0",
- "6": "\u09b6\u09a8\u09bf"
- },
- "SHORTMONTH": {
- "0": "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
- "1": "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
- "2": "\u09ae\u09be\u09b0\u09cd\u099a",
- "3": "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2",
- "4": "\u09ae\u09c7",
- "5": "\u099c\u09c1\u09a8",
- "6": "\u099c\u09c1\u09b2\u09be\u0987",
- "7": "\u0986\u0997\u09b8\u09cd\u099f",
- "8": "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
- "9": "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
- "10": "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
- "11": "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u09b0\u09ac\u09bf\u09ac\u09be\u09b0",
+ "\u09b8\u09cb\u09ae\u09ac\u09be\u09b0",
+ "\u09ae\u0999\u09cd\u0997\u09b2\u09ac\u09be\u09b0",
+ "\u09ac\u09c1\u09a7\u09ac\u09be\u09b0",
+ "\u09ac\u09c3\u09b9\u09b7\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0",
+ "\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0",
+ "\u09b6\u09a8\u09bf\u09ac\u09be\u09b0"
+ ],
+ "MONTH": [
+ "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
+ "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
+ "\u09ae\u09be\u09b0\u09cd\u099a",
+ "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2",
+ "\u09ae\u09c7",
+ "\u099c\u09c1\u09a8",
+ "\u099c\u09c1\u09b2\u09be\u0987",
+ "\u0986\u0997\u09b8\u09cd\u099f",
+ "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
+ "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
+ "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
+ "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"
+ ],
+ "SHORTDAY": [
+ "\u09b0\u09ac\u09bf",
+ "\u09b8\u09cb\u09ae",
+ "\u09ae\u0999\u09cd\u0997\u09b2",
+ "\u09ac\u09c1\u09a7",
+ "\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf",
+ "\u09b6\u09c1\u0995\u09cd\u09b0",
+ "\u09b6\u09a8\u09bf"
+ ],
+ "SHORTMONTH": [
+ "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
+ "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09c0",
+ "\u09ae\u09be\u09b0\u09cd\u099a",
+ "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2",
+ "\u09ae\u09c7",
+ "\u099c\u09c1\u09a8",
+ "\u099c\u09c1\u09b2\u09be\u0987",
+ "\u0986\u0997\u09b8\u09cd\u099f",
+ "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
+ "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
+ "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
+ "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"
+ ],
"fullDate": "EEEE, d MMMM, y",
"longDate": "d MMMM, y",
"medium": "d MMM, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u09f3",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a4"
}
- }
+ ]
},
"id": "bn",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-ad.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-ad.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-ad.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "diumenge",
- "1": "dilluns",
- "2": "dimarts",
- "3": "dimecres",
- "4": "dijous",
- "5": "divendres",
- "6": "dissabte"
- },
- "MONTH": {
- "0": "de gener",
- "1": "de febrer",
- "2": "de mar\u00e7",
- "3": "d\u2019abril",
- "4": "de maig",
- "5": "de juny",
- "6": "de juliol",
- "7": "d\u2019agost",
- "8": "de setembre",
- "9": "d\u2019octubre",
- "10": "de novembre",
- "11": "de desembre"
- },
- "SHORTDAY": {
- "0": "dg.",
- "1": "dl.",
- "2": "dt.",
- "3": "dc.",
- "4": "dj.",
- "5": "dv.",
- "6": "ds."
- },
- "SHORTMONTH": {
- "0": "de gen.",
- "1": "de febr.",
- "2": "de mar\u00e7",
- "3": "d\u2019abr.",
- "4": "de maig",
- "5": "de juny",
- "6": "de jul.",
- "7": "d\u2019ag.",
- "8": "de set.",
- "9": "d\u2019oct.",
- "10": "de nov.",
- "11": "de des."
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "diumenge",
+ "dilluns",
+ "dimarts",
+ "dimecres",
+ "dijous",
+ "divendres",
+ "dissabte"
+ ],
+ "MONTH": [
+ "de gener",
+ "de febrer",
+ "de mar\u00e7",
+ "d\u2019abril",
+ "de maig",
+ "de juny",
+ "de juliol",
+ "d\u2019agost",
+ "de setembre",
+ "d\u2019octubre",
+ "de novembre",
+ "de desembre"
+ ],
+ "SHORTDAY": [
+ "dg.",
+ "dl.",
+ "dt.",
+ "dc.",
+ "dj.",
+ "dv.",
+ "ds."
+ ],
+ "SHORTMONTH": [
+ "de gen.",
+ "de febr.",
+ "de mar\u00e7",
+ "d\u2019abr.",
+ "de maig",
+ "de juny",
+ "de jul.",
+ "d\u2019ag.",
+ "de set.",
+ "d\u2019oct.",
+ "de nov.",
+ "de des."
+ ],
"fullDate": "EEEE d MMMM 'de' y",
"longDate": "d MMMM 'de' y",
"medium": "dd/MM/yyyy H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "ca-ad",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-es.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-es.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca-es.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "diumenge",
- "1": "dilluns",
- "2": "dimarts",
- "3": "dimecres",
- "4": "dijous",
- "5": "divendres",
- "6": "dissabte"
- },
- "MONTH": {
- "0": "de gener",
- "1": "de febrer",
- "2": "de mar\u00e7",
- "3": "d\u2019abril",
- "4": "de maig",
- "5": "de juny",
- "6": "de juliol",
- "7": "d\u2019agost",
- "8": "de setembre",
- "9": "d\u2019octubre",
- "10": "de novembre",
- "11": "de desembre"
- },
- "SHORTDAY": {
- "0": "dg.",
- "1": "dl.",
- "2": "dt.",
- "3": "dc.",
- "4": "dj.",
- "5": "dv.",
- "6": "ds."
- },
- "SHORTMONTH": {
- "0": "de gen.",
- "1": "de febr.",
- "2": "de mar\u00e7",
- "3": "d\u2019abr.",
- "4": "de maig",
- "5": "de juny",
- "6": "de jul.",
- "7": "d\u2019ag.",
- "8": "de set.",
- "9": "d\u2019oct.",
- "10": "de nov.",
- "11": "de des."
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "diumenge",
+ "dilluns",
+ "dimarts",
+ "dimecres",
+ "dijous",
+ "divendres",
+ "dissabte"
+ ],
+ "MONTH": [
+ "de gener",
+ "de febrer",
+ "de mar\u00e7",
+ "d\u2019abril",
+ "de maig",
+ "de juny",
+ "de juliol",
+ "d\u2019agost",
+ "de setembre",
+ "d\u2019octubre",
+ "de novembre",
+ "de desembre"
+ ],
+ "SHORTDAY": [
+ "dg.",
+ "dl.",
+ "dt.",
+ "dc.",
+ "dj.",
+ "dv.",
+ "ds."
+ ],
+ "SHORTMONTH": [
+ "de gen.",
+ "de febr.",
+ "de mar\u00e7",
+ "d\u2019abr.",
+ "de maig",
+ "de juny",
+ "de jul.",
+ "d\u2019ag.",
+ "de set.",
+ "d\u2019oct.",
+ "de nov.",
+ "de des."
+ ],
"fullDate": "EEEE d MMMM 'de' y",
"longDate": "d MMMM 'de' y",
"medium": "dd/MM/yyyy H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "ca-es",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ca.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "diumenge",
- "1": "dilluns",
- "2": "dimarts",
- "3": "dimecres",
- "4": "dijous",
- "5": "divendres",
- "6": "dissabte"
- },
- "MONTH": {
- "0": "de gener",
- "1": "de febrer",
- "2": "de mar\u00e7",
- "3": "d\u2019abril",
- "4": "de maig",
- "5": "de juny",
- "6": "de juliol",
- "7": "d\u2019agost",
- "8": "de setembre",
- "9": "d\u2019octubre",
- "10": "de novembre",
- "11": "de desembre"
- },
- "SHORTDAY": {
- "0": "dg.",
- "1": "dl.",
- "2": "dt.",
- "3": "dc.",
- "4": "dj.",
- "5": "dv.",
- "6": "ds."
- },
- "SHORTMONTH": {
- "0": "de gen.",
- "1": "de febr.",
- "2": "de mar\u00e7",
- "3": "d\u2019abr.",
- "4": "de maig",
- "5": "de juny",
- "6": "de jul.",
- "7": "d\u2019ag.",
- "8": "de set.",
- "9": "d\u2019oct.",
- "10": "de nov.",
- "11": "de des."
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "diumenge",
+ "dilluns",
+ "dimarts",
+ "dimecres",
+ "dijous",
+ "divendres",
+ "dissabte"
+ ],
+ "MONTH": [
+ "de gener",
+ "de febrer",
+ "de mar\u00e7",
+ "d\u2019abril",
+ "de maig",
+ "de juny",
+ "de juliol",
+ "d\u2019agost",
+ "de setembre",
+ "d\u2019octubre",
+ "de novembre",
+ "de desembre"
+ ],
+ "SHORTDAY": [
+ "dg.",
+ "dl.",
+ "dt.",
+ "dc.",
+ "dj.",
+ "dv.",
+ "ds."
+ ],
+ "SHORTMONTH": [
+ "de gen.",
+ "de febr.",
+ "de mar\u00e7",
+ "d\u2019abr.",
+ "de maig",
+ "de juny",
+ "de jul.",
+ "d\u2019ag.",
+ "de set.",
+ "d\u2019oct.",
+ "de nov.",
+ "de des."
+ ],
"fullDate": "EEEE d MMMM 'de' y",
"longDate": "d MMMM 'de' y",
"medium": "dd/MM/yyyy H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "ca",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs-cz.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs-cz.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs-cz.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "dop.",
- "1": "odp."
- },
- "DAY": {
- "0": "ned\u011ble",
- "1": "pond\u011bl\u00ed",
- "2": "\u00fater\u00fd",
- "3": "st\u0159eda",
- "4": "\u010dtvrtek",
- "5": "p\u00e1tek",
- "6": "sobota"
- },
- "MONTH": {
- "0": "ledna",
- "1": "\u00fanora",
- "2": "b\u0159ezna",
- "3": "dubna",
- "4": "kv\u011btna",
- "5": "\u010dervna",
- "6": "\u010dervence",
- "7": "srpna",
- "8": "z\u00e1\u0159\u00ed",
- "9": "\u0159\u00edjna",
- "10": "listopadu",
- "11": "prosince"
- },
- "SHORTDAY": {
- "0": "ne",
- "1": "po",
- "2": "\u00fat",
- "3": "st",
- "4": "\u010dt",
- "5": "p\u00e1",
- "6": "so"
- },
- "SHORTMONTH": {
- "0": "Led",
- "1": "\u00dano",
- "2": "B\u0159e",
- "3": "Dub",
- "4": "Kv\u011b",
- "5": "\u010cer",
- "6": "\u010cvc",
- "7": "Srp",
- "8": "Z\u00e1\u0159",
- "9": "\u0158\u00edj",
- "10": "Lis",
- "11": "Pro"
- },
+ "AMPMS": [
+ "dop.",
+ "odp."
+ ],
+ "DAY": [
+ "ned\u011ble",
+ "pond\u011bl\u00ed",
+ "\u00fater\u00fd",
+ "st\u0159eda",
+ "\u010dtvrtek",
+ "p\u00e1tek",
+ "sobota"
+ ],
+ "MONTH": [
+ "ledna",
+ "\u00fanora",
+ "b\u0159ezna",
+ "dubna",
+ "kv\u011btna",
+ "\u010dervna",
+ "\u010dervence",
+ "srpna",
+ "z\u00e1\u0159\u00ed",
+ "\u0159\u00edjna",
+ "listopadu",
+ "prosince"
+ ],
+ "SHORTDAY": [
+ "ne",
+ "po",
+ "\u00fat",
+ "st",
+ "\u010dt",
+ "p\u00e1",
+ "so"
+ ],
+ "SHORTMONTH": [
+ "Led",
+ "\u00dano",
+ "B\u0159e",
+ "Dub",
+ "Kv\u011b",
+ "\u010cer",
+ "\u010cvc",
+ "Srp",
+ "Z\u00e1\u0159",
+ "\u0158\u00edj",
+ "Lis",
+ "Pro"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "d. M. yyyy H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "K\u010d",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "cs-cz",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n >= 2 && n <= 4) { return PLURAL_CATEGORY.FEW; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_cs.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "dop.",
- "1": "odp."
- },
- "DAY": {
- "0": "ned\u011ble",
- "1": "pond\u011bl\u00ed",
- "2": "\u00fater\u00fd",
- "3": "st\u0159eda",
- "4": "\u010dtvrtek",
- "5": "p\u00e1tek",
- "6": "sobota"
- },
- "MONTH": {
- "0": "ledna",
- "1": "\u00fanora",
- "2": "b\u0159ezna",
- "3": "dubna",
- "4": "kv\u011btna",
- "5": "\u010dervna",
- "6": "\u010dervence",
- "7": "srpna",
- "8": "z\u00e1\u0159\u00ed",
- "9": "\u0159\u00edjna",
- "10": "listopadu",
- "11": "prosince"
- },
- "SHORTDAY": {
- "0": "ne",
- "1": "po",
- "2": "\u00fat",
- "3": "st",
- "4": "\u010dt",
- "5": "p\u00e1",
- "6": "so"
- },
- "SHORTMONTH": {
- "0": "Led",
- "1": "\u00dano",
- "2": "B\u0159e",
- "3": "Dub",
- "4": "Kv\u011b",
- "5": "\u010cer",
- "6": "\u010cvc",
- "7": "Srp",
- "8": "Z\u00e1\u0159",
- "9": "\u0158\u00edj",
- "10": "Lis",
- "11": "Pro"
- },
+ "AMPMS": [
+ "dop.",
+ "odp."
+ ],
+ "DAY": [
+ "ned\u011ble",
+ "pond\u011bl\u00ed",
+ "\u00fater\u00fd",
+ "st\u0159eda",
+ "\u010dtvrtek",
+ "p\u00e1tek",
+ "sobota"
+ ],
+ "MONTH": [
+ "ledna",
+ "\u00fanora",
+ "b\u0159ezna",
+ "dubna",
+ "kv\u011btna",
+ "\u010dervna",
+ "\u010dervence",
+ "srpna",
+ "z\u00e1\u0159\u00ed",
+ "\u0159\u00edjna",
+ "listopadu",
+ "prosince"
+ ],
+ "SHORTDAY": [
+ "ne",
+ "po",
+ "\u00fat",
+ "st",
+ "\u010dt",
+ "p\u00e1",
+ "so"
+ ],
+ "SHORTMONTH": [
+ "Led",
+ "\u00dano",
+ "B\u0159e",
+ "Dub",
+ "Kv\u011b",
+ "\u010cer",
+ "\u010cvc",
+ "Srp",
+ "Z\u00e1\u0159",
+ "\u0158\u00edj",
+ "Lis",
+ "Pro"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "d. M. yyyy H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "K\u010d",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "cs",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n >= 2 && n <= 4) { return PLURAL_CATEGORY.FEW; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da-dk.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da-dk.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da-dk.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "f.m.",
- "1": "e.m."
- },
- "DAY": {
- "0": "s\u00f8ndag",
- "1": "mandag",
- "2": "tirsdag",
- "3": "onsdag",
- "4": "torsdag",
- "5": "fredag",
- "6": "l\u00f8rdag"
- },
- "MONTH": {
- "0": "januar",
- "1": "februar",
- "2": "marts",
- "3": "april",
- "4": "maj",
- "5": "juni",
- "6": "juli",
- "7": "august",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "s\u00f8n",
- "1": "man",
- "2": "tir",
- "3": "ons",
- "4": "tor",
- "5": "fre",
- "6": "l\u00f8r"
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "feb.",
- "2": "mar.",
- "3": "apr.",
- "4": "maj",
- "5": "jun.",
- "6": "jul.",
- "7": "aug.",
- "8": "sep.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "f.m.",
+ "e.m."
+ ],
+ "DAY": [
+ "s\u00f8ndag",
+ "mandag",
+ "tirsdag",
+ "onsdag",
+ "torsdag",
+ "fredag",
+ "l\u00f8rdag"
+ ],
+ "MONTH": [
+ "januar",
+ "februar",
+ "marts",
+ "april",
+ "maj",
+ "juni",
+ "juli",
+ "august",
+ "september",
+ "oktober",
+ "november",
+ "december"
+ ],
+ "SHORTDAY": [
+ "s\u00f8n",
+ "man",
+ "tir",
+ "ons",
+ "tor",
+ "fre",
+ "l\u00f8r"
+ ],
+ "SHORTMONTH": [
+ "jan.",
+ "feb.",
+ "mar.",
+ "apr.",
+ "maj",
+ "jun.",
+ "jul.",
+ "aug.",
+ "sep.",
+ "okt.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "EEEE 'den' d. MMMM y",
"longDate": "d. MMM y",
"medium": "dd/MM/yyyy HH.mm.ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "kr",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "da-dk",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_da.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "f.m.",
- "1": "e.m."
- },
- "DAY": {
- "0": "s\u00f8ndag",
- "1": "mandag",
- "2": "tirsdag",
- "3": "onsdag",
- "4": "torsdag",
- "5": "fredag",
- "6": "l\u00f8rdag"
- },
- "MONTH": {
- "0": "januar",
- "1": "februar",
- "2": "marts",
- "3": "april",
- "4": "maj",
- "5": "juni",
- "6": "juli",
- "7": "august",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "s\u00f8n",
- "1": "man",
- "2": "tir",
- "3": "ons",
- "4": "tor",
- "5": "fre",
- "6": "l\u00f8r"
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "feb.",
- "2": "mar.",
- "3": "apr.",
- "4": "maj",
- "5": "jun.",
- "6": "jul.",
- "7": "aug.",
- "8": "sep.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "f.m.",
+ "e.m."
+ ],
+ "DAY": [
+ "s\u00f8ndag",
+ "mandag",
+ "tirsdag",
+ "onsdag",
+ "torsdag",
+ "fredag",
+ "l\u00f8rdag"
+ ],
+ "MONTH": [
+ "januar",
+ "februar",
+ "marts",
+ "april",
+ "maj",
+ "juni",
+ "juli",
+ "august",
+ "september",
+ "oktober",
+ "november",
+ "december"
+ ],
+ "SHORTDAY": [
+ "s\u00f8n",
+ "man",
+ "tir",
+ "ons",
+ "tor",
+ "fre",
+ "l\u00f8r"
+ ],
+ "SHORTMONTH": [
+ "jan.",
+ "feb.",
+ "mar.",
+ "apr.",
+ "maj",
+ "jun.",
+ "jul.",
+ "aug.",
+ "sep.",
+ "okt.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "EEEE 'den' d. MMMM y",
"longDate": "d. MMM y",
"medium": "dd/MM/yyyy HH.mm.ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "kr",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "da",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-at.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-at.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-at.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "vorm.",
- "1": "nachm."
- },
- "DAY": {
- "0": "Sonntag",
- "1": "Montag",
- "2": "Dienstag",
- "3": "Mittwoch",
- "4": "Donnerstag",
- "5": "Freitag",
- "6": "Samstag"
- },
- "MONTH": {
- "0": "J\u00e4nner",
- "1": "Februar",
- "2": "M\u00e4rz",
- "3": "April",
- "4": "Mai",
- "5": "Juni",
- "6": "Juli",
- "7": "August",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Dezember"
- },
- "SHORTDAY": {
- "0": "So.",
- "1": "Mo.",
- "2": "Di.",
- "3": "Mi.",
- "4": "Do.",
- "5": "Fr.",
- "6": "Sa."
- },
- "SHORTMONTH": {
- "0": "J\u00e4n",
- "1": "Feb",
- "2": "M\u00e4r",
- "3": "Apr",
- "4": "Mai",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dez"
- },
+ "AMPMS": [
+ "vorm.",
+ "nachm."
+ ],
+ "DAY": [
+ "Sonntag",
+ "Montag",
+ "Dienstag",
+ "Mittwoch",
+ "Donnerstag",
+ "Freitag",
+ "Samstag"
+ ],
+ "MONTH": [
+ "J\u00e4nner",
+ "Februar",
+ "M\u00e4rz",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "August",
+ "September",
+ "Oktober",
+ "November",
+ "Dezember"
+ ],
+ "SHORTDAY": [
+ "So.",
+ "Mo.",
+ "Di.",
+ "Mi.",
+ "Do.",
+ "Fr.",
+ "Sa."
+ ],
+ "SHORTMONTH": [
+ "J\u00e4n",
+ "Feb",
+ "M\u00e4r",
+ "Apr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dez"
+ ],
"fullDate": "EEEE, dd. MMMM y",
"longDate": "dd. MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "de-at",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-be.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-be.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-be.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "vorm.",
- "1": "nachm."
- },
- "DAY": {
- "0": "Sonntag",
- "1": "Montag",
- "2": "Dienstag",
- "3": "Mittwoch",
- "4": "Donnerstag",
- "5": "Freitag",
- "6": "Samstag"
- },
- "MONTH": {
- "0": "Januar",
- "1": "Februar",
- "2": "M\u00e4rz",
- "3": "April",
- "4": "Mai",
- "5": "Juni",
- "6": "Juli",
- "7": "August",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Dezember"
- },
- "SHORTDAY": {
- "0": "So.",
- "1": "Mo.",
- "2": "Di.",
- "3": "Mi.",
- "4": "Do.",
- "5": "Fr.",
- "6": "Sa."
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "M\u00e4r",
- "3": "Apr",
- "4": "Mai",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dez"
- },
+ "AMPMS": [
+ "vorm.",
+ "nachm."
+ ],
+ "DAY": [
+ "Sonntag",
+ "Montag",
+ "Dienstag",
+ "Mittwoch",
+ "Donnerstag",
+ "Freitag",
+ "Samstag"
+ ],
+ "MONTH": [
+ "Januar",
+ "Februar",
+ "M\u00e4rz",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "August",
+ "September",
+ "Oktober",
+ "November",
+ "Dezember"
+ ],
+ "SHORTDAY": [
+ "So.",
+ "Mo.",
+ "Di.",
+ "Mi.",
+ "Do.",
+ "Fr.",
+ "Sa."
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "M\u00e4r",
+ "Apr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dez"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "de-be",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-ch.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-ch.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-ch.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "vorm.",
- "1": "nachm."
- },
- "DAY": {
- "0": "Sonntag",
- "1": "Montag",
- "2": "Dienstag",
- "3": "Mittwoch",
- "4": "Donnerstag",
- "5": "Freitag",
- "6": "Samstag"
- },
- "MONTH": {
- "0": "Januar",
- "1": "Februar",
- "2": "M\u00e4rz",
- "3": "April",
- "4": "Mai",
- "5": "Juni",
- "6": "Juli",
- "7": "August",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Dezember"
- },
- "SHORTDAY": {
- "0": "So.",
- "1": "Mo.",
- "2": "Di.",
- "3": "Mi.",
- "4": "Do.",
- "5": "Fr.",
- "6": "Sa."
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "M\u00e4r",
- "3": "Apr",
- "4": "Mai",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dez"
- },
+ "AMPMS": [
+ "vorm.",
+ "nachm."
+ ],
+ "DAY": [
+ "Sonntag",
+ "Montag",
+ "Dienstag",
+ "Mittwoch",
+ "Donnerstag",
+ "Freitag",
+ "Samstag"
+ ],
+ "MONTH": [
+ "Januar",
+ "Februar",
+ "M\u00e4rz",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "August",
+ "September",
+ "Oktober",
+ "November",
+ "Dezember"
+ ],
+ "SHORTDAY": [
+ "So.",
+ "Mo.",
+ "Di.",
+ "Mi.",
+ "Do.",
+ "Fr.",
+ "Sa."
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "M\u00e4r",
+ "Apr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dez"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "CHF",
"DECIMAL_SEP": ".",
"GROUP_SEP": "'",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "de-ch",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-de.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-de.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-de.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "vorm.",
- "1": "nachm."
- },
- "DAY": {
- "0": "Sonntag",
- "1": "Montag",
- "2": "Dienstag",
- "3": "Mittwoch",
- "4": "Donnerstag",
- "5": "Freitag",
- "6": "Samstag"
- },
- "MONTH": {
- "0": "Januar",
- "1": "Februar",
- "2": "M\u00e4rz",
- "3": "April",
- "4": "Mai",
- "5": "Juni",
- "6": "Juli",
- "7": "August",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Dezember"
- },
- "SHORTDAY": {
- "0": "So.",
- "1": "Mo.",
- "2": "Di.",
- "3": "Mi.",
- "4": "Do.",
- "5": "Fr.",
- "6": "Sa."
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "M\u00e4r",
- "3": "Apr",
- "4": "Mai",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dez"
- },
+ "AMPMS": [
+ "vorm.",
+ "nachm."
+ ],
+ "DAY": [
+ "Sonntag",
+ "Montag",
+ "Dienstag",
+ "Mittwoch",
+ "Donnerstag",
+ "Freitag",
+ "Samstag"
+ ],
+ "MONTH": [
+ "Januar",
+ "Februar",
+ "M\u00e4rz",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "August",
+ "September",
+ "Oktober",
+ "November",
+ "Dezember"
+ ],
+ "SHORTDAY": [
+ "So.",
+ "Mo.",
+ "Di.",
+ "Mi.",
+ "Do.",
+ "Fr.",
+ "Sa."
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "M\u00e4r",
+ "Apr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dez"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "de-de",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-li.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-li.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-li.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "vorm.",
- "1": "nachm."
- },
- "DAY": {
- "0": "Sonntag",
- "1": "Montag",
- "2": "Dienstag",
- "3": "Mittwoch",
- "4": "Donnerstag",
- "5": "Freitag",
- "6": "Samstag"
- },
- "MONTH": {
- "0": "Januar",
- "1": "Februar",
- "2": "M\u00e4rz",
- "3": "April",
- "4": "Mai",
- "5": "Juni",
- "6": "Juli",
- "7": "August",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Dezember"
- },
- "SHORTDAY": {
- "0": "So.",
- "1": "Mo.",
- "2": "Di.",
- "3": "Mi.",
- "4": "Do.",
- "5": "Fr.",
- "6": "Sa."
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "M\u00e4r",
- "3": "Apr",
- "4": "Mai",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dez"
- },
+ "AMPMS": [
+ "vorm.",
+ "nachm."
+ ],
+ "DAY": [
+ "Sonntag",
+ "Montag",
+ "Dienstag",
+ "Mittwoch",
+ "Donnerstag",
+ "Freitag",
+ "Samstag"
+ ],
+ "MONTH": [
+ "Januar",
+ "Februar",
+ "M\u00e4rz",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "August",
+ "September",
+ "Oktober",
+ "November",
+ "Dezember"
+ ],
+ "SHORTDAY": [
+ "So.",
+ "Mo.",
+ "Di.",
+ "Mi.",
+ "Do.",
+ "Fr.",
+ "Sa."
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "M\u00e4r",
+ "Apr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dez"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "de-li",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-lu.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-lu.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de-lu.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "vorm.",
- "1": "nachm."
- },
- "DAY": {
- "0": "Sonntag",
- "1": "Montag",
- "2": "Dienstag",
- "3": "Mittwoch",
- "4": "Donnerstag",
- "5": "Freitag",
- "6": "Samstag"
- },
- "MONTH": {
- "0": "Januar",
- "1": "Februar",
- "2": "M\u00e4rz",
- "3": "April",
- "4": "Mai",
- "5": "Juni",
- "6": "Juli",
- "7": "August",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Dezember"
- },
- "SHORTDAY": {
- "0": "So.",
- "1": "Mo.",
- "2": "Di.",
- "3": "Mi.",
- "4": "Do.",
- "5": "Fr.",
- "6": "Sa."
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "M\u00e4r",
- "3": "Apr",
- "4": "Mai",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dez"
- },
+ "AMPMS": [
+ "vorm.",
+ "nachm."
+ ],
+ "DAY": [
+ "Sonntag",
+ "Montag",
+ "Dienstag",
+ "Mittwoch",
+ "Donnerstag",
+ "Freitag",
+ "Samstag"
+ ],
+ "MONTH": [
+ "Januar",
+ "Februar",
+ "M\u00e4rz",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "August",
+ "September",
+ "Oktober",
+ "November",
+ "Dezember"
+ ],
+ "SHORTDAY": [
+ "So.",
+ "Mo.",
+ "Di.",
+ "Mi.",
+ "Do.",
+ "Fr.",
+ "Sa."
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "M\u00e4r",
+ "Apr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dez"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "de-lu",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_de.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "vorm.",
- "1": "nachm."
- },
- "DAY": {
- "0": "Sonntag",
- "1": "Montag",
- "2": "Dienstag",
- "3": "Mittwoch",
- "4": "Donnerstag",
- "5": "Freitag",
- "6": "Samstag"
- },
- "MONTH": {
- "0": "Januar",
- "1": "Februar",
- "2": "M\u00e4rz",
- "3": "April",
- "4": "Mai",
- "5": "Juni",
- "6": "Juli",
- "7": "August",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Dezember"
- },
- "SHORTDAY": {
- "0": "So.",
- "1": "Mo.",
- "2": "Di.",
- "3": "Mi.",
- "4": "Do.",
- "5": "Fr.",
- "6": "Sa."
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "M\u00e4r",
- "3": "Apr",
- "4": "Mai",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dez"
- },
+ "AMPMS": [
+ "vorm.",
+ "nachm."
+ ],
+ "DAY": [
+ "Sonntag",
+ "Montag",
+ "Dienstag",
+ "Mittwoch",
+ "Donnerstag",
+ "Freitag",
+ "Samstag"
+ ],
+ "MONTH": [
+ "Januar",
+ "Februar",
+ "M\u00e4rz",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "August",
+ "September",
+ "Oktober",
+ "November",
+ "Dezember"
+ ],
+ "SHORTDAY": [
+ "So.",
+ "Mo.",
+ "Di.",
+ "Mi.",
+ "Do.",
+ "Fr.",
+ "Sa."
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "M\u00e4r",
+ "Apr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dez"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "de",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-cy.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-cy.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-cy.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u03c0.\u03bc.",
- "1": "\u03bc.\u03bc."
- },
- "DAY": {
- "0": "\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae",
- "1": "\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1",
- "2": "\u03a4\u03c1\u03af\u03c4\u03b7",
- "3": "\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7",
- "4": "\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7",
- "5": "\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae",
- "6": "\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf"
- },
- "MONTH": {
- "0": "\u0399\u03b1\u03bd\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5",
- "1": "\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5",
- "2": "\u039c\u03b1\u03c1\u03c4\u03af\u03bf\u03c5",
- "3": "\u0391\u03c0\u03c1\u03b9\u03bb\u03af\u03bf\u03c5",
- "4": "\u039c\u03b1\u0390\u03bf\u03c5",
- "5": "\u0399\u03bf\u03c5\u03bd\u03af\u03bf\u03c5",
- "6": "\u0399\u03bf\u03c5\u03bb\u03af\u03bf\u03c5",
- "7": "\u0391\u03c5\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5",
- "8": "\u03a3\u03b5\u03c0\u03c4\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5",
- "9": "\u039f\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5",
- "10": "\u039d\u03bf\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5",
- "11": "\u0394\u03b5\u03ba\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5"
- },
- "SHORTDAY": {
- "0": "\u039a\u03c5\u03c1",
- "1": "\u0394\u03b5\u03c5",
- "2": "\u03a4\u03c1\u03b9",
- "3": "\u03a4\u03b5\u03c4",
- "4": "\u03a0\u03b5\u03bc",
- "5": "\u03a0\u03b1\u03c1",
- "6": "\u03a3\u03b1\u03b2"
- },
- "SHORTMONTH": {
- "0": "\u0399\u03b1\u03bd",
- "1": "\u03a6\u03b5\u03b2",
- "2": "\u039c\u03b1\u03c1",
- "3": "\u0391\u03c0\u03c1",
- "4": "\u039c\u03b1\u03ca",
- "5": "\u0399\u03bf\u03c5\u03bd",
- "6": "\u0399\u03bf\u03c5\u03bb",
- "7": "\u0391\u03c5\u03b3",
- "8": "\u03a3\u03b5\u03c0",
- "9": "\u039f\u03ba\u03c4",
- "10": "\u039d\u03bf\u03b5",
- "11": "\u0394\u03b5\u03ba"
- },
+ "AMPMS": [
+ "\u03c0.\u03bc.",
+ "\u03bc.\u03bc."
+ ],
+ "DAY": [
+ "\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae",
+ "\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1",
+ "\u03a4\u03c1\u03af\u03c4\u03b7",
+ "\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7",
+ "\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7",
+ "\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae",
+ "\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf"
+ ],
+ "MONTH": [
+ "\u0399\u03b1\u03bd\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5",
+ "\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5",
+ "\u039c\u03b1\u03c1\u03c4\u03af\u03bf\u03c5",
+ "\u0391\u03c0\u03c1\u03b9\u03bb\u03af\u03bf\u03c5",
+ "\u039c\u03b1\u0390\u03bf\u03c5",
+ "\u0399\u03bf\u03c5\u03bd\u03af\u03bf\u03c5",
+ "\u0399\u03bf\u03c5\u03bb\u03af\u03bf\u03c5",
+ "\u0391\u03c5\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5",
+ "\u03a3\u03b5\u03c0\u03c4\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5",
+ "\u039f\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5",
+ "\u039d\u03bf\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5",
+ "\u0394\u03b5\u03ba\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5"
+ ],
+ "SHORTDAY": [
+ "\u039a\u03c5\u03c1",
+ "\u0394\u03b5\u03c5",
+ "\u03a4\u03c1\u03b9",
+ "\u03a4\u03b5\u03c4",
+ "\u03a0\u03b5\u03bc",
+ "\u03a0\u03b1\u03c1",
+ "\u03a3\u03b1\u03b2"
+ ],
+ "SHORTMONTH": [
+ "\u0399\u03b1\u03bd",
+ "\u03a6\u03b5\u03b2",
+ "\u039c\u03b1\u03c1",
+ "\u0391\u03c0\u03c1",
+ "\u039c\u03b1\u03ca",
+ "\u0399\u03bf\u03c5\u03bd",
+ "\u0399\u03bf\u03c5\u03bb",
+ "\u0391\u03c5\u03b3",
+ "\u03a3\u03b5\u03c0",
+ "\u039f\u03ba\u03c4",
+ "\u039d\u03bf\u03b5",
+ "\u0394\u03b5\u03ba"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "el-cy",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-gr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-gr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el-gr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u03c0.\u03bc.",
- "1": "\u03bc.\u03bc."
- },
- "DAY": {
- "0": "\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae",
- "1": "\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1",
- "2": "\u03a4\u03c1\u03af\u03c4\u03b7",
- "3": "\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7",
- "4": "\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7",
- "5": "\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae",
- "6": "\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf"
- },
- "MONTH": {
- "0": "\u0399\u03b1\u03bd\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5",
- "1": "\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5",
- "2": "\u039c\u03b1\u03c1\u03c4\u03af\u03bf\u03c5",
- "3": "\u0391\u03c0\u03c1\u03b9\u03bb\u03af\u03bf\u03c5",
- "4": "\u039c\u03b1\u0390\u03bf\u03c5",
- "5": "\u0399\u03bf\u03c5\u03bd\u03af\u03bf\u03c5",
- "6": "\u0399\u03bf\u03c5\u03bb\u03af\u03bf\u03c5",
- "7": "\u0391\u03c5\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5",
- "8": "\u03a3\u03b5\u03c0\u03c4\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5",
- "9": "\u039f\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5",
- "10": "\u039d\u03bf\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5",
- "11": "\u0394\u03b5\u03ba\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5"
- },
- "SHORTDAY": {
- "0": "\u039a\u03c5\u03c1",
- "1": "\u0394\u03b5\u03c5",
- "2": "\u03a4\u03c1\u03b9",
- "3": "\u03a4\u03b5\u03c4",
- "4": "\u03a0\u03b5\u03bc",
- "5": "\u03a0\u03b1\u03c1",
- "6": "\u03a3\u03b1\u03b2"
- },
- "SHORTMONTH": {
- "0": "\u0399\u03b1\u03bd",
- "1": "\u03a6\u03b5\u03b2",
- "2": "\u039c\u03b1\u03c1",
- "3": "\u0391\u03c0\u03c1",
- "4": "\u039c\u03b1\u03ca",
- "5": "\u0399\u03bf\u03c5\u03bd",
- "6": "\u0399\u03bf\u03c5\u03bb",
- "7": "\u0391\u03c5\u03b3",
- "8": "\u03a3\u03b5\u03c0",
- "9": "\u039f\u03ba\u03c4",
- "10": "\u039d\u03bf\u03b5",
- "11": "\u0394\u03b5\u03ba"
- },
+ "AMPMS": [
+ "\u03c0.\u03bc.",
+ "\u03bc.\u03bc."
+ ],
+ "DAY": [
+ "\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae",
+ "\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1",
+ "\u03a4\u03c1\u03af\u03c4\u03b7",
+ "\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7",
+ "\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7",
+ "\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae",
+ "\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf"
+ ],
+ "MONTH": [
+ "\u0399\u03b1\u03bd\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5",
+ "\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5",
+ "\u039c\u03b1\u03c1\u03c4\u03af\u03bf\u03c5",
+ "\u0391\u03c0\u03c1\u03b9\u03bb\u03af\u03bf\u03c5",
+ "\u039c\u03b1\u0390\u03bf\u03c5",
+ "\u0399\u03bf\u03c5\u03bd\u03af\u03bf\u03c5",
+ "\u0399\u03bf\u03c5\u03bb\u03af\u03bf\u03c5",
+ "\u0391\u03c5\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5",
+ "\u03a3\u03b5\u03c0\u03c4\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5",
+ "\u039f\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5",
+ "\u039d\u03bf\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5",
+ "\u0394\u03b5\u03ba\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5"
+ ],
+ "SHORTDAY": [
+ "\u039a\u03c5\u03c1",
+ "\u0394\u03b5\u03c5",
+ "\u03a4\u03c1\u03b9",
+ "\u03a4\u03b5\u03c4",
+ "\u03a0\u03b5\u03bc",
+ "\u03a0\u03b1\u03c1",
+ "\u03a3\u03b1\u03b2"
+ ],
+ "SHORTMONTH": [
+ "\u0399\u03b1\u03bd",
+ "\u03a6\u03b5\u03b2",
+ "\u039c\u03b1\u03c1",
+ "\u0391\u03c0\u03c1",
+ "\u039c\u03b1\u03ca",
+ "\u0399\u03bf\u03c5\u03bd",
+ "\u0399\u03bf\u03c5\u03bb",
+ "\u0391\u03c5\u03b3",
+ "\u03a3\u03b5\u03c0",
+ "\u039f\u03ba\u03c4",
+ "\u039d\u03bf\u03b5",
+ "\u0394\u03b5\u03ba"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "el-gr",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_el.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u03c0.\u03bc.",
- "1": "\u03bc.\u03bc."
- },
- "DAY": {
- "0": "\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae",
- "1": "\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1",
- "2": "\u03a4\u03c1\u03af\u03c4\u03b7",
- "3": "\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7",
- "4": "\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7",
- "5": "\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae",
- "6": "\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf"
- },
- "MONTH": {
- "0": "\u0399\u03b1\u03bd\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5",
- "1": "\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5",
- "2": "\u039c\u03b1\u03c1\u03c4\u03af\u03bf\u03c5",
- "3": "\u0391\u03c0\u03c1\u03b9\u03bb\u03af\u03bf\u03c5",
- "4": "\u039c\u03b1\u0390\u03bf\u03c5",
- "5": "\u0399\u03bf\u03c5\u03bd\u03af\u03bf\u03c5",
- "6": "\u0399\u03bf\u03c5\u03bb\u03af\u03bf\u03c5",
- "7": "\u0391\u03c5\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5",
- "8": "\u03a3\u03b5\u03c0\u03c4\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5",
- "9": "\u039f\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5",
- "10": "\u039d\u03bf\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5",
- "11": "\u0394\u03b5\u03ba\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5"
- },
- "SHORTDAY": {
- "0": "\u039a\u03c5\u03c1",
- "1": "\u0394\u03b5\u03c5",
- "2": "\u03a4\u03c1\u03b9",
- "3": "\u03a4\u03b5\u03c4",
- "4": "\u03a0\u03b5\u03bc",
- "5": "\u03a0\u03b1\u03c1",
- "6": "\u03a3\u03b1\u03b2"
- },
- "SHORTMONTH": {
- "0": "\u0399\u03b1\u03bd",
- "1": "\u03a6\u03b5\u03b2",
- "2": "\u039c\u03b1\u03c1",
- "3": "\u0391\u03c0\u03c1",
- "4": "\u039c\u03b1\u03ca",
- "5": "\u0399\u03bf\u03c5\u03bd",
- "6": "\u0399\u03bf\u03c5\u03bb",
- "7": "\u0391\u03c5\u03b3",
- "8": "\u03a3\u03b5\u03c0",
- "9": "\u039f\u03ba\u03c4",
- "10": "\u039d\u03bf\u03b5",
- "11": "\u0394\u03b5\u03ba"
- },
+ "AMPMS": [
+ "\u03c0.\u03bc.",
+ "\u03bc.\u03bc."
+ ],
+ "DAY": [
+ "\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae",
+ "\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1",
+ "\u03a4\u03c1\u03af\u03c4\u03b7",
+ "\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7",
+ "\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7",
+ "\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae",
+ "\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf"
+ ],
+ "MONTH": [
+ "\u0399\u03b1\u03bd\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5",
+ "\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5",
+ "\u039c\u03b1\u03c1\u03c4\u03af\u03bf\u03c5",
+ "\u0391\u03c0\u03c1\u03b9\u03bb\u03af\u03bf\u03c5",
+ "\u039c\u03b1\u0390\u03bf\u03c5",
+ "\u0399\u03bf\u03c5\u03bd\u03af\u03bf\u03c5",
+ "\u0399\u03bf\u03c5\u03bb\u03af\u03bf\u03c5",
+ "\u0391\u03c5\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5",
+ "\u03a3\u03b5\u03c0\u03c4\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5",
+ "\u039f\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5",
+ "\u039d\u03bf\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5",
+ "\u0394\u03b5\u03ba\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5"
+ ],
+ "SHORTDAY": [
+ "\u039a\u03c5\u03c1",
+ "\u0394\u03b5\u03c5",
+ "\u03a4\u03c1\u03b9",
+ "\u03a4\u03b5\u03c4",
+ "\u03a0\u03b5\u03bc",
+ "\u03a0\u03b1\u03c1",
+ "\u03a3\u03b1\u03b2"
+ ],
+ "SHORTMONTH": [
+ "\u0399\u03b1\u03bd",
+ "\u03a6\u03b5\u03b2",
+ "\u039c\u03b1\u03c1",
+ "\u0391\u03c0\u03c1",
+ "\u039c\u03b1\u03ca",
+ "\u0399\u03bf\u03c5\u03bd",
+ "\u0399\u03bf\u03c5\u03bb",
+ "\u0391\u03c5\u03b3",
+ "\u03a3\u03b5\u03c0",
+ "\u039f\u03ba\u03c4",
+ "\u039d\u03bf\u03b5",
+ "\u0394\u03b5\u03ba"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "el",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-as.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-as.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-as.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-as",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-au.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-au.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-au.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "dd/MM/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-au",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bb.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bb.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bb.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-bb",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-be.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-be.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-be.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMM y",
"medium": "dd MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-be",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bm.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bm.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bm.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-bm",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bw.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bw.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE dd MMMM y",
"longDate": "dd MMMM y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-bw",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bz.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bz.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-bz.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "dd MMMM y",
"longDate": "dd MMMM y",
"medium": "dd-MMM-y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-bz",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ca.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ca.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ca.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, d MMMM, y",
"longDate": "d MMMM, y",
"medium": "yyyy-MM-dd h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-ca",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt-us.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt-us.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt-us.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\ud801\udc08\ud801\udc23",
- "1": "\ud801\udc11\ud801\udc23"
- },
- "DAY": {
- "0": "\ud801\udc1d\ud801\udc32\ud801\udc4c\ud801\udc3c\ud801\udc29",
- "1": "\ud801\udc23\ud801\udc32\ud801\udc4c\ud801\udc3c\ud801\udc29",
- "2": "\ud801\udc13\ud801\udc2d\ud801\udc46\ud801\udc3c\ud801\udc29",
- "3": "\ud801\udc0e\ud801\udc2f\ud801\udc4c\ud801\udc46\ud801\udc3c\ud801\udc29",
- "4": "\ud801\udc1b\ud801\udc32\ud801\udc49\ud801\udc46\ud801\udc3c\ud801\udc29",
- "5": "\ud801\udc19\ud801\udc49\ud801\udc34\ud801\udc3c\ud801\udc29",
- "6": "\ud801\udc1d\ud801\udc30\ud801\udc3b\ud801\udc32\ud801\udc49\ud801\udc3c\ud801\udc29"
- },
- "MONTH": {
- "0": "\ud801\udc16\ud801\udc30\ud801\udc4c\ud801\udc37\ud801\udc2d\ud801\udc2f\ud801\udc49\ud801\udc28",
- "1": "\ud801\udc19\ud801\udc2f\ud801\udc3a\ud801\udc49\ud801\udc2d\ud801\udc2f\ud801\udc49\ud801\udc28",
- "2": "\ud801\udc23\ud801\udc2a\ud801\udc49\ud801\udc3d",
- "3": "\ud801\udc01\ud801\udc39\ud801\udc49\ud801\udc2e\ud801\udc4a",
- "4": "\ud801\udc23\ud801\udc29",
- "5": "\ud801\udc16\ud801\udc2d\ud801\udc4c",
- "6": "\ud801\udc16\ud801\udc2d\ud801\udc4a\ud801\udc34",
- "7": "\ud801\udc02\ud801\udc40\ud801\udc32\ud801\udc45\ud801\udc3b",
- "8": "\ud801\udc1d\ud801\udc2f\ud801\udc39\ud801\udc3b\ud801\udc2f\ud801\udc4b\ud801\udc3a\ud801\udc32\ud801\udc49",
- "9": "\ud801\udc09\ud801\udc3f\ud801\udc3b\ud801\udc2c\ud801\udc3a\ud801\udc32\ud801\udc49",
- "10": "\ud801\udc24\ud801\udc2c\ud801\udc42\ud801\udc2f\ud801\udc4b\ud801\udc3a\ud801\udc32\ud801\udc49",
- "11": "\ud801\udc14\ud801\udc28\ud801\udc45\ud801\udc2f\ud801\udc4b\ud801\udc3a\ud801\udc32\ud801\udc49"
- },
- "SHORTDAY": {
- "0": "\ud801\udc1d\ud801\udc32\ud801\udc4c",
- "1": "\ud801\udc23\ud801\udc32\ud801\udc4c",
- "2": "\ud801\udc13\ud801\udc2d\ud801\udc46",
- "3": "\ud801\udc0e\ud801\udc2f\ud801\udc4c",
- "4": "\ud801\udc1b\ud801\udc32\ud801\udc49",
- "5": "\ud801\udc19\ud801\udc49\ud801\udc34",
- "6": "\ud801\udc1d\ud801\udc30\ud801\udc3b"
- },
- "SHORTMONTH": {
- "0": "\ud801\udc16\ud801\udc30\ud801\udc4c",
- "1": "\ud801\udc19\ud801\udc2f\ud801\udc3a",
- "2": "\ud801\udc23\ud801\udc2a\ud801\udc49",
- "3": "\ud801\udc01\ud801\udc39\ud801\udc49",
- "4": "\ud801\udc23\ud801\udc29",
- "5": "\ud801\udc16\ud801\udc2d\ud801\udc4c",
- "6": "\ud801\udc16\ud801\udc2d\ud801\udc4a",
- "7": "\ud801\udc02\ud801\udc40",
- "8": "\ud801\udc1d\ud801\udc2f\ud801\udc39",
- "9": "\ud801\udc09\ud801\udc3f\ud801\udc3b",
- "10": "\ud801\udc24\ud801\udc2c\ud801\udc42",
- "11": "\ud801\udc14\ud801\udc28\ud801\udc45"
- },
+ "AMPMS": [
+ "\ud801\udc08\ud801\udc23",
+ "\ud801\udc11\ud801\udc23"
+ ],
+ "DAY": [
+ "\ud801\udc1d\ud801\udc32\ud801\udc4c\ud801\udc3c\ud801\udc29",
+ "\ud801\udc23\ud801\udc32\ud801\udc4c\ud801\udc3c\ud801\udc29",
+ "\ud801\udc13\ud801\udc2d\ud801\udc46\ud801\udc3c\ud801\udc29",
+ "\ud801\udc0e\ud801\udc2f\ud801\udc4c\ud801\udc46\ud801\udc3c\ud801\udc29",
+ "\ud801\udc1b\ud801\udc32\ud801\udc49\ud801\udc46\ud801\udc3c\ud801\udc29",
+ "\ud801\udc19\ud801\udc49\ud801\udc34\ud801\udc3c\ud801\udc29",
+ "\ud801\udc1d\ud801\udc30\ud801\udc3b\ud801\udc32\ud801\udc49\ud801\udc3c\ud801\udc29"
+ ],
+ "MONTH": [
+ "\ud801\udc16\ud801\udc30\ud801\udc4c\ud801\udc37\ud801\udc2d\ud801\udc2f\ud801\udc49\ud801\udc28",
+ "\ud801\udc19\ud801\udc2f\ud801\udc3a\ud801\udc49\ud801\udc2d\ud801\udc2f\ud801\udc49\ud801\udc28",
+ "\ud801\udc23\ud801\udc2a\ud801\udc49\ud801\udc3d",
+ "\ud801\udc01\ud801\udc39\ud801\udc49\ud801\udc2e\ud801\udc4a",
+ "\ud801\udc23\ud801\udc29",
+ "\ud801\udc16\ud801\udc2d\ud801\udc4c",
+ "\ud801\udc16\ud801\udc2d\ud801\udc4a\ud801\udc34",
+ "\ud801\udc02\ud801\udc40\ud801\udc32\ud801\udc45\ud801\udc3b",
+ "\ud801\udc1d\ud801\udc2f\ud801\udc39\ud801\udc3b\ud801\udc2f\ud801\udc4b\ud801\udc3a\ud801\udc32\ud801\udc49",
+ "\ud801\udc09\ud801\udc3f\ud801\udc3b\ud801\udc2c\ud801\udc3a\ud801\udc32\ud801\udc49",
+ "\ud801\udc24\ud801\udc2c\ud801\udc42\ud801\udc2f\ud801\udc4b\ud801\udc3a\ud801\udc32\ud801\udc49",
+ "\ud801\udc14\ud801\udc28\ud801\udc45\ud801\udc2f\ud801\udc4b\ud801\udc3a\ud801\udc32\ud801\udc49"
+ ],
+ "SHORTDAY": [
+ "\ud801\udc1d\ud801\udc32\ud801\udc4c",
+ "\ud801\udc23\ud801\udc32\ud801\udc4c",
+ "\ud801\udc13\ud801\udc2d\ud801\udc46",
+ "\ud801\udc0e\ud801\udc2f\ud801\udc4c",
+ "\ud801\udc1b\ud801\udc32\ud801\udc49",
+ "\ud801\udc19\ud801\udc49\ud801\udc34",
+ "\ud801\udc1d\ud801\udc30\ud801\udc3b"
+ ],
+ "SHORTMONTH": [
+ "\ud801\udc16\ud801\udc30\ud801\udc4c",
+ "\ud801\udc19\ud801\udc2f\ud801\udc3a",
+ "\ud801\udc23\ud801\udc2a\ud801\udc49",
+ "\ud801\udc01\ud801\udc39\ud801\udc49",
+ "\ud801\udc23\ud801\udc29",
+ "\ud801\udc16\ud801\udc2d\ud801\udc4c",
+ "\ud801\udc16\ud801\udc2d\ud801\udc4a",
+ "\ud801\udc02\ud801\udc40",
+ "\ud801\udc1d\ud801\udc2f\ud801\udc39",
+ "\ud801\udc09\ud801\udc3f\ud801\udc3b",
+ "\ud801\udc24\ud801\udc2c\ud801\udc42",
+ "\ud801\udc14\ud801\udc28\ud801\udc45"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-dsrt-us",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-dsrt.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\ud801\udc08\ud801\udc23",
- "1": "\ud801\udc11\ud801\udc23"
- },
- "DAY": {
- "0": "\ud801\udc1d\ud801\udc32\ud801\udc4c\ud801\udc3c\ud801\udc29",
- "1": "\ud801\udc23\ud801\udc32\ud801\udc4c\ud801\udc3c\ud801\udc29",
- "2": "\ud801\udc13\ud801\udc2d\ud801\udc46\ud801\udc3c\ud801\udc29",
- "3": "\ud801\udc0e\ud801\udc2f\ud801\udc4c\ud801\udc46\ud801\udc3c\ud801\udc29",
- "4": "\ud801\udc1b\ud801\udc32\ud801\udc49\ud801\udc46\ud801\udc3c\ud801\udc29",
- "5": "\ud801\udc19\ud801\udc49\ud801\udc34\ud801\udc3c\ud801\udc29",
- "6": "\ud801\udc1d\ud801\udc30\ud801\udc3b\ud801\udc32\ud801\udc49\ud801\udc3c\ud801\udc29"
- },
- "MONTH": {
- "0": "\ud801\udc16\ud801\udc30\ud801\udc4c\ud801\udc37\ud801\udc2d\ud801\udc2f\ud801\udc49\ud801\udc28",
- "1": "\ud801\udc19\ud801\udc2f\ud801\udc3a\ud801\udc49\ud801\udc2d\ud801\udc2f\ud801\udc49\ud801\udc28",
- "2": "\ud801\udc23\ud801\udc2a\ud801\udc49\ud801\udc3d",
- "3": "\ud801\udc01\ud801\udc39\ud801\udc49\ud801\udc2e\ud801\udc4a",
- "4": "\ud801\udc23\ud801\udc29",
- "5": "\ud801\udc16\ud801\udc2d\ud801\udc4c",
- "6": "\ud801\udc16\ud801\udc2d\ud801\udc4a\ud801\udc34",
- "7": "\ud801\udc02\ud801\udc40\ud801\udc32\ud801\udc45\ud801\udc3b",
- "8": "\ud801\udc1d\ud801\udc2f\ud801\udc39\ud801\udc3b\ud801\udc2f\ud801\udc4b\ud801\udc3a\ud801\udc32\ud801\udc49",
- "9": "\ud801\udc09\ud801\udc3f\ud801\udc3b\ud801\udc2c\ud801\udc3a\ud801\udc32\ud801\udc49",
- "10": "\ud801\udc24\ud801\udc2c\ud801\udc42\ud801\udc2f\ud801\udc4b\ud801\udc3a\ud801\udc32\ud801\udc49",
- "11": "\ud801\udc14\ud801\udc28\ud801\udc45\ud801\udc2f\ud801\udc4b\ud801\udc3a\ud801\udc32\ud801\udc49"
- },
- "SHORTDAY": {
- "0": "\ud801\udc1d\ud801\udc32\ud801\udc4c",
- "1": "\ud801\udc23\ud801\udc32\ud801\udc4c",
- "2": "\ud801\udc13\ud801\udc2d\ud801\udc46",
- "3": "\ud801\udc0e\ud801\udc2f\ud801\udc4c",
- "4": "\ud801\udc1b\ud801\udc32\ud801\udc49",
- "5": "\ud801\udc19\ud801\udc49\ud801\udc34",
- "6": "\ud801\udc1d\ud801\udc30\ud801\udc3b"
- },
- "SHORTMONTH": {
- "0": "\ud801\udc16\ud801\udc30\ud801\udc4c",
- "1": "\ud801\udc19\ud801\udc2f\ud801\udc3a",
- "2": "\ud801\udc23\ud801\udc2a\ud801\udc49",
- "3": "\ud801\udc01\ud801\udc39\ud801\udc49",
- "4": "\ud801\udc23\ud801\udc29",
- "5": "\ud801\udc16\ud801\udc2d\ud801\udc4c",
- "6": "\ud801\udc16\ud801\udc2d\ud801\udc4a",
- "7": "\ud801\udc02\ud801\udc40",
- "8": "\ud801\udc1d\ud801\udc2f\ud801\udc39",
- "9": "\ud801\udc09\ud801\udc3f\ud801\udc3b",
- "10": "\ud801\udc24\ud801\udc2c\ud801\udc42",
- "11": "\ud801\udc14\ud801\udc28\ud801\udc45"
- },
+ "AMPMS": [
+ "\ud801\udc08\ud801\udc23",
+ "\ud801\udc11\ud801\udc23"
+ ],
+ "DAY": [
+ "\ud801\udc1d\ud801\udc32\ud801\udc4c\ud801\udc3c\ud801\udc29",
+ "\ud801\udc23\ud801\udc32\ud801\udc4c\ud801\udc3c\ud801\udc29",
+ "\ud801\udc13\ud801\udc2d\ud801\udc46\ud801\udc3c\ud801\udc29",
+ "\ud801\udc0e\ud801\udc2f\ud801\udc4c\ud801\udc46\ud801\udc3c\ud801\udc29",
+ "\ud801\udc1b\ud801\udc32\ud801\udc49\ud801\udc46\ud801\udc3c\ud801\udc29",
+ "\ud801\udc19\ud801\udc49\ud801\udc34\ud801\udc3c\ud801\udc29",
+ "\ud801\udc1d\ud801\udc30\ud801\udc3b\ud801\udc32\ud801\udc49\ud801\udc3c\ud801\udc29"
+ ],
+ "MONTH": [
+ "\ud801\udc16\ud801\udc30\ud801\udc4c\ud801\udc37\ud801\udc2d\ud801\udc2f\ud801\udc49\ud801\udc28",
+ "\ud801\udc19\ud801\udc2f\ud801\udc3a\ud801\udc49\ud801\udc2d\ud801\udc2f\ud801\udc49\ud801\udc28",
+ "\ud801\udc23\ud801\udc2a\ud801\udc49\ud801\udc3d",
+ "\ud801\udc01\ud801\udc39\ud801\udc49\ud801\udc2e\ud801\udc4a",
+ "\ud801\udc23\ud801\udc29",
+ "\ud801\udc16\ud801\udc2d\ud801\udc4c",
+ "\ud801\udc16\ud801\udc2d\ud801\udc4a\ud801\udc34",
+ "\ud801\udc02\ud801\udc40\ud801\udc32\ud801\udc45\ud801\udc3b",
+ "\ud801\udc1d\ud801\udc2f\ud801\udc39\ud801\udc3b\ud801\udc2f\ud801\udc4b\ud801\udc3a\ud801\udc32\ud801\udc49",
+ "\ud801\udc09\ud801\udc3f\ud801\udc3b\ud801\udc2c\ud801\udc3a\ud801\udc32\ud801\udc49",
+ "\ud801\udc24\ud801\udc2c\ud801\udc42\ud801\udc2f\ud801\udc4b\ud801\udc3a\ud801\udc32\ud801\udc49",
+ "\ud801\udc14\ud801\udc28\ud801\udc45\ud801\udc2f\ud801\udc4b\ud801\udc3a\ud801\udc32\ud801\udc49"
+ ],
+ "SHORTDAY": [
+ "\ud801\udc1d\ud801\udc32\ud801\udc4c",
+ "\ud801\udc23\ud801\udc32\ud801\udc4c",
+ "\ud801\udc13\ud801\udc2d\ud801\udc46",
+ "\ud801\udc0e\ud801\udc2f\ud801\udc4c",
+ "\ud801\udc1b\ud801\udc32\ud801\udc49",
+ "\ud801\udc19\ud801\udc49\ud801\udc34",
+ "\ud801\udc1d\ud801\udc30\ud801\udc3b"
+ ],
+ "SHORTMONTH": [
+ "\ud801\udc16\ud801\udc30\ud801\udc4c",
+ "\ud801\udc19\ud801\udc2f\ud801\udc3a",
+ "\ud801\udc23\ud801\udc2a\ud801\udc49",
+ "\ud801\udc01\ud801\udc39\ud801\udc49",
+ "\ud801\udc23\ud801\udc29",
+ "\ud801\udc16\ud801\udc2d\ud801\udc4c",
+ "\ud801\udc16\ud801\udc2d\ud801\udc4a",
+ "\ud801\udc02\ud801\udc40",
+ "\ud801\udc1d\ud801\udc2f\ud801\udc39",
+ "\ud801\udc09\ud801\udc3f\ud801\udc3b",
+ "\ud801\udc24\ud801\udc2c\ud801\udc42",
+ "\ud801\udc14\ud801\udc28\ud801\udc45"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-dsrt",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-fm.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-fm.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-fm.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-fm",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gb.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gb.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gb.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a3",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-gb",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gu.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gu.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gu.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-gu",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gy.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gy.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-gy.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-gy",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-hk.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-hk.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-hk.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, d MMMM, y",
"longDate": "d MMMM, y",
"medium": "d MMM, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-hk",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ie.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ie.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ie.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-ie",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-in.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-in.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-in.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "dd-MMM-y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "en-in",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-iso.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-iso.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-iso.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, y MMMM dd",
"longDate": "y MMMM d",
"medium": "y MMM d HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-iso",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-jm.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-jm.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-jm.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-jm",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mh.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mh.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mh.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-mh",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mp.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mp.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mp.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-mp",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mt.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mt.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mt.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "dd MMMM y",
"medium": "dd MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-mt",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mu.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mu.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-mu.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-mu",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-na.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-na.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-na.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-na",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-nz.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-nz.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-nz.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d/MM/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-nz",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ph.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ph.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-ph.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-ph",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pk.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pk.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pk.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "dd-MMM-y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-pk",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-pr",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pw.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-pw.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-pw",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-sg.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-sg.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-sg.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, d MMMM, y",
"longDate": "d MMMM, y",
"medium": "d MMM, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-sg",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tc.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tc.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tc.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-tc",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tt.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tt.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-tt.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-tt",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-um.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-um.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-um.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-um",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-us.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-us.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-us.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-us",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vg.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vg.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vg.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-vg",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vi.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vi.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-vi.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-vi",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-za.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-za.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-za.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE dd MMMM y",
"longDate": "dd MMMM y",
"medium": "dd MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "R",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-za",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-zw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-zw.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en-zw.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE dd MMMM y",
"longDate": "dd MMMM y",
"medium": "dd MMM,y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en-zw",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_en.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- },
- "MONTH": {
- "0": "January",
- "1": "February",
- "2": "March",
- "3": "April",
- "4": "May",
- "5": "June",
- "6": "July",
- "7": "August",
- "8": "September",
- "9": "October",
- "10": "November",
- "11": "December"
- },
- "SHORTDAY": {
- "0": "Sun",
- "1": "Mon",
- "2": "Tue",
- "3": "Wed",
- "4": "Thu",
- "5": "Fri",
- "6": "Sat"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "May",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Oct",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday"
+ ],
+ "MONTH": [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+ ],
+ "SHORTDAY": [
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE, MMMM d, y",
"longDate": "MMMM d, y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "en",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-419.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-419.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-419.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "es-419",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ar.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ar.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ar.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-ar",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-bo.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-bo.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-bo.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-bo",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cl.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cl.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cl.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd-MM-yyyy H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-cl",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-co.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-co.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-co.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "d/MM/yyyy H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-co",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-cr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-cr",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-do.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-do.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-do.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-do",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ea.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ea.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ea.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-ea",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ec.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ec.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ec.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-ec",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-es.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-es.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-es.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-es",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gq.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gq.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gq.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-gq",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gt.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gt.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-gt.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "d/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-gt",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-hn.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-hn.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-hn.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE dd 'de' MMMM 'de' y",
"longDate": "dd 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-hn",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ic.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ic.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ic.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-ic",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-mx.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-mx.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-mx.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-mx",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ni.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ni.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ni.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-ni",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pa.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pa.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pa.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "MM/dd/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-pa",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pe.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pe.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pe.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-pe",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-pr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "MM/dd/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-pr",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-py.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-py.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-py.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-py",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-sv.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-sv.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-sv.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-sv",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-us.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-us.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-us.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "MMM d, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-us",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-uy.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-uy.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-uy.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-uy",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ve.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ve.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es-ve.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es-ve",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_es.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "domingo",
- "1": "lunes",
- "2": "martes",
- "3": "mi\u00e9rcoles",
- "4": "jueves",
- "5": "viernes",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "enero",
- "1": "febrero",
- "2": "marzo",
- "3": "abril",
- "4": "mayo",
- "5": "junio",
- "6": "julio",
- "7": "agosto",
- "8": "septiembre",
- "9": "octubre",
- "10": "noviembre",
- "11": "diciembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mi\u00e9",
- "4": "jue",
- "5": "vie",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "ene",
- "1": "feb",
- "2": "mar",
- "3": "abr",
- "4": "may",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "sep",
- "9": "oct",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "domingo",
+ "lunes",
+ "martes",
+ "mi\u00e9rcoles",
+ "jueves",
+ "viernes",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "enero",
+ "febrero",
+ "marzo",
+ "abril",
+ "mayo",
+ "junio",
+ "julio",
+ "agosto",
+ "septiembre",
+ "octubre",
+ "noviembre",
+ "diciembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mi\u00e9",
+ "jue",
+ "vie",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "ene",
+ "feb",
+ "mar",
+ "abr",
+ "may",
+ "jun",
+ "jul",
+ "ago",
+ "sep",
+ "oct",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "es",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et-ee.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et-ee.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et-ee.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "enne keskp\u00e4eva",
- "1": "p\u00e4rast keskp\u00e4eva"
- },
- "DAY": {
- "0": "p\u00fchap\u00e4ev",
- "1": "esmasp\u00e4ev",
- "2": "teisip\u00e4ev",
- "3": "kolmap\u00e4ev",
- "4": "neljap\u00e4ev",
- "5": "reede",
- "6": "laup\u00e4ev"
- },
- "MONTH": {
- "0": "jaanuar",
- "1": "veebruar",
- "2": "m\u00e4rts",
- "3": "aprill",
- "4": "mai",
- "5": "juuni",
- "6": "juuli",
- "7": "august",
- "8": "september",
- "9": "oktoober",
- "10": "november",
- "11": "detsember"
- },
- "SHORTDAY": {
- "0": "P",
- "1": "E",
- "2": "T",
- "3": "K",
- "4": "N",
- "5": "R",
- "6": "L"
- },
- "SHORTMONTH": {
- "0": "jaan",
- "1": "veebr",
- "2": "m\u00e4rts",
- "3": "apr",
- "4": "mai",
- "5": "juuni",
- "6": "juuli",
- "7": "aug",
- "8": "sept",
- "9": "okt",
- "10": "nov",
- "11": "dets"
- },
+ "AMPMS": [
+ "enne keskp\u00e4eva",
+ "p\u00e4rast keskp\u00e4eva"
+ ],
+ "DAY": [
+ "p\u00fchap\u00e4ev",
+ "esmasp\u00e4ev",
+ "teisip\u00e4ev",
+ "kolmap\u00e4ev",
+ "neljap\u00e4ev",
+ "reede",
+ "laup\u00e4ev"
+ ],
+ "MONTH": [
+ "jaanuar",
+ "veebruar",
+ "m\u00e4rts",
+ "aprill",
+ "mai",
+ "juuni",
+ "juuli",
+ "august",
+ "september",
+ "oktoober",
+ "november",
+ "detsember"
+ ],
+ "SHORTDAY": [
+ "P",
+ "E",
+ "T",
+ "K",
+ "N",
+ "R",
+ "L"
+ ],
+ "SHORTMONTH": [
+ "jaan",
+ "veebr",
+ "m\u00e4rts",
+ "apr",
+ "mai",
+ "juuni",
+ "juuli",
+ "aug",
+ "sept",
+ "okt",
+ "nov",
+ "dets"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "dd.MM.yyyy H:mm.ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a4"
}
- }
+ ]
},
"id": "et-ee",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_et.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "enne keskp\u00e4eva",
- "1": "p\u00e4rast keskp\u00e4eva"
- },
- "DAY": {
- "0": "p\u00fchap\u00e4ev",
- "1": "esmasp\u00e4ev",
- "2": "teisip\u00e4ev",
- "3": "kolmap\u00e4ev",
- "4": "neljap\u00e4ev",
- "5": "reede",
- "6": "laup\u00e4ev"
- },
- "MONTH": {
- "0": "jaanuar",
- "1": "veebruar",
- "2": "m\u00e4rts",
- "3": "aprill",
- "4": "mai",
- "5": "juuni",
- "6": "juuli",
- "7": "august",
- "8": "september",
- "9": "oktoober",
- "10": "november",
- "11": "detsember"
- },
- "SHORTDAY": {
- "0": "P",
- "1": "E",
- "2": "T",
- "3": "K",
- "4": "N",
- "5": "R",
- "6": "L"
- },
- "SHORTMONTH": {
- "0": "jaan",
- "1": "veebr",
- "2": "m\u00e4rts",
- "3": "apr",
- "4": "mai",
- "5": "juuni",
- "6": "juuli",
- "7": "aug",
- "8": "sept",
- "9": "okt",
- "10": "nov",
- "11": "dets"
- },
+ "AMPMS": [
+ "enne keskp\u00e4eva",
+ "p\u00e4rast keskp\u00e4eva"
+ ],
+ "DAY": [
+ "p\u00fchap\u00e4ev",
+ "esmasp\u00e4ev",
+ "teisip\u00e4ev",
+ "kolmap\u00e4ev",
+ "neljap\u00e4ev",
+ "reede",
+ "laup\u00e4ev"
+ ],
+ "MONTH": [
+ "jaanuar",
+ "veebruar",
+ "m\u00e4rts",
+ "aprill",
+ "mai",
+ "juuni",
+ "juuli",
+ "august",
+ "september",
+ "oktoober",
+ "november",
+ "detsember"
+ ],
+ "SHORTDAY": [
+ "P",
+ "E",
+ "T",
+ "K",
+ "N",
+ "R",
+ "L"
+ ],
+ "SHORTMONTH": [
+ "jaan",
+ "veebr",
+ "m\u00e4rts",
+ "apr",
+ "mai",
+ "juuni",
+ "juuli",
+ "aug",
+ "sept",
+ "okt",
+ "nov",
+ "dets"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "dd.MM.yyyy H:mm.ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 0,
"lgSize": 0,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a4"
}
- }
+ ]
},
"id": "et",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu-es.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu-es.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu-es.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "igandea",
- "1": "astelehena",
- "2": "asteartea",
- "3": "asteazkena",
- "4": "osteguna",
- "5": "ostirala",
- "6": "larunbata"
- },
- "MONTH": {
- "0": "urtarrila",
- "1": "otsaila",
- "2": "martxoa",
- "3": "apirila",
- "4": "maiatza",
- "5": "ekaina",
- "6": "uztaila",
- "7": "abuztua",
- "8": "iraila",
- "9": "urria",
- "10": "azaroa",
- "11": "abendua"
- },
- "SHORTDAY": {
- "0": "ig",
- "1": "al",
- "2": "as",
- "3": "az",
- "4": "og",
- "5": "or",
- "6": "lr"
- },
- "SHORTMONTH": {
- "0": "urt",
- "1": "ots",
- "2": "mar",
- "3": "api",
- "4": "mai",
- "5": "eka",
- "6": "uzt",
- "7": "abu",
- "8": "ira",
- "9": "urr",
- "10": "aza",
- "11": "abe"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "igandea",
+ "astelehena",
+ "asteartea",
+ "asteazkena",
+ "osteguna",
+ "ostirala",
+ "larunbata"
+ ],
+ "MONTH": [
+ "urtarrila",
+ "otsaila",
+ "martxoa",
+ "apirila",
+ "maiatza",
+ "ekaina",
+ "uztaila",
+ "abuztua",
+ "iraila",
+ "urria",
+ "azaroa",
+ "abendua"
+ ],
+ "SHORTDAY": [
+ "ig",
+ "al",
+ "as",
+ "az",
+ "og",
+ "or",
+ "lr"
+ ],
+ "SHORTMONTH": [
+ "urt",
+ "ots",
+ "mar",
+ "api",
+ "mai",
+ "eka",
+ "uzt",
+ "abu",
+ "ira",
+ "urr",
+ "aza",
+ "abe"
+ ],
"fullDate": "EEEE, y'eko' MMMM'ren' dd'a'",
"longDate": "y'eko' MMM'ren' dd'a'",
"medium": "y MMM d HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "eu-es",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_eu.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "igandea",
- "1": "astelehena",
- "2": "asteartea",
- "3": "asteazkena",
- "4": "osteguna",
- "5": "ostirala",
- "6": "larunbata"
- },
- "MONTH": {
- "0": "urtarrila",
- "1": "otsaila",
- "2": "martxoa",
- "3": "apirila",
- "4": "maiatza",
- "5": "ekaina",
- "6": "uztaila",
- "7": "abuztua",
- "8": "iraila",
- "9": "urria",
- "10": "azaroa",
- "11": "abendua"
- },
- "SHORTDAY": {
- "0": "ig",
- "1": "al",
- "2": "as",
- "3": "az",
- "4": "og",
- "5": "or",
- "6": "lr"
- },
- "SHORTMONTH": {
- "0": "urt",
- "1": "ots",
- "2": "mar",
- "3": "api",
- "4": "mai",
- "5": "eka",
- "6": "uzt",
- "7": "abu",
- "8": "ira",
- "9": "urr",
- "10": "aza",
- "11": "abe"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "igandea",
+ "astelehena",
+ "asteartea",
+ "asteazkena",
+ "osteguna",
+ "ostirala",
+ "larunbata"
+ ],
+ "MONTH": [
+ "urtarrila",
+ "otsaila",
+ "martxoa",
+ "apirila",
+ "maiatza",
+ "ekaina",
+ "uztaila",
+ "abuztua",
+ "iraila",
+ "urria",
+ "azaroa",
+ "abendua"
+ ],
+ "SHORTDAY": [
+ "ig",
+ "al",
+ "as",
+ "az",
+ "og",
+ "or",
+ "lr"
+ ],
+ "SHORTMONTH": [
+ "urt",
+ "ots",
+ "mar",
+ "api",
+ "mai",
+ "eka",
+ "uzt",
+ "abu",
+ "ira",
+ "urr",
+ "aza",
+ "abe"
+ ],
"fullDate": "EEEE, y'eko' MMMM'ren' dd'a'",
"longDate": "y'eko' MMM'ren' dd'a'",
"medium": "y MMM d HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "eu",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-af.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-af.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-af.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0642\u0628\u0644\u200c\u0627\u0632\u0638\u0647\u0631",
- "1": "\u0628\u0639\u062f\u0627\u0632\u0638\u0647\u0631"
- },
- "DAY": {
- "0": "\u06cc\u06a9\u0634\u0646\u0628\u0647",
- "1": "\u062f\u0648\u0634\u0646\u0628\u0647",
- "2": "\u0633\u0647\u200c\u0634\u0646\u0628\u0647",
- "3": "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647",
- "4": "\u067e\u0646\u062c\u0634\u0646\u0628\u0647",
- "5": "\u062c\u0645\u0639\u0647",
- "6": "\u0634\u0646\u0628\u0647"
- },
- "MONTH": {
- "0": "\u062c\u0646\u0648\u0631\u06cc",
- "1": "\u0641\u0628\u0631\u0648\u0631\u06cc",
- "2": "\u0645\u0627\u0631\u0686",
- "3": "\u0627\u067e\u0631\u06cc\u0644",
- "4": "\u0645\u06cc",
- "5": "\u062c\u0648\u0646",
- "6": "\u062c\u0648\u0644\u0627\u06cc",
- "7": "\u0627\u06af\u0633\u062a",
- "8": "\u0633\u067e\u062a\u0645\u0628\u0631",
- "9": "\u0627\u06a9\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0645\u0628\u0631",
- "11": "\u062f\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u06cc\u06a9\u0634\u0646\u0628\u0647",
- "1": "\u062f\u0648\u0634\u0646\u0628\u0647",
- "2": "\u0633\u0647\u200c\u0634\u0646\u0628\u0647",
- "3": "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647",
- "4": "\u067e\u0646\u062c\u0634\u0646\u0628\u0647",
- "5": "\u062c\u0645\u0639\u0647",
- "6": "\u0634\u0646\u0628\u0647"
- },
- "SHORTMONTH": {
- "0": "\u062c\u0646\u0648",
- "1": "\u0641\u0648\u0631\u06cc\u0647\u0654",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0622\u0648\u0631\u06cc\u0644",
- "4": "\u0645\u0640\u06cc",
- "5": "\u0698\u0648\u0626\u0646",
- "6": "\u062c\u0648\u0644",
- "7": "\u0627\u0648\u062a",
- "8": "\u0633\u067e\u062a\u0627\u0645\u0628\u0631",
- "9": "\u0627\u06a9\u062a\u0628\u0631",
- "10": "\u0646\u0648\u0627\u0645\u0628\u0631",
- "11": "\u062f\u0633\u0645"
- },
+ "AMPMS": [
+ "\u0642\u0628\u0644\u200c\u0627\u0632\u0638\u0647\u0631",
+ "\u0628\u0639\u062f\u0627\u0632\u0638\u0647\u0631"
+ ],
+ "DAY": [
+ "\u06cc\u06a9\u0634\u0646\u0628\u0647",
+ "\u062f\u0648\u0634\u0646\u0628\u0647",
+ "\u0633\u0647\u200c\u0634\u0646\u0628\u0647",
+ "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647",
+ "\u067e\u0646\u062c\u0634\u0646\u0628\u0647",
+ "\u062c\u0645\u0639\u0647",
+ "\u0634\u0646\u0628\u0647"
+ ],
+ "MONTH": [
+ "\u062c\u0646\u0648\u0631\u06cc",
+ "\u0641\u0628\u0631\u0648\u0631\u06cc",
+ "\u0645\u0627\u0631\u0686",
+ "\u0627\u067e\u0631\u06cc\u0644",
+ "\u0645\u06cc",
+ "\u062c\u0648\u0646",
+ "\u062c\u0648\u0644\u0627\u06cc",
+ "\u0627\u06af\u0633\u062a",
+ "\u0633\u067e\u062a\u0645\u0628\u0631",
+ "\u0627\u06a9\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0645\u0628\u0631",
+ "\u062f\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u06cc\u06a9\u0634\u0646\u0628\u0647",
+ "\u062f\u0648\u0634\u0646\u0628\u0647",
+ "\u0633\u0647\u200c\u0634\u0646\u0628\u0647",
+ "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647",
+ "\u067e\u0646\u062c\u0634\u0646\u0628\u0647",
+ "\u062c\u0645\u0639\u0647",
+ "\u0634\u0646\u0628\u0647"
+ ],
+ "SHORTMONTH": [
+ "\u062c\u0646\u0648",
+ "\u0641\u0648\u0631\u06cc\u0647\u0654",
+ "\u0645\u0627\u0631\u0633",
+ "\u0622\u0648\u0631\u06cc\u0644",
+ "\u0645\u0640\u06cc",
+ "\u0698\u0648\u0626\u0646",
+ "\u062c\u0648\u0644",
+ "\u0627\u0648\u062a",
+ "\u0633\u067e\u062a\u0627\u0645\u0628\u0631",
+ "\u0627\u06a9\u062a\u0628\u0631",
+ "\u0646\u0648\u0627\u0645\u0628\u0631",
+ "\u062f\u0633\u0645"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Rial",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u200e\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "fa-af",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-ir.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-ir.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa-ir.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0642\u0628\u0644\u200c\u0627\u0632\u0638\u0647\u0631",
- "1": "\u0628\u0639\u062f\u0627\u0632\u0638\u0647\u0631"
- },
- "DAY": {
- "0": "\u06cc\u06a9\u0634\u0646\u0628\u0647",
- "1": "\u062f\u0648\u0634\u0646\u0628\u0647",
- "2": "\u0633\u0647\u200c\u0634\u0646\u0628\u0647",
- "3": "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647",
- "4": "\u067e\u0646\u062c\u0634\u0646\u0628\u0647",
- "5": "\u062c\u0645\u0639\u0647",
- "6": "\u0634\u0646\u0628\u0647"
- },
- "MONTH": {
- "0": "\u0698\u0627\u0646\u0648\u06cc\u0647\u0654",
- "1": "\u0641\u0648\u0631\u06cc\u0647\u0654",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0622\u0648\u0631\u06cc\u0644",
- "4": "\u0645\u0647\u0654",
- "5": "\u0698\u0648\u0626\u0646",
- "6": "\u0698\u0648\u0626\u06cc\u0647\u0654",
- "7": "\u0627\u0648\u062a",
- "8": "\u0633\u067e\u062a\u0627\u0645\u0628\u0631",
- "9": "\u0627\u06a9\u062a\u0628\u0631",
- "10": "\u0646\u0648\u0627\u0645\u0628\u0631",
- "11": "\u062f\u0633\u0627\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u06cc\u06a9\u0634\u0646\u0628\u0647",
- "1": "\u062f\u0648\u0634\u0646\u0628\u0647",
- "2": "\u0633\u0647\u200c\u0634\u0646\u0628\u0647",
- "3": "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647",
- "4": "\u067e\u0646\u062c\u0634\u0646\u0628\u0647",
- "5": "\u062c\u0645\u0639\u0647",
- "6": "\u0634\u0646\u0628\u0647"
- },
- "SHORTMONTH": {
- "0": "\u0698\u0627\u0646\u0648\u06cc\u0647\u0654",
- "1": "\u0641\u0648\u0631\u06cc\u0647\u0654",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0622\u0648\u0631\u06cc\u0644",
- "4": "\u0645\u0647\u0654",
- "5": "\u0698\u0648\u0626\u0646",
- "6": "\u0698\u0648\u0626\u06cc\u0647\u0654",
- "7": "\u0627\u0648\u062a",
- "8": "\u0633\u067e\u062a\u0627\u0645\u0628\u0631",
- "9": "\u0627\u06a9\u062a\u0628\u0631",
- "10": "\u0646\u0648\u0627\u0645\u0628\u0631",
- "11": "\u062f\u0633\u0627\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0642\u0628\u0644\u200c\u0627\u0632\u0638\u0647\u0631",
+ "\u0628\u0639\u062f\u0627\u0632\u0638\u0647\u0631"
+ ],
+ "DAY": [
+ "\u06cc\u06a9\u0634\u0646\u0628\u0647",
+ "\u062f\u0648\u0634\u0646\u0628\u0647",
+ "\u0633\u0647\u200c\u0634\u0646\u0628\u0647",
+ "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647",
+ "\u067e\u0646\u062c\u0634\u0646\u0628\u0647",
+ "\u062c\u0645\u0639\u0647",
+ "\u0634\u0646\u0628\u0647"
+ ],
+ "MONTH": [
+ "\u0698\u0627\u0646\u0648\u06cc\u0647\u0654",
+ "\u0641\u0648\u0631\u06cc\u0647\u0654",
+ "\u0645\u0627\u0631\u0633",
+ "\u0622\u0648\u0631\u06cc\u0644",
+ "\u0645\u0647\u0654",
+ "\u0698\u0648\u0626\u0646",
+ "\u0698\u0648\u0626\u06cc\u0647\u0654",
+ "\u0627\u0648\u062a",
+ "\u0633\u067e\u062a\u0627\u0645\u0628\u0631",
+ "\u0627\u06a9\u062a\u0628\u0631",
+ "\u0646\u0648\u0627\u0645\u0628\u0631",
+ "\u062f\u0633\u0627\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u06cc\u06a9\u0634\u0646\u0628\u0647",
+ "\u062f\u0648\u0634\u0646\u0628\u0647",
+ "\u0633\u0647\u200c\u0634\u0646\u0628\u0647",
+ "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647",
+ "\u067e\u0646\u062c\u0634\u0646\u0628\u0647",
+ "\u062c\u0645\u0639\u0647",
+ "\u0634\u0646\u0628\u0647"
+ ],
+ "SHORTMONTH": [
+ "\u0698\u0627\u0646\u0648\u06cc\u0647\u0654",
+ "\u0641\u0648\u0631\u06cc\u0647\u0654",
+ "\u0645\u0627\u0631\u0633",
+ "\u0622\u0648\u0631\u06cc\u0644",
+ "\u0645\u0647\u0654",
+ "\u0698\u0648\u0626\u0646",
+ "\u0698\u0648\u0626\u06cc\u0647\u0654",
+ "\u0627\u0648\u062a",
+ "\u0633\u067e\u062a\u0627\u0645\u0628\u0631",
+ "\u0627\u06a9\u062a\u0628\u0631",
+ "\u0646\u0648\u0627\u0645\u0628\u0631",
+ "\u062f\u0633\u0627\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Rial",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u200e\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "fa-ir",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fa.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0642\u0628\u0644\u200c\u0627\u0632\u0638\u0647\u0631",
- "1": "\u0628\u0639\u062f\u0627\u0632\u0638\u0647\u0631"
- },
- "DAY": {
- "0": "\u06cc\u06a9\u0634\u0646\u0628\u0647",
- "1": "\u062f\u0648\u0634\u0646\u0628\u0647",
- "2": "\u0633\u0647\u200c\u0634\u0646\u0628\u0647",
- "3": "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647",
- "4": "\u067e\u0646\u062c\u0634\u0646\u0628\u0647",
- "5": "\u062c\u0645\u0639\u0647",
- "6": "\u0634\u0646\u0628\u0647"
- },
- "MONTH": {
- "0": "\u0698\u0627\u0646\u0648\u06cc\u0647\u0654",
- "1": "\u0641\u0648\u0631\u06cc\u0647\u0654",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0622\u0648\u0631\u06cc\u0644",
- "4": "\u0645\u0647\u0654",
- "5": "\u0698\u0648\u0626\u0646",
- "6": "\u0698\u0648\u0626\u06cc\u0647\u0654",
- "7": "\u0627\u0648\u062a",
- "8": "\u0633\u067e\u062a\u0627\u0645\u0628\u0631",
- "9": "\u0627\u06a9\u062a\u0628\u0631",
- "10": "\u0646\u0648\u0627\u0645\u0628\u0631",
- "11": "\u062f\u0633\u0627\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u06cc\u06a9\u0634\u0646\u0628\u0647",
- "1": "\u062f\u0648\u0634\u0646\u0628\u0647",
- "2": "\u0633\u0647\u200c\u0634\u0646\u0628\u0647",
- "3": "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647",
- "4": "\u067e\u0646\u062c\u0634\u0646\u0628\u0647",
- "5": "\u062c\u0645\u0639\u0647",
- "6": "\u0634\u0646\u0628\u0647"
- },
- "SHORTMONTH": {
- "0": "\u0698\u0627\u0646\u0648\u06cc\u0647\u0654",
- "1": "\u0641\u0648\u0631\u06cc\u0647\u0654",
- "2": "\u0645\u0627\u0631\u0633",
- "3": "\u0622\u0648\u0631\u06cc\u0644",
- "4": "\u0645\u0647\u0654",
- "5": "\u0698\u0648\u0626\u0646",
- "6": "\u0698\u0648\u0626\u06cc\u0647\u0654",
- "7": "\u0627\u0648\u062a",
- "8": "\u0633\u067e\u062a\u0627\u0645\u0628\u0631",
- "9": "\u0627\u06a9\u062a\u0628\u0631",
- "10": "\u0646\u0648\u0627\u0645\u0628\u0631",
- "11": "\u062f\u0633\u0627\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u0642\u0628\u0644\u200c\u0627\u0632\u0638\u0647\u0631",
+ "\u0628\u0639\u062f\u0627\u0632\u0638\u0647\u0631"
+ ],
+ "DAY": [
+ "\u06cc\u06a9\u0634\u0646\u0628\u0647",
+ "\u062f\u0648\u0634\u0646\u0628\u0647",
+ "\u0633\u0647\u200c\u0634\u0646\u0628\u0647",
+ "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647",
+ "\u067e\u0646\u062c\u0634\u0646\u0628\u0647",
+ "\u062c\u0645\u0639\u0647",
+ "\u0634\u0646\u0628\u0647"
+ ],
+ "MONTH": [
+ "\u0698\u0627\u0646\u0648\u06cc\u0647\u0654",
+ "\u0641\u0648\u0631\u06cc\u0647\u0654",
+ "\u0645\u0627\u0631\u0633",
+ "\u0622\u0648\u0631\u06cc\u0644",
+ "\u0645\u0647\u0654",
+ "\u0698\u0648\u0626\u0646",
+ "\u0698\u0648\u0626\u06cc\u0647\u0654",
+ "\u0627\u0648\u062a",
+ "\u0633\u067e\u062a\u0627\u0645\u0628\u0631",
+ "\u0627\u06a9\u062a\u0628\u0631",
+ "\u0646\u0648\u0627\u0645\u0628\u0631",
+ "\u062f\u0633\u0627\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u06cc\u06a9\u0634\u0646\u0628\u0647",
+ "\u062f\u0648\u0634\u0646\u0628\u0647",
+ "\u0633\u0647\u200c\u0634\u0646\u0628\u0647",
+ "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647",
+ "\u067e\u0646\u062c\u0634\u0646\u0628\u0647",
+ "\u062c\u0645\u0639\u0647",
+ "\u0634\u0646\u0628\u0647"
+ ],
+ "SHORTMONTH": [
+ "\u0698\u0627\u0646\u0648\u06cc\u0647\u0654",
+ "\u0641\u0648\u0631\u06cc\u0647\u0654",
+ "\u0645\u0627\u0631\u0633",
+ "\u0622\u0648\u0631\u06cc\u0644",
+ "\u0645\u0647\u0654",
+ "\u0698\u0648\u0626\u0646",
+ "\u0698\u0648\u0626\u06cc\u0647\u0654",
+ "\u0627\u0648\u062a",
+ "\u0633\u067e\u062a\u0627\u0645\u0628\u0631",
+ "\u0627\u06a9\u062a\u0628\u0631",
+ "\u0646\u0648\u0627\u0645\u0628\u0631",
+ "\u062f\u0633\u0627\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Rial",
"DECIMAL_SEP": "\u066b",
"GROUP_SEP": "\u066c",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u200e\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "fa",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi-fi.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi-fi.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi-fi.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "ap.",
- "1": "ip."
- },
- "DAY": {
- "0": "sunnuntaina",
- "1": "maanantaina",
- "2": "tiistaina",
- "3": "keskiviikkona",
- "4": "torstaina",
- "5": "perjantaina",
- "6": "lauantaina"
- },
- "MONTH": {
- "0": "tammikuuta",
- "1": "helmikuuta",
- "2": "maaliskuuta",
- "3": "huhtikuuta",
- "4": "toukokuuta",
- "5": "kes\u00e4kuuta",
- "6": "hein\u00e4kuuta",
- "7": "elokuuta",
- "8": "syyskuuta",
- "9": "lokakuuta",
- "10": "marraskuuta",
- "11": "joulukuuta"
- },
- "SHORTDAY": {
- "0": "su",
- "1": "ma",
- "2": "ti",
- "3": "ke",
- "4": "to",
- "5": "pe",
- "6": "la"
- },
- "SHORTMONTH": {
- "0": "tammikuuta",
- "1": "helmikuuta",
- "2": "maaliskuuta",
- "3": "huhtikuuta",
- "4": "toukokuuta",
- "5": "kes\u00e4kuuta",
- "6": "hein\u00e4kuuta",
- "7": "elokuuta",
- "8": "syyskuuta",
- "9": "lokakuuta",
- "10": "marraskuuta",
- "11": "joulukuuta"
- },
+ "AMPMS": [
+ "ap.",
+ "ip."
+ ],
+ "DAY": [
+ "sunnuntaina",
+ "maanantaina",
+ "tiistaina",
+ "keskiviikkona",
+ "torstaina",
+ "perjantaina",
+ "lauantaina"
+ ],
+ "MONTH": [
+ "tammikuuta",
+ "helmikuuta",
+ "maaliskuuta",
+ "huhtikuuta",
+ "toukokuuta",
+ "kes\u00e4kuuta",
+ "hein\u00e4kuuta",
+ "elokuuta",
+ "syyskuuta",
+ "lokakuuta",
+ "marraskuuta",
+ "joulukuuta"
+ ],
+ "SHORTDAY": [
+ "su",
+ "ma",
+ "ti",
+ "ke",
+ "to",
+ "pe",
+ "la"
+ ],
+ "SHORTMONTH": [
+ "tammikuuta",
+ "helmikuuta",
+ "maaliskuuta",
+ "huhtikuuta",
+ "toukokuuta",
+ "kes\u00e4kuuta",
+ "hein\u00e4kuuta",
+ "elokuuta",
+ "syyskuuta",
+ "lokakuuta",
+ "marraskuuta",
+ "joulukuuta"
+ ],
"fullDate": "cccc, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "d.M.yyyy H.mm.ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fi-fi",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fi.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "ap.",
- "1": "ip."
- },
- "DAY": {
- "0": "sunnuntaina",
- "1": "maanantaina",
- "2": "tiistaina",
- "3": "keskiviikkona",
- "4": "torstaina",
- "5": "perjantaina",
- "6": "lauantaina"
- },
- "MONTH": {
- "0": "tammikuuta",
- "1": "helmikuuta",
- "2": "maaliskuuta",
- "3": "huhtikuuta",
- "4": "toukokuuta",
- "5": "kes\u00e4kuuta",
- "6": "hein\u00e4kuuta",
- "7": "elokuuta",
- "8": "syyskuuta",
- "9": "lokakuuta",
- "10": "marraskuuta",
- "11": "joulukuuta"
- },
- "SHORTDAY": {
- "0": "su",
- "1": "ma",
- "2": "ti",
- "3": "ke",
- "4": "to",
- "5": "pe",
- "6": "la"
- },
- "SHORTMONTH": {
- "0": "tammikuuta",
- "1": "helmikuuta",
- "2": "maaliskuuta",
- "3": "huhtikuuta",
- "4": "toukokuuta",
- "5": "kes\u00e4kuuta",
- "6": "hein\u00e4kuuta",
- "7": "elokuuta",
- "8": "syyskuuta",
- "9": "lokakuuta",
- "10": "marraskuuta",
- "11": "joulukuuta"
- },
+ "AMPMS": [
+ "ap.",
+ "ip."
+ ],
+ "DAY": [
+ "sunnuntaina",
+ "maanantaina",
+ "tiistaina",
+ "keskiviikkona",
+ "torstaina",
+ "perjantaina",
+ "lauantaina"
+ ],
+ "MONTH": [
+ "tammikuuta",
+ "helmikuuta",
+ "maaliskuuta",
+ "huhtikuuta",
+ "toukokuuta",
+ "kes\u00e4kuuta",
+ "hein\u00e4kuuta",
+ "elokuuta",
+ "syyskuuta",
+ "lokakuuta",
+ "marraskuuta",
+ "joulukuuta"
+ ],
+ "SHORTDAY": [
+ "su",
+ "ma",
+ "ti",
+ "ke",
+ "to",
+ "pe",
+ "la"
+ ],
+ "SHORTMONTH": [
+ "tammikuuta",
+ "helmikuuta",
+ "maaliskuuta",
+ "huhtikuuta",
+ "toukokuuta",
+ "kes\u00e4kuuta",
+ "hein\u00e4kuuta",
+ "elokuuta",
+ "syyskuuta",
+ "lokakuuta",
+ "marraskuuta",
+ "joulukuuta"
+ ],
"fullDate": "cccc, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "d.M.yyyy H.mm.ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fi",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil-ph.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil-ph.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil-ph.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Linggo",
- "1": "Lunes",
- "2": "Martes",
- "3": "Miyerkules",
- "4": "Huwebes",
- "5": "Biyernes",
- "6": "Sabado"
- },
- "MONTH": {
- "0": "Enero",
- "1": "Pebrero",
- "2": "Marso",
- "3": "Abril",
- "4": "Mayo",
- "5": "Hunyo",
- "6": "Hulyo",
- "7": "Agosto",
- "8": "Setyembre",
- "9": "Oktubre",
- "10": "Nobyembre",
- "11": "Disyembre"
- },
- "SHORTDAY": {
- "0": "Lin",
- "1": "Lun",
- "2": "Mar",
- "3": "Mye",
- "4": "Huw",
- "5": "Bye",
- "6": "Sab"
- },
- "SHORTMONTH": {
- "0": "Ene",
- "1": "Peb",
- "2": "Mar",
- "3": "Abr",
- "4": "May",
- "5": "Hun",
- "6": "Hul",
- "7": "Ago",
- "8": "Set",
- "9": "Okt",
- "10": "Nob",
- "11": "Dis"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Linggo",
+ "Lunes",
+ "Martes",
+ "Miyerkules",
+ "Huwebes",
+ "Biyernes",
+ "Sabado"
+ ],
+ "MONTH": [
+ "Enero",
+ "Pebrero",
+ "Marso",
+ "Abril",
+ "Mayo",
+ "Hunyo",
+ "Hulyo",
+ "Agosto",
+ "Setyembre",
+ "Oktubre",
+ "Nobyembre",
+ "Disyembre"
+ ],
+ "SHORTDAY": [
+ "Lin",
+ "Lun",
+ "Mar",
+ "Mye",
+ "Huw",
+ "Bye",
+ "Sab"
+ ],
+ "SHORTMONTH": [
+ "Ene",
+ "Peb",
+ "Mar",
+ "Abr",
+ "May",
+ "Hun",
+ "Hul",
+ "Ago",
+ "Set",
+ "Okt",
+ "Nob",
+ "Dis"
+ ],
"fullDate": "EEEE, MMMM dd y",
"longDate": "MMMM d, y",
"medium": "MMM d, y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b1",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "fil-ph",
"pluralCat": function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fil.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Linggo",
- "1": "Lunes",
- "2": "Martes",
- "3": "Miyerkules",
- "4": "Huwebes",
- "5": "Biyernes",
- "6": "Sabado"
- },
- "MONTH": {
- "0": "Enero",
- "1": "Pebrero",
- "2": "Marso",
- "3": "Abril",
- "4": "Mayo",
- "5": "Hunyo",
- "6": "Hulyo",
- "7": "Agosto",
- "8": "Setyembre",
- "9": "Oktubre",
- "10": "Nobyembre",
- "11": "Disyembre"
- },
- "SHORTDAY": {
- "0": "Lin",
- "1": "Lun",
- "2": "Mar",
- "3": "Mye",
- "4": "Huw",
- "5": "Bye",
- "6": "Sab"
- },
- "SHORTMONTH": {
- "0": "Ene",
- "1": "Peb",
- "2": "Mar",
- "3": "Abr",
- "4": "May",
- "5": "Hun",
- "6": "Hul",
- "7": "Ago",
- "8": "Set",
- "9": "Okt",
- "10": "Nob",
- "11": "Dis"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Linggo",
+ "Lunes",
+ "Martes",
+ "Miyerkules",
+ "Huwebes",
+ "Biyernes",
+ "Sabado"
+ ],
+ "MONTH": [
+ "Enero",
+ "Pebrero",
+ "Marso",
+ "Abril",
+ "Mayo",
+ "Hunyo",
+ "Hulyo",
+ "Agosto",
+ "Setyembre",
+ "Oktubre",
+ "Nobyembre",
+ "Disyembre"
+ ],
+ "SHORTDAY": [
+ "Lin",
+ "Lun",
+ "Mar",
+ "Mye",
+ "Huw",
+ "Bye",
+ "Sab"
+ ],
+ "SHORTMONTH": [
+ "Ene",
+ "Peb",
+ "Mar",
+ "Abr",
+ "May",
+ "Hun",
+ "Hul",
+ "Ago",
+ "Set",
+ "Okt",
+ "Nob",
+ "Dis"
+ ],
"fullDate": "EEEE, MMMM dd y",
"longDate": "MMMM d, y",
"medium": "MMM d, y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b1",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "fil",
"pluralCat": function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-be.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-be.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-be.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-be",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bf.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bf.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bf.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-bf",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bi.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bi.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bi.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-bi",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bj.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bj.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bj.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-bj",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bl.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bl.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-bl.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-bl",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ca.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ca.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ca.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "yyyy-MM-dd HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-ca",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cd.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cd.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cd.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-cd",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cf.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cf.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cf.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-cf",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cg.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cg.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cg.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-cg",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ch.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ch.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ch.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-ch",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ci.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ci.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ci.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-ci",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cm.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cm.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-cm.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-cm",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-dj.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-dj.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-dj.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-dj",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-fr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-fr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-fr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-fr",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ga.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ga.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ga.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-ga",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gf.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gf.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gf.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-gf",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gn.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gn.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gn.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-gn",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gp.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gp.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gp.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-gp",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gq.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gq.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-gq.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-gq",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-km.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-km.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-km.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-km",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-lu.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-lu.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-lu.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-lu",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mc.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mc.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mc.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-mc",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mf.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mf.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mf.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-mf",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mg.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mg.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mg.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-mg",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ml.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ml.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ml.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-ml",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mq.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mq.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-mq.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-mq",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ne.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ne.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-ne.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-ne",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-re.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-re.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-re.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-re",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-yt.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-yt.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr-yt.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr-yt",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_fr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "dimanche",
- "1": "lundi",
- "2": "mardi",
- "3": "mercredi",
- "4": "jeudi",
- "5": "vendredi",
- "6": "samedi"
- },
- "MONTH": {
- "0": "janvier",
- "1": "f\u00e9vrier",
- "2": "mars",
- "3": "avril",
- "4": "mai",
- "5": "juin",
- "6": "juillet",
- "7": "ao\u00fbt",
- "8": "septembre",
- "9": "octobre",
- "10": "novembre",
- "11": "d\u00e9cembre"
- },
- "SHORTDAY": {
- "0": "dim.",
- "1": "lun.",
- "2": "mar.",
- "3": "mer.",
- "4": "jeu.",
- "5": "ven.",
- "6": "sam."
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "f\u00e9vr.",
- "2": "mars",
- "3": "avr.",
- "4": "mai",
- "5": "juin",
- "6": "juil.",
- "7": "ao\u00fbt",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "d\u00e9c."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "dimanche",
+ "lundi",
+ "mardi",
+ "mercredi",
+ "jeudi",
+ "vendredi",
+ "samedi"
+ ],
+ "MONTH": [
+ "janvier",
+ "f\u00e9vrier",
+ "mars",
+ "avril",
+ "mai",
+ "juin",
+ "juillet",
+ "ao\u00fbt",
+ "septembre",
+ "octobre",
+ "novembre",
+ "d\u00e9cembre"
+ ],
+ "SHORTDAY": [
+ "dim.",
+ "lun.",
+ "mar.",
+ "mer.",
+ "jeu.",
+ "ven.",
+ "sam."
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "f\u00e9vr.",
+ "mars",
+ "avr.",
+ "mai",
+ "juin",
+ "juil.",
+ "ao\u00fbt",
+ "sept.",
+ "oct.",
+ "nov.",
+ "d\u00e9c."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "fr",
"pluralCat": function (n) { if (n >= 0 && n <= 2 && n != 2) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl-es.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl-es.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl-es.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "Domingo",
- "1": "Luns",
- "2": "Martes",
- "3": "M\u00e9rcores",
- "4": "Xoves",
- "5": "Venres",
- "6": "S\u00e1bado"
- },
- "MONTH": {
- "0": "Xaneiro",
- "1": "Febreiro",
- "2": "Marzo",
- "3": "Abril",
- "4": "Maio",
- "5": "Xu\u00f1o",
- "6": "Xullo",
- "7": "Agosto",
- "8": "Setembro",
- "9": "Outubro",
- "10": "Novembro",
- "11": "Decembro"
- },
- "SHORTDAY": {
- "0": "Dom",
- "1": "Lun",
- "2": "Mar",
- "3": "M\u00e9r",
- "4": "Xov",
- "5": "Ven",
- "6": "S\u00e1b"
- },
- "SHORTMONTH": {
- "0": "Xan",
- "1": "Feb",
- "2": "Mar",
- "3": "Abr",
- "4": "Mai",
- "5": "Xu\u00f1",
- "6": "Xul",
- "7": "Ago",
- "8": "Set",
- "9": "Out",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "Domingo",
+ "Luns",
+ "Martes",
+ "M\u00e9rcores",
+ "Xoves",
+ "Venres",
+ "S\u00e1bado"
+ ],
+ "MONTH": [
+ "Xaneiro",
+ "Febreiro",
+ "Marzo",
+ "Abril",
+ "Maio",
+ "Xu\u00f1o",
+ "Xullo",
+ "Agosto",
+ "Setembro",
+ "Outubro",
+ "Novembro",
+ "Decembro"
+ ],
+ "SHORTDAY": [
+ "Dom",
+ "Lun",
+ "Mar",
+ "M\u00e9r",
+ "Xov",
+ "Ven",
+ "S\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "Xan",
+ "Feb",
+ "Mar",
+ "Abr",
+ "Mai",
+ "Xu\u00f1",
+ "Xul",
+ "Ago",
+ "Set",
+ "Out",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE dd MMMM y",
"longDate": "dd MMMM y",
"medium": "d MMM, y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "gl-es",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gl.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "Domingo",
- "1": "Luns",
- "2": "Martes",
- "3": "M\u00e9rcores",
- "4": "Xoves",
- "5": "Venres",
- "6": "S\u00e1bado"
- },
- "MONTH": {
- "0": "Xaneiro",
- "1": "Febreiro",
- "2": "Marzo",
- "3": "Abril",
- "4": "Maio",
- "5": "Xu\u00f1o",
- "6": "Xullo",
- "7": "Agosto",
- "8": "Setembro",
- "9": "Outubro",
- "10": "Novembro",
- "11": "Decembro"
- },
- "SHORTDAY": {
- "0": "Dom",
- "1": "Lun",
- "2": "Mar",
- "3": "M\u00e9r",
- "4": "Xov",
- "5": "Ven",
- "6": "S\u00e1b"
- },
- "SHORTMONTH": {
- "0": "Xan",
- "1": "Feb",
- "2": "Mar",
- "3": "Abr",
- "4": "Mai",
- "5": "Xu\u00f1",
- "6": "Xul",
- "7": "Ago",
- "8": "Set",
- "9": "Out",
- "10": "Nov",
- "11": "Dec"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "Domingo",
+ "Luns",
+ "Martes",
+ "M\u00e9rcores",
+ "Xoves",
+ "Venres",
+ "S\u00e1bado"
+ ],
+ "MONTH": [
+ "Xaneiro",
+ "Febreiro",
+ "Marzo",
+ "Abril",
+ "Maio",
+ "Xu\u00f1o",
+ "Xullo",
+ "Agosto",
+ "Setembro",
+ "Outubro",
+ "Novembro",
+ "Decembro"
+ ],
+ "SHORTDAY": [
+ "Dom",
+ "Lun",
+ "Mar",
+ "M\u00e9r",
+ "Xov",
+ "Ven",
+ "S\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "Xan",
+ "Feb",
+ "Mar",
+ "Abr",
+ "Mai",
+ "Xu\u00f1",
+ "Xul",
+ "Ago",
+ "Set",
+ "Out",
+ "Nov",
+ "Dec"
+ ],
"fullDate": "EEEE dd MMMM y",
"longDate": "dd MMMM y",
"medium": "d MMM, y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "gl",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw-ch.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw-ch.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw-ch.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "vorm.",
- "1": "nam."
- },
- "DAY": {
- "0": "Sunntig",
- "1": "M\u00e4\u00e4ntig",
- "2": "Ziischtig",
- "3": "Mittwuch",
- "4": "Dunschtig",
- "5": "Friitig",
- "6": "Samschtig"
- },
- "MONTH": {
- "0": "Januar",
- "1": "Februar",
- "2": "M\u00e4rz",
- "3": "April",
- "4": "Mai",
- "5": "Juni",
- "6": "Juli",
- "7": "Auguscht",
- "8": "Sept\u00e4mber",
- "9": "Oktoober",
- "10": "Nov\u00e4mber",
- "11": "Dez\u00e4mber"
- },
- "SHORTDAY": {
- "0": "Su.",
- "1": "M\u00e4.",
- "2": "Zi.",
- "3": "Mi.",
- "4": "Du.",
- "5": "Fr.",
- "6": "Sa."
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "M\u00e4r",
- "3": "Apr",
- "4": "Mai",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dez"
- },
+ "AMPMS": [
+ "vorm.",
+ "nam."
+ ],
+ "DAY": [
+ "Sunntig",
+ "M\u00e4\u00e4ntig",
+ "Ziischtig",
+ "Mittwuch",
+ "Dunschtig",
+ "Friitig",
+ "Samschtig"
+ ],
+ "MONTH": [
+ "Januar",
+ "Februar",
+ "M\u00e4rz",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "Auguscht",
+ "Sept\u00e4mber",
+ "Oktoober",
+ "Nov\u00e4mber",
+ "Dez\u00e4mber"
+ ],
+ "SHORTDAY": [
+ "Su.",
+ "M\u00e4.",
+ "Zi.",
+ "Mi.",
+ "Du.",
+ "Fr.",
+ "Sa."
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "M\u00e4r",
+ "Apr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dez"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "CHF",
"DECIMAL_SEP": ".",
"GROUP_SEP": "\u2019",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "gsw-ch",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gsw.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "vorm.",
- "1": "nam."
- },
- "DAY": {
- "0": "Sunntig",
- "1": "M\u00e4\u00e4ntig",
- "2": "Ziischtig",
- "3": "Mittwuch",
- "4": "Dunschtig",
- "5": "Friitig",
- "6": "Samschtig"
- },
- "MONTH": {
- "0": "Januar",
- "1": "Februar",
- "2": "M\u00e4rz",
- "3": "April",
- "4": "Mai",
- "5": "Juni",
- "6": "Juli",
- "7": "Auguscht",
- "8": "Sept\u00e4mber",
- "9": "Oktoober",
- "10": "Nov\u00e4mber",
- "11": "Dez\u00e4mber"
- },
- "SHORTDAY": {
- "0": "Su.",
- "1": "M\u00e4.",
- "2": "Zi.",
- "3": "Mi.",
- "4": "Du.",
- "5": "Fr.",
- "6": "Sa."
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "M\u00e4r",
- "3": "Apr",
- "4": "Mai",
- "5": "Jun",
- "6": "Jul",
- "7": "Aug",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dez"
- },
+ "AMPMS": [
+ "vorm.",
+ "nam."
+ ],
+ "DAY": [
+ "Sunntig",
+ "M\u00e4\u00e4ntig",
+ "Ziischtig",
+ "Mittwuch",
+ "Dunschtig",
+ "Friitig",
+ "Samschtig"
+ ],
+ "MONTH": [
+ "Januar",
+ "Februar",
+ "M\u00e4rz",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "Auguscht",
+ "Sept\u00e4mber",
+ "Oktoober",
+ "Nov\u00e4mber",
+ "Dez\u00e4mber"
+ ],
+ "SHORTDAY": [
+ "Su.",
+ "M\u00e4.",
+ "Zi.",
+ "Mi.",
+ "Du.",
+ "Fr.",
+ "Sa."
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "M\u00e4r",
+ "Apr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dez"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "CHF",
"DECIMAL_SEP": ".",
"GROUP_SEP": "\u2019",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "gsw",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu-in.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu-in.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu-in.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0ab0\u0ab5\u0abf\u0ab5\u0abe\u0ab0",
- "1": "\u0ab8\u0acb\u0aae\u0ab5\u0abe\u0ab0",
- "2": "\u0aae\u0a82\u0a97\u0ab3\u0ab5\u0abe\u0ab0",
- "3": "\u0aac\u0ac1\u0aa7\u0ab5\u0abe\u0ab0",
- "4": "\u0a97\u0ac1\u0ab0\u0ac1\u0ab5\u0abe\u0ab0",
- "5": "\u0ab6\u0ac1\u0a95\u0acd\u0ab0\u0ab5\u0abe\u0ab0",
- "6": "\u0ab6\u0aa8\u0abf\u0ab5\u0abe\u0ab0"
- },
- "MONTH": {
- "0": "\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1\u0a86\u0ab0\u0ac0",
- "1": "\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1\u0a86\u0ab0\u0ac0",
- "2": "\u0aae\u0abe\u0ab0\u0acd\u0a9a",
- "3": "\u0a8f\u0aaa\u0acd\u0ab0\u0abf\u0ab2",
- "4": "\u0aae\u0ac7",
- "5": "\u0a9c\u0ac2\u0aa8",
- "6": "\u0a9c\u0ac1\u0ab2\u0abe\u0a88",
- "7": "\u0a91\u0a97\u0ab8\u0acd\u0a9f",
- "8": "\u0ab8\u0aaa\u0acd\u0a9f\u0ac7\u0aae\u0acd\u0aac\u0ab0",
- "9": "\u0a91\u0a95\u0acd\u0a9f\u0acb\u0aac\u0ab0",
- "10": "\u0aa8\u0ab5\u0ac7\u0aae\u0acd\u0aac\u0ab0",
- "11": "\u0aa1\u0abf\u0ab8\u0ac7\u0aae\u0acd\u0aac\u0ab0"
- },
- "SHORTDAY": {
- "0": "\u0ab0\u0ab5\u0abf",
- "1": "\u0ab8\u0acb\u0aae",
- "2": "\u0aae\u0a82\u0a97\u0ab3",
- "3": "\u0aac\u0ac1\u0aa7",
- "4": "\u0a97\u0ac1\u0ab0\u0ac1",
- "5": "\u0ab6\u0ac1\u0a95\u0acd\u0ab0",
- "6": "\u0ab6\u0aa8\u0abf"
- },
- "SHORTMONTH": {
- "0": "\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1",
- "1": "\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1",
- "2": "\u0aae\u0abe\u0ab0\u0acd\u0a9a",
- "3": "\u0a8f\u0aaa\u0acd\u0ab0\u0abf\u0ab2",
- "4": "\u0aae\u0ac7",
- "5": "\u0a9c\u0ac2\u0aa8",
- "6": "\u0a9c\u0ac1\u0ab2\u0abe\u0a88",
- "7": "\u0a91\u0a97\u0ab8\u0acd\u0a9f",
- "8": "\u0ab8\u0aaa\u0acd\u0a9f\u0ac7",
- "9": "\u0a91\u0a95\u0acd\u0a9f\u0acb",
- "10": "\u0aa8\u0ab5\u0ac7",
- "11": "\u0aa1\u0abf\u0ab8\u0ac7"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0ab0\u0ab5\u0abf\u0ab5\u0abe\u0ab0",
+ "\u0ab8\u0acb\u0aae\u0ab5\u0abe\u0ab0",
+ "\u0aae\u0a82\u0a97\u0ab3\u0ab5\u0abe\u0ab0",
+ "\u0aac\u0ac1\u0aa7\u0ab5\u0abe\u0ab0",
+ "\u0a97\u0ac1\u0ab0\u0ac1\u0ab5\u0abe\u0ab0",
+ "\u0ab6\u0ac1\u0a95\u0acd\u0ab0\u0ab5\u0abe\u0ab0",
+ "\u0ab6\u0aa8\u0abf\u0ab5\u0abe\u0ab0"
+ ],
+ "MONTH": [
+ "\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1\u0a86\u0ab0\u0ac0",
+ "\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1\u0a86\u0ab0\u0ac0",
+ "\u0aae\u0abe\u0ab0\u0acd\u0a9a",
+ "\u0a8f\u0aaa\u0acd\u0ab0\u0abf\u0ab2",
+ "\u0aae\u0ac7",
+ "\u0a9c\u0ac2\u0aa8",
+ "\u0a9c\u0ac1\u0ab2\u0abe\u0a88",
+ "\u0a91\u0a97\u0ab8\u0acd\u0a9f",
+ "\u0ab8\u0aaa\u0acd\u0a9f\u0ac7\u0aae\u0acd\u0aac\u0ab0",
+ "\u0a91\u0a95\u0acd\u0a9f\u0acb\u0aac\u0ab0",
+ "\u0aa8\u0ab5\u0ac7\u0aae\u0acd\u0aac\u0ab0",
+ "\u0aa1\u0abf\u0ab8\u0ac7\u0aae\u0acd\u0aac\u0ab0"
+ ],
+ "SHORTDAY": [
+ "\u0ab0\u0ab5\u0abf",
+ "\u0ab8\u0acb\u0aae",
+ "\u0aae\u0a82\u0a97\u0ab3",
+ "\u0aac\u0ac1\u0aa7",
+ "\u0a97\u0ac1\u0ab0\u0ac1",
+ "\u0ab6\u0ac1\u0a95\u0acd\u0ab0",
+ "\u0ab6\u0aa8\u0abf"
+ ],
+ "SHORTMONTH": [
+ "\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1",
+ "\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1",
+ "\u0aae\u0abe\u0ab0\u0acd\u0a9a",
+ "\u0a8f\u0aaa\u0acd\u0ab0\u0abf\u0ab2",
+ "\u0aae\u0ac7",
+ "\u0a9c\u0ac2\u0aa8",
+ "\u0a9c\u0ac1\u0ab2\u0abe\u0a88",
+ "\u0a91\u0a97\u0ab8\u0acd\u0a9f",
+ "\u0ab8\u0aaa\u0acd\u0a9f\u0ac7",
+ "\u0a91\u0a95\u0acd\u0a9f\u0acb",
+ "\u0aa8\u0ab5\u0ac7",
+ "\u0aa1\u0abf\u0ab8\u0ac7"
+ ],
"fullDate": "EEEE, d MMMM, y",
"longDate": "d MMMM, y",
"medium": "d MMM, y hh:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "gu-in",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_gu.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0ab0\u0ab5\u0abf\u0ab5\u0abe\u0ab0",
- "1": "\u0ab8\u0acb\u0aae\u0ab5\u0abe\u0ab0",
- "2": "\u0aae\u0a82\u0a97\u0ab3\u0ab5\u0abe\u0ab0",
- "3": "\u0aac\u0ac1\u0aa7\u0ab5\u0abe\u0ab0",
- "4": "\u0a97\u0ac1\u0ab0\u0ac1\u0ab5\u0abe\u0ab0",
- "5": "\u0ab6\u0ac1\u0a95\u0acd\u0ab0\u0ab5\u0abe\u0ab0",
- "6": "\u0ab6\u0aa8\u0abf\u0ab5\u0abe\u0ab0"
- },
- "MONTH": {
- "0": "\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1\u0a86\u0ab0\u0ac0",
- "1": "\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1\u0a86\u0ab0\u0ac0",
- "2": "\u0aae\u0abe\u0ab0\u0acd\u0a9a",
- "3": "\u0a8f\u0aaa\u0acd\u0ab0\u0abf\u0ab2",
- "4": "\u0aae\u0ac7",
- "5": "\u0a9c\u0ac2\u0aa8",
- "6": "\u0a9c\u0ac1\u0ab2\u0abe\u0a88",
- "7": "\u0a91\u0a97\u0ab8\u0acd\u0a9f",
- "8": "\u0ab8\u0aaa\u0acd\u0a9f\u0ac7\u0aae\u0acd\u0aac\u0ab0",
- "9": "\u0a91\u0a95\u0acd\u0a9f\u0acb\u0aac\u0ab0",
- "10": "\u0aa8\u0ab5\u0ac7\u0aae\u0acd\u0aac\u0ab0",
- "11": "\u0aa1\u0abf\u0ab8\u0ac7\u0aae\u0acd\u0aac\u0ab0"
- },
- "SHORTDAY": {
- "0": "\u0ab0\u0ab5\u0abf",
- "1": "\u0ab8\u0acb\u0aae",
- "2": "\u0aae\u0a82\u0a97\u0ab3",
- "3": "\u0aac\u0ac1\u0aa7",
- "4": "\u0a97\u0ac1\u0ab0\u0ac1",
- "5": "\u0ab6\u0ac1\u0a95\u0acd\u0ab0",
- "6": "\u0ab6\u0aa8\u0abf"
- },
- "SHORTMONTH": {
- "0": "\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1",
- "1": "\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1",
- "2": "\u0aae\u0abe\u0ab0\u0acd\u0a9a",
- "3": "\u0a8f\u0aaa\u0acd\u0ab0\u0abf\u0ab2",
- "4": "\u0aae\u0ac7",
- "5": "\u0a9c\u0ac2\u0aa8",
- "6": "\u0a9c\u0ac1\u0ab2\u0abe\u0a88",
- "7": "\u0a91\u0a97\u0ab8\u0acd\u0a9f",
- "8": "\u0ab8\u0aaa\u0acd\u0a9f\u0ac7",
- "9": "\u0a91\u0a95\u0acd\u0a9f\u0acb",
- "10": "\u0aa8\u0ab5\u0ac7",
- "11": "\u0aa1\u0abf\u0ab8\u0ac7"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0ab0\u0ab5\u0abf\u0ab5\u0abe\u0ab0",
+ "\u0ab8\u0acb\u0aae\u0ab5\u0abe\u0ab0",
+ "\u0aae\u0a82\u0a97\u0ab3\u0ab5\u0abe\u0ab0",
+ "\u0aac\u0ac1\u0aa7\u0ab5\u0abe\u0ab0",
+ "\u0a97\u0ac1\u0ab0\u0ac1\u0ab5\u0abe\u0ab0",
+ "\u0ab6\u0ac1\u0a95\u0acd\u0ab0\u0ab5\u0abe\u0ab0",
+ "\u0ab6\u0aa8\u0abf\u0ab5\u0abe\u0ab0"
+ ],
+ "MONTH": [
+ "\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1\u0a86\u0ab0\u0ac0",
+ "\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1\u0a86\u0ab0\u0ac0",
+ "\u0aae\u0abe\u0ab0\u0acd\u0a9a",
+ "\u0a8f\u0aaa\u0acd\u0ab0\u0abf\u0ab2",
+ "\u0aae\u0ac7",
+ "\u0a9c\u0ac2\u0aa8",
+ "\u0a9c\u0ac1\u0ab2\u0abe\u0a88",
+ "\u0a91\u0a97\u0ab8\u0acd\u0a9f",
+ "\u0ab8\u0aaa\u0acd\u0a9f\u0ac7\u0aae\u0acd\u0aac\u0ab0",
+ "\u0a91\u0a95\u0acd\u0a9f\u0acb\u0aac\u0ab0",
+ "\u0aa8\u0ab5\u0ac7\u0aae\u0acd\u0aac\u0ab0",
+ "\u0aa1\u0abf\u0ab8\u0ac7\u0aae\u0acd\u0aac\u0ab0"
+ ],
+ "SHORTDAY": [
+ "\u0ab0\u0ab5\u0abf",
+ "\u0ab8\u0acb\u0aae",
+ "\u0aae\u0a82\u0a97\u0ab3",
+ "\u0aac\u0ac1\u0aa7",
+ "\u0a97\u0ac1\u0ab0\u0ac1",
+ "\u0ab6\u0ac1\u0a95\u0acd\u0ab0",
+ "\u0ab6\u0aa8\u0abf"
+ ],
+ "SHORTMONTH": [
+ "\u0a9c\u0abe\u0aa8\u0acd\u0aaf\u0ac1",
+ "\u0aab\u0ac7\u0aac\u0acd\u0ab0\u0ac1",
+ "\u0aae\u0abe\u0ab0\u0acd\u0a9a",
+ "\u0a8f\u0aaa\u0acd\u0ab0\u0abf\u0ab2",
+ "\u0aae\u0ac7",
+ "\u0a9c\u0ac2\u0aa8",
+ "\u0a9c\u0ac1\u0ab2\u0abe\u0a88",
+ "\u0a91\u0a97\u0ab8\u0acd\u0a9f",
+ "\u0ab8\u0aaa\u0acd\u0a9f\u0ac7",
+ "\u0a91\u0a95\u0acd\u0a9f\u0acb",
+ "\u0aa8\u0ab5\u0ac7",
+ "\u0aa1\u0abf\u0ab8\u0ac7"
+ ],
"fullDate": "EEEE, d MMMM, y",
"longDate": "d MMMM, y",
"medium": "d MMM, y hh:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "gu",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he-il.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he-il.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he-il.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u05dc\u05e4\u05e0\u05d4\u05f4\u05e6",
- "1": "\u05d0\u05d7\u05d4\u05f4\u05e6"
- },
- "DAY": {
- "0": "\u05d9\u05d5\u05dd \u05e8\u05d0\u05e9\u05d5\u05df",
- "1": "\u05d9\u05d5\u05dd \u05e9\u05e0\u05d9",
- "2": "\u05d9\u05d5\u05dd \u05e9\u05dc\u05d9\u05e9\u05d9",
- "3": "\u05d9\u05d5\u05dd \u05e8\u05d1\u05d9\u05e2\u05d9",
- "4": "\u05d9\u05d5\u05dd \u05d7\u05de\u05d9\u05e9\u05d9",
- "5": "\u05d9\u05d5\u05dd \u05e9\u05d9\u05e9\u05d9",
- "6": "\u05d9\u05d5\u05dd \u05e9\u05d1\u05ea"
- },
- "MONTH": {
- "0": "\u05d9\u05e0\u05d5\u05d0\u05e8",
- "1": "\u05e4\u05d1\u05e8\u05d5\u05d0\u05e8",
- "2": "\u05de\u05e8\u05e5",
- "3": "\u05d0\u05e4\u05e8\u05d9\u05dc",
- "4": "\u05de\u05d0\u05d9",
- "5": "\u05d9\u05d5\u05e0\u05d9",
- "6": "\u05d9\u05d5\u05dc\u05d9",
- "7": "\u05d0\u05d5\u05d2\u05d5\u05e1\u05d8",
- "8": "\u05e1\u05e4\u05d8\u05de\u05d1\u05e8",
- "9": "\u05d0\u05d5\u05e7\u05d8\u05d5\u05d1\u05e8",
- "10": "\u05e0\u05d5\u05d1\u05de\u05d1\u05e8",
- "11": "\u05d3\u05e6\u05de\u05d1\u05e8"
- },
- "SHORTDAY": {
- "0": "\u05d9\u05d5\u05dd \u05d0\u05f3",
- "1": "\u05d9\u05d5\u05dd \u05d1\u05f3",
- "2": "\u05d9\u05d5\u05dd \u05d2\u05f3",
- "3": "\u05d9\u05d5\u05dd \u05d3\u05f3",
- "4": "\u05d9\u05d5\u05dd \u05d4\u05f3",
- "5": "\u05d9\u05d5\u05dd \u05d5\u05f3",
- "6": "\u05e9\u05d1\u05ea"
- },
- "SHORTMONTH": {
- "0": "\u05d9\u05e0\u05d5",
- "1": "\u05e4\u05d1\u05e8",
- "2": "\u05de\u05e8\u05e5",
- "3": "\u05d0\u05e4\u05e8",
- "4": "\u05de\u05d0\u05d9",
- "5": "\u05d9\u05d5\u05e0",
- "6": "\u05d9\u05d5\u05dc",
- "7": "\u05d0\u05d5\u05d2",
- "8": "\u05e1\u05e4\u05d8",
- "9": "\u05d0\u05d5\u05e7",
- "10": "\u05e0\u05d5\u05d1",
- "11": "\u05d3\u05e6\u05de"
- },
+ "AMPMS": [
+ "\u05dc\u05e4\u05e0\u05d4\u05f4\u05e6",
+ "\u05d0\u05d7\u05d4\u05f4\u05e6"
+ ],
+ "DAY": [
+ "\u05d9\u05d5\u05dd \u05e8\u05d0\u05e9\u05d5\u05df",
+ "\u05d9\u05d5\u05dd \u05e9\u05e0\u05d9",
+ "\u05d9\u05d5\u05dd \u05e9\u05dc\u05d9\u05e9\u05d9",
+ "\u05d9\u05d5\u05dd \u05e8\u05d1\u05d9\u05e2\u05d9",
+ "\u05d9\u05d5\u05dd \u05d7\u05de\u05d9\u05e9\u05d9",
+ "\u05d9\u05d5\u05dd \u05e9\u05d9\u05e9\u05d9",
+ "\u05d9\u05d5\u05dd \u05e9\u05d1\u05ea"
+ ],
+ "MONTH": [
+ "\u05d9\u05e0\u05d5\u05d0\u05e8",
+ "\u05e4\u05d1\u05e8\u05d5\u05d0\u05e8",
+ "\u05de\u05e8\u05e5",
+ "\u05d0\u05e4\u05e8\u05d9\u05dc",
+ "\u05de\u05d0\u05d9",
+ "\u05d9\u05d5\u05e0\u05d9",
+ "\u05d9\u05d5\u05dc\u05d9",
+ "\u05d0\u05d5\u05d2\u05d5\u05e1\u05d8",
+ "\u05e1\u05e4\u05d8\u05de\u05d1\u05e8",
+ "\u05d0\u05d5\u05e7\u05d8\u05d5\u05d1\u05e8",
+ "\u05e0\u05d5\u05d1\u05de\u05d1\u05e8",
+ "\u05d3\u05e6\u05de\u05d1\u05e8"
+ ],
+ "SHORTDAY": [
+ "\u05d9\u05d5\u05dd \u05d0\u05f3",
+ "\u05d9\u05d5\u05dd \u05d1\u05f3",
+ "\u05d9\u05d5\u05dd \u05d2\u05f3",
+ "\u05d9\u05d5\u05dd \u05d3\u05f3",
+ "\u05d9\u05d5\u05dd \u05d4\u05f3",
+ "\u05d9\u05d5\u05dd \u05d5\u05f3",
+ "\u05e9\u05d1\u05ea"
+ ],
+ "SHORTMONTH": [
+ "\u05d9\u05e0\u05d5",
+ "\u05e4\u05d1\u05e8",
+ "\u05de\u05e8\u05e5",
+ "\u05d0\u05e4\u05e8",
+ "\u05de\u05d0\u05d9",
+ "\u05d9\u05d5\u05e0",
+ "\u05d9\u05d5\u05dc",
+ "\u05d0\u05d5\u05d2",
+ "\u05e1\u05e4\u05d8",
+ "\u05d0\u05d5\u05e7",
+ "\u05e0\u05d5\u05d1",
+ "\u05d3\u05e6\u05de"
+ ],
"fullDate": "EEEE, d \u05d1MMMM y",
"longDate": "d \u05d1MMMM y",
"medium": "d \u05d1MMM yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20aa",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "he-il",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_he.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u05dc\u05e4\u05e0\u05d4\u05f4\u05e6",
- "1": "\u05d0\u05d7\u05d4\u05f4\u05e6"
- },
- "DAY": {
- "0": "\u05d9\u05d5\u05dd \u05e8\u05d0\u05e9\u05d5\u05df",
- "1": "\u05d9\u05d5\u05dd \u05e9\u05e0\u05d9",
- "2": "\u05d9\u05d5\u05dd \u05e9\u05dc\u05d9\u05e9\u05d9",
- "3": "\u05d9\u05d5\u05dd \u05e8\u05d1\u05d9\u05e2\u05d9",
- "4": "\u05d9\u05d5\u05dd \u05d7\u05de\u05d9\u05e9\u05d9",
- "5": "\u05d9\u05d5\u05dd \u05e9\u05d9\u05e9\u05d9",
- "6": "\u05d9\u05d5\u05dd \u05e9\u05d1\u05ea"
- },
- "MONTH": {
- "0": "\u05d9\u05e0\u05d5\u05d0\u05e8",
- "1": "\u05e4\u05d1\u05e8\u05d5\u05d0\u05e8",
- "2": "\u05de\u05e8\u05e5",
- "3": "\u05d0\u05e4\u05e8\u05d9\u05dc",
- "4": "\u05de\u05d0\u05d9",
- "5": "\u05d9\u05d5\u05e0\u05d9",
- "6": "\u05d9\u05d5\u05dc\u05d9",
- "7": "\u05d0\u05d5\u05d2\u05d5\u05e1\u05d8",
- "8": "\u05e1\u05e4\u05d8\u05de\u05d1\u05e8",
- "9": "\u05d0\u05d5\u05e7\u05d8\u05d5\u05d1\u05e8",
- "10": "\u05e0\u05d5\u05d1\u05de\u05d1\u05e8",
- "11": "\u05d3\u05e6\u05de\u05d1\u05e8"
- },
- "SHORTDAY": {
- "0": "\u05d9\u05d5\u05dd \u05d0\u05f3",
- "1": "\u05d9\u05d5\u05dd \u05d1\u05f3",
- "2": "\u05d9\u05d5\u05dd \u05d2\u05f3",
- "3": "\u05d9\u05d5\u05dd \u05d3\u05f3",
- "4": "\u05d9\u05d5\u05dd \u05d4\u05f3",
- "5": "\u05d9\u05d5\u05dd \u05d5\u05f3",
- "6": "\u05e9\u05d1\u05ea"
- },
- "SHORTMONTH": {
- "0": "\u05d9\u05e0\u05d5",
- "1": "\u05e4\u05d1\u05e8",
- "2": "\u05de\u05e8\u05e5",
- "3": "\u05d0\u05e4\u05e8",
- "4": "\u05de\u05d0\u05d9",
- "5": "\u05d9\u05d5\u05e0",
- "6": "\u05d9\u05d5\u05dc",
- "7": "\u05d0\u05d5\u05d2",
- "8": "\u05e1\u05e4\u05d8",
- "9": "\u05d0\u05d5\u05e7",
- "10": "\u05e0\u05d5\u05d1",
- "11": "\u05d3\u05e6\u05de"
- },
+ "AMPMS": [
+ "\u05dc\u05e4\u05e0\u05d4\u05f4\u05e6",
+ "\u05d0\u05d7\u05d4\u05f4\u05e6"
+ ],
+ "DAY": [
+ "\u05d9\u05d5\u05dd \u05e8\u05d0\u05e9\u05d5\u05df",
+ "\u05d9\u05d5\u05dd \u05e9\u05e0\u05d9",
+ "\u05d9\u05d5\u05dd \u05e9\u05dc\u05d9\u05e9\u05d9",
+ "\u05d9\u05d5\u05dd \u05e8\u05d1\u05d9\u05e2\u05d9",
+ "\u05d9\u05d5\u05dd \u05d7\u05de\u05d9\u05e9\u05d9",
+ "\u05d9\u05d5\u05dd \u05e9\u05d9\u05e9\u05d9",
+ "\u05d9\u05d5\u05dd \u05e9\u05d1\u05ea"
+ ],
+ "MONTH": [
+ "\u05d9\u05e0\u05d5\u05d0\u05e8",
+ "\u05e4\u05d1\u05e8\u05d5\u05d0\u05e8",
+ "\u05de\u05e8\u05e5",
+ "\u05d0\u05e4\u05e8\u05d9\u05dc",
+ "\u05de\u05d0\u05d9",
+ "\u05d9\u05d5\u05e0\u05d9",
+ "\u05d9\u05d5\u05dc\u05d9",
+ "\u05d0\u05d5\u05d2\u05d5\u05e1\u05d8",
+ "\u05e1\u05e4\u05d8\u05de\u05d1\u05e8",
+ "\u05d0\u05d5\u05e7\u05d8\u05d5\u05d1\u05e8",
+ "\u05e0\u05d5\u05d1\u05de\u05d1\u05e8",
+ "\u05d3\u05e6\u05de\u05d1\u05e8"
+ ],
+ "SHORTDAY": [
+ "\u05d9\u05d5\u05dd \u05d0\u05f3",
+ "\u05d9\u05d5\u05dd \u05d1\u05f3",
+ "\u05d9\u05d5\u05dd \u05d2\u05f3",
+ "\u05d9\u05d5\u05dd \u05d3\u05f3",
+ "\u05d9\u05d5\u05dd \u05d4\u05f3",
+ "\u05d9\u05d5\u05dd \u05d5\u05f3",
+ "\u05e9\u05d1\u05ea"
+ ],
+ "SHORTMONTH": [
+ "\u05d9\u05e0\u05d5",
+ "\u05e4\u05d1\u05e8",
+ "\u05de\u05e8\u05e5",
+ "\u05d0\u05e4\u05e8",
+ "\u05de\u05d0\u05d9",
+ "\u05d9\u05d5\u05e0",
+ "\u05d9\u05d5\u05dc",
+ "\u05d0\u05d5\u05d2",
+ "\u05e1\u05e4\u05d8",
+ "\u05d0\u05d5\u05e7",
+ "\u05e0\u05d5\u05d1",
+ "\u05d3\u05e6\u05de"
+ ],
"fullDate": "EEEE, d \u05d1MMMM y",
"longDate": "d \u05d1MMMM y",
"medium": "d \u05d1MMM yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20aa",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "he",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi-in.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi-in.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi-in.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0930\u0935\u093f\u0935\u093e\u0930",
- "1": "\u0938\u094b\u092e\u0935\u093e\u0930",
- "2": "\u092e\u0902\u0917\u0932\u0935\u093e\u0930",
- "3": "\u092c\u0941\u0927\u0935\u093e\u0930",
- "4": "\u092c\u0943\u0939\u0938\u094d\u092a\u0924\u093f\u0935\u093e\u0930",
- "5": "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930",
- "6": "\u0936\u0928\u093f\u0935\u093e\u0930"
- },
- "MONTH": {
- "0": "\u091c\u0928\u0935\u0930\u0940",
- "1": "\u092b\u0930\u0935\u0930\u0940",
- "2": "\u092e\u093e\u0930\u094d\u091a",
- "3": "\u0905\u092a\u094d\u0930\u0948\u0932",
- "4": "\u092e\u0908",
- "5": "\u091c\u0942\u0928",
- "6": "\u091c\u0941\u0932\u093e\u0908",
- "7": "\u0905\u0917\u0938\u094d\u0924",
- "8": "\u0938\u093f\u0924\u092e\u094d\u092c\u0930",
- "9": "\u0905\u0915\u094d\u0924\u0942\u092c\u0930",
- "10": "\u0928\u0935\u092e\u094d\u092c\u0930",
- "11": "\u0926\u093f\u0938\u092e\u094d\u092c\u0930"
- },
- "SHORTDAY": {
- "0": "\u0930\u0935\u093f.",
- "1": "\u0938\u094b\u092e.",
- "2": "\u092e\u0902\u0917\u0932.",
- "3": "\u092c\u0941\u0927.",
- "4": "\u092c\u0943\u0939.",
- "5": "\u0936\u0941\u0915\u094d\u0930.",
- "6": "\u0936\u0928\u093f."
- },
- "SHORTMONTH": {
- "0": "\u091c\u0928\u0935\u0930\u0940",
- "1": "\u092b\u0930\u0935\u0930\u0940",
- "2": "\u092e\u093e\u0930\u094d\u091a",
- "3": "\u0905\u092a\u094d\u0930\u0948\u0932",
- "4": "\u092e\u0908",
- "5": "\u091c\u0942\u0928",
- "6": "\u091c\u0941\u0932\u093e\u0908",
- "7": "\u0905\u0917\u0938\u094d\u0924",
- "8": "\u0938\u093f\u0924\u092e\u094d\u092c\u0930",
- "9": "\u0905\u0915\u094d\u0924\u0942\u092c\u0930",
- "10": "\u0928\u0935\u092e\u094d\u092c\u0930",
- "11": "\u0926\u093f\u0938\u092e\u094d\u092c\u0930"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0930\u0935\u093f\u0935\u093e\u0930",
+ "\u0938\u094b\u092e\u0935\u093e\u0930",
+ "\u092e\u0902\u0917\u0932\u0935\u093e\u0930",
+ "\u092c\u0941\u0927\u0935\u093e\u0930",
+ "\u092c\u0943\u0939\u0938\u094d\u092a\u0924\u093f\u0935\u093e\u0930",
+ "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930",
+ "\u0936\u0928\u093f\u0935\u093e\u0930"
+ ],
+ "MONTH": [
+ "\u091c\u0928\u0935\u0930\u0940",
+ "\u092b\u0930\u0935\u0930\u0940",
+ "\u092e\u093e\u0930\u094d\u091a",
+ "\u0905\u092a\u094d\u0930\u0948\u0932",
+ "\u092e\u0908",
+ "\u091c\u0942\u0928",
+ "\u091c\u0941\u0932\u093e\u0908",
+ "\u0905\u0917\u0938\u094d\u0924",
+ "\u0938\u093f\u0924\u092e\u094d\u092c\u0930",
+ "\u0905\u0915\u094d\u0924\u0942\u092c\u0930",
+ "\u0928\u0935\u092e\u094d\u092c\u0930",
+ "\u0926\u093f\u0938\u092e\u094d\u092c\u0930"
+ ],
+ "SHORTDAY": [
+ "\u0930\u0935\u093f.",
+ "\u0938\u094b\u092e.",
+ "\u092e\u0902\u0917\u0932.",
+ "\u092c\u0941\u0927.",
+ "\u092c\u0943\u0939.",
+ "\u0936\u0941\u0915\u094d\u0930.",
+ "\u0936\u0928\u093f."
+ ],
+ "SHORTMONTH": [
+ "\u091c\u0928\u0935\u0930\u0940",
+ "\u092b\u0930\u0935\u0930\u0940",
+ "\u092e\u093e\u0930\u094d\u091a",
+ "\u0905\u092a\u094d\u0930\u0948\u0932",
+ "\u092e\u0908",
+ "\u091c\u0942\u0928",
+ "\u091c\u0941\u0932\u093e\u0908",
+ "\u0905\u0917\u0938\u094d\u0924",
+ "\u0938\u093f\u0924\u092e\u094d\u092c\u0930",
+ "\u0905\u0915\u094d\u0924\u0942\u092c\u0930",
+ "\u0928\u0935\u092e\u094d\u092c\u0930",
+ "\u0926\u093f\u0938\u092e\u094d\u092c\u0930"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "dd-MM-yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "hi-in",
"pluralCat": function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hi.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0930\u0935\u093f\u0935\u093e\u0930",
- "1": "\u0938\u094b\u092e\u0935\u093e\u0930",
- "2": "\u092e\u0902\u0917\u0932\u0935\u093e\u0930",
- "3": "\u092c\u0941\u0927\u0935\u093e\u0930",
- "4": "\u092c\u0943\u0939\u0938\u094d\u092a\u0924\u093f\u0935\u093e\u0930",
- "5": "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930",
- "6": "\u0936\u0928\u093f\u0935\u093e\u0930"
- },
- "MONTH": {
- "0": "\u091c\u0928\u0935\u0930\u0940",
- "1": "\u092b\u0930\u0935\u0930\u0940",
- "2": "\u092e\u093e\u0930\u094d\u091a",
- "3": "\u0905\u092a\u094d\u0930\u0948\u0932",
- "4": "\u092e\u0908",
- "5": "\u091c\u0942\u0928",
- "6": "\u091c\u0941\u0932\u093e\u0908",
- "7": "\u0905\u0917\u0938\u094d\u0924",
- "8": "\u0938\u093f\u0924\u092e\u094d\u092c\u0930",
- "9": "\u0905\u0915\u094d\u0924\u0942\u092c\u0930",
- "10": "\u0928\u0935\u092e\u094d\u092c\u0930",
- "11": "\u0926\u093f\u0938\u092e\u094d\u092c\u0930"
- },
- "SHORTDAY": {
- "0": "\u0930\u0935\u093f.",
- "1": "\u0938\u094b\u092e.",
- "2": "\u092e\u0902\u0917\u0932.",
- "3": "\u092c\u0941\u0927.",
- "4": "\u092c\u0943\u0939.",
- "5": "\u0936\u0941\u0915\u094d\u0930.",
- "6": "\u0936\u0928\u093f."
- },
- "SHORTMONTH": {
- "0": "\u091c\u0928\u0935\u0930\u0940",
- "1": "\u092b\u0930\u0935\u0930\u0940",
- "2": "\u092e\u093e\u0930\u094d\u091a",
- "3": "\u0905\u092a\u094d\u0930\u0948\u0932",
- "4": "\u092e\u0908",
- "5": "\u091c\u0942\u0928",
- "6": "\u091c\u0941\u0932\u093e\u0908",
- "7": "\u0905\u0917\u0938\u094d\u0924",
- "8": "\u0938\u093f\u0924\u092e\u094d\u092c\u0930",
- "9": "\u0905\u0915\u094d\u0924\u0942\u092c\u0930",
- "10": "\u0928\u0935\u092e\u094d\u092c\u0930",
- "11": "\u0926\u093f\u0938\u092e\u094d\u092c\u0930"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0930\u0935\u093f\u0935\u093e\u0930",
+ "\u0938\u094b\u092e\u0935\u093e\u0930",
+ "\u092e\u0902\u0917\u0932\u0935\u093e\u0930",
+ "\u092c\u0941\u0927\u0935\u093e\u0930",
+ "\u092c\u0943\u0939\u0938\u094d\u092a\u0924\u093f\u0935\u093e\u0930",
+ "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930",
+ "\u0936\u0928\u093f\u0935\u093e\u0930"
+ ],
+ "MONTH": [
+ "\u091c\u0928\u0935\u0930\u0940",
+ "\u092b\u0930\u0935\u0930\u0940",
+ "\u092e\u093e\u0930\u094d\u091a",
+ "\u0905\u092a\u094d\u0930\u0948\u0932",
+ "\u092e\u0908",
+ "\u091c\u0942\u0928",
+ "\u091c\u0941\u0932\u093e\u0908",
+ "\u0905\u0917\u0938\u094d\u0924",
+ "\u0938\u093f\u0924\u092e\u094d\u092c\u0930",
+ "\u0905\u0915\u094d\u0924\u0942\u092c\u0930",
+ "\u0928\u0935\u092e\u094d\u092c\u0930",
+ "\u0926\u093f\u0938\u092e\u094d\u092c\u0930"
+ ],
+ "SHORTDAY": [
+ "\u0930\u0935\u093f.",
+ "\u0938\u094b\u092e.",
+ "\u092e\u0902\u0917\u0932.",
+ "\u092c\u0941\u0927.",
+ "\u092c\u0943\u0939.",
+ "\u0936\u0941\u0915\u094d\u0930.",
+ "\u0936\u0928\u093f."
+ ],
+ "SHORTMONTH": [
+ "\u091c\u0928\u0935\u0930\u0940",
+ "\u092b\u0930\u0935\u0930\u0940",
+ "\u092e\u093e\u0930\u094d\u091a",
+ "\u0905\u092a\u094d\u0930\u0948\u0932",
+ "\u092e\u0908",
+ "\u091c\u0942\u0928",
+ "\u091c\u0941\u0932\u093e\u0908",
+ "\u0905\u0917\u0938\u094d\u0924",
+ "\u0938\u093f\u0924\u092e\u094d\u092c\u0930",
+ "\u0905\u0915\u094d\u0924\u0942\u092c\u0930",
+ "\u0928\u0935\u092e\u094d\u092c\u0930",
+ "\u0926\u093f\u0938\u092e\u094d\u092c\u0930"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "dd-MM-yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "hi",
"pluralCat": function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr-hr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr-hr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr-hr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "nedjelja",
- "1": "ponedjeljak",
- "2": "utorak",
- "3": "srijeda",
- "4": "\u010detvrtak",
- "5": "petak",
- "6": "subota"
- },
- "MONTH": {
- "0": "sije\u010dnja",
- "1": "velja\u010de",
- "2": "o\u017eujka",
- "3": "travnja",
- "4": "svibnja",
- "5": "lipnja",
- "6": "srpnja",
- "7": "kolovoza",
- "8": "rujna",
- "9": "listopada",
- "10": "studenoga",
- "11": "prosinca"
- },
- "SHORTDAY": {
- "0": "ned",
- "1": "pon",
- "2": "uto",
- "3": "sri",
- "4": "\u010det",
- "5": "pet",
- "6": "sub"
- },
- "SHORTMONTH": {
- "0": "sij",
- "1": "velj",
- "2": "o\u017eu",
- "3": "tra",
- "4": "svi",
- "5": "lip",
- "6": "srp",
- "7": "kol",
- "8": "ruj",
- "9": "lis",
- "10": "stu",
- "11": "pro"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "nedjelja",
+ "ponedjeljak",
+ "utorak",
+ "srijeda",
+ "\u010detvrtak",
+ "petak",
+ "subota"
+ ],
+ "MONTH": [
+ "sije\u010dnja",
+ "velja\u010de",
+ "o\u017eujka",
+ "travnja",
+ "svibnja",
+ "lipnja",
+ "srpnja",
+ "kolovoza",
+ "rujna",
+ "listopada",
+ "studenoga",
+ "prosinca"
+ ],
+ "SHORTDAY": [
+ "ned",
+ "pon",
+ "uto",
+ "sri",
+ "\u010det",
+ "pet",
+ "sub"
+ ],
+ "SHORTMONTH": [
+ "sij",
+ "velj",
+ "o\u017eu",
+ "tra",
+ "svi",
+ "lip",
+ "srp",
+ "kol",
+ "ruj",
+ "lis",
+ "stu",
+ "pro"
+ ],
"fullDate": "EEEE, d. MMMM y.",
"longDate": "d. MMMM y.",
"medium": "d. M. y. HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "kn",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "hr-hr",
"pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "nedjelja",
- "1": "ponedjeljak",
- "2": "utorak",
- "3": "srijeda",
- "4": "\u010detvrtak",
- "5": "petak",
- "6": "subota"
- },
- "MONTH": {
- "0": "sije\u010dnja",
- "1": "velja\u010de",
- "2": "o\u017eujka",
- "3": "travnja",
- "4": "svibnja",
- "5": "lipnja",
- "6": "srpnja",
- "7": "kolovoza",
- "8": "rujna",
- "9": "listopada",
- "10": "studenoga",
- "11": "prosinca"
- },
- "SHORTDAY": {
- "0": "ned",
- "1": "pon",
- "2": "uto",
- "3": "sri",
- "4": "\u010det",
- "5": "pet",
- "6": "sub"
- },
- "SHORTMONTH": {
- "0": "sij",
- "1": "velj",
- "2": "o\u017eu",
- "3": "tra",
- "4": "svi",
- "5": "lip",
- "6": "srp",
- "7": "kol",
- "8": "ruj",
- "9": "lis",
- "10": "stu",
- "11": "pro"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "nedjelja",
+ "ponedjeljak",
+ "utorak",
+ "srijeda",
+ "\u010detvrtak",
+ "petak",
+ "subota"
+ ],
+ "MONTH": [
+ "sije\u010dnja",
+ "velja\u010de",
+ "o\u017eujka",
+ "travnja",
+ "svibnja",
+ "lipnja",
+ "srpnja",
+ "kolovoza",
+ "rujna",
+ "listopada",
+ "studenoga",
+ "prosinca"
+ ],
+ "SHORTDAY": [
+ "ned",
+ "pon",
+ "uto",
+ "sri",
+ "\u010det",
+ "pet",
+ "sub"
+ ],
+ "SHORTMONTH": [
+ "sij",
+ "velj",
+ "o\u017eu",
+ "tra",
+ "svi",
+ "lip",
+ "srp",
+ "kol",
+ "ruj",
+ "lis",
+ "stu",
+ "pro"
+ ],
"fullDate": "EEEE, d. MMMM y.",
"longDate": "d. MMMM y.",
"medium": "d. M. y. HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "kn",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "hr",
"pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu-hu.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu-hu.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu-hu.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "de.",
- "1": "du."
- },
- "DAY": {
- "0": "vas\u00e1rnap",
- "1": "h\u00e9tf\u0151",
- "2": "kedd",
- "3": "szerda",
- "4": "cs\u00fct\u00f6rt\u00f6k",
- "5": "p\u00e9ntek",
- "6": "szombat"
- },
- "MONTH": {
- "0": "janu\u00e1r",
- "1": "febru\u00e1r",
- "2": "m\u00e1rcius",
- "3": "\u00e1prilis",
- "4": "m\u00e1jus",
- "5": "j\u00fanius",
- "6": "j\u00falius",
- "7": "augusztus",
- "8": "szeptember",
- "9": "okt\u00f3ber",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "V",
- "1": "H",
- "2": "K",
- "3": "Sze",
- "4": "Cs",
- "5": "P",
- "6": "Szo"
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "febr.",
- "2": "m\u00e1rc.",
- "3": "\u00e1pr.",
- "4": "m\u00e1j.",
- "5": "j\u00fan.",
- "6": "j\u00fal.",
- "7": "aug.",
- "8": "szept.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "de.",
+ "du."
+ ],
+ "DAY": [
+ "vas\u00e1rnap",
+ "h\u00e9tf\u0151",
+ "kedd",
+ "szerda",
+ "cs\u00fct\u00f6rt\u00f6k",
+ "p\u00e9ntek",
+ "szombat"
+ ],
+ "MONTH": [
+ "janu\u00e1r",
+ "febru\u00e1r",
+ "m\u00e1rcius",
+ "\u00e1prilis",
+ "m\u00e1jus",
+ "j\u00fanius",
+ "j\u00falius",
+ "augusztus",
+ "szeptember",
+ "okt\u00f3ber",
+ "november",
+ "december"
+ ],
+ "SHORTDAY": [
+ "V",
+ "H",
+ "K",
+ "Sze",
+ "Cs",
+ "P",
+ "Szo"
+ ],
+ "SHORTMONTH": [
+ "jan.",
+ "febr.",
+ "m\u00e1rc.",
+ "\u00e1pr.",
+ "m\u00e1j.",
+ "j\u00fan.",
+ "j\u00fal.",
+ "aug.",
+ "szept.",
+ "okt.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "y. MMMM d., EEEE",
"longDate": "y. MMMM d.",
"medium": "yyyy.MM.dd. H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Ft",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "hu-hu",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_hu.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "de.",
- "1": "du."
- },
- "DAY": {
- "0": "vas\u00e1rnap",
- "1": "h\u00e9tf\u0151",
- "2": "kedd",
- "3": "szerda",
- "4": "cs\u00fct\u00f6rt\u00f6k",
- "5": "p\u00e9ntek",
- "6": "szombat"
- },
- "MONTH": {
- "0": "janu\u00e1r",
- "1": "febru\u00e1r",
- "2": "m\u00e1rcius",
- "3": "\u00e1prilis",
- "4": "m\u00e1jus",
- "5": "j\u00fanius",
- "6": "j\u00falius",
- "7": "augusztus",
- "8": "szeptember",
- "9": "okt\u00f3ber",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "V",
- "1": "H",
- "2": "K",
- "3": "Sze",
- "4": "Cs",
- "5": "P",
- "6": "Szo"
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "febr.",
- "2": "m\u00e1rc.",
- "3": "\u00e1pr.",
- "4": "m\u00e1j.",
- "5": "j\u00fan.",
- "6": "j\u00fal.",
- "7": "aug.",
- "8": "szept.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "de.",
+ "du."
+ ],
+ "DAY": [
+ "vas\u00e1rnap",
+ "h\u00e9tf\u0151",
+ "kedd",
+ "szerda",
+ "cs\u00fct\u00f6rt\u00f6k",
+ "p\u00e9ntek",
+ "szombat"
+ ],
+ "MONTH": [
+ "janu\u00e1r",
+ "febru\u00e1r",
+ "m\u00e1rcius",
+ "\u00e1prilis",
+ "m\u00e1jus",
+ "j\u00fanius",
+ "j\u00falius",
+ "augusztus",
+ "szeptember",
+ "okt\u00f3ber",
+ "november",
+ "december"
+ ],
+ "SHORTDAY": [
+ "V",
+ "H",
+ "K",
+ "Sze",
+ "Cs",
+ "P",
+ "Szo"
+ ],
+ "SHORTMONTH": [
+ "jan.",
+ "febr.",
+ "m\u00e1rc.",
+ "\u00e1pr.",
+ "m\u00e1j.",
+ "j\u00fan.",
+ "j\u00fal.",
+ "aug.",
+ "szept.",
+ "okt.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "y. MMMM d., EEEE",
"longDate": "y. MMMM d.",
"medium": "yyyy.MM.dd. H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Ft",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "hu",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id-id.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id-id.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id-id.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Minggu",
- "1": "Senin",
- "2": "Selasa",
- "3": "Rabu",
- "4": "Kamis",
- "5": "Jumat",
- "6": "Sabtu"
- },
- "MONTH": {
- "0": "Januari",
- "1": "Februari",
- "2": "Maret",
- "3": "April",
- "4": "Mei",
- "5": "Juni",
- "6": "Juli",
- "7": "Agustus",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Desember"
- },
- "SHORTDAY": {
- "0": "Min",
- "1": "Sen",
- "2": "Sel",
- "3": "Rab",
- "4": "Kam",
- "5": "Jum",
- "6": "Sab"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "Mei",
- "5": "Jun",
- "6": "Jul",
- "7": "Agt",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Des"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Minggu",
+ "Senin",
+ "Selasa",
+ "Rabu",
+ "Kamis",
+ "Jumat",
+ "Sabtu"
+ ],
+ "MONTH": [
+ "Januari",
+ "Februari",
+ "Maret",
+ "April",
+ "Mei",
+ "Juni",
+ "Juli",
+ "Agustus",
+ "September",
+ "Oktober",
+ "November",
+ "Desember"
+ ],
+ "SHORTDAY": [
+ "Min",
+ "Sen",
+ "Sel",
+ "Rab",
+ "Kam",
+ "Jum",
+ "Sab"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Agt",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Des"
+ ],
"fullDate": "EEEE, dd MMMM yyyy",
"longDate": "d MMMM yyyy",
"medium": "d MMM yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Rp",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "id-id",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_id.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Minggu",
- "1": "Senin",
- "2": "Selasa",
- "3": "Rabu",
- "4": "Kamis",
- "5": "Jumat",
- "6": "Sabtu"
- },
- "MONTH": {
- "0": "Januari",
- "1": "Februari",
- "2": "Maret",
- "3": "April",
- "4": "Mei",
- "5": "Juni",
- "6": "Juli",
- "7": "Agustus",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Desember"
- },
- "SHORTDAY": {
- "0": "Min",
- "1": "Sen",
- "2": "Sel",
- "3": "Rab",
- "4": "Kam",
- "5": "Jum",
- "6": "Sab"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "Mei",
- "5": "Jun",
- "6": "Jul",
- "7": "Agt",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Des"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Minggu",
+ "Senin",
+ "Selasa",
+ "Rabu",
+ "Kamis",
+ "Jumat",
+ "Sabtu"
+ ],
+ "MONTH": [
+ "Januari",
+ "Februari",
+ "Maret",
+ "April",
+ "Mei",
+ "Juni",
+ "Juli",
+ "Agustus",
+ "September",
+ "Oktober",
+ "November",
+ "Desember"
+ ],
+ "SHORTDAY": [
+ "Min",
+ "Sen",
+ "Sel",
+ "Rab",
+ "Kam",
+ "Jum",
+ "Sab"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Agt",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Des"
+ ],
"fullDate": "EEEE, dd MMMM yyyy",
"longDate": "d MMMM yyyy",
"medium": "d MMM yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Rp",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "id",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_in.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_in.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_in.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Minggu",
- "1": "Senin",
- "2": "Selasa",
- "3": "Rabu",
- "4": "Kamis",
- "5": "Jumat",
- "6": "Sabtu"
- },
- "MONTH": {
- "0": "Januari",
- "1": "Februari",
- "2": "Maret",
- "3": "April",
- "4": "Mei",
- "5": "Juni",
- "6": "Juli",
- "7": "Agustus",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Desember"
- },
- "SHORTDAY": {
- "0": "Min",
- "1": "Sen",
- "2": "Sel",
- "3": "Rab",
- "4": "Kam",
- "5": "Jum",
- "6": "Sab"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mar",
- "3": "Apr",
- "4": "Mei",
- "5": "Jun",
- "6": "Jul",
- "7": "Agt",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Des"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Minggu",
+ "Senin",
+ "Selasa",
+ "Rabu",
+ "Kamis",
+ "Jumat",
+ "Sabtu"
+ ],
+ "MONTH": [
+ "Januari",
+ "Februari",
+ "Maret",
+ "April",
+ "Mei",
+ "Juni",
+ "Juli",
+ "Agustus",
+ "September",
+ "Oktober",
+ "November",
+ "Desember"
+ ],
+ "SHORTDAY": [
+ "Min",
+ "Sen",
+ "Sel",
+ "Rab",
+ "Kam",
+ "Jum",
+ "Sab"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Agt",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Des"
+ ],
"fullDate": "EEEE, dd MMMM yyyy",
"longDate": "d MMMM yyyy",
"medium": "d MMM yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Rp",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "in",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is-is.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is-is.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is-is.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "f.h.",
- "1": "e.h."
- },
- "DAY": {
- "0": "sunnudagur",
- "1": "m\u00e1nudagur",
- "2": "\u00feri\u00f0judagur",
- "3": "mi\u00f0vikudagur",
- "4": "fimmtudagur",
- "5": "f\u00f6studagur",
- "6": "laugardagur"
- },
- "MONTH": {
- "0": "jan\u00faar",
- "1": "febr\u00faar",
- "2": "mars",
- "3": "apr\u00edl",
- "4": "ma\u00ed",
- "5": "j\u00fan\u00ed",
- "6": "j\u00fal\u00ed",
- "7": "\u00e1g\u00fast",
- "8": "september",
- "9": "okt\u00f3ber",
- "10": "n\u00f3vember",
- "11": "desember"
- },
- "SHORTDAY": {
- "0": "sun",
- "1": "m\u00e1n",
- "2": "\u00feri",
- "3": "mi\u00f0",
- "4": "fim",
- "5": "f\u00f6s",
- "6": "lau"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "ma\u00ed",
- "5": "j\u00fan",
- "6": "j\u00fal",
- "7": "\u00e1g\u00fa",
- "8": "sep",
- "9": "okt",
- "10": "n\u00f3v",
- "11": "des"
- },
+ "AMPMS": [
+ "f.h.",
+ "e.h."
+ ],
+ "DAY": [
+ "sunnudagur",
+ "m\u00e1nudagur",
+ "\u00feri\u00f0judagur",
+ "mi\u00f0vikudagur",
+ "fimmtudagur",
+ "f\u00f6studagur",
+ "laugardagur"
+ ],
+ "MONTH": [
+ "jan\u00faar",
+ "febr\u00faar",
+ "mars",
+ "apr\u00edl",
+ "ma\u00ed",
+ "j\u00fan\u00ed",
+ "j\u00fal\u00ed",
+ "\u00e1g\u00fast",
+ "september",
+ "okt\u00f3ber",
+ "n\u00f3vember",
+ "desember"
+ ],
+ "SHORTDAY": [
+ "sun",
+ "m\u00e1n",
+ "\u00feri",
+ "mi\u00f0",
+ "fim",
+ "f\u00f6s",
+ "lau"
+ ],
+ "SHORTMONTH": [
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "ma\u00ed",
+ "j\u00fan",
+ "j\u00fal",
+ "\u00e1g\u00fa",
+ "sep",
+ "okt",
+ "n\u00f3v",
+ "des"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "d.M.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "kr",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "is-is",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_is.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "f.h.",
- "1": "e.h."
- },
- "DAY": {
- "0": "sunnudagur",
- "1": "m\u00e1nudagur",
- "2": "\u00feri\u00f0judagur",
- "3": "mi\u00f0vikudagur",
- "4": "fimmtudagur",
- "5": "f\u00f6studagur",
- "6": "laugardagur"
- },
- "MONTH": {
- "0": "jan\u00faar",
- "1": "febr\u00faar",
- "2": "mars",
- "3": "apr\u00edl",
- "4": "ma\u00ed",
- "5": "j\u00fan\u00ed",
- "6": "j\u00fal\u00ed",
- "7": "\u00e1g\u00fast",
- "8": "september",
- "9": "okt\u00f3ber",
- "10": "n\u00f3vember",
- "11": "desember"
- },
- "SHORTDAY": {
- "0": "sun",
- "1": "m\u00e1n",
- "2": "\u00feri",
- "3": "mi\u00f0",
- "4": "fim",
- "5": "f\u00f6s",
- "6": "lau"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "ma\u00ed",
- "5": "j\u00fan",
- "6": "j\u00fal",
- "7": "\u00e1g\u00fa",
- "8": "sep",
- "9": "okt",
- "10": "n\u00f3v",
- "11": "des"
- },
+ "AMPMS": [
+ "f.h.",
+ "e.h."
+ ],
+ "DAY": [
+ "sunnudagur",
+ "m\u00e1nudagur",
+ "\u00feri\u00f0judagur",
+ "mi\u00f0vikudagur",
+ "fimmtudagur",
+ "f\u00f6studagur",
+ "laugardagur"
+ ],
+ "MONTH": [
+ "jan\u00faar",
+ "febr\u00faar",
+ "mars",
+ "apr\u00edl",
+ "ma\u00ed",
+ "j\u00fan\u00ed",
+ "j\u00fal\u00ed",
+ "\u00e1g\u00fast",
+ "september",
+ "okt\u00f3ber",
+ "n\u00f3vember",
+ "desember"
+ ],
+ "SHORTDAY": [
+ "sun",
+ "m\u00e1n",
+ "\u00feri",
+ "mi\u00f0",
+ "fim",
+ "f\u00f6s",
+ "lau"
+ ],
+ "SHORTMONTH": [
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "ma\u00ed",
+ "j\u00fan",
+ "j\u00fal",
+ "\u00e1g\u00fa",
+ "sep",
+ "okt",
+ "n\u00f3v",
+ "des"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "d.M.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "kr",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "is",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-it.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-it.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-it.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "m.",
- "1": "p."
- },
- "DAY": {
- "0": "domenica",
- "1": "luned\u00ec",
- "2": "marted\u00ec",
- "3": "mercoled\u00ec",
- "4": "gioved\u00ec",
- "5": "venerd\u00ec",
- "6": "sabato"
- },
- "MONTH": {
- "0": "gennaio",
- "1": "febbraio",
- "2": "marzo",
- "3": "aprile",
- "4": "maggio",
- "5": "giugno",
- "6": "luglio",
- "7": "agosto",
- "8": "settembre",
- "9": "ottobre",
- "10": "novembre",
- "11": "dicembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mer",
- "4": "gio",
- "5": "ven",
- "6": "sab"
- },
- "SHORTMONTH": {
- "0": "gen",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "mag",
- "5": "giu",
- "6": "lug",
- "7": "ago",
- "8": "set",
- "9": "ott",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "m.",
+ "p."
+ ],
+ "DAY": [
+ "domenica",
+ "luned\u00ec",
+ "marted\u00ec",
+ "mercoled\u00ec",
+ "gioved\u00ec",
+ "venerd\u00ec",
+ "sabato"
+ ],
+ "MONTH": [
+ "gennaio",
+ "febbraio",
+ "marzo",
+ "aprile",
+ "maggio",
+ "giugno",
+ "luglio",
+ "agosto",
+ "settembre",
+ "ottobre",
+ "novembre",
+ "dicembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mer",
+ "gio",
+ "ven",
+ "sab"
+ ],
+ "SHORTMONTH": [
+ "gen",
+ "feb",
+ "mar",
+ "apr",
+ "mag",
+ "giu",
+ "lug",
+ "ago",
+ "set",
+ "ott",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "dd MMMM y",
"medium": "dd/MMM/y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "it-it",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-sm.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-sm.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it-sm.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "m.",
- "1": "p."
- },
- "DAY": {
- "0": "domenica",
- "1": "luned\u00ec",
- "2": "marted\u00ec",
- "3": "mercoled\u00ec",
- "4": "gioved\u00ec",
- "5": "venerd\u00ec",
- "6": "sabato"
- },
- "MONTH": {
- "0": "gennaio",
- "1": "febbraio",
- "2": "marzo",
- "3": "aprile",
- "4": "maggio",
- "5": "giugno",
- "6": "luglio",
- "7": "agosto",
- "8": "settembre",
- "9": "ottobre",
- "10": "novembre",
- "11": "dicembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mer",
- "4": "gio",
- "5": "ven",
- "6": "sab"
- },
- "SHORTMONTH": {
- "0": "gen",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "mag",
- "5": "giu",
- "6": "lug",
- "7": "ago",
- "8": "set",
- "9": "ott",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "m.",
+ "p."
+ ],
+ "DAY": [
+ "domenica",
+ "luned\u00ec",
+ "marted\u00ec",
+ "mercoled\u00ec",
+ "gioved\u00ec",
+ "venerd\u00ec",
+ "sabato"
+ ],
+ "MONTH": [
+ "gennaio",
+ "febbraio",
+ "marzo",
+ "aprile",
+ "maggio",
+ "giugno",
+ "luglio",
+ "agosto",
+ "settembre",
+ "ottobre",
+ "novembre",
+ "dicembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mer",
+ "gio",
+ "ven",
+ "sab"
+ ],
+ "SHORTMONTH": [
+ "gen",
+ "feb",
+ "mar",
+ "apr",
+ "mag",
+ "giu",
+ "lug",
+ "ago",
+ "set",
+ "ott",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "dd MMMM y",
"medium": "dd/MMM/y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "it-sm",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_it.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "m.",
- "1": "p."
- },
- "DAY": {
- "0": "domenica",
- "1": "luned\u00ec",
- "2": "marted\u00ec",
- "3": "mercoled\u00ec",
- "4": "gioved\u00ec",
- "5": "venerd\u00ec",
- "6": "sabato"
- },
- "MONTH": {
- "0": "gennaio",
- "1": "febbraio",
- "2": "marzo",
- "3": "aprile",
- "4": "maggio",
- "5": "giugno",
- "6": "luglio",
- "7": "agosto",
- "8": "settembre",
- "9": "ottobre",
- "10": "novembre",
- "11": "dicembre"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "lun",
- "2": "mar",
- "3": "mer",
- "4": "gio",
- "5": "ven",
- "6": "sab"
- },
- "SHORTMONTH": {
- "0": "gen",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "mag",
- "5": "giu",
- "6": "lug",
- "7": "ago",
- "8": "set",
- "9": "ott",
- "10": "nov",
- "11": "dic"
- },
+ "AMPMS": [
+ "m.",
+ "p."
+ ],
+ "DAY": [
+ "domenica",
+ "luned\u00ec",
+ "marted\u00ec",
+ "mercoled\u00ec",
+ "gioved\u00ec",
+ "venerd\u00ec",
+ "sabato"
+ ],
+ "MONTH": [
+ "gennaio",
+ "febbraio",
+ "marzo",
+ "aprile",
+ "maggio",
+ "giugno",
+ "luglio",
+ "agosto",
+ "settembre",
+ "ottobre",
+ "novembre",
+ "dicembre"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "lun",
+ "mar",
+ "mer",
+ "gio",
+ "ven",
+ "sab"
+ ],
+ "SHORTMONTH": [
+ "gen",
+ "feb",
+ "mar",
+ "apr",
+ "mag",
+ "giu",
+ "lug",
+ "ago",
+ "set",
+ "ott",
+ "nov",
+ "dic"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "dd MMMM y",
"medium": "dd/MMM/y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "it",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_iw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_iw.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_iw.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u05dc\u05e4\u05e0\u05d4\u05f4\u05e6",
- "1": "\u05d0\u05d7\u05d4\u05f4\u05e6"
- },
- "DAY": {
- "0": "\u05d9\u05d5\u05dd \u05e8\u05d0\u05e9\u05d5\u05df",
- "1": "\u05d9\u05d5\u05dd \u05e9\u05e0\u05d9",
- "2": "\u05d9\u05d5\u05dd \u05e9\u05dc\u05d9\u05e9\u05d9",
- "3": "\u05d9\u05d5\u05dd \u05e8\u05d1\u05d9\u05e2\u05d9",
- "4": "\u05d9\u05d5\u05dd \u05d7\u05de\u05d9\u05e9\u05d9",
- "5": "\u05d9\u05d5\u05dd \u05e9\u05d9\u05e9\u05d9",
- "6": "\u05d9\u05d5\u05dd \u05e9\u05d1\u05ea"
- },
- "MONTH": {
- "0": "\u05d9\u05e0\u05d5\u05d0\u05e8",
- "1": "\u05e4\u05d1\u05e8\u05d5\u05d0\u05e8",
- "2": "\u05de\u05e8\u05e5",
- "3": "\u05d0\u05e4\u05e8\u05d9\u05dc",
- "4": "\u05de\u05d0\u05d9",
- "5": "\u05d9\u05d5\u05e0\u05d9",
- "6": "\u05d9\u05d5\u05dc\u05d9",
- "7": "\u05d0\u05d5\u05d2\u05d5\u05e1\u05d8",
- "8": "\u05e1\u05e4\u05d8\u05de\u05d1\u05e8",
- "9": "\u05d0\u05d5\u05e7\u05d8\u05d5\u05d1\u05e8",
- "10": "\u05e0\u05d5\u05d1\u05de\u05d1\u05e8",
- "11": "\u05d3\u05e6\u05de\u05d1\u05e8"
- },
- "SHORTDAY": {
- "0": "\u05d9\u05d5\u05dd \u05d0\u05f3",
- "1": "\u05d9\u05d5\u05dd \u05d1\u05f3",
- "2": "\u05d9\u05d5\u05dd \u05d2\u05f3",
- "3": "\u05d9\u05d5\u05dd \u05d3\u05f3",
- "4": "\u05d9\u05d5\u05dd \u05d4\u05f3",
- "5": "\u05d9\u05d5\u05dd \u05d5\u05f3",
- "6": "\u05e9\u05d1\u05ea"
- },
- "SHORTMONTH": {
- "0": "\u05d9\u05e0\u05d5",
- "1": "\u05e4\u05d1\u05e8",
- "2": "\u05de\u05e8\u05e5",
- "3": "\u05d0\u05e4\u05e8",
- "4": "\u05de\u05d0\u05d9",
- "5": "\u05d9\u05d5\u05e0",
- "6": "\u05d9\u05d5\u05dc",
- "7": "\u05d0\u05d5\u05d2",
- "8": "\u05e1\u05e4\u05d8",
- "9": "\u05d0\u05d5\u05e7",
- "10": "\u05e0\u05d5\u05d1",
- "11": "\u05d3\u05e6\u05de"
- },
+ "AMPMS": [
+ "\u05dc\u05e4\u05e0\u05d4\u05f4\u05e6",
+ "\u05d0\u05d7\u05d4\u05f4\u05e6"
+ ],
+ "DAY": [
+ "\u05d9\u05d5\u05dd \u05e8\u05d0\u05e9\u05d5\u05df",
+ "\u05d9\u05d5\u05dd \u05e9\u05e0\u05d9",
+ "\u05d9\u05d5\u05dd \u05e9\u05dc\u05d9\u05e9\u05d9",
+ "\u05d9\u05d5\u05dd \u05e8\u05d1\u05d9\u05e2\u05d9",
+ "\u05d9\u05d5\u05dd \u05d7\u05de\u05d9\u05e9\u05d9",
+ "\u05d9\u05d5\u05dd \u05e9\u05d9\u05e9\u05d9",
+ "\u05d9\u05d5\u05dd \u05e9\u05d1\u05ea"
+ ],
+ "MONTH": [
+ "\u05d9\u05e0\u05d5\u05d0\u05e8",
+ "\u05e4\u05d1\u05e8\u05d5\u05d0\u05e8",
+ "\u05de\u05e8\u05e5",
+ "\u05d0\u05e4\u05e8\u05d9\u05dc",
+ "\u05de\u05d0\u05d9",
+ "\u05d9\u05d5\u05e0\u05d9",
+ "\u05d9\u05d5\u05dc\u05d9",
+ "\u05d0\u05d5\u05d2\u05d5\u05e1\u05d8",
+ "\u05e1\u05e4\u05d8\u05de\u05d1\u05e8",
+ "\u05d0\u05d5\u05e7\u05d8\u05d5\u05d1\u05e8",
+ "\u05e0\u05d5\u05d1\u05de\u05d1\u05e8",
+ "\u05d3\u05e6\u05de\u05d1\u05e8"
+ ],
+ "SHORTDAY": [
+ "\u05d9\u05d5\u05dd \u05d0\u05f3",
+ "\u05d9\u05d5\u05dd \u05d1\u05f3",
+ "\u05d9\u05d5\u05dd \u05d2\u05f3",
+ "\u05d9\u05d5\u05dd \u05d3\u05f3",
+ "\u05d9\u05d5\u05dd \u05d4\u05f3",
+ "\u05d9\u05d5\u05dd \u05d5\u05f3",
+ "\u05e9\u05d1\u05ea"
+ ],
+ "SHORTMONTH": [
+ "\u05d9\u05e0\u05d5",
+ "\u05e4\u05d1\u05e8",
+ "\u05de\u05e8\u05e5",
+ "\u05d0\u05e4\u05e8",
+ "\u05de\u05d0\u05d9",
+ "\u05d9\u05d5\u05e0",
+ "\u05d9\u05d5\u05dc",
+ "\u05d0\u05d5\u05d2",
+ "\u05e1\u05e4\u05d8",
+ "\u05d0\u05d5\u05e7",
+ "\u05e0\u05d5\u05d1",
+ "\u05d3\u05e6\u05de"
+ ],
"fullDate": "EEEE, d \u05d1MMMM y",
"longDate": "d \u05d1MMMM y",
"medium": "d \u05d1MMM yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20aa",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "iw",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja-jp.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja-jp.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja-jp.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u5348\u524d",
- "1": "\u5348\u5f8c"
- },
- "DAY": {
- "0": "\u65e5\u66dc\u65e5",
- "1": "\u6708\u66dc\u65e5",
- "2": "\u706b\u66dc\u65e5",
- "3": "\u6c34\u66dc\u65e5",
- "4": "\u6728\u66dc\u65e5",
- "5": "\u91d1\u66dc\u65e5",
- "6": "\u571f\u66dc\u65e5"
- },
- "MONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
- "SHORTDAY": {
- "0": "\u65e5",
- "1": "\u6708",
- "2": "\u706b",
- "3": "\u6c34",
- "4": "\u6728",
- "5": "\u91d1",
- "6": "\u571f"
- },
- "SHORTMONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
+ "AMPMS": [
+ "\u5348\u524d",
+ "\u5348\u5f8c"
+ ],
+ "DAY": [
+ "\u65e5\u66dc\u65e5",
+ "\u6708\u66dc\u65e5",
+ "\u706b\u66dc\u65e5",
+ "\u6c34\u66dc\u65e5",
+ "\u6728\u66dc\u65e5",
+ "\u91d1\u66dc\u65e5",
+ "\u571f\u66dc\u65e5"
+ ],
+ "MONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
+ "SHORTDAY": [
+ "\u65e5",
+ "\u6708",
+ "\u706b",
+ "\u6c34",
+ "\u6728",
+ "\u91d1",
+ "\u571f"
+ ],
+ "SHORTMONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
"fullDate": "y\u5e74M\u6708d\u65e5EEEE",
"longDate": "y\u5e74M\u6708d\u65e5",
"medium": "yyyy/MM/dd H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a5",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "ja-jp",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ja.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u5348\u524d",
- "1": "\u5348\u5f8c"
- },
- "DAY": {
- "0": "\u65e5\u66dc\u65e5",
- "1": "\u6708\u66dc\u65e5",
- "2": "\u706b\u66dc\u65e5",
- "3": "\u6c34\u66dc\u65e5",
- "4": "\u6728\u66dc\u65e5",
- "5": "\u91d1\u66dc\u65e5",
- "6": "\u571f\u66dc\u65e5"
- },
- "MONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
- "SHORTDAY": {
- "0": "\u65e5",
- "1": "\u6708",
- "2": "\u706b",
- "3": "\u6c34",
- "4": "\u6728",
- "5": "\u91d1",
- "6": "\u571f"
- },
- "SHORTMONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
+ "AMPMS": [
+ "\u5348\u524d",
+ "\u5348\u5f8c"
+ ],
+ "DAY": [
+ "\u65e5\u66dc\u65e5",
+ "\u6708\u66dc\u65e5",
+ "\u706b\u66dc\u65e5",
+ "\u6c34\u66dc\u65e5",
+ "\u6728\u66dc\u65e5",
+ "\u91d1\u66dc\u65e5",
+ "\u571f\u66dc\u65e5"
+ ],
+ "MONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
+ "SHORTDAY": [
+ "\u65e5",
+ "\u6708",
+ "\u706b",
+ "\u6c34",
+ "\u6728",
+ "\u91d1",
+ "\u571f"
+ ],
+ "SHORTMONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
"fullDate": "y\u5e74M\u6708d\u65e5EEEE",
"longDate": "y\u5e74M\u6708d\u65e5",
"medium": "yyyy/MM/dd H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a5",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "ja",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn-in.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn-in.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn-in.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0cb0\u0cb5\u0cbf\u0cb5\u0cbe\u0cb0",
- "1": "\u0cb8\u0ccb\u0cae\u0cb5\u0cbe\u0cb0",
- "2": "\u0cae\u0c82\u0c97\u0cb3\u0cb5\u0cbe\u0cb0",
- "3": "\u0cac\u0cc1\u0ca7\u0cb5\u0cbe\u0cb0",
- "4": "\u0c97\u0cc1\u0cb0\u0cc1\u0cb5\u0cbe\u0cb0",
- "5": "\u0cb6\u0cc1\u0c95\u0ccd\u0cb0\u0cb5\u0cbe\u0cb0",
- "6": "\u0cb6\u0ca8\u0cbf\u0cb5\u0cbe\u0cb0"
- },
- "MONTH": {
- "0": "\u0c9c\u0ca8\u0cb5\u0cb0\u0cc0",
- "1": "\u0cab\u0cc6\u0cac\u0ccd\u0cb0\u0cb5\u0cb0\u0cc0",
- "2": "\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd",
- "3": "\u0c8e\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd",
- "4": "\u0cae\u0cc6",
- "5": "\u0c9c\u0cc2\u0ca8\u0ccd",
- "6": "\u0c9c\u0cc1\u0cb2\u0cc8",
- "7": "\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd",
- "8": "\u0cb8\u0caa\u0ccd\u0c9f\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
- "9": "\u0c85\u0c95\u0ccd\u0c9f\u0ccb\u0cac\u0cb0\u0ccd",
- "10": "\u0ca8\u0cb5\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
- "11": "\u0ca1\u0cbf\u0cb8\u0cc6\u0c82\u0cac\u0cb0\u0ccd"
- },
- "SHORTDAY": {
- "0": "\u0cb0.",
- "1": "\u0cb8\u0ccb.",
- "2": "\u0cae\u0c82.",
- "3": "\u0cac\u0cc1.",
- "4": "\u0c97\u0cc1.",
- "5": "\u0cb6\u0cc1.",
- "6": "\u0cb6\u0ca8\u0cbf."
- },
- "SHORTMONTH": {
- "0": "\u0c9c\u0ca8\u0cb5\u0cb0\u0cc0",
- "1": "\u0cab\u0cc6\u0cac\u0ccd\u0cb0\u0cb5\u0cb0\u0cc0",
- "2": "\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd",
- "3": "\u0c8e\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd",
- "4": "\u0cae\u0cc6",
- "5": "\u0c9c\u0cc2\u0ca8\u0ccd",
- "6": "\u0c9c\u0cc1\u0cb2\u0cc8",
- "7": "\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd",
- "8": "\u0cb8\u0caa\u0ccd\u0c9f\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
- "9": "\u0c85\u0c95\u0ccd\u0c9f\u0ccb\u0cac\u0cb0\u0ccd",
- "10": "\u0ca8\u0cb5\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
- "11": "\u0ca1\u0cbf\u0cb8\u0cc6\u0c82\u0cac\u0cb0\u0ccd"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0cb0\u0cb5\u0cbf\u0cb5\u0cbe\u0cb0",
+ "\u0cb8\u0ccb\u0cae\u0cb5\u0cbe\u0cb0",
+ "\u0cae\u0c82\u0c97\u0cb3\u0cb5\u0cbe\u0cb0",
+ "\u0cac\u0cc1\u0ca7\u0cb5\u0cbe\u0cb0",
+ "\u0c97\u0cc1\u0cb0\u0cc1\u0cb5\u0cbe\u0cb0",
+ "\u0cb6\u0cc1\u0c95\u0ccd\u0cb0\u0cb5\u0cbe\u0cb0",
+ "\u0cb6\u0ca8\u0cbf\u0cb5\u0cbe\u0cb0"
+ ],
+ "MONTH": [
+ "\u0c9c\u0ca8\u0cb5\u0cb0\u0cc0",
+ "\u0cab\u0cc6\u0cac\u0ccd\u0cb0\u0cb5\u0cb0\u0cc0",
+ "\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd",
+ "\u0c8e\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd",
+ "\u0cae\u0cc6",
+ "\u0c9c\u0cc2\u0ca8\u0ccd",
+ "\u0c9c\u0cc1\u0cb2\u0cc8",
+ "\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd",
+ "\u0cb8\u0caa\u0ccd\u0c9f\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
+ "\u0c85\u0c95\u0ccd\u0c9f\u0ccb\u0cac\u0cb0\u0ccd",
+ "\u0ca8\u0cb5\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
+ "\u0ca1\u0cbf\u0cb8\u0cc6\u0c82\u0cac\u0cb0\u0ccd"
+ ],
+ "SHORTDAY": [
+ "\u0cb0.",
+ "\u0cb8\u0ccb.",
+ "\u0cae\u0c82.",
+ "\u0cac\u0cc1.",
+ "\u0c97\u0cc1.",
+ "\u0cb6\u0cc1.",
+ "\u0cb6\u0ca8\u0cbf."
+ ],
+ "SHORTMONTH": [
+ "\u0c9c\u0ca8\u0cb5\u0cb0\u0cc0",
+ "\u0cab\u0cc6\u0cac\u0ccd\u0cb0\u0cb5\u0cb0\u0cc0",
+ "\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd",
+ "\u0c8e\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd",
+ "\u0cae\u0cc6",
+ "\u0c9c\u0cc2\u0ca8\u0ccd",
+ "\u0c9c\u0cc1\u0cb2\u0cc8",
+ "\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd",
+ "\u0cb8\u0caa\u0ccd\u0c9f\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
+ "\u0c85\u0c95\u0ccd\u0c9f\u0ccb\u0cac\u0cb0\u0ccd",
+ "\u0ca8\u0cb5\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
+ "\u0ca1\u0cbf\u0cb8\u0cc6\u0c82\u0cac\u0cb0\u0ccd"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y hh:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "kn-in",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_kn.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0cb0\u0cb5\u0cbf\u0cb5\u0cbe\u0cb0",
- "1": "\u0cb8\u0ccb\u0cae\u0cb5\u0cbe\u0cb0",
- "2": "\u0cae\u0c82\u0c97\u0cb3\u0cb5\u0cbe\u0cb0",
- "3": "\u0cac\u0cc1\u0ca7\u0cb5\u0cbe\u0cb0",
- "4": "\u0c97\u0cc1\u0cb0\u0cc1\u0cb5\u0cbe\u0cb0",
- "5": "\u0cb6\u0cc1\u0c95\u0ccd\u0cb0\u0cb5\u0cbe\u0cb0",
- "6": "\u0cb6\u0ca8\u0cbf\u0cb5\u0cbe\u0cb0"
- },
- "MONTH": {
- "0": "\u0c9c\u0ca8\u0cb5\u0cb0\u0cc0",
- "1": "\u0cab\u0cc6\u0cac\u0ccd\u0cb0\u0cb5\u0cb0\u0cc0",
- "2": "\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd",
- "3": "\u0c8e\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd",
- "4": "\u0cae\u0cc6",
- "5": "\u0c9c\u0cc2\u0ca8\u0ccd",
- "6": "\u0c9c\u0cc1\u0cb2\u0cc8",
- "7": "\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd",
- "8": "\u0cb8\u0caa\u0ccd\u0c9f\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
- "9": "\u0c85\u0c95\u0ccd\u0c9f\u0ccb\u0cac\u0cb0\u0ccd",
- "10": "\u0ca8\u0cb5\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
- "11": "\u0ca1\u0cbf\u0cb8\u0cc6\u0c82\u0cac\u0cb0\u0ccd"
- },
- "SHORTDAY": {
- "0": "\u0cb0.",
- "1": "\u0cb8\u0ccb.",
- "2": "\u0cae\u0c82.",
- "3": "\u0cac\u0cc1.",
- "4": "\u0c97\u0cc1.",
- "5": "\u0cb6\u0cc1.",
- "6": "\u0cb6\u0ca8\u0cbf."
- },
- "SHORTMONTH": {
- "0": "\u0c9c\u0ca8\u0cb5\u0cb0\u0cc0",
- "1": "\u0cab\u0cc6\u0cac\u0ccd\u0cb0\u0cb5\u0cb0\u0cc0",
- "2": "\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd",
- "3": "\u0c8e\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd",
- "4": "\u0cae\u0cc6",
- "5": "\u0c9c\u0cc2\u0ca8\u0ccd",
- "6": "\u0c9c\u0cc1\u0cb2\u0cc8",
- "7": "\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd",
- "8": "\u0cb8\u0caa\u0ccd\u0c9f\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
- "9": "\u0c85\u0c95\u0ccd\u0c9f\u0ccb\u0cac\u0cb0\u0ccd",
- "10": "\u0ca8\u0cb5\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
- "11": "\u0ca1\u0cbf\u0cb8\u0cc6\u0c82\u0cac\u0cb0\u0ccd"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0cb0\u0cb5\u0cbf\u0cb5\u0cbe\u0cb0",
+ "\u0cb8\u0ccb\u0cae\u0cb5\u0cbe\u0cb0",
+ "\u0cae\u0c82\u0c97\u0cb3\u0cb5\u0cbe\u0cb0",
+ "\u0cac\u0cc1\u0ca7\u0cb5\u0cbe\u0cb0",
+ "\u0c97\u0cc1\u0cb0\u0cc1\u0cb5\u0cbe\u0cb0",
+ "\u0cb6\u0cc1\u0c95\u0ccd\u0cb0\u0cb5\u0cbe\u0cb0",
+ "\u0cb6\u0ca8\u0cbf\u0cb5\u0cbe\u0cb0"
+ ],
+ "MONTH": [
+ "\u0c9c\u0ca8\u0cb5\u0cb0\u0cc0",
+ "\u0cab\u0cc6\u0cac\u0ccd\u0cb0\u0cb5\u0cb0\u0cc0",
+ "\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd",
+ "\u0c8e\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd",
+ "\u0cae\u0cc6",
+ "\u0c9c\u0cc2\u0ca8\u0ccd",
+ "\u0c9c\u0cc1\u0cb2\u0cc8",
+ "\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd",
+ "\u0cb8\u0caa\u0ccd\u0c9f\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
+ "\u0c85\u0c95\u0ccd\u0c9f\u0ccb\u0cac\u0cb0\u0ccd",
+ "\u0ca8\u0cb5\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
+ "\u0ca1\u0cbf\u0cb8\u0cc6\u0c82\u0cac\u0cb0\u0ccd"
+ ],
+ "SHORTDAY": [
+ "\u0cb0.",
+ "\u0cb8\u0ccb.",
+ "\u0cae\u0c82.",
+ "\u0cac\u0cc1.",
+ "\u0c97\u0cc1.",
+ "\u0cb6\u0cc1.",
+ "\u0cb6\u0ca8\u0cbf."
+ ],
+ "SHORTMONTH": [
+ "\u0c9c\u0ca8\u0cb5\u0cb0\u0cc0",
+ "\u0cab\u0cc6\u0cac\u0ccd\u0cb0\u0cb5\u0cb0\u0cc0",
+ "\u0cae\u0cbe\u0cb0\u0ccd\u0c9a\u0ccd",
+ "\u0c8e\u0caa\u0ccd\u0cb0\u0cbf\u0cb2\u0ccd",
+ "\u0cae\u0cc6",
+ "\u0c9c\u0cc2\u0ca8\u0ccd",
+ "\u0c9c\u0cc1\u0cb2\u0cc8",
+ "\u0c86\u0c97\u0cb8\u0ccd\u0c9f\u0ccd",
+ "\u0cb8\u0caa\u0ccd\u0c9f\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
+ "\u0c85\u0c95\u0ccd\u0c9f\u0ccb\u0cac\u0cb0\u0ccd",
+ "\u0ca8\u0cb5\u0cc6\u0c82\u0cac\u0cb0\u0ccd",
+ "\u0ca1\u0cbf\u0cb8\u0cc6\u0c82\u0cac\u0cb0\u0ccd"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y hh:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "kn",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko-kr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko-kr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko-kr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\uc624\uc804",
- "1": "\uc624\ud6c4"
- },
- "DAY": {
- "0": "\uc77c\uc694\uc77c",
- "1": "\uc6d4\uc694\uc77c",
- "2": "\ud654\uc694\uc77c",
- "3": "\uc218\uc694\uc77c",
- "4": "\ubaa9\uc694\uc77c",
- "5": "\uae08\uc694\uc77c",
- "6": "\ud1a0\uc694\uc77c"
- },
- "MONTH": {
- "0": "1\uc6d4",
- "1": "2\uc6d4",
- "2": "3\uc6d4",
- "3": "4\uc6d4",
- "4": "5\uc6d4",
- "5": "6\uc6d4",
- "6": "7\uc6d4",
- "7": "8\uc6d4",
- "8": "9\uc6d4",
- "9": "10\uc6d4",
- "10": "11\uc6d4",
- "11": "12\uc6d4"
- },
- "SHORTDAY": {
- "0": "\uc77c",
- "1": "\uc6d4",
- "2": "\ud654",
- "3": "\uc218",
- "4": "\ubaa9",
- "5": "\uae08",
- "6": "\ud1a0"
- },
- "SHORTMONTH": {
- "0": "1\uc6d4",
- "1": "2\uc6d4",
- "2": "3\uc6d4",
- "3": "4\uc6d4",
- "4": "5\uc6d4",
- "5": "6\uc6d4",
- "6": "7\uc6d4",
- "7": "8\uc6d4",
- "8": "9\uc6d4",
- "9": "10\uc6d4",
- "10": "11\uc6d4",
- "11": "12\uc6d4"
- },
+ "AMPMS": [
+ "\uc624\uc804",
+ "\uc624\ud6c4"
+ ],
+ "DAY": [
+ "\uc77c\uc694\uc77c",
+ "\uc6d4\uc694\uc77c",
+ "\ud654\uc694\uc77c",
+ "\uc218\uc694\uc77c",
+ "\ubaa9\uc694\uc77c",
+ "\uae08\uc694\uc77c",
+ "\ud1a0\uc694\uc77c"
+ ],
+ "MONTH": [
+ "1\uc6d4",
+ "2\uc6d4",
+ "3\uc6d4",
+ "4\uc6d4",
+ "5\uc6d4",
+ "6\uc6d4",
+ "7\uc6d4",
+ "8\uc6d4",
+ "9\uc6d4",
+ "10\uc6d4",
+ "11\uc6d4",
+ "12\uc6d4"
+ ],
+ "SHORTDAY": [
+ "\uc77c",
+ "\uc6d4",
+ "\ud654",
+ "\uc218",
+ "\ubaa9",
+ "\uae08",
+ "\ud1a0"
+ ],
+ "SHORTMONTH": [
+ "1\uc6d4",
+ "2\uc6d4",
+ "3\uc6d4",
+ "4\uc6d4",
+ "5\uc6d4",
+ "6\uc6d4",
+ "7\uc6d4",
+ "8\uc6d4",
+ "9\uc6d4",
+ "10\uc6d4",
+ "11\uc6d4",
+ "12\uc6d4"
+ ],
"fullDate": "y\ub144 M\uc6d4 d\uc77c EEEE",
"longDate": "y\ub144 M\uc6d4 d\uc77c",
"medium": "yyyy. M. d. a h:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20a9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "ko-kr",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ko.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\uc624\uc804",
- "1": "\uc624\ud6c4"
- },
- "DAY": {
- "0": "\uc77c\uc694\uc77c",
- "1": "\uc6d4\uc694\uc77c",
- "2": "\ud654\uc694\uc77c",
- "3": "\uc218\uc694\uc77c",
- "4": "\ubaa9\uc694\uc77c",
- "5": "\uae08\uc694\uc77c",
- "6": "\ud1a0\uc694\uc77c"
- },
- "MONTH": {
- "0": "1\uc6d4",
- "1": "2\uc6d4",
- "2": "3\uc6d4",
- "3": "4\uc6d4",
- "4": "5\uc6d4",
- "5": "6\uc6d4",
- "6": "7\uc6d4",
- "7": "8\uc6d4",
- "8": "9\uc6d4",
- "9": "10\uc6d4",
- "10": "11\uc6d4",
- "11": "12\uc6d4"
- },
- "SHORTDAY": {
- "0": "\uc77c",
- "1": "\uc6d4",
- "2": "\ud654",
- "3": "\uc218",
- "4": "\ubaa9",
- "5": "\uae08",
- "6": "\ud1a0"
- },
- "SHORTMONTH": {
- "0": "1\uc6d4",
- "1": "2\uc6d4",
- "2": "3\uc6d4",
- "3": "4\uc6d4",
- "4": "5\uc6d4",
- "5": "6\uc6d4",
- "6": "7\uc6d4",
- "7": "8\uc6d4",
- "8": "9\uc6d4",
- "9": "10\uc6d4",
- "10": "11\uc6d4",
- "11": "12\uc6d4"
- },
+ "AMPMS": [
+ "\uc624\uc804",
+ "\uc624\ud6c4"
+ ],
+ "DAY": [
+ "\uc77c\uc694\uc77c",
+ "\uc6d4\uc694\uc77c",
+ "\ud654\uc694\uc77c",
+ "\uc218\uc694\uc77c",
+ "\ubaa9\uc694\uc77c",
+ "\uae08\uc694\uc77c",
+ "\ud1a0\uc694\uc77c"
+ ],
+ "MONTH": [
+ "1\uc6d4",
+ "2\uc6d4",
+ "3\uc6d4",
+ "4\uc6d4",
+ "5\uc6d4",
+ "6\uc6d4",
+ "7\uc6d4",
+ "8\uc6d4",
+ "9\uc6d4",
+ "10\uc6d4",
+ "11\uc6d4",
+ "12\uc6d4"
+ ],
+ "SHORTDAY": [
+ "\uc77c",
+ "\uc6d4",
+ "\ud654",
+ "\uc218",
+ "\ubaa9",
+ "\uae08",
+ "\ud1a0"
+ ],
+ "SHORTMONTH": [
+ "1\uc6d4",
+ "2\uc6d4",
+ "3\uc6d4",
+ "4\uc6d4",
+ "5\uc6d4",
+ "6\uc6d4",
+ "7\uc6d4",
+ "8\uc6d4",
+ "9\uc6d4",
+ "10\uc6d4",
+ "11\uc6d4",
+ "12\uc6d4"
+ ],
"fullDate": "y\ub144 M\uc6d4 d\uc77c EEEE",
"longDate": "y\ub144 M\uc6d4 d\uc77c",
"medium": "yyyy. M. d. a h:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20a9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "ko",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln-cd.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln-cd.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln-cd.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "nt\u0254\u0301ng\u0254\u0301",
- "1": "mp\u00f3kwa"
- },
- "DAY": {
- "0": "eyenga",
- "1": "mok\u0254l\u0254 mwa yambo",
- "2": "mok\u0254l\u0254 mwa m\u00edbal\u00e9",
- "3": "mok\u0254l\u0254 mwa m\u00eds\u00e1to",
- "4": "mok\u0254l\u0254 ya m\u00edn\u00e9i",
- "5": "mok\u0254l\u0254 ya m\u00edt\u00e1no",
- "6": "mp\u0254\u0301s\u0254"
- },
- "MONTH": {
- "0": "s\u00e1nz\u00e1 ya yambo",
- "1": "s\u00e1nz\u00e1 ya m\u00edbal\u00e9",
- "2": "s\u00e1nz\u00e1 ya m\u00eds\u00e1to",
- "3": "s\u00e1nz\u00e1 ya m\u00ednei",
- "4": "s\u00e1nz\u00e1 ya m\u00edt\u00e1no",
- "5": "s\u00e1nz\u00e1 ya mot\u00f3b\u00e1",
- "6": "s\u00e1nz\u00e1 ya nsambo",
- "7": "s\u00e1nz\u00e1 ya mwambe",
- "8": "s\u00e1nz\u00e1 ya libwa",
- "9": "s\u00e1nz\u00e1 ya z\u00f3mi",
- "10": "s\u00e1nz\u00e1 ya z\u00f3mi na m\u0254\u030ck\u0254\u0301",
- "11": "s\u00e1nz\u00e1 ya z\u00f3mi na m\u00edbal\u00e9"
- },
- "SHORTDAY": {
- "0": "eye",
- "1": "ybo",
- "2": "mbl",
- "3": "mst",
- "4": "min",
- "5": "mtn",
- "6": "mps"
- },
- "SHORTMONTH": {
- "0": "yan",
- "1": "fbl",
- "2": "msi",
- "3": "apl",
- "4": "mai",
- "5": "yun",
- "6": "yul",
- "7": "agt",
- "8": "stb",
- "9": "\u0254tb",
- "10": "nvb",
- "11": "dsb"
- },
+ "AMPMS": [
+ "nt\u0254\u0301ng\u0254\u0301",
+ "mp\u00f3kwa"
+ ],
+ "DAY": [
+ "eyenga",
+ "mok\u0254l\u0254 mwa yambo",
+ "mok\u0254l\u0254 mwa m\u00edbal\u00e9",
+ "mok\u0254l\u0254 mwa m\u00eds\u00e1to",
+ "mok\u0254l\u0254 ya m\u00edn\u00e9i",
+ "mok\u0254l\u0254 ya m\u00edt\u00e1no",
+ "mp\u0254\u0301s\u0254"
+ ],
+ "MONTH": [
+ "s\u00e1nz\u00e1 ya yambo",
+ "s\u00e1nz\u00e1 ya m\u00edbal\u00e9",
+ "s\u00e1nz\u00e1 ya m\u00eds\u00e1to",
+ "s\u00e1nz\u00e1 ya m\u00ednei",
+ "s\u00e1nz\u00e1 ya m\u00edt\u00e1no",
+ "s\u00e1nz\u00e1 ya mot\u00f3b\u00e1",
+ "s\u00e1nz\u00e1 ya nsambo",
+ "s\u00e1nz\u00e1 ya mwambe",
+ "s\u00e1nz\u00e1 ya libwa",
+ "s\u00e1nz\u00e1 ya z\u00f3mi",
+ "s\u00e1nz\u00e1 ya z\u00f3mi na m\u0254\u030ck\u0254\u0301",
+ "s\u00e1nz\u00e1 ya z\u00f3mi na m\u00edbal\u00e9"
+ ],
+ "SHORTDAY": [
+ "eye",
+ "ybo",
+ "mbl",
+ "mst",
+ "min",
+ "mtn",
+ "mps"
+ ],
+ "SHORTMONTH": [
+ "yan",
+ "fbl",
+ "msi",
+ "apl",
+ "mai",
+ "yun",
+ "yul",
+ "agt",
+ "stb",
+ "\u0254tb",
+ "nvb",
+ "dsb"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "FrCD",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "ln-cd",
"pluralCat": function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ln.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "nt\u0254\u0301ng\u0254\u0301",
- "1": "mp\u00f3kwa"
- },
- "DAY": {
- "0": "eyenga",
- "1": "mok\u0254l\u0254 mwa yambo",
- "2": "mok\u0254l\u0254 mwa m\u00edbal\u00e9",
- "3": "mok\u0254l\u0254 mwa m\u00eds\u00e1to",
- "4": "mok\u0254l\u0254 ya m\u00edn\u00e9i",
- "5": "mok\u0254l\u0254 ya m\u00edt\u00e1no",
- "6": "mp\u0254\u0301s\u0254"
- },
- "MONTH": {
- "0": "s\u00e1nz\u00e1 ya yambo",
- "1": "s\u00e1nz\u00e1 ya m\u00edbal\u00e9",
- "2": "s\u00e1nz\u00e1 ya m\u00eds\u00e1to",
- "3": "s\u00e1nz\u00e1 ya m\u00ednei",
- "4": "s\u00e1nz\u00e1 ya m\u00edt\u00e1no",
- "5": "s\u00e1nz\u00e1 ya mot\u00f3b\u00e1",
- "6": "s\u00e1nz\u00e1 ya nsambo",
- "7": "s\u00e1nz\u00e1 ya mwambe",
- "8": "s\u00e1nz\u00e1 ya libwa",
- "9": "s\u00e1nz\u00e1 ya z\u00f3mi",
- "10": "s\u00e1nz\u00e1 ya z\u00f3mi na m\u0254\u030ck\u0254\u0301",
- "11": "s\u00e1nz\u00e1 ya z\u00f3mi na m\u00edbal\u00e9"
- },
- "SHORTDAY": {
- "0": "eye",
- "1": "ybo",
- "2": "mbl",
- "3": "mst",
- "4": "min",
- "5": "mtn",
- "6": "mps"
- },
- "SHORTMONTH": {
- "0": "yan",
- "1": "fbl",
- "2": "msi",
- "3": "apl",
- "4": "mai",
- "5": "yun",
- "6": "yul",
- "7": "agt",
- "8": "stb",
- "9": "\u0254tb",
- "10": "nvb",
- "11": "dsb"
- },
+ "AMPMS": [
+ "nt\u0254\u0301ng\u0254\u0301",
+ "mp\u00f3kwa"
+ ],
+ "DAY": [
+ "eyenga",
+ "mok\u0254l\u0254 mwa yambo",
+ "mok\u0254l\u0254 mwa m\u00edbal\u00e9",
+ "mok\u0254l\u0254 mwa m\u00eds\u00e1to",
+ "mok\u0254l\u0254 ya m\u00edn\u00e9i",
+ "mok\u0254l\u0254 ya m\u00edt\u00e1no",
+ "mp\u0254\u0301s\u0254"
+ ],
+ "MONTH": [
+ "s\u00e1nz\u00e1 ya yambo",
+ "s\u00e1nz\u00e1 ya m\u00edbal\u00e9",
+ "s\u00e1nz\u00e1 ya m\u00eds\u00e1to",
+ "s\u00e1nz\u00e1 ya m\u00ednei",
+ "s\u00e1nz\u00e1 ya m\u00edt\u00e1no",
+ "s\u00e1nz\u00e1 ya mot\u00f3b\u00e1",
+ "s\u00e1nz\u00e1 ya nsambo",
+ "s\u00e1nz\u00e1 ya mwambe",
+ "s\u00e1nz\u00e1 ya libwa",
+ "s\u00e1nz\u00e1 ya z\u00f3mi",
+ "s\u00e1nz\u00e1 ya z\u00f3mi na m\u0254\u030ck\u0254\u0301",
+ "s\u00e1nz\u00e1 ya z\u00f3mi na m\u00edbal\u00e9"
+ ],
+ "SHORTDAY": [
+ "eye",
+ "ybo",
+ "mbl",
+ "mst",
+ "min",
+ "mtn",
+ "mps"
+ ],
+ "SHORTMONTH": [
+ "yan",
+ "fbl",
+ "msi",
+ "apl",
+ "mai",
+ "yun",
+ "yul",
+ "agt",
+ "stb",
+ "\u0254tb",
+ "nvb",
+ "dsb"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "FrCD",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "ln",
"pluralCat": function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt-lt.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt-lt.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt-lt.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "prie\u0161piet",
- "1": "popiet"
- },
- "DAY": {
- "0": "sekmadienis",
- "1": "pirmadienis",
- "2": "antradienis",
- "3": "tre\u010diadienis",
- "4": "ketvirtadienis",
- "5": "penktadienis",
- "6": "\u0161e\u0161tadienis"
- },
- "MONTH": {
- "0": "sausio",
- "1": "vasaris",
- "2": "kovas",
- "3": "balandis",
- "4": "gegu\u017e\u0117",
- "5": "bir\u017eelis",
- "6": "liepa",
- "7": "rugpj\u016btis",
- "8": "rugs\u0117jis",
- "9": "spalis",
- "10": "lapkritis",
- "11": "gruodis"
- },
- "SHORTDAY": {
- "0": "Sk",
- "1": "Pr",
- "2": "An",
- "3": "Tr",
- "4": "Kt",
- "5": "Pn",
- "6": "\u0160t"
- },
- "SHORTMONTH": {
- "0": "Saus.",
- "1": "Vas",
- "2": "Kov.",
- "3": "Bal.",
- "4": "Geg.",
- "5": "Bir.",
- "6": "Liep.",
- "7": "Rugp.",
- "8": "Rugs.",
- "9": "Spal.",
- "10": "Lapkr.",
- "11": "Gruod."
- },
+ "AMPMS": [
+ "prie\u0161piet",
+ "popiet"
+ ],
+ "DAY": [
+ "sekmadienis",
+ "pirmadienis",
+ "antradienis",
+ "tre\u010diadienis",
+ "ketvirtadienis",
+ "penktadienis",
+ "\u0161e\u0161tadienis"
+ ],
+ "MONTH": [
+ "sausio",
+ "vasaris",
+ "kovas",
+ "balandis",
+ "gegu\u017e\u0117",
+ "bir\u017eelis",
+ "liepa",
+ "rugpj\u016btis",
+ "rugs\u0117jis",
+ "spalis",
+ "lapkritis",
+ "gruodis"
+ ],
+ "SHORTDAY": [
+ "Sk",
+ "Pr",
+ "An",
+ "Tr",
+ "Kt",
+ "Pn",
+ "\u0160t"
+ ],
+ "SHORTMONTH": [
+ "Saus.",
+ "Vas",
+ "Kov.",
+ "Bal.",
+ "Geg.",
+ "Bir.",
+ "Liep.",
+ "Rugp.",
+ "Rugs.",
+ "Spal.",
+ "Lapkr.",
+ "Gruod."
+ ],
"fullDate": "y 'm'. MMMM d 'd'., EEEE",
"longDate": "y 'm'. MMMM d 'd'.",
"medium": "y MMM d HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Lt",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "lt-lt",
"pluralCat": function (n) { if (n % 10 == 1 && (n % 100 < 11 || n % 100 > 19)) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 9 && (n % 100 < 11 || n % 100 > 19)) { return PLURAL_CATEGORY.FEW; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lt.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "prie\u0161piet",
- "1": "popiet"
- },
- "DAY": {
- "0": "sekmadienis",
- "1": "pirmadienis",
- "2": "antradienis",
- "3": "tre\u010diadienis",
- "4": "ketvirtadienis",
- "5": "penktadienis",
- "6": "\u0161e\u0161tadienis"
- },
- "MONTH": {
- "0": "sausio",
- "1": "vasaris",
- "2": "kovas",
- "3": "balandis",
- "4": "gegu\u017e\u0117",
- "5": "bir\u017eelis",
- "6": "liepa",
- "7": "rugpj\u016btis",
- "8": "rugs\u0117jis",
- "9": "spalis",
- "10": "lapkritis",
- "11": "gruodis"
- },
- "SHORTDAY": {
- "0": "Sk",
- "1": "Pr",
- "2": "An",
- "3": "Tr",
- "4": "Kt",
- "5": "Pn",
- "6": "\u0160t"
- },
- "SHORTMONTH": {
- "0": "Saus.",
- "1": "Vas",
- "2": "Kov.",
- "3": "Bal.",
- "4": "Geg.",
- "5": "Bir.",
- "6": "Liep.",
- "7": "Rugp.",
- "8": "Rugs.",
- "9": "Spal.",
- "10": "Lapkr.",
- "11": "Gruod."
- },
+ "AMPMS": [
+ "prie\u0161piet",
+ "popiet"
+ ],
+ "DAY": [
+ "sekmadienis",
+ "pirmadienis",
+ "antradienis",
+ "tre\u010diadienis",
+ "ketvirtadienis",
+ "penktadienis",
+ "\u0161e\u0161tadienis"
+ ],
+ "MONTH": [
+ "sausio",
+ "vasaris",
+ "kovas",
+ "balandis",
+ "gegu\u017e\u0117",
+ "bir\u017eelis",
+ "liepa",
+ "rugpj\u016btis",
+ "rugs\u0117jis",
+ "spalis",
+ "lapkritis",
+ "gruodis"
+ ],
+ "SHORTDAY": [
+ "Sk",
+ "Pr",
+ "An",
+ "Tr",
+ "Kt",
+ "Pn",
+ "\u0160t"
+ ],
+ "SHORTMONTH": [
+ "Saus.",
+ "Vas",
+ "Kov.",
+ "Bal.",
+ "Geg.",
+ "Bir.",
+ "Liep.",
+ "Rugp.",
+ "Rugs.",
+ "Spal.",
+ "Lapkr.",
+ "Gruod."
+ ],
"fullDate": "y 'm'. MMMM d 'd'., EEEE",
"longDate": "y 'm'. MMMM d 'd'.",
"medium": "y MMM d HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Lt",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "lt",
"pluralCat": function (n) { if (n % 10 == 1 && (n % 100 < 11 || n % 100 > 19)) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 9 && (n % 100 < 11 || n % 100 > 19)) { return PLURAL_CATEGORY.FEW; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv-lv.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv-lv.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv-lv.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "priek\u0161pusdien\u0101",
- "1": "p\u0113cpusdien\u0101"
- },
- "DAY": {
- "0": "sv\u0113tdiena",
- "1": "pirmdiena",
- "2": "otrdiena",
- "3": "tre\u0161diena",
- "4": "ceturtdiena",
- "5": "piektdiena",
- "6": "sestdiena"
- },
- "MONTH": {
- "0": "janv\u0101ris",
- "1": "febru\u0101ris",
- "2": "marts",
- "3": "apr\u012blis",
- "4": "maijs",
- "5": "j\u016bnijs",
- "6": "j\u016blijs",
- "7": "augusts",
- "8": "septembris",
- "9": "oktobris",
- "10": "novembris",
- "11": "decembris"
- },
- "SHORTDAY": {
- "0": "Sv",
- "1": "Pr",
- "2": "Ot",
- "3": "Tr",
- "4": "Ce",
- "5": "Pk",
- "6": "Se"
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "febr.",
- "2": "marts",
- "3": "apr.",
- "4": "maijs",
- "5": "j\u016bn.",
- "6": "j\u016bl.",
- "7": "aug.",
- "8": "sept.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "priek\u0161pusdien\u0101",
+ "p\u0113cpusdien\u0101"
+ ],
+ "DAY": [
+ "sv\u0113tdiena",
+ "pirmdiena",
+ "otrdiena",
+ "tre\u0161diena",
+ "ceturtdiena",
+ "piektdiena",
+ "sestdiena"
+ ],
+ "MONTH": [
+ "janv\u0101ris",
+ "febru\u0101ris",
+ "marts",
+ "apr\u012blis",
+ "maijs",
+ "j\u016bnijs",
+ "j\u016blijs",
+ "augusts",
+ "septembris",
+ "oktobris",
+ "novembris",
+ "decembris"
+ ],
+ "SHORTDAY": [
+ "Sv",
+ "Pr",
+ "Ot",
+ "Tr",
+ "Ce",
+ "Pk",
+ "Se"
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "febr.",
+ "marts",
+ "apr.",
+ "maijs",
+ "j\u016bn.",
+ "j\u016bl.",
+ "aug.",
+ "sept.",
+ "okt.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "EEEE, y. 'gada' d. MMMM",
"longDate": "y. 'gada' d. MMMM",
"medium": "y. 'gada' d. MMM HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Ls",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "lv-lv",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_lv.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "priek\u0161pusdien\u0101",
- "1": "p\u0113cpusdien\u0101"
- },
- "DAY": {
- "0": "sv\u0113tdiena",
- "1": "pirmdiena",
- "2": "otrdiena",
- "3": "tre\u0161diena",
- "4": "ceturtdiena",
- "5": "piektdiena",
- "6": "sestdiena"
- },
- "MONTH": {
- "0": "janv\u0101ris",
- "1": "febru\u0101ris",
- "2": "marts",
- "3": "apr\u012blis",
- "4": "maijs",
- "5": "j\u016bnijs",
- "6": "j\u016blijs",
- "7": "augusts",
- "8": "septembris",
- "9": "oktobris",
- "10": "novembris",
- "11": "decembris"
- },
- "SHORTDAY": {
- "0": "Sv",
- "1": "Pr",
- "2": "Ot",
- "3": "Tr",
- "4": "Ce",
- "5": "Pk",
- "6": "Se"
- },
- "SHORTMONTH": {
- "0": "janv.",
- "1": "febr.",
- "2": "marts",
- "3": "apr.",
- "4": "maijs",
- "5": "j\u016bn.",
- "6": "j\u016bl.",
- "7": "aug.",
- "8": "sept.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "priek\u0161pusdien\u0101",
+ "p\u0113cpusdien\u0101"
+ ],
+ "DAY": [
+ "sv\u0113tdiena",
+ "pirmdiena",
+ "otrdiena",
+ "tre\u0161diena",
+ "ceturtdiena",
+ "piektdiena",
+ "sestdiena"
+ ],
+ "MONTH": [
+ "janv\u0101ris",
+ "febru\u0101ris",
+ "marts",
+ "apr\u012blis",
+ "maijs",
+ "j\u016bnijs",
+ "j\u016blijs",
+ "augusts",
+ "septembris",
+ "oktobris",
+ "novembris",
+ "decembris"
+ ],
+ "SHORTDAY": [
+ "Sv",
+ "Pr",
+ "Ot",
+ "Tr",
+ "Ce",
+ "Pk",
+ "Se"
+ ],
+ "SHORTMONTH": [
+ "janv.",
+ "febr.",
+ "marts",
+ "apr.",
+ "maijs",
+ "j\u016bn.",
+ "j\u016bl.",
+ "aug.",
+ "sept.",
+ "okt.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "EEEE, y. 'gada' d. MMMM",
"longDate": "y. 'gada' d. MMMM",
"medium": "y. 'gada' d. MMM HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Ls",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "lv",
"pluralCat": function (n) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml-in.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml-in.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml-in.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0d1e\u0d3e\u0d2f\u0d31\u0d3e\u0d34\u0d4d\u0d1a",
- "1": "\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d33\u0d3e\u0d34\u0d4d\u0d1a",
- "2": "\u0d1a\u0d4a\u0d35\u0d4d\u0d35\u0d3e\u0d34\u0d4d\u0d1a",
- "3": "\u0d2c\u0d41\u0d27\u0d28\u0d3e\u0d34\u0d4d\u0d1a",
- "4": "\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d3e\u0d34\u0d4d\u0d1a",
- "5": "\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a",
- "6": "\u0d36\u0d28\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a"
- },
- "MONTH": {
- "0": "\u0d1c\u0d28\u0d41\u0d35\u0d30\u0d3f",
- "1": "\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41\u0d35\u0d30\u0d3f",
- "2": "\u0d2e\u0d3e\u0d30\u0d4d\u200d\u0d1a\u0d4d\u0d1a\u0d4d",
- "3": "\u0d0f\u0d2a\u0d4d\u0d30\u0d3f\u0d32\u0d4d\u200d",
- "4": "\u0d2e\u0d47\u0d2f\u0d4d",
- "5": "\u0d1c\u0d42\u0d23\u0d4d\u200d",
- "6": "\u0d1c\u0d42\u0d32\u0d48",
- "7": "\u0d06\u0d17\u0d38\u0d4d\u0d31\u0d4d\u0d31\u0d4d",
- "8": "\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31\u0d02\u0d2c\u0d30\u0d4d\u200d",
- "9": "\u0d12\u0d15\u0d4d\u0d1f\u0d4b\u0d2c\u0d30\u0d4d\u200d",
- "10": "\u0d28\u0d35\u0d02\u0d2c\u0d30\u0d4d\u200d",
- "11": "\u0d21\u0d3f\u0d38\u0d02\u0d2c\u0d30\u0d4d\u200d"
- },
- "SHORTDAY": {
- "0": "\u0d1e\u0d3e\u0d2f\u0d30\u0d4d\u200d",
- "1": "\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d33\u0d4d\u200d",
- "2": "\u0d1a\u0d4a\u0d35\u0d4d\u0d35",
- "3": "\u0d2c\u0d41\u0d27\u0d28\u0d4d\u200d",
- "4": "\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d02",
- "5": "\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f",
- "6": "\u0d36\u0d28\u0d3f"
- },
- "SHORTMONTH": {
- "0": "\u0d1c\u0d28\u0d41",
- "1": "\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41",
- "2": "\u0d2e\u0d3e\u0d30\u0d4d\u200d",
- "3": "\u0d0f\u0d2a\u0d4d\u0d30\u0d3f",
- "4": "\u0d2e\u0d47\u0d2f\u0d4d",
- "5": "\u0d1c\u0d42\u0d23\u0d4d\u200d",
- "6": "\u0d1c\u0d42\u0d32\u0d48",
- "7": "\u0d13\u0d17",
- "8": "\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31\u0d02",
- "9": "\u0d12\u0d15\u0d4d\u0d1f\u0d4b",
- "10": "\u0d28\u0d35\u0d02",
- "11": "\u0d21\u0d3f\u0d38\u0d02"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0d1e\u0d3e\u0d2f\u0d31\u0d3e\u0d34\u0d4d\u0d1a",
+ "\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d33\u0d3e\u0d34\u0d4d\u0d1a",
+ "\u0d1a\u0d4a\u0d35\u0d4d\u0d35\u0d3e\u0d34\u0d4d\u0d1a",
+ "\u0d2c\u0d41\u0d27\u0d28\u0d3e\u0d34\u0d4d\u0d1a",
+ "\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d3e\u0d34\u0d4d\u0d1a",
+ "\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a",
+ "\u0d36\u0d28\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a"
+ ],
+ "MONTH": [
+ "\u0d1c\u0d28\u0d41\u0d35\u0d30\u0d3f",
+ "\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41\u0d35\u0d30\u0d3f",
+ "\u0d2e\u0d3e\u0d30\u0d4d\u200d\u0d1a\u0d4d\u0d1a\u0d4d",
+ "\u0d0f\u0d2a\u0d4d\u0d30\u0d3f\u0d32\u0d4d\u200d",
+ "\u0d2e\u0d47\u0d2f\u0d4d",
+ "\u0d1c\u0d42\u0d23\u0d4d\u200d",
+ "\u0d1c\u0d42\u0d32\u0d48",
+ "\u0d06\u0d17\u0d38\u0d4d\u0d31\u0d4d\u0d31\u0d4d",
+ "\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31\u0d02\u0d2c\u0d30\u0d4d\u200d",
+ "\u0d12\u0d15\u0d4d\u0d1f\u0d4b\u0d2c\u0d30\u0d4d\u200d",
+ "\u0d28\u0d35\u0d02\u0d2c\u0d30\u0d4d\u200d",
+ "\u0d21\u0d3f\u0d38\u0d02\u0d2c\u0d30\u0d4d\u200d"
+ ],
+ "SHORTDAY": [
+ "\u0d1e\u0d3e\u0d2f\u0d30\u0d4d\u200d",
+ "\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d33\u0d4d\u200d",
+ "\u0d1a\u0d4a\u0d35\u0d4d\u0d35",
+ "\u0d2c\u0d41\u0d27\u0d28\u0d4d\u200d",
+ "\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d02",
+ "\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f",
+ "\u0d36\u0d28\u0d3f"
+ ],
+ "SHORTMONTH": [
+ "\u0d1c\u0d28\u0d41",
+ "\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41",
+ "\u0d2e\u0d3e\u0d30\u0d4d\u200d",
+ "\u0d0f\u0d2a\u0d4d\u0d30\u0d3f",
+ "\u0d2e\u0d47\u0d2f\u0d4d",
+ "\u0d1c\u0d42\u0d23\u0d4d\u200d",
+ "\u0d1c\u0d42\u0d32\u0d48",
+ "\u0d13\u0d17",
+ "\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31\u0d02",
+ "\u0d12\u0d15\u0d4d\u0d1f\u0d4b",
+ "\u0d28\u0d35\u0d02",
+ "\u0d21\u0d3f\u0d38\u0d02"
+ ],
"fullDate": "y, MMMM d, EEEE",
"longDate": "y, MMMM d",
"medium": "y, MMM d h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a4"
}
- }
+ ]
},
"id": "ml-in",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ml.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0d1e\u0d3e\u0d2f\u0d31\u0d3e\u0d34\u0d4d\u0d1a",
- "1": "\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d33\u0d3e\u0d34\u0d4d\u0d1a",
- "2": "\u0d1a\u0d4a\u0d35\u0d4d\u0d35\u0d3e\u0d34\u0d4d\u0d1a",
- "3": "\u0d2c\u0d41\u0d27\u0d28\u0d3e\u0d34\u0d4d\u0d1a",
- "4": "\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d3e\u0d34\u0d4d\u0d1a",
- "5": "\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a",
- "6": "\u0d36\u0d28\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a"
- },
- "MONTH": {
- "0": "\u0d1c\u0d28\u0d41\u0d35\u0d30\u0d3f",
- "1": "\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41\u0d35\u0d30\u0d3f",
- "2": "\u0d2e\u0d3e\u0d30\u0d4d\u200d\u0d1a\u0d4d\u0d1a\u0d4d",
- "3": "\u0d0f\u0d2a\u0d4d\u0d30\u0d3f\u0d32\u0d4d\u200d",
- "4": "\u0d2e\u0d47\u0d2f\u0d4d",
- "5": "\u0d1c\u0d42\u0d23\u0d4d\u200d",
- "6": "\u0d1c\u0d42\u0d32\u0d48",
- "7": "\u0d06\u0d17\u0d38\u0d4d\u0d31\u0d4d\u0d31\u0d4d",
- "8": "\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31\u0d02\u0d2c\u0d30\u0d4d\u200d",
- "9": "\u0d12\u0d15\u0d4d\u0d1f\u0d4b\u0d2c\u0d30\u0d4d\u200d",
- "10": "\u0d28\u0d35\u0d02\u0d2c\u0d30\u0d4d\u200d",
- "11": "\u0d21\u0d3f\u0d38\u0d02\u0d2c\u0d30\u0d4d\u200d"
- },
- "SHORTDAY": {
- "0": "\u0d1e\u0d3e\u0d2f\u0d30\u0d4d\u200d",
- "1": "\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d33\u0d4d\u200d",
- "2": "\u0d1a\u0d4a\u0d35\u0d4d\u0d35",
- "3": "\u0d2c\u0d41\u0d27\u0d28\u0d4d\u200d",
- "4": "\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d02",
- "5": "\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f",
- "6": "\u0d36\u0d28\u0d3f"
- },
- "SHORTMONTH": {
- "0": "\u0d1c\u0d28\u0d41",
- "1": "\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41",
- "2": "\u0d2e\u0d3e\u0d30\u0d4d\u200d",
- "3": "\u0d0f\u0d2a\u0d4d\u0d30\u0d3f",
- "4": "\u0d2e\u0d47\u0d2f\u0d4d",
- "5": "\u0d1c\u0d42\u0d23\u0d4d\u200d",
- "6": "\u0d1c\u0d42\u0d32\u0d48",
- "7": "\u0d13\u0d17",
- "8": "\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31\u0d02",
- "9": "\u0d12\u0d15\u0d4d\u0d1f\u0d4b",
- "10": "\u0d28\u0d35\u0d02",
- "11": "\u0d21\u0d3f\u0d38\u0d02"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0d1e\u0d3e\u0d2f\u0d31\u0d3e\u0d34\u0d4d\u0d1a",
+ "\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d33\u0d3e\u0d34\u0d4d\u0d1a",
+ "\u0d1a\u0d4a\u0d35\u0d4d\u0d35\u0d3e\u0d34\u0d4d\u0d1a",
+ "\u0d2c\u0d41\u0d27\u0d28\u0d3e\u0d34\u0d4d\u0d1a",
+ "\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d3e\u0d34\u0d4d\u0d1a",
+ "\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a",
+ "\u0d36\u0d28\u0d3f\u0d2f\u0d3e\u0d34\u0d4d\u0d1a"
+ ],
+ "MONTH": [
+ "\u0d1c\u0d28\u0d41\u0d35\u0d30\u0d3f",
+ "\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41\u0d35\u0d30\u0d3f",
+ "\u0d2e\u0d3e\u0d30\u0d4d\u200d\u0d1a\u0d4d\u0d1a\u0d4d",
+ "\u0d0f\u0d2a\u0d4d\u0d30\u0d3f\u0d32\u0d4d\u200d",
+ "\u0d2e\u0d47\u0d2f\u0d4d",
+ "\u0d1c\u0d42\u0d23\u0d4d\u200d",
+ "\u0d1c\u0d42\u0d32\u0d48",
+ "\u0d06\u0d17\u0d38\u0d4d\u0d31\u0d4d\u0d31\u0d4d",
+ "\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31\u0d02\u0d2c\u0d30\u0d4d\u200d",
+ "\u0d12\u0d15\u0d4d\u0d1f\u0d4b\u0d2c\u0d30\u0d4d\u200d",
+ "\u0d28\u0d35\u0d02\u0d2c\u0d30\u0d4d\u200d",
+ "\u0d21\u0d3f\u0d38\u0d02\u0d2c\u0d30\u0d4d\u200d"
+ ],
+ "SHORTDAY": [
+ "\u0d1e\u0d3e\u0d2f\u0d30\u0d4d\u200d",
+ "\u0d24\u0d3f\u0d19\u0d4d\u0d15\u0d33\u0d4d\u200d",
+ "\u0d1a\u0d4a\u0d35\u0d4d\u0d35",
+ "\u0d2c\u0d41\u0d27\u0d28\u0d4d\u200d",
+ "\u0d35\u0d4d\u0d2f\u0d3e\u0d34\u0d02",
+ "\u0d35\u0d46\u0d33\u0d4d\u0d33\u0d3f",
+ "\u0d36\u0d28\u0d3f"
+ ],
+ "SHORTMONTH": [
+ "\u0d1c\u0d28\u0d41",
+ "\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41",
+ "\u0d2e\u0d3e\u0d30\u0d4d\u200d",
+ "\u0d0f\u0d2a\u0d4d\u0d30\u0d3f",
+ "\u0d2e\u0d47\u0d2f\u0d4d",
+ "\u0d1c\u0d42\u0d23\u0d4d\u200d",
+ "\u0d1c\u0d42\u0d32\u0d48",
+ "\u0d13\u0d17",
+ "\u0d38\u0d46\u0d2a\u0d4d\u0d31\u0d4d\u0d31\u0d02",
+ "\u0d12\u0d15\u0d4d\u0d1f\u0d4b",
+ "\u0d28\u0d35\u0d02",
+ "\u0d21\u0d3f\u0d38\u0d02"
+ ],
"fullDate": "y, MMMM d, EEEE",
"longDate": "y, MMMM d",
"medium": "y, MMM d h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a4"
}
- }
+ ]
},
"id": "ml",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr-in.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr-in.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr-in.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0930\u0935\u093f\u0935\u093e\u0930",
- "1": "\u0938\u094b\u092e\u0935\u093e\u0930",
- "2": "\u092e\u0902\u0917\u0933\u0935\u093e\u0930",
- "3": "\u092c\u0941\u0927\u0935\u093e\u0930",
- "4": "\u0917\u0941\u0930\u0941\u0935\u093e\u0930",
- "5": "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930",
- "6": "\u0936\u0928\u093f\u0935\u093e\u0930"
- },
- "MONTH": {
- "0": "\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940",
- "1": "\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u093e\u0930\u0940",
- "2": "\u092e\u093e\u0930\u094d\u091a",
- "3": "\u090f\u092a\u094d\u0930\u093f\u0932",
- "4": "\u092e\u0947",
- "5": "\u091c\u0942\u0928",
- "6": "\u091c\u0941\u0932\u0948",
- "7": "\u0911\u0917\u0938\u094d\u091f",
- "8": "\u0938\u092a\u094d\u091f\u0947\u0902\u092c\u0930",
- "9": "\u0911\u0915\u094d\u091f\u094b\u092c\u0930",
- "10": "\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930",
- "11": "\u0921\u093f\u0938\u0947\u0902\u092c\u0930"
- },
- "SHORTDAY": {
- "0": "\u0930\u0935\u093f",
- "1": "\u0938\u094b\u092e",
- "2": "\u092e\u0902\u0917\u0933",
- "3": "\u092c\u0941\u0927",
- "4": "\u0917\u0941\u0930\u0941",
- "5": "\u0936\u0941\u0915\u094d\u0930",
- "6": "\u0936\u0928\u093f"
- },
- "SHORTMONTH": {
- "0": "\u091c\u093e\u0928\u0947",
- "1": "\u092b\u0947\u092c\u094d\u0930\u0941",
- "2": "\u092e\u093e\u0930\u094d\u091a",
- "3": "\u090f\u092a\u094d\u0930\u093f",
- "4": "\u092e\u0947",
- "5": "\u091c\u0942\u0928",
- "6": "\u091c\u0941\u0932\u0948",
- "7": "\u0911\u0917",
- "8": "\u0938\u0947\u092a\u094d\u091f\u0947\u0902",
- "9": "\u0911\u0915\u094d\u091f\u094b\u092c\u0930",
- "10": "\u0928\u094b\u0935\u094d\u0939\u0947\u0902",
- "11": "\u0921\u093f\u0938\u0947\u0902"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0930\u0935\u093f\u0935\u093e\u0930",
+ "\u0938\u094b\u092e\u0935\u093e\u0930",
+ "\u092e\u0902\u0917\u0933\u0935\u093e\u0930",
+ "\u092c\u0941\u0927\u0935\u093e\u0930",
+ "\u0917\u0941\u0930\u0941\u0935\u093e\u0930",
+ "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930",
+ "\u0936\u0928\u093f\u0935\u093e\u0930"
+ ],
+ "MONTH": [
+ "\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940",
+ "\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u093e\u0930\u0940",
+ "\u092e\u093e\u0930\u094d\u091a",
+ "\u090f\u092a\u094d\u0930\u093f\u0932",
+ "\u092e\u0947",
+ "\u091c\u0942\u0928",
+ "\u091c\u0941\u0932\u0948",
+ "\u0911\u0917\u0938\u094d\u091f",
+ "\u0938\u092a\u094d\u091f\u0947\u0902\u092c\u0930",
+ "\u0911\u0915\u094d\u091f\u094b\u092c\u0930",
+ "\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930",
+ "\u0921\u093f\u0938\u0947\u0902\u092c\u0930"
+ ],
+ "SHORTDAY": [
+ "\u0930\u0935\u093f",
+ "\u0938\u094b\u092e",
+ "\u092e\u0902\u0917\u0933",
+ "\u092c\u0941\u0927",
+ "\u0917\u0941\u0930\u0941",
+ "\u0936\u0941\u0915\u094d\u0930",
+ "\u0936\u0928\u093f"
+ ],
+ "SHORTMONTH": [
+ "\u091c\u093e\u0928\u0947",
+ "\u092b\u0947\u092c\u094d\u0930\u0941",
+ "\u092e\u093e\u0930\u094d\u091a",
+ "\u090f\u092a\u094d\u0930\u093f",
+ "\u092e\u0947",
+ "\u091c\u0942\u0928",
+ "\u091c\u0941\u0932\u0948",
+ "\u0911\u0917",
+ "\u0938\u0947\u092a\u094d\u091f\u0947\u0902",
+ "\u0911\u0915\u094d\u091f\u094b\u092c\u0930",
+ "\u0928\u094b\u0935\u094d\u0939\u0947\u0902",
+ "\u0921\u093f\u0938\u0947\u0902"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h-mm-ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "mr-in",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0930\u0935\u093f\u0935\u093e\u0930",
- "1": "\u0938\u094b\u092e\u0935\u093e\u0930",
- "2": "\u092e\u0902\u0917\u0933\u0935\u093e\u0930",
- "3": "\u092c\u0941\u0927\u0935\u093e\u0930",
- "4": "\u0917\u0941\u0930\u0941\u0935\u093e\u0930",
- "5": "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930",
- "6": "\u0936\u0928\u093f\u0935\u093e\u0930"
- },
- "MONTH": {
- "0": "\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940",
- "1": "\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u093e\u0930\u0940",
- "2": "\u092e\u093e\u0930\u094d\u091a",
- "3": "\u090f\u092a\u094d\u0930\u093f\u0932",
- "4": "\u092e\u0947",
- "5": "\u091c\u0942\u0928",
- "6": "\u091c\u0941\u0932\u0948",
- "7": "\u0911\u0917\u0938\u094d\u091f",
- "8": "\u0938\u092a\u094d\u091f\u0947\u0902\u092c\u0930",
- "9": "\u0911\u0915\u094d\u091f\u094b\u092c\u0930",
- "10": "\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930",
- "11": "\u0921\u093f\u0938\u0947\u0902\u092c\u0930"
- },
- "SHORTDAY": {
- "0": "\u0930\u0935\u093f",
- "1": "\u0938\u094b\u092e",
- "2": "\u092e\u0902\u0917\u0933",
- "3": "\u092c\u0941\u0927",
- "4": "\u0917\u0941\u0930\u0941",
- "5": "\u0936\u0941\u0915\u094d\u0930",
- "6": "\u0936\u0928\u093f"
- },
- "SHORTMONTH": {
- "0": "\u091c\u093e\u0928\u0947",
- "1": "\u092b\u0947\u092c\u094d\u0930\u0941",
- "2": "\u092e\u093e\u0930\u094d\u091a",
- "3": "\u090f\u092a\u094d\u0930\u093f",
- "4": "\u092e\u0947",
- "5": "\u091c\u0942\u0928",
- "6": "\u091c\u0941\u0932\u0948",
- "7": "\u0911\u0917",
- "8": "\u0938\u0947\u092a\u094d\u091f\u0947\u0902",
- "9": "\u0911\u0915\u094d\u091f\u094b\u092c\u0930",
- "10": "\u0928\u094b\u0935\u094d\u0939\u0947\u0902",
- "11": "\u0921\u093f\u0938\u0947\u0902"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0930\u0935\u093f\u0935\u093e\u0930",
+ "\u0938\u094b\u092e\u0935\u093e\u0930",
+ "\u092e\u0902\u0917\u0933\u0935\u093e\u0930",
+ "\u092c\u0941\u0927\u0935\u093e\u0930",
+ "\u0917\u0941\u0930\u0941\u0935\u093e\u0930",
+ "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930",
+ "\u0936\u0928\u093f\u0935\u093e\u0930"
+ ],
+ "MONTH": [
+ "\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940",
+ "\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u093e\u0930\u0940",
+ "\u092e\u093e\u0930\u094d\u091a",
+ "\u090f\u092a\u094d\u0930\u093f\u0932",
+ "\u092e\u0947",
+ "\u091c\u0942\u0928",
+ "\u091c\u0941\u0932\u0948",
+ "\u0911\u0917\u0938\u094d\u091f",
+ "\u0938\u092a\u094d\u091f\u0947\u0902\u092c\u0930",
+ "\u0911\u0915\u094d\u091f\u094b\u092c\u0930",
+ "\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930",
+ "\u0921\u093f\u0938\u0947\u0902\u092c\u0930"
+ ],
+ "SHORTDAY": [
+ "\u0930\u0935\u093f",
+ "\u0938\u094b\u092e",
+ "\u092e\u0902\u0917\u0933",
+ "\u092c\u0941\u0927",
+ "\u0917\u0941\u0930\u0941",
+ "\u0936\u0941\u0915\u094d\u0930",
+ "\u0936\u0928\u093f"
+ ],
+ "SHORTMONTH": [
+ "\u091c\u093e\u0928\u0947",
+ "\u092b\u0947\u092c\u094d\u0930\u0941",
+ "\u092e\u093e\u0930\u094d\u091a",
+ "\u090f\u092a\u094d\u0930\u093f",
+ "\u092e\u0947",
+ "\u091c\u0942\u0928",
+ "\u091c\u0941\u0932\u0948",
+ "\u0911\u0917",
+ "\u0938\u0947\u092a\u094d\u091f\u0947\u0902",
+ "\u0911\u0915\u094d\u091f\u094b\u092c\u0930",
+ "\u0928\u094b\u0935\u094d\u0939\u0947\u0902",
+ "\u0921\u093f\u0938\u0947\u0902"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h-mm-ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "mr",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms-my.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms-my.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms-my.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "PG",
- "1": "PTG"
- },
- "DAY": {
- "0": "Ahad",
- "1": "Isnin",
- "2": "Selasa",
- "3": "Rabu",
- "4": "Khamis",
- "5": "Jumaat",
- "6": "Sabtu"
- },
- "MONTH": {
- "0": "Januari",
- "1": "Februari",
- "2": "Mac",
- "3": "April",
- "4": "Mei",
- "5": "Jun",
- "6": "Julai",
- "7": "Ogos",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Disember"
- },
- "SHORTDAY": {
- "0": "Ahd",
- "1": "Isn",
- "2": "Sel",
- "3": "Rab",
- "4": "Kha",
- "5": "Jum",
- "6": "Sab"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mac",
- "3": "Apr",
- "4": "Mei",
- "5": "Jun",
- "6": "Jul",
- "7": "Ogos",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dis"
- },
+ "AMPMS": [
+ "PG",
+ "PTG"
+ ],
+ "DAY": [
+ "Ahad",
+ "Isnin",
+ "Selasa",
+ "Rabu",
+ "Khamis",
+ "Jumaat",
+ "Sabtu"
+ ],
+ "MONTH": [
+ "Januari",
+ "Februari",
+ "Mac",
+ "April",
+ "Mei",
+ "Jun",
+ "Julai",
+ "Ogos",
+ "September",
+ "Oktober",
+ "November",
+ "Disember"
+ ],
+ "SHORTDAY": [
+ "Ahd",
+ "Isn",
+ "Sel",
+ "Rab",
+ "Kha",
+ "Jum",
+ "Sab"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mac",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Ogos",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dis"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "dd/MM/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "RM",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "ms-my",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ms.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "PG",
- "1": "PTG"
- },
- "DAY": {
- "0": "Ahad",
- "1": "Isnin",
- "2": "Selasa",
- "3": "Rabu",
- "4": "Khamis",
- "5": "Jumaat",
- "6": "Sabtu"
- },
- "MONTH": {
- "0": "Januari",
- "1": "Februari",
- "2": "Mac",
- "3": "April",
- "4": "Mei",
- "5": "Jun",
- "6": "Julai",
- "7": "Ogos",
- "8": "September",
- "9": "Oktober",
- "10": "November",
- "11": "Disember"
- },
- "SHORTDAY": {
- "0": "Ahd",
- "1": "Isn",
- "2": "Sel",
- "3": "Rab",
- "4": "Kha",
- "5": "Jum",
- "6": "Sab"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mac",
- "3": "Apr",
- "4": "Mei",
- "5": "Jun",
- "6": "Jul",
- "7": "Ogos",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dis"
- },
+ "AMPMS": [
+ "PG",
+ "PTG"
+ ],
+ "DAY": [
+ "Ahad",
+ "Isnin",
+ "Selasa",
+ "Rabu",
+ "Khamis",
+ "Jumaat",
+ "Sabtu"
+ ],
+ "MONTH": [
+ "Januari",
+ "Februari",
+ "Mac",
+ "April",
+ "Mei",
+ "Jun",
+ "Julai",
+ "Ogos",
+ "September",
+ "Oktober",
+ "November",
+ "Disember"
+ ],
+ "SHORTDAY": [
+ "Ahd",
+ "Isn",
+ "Sel",
+ "Rab",
+ "Kha",
+ "Jum",
+ "Sab"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mac",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Ogos",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dis"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "dd/MM/yyyy h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "RM",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "ms",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt-mt.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt-mt.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt-mt.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "QN",
- "1": "WN"
- },
- "DAY": {
- "0": "Il-\u0126add",
- "1": "It-Tnejn",
- "2": "It-Tlieta",
- "3": "L-Erbg\u0127a",
- "4": "Il-\u0126amis",
- "5": "Il-\u0120img\u0127a",
- "6": "Is-Sibt"
- },
- "MONTH": {
- "0": "Jannar",
- "1": "Frar",
- "2": "Marzu",
- "3": "April",
- "4": "Mejju",
- "5": "\u0120unju",
- "6": "Lulju",
- "7": "Awwissu",
- "8": "Settembru",
- "9": "Ottubru",
- "10": "Novembru",
- "11": "Di\u010bembru"
- },
- "SHORTDAY": {
- "0": "\u0126ad",
- "1": "Tne",
- "2": "Tli",
- "3": "Erb",
- "4": "\u0126am",
- "5": "\u0120im",
- "6": "Sib"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Fra",
- "2": "Mar",
- "3": "Apr",
- "4": "Mej",
- "5": "\u0120un",
- "6": "Lul",
- "7": "Aww",
- "8": "Set",
- "9": "Ott",
- "10": "Nov",
- "11": "Di\u010b"
- },
+ "AMPMS": [
+ "QN",
+ "WN"
+ ],
+ "DAY": [
+ "Il-\u0126add",
+ "It-Tnejn",
+ "It-Tlieta",
+ "L-Erbg\u0127a",
+ "Il-\u0126amis",
+ "Il-\u0120img\u0127a",
+ "Is-Sibt"
+ ],
+ "MONTH": [
+ "Jannar",
+ "Frar",
+ "Marzu",
+ "April",
+ "Mejju",
+ "\u0120unju",
+ "Lulju",
+ "Awwissu",
+ "Settembru",
+ "Ottubru",
+ "Novembru",
+ "Di\u010bembru"
+ ],
+ "SHORTDAY": [
+ "\u0126ad",
+ "Tne",
+ "Tli",
+ "Erb",
+ "\u0126am",
+ "\u0120im",
+ "Sib"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Fra",
+ "Mar",
+ "Apr",
+ "Mej",
+ "\u0120un",
+ "Lul",
+ "Aww",
+ "Set",
+ "Ott",
+ "Nov",
+ "Di\u010b"
+ ],
"fullDate": "EEEE, d 'ta'\u2019 MMMM y",
"longDate": "d 'ta'\u2019 MMMM y",
"medium": "dd MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "mt-mt",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 0 || n == (n | 0) && n % 100 >= 2 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 19) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_mt.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "QN",
- "1": "WN"
- },
- "DAY": {
- "0": "Il-\u0126add",
- "1": "It-Tnejn",
- "2": "It-Tlieta",
- "3": "L-Erbg\u0127a",
- "4": "Il-\u0126amis",
- "5": "Il-\u0120img\u0127a",
- "6": "Is-Sibt"
- },
- "MONTH": {
- "0": "Jannar",
- "1": "Frar",
- "2": "Marzu",
- "3": "April",
- "4": "Mejju",
- "5": "\u0120unju",
- "6": "Lulju",
- "7": "Awwissu",
- "8": "Settembru",
- "9": "Ottubru",
- "10": "Novembru",
- "11": "Di\u010bembru"
- },
- "SHORTDAY": {
- "0": "\u0126ad",
- "1": "Tne",
- "2": "Tli",
- "3": "Erb",
- "4": "\u0126am",
- "5": "\u0120im",
- "6": "Sib"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Fra",
- "2": "Mar",
- "3": "Apr",
- "4": "Mej",
- "5": "\u0120un",
- "6": "Lul",
- "7": "Aww",
- "8": "Set",
- "9": "Ott",
- "10": "Nov",
- "11": "Di\u010b"
- },
+ "AMPMS": [
+ "QN",
+ "WN"
+ ],
+ "DAY": [
+ "Il-\u0126add",
+ "It-Tnejn",
+ "It-Tlieta",
+ "L-Erbg\u0127a",
+ "Il-\u0126amis",
+ "Il-\u0120img\u0127a",
+ "Is-Sibt"
+ ],
+ "MONTH": [
+ "Jannar",
+ "Frar",
+ "Marzu",
+ "April",
+ "Mejju",
+ "\u0120unju",
+ "Lulju",
+ "Awwissu",
+ "Settembru",
+ "Ottubru",
+ "Novembru",
+ "Di\u010bembru"
+ ],
+ "SHORTDAY": [
+ "\u0126ad",
+ "Tne",
+ "Tli",
+ "Erb",
+ "\u0126am",
+ "\u0120im",
+ "Sib"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Fra",
+ "Mar",
+ "Apr",
+ "Mej",
+ "\u0120un",
+ "Lul",
+ "Aww",
+ "Set",
+ "Ott",
+ "Nov",
+ "Di\u010b"
+ ],
"fullDate": "EEEE, d 'ta'\u2019 MMMM y",
"longDate": "d 'ta'\u2019 MMMM y",
"medium": "dd MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "mt",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 0 || n == (n | 0) && n % 100 >= 2 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n == (n | 0) && n % 100 >= 11 && n % 100 <= 19) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-cw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-cw.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-cw.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "zondag",
- "1": "maandag",
- "2": "dinsdag",
- "3": "woensdag",
- "4": "donderdag",
- "5": "vrijdag",
- "6": "zaterdag"
- },
- "MONTH": {
- "0": "januari",
- "1": "februari",
- "2": "maart",
- "3": "april",
- "4": "mei",
- "5": "juni",
- "6": "juli",
- "7": "augustus",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "zo",
- "1": "ma",
- "2": "di",
- "3": "wo",
- "4": "do",
- "5": "vr",
- "6": "za"
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "feb.",
- "2": "mrt.",
- "3": "apr.",
- "4": "mei",
- "5": "jun.",
- "6": "jul.",
- "7": "aug.",
- "8": "sep.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "zondag",
+ "maandag",
+ "dinsdag",
+ "woensdag",
+ "donderdag",
+ "vrijdag",
+ "zaterdag"
+ ],
+ "MONTH": [
+ "januari",
+ "februari",
+ "maart",
+ "april",
+ "mei",
+ "juni",
+ "juli",
+ "augustus",
+ "september",
+ "oktober",
+ "november",
+ "december"
+ ],
+ "SHORTDAY": [
+ "zo",
+ "ma",
+ "di",
+ "wo",
+ "do",
+ "vr",
+ "za"
+ ],
+ "SHORTMONTH": [
+ "jan.",
+ "feb.",
+ "mrt.",
+ "apr.",
+ "mei",
+ "jun.",
+ "jul.",
+ "aug.",
+ "sep.",
+ "okt.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "nl-cw",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-nl.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-nl.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-nl.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "zondag",
- "1": "maandag",
- "2": "dinsdag",
- "3": "woensdag",
- "4": "donderdag",
- "5": "vrijdag",
- "6": "zaterdag"
- },
- "MONTH": {
- "0": "januari",
- "1": "februari",
- "2": "maart",
- "3": "april",
- "4": "mei",
- "5": "juni",
- "6": "juli",
- "7": "augustus",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "zo",
- "1": "ma",
- "2": "di",
- "3": "wo",
- "4": "do",
- "5": "vr",
- "6": "za"
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "feb.",
- "2": "mrt.",
- "3": "apr.",
- "4": "mei",
- "5": "jun.",
- "6": "jul.",
- "7": "aug.",
- "8": "sep.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "zondag",
+ "maandag",
+ "dinsdag",
+ "woensdag",
+ "donderdag",
+ "vrijdag",
+ "zaterdag"
+ ],
+ "MONTH": [
+ "januari",
+ "februari",
+ "maart",
+ "april",
+ "mei",
+ "juni",
+ "juli",
+ "augustus",
+ "september",
+ "oktober",
+ "november",
+ "december"
+ ],
+ "SHORTDAY": [
+ "zo",
+ "ma",
+ "di",
+ "wo",
+ "do",
+ "vr",
+ "za"
+ ],
+ "SHORTMONTH": [
+ "jan.",
+ "feb.",
+ "mrt.",
+ "apr.",
+ "mei",
+ "jun.",
+ "jul.",
+ "aug.",
+ "sep.",
+ "okt.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "nl-nl",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-sx.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-sx.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl-sx.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "zondag",
- "1": "maandag",
- "2": "dinsdag",
- "3": "woensdag",
- "4": "donderdag",
- "5": "vrijdag",
- "6": "zaterdag"
- },
- "MONTH": {
- "0": "januari",
- "1": "februari",
- "2": "maart",
- "3": "april",
- "4": "mei",
- "5": "juni",
- "6": "juli",
- "7": "augustus",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "zo",
- "1": "ma",
- "2": "di",
- "3": "wo",
- "4": "do",
- "5": "vr",
- "6": "za"
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "feb.",
- "2": "mrt.",
- "3": "apr.",
- "4": "mei",
- "5": "jun.",
- "6": "jul.",
- "7": "aug.",
- "8": "sep.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "zondag",
+ "maandag",
+ "dinsdag",
+ "woensdag",
+ "donderdag",
+ "vrijdag",
+ "zaterdag"
+ ],
+ "MONTH": [
+ "januari",
+ "februari",
+ "maart",
+ "april",
+ "mei",
+ "juni",
+ "juli",
+ "augustus",
+ "september",
+ "oktober",
+ "november",
+ "december"
+ ],
+ "SHORTDAY": [
+ "zo",
+ "ma",
+ "di",
+ "wo",
+ "do",
+ "vr",
+ "za"
+ ],
+ "SHORTMONTH": [
+ "jan.",
+ "feb.",
+ "mrt.",
+ "apr.",
+ "mei",
+ "jun.",
+ "jul.",
+ "aug.",
+ "sep.",
+ "okt.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "nl-sx",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_nl.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "zondag",
- "1": "maandag",
- "2": "dinsdag",
- "3": "woensdag",
- "4": "donderdag",
- "5": "vrijdag",
- "6": "zaterdag"
- },
- "MONTH": {
- "0": "januari",
- "1": "februari",
- "2": "maart",
- "3": "april",
- "4": "mei",
- "5": "juni",
- "6": "juli",
- "7": "augustus",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "zo",
- "1": "ma",
- "2": "di",
- "3": "wo",
- "4": "do",
- "5": "vr",
- "6": "za"
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "feb.",
- "2": "mrt.",
- "3": "apr.",
- "4": "mei",
- "5": "jun.",
- "6": "jul.",
- "7": "aug.",
- "8": "sep.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "zondag",
+ "maandag",
+ "dinsdag",
+ "woensdag",
+ "donderdag",
+ "vrijdag",
+ "zaterdag"
+ ],
+ "MONTH": [
+ "januari",
+ "februari",
+ "maart",
+ "april",
+ "mei",
+ "juni",
+ "juli",
+ "augustus",
+ "september",
+ "oktober",
+ "november",
+ "december"
+ ],
+ "SHORTDAY": [
+ "zo",
+ "ma",
+ "di",
+ "wo",
+ "do",
+ "vr",
+ "za"
+ ],
+ "SHORTMONTH": [
+ "jan.",
+ "feb.",
+ "mrt.",
+ "apr.",
+ "mei",
+ "jun.",
+ "jul.",
+ "aug.",
+ "sep.",
+ "okt.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "nl",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_no.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_no.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_no.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "s\u00f8ndag",
- "1": "mandag",
- "2": "tirsdag",
- "3": "onsdag",
- "4": "torsdag",
- "5": "fredag",
- "6": "l\u00f8rdag"
- },
- "MONTH": {
- "0": "januar",
- "1": "februar",
- "2": "mars",
- "3": "april",
- "4": "mai",
- "5": "juni",
- "6": "juli",
- "7": "august",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "desember"
- },
- "SHORTDAY": {
- "0": "s\u00f8n.",
- "1": "man.",
- "2": "tir.",
- "3": "ons.",
- "4": "tor.",
- "5": "fre.",
- "6": "l\u00f8r."
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "feb.",
- "2": "mars",
- "3": "apr.",
- "4": "mai",
- "5": "juni",
- "6": "juli",
- "7": "aug.",
- "8": "sep.",
- "9": "okt.",
- "10": "nov.",
- "11": "des."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "s\u00f8ndag",
+ "mandag",
+ "tirsdag",
+ "onsdag",
+ "torsdag",
+ "fredag",
+ "l\u00f8rdag"
+ ],
+ "MONTH": [
+ "januar",
+ "februar",
+ "mars",
+ "april",
+ "mai",
+ "juni",
+ "juli",
+ "august",
+ "september",
+ "oktober",
+ "november",
+ "desember"
+ ],
+ "SHORTDAY": [
+ "s\u00f8n.",
+ "man.",
+ "tir.",
+ "ons.",
+ "tor.",
+ "fre.",
+ "l\u00f8r."
+ ],
+ "SHORTMONTH": [
+ "jan.",
+ "feb.",
+ "mars",
+ "apr.",
+ "mai",
+ "juni",
+ "juli",
+ "aug.",
+ "sep.",
+ "okt.",
+ "nov.",
+ "des."
+ ],
"fullDate": "EEEE d. MMMM y",
"longDate": "d. MMMM y",
"medium": "d. MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "kr",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "no",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or-in.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or-in.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or-in.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0b30\u0b2c\u0b3f\u0b2c\u0b3e\u0b30",
- "1": "\u0b38\u0b4b\u0b2e\u0b2c\u0b3e\u0b30",
- "2": "\u0b2e\u0b19\u0b4d\u0b17\u0b33\u0b2c\u0b3e\u0b30",
- "3": "\u0b2c\u0b41\u0b27\u0b2c\u0b3e\u0b30",
- "4": "\u0b17\u0b41\u0b30\u0b41\u0b2c\u0b3e\u0b30",
- "5": "\u0b36\u0b41\u0b15\u0b4d\u0b30\u0b2c\u0b3e\u0b30",
- "6": "\u0b36\u0b28\u0b3f\u0b2c\u0b3e\u0b30"
- },
- "MONTH": {
- "0": "\u0b1c\u0b3e\u0b28\u0b41\u0b06\u0b30\u0b40",
- "1": "\u0b2b\u0b47\u0b2c\u0b4d\u0b30\u0b41\u0b5f\u0b3e\u0b30\u0b40",
- "2": "\u0b2e\u0b3e\u0b30\u0b4d\u0b1a\u0b4d\u0b1a",
- "3": "\u0b05\u0b2a\u0b4d\u0b30\u0b47\u0b32",
- "4": "\u0b2e\u0b47",
- "5": "\u0b1c\u0b41\u0b28",
- "6": "\u0b1c\u0b41\u0b32\u0b3e\u0b07",
- "7": "\u0b05\u0b17\u0b37\u0b4d\u0b1f",
- "8": "\u0b38\u0b47\u0b2a\u0b4d\u0b1f\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
- "9": "\u0b05\u0b15\u0b4d\u0b1f\u0b4b\u0b2c\u0b30",
- "10": "\u0b28\u0b2d\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
- "11": "\u0b21\u0b3f\u0b38\u0b47\u0b2e\u0b4d\u0b2c\u0b30"
- },
- "SHORTDAY": {
- "0": "\u0b30\u0b2c\u0b3f",
- "1": "\u0b38\u0b4b\u0b2e",
- "2": "\u0b2e\u0b19\u0b4d\u0b17\u0b33",
- "3": "\u0b2c\u0b41\u0b27",
- "4": "\u0b17\u0b41\u0b30\u0b41",
- "5": "\u0b36\u0b41\u0b15\u0b4d\u0b30",
- "6": "\u0b36\u0b28\u0b3f"
- },
- "SHORTMONTH": {
- "0": "\u0b1c\u0b3e\u0b28\u0b41\u0b06\u0b30\u0b40",
- "1": "\u0b2b\u0b47\u0b2c\u0b4d\u0b30\u0b41\u0b5f\u0b3e\u0b30\u0b40",
- "2": "\u0b2e\u0b3e\u0b30\u0b4d\u0b1a\u0b4d\u0b1a",
- "3": "\u0b05\u0b2a\u0b4d\u0b30\u0b47\u0b32",
- "4": "\u0b2e\u0b47",
- "5": "\u0b1c\u0b41\u0b28",
- "6": "\u0b1c\u0b41\u0b32\u0b3e\u0b07",
- "7": "\u0b05\u0b17\u0b37\u0b4d\u0b1f",
- "8": "\u0b38\u0b47\u0b2a\u0b4d\u0b1f\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
- "9": "\u0b05\u0b15\u0b4d\u0b1f\u0b4b\u0b2c\u0b30",
- "10": "\u0b28\u0b2d\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
- "11": "\u0b21\u0b3f\u0b38\u0b47\u0b2e\u0b4d\u0b2c\u0b30"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0b30\u0b2c\u0b3f\u0b2c\u0b3e\u0b30",
+ "\u0b38\u0b4b\u0b2e\u0b2c\u0b3e\u0b30",
+ "\u0b2e\u0b19\u0b4d\u0b17\u0b33\u0b2c\u0b3e\u0b30",
+ "\u0b2c\u0b41\u0b27\u0b2c\u0b3e\u0b30",
+ "\u0b17\u0b41\u0b30\u0b41\u0b2c\u0b3e\u0b30",
+ "\u0b36\u0b41\u0b15\u0b4d\u0b30\u0b2c\u0b3e\u0b30",
+ "\u0b36\u0b28\u0b3f\u0b2c\u0b3e\u0b30"
+ ],
+ "MONTH": [
+ "\u0b1c\u0b3e\u0b28\u0b41\u0b06\u0b30\u0b40",
+ "\u0b2b\u0b47\u0b2c\u0b4d\u0b30\u0b41\u0b5f\u0b3e\u0b30\u0b40",
+ "\u0b2e\u0b3e\u0b30\u0b4d\u0b1a\u0b4d\u0b1a",
+ "\u0b05\u0b2a\u0b4d\u0b30\u0b47\u0b32",
+ "\u0b2e\u0b47",
+ "\u0b1c\u0b41\u0b28",
+ "\u0b1c\u0b41\u0b32\u0b3e\u0b07",
+ "\u0b05\u0b17\u0b37\u0b4d\u0b1f",
+ "\u0b38\u0b47\u0b2a\u0b4d\u0b1f\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
+ "\u0b05\u0b15\u0b4d\u0b1f\u0b4b\u0b2c\u0b30",
+ "\u0b28\u0b2d\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
+ "\u0b21\u0b3f\u0b38\u0b47\u0b2e\u0b4d\u0b2c\u0b30"
+ ],
+ "SHORTDAY": [
+ "\u0b30\u0b2c\u0b3f",
+ "\u0b38\u0b4b\u0b2e",
+ "\u0b2e\u0b19\u0b4d\u0b17\u0b33",
+ "\u0b2c\u0b41\u0b27",
+ "\u0b17\u0b41\u0b30\u0b41",
+ "\u0b36\u0b41\u0b15\u0b4d\u0b30",
+ "\u0b36\u0b28\u0b3f"
+ ],
+ "SHORTMONTH": [
+ "\u0b1c\u0b3e\u0b28\u0b41\u0b06\u0b30\u0b40",
+ "\u0b2b\u0b47\u0b2c\u0b4d\u0b30\u0b41\u0b5f\u0b3e\u0b30\u0b40",
+ "\u0b2e\u0b3e\u0b30\u0b4d\u0b1a\u0b4d\u0b1a",
+ "\u0b05\u0b2a\u0b4d\u0b30\u0b47\u0b32",
+ "\u0b2e\u0b47",
+ "\u0b1c\u0b41\u0b28",
+ "\u0b1c\u0b41\u0b32\u0b3e\u0b07",
+ "\u0b05\u0b17\u0b37\u0b4d\u0b1f",
+ "\u0b38\u0b47\u0b2a\u0b4d\u0b1f\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
+ "\u0b05\u0b15\u0b4d\u0b1f\u0b4b\u0b2c\u0b30",
+ "\u0b28\u0b2d\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
+ "\u0b21\u0b3f\u0b38\u0b47\u0b2e\u0b4d\u0b2c\u0b30"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "or-in",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_or.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0b30\u0b2c\u0b3f\u0b2c\u0b3e\u0b30",
- "1": "\u0b38\u0b4b\u0b2e\u0b2c\u0b3e\u0b30",
- "2": "\u0b2e\u0b19\u0b4d\u0b17\u0b33\u0b2c\u0b3e\u0b30",
- "3": "\u0b2c\u0b41\u0b27\u0b2c\u0b3e\u0b30",
- "4": "\u0b17\u0b41\u0b30\u0b41\u0b2c\u0b3e\u0b30",
- "5": "\u0b36\u0b41\u0b15\u0b4d\u0b30\u0b2c\u0b3e\u0b30",
- "6": "\u0b36\u0b28\u0b3f\u0b2c\u0b3e\u0b30"
- },
- "MONTH": {
- "0": "\u0b1c\u0b3e\u0b28\u0b41\u0b06\u0b30\u0b40",
- "1": "\u0b2b\u0b47\u0b2c\u0b4d\u0b30\u0b41\u0b5f\u0b3e\u0b30\u0b40",
- "2": "\u0b2e\u0b3e\u0b30\u0b4d\u0b1a\u0b4d\u0b1a",
- "3": "\u0b05\u0b2a\u0b4d\u0b30\u0b47\u0b32",
- "4": "\u0b2e\u0b47",
- "5": "\u0b1c\u0b41\u0b28",
- "6": "\u0b1c\u0b41\u0b32\u0b3e\u0b07",
- "7": "\u0b05\u0b17\u0b37\u0b4d\u0b1f",
- "8": "\u0b38\u0b47\u0b2a\u0b4d\u0b1f\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
- "9": "\u0b05\u0b15\u0b4d\u0b1f\u0b4b\u0b2c\u0b30",
- "10": "\u0b28\u0b2d\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
- "11": "\u0b21\u0b3f\u0b38\u0b47\u0b2e\u0b4d\u0b2c\u0b30"
- },
- "SHORTDAY": {
- "0": "\u0b30\u0b2c\u0b3f",
- "1": "\u0b38\u0b4b\u0b2e",
- "2": "\u0b2e\u0b19\u0b4d\u0b17\u0b33",
- "3": "\u0b2c\u0b41\u0b27",
- "4": "\u0b17\u0b41\u0b30\u0b41",
- "5": "\u0b36\u0b41\u0b15\u0b4d\u0b30",
- "6": "\u0b36\u0b28\u0b3f"
- },
- "SHORTMONTH": {
- "0": "\u0b1c\u0b3e\u0b28\u0b41\u0b06\u0b30\u0b40",
- "1": "\u0b2b\u0b47\u0b2c\u0b4d\u0b30\u0b41\u0b5f\u0b3e\u0b30\u0b40",
- "2": "\u0b2e\u0b3e\u0b30\u0b4d\u0b1a\u0b4d\u0b1a",
- "3": "\u0b05\u0b2a\u0b4d\u0b30\u0b47\u0b32",
- "4": "\u0b2e\u0b47",
- "5": "\u0b1c\u0b41\u0b28",
- "6": "\u0b1c\u0b41\u0b32\u0b3e\u0b07",
- "7": "\u0b05\u0b17\u0b37\u0b4d\u0b1f",
- "8": "\u0b38\u0b47\u0b2a\u0b4d\u0b1f\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
- "9": "\u0b05\u0b15\u0b4d\u0b1f\u0b4b\u0b2c\u0b30",
- "10": "\u0b28\u0b2d\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
- "11": "\u0b21\u0b3f\u0b38\u0b47\u0b2e\u0b4d\u0b2c\u0b30"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0b30\u0b2c\u0b3f\u0b2c\u0b3e\u0b30",
+ "\u0b38\u0b4b\u0b2e\u0b2c\u0b3e\u0b30",
+ "\u0b2e\u0b19\u0b4d\u0b17\u0b33\u0b2c\u0b3e\u0b30",
+ "\u0b2c\u0b41\u0b27\u0b2c\u0b3e\u0b30",
+ "\u0b17\u0b41\u0b30\u0b41\u0b2c\u0b3e\u0b30",
+ "\u0b36\u0b41\u0b15\u0b4d\u0b30\u0b2c\u0b3e\u0b30",
+ "\u0b36\u0b28\u0b3f\u0b2c\u0b3e\u0b30"
+ ],
+ "MONTH": [
+ "\u0b1c\u0b3e\u0b28\u0b41\u0b06\u0b30\u0b40",
+ "\u0b2b\u0b47\u0b2c\u0b4d\u0b30\u0b41\u0b5f\u0b3e\u0b30\u0b40",
+ "\u0b2e\u0b3e\u0b30\u0b4d\u0b1a\u0b4d\u0b1a",
+ "\u0b05\u0b2a\u0b4d\u0b30\u0b47\u0b32",
+ "\u0b2e\u0b47",
+ "\u0b1c\u0b41\u0b28",
+ "\u0b1c\u0b41\u0b32\u0b3e\u0b07",
+ "\u0b05\u0b17\u0b37\u0b4d\u0b1f",
+ "\u0b38\u0b47\u0b2a\u0b4d\u0b1f\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
+ "\u0b05\u0b15\u0b4d\u0b1f\u0b4b\u0b2c\u0b30",
+ "\u0b28\u0b2d\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
+ "\u0b21\u0b3f\u0b38\u0b47\u0b2e\u0b4d\u0b2c\u0b30"
+ ],
+ "SHORTDAY": [
+ "\u0b30\u0b2c\u0b3f",
+ "\u0b38\u0b4b\u0b2e",
+ "\u0b2e\u0b19\u0b4d\u0b17\u0b33",
+ "\u0b2c\u0b41\u0b27",
+ "\u0b17\u0b41\u0b30\u0b41",
+ "\u0b36\u0b41\u0b15\u0b4d\u0b30",
+ "\u0b36\u0b28\u0b3f"
+ ],
+ "SHORTMONTH": [
+ "\u0b1c\u0b3e\u0b28\u0b41\u0b06\u0b30\u0b40",
+ "\u0b2b\u0b47\u0b2c\u0b4d\u0b30\u0b41\u0b5f\u0b3e\u0b30\u0b40",
+ "\u0b2e\u0b3e\u0b30\u0b4d\u0b1a\u0b4d\u0b1a",
+ "\u0b05\u0b2a\u0b4d\u0b30\u0b47\u0b32",
+ "\u0b2e\u0b47",
+ "\u0b1c\u0b41\u0b28",
+ "\u0b1c\u0b41\u0b32\u0b3e\u0b07",
+ "\u0b05\u0b17\u0b37\u0b4d\u0b1f",
+ "\u0b38\u0b47\u0b2a\u0b4d\u0b1f\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
+ "\u0b05\u0b15\u0b4d\u0b1f\u0b4b\u0b2c\u0b30",
+ "\u0b28\u0b2d\u0b47\u0b2e\u0b4d\u0b2c\u0b30",
+ "\u0b21\u0b3f\u0b38\u0b47\u0b2e\u0b4d\u0b2c\u0b30"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "or",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl-pl.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl-pl.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl-pl.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "niedziela",
- "1": "poniedzia\u0142ek",
- "2": "wtorek",
- "3": "\u015broda",
- "4": "czwartek",
- "5": "pi\u0105tek",
- "6": "sobota"
- },
- "MONTH": {
- "0": "stycznia",
- "1": "lutego",
- "2": "marca",
- "3": "kwietnia",
- "4": "maja",
- "5": "czerwca",
- "6": "lipca",
- "7": "sierpnia",
- "8": "wrze\u015bnia",
- "9": "pa\u017adziernika",
- "10": "listopada",
- "11": "grudnia"
- },
- "SHORTDAY": {
- "0": "niedz.",
- "1": "pon.",
- "2": "wt.",
- "3": "\u015br.",
- "4": "czw.",
- "5": "pt.",
- "6": "sob."
- },
- "SHORTMONTH": {
- "0": "sty",
- "1": "lut",
- "2": "mar",
- "3": "kwi",
- "4": "maj",
- "5": "cze",
- "6": "lip",
- "7": "sie",
- "8": "wrz",
- "9": "pa\u017a",
- "10": "lis",
- "11": "gru"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "niedziela",
+ "poniedzia\u0142ek",
+ "wtorek",
+ "\u015broda",
+ "czwartek",
+ "pi\u0105tek",
+ "sobota"
+ ],
+ "MONTH": [
+ "stycznia",
+ "lutego",
+ "marca",
+ "kwietnia",
+ "maja",
+ "czerwca",
+ "lipca",
+ "sierpnia",
+ "wrze\u015bnia",
+ "pa\u017adziernika",
+ "listopada",
+ "grudnia"
+ ],
+ "SHORTDAY": [
+ "niedz.",
+ "pon.",
+ "wt.",
+ "\u015br.",
+ "czw.",
+ "pt.",
+ "sob."
+ ],
+ "SHORTMONTH": [
+ "sty",
+ "lut",
+ "mar",
+ "kwi",
+ "maj",
+ "cze",
+ "lip",
+ "sie",
+ "wrz",
+ "pa\u017a",
+ "lis",
+ "gru"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "z\u0142",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "pl-pl",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n != 1 && (n % 10 == 0 || n % 10 == 1) || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 12 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pl.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "niedziela",
- "1": "poniedzia\u0142ek",
- "2": "wtorek",
- "3": "\u015broda",
- "4": "czwartek",
- "5": "pi\u0105tek",
- "6": "sobota"
- },
- "MONTH": {
- "0": "stycznia",
- "1": "lutego",
- "2": "marca",
- "3": "kwietnia",
- "4": "maja",
- "5": "czerwca",
- "6": "lipca",
- "7": "sierpnia",
- "8": "wrze\u015bnia",
- "9": "pa\u017adziernika",
- "10": "listopada",
- "11": "grudnia"
- },
- "SHORTDAY": {
- "0": "niedz.",
- "1": "pon.",
- "2": "wt.",
- "3": "\u015br.",
- "4": "czw.",
- "5": "pt.",
- "6": "sob."
- },
- "SHORTMONTH": {
- "0": "sty",
- "1": "lut",
- "2": "mar",
- "3": "kwi",
- "4": "maj",
- "5": "cze",
- "6": "lip",
- "7": "sie",
- "8": "wrz",
- "9": "pa\u017a",
- "10": "lis",
- "11": "gru"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "niedziela",
+ "poniedzia\u0142ek",
+ "wtorek",
+ "\u015broda",
+ "czwartek",
+ "pi\u0105tek",
+ "sobota"
+ ],
+ "MONTH": [
+ "stycznia",
+ "lutego",
+ "marca",
+ "kwietnia",
+ "maja",
+ "czerwca",
+ "lipca",
+ "sierpnia",
+ "wrze\u015bnia",
+ "pa\u017adziernika",
+ "listopada",
+ "grudnia"
+ ],
+ "SHORTDAY": [
+ "niedz.",
+ "pon.",
+ "wt.",
+ "\u015br.",
+ "czw.",
+ "pt.",
+ "sob."
+ ],
+ "SHORTMONTH": [
+ "sty",
+ "lut",
+ "mar",
+ "kwi",
+ "maj",
+ "cze",
+ "lip",
+ "sie",
+ "wrz",
+ "pa\u017a",
+ "lis",
+ "gru"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "z\u0142",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "pl",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n != 1 && (n % 10 == 0 || n % 10 == 1) || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 12 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-br.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-br.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-br.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "domingo",
- "1": "segunda-feira",
- "2": "ter\u00e7a-feira",
- "3": "quarta-feira",
- "4": "quinta-feira",
- "5": "sexta-feira",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "janeiro",
- "1": "fevereiro",
- "2": "mar\u00e7o",
- "3": "abril",
- "4": "maio",
- "5": "junho",
- "6": "julho",
- "7": "agosto",
- "8": "setembro",
- "9": "outubro",
- "10": "novembro",
- "11": "dezembro"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "seg",
- "2": "ter",
- "3": "qua",
- "4": "qui",
- "5": "sex",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "fev",
- "2": "mar",
- "3": "abr",
- "4": "mai",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "set",
- "9": "out",
- "10": "nov",
- "11": "dez"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "domingo",
+ "segunda-feira",
+ "ter\u00e7a-feira",
+ "quarta-feira",
+ "quinta-feira",
+ "sexta-feira",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "janeiro",
+ "fevereiro",
+ "mar\u00e7o",
+ "abril",
+ "maio",
+ "junho",
+ "julho",
+ "agosto",
+ "setembro",
+ "outubro",
+ "novembro",
+ "dezembro"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "seg",
+ "ter",
+ "qua",
+ "qui",
+ "sex",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "jan",
+ "fev",
+ "mar",
+ "abr",
+ "mai",
+ "jun",
+ "jul",
+ "ago",
+ "set",
+ "out",
+ "nov",
+ "dez"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "R$",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "pt-br",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-pt.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-pt.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt-pt.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "a.m.",
- "1": "p.m."
- },
- "DAY": {
- "0": "Domingo",
- "1": "Segunda-feira",
- "2": "Ter\u00e7a-feira",
- "3": "Quarta-feira",
- "4": "Quinta-feira",
- "5": "Sexta-feira",
- "6": "S\u00e1bado"
- },
- "MONTH": {
- "0": "Janeiro",
- "1": "Fevereiro",
- "2": "Mar\u00e7o",
- "3": "Abril",
- "4": "Maio",
- "5": "Junho",
- "6": "Julho",
- "7": "Agosto",
- "8": "Setembro",
- "9": "Outubro",
- "10": "Novembro",
- "11": "Dezembro"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "seg",
- "2": "ter",
- "3": "qua",
- "4": "qui",
- "5": "sex",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Fev",
- "2": "Mar",
- "3": "Abr",
- "4": "Mai",
- "5": "Jun",
- "6": "Jul",
- "7": "Ago",
- "8": "Set",
- "9": "Out",
- "10": "Nov",
- "11": "Dez"
- },
+ "AMPMS": [
+ "a.m.",
+ "p.m."
+ ],
+ "DAY": [
+ "Domingo",
+ "Segunda-feira",
+ "Ter\u00e7a-feira",
+ "Quarta-feira",
+ "Quinta-feira",
+ "Sexta-feira",
+ "S\u00e1bado"
+ ],
+ "MONTH": [
+ "Janeiro",
+ "Fevereiro",
+ "Mar\u00e7o",
+ "Abril",
+ "Maio",
+ "Junho",
+ "Julho",
+ "Agosto",
+ "Setembro",
+ "Outubro",
+ "Novembro",
+ "Dezembro"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "seg",
+ "ter",
+ "qua",
+ "qui",
+ "sex",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Fev",
+ "Mar",
+ "Abr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Ago",
+ "Set",
+ "Out",
+ "Nov",
+ "Dez"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "pt-pt",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_pt.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "domingo",
- "1": "segunda-feira",
- "2": "ter\u00e7a-feira",
- "3": "quarta-feira",
- "4": "quinta-feira",
- "5": "sexta-feira",
- "6": "s\u00e1bado"
- },
- "MONTH": {
- "0": "janeiro",
- "1": "fevereiro",
- "2": "mar\u00e7o",
- "3": "abril",
- "4": "maio",
- "5": "junho",
- "6": "julho",
- "7": "agosto",
- "8": "setembro",
- "9": "outubro",
- "10": "novembro",
- "11": "dezembro"
- },
- "SHORTDAY": {
- "0": "dom",
- "1": "seg",
- "2": "ter",
- "3": "qua",
- "4": "qui",
- "5": "sex",
- "6": "s\u00e1b"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "fev",
- "2": "mar",
- "3": "abr",
- "4": "mai",
- "5": "jun",
- "6": "jul",
- "7": "ago",
- "8": "set",
- "9": "out",
- "10": "nov",
- "11": "dez"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "domingo",
+ "segunda-feira",
+ "ter\u00e7a-feira",
+ "quarta-feira",
+ "quinta-feira",
+ "sexta-feira",
+ "s\u00e1bado"
+ ],
+ "MONTH": [
+ "janeiro",
+ "fevereiro",
+ "mar\u00e7o",
+ "abril",
+ "maio",
+ "junho",
+ "julho",
+ "agosto",
+ "setembro",
+ "outubro",
+ "novembro",
+ "dezembro"
+ ],
+ "SHORTDAY": [
+ "dom",
+ "seg",
+ "ter",
+ "qua",
+ "qui",
+ "sex",
+ "s\u00e1b"
+ ],
+ "SHORTMONTH": [
+ "jan",
+ "fev",
+ "mar",
+ "abr",
+ "mai",
+ "jun",
+ "jul",
+ "ago",
+ "set",
+ "out",
+ "nov",
+ "dez"
+ ],
"fullDate": "EEEE, d 'de' MMMM 'de' y",
"longDate": "d 'de' MMMM 'de' y",
"medium": "dd/MM/yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "R$",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "pt",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro-ro.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro-ro.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro-ro.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "duminic\u0103",
- "1": "luni",
- "2": "mar\u021bi",
- "3": "miercuri",
- "4": "joi",
- "5": "vineri",
- "6": "s\u00e2mb\u0103t\u0103"
- },
- "MONTH": {
- "0": "ianuarie",
- "1": "februarie",
- "2": "martie",
- "3": "aprilie",
- "4": "mai",
- "5": "iunie",
- "6": "iulie",
- "7": "august",
- "8": "septembrie",
- "9": "octombrie",
- "10": "noiembrie",
- "11": "decembrie"
- },
- "SHORTDAY": {
- "0": "Du",
- "1": "Lu",
- "2": "Ma",
- "3": "Mi",
- "4": "Jo",
- "5": "Vi",
- "6": "S\u00e2"
- },
- "SHORTMONTH": {
- "0": "ian.",
- "1": "feb.",
- "2": "mar.",
- "3": "apr.",
- "4": "mai",
- "5": "iun.",
- "6": "iul.",
- "7": "aug.",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "duminic\u0103",
+ "luni",
+ "mar\u021bi",
+ "miercuri",
+ "joi",
+ "vineri",
+ "s\u00e2mb\u0103t\u0103"
+ ],
+ "MONTH": [
+ "ianuarie",
+ "februarie",
+ "martie",
+ "aprilie",
+ "mai",
+ "iunie",
+ "iulie",
+ "august",
+ "septembrie",
+ "octombrie",
+ "noiembrie",
+ "decembrie"
+ ],
+ "SHORTDAY": [
+ "Du",
+ "Lu",
+ "Ma",
+ "Mi",
+ "Jo",
+ "Vi",
+ "S\u00e2"
+ ],
+ "SHORTMONTH": [
+ "ian.",
+ "feb.",
+ "mar.",
+ "apr.",
+ "mai",
+ "iun.",
+ "iul.",
+ "aug.",
+ "sept.",
+ "oct.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "RON",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "ro-ro",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 0 || n != 1 && n == (n | 0) && n % 100 >= 1 && n % 100 <= 19) { return PLURAL_CATEGORY.FEW; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ro.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "duminic\u0103",
- "1": "luni",
- "2": "mar\u021bi",
- "3": "miercuri",
- "4": "joi",
- "5": "vineri",
- "6": "s\u00e2mb\u0103t\u0103"
- },
- "MONTH": {
- "0": "ianuarie",
- "1": "februarie",
- "2": "martie",
- "3": "aprilie",
- "4": "mai",
- "5": "iunie",
- "6": "iulie",
- "7": "august",
- "8": "septembrie",
- "9": "octombrie",
- "10": "noiembrie",
- "11": "decembrie"
- },
- "SHORTDAY": {
- "0": "Du",
- "1": "Lu",
- "2": "Ma",
- "3": "Mi",
- "4": "Jo",
- "5": "Vi",
- "6": "S\u00e2"
- },
- "SHORTMONTH": {
- "0": "ian.",
- "1": "feb.",
- "2": "mar.",
- "3": "apr.",
- "4": "mai",
- "5": "iun.",
- "6": "iul.",
- "7": "aug.",
- "8": "sept.",
- "9": "oct.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "duminic\u0103",
+ "luni",
+ "mar\u021bi",
+ "miercuri",
+ "joi",
+ "vineri",
+ "s\u00e2mb\u0103t\u0103"
+ ],
+ "MONTH": [
+ "ianuarie",
+ "februarie",
+ "martie",
+ "aprilie",
+ "mai",
+ "iunie",
+ "iulie",
+ "august",
+ "septembrie",
+ "octombrie",
+ "noiembrie",
+ "decembrie"
+ ],
+ "SHORTDAY": [
+ "Du",
+ "Lu",
+ "Ma",
+ "Mi",
+ "Jo",
+ "Vi",
+ "S\u00e2"
+ ],
+ "SHORTMONTH": [
+ "ian.",
+ "feb.",
+ "mar.",
+ "apr.",
+ "mai",
+ "iun.",
+ "iul.",
+ "aug.",
+ "sept.",
+ "oct.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "dd.MM.yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "RON",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "ro",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 0 || n != 1 && n == (n | 0) && n % 100 >= 1 && n % 100 <= 19) { return PLURAL_CATEGORY.FEW; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-ru.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-ru.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru-ru.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0434\u043e \u043f\u043e\u043b\u0443\u0434\u043d\u044f",
- "1": "\u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0434\u043d\u044f"
- },
- "DAY": {
- "0": "\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435",
- "1": "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a",
- "2": "\u0432\u0442\u043e\u0440\u043d\u0438\u043a",
- "3": "\u0441\u0440\u0435\u0434\u0430",
- "4": "\u0447\u0435\u0442\u0432\u0435\u0440\u0433",
- "5": "\u043f\u044f\u0442\u043d\u0438\u0446\u0430",
- "6": "\u0441\u0443\u0431\u0431\u043e\u0442\u0430"
- },
- "MONTH": {
- "0": "\u044f\u043d\u0432\u0430\u0440\u044f",
- "1": "\u0444\u0435\u0432\u0440\u0430\u043b\u044f",
- "2": "\u043c\u0430\u0440\u0442\u0430",
- "3": "\u0430\u043f\u0440\u0435\u043b\u044f",
- "4": "\u043c\u0430\u044f",
- "5": "\u0438\u044e\u043d\u044f",
- "6": "\u0438\u044e\u043b\u044f",
- "7": "\u0430\u0432\u0433\u0443\u0441\u0442\u0430",
- "8": "\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f",
- "9": "\u043e\u043a\u0442\u044f\u0431\u0440\u044f",
- "10": "\u043d\u043e\u044f\u0431\u0440\u044f",
- "11": "\u0434\u0435\u043a\u0430\u0431\u0440\u044f"
- },
- "SHORTDAY": {
- "0": "\u0432\u0441",
- "1": "\u043f\u043d",
- "2": "\u0432\u0442",
- "3": "\u0441\u0440",
- "4": "\u0447\u0442",
- "5": "\u043f\u0442",
- "6": "\u0441\u0431"
- },
- "SHORTMONTH": {
- "0": "\u044f\u043d\u0432.",
- "1": "\u0444\u0435\u0432\u0440.",
- "2": "\u043c\u0430\u0440\u0442\u0430",
- "3": "\u0430\u043f\u0440.",
- "4": "\u043c\u0430\u044f",
- "5": "\u0438\u044e\u043d\u044f",
- "6": "\u0438\u044e\u043b\u044f",
- "7": "\u0430\u0432\u0433.",
- "8": "\u0441\u0435\u043d\u0442.",
- "9": "\u043e\u043a\u0442.",
- "10": "\u043d\u043e\u044f\u0431.",
- "11": "\u0434\u0435\u043a."
- },
+ "AMPMS": [
+ "\u0434\u043e \u043f\u043e\u043b\u0443\u0434\u043d\u044f",
+ "\u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0434\u043d\u044f"
+ ],
+ "DAY": [
+ "\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435",
+ "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a",
+ "\u0432\u0442\u043e\u0440\u043d\u0438\u043a",
+ "\u0441\u0440\u0435\u0434\u0430",
+ "\u0447\u0435\u0442\u0432\u0435\u0440\u0433",
+ "\u043f\u044f\u0442\u043d\u0438\u0446\u0430",
+ "\u0441\u0443\u0431\u0431\u043e\u0442\u0430"
+ ],
+ "MONTH": [
+ "\u044f\u043d\u0432\u0430\u0440\u044f",
+ "\u0444\u0435\u0432\u0440\u0430\u043b\u044f",
+ "\u043c\u0430\u0440\u0442\u0430",
+ "\u0430\u043f\u0440\u0435\u043b\u044f",
+ "\u043c\u0430\u044f",
+ "\u0438\u044e\u043d\u044f",
+ "\u0438\u044e\u043b\u044f",
+ "\u0430\u0432\u0433\u0443\u0441\u0442\u0430",
+ "\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f",
+ "\u043e\u043a\u0442\u044f\u0431\u0440\u044f",
+ "\u043d\u043e\u044f\u0431\u0440\u044f",
+ "\u0434\u0435\u043a\u0430\u0431\u0440\u044f"
+ ],
+ "SHORTDAY": [
+ "\u0432\u0441",
+ "\u043f\u043d",
+ "\u0432\u0442",
+ "\u0441\u0440",
+ "\u0447\u0442",
+ "\u043f\u0442",
+ "\u0441\u0431"
+ ],
+ "SHORTMONTH": [
+ "\u044f\u043d\u0432.",
+ "\u0444\u0435\u0432\u0440.",
+ "\u043c\u0430\u0440\u0442\u0430",
+ "\u0430\u043f\u0440.",
+ "\u043c\u0430\u044f",
+ "\u0438\u044e\u043d\u044f",
+ "\u0438\u044e\u043b\u044f",
+ "\u0430\u0432\u0433.",
+ "\u0441\u0435\u043d\u0442.",
+ "\u043e\u043a\u0442.",
+ "\u043d\u043e\u044f\u0431.",
+ "\u0434\u0435\u043a."
+ ],
"fullDate": "EEEE, d MMMM y\u00a0'\u0433'.",
"longDate": "d MMMM y\u00a0'\u0433'.",
"medium": "dd.MM.yyyy H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u0440\u0443\u0431.",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "ru-ru",
"pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ru.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0434\u043e \u043f\u043e\u043b\u0443\u0434\u043d\u044f",
- "1": "\u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0434\u043d\u044f"
- },
- "DAY": {
- "0": "\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435",
- "1": "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a",
- "2": "\u0432\u0442\u043e\u0440\u043d\u0438\u043a",
- "3": "\u0441\u0440\u0435\u0434\u0430",
- "4": "\u0447\u0435\u0442\u0432\u0435\u0440\u0433",
- "5": "\u043f\u044f\u0442\u043d\u0438\u0446\u0430",
- "6": "\u0441\u0443\u0431\u0431\u043e\u0442\u0430"
- },
- "MONTH": {
- "0": "\u044f\u043d\u0432\u0430\u0440\u044f",
- "1": "\u0444\u0435\u0432\u0440\u0430\u043b\u044f",
- "2": "\u043c\u0430\u0440\u0442\u0430",
- "3": "\u0430\u043f\u0440\u0435\u043b\u044f",
- "4": "\u043c\u0430\u044f",
- "5": "\u0438\u044e\u043d\u044f",
- "6": "\u0438\u044e\u043b\u044f",
- "7": "\u0430\u0432\u0433\u0443\u0441\u0442\u0430",
- "8": "\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f",
- "9": "\u043e\u043a\u0442\u044f\u0431\u0440\u044f",
- "10": "\u043d\u043e\u044f\u0431\u0440\u044f",
- "11": "\u0434\u0435\u043a\u0430\u0431\u0440\u044f"
- },
- "SHORTDAY": {
- "0": "\u0432\u0441",
- "1": "\u043f\u043d",
- "2": "\u0432\u0442",
- "3": "\u0441\u0440",
- "4": "\u0447\u0442",
- "5": "\u043f\u0442",
- "6": "\u0441\u0431"
- },
- "SHORTMONTH": {
- "0": "\u044f\u043d\u0432.",
- "1": "\u0444\u0435\u0432\u0440.",
- "2": "\u043c\u0430\u0440\u0442\u0430",
- "3": "\u0430\u043f\u0440.",
- "4": "\u043c\u0430\u044f",
- "5": "\u0438\u044e\u043d\u044f",
- "6": "\u0438\u044e\u043b\u044f",
- "7": "\u0430\u0432\u0433.",
- "8": "\u0441\u0435\u043d\u0442.",
- "9": "\u043e\u043a\u0442.",
- "10": "\u043d\u043e\u044f\u0431.",
- "11": "\u0434\u0435\u043a."
- },
+ "AMPMS": [
+ "\u0434\u043e \u043f\u043e\u043b\u0443\u0434\u043d\u044f",
+ "\u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0434\u043d\u044f"
+ ],
+ "DAY": [
+ "\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435",
+ "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a",
+ "\u0432\u0442\u043e\u0440\u043d\u0438\u043a",
+ "\u0441\u0440\u0435\u0434\u0430",
+ "\u0447\u0435\u0442\u0432\u0435\u0440\u0433",
+ "\u043f\u044f\u0442\u043d\u0438\u0446\u0430",
+ "\u0441\u0443\u0431\u0431\u043e\u0442\u0430"
+ ],
+ "MONTH": [
+ "\u044f\u043d\u0432\u0430\u0440\u044f",
+ "\u0444\u0435\u0432\u0440\u0430\u043b\u044f",
+ "\u043c\u0430\u0440\u0442\u0430",
+ "\u0430\u043f\u0440\u0435\u043b\u044f",
+ "\u043c\u0430\u044f",
+ "\u0438\u044e\u043d\u044f",
+ "\u0438\u044e\u043b\u044f",
+ "\u0430\u0432\u0433\u0443\u0441\u0442\u0430",
+ "\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f",
+ "\u043e\u043a\u0442\u044f\u0431\u0440\u044f",
+ "\u043d\u043e\u044f\u0431\u0440\u044f",
+ "\u0434\u0435\u043a\u0430\u0431\u0440\u044f"
+ ],
+ "SHORTDAY": [
+ "\u0432\u0441",
+ "\u043f\u043d",
+ "\u0432\u0442",
+ "\u0441\u0440",
+ "\u0447\u0442",
+ "\u043f\u0442",
+ "\u0441\u0431"
+ ],
+ "SHORTMONTH": [
+ "\u044f\u043d\u0432.",
+ "\u0444\u0435\u0432\u0440.",
+ "\u043c\u0430\u0440\u0442\u0430",
+ "\u0430\u043f\u0440.",
+ "\u043c\u0430\u044f",
+ "\u0438\u044e\u043d\u044f",
+ "\u0438\u044e\u043b\u044f",
+ "\u0430\u0432\u0433.",
+ "\u0441\u0435\u043d\u0442.",
+ "\u043e\u043a\u0442.",
+ "\u043d\u043e\u044f\u0431.",
+ "\u0434\u0435\u043a."
+ ],
"fullDate": "EEEE, d MMMM y\u00a0'\u0433'.",
"longDate": "d MMMM y\u00a0'\u0433'.",
"medium": "dd.MM.yyyy H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u0440\u0443\u0431.",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "ru",
"pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk-sk.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk-sk.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk-sk.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "dopoludnia",
- "1": "popoludn\u00ed"
- },
- "DAY": {
- "0": "nede\u013ea",
- "1": "pondelok",
- "2": "utorok",
- "3": "streda",
- "4": "\u0161tvrtok",
- "5": "piatok",
- "6": "sobota"
- },
- "MONTH": {
- "0": "janu\u00e1ra",
- "1": "febru\u00e1ra",
- "2": "marca",
- "3": "apr\u00edla",
- "4": "m\u00e1ja",
- "5": "j\u00fana",
- "6": "j\u00fala",
- "7": "augusta",
- "8": "septembra",
- "9": "okt\u00f3bra",
- "10": "novembra",
- "11": "decembra"
- },
- "SHORTDAY": {
- "0": "ne",
- "1": "po",
- "2": "ut",
- "3": "st",
- "4": "\u0161t",
- "5": "pi",
- "6": "so"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "m\u00e1j",
- "5": "j\u00fan",
- "6": "j\u00fal",
- "7": "aug",
- "8": "sep",
- "9": "okt",
- "10": "nov",
- "11": "dec"
- },
+ "AMPMS": [
+ "dopoludnia",
+ "popoludn\u00ed"
+ ],
+ "DAY": [
+ "nede\u013ea",
+ "pondelok",
+ "utorok",
+ "streda",
+ "\u0161tvrtok",
+ "piatok",
+ "sobota"
+ ],
+ "MONTH": [
+ "janu\u00e1ra",
+ "febru\u00e1ra",
+ "marca",
+ "apr\u00edla",
+ "m\u00e1ja",
+ "j\u00fana",
+ "j\u00fala",
+ "augusta",
+ "septembra",
+ "okt\u00f3bra",
+ "novembra",
+ "decembra"
+ ],
+ "SHORTDAY": [
+ "ne",
+ "po",
+ "ut",
+ "st",
+ "\u0161t",
+ "pi",
+ "so"
+ ],
+ "SHORTMONTH": [
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "m\u00e1j",
+ "j\u00fan",
+ "j\u00fal",
+ "aug",
+ "sep",
+ "okt",
+ "nov",
+ "dec"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "d.M.yyyy H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "sk-sk",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n >= 2 && n <= 4) { return PLURAL_CATEGORY.FEW; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sk.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "dopoludnia",
- "1": "popoludn\u00ed"
- },
- "DAY": {
- "0": "nede\u013ea",
- "1": "pondelok",
- "2": "utorok",
- "3": "streda",
- "4": "\u0161tvrtok",
- "5": "piatok",
- "6": "sobota"
- },
- "MONTH": {
- "0": "janu\u00e1ra",
- "1": "febru\u00e1ra",
- "2": "marca",
- "3": "apr\u00edla",
- "4": "m\u00e1ja",
- "5": "j\u00fana",
- "6": "j\u00fala",
- "7": "augusta",
- "8": "septembra",
- "9": "okt\u00f3bra",
- "10": "novembra",
- "11": "decembra"
- },
- "SHORTDAY": {
- "0": "ne",
- "1": "po",
- "2": "ut",
- "3": "st",
- "4": "\u0161t",
- "5": "pi",
- "6": "so"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "m\u00e1j",
- "5": "j\u00fan",
- "6": "j\u00fal",
- "7": "aug",
- "8": "sep",
- "9": "okt",
- "10": "nov",
- "11": "dec"
- },
+ "AMPMS": [
+ "dopoludnia",
+ "popoludn\u00ed"
+ ],
+ "DAY": [
+ "nede\u013ea",
+ "pondelok",
+ "utorok",
+ "streda",
+ "\u0161tvrtok",
+ "piatok",
+ "sobota"
+ ],
+ "MONTH": [
+ "janu\u00e1ra",
+ "febru\u00e1ra",
+ "marca",
+ "apr\u00edla",
+ "m\u00e1ja",
+ "j\u00fana",
+ "j\u00fala",
+ "augusta",
+ "septembra",
+ "okt\u00f3bra",
+ "novembra",
+ "decembra"
+ ],
+ "SHORTDAY": [
+ "ne",
+ "po",
+ "ut",
+ "st",
+ "\u0161t",
+ "pi",
+ "so"
+ ],
+ "SHORTMONTH": [
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "m\u00e1j",
+ "j\u00fan",
+ "j\u00fal",
+ "aug",
+ "sep",
+ "okt",
+ "nov",
+ "dec"
+ ],
"fullDate": "EEEE, d. MMMM y",
"longDate": "d. MMMM y",
"medium": "d.M.yyyy H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "sk",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n >= 2 && n <= 4) { return PLURAL_CATEGORY.FEW; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl-si.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl-si.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl-si.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "dop.",
- "1": "pop."
- },
- "DAY": {
- "0": "nedelja",
- "1": "ponedeljek",
- "2": "torek",
- "3": "sreda",
- "4": "\u010detrtek",
- "5": "petek",
- "6": "sobota"
- },
- "MONTH": {
- "0": "januar",
- "1": "februar",
- "2": "marec",
- "3": "april",
- "4": "maj",
- "5": "junij",
- "6": "julij",
- "7": "avgust",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "ned.",
- "1": "pon.",
- "2": "tor.",
- "3": "sre.",
- "4": "\u010det.",
- "5": "pet.",
- "6": "sob."
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "feb.",
- "2": "mar.",
- "3": "apr.",
- "4": "maj",
- "5": "jun.",
- "6": "jul.",
- "7": "avg.",
- "8": "sep.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "dop.",
+ "pop."
+ ],
+ "DAY": [
+ "nedelja",
+ "ponedeljek",
+ "torek",
+ "sreda",
+ "\u010detrtek",
+ "petek",
+ "sobota"
+ ],
+ "MONTH": [
+ "januar",
+ "februar",
+ "marec",
+ "april",
+ "maj",
+ "junij",
+ "julij",
+ "avgust",
+ "september",
+ "oktober",
+ "november",
+ "december"
+ ],
+ "SHORTDAY": [
+ "ned.",
+ "pon.",
+ "tor.",
+ "sre.",
+ "\u010det.",
+ "pet.",
+ "sob."
+ ],
+ "SHORTMONTH": [
+ "jan.",
+ "feb.",
+ "mar.",
+ "apr.",
+ "maj",
+ "jun.",
+ "jul.",
+ "avg.",
+ "sep.",
+ "okt.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "EEEE, dd. MMMM y",
"longDate": "dd. MMMM y",
"medium": "d. MMM yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "sl-si",
"pluralCat": function (n) { if (n % 100 == 1) { return PLURAL_CATEGORY.ONE; } if (n % 100 == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 == 3 || n % 100 == 4) { return PLURAL_CATEGORY.FEW; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sl.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "dop.",
- "1": "pop."
- },
- "DAY": {
- "0": "nedelja",
- "1": "ponedeljek",
- "2": "torek",
- "3": "sreda",
- "4": "\u010detrtek",
- "5": "petek",
- "6": "sobota"
- },
- "MONTH": {
- "0": "januar",
- "1": "februar",
- "2": "marec",
- "3": "april",
- "4": "maj",
- "5": "junij",
- "6": "julij",
- "7": "avgust",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "ned.",
- "1": "pon.",
- "2": "tor.",
- "3": "sre.",
- "4": "\u010det.",
- "5": "pet.",
- "6": "sob."
- },
- "SHORTMONTH": {
- "0": "jan.",
- "1": "feb.",
- "2": "mar.",
- "3": "apr.",
- "4": "maj",
- "5": "jun.",
- "6": "jul.",
- "7": "avg.",
- "8": "sep.",
- "9": "okt.",
- "10": "nov.",
- "11": "dec."
- },
+ "AMPMS": [
+ "dop.",
+ "pop."
+ ],
+ "DAY": [
+ "nedelja",
+ "ponedeljek",
+ "torek",
+ "sreda",
+ "\u010detrtek",
+ "petek",
+ "sobota"
+ ],
+ "MONTH": [
+ "januar",
+ "februar",
+ "marec",
+ "april",
+ "maj",
+ "junij",
+ "julij",
+ "avgust",
+ "september",
+ "oktober",
+ "november",
+ "december"
+ ],
+ "SHORTDAY": [
+ "ned.",
+ "pon.",
+ "tor.",
+ "sre.",
+ "\u010det.",
+ "pet.",
+ "sob."
+ ],
+ "SHORTMONTH": [
+ "jan.",
+ "feb.",
+ "mar.",
+ "apr.",
+ "maj",
+ "jun.",
+ "jul.",
+ "avg.",
+ "sep.",
+ "okt.",
+ "nov.",
+ "dec."
+ ],
"fullDate": "EEEE, dd. MMMM y",
"longDate": "dd. MMMM y",
"medium": "d. MMM yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ac",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "sl",
"pluralCat": function (n) { if (n % 100 == 1) { return PLURAL_CATEGORY.ONE; } if (n % 100 == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 == 3 || n % 100 == 4) { return PLURAL_CATEGORY.FEW; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq-al.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq-al.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq-al.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "PD",
- "1": "MD"
- },
- "DAY": {
- "0": "e diel",
- "1": "e h\u00ebn\u00eb",
- "2": "e mart\u00eb",
- "3": "e m\u00ebrkur\u00eb",
- "4": "e enjte",
- "5": "e premte",
- "6": "e shtun\u00eb"
- },
- "MONTH": {
- "0": "janar",
- "1": "shkurt",
- "2": "mars",
- "3": "prill",
- "4": "maj",
- "5": "qershor",
- "6": "korrik",
- "7": "gusht",
- "8": "shtator",
- "9": "tetor",
- "10": "n\u00ebntor",
- "11": "dhjetor"
- },
- "SHORTDAY": {
- "0": "Die",
- "1": "H\u00ebn",
- "2": "Mar",
- "3": "M\u00ebr",
- "4": "Enj",
- "5": "Pre",
- "6": "Sht"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Shk",
- "2": "Mar",
- "3": "Pri",
- "4": "Maj",
- "5": "Qer",
- "6": "Kor",
- "7": "Gsh",
- "8": "Sht",
- "9": "Tet",
- "10": "N\u00ebn",
- "11": "Dhj"
- },
+ "AMPMS": [
+ "PD",
+ "MD"
+ ],
+ "DAY": [
+ "e diel",
+ "e h\u00ebn\u00eb",
+ "e mart\u00eb",
+ "e m\u00ebrkur\u00eb",
+ "e enjte",
+ "e premte",
+ "e shtun\u00eb"
+ ],
+ "MONTH": [
+ "janar",
+ "shkurt",
+ "mars",
+ "prill",
+ "maj",
+ "qershor",
+ "korrik",
+ "gusht",
+ "shtator",
+ "tetor",
+ "n\u00ebntor",
+ "dhjetor"
+ ],
+ "SHORTDAY": [
+ "Die",
+ "H\u00ebn",
+ "Mar",
+ "M\u00ebr",
+ "Enj",
+ "Pre",
+ "Sht"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Shk",
+ "Mar",
+ "Pri",
+ "Maj",
+ "Qer",
+ "Kor",
+ "Gsh",
+ "Sht",
+ "Tet",
+ "N\u00ebn",
+ "Dhj"
+ ],
"fullDate": "EEEE, dd MMMM y",
"longDate": "dd MMMM y",
"medium": "yyyy-MM-dd h.mm.ss.a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Lek",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "sq-al",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sq.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "PD",
- "1": "MD"
- },
- "DAY": {
- "0": "e diel",
- "1": "e h\u00ebn\u00eb",
- "2": "e mart\u00eb",
- "3": "e m\u00ebrkur\u00eb",
- "4": "e enjte",
- "5": "e premte",
- "6": "e shtun\u00eb"
- },
- "MONTH": {
- "0": "janar",
- "1": "shkurt",
- "2": "mars",
- "3": "prill",
- "4": "maj",
- "5": "qershor",
- "6": "korrik",
- "7": "gusht",
- "8": "shtator",
- "9": "tetor",
- "10": "n\u00ebntor",
- "11": "dhjetor"
- },
- "SHORTDAY": {
- "0": "Die",
- "1": "H\u00ebn",
- "2": "Mar",
- "3": "M\u00ebr",
- "4": "Enj",
- "5": "Pre",
- "6": "Sht"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Shk",
- "2": "Mar",
- "3": "Pri",
- "4": "Maj",
- "5": "Qer",
- "6": "Kor",
- "7": "Gsh",
- "8": "Sht",
- "9": "Tet",
- "10": "N\u00ebn",
- "11": "Dhj"
- },
+ "AMPMS": [
+ "PD",
+ "MD"
+ ],
+ "DAY": [
+ "e diel",
+ "e h\u00ebn\u00eb",
+ "e mart\u00eb",
+ "e m\u00ebrkur\u00eb",
+ "e enjte",
+ "e premte",
+ "e shtun\u00eb"
+ ],
+ "MONTH": [
+ "janar",
+ "shkurt",
+ "mars",
+ "prill",
+ "maj",
+ "qershor",
+ "korrik",
+ "gusht",
+ "shtator",
+ "tetor",
+ "n\u00ebntor",
+ "dhjetor"
+ ],
+ "SHORTDAY": [
+ "Die",
+ "H\u00ebn",
+ "Mar",
+ "M\u00ebr",
+ "Enj",
+ "Pre",
+ "Sht"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Shk",
+ "Mar",
+ "Pri",
+ "Maj",
+ "Qer",
+ "Kor",
+ "Gsh",
+ "Sht",
+ "Tet",
+ "N\u00ebn",
+ "Dhj"
+ ],
"fullDate": "EEEE, dd MMMM y",
"longDate": "dd MMMM y",
"medium": "yyyy-MM-dd h.mm.ss.a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Lek",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "sq",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-rs.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-rs.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-cyrl-rs.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u043f\u0440\u0435 \u043f\u043e\u0434\u043d\u0435",
- "1": "\u043f\u043e\u043f\u043e\u0434\u043d\u0435"
- },
- "DAY": {
- "0": "\u043d\u0435\u0434\u0435\u0459\u0430",
- "1": "\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a",
- "2": "\u0443\u0442\u043e\u0440\u0430\u043a",
- "3": "\u0441\u0440\u0435\u0434\u0430",
- "4": "\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a",
- "5": "\u043f\u0435\u0442\u0430\u043a",
- "6": "\u0441\u0443\u0431\u043e\u0442\u0430"
- },
- "MONTH": {
- "0": "\u0458\u0430\u043d\u0443\u0430\u0440",
- "1": "\u0444\u0435\u0431\u0440\u0443\u0430\u0440",
- "2": "\u043c\u0430\u0440\u0442",
- "3": "\u0430\u043f\u0440\u0438\u043b",
- "4": "\u043c\u0430\u0458",
- "5": "\u0458\u0443\u043d",
- "6": "\u0458\u0443\u043b",
- "7": "\u0430\u0432\u0433\u0443\u0441\u0442",
- "8": "\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440",
- "9": "\u043e\u043a\u0442\u043e\u0431\u0430\u0440",
- "10": "\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440",
- "11": "\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440"
- },
- "SHORTDAY": {
- "0": "\u043d\u0435\u0434",
- "1": "\u043f\u043e\u043d",
- "2": "\u0443\u0442\u043e",
- "3": "\u0441\u0440\u0435",
- "4": "\u0447\u0435\u0442",
- "5": "\u043f\u0435\u0442",
- "6": "\u0441\u0443\u0431"
- },
- "SHORTMONTH": {
- "0": "\u0458\u0430\u043d",
- "1": "\u0444\u0435\u0431",
- "2": "\u043c\u0430\u0440",
- "3": "\u0430\u043f\u0440",
- "4": "\u043c\u0430\u0458",
- "5": "\u0458\u0443\u043d",
- "6": "\u0458\u0443\u043b",
- "7": "\u0430\u0432\u0433",
- "8": "\u0441\u0435\u043f",
- "9": "\u043e\u043a\u0442",
- "10": "\u043d\u043e\u0432",
- "11": "\u0434\u0435\u0446"
- },
+ "AMPMS": [
+ "\u043f\u0440\u0435 \u043f\u043e\u0434\u043d\u0435",
+ "\u043f\u043e\u043f\u043e\u0434\u043d\u0435"
+ ],
+ "DAY": [
+ "\u043d\u0435\u0434\u0435\u0459\u0430",
+ "\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a",
+ "\u0443\u0442\u043e\u0440\u0430\u043a",
+ "\u0441\u0440\u0435\u0434\u0430",
+ "\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a",
+ "\u043f\u0435\u0442\u0430\u043a",
+ "\u0441\u0443\u0431\u043e\u0442\u0430"
+ ],
+ "MONTH": [
+ "\u0458\u0430\u043d\u0443\u0430\u0440",
+ "\u0444\u0435\u0431\u0440\u0443\u0430\u0440",
+ "\u043c\u0430\u0440\u0442",
+ "\u0430\u043f\u0440\u0438\u043b",
+ "\u043c\u0430\u0458",
+ "\u0458\u0443\u043d",
+ "\u0458\u0443\u043b",
+ "\u0430\u0432\u0433\u0443\u0441\u0442",
+ "\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440",
+ "\u043e\u043a\u0442\u043e\u0431\u0430\u0440",
+ "\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440",
+ "\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440"
+ ],
+ "SHORTDAY": [
+ "\u043d\u0435\u0434",
+ "\u043f\u043e\u043d",
+ "\u0443\u0442\u043e",
+ "\u0441\u0440\u0435",
+ "\u0447\u0435\u0442",
+ "\u043f\u0435\u0442",
+ "\u0441\u0443\u0431"
+ ],
+ "SHORTMONTH": [
+ "\u0458\u0430\u043d",
+ "\u0444\u0435\u0431",
+ "\u043c\u0430\u0440",
+ "\u0430\u043f\u0440",
+ "\u043c\u0430\u0458",
+ "\u0458\u0443\u043d",
+ "\u0458\u0443\u043b",
+ "\u0430\u0432\u0433",
+ "\u0441\u0435\u043f",
+ "\u043e\u043a\u0442",
+ "\u043d\u043e\u0432",
+ "\u0434\u0435\u0446"
+ ],
"fullDate": "EEEE, dd. MMMM y.",
"longDate": "dd. MMMM y.",
"medium": "dd.MM.y. HH.mm.ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "din",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "sr-cyrl-rs",
"pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-rs.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-rs.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr-latn-rs.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "pre podne",
- "1": "popodne"
- },
- "DAY": {
- "0": "nedelja",
- "1": "ponedeljak",
- "2": "utorak",
- "3": "sreda",
- "4": "\u010detvrtak",
- "5": "petak",
- "6": "subota"
- },
- "MONTH": {
- "0": "januar",
- "1": "februar",
- "2": "mart",
- "3": "april",
- "4": "maj",
- "5": "jun",
- "6": "jul",
- "7": "avgust",
- "8": "septembar",
- "9": "oktobar",
- "10": "novembar",
- "11": "decembar"
- },
- "SHORTDAY": {
- "0": "ned",
- "1": "pon",
- "2": "uto",
- "3": "sre",
- "4": "\u010det",
- "5": "pet",
- "6": "sub"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "maj",
- "5": "jun",
- "6": "jul",
- "7": "avg",
- "8": "sep",
- "9": "okt",
- "10": "nov",
- "11": "dec"
- },
+ "AMPMS": [
+ "pre podne",
+ "popodne"
+ ],
+ "DAY": [
+ "nedelja",
+ "ponedeljak",
+ "utorak",
+ "sreda",
+ "\u010detvrtak",
+ "petak",
+ "subota"
+ ],
+ "MONTH": [
+ "januar",
+ "februar",
+ "mart",
+ "april",
+ "maj",
+ "jun",
+ "jul",
+ "avgust",
+ "septembar",
+ "oktobar",
+ "novembar",
+ "decembar"
+ ],
+ "SHORTDAY": [
+ "ned",
+ "pon",
+ "uto",
+ "sre",
+ "\u010det",
+ "pet",
+ "sub"
+ ],
+ "SHORTMONTH": [
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "maj",
+ "jun",
+ "jul",
+ "avg",
+ "sep",
+ "okt",
+ "nov",
+ "dec"
+ ],
"fullDate": "EEEE, dd. MMMM y.",
"longDate": "dd. MMMM y.",
"medium": "dd.MM.y. HH.mm.ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "din",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "sr-latn-rs",
"pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u043f\u0440\u0435 \u043f\u043e\u0434\u043d\u0435",
- "1": "\u043f\u043e\u043f\u043e\u0434\u043d\u0435"
- },
- "DAY": {
- "0": "\u043d\u0435\u0434\u0435\u0459\u0430",
- "1": "\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a",
- "2": "\u0443\u0442\u043e\u0440\u0430\u043a",
- "3": "\u0441\u0440\u0435\u0434\u0430",
- "4": "\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a",
- "5": "\u043f\u0435\u0442\u0430\u043a",
- "6": "\u0441\u0443\u0431\u043e\u0442\u0430"
- },
- "MONTH": {
- "0": "\u0458\u0430\u043d\u0443\u0430\u0440",
- "1": "\u0444\u0435\u0431\u0440\u0443\u0430\u0440",
- "2": "\u043c\u0430\u0440\u0442",
- "3": "\u0430\u043f\u0440\u0438\u043b",
- "4": "\u043c\u0430\u0458",
- "5": "\u0458\u0443\u043d",
- "6": "\u0458\u0443\u043b",
- "7": "\u0430\u0432\u0433\u0443\u0441\u0442",
- "8": "\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440",
- "9": "\u043e\u043a\u0442\u043e\u0431\u0430\u0440",
- "10": "\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440",
- "11": "\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440"
- },
- "SHORTDAY": {
- "0": "\u043d\u0435\u0434",
- "1": "\u043f\u043e\u043d",
- "2": "\u0443\u0442\u043e",
- "3": "\u0441\u0440\u0435",
- "4": "\u0447\u0435\u0442",
- "5": "\u043f\u0435\u0442",
- "6": "\u0441\u0443\u0431"
- },
- "SHORTMONTH": {
- "0": "\u0458\u0430\u043d",
- "1": "\u0444\u0435\u0431",
- "2": "\u043c\u0430\u0440",
- "3": "\u0430\u043f\u0440",
- "4": "\u043c\u0430\u0458",
- "5": "\u0458\u0443\u043d",
- "6": "\u0458\u0443\u043b",
- "7": "\u0430\u0432\u0433",
- "8": "\u0441\u0435\u043f",
- "9": "\u043e\u043a\u0442",
- "10": "\u043d\u043e\u0432",
- "11": "\u0434\u0435\u0446"
- },
+ "AMPMS": [
+ "\u043f\u0440\u0435 \u043f\u043e\u0434\u043d\u0435",
+ "\u043f\u043e\u043f\u043e\u0434\u043d\u0435"
+ ],
+ "DAY": [
+ "\u043d\u0435\u0434\u0435\u0459\u0430",
+ "\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a",
+ "\u0443\u0442\u043e\u0440\u0430\u043a",
+ "\u0441\u0440\u0435\u0434\u0430",
+ "\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a",
+ "\u043f\u0435\u0442\u0430\u043a",
+ "\u0441\u0443\u0431\u043e\u0442\u0430"
+ ],
+ "MONTH": [
+ "\u0458\u0430\u043d\u0443\u0430\u0440",
+ "\u0444\u0435\u0431\u0440\u0443\u0430\u0440",
+ "\u043c\u0430\u0440\u0442",
+ "\u0430\u043f\u0440\u0438\u043b",
+ "\u043c\u0430\u0458",
+ "\u0458\u0443\u043d",
+ "\u0458\u0443\u043b",
+ "\u0430\u0432\u0433\u0443\u0441\u0442",
+ "\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440",
+ "\u043e\u043a\u0442\u043e\u0431\u0430\u0440",
+ "\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440",
+ "\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440"
+ ],
+ "SHORTDAY": [
+ "\u043d\u0435\u0434",
+ "\u043f\u043e\u043d",
+ "\u0443\u0442\u043e",
+ "\u0441\u0440\u0435",
+ "\u0447\u0435\u0442",
+ "\u043f\u0435\u0442",
+ "\u0441\u0443\u0431"
+ ],
+ "SHORTMONTH": [
+ "\u0458\u0430\u043d",
+ "\u0444\u0435\u0431",
+ "\u043c\u0430\u0440",
+ "\u0430\u043f\u0440",
+ "\u043c\u0430\u0458",
+ "\u0458\u0443\u043d",
+ "\u0458\u0443\u043b",
+ "\u0430\u0432\u0433",
+ "\u0441\u0435\u043f",
+ "\u043e\u043a\u0442",
+ "\u043d\u043e\u0432",
+ "\u0434\u0435\u0446"
+ ],
"fullDate": "EEEE, dd. MMMM y.",
"longDate": "dd. MMMM y.",
"medium": "dd.MM.y. HH.mm.ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "din",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "sr",
"pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv-se.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv-se.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv-se.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "fm",
- "1": "em"
- },
- "DAY": {
- "0": "s\u00f6ndag",
- "1": "m\u00e5ndag",
- "2": "tisdag",
- "3": "onsdag",
- "4": "torsdag",
- "5": "fredag",
- "6": "l\u00f6rdag"
- },
- "MONTH": {
- "0": "januari",
- "1": "februari",
- "2": "mars",
- "3": "april",
- "4": "maj",
- "5": "juni",
- "6": "juli",
- "7": "augusti",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "s\u00f6n",
- "1": "m\u00e5n",
- "2": "tis",
- "3": "ons",
- "4": "tors",
- "5": "fre",
- "6": "l\u00f6r"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "maj",
- "5": "jun",
- "6": "jul",
- "7": "aug",
- "8": "sep",
- "9": "okt",
- "10": "nov",
- "11": "dec"
- },
+ "AMPMS": [
+ "fm",
+ "em"
+ ],
+ "DAY": [
+ "s\u00f6ndag",
+ "m\u00e5ndag",
+ "tisdag",
+ "onsdag",
+ "torsdag",
+ "fredag",
+ "l\u00f6rdag"
+ ],
+ "MONTH": [
+ "januari",
+ "februari",
+ "mars",
+ "april",
+ "maj",
+ "juni",
+ "juli",
+ "augusti",
+ "september",
+ "oktober",
+ "november",
+ "december"
+ ],
+ "SHORTDAY": [
+ "s\u00f6n",
+ "m\u00e5n",
+ "tis",
+ "ons",
+ "tors",
+ "fre",
+ "l\u00f6r"
+ ],
+ "SHORTMONTH": [
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "maj",
+ "jun",
+ "jul",
+ "aug",
+ "sep",
+ "okt",
+ "nov",
+ "dec"
+ ],
"fullDate": "EEEE'en' 'den' d:'e' MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "kr",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "sv-se",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sv.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "fm",
- "1": "em"
- },
- "DAY": {
- "0": "s\u00f6ndag",
- "1": "m\u00e5ndag",
- "2": "tisdag",
- "3": "onsdag",
- "4": "torsdag",
- "5": "fredag",
- "6": "l\u00f6rdag"
- },
- "MONTH": {
- "0": "januari",
- "1": "februari",
- "2": "mars",
- "3": "april",
- "4": "maj",
- "5": "juni",
- "6": "juli",
- "7": "augusti",
- "8": "september",
- "9": "oktober",
- "10": "november",
- "11": "december"
- },
- "SHORTDAY": {
- "0": "s\u00f6n",
- "1": "m\u00e5n",
- "2": "tis",
- "3": "ons",
- "4": "tors",
- "5": "fre",
- "6": "l\u00f6r"
- },
- "SHORTMONTH": {
- "0": "jan",
- "1": "feb",
- "2": "mar",
- "3": "apr",
- "4": "maj",
- "5": "jun",
- "6": "jul",
- "7": "aug",
- "8": "sep",
- "9": "okt",
- "10": "nov",
- "11": "dec"
- },
+ "AMPMS": [
+ "fm",
+ "em"
+ ],
+ "DAY": [
+ "s\u00f6ndag",
+ "m\u00e5ndag",
+ "tisdag",
+ "onsdag",
+ "torsdag",
+ "fredag",
+ "l\u00f6rdag"
+ ],
+ "MONTH": [
+ "januari",
+ "februari",
+ "mars",
+ "april",
+ "maj",
+ "juni",
+ "juli",
+ "augusti",
+ "september",
+ "oktober",
+ "november",
+ "december"
+ ],
+ "SHORTDAY": [
+ "s\u00f6n",
+ "m\u00e5n",
+ "tis",
+ "ons",
+ "tors",
+ "fre",
+ "l\u00f6r"
+ ],
+ "SHORTMONTH": [
+ "jan",
+ "feb",
+ "mar",
+ "apr",
+ "maj",
+ "jun",
+ "jul",
+ "aug",
+ "sep",
+ "okt",
+ "nov",
+ "dec"
+ ],
"fullDate": "EEEE'en' 'den' d:'e' MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "kr",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "sv",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw-tz.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw-tz.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw-tz.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "asubuhi",
- "1": "alasiri"
- },
- "DAY": {
- "0": "Jumapili",
- "1": "Jumatatu",
- "2": "Jumanne",
- "3": "Jumatano",
- "4": "Alhamisi",
- "5": "Ijumaa",
- "6": "Jumamosi"
- },
- "MONTH": {
- "0": "Januari",
- "1": "Februari",
- "2": "Machi",
- "3": "Aprili",
- "4": "Mei",
- "5": "Juni",
- "6": "Julai",
- "7": "Agosti",
- "8": "Septemba",
- "9": "Oktoba",
- "10": "Novemba",
- "11": "Desemba"
- },
- "SHORTDAY": {
- "0": "J2",
- "1": "J3",
- "2": "J4",
- "3": "J5",
- "4": "Alh",
- "5": "Ij",
- "6": "J1"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mac",
- "3": "Apr",
- "4": "Mei",
- "5": "Jun",
- "6": "Jul",
- "7": "Ago",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Des"
- },
+ "AMPMS": [
+ "asubuhi",
+ "alasiri"
+ ],
+ "DAY": [
+ "Jumapili",
+ "Jumatatu",
+ "Jumanne",
+ "Jumatano",
+ "Alhamisi",
+ "Ijumaa",
+ "Jumamosi"
+ ],
+ "MONTH": [
+ "Januari",
+ "Februari",
+ "Machi",
+ "Aprili",
+ "Mei",
+ "Juni",
+ "Julai",
+ "Agosti",
+ "Septemba",
+ "Oktoba",
+ "Novemba",
+ "Desemba"
+ ],
+ "SHORTDAY": [
+ "J2",
+ "J3",
+ "J4",
+ "J5",
+ "Alh",
+ "Ij",
+ "J1"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mac",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Ago",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Des"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "TSh",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "sw-tz",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_sw.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "asubuhi",
- "1": "alasiri"
- },
- "DAY": {
- "0": "Jumapili",
- "1": "Jumatatu",
- "2": "Jumanne",
- "3": "Jumatano",
- "4": "Alhamisi",
- "5": "Ijumaa",
- "6": "Jumamosi"
- },
- "MONTH": {
- "0": "Januari",
- "1": "Februari",
- "2": "Machi",
- "3": "Aprili",
- "4": "Mei",
- "5": "Juni",
- "6": "Julai",
- "7": "Agosti",
- "8": "Septemba",
- "9": "Oktoba",
- "10": "Novemba",
- "11": "Desemba"
- },
- "SHORTDAY": {
- "0": "J2",
- "1": "J3",
- "2": "J4",
- "3": "J5",
- "4": "Alh",
- "5": "Ij",
- "6": "J1"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mac",
- "3": "Apr",
- "4": "Mei",
- "5": "Jun",
- "6": "Jul",
- "7": "Ago",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Des"
- },
+ "AMPMS": [
+ "asubuhi",
+ "alasiri"
+ ],
+ "DAY": [
+ "Jumapili",
+ "Jumatatu",
+ "Jumanne",
+ "Jumatano",
+ "Alhamisi",
+ "Ijumaa",
+ "Jumamosi"
+ ],
+ "MONTH": [
+ "Januari",
+ "Februari",
+ "Machi",
+ "Aprili",
+ "Mei",
+ "Juni",
+ "Julai",
+ "Agosti",
+ "Septemba",
+ "Oktoba",
+ "Novemba",
+ "Desemba"
+ ],
+ "SHORTDAY": [
+ "J2",
+ "J3",
+ "J4",
+ "J5",
+ "Alh",
+ "Ij",
+ "J1"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mac",
+ "Apr",
+ "Mei",
+ "Jun",
+ "Jul",
+ "Ago",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Des"
+ ],
"fullDate": "EEEE, d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "TSh",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "sw",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta-in.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta-in.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta-in.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bc1",
- "1": "\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0bb3\u0bcd",
- "2": "\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd",
- "3": "\u0baa\u0bc1\u0ba4\u0ba9\u0bcd",
- "4": "\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0ba9\u0bcd",
- "5": "\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf",
- "6": "\u0b9a\u0ba9\u0bbf"
- },
- "MONTH": {
- "0": "\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf",
- "1": "\u0baa\u0bbf\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf",
- "2": "\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd",
- "3": "\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd",
- "4": "\u0bae\u0bc7",
- "5": "\u0b9c\u0bc2\u0ba9\u0bcd",
- "6": "\u0b9c\u0bc2\u0bb2\u0bc8",
- "7": "\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd",
- "8": "\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bae\u0bcd\u0baa\u0bb0\u0bcd",
- "9": "\u0b85\u0b95\u0bcd\u0b9f\u0bcb\u0baa\u0bb0\u0bcd",
- "10": "\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd",
- "11": "\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcd"
- },
- "SHORTDAY": {
- "0": "\u0b9e\u0bbe",
- "1": "\u0ba4\u0bbf",
- "2": "\u0b9a\u0bc6",
- "3": "\u0baa\u0bc1",
- "4": "\u0bb5\u0bbf",
- "5": "\u0bb5\u0bc6",
- "6": "\u0b9a"
- },
- "SHORTMONTH": {
- "0": "\u0b9c\u0ba9.",
- "1": "\u0baa\u0bbf\u0baa\u0bcd.",
- "2": "\u0bae\u0bbe\u0bb0\u0bcd.",
- "3": "\u0b8f\u0baa\u0bcd.",
- "4": "\u0bae\u0bc7",
- "5": "\u0b9c\u0bc2\u0ba9\u0bcd",
- "6": "\u0b9c\u0bc2\u0bb2\u0bc8",
- "7": "\u0b86\u0b95.",
- "8": "\u0b9a\u0bc6\u0baa\u0bcd.",
- "9": "\u0b85\u0b95\u0bcd.",
- "10": "\u0ba8\u0bb5.",
- "11": "\u0b9f\u0bbf\u0b9a."
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bc1",
+ "\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0bb3\u0bcd",
+ "\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd",
+ "\u0baa\u0bc1\u0ba4\u0ba9\u0bcd",
+ "\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0ba9\u0bcd",
+ "\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf",
+ "\u0b9a\u0ba9\u0bbf"
+ ],
+ "MONTH": [
+ "\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf",
+ "\u0baa\u0bbf\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf",
+ "\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd",
+ "\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd",
+ "\u0bae\u0bc7",
+ "\u0b9c\u0bc2\u0ba9\u0bcd",
+ "\u0b9c\u0bc2\u0bb2\u0bc8",
+ "\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd",
+ "\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bae\u0bcd\u0baa\u0bb0\u0bcd",
+ "\u0b85\u0b95\u0bcd\u0b9f\u0bcb\u0baa\u0bb0\u0bcd",
+ "\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd",
+ "\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcd"
+ ],
+ "SHORTDAY": [
+ "\u0b9e\u0bbe",
+ "\u0ba4\u0bbf",
+ "\u0b9a\u0bc6",
+ "\u0baa\u0bc1",
+ "\u0bb5\u0bbf",
+ "\u0bb5\u0bc6",
+ "\u0b9a"
+ ],
+ "SHORTMONTH": [
+ "\u0b9c\u0ba9.",
+ "\u0baa\u0bbf\u0baa\u0bcd.",
+ "\u0bae\u0bbe\u0bb0\u0bcd.",
+ "\u0b8f\u0baa\u0bcd.",
+ "\u0bae\u0bc7",
+ "\u0b9c\u0bc2\u0ba9\u0bcd",
+ "\u0b9c\u0bc2\u0bb2\u0bc8",
+ "\u0b86\u0b95.",
+ "\u0b9a\u0bc6\u0baa\u0bcd.",
+ "\u0b85\u0b95\u0bcd.",
+ "\u0ba8\u0bb5.",
+ "\u0b9f\u0bbf\u0b9a."
+ ],
"fullDate": "EEEE, d MMMM, y",
"longDate": "d MMMM, y",
"medium": "d MMM, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ta-in",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ta.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bc1",
- "1": "\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0bb3\u0bcd",
- "2": "\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd",
- "3": "\u0baa\u0bc1\u0ba4\u0ba9\u0bcd",
- "4": "\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0ba9\u0bcd",
- "5": "\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf",
- "6": "\u0b9a\u0ba9\u0bbf"
- },
- "MONTH": {
- "0": "\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf",
- "1": "\u0baa\u0bbf\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf",
- "2": "\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd",
- "3": "\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd",
- "4": "\u0bae\u0bc7",
- "5": "\u0b9c\u0bc2\u0ba9\u0bcd",
- "6": "\u0b9c\u0bc2\u0bb2\u0bc8",
- "7": "\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd",
- "8": "\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bae\u0bcd\u0baa\u0bb0\u0bcd",
- "9": "\u0b85\u0b95\u0bcd\u0b9f\u0bcb\u0baa\u0bb0\u0bcd",
- "10": "\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd",
- "11": "\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcd"
- },
- "SHORTDAY": {
- "0": "\u0b9e\u0bbe",
- "1": "\u0ba4\u0bbf",
- "2": "\u0b9a\u0bc6",
- "3": "\u0baa\u0bc1",
- "4": "\u0bb5\u0bbf",
- "5": "\u0bb5\u0bc6",
- "6": "\u0b9a"
- },
- "SHORTMONTH": {
- "0": "\u0b9c\u0ba9.",
- "1": "\u0baa\u0bbf\u0baa\u0bcd.",
- "2": "\u0bae\u0bbe\u0bb0\u0bcd.",
- "3": "\u0b8f\u0baa\u0bcd.",
- "4": "\u0bae\u0bc7",
- "5": "\u0b9c\u0bc2\u0ba9\u0bcd",
- "6": "\u0b9c\u0bc2\u0bb2\u0bc8",
- "7": "\u0b86\u0b95.",
- "8": "\u0b9a\u0bc6\u0baa\u0bcd.",
- "9": "\u0b85\u0b95\u0bcd.",
- "10": "\u0ba8\u0bb5.",
- "11": "\u0b9f\u0bbf\u0b9a."
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bc1",
+ "\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0bb3\u0bcd",
+ "\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd",
+ "\u0baa\u0bc1\u0ba4\u0ba9\u0bcd",
+ "\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0ba9\u0bcd",
+ "\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf",
+ "\u0b9a\u0ba9\u0bbf"
+ ],
+ "MONTH": [
+ "\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf",
+ "\u0baa\u0bbf\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf",
+ "\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd",
+ "\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd",
+ "\u0bae\u0bc7",
+ "\u0b9c\u0bc2\u0ba9\u0bcd",
+ "\u0b9c\u0bc2\u0bb2\u0bc8",
+ "\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd",
+ "\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bae\u0bcd\u0baa\u0bb0\u0bcd",
+ "\u0b85\u0b95\u0bcd\u0b9f\u0bcb\u0baa\u0bb0\u0bcd",
+ "\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd",
+ "\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcd"
+ ],
+ "SHORTDAY": [
+ "\u0b9e\u0bbe",
+ "\u0ba4\u0bbf",
+ "\u0b9a\u0bc6",
+ "\u0baa\u0bc1",
+ "\u0bb5\u0bbf",
+ "\u0bb5\u0bc6",
+ "\u0b9a"
+ ],
+ "SHORTMONTH": [
+ "\u0b9c\u0ba9.",
+ "\u0baa\u0bbf\u0baa\u0bcd.",
+ "\u0bae\u0bbe\u0bb0\u0bcd.",
+ "\u0b8f\u0baa\u0bcd.",
+ "\u0bae\u0bc7",
+ "\u0b9c\u0bc2\u0ba9\u0bcd",
+ "\u0b9c\u0bc2\u0bb2\u0bc8",
+ "\u0b86\u0b95.",
+ "\u0b9a\u0bc6\u0baa\u0bcd.",
+ "\u0b85\u0b95\u0bcd.",
+ "\u0ba8\u0bb5.",
+ "\u0b9f\u0bbf\u0b9a."
+ ],
"fullDate": "EEEE, d MMMM, y",
"longDate": "d MMMM, y",
"medium": "d MMM, y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 2,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4\u00a0",
"posSuf": ""
}
- }
+ ]
},
"id": "ta",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te-in.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te-in.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te-in.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0c06\u0c26\u0c3f\u0c35\u0c3e\u0c30\u0c02",
- "1": "\u0c38\u0c4b\u0c2e\u0c35\u0c3e\u0c30\u0c02",
- "2": "\u0c2e\u0c02\u0c17\u0c33\u0c35\u0c3e\u0c30\u0c02",
- "3": "\u0c2c\u0c41\u0c27\u0c35\u0c3e\u0c30\u0c02",
- "4": "\u0c17\u0c41\u0c30\u0c41\u0c35\u0c3e\u0c30\u0c02",
- "5": "\u0c36\u0c41\u0c15\u0c4d\u0c30\u0c35\u0c3e\u0c30\u0c02",
- "6": "\u0c36\u0c28\u0c3f\u0c35\u0c3e\u0c30\u0c02"
- },
- "MONTH": {
- "0": "\u0c1c\u0c28\u0c35\u0c30\u0c3f",
- "1": "\u0c2b\u0c3f\u0c2c\u0c4d\u0c30\u0c35\u0c30\u0c3f",
- "2": "\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f",
- "3": "\u0c0e\u0c2a\u0c4d\u0c30\u0c3f\u0c32\u0c4d",
- "4": "\u0c2e\u0c47",
- "5": "\u0c1c\u0c42\u0c28\u0c4d",
- "6": "\u0c1c\u0c42\u0c32\u0c48",
- "7": "\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41",
- "8": "\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d",
- "9": "\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d",
- "10": "\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d",
- "11": "\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d"
- },
- "SHORTDAY": {
- "0": "\u0c06\u0c26\u0c3f",
- "1": "\u0c38\u0c4b\u0c2e",
- "2": "\u0c2e\u0c02\u0c17\u0c33",
- "3": "\u0c2c\u0c41\u0c27",
- "4": "\u0c17\u0c41\u0c30\u0c41",
- "5": "\u0c36\u0c41\u0c15\u0c4d\u0c30",
- "6": "\u0c36\u0c28\u0c3f"
- },
- "SHORTMONTH": {
- "0": "\u0c1c\u0c28",
- "1": "\u0c2b\u0c3f\u0c2c\u0c4d\u0c30",
- "2": "\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f",
- "3": "\u0c0f\u0c2a\u0c4d\u0c30\u0c3f",
- "4": "\u0c2e\u0c47",
- "5": "\u0c1c\u0c42\u0c28\u0c4d",
- "6": "\u0c1c\u0c42\u0c32\u0c48",
- "7": "\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41",
- "8": "\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d",
- "9": "\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d",
- "10": "\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d",
- "11": "\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0c06\u0c26\u0c3f\u0c35\u0c3e\u0c30\u0c02",
+ "\u0c38\u0c4b\u0c2e\u0c35\u0c3e\u0c30\u0c02",
+ "\u0c2e\u0c02\u0c17\u0c33\u0c35\u0c3e\u0c30\u0c02",
+ "\u0c2c\u0c41\u0c27\u0c35\u0c3e\u0c30\u0c02",
+ "\u0c17\u0c41\u0c30\u0c41\u0c35\u0c3e\u0c30\u0c02",
+ "\u0c36\u0c41\u0c15\u0c4d\u0c30\u0c35\u0c3e\u0c30\u0c02",
+ "\u0c36\u0c28\u0c3f\u0c35\u0c3e\u0c30\u0c02"
+ ],
+ "MONTH": [
+ "\u0c1c\u0c28\u0c35\u0c30\u0c3f",
+ "\u0c2b\u0c3f\u0c2c\u0c4d\u0c30\u0c35\u0c30\u0c3f",
+ "\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f",
+ "\u0c0e\u0c2a\u0c4d\u0c30\u0c3f\u0c32\u0c4d",
+ "\u0c2e\u0c47",
+ "\u0c1c\u0c42\u0c28\u0c4d",
+ "\u0c1c\u0c42\u0c32\u0c48",
+ "\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41",
+ "\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d",
+ "\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d",
+ "\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d",
+ "\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d"
+ ],
+ "SHORTDAY": [
+ "\u0c06\u0c26\u0c3f",
+ "\u0c38\u0c4b\u0c2e",
+ "\u0c2e\u0c02\u0c17\u0c33",
+ "\u0c2c\u0c41\u0c27",
+ "\u0c17\u0c41\u0c30\u0c41",
+ "\u0c36\u0c41\u0c15\u0c4d\u0c30",
+ "\u0c36\u0c28\u0c3f"
+ ],
+ "SHORTMONTH": [
+ "\u0c1c\u0c28",
+ "\u0c2b\u0c3f\u0c2c\u0c4d\u0c30",
+ "\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f",
+ "\u0c0f\u0c2a\u0c4d\u0c30\u0c3f",
+ "\u0c2e\u0c47",
+ "\u0c1c\u0c42\u0c28\u0c4d",
+ "\u0c1c\u0c42\u0c32\u0c48",
+ "\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41",
+ "\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d",
+ "\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d",
+ "\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d",
+ "\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "te-in",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_te.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "am",
- "1": "pm"
- },
- "DAY": {
- "0": "\u0c06\u0c26\u0c3f\u0c35\u0c3e\u0c30\u0c02",
- "1": "\u0c38\u0c4b\u0c2e\u0c35\u0c3e\u0c30\u0c02",
- "2": "\u0c2e\u0c02\u0c17\u0c33\u0c35\u0c3e\u0c30\u0c02",
- "3": "\u0c2c\u0c41\u0c27\u0c35\u0c3e\u0c30\u0c02",
- "4": "\u0c17\u0c41\u0c30\u0c41\u0c35\u0c3e\u0c30\u0c02",
- "5": "\u0c36\u0c41\u0c15\u0c4d\u0c30\u0c35\u0c3e\u0c30\u0c02",
- "6": "\u0c36\u0c28\u0c3f\u0c35\u0c3e\u0c30\u0c02"
- },
- "MONTH": {
- "0": "\u0c1c\u0c28\u0c35\u0c30\u0c3f",
- "1": "\u0c2b\u0c3f\u0c2c\u0c4d\u0c30\u0c35\u0c30\u0c3f",
- "2": "\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f",
- "3": "\u0c0e\u0c2a\u0c4d\u0c30\u0c3f\u0c32\u0c4d",
- "4": "\u0c2e\u0c47",
- "5": "\u0c1c\u0c42\u0c28\u0c4d",
- "6": "\u0c1c\u0c42\u0c32\u0c48",
- "7": "\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41",
- "8": "\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d",
- "9": "\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d",
- "10": "\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d",
- "11": "\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d"
- },
- "SHORTDAY": {
- "0": "\u0c06\u0c26\u0c3f",
- "1": "\u0c38\u0c4b\u0c2e",
- "2": "\u0c2e\u0c02\u0c17\u0c33",
- "3": "\u0c2c\u0c41\u0c27",
- "4": "\u0c17\u0c41\u0c30\u0c41",
- "5": "\u0c36\u0c41\u0c15\u0c4d\u0c30",
- "6": "\u0c36\u0c28\u0c3f"
- },
- "SHORTMONTH": {
- "0": "\u0c1c\u0c28",
- "1": "\u0c2b\u0c3f\u0c2c\u0c4d\u0c30",
- "2": "\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f",
- "3": "\u0c0f\u0c2a\u0c4d\u0c30\u0c3f",
- "4": "\u0c2e\u0c47",
- "5": "\u0c1c\u0c42\u0c28\u0c4d",
- "6": "\u0c1c\u0c42\u0c32\u0c48",
- "7": "\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41",
- "8": "\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d",
- "9": "\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d",
- "10": "\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d",
- "11": "\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d"
- },
+ "AMPMS": [
+ "am",
+ "pm"
+ ],
+ "DAY": [
+ "\u0c06\u0c26\u0c3f\u0c35\u0c3e\u0c30\u0c02",
+ "\u0c38\u0c4b\u0c2e\u0c35\u0c3e\u0c30\u0c02",
+ "\u0c2e\u0c02\u0c17\u0c33\u0c35\u0c3e\u0c30\u0c02",
+ "\u0c2c\u0c41\u0c27\u0c35\u0c3e\u0c30\u0c02",
+ "\u0c17\u0c41\u0c30\u0c41\u0c35\u0c3e\u0c30\u0c02",
+ "\u0c36\u0c41\u0c15\u0c4d\u0c30\u0c35\u0c3e\u0c30\u0c02",
+ "\u0c36\u0c28\u0c3f\u0c35\u0c3e\u0c30\u0c02"
+ ],
+ "MONTH": [
+ "\u0c1c\u0c28\u0c35\u0c30\u0c3f",
+ "\u0c2b\u0c3f\u0c2c\u0c4d\u0c30\u0c35\u0c30\u0c3f",
+ "\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f",
+ "\u0c0e\u0c2a\u0c4d\u0c30\u0c3f\u0c32\u0c4d",
+ "\u0c2e\u0c47",
+ "\u0c1c\u0c42\u0c28\u0c4d",
+ "\u0c1c\u0c42\u0c32\u0c48",
+ "\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41",
+ "\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d",
+ "\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d",
+ "\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d",
+ "\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d"
+ ],
+ "SHORTDAY": [
+ "\u0c06\u0c26\u0c3f",
+ "\u0c38\u0c4b\u0c2e",
+ "\u0c2e\u0c02\u0c17\u0c33",
+ "\u0c2c\u0c41\u0c27",
+ "\u0c17\u0c41\u0c30\u0c41",
+ "\u0c36\u0c41\u0c15\u0c4d\u0c30",
+ "\u0c36\u0c28\u0c3f"
+ ],
+ "SHORTMONTH": [
+ "\u0c1c\u0c28",
+ "\u0c2b\u0c3f\u0c2c\u0c4d\u0c30",
+ "\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f",
+ "\u0c0f\u0c2a\u0c4d\u0c30\u0c3f",
+ "\u0c2e\u0c47",
+ "\u0c1c\u0c42\u0c28\u0c4d",
+ "\u0c1c\u0c42\u0c32\u0c48",
+ "\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41",
+ "\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d",
+ "\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d",
+ "\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d",
+ "\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d"
+ ],
"fullDate": "EEEE d MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b9",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "te",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th-th.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th-th.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th-th.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07",
- "1": "\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07"
- },
- "DAY": {
- "0": "\u0e27\u0e31\u0e19\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c",
- "1": "\u0e27\u0e31\u0e19\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c",
- "2": "\u0e27\u0e31\u0e19\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23",
- "3": "\u0e27\u0e31\u0e19\u0e1e\u0e38\u0e18",
- "4": "\u0e27\u0e31\u0e19\u0e1e\u0e24\u0e2b\u0e31\u0e2a\u0e1a\u0e14\u0e35",
- "5": "\u0e27\u0e31\u0e19\u0e28\u0e38\u0e01\u0e23\u0e4c",
- "6": "\u0e27\u0e31\u0e19\u0e40\u0e2a\u0e32\u0e23\u0e4c"
- },
- "MONTH": {
- "0": "\u0e21\u0e01\u0e23\u0e32\u0e04\u0e21",
- "1": "\u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c",
- "2": "\u0e21\u0e35\u0e19\u0e32\u0e04\u0e21",
- "3": "\u0e40\u0e21\u0e29\u0e32\u0e22\u0e19",
- "4": "\u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21",
- "5": "\u0e21\u0e34\u0e16\u0e38\u0e19\u0e32\u0e22\u0e19",
- "6": "\u0e01\u0e23\u0e01\u0e0e\u0e32\u0e04\u0e21",
- "7": "\u0e2a\u0e34\u0e07\u0e2b\u0e32\u0e04\u0e21",
- "8": "\u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19",
- "9": "\u0e15\u0e38\u0e25\u0e32\u0e04\u0e21",
- "10": "\u0e1e\u0e24\u0e28\u0e08\u0e34\u0e01\u0e32\u0e22\u0e19",
- "11": "\u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21"
- },
- "SHORTDAY": {
- "0": "\u0e2d\u0e32.",
- "1": "\u0e08.",
- "2": "\u0e2d.",
- "3": "\u0e1e.",
- "4": "\u0e1e\u0e24.",
- "5": "\u0e28.",
- "6": "\u0e2a."
- },
- "SHORTMONTH": {
- "0": "\u0e21.\u0e04.",
- "1": "\u0e01.\u0e1e.",
- "2": "\u0e21\u0e35.\u0e04.",
- "3": "\u0e40\u0e21.\u0e22.",
- "4": "\u0e1e.\u0e04.",
- "5": "\u0e21\u0e34.\u0e22.",
- "6": "\u0e01.\u0e04.",
- "7": "\u0e2a.\u0e04.",
- "8": "\u0e01.\u0e22.",
- "9": "\u0e15.\u0e04.",
- "10": "\u0e1e.\u0e22.",
- "11": "\u0e18.\u0e04."
- },
+ "AMPMS": [
+ "\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07",
+ "\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07"
+ ],
+ "DAY": [
+ "\u0e27\u0e31\u0e19\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c",
+ "\u0e27\u0e31\u0e19\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c",
+ "\u0e27\u0e31\u0e19\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23",
+ "\u0e27\u0e31\u0e19\u0e1e\u0e38\u0e18",
+ "\u0e27\u0e31\u0e19\u0e1e\u0e24\u0e2b\u0e31\u0e2a\u0e1a\u0e14\u0e35",
+ "\u0e27\u0e31\u0e19\u0e28\u0e38\u0e01\u0e23\u0e4c",
+ "\u0e27\u0e31\u0e19\u0e40\u0e2a\u0e32\u0e23\u0e4c"
+ ],
+ "MONTH": [
+ "\u0e21\u0e01\u0e23\u0e32\u0e04\u0e21",
+ "\u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c",
+ "\u0e21\u0e35\u0e19\u0e32\u0e04\u0e21",
+ "\u0e40\u0e21\u0e29\u0e32\u0e22\u0e19",
+ "\u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21",
+ "\u0e21\u0e34\u0e16\u0e38\u0e19\u0e32\u0e22\u0e19",
+ "\u0e01\u0e23\u0e01\u0e0e\u0e32\u0e04\u0e21",
+ "\u0e2a\u0e34\u0e07\u0e2b\u0e32\u0e04\u0e21",
+ "\u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19",
+ "\u0e15\u0e38\u0e25\u0e32\u0e04\u0e21",
+ "\u0e1e\u0e24\u0e28\u0e08\u0e34\u0e01\u0e32\u0e22\u0e19",
+ "\u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21"
+ ],
+ "SHORTDAY": [
+ "\u0e2d\u0e32.",
+ "\u0e08.",
+ "\u0e2d.",
+ "\u0e1e.",
+ "\u0e1e\u0e24.",
+ "\u0e28.",
+ "\u0e2a."
+ ],
+ "SHORTMONTH": [
+ "\u0e21.\u0e04.",
+ "\u0e01.\u0e1e.",
+ "\u0e21\u0e35.\u0e04.",
+ "\u0e40\u0e21.\u0e22.",
+ "\u0e1e.\u0e04.",
+ "\u0e21\u0e34.\u0e22.",
+ "\u0e01.\u0e04.",
+ "\u0e2a.\u0e04.",
+ "\u0e01.\u0e22.",
+ "\u0e15.\u0e04.",
+ "\u0e1e.\u0e22.",
+ "\u0e18.\u0e04."
+ ],
"fullDate": "EEEE\u0e17\u0e35\u0e48 d MMMM G y",
"longDate": "d MMMM y",
"medium": "d MMM y H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u0e3f",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "th-th",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_th.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07",
- "1": "\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07"
- },
- "DAY": {
- "0": "\u0e27\u0e31\u0e19\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c",
- "1": "\u0e27\u0e31\u0e19\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c",
- "2": "\u0e27\u0e31\u0e19\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23",
- "3": "\u0e27\u0e31\u0e19\u0e1e\u0e38\u0e18",
- "4": "\u0e27\u0e31\u0e19\u0e1e\u0e24\u0e2b\u0e31\u0e2a\u0e1a\u0e14\u0e35",
- "5": "\u0e27\u0e31\u0e19\u0e28\u0e38\u0e01\u0e23\u0e4c",
- "6": "\u0e27\u0e31\u0e19\u0e40\u0e2a\u0e32\u0e23\u0e4c"
- },
- "MONTH": {
- "0": "\u0e21\u0e01\u0e23\u0e32\u0e04\u0e21",
- "1": "\u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c",
- "2": "\u0e21\u0e35\u0e19\u0e32\u0e04\u0e21",
- "3": "\u0e40\u0e21\u0e29\u0e32\u0e22\u0e19",
- "4": "\u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21",
- "5": "\u0e21\u0e34\u0e16\u0e38\u0e19\u0e32\u0e22\u0e19",
- "6": "\u0e01\u0e23\u0e01\u0e0e\u0e32\u0e04\u0e21",
- "7": "\u0e2a\u0e34\u0e07\u0e2b\u0e32\u0e04\u0e21",
- "8": "\u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19",
- "9": "\u0e15\u0e38\u0e25\u0e32\u0e04\u0e21",
- "10": "\u0e1e\u0e24\u0e28\u0e08\u0e34\u0e01\u0e32\u0e22\u0e19",
- "11": "\u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21"
- },
- "SHORTDAY": {
- "0": "\u0e2d\u0e32.",
- "1": "\u0e08.",
- "2": "\u0e2d.",
- "3": "\u0e1e.",
- "4": "\u0e1e\u0e24.",
- "5": "\u0e28.",
- "6": "\u0e2a."
- },
- "SHORTMONTH": {
- "0": "\u0e21.\u0e04.",
- "1": "\u0e01.\u0e1e.",
- "2": "\u0e21\u0e35.\u0e04.",
- "3": "\u0e40\u0e21.\u0e22.",
- "4": "\u0e1e.\u0e04.",
- "5": "\u0e21\u0e34.\u0e22.",
- "6": "\u0e01.\u0e04.",
- "7": "\u0e2a.\u0e04.",
- "8": "\u0e01.\u0e22.",
- "9": "\u0e15.\u0e04.",
- "10": "\u0e1e.\u0e22.",
- "11": "\u0e18.\u0e04."
- },
+ "AMPMS": [
+ "\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07",
+ "\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07"
+ ],
+ "DAY": [
+ "\u0e27\u0e31\u0e19\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c",
+ "\u0e27\u0e31\u0e19\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c",
+ "\u0e27\u0e31\u0e19\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23",
+ "\u0e27\u0e31\u0e19\u0e1e\u0e38\u0e18",
+ "\u0e27\u0e31\u0e19\u0e1e\u0e24\u0e2b\u0e31\u0e2a\u0e1a\u0e14\u0e35",
+ "\u0e27\u0e31\u0e19\u0e28\u0e38\u0e01\u0e23\u0e4c",
+ "\u0e27\u0e31\u0e19\u0e40\u0e2a\u0e32\u0e23\u0e4c"
+ ],
+ "MONTH": [
+ "\u0e21\u0e01\u0e23\u0e32\u0e04\u0e21",
+ "\u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c",
+ "\u0e21\u0e35\u0e19\u0e32\u0e04\u0e21",
+ "\u0e40\u0e21\u0e29\u0e32\u0e22\u0e19",
+ "\u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21",
+ "\u0e21\u0e34\u0e16\u0e38\u0e19\u0e32\u0e22\u0e19",
+ "\u0e01\u0e23\u0e01\u0e0e\u0e32\u0e04\u0e21",
+ "\u0e2a\u0e34\u0e07\u0e2b\u0e32\u0e04\u0e21",
+ "\u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19",
+ "\u0e15\u0e38\u0e25\u0e32\u0e04\u0e21",
+ "\u0e1e\u0e24\u0e28\u0e08\u0e34\u0e01\u0e32\u0e22\u0e19",
+ "\u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21"
+ ],
+ "SHORTDAY": [
+ "\u0e2d\u0e32.",
+ "\u0e08.",
+ "\u0e2d.",
+ "\u0e1e.",
+ "\u0e1e\u0e24.",
+ "\u0e28.",
+ "\u0e2a."
+ ],
+ "SHORTMONTH": [
+ "\u0e21.\u0e04.",
+ "\u0e01.\u0e1e.",
+ "\u0e21\u0e35.\u0e04.",
+ "\u0e40\u0e21.\u0e22.",
+ "\u0e1e.\u0e04.",
+ "\u0e21\u0e34.\u0e22.",
+ "\u0e01.\u0e04.",
+ "\u0e2a.\u0e04.",
+ "\u0e01.\u0e22.",
+ "\u0e15.\u0e04.",
+ "\u0e1e.\u0e22.",
+ "\u0e18.\u0e04."
+ ],
"fullDate": "EEEE\u0e17\u0e35\u0e48 d MMMM G y",
"longDate": "d MMMM y",
"medium": "d MMM y H:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u0e3f",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "th",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tl.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tl.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tl.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Linggo",
- "1": "Lunes",
- "2": "Martes",
- "3": "Miyerkules",
- "4": "Huwebes",
- "5": "Biyernes",
- "6": "Sabado"
- },
- "MONTH": {
- "0": "Enero",
- "1": "Pebrero",
- "2": "Marso",
- "3": "Abril",
- "4": "Mayo",
- "5": "Hunyo",
- "6": "Hulyo",
- "7": "Agosto",
- "8": "Setyembre",
- "9": "Oktubre",
- "10": "Nobyembre",
- "11": "Disyembre"
- },
- "SHORTDAY": {
- "0": "Lin",
- "1": "Lun",
- "2": "Mar",
- "3": "Mye",
- "4": "Huw",
- "5": "Bye",
- "6": "Sab"
- },
- "SHORTMONTH": {
- "0": "Ene",
- "1": "Peb",
- "2": "Mar",
- "3": "Abr",
- "4": "May",
- "5": "Hun",
- "6": "Hul",
- "7": "Ago",
- "8": "Set",
- "9": "Okt",
- "10": "Nob",
- "11": "Dis"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Linggo",
+ "Lunes",
+ "Martes",
+ "Miyerkules",
+ "Huwebes",
+ "Biyernes",
+ "Sabado"
+ ],
+ "MONTH": [
+ "Enero",
+ "Pebrero",
+ "Marso",
+ "Abril",
+ "Mayo",
+ "Hunyo",
+ "Hulyo",
+ "Agosto",
+ "Setyembre",
+ "Oktubre",
+ "Nobyembre",
+ "Disyembre"
+ ],
+ "SHORTDAY": [
+ "Lin",
+ "Lun",
+ "Mar",
+ "Mye",
+ "Huw",
+ "Bye",
+ "Sab"
+ ],
+ "SHORTMONTH": [
+ "Ene",
+ "Peb",
+ "Mar",
+ "Abr",
+ "May",
+ "Hun",
+ "Hul",
+ "Ago",
+ "Set",
+ "Okt",
+ "Nob",
+ "Dis"
+ ],
"fullDate": "EEEE, MMMM dd y",
"longDate": "MMMM d, y",
"medium": "MMM d, y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b1",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "tl",
"pluralCat": function (n) { if (n == 0 || n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr-tr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr-tr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr-tr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Pazar",
- "1": "Pazartesi",
- "2": "Sal\u0131",
- "3": "\u00c7ar\u015famba",
- "4": "Per\u015fembe",
- "5": "Cuma",
- "6": "Cumartesi"
- },
- "MONTH": {
- "0": "Ocak",
- "1": "\u015eubat",
- "2": "Mart",
- "3": "Nisan",
- "4": "May\u0131s",
- "5": "Haziran",
- "6": "Temmuz",
- "7": "A\u011fustos",
- "8": "Eyl\u00fcl",
- "9": "Ekim",
- "10": "Kas\u0131m",
- "11": "Aral\u0131k"
- },
- "SHORTDAY": {
- "0": "Paz",
- "1": "Pzt",
- "2": "Sal",
- "3": "\u00c7ar",
- "4": "Per",
- "5": "Cum",
- "6": "Cmt"
- },
- "SHORTMONTH": {
- "0": "Oca",
- "1": "\u015eub",
- "2": "Mar",
- "3": "Nis",
- "4": "May",
- "5": "Haz",
- "6": "Tem",
- "7": "A\u011fu",
- "8": "Eyl",
- "9": "Eki",
- "10": "Kas",
- "11": "Ara"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Pazar",
+ "Pazartesi",
+ "Sal\u0131",
+ "\u00c7ar\u015famba",
+ "Per\u015fembe",
+ "Cuma",
+ "Cumartesi"
+ ],
+ "MONTH": [
+ "Ocak",
+ "\u015eubat",
+ "Mart",
+ "Nisan",
+ "May\u0131s",
+ "Haziran",
+ "Temmuz",
+ "A\u011fustos",
+ "Eyl\u00fcl",
+ "Ekim",
+ "Kas\u0131m",
+ "Aral\u0131k"
+ ],
+ "SHORTDAY": [
+ "Paz",
+ "Pzt",
+ "Sal",
+ "\u00c7ar",
+ "Per",
+ "Cum",
+ "Cmt"
+ ],
+ "SHORTMONTH": [
+ "Oca",
+ "\u015eub",
+ "Mar",
+ "Nis",
+ "May",
+ "Haz",
+ "Tem",
+ "A\u011fu",
+ "Eyl",
+ "Eki",
+ "Kas",
+ "Ara"
+ ],
"fullDate": "d MMMM y EEEE",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "TL",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "tr-tr",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_tr.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Pazar",
- "1": "Pazartesi",
- "2": "Sal\u0131",
- "3": "\u00c7ar\u015famba",
- "4": "Per\u015fembe",
- "5": "Cuma",
- "6": "Cumartesi"
- },
- "MONTH": {
- "0": "Ocak",
- "1": "\u015eubat",
- "2": "Mart",
- "3": "Nisan",
- "4": "May\u0131s",
- "5": "Haziran",
- "6": "Temmuz",
- "7": "A\u011fustos",
- "8": "Eyl\u00fcl",
- "9": "Ekim",
- "10": "Kas\u0131m",
- "11": "Aral\u0131k"
- },
- "SHORTDAY": {
- "0": "Paz",
- "1": "Pzt",
- "2": "Sal",
- "3": "\u00c7ar",
- "4": "Per",
- "5": "Cum",
- "6": "Cmt"
- },
- "SHORTMONTH": {
- "0": "Oca",
- "1": "\u015eub",
- "2": "Mar",
- "3": "Nis",
- "4": "May",
- "5": "Haz",
- "6": "Tem",
- "7": "A\u011fu",
- "8": "Eyl",
- "9": "Eki",
- "10": "Kas",
- "11": "Ara"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Pazar",
+ "Pazartesi",
+ "Sal\u0131",
+ "\u00c7ar\u015famba",
+ "Per\u015fembe",
+ "Cuma",
+ "Cumartesi"
+ ],
+ "MONTH": [
+ "Ocak",
+ "\u015eubat",
+ "Mart",
+ "Nisan",
+ "May\u0131s",
+ "Haziran",
+ "Temmuz",
+ "A\u011fustos",
+ "Eyl\u00fcl",
+ "Ekim",
+ "Kas\u0131m",
+ "Aral\u0131k"
+ ],
+ "SHORTDAY": [
+ "Paz",
+ "Pzt",
+ "Sal",
+ "\u00c7ar",
+ "Per",
+ "Cum",
+ "Cmt"
+ ],
+ "SHORTMONTH": [
+ "Oca",
+ "\u015eub",
+ "Mar",
+ "Nis",
+ "May",
+ "Haz",
+ "Tem",
+ "A\u011fu",
+ "Eyl",
+ "Eki",
+ "Kas",
+ "Ara"
+ ],
"fullDate": "d MMMM y EEEE",
"longDate": "d MMMM y",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "TL",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "tr",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk-ua.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk-ua.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk-ua.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0434\u043f",
- "1": "\u043f\u043f"
- },
- "DAY": {
- "0": "\u041d\u0435\u0434\u0456\u043b\u044f",
- "1": "\u041f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a",
- "2": "\u0412\u0456\u0432\u0442\u043e\u0440\u043e\u043a",
- "3": "\u0421\u0435\u0440\u0435\u0434\u0430",
- "4": "\u0427\u0435\u0442\u0432\u0435\u0440",
- "5": "\u041f\u02bc\u044f\u0442\u043d\u0438\u0446\u044f",
- "6": "\u0421\u0443\u0431\u043e\u0442\u0430"
- },
- "MONTH": {
- "0": "\u0441\u0456\u0447\u043d\u044f",
- "1": "\u043b\u044e\u0442\u043e\u0433\u043e",
- "2": "\u0431\u0435\u0440\u0435\u0437\u043d\u044f",
- "3": "\u043a\u0432\u0456\u0442\u043d\u044f",
- "4": "\u0442\u0440\u0430\u0432\u043d\u044f",
- "5": "\u0447\u0435\u0440\u0432\u043d\u044f",
- "6": "\u043b\u0438\u043f\u043d\u044f",
- "7": "\u0441\u0435\u0440\u043f\u043d\u044f",
- "8": "\u0432\u0435\u0440\u0435\u0441\u043d\u044f",
- "9": "\u0436\u043e\u0432\u0442\u043d\u044f",
- "10": "\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434\u0430",
- "11": "\u0433\u0440\u0443\u0434\u043d\u044f"
- },
- "SHORTDAY": {
- "0": "\u041d\u0434",
- "1": "\u041f\u043d",
- "2": "\u0412\u0442",
- "3": "\u0421\u0440",
- "4": "\u0427\u0442",
- "5": "\u041f\u0442",
- "6": "\u0421\u0431"
- },
- "SHORTMONTH": {
- "0": "\u0441\u0456\u0447.",
- "1": "\u043b\u044e\u0442.",
- "2": "\u0431\u0435\u0440.",
- "3": "\u043a\u0432\u0456\u0442.",
- "4": "\u0442\u0440\u0430\u0432.",
- "5": "\u0447\u0435\u0440\u0432.",
- "6": "\u043b\u0438\u043f.",
- "7": "\u0441\u0435\u0440\u043f.",
- "8": "\u0432\u0435\u0440.",
- "9": "\u0436\u043e\u0432\u0442.",
- "10": "\u043b\u0438\u0441\u0442.",
- "11": "\u0433\u0440\u0443\u0434."
- },
+ "AMPMS": [
+ "\u0434\u043f",
+ "\u043f\u043f"
+ ],
+ "DAY": [
+ "\u041d\u0435\u0434\u0456\u043b\u044f",
+ "\u041f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a",
+ "\u0412\u0456\u0432\u0442\u043e\u0440\u043e\u043a",
+ "\u0421\u0435\u0440\u0435\u0434\u0430",
+ "\u0427\u0435\u0442\u0432\u0435\u0440",
+ "\u041f\u02bc\u044f\u0442\u043d\u0438\u0446\u044f",
+ "\u0421\u0443\u0431\u043e\u0442\u0430"
+ ],
+ "MONTH": [
+ "\u0441\u0456\u0447\u043d\u044f",
+ "\u043b\u044e\u0442\u043e\u0433\u043e",
+ "\u0431\u0435\u0440\u0435\u0437\u043d\u044f",
+ "\u043a\u0432\u0456\u0442\u043d\u044f",
+ "\u0442\u0440\u0430\u0432\u043d\u044f",
+ "\u0447\u0435\u0440\u0432\u043d\u044f",
+ "\u043b\u0438\u043f\u043d\u044f",
+ "\u0441\u0435\u0440\u043f\u043d\u044f",
+ "\u0432\u0435\u0440\u0435\u0441\u043d\u044f",
+ "\u0436\u043e\u0432\u0442\u043d\u044f",
+ "\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434\u0430",
+ "\u0433\u0440\u0443\u0434\u043d\u044f"
+ ],
+ "SHORTDAY": [
+ "\u041d\u0434",
+ "\u041f\u043d",
+ "\u0412\u0442",
+ "\u0421\u0440",
+ "\u0427\u0442",
+ "\u041f\u0442",
+ "\u0421\u0431"
+ ],
+ "SHORTMONTH": [
+ "\u0441\u0456\u0447.",
+ "\u043b\u044e\u0442.",
+ "\u0431\u0435\u0440.",
+ "\u043a\u0432\u0456\u0442.",
+ "\u0442\u0440\u0430\u0432.",
+ "\u0447\u0435\u0440\u0432.",
+ "\u043b\u0438\u043f.",
+ "\u0441\u0435\u0440\u043f.",
+ "\u0432\u0435\u0440.",
+ "\u0436\u043e\u0432\u0442.",
+ "\u043b\u0438\u0441\u0442.",
+ "\u0433\u0440\u0443\u0434."
+ ],
"fullDate": "EEEE, d MMMM y '\u0440'.",
"longDate": "d MMMM y '\u0440'.",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b4",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "uk-ua",
"pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_uk.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u0434\u043f",
- "1": "\u043f\u043f"
- },
- "DAY": {
- "0": "\u041d\u0435\u0434\u0456\u043b\u044f",
- "1": "\u041f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a",
- "2": "\u0412\u0456\u0432\u0442\u043e\u0440\u043e\u043a",
- "3": "\u0421\u0435\u0440\u0435\u0434\u0430",
- "4": "\u0427\u0435\u0442\u0432\u0435\u0440",
- "5": "\u041f\u02bc\u044f\u0442\u043d\u0438\u0446\u044f",
- "6": "\u0421\u0443\u0431\u043e\u0442\u0430"
- },
- "MONTH": {
- "0": "\u0441\u0456\u0447\u043d\u044f",
- "1": "\u043b\u044e\u0442\u043e\u0433\u043e",
- "2": "\u0431\u0435\u0440\u0435\u0437\u043d\u044f",
- "3": "\u043a\u0432\u0456\u0442\u043d\u044f",
- "4": "\u0442\u0440\u0430\u0432\u043d\u044f",
- "5": "\u0447\u0435\u0440\u0432\u043d\u044f",
- "6": "\u043b\u0438\u043f\u043d\u044f",
- "7": "\u0441\u0435\u0440\u043f\u043d\u044f",
- "8": "\u0432\u0435\u0440\u0435\u0441\u043d\u044f",
- "9": "\u0436\u043e\u0432\u0442\u043d\u044f",
- "10": "\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434\u0430",
- "11": "\u0433\u0440\u0443\u0434\u043d\u044f"
- },
- "SHORTDAY": {
- "0": "\u041d\u0434",
- "1": "\u041f\u043d",
- "2": "\u0412\u0442",
- "3": "\u0421\u0440",
- "4": "\u0427\u0442",
- "5": "\u041f\u0442",
- "6": "\u0421\u0431"
- },
- "SHORTMONTH": {
- "0": "\u0441\u0456\u0447.",
- "1": "\u043b\u044e\u0442.",
- "2": "\u0431\u0435\u0440.",
- "3": "\u043a\u0432\u0456\u0442.",
- "4": "\u0442\u0440\u0430\u0432.",
- "5": "\u0447\u0435\u0440\u0432.",
- "6": "\u043b\u0438\u043f.",
- "7": "\u0441\u0435\u0440\u043f.",
- "8": "\u0432\u0435\u0440.",
- "9": "\u0436\u043e\u0432\u0442.",
- "10": "\u043b\u0438\u0441\u0442.",
- "11": "\u0433\u0440\u0443\u0434."
- },
+ "AMPMS": [
+ "\u0434\u043f",
+ "\u043f\u043f"
+ ],
+ "DAY": [
+ "\u041d\u0435\u0434\u0456\u043b\u044f",
+ "\u041f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a",
+ "\u0412\u0456\u0432\u0442\u043e\u0440\u043e\u043a",
+ "\u0421\u0435\u0440\u0435\u0434\u0430",
+ "\u0427\u0435\u0442\u0432\u0435\u0440",
+ "\u041f\u02bc\u044f\u0442\u043d\u0438\u0446\u044f",
+ "\u0421\u0443\u0431\u043e\u0442\u0430"
+ ],
+ "MONTH": [
+ "\u0441\u0456\u0447\u043d\u044f",
+ "\u043b\u044e\u0442\u043e\u0433\u043e",
+ "\u0431\u0435\u0440\u0435\u0437\u043d\u044f",
+ "\u043a\u0432\u0456\u0442\u043d\u044f",
+ "\u0442\u0440\u0430\u0432\u043d\u044f",
+ "\u0447\u0435\u0440\u0432\u043d\u044f",
+ "\u043b\u0438\u043f\u043d\u044f",
+ "\u0441\u0435\u0440\u043f\u043d\u044f",
+ "\u0432\u0435\u0440\u0435\u0441\u043d\u044f",
+ "\u0436\u043e\u0432\u0442\u043d\u044f",
+ "\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434\u0430",
+ "\u0433\u0440\u0443\u0434\u043d\u044f"
+ ],
+ "SHORTDAY": [
+ "\u041d\u0434",
+ "\u041f\u043d",
+ "\u0412\u0442",
+ "\u0421\u0440",
+ "\u0427\u0442",
+ "\u041f\u0442",
+ "\u0421\u0431"
+ ],
+ "SHORTMONTH": [
+ "\u0441\u0456\u0447.",
+ "\u043b\u044e\u0442.",
+ "\u0431\u0435\u0440.",
+ "\u043a\u0432\u0456\u0442.",
+ "\u0442\u0440\u0430\u0432.",
+ "\u0447\u0435\u0440\u0432.",
+ "\u043b\u0438\u043f.",
+ "\u0441\u0435\u0440\u043f.",
+ "\u0432\u0435\u0440.",
+ "\u0436\u043e\u0432\u0442.",
+ "\u043b\u0438\u0441\u0442.",
+ "\u0433\u0440\u0443\u0434."
+ ],
"fullDate": "EEEE, d MMMM y '\u0440'.",
"longDate": "d MMMM y '\u0440'.",
"medium": "d MMM y HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20b4",
"DECIMAL_SEP": ",",
"GROUP_SEP": "\u00a0",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "uk",
"pluralCat": function (n) { if (n % 10 == 1 && n % 100 != 11) { return PLURAL_CATEGORY.ONE; } if (n == (n | 0) && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) { return PLURAL_CATEGORY.FEW; } if (n % 10 == 0 || n == (n | 0) && n % 10 >= 5 && n % 10 <= 9 || n == (n | 0) && n % 100 >= 11 && n % 100 <= 14) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur-pk.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur-pk.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur-pk.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u062f\u0646",
- "1": "\u0631\u0627\u062a"
- },
- "DAY": {
- "0": "\u0627\u062a\u0648\u0627\u0631",
- "1": "\u067e\u064a\u0631",
- "2": "\u0645\u0646\u06af\u0644",
- "3": "\u0628\u062f\u0647",
- "4": "\u062c\u0645\u0639\u0631\u0627\u062a",
- "5": "\u062c\u0645\u0639\u06c1",
- "6": "\u06c1\u0641\u062a\u06c1"
- },
- "MONTH": {
- "0": "\u062c\u0646\u0648\u0631\u06cc",
- "1": "\u0641\u0631\u0648\u0631\u06cc",
- "2": "\u0645\u0627\u0631\u0686",
- "3": "\u0627\u067e\u0631\u064a\u0644",
- "4": "\u0645\u0626",
- "5": "\u062c\u0648\u0646",
- "6": "\u062c\u0648\u0644\u0627\u0626",
- "7": "\u0627\u06af\u0633\u062a",
- "8": "\u0633\u062a\u0645\u0628\u0631",
- "9": "\u0627\u06a9\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0645\u0628\u0631",
- "11": "\u062f\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u062a\u0648\u0627\u0631",
- "1": "\u067e\u064a\u0631",
- "2": "\u0645\u0646\u06af\u0644",
- "3": "\u0628\u062f\u0647",
- "4": "\u062c\u0645\u0639\u0631\u0627\u062a",
- "5": "\u062c\u0645\u0639\u06c1",
- "6": "\u06c1\u0641\u062a\u06c1"
- },
- "SHORTMONTH": {
- "0": "\u062c\u0646\u0648\u0631\u06cc",
- "1": "\u0641\u0631\u0648\u0631\u06cc",
- "2": "\u0645\u0627\u0631\u0686",
- "3": "\u0627\u067e\u0631\u064a\u0644",
- "4": "\u0645\u0626",
- "5": "\u062c\u0648\u0646",
- "6": "\u062c\u0648\u0644\u0627\u0626",
- "7": "\u0627\u06af\u0633\u062a",
- "8": "\u0633\u062a\u0645\u0628\u0631",
- "9": "\u0627\u06a9\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0645\u0628\u0631",
- "11": "\u062f\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u062f\u0646",
+ "\u0631\u0627\u062a"
+ ],
+ "DAY": [
+ "\u0627\u062a\u0648\u0627\u0631",
+ "\u067e\u064a\u0631",
+ "\u0645\u0646\u06af\u0644",
+ "\u0628\u062f\u0647",
+ "\u062c\u0645\u0639\u0631\u0627\u062a",
+ "\u062c\u0645\u0639\u06c1",
+ "\u06c1\u0641\u062a\u06c1"
+ ],
+ "MONTH": [
+ "\u062c\u0646\u0648\u0631\u06cc",
+ "\u0641\u0631\u0648\u0631\u06cc",
+ "\u0645\u0627\u0631\u0686",
+ "\u0627\u067e\u0631\u064a\u0644",
+ "\u0645\u0626",
+ "\u062c\u0648\u0646",
+ "\u062c\u0648\u0644\u0627\u0626",
+ "\u0627\u06af\u0633\u062a",
+ "\u0633\u062a\u0645\u0628\u0631",
+ "\u0627\u06a9\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0645\u0628\u0631",
+ "\u062f\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u062a\u0648\u0627\u0631",
+ "\u067e\u064a\u0631",
+ "\u0645\u0646\u06af\u0644",
+ "\u0628\u062f\u0647",
+ "\u062c\u0645\u0639\u0631\u0627\u062a",
+ "\u062c\u0645\u0639\u06c1",
+ "\u06c1\u0641\u062a\u06c1"
+ ],
+ "SHORTMONTH": [
+ "\u062c\u0646\u0648\u0631\u06cc",
+ "\u0641\u0631\u0648\u0631\u06cc",
+ "\u0645\u0627\u0631\u0686",
+ "\u0627\u067e\u0631\u064a\u0644",
+ "\u0645\u0626",
+ "\u062c\u0648\u0646",
+ "\u062c\u0648\u0644\u0627\u0626",
+ "\u0627\u06af\u0633\u062a",
+ "\u0633\u062a\u0645\u0628\u0631",
+ "\u0627\u06a9\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0645\u0628\u0631",
+ "\u062f\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060d d\u060d MMMM y",
"longDate": "d\u060d MMMM y",
"medium": "d\u060d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Rs",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "ur-pk",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_ur.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u062f\u0646",
- "1": "\u0631\u0627\u062a"
- },
- "DAY": {
- "0": "\u0627\u062a\u0648\u0627\u0631",
- "1": "\u067e\u064a\u0631",
- "2": "\u0645\u0646\u06af\u0644",
- "3": "\u0628\u062f\u0647",
- "4": "\u062c\u0645\u0639\u0631\u0627\u062a",
- "5": "\u062c\u0645\u0639\u06c1",
- "6": "\u06c1\u0641\u062a\u06c1"
- },
- "MONTH": {
- "0": "\u062c\u0646\u0648\u0631\u06cc",
- "1": "\u0641\u0631\u0648\u0631\u06cc",
- "2": "\u0645\u0627\u0631\u0686",
- "3": "\u0627\u067e\u0631\u064a\u0644",
- "4": "\u0645\u0626",
- "5": "\u062c\u0648\u0646",
- "6": "\u062c\u0648\u0644\u0627\u0626",
- "7": "\u0627\u06af\u0633\u062a",
- "8": "\u0633\u062a\u0645\u0628\u0631",
- "9": "\u0627\u06a9\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0645\u0628\u0631",
- "11": "\u062f\u0633\u0645\u0628\u0631"
- },
- "SHORTDAY": {
- "0": "\u0627\u062a\u0648\u0627\u0631",
- "1": "\u067e\u064a\u0631",
- "2": "\u0645\u0646\u06af\u0644",
- "3": "\u0628\u062f\u0647",
- "4": "\u062c\u0645\u0639\u0631\u0627\u062a",
- "5": "\u062c\u0645\u0639\u06c1",
- "6": "\u06c1\u0641\u062a\u06c1"
- },
- "SHORTMONTH": {
- "0": "\u062c\u0646\u0648\u0631\u06cc",
- "1": "\u0641\u0631\u0648\u0631\u06cc",
- "2": "\u0645\u0627\u0631\u0686",
- "3": "\u0627\u067e\u0631\u064a\u0644",
- "4": "\u0645\u0626",
- "5": "\u062c\u0648\u0646",
- "6": "\u062c\u0648\u0644\u0627\u0626",
- "7": "\u0627\u06af\u0633\u062a",
- "8": "\u0633\u062a\u0645\u0628\u0631",
- "9": "\u0627\u06a9\u062a\u0648\u0628\u0631",
- "10": "\u0646\u0648\u0645\u0628\u0631",
- "11": "\u062f\u0633\u0645\u0628\u0631"
- },
+ "AMPMS": [
+ "\u062f\u0646",
+ "\u0631\u0627\u062a"
+ ],
+ "DAY": [
+ "\u0627\u062a\u0648\u0627\u0631",
+ "\u067e\u064a\u0631",
+ "\u0645\u0646\u06af\u0644",
+ "\u0628\u062f\u0647",
+ "\u062c\u0645\u0639\u0631\u0627\u062a",
+ "\u062c\u0645\u0639\u06c1",
+ "\u06c1\u0641\u062a\u06c1"
+ ],
+ "MONTH": [
+ "\u062c\u0646\u0648\u0631\u06cc",
+ "\u0641\u0631\u0648\u0631\u06cc",
+ "\u0645\u0627\u0631\u0686",
+ "\u0627\u067e\u0631\u064a\u0644",
+ "\u0645\u0626",
+ "\u062c\u0648\u0646",
+ "\u062c\u0648\u0644\u0627\u0626",
+ "\u0627\u06af\u0633\u062a",
+ "\u0633\u062a\u0645\u0628\u0631",
+ "\u0627\u06a9\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0645\u0628\u0631",
+ "\u062f\u0633\u0645\u0628\u0631"
+ ],
+ "SHORTDAY": [
+ "\u0627\u062a\u0648\u0627\u0631",
+ "\u067e\u064a\u0631",
+ "\u0645\u0646\u06af\u0644",
+ "\u0628\u062f\u0647",
+ "\u062c\u0645\u0639\u0631\u0627\u062a",
+ "\u062c\u0645\u0639\u06c1",
+ "\u06c1\u0641\u062a\u06c1"
+ ],
+ "SHORTMONTH": [
+ "\u062c\u0646\u0648\u0631\u06cc",
+ "\u0641\u0631\u0648\u0631\u06cc",
+ "\u0645\u0627\u0631\u0686",
+ "\u0627\u067e\u0631\u064a\u0644",
+ "\u0645\u0626",
+ "\u062c\u0648\u0646",
+ "\u062c\u0648\u0644\u0627\u0626",
+ "\u0627\u06af\u0633\u062a",
+ "\u0633\u062a\u0645\u0628\u0631",
+ "\u0627\u06a9\u062a\u0648\u0628\u0631",
+ "\u0646\u0648\u0645\u0628\u0631",
+ "\u062f\u0633\u0645\u0628\u0631"
+ ],
"fullDate": "EEEE\u060d d\u060d MMMM y",
"longDate": "d\u060d MMMM y",
"medium": "d\u060d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "Rs",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "ur",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi-vn.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi-vn.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi-vn.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "SA",
- "1": "CH"
- },
- "DAY": {
- "0": "Ch\u1ee7 nh\u1eadt",
- "1": "Th\u1ee9 hai",
- "2": "Th\u1ee9 ba",
- "3": "Th\u1ee9 t\u01b0",
- "4": "Th\u1ee9 n\u0103m",
- "5": "Th\u1ee9 s\u00e1u",
- "6": "Th\u1ee9 b\u1ea3y"
- },
- "MONTH": {
- "0": "th\u00e1ng m\u1ed9t",
- "1": "th\u00e1ng hai",
- "2": "th\u00e1ng ba",
- "3": "th\u00e1ng t\u01b0",
- "4": "th\u00e1ng n\u0103m",
- "5": "th\u00e1ng s\u00e1u",
- "6": "th\u00e1ng b\u1ea3y",
- "7": "th\u00e1ng t\u00e1m",
- "8": "th\u00e1ng ch\u00edn",
- "9": "th\u00e1ng m\u01b0\u1eddi",
- "10": "th\u00e1ng m\u01b0\u1eddi m\u1ed9t",
- "11": "th\u00e1ng m\u01b0\u1eddi hai"
- },
- "SHORTDAY": {
- "0": "CN",
- "1": "Th 2",
- "2": "Th 3",
- "3": "Th 4",
- "4": "Th 5",
- "5": "Th 6",
- "6": "Th 7"
- },
- "SHORTMONTH": {
- "0": "thg 1",
- "1": "thg 2",
- "2": "thg 3",
- "3": "thg 4",
- "4": "thg 5",
- "5": "thg 6",
- "6": "thg 7",
- "7": "thg 8",
- "8": "thg 9",
- "9": "thg 10",
- "10": "thg 11",
- "11": "thg 12"
- },
+ "AMPMS": [
+ "SA",
+ "CH"
+ ],
+ "DAY": [
+ "Ch\u1ee7 nh\u1eadt",
+ "Th\u1ee9 hai",
+ "Th\u1ee9 ba",
+ "Th\u1ee9 t\u01b0",
+ "Th\u1ee9 n\u0103m",
+ "Th\u1ee9 s\u00e1u",
+ "Th\u1ee9 b\u1ea3y"
+ ],
+ "MONTH": [
+ "th\u00e1ng m\u1ed9t",
+ "th\u00e1ng hai",
+ "th\u00e1ng ba",
+ "th\u00e1ng t\u01b0",
+ "th\u00e1ng n\u0103m",
+ "th\u00e1ng s\u00e1u",
+ "th\u00e1ng b\u1ea3y",
+ "th\u00e1ng t\u00e1m",
+ "th\u00e1ng ch\u00edn",
+ "th\u00e1ng m\u01b0\u1eddi",
+ "th\u00e1ng m\u01b0\u1eddi m\u1ed9t",
+ "th\u00e1ng m\u01b0\u1eddi hai"
+ ],
+ "SHORTDAY": [
+ "CN",
+ "Th 2",
+ "Th 3",
+ "Th 4",
+ "Th 5",
+ "Th 6",
+ "Th 7"
+ ],
+ "SHORTMONTH": [
+ "thg 1",
+ "thg 2",
+ "thg 3",
+ "thg 4",
+ "thg 5",
+ "thg 6",
+ "thg 7",
+ "thg 8",
+ "thg 9",
+ "thg 10",
+ "thg 11",
+ "thg 12"
+ ],
"fullDate": "EEEE, 'ng\u00e0y' dd MMMM 'n\u0103m' y",
"longDate": "'Ng\u00e0y' dd 'th\u00e1ng' M 'n\u0103m' y",
"medium": "dd-MM-yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ab",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "vi-vn",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_vi.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "SA",
- "1": "CH"
- },
- "DAY": {
- "0": "Ch\u1ee7 nh\u1eadt",
- "1": "Th\u1ee9 hai",
- "2": "Th\u1ee9 ba",
- "3": "Th\u1ee9 t\u01b0",
- "4": "Th\u1ee9 n\u0103m",
- "5": "Th\u1ee9 s\u00e1u",
- "6": "Th\u1ee9 b\u1ea3y"
- },
- "MONTH": {
- "0": "th\u00e1ng m\u1ed9t",
- "1": "th\u00e1ng hai",
- "2": "th\u00e1ng ba",
- "3": "th\u00e1ng t\u01b0",
- "4": "th\u00e1ng n\u0103m",
- "5": "th\u00e1ng s\u00e1u",
- "6": "th\u00e1ng b\u1ea3y",
- "7": "th\u00e1ng t\u00e1m",
- "8": "th\u00e1ng ch\u00edn",
- "9": "th\u00e1ng m\u01b0\u1eddi",
- "10": "th\u00e1ng m\u01b0\u1eddi m\u1ed9t",
- "11": "th\u00e1ng m\u01b0\u1eddi hai"
- },
- "SHORTDAY": {
- "0": "CN",
- "1": "Th 2",
- "2": "Th 3",
- "3": "Th 4",
- "4": "Th 5",
- "5": "Th 6",
- "6": "Th 7"
- },
- "SHORTMONTH": {
- "0": "thg 1",
- "1": "thg 2",
- "2": "thg 3",
- "3": "thg 4",
- "4": "thg 5",
- "5": "thg 6",
- "6": "thg 7",
- "7": "thg 8",
- "8": "thg 9",
- "9": "thg 10",
- "10": "thg 11",
- "11": "thg 12"
- },
+ "AMPMS": [
+ "SA",
+ "CH"
+ ],
+ "DAY": [
+ "Ch\u1ee7 nh\u1eadt",
+ "Th\u1ee9 hai",
+ "Th\u1ee9 ba",
+ "Th\u1ee9 t\u01b0",
+ "Th\u1ee9 n\u0103m",
+ "Th\u1ee9 s\u00e1u",
+ "Th\u1ee9 b\u1ea3y"
+ ],
+ "MONTH": [
+ "th\u00e1ng m\u1ed9t",
+ "th\u00e1ng hai",
+ "th\u00e1ng ba",
+ "th\u00e1ng t\u01b0",
+ "th\u00e1ng n\u0103m",
+ "th\u00e1ng s\u00e1u",
+ "th\u00e1ng b\u1ea3y",
+ "th\u00e1ng t\u00e1m",
+ "th\u00e1ng ch\u00edn",
+ "th\u00e1ng m\u01b0\u1eddi",
+ "th\u00e1ng m\u01b0\u1eddi m\u1ed9t",
+ "th\u00e1ng m\u01b0\u1eddi hai"
+ ],
+ "SHORTDAY": [
+ "CN",
+ "Th 2",
+ "Th 3",
+ "Th 4",
+ "Th 5",
+ "Th 6",
+ "Th 7"
+ ],
+ "SHORTMONTH": [
+ "thg 1",
+ "thg 2",
+ "thg 3",
+ "thg 4",
+ "thg 5",
+ "thg 6",
+ "thg 7",
+ "thg 8",
+ "thg 9",
+ "thg 10",
+ "thg 11",
+ "thg 12"
+ ],
"fullDate": "EEEE, 'ng\u00e0y' dd MMMM 'n\u0103m' y",
"longDate": "'Ng\u00e0y' dd 'th\u00e1ng' M 'n\u0103m' y",
"medium": "dd-MM-yyyy HH:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u20ab",
"DECIMAL_SEP": ",",
"GROUP_SEP": ".",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "",
"posSuf": "\u00a0\u00a4"
}
- }
+ ]
},
"id": "vi",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-cn.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-cn.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-cn.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u4e0a\u5348",
- "1": "\u4e0b\u5348"
- },
- "DAY": {
- "0": "\u661f\u671f\u65e5",
- "1": "\u661f\u671f\u4e00",
- "2": "\u661f\u671f\u4e8c",
- "3": "\u661f\u671f\u4e09",
- "4": "\u661f\u671f\u56db",
- "5": "\u661f\u671f\u4e94",
- "6": "\u661f\u671f\u516d"
- },
- "MONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
- "SHORTDAY": {
- "0": "\u5468\u65e5",
- "1": "\u5468\u4e00",
- "2": "\u5468\u4e8c",
- "3": "\u5468\u4e09",
- "4": "\u5468\u56db",
- "5": "\u5468\u4e94",
- "6": "\u5468\u516d"
- },
- "SHORTMONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
+ "AMPMS": [
+ "\u4e0a\u5348",
+ "\u4e0b\u5348"
+ ],
+ "DAY": [
+ "\u661f\u671f\u65e5",
+ "\u661f\u671f\u4e00",
+ "\u661f\u671f\u4e8c",
+ "\u661f\u671f\u4e09",
+ "\u661f\u671f\u56db",
+ "\u661f\u671f\u4e94",
+ "\u661f\u671f\u516d"
+ ],
+ "MONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
+ "SHORTDAY": [
+ "\u5468\u65e5",
+ "\u5468\u4e00",
+ "\u5468\u4e8c",
+ "\u5468\u4e09",
+ "\u5468\u56db",
+ "\u5468\u4e94",
+ "\u5468\u516d"
+ ],
+ "SHORTMONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
"fullDate": "y\u5e74M\u6708d\u65e5EEEE",
"longDate": "y\u5e74M\u6708d\u65e5",
"medium": "yyyy-M-d ah:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a5",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "zh-cn",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-cn.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-cn.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hans-cn.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u4e0a\u5348",
- "1": "\u4e0b\u5348"
- },
- "DAY": {
- "0": "\u661f\u671f\u65e5",
- "1": "\u661f\u671f\u4e00",
- "2": "\u661f\u671f\u4e8c",
- "3": "\u661f\u671f\u4e09",
- "4": "\u661f\u671f\u56db",
- "5": "\u661f\u671f\u4e94",
- "6": "\u661f\u671f\u516d"
- },
- "MONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
- "SHORTDAY": {
- "0": "\u5468\u65e5",
- "1": "\u5468\u4e00",
- "2": "\u5468\u4e8c",
- "3": "\u5468\u4e09",
- "4": "\u5468\u56db",
- "5": "\u5468\u4e94",
- "6": "\u5468\u516d"
- },
- "SHORTMONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
+ "AMPMS": [
+ "\u4e0a\u5348",
+ "\u4e0b\u5348"
+ ],
+ "DAY": [
+ "\u661f\u671f\u65e5",
+ "\u661f\u671f\u4e00",
+ "\u661f\u671f\u4e8c",
+ "\u661f\u671f\u4e09",
+ "\u661f\u671f\u56db",
+ "\u661f\u671f\u4e94",
+ "\u661f\u671f\u516d"
+ ],
+ "MONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
+ "SHORTDAY": [
+ "\u5468\u65e5",
+ "\u5468\u4e00",
+ "\u5468\u4e8c",
+ "\u5468\u4e09",
+ "\u5468\u56db",
+ "\u5468\u4e94",
+ "\u5468\u516d"
+ ],
+ "SHORTMONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
"fullDate": "y\u5e74M\u6708d\u65e5EEEE",
"longDate": "y\u5e74M\u6708d\u65e5",
"medium": "yyyy-M-d ah:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a5",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "zh-hans-cn",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hk.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hk.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-hk.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u4e0a\u5348",
- "1": "\u4e0b\u5348"
- },
- "DAY": {
- "0": "\u661f\u671f\u65e5",
- "1": "\u661f\u671f\u4e00",
- "2": "\u661f\u671f\u4e8c",
- "3": "\u661f\u671f\u4e09",
- "4": "\u661f\u671f\u56db",
- "5": "\u661f\u671f\u4e94",
- "6": "\u661f\u671f\u516d"
- },
- "MONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
- "SHORTDAY": {
- "0": "\u9031\u65e5",
- "1": "\u9031\u4e00",
- "2": "\u9031\u4e8c",
- "3": "\u9031\u4e09",
- "4": "\u9031\u56db",
- "5": "\u9031\u4e94",
- "6": "\u9031\u516d"
- },
- "SHORTMONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
+ "AMPMS": [
+ "\u4e0a\u5348",
+ "\u4e0b\u5348"
+ ],
+ "DAY": [
+ "\u661f\u671f\u65e5",
+ "\u661f\u671f\u4e00",
+ "\u661f\u671f\u4e8c",
+ "\u661f\u671f\u4e09",
+ "\u661f\u671f\u56db",
+ "\u661f\u671f\u4e94",
+ "\u661f\u671f\u516d"
+ ],
+ "MONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
+ "SHORTDAY": [
+ "\u9031\u65e5",
+ "\u9031\u4e00",
+ "\u9031\u4e8c",
+ "\u9031\u4e09",
+ "\u9031\u56db",
+ "\u9031\u4e94",
+ "\u9031\u516d"
+ ],
+ "SHORTMONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
"fullDate": "y\u5e74M\u6708d\u65e5EEEE",
"longDate": "y\u5e74M\u6708d\u65e5",
"medium": "y\u5e74M\u6708d\u65e5 ahh:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "zh-hk",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-tw.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-tw.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh-tw.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u4e0a\u5348",
- "1": "\u4e0b\u5348"
- },
- "DAY": {
- "0": "\u661f\u671f\u65e5",
- "1": "\u661f\u671f\u4e00",
- "2": "\u661f\u671f\u4e8c",
- "3": "\u661f\u671f\u4e09",
- "4": "\u661f\u671f\u56db",
- "5": "\u661f\u671f\u4e94",
- "6": "\u661f\u671f\u516d"
- },
- "MONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
- "SHORTDAY": {
- "0": "\u9031\u65e5",
- "1": "\u9031\u4e00",
- "2": "\u9031\u4e8c",
- "3": "\u9031\u4e09",
- "4": "\u9031\u56db",
- "5": "\u9031\u4e94",
- "6": "\u9031\u516d"
- },
- "SHORTMONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
+ "AMPMS": [
+ "\u4e0a\u5348",
+ "\u4e0b\u5348"
+ ],
+ "DAY": [
+ "\u661f\u671f\u65e5",
+ "\u661f\u671f\u4e00",
+ "\u661f\u671f\u4e8c",
+ "\u661f\u671f\u4e09",
+ "\u661f\u671f\u56db",
+ "\u661f\u671f\u4e94",
+ "\u661f\u671f\u516d"
+ ],
+ "MONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
+ "SHORTDAY": [
+ "\u9031\u65e5",
+ "\u9031\u4e00",
+ "\u9031\u4e8c",
+ "\u9031\u4e09",
+ "\u9031\u56db",
+ "\u9031\u4e94",
+ "\u9031\u516d"
+ ],
+ "SHORTMONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
"fullDate": "y\u5e74M\u6708d\u65e5EEEE",
"longDate": "y\u5e74M\u6708d\u65e5",
"medium": "yyyy/M/d ah:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "NT$",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "zh-tw",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zh.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "\u4e0a\u5348",
- "1": "\u4e0b\u5348"
- },
- "DAY": {
- "0": "\u661f\u671f\u65e5",
- "1": "\u661f\u671f\u4e00",
- "2": "\u661f\u671f\u4e8c",
- "3": "\u661f\u671f\u4e09",
- "4": "\u661f\u671f\u56db",
- "5": "\u661f\u671f\u4e94",
- "6": "\u661f\u671f\u516d"
- },
- "MONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
- "SHORTDAY": {
- "0": "\u5468\u65e5",
- "1": "\u5468\u4e00",
- "2": "\u5468\u4e8c",
- "3": "\u5468\u4e09",
- "4": "\u5468\u56db",
- "5": "\u5468\u4e94",
- "6": "\u5468\u516d"
- },
- "SHORTMONTH": {
- "0": "1\u6708",
- "1": "2\u6708",
- "2": "3\u6708",
- "3": "4\u6708",
- "4": "5\u6708",
- "5": "6\u6708",
- "6": "7\u6708",
- "7": "8\u6708",
- "8": "9\u6708",
- "9": "10\u6708",
- "10": "11\u6708",
- "11": "12\u6708"
- },
+ "AMPMS": [
+ "\u4e0a\u5348",
+ "\u4e0b\u5348"
+ ],
+ "DAY": [
+ "\u661f\u671f\u65e5",
+ "\u661f\u671f\u4e00",
+ "\u661f\u671f\u4e8c",
+ "\u661f\u671f\u4e09",
+ "\u661f\u671f\u56db",
+ "\u661f\u671f\u4e94",
+ "\u661f\u671f\u516d"
+ ],
+ "MONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
+ "SHORTDAY": [
+ "\u5468\u65e5",
+ "\u5468\u4e00",
+ "\u5468\u4e8c",
+ "\u5468\u4e09",
+ "\u5468\u56db",
+ "\u5468\u4e94",
+ "\u5468\u516d"
+ ],
+ "SHORTMONTH": [
+ "1\u6708",
+ "2\u6708",
+ "3\u6708",
+ "4\u6708",
+ "5\u6708",
+ "6\u6708",
+ "7\u6708",
+ "8\u6708",
+ "9\u6708",
+ "10\u6708",
+ "11\u6708",
+ "12\u6708"
+ ],
"fullDate": "y\u5e74M\u6708d\u65e5EEEE",
"longDate": "y\u5e74M\u6708d\u65e5",
"medium": "yyyy-M-d ah:mm:ss",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "\u00a5",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "zh",
"pluralCat": function (n) { return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu-za.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu-za.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu-za.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sonto",
- "1": "Msombuluko",
- "2": "Lwesibili",
- "3": "Lwesithathu",
- "4": "uLwesine",
- "5": "Lwesihlanu",
- "6": "Mgqibelo"
- },
- "MONTH": {
- "0": "Januwari",
- "1": "Februwari",
- "2": "Mashi",
- "3": "Apreli",
- "4": "Meyi",
- "5": "Juni",
- "6": "Julayi",
- "7": "Agasti",
- "8": "Septhemba",
- "9": "Okthoba",
- "10": "Novemba",
- "11": "Disemba"
- },
- "SHORTDAY": {
- "0": "Son",
- "1": "Mso",
- "2": "Bil",
- "3": "Tha",
- "4": "Sin",
- "5": "Hla",
- "6": "Mgq"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mas",
- "3": "Apr",
- "4": "Mey",
- "5": "Jun",
- "6": "Jul",
- "7": "Aga",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dis"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sonto",
+ "Msombuluko",
+ "Lwesibili",
+ "Lwesithathu",
+ "uLwesine",
+ "Lwesihlanu",
+ "Mgqibelo"
+ ],
+ "MONTH": [
+ "Januwari",
+ "Februwari",
+ "Mashi",
+ "Apreli",
+ "Meyi",
+ "Juni",
+ "Julayi",
+ "Agasti",
+ "Septhemba",
+ "Okthoba",
+ "Novemba",
+ "Disemba"
+ ],
+ "SHORTDAY": [
+ "Son",
+ "Mso",
+ "Bil",
+ "Tha",
+ "Sin",
+ "Hla",
+ "Mgq"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mas",
+ "Apr",
+ "Mey",
+ "Jun",
+ "Jul",
+ "Aga",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dis"
+ ],
"fullDate": "EEEE dd MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "R",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "zu-za",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
Modified: sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu.js
===================================================================
--- sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu.js 2013-08-12 09:54:05 UTC (rev 198)
+++ sandbox/nuiton-js-angular/src/main/resources/nuiton-js-angular/i18n/angular-locale_zu.js 2013-08-14 08:20:29 UTC (rev 199)
@@ -3,56 +3,56 @@
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
$provide.value("$locale", {
"DATETIME_FORMATS": {
- "AMPMS": {
- "0": "AM",
- "1": "PM"
- },
- "DAY": {
- "0": "Sonto",
- "1": "Msombuluko",
- "2": "Lwesibili",
- "3": "Lwesithathu",
- "4": "uLwesine",
- "5": "Lwesihlanu",
- "6": "Mgqibelo"
- },
- "MONTH": {
- "0": "Januwari",
- "1": "Februwari",
- "2": "Mashi",
- "3": "Apreli",
- "4": "Meyi",
- "5": "Juni",
- "6": "Julayi",
- "7": "Agasti",
- "8": "Septhemba",
- "9": "Okthoba",
- "10": "Novemba",
- "11": "Disemba"
- },
- "SHORTDAY": {
- "0": "Son",
- "1": "Mso",
- "2": "Bil",
- "3": "Tha",
- "4": "Sin",
- "5": "Hla",
- "6": "Mgq"
- },
- "SHORTMONTH": {
- "0": "Jan",
- "1": "Feb",
- "2": "Mas",
- "3": "Apr",
- "4": "Mey",
- "5": "Jun",
- "6": "Jul",
- "7": "Aga",
- "8": "Sep",
- "9": "Okt",
- "10": "Nov",
- "11": "Dis"
- },
+ "AMPMS": [
+ "AM",
+ "PM"
+ ],
+ "DAY": [
+ "Sonto",
+ "Msombuluko",
+ "Lwesibili",
+ "Lwesithathu",
+ "uLwesine",
+ "Lwesihlanu",
+ "Mgqibelo"
+ ],
+ "MONTH": [
+ "Januwari",
+ "Februwari",
+ "Mashi",
+ "Apreli",
+ "Meyi",
+ "Juni",
+ "Julayi",
+ "Agasti",
+ "Septhemba",
+ "Okthoba",
+ "Novemba",
+ "Disemba"
+ ],
+ "SHORTDAY": [
+ "Son",
+ "Mso",
+ "Bil",
+ "Tha",
+ "Sin",
+ "Hla",
+ "Mgq"
+ ],
+ "SHORTMONTH": [
+ "Jan",
+ "Feb",
+ "Mas",
+ "Apr",
+ "Mey",
+ "Jun",
+ "Jul",
+ "Aga",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dis"
+ ],
"fullDate": "EEEE dd MMMM y",
"longDate": "d MMMM y",
"medium": "d MMM y h:mm:ss a",
@@ -66,8 +66,8 @@
"CURRENCY_SYM": "R",
"DECIMAL_SEP": ".",
"GROUP_SEP": ",",
- "PATTERNS": {
- "0": {
+ "PATTERNS": [
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -79,7 +79,7 @@
"posPre": "",
"posSuf": ""
},
- "1": {
+ {
"gSize": 3,
"lgSize": 3,
"macFrac": 0,
@@ -91,7 +91,7 @@
"posPre": "\u00a4",
"posSuf": ""
}
- }
+ ]
},
"id": "zu",
"pluralCat": function (n) { if (n == 1) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
1
0
r198 - sandbox/nuiton-js-mustache/src/main/resources/META-INF/nuiton-js
by echatellier@users.nuiton.org Aug. 12, 2013
by echatellier@users.nuiton.org Aug. 12, 2013
Aug. 12, 2013
Author: echatellier
Date: 2013-08-12 11:54:05 +0200 (Mon, 12 Aug 2013)
New Revision: 198
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/198
Log:
fix wrong wro group name
Modified:
sandbox/nuiton-js-mustache/src/main/resources/META-INF/nuiton-js/wro-mustache.xml
Modified: sandbox/nuiton-js-mustache/src/main/resources/META-INF/nuiton-js/wro-mustache.xml
===================================================================
--- sandbox/nuiton-js-mustache/src/main/resources/META-INF/nuiton-js/wro-mustache.xml 2013-08-09 09:04:36 UTC (rev 197)
+++ sandbox/nuiton-js-mustache/src/main/resources/META-INF/nuiton-js/wro-mustache.xml 2013-08-12 09:54:05 UTC (rev 198)
@@ -22,7 +22,7 @@
#L%
-->
<groups xmlns="http://www.isdc.ro/wro">
- <group name='jquery'>
+ <group name='mustache'>
<js>classpath:nuiton-js-mustache/*.js</js>
</group>
</groups>
1
0
Author: tchemit
Date: 2013-08-09 11:04:36 +0200 (Fri, 09 Aug 2013)
New Revision: 197
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/197
Log:
- updates mavenpom to 4.0
- reformat poms
Modified:
trunk/nuiton-js-lib/pom.xml
trunk/pom.xml
Modified: trunk/nuiton-js-lib/pom.xml
===================================================================
(Binary files differ)
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2013-07-26 18:35:28 UTC (rev 196)
+++ trunk/pom.xml 2013-08-09 09:04:36 UTC (rev 197)
@@ -10,7 +10,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>mavenpom4redmineAndCentral</artifactId>
- <version>3.4.13</version>
+ <version>4.0</version>
</parent>
<groupId>org.nuiton.js</groupId>
1
0
Author: bpoussin
Date: 2013-07-26 20:35:28 +0200 (Fri, 26 Jul 2013)
New Revision: 196
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/196
Log:
add some explain about css file and font path modification
Modified:
sandbox/nuiton-js-font-awesome/README.txt
Modified: sandbox/nuiton-js-font-awesome/README.txt
===================================================================
(Binary files differ)
1
0
r195 - in sandbox/nuiton-js-font-awesome: . src/main/resources/nuiton-js-font-awesome/css
by bpoussin@users.nuiton.org July 26, 2013
by bpoussin@users.nuiton.org July 26, 2013
July 26, 2013
Author: bpoussin
Date: 2013-07-26 20:32:54 +0200 (Fri, 26 Jul 2013)
New Revision: 195
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/195
Log:
- don't filter font resource, otherwise font is corrupted
- remove extra path "?..." in font path otherwize find resource in classpath doesn't work
Modified:
sandbox/nuiton-js-font-awesome/pom.xml
sandbox/nuiton-js-font-awesome/src/main/resources/nuiton-js-font-awesome/css/font-awesome.css
Modified: sandbox/nuiton-js-font-awesome/pom.xml
===================================================================
(Binary files differ)
Modified: sandbox/nuiton-js-font-awesome/src/main/resources/nuiton-js-font-awesome/css/font-awesome.css
===================================================================
--- sandbox/nuiton-js-font-awesome/src/main/resources/nuiton-js-font-awesome/css/font-awesome.css 2013-07-22 13:42:18 UTC (rev 194)
+++ sandbox/nuiton-js-font-awesome/src/main/resources/nuiton-js-font-awesome/css/font-awesome.css 2013-07-26 18:32:54 UTC (rev 195)
@@ -28,7 +28,11 @@
@font-face {
font-family: 'FontAwesome';
src: url('../font/fontawesome-webfont.eot?v=3.2.1');
+ src: url('../font/fontawesome-webfont.eot') format('embedded-opentype'), url('../font/fontawesome-webfont.woff') format('woff'), url('../font/fontawesome-webfont.ttf') format('truetype'), url('../font/fontawesome-webfont.svg#fontawesomeregular') format('svg');
+/*
+ fixes CL: on ne met pas les '?...' car sinon le fichier n'est pas retrouve convenablement dans le classpath
src: url('../font/fontawesome-webfont.eot?#iefix&v=3.2.1') format('embedded-opentype'), url('../font/fontawesome-webfont.woff?v=3.2.1') format('woff'), url('../font/fontawesome-webfont.ttf?v=3.2.1') format('truetype'), url('../font/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1') format('svg');
+*/
font-weight: normal;
font-style: normal;
}
1
0
July 22, 2013
Author: echatellier
Date: 2013-07-22 15:42:18 +0200 (Mon, 22 Jul 2013)
New Revision: 194
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/194
Log:
Use released parent
Removed:
sandbox/nuiton-js-jquery-i18n-properties/changelog.txt
Deleted: sandbox/nuiton-js-jquery-i18n-properties/changelog.txt
===================================================================
--- sandbox/nuiton-js-jquery-i18n-properties/changelog.txt 2013-07-22 13:42:05 UTC (rev 193)
+++ sandbox/nuiton-js-jquery-i18n-properties/changelog.txt 2013-07-22 13:42:18 UTC (rev 194)
@@ -1,2 +0,0 @@
-Please refer to the release note :
- http://maven-site.nuiton.org/nuiton-js/changes-report.html
1
0
r193 - in sandbox: nuiton-js-moment nuiton-js-mustache nuiton-js-select2
by echatellier@users.nuiton.org July 22, 2013
by echatellier@users.nuiton.org July 22, 2013
July 22, 2013
Author: echatellier
Date: 2013-07-22 15:42:05 +0200 (Mon, 22 Jul 2013)
New Revision: 193
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/193
Log:
Use released parent
Modified:
sandbox/nuiton-js-moment/pom.xml
sandbox/nuiton-js-mustache/pom.xml
sandbox/nuiton-js-select2/pom.xml
Modified: sandbox/nuiton-js-moment/pom.xml
===================================================================
--- sandbox/nuiton-js-moment/pom.xml 2013-07-22 13:41:56 UTC (rev 192)
+++ sandbox/nuiton-js-moment/pom.xml 2013-07-22 13:42:05 UTC (rev 193)
@@ -10,7 +10,7 @@
<parent>
<groupId>org.nuiton.js</groupId>
<artifactId>nuiton-js-lib</artifactId>
- <version>1.0.1-SNAPSHOT</version>
+ <version>1.0.1</version>
</parent>
<artifactId>nuiton-js-moment</artifactId>
Modified: sandbox/nuiton-js-mustache/pom.xml
===================================================================
--- sandbox/nuiton-js-mustache/pom.xml 2013-07-22 13:41:56 UTC (rev 192)
+++ sandbox/nuiton-js-mustache/pom.xml 2013-07-22 13:42:05 UTC (rev 193)
@@ -10,7 +10,7 @@
<parent>
<groupId>org.nuiton.js</groupId>
<artifactId>nuiton-js-lib</artifactId>
- <version>1.0.1-SNAPSHOT</version>
+ <version>1.0.1</version>
</parent>
<artifactId>nuiton-js-mustache</artifactId>
Modified: sandbox/nuiton-js-select2/pom.xml
===================================================================
--- sandbox/nuiton-js-select2/pom.xml 2013-07-22 13:41:56 UTC (rev 192)
+++ sandbox/nuiton-js-select2/pom.xml 2013-07-22 13:42:05 UTC (rev 193)
@@ -10,7 +10,7 @@
<parent>
<groupId>org.nuiton.js</groupId>
<artifactId>nuiton-js-lib</artifactId>
- <version>1.0.1-SNAPSHOT</version>
+ <version>1.0.1</version>
</parent>
<artifactId>nuiton-js-select2</artifactId>
1
0
Author: echatellier
Date: 2013-07-22 15:41:56 +0200 (Mon, 22 Jul 2013)
New Revision: 192
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/192
Log:
Use released parent
Removed:
sandbox/nuiton-js-leaflet/changelog.txt
Modified:
sandbox/nuiton-js-leaflet/pom.xml
Deleted: sandbox/nuiton-js-leaflet/changelog.txt
===================================================================
Modified: sandbox/nuiton-js-leaflet/pom.xml
===================================================================
--- sandbox/nuiton-js-leaflet/pom.xml 2013-07-22 13:41:47 UTC (rev 191)
+++ sandbox/nuiton-js-leaflet/pom.xml 2013-07-22 13:41:56 UTC (rev 192)
@@ -10,7 +10,7 @@
<parent>
<groupId>org.nuiton.js</groupId>
<artifactId>nuiton-js-lib</artifactId>
- <version>1.0.1-SNAPSHOT</version>
+ <version>1.0.1</version>
</parent>
<artifactId>nuiton-js-leaflet</artifactId>
Property changes on: sandbox/nuiton-js-leaflet/pom.xml
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
1
0
r191 - in sandbox: nuiton-js-jquery-ui nuiton-js-jstree
by echatellier@users.nuiton.org July 22, 2013
by echatellier@users.nuiton.org July 22, 2013
July 22, 2013
Author: echatellier
Date: 2013-07-22 15:41:47 +0200 (Mon, 22 Jul 2013)
New Revision: 191
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/191
Log:
Use released parent
Removed:
sandbox/nuiton-js-jstree/changelog.txt
Modified:
sandbox/nuiton-js-jquery-ui/pom.xml
sandbox/nuiton-js-jstree/pom.xml
Modified: sandbox/nuiton-js-jquery-ui/pom.xml
===================================================================
--- sandbox/nuiton-js-jquery-ui/pom.xml 2013-07-22 13:41:36 UTC (rev 190)
+++ sandbox/nuiton-js-jquery-ui/pom.xml 2013-07-22 13:41:47 UTC (rev 191)
@@ -10,7 +10,7 @@
<parent>
<groupId>org.nuiton.js</groupId>
<artifactId>nuiton-js-lib</artifactId>
- <version>1.0.1-SNAPSHOT</version>
+ <version>1.0.1</version>
</parent>
<artifactId>nuiton-js-jquery-ui</artifactId>
Deleted: sandbox/nuiton-js-jstree/changelog.txt
===================================================================
--- sandbox/nuiton-js-jstree/changelog.txt 2013-07-22 13:41:36 UTC (rev 190)
+++ sandbox/nuiton-js-jstree/changelog.txt 2013-07-22 13:41:47 UTC (rev 191)
@@ -1,2 +0,0 @@
-Please refer to the release note :
- http://maven-site.nuiton.org/nuiton-js/changes-report.html
Modified: sandbox/nuiton-js-jstree/pom.xml
===================================================================
--- sandbox/nuiton-js-jstree/pom.xml 2013-07-22 13:41:36 UTC (rev 190)
+++ sandbox/nuiton-js-jstree/pom.xml 2013-07-22 13:41:47 UTC (rev 191)
@@ -10,11 +10,11 @@
<parent>
<groupId>org.nuiton.js</groupId>
<artifactId>nuiton-js-lib</artifactId>
- <version>1.0.1-SNAPSHOT</version>
+ <version>1.0.1</version>
</parent>
<artifactId>nuiton-js-jstree</artifactId>
- <version>1.0-rc3-1</version>
+ <version>1.0-rc3-2-SNAPSHOT</version>
<name>Nuiton JS :: JsTree</name>
<description>JsTree jar packaging</description>
Property changes on: sandbox/nuiton-js-jstree/pom.xml
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
1
0
July 22, 2013
Author: echatellier
Date: 2013-07-22 15:41:36 +0200 (Mon, 22 Jul 2013)
New Revision: 190
Url: http://nuiton.org/projects/nuiton-js/repository/revisions/190
Log:
Use released parent
Modified:
sandbox/nuiton-js-jquery-i18n-properties/pom.xml
Modified: sandbox/nuiton-js-jquery-i18n-properties/pom.xml
===================================================================
--- sandbox/nuiton-js-jquery-i18n-properties/pom.xml 2013-07-22 13:41:27 UTC (rev 189)
+++ sandbox/nuiton-js-jquery-i18n-properties/pom.xml 2013-07-22 13:41:36 UTC (rev 190)
@@ -10,11 +10,11 @@
<parent>
<groupId>org.nuiton.js</groupId>
<artifactId>nuiton-js-lib</artifactId>
- <version>1.0.1-SNAPSHOT</version>
+ <version>1.0.1</version>
</parent>
<artifactId>nuiton-js-jquery-i18n-properties</artifactId>
- <version>1.0.9-1</version>
+ <version>1.0.9-2-SNAPSHOT</version>
<name>Nuiton JS :: jQuery i18n properties</name>
<description>jQuery i18n properties jar packaging</description>
Property changes on: sandbox/nuiton-js-jquery-i18n-properties/pom.xml
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
1
0