yellow-brick-road 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. data/README.rst +42 -20
  2. data/lib/generators/templates/yellow_brick_road.rb.erb +19 -0
  3. data/lib/generators/yellow_brick_road/install_generator.rb +14 -0
  4. data/lib/yellow-brick-road/config.rb +41 -8
  5. data/lib/yellow-brick-road/directive_processor.rb +6 -5
  6. data/lib/yellow-brick-road/engine.rb +2 -3
  7. data/lib/yellow-brick-road/soy_processor.rb +1 -1
  8. data/lib/yellow-brick-road/version.rb +1 -1
  9. data/test/dummy/app/assets/javascripts/closure-deps.js +1 -1
  10. data/test/dummy/config/initializers/yellow_brick_road.rb +18 -1
  11. data/test/dummy/log/development.log +2208 -0
  12. data/test/dummy/tmp/cache/assets/C33/E00/sprockets%2F50c54266987e056bca666f8951752841 +2556 -0
  13. data/test/dummy/tmp/cache/assets/C48/990/sprockets%2F182c7921a46c3b8603c7f5595a111407 +823 -0
  14. data/test/dummy/tmp/cache/assets/C53/B40/sprockets%2F48cf0c035092dc945559526a279061c6 +204 -0
  15. data/test/dummy/tmp/cache/assets/C60/DB0/sprockets%2F3f00684578f2a3246581db667309ed89 +187 -0
  16. data/test/dummy/tmp/cache/assets/C60/E40/sprockets%2F3c5422f721521f492a5f02ca00b70009 +457 -0
  17. data/test/dummy/tmp/cache/assets/C73/DE0/sprockets%2F21f1f4574326846114a3c106873cebc3 +0 -0
  18. data/test/dummy/tmp/cache/assets/C7E/9F0/sprockets%2F89862076204c62c4593ac20de32da909 +4 -4
  19. data/test/dummy/tmp/cache/assets/C80/6F0/sprockets%2F56459a0713f8610d7d261f8be93073a2 +115 -0
  20. data/test/dummy/tmp/cache/assets/C8D/E10/sprockets%2F34b84bc4732937f885707002eda3896e +511 -0
  21. data/test/dummy/tmp/cache/assets/C93/CB0/sprockets%2F539b403b24833ca478a6f5877f37687c +239 -0
  22. data/test/dummy/tmp/cache/assets/C9A/C70/sprockets%2F10933dc6d342f604514713510b9ef0ab +806 -0
  23. data/test/dummy/tmp/cache/assets/CA0/7C0/sprockets%2Ff591bc0af8f085501241305c04907d3e +590 -0
  24. data/test/dummy/tmp/cache/assets/CA1/4A0/sprockets%2F5a9ad311e7d225b530b597041714b1e9 +2539 -0
  25. data/test/dummy/tmp/cache/assets/CA7/310/sprockets%2F45664cf816315200b574e029fde6f10a +0 -0
  26. data/test/dummy/tmp/cache/assets/CA7/A80/sprockets%2F1f32590957635a5a4f35442bc22f4ca4 +0 -0
  27. data/test/dummy/tmp/cache/assets/CAE/1D0/sprockets%2F2e62c7733d38a817a1532a744c6287bd +72 -0
  28. data/test/dummy/tmp/cache/assets/CB2/3C0/sprockets%2F9c35c290501a896b82c31448a39f3d5d +142 -0
  29. data/test/dummy/tmp/cache/assets/CB3/F20/sprockets%2F558b00e493fb501f7d95761e7eb40273 +2539 -0
  30. data/test/dummy/tmp/cache/assets/CBE/550/sprockets%2Fd680cac830e0b3408ba910f0b0421147 +2 -2
  31. data/test/dummy/tmp/cache/assets/CCD/480/sprockets%2Ffe7e11511634a2d03e1a20980b4593cf +0 -0
  32. data/test/dummy/tmp/cache/assets/CD0/080/sprockets%2Ffd5cbb87741244521d013d11c55573fa +204 -0
  33. data/test/dummy/tmp/cache/assets/CD2/020/sprockets%2Ff97740ba22118a2c91e992aac041843b +811 -0
  34. data/test/dummy/tmp/cache/assets/CD8/D90/sprockets%2F55dd841661d646f0024261a08ecf8ec0 +823 -0
  35. data/test/dummy/tmp/cache/assets/CE3/0D0/sprockets%2F301f97a178fd839a81bd663a6e22b616 +811 -0
  36. data/test/dummy/tmp/cache/assets/CE4/330/sprockets%2Fbd23466639af99164ab8e1c93721f14b +127 -0
  37. data/test/dummy/tmp/cache/assets/CE6/8A0/sprockets%2F3c0e7c5fa31563c8e820d6771e09918d +103 -0
  38. data/test/dummy/tmp/cache/assets/CEB/120/sprockets%2F857a0dde6829f7a27b93a840e1c60469 +522 -0
  39. data/test/dummy/tmp/cache/assets/CEE/CF0/sprockets%2F376f94b987d8156056c4e1d38ec06bf0 +0 -0
  40. data/test/dummy/tmp/cache/assets/CF2/C10/sprockets%2Fc64ef8a9dd0a1c3101d662750105c11a +806 -0
  41. data/test/dummy/tmp/cache/assets/CF3/CD0/sprockets%2F4bb42a5a6b504190f10d20b1c5f93d54 +1529 -0
  42. data/test/dummy/tmp/cache/assets/CF6/890/sprockets%2F36007a87f140155b5a04f2ca6b262dcc +494 -0
  43. data/test/dummy/tmp/cache/assets/CF6/9D0/sprockets%2F34b7199e9d33994c8ec7a442d60ca985 +173 -0
  44. data/test/dummy/tmp/cache/assets/CFA/A90/sprockets%2F901ba405a6d6747f6412ed4d0e0ac620 +256 -0
  45. data/test/dummy/tmp/cache/assets/CFC/E70/sprockets%2F8ee639668b5f0e629fbe0d62d1394689 +173 -0
  46. data/test/dummy/tmp/cache/assets/D04/1B0/sprockets%2F418f2b3b6b08b320f6db268a0991c54c +0 -0
  47. data/test/dummy/tmp/cache/assets/D05/920/sprockets%2F909507434dcc270db4853e4c147f0aac +5 -4
  48. data/test/dummy/tmp/cache/assets/D07/DB0/sprockets%2F0c17d7dac64290e385c91eb6f1570b31 +511 -0
  49. data/test/dummy/tmp/cache/assets/D07/EE0/sprockets%2F4999982b09e0b786894fce44f5d783cc +1371 -0
  50. data/test/dummy/tmp/cache/assets/D09/380/sprockets%2F14383e18fa2faac6b561a29d8e132863 +0 -0
  51. data/test/dummy/tmp/cache/assets/D0D/200/sprockets%2F545a7e34cce1d4272d83d58fd4215d42 +1277 -0
  52. data/test/dummy/tmp/cache/assets/D0E/870/sprockets%2F84996444f4f1f3fdc0248131cfb1a3b6 +794 -0
  53. data/test/dummy/tmp/cache/assets/D15/F60/sprockets%2Fa28394e3f80365b5bc86794dd46daa22 +0 -0
  54. data/test/dummy/tmp/cache/assets/D18/950/sprockets%2Fcf650d67c5d431ffdb38552e562299b2 +474 -0
  55. data/test/dummy/tmp/cache/assets/D18/E10/sprockets%2Fec7c58f640556b401fcd66528352dc9d +474 -0
  56. data/test/dummy/tmp/cache/assets/D20/660/sprockets%2F0d2875475ced01df962f3d758cda7792 +103 -0
  57. data/test/dummy/tmp/cache/assets/D22/AB0/sprockets%2F0b08e7f81651aaf739a93d61ae99779c +283 -0
  58. data/test/dummy/tmp/cache/assets/D2E/B20/sprockets%2Feed5412a17a52b1a335925e2af1f75d3 +0 -0
  59. data/test/dummy/tmp/cache/assets/D36/700/sprockets%2Fd219bf9db2eacc105bb294755093a437 +505 -0
  60. data/test/dummy/tmp/cache/assets/D3B/A10/sprockets%2Fcf38b51682d84a04da7b8a7313de52c6 +207 -0
  61. data/test/dummy/tmp/cache/assets/D3C/0E0/sprockets%2Fe9d7aba138d602c4a6ac701bc9615977 +505 -0
  62. data/test/dummy/tmp/cache/assets/D3E/FF0/sprockets%2F6bd8ccd3e02f397c20f349d5c0960e51 +0 -0
  63. data/test/dummy/tmp/cache/assets/D41/B30/sprockets%2Fba1b93913dd01d83ac9a96df334456f8 +0 -0
  64. data/test/dummy/tmp/cache/assets/D41/DA0/sprockets%2Fe8d00810698a9fcee032022fefd084f7 +0 -0
  65. data/test/dummy/tmp/cache/assets/D44/CF0/sprockets%2Ffa31a45f04884493c909c5a67fcbdf23 +1371 -0
  66. data/test/dummy/tmp/cache/assets/D47/BE0/sprockets%2F0b5ebdf6dec160a264698e7f745061e8 +142 -0
  67. data/test/dummy/tmp/cache/assets/D4C/F30/sprockets%2Ff90155c10f59a3fe44959ac09bf817fe +2556 -0
  68. data/test/dummy/tmp/cache/assets/D4E/7C0/sprockets%2Ff01b58512d01eda23fd5cb23a2b28b60 +1529 -0
  69. data/test/dummy/tmp/cache/assets/D4E/860/sprockets%2F86eed0c77c47d0970345bbabb58d8939 +1277 -0
  70. data/test/dummy/tmp/cache/assets/D4E/C30/sprockets%2F52420c10c73ca310d026565eafdadb4e +1545 -0
  71. data/test/dummy/tmp/cache/assets/D4E/F60/sprockets%2F9893a3c5aeb1a9e77469f4751b4d3c3f +115 -0
  72. data/test/dummy/tmp/cache/assets/D4F/E60/sprockets%2F17ee65de1f78c3dd5c165a9867e810b6 +165 -0
  73. data/test/dummy/tmp/cache/assets/D57/0D0/sprockets%2Fa29e6e8106d9d5ed1e2889126cfbf877 +300 -0
  74. data/test/dummy/tmp/cache/assets/D5C/650/sprockets%2Fe1c381da3cc213a639e956ae3315a2bd +607 -0
  75. data/test/dummy/tmp/cache/assets/D61/860/sprockets%2Fbf032a3b4aad2c2e25704e65c966cf45 +794 -0
  76. data/test/dummy/tmp/cache/assets/D63/B20/sprockets%2F31fc70ce66bb80fb9421be34eb3b0287 +0 -0
  77. data/test/dummy/tmp/cache/assets/D64/D60/sprockets%2Fa544ea03bf0a45948a053ba76ec2a79f +239 -0
  78. data/test/dummy/tmp/cache/assets/D6B/F90/sprockets%2F66636712ecb1fcc777dccf7643a0e1b1 +127 -0
  79. data/test/dummy/tmp/cache/assets/D6E/AD0/sprockets%2Fc91cdc6a72c729d7a64119198b3d2eab +0 -0
  80. data/test/dummy/tmp/cache/assets/D6F/140/sprockets%2F9ddc51f4388dd5243a28dba1ce47572b +53 -0
  81. data/test/dummy/tmp/cache/assets/D72/800/sprockets%2F92baa375d54e16fe0a5c7f079a1ce992 +165 -0
  82. data/test/dummy/tmp/cache/assets/D74/220/sprockets%2F3f888bda53179cb945eab35fbd31a708 +53 -0
  83. data/test/dummy/tmp/cache/assets/D78/5F0/sprockets%2F638ed6af667d4fc5147f72ff34aa2d33 +0 -0
  84. data/test/dummy/tmp/cache/assets/D7D/640/sprockets%2F95a7c5580f957c31e1ab9d0773ed5fde +607 -0
  85. data/test/dummy/tmp/cache/assets/D84/210/sprockets%2Fabd0103ccec2b428ac62c94e4c40b384 +6 -5
  86. data/test/dummy/tmp/cache/assets/D89/020/sprockets%2Fa06df6166e70324e712e54b1cafca0ae +187 -0
  87. data/test/dummy/tmp/cache/assets/D8A/9F0/sprockets%2Fc06547ca33ee3d03be14ce045ae1c9e2 +207 -0
  88. data/test/dummy/tmp/cache/assets/D9E/B80/sprockets%2F9561df1d45c7ff4aa8ac3e2df0c99121 +0 -0
  89. data/test/dummy/tmp/cache/assets/DA3/F30/sprockets%2Fe015d6ccdfcf022e47c83d7906f728ae +457 -0
  90. data/test/dummy/tmp/cache/assets/DAE/190/sprockets%2F433c7b21968be8d1f9bfdbdf7a637c57 +0 -0
  91. data/test/dummy/tmp/cache/assets/DB3/600/sprockets%2F9b70ae73f15ba693886eeef4eb5d6c75 +0 -0
  92. data/test/dummy/tmp/cache/assets/DB4/510/sprockets%2F29cdae8e29c88fd9ddbd4831419560fe +1260 -0
  93. data/test/dummy/tmp/cache/assets/DC1/4A0/sprockets%2F0b63dfcf163f2faeb612724eb4545bcc +1354 -0
  94. data/test/dummy/tmp/cache/assets/DC4/C10/sprockets%2Fcf48f4cbad3db33146eab4c577c1d209 +300 -0
  95. data/test/dummy/tmp/cache/assets/DC4/CA0/sprockets%2Fd0da8a60ea4dc16b9fd3e2a50d88633c +0 -0
  96. data/test/dummy/tmp/cache/assets/DC7/8C0/sprockets%2F1ad68dcc9ef598d3811ba2ac5c0ea182 +1354 -0
  97. data/test/dummy/tmp/cache/assets/DC7/C00/sprockets%2Fba755ff3a81c3192f0e45a4f7c0c7dcb +0 -0
  98. data/test/dummy/tmp/cache/assets/DCA/760/sprockets%2F717c4cea10bf601090ffdfe4e668e4cb +283 -0
  99. data/test/dummy/tmp/cache/assets/DCA/DE0/sprockets%2F51dcced9ec2b3cd4b1cc2949f860c361 +590 -0
  100. data/test/dummy/tmp/cache/assets/DD7/E70/sprockets%2F2595d8c8d1d5f4deb096247fb3bfc7ab +256 -0
  101. data/test/dummy/tmp/cache/assets/DE1/9D0/sprockets%2F8befd77af580ee16ec42ec95b1766ff3 +1545 -0
  102. data/test/dummy/tmp/cache/assets/E00/D80/sprockets%2F9debc27161f7bccf2d84a36b8c36c4bf +522 -0
  103. data/test/dummy/tmp/cache/assets/E00/E60/sprockets%2Fac159b94b0a6d621e4f6cde9b4de87bb +0 -0
  104. data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  105. data/test/dummy/tmp/cache/assets/E1B/D00/sprockets%2F886dff4afe55f9d3f8abe434f2689add +72 -0
  106. data/test/dummy/tmp/cache/assets/E1B/F20/sprockets%2Fa4bbc04eb83ebf94fd8134c3abd220dd +494 -0
  107. data/test/dummy/tmp/cache/assets/E71/0C0/sprockets%2F5ffdc0daa0a1f9638c787897ceefcdee +1260 -0
  108. metadata +186 -10
  109. data/test/dummy/tmp/pids/server.pid +0 -1
@@ -0,0 +1,300 @@
1
+ o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1325538161.897861: @value{I"
2
+ class:EFI"BundledAsset;
3
+ FI"id;
4
+ F"%6d1163dce166bc398445852c1e98d4fbI"logical_path;
5
+ FI"$closure/goog/asserts/asserts.js;
6
+ TI"
7
+ F"p/Volumes/Development/dev-web/closure-library-wrapper/vendor/closure-library/closure/goog/asserts/asserts.jsI"content_type;
8
+ FI"application/javascript;
9
+ FI"
10
+ mtime;
11
+ FI"2012-01-02T16:18:51+00:00;
12
+ FI" body;
13
+ FI"A)// Copyright 2008 The Closure Library Authors. All Rights Reserved.
14
+ //
15
+ // Licensed under the Apache License, Version 2.0 (the "License");
16
+ // you may not use this file except in compliance with the License.
17
+ // You may obtain a copy of the License at
18
+ //
19
+ // http://www.apache.org/licenses/LICENSE-2.0
20
+ //
21
+ // Unless required by applicable law or agreed to in writing, software
22
+ // distributed under the License is distributed on an "AS-IS" BASIS,
23
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
+ // See the License for the specific language governing permissions and
25
+ // limitations under the License.
26
+
27
+ /**
28
+ * @fileoverview Utilities to check the preconditions, postconditions and
29
+ * invariants runtime.
30
+ *
31
+ * Methods in this package should be given special treatment by the compiler
32
+ * for type-inference. For example, <code>goog.asserts.assert(foo)</code>
33
+ * will restrict <code>foo</code> to a truthy value.
34
+ *
35
+ * The compiler has an option to disable asserts. So code like:
36
+ * <code>
37
+ * var x = goog.asserts.assert(foo()); goog.asserts.assert(bar());
38
+ * </code>
39
+ * will be transformed into:
40
+ * <code>
41
+ * var x = foo();
42
+ * </code>
43
+ * The compiler will leave in foo() (because its return value is used),
44
+ * but it will remove bar() because it assumes it does not have side-effects.
45
+ *
46
+ */
47
+
48
+
49
+ goog.provide('goog.asserts');
50
+ goog.provide('goog.asserts.AssertionError');
51
+
52
+ goog.require('goog.debug.Error');
53
+ goog.require('goog.string');
54
+
55
+
56
+ /**
57
+ * @define {boolean} Whether to strip out asserts or to leave them in.
58
+ */
59
+ goog.asserts.ENABLE_ASSERTS = goog.DEBUG;
60
+
61
+
62
+
63
+ /**
64
+ * Error object for failed assertions.
65
+ * @param {string} messagePattern The pattern that was used to form message.
66
+ * @param {!Array.<*>} messageArgs The items to substitute into the pattern.
67
+ * @constructor
68
+ * @extends {goog.debug.Error}
69
+ */
70
+ goog.asserts.AssertionError = function(messagePattern, messageArgs) {
71
+ messageArgs.unshift(messagePattern);
72
+ goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs));
73
+ // Remove the messagePattern afterwards to avoid permenantly modifying the
74
+ // passed in array.
75
+ messageArgs.shift();
76
+
77
+ /**
78
+ * The message pattern used to format the error message. Error handlers can
79
+ * use this to uniquely identify the assertion.
80
+ * @type {string}
81
+ */
82
+ this.messagePattern = messagePattern;
83
+ };
84
+ goog.inherits(goog.asserts.AssertionError, goog.debug.Error);
85
+
86
+
87
+ /** @override */
88
+ goog.asserts.AssertionError.prototype.name = 'AssertionError';
89
+
90
+
91
+ /**
92
+ * Throws an exception with the given message and "Assertion failed" prefixed
93
+ * onto it.
94
+ * @param {string} defaultMessage The message to use if givenMessage is empty.
95
+ * @param {Array.<*>} defaultArgs The substitution arguments for defaultMessage.
96
+ * @param {string|undefined} givenMessage Message supplied by the caller.
97
+ * @param {Array.<*>} givenArgs The substitution arguments for givenMessage.
98
+ * @throws {goog.asserts.AssertionError} When the value is not a number.
99
+ * @private
100
+ */
101
+ goog.asserts.doAssertFailure_ =
102
+ function(defaultMessage, defaultArgs, givenMessage, givenArgs) {
103
+ var message = 'Assertion failed';
104
+ if (givenMessage) {
105
+ message += ': ' + givenMessage;
106
+ var args = givenArgs;
107
+ } else if (defaultMessage) {
108
+ message += ': ' + defaultMessage;
109
+ args = defaultArgs;
110
+ }
111
+ // The '' + works around an Opera 10 bug in the unit tests. Without it,
112
+ // a stack trace is added to var message above. With this, a stack trace is
113
+ // not added until this line (it causes the extra garbage to be added after
114
+ // the assertion message instead of in the middle of it).
115
+ throw new goog.asserts.AssertionError('' + message, args || []);
116
+ };
117
+
118
+
119
+ /**
120
+ * Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is
121
+ * true.
122
+ * @param {*} condition The condition to check.
123
+ * @param {string=} opt_message Error message in case of failure.
124
+ * @param {...*} var_args The items to substitute into the failure message.
125
+ * @return {*} The value of the condition.
126
+ * @throws {goog.asserts.AssertionError} When the condition evaluates to false.
127
+ */
128
+ goog.asserts.assert = function(condition, opt_message, var_args) {
129
+ if (goog.asserts.ENABLE_ASSERTS && !condition) {
130
+ goog.asserts.doAssertFailure_('', null, opt_message,
131
+ Array.prototype.slice.call(arguments, 2));
132
+ }
133
+ return condition;
134
+ };
135
+
136
+
137
+ /**
138
+ * Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case
139
+ * when we want to add a check in the unreachable area like switch-case
140
+ * statement:
141
+ *
142
+ * <pre>
143
+ * switch(type) {
144
+ * case FOO: doSomething(); break;
145
+ * case BAR: doSomethingElse(); break;
146
+ * default: goog.assert.fail('Unrecognized type: ' + type);
147
+ * // We have only 2 types - "default:" section is unreachable code.
148
+ * }
149
+ * </pre>
150
+ *
151
+ * @param {string=} opt_message Error message in case of failure.
152
+ * @param {...*} var_args The items to substitute into the failure message.
153
+ * @throws {goog.asserts.AssertionError} Failure.
154
+ */
155
+ goog.asserts.fail = function(opt_message, var_args) {
156
+ if (goog.asserts.ENABLE_ASSERTS) {
157
+ throw new goog.asserts.AssertionError(
158
+ 'Failure' + (opt_message ? ': ' + opt_message : ''),
159
+ Array.prototype.slice.call(arguments, 1));
160
+ }
161
+ };
162
+
163
+
164
+ /**
165
+ * Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true.
166
+ * @param {*} value The value to check.
167
+ * @param {string=} opt_message Error message in case of failure.
168
+ * @param {...*} var_args The items to substitute into the failure message.
169
+ * @return {number} The value, guaranteed to be a number when asserts enabled.
170
+ * @throws {goog.asserts.AssertionError} When the value is not a number.
171
+ */
172
+ goog.asserts.assertNumber = function(value, opt_message, var_args) {
173
+ if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) {
174
+ goog.asserts.doAssertFailure_('Expected number but got %s: %s.',
175
+ [goog.typeOf(value), value], opt_message,
176
+ Array.prototype.slice.call(arguments, 2));
177
+ }
178
+ return /** @type {number} */ (value);
179
+ };
180
+
181
+
182
+ /**
183
+ * Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true.
184
+ * @param {*} value The value to check.
185
+ * @param {string=} opt_message Error message in case of failure.
186
+ * @param {...*} var_args The items to substitute into the failure message.
187
+ * @return {string} The value, guaranteed to be a string when asserts enabled.
188
+ * @throws {goog.asserts.AssertionError} When the value is not a string.
189
+ */
190
+ goog.asserts.assertString = function(value, opt_message, var_args) {
191
+ if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) {
192
+ goog.asserts.doAssertFailure_('Expected string but got %s: %s.',
193
+ [goog.typeOf(value), value], opt_message,
194
+ Array.prototype.slice.call(arguments, 2));
195
+ }
196
+ return /** @type {string} */ (value);
197
+ };
198
+
199
+
200
+ /**
201
+ * Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true.
202
+ * @param {*} value The value to check.
203
+ * @param {string=} opt_message Error message in case of failure.
204
+ * @param {...*} var_args The items to substitute into the failure message.
205
+ * @return {!Function} The value, guaranteed to be a function when asserts
206
+ * enabled.
207
+ * @throws {goog.asserts.AssertionError} When the value is not a function.
208
+ */
209
+ goog.asserts.assertFunction = function(value, opt_message, var_args) {
210
+ if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) {
211
+ goog.asserts.doAssertFailure_('Expected function but got %s: %s.',
212
+ [goog.typeOf(value), value], opt_message,
213
+ Array.prototype.slice.call(arguments, 2));
214
+ }
215
+ return /** @type {!Function} */ (value);
216
+ };
217
+
218
+
219
+ /**
220
+ * Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true.
221
+ * @param {*} value The value to check.
222
+ * @param {string=} opt_message Error message in case of failure.
223
+ * @param {...*} var_args The items to substitute into the failure message.
224
+ * @return {!Object} The value, guaranteed to be a non-null object.
225
+ * @throws {goog.asserts.AssertionError} When the value is not an object.
226
+ */
227
+ goog.asserts.assertObject = function(value, opt_message, var_args) {
228
+ if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) {
229
+ goog.asserts.doAssertFailure_('Expected object but got %s: %s.',
230
+ [goog.typeOf(value), value],
231
+ opt_message, Array.prototype.slice.call(arguments, 2));
232
+ }
233
+ return /** @type {!Object} */ (value);
234
+ };
235
+
236
+
237
+ /**
238
+ * Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true.
239
+ * @param {*} value The value to check.
240
+ * @param {string=} opt_message Error message in case of failure.
241
+ * @param {...*} var_args The items to substitute into the failure message.
242
+ * @return {!Array} The value, guaranteed to be a non-null array.
243
+ * @throws {goog.asserts.AssertionError} When the value is not an array.
244
+ */
245
+ goog.asserts.assertArray = function(value, opt_message, var_args) {
246
+ if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) {
247
+ goog.asserts.doAssertFailure_('Expected array but got %s: %s.',
248
+ [goog.typeOf(value), value], opt_message,
249
+ Array.prototype.slice.call(arguments, 2));
250
+ }
251
+ return /** @type {!Array} */ (value);
252
+ };
253
+
254
+
255
+ /**
256
+ * Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true.
257
+ * @param {*} value The value to check.
258
+ * @param {string=} opt_message Error message in case of failure.
259
+ * @param {...*} var_args The items to substitute into the failure message.
260
+ * @return {boolean} The value, guaranteed to be a boolean when asserts are
261
+ * enabled.
262
+ * @throws {goog.asserts.AssertionError} When the value is not a boolean.
263
+ */
264
+ goog.asserts.assertBoolean = function(value, opt_message, var_args) {
265
+ if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) {
266
+ goog.asserts.doAssertFailure_('Expected boolean but got %s: %s.',
267
+ [goog.typeOf(value), value], opt_message,
268
+ Array.prototype.slice.call(arguments, 2));
269
+ }
270
+ return /** @type {boolean} */ (value);
271
+ };
272
+
273
+
274
+ /**
275
+ * Checks if the value is an instance of the user-defined type if
276
+ * goog.asserts.ENABLE_ASSERTS is true.
277
+ * @param {*} value The value to check.
278
+ * @param {!Function} type A user-defined constructor.
279
+ * @param {string=} opt_message Error message in case of failure.
280
+ * @param {...*} var_args The items to substitute into the failure message.
281
+ * @throws {goog.asserts.AssertionError} When the value is not an instance of
282
+ * type.
283
+ */
284
+ goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) {
285
+ if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) {
286
+ goog.asserts.doAssertFailure_('instanceof check failed.', null,
287
+ opt_message, Array.prototype.slice.call(arguments, 3));
288
+ }
289
+ };
290
+
291
+ ;
292
+ FI"asset_paths;
293
+ F["p/Volumes/Development/dev-web/closure-library-wrapper/vendor/closure-library/closure/goog/asserts/asserts.jsI"dependency_paths;
294
+ F[{I" path;
295
+ F"p/Volumes/Development/dev-web/closure-library-wrapper/vendor/closure-library/closure/goog/asserts/asserts.jsI"
296
+ mtime;
297
+ FIu: Time
298
+ T: offsetiI"hexdigest;
299
+ F"%c09bdc53388154b1db8b4425178cb6f0I"
300
+ F"%46dde6621c301f4928e3b34efee9e3b5
@@ -0,0 +1,1354 @@
1
+ o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1325549267.871167: @value{ I" length:EFi��I" digest;
2
+ F"%76437b1cb251e11f06c726ab3c5118ceI" source;
3
+ FI"��// Copyright 2006 The Closure Library Authors. All Rights Reserved.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS-IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+
17
+ /**
18
+ * @fileoverview Utilities for manipulating arrays.
19
+ *
20
+ */
21
+
22
+
23
+
24
+ goog.provide('goog.array');
25
+ goog.provide('goog.array.ArrayLike');
26
+
27
+ goog.require('goog.asserts');
28
+
29
+
30
+ /**
31
+ * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should
32
+ * rely on Array.prototype functions, if available.
33
+ *
34
+ * The Array.prototype functions can be defined by external libraries like
35
+ * Prototype and setting this flag to false forces closure to use its own
36
+ * goog.array implementation.
37
+ *
38
+ * If your javascript can be loaded by a third party site and you are wary about
39
+ * relying on the prototype functions, specify
40
+ * "--define goog.NATIVE_ARRAY_PROTOTYPES=false" to the JSCompiler.
41
+ */
42
+ goog.NATIVE_ARRAY_PROTOTYPES = true;
43
+
44
+
45
+ /**
46
+ * @typedef {Array|NodeList|Arguments|{length: number}}
47
+ */
48
+ goog.array.ArrayLike;
49
+
50
+
51
+ /**
52
+ * Returns the last element in an array without removing it.
53
+ * @param {goog.array.ArrayLike} array The array.
54
+ * @return {*} Last item in array.
55
+ */
56
+ goog.array.peek = function(array) {
57
+ return array[array.length - 1];
58
+ };
59
+
60
+
61
+ /**
62
+ * Reference to the original {@code Array.prototype}.
63
+ * @private
64
+ */
65
+ goog.array.ARRAY_PROTOTYPE_ = Array.prototype;
66
+
67
+
68
+ // NOTE(arv): Since most of the array functions are generic it allows you to
69
+ // pass an array-like object. Strings have a length and are considered array-
70
+ // like. However, the 'in' operator does not work on strings so we cannot just
71
+ // use the array path even if the browser supports indexing into strings. We
72
+ // therefore end up splitting the string.
73
+
74
+
75
+ /**
76
+ * Returns the index of the first element of an array with a specified
77
+ * value, or -1 if the element is not present in the array.
78
+ *
79
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof}
80
+ *
81
+ * @param {goog.array.ArrayLike} arr The array to be searched.
82
+ * @param {*} obj The object for which we are searching.
83
+ * @param {number=} opt_fromIndex The index at which to start the search. If
84
+ * omitted the search starts at index 0.
85
+ * @return {number} The index of the first matching array element.
86
+ */
87
+ goog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES &&
88
+ goog.array.ARRAY_PROTOTYPE_.indexOf ?
89
+ function(arr, obj, opt_fromIndex) {
90
+ goog.asserts.assert(arr.length != null);
91
+
92
+ return goog.array.ARRAY_PROTOTYPE_.indexOf.call(arr, obj, opt_fromIndex);
93
+ } :
94
+ function(arr, obj, opt_fromIndex) {
95
+ var fromIndex = opt_fromIndex == null ?
96
+ 0 : (opt_fromIndex < 0 ?
97
+ Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex);
98
+
99
+ if (goog.isString(arr)) {
100
+ // Array.prototype.indexOf uses === so only strings should be found.
101
+ if (!goog.isString(obj) || obj.length != 1) {
102
+ return -1;
103
+ }
104
+ return arr.indexOf(obj, fromIndex);
105
+ }
106
+
107
+ for (var i = fromIndex; i < arr.length; i++) {
108
+ if (i in arr && arr[i] === obj)
109
+ return i;
110
+ }
111
+ return -1;
112
+ };
113
+
114
+
115
+ /**
116
+ * Returns the index of the last element of an array with a specified value, or
117
+ * -1 if the element is not present in the array.
118
+ *
119
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof}
120
+ *
121
+ * @param {goog.array.ArrayLike} arr The array to be searched.
122
+ * @param {*} obj The object for which we are searching.
123
+ * @param {?number=} opt_fromIndex The index at which to start the search. If
124
+ * omitted the search starts at the end of the array.
125
+ * @return {number} The index of the last matching array element.
126
+ */
127
+ goog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES &&
128
+ goog.array.ARRAY_PROTOTYPE_.lastIndexOf ?
129
+ function(arr, obj, opt_fromIndex) {
130
+ goog.asserts.assert(arr.length != null);
131
+
132
+ // Firefox treats undefined and null as 0 in the fromIndex argument which
133
+ // leads it to always return -1
134
+ var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;
135
+ return goog.array.ARRAY_PROTOTYPE_.lastIndexOf.call(arr, obj, fromIndex);
136
+ } :
137
+ function(arr, obj, opt_fromIndex) {
138
+ var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;
139
+
140
+ if (fromIndex < 0) {
141
+ fromIndex = Math.max(0, arr.length + fromIndex);
142
+ }
143
+
144
+ if (goog.isString(arr)) {
145
+ // Array.prototype.lastIndexOf uses === so only strings should be found.
146
+ if (!goog.isString(obj) || obj.length != 1) {
147
+ return -1;
148
+ }
149
+ return arr.lastIndexOf(obj, fromIndex);
150
+ }
151
+
152
+ for (var i = fromIndex; i >= 0; i--) {
153
+ if (i in arr && arr[i] === obj)
154
+ return i;
155
+ }
156
+ return -1;
157
+ };
158
+
159
+
160
+ /**
161
+ * Calls a function for each element in an array.
162
+ *
163
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach}
164
+ *
165
+ * @param {goog.array.ArrayLike} arr Array or array like object over
166
+ * which to iterate.
167
+ * @param {?function(this: T, ...)} f The function to call for every element.
168
+ * This function takes 3 arguments (the element, the index and the array).
169
+ * The return value is ignored. The function is called only for indexes of
170
+ * the array which have assigned values; it is not called for indexes which
171
+ * have been deleted or which have never been assigned values.
172
+ * @param {T=} opt_obj The object to be used as the value of 'this'
173
+ * within f.
174
+ * @template T
175
+ */
176
+ goog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES &&
177
+ goog.array.ARRAY_PROTOTYPE_.forEach ?
178
+ function(arr, f, opt_obj) {
179
+ goog.asserts.assert(arr.length != null);
180
+
181
+ goog.array.ARRAY_PROTOTYPE_.forEach.call(arr, f, opt_obj);
182
+ } :
183
+ function(arr, f, opt_obj) {
184
+ var l = arr.length; // must be fixed during loop... see docs
185
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
186
+ for (var i = 0; i < l; i++) {
187
+ if (i in arr2) {
188
+ f.call(opt_obj, arr2[i], i, arr);
189
+ }
190
+ }
191
+ };
192
+
193
+
194
+ /**
195
+ * Calls a function for each element in an array, starting from the last
196
+ * element rather than the first.
197
+ *
198
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
199
+ * @param {Function} f The function to call for every element. This function
200
+ * takes 3 arguments (the element, the index and the array). The return
201
+ * value is ignored.
202
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
203
+ * within f.
204
+ */
205
+ goog.array.forEachRight = function(arr, f, opt_obj) {
206
+ var l = arr.length; // must be fixed during loop... see docs
207
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
208
+ for (var i = l - 1; i >= 0; --i) {
209
+ if (i in arr2) {
210
+ f.call(opt_obj, arr2[i], i, arr);
211
+ }
212
+ }
213
+ };
214
+
215
+
216
+ /**
217
+ * Calls a function for each element in an array, and if the function returns
218
+ * true adds the element to a new array.
219
+ *
220
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-filter}
221
+ *
222
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
223
+ * @param {Function} f The function to call for every element. This function
224
+ * takes 3 arguments (the element, the index and the array) and must
225
+ * return a Boolean. If the return value is true the element is added to the
226
+ * result array. If it is false the element is not included.
227
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
228
+ * within f.
229
+ * @return {!Array} a new array in which only elements that passed the test are
230
+ * present.
231
+ */
232
+ goog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES &&
233
+ goog.array.ARRAY_PROTOTYPE_.filter ?
234
+ function(arr, f, opt_obj) {
235
+ goog.asserts.assert(arr.length != null);
236
+
237
+ return goog.array.ARRAY_PROTOTYPE_.filter.call(arr, f, opt_obj);
238
+ } :
239
+ function(arr, f, opt_obj) {
240
+ var l = arr.length; // must be fixed during loop... see docs
241
+ var res = [];
242
+ var resLength = 0;
243
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
244
+ for (var i = 0; i < l; i++) {
245
+ if (i in arr2) {
246
+ var val = arr2[i]; // in case f mutates arr2
247
+ if (f.call(opt_obj, val, i, arr)) {
248
+ res[resLength++] = val;
249
+ }
250
+ }
251
+ }
252
+ return res;
253
+ };
254
+
255
+
256
+ /**
257
+ * Calls a function for each element in an array and inserts the result into a
258
+ * new array.
259
+ *
260
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-map}
261
+ *
262
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
263
+ * @param {Function} f The function to call for every element. This function
264
+ * takes 3 arguments (the element, the index and the array) and should
265
+ * return something. The result will be inserted into a new array.
266
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
267
+ * within f.
268
+ * @return {!Array} a new array with the results from f.
269
+ */
270
+ goog.array.map = goog.NATIVE_ARRAY_PROTOTYPES &&
271
+ goog.array.ARRAY_PROTOTYPE_.map ?
272
+ function(arr, f, opt_obj) {
273
+ goog.asserts.assert(arr.length != null);
274
+
275
+ return goog.array.ARRAY_PROTOTYPE_.map.call(arr, f, opt_obj);
276
+ } :
277
+ function(arr, f, opt_obj) {
278
+ var l = arr.length; // must be fixed during loop... see docs
279
+ var res = new Array(l);
280
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
281
+ for (var i = 0; i < l; i++) {
282
+ if (i in arr2) {
283
+ res[i] = f.call(opt_obj, arr2[i], i, arr);
284
+ }
285
+ }
286
+ return res;
287
+ };
288
+
289
+
290
+ /**
291
+ * Passes every element of an array into a function and accumulates the result.
292
+ *
293
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce}
294
+ *
295
+ * For example:
296
+ * var a = [1, 2, 3, 4];
297
+ * goog.array.reduce(a, function(r, v, i, arr) {return r + v;}, 0);
298
+ * returns 10
299
+ *
300
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
301
+ * @param {Function} f The function to call for every element. This function
302
+ * takes 4 arguments (the function's previous result or the initial value,
303
+ * the value of the current array element, the current array index, and the
304
+ * array itself)
305
+ * function(previousValue, currentValue, index, array).
306
+ * @param {*} val The initial value to pass into the function on the first call.
307
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
308
+ * within f.
309
+ * @return {*} Result of evaluating f repeatedly across the values of the array.
310
+ */
311
+ goog.array.reduce = function(arr, f, val, opt_obj) {
312
+ if (arr.reduce) {
313
+ if (opt_obj) {
314
+ return arr.reduce(goog.bind(f, opt_obj), val);
315
+ } else {
316
+ return arr.reduce(f, val);
317
+ }
318
+ }
319
+ var rval = val;
320
+ goog.array.forEach(arr, function(val, index) {
321
+ rval = f.call(opt_obj, rval, val, index, arr);
322
+ });
323
+ return rval;
324
+ };
325
+
326
+
327
+ /**
328
+ * Passes every element of an array into a function and accumulates the result,
329
+ * starting from the last element and working towards the first.
330
+ *
331
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright}
332
+ *
333
+ * For example:
334
+ * var a = ['a', 'b', 'c'];
335
+ * goog.array.reduceRight(a, function(r, v, i, arr) {return r + v;}, '');
336
+ * returns 'cba'
337
+ *
338
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
339
+ * @param {Function} f The function to call for every element. This function
340
+ * takes 4 arguments (the function's previous result or the initial value,
341
+ * the value of the current array element, the current array index, and the
342
+ * array itself)
343
+ * function(previousValue, currentValue, index, array).
344
+ * @param {*} val The initial value to pass into the function on the first call.
345
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
346
+ * within f.
347
+ * @return {*} Object returned as a result of evaluating f repeatedly across the
348
+ * values of the array.
349
+ */
350
+ goog.array.reduceRight = function(arr, f, val, opt_obj) {
351
+ if (arr.reduceRight) {
352
+ if (opt_obj) {
353
+ return arr.reduceRight(goog.bind(f, opt_obj), val);
354
+ } else {
355
+ return arr.reduceRight(f, val);
356
+ }
357
+ }
358
+ var rval = val;
359
+ goog.array.forEachRight(arr, function(val, index) {
360
+ rval = f.call(opt_obj, rval, val, index, arr);
361
+ });
362
+ return rval;
363
+ };
364
+
365
+
366
+ /**
367
+ * Calls f for each element of an array. If any call returns true, some()
368
+ * returns true (without checking the remaining elements). If all calls
369
+ * return false, some() returns false.
370
+ *
371
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-some}
372
+ *
373
+ * @param {goog.array.ArrayLike} arr The array to check.
374
+ * @param {Function} f The function to call for every element. This function
375
+ * takes 3 arguments (the element, the index and the array) and must
376
+ * return a Boolean.
377
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
378
+ * within f.
379
+ * @return {boolean} true if any element passes the test.
380
+ */
381
+ goog.array.some = goog.NATIVE_ARRAY_PROTOTYPES &&
382
+ goog.array.ARRAY_PROTOTYPE_.some ?
383
+ function(arr, f, opt_obj) {
384
+ goog.asserts.assert(arr.length != null);
385
+
386
+ return goog.array.ARRAY_PROTOTYPE_.some.call(arr, f, opt_obj);
387
+ } :
388
+ function(arr, f, opt_obj) {
389
+ var l = arr.length; // must be fixed during loop... see docs
390
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
391
+ for (var i = 0; i < l; i++) {
392
+ if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
393
+ return true;
394
+ }
395
+ }
396
+ return false;
397
+ };
398
+
399
+
400
+ /**
401
+ * Call f for each element of an array. If all calls return true, every()
402
+ * returns true. If any call returns false, every() returns false and
403
+ * does not continue to check the remaining elements.
404
+ *
405
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-every}
406
+ *
407
+ * @param {goog.array.ArrayLike} arr The array to check.
408
+ * @param {Function} f The function to call for every element. This function
409
+ * takes 3 arguments (the element, the index and the array) and must
410
+ * return a Boolean.
411
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
412
+ * within f.
413
+ * @return {boolean} false if any element fails the test.
414
+ */
415
+ goog.array.every = goog.NATIVE_ARRAY_PROTOTYPES &&
416
+ goog.array.ARRAY_PROTOTYPE_.every ?
417
+ function(arr, f, opt_obj) {
418
+ goog.asserts.assert(arr.length != null);
419
+
420
+ return goog.array.ARRAY_PROTOTYPE_.every.call(arr, f, opt_obj);
421
+ } :
422
+ function(arr, f, opt_obj) {
423
+ var l = arr.length; // must be fixed during loop... see docs
424
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
425
+ for (var i = 0; i < l; i++) {
426
+ if (i in arr2 && !f.call(opt_obj, arr2[i], i, arr)) {
427
+ return false;
428
+ }
429
+ }
430
+ return true;
431
+ };
432
+
433
+
434
+ /**
435
+ * Search an array for the first element that satisfies a given condition and
436
+ * return that element.
437
+ * @param {goog.array.ArrayLike} arr The array to search.
438
+ * @param {Function} f The function to call for every element. This function
439
+ * takes 3 arguments (the element, the index and the array) and should
440
+ * return a boolean.
441
+ * @param {Object=} opt_obj An optional "this" context for the function.
442
+ * @return {*} The first array element that passes the test, or null if no
443
+ * element is found.
444
+ */
445
+ goog.array.find = function(arr, f, opt_obj) {
446
+ var i = goog.array.findIndex(arr, f, opt_obj);
447
+ return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];
448
+ };
449
+
450
+
451
+ /**
452
+ * Search an array for the first element that satisfies a given condition and
453
+ * return its index.
454
+ * @param {goog.array.ArrayLike} arr The array to search.
455
+ * @param {Function} f The function to call for every element. This function
456
+ * takes 3 arguments (the element, the index and the array) and should
457
+ * return a boolean.
458
+ * @param {Object=} opt_obj An optional "this" context for the function.
459
+ * @return {number} The index of the first array element that passes the test,
460
+ * or -1 if no element is found.
461
+ */
462
+ goog.array.findIndex = function(arr, f, opt_obj) {
463
+ var l = arr.length; // must be fixed during loop... see docs
464
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
465
+ for (var i = 0; i < l; i++) {
466
+ if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
467
+ return i;
468
+ }
469
+ }
470
+ return -1;
471
+ };
472
+
473
+
474
+ /**
475
+ * Search an array (in reverse order) for the last element that satisfies a
476
+ * given condition and return that element.
477
+ * @param {goog.array.ArrayLike} arr The array to search.
478
+ * @param {Function} f The function to call for every element. This function
479
+ * takes 3 arguments (the element, the index and the array) and should
480
+ * return a boolean.
481
+ * @param {Object=} opt_obj An optional "this" context for the function.
482
+ * @return {*} The last array element that passes the test, or null if no
483
+ * element is found.
484
+ */
485
+ goog.array.findRight = function(arr, f, opt_obj) {
486
+ var i = goog.array.findIndexRight(arr, f, opt_obj);
487
+ return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];
488
+ };
489
+
490
+
491
+ /**
492
+ * Search an array (in reverse order) for the last element that satisfies a
493
+ * given condition and return its index.
494
+ * @param {goog.array.ArrayLike} arr The array to search.
495
+ * @param {Function} f The function to call for every element. This function
496
+ * takes 3 arguments (the element, the index and the array) and should
497
+ * return a boolean.
498
+ * @param {Object=} opt_obj An optional "this" context for the function.
499
+ * @return {number} The index of the last array element that passes the test,
500
+ * or -1 if no element is found.
501
+ */
502
+ goog.array.findIndexRight = function(arr, f, opt_obj) {
503
+ var l = arr.length; // must be fixed during loop... see docs
504
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
505
+ for (var i = l - 1; i >= 0; i--) {
506
+ if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
507
+ return i;
508
+ }
509
+ }
510
+ return -1;
511
+ };
512
+
513
+
514
+ /**
515
+ * Whether the array contains the given object.
516
+ * @param {goog.array.ArrayLike} arr The array to test for the presence of the
517
+ * element.
518
+ * @param {*} obj The object for which to test.
519
+ * @return {boolean} true if obj is present.
520
+ */
521
+ goog.array.contains = function(arr, obj) {
522
+ return goog.array.indexOf(arr, obj) >= 0;
523
+ };
524
+
525
+
526
+ /**
527
+ * Whether the array is empty.
528
+ * @param {goog.array.ArrayLike} arr The array to test.
529
+ * @return {boolean} true if empty.
530
+ */
531
+ goog.array.isEmpty = function(arr) {
532
+ return arr.length == 0;
533
+ };
534
+
535
+
536
+ /**
537
+ * Clears the array.
538
+ * @param {goog.array.ArrayLike} arr Array or array like object to clear.
539
+ */
540
+ goog.array.clear = function(arr) {
541
+ // For non real arrays we don't have the magic length so we delete the
542
+ // indices.
543
+ if (!goog.isArray(arr)) {
544
+ for (var i = arr.length - 1; i >= 0; i--) {
545
+ delete arr[i];
546
+ }
547
+ }
548
+ arr.length = 0;
549
+ };
550
+
551
+
552
+ /**
553
+ * Pushes an item into an array, if it's not already in the array.
554
+ * @param {Array} arr Array into which to insert the item.
555
+ * @param {*} obj Value to add.
556
+ */
557
+ goog.array.insert = function(arr, obj) {
558
+ if (!goog.array.contains(arr, obj)) {
559
+ arr.push(obj);
560
+ }
561
+ };
562
+
563
+
564
+ /**
565
+ * Inserts an object at the given index of the array.
566
+ * @param {goog.array.ArrayLike} arr The array to modify.
567
+ * @param {*} obj The object to insert.
568
+ * @param {number=} opt_i The index at which to insert the object. If omitted,
569
+ * treated as 0. A negative index is counted from the end of the array.
570
+ */
571
+ goog.array.insertAt = function(arr, obj, opt_i) {
572
+ goog.array.splice(arr, opt_i, 0, obj);
573
+ };
574
+
575
+
576
+ /**
577
+ * Inserts at the given index of the array, all elements of another array.
578
+ * @param {goog.array.ArrayLike} arr The array to modify.
579
+ * @param {goog.array.ArrayLike} elementsToAdd The array of elements to add.
580
+ * @param {number=} opt_i The index at which to insert the object. If omitted,
581
+ * treated as 0. A negative index is counted from the end of the array.
582
+ */
583
+ goog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) {
584
+ goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd);
585
+ };
586
+
587
+
588
+ /**
589
+ * Inserts an object into an array before a specified object.
590
+ * @param {Array} arr The array to modify.
591
+ * @param {*} obj The object to insert.
592
+ * @param {*=} opt_obj2 The object before which obj should be inserted. If obj2
593
+ * is omitted or not found, obj is inserted at the end of the array.
594
+ */
595
+ goog.array.insertBefore = function(arr, obj, opt_obj2) {
596
+ var i;
597
+ if (arguments.length == 2 || (i = goog.array.indexOf(arr, opt_obj2)) < 0) {
598
+ arr.push(obj);
599
+ } else {
600
+ goog.array.insertAt(arr, obj, i);
601
+ }
602
+ };
603
+
604
+
605
+ /**
606
+ * Removes the first occurrence of a particular value from an array.
607
+ * @param {goog.array.ArrayLike} arr Array from which to remove value.
608
+ * @param {*} obj Object to remove.
609
+ * @return {boolean} True if an element was removed.
610
+ */
611
+ goog.array.remove = function(arr, obj) {
612
+ var i = goog.array.indexOf(arr, obj);
613
+ var rv;
614
+ if ((rv = i >= 0)) {
615
+ goog.array.removeAt(arr, i);
616
+ }
617
+ return rv;
618
+ };
619
+
620
+
621
+ /**
622
+ * Removes from an array the element at index i
623
+ * @param {goog.array.ArrayLike} arr Array or array like object from which to
624
+ * remove value.
625
+ * @param {number} i The index to remove.
626
+ * @return {boolean} True if an element was removed.
627
+ */
628
+ goog.array.removeAt = function(arr, i) {
629
+ goog.asserts.assert(arr.length != null);
630
+
631
+ // use generic form of splice
632
+ // splice returns the removed items and if successful the length of that
633
+ // will be 1
634
+ return goog.array.ARRAY_PROTOTYPE_.splice.call(arr, i, 1).length == 1;
635
+ };
636
+
637
+
638
+ /**
639
+ * Removes the first value that satisfies the given condition.
640
+ * @param {goog.array.ArrayLike} arr Array from which to remove value.
641
+ * @param {Function} f The function to call for every element. This function
642
+ * takes 3 arguments (the element, the index and the array) and should
643
+ * return a boolean.
644
+ * @param {Object=} opt_obj An optional "this" context for the function.
645
+ * @return {boolean} True if an element was removed.
646
+ */
647
+ goog.array.removeIf = function(arr, f, opt_obj) {
648
+ var i = goog.array.findIndex(arr, f, opt_obj);
649
+ if (i >= 0) {
650
+ goog.array.removeAt(arr, i);
651
+ return true;
652
+ }
653
+ return false;
654
+ };
655
+
656
+
657
+ /**
658
+ * Returns a new array that is the result of joining the arguments. If arrays
659
+ * are passed then their items are added, however, if non-arrays are passed they
660
+ * will be added to the return array as is.
661
+ *
662
+ * Note that ArrayLike objects will be added as is, rather than having their
663
+ * items added.
664
+ *
665
+ * goog.array.concat([1, 2], [3, 4]) -> [1, 2, 3, 4]
666
+ * goog.array.concat(0, [1, 2]) -> [0, 1, 2]
667
+ * goog.array.concat([1, 2], null) -> [1, 2, null]
668
+ *
669
+ * There is bug in all current versions of IE (6, 7 and 8) where arrays created
670
+ * in an iframe become corrupted soon (not immediately) after the iframe is
671
+ * destroyed. This is common if loading data via goog.net.IframeIo, for example.
672
+ * This corruption only affects the concat method which will start throwing
673
+ * Catastrophic Errors (#-2147418113).
674
+ *
675
+ * See http://endoflow.com/scratch/corrupted-arrays.html for a test case.
676
+ *
677
+ * Internally goog.array should use this, so that all methods will continue to
678
+ * work on these broken array objects.
679
+ *
680
+ * @param {...*} var_args Items to concatenate. Arrays will have each item
681
+ * added, while primitives and objects will be added as is.
682
+ * @return {!Array} The new resultant array.
683
+ */
684
+ goog.array.concat = function(var_args) {
685
+ return goog.array.ARRAY_PROTOTYPE_.concat.apply(
686
+ goog.array.ARRAY_PROTOTYPE_, arguments);
687
+ };
688
+
689
+
690
+ /**
691
+ * Does a shallow copy of an array.
692
+ * @param {goog.array.ArrayLike} arr Array or array-like object to clone.
693
+ * @return {!Array} Clone of the input array.
694
+ */
695
+ goog.array.clone = function(arr) {
696
+ if (goog.isArray(arr)) {
697
+ return goog.array.concat(/** @type {!Array} */ (arr));
698
+ } else { // array like
699
+ // Concat does not work with non arrays.
700
+ var rv = [];
701
+ for (var i = 0, len = arr.length; i < len; i++) {
702
+ rv[i] = arr[i];
703
+ }
704
+ return rv;
705
+ }
706
+ };
707
+
708
+
709
+ /**
710
+ * Converts an object to an array.
711
+ * @param {goog.array.ArrayLike} object The object to convert to an array.
712
+ * @return {!Array} The object converted into an array. If object has a
713
+ * length property, every property indexed with a non-negative number
714
+ * less than length will be included in the result. If object does not
715
+ * have a length property, an empty array will be returned.
716
+ */
717
+ goog.array.toArray = function(object) {
718
+ if (goog.isArray(object)) {
719
+ // This fixes the JS compiler warning and forces the Object to an Array type
720
+ return goog.array.concat(/** @type {!Array} */ (object));
721
+ }
722
+ // Clone what we hope to be an array-like object to an array.
723
+ // We could check isArrayLike() first, but no check we perform would be as
724
+ // reliable as simply making the call.
725
+ return goog.array.clone(/** @type {Array} */ (object));
726
+ };
727
+
728
+
729
+ /**
730
+ * Extends an array with another array, element, or "array like" object.
731
+ * This function operates 'in-place', it does not create a new Array.
732
+ *
733
+ * Example:
734
+ * var a = [];
735
+ * goog.array.extend(a, [0, 1]);
736
+ * a; // [0, 1]
737
+ * goog.array.extend(a, 2);
738
+ * a; // [0, 1, 2]
739
+ *
740
+ * @param {Array} arr1 The array to modify.
741
+ * @param {...*} var_args The elements or arrays of elements to add to arr1.
742
+ */
743
+ goog.array.extend = function(arr1, var_args) {
744
+ for (var i = 1; i < arguments.length; i++) {
745
+ var arr2 = arguments[i];
746
+ // If we have an Array or an Arguments object we can just call push
747
+ // directly.
748
+ var isArrayLike;
749
+ if (goog.isArray(arr2) ||
750
+ // Detect Arguments. ES5 says that the [[Class]] of an Arguments object
751
+ // is "Arguments" but only V8 and JSC/Safari gets this right. We instead
752
+ // detect Arguments by checking for array like and presence of "callee".
753
+ (isArrayLike = goog.isArrayLike(arr2)) &&
754
+ // The getter for callee throws an exception in strict mode
755
+ // according to section 10.6 in ES5 so check for presence instead.
756
+ arr2.hasOwnProperty('callee')) {
757
+ arr1.push.apply(arr1, arr2);
758
+
759
+ } else if (isArrayLike) {
760
+ // Otherwise loop over arr2 to prevent copying the object.
761
+ var len1 = arr1.length;
762
+ var len2 = arr2.length;
763
+ for (var j = 0; j < len2; j++) {
764
+ arr1[len1 + j] = arr2[j];
765
+ }
766
+ } else {
767
+ arr1.push(arr2);
768
+ }
769
+ }
770
+ };
771
+
772
+
773
+ /**
774
+ * Adds or removes elements from an array. This is a generic version of Array
775
+ * splice. This means that it might work on other objects similar to arrays,
776
+ * such as the arguments object.
777
+ *
778
+ * @param {goog.array.ArrayLike} arr The array to modify.
779
+ * @param {number|undefined} index The index at which to start changing the
780
+ * array. If not defined, treated as 0.
781
+ * @param {number} howMany How many elements to remove (0 means no removal. A
782
+ * value below 0 is treated as zero and so is any other non number. Numbers
783
+ * are floored).
784
+ * @param {...*} var_args Optional, additional elements to insert into the
785
+ * array.
786
+ * @return {!Array} the removed elements.
787
+ */
788
+ goog.array.splice = function(arr, index, howMany, var_args) {
789
+ goog.asserts.assert(arr.length != null);
790
+
791
+ return goog.array.ARRAY_PROTOTYPE_.splice.apply(
792
+ arr, goog.array.slice(arguments, 1));
793
+ };
794
+
795
+
796
+ /**
797
+ * Returns a new array from a segment of an array. This is a generic version of
798
+ * Array slice. This means that it might work on other objects similar to
799
+ * arrays, such as the arguments object.
800
+ *
801
+ * @param {goog.array.ArrayLike} arr The array from which to copy a segment.
802
+ * @param {number} start The index of the first element to copy.
803
+ * @param {number=} opt_end The index after the last element to copy.
804
+ * @return {!Array} A new array containing the specified segment of the original
805
+ * array.
806
+ */
807
+ goog.array.slice = function(arr, start, opt_end) {
808
+ goog.asserts.assert(arr.length != null);
809
+
810
+ // passing 1 arg to slice is not the same as passing 2 where the second is
811
+ // null or undefined (in that case the second argument is treated as 0).
812
+ // we could use slice on the arguments object and then use apply instead of
813
+ // testing the length
814
+ if (arguments.length <= 2) {
815
+ return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start);
816
+ } else {
817
+ return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start, opt_end);
818
+ }
819
+ };
820
+
821
+
822
+ /**
823
+ * Removes all duplicates from an array (retaining only the first
824
+ * occurrence of each array element). This function modifies the
825
+ * array in place and doesn't change the order of the non-duplicate items.
826
+ *
827
+ * For objects, duplicates are identified as having the same unique ID as
828
+ * defined by {@link goog.getUid}.
829
+ *
830
+ * Runtime: N,
831
+ * Worstcase space: 2N (no dupes)
832
+ *
833
+ * @param {goog.array.ArrayLike} arr The array from which to remove duplicates.
834
+ * @param {Array=} opt_rv An optional array in which to return the results,
835
+ * instead of performing the removal inplace. If specified, the original
836
+ * array will remain unchanged.
837
+ */
838
+ goog.array.removeDuplicates = function(arr, opt_rv) {
839
+ var returnArray = opt_rv || arr;
840
+
841
+ var seen = {}, cursorInsert = 0, cursorRead = 0;
842
+ while (cursorRead < arr.length) {
843
+ var current = arr[cursorRead++];
844
+
845
+ // Prefix each type with a single character representing the type to
846
+ // prevent conflicting keys (e.g. true and 'true').
847
+ var key = goog.isObject(current) ?
848
+ 'o' + goog.getUid(current) :
849
+ (typeof current).charAt(0) + current;
850
+
851
+ if (!Object.prototype.hasOwnProperty.call(seen, key)) {
852
+ seen[key] = true;
853
+ returnArray[cursorInsert++] = current;
854
+ }
855
+ }
856
+ returnArray.length = cursorInsert;
857
+ };
858
+
859
+
860
+ /**
861
+ * Searches the specified array for the specified target using the binary
862
+ * search algorithm. If no opt_compareFn is specified, elements are compared
863
+ * using <code>goog.array.defaultCompare</code>, which compares the elements
864
+ * using the built in < and > operators. This will produce the expected
865
+ * behavior for homogeneous arrays of String(s) and Number(s). The array
866
+ * specified <b>must</b> be sorted in ascending order (as defined by the
867
+ * comparison function). If the array is not sorted, results are undefined.
868
+ * If the array contains multiple instances of the specified target value, any
869
+ * of these instances may be found.
870
+ *
871
+ * Runtime: O(log n)
872
+ *
873
+ * @param {goog.array.ArrayLike} arr The array to be searched.
874
+ * @param {*} target The sought value.
875
+ * @param {Function=} opt_compareFn Optional comparison function by which the
876
+ * array is ordered. Should take 2 arguments to compare, and return a
877
+ * negative number, zero, or a positive number depending on whether the
878
+ * first argument is less than, equal to, or greater than the second.
879
+ * @return {number} Lowest index of the target value if found, otherwise
880
+ * (-(insertion point) - 1). The insertion point is where the value should
881
+ * be inserted into arr to preserve the sorted property. Return value >= 0
882
+ * iff target is found.
883
+ */
884
+ goog.array.binarySearch = function(arr, target, opt_compareFn) {
885
+ return goog.array.binarySearch_(arr,
886
+ opt_compareFn || goog.array.defaultCompare, false /* isEvaluator */,
887
+ target);
888
+ };
889
+
890
+
891
+ /**
892
+ * Selects an index in the specified array using the binary search algorithm.
893
+ * The evaluator receives an element and determines whether the desired index
894
+ * is before, at, or after it. The evaluator must be consistent (formally,
895
+ * goog.array.map(goog.array.map(arr, evaluator, opt_obj), goog.math.sign)
896
+ * must be monotonically non-increasing).
897
+ *
898
+ * Runtime: O(log n)
899
+ *
900
+ * @param {goog.array.ArrayLike} arr The array to be searched.
901
+ * @param {Function} evaluator Evaluator function that receives 3 arguments
902
+ * (the element, the index and the array). Should return a negative number,
903
+ * zero, or a positive number depending on whether the desired index is
904
+ * before, at, or after the element passed to it.
905
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
906
+ * within evaluator.
907
+ * @return {number} Index of the leftmost element matched by the evaluator, if
908
+ * such exists; otherwise (-(insertion point) - 1). The insertion point is
909
+ * the index of the first element for which the evaluator returns negative,
910
+ * or arr.length if no such element exists. The return value is non-negative
911
+ * iff a match is found.
912
+ */
913
+ goog.array.binarySelect = function(arr, evaluator, opt_obj) {
914
+ return goog.array.binarySearch_(arr, evaluator, true /* isEvaluator */,
915
+ undefined /* opt_target */, opt_obj);
916
+ };
917
+
918
+
919
+ /**
920
+ * Implementation of a binary search algorithm which knows how to use both
921
+ * comparison functions and evaluators. If an evaluator is provided, will call
922
+ * the evaluator with the given optional data object, conforming to the
923
+ * interface defined in binarySelect. Otherwise, if a comparison function is
924
+ * provided, will call the comparison function against the given data object.
925
+ *
926
+ * This implementation purposefully does not use goog.bind or goog.partial for
927
+ * performance reasons.
928
+ *
929
+ * Runtime: O(log n)
930
+ *
931
+ * @param {goog.array.ArrayLike} arr The array to be searched.
932
+ * @param {Function} compareFn Either an evaluator or a comparison function,
933
+ * as defined by binarySearch and binarySelect above.
934
+ * @param {boolean} isEvaluator Whether the function is an evaluator or a
935
+ * comparison function.
936
+ * @param {*=} opt_target If the function is a comparison function, then this is
937
+ * the target to binary search for.
938
+ * @param {Object=} opt_selfObj If the function is an evaluator, this is an
939
+ * optional this object for the evaluator.
940
+ * @return {number} Lowest index of the target value if found, otherwise
941
+ * (-(insertion point) - 1). The insertion point is where the value should
942
+ * be inserted into arr to preserve the sorted property. Return value >= 0
943
+ * iff target is found.
944
+ * @private
945
+ */
946
+ goog.array.binarySearch_ = function(arr, compareFn, isEvaluator, opt_target,
947
+ opt_selfObj) {
948
+ var left = 0; // inclusive
949
+ var right = arr.length; // exclusive
950
+ var found;
951
+ while (left < right) {
952
+ var middle = (left + right) >> 1;
953
+ var compareResult;
954
+ if (isEvaluator) {
955
+ compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);
956
+ } else {
957
+ compareResult = compareFn(opt_target, arr[middle]);
958
+ }
959
+ if (compareResult > 0) {
960
+ left = middle + 1;
961
+ } else {
962
+ right = middle;
963
+ // We are looking for the lowest index so we can't return immediately.
964
+ found = !compareResult;
965
+ }
966
+ }
967
+ // left is the index if found, or the insertion point otherwise.
968
+ // ~left is a shorthand for -left - 1.
969
+ return found ? left : ~left;
970
+ };
971
+
972
+
973
+ /**
974
+ * Sorts the specified array into ascending order. If no opt_compareFn is
975
+ * specified, elements are compared using
976
+ * <code>goog.array.defaultCompare</code>, which compares the elements using
977
+ * the built in < and > operators. This will produce the expected behavior
978
+ * for homogeneous arrays of String(s) and Number(s), unlike the native sort,
979
+ * but will give unpredictable results for heterogenous lists of strings and
980
+ * numbers with different numbers of digits.
981
+ *
982
+ * This sort is not guaranteed to be stable.
983
+ *
984
+ * Runtime: Same as <code>Array.prototype.sort</code>
985
+ *
986
+ * @param {Array} arr The array to be sorted.
987
+ * @param {Function=} opt_compareFn Optional comparison function by which the
988
+ * array is to be ordered. Should take 2 arguments to compare, and return a
989
+ * negative number, zero, or a positive number depending on whether the
990
+ * first argument is less than, equal to, or greater than the second.
991
+ */
992
+ goog.array.sort = function(arr, opt_compareFn) {
993
+ // TODO(arv): Update type annotation since null is not accepted.
994
+ goog.asserts.assert(arr.length != null);
995
+
996
+ goog.array.ARRAY_PROTOTYPE_.sort.call(
997
+ arr, opt_compareFn || goog.array.defaultCompare);
998
+ };
999
+
1000
+
1001
+ /**
1002
+ * Sorts the specified array into ascending order in a stable way. If no
1003
+ * opt_compareFn is specified, elements are compared using
1004
+ * <code>goog.array.defaultCompare</code>, which compares the elements using
1005
+ * the built in < and > operators. This will produce the expected behavior
1006
+ * for homogeneous arrays of String(s) and Number(s).
1007
+ *
1008
+ * Runtime: Same as <code>Array.prototype.sort</code>, plus an additional
1009
+ * O(n) overhead of copying the array twice.
1010
+ *
1011
+ * @param {Array} arr The array to be sorted.
1012
+ * @param {function(*, *): number=} opt_compareFn Optional comparison function
1013
+ * by which the array is to be ordered. Should take 2 arguments to compare,
1014
+ * and return a negative number, zero, or a positive number depending on
1015
+ * whether the first argument is less than, equal to, or greater than the
1016
+ * second.
1017
+ */
1018
+ goog.array.stableSort = function(arr, opt_compareFn) {
1019
+ for (var i = 0; i < arr.length; i++) {
1020
+ arr[i] = {index: i, value: arr[i]};
1021
+ }
1022
+ var valueCompareFn = opt_compareFn || goog.array.defaultCompare;
1023
+ function stableCompareFn(obj1, obj2) {
1024
+ return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;
1025
+ };
1026
+ goog.array.sort(arr, stableCompareFn);
1027
+ for (var i = 0; i < arr.length; i++) {
1028
+ arr[i] = arr[i].value;
1029
+ }
1030
+ };
1031
+
1032
+
1033
+ /**
1034
+ * Sorts an array of objects by the specified object key and compare
1035
+ * function. If no compare function is provided, the key values are
1036
+ * compared in ascending order using <code>goog.array.defaultCompare</code>.
1037
+ * This won't work for keys that get renamed by the compiler. So use
1038
+ * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.
1039
+ * @param {Array.<Object>} arr An array of objects to sort.
1040
+ * @param {string} key The object key to sort by.
1041
+ * @param {Function=} opt_compareFn The function to use to compare key
1042
+ * values.
1043
+ */
1044
+ goog.array.sortObjectsByKey = function(arr, key, opt_compareFn) {
1045
+ var compare = opt_compareFn || goog.array.defaultCompare;
1046
+ goog.array.sort(arr, function(a, b) {
1047
+ return compare(a[key], b[key]);
1048
+ });
1049
+ };
1050
+
1051
+
1052
+ /**
1053
+ * Tells if the array is sorted.
1054
+ * @param {!Array} arr The array.
1055
+ * @param {Function=} opt_compareFn Function to compare the array elements.
1056
+ * Should take 2 arguments to compare, and return a negative number, zero,
1057
+ * or a positive number depending on whether the first argument is less
1058
+ * than, equal to, or greater than the second.
1059
+ * @param {boolean=} opt_strict If true no equal elements are allowed.
1060
+ * @return {boolean} Whether the array is sorted.
1061
+ */
1062
+ goog.array.isSorted = function(arr, opt_compareFn, opt_strict) {
1063
+ var compare = opt_compareFn || goog.array.defaultCompare;
1064
+ for (var i = 1; i < arr.length; i++) {
1065
+ var compareResult = compare(arr[i - 1], arr[i]);
1066
+ if (compareResult > 0 || compareResult == 0 && opt_strict) {
1067
+ return false;
1068
+ }
1069
+ }
1070
+ return true;
1071
+ };
1072
+
1073
+
1074
+ /**
1075
+ * Compares two arrays for equality. Two arrays are considered equal if they
1076
+ * have the same length and their corresponding elements are equal according to
1077
+ * the comparison function.
1078
+ *
1079
+ * @param {goog.array.ArrayLike} arr1 The first array to compare.
1080
+ * @param {goog.array.ArrayLike} arr2 The second array to compare.
1081
+ * @param {Function=} opt_equalsFn Optional comparison function.
1082
+ * Should take 2 arguments to compare, and return true if the arguments
1083
+ * are equal. Defaults to {@link goog.array.defaultCompareEquality} which
1084
+ * compares the elements using the built-in '===' operator.
1085
+ * @return {boolean} Whether the two arrays are equal.
1086
+ */
1087
+ goog.array.equals = function(arr1, arr2, opt_equalsFn) {
1088
+ if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||
1089
+ arr1.length != arr2.length) {
1090
+ return false;
1091
+ }
1092
+ var l = arr1.length;
1093
+ var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality;
1094
+ for (var i = 0; i < l; i++) {
1095
+ if (!equalsFn(arr1[i], arr2[i])) {
1096
+ return false;
1097
+ }
1098
+ }
1099
+ return true;
1100
+ };
1101
+
1102
+
1103
+ /**
1104
+ * @deprecated Use {@link goog.array.equals}.
1105
+ * @param {goog.array.ArrayLike} arr1 See {@link goog.array.equals}.
1106
+ * @param {goog.array.ArrayLike} arr2 See {@link goog.array.equals}.
1107
+ * @param {Function=} opt_equalsFn See {@link goog.array.equals}.
1108
+ * @return {boolean} See {@link goog.array.equals}.
1109
+ */
1110
+ goog.array.compare = function(arr1, arr2, opt_equalsFn) {
1111
+ return goog.array.equals(arr1, arr2, opt_equalsFn);
1112
+ };
1113
+
1114
+
1115
+ /**
1116
+ * 3-way array compare function.
1117
+ * @param {!goog.array.ArrayLike} arr1 The first array to compare.
1118
+ * @param {!goog.array.ArrayLike} arr2 The second array to compare.
1119
+ * @param {(function(*, *): number)=} opt_compareFn Optional comparison function
1120
+ * by which the array is to be ordered. Should take 2 arguments to compare,
1121
+ * and return a negative number, zero, or a positive number depending on
1122
+ * whether the first argument is less than, equal to, or greater than the
1123
+ * second.
1124
+ * @return {number} Negative number, zero, or a positive number depending on
1125
+ * whether the first argument is less than, equal to, or greater than the
1126
+ * second.
1127
+ */
1128
+ goog.array.compare3 = function(arr1, arr2, opt_compareFn) {
1129
+ var compare = opt_compareFn || goog.array.defaultCompare;
1130
+ var l = Math.min(arr1.length, arr2.length);
1131
+ for (var i = 0; i < l; i++) {
1132
+ var result = compare(arr1[i], arr2[i]);
1133
+ if (result != 0) {
1134
+ return result;
1135
+ }
1136
+ }
1137
+ return goog.array.defaultCompare(arr1.length, arr2.length);
1138
+ };
1139
+
1140
+
1141
+ /**
1142
+ * Compares its two arguments for order, using the built in < and >
1143
+ * operators.
1144
+ * @param {*} a The first object to be compared.
1145
+ * @param {*} b The second object to be compared.
1146
+ * @return {number} A negative number, zero, or a positive number as the first
1147
+ * argument is less than, equal to, or greater than the second.
1148
+ */
1149
+ goog.array.defaultCompare = function(a, b) {
1150
+ return a > b ? 1 : a < b ? -1 : 0;
1151
+ };
1152
+
1153
+
1154
+ /**
1155
+ * Compares its two arguments for equality, using the built in === operator.
1156
+ * @param {*} a The first object to compare.
1157
+ * @param {*} b The second object to compare.
1158
+ * @return {boolean} True if the two arguments are equal, false otherwise.
1159
+ */
1160
+ goog.array.defaultCompareEquality = function(a, b) {
1161
+ return a === b;
1162
+ };
1163
+
1164
+
1165
+ /**
1166
+ * Inserts a value into a sorted array. The array is not modified if the
1167
+ * value is already present.
1168
+ * @param {Array} array The array to modify.
1169
+ * @param {*} value The object to insert.
1170
+ * @param {Function=} opt_compareFn Optional comparison function by which the
1171
+ * array is ordered. Should take 2 arguments to compare, and return a
1172
+ * negative number, zero, or a positive number depending on whether the
1173
+ * first argument is less than, equal to, or greater than the second.
1174
+ * @return {boolean} True if an element was inserted.
1175
+ */
1176
+ goog.array.binaryInsert = function(array, value, opt_compareFn) {
1177
+ var index = goog.array.binarySearch(array, value, opt_compareFn);
1178
+ if (index < 0) {
1179
+ goog.array.insertAt(array, value, -(index + 1));
1180
+ return true;
1181
+ }
1182
+ return false;
1183
+ };
1184
+
1185
+
1186
+ /**
1187
+ * Removes a value from a sorted array.
1188
+ * @param {Array} array The array to modify.
1189
+ * @param {*} value The object to remove.
1190
+ * @param {Function=} opt_compareFn Optional comparison function by which the
1191
+ * array is ordered. Should take 2 arguments to compare, and return a
1192
+ * negative number, zero, or a positive number depending on whether the
1193
+ * first argument is less than, equal to, or greater than the second.
1194
+ * @return {boolean} True if an element was removed.
1195
+ */
1196
+ goog.array.binaryRemove = function(array, value, opt_compareFn) {
1197
+ var index = goog.array.binarySearch(array, value, opt_compareFn);
1198
+ return (index >= 0) ? goog.array.removeAt(array, index) : false;
1199
+ };
1200
+
1201
+
1202
+ /**
1203
+ * Splits an array into disjoint buckets according to a splitting function.
1204
+ * @param {Array} array The array.
1205
+ * @param {Function} sorter Function to call for every element. This
1206
+ * takes 3 arguments (the element, the index and the array) and must
1207
+ * return a valid object key (a string, number, etc), or undefined, if
1208
+ * that object should not be placed in a bucket.
1209
+ * @return {!Object} An object, with keys being all of the unique return values
1210
+ * of sorter, and values being arrays containing the items for
1211
+ * which the splitter returned that key.
1212
+ */
1213
+ goog.array.bucket = function(array, sorter) {
1214
+ var buckets = {};
1215
+
1216
+ for (var i = 0; i < array.length; i++) {
1217
+ var value = array[i];
1218
+ var key = sorter(value, i, array);
1219
+ if (goog.isDef(key)) {
1220
+ // Push the value to the right bucket, creating it if necessary.
1221
+ var bucket = buckets[key] || (buckets[key] = []);
1222
+ bucket.push(value);
1223
+ }
1224
+ }
1225
+
1226
+ return buckets;
1227
+ };
1228
+
1229
+
1230
+ /**
1231
+ * Returns an array consisting of the given value repeated N times.
1232
+ *
1233
+ * @param {*} value The value to repeat.
1234
+ * @param {number} n The repeat count.
1235
+ * @return {!Array.<*>} An array with the repeated value.
1236
+ */
1237
+ goog.array.repeat = function(value, n) {
1238
+ var array = [];
1239
+ for (var i = 0; i < n; i++) {
1240
+ array[i] = value;
1241
+ }
1242
+ return array;
1243
+ };
1244
+
1245
+
1246
+ /**
1247
+ * Returns an array consisting of every argument with all arrays
1248
+ * expanded in-place recursively.
1249
+ *
1250
+ * @param {...*} var_args The values to flatten.
1251
+ * @return {!Array.<*>} An array containing the flattened values.
1252
+ */
1253
+ goog.array.flatten = function(var_args) {
1254
+ var result = [];
1255
+ for (var i = 0; i < arguments.length; i++) {
1256
+ var element = arguments[i];
1257
+ if (goog.isArray(element)) {
1258
+ result.push.apply(result, goog.array.flatten.apply(null, element));
1259
+ } else {
1260
+ result.push(element);
1261
+ }
1262
+ }
1263
+ return result;
1264
+ };
1265
+
1266
+
1267
+ /**
1268
+ * Rotates an array in-place. After calling this method, the element at
1269
+ * index i will be the element previously at index (i - n) %
1270
+ * array.length, for all values of i between 0 and array.length - 1,
1271
+ * inclusive.
1272
+ *
1273
+ * For example, suppose list comprises [t, a, n, k, s]. After invoking
1274
+ * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].
1275
+ *
1276
+ * @param {!Array.<*>} array The array to rotate.
1277
+ * @param {number} n The amount to rotate.
1278
+ * @return {!Array.<*>} The array.
1279
+ */
1280
+ goog.array.rotate = function(array, n) {
1281
+ goog.asserts.assert(array.length != null);
1282
+
1283
+ if (array.length) {
1284
+ n %= array.length;
1285
+ if (n > 0) {
1286
+ goog.array.ARRAY_PROTOTYPE_.unshift.apply(array, array.splice(-n, n));
1287
+ } else if (n < 0) {
1288
+ goog.array.ARRAY_PROTOTYPE_.push.apply(array, array.splice(0, -n));
1289
+ }
1290
+ }
1291
+ return array;
1292
+ };
1293
+
1294
+
1295
+ /**
1296
+ * Creates a new array for which the element at position i is an array of the
1297
+ * ith element of the provided arrays. The returned array will only be as long
1298
+ * as the shortest array provided; additional values are ignored. For example,
1299
+ * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]].
1300
+ *
1301
+ * This is similar to the zip() function in Python. See {@link
1302
+ * http://docs.python.org/library/functions.html#zip}
1303
+ *
1304
+ * @param {...!goog.array.ArrayLike} var_args Arrays to be combined.
1305
+ * @return {!Array.<!Array>} A new array of arrays created from provided arrays.
1306
+ */
1307
+ goog.array.zip = function(var_args) {
1308
+ if (!arguments.length) {
1309
+ return [];
1310
+ }
1311
+ var result = [];
1312
+ for (var i = 0; true; i++) {
1313
+ var value = [];
1314
+ for (var j = 0; j < arguments.length; j++) {
1315
+ var arr = arguments[j];
1316
+ // If i is larger than the array length, this is the shortest array.
1317
+ if (i >= arr.length) {
1318
+ return result;
1319
+ }
1320
+ value.push(arr[i]);
1321
+ }
1322
+ result.push(value);
1323
+ }
1324
+ };
1325
+
1326
+
1327
+ /**
1328
+ * Shuffles the values in the specified array using the Fisher-Yates in-place
1329
+ * shuffle (also known as the Knuth Shuffle). By default, calls Math.random()
1330
+ * and so resets the state of that random number generator. Similarly, may reset
1331
+ * the state of the any other specified random number generator.
1332
+ *
1333
+ * Runtime: O(n)
1334
+ *
1335
+ * @param {!Array} arr The array to be shuffled.
1336
+ * @param {Function=} opt_randFn Optional random function to use for shuffling.
1337
+ * Takes no arguments, and returns a random number on the interval [0, 1).
1338
+ * Defaults to Math.random() using JavaScript's built-in Math library.
1339
+ */
1340
+ goog.array.shuffle = function(arr, opt_randFn) {
1341
+ var randFn = opt_randFn || Math.random;
1342
+
1343
+ for (var i = arr.length - 1; i > 0; i--) {
1344
+ // Choose a random array index in [0, i] (inclusive with i).
1345
+ var j = Math.floor(randFn() * (i + 1));
1346
+
1347
+ var tmp = arr[i];
1348
+ arr[i] = arr[j];
1349
+ arr[j] = tmp;
1350
+ }
1351
+ };
1352
+ ;
1353
+ FI"
1354
+ F"%17ac20756a770afbab2d234d9f34de67