yellow-brick-road 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. data/README.rst +148 -0
  2. data/Rakefile +37 -0
  3. data/lib/tasks/yellow-brick-road_tasks.rake +4 -0
  4. data/lib/yellow-brick-road.rb +6 -0
  5. data/lib/yellow-brick-road/config.rb +15 -0
  6. data/lib/yellow-brick-road/directive_processor.rb +68 -0
  7. data/lib/yellow-brick-road/engine.rb +22 -0
  8. data/lib/yellow-brick-road/soy_processor.rb +56 -0
  9. data/lib/yellow-brick-road/utils.rb +38 -0
  10. data/lib/yellow-brick-road/version.rb +3 -0
  11. data/test/dummy/Rakefile +7 -0
  12. data/test/dummy/app/assets/javascripts/application.js +12 -0
  13. data/test/dummy/app/assets/javascripts/closure-deps.js +4 -0
  14. data/test/dummy/app/assets/javascripts/my-closure/simple.js.soy +14 -0
  15. data/test/dummy/app/assets/javascripts/my-closure/start.js +25 -0
  16. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  17. data/test/dummy/app/controllers/application_controller.rb +7 -0
  18. data/test/dummy/app/helpers/application_helper.rb +2 -0
  19. data/test/dummy/app/views/application/index.html.erb +0 -0
  20. data/test/dummy/app/views/layouts/application.html.erb +18 -0
  21. data/test/dummy/config.ru +4 -0
  22. data/test/dummy/config/application.rb +51 -0
  23. data/test/dummy/config/boot.rb +10 -0
  24. data/test/dummy/config/environment.rb +5 -0
  25. data/test/dummy/config/environments/development.rb +30 -0
  26. data/test/dummy/config/environments/production.rb +60 -0
  27. data/test/dummy/config/environments/test.rb +39 -0
  28. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  29. data/test/dummy/config/initializers/inflections.rb +10 -0
  30. data/test/dummy/config/initializers/mime_types.rb +5 -0
  31. data/test/dummy/config/initializers/secret_token.rb +7 -0
  32. data/test/dummy/config/initializers/session_store.rb +8 -0
  33. data/test/dummy/config/initializers/wrap_parameters.rb +10 -0
  34. data/test/dummy/config/initializers/yellow_brick_road.rb +2 -0
  35. data/test/dummy/config/locales/en.yml +5 -0
  36. data/test/dummy/config/routes.rb +58 -0
  37. data/test/dummy/log/development.log +13924 -0
  38. data/test/dummy/log/test.log +0 -0
  39. data/test/dummy/public/404.html +26 -0
  40. data/test/dummy/public/422.html +26 -0
  41. data/test/dummy/public/500.html +26 -0
  42. data/test/dummy/public/favicon.ico +0 -0
  43. data/test/dummy/script/rails +6 -0
  44. data/test/dummy/tmp/cache/assets/BE0/120/sprockets%2F751842b8c6750008c7310d182600d173 +142 -0
  45. data/test/dummy/tmp/cache/assets/C19/950/sprockets%2F142437f1d8d9424007b4a882a5429333 +1372 -0
  46. data/test/dummy/tmp/cache/assets/C4B/D00/sprockets%2F400f22c081529179ce3d079457de3009 +806 -0
  47. data/test/dummy/tmp/cache/assets/C5A/EE0/sprockets%2Fb711429ed948c503b718d077037780f8 +0 -0
  48. data/test/dummy/tmp/cache/assets/C5B/A80/sprockets%2F508569b474262724c61a461f7777dab7 +1118 -0
  49. data/test/dummy/tmp/cache/assets/C6C/660/sprockets%2F2c298b3b02232a21527680685a3efc30 +9289 -0
  50. data/test/dummy/tmp/cache/assets/C72/8A0/sprockets%2F167b265129e30d87d253c406db305c60 +293 -0
  51. data/test/dummy/tmp/cache/assets/C7E/9F0/sprockets%2F89862076204c62c4593ac20de32da909 +9 -0
  52. data/test/dummy/tmp/cache/assets/C8B/5F0/sprockets%2Fc6a4470b5c21e285e829a99365839b24 +0 -0
  53. data/test/dummy/tmp/cache/assets/C92/D20/sprockets%2F2e618f7805f445889aec94885a500f03 +457 -0
  54. data/test/dummy/tmp/cache/assets/C98/FD0/sprockets%2Fb11442af041f96e87a43a1dc11231745 +283 -0
  55. data/test/dummy/tmp/cache/assets/CA3/520/sprockets%2F5379d7143c6c52b11b88dc0ab5436133 +277 -0
  56. data/test/dummy/tmp/cache/assets/CA5/450/sprockets%2F6bb727c9312a749134ad67323a317f0d +73 -0
  57. data/test/dummy/tmp/cache/assets/CA5/4F0/sprockets%2Feeb7de7771527700af194c0441d29101 +709 -0
  58. data/test/dummy/tmp/cache/assets/CA6/E90/sprockets%2F611f68180f43c4181f06ae5c5f8201e2 +1546 -0
  59. data/test/dummy/tmp/cache/assets/CA7/310/sprockets%2F45664cf816315200b574e029fde6f10a +0 -0
  60. data/test/dummy/tmp/cache/assets/CA9/9D0/sprockets%2F2672e32464cf7267c4ba3d028f54b153 +224 -0
  61. data/test/dummy/tmp/cache/assets/CAB/5A0/sprockets%2F7f50e0289f150c8636ac9253129bc13c +2556 -0
  62. data/test/dummy/tmp/cache/assets/CB5/7E0/sprockets%2F42ff6672683b2029233a800e7539eeee +474 -0
  63. data/test/dummy/tmp/cache/assets/CB6/DC0/sprockets%2F2f9882155bb2d4d3ab5d708951857c60 +494 -0
  64. data/test/dummy/tmp/cache/assets/CBB/680/sprockets%2F1dc336d96fb52df34b458185559922b5 +1018 -0
  65. data/test/dummy/tmp/cache/assets/CBC/640/sprockets%2F67d2e0d9e5129d237e575d2780c64b47 +1260 -0
  66. data/test/dummy/tmp/cache/assets/CBE/550/sprockets%2Fd680cac830e0b3408ba910f0b0421147 +25 -0
  67. data/test/dummy/tmp/cache/assets/CC7/790/sprockets%2F69941f32a12e4f99d4a57f65386d870d +608 -0
  68. data/test/dummy/tmp/cache/assets/CCB/F80/sprockets%2Fa865701ef2ec41155e524772c31a1a2b +1088 -0
  69. data/test/dummy/tmp/cache/assets/CCE/580/sprockets%2F879411ed27ed1c557d57853d8f579b56 +0 -0
  70. data/test/dummy/tmp/cache/assets/CD0/070/sprockets%2F6748fe8481965f260d9c56b7f9f508a2 +1530 -0
  71. data/test/dummy/tmp/cache/assets/CD4/750/sprockets%2Faf3505141ecb3169ce41ce519d136924 +0 -0
  72. data/test/dummy/tmp/cache/assets/CD6/A90/sprockets%2F3f55ac75b9fb8426312116bcb940a580 +2539 -0
  73. data/test/dummy/tmp/cache/assets/CD9/6C0/sprockets%2F5e2458bc52da90ba349a66035e3b6752 +0 -0
  74. data/test/dummy/tmp/cache/assets/CD9/F50/sprockets%2F9008bf696500cfae1d61f045f209181e +256 -0
  75. data/test/dummy/tmp/cache/assets/CDB/B40/sprockets%2F53529a22c994570a0df4742c0bfe61f4 +0 -0
  76. data/test/dummy/tmp/cache/assets/CDC/D10/sprockets%2F1e775b4ff06b4401c07503ce95a839b5 +75 -0
  77. data/test/dummy/tmp/cache/assets/CDE/CD0/sprockets%2F141066798b4acf07053f7e3a6cb4e555 +1613 -0
  78. data/test/dummy/tmp/cache/assets/CE1/760/sprockets%2F245fe11803630fe30d0cf8a869886ab5 +357 -0
  79. data/test/dummy/tmp/cache/assets/CE1/FA0/sprockets%2F863d1650ef066e4a2168bc57c7c0e096 +0 -0
  80. data/test/dummy/tmp/cache/assets/CE2/310/sprockets%2Fd38075d5592ecaf82e43526c03b467c4 +1545 -0
  81. data/test/dummy/tmp/cache/assets/CE2/420/sprockets%2F30f2e8f30477e80cf6416dfe27307c07 +204 -0
  82. data/test/dummy/tmp/cache/assets/CE2/D70/sprockets%2F467c44b63644e0f44dd06a585f36f1a6 +522 -0
  83. data/test/dummy/tmp/cache/assets/CE3/670/sprockets%2Fddd11860b444cd0f9996be0c46762318 +796 -0
  84. data/test/dummy/tmp/cache/assets/CE4/0B0/sprockets%2Ff11535d785c0d34349c64d673bd4b28f +1105 -0
  85. data/test/dummy/tmp/cache/assets/CE4/590/sprockets%2Fd68edcc87a4ae302794093081b45b819 +10 -0
  86. data/test/dummy/tmp/cache/assets/CE4/D60/sprockets%2F61772e4a60b616f74da91b838a2f4f82 +0 -0
  87. data/test/dummy/tmp/cache/assets/CE6/DD0/sprockets%2F2fe073024a2bf26bd98458388b57af37 +1355 -0
  88. data/test/dummy/tmp/cache/assets/CE7/160/sprockets%2Fba1f9939f031b4356ec1869d40fc2747 +1261 -0
  89. data/test/dummy/tmp/cache/assets/CE8/C70/sprockets%2Fc6c9ba3c677b5e2af8520395192c9445 +173 -0
  90. data/test/dummy/tmp/cache/assets/CEA/8B0/sprockets%2Ff77e549cb6d37604105f35d4e67d8c21 +511 -0
  91. data/test/dummy/tmp/cache/assets/CEA/AA0/sprockets%2F5f816982c86d2e6b72b2f5f65c51d070 +1529 -0
  92. data/test/dummy/tmp/cache/assets/CEA/C10/sprockets%2F9dcd541e67c299ab076a44a2183872f8 +0 -0
  93. data/test/dummy/tmp/cache/assets/CF1/5A0/sprockets%2F1a697695edf2bb7b49a2896904218bc7 +115 -0
  94. data/test/dummy/tmp/cache/assets/CF4/480/sprockets%2F5e99c77e93f4a522c84357e62b25e0f7 +43 -0
  95. data/test/dummy/tmp/cache/assets/CF7/460/sprockets%2Fd12ea9733fe3c92456f57f9145569b9c +0 -0
  96. data/test/dummy/tmp/cache/assets/CF7/470/sprockets%2F2897897a166ca3369fecb88f83f211b5 +435 -0
  97. data/test/dummy/tmp/cache/assets/CFA/760/sprockets%2Fa9024adba14091e0635c6874d1db4e22 +0 -0
  98. data/test/dummy/tmp/cache/assets/D01/F30/sprockets%2Fe639a15b6e0cca37d12443b408e1166f +25 -0
  99. data/test/dummy/tmp/cache/assets/D02/9F0/sprockets%2Fb99eae308897fe88cb9414b96824098b +0 -0
  100. data/test/dummy/tmp/cache/assets/D03/330/sprockets%2F1e003cdb3e7dcc9307e84090ad457127 +454 -0
  101. data/test/dummy/tmp/cache/assets/D03/8B0/sprockets%2Ff74632bddf2c0b2018ca7b736309380e +365 -0
  102. data/test/dummy/tmp/cache/assets/D05/0A0/sprockets%2Fe57658220260db13eb5577aef42cb61b +257 -0
  103. data/test/dummy/tmp/cache/assets/D05/920/sprockets%2F909507434dcc270db4853e4c147f0aac +31 -0
  104. data/test/dummy/tmp/cache/assets/D08/510/sprockets%2Fa567be6cb6d7310096f1739b25a5a3f0 +50 -0
  105. data/test/dummy/tmp/cache/assets/D08/9F0/sprockets%2F1d61d2c89ca50957066bacc5b69011f5 +1424 -0
  106. data/test/dummy/tmp/cache/assets/D0A/790/sprockets%2Feb16913e6504c9b0d3be431de39e4751 +300 -0
  107. data/test/dummy/tmp/cache/assets/D0C/C50/sprockets%2Fd6613bee8b40d50459af6b52a7084f34 +796 -0
  108. data/test/dummy/tmp/cache/assets/D0D/030/sprockets%2Fba3f13b4a444679e8bc2549226ec743b +21 -0
  109. data/test/dummy/tmp/cache/assets/D0D/350/sprockets%2F2670bce036d485e15d059c0f1e98f24a +207 -0
  110. data/test/dummy/tmp/cache/assets/D13/270/sprockets%2F497cb163e6317e3fc1565d832f406cfb +348 -0
  111. data/test/dummy/tmp/cache/assets/D13/380/sprockets%2F786d003c9c7fb759dd26c1030c087cf6 +813 -0
  112. data/test/dummy/tmp/cache/assets/D13/7C0/sprockets%2F528d22310a9ab8e6fba08d82844ce795 +0 -0
  113. data/test/dummy/tmp/cache/assets/D15/F60/sprockets%2Fa28394e3f80365b5bc86794dd46daa22 +0 -0
  114. data/test/dummy/tmp/cache/assets/D18/500/sprockets%2Fd22c2d97d1db2154f2f7592906e957ea +1001 -0
  115. data/test/dummy/tmp/cache/assets/D1B/C70/sprockets%2F1c04848b1e1d6e8e33b8581f8c8128ff +223 -0
  116. data/test/dummy/tmp/cache/assets/D1C/600/sprockets%2Fa0601f99147f59ddd6266e6aff077e14 +0 -0
  117. data/test/dummy/tmp/cache/assets/D1E/470/sprockets%2Fb3933e694547b78bf6fb15f44a4623fe +53 -0
  118. data/test/dummy/tmp/cache/assets/D1F/480/sprockets%2F545164168becf42b289efc8708f1db68 +1278 -0
  119. data/test/dummy/tmp/cache/assets/D21/630/sprockets%2F0a14114729c14637f2e8f122acabd1ab +823 -0
  120. data/test/dummy/tmp/cache/assets/D24/A90/sprockets%2F21c8a0d48c51b8585ba03bc112ecd153 +692 -0
  121. data/test/dummy/tmp/cache/assets/D25/D30/sprockets%2F3b937f4c16d2aa0a28fc02a0e922712b +1441 -0
  122. data/test/dummy/tmp/cache/assets/D25/F30/sprockets%2Fe251527c0c018f4b4ad44b2ad7064fb0 +2255 -0
  123. data/test/dummy/tmp/cache/assets/D26/DE0/sprockets%2F761ac1bdb0739cc56fa0c1224b137b09 +0 -0
  124. data/test/dummy/tmp/cache/assets/D2A/C30/sprockets%2F978fe7268754f451c59b9ccb323ffa56 +0 -0
  125. data/test/dummy/tmp/cache/assets/D2B/0F0/sprockets%2Fbf223af03335cfc08a71e549e10c0e27 +2539 -0
  126. data/test/dummy/tmp/cache/assets/D2E/6D0/sprockets%2F9e7fda3affb389313cc50223f01c0324 +0 -0
  127. data/test/dummy/tmp/cache/assets/D2F/110/sprockets%2F3730ffe2ed34c1219d580bd1615ea7b0 +2239 -0
  128. data/test/dummy/tmp/cache/assets/D2F/F10/sprockets%2F9cac242f0bf5ec00079ea3a463e26552 +153 -0
  129. data/test/dummy/tmp/cache/assets/D30/1D0/sprockets%2Fd690a26a0b0ae138c1c48d257a7674bc +589 -0
  130. data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  131. data/test/dummy/tmp/cache/assets/D36/940/sprockets%2Fb4ba462ac9f4aac561c36e60367c1378 +572 -0
  132. data/test/dummy/tmp/cache/assets/D37/090/sprockets%2F2f2e71ebbc240014ebf648f0917e854a +798 -0
  133. data/test/dummy/tmp/cache/assets/D3A/440/sprockets%2F6d332243647c841dea36ed822cdfc23e +165 -0
  134. data/test/dummy/tmp/cache/assets/D3B/5A0/sprockets%2F82e05cf8c88ba8cb1c87e50d51372a03 +0 -0
  135. data/test/dummy/tmp/cache/assets/D41/B30/sprockets%2Fba1b93913dd01d83ac9a96df334456f8 +0 -0
  136. data/test/dummy/tmp/cache/assets/D43/D90/sprockets%2F04f3a5926d5a7672456dc7afa73d0c7f +38 -0
  137. data/test/dummy/tmp/cache/assets/D45/1F0/sprockets%2F1bfa855d9c10ff2431a9a548958cc5e4 +83 -0
  138. data/test/dummy/tmp/cache/assets/D45/B10/sprockets%2F643f3d9b216e48df952b7f150a46a7ec +60 -0
  139. data/test/dummy/tmp/cache/assets/D46/040/sprockets%2F199546844e5939721a5afcbcce4ea43a +143 -0
  140. data/test/dummy/tmp/cache/assets/D49/320/sprockets%2Fd8123eb229e34c9f507f7b1876f1c4ee +506 -0
  141. data/test/dummy/tmp/cache/assets/D49/750/sprockets%2Ff41ef1c0832b7294fb15588ff5c783cb +0 -0
  142. data/test/dummy/tmp/cache/assets/D49/930/sprockets%2F1071926698fa55abc71e1b6fd966dfe1 +72 -0
  143. data/test/dummy/tmp/cache/assets/D49/D10/sprockets%2Fb67b8d7cc7579352a91694f9ae10cdb0 +127 -0
  144. data/test/dummy/tmp/cache/assets/D4A/160/sprockets%2Fcbd8988b5e18d153eff6230d72e9046a +516 -0
  145. data/test/dummy/tmp/cache/assets/D4A/2B0/sprockets%2Ffcdf002d38fd938bf7226b46b76706c8 +1101 -0
  146. data/test/dummy/tmp/cache/assets/D4E/2F0/sprockets%2F77cb87ae57f0d8c25cdaa74181a64997 +1441 -0
  147. data/test/dummy/tmp/cache/assets/D4F/060/sprockets%2Fa9e66b39ada7394a29bf44f3a682f665 +511 -0
  148. data/test/dummy/tmp/cache/assets/D50/BD0/sprockets%2F88650dd57ef64075462e6dae757dbe2c +0 -0
  149. data/test/dummy/tmp/cache/assets/D53/CA0/sprockets%2Fa85032e82709a043fbb2ec00e04f2bbd +0 -0
  150. data/test/dummy/tmp/cache/assets/D54/BF0/sprockets%2F91970514ff528e8d2bfd81f1ec83c9c8 +240 -0
  151. data/test/dummy/tmp/cache/assets/D54/ED0/sprockets%2F71c9fa01091d432b131da3bb73faf3d4 +10 -0
  152. data/test/dummy/tmp/cache/assets/D56/500/sprockets%2F75ebadd035f1324b194034af92eac3a0 +0 -0
  153. data/test/dummy/tmp/cache/assets/D5A/900/sprockets%2F5729f77d97fdee53b1942cf17f6f05e4 +474 -0
  154. data/test/dummy/tmp/cache/assets/D5A/D50/sprockets%2F81bace3db2c2f1241175ff3c5009d08c +0 -0
  155. data/test/dummy/tmp/cache/assets/D5B/C70/sprockets%2Fe64119a9db7017b7ab3b0da1b6076f0d +44 -0
  156. data/test/dummy/tmp/cache/assets/D5E/4D0/sprockets%2F756f25e4ad861a050cdc41bb8414e4ab +126 -0
  157. data/test/dummy/tmp/cache/assets/D5E/730/sprockets%2Fd30caf70b387c4604326bdda32aeb549 +0 -0
  158. data/test/dummy/tmp/cache/assets/D5E/AA0/sprockets%2F790dd07caaaacb30ceb0174664e90817 +136 -0
  159. data/test/dummy/tmp/cache/assets/D64/D30/sprockets%2Fe4bd8f60a3a446274c3cb2f5d16563ac +590 -0
  160. data/test/dummy/tmp/cache/assets/D66/400/sprockets%2Fecb7401d20daf25605a7afad3a793778 +0 -0
  161. data/test/dummy/tmp/cache/assets/D67/250/sprockets%2F8422eb26855ca9c953a3bf1aeade8004 +0 -0
  162. data/test/dummy/tmp/cache/assets/D69/900/sprockets%2F28ae64f52cb18f77b1a1bd9c51293da4 +0 -0
  163. data/test/dummy/tmp/cache/assets/D6A/870/sprockets%2F1ece6a51b42f9280f4cee9020c94b72e +197 -0
  164. data/test/dummy/tmp/cache/assets/D6B/DD0/sprockets%2F9a0abc735e27fc61dab019788518eba4 +164 -0
  165. data/test/dummy/tmp/cache/assets/D6E/CC0/sprockets%2F8b4fbcec2475e7203b8859baf8e310a3 +0 -0
  166. data/test/dummy/tmp/cache/assets/D72/470/sprockets%2Fbc0c6d850e7c769e83d58eb3e6061b2a +2556 -0
  167. data/test/dummy/tmp/cache/assets/D72/9D0/sprockets%2F9402daf6da6f7eed331a9d78216cb761 +0 -0
  168. data/test/dummy/tmp/cache/assets/D74/070/sprockets%2F91ae68f698a39bd7d0d11150fc46e4cd +418 -0
  169. data/test/dummy/tmp/cache/assets/D74/7F0/sprockets%2F22dad1069ea6a8f29ae757c44e18ec83 +0 -0
  170. data/test/dummy/tmp/cache/assets/D75/3C0/sprockets%2F44e2ae51b97853d8ecda7b264a267c7d +1630 -0
  171. data/test/dummy/tmp/cache/assets/D77/780/sprockets%2Ffa2abdfb0b62867c346f79187b8e42d5 +823 -0
  172. data/test/dummy/tmp/cache/assets/D79/850/sprockets%2F4d540586ed379fd9a70fa0b7ce4f5b27 +306 -0
  173. data/test/dummy/tmp/cache/assets/D7A/B60/sprockets%2F5925c92f48caff053d08853dc69e5bba +0 -0
  174. data/test/dummy/tmp/cache/assets/D81/C90/sprockets%2F19aca5c835efce74878c23e581e2a89e +2239 -0
  175. data/test/dummy/tmp/cache/assets/D84/210/sprockets%2Fabd0103ccec2b428ac62c94e4c40b384 +11228 -0
  176. data/test/dummy/tmp/cache/assets/D8B/B10/sprockets%2Fbb7a2305a8f2832631863bbababb67be +301 -0
  177. data/test/dummy/tmp/cache/assets/D92/3B0/sprockets%2F93dc71f411faf72ec8ef0b5d217b51a0 +505 -0
  178. data/test/dummy/tmp/cache/assets/D92/EE0/sprockets%2Ffd051ea0abf6be6970754aa732e40c8b +289 -0
  179. data/test/dummy/tmp/cache/assets/D93/810/sprockets%2F7dc1ac5e1b83ba5144e34cf156d48a8a +471 -0
  180. data/test/dummy/tmp/cache/assets/D94/020/sprockets%2F35cb4ce22488fb5bdd260508ca47a3fb +239 -0
  181. data/test/dummy/tmp/cache/assets/D94/EC0/sprockets%2F8b900fba18f8e046f5f12e6d1f0ac15b +74 -0
  182. data/test/dummy/tmp/cache/assets/D95/470/sprockets%2F5be5d361a52575c433831b5e8cccbace +9273 -0
  183. data/test/dummy/tmp/cache/assets/D97/9D0/sprockets%2F524a2a94a88c1d392dabcba654e365fc +103 -0
  184. data/test/dummy/tmp/cache/assets/D9D/800/sprockets%2Ff8387220eb4dda9b29a37b5deb9f2a40 +54 -0
  185. data/test/dummy/tmp/cache/assets/D9E/DD0/sprockets%2Fb6b4ffad6485eda046b327a196e8c44a +0 -0
  186. data/test/dummy/tmp/cache/assets/DA1/0A0/sprockets%2F359c94aee6ba2e15fc9666aa4de311c8 +166 -0
  187. data/test/dummy/tmp/cache/assets/DA1/0D0/sprockets%2F798de3c28452e164a7fc1a3a6e8cdb4b +652 -0
  188. data/test/dummy/tmp/cache/assets/DA3/CB0/sprockets%2Fdfad6bb1857a8af91f98ba137c18504e +815 -0
  189. data/test/dummy/tmp/cache/assets/DA4/E10/sprockets%2Fbda7705734ace95f12a7d79df9c14af2 +1354 -0
  190. data/test/dummy/tmp/cache/assets/DA5/E30/sprockets%2F2e6707a119e94a784efbadca18d7e8d1 +129 -0
  191. data/test/dummy/tmp/cache/assets/DA6/4B0/sprockets%2F4f7a708b6aa2d42eb577493dea7cef55 +115 -0
  192. data/test/dummy/tmp/cache/assets/DA8/A10/sprockets%2F0ae5bbb4ca200e74db3b64d72c2be120 +0 -0
  193. data/test/dummy/tmp/cache/assets/DA9/3F0/sprockets%2Fdd0af9cfd65fb7d02fe778c8f6015361 +499 -0
  194. data/test/dummy/tmp/cache/assets/DA9/780/sprockets%2Fe3559a635e8f92dec7727a3db2ae7b4c +813 -0
  195. data/test/dummy/tmp/cache/assets/DAC/0E0/sprockets%2F04cef8243a9ef7321846debc977ea8db +607 -0
  196. data/test/dummy/tmp/cache/assets/DB1/260/sprockets%2Fb879ff7530bf8cc175e0c7e70dc4e79b +0 -0
  197. data/test/dummy/tmp/cache/assets/DB4/4C0/sprockets%2F30a76cbd98dedb56742cd8ecaf858757 +0 -0
  198. data/test/dummy/tmp/cache/assets/DBD/7E0/sprockets%2F236fb1ac5ed9f2e3fe32203acc3a842d +0 -0
  199. data/test/dummy/tmp/cache/assets/DC2/DF0/sprockets%2Fe233bcaba8beff15626c35cb5e0e0936 +845 -0
  200. data/test/dummy/tmp/cache/assets/DC4/600/sprockets%2F59c96aa6c1cbebc61bff6c050a5351d7 +225 -0
  201. data/test/dummy/tmp/cache/assets/DC5/030/sprockets%2Fcb2fe864a0177eec19017c43ce9aa4ad +187 -0
  202. data/test/dummy/tmp/cache/assets/DC8/A60/sprockets%2F9fcb9f5c3f679ce749ee4c3f93869ba6 +74 -0
  203. data/test/dummy/tmp/cache/assets/DCB/D40/sprockets%2Ffd5542bfb7660a8d8cac3a2e46fb01f8 +828 -0
  204. data/test/dummy/tmp/cache/assets/DCC/020/sprockets%2F0c129c5f2784c96fa1dc3da6c19c1efc +128 -0
  205. data/test/dummy/tmp/cache/assets/DCF/520/sprockets%2F975162fb97a3ec7033db5f2fdba4fcd3 +70 -0
  206. data/test/dummy/tmp/cache/assets/DD0/000/sprockets%2F0d5d631cce6f0b078bb29cf98b3d78bb +276 -0
  207. data/test/dummy/tmp/cache/assets/DD0/C90/sprockets%2F84eeca4ef8f5eb29b13f7e1ea3c71324 +591 -0
  208. data/test/dummy/tmp/cache/assets/DD6/710/sprockets%2F9e83f2ebbe3e349efca2de390e15d635 +204 -0
  209. data/test/dummy/tmp/cache/assets/DE1/830/sprockets%2Fd23d3cafef2e2a9055bc103dffc1a023 +208 -0
  210. data/test/dummy/tmp/cache/assets/DEB/470/sprockets%2Fae2de0fcbc2214b71d3f2a875d2bc8c3 +2255 -0
  211. data/test/dummy/tmp/cache/assets/DEE/690/sprockets%2F5d824bcadef29060cc13eed71af4b4d0 +550 -0
  212. data/test/dummy/tmp/cache/assets/DF0/5D0/sprockets%2F25a875eb0a5d4c49bcc3fa39ea0adb26 +567 -0
  213. data/test/dummy/tmp/cache/assets/DF3/E20/sprockets%2Fada770c49a5d6b38d1cc43ed4d51c1fc +0 -0
  214. data/test/dummy/tmp/cache/assets/DF5/C80/sprockets%2F03ad7d7b3a8feba9ed9be82ae2083b20 +340 -0
  215. data/test/dummy/tmp/cache/assets/DF6/560/sprockets%2Fafceb2b55eb108efe4446dfb02b519b8 +0 -0
  216. data/test/dummy/tmp/cache/assets/DFC/030/sprockets%2Fcbdd3679eaba219b4e1ff20677af1c6f +1371 -0
  217. data/test/dummy/tmp/cache/assets/E00/970/sprockets%2F8bc6dde8d05c382dd07cbcec70f54e09 +378 -0
  218. data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  219. data/test/dummy/tmp/cache/assets/E12/2F0/sprockets%2F5c45062ecfbe512dcba176ba6ddacc00 +523 -0
  220. data/test/dummy/tmp/cache/assets/E21/5D0/sprockets%2Fd4fe6d611bfb0e63c04de5dbfb128a8a +0 -0
  221. data/test/dummy/tmp/cache/assets/E22/770/sprockets%2F2ccebcabfbb9b59159e4b73b3b30a74d +208 -0
  222. data/test/dummy/tmp/cache/assets/E31/A90/sprockets%2F26b98bbbc15eee9b370c7dcde88d16aa +394 -0
  223. data/test/dummy/tmp/cache/assets/E31/E30/sprockets%2Ffbdafcc4e2f44bb9fc653bcf9625b750 +284 -0
  224. data/test/dummy/tmp/cache/assets/E37/1C0/sprockets%2Fa5eb45fc86dafe2bee4e4fa3f53c4785 +0 -0
  225. data/test/dummy/tmp/cache/assets/E4C/960/sprockets%2F13fd6e4bfdf031acb3dedca8d0f407b4 +1277 -0
  226. data/test/dummy/tmp/cache/assets/E88/330/sprockets%2Fe02d0adb5529ffafcea1b9e5ccf69a5b +669 -0
  227. data/test/dummy/tmp/pids/server.pid +1 -0
  228. data/test/dummy/tmp/simple.js.js +20 -0
  229. data/test/dummy/tmp/soy-1325274421.js +20 -0
  230. data/test/dummy/tmp/soy-1325286267.js +20 -0
  231. data/test/test_helper.rb +10 -0
  232. data/test/yellow-brick-road_test.rb +7 -0
  233. metadata +538 -0
@@ -0,0 +1,340 @@
1
+ o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1325441615.563265: @value{ I" length:EFi�'I" digest;
2
+ F"%b5c48f913577ca61ad6b908ba2c7c7eeI" 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 JSON utility functions.
19
+ * @author arv@google.com (Erik Arvidsson)
20
+ */
21
+
22
+
23
+
24
+ goog.provide('goog.json');
25
+ goog.provide('goog.json.Serializer');
26
+
27
+
28
+ /**
29
+ * Tests if a string is an invalid JSON string. This only ensures that we are
30
+ * not using any invalid characters
31
+ * @param {string} s The string to test.
32
+ * @return {boolean} True if the input is a valid JSON string.
33
+ * @private
34
+ */
35
+ goog.json.isValid_ = function(s) {
36
+ // All empty whitespace is not valid.
37
+ if (/^\s*$/.test(s)) {
38
+ return false;
39
+ }
40
+
41
+ // This is taken from http://www.json.org/json2.js which is released to the
42
+ // public domain.
43
+ // Changes: We dissallow \u2028 Line separator and \u2029 Paragraph separator
44
+ // inside strings. We also treat \u2028 and \u2029 as whitespace which they
45
+ // are in the RFC but IE and Safari does not match \s to these so we need to
46
+ // include them in the reg exps in all places where whitespace is allowed.
47
+ // We allowed \x7f inside strings because some tools don't escape it,
48
+ // e.g. http://www.json.org/java/org/json/JSONObject.java
49
+
50
+ // Parsing happens in three stages. In the first stage, we run the text
51
+ // against regular expressions that look for non-JSON patterns. We are
52
+ // especially concerned with '()' and 'new' because they can cause invocation,
53
+ // and '=' because it can cause mutation. But just to be safe, we want to
54
+ // reject all unexpected forms.
55
+
56
+ // We split the first stage into 4 regexp operations in order to work around
57
+ // crippling inefficiencies in IE's and Safari's regexp engines. First we
58
+ // replace all backslash pairs with '@' (a non-JSON character). Second, we
59
+ // replace all simple value tokens with ']' characters. Third, we delete all
60
+ // open brackets that follow a colon or comma or that begin the text. Finally,
61
+ // we look to see that the remaining characters are only whitespace or ']' or
62
+ // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
63
+
64
+ // Don't make these static since they have the global flag.
65
+ var backslashesRe = /\\["\\\/bfnrtu]/g;
66
+ var simpleValuesRe =
67
+ /"[^"\\\n\r\u2028\u2029\x00-\x08\x10-\x1f\x80-\x9f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
68
+ var openBracketsRe = /(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g;
69
+ var remainderRe = /^[\],:{}\s\u2028\u2029]*$/;
70
+
71
+ return remainderRe.test(s.replace(backslashesRe, '@').
72
+ replace(simpleValuesRe, ']').
73
+ replace(openBracketsRe, ''));
74
+ };
75
+
76
+
77
+ /**
78
+ * Parses a JSON string and returns the result. This throws an exception if
79
+ * the string is an invalid JSON string.
80
+ *
81
+ * Note that this is very slow on large strings. If you trust the source of
82
+ * the string then you should use unsafeParse instead.
83
+ *
84
+ * @param {*} s The JSON string to parse.
85
+ * @return {Object} The object generated from the JSON string.
86
+ */
87
+ goog.json.parse = function(s) {
88
+ var o = String(s);
89
+ if (goog.json.isValid_(o)) {
90
+ /** @preserveTry */
91
+ try {
92
+ return /** @type {Object} */ (eval('(' + o + ')'));
93
+ } catch (ex) {
94
+ }
95
+ }
96
+ throw Error('Invalid JSON string: ' + o);
97
+ };
98
+
99
+
100
+ /**
101
+ * Parses a JSON string and returns the result. This uses eval so it is open
102
+ * to security issues and it should only be used if you trust the source.
103
+ *
104
+ * @param {string} s The JSON string to parse.
105
+ * @return {Object} The object generated from the JSON string.
106
+ */
107
+ goog.json.unsafeParse = function(s) {
108
+ return /** @type {Object} */ (eval('(' + s + ')'));
109
+ };
110
+
111
+
112
+ /**
113
+ * JSON replacer, as defined in Section 15.12.3 of the ES5 spec.
114
+ *
115
+ * TODO(nicksantos): Array should also be a valid replacer.
116
+ *
117
+ * @typedef {function(this:Object, string, *): *}
118
+ */
119
+ goog.json.Replacer;
120
+
121
+
122
+ /**
123
+ * Serializes an object or a value to a JSON string.
124
+ *
125
+ * @param {*} object The object to serialize.
126
+ * @param {?goog.json.Replacer=} opt_replacer A replacer function
127
+ * called for each (key, value) pair that determines how the value
128
+ * should be serialized. By defult, this just returns the value
129
+ * and allows default serialization to kick in.
130
+ * @throws Error if there are loops in the object graph.
131
+ * @return {string} A JSON string representation of the input.
132
+ */
133
+ goog.json.serialize = function(object, opt_replacer) {
134
+ // TODO(nicksantos): Change this to default to JSON.stringify when available.
135
+ // I need to fiddle with the default externs a bit to make this happen.
136
+ return new goog.json.Serializer(opt_replacer).serialize(object);
137
+ };
138
+
139
+
140
+
141
+ /**
142
+ * Class that is used to serialize JSON objects to a string.
143
+ * @param {?goog.json.Replacer=} opt_replacer Replacer.
144
+ * @constructor
145
+ */
146
+ goog.json.Serializer = function(opt_replacer) {
147
+ /**
148
+ * @type {goog.json.Replacer|null|undefined}
149
+ * @private
150
+ */
151
+ this.replacer_ = opt_replacer;
152
+ };
153
+
154
+
155
+ /**
156
+ * Serializes an object or a value to a JSON string.
157
+ *
158
+ * @param {*} object The object to serialize.
159
+ * @throws Error if there are loops in the object graph.
160
+ * @return {string} A JSON string representation of the input.
161
+ */
162
+ goog.json.Serializer.prototype.serialize = function(object) {
163
+ var sb = [];
164
+ this.serialize_(object, sb);
165
+ return sb.join('');
166
+ };
167
+
168
+
169
+ /**
170
+ * Serializes a generic value to a JSON string
171
+ * @private
172
+ * @param {*} object The object to serialize.
173
+ * @param {Array} sb Array used as a string builder.
174
+ * @throws Error if there are loops in the object graph.
175
+ */
176
+ goog.json.Serializer.prototype.serialize_ = function(object, sb) {
177
+ switch (typeof object) {
178
+ case 'string':
179
+ this.serializeString_((/** @type {string} */ object), sb);
180
+ break;
181
+ case 'number':
182
+ this.serializeNumber_((/** @type {number} */ object), sb);
183
+ break;
184
+ case 'boolean':
185
+ sb.push(object);
186
+ break;
187
+ case 'undefined':
188
+ sb.push('null');
189
+ break;
190
+ case 'object':
191
+ if (object == null) {
192
+ sb.push('null');
193
+ break;
194
+ }
195
+ if (goog.isArray(object)) {
196
+ this.serializeArray_((/** @type {!Array} */ object), sb);
197
+ break;
198
+ }
199
+ // should we allow new String, new Number and new Boolean to be treated
200
+ // as string, number and boolean? Most implementations do not and the
201
+ // need is not very big
202
+ this.serializeObject_((/** @type {Object} */ object), sb);
203
+ break;
204
+ case 'function':
205
+ // Skip functions.
206
+ // TODO(user) Should we return something here?
207
+ break;
208
+ default:
209
+ throw Error('Unknown type: ' + typeof object);
210
+ }
211
+ };
212
+
213
+
214
+ /**
215
+ * Character mappings used internally for goog.string.quote
216
+ * @private
217
+ * @type {Object}
218
+ */
219
+ goog.json.Serializer.charToJsonCharCache_ = {
220
+ '\"': '\\"',
221
+ '\\': '\\\\',
222
+ '/': '\\/',
223
+ '\b': '\\b',
224
+ '\f': '\\f',
225
+ '\n': '\\n',
226
+ '\r': '\\r',
227
+ '\t': '\\t',
228
+
229
+ '\x0B': '\\u000b' // '\v' is not supported in JScript
230
+ };
231
+
232
+
233
+ /**
234
+ * Regular expression used to match characters that need to be replaced.
235
+ * The S60 browser has a bug where unicode characters are not matched by
236
+ * regular expressions. The condition below detects such behaviour and
237
+ * adjusts the regular expression accordingly.
238
+ * @private
239
+ * @type {RegExp}
240
+ */
241
+ goog.json.Serializer.charsToReplace_ = /\uffff/.test('\uffff') ?
242
+ /[\\\"\x00-\x1f\x7f-\uffff]/g : /[\\\"\x00-\x1f\x7f-\xff]/g;
243
+
244
+
245
+ /**
246
+ * Serializes a string to a JSON string
247
+ * @private
248
+ * @param {string} s The string to serialize.
249
+ * @param {Array} sb Array used as a string builder.
250
+ */
251
+ goog.json.Serializer.prototype.serializeString_ = function(s, sb) {
252
+ // The official JSON implementation does not work with international
253
+ // characters.
254
+ sb.push('"', s.replace(goog.json.Serializer.charsToReplace_, function(c) {
255
+ // caching the result improves performance by a factor 2-3
256
+ if (c in goog.json.Serializer.charToJsonCharCache_) {
257
+ return goog.json.Serializer.charToJsonCharCache_[c];
258
+ }
259
+
260
+ var cc = c.charCodeAt(0);
261
+ var rv = '\\u';
262
+ if (cc < 16) {
263
+ rv += '000';
264
+ } else if (cc < 256) {
265
+ rv += '00';
266
+ } else if (cc < 4096) { // \u1000
267
+ rv += '0';
268
+ }
269
+ return goog.json.Serializer.charToJsonCharCache_[c] = rv + cc.toString(16);
270
+ }), '"');
271
+ };
272
+
273
+
274
+ /**
275
+ * Serializes a number to a JSON string
276
+ * @private
277
+ * @param {number} n The number to serialize.
278
+ * @param {Array} sb Array used as a string builder.
279
+ */
280
+ goog.json.Serializer.prototype.serializeNumber_ = function(n, sb) {
281
+ sb.push(isFinite(n) && !isNaN(n) ? n : 'null');
282
+ };
283
+
284
+
285
+ /**
286
+ * Serializes an array to a JSON string
287
+ * @private
288
+ * @param {Array} arr The array to serialize.
289
+ * @param {Array} sb Array used as a string builder.
290
+ */
291
+ goog.json.Serializer.prototype.serializeArray_ = function(arr, sb) {
292
+ var l = arr.length;
293
+ sb.push('[');
294
+ var sep = '';
295
+ for (var i = 0; i < l; i++) {
296
+ sb.push(sep);
297
+
298
+ var value = arr[i];
299
+ this.serialize_(
300
+ this.replacer_ ? this.replacer_.call(arr, String(i), value) : value,
301
+ sb);
302
+
303
+ sep = ',';
304
+ }
305
+ sb.push(']');
306
+ };
307
+
308
+
309
+ /**
310
+ * Serializes an object to a JSON string
311
+ * @private
312
+ * @param {Object} obj The object to serialize.
313
+ * @param {Array} sb Array used as a string builder.
314
+ */
315
+ goog.json.Serializer.prototype.serializeObject_ = function(obj, sb) {
316
+ sb.push('{');
317
+ var sep = '';
318
+ for (var key in obj) {
319
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
320
+ var value = obj[key];
321
+ // Skip functions.
322
+ // TODO(ptucker) Should we return something for function properties?
323
+ if (typeof value != 'function') {
324
+ sb.push(sep);
325
+ this.serializeString_(key, sb);
326
+ sb.push(':');
327
+
328
+ this.serialize_(
329
+ this.replacer_ ? this.replacer_.call(obj, key, value) : value,
330
+ sb);
331
+
332
+ sep = ',';
333
+ }
334
+ }
335
+ }
336
+ sb.push('}');
337
+ };
338
+ ;
339
+ FI"
340
+ F"%78a28b2cc81bc1215c8e54f5af6e1f65
@@ -0,0 +1,1371 @@
1
+ o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1325458072.29262: @value{I"
2
+ class:EFI"BundledAsset;
3
+ FI"id;
4
+ F"%5358f5a6ea2494e1dedb86f86a078827I"logical_path;
5
+ FI" closure/goog/array/array.js;
6
+ TI"
7
+ F"f/Volumes/Development/dev-web/yellow-brick-road/vendor/closure-library/closure/goog/array/array.jsI"content_type;
8
+ FI"application/javascript;
9
+ FI"
10
+ mtime;
11
+ FI"2011-12-30T02:16:24+00:00;
12
+ FI" body;
13
+ FI"��// Copyright 2006 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 for manipulating arrays.
29
+ *
30
+ */
31
+
32
+
33
+
34
+ goog.provide('goog.array');
35
+ goog.provide('goog.array.ArrayLike');
36
+
37
+ goog.require('goog.asserts');
38
+
39
+
40
+ /**
41
+ * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should
42
+ * rely on Array.prototype functions, if available.
43
+ *
44
+ * The Array.prototype functions can be defined by external libraries like
45
+ * Prototype and setting this flag to false forces closure to use its own
46
+ * goog.array implementation.
47
+ *
48
+ * If your javascript can be loaded by a third party site and you are wary about
49
+ * relying on the prototype functions, specify
50
+ * "--define goog.NATIVE_ARRAY_PROTOTYPES=false" to the JSCompiler.
51
+ */
52
+ goog.NATIVE_ARRAY_PROTOTYPES = true;
53
+
54
+
55
+ /**
56
+ * @typedef {Array|NodeList|Arguments|{length: number}}
57
+ */
58
+ goog.array.ArrayLike;
59
+
60
+
61
+ /**
62
+ * Returns the last element in an array without removing it.
63
+ * @param {goog.array.ArrayLike} array The array.
64
+ * @return {*} Last item in array.
65
+ */
66
+ goog.array.peek = function(array) {
67
+ return array[array.length - 1];
68
+ };
69
+
70
+
71
+ /**
72
+ * Reference to the original {@code Array.prototype}.
73
+ * @private
74
+ */
75
+ goog.array.ARRAY_PROTOTYPE_ = Array.prototype;
76
+
77
+
78
+ // NOTE(arv): Since most of the array functions are generic it allows you to
79
+ // pass an array-like object. Strings have a length and are considered array-
80
+ // like. However, the 'in' operator does not work on strings so we cannot just
81
+ // use the array path even if the browser supports indexing into strings. We
82
+ // therefore end up splitting the string.
83
+
84
+
85
+ /**
86
+ * Returns the index of the first element of an array with a specified
87
+ * value, or -1 if the element is not present in the array.
88
+ *
89
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof}
90
+ *
91
+ * @param {goog.array.ArrayLike} arr The array to be searched.
92
+ * @param {*} obj The object for which we are searching.
93
+ * @param {number=} opt_fromIndex The index at which to start the search. If
94
+ * omitted the search starts at index 0.
95
+ * @return {number} The index of the first matching array element.
96
+ */
97
+ goog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES &&
98
+ goog.array.ARRAY_PROTOTYPE_.indexOf ?
99
+ function(arr, obj, opt_fromIndex) {
100
+ goog.asserts.assert(arr.length != null);
101
+
102
+ return goog.array.ARRAY_PROTOTYPE_.indexOf.call(arr, obj, opt_fromIndex);
103
+ } :
104
+ function(arr, obj, opt_fromIndex) {
105
+ var fromIndex = opt_fromIndex == null ?
106
+ 0 : (opt_fromIndex < 0 ?
107
+ Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex);
108
+
109
+ if (goog.isString(arr)) {
110
+ // Array.prototype.indexOf uses === so only strings should be found.
111
+ if (!goog.isString(obj) || obj.length != 1) {
112
+ return -1;
113
+ }
114
+ return arr.indexOf(obj, fromIndex);
115
+ }
116
+
117
+ for (var i = fromIndex; i < arr.length; i++) {
118
+ if (i in arr && arr[i] === obj)
119
+ return i;
120
+ }
121
+ return -1;
122
+ };
123
+
124
+
125
+ /**
126
+ * Returns the index of the last element of an array with a specified value, or
127
+ * -1 if the element is not present in the array.
128
+ *
129
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof}
130
+ *
131
+ * @param {goog.array.ArrayLike} arr The array to be searched.
132
+ * @param {*} obj The object for which we are searching.
133
+ * @param {?number=} opt_fromIndex The index at which to start the search. If
134
+ * omitted the search starts at the end of the array.
135
+ * @return {number} The index of the last matching array element.
136
+ */
137
+ goog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES &&
138
+ goog.array.ARRAY_PROTOTYPE_.lastIndexOf ?
139
+ function(arr, obj, opt_fromIndex) {
140
+ goog.asserts.assert(arr.length != null);
141
+
142
+ // Firefox treats undefined and null as 0 in the fromIndex argument which
143
+ // leads it to always return -1
144
+ var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;
145
+ return goog.array.ARRAY_PROTOTYPE_.lastIndexOf.call(arr, obj, fromIndex);
146
+ } :
147
+ function(arr, obj, opt_fromIndex) {
148
+ var fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;
149
+
150
+ if (fromIndex < 0) {
151
+ fromIndex = Math.max(0, arr.length + fromIndex);
152
+ }
153
+
154
+ if (goog.isString(arr)) {
155
+ // Array.prototype.lastIndexOf uses === so only strings should be found.
156
+ if (!goog.isString(obj) || obj.length != 1) {
157
+ return -1;
158
+ }
159
+ return arr.lastIndexOf(obj, fromIndex);
160
+ }
161
+
162
+ for (var i = fromIndex; i >= 0; i--) {
163
+ if (i in arr && arr[i] === obj)
164
+ return i;
165
+ }
166
+ return -1;
167
+ };
168
+
169
+
170
+ /**
171
+ * Calls a function for each element in an array.
172
+ *
173
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach}
174
+ *
175
+ * @param {goog.array.ArrayLike} arr Array or array like object over
176
+ * which to iterate.
177
+ * @param {?function(this: T, ...)} f The function to call for every element.
178
+ * This function takes 3 arguments (the element, the index and the array).
179
+ * The return value is ignored. The function is called only for indexes of
180
+ * the array which have assigned values; it is not called for indexes which
181
+ * have been deleted or which have never been assigned values.
182
+ * @param {T=} opt_obj The object to be used as the value of 'this'
183
+ * within f.
184
+ * @template T
185
+ */
186
+ goog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES &&
187
+ goog.array.ARRAY_PROTOTYPE_.forEach ?
188
+ function(arr, f, opt_obj) {
189
+ goog.asserts.assert(arr.length != null);
190
+
191
+ goog.array.ARRAY_PROTOTYPE_.forEach.call(arr, f, opt_obj);
192
+ } :
193
+ function(arr, f, opt_obj) {
194
+ var l = arr.length; // must be fixed during loop... see docs
195
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
196
+ for (var i = 0; i < l; i++) {
197
+ if (i in arr2) {
198
+ f.call(opt_obj, arr2[i], i, arr);
199
+ }
200
+ }
201
+ };
202
+
203
+
204
+ /**
205
+ * Calls a function for each element in an array, starting from the last
206
+ * element rather than the first.
207
+ *
208
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
209
+ * @param {Function} f The function to call for every element. This function
210
+ * takes 3 arguments (the element, the index and the array). The return
211
+ * value is ignored.
212
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
213
+ * within f.
214
+ */
215
+ goog.array.forEachRight = function(arr, f, opt_obj) {
216
+ var l = arr.length; // must be fixed during loop... see docs
217
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
218
+ for (var i = l - 1; i >= 0; --i) {
219
+ if (i in arr2) {
220
+ f.call(opt_obj, arr2[i], i, arr);
221
+ }
222
+ }
223
+ };
224
+
225
+
226
+ /**
227
+ * Calls a function for each element in an array, and if the function returns
228
+ * true adds the element to a new array.
229
+ *
230
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-filter}
231
+ *
232
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
233
+ * @param {Function} f The function to call for every element. This function
234
+ * takes 3 arguments (the element, the index and the array) and must
235
+ * return a Boolean. If the return value is true the element is added to the
236
+ * result array. If it is false the element is not included.
237
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
238
+ * within f.
239
+ * @return {!Array} a new array in which only elements that passed the test are
240
+ * present.
241
+ */
242
+ goog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES &&
243
+ goog.array.ARRAY_PROTOTYPE_.filter ?
244
+ function(arr, f, opt_obj) {
245
+ goog.asserts.assert(arr.length != null);
246
+
247
+ return goog.array.ARRAY_PROTOTYPE_.filter.call(arr, f, opt_obj);
248
+ } :
249
+ function(arr, f, opt_obj) {
250
+ var l = arr.length; // must be fixed during loop... see docs
251
+ var res = [];
252
+ var resLength = 0;
253
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
254
+ for (var i = 0; i < l; i++) {
255
+ if (i in arr2) {
256
+ var val = arr2[i]; // in case f mutates arr2
257
+ if (f.call(opt_obj, val, i, arr)) {
258
+ res[resLength++] = val;
259
+ }
260
+ }
261
+ }
262
+ return res;
263
+ };
264
+
265
+
266
+ /**
267
+ * Calls a function for each element in an array and inserts the result into a
268
+ * new array.
269
+ *
270
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-map}
271
+ *
272
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
273
+ * @param {Function} f The function to call for every element. This function
274
+ * takes 3 arguments (the element, the index and the array) and should
275
+ * return something. The result will be inserted into a new array.
276
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
277
+ * within f.
278
+ * @return {!Array} a new array with the results from f.
279
+ */
280
+ goog.array.map = goog.NATIVE_ARRAY_PROTOTYPES &&
281
+ goog.array.ARRAY_PROTOTYPE_.map ?
282
+ function(arr, f, opt_obj) {
283
+ goog.asserts.assert(arr.length != null);
284
+
285
+ return goog.array.ARRAY_PROTOTYPE_.map.call(arr, f, opt_obj);
286
+ } :
287
+ function(arr, f, opt_obj) {
288
+ var l = arr.length; // must be fixed during loop... see docs
289
+ var res = new Array(l);
290
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
291
+ for (var i = 0; i < l; i++) {
292
+ if (i in arr2) {
293
+ res[i] = f.call(opt_obj, arr2[i], i, arr);
294
+ }
295
+ }
296
+ return res;
297
+ };
298
+
299
+
300
+ /**
301
+ * Passes every element of an array into a function and accumulates the result.
302
+ *
303
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce}
304
+ *
305
+ * For example:
306
+ * var a = [1, 2, 3, 4];
307
+ * goog.array.reduce(a, function(r, v, i, arr) {return r + v;}, 0);
308
+ * returns 10
309
+ *
310
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
311
+ * @param {Function} f The function to call for every element. This function
312
+ * takes 4 arguments (the function's previous result or the initial value,
313
+ * the value of the current array element, the current array index, and the
314
+ * array itself)
315
+ * function(previousValue, currentValue, index, array).
316
+ * @param {*} val The initial value to pass into the function on the first call.
317
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
318
+ * within f.
319
+ * @return {*} Result of evaluating f repeatedly across the values of the array.
320
+ */
321
+ goog.array.reduce = function(arr, f, val, opt_obj) {
322
+ if (arr.reduce) {
323
+ if (opt_obj) {
324
+ return arr.reduce(goog.bind(f, opt_obj), val);
325
+ } else {
326
+ return arr.reduce(f, val);
327
+ }
328
+ }
329
+ var rval = val;
330
+ goog.array.forEach(arr, function(val, index) {
331
+ rval = f.call(opt_obj, rval, val, index, arr);
332
+ });
333
+ return rval;
334
+ };
335
+
336
+
337
+ /**
338
+ * Passes every element of an array into a function and accumulates the result,
339
+ * starting from the last element and working towards the first.
340
+ *
341
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright}
342
+ *
343
+ * For example:
344
+ * var a = ['a', 'b', 'c'];
345
+ * goog.array.reduceRight(a, function(r, v, i, arr) {return r + v;}, '');
346
+ * returns 'cba'
347
+ *
348
+ * @param {goog.array.ArrayLike} arr The array over which to iterate.
349
+ * @param {Function} f The function to call for every element. This function
350
+ * takes 4 arguments (the function's previous result or the initial value,
351
+ * the value of the current array element, the current array index, and the
352
+ * array itself)
353
+ * function(previousValue, currentValue, index, array).
354
+ * @param {*} val The initial value to pass into the function on the first call.
355
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
356
+ * within f.
357
+ * @return {*} Object returned as a result of evaluating f repeatedly across the
358
+ * values of the array.
359
+ */
360
+ goog.array.reduceRight = function(arr, f, val, opt_obj) {
361
+ if (arr.reduceRight) {
362
+ if (opt_obj) {
363
+ return arr.reduceRight(goog.bind(f, opt_obj), val);
364
+ } else {
365
+ return arr.reduceRight(f, val);
366
+ }
367
+ }
368
+ var rval = val;
369
+ goog.array.forEachRight(arr, function(val, index) {
370
+ rval = f.call(opt_obj, rval, val, index, arr);
371
+ });
372
+ return rval;
373
+ };
374
+
375
+
376
+ /**
377
+ * Calls f for each element of an array. If any call returns true, some()
378
+ * returns true (without checking the remaining elements). If all calls
379
+ * return false, some() returns false.
380
+ *
381
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-some}
382
+ *
383
+ * @param {goog.array.ArrayLike} arr The array to check.
384
+ * @param {Function} f The function to call for every element. This function
385
+ * takes 3 arguments (the element, the index and the array) and must
386
+ * return a Boolean.
387
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
388
+ * within f.
389
+ * @return {boolean} true if any element passes the test.
390
+ */
391
+ goog.array.some = goog.NATIVE_ARRAY_PROTOTYPES &&
392
+ goog.array.ARRAY_PROTOTYPE_.some ?
393
+ function(arr, f, opt_obj) {
394
+ goog.asserts.assert(arr.length != null);
395
+
396
+ return goog.array.ARRAY_PROTOTYPE_.some.call(arr, f, opt_obj);
397
+ } :
398
+ function(arr, f, opt_obj) {
399
+ var l = arr.length; // must be fixed during loop... see docs
400
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
401
+ for (var i = 0; i < l; i++) {
402
+ if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
403
+ return true;
404
+ }
405
+ }
406
+ return false;
407
+ };
408
+
409
+
410
+ /**
411
+ * Call f for each element of an array. If all calls return true, every()
412
+ * returns true. If any call returns false, every() returns false and
413
+ * does not continue to check the remaining elements.
414
+ *
415
+ * See {@link http://tinyurl.com/developer-mozilla-org-array-every}
416
+ *
417
+ * @param {goog.array.ArrayLike} arr The array to check.
418
+ * @param {Function} f The function to call for every element. This function
419
+ * takes 3 arguments (the element, the index and the array) and must
420
+ * return a Boolean.
421
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
422
+ * within f.
423
+ * @return {boolean} false if any element fails the test.
424
+ */
425
+ goog.array.every = goog.NATIVE_ARRAY_PROTOTYPES &&
426
+ goog.array.ARRAY_PROTOTYPE_.every ?
427
+ function(arr, f, opt_obj) {
428
+ goog.asserts.assert(arr.length != null);
429
+
430
+ return goog.array.ARRAY_PROTOTYPE_.every.call(arr, f, opt_obj);
431
+ } :
432
+ function(arr, f, opt_obj) {
433
+ var l = arr.length; // must be fixed during loop... see docs
434
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
435
+ for (var i = 0; i < l; i++) {
436
+ if (i in arr2 && !f.call(opt_obj, arr2[i], i, arr)) {
437
+ return false;
438
+ }
439
+ }
440
+ return true;
441
+ };
442
+
443
+
444
+ /**
445
+ * Search an array for the first element that satisfies a given condition and
446
+ * return that element.
447
+ * @param {goog.array.ArrayLike} arr The array to search.
448
+ * @param {Function} f The function to call for every element. This function
449
+ * takes 3 arguments (the element, the index and the array) and should
450
+ * return a boolean.
451
+ * @param {Object=} opt_obj An optional "this" context for the function.
452
+ * @return {*} The first array element that passes the test, or null if no
453
+ * element is found.
454
+ */
455
+ goog.array.find = function(arr, f, opt_obj) {
456
+ var i = goog.array.findIndex(arr, f, opt_obj);
457
+ return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];
458
+ };
459
+
460
+
461
+ /**
462
+ * Search an array for the first element that satisfies a given condition and
463
+ * return its index.
464
+ * @param {goog.array.ArrayLike} arr The array to search.
465
+ * @param {Function} f The function to call for every element. This function
466
+ * takes 3 arguments (the element, the index and the array) and should
467
+ * return a boolean.
468
+ * @param {Object=} opt_obj An optional "this" context for the function.
469
+ * @return {number} The index of the first array element that passes the test,
470
+ * or -1 if no element is found.
471
+ */
472
+ goog.array.findIndex = function(arr, f, opt_obj) {
473
+ var l = arr.length; // must be fixed during loop... see docs
474
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
475
+ for (var i = 0; i < l; i++) {
476
+ if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
477
+ return i;
478
+ }
479
+ }
480
+ return -1;
481
+ };
482
+
483
+
484
+ /**
485
+ * Search an array (in reverse order) for the last element that satisfies a
486
+ * given condition and return that element.
487
+ * @param {goog.array.ArrayLike} arr The array to search.
488
+ * @param {Function} f The function to call for every element. This function
489
+ * takes 3 arguments (the element, the index and the array) and should
490
+ * return a boolean.
491
+ * @param {Object=} opt_obj An optional "this" context for the function.
492
+ * @return {*} The last array element that passes the test, or null if no
493
+ * element is found.
494
+ */
495
+ goog.array.findRight = function(arr, f, opt_obj) {
496
+ var i = goog.array.findIndexRight(arr, f, opt_obj);
497
+ return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];
498
+ };
499
+
500
+
501
+ /**
502
+ * Search an array (in reverse order) for the last element that satisfies a
503
+ * given condition and return its index.
504
+ * @param {goog.array.ArrayLike} arr The array to search.
505
+ * @param {Function} f The function to call for every element. This function
506
+ * takes 3 arguments (the element, the index and the array) and should
507
+ * return a boolean.
508
+ * @param {Object=} opt_obj An optional "this" context for the function.
509
+ * @return {number} The index of the last array element that passes the test,
510
+ * or -1 if no element is found.
511
+ */
512
+ goog.array.findIndexRight = function(arr, f, opt_obj) {
513
+ var l = arr.length; // must be fixed during loop... see docs
514
+ var arr2 = goog.isString(arr) ? arr.split('') : arr;
515
+ for (var i = l - 1; i >= 0; i--) {
516
+ if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {
517
+ return i;
518
+ }
519
+ }
520
+ return -1;
521
+ };
522
+
523
+
524
+ /**
525
+ * Whether the array contains the given object.
526
+ * @param {goog.array.ArrayLike} arr The array to test for the presence of the
527
+ * element.
528
+ * @param {*} obj The object for which to test.
529
+ * @return {boolean} true if obj is present.
530
+ */
531
+ goog.array.contains = function(arr, obj) {
532
+ return goog.array.indexOf(arr, obj) >= 0;
533
+ };
534
+
535
+
536
+ /**
537
+ * Whether the array is empty.
538
+ * @param {goog.array.ArrayLike} arr The array to test.
539
+ * @return {boolean} true if empty.
540
+ */
541
+ goog.array.isEmpty = function(arr) {
542
+ return arr.length == 0;
543
+ };
544
+
545
+
546
+ /**
547
+ * Clears the array.
548
+ * @param {goog.array.ArrayLike} arr Array or array like object to clear.
549
+ */
550
+ goog.array.clear = function(arr) {
551
+ // For non real arrays we don't have the magic length so we delete the
552
+ // indices.
553
+ if (!goog.isArray(arr)) {
554
+ for (var i = arr.length - 1; i >= 0; i--) {
555
+ delete arr[i];
556
+ }
557
+ }
558
+ arr.length = 0;
559
+ };
560
+
561
+
562
+ /**
563
+ * Pushes an item into an array, if it's not already in the array.
564
+ * @param {Array} arr Array into which to insert the item.
565
+ * @param {*} obj Value to add.
566
+ */
567
+ goog.array.insert = function(arr, obj) {
568
+ if (!goog.array.contains(arr, obj)) {
569
+ arr.push(obj);
570
+ }
571
+ };
572
+
573
+
574
+ /**
575
+ * Inserts an object at the given index of the array.
576
+ * @param {goog.array.ArrayLike} arr The array to modify.
577
+ * @param {*} obj The object to insert.
578
+ * @param {number=} opt_i The index at which to insert the object. If omitted,
579
+ * treated as 0. A negative index is counted from the end of the array.
580
+ */
581
+ goog.array.insertAt = function(arr, obj, opt_i) {
582
+ goog.array.splice(arr, opt_i, 0, obj);
583
+ };
584
+
585
+
586
+ /**
587
+ * Inserts at the given index of the array, all elements of another array.
588
+ * @param {goog.array.ArrayLike} arr The array to modify.
589
+ * @param {goog.array.ArrayLike} elementsToAdd The array of elements to add.
590
+ * @param {number=} opt_i The index at which to insert the object. If omitted,
591
+ * treated as 0. A negative index is counted from the end of the array.
592
+ */
593
+ goog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) {
594
+ goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd);
595
+ };
596
+
597
+
598
+ /**
599
+ * Inserts an object into an array before a specified object.
600
+ * @param {Array} arr The array to modify.
601
+ * @param {*} obj The object to insert.
602
+ * @param {*=} opt_obj2 The object before which obj should be inserted. If obj2
603
+ * is omitted or not found, obj is inserted at the end of the array.
604
+ */
605
+ goog.array.insertBefore = function(arr, obj, opt_obj2) {
606
+ var i;
607
+ if (arguments.length == 2 || (i = goog.array.indexOf(arr, opt_obj2)) < 0) {
608
+ arr.push(obj);
609
+ } else {
610
+ goog.array.insertAt(arr, obj, i);
611
+ }
612
+ };
613
+
614
+
615
+ /**
616
+ * Removes the first occurrence of a particular value from an array.
617
+ * @param {goog.array.ArrayLike} arr Array from which to remove value.
618
+ * @param {*} obj Object to remove.
619
+ * @return {boolean} True if an element was removed.
620
+ */
621
+ goog.array.remove = function(arr, obj) {
622
+ var i = goog.array.indexOf(arr, obj);
623
+ var rv;
624
+ if ((rv = i >= 0)) {
625
+ goog.array.removeAt(arr, i);
626
+ }
627
+ return rv;
628
+ };
629
+
630
+
631
+ /**
632
+ * Removes from an array the element at index i
633
+ * @param {goog.array.ArrayLike} arr Array or array like object from which to
634
+ * remove value.
635
+ * @param {number} i The index to remove.
636
+ * @return {boolean} True if an element was removed.
637
+ */
638
+ goog.array.removeAt = function(arr, i) {
639
+ goog.asserts.assert(arr.length != null);
640
+
641
+ // use generic form of splice
642
+ // splice returns the removed items and if successful the length of that
643
+ // will be 1
644
+ return goog.array.ARRAY_PROTOTYPE_.splice.call(arr, i, 1).length == 1;
645
+ };
646
+
647
+
648
+ /**
649
+ * Removes the first value that satisfies the given condition.
650
+ * @param {goog.array.ArrayLike} arr Array from which to remove value.
651
+ * @param {Function} f The function to call for every element. This function
652
+ * takes 3 arguments (the element, the index and the array) and should
653
+ * return a boolean.
654
+ * @param {Object=} opt_obj An optional "this" context for the function.
655
+ * @return {boolean} True if an element was removed.
656
+ */
657
+ goog.array.removeIf = function(arr, f, opt_obj) {
658
+ var i = goog.array.findIndex(arr, f, opt_obj);
659
+ if (i >= 0) {
660
+ goog.array.removeAt(arr, i);
661
+ return true;
662
+ }
663
+ return false;
664
+ };
665
+
666
+
667
+ /**
668
+ * Returns a new array that is the result of joining the arguments. If arrays
669
+ * are passed then their items are added, however, if non-arrays are passed they
670
+ * will be added to the return array as is.
671
+ *
672
+ * Note that ArrayLike objects will be added as is, rather than having their
673
+ * items added.
674
+ *
675
+ * goog.array.concat([1, 2], [3, 4]) -> [1, 2, 3, 4]
676
+ * goog.array.concat(0, [1, 2]) -> [0, 1, 2]
677
+ * goog.array.concat([1, 2], null) -> [1, 2, null]
678
+ *
679
+ * There is bug in all current versions of IE (6, 7 and 8) where arrays created
680
+ * in an iframe become corrupted soon (not immediately) after the iframe is
681
+ * destroyed. This is common if loading data via goog.net.IframeIo, for example.
682
+ * This corruption only affects the concat method which will start throwing
683
+ * Catastrophic Errors (#-2147418113).
684
+ *
685
+ * See http://endoflow.com/scratch/corrupted-arrays.html for a test case.
686
+ *
687
+ * Internally goog.array should use this, so that all methods will continue to
688
+ * work on these broken array objects.
689
+ *
690
+ * @param {...*} var_args Items to concatenate. Arrays will have each item
691
+ * added, while primitives and objects will be added as is.
692
+ * @return {!Array} The new resultant array.
693
+ */
694
+ goog.array.concat = function(var_args) {
695
+ return goog.array.ARRAY_PROTOTYPE_.concat.apply(
696
+ goog.array.ARRAY_PROTOTYPE_, arguments);
697
+ };
698
+
699
+
700
+ /**
701
+ * Does a shallow copy of an array.
702
+ * @param {goog.array.ArrayLike} arr Array or array-like object to clone.
703
+ * @return {!Array} Clone of the input array.
704
+ */
705
+ goog.array.clone = function(arr) {
706
+ if (goog.isArray(arr)) {
707
+ return goog.array.concat(/** @type {!Array} */ (arr));
708
+ } else { // array like
709
+ // Concat does not work with non arrays.
710
+ var rv = [];
711
+ for (var i = 0, len = arr.length; i < len; i++) {
712
+ rv[i] = arr[i];
713
+ }
714
+ return rv;
715
+ }
716
+ };
717
+
718
+
719
+ /**
720
+ * Converts an object to an array.
721
+ * @param {goog.array.ArrayLike} object The object to convert to an array.
722
+ * @return {!Array} The object converted into an array. If object has a
723
+ * length property, every property indexed with a non-negative number
724
+ * less than length will be included in the result. If object does not
725
+ * have a length property, an empty array will be returned.
726
+ */
727
+ goog.array.toArray = function(object) {
728
+ if (goog.isArray(object)) {
729
+ // This fixes the JS compiler warning and forces the Object to an Array type
730
+ return goog.array.concat(/** @type {!Array} */ (object));
731
+ }
732
+ // Clone what we hope to be an array-like object to an array.
733
+ // We could check isArrayLike() first, but no check we perform would be as
734
+ // reliable as simply making the call.
735
+ return goog.array.clone(/** @type {Array} */ (object));
736
+ };
737
+
738
+
739
+ /**
740
+ * Extends an array with another array, element, or "array like" object.
741
+ * This function operates 'in-place', it does not create a new Array.
742
+ *
743
+ * Example:
744
+ * var a = [];
745
+ * goog.array.extend(a, [0, 1]);
746
+ * a; // [0, 1]
747
+ * goog.array.extend(a, 2);
748
+ * a; // [0, 1, 2]
749
+ *
750
+ * @param {Array} arr1 The array to modify.
751
+ * @param {...*} var_args The elements or arrays of elements to add to arr1.
752
+ */
753
+ goog.array.extend = function(arr1, var_args) {
754
+ for (var i = 1; i < arguments.length; i++) {
755
+ var arr2 = arguments[i];
756
+ // If we have an Array or an Arguments object we can just call push
757
+ // directly.
758
+ var isArrayLike;
759
+ if (goog.isArray(arr2) ||
760
+ // Detect Arguments. ES5 says that the [[Class]] of an Arguments object
761
+ // is "Arguments" but only V8 and JSC/Safari gets this right. We instead
762
+ // detect Arguments by checking for array like and presence of "callee".
763
+ (isArrayLike = goog.isArrayLike(arr2)) &&
764
+ // The getter for callee throws an exception in strict mode
765
+ // according to section 10.6 in ES5 so check for presence instead.
766
+ arr2.hasOwnProperty('callee')) {
767
+ arr1.push.apply(arr1, arr2);
768
+
769
+ } else if (isArrayLike) {
770
+ // Otherwise loop over arr2 to prevent copying the object.
771
+ var len1 = arr1.length;
772
+ var len2 = arr2.length;
773
+ for (var j = 0; j < len2; j++) {
774
+ arr1[len1 + j] = arr2[j];
775
+ }
776
+ } else {
777
+ arr1.push(arr2);
778
+ }
779
+ }
780
+ };
781
+
782
+
783
+ /**
784
+ * Adds or removes elements from an array. This is a generic version of Array
785
+ * splice. This means that it might work on other objects similar to arrays,
786
+ * such as the arguments object.
787
+ *
788
+ * @param {goog.array.ArrayLike} arr The array to modify.
789
+ * @param {number|undefined} index The index at which to start changing the
790
+ * array. If not defined, treated as 0.
791
+ * @param {number} howMany How many elements to remove (0 means no removal. A
792
+ * value below 0 is treated as zero and so is any other non number. Numbers
793
+ * are floored).
794
+ * @param {...*} var_args Optional, additional elements to insert into the
795
+ * array.
796
+ * @return {!Array} the removed elements.
797
+ */
798
+ goog.array.splice = function(arr, index, howMany, var_args) {
799
+ goog.asserts.assert(arr.length != null);
800
+
801
+ return goog.array.ARRAY_PROTOTYPE_.splice.apply(
802
+ arr, goog.array.slice(arguments, 1));
803
+ };
804
+
805
+
806
+ /**
807
+ * Returns a new array from a segment of an array. This is a generic version of
808
+ * Array slice. This means that it might work on other objects similar to
809
+ * arrays, such as the arguments object.
810
+ *
811
+ * @param {goog.array.ArrayLike} arr The array from which to copy a segment.
812
+ * @param {number} start The index of the first element to copy.
813
+ * @param {number=} opt_end The index after the last element to copy.
814
+ * @return {!Array} A new array containing the specified segment of the original
815
+ * array.
816
+ */
817
+ goog.array.slice = function(arr, start, opt_end) {
818
+ goog.asserts.assert(arr.length != null);
819
+
820
+ // passing 1 arg to slice is not the same as passing 2 where the second is
821
+ // null or undefined (in that case the second argument is treated as 0).
822
+ // we could use slice on the arguments object and then use apply instead of
823
+ // testing the length
824
+ if (arguments.length <= 2) {
825
+ return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start);
826
+ } else {
827
+ return goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start, opt_end);
828
+ }
829
+ };
830
+
831
+
832
+ /**
833
+ * Removes all duplicates from an array (retaining only the first
834
+ * occurrence of each array element). This function modifies the
835
+ * array in place and doesn't change the order of the non-duplicate items.
836
+ *
837
+ * For objects, duplicates are identified as having the same unique ID as
838
+ * defined by {@link goog.getUid}.
839
+ *
840
+ * Runtime: N,
841
+ * Worstcase space: 2N (no dupes)
842
+ *
843
+ * @param {goog.array.ArrayLike} arr The array from which to remove duplicates.
844
+ * @param {Array=} opt_rv An optional array in which to return the results,
845
+ * instead of performing the removal inplace. If specified, the original
846
+ * array will remain unchanged.
847
+ */
848
+ goog.array.removeDuplicates = function(arr, opt_rv) {
849
+ var returnArray = opt_rv || arr;
850
+
851
+ var seen = {}, cursorInsert = 0, cursorRead = 0;
852
+ while (cursorRead < arr.length) {
853
+ var current = arr[cursorRead++];
854
+
855
+ // Prefix each type with a single character representing the type to
856
+ // prevent conflicting keys (e.g. true and 'true').
857
+ var key = goog.isObject(current) ?
858
+ 'o' + goog.getUid(current) :
859
+ (typeof current).charAt(0) + current;
860
+
861
+ if (!Object.prototype.hasOwnProperty.call(seen, key)) {
862
+ seen[key] = true;
863
+ returnArray[cursorInsert++] = current;
864
+ }
865
+ }
866
+ returnArray.length = cursorInsert;
867
+ };
868
+
869
+
870
+ /**
871
+ * Searches the specified array for the specified target using the binary
872
+ * search algorithm. If no opt_compareFn is specified, elements are compared
873
+ * using <code>goog.array.defaultCompare</code>, which compares the elements
874
+ * using the built in < and > operators. This will produce the expected
875
+ * behavior for homogeneous arrays of String(s) and Number(s). The array
876
+ * specified <b>must</b> be sorted in ascending order (as defined by the
877
+ * comparison function). If the array is not sorted, results are undefined.
878
+ * If the array contains multiple instances of the specified target value, any
879
+ * of these instances may be found.
880
+ *
881
+ * Runtime: O(log n)
882
+ *
883
+ * @param {goog.array.ArrayLike} arr The array to be searched.
884
+ * @param {*} target The sought value.
885
+ * @param {Function=} opt_compareFn Optional comparison function by which the
886
+ * array is ordered. Should take 2 arguments to compare, and return a
887
+ * negative number, zero, or a positive number depending on whether the
888
+ * first argument is less than, equal to, or greater than the second.
889
+ * @return {number} Lowest index of the target value if found, otherwise
890
+ * (-(insertion point) - 1). The insertion point is where the value should
891
+ * be inserted into arr to preserve the sorted property. Return value >= 0
892
+ * iff target is found.
893
+ */
894
+ goog.array.binarySearch = function(arr, target, opt_compareFn) {
895
+ return goog.array.binarySearch_(arr,
896
+ opt_compareFn || goog.array.defaultCompare, false /* isEvaluator */,
897
+ target);
898
+ };
899
+
900
+
901
+ /**
902
+ * Selects an index in the specified array using the binary search algorithm.
903
+ * The evaluator receives an element and determines whether the desired index
904
+ * is before, at, or after it. The evaluator must be consistent (formally,
905
+ * goog.array.map(goog.array.map(arr, evaluator, opt_obj), goog.math.sign)
906
+ * must be monotonically non-increasing).
907
+ *
908
+ * Runtime: O(log n)
909
+ *
910
+ * @param {goog.array.ArrayLike} arr The array to be searched.
911
+ * @param {Function} evaluator Evaluator function that receives 3 arguments
912
+ * (the element, the index and the array). Should return a negative number,
913
+ * zero, or a positive number depending on whether the desired index is
914
+ * before, at, or after the element passed to it.
915
+ * @param {Object=} opt_obj The object to be used as the value of 'this'
916
+ * within evaluator.
917
+ * @return {number} Index of the leftmost element matched by the evaluator, if
918
+ * such exists; otherwise (-(insertion point) - 1). The insertion point is
919
+ * the index of the first element for which the evaluator returns negative,
920
+ * or arr.length if no such element exists. The return value is non-negative
921
+ * iff a match is found.
922
+ */
923
+ goog.array.binarySelect = function(arr, evaluator, opt_obj) {
924
+ return goog.array.binarySearch_(arr, evaluator, true /* isEvaluator */,
925
+ undefined /* opt_target */, opt_obj);
926
+ };
927
+
928
+
929
+ /**
930
+ * Implementation of a binary search algorithm which knows how to use both
931
+ * comparison functions and evaluators. If an evaluator is provided, will call
932
+ * the evaluator with the given optional data object, conforming to the
933
+ * interface defined in binarySelect. Otherwise, if a comparison function is
934
+ * provided, will call the comparison function against the given data object.
935
+ *
936
+ * This implementation purposefully does not use goog.bind or goog.partial for
937
+ * performance reasons.
938
+ *
939
+ * Runtime: O(log n)
940
+ *
941
+ * @param {goog.array.ArrayLike} arr The array to be searched.
942
+ * @param {Function} compareFn Either an evaluator or a comparison function,
943
+ * as defined by binarySearch and binarySelect above.
944
+ * @param {boolean} isEvaluator Whether the function is an evaluator or a
945
+ * comparison function.
946
+ * @param {*=} opt_target If the function is a comparison function, then this is
947
+ * the target to binary search for.
948
+ * @param {Object=} opt_selfObj If the function is an evaluator, this is an
949
+ * optional this object for the evaluator.
950
+ * @return {number} Lowest index of the target value if found, otherwise
951
+ * (-(insertion point) - 1). The insertion point is where the value should
952
+ * be inserted into arr to preserve the sorted property. Return value >= 0
953
+ * iff target is found.
954
+ * @private
955
+ */
956
+ goog.array.binarySearch_ = function(arr, compareFn, isEvaluator, opt_target,
957
+ opt_selfObj) {
958
+ var left = 0; // inclusive
959
+ var right = arr.length; // exclusive
960
+ var found;
961
+ while (left < right) {
962
+ var middle = (left + right) >> 1;
963
+ var compareResult;
964
+ if (isEvaluator) {
965
+ compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);
966
+ } else {
967
+ compareResult = compareFn(opt_target, arr[middle]);
968
+ }
969
+ if (compareResult > 0) {
970
+ left = middle + 1;
971
+ } else {
972
+ right = middle;
973
+ // We are looking for the lowest index so we can't return immediately.
974
+ found = !compareResult;
975
+ }
976
+ }
977
+ // left is the index if found, or the insertion point otherwise.
978
+ // ~left is a shorthand for -left - 1.
979
+ return found ? left : ~left;
980
+ };
981
+
982
+
983
+ /**
984
+ * Sorts the specified array into ascending order. If no opt_compareFn is
985
+ * specified, elements are compared using
986
+ * <code>goog.array.defaultCompare</code>, which compares the elements using
987
+ * the built in < and > operators. This will produce the expected behavior
988
+ * for homogeneous arrays of String(s) and Number(s), unlike the native sort,
989
+ * but will give unpredictable results for heterogenous lists of strings and
990
+ * numbers with different numbers of digits.
991
+ *
992
+ * This sort is not guaranteed to be stable.
993
+ *
994
+ * Runtime: Same as <code>Array.prototype.sort</code>
995
+ *
996
+ * @param {Array} arr The array to be sorted.
997
+ * @param {Function=} opt_compareFn Optional comparison function by which the
998
+ * array is to be ordered. Should take 2 arguments to compare, and return a
999
+ * negative number, zero, or a positive number depending on whether the
1000
+ * first argument is less than, equal to, or greater than the second.
1001
+ */
1002
+ goog.array.sort = function(arr, opt_compareFn) {
1003
+ // TODO(arv): Update type annotation since null is not accepted.
1004
+ goog.asserts.assert(arr.length != null);
1005
+
1006
+ goog.array.ARRAY_PROTOTYPE_.sort.call(
1007
+ arr, opt_compareFn || goog.array.defaultCompare);
1008
+ };
1009
+
1010
+
1011
+ /**
1012
+ * Sorts the specified array into ascending order in a stable way. If no
1013
+ * opt_compareFn is specified, elements are compared using
1014
+ * <code>goog.array.defaultCompare</code>, which compares the elements using
1015
+ * the built in < and > operators. This will produce the expected behavior
1016
+ * for homogeneous arrays of String(s) and Number(s).
1017
+ *
1018
+ * Runtime: Same as <code>Array.prototype.sort</code>, plus an additional
1019
+ * O(n) overhead of copying the array twice.
1020
+ *
1021
+ * @param {Array} arr The array to be sorted.
1022
+ * @param {function(*, *): number=} opt_compareFn Optional comparison function
1023
+ * by which the array is to be ordered. Should take 2 arguments to compare,
1024
+ * and return a negative number, zero, or a positive number depending on
1025
+ * whether the first argument is less than, equal to, or greater than the
1026
+ * second.
1027
+ */
1028
+ goog.array.stableSort = function(arr, opt_compareFn) {
1029
+ for (var i = 0; i < arr.length; i++) {
1030
+ arr[i] = {index: i, value: arr[i]};
1031
+ }
1032
+ var valueCompareFn = opt_compareFn || goog.array.defaultCompare;
1033
+ function stableCompareFn(obj1, obj2) {
1034
+ return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;
1035
+ };
1036
+ goog.array.sort(arr, stableCompareFn);
1037
+ for (var i = 0; i < arr.length; i++) {
1038
+ arr[i] = arr[i].value;
1039
+ }
1040
+ };
1041
+
1042
+
1043
+ /**
1044
+ * Sorts an array of objects by the specified object key and compare
1045
+ * function. If no compare function is provided, the key values are
1046
+ * compared in ascending order using <code>goog.array.defaultCompare</code>.
1047
+ * This won't work for keys that get renamed by the compiler. So use
1048
+ * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.
1049
+ * @param {Array.<Object>} arr An array of objects to sort.
1050
+ * @param {string} key The object key to sort by.
1051
+ * @param {Function=} opt_compareFn The function to use to compare key
1052
+ * values.
1053
+ */
1054
+ goog.array.sortObjectsByKey = function(arr, key, opt_compareFn) {
1055
+ var compare = opt_compareFn || goog.array.defaultCompare;
1056
+ goog.array.sort(arr, function(a, b) {
1057
+ return compare(a[key], b[key]);
1058
+ });
1059
+ };
1060
+
1061
+
1062
+ /**
1063
+ * Tells if the array is sorted.
1064
+ * @param {!Array} arr The array.
1065
+ * @param {Function=} opt_compareFn Function to compare the array elements.
1066
+ * Should take 2 arguments to compare, and return a negative number, zero,
1067
+ * or a positive number depending on whether the first argument is less
1068
+ * than, equal to, or greater than the second.
1069
+ * @param {boolean=} opt_strict If true no equal elements are allowed.
1070
+ * @return {boolean} Whether the array is sorted.
1071
+ */
1072
+ goog.array.isSorted = function(arr, opt_compareFn, opt_strict) {
1073
+ var compare = opt_compareFn || goog.array.defaultCompare;
1074
+ for (var i = 1; i < arr.length; i++) {
1075
+ var compareResult = compare(arr[i - 1], arr[i]);
1076
+ if (compareResult > 0 || compareResult == 0 && opt_strict) {
1077
+ return false;
1078
+ }
1079
+ }
1080
+ return true;
1081
+ };
1082
+
1083
+
1084
+ /**
1085
+ * Compares two arrays for equality. Two arrays are considered equal if they
1086
+ * have the same length and their corresponding elements are equal according to
1087
+ * the comparison function.
1088
+ *
1089
+ * @param {goog.array.ArrayLike} arr1 The first array to compare.
1090
+ * @param {goog.array.ArrayLike} arr2 The second array to compare.
1091
+ * @param {Function=} opt_equalsFn Optional comparison function.
1092
+ * Should take 2 arguments to compare, and return true if the arguments
1093
+ * are equal. Defaults to {@link goog.array.defaultCompareEquality} which
1094
+ * compares the elements using the built-in '===' operator.
1095
+ * @return {boolean} Whether the two arrays are equal.
1096
+ */
1097
+ goog.array.equals = function(arr1, arr2, opt_equalsFn) {
1098
+ if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||
1099
+ arr1.length != arr2.length) {
1100
+ return false;
1101
+ }
1102
+ var l = arr1.length;
1103
+ var equalsFn = opt_equalsFn || goog.array.defaultCompareEquality;
1104
+ for (var i = 0; i < l; i++) {
1105
+ if (!equalsFn(arr1[i], arr2[i])) {
1106
+ return false;
1107
+ }
1108
+ }
1109
+ return true;
1110
+ };
1111
+
1112
+
1113
+ /**
1114
+ * @deprecated Use {@link goog.array.equals}.
1115
+ * @param {goog.array.ArrayLike} arr1 See {@link goog.array.equals}.
1116
+ * @param {goog.array.ArrayLike} arr2 See {@link goog.array.equals}.
1117
+ * @param {Function=} opt_equalsFn See {@link goog.array.equals}.
1118
+ * @return {boolean} See {@link goog.array.equals}.
1119
+ */
1120
+ goog.array.compare = function(arr1, arr2, opt_equalsFn) {
1121
+ return goog.array.equals(arr1, arr2, opt_equalsFn);
1122
+ };
1123
+
1124
+
1125
+ /**
1126
+ * 3-way array compare function.
1127
+ * @param {!goog.array.ArrayLike} arr1 The first array to compare.
1128
+ * @param {!goog.array.ArrayLike} arr2 The second array to compare.
1129
+ * @param {(function(*, *): number)=} opt_compareFn Optional comparison function
1130
+ * by which the array is to be ordered. Should take 2 arguments to compare,
1131
+ * and return a negative number, zero, or a positive number depending on
1132
+ * whether the first argument is less than, equal to, or greater than the
1133
+ * second.
1134
+ * @return {number} Negative number, zero, or a positive number depending on
1135
+ * whether the first argument is less than, equal to, or greater than the
1136
+ * second.
1137
+ */
1138
+ goog.array.compare3 = function(arr1, arr2, opt_compareFn) {
1139
+ var compare = opt_compareFn || goog.array.defaultCompare;
1140
+ var l = Math.min(arr1.length, arr2.length);
1141
+ for (var i = 0; i < l; i++) {
1142
+ var result = compare(arr1[i], arr2[i]);
1143
+ if (result != 0) {
1144
+ return result;
1145
+ }
1146
+ }
1147
+ return goog.array.defaultCompare(arr1.length, arr2.length);
1148
+ };
1149
+
1150
+
1151
+ /**
1152
+ * Compares its two arguments for order, using the built in < and >
1153
+ * operators.
1154
+ * @param {*} a The first object to be compared.
1155
+ * @param {*} b The second object to be compared.
1156
+ * @return {number} A negative number, zero, or a positive number as the first
1157
+ * argument is less than, equal to, or greater than the second.
1158
+ */
1159
+ goog.array.defaultCompare = function(a, b) {
1160
+ return a > b ? 1 : a < b ? -1 : 0;
1161
+ };
1162
+
1163
+
1164
+ /**
1165
+ * Compares its two arguments for equality, using the built in === operator.
1166
+ * @param {*} a The first object to compare.
1167
+ * @param {*} b The second object to compare.
1168
+ * @return {boolean} True if the two arguments are equal, false otherwise.
1169
+ */
1170
+ goog.array.defaultCompareEquality = function(a, b) {
1171
+ return a === b;
1172
+ };
1173
+
1174
+
1175
+ /**
1176
+ * Inserts a value into a sorted array. The array is not modified if the
1177
+ * value is already present.
1178
+ * @param {Array} array The array to modify.
1179
+ * @param {*} value The object to insert.
1180
+ * @param {Function=} opt_compareFn Optional comparison function by which the
1181
+ * array is ordered. Should take 2 arguments to compare, and return a
1182
+ * negative number, zero, or a positive number depending on whether the
1183
+ * first argument is less than, equal to, or greater than the second.
1184
+ * @return {boolean} True if an element was inserted.
1185
+ */
1186
+ goog.array.binaryInsert = function(array, value, opt_compareFn) {
1187
+ var index = goog.array.binarySearch(array, value, opt_compareFn);
1188
+ if (index < 0) {
1189
+ goog.array.insertAt(array, value, -(index + 1));
1190
+ return true;
1191
+ }
1192
+ return false;
1193
+ };
1194
+
1195
+
1196
+ /**
1197
+ * Removes a value from a sorted array.
1198
+ * @param {Array} array The array to modify.
1199
+ * @param {*} value The object to remove.
1200
+ * @param {Function=} opt_compareFn Optional comparison function by which the
1201
+ * array is ordered. Should take 2 arguments to compare, and return a
1202
+ * negative number, zero, or a positive number depending on whether the
1203
+ * first argument is less than, equal to, or greater than the second.
1204
+ * @return {boolean} True if an element was removed.
1205
+ */
1206
+ goog.array.binaryRemove = function(array, value, opt_compareFn) {
1207
+ var index = goog.array.binarySearch(array, value, opt_compareFn);
1208
+ return (index >= 0) ? goog.array.removeAt(array, index) : false;
1209
+ };
1210
+
1211
+
1212
+ /**
1213
+ * Splits an array into disjoint buckets according to a splitting function.
1214
+ * @param {Array} array The array.
1215
+ * @param {Function} sorter Function to call for every element. This
1216
+ * takes 3 arguments (the element, the index and the array) and must
1217
+ * return a valid object key (a string, number, etc), or undefined, if
1218
+ * that object should not be placed in a bucket.
1219
+ * @return {!Object} An object, with keys being all of the unique return values
1220
+ * of sorter, and values being arrays containing the items for
1221
+ * which the splitter returned that key.
1222
+ */
1223
+ goog.array.bucket = function(array, sorter) {
1224
+ var buckets = {};
1225
+
1226
+ for (var i = 0; i < array.length; i++) {
1227
+ var value = array[i];
1228
+ var key = sorter(value, i, array);
1229
+ if (goog.isDef(key)) {
1230
+ // Push the value to the right bucket, creating it if necessary.
1231
+ var bucket = buckets[key] || (buckets[key] = []);
1232
+ bucket.push(value);
1233
+ }
1234
+ }
1235
+
1236
+ return buckets;
1237
+ };
1238
+
1239
+
1240
+ /**
1241
+ * Returns an array consisting of the given value repeated N times.
1242
+ *
1243
+ * @param {*} value The value to repeat.
1244
+ * @param {number} n The repeat count.
1245
+ * @return {!Array.<*>} An array with the repeated value.
1246
+ */
1247
+ goog.array.repeat = function(value, n) {
1248
+ var array = [];
1249
+ for (var i = 0; i < n; i++) {
1250
+ array[i] = value;
1251
+ }
1252
+ return array;
1253
+ };
1254
+
1255
+
1256
+ /**
1257
+ * Returns an array consisting of every argument with all arrays
1258
+ * expanded in-place recursively.
1259
+ *
1260
+ * @param {...*} var_args The values to flatten.
1261
+ * @return {!Array.<*>} An array containing the flattened values.
1262
+ */
1263
+ goog.array.flatten = function(var_args) {
1264
+ var result = [];
1265
+ for (var i = 0; i < arguments.length; i++) {
1266
+ var element = arguments[i];
1267
+ if (goog.isArray(element)) {
1268
+ result.push.apply(result, goog.array.flatten.apply(null, element));
1269
+ } else {
1270
+ result.push(element);
1271
+ }
1272
+ }
1273
+ return result;
1274
+ };
1275
+
1276
+
1277
+ /**
1278
+ * Rotates an array in-place. After calling this method, the element at
1279
+ * index i will be the element previously at index (i - n) %
1280
+ * array.length, for all values of i between 0 and array.length - 1,
1281
+ * inclusive.
1282
+ *
1283
+ * For example, suppose list comprises [t, a, n, k, s]. After invoking
1284
+ * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].
1285
+ *
1286
+ * @param {!Array.<*>} array The array to rotate.
1287
+ * @param {number} n The amount to rotate.
1288
+ * @return {!Array.<*>} The array.
1289
+ */
1290
+ goog.array.rotate = function(array, n) {
1291
+ goog.asserts.assert(array.length != null);
1292
+
1293
+ if (array.length) {
1294
+ n %= array.length;
1295
+ if (n > 0) {
1296
+ goog.array.ARRAY_PROTOTYPE_.unshift.apply(array, array.splice(-n, n));
1297
+ } else if (n < 0) {
1298
+ goog.array.ARRAY_PROTOTYPE_.push.apply(array, array.splice(0, -n));
1299
+ }
1300
+ }
1301
+ return array;
1302
+ };
1303
+
1304
+
1305
+ /**
1306
+ * Creates a new array for which the element at position i is an array of the
1307
+ * ith element of the provided arrays. The returned array will only be as long
1308
+ * as the shortest array provided; additional values are ignored. For example,
1309
+ * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]].
1310
+ *
1311
+ * This is similar to the zip() function in Python. See {@link
1312
+ * http://docs.python.org/library/functions.html#zip}
1313
+ *
1314
+ * @param {...!goog.array.ArrayLike} var_args Arrays to be combined.
1315
+ * @return {!Array.<!Array>} A new array of arrays created from provided arrays.
1316
+ */
1317
+ goog.array.zip = function(var_args) {
1318
+ if (!arguments.length) {
1319
+ return [];
1320
+ }
1321
+ var result = [];
1322
+ for (var i = 0; true; i++) {
1323
+ var value = [];
1324
+ for (var j = 0; j < arguments.length; j++) {
1325
+ var arr = arguments[j];
1326
+ // If i is larger than the array length, this is the shortest array.
1327
+ if (i >= arr.length) {
1328
+ return result;
1329
+ }
1330
+ value.push(arr[i]);
1331
+ }
1332
+ result.push(value);
1333
+ }
1334
+ };
1335
+
1336
+
1337
+ /**
1338
+ * Shuffles the values in the specified array using the Fisher-Yates in-place
1339
+ * shuffle (also known as the Knuth Shuffle). By default, calls Math.random()
1340
+ * and so resets the state of that random number generator. Similarly, may reset
1341
+ * the state of the any other specified random number generator.
1342
+ *
1343
+ * Runtime: O(n)
1344
+ *
1345
+ * @param {!Array} arr The array to be shuffled.
1346
+ * @param {Function=} opt_randFn Optional random function to use for shuffling.
1347
+ * Takes no arguments, and returns a random number on the interval [0, 1).
1348
+ * Defaults to Math.random() using JavaScript's built-in Math library.
1349
+ */
1350
+ goog.array.shuffle = function(arr, opt_randFn) {
1351
+ var randFn = opt_randFn || Math.random;
1352
+
1353
+ for (var i = arr.length - 1; i > 0; i--) {
1354
+ // Choose a random array index in [0, i] (inclusive with i).
1355
+ var j = Math.floor(randFn() * (i + 1));
1356
+
1357
+ var tmp = arr[i];
1358
+ arr[i] = arr[j];
1359
+ arr[j] = tmp;
1360
+ }
1361
+ };
1362
+ ;
1363
+ FI"asset_paths;
1364
+ F["f/Volumes/Development/dev-web/yellow-brick-road/vendor/closure-library/closure/goog/array/array.jsI"dependency_paths;
1365
+ F[{I" path;
1366
+ F"f/Volumes/Development/dev-web/yellow-brick-road/vendor/closure-library/closure/goog/array/array.jsI"
1367
+ mtime;
1368
+ FIu: Time
1369
+ T: offsetiI"hexdigest;
1370
+ F"%fc445b29e990f038942b0cffd6d63af2I"
1371
+ F"%46dde6621c301f4928e3b34efee9e3b5