d3_rails 2.8.0 → 2.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.DS_Store +0 -0
  2. data/README.md +27 -5
  3. data/lib/d3_rails/version.rb +1 -1
  4. data/vendor/.DS_Store +0 -0
  5. data/vendor/assets/.DS_Store +0 -0
  6. data/vendor/assets/javascripts/.DS_Store +0 -0
  7. data/vendor/assets/javascripts/d3.v2.js +99 -80
  8. data/vendor/assets/javascripts/morris.js +1 -0
  9. data/vendor/assets/javascripts/morris/.DS_Store +0 -0
  10. data/vendor/assets/javascripts/morris/Makefile +10 -0
  11. data/vendor/assets/javascripts/morris/README.md +87 -0
  12. data/vendor/assets/javascripts/morris/examples/_template.html +18 -0
  13. data/vendor/assets/javascripts/morris/examples/days.html +36 -0
  14. data/vendor/assets/javascripts/morris/examples/decimal.html +31 -0
  15. data/vendor/assets/javascripts/morris/examples/lib/example.css +13 -0
  16. data/vendor/assets/javascripts/morris/examples/lib/example.js +4 -0
  17. data/vendor/assets/javascripts/morris/examples/lib/prettify.css +1 -0
  18. data/vendor/assets/javascripts/morris/examples/lib/prettify.js +28 -0
  19. data/vendor/assets/javascripts/morris/examples/months-no-smooth.html +37 -0
  20. data/vendor/assets/javascripts/morris/examples/negative.html +35 -0
  21. data/vendor/assets/javascripts/morris/examples/non-date.html +36 -0
  22. data/vendor/assets/javascripts/morris/examples/quarters.html +53 -0
  23. data/vendor/assets/javascripts/morris/examples/timestamps.html +37 -0
  24. data/vendor/assets/javascripts/morris/examples/weeks.html +52 -0
  25. data/vendor/assets/javascripts/morris/morris.coffee +444 -0
  26. data/vendor/assets/javascripts/morris/morris.js +493 -0
  27. data/vendor/assets/javascripts/morris/morris.min.js +1 -0
  28. data/vendor/assets/javascripts/tesseract.js +1 -0
  29. data/vendor/assets/javascripts/tesseract/.gitignore +2 -0
  30. data/vendor/assets/javascripts/tesseract/LICENSE +12 -0
  31. data/vendor/assets/javascripts/tesseract/Makefile +48 -0
  32. data/vendor/assets/javascripts/tesseract/README.md +11 -0
  33. data/vendor/assets/javascripts/tesseract/index.js +1 -0
  34. data/vendor/assets/javascripts/tesseract/lib/dart/AUTHORS +9 -0
  35. data/vendor/assets/javascripts/tesseract/lib/dart/LICENSE +25 -0
  36. data/vendor/assets/javascripts/tesseract/lib/dart/dual_pivot_quicksort.dart +342 -0
  37. data/vendor/assets/javascripts/tesseract/package.json +11 -0
  38. data/vendor/assets/javascripts/tesseract/src/array.js +32 -0
  39. data/vendor/assets/javascripts/tesseract/src/bisect.js +44 -0
  40. data/vendor/assets/javascripts/tesseract/src/filter.js +19 -0
  41. data/vendor/assets/javascripts/tesseract/src/heap.js +44 -0
  42. data/vendor/assets/javascripts/tesseract/src/heapselect.js +36 -0
  43. data/vendor/assets/javascripts/tesseract/src/identity.js +3 -0
  44. data/vendor/assets/javascripts/tesseract/src/insertionsort.js +18 -0
  45. data/vendor/assets/javascripts/tesseract/src/null.js +3 -0
  46. data/vendor/assets/javascripts/tesseract/src/package.js +14 -0
  47. data/vendor/assets/javascripts/tesseract/src/permute.js +8 -0
  48. data/vendor/assets/javascripts/tesseract/src/quicksort.js +282 -0
  49. data/vendor/assets/javascripts/tesseract/src/reduce.js +19 -0
  50. data/vendor/assets/javascripts/tesseract/src/tesseract.js +663 -0
  51. data/vendor/assets/javascripts/tesseract/src/version.js +1 -0
  52. data/vendor/assets/javascripts/tesseract/src/zero.js +3 -0
  53. data/vendor/assets/javascripts/tesseract/tesseract.js +1177 -0
  54. data/vendor/assets/javascripts/tesseract/tesseract.min.js +1 -0
  55. data/vendor/assets/javascripts/tesseract/test/benchmark.js +177 -0
  56. data/vendor/assets/javascripts/tesseract/test/bisect-test.js +206 -0
  57. data/vendor/assets/javascripts/tesseract/test/heap-test.js +44 -0
  58. data/vendor/assets/javascripts/tesseract/test/permute-test.js +51 -0
  59. data/vendor/assets/javascripts/tesseract/test/select-test.js +63 -0
  60. data/vendor/assets/javascripts/tesseract/test/sort-test.js +83 -0
  61. data/vendor/assets/javascripts/tesseract/test/tesseract-test.js +655 -0
  62. data/vendor/assets/javascripts/tesseract/test/version-test.js +16 -0
  63. metadata +63 -8
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "tesseract",
3
+ "version": "1.0.1",
4
+ "private": true,
5
+ "main": "./index.js",
6
+ "devDependencies": {
7
+ "d3": "2.8.0",
8
+ "vows": "0.6.1",
9
+ "uglify-js": "1.2.5"
10
+ }
11
+ }
@@ -0,0 +1,32 @@
1
+ var tesseract_array8 = tesseract_arrayUntyped,
2
+ tesseract_array16 = tesseract_arrayUntyped,
3
+ tesseract_array32 = tesseract_arrayUntyped,
4
+ tesseract_arrayLengthen = tesseract_identity,
5
+ tesseract_arrayWiden = tesseract_identity;
6
+
7
+ if (typeof Uint8Array !== "undefined") {
8
+ tesseract_array8 = function(n) { return new Uint8Array(n); };
9
+ tesseract_array16 = function(n) { return new Uint16Array(n); };
10
+ tesseract_array32 = function(n) { return new Uint32Array(n); };
11
+
12
+ tesseract_arrayLengthen = function(array, length) {
13
+ var copy = new array.constructor(length);
14
+ copy.set(array);
15
+ return copy;
16
+ };
17
+
18
+ tesseract_arrayWiden = function(array, width) {
19
+ var copy;
20
+ switch (width) {
21
+ case 16: copy = tesseract_array16(array.length); break;
22
+ case 32: copy = tesseract_array32(array.length); break;
23
+ default: throw new Error("invalid array width!");
24
+ }
25
+ copy.set(array);
26
+ return copy;
27
+ };
28
+ }
29
+
30
+ function tesseract_arrayUntyped(n) {
31
+ return new Array(n);
32
+ }
@@ -0,0 +1,44 @@
1
+ var bisect = tesseract.bisect = bisect_by(tesseract_identity);
2
+
3
+ bisect.by = bisect_by;
4
+
5
+ function bisect_by(f) {
6
+
7
+ // Locate the insertion point for x in a to maintain sorted order. The
8
+ // arguments lo and hi may be used to specify a subset of the array which
9
+ // should be considered; by default the entire array is used. If x is already
10
+ // present in a, the insertion point will be before (to the left of) any
11
+ // existing entries. The return value is suitable for use as the first
12
+ // argument to `array.splice` assuming that a is already sorted.
13
+ //
14
+ // The returned insertion point i partitions the array a into two halves so
15
+ // that all v < x for v in a[lo:i] for the left side and all v >= x for v in
16
+ // a[i:hi] for the right side.
17
+ function bisectLeft(a, x, lo, hi) {
18
+ while (lo < hi) {
19
+ var mid = lo + hi >> 1;
20
+ if (f(a[mid]) < x) lo = mid + 1;
21
+ else hi = mid;
22
+ }
23
+ return lo;
24
+ }
25
+
26
+ // Similar to bisectLeft, but returns an insertion point which comes after (to
27
+ // the right of) any existing entries of x in a.
28
+ //
29
+ // The returned insertion point i partitions the array into two halves so that
30
+ // all v <= x for v in a[lo:i] for the left side and all v > x for v in
31
+ // a[i:hi] for the right side.
32
+ function bisectRight(a, x, lo, hi) {
33
+ while (lo < hi) {
34
+ var mid = lo + hi >> 1;
35
+ if (x < f(a[mid])) hi = mid;
36
+ else lo = mid + 1;
37
+ }
38
+ return lo;
39
+ }
40
+
41
+ bisectRight.right = bisectRight;
42
+ bisectRight.left = bisectLeft;
43
+ return bisectRight;
44
+ }
@@ -0,0 +1,19 @@
1
+ function tesseract_filterExact(bisect, value) {
2
+ return function(values) {
3
+ var n = values.length;
4
+ return [bisect.left(values, value, 0, n), bisect.right(values, value, 0, n)];
5
+ };
6
+ }
7
+
8
+ function tesseract_filterRange(bisect, range) {
9
+ var min = range[0],
10
+ max = range[1];
11
+ return function(values) {
12
+ var n = values.length;
13
+ return [bisect.left(values, min, 0, n), bisect.left(values, max, 0, n)];
14
+ };
15
+ }
16
+
17
+ function tesseract_filterAll(values) {
18
+ return [0, values.length];
19
+ }
@@ -0,0 +1,44 @@
1
+ var heap = tesseract.heap = heap_by(tesseract_identity);
2
+
3
+ heap.by = heap_by;
4
+
5
+ function heap_by(f) {
6
+
7
+ // Builds a binary heap within the specified array a[lo:hi]. The heap has the
8
+ // property such that the parent a[lo+i] is always less than or equal to its
9
+ // two children: a[lo+2*i+1] and a[lo+2*i+2].
10
+ function heap(a, lo, hi) {
11
+ var n = hi - lo,
12
+ i = (n >>> 1) + 1;
13
+ while (--i > 0) sift(a, i, n, lo);
14
+ return a;
15
+ }
16
+
17
+ // Sorts the specified array a[lo:hi] in descending order, assuming it is
18
+ // already a heap.
19
+ function sort(a, lo, hi) {
20
+ var n = hi - lo,
21
+ t;
22
+ while (--n > 0) t = a[lo], a[lo] = a[lo + n], a[lo + n] = t, sift(a, 1, n, lo);
23
+ return a;
24
+ }
25
+
26
+ // Sifts the element a[lo+i-1] down the heap, where the heap is the contiguous
27
+ // slice of array a[lo:lo+n]. This method can also be used to update the heap
28
+ // incrementally, without incurring the full cost of reconstructing the heap.
29
+ function sift(a, i, n, lo) {
30
+ var d = a[--lo + i],
31
+ x = f(d),
32
+ child;
33
+ while ((child = i << 1) <= n) {
34
+ if (child < n && f(a[lo + child]) > f(a[lo + child + 1])) child++;
35
+ if (x <= f(a[lo + child])) break;
36
+ a[lo + i] = a[lo + child];
37
+ i = child;
38
+ }
39
+ a[lo + i] = d;
40
+ }
41
+
42
+ heap.sort = sort;
43
+ return heap;
44
+ }
@@ -0,0 +1,36 @@
1
+ var heapselect = tesseract.heapselect = heapselect_by(tesseract_identity);
2
+
3
+ heapselect.by = heapselect_by;
4
+
5
+ function heapselect_by(f) {
6
+ var heap = heap_by(f);
7
+
8
+ // Returns a new array containing the top k elements in the array a[lo:hi].
9
+ // The returned array is not sorted, but maintains the heap property. If k is
10
+ // greater than hi - lo, then fewer than k elements will be returned. The
11
+ // order of elements in a is unchanged by this operation.
12
+ function heapselect(a, lo, hi, k) {
13
+ var queue = new Array(k = Math.min(hi - lo, k)),
14
+ min,
15
+ i,
16
+ x,
17
+ d;
18
+
19
+ for (i = 0; i < k; ++i) queue[i] = a[lo++];
20
+ heap(queue, 0, k);
21
+
22
+ if (lo < hi) {
23
+ min = f(queue[0]);
24
+ do {
25
+ if (x = f(d = a[lo]) > min) {
26
+ queue[0] = d;
27
+ min = f(heap(queue, 0, k)[0]);
28
+ }
29
+ } while (++lo < hi);
30
+ }
31
+
32
+ return queue;
33
+ }
34
+
35
+ return heapselect;
36
+ }
@@ -0,0 +1,3 @@
1
+ function tesseract_identity(d) {
2
+ return d;
3
+ }
@@ -0,0 +1,18 @@
1
+ var insertionsort = tesseract.insertionsort = insertionsort_by(tesseract_identity);
2
+
3
+ insertionsort.by = insertionsort_by;
4
+
5
+ function insertionsort_by(f) {
6
+
7
+ function insertionsort(a, lo, hi) {
8
+ for (var i = lo + 1; i < hi; ++i) {
9
+ for (var j = i, t = a[i], x = f(t); j > lo && f(a[j - 1]) > x; --j) {
10
+ a[j] = a[j - 1];
11
+ }
12
+ a[j] = t;
13
+ }
14
+ return a;
15
+ }
16
+
17
+ return insertionsort;
18
+ }
@@ -0,0 +1,3 @@
1
+ function tesseract_null() {
2
+ return null;
3
+ }
@@ -0,0 +1,14 @@
1
+ var util = require("util"),
2
+ tesseract = require("../tesseract").tesseract;
3
+
4
+ util.puts(JSON.stringify({
5
+ "name": "tesseract",
6
+ "version": tesseract.version,
7
+ "private": true,
8
+ "main": "./index.js",
9
+ "devDependencies": {
10
+ "d3": "2.8.0",
11
+ "vows": "0.6.1",
12
+ "uglify-js": "1.2.5"
13
+ }
14
+ }, null, 2));
@@ -0,0 +1,8 @@
1
+ tesseract.permute = permute;
2
+
3
+ function permute(array, index) {
4
+ for (var i = 0, n = index.length, copy = new Array(n); i < n; ++i) {
5
+ copy[i] = array[index[i]];
6
+ }
7
+ return copy;
8
+ }
@@ -0,0 +1,282 @@
1
+ // Algorithm designed by Vladimir Yaroslavskiy.
2
+ // Implementation based on the Dart project; see lib/dart/LICENSE for details.
3
+
4
+ var quicksort = tesseract.quicksort = quicksort_by(tesseract_identity);
5
+
6
+ quicksort.by = quicksort_by;
7
+
8
+ function quicksort_by(f) {
9
+ var insertionsort = insertionsort_by(f);
10
+
11
+ function sort(a, lo, hi) {
12
+ return (hi - lo < quicksort_sizeThreshold
13
+ ? insertionsort
14
+ : quicksort)(a, lo, hi);
15
+ }
16
+
17
+ function quicksort(a, lo, hi) {
18
+
19
+ // Compute the two pivots by looking at 5 elements.
20
+ var sixth = (hi - lo) / 6 | 0,
21
+ i1 = lo + sixth,
22
+ i5 = hi - 1 - sixth,
23
+ i3 = lo + hi - 1 >> 1, // The midpoint.
24
+ i2 = i3 - sixth,
25
+ i4 = i3 + sixth;
26
+
27
+ var e1 = a[i1], x1 = f(e1),
28
+ e2 = a[i2], x2 = f(e2),
29
+ e3 = a[i3], x3 = f(e3),
30
+ e4 = a[i4], x4 = f(e4),
31
+ e5 = a[i5], x5 = f(e5);
32
+
33
+ // Sort the selected 5 elements using a sorting network.
34
+ if (x1 > x2) t = e1, e1 = e2, e2 = t, t = x1, x1 = x2, x2 = t;
35
+ if (x4 > x5) t = e4, e4 = e5, e5 = t, t = x4, x4 = x5, x5 = t;
36
+ if (x1 > x3) t = e1, e1 = e3, e3 = t, t = x1, x1 = x3, x3 = t;
37
+ if (x2 > x3) t = e2, e2 = e3, e3 = t, t = x2, x2 = x3, x3 = t;
38
+ if (x1 > x4) t = e1, e1 = e4, e4 = t, t = x1, x1 = x4, x4 = t;
39
+ if (x3 > x4) t = e3, e3 = e4, e4 = t, t = x3, x3 = x4, x4 = t;
40
+ if (x2 > x5) t = e2, e2 = e5, e5 = t, t = x2, x2 = x5, x5 = t;
41
+ if (x2 > x3) t = e2, e2 = e3, e3 = t, t = x2, x2 = x3, x3 = t;
42
+ if (x4 > x5) t = e4, e4 = e5, e5 = t, t = x4, x4 = x5, x5 = t;
43
+
44
+ var pivot1 = e2, pivotValue1 = x2,
45
+ pivot2 = e4, pivotValue2 = x4;
46
+
47
+ // e2 and e4 have been saved in the pivot variables. They will be written
48
+ // back, once the partitioning is finished.
49
+ a[i1] = e1;
50
+ a[i2] = a[lo];
51
+ a[i3] = e3;
52
+ a[i4] = a[hi - 1];
53
+ a[i5] = e5;
54
+
55
+ var less = lo + 1, // First element in the middle partition.
56
+ great = hi - 2; // Last element in the middle partition.
57
+
58
+ // Note that for value comparison, <, <=, >= and > coerce to a primitive via
59
+ // Object.prototype.valueOf; == and === do not, so in order to be consistent
60
+ // with natural order (such as for Date objects), we must do two compares.
61
+ var pivotsEqual = pivotValue1 <= pivotValue2 && pivotValue1 >= pivotValue2;
62
+ if (pivotsEqual) {
63
+
64
+ // Degenerated case where the partitioning becomes a dutch national flag
65
+ // problem.
66
+ //
67
+ // [ | < pivot | == pivot | unpartitioned | > pivot | ]
68
+ // ^ ^ ^ ^ ^
69
+ // left less k great right
70
+ //
71
+ // a[left] and a[right] are undefined and are filled after the
72
+ // partitioning.
73
+ //
74
+ // Invariants:
75
+ // 1) for x in ]left, less[ : x < pivot.
76
+ // 2) for x in [less, k[ : x == pivot.
77
+ // 3) for x in ]great, right[ : x > pivot.
78
+ for (var k = less; k <= great; ++k) {
79
+ var ek = a[k], xk = f(ek);
80
+ if (xk < pivotValue1) {
81
+ if (k !== less) {
82
+ a[k] = a[less];
83
+ a[less] = ek;
84
+ }
85
+ ++less;
86
+ } else if (xk > pivotValue1) {
87
+
88
+ // Find the first element <= pivot in the range [k - 1, great] and
89
+ // put [:ek:] there. We know that such an element must exist:
90
+ // When k == less, then el3 (which is equal to pivot) lies in the
91
+ // interval. Otherwise a[k - 1] == pivot and the search stops at k-1.
92
+ // Note that in the latter case invariant 2 will be violated for a
93
+ // short amount of time. The invariant will be restored when the
94
+ // pivots are put into their final positions.
95
+ while (true) {
96
+ var greatValue = f(a[great]);
97
+ if (greatValue > pivotValue1) {
98
+ great--;
99
+ // This is the only location in the while-loop where a new
100
+ // iteration is started.
101
+ continue;
102
+ } else if (greatValue < pivotValue1) {
103
+ // Triple exchange.
104
+ a[k] = a[less];
105
+ a[less++] = a[great];
106
+ a[great--] = ek;
107
+ break;
108
+ } else {
109
+ a[k] = a[great];
110
+ a[great--] = ek;
111
+ // Note: if great < k then we will exit the outer loop and fix
112
+ // invariant 2 (which we just violated).
113
+ break;
114
+ }
115
+ }
116
+ }
117
+ }
118
+ } else {
119
+
120
+ // We partition the list into three parts:
121
+ // 1. < pivot1
122
+ // 2. >= pivot1 && <= pivot2
123
+ // 3. > pivot2
124
+ //
125
+ // During the loop we have:
126
+ // [ | < pivot1 | >= pivot1 && <= pivot2 | unpartitioned | > pivot2 | ]
127
+ // ^ ^ ^ ^ ^
128
+ // left less k great right
129
+ //
130
+ // a[left] and a[right] are undefined and are filled after the
131
+ // partitioning.
132
+ //
133
+ // Invariants:
134
+ // 1. for x in ]left, less[ : x < pivot1
135
+ // 2. for x in [less, k[ : pivot1 <= x && x <= pivot2
136
+ // 3. for x in ]great, right[ : x > pivot2
137
+ for (var k = less; k <= great; k++) {
138
+ var ek = a[k], xk = f(ek);
139
+ if (xk < pivotValue1) {
140
+ if (k !== less) {
141
+ a[k] = a[less];
142
+ a[less] = ek;
143
+ }
144
+ ++less;
145
+ } else {
146
+ if (xk > pivotValue2) {
147
+ while (true) {
148
+ var greatValue = f(a[great]);
149
+ if (greatValue > pivotValue2) {
150
+ great--;
151
+ if (great < k) break;
152
+ // This is the only location inside the loop where a new
153
+ // iteration is started.
154
+ continue;
155
+ } else {
156
+ // a[great] <= pivot2.
157
+ if (greatValue < pivotValue1) {
158
+ // Triple exchange.
159
+ a[k] = a[less];
160
+ a[less++] = a[great];
161
+ a[great--] = ek;
162
+ } else {
163
+ // a[great] >= pivot1.
164
+ a[k] = a[great];
165
+ a[great--] = ek;
166
+ }
167
+ break;
168
+ }
169
+ }
170
+ }
171
+ }
172
+ }
173
+ }
174
+
175
+ // Move pivots into their final positions.
176
+ // We shrunk the list from both sides (a[left] and a[right] have
177
+ // meaningless values in them) and now we move elements from the first
178
+ // and third partition into these locations so that we can store the
179
+ // pivots.
180
+ a[lo] = a[less - 1];
181
+ a[less - 1] = pivot1;
182
+ a[hi - 1] = a[great + 1];
183
+ a[great + 1] = pivot2;
184
+
185
+ // The list is now partitioned into three partitions:
186
+ // [ < pivot1 | >= pivot1 && <= pivot2 | > pivot2 ]
187
+ // ^ ^ ^ ^
188
+ // left less great right
189
+
190
+ // Recursive descent. (Don't include the pivot values.)
191
+ sort(a, lo, less - 1);
192
+ sort(a, great + 2, hi);
193
+
194
+ if (pivotsEqual) {
195
+ // All elements in the second partition are equal to the pivot. No
196
+ // need to sort them.
197
+ return a;
198
+ }
199
+
200
+ // In theory it should be enough to call _doSort recursively on the second
201
+ // partition.
202
+ // The Android source however removes the pivot elements from the recursive
203
+ // call if the second partition is too large (more than 2/3 of the list).
204
+ if (less < i1 && great > i5) {
205
+ var lessValue, greatValue;
206
+ while ((lessValue = f(a[less])) <= pivotValue1 && lessValue >= pivotValue1) ++less;
207
+ while ((greatValue = f(a[great])) <= pivotValue2 && greatValue >= pivotValue2) --great;
208
+
209
+ // Copy paste of the previous 3-way partitioning with adaptions.
210
+ //
211
+ // We partition the list into three parts:
212
+ // 1. == pivot1
213
+ // 2. > pivot1 && < pivot2
214
+ // 3. == pivot2
215
+ //
216
+ // During the loop we have:
217
+ // [ == pivot1 | > pivot1 && < pivot2 | unpartitioned | == pivot2 ]
218
+ // ^ ^ ^
219
+ // less k great
220
+ //
221
+ // Invariants:
222
+ // 1. for x in [ *, less[ : x == pivot1
223
+ // 2. for x in [less, k[ : pivot1 < x && x < pivot2
224
+ // 3. for x in ]great, * ] : x == pivot2
225
+ for (var k = less; k <= great; k++) {
226
+ var ek = a[k], xk = f(ek);
227
+ if (xk <= pivotValue1 && xk >= pivotValue1) {
228
+ if (k !== less) {
229
+ a[k] = a[less];
230
+ a[less] = ek;
231
+ }
232
+ less++;
233
+ } else {
234
+ if (xk <= pivotValue2 && xk >= pivotValue2) {
235
+ while (true) {
236
+ var greatValue = f(a[great]);
237
+ if (greatValue <= pivotValue2 && greatValue >= pivotValue2) {
238
+ great--;
239
+ if (great < k) break;
240
+ // This is the only location inside the loop where a new
241
+ // iteration is started.
242
+ continue;
243
+ } else {
244
+ // a[great] < pivot2.
245
+ if (greatValue < pivotValue1) {
246
+ // Triple exchange.
247
+ a[k] = a[less];
248
+ a[less++] = a[great];
249
+ a[great--] = ek;
250
+ } else {
251
+ // a[great] == pivot1.
252
+ a[k] = a[great];
253
+ a[great--] = ek;
254
+ }
255
+ break;
256
+ }
257
+ }
258
+ }
259
+ }
260
+ }
261
+ }
262
+
263
+ // The second partition has now been cleared of pivot elements and looks
264
+ // as follows:
265
+ // [ * | > pivot1 && < pivot2 | * ]
266
+ // ^ ^
267
+ // less great
268
+ // Sort the second partition using recursive descent.
269
+
270
+ // The second partition looks as follows:
271
+ // [ * | >= pivot1 && <= pivot2 | * ]
272
+ // ^ ^
273
+ // less great
274
+ // Simply sort it by recursive descent.
275
+
276
+ return sort(a, less, great + 1);
277
+ }
278
+
279
+ return sort;
280
+ }
281
+
282
+ var quicksort_sizeThreshold = 32;