├── .github └── pull_request_template.md ├── .gitignore ├── Gruntfile.js ├── LICENSE ├── README.md ├── VERSION_PREFIX ├── bench └── bench.js ├── bin ├── build_dev_browser ├── build_dev_browser_amd ├── build_dev_node ├── build_jar ├── build_release_browser ├── build_release_browser_amd ├── build_release_node ├── closure_deps_graph.clj ├── deps ├── docs ├── make_deps_js ├── prelude └── test ├── build ├── package_local ├── release └── revision ├── doctheme ├── assets │ ├── css │ │ ├── cognitect.jpg │ │ ├── external-small.png │ │ ├── logo.png │ │ └── main.css │ ├── js │ │ ├── tabs.js │ │ └── yui-prettify.js │ └── vendor │ │ └── prettify │ │ ├── CHANGES.html │ │ ├── COPYING │ │ ├── README.html │ │ ├── prettify-min.css │ │ └── prettify-min.js ├── layouts │ └── main.handlebars ├── partials │ ├── attrs.handlebars │ ├── classes.handlebars │ ├── events.handlebars │ ├── files.handlebars │ ├── index.handlebars │ ├── method.handlebars │ ├── module.handlebars │ ├── props.handlebars │ └── sidebar.handlebars └── theme.json ├── package.json ├── pom.xml ├── resources ├── amd_externs.js ├── externs.js ├── node_externs.js └── prelude.txt ├── src └── com │ └── cognitect │ ├── transducers.js │ └── transducers_amd.js ├── test └── tests.js ├── transducers-js.iml └── yuidoc.json /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Hi! Thanks for your interest in contributing to this project. 2 | 3 | Because transducers-js may be incorporated into products or client 4 | projects, we prefer to do development internally and do not accept 5 | pull requests or patches. Issues can be filed using GitHub issues. 6 | 7 | - Contributing : https://github.com/cognitect-labs/transducers-js#contributing 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | docs 2 | npm-debug.log 3 | deps 4 | node_modules 5 | target/* 6 | .idea -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /*global module:false*/ 2 | module.exports = function(grunt) { 3 | 4 | // Project configuration. 5 | grunt.initConfig({ 6 | // Metadata. 7 | pkg: grunt.file.readJSON('package.json'), 8 | banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + 9 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' + 10 | '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + 11 | '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + 12 | ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n', 13 | // Task configuration. 14 | concat: { 15 | options: { 16 | banner: '<%= banner %>', 17 | stripBanners: true 18 | }, 19 | dist: { 20 | src: ['lib/<%= pkg.name %>.js'], 21 | dest: 'dist/<%= pkg.name %>.js' 22 | } 23 | }, 24 | jshint: { 25 | options: { 26 | curly: true, 27 | eqeqeq: true, 28 | immed: true, 29 | latedef: true, 30 | newcap: true, 31 | noarg: true, 32 | sub: true, 33 | undef: true, 34 | unused: true, 35 | boss: true, 36 | eqnull: true, 37 | globals: {} 38 | }, 39 | gruntfile: { 40 | src: 'Gruntfile.js' 41 | }, 42 | lib_test: { 43 | src: ['lib/**/*.js', 'test/**/*.js'] 44 | } 45 | }, 46 | nodeunit: { 47 | files: ['test/**/*.js'] 48 | }, 49 | watch: { 50 | gruntfile: { 51 | files: '<%= jshint.gruntfile.src %>', 52 | tasks: ['jshint:gruntfile'] 53 | }, 54 | lib_test: { 55 | files: '<%= jshint.lib_test.src %>', 56 | tasks: ['jshint:lib_test', 'nodeunit'] 57 | } 58 | } 59 | }); 60 | 61 | // These plugins provide necessary tasks. 62 | grunt.loadNpmTasks('grunt-contrib-concat'); 63 | grunt.loadNpmTasks('grunt-contrib-nodeunit'); 64 | grunt.loadNpmTasks('grunt-contrib-jshint'); 65 | grunt.loadNpmTasks('grunt-contrib-watch'); 66 | 67 | // Default task. 68 | grunt.registerTask('default', ['jshint', 'nodeunit', 'concat', 'uglify']); 69 | 70 | }; 71 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This library is no longer maintained, feel free to fork and update as per the license 2 | 3 | # transducers-js 4 | 5 | A high performance 6 | [Transducers](http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming) 7 | implementation for JavaScript. 8 | 9 | Transducers are composable algorithmic transformations. They are 10 | independent from the context of their input and output sources and 11 | specify only the essence of the transformation in terms of an 12 | individual element. Because transducers are decoupled from input or 13 | output sources, they can be used in many different processes - 14 | collections, streams, channels, observables, etc. Transducers compose 15 | directly, without awareness of input or creation of intermediate 16 | aggregates. 17 | 18 | For further details about Transducers see the following resources: 19 | * ["Transducers are coming" announce blog post](http://blog.cognitect.com/blog/2014/8/6/transducers-are-coming) 20 | * [Rich Hickey's Transducers StrangeLoop presentation](https://www.youtube.com/watch?v=6mTbuzafcII) 21 | * [API Docs](http://cognitect-labs.github.io/transducers-js/classes/transducers.html) 22 | 23 | transducers-js is brought to you by [Cognitect Labs](http://cognitect-labs.github.io/). 24 | 25 | ## Releases and Dependency Information 26 | 27 | * Latest release: 0.4.180 28 | 29 | ### JavaScript 30 | 31 | You can include either the [release](http://cdn.cognitect.com/transducers/transducers-0.4.180-min.js) (2K gzipped) or [development](http://cdn.cognitect.com/transducers/transducers-0.4.180.js) build of transducers-js on your webpage. We also provide [Require.js](http://requirejs.org) compatible [release](http://cdn.cognitect.com/transducers/transducers-0.4.180-amd-min.js) and [dev](http://cdn.cognitect.com/transducers/transducers-0.4.180-amd.js) builds. 32 | 33 | ### Node.js 34 | 35 | transducers-js is released to [npm](https://www.npmjs.org). Add transducers-js to your `package.json` dependencies: 36 | 37 | ```javascript 38 | {... 39 | "dependencies": { 40 | "transducers-js": "0.4.180" 41 | } 42 | ...} 43 | ``` 44 | 45 | ### Bower 46 | 47 | You can also include transducers-js in your `bower.json` dependencies: 48 | 49 | ```javascript 50 | {... 51 | "dependencies": { 52 | "transducers-js": "0.4.180" 53 | } 54 | ...} 55 | ``` 56 | 57 | ## Usage 58 | 59 | ### Requiring 60 | 61 | To import the library under Node.js you can just use `require`: 62 | 63 | ```js 64 | var t = require("transducers-js"); 65 | ``` 66 | 67 | The browser release of the library simply exports a top level 68 | `transducers` object: 69 | 70 | ```js 71 | var t = transducers; 72 | ``` 73 | 74 | ### Basic Usage 75 | 76 | With <=ES5: 77 | 78 | ```js 79 | var map = t.map, 80 | filter = t.filter, 81 | comp = t.comp, 82 | into = t.into; 83 | 84 | var inc = function(n) { return n + 1; }; 85 | var isEven = function(n) { return n % 2 == 0; }; 86 | var xf = comp(map(inc), filter(isEven)); 87 | 88 | console.log(into([], xf, [0,1,2,3,4])); // [2,4] 89 | ``` 90 | 91 | With ES6: 92 | 93 | ```js 94 | let {map, filter, comp, into} = t; 95 | 96 | let inc = (n) => n + 1; 97 | let isEven = (n) => n % 2 == 0; 98 | let xf = comp(map(inc), filter(isEven)); 99 | 100 | console.log(into([], xf, [0,1,2,3,4])); // [2,4] 101 | ``` 102 | 103 | ## Documentation 104 | 105 | Documentation can be found [here](http://cognitect-labs.github.io/transducers-js/classes/transducers.html) 106 | 107 | ## Integration 108 | 109 | transducers-js can also easily be used in combination with *existing* 110 | reduce implementations, whether native or the shims provided by 111 | [Underscore](http://underscorejs.org) and 112 | [Lodash](http://lodash.com). Doing so with native and Underscore can 113 | deliver significant performance benefits. Transducers may be easily 114 | converted from their object representation into the necessary 115 | two-arity function via `toFn`. 116 | 117 | ```js 118 | var arr = [0,1,2,3,4,5,6,7,8,9,10], 119 | apush = function(arr, x) { arr.push(x); return arr; }, 120 | xf = comp(map(inc), filter(isEven)), 121 | toFn = t.toFn; 122 | 123 | arr.reduce(toFn(xf, apush), []); // native 124 | _(arr).reduce(toFn(xf, apush), []); // underscore or lodash 125 | ``` 126 | 127 | ### Immutable-js 128 | 129 | transducers-js can work with custom collection types and still 130 | deliver the same performance benefits, for example with Immutable-js: 131 | 132 | ```js 133 | var Immutable = require("immutable"), 134 | t = require("transducers-js"), 135 | comp = t.comp, 136 | map = t.map, 137 | filter = t.filter, 138 | transduce = t.transduce; 139 | 140 | var inc = function(n) { return n + 1; }; 141 | var isEven = function(n) { return n % 2 == 0; }; 142 | var sum = function(a,b) { return a+b; }; 143 | 144 | var largeVector = Immutable.List(); 145 | 146 | for(var i = 0; i < 1000000; i++) { 147 | largeVector = largeVector.push(i); 148 | } 149 | 150 | // built in Immutable-js functionality 151 | largeVector.map(inc).filter(isEven).reduce(sum); 152 | 153 | // faster with transducers 154 | var xf = comp(map(inc),filter(isEven)); 155 | transduce(xf, sum, 0, largeVector); 156 | ``` 157 | 158 | ### ES6 Collections 159 | 160 | ES6 collections return iterators and therefore can be 161 | reduced/transduced. For example with 162 | [transit-js](https://github.com/cognitect/transit-js) collections 163 | which satisfy many of the proposed Map/Set methods: 164 | 165 | ```js 166 | var transit = require("transit-js"), 167 | t = require("transducers-js"), 168 | m = transit.map(["foo", "bar", "baz", "woz"]), 169 | vUC = function(kv) { return [kv[0], kv[1].toUpperCase()]; }, 170 | xf = t.map(vUC); 171 | madd = function(m, kv) { m.set(kv[0], kv[1]); return m; }; 172 | 173 | transduce(xf, madd, transit.map(), m.entries()); // Map ["foo", "BAR", "baz", "WOZ"] 174 | ``` 175 | 176 | ## The Transducer Protocol 177 | 178 | It is a goal that all JavaScript transducer implementations 179 | interoperate regardless of the surface level API. Towards this end the 180 | following outlines the protocol all transducers must follow. 181 | 182 | ### Transducer composition 183 | 184 | Transducers are simply a function of one arity. The only argument 185 | is another transducer *transformer* (labeled `xf` in the code base). 186 | Note the distinction between the *transducer* which is a function of 187 | one argument and the *transformer* an object whose methods we'll 188 | describe in the following section. 189 | 190 | For example the following simplified definition of `map`: 191 | 192 | ```js 193 | var map = function(f) { 194 | return function(xf) { 195 | return Map(f, xf); 196 | }; 197 | }; 198 | ``` 199 | 200 | Since transducers are simply functions of one argument they can be 201 | composed easily via function composition to create transformer 202 | pipelines. Note that transducers return transformers when invoked. 203 | 204 | ### Transformer protocol 205 | 206 | Transformers are objects. They must implement 3 methods, `@@transducer/init`, 207 | `@@transducer/result` and `@@transducer/step`. If a transformer is intended to 208 | be composed with other transformers they should either close over the next 209 | transformer or store it in a field. 210 | 211 | For example the `Map` transformer could look something like the 212 | following: 213 | 214 | ```js 215 | var Map = function(f, xf) { 216 | return { 217 | "@@transducer/init": function() { 218 | return xf["@@transducer/init"](); 219 | }, 220 | "@@transducer/result": function(result) { 221 | return xf["@@transducer/result"](result); 222 | }, 223 | "@@transducer/step": function(result, input) { 224 | return xf["@@transducer/step"](result, f(input)); 225 | } 226 | }; 227 | }; 228 | ``` 229 | 230 | Note how we take care to call the next transformer in the pipeline. We 231 | could have of course created `Map` as a proper JavaScript type with 232 | prototype methods - this is in fact how it is done in transducers-js. 233 | 234 | ### Reduced 235 | 236 | Detecting the reduced state is critical to short circuiting a 237 | reduction/transduction. A reduced value is denoted by any JavaScript 238 | object that has the property `@@transducer/reduced` set to `true`. 239 | The reduced value should be stored in the `@@transducer/value` property of this 240 | object. 241 | 242 | ### Iteration 243 | 244 | Anything which implements `@@iterator` which returns an ES6 compliant 245 | iterator is reducible/transducible. An ES6 iterator may also just be given directly to `reduce` or `transduce`. 246 | 247 | ## Building 248 | 249 | Fetch the dependencies: 250 | 251 | ``` 252 | bin/deps 253 | ``` 254 | 255 | To build for Node.js 256 | 257 | ``` 258 | bin/build_release_node 259 | ``` 260 | 261 | To build for the browser 262 | 263 | ``` 264 | bin/build_release_browser 265 | ``` 266 | 267 | ## Running the tests 268 | 269 | Make sure you've first fetched the dependencies, then: 270 | 271 | ``` 272 | bin/test 273 | ``` 274 | 275 | ## Contributing 276 | 277 | This library is open source, developed internally by [Cognitect](http://cognitect.com). Issues can be filed using [GitHub Issues](https://github.com/cognitect-labs/transducers-js/issues). 278 | 279 | This project is provided without support or guarantee of continued development. 280 | Because transducers-js may be incorporated into products or client projects, we prefer to do development internally and do not accept pull requests or patches. 281 | 282 | ## Copyright and License 283 | 284 | Copyright © 2014-2015 Cognitect 285 | 286 | Licensed under the Apache License, Version 2.0 (the "License"); 287 | you may not use this file except in compliance with the License. 288 | You may obtain a copy of the License at 289 | 290 | http://www.apache.org/licenses/LICENSE-2.0 291 | 292 | Unless required by applicable law or agreed to in writing, software 293 | distributed under the License is distributed on an "AS IS" BASIS, 294 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 295 | See the License for the specific language governing permissions and 296 | limitations under the License. 297 | -------------------------------------------------------------------------------- /VERSION_PREFIX: -------------------------------------------------------------------------------- 1 | 0.4 -------------------------------------------------------------------------------- /bench/bench.js: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2015 Cognitect. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS-IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | "use strict"; 16 | 17 | var t = null; 18 | var ld = null; 19 | var ud = null; 20 | 21 | if(typeof require != "undefined") { 22 | t = require("../target/transducers.js"); 23 | ld = require("../node_modules/lodash/lodash.js"); 24 | ud = require("../node_modules/underscore/underscore.js"); 25 | } else { 26 | if(typeof _ != "undefined") { 27 | ld = _; 28 | } 29 | t = transducers; 30 | } 31 | 32 | var map = t.map, 33 | filter = t.filter, 34 | reduce = t.reduce, 35 | transduce = t.transduce, 36 | mapcat = t.mapcat, 37 | reduced = t.reduced, 38 | isReduced = t.isReduced, 39 | comp = t.comp; 40 | 41 | function log(varArgs) { 42 | if(typeof console != "undefined") { 43 | console.log.apply(console, Array.prototype.slice.call(arguments, 0)); 44 | } else { 45 | print(Array.prototype.slice.call(arguments, 0).join(" ")); 46 | } 47 | } 48 | 49 | function time(f, iters) { 50 | iters = iters || 1; 51 | for(var i = 0; i < iters; i++) { 52 | var s = new Date(); 53 | var ret = f(); 54 | log(ret, "elapsed "+((new Date()).valueOf()-s.valueOf())+"ms"); 55 | log("----------"); 56 | } 57 | } 58 | 59 | function inc(n) { return n + 1; }; 60 | function isEven(n) { return n % 2 == 0; }; 61 | function apush(arr, x) { arr.push(x); return arr; }; 62 | function addEntry(obj, entry) { obj[entry[0]] = entry[1]; return obj; }; 63 | function ucKeys(entry) { return [entry[0].toUpperCase(), entry[1]]; }; 64 | function doubleN(n) { return n + n; }; 65 | function squareN(n) { return n * n; }; 66 | function reverse(arr) { 67 | var clone = Array.prototype.slice.call(arr, 0); 68 | clone.reverse(); 69 | return clone; 70 | }; 71 | 72 | log(comp(doubleN,squareN)(3)); 73 | log(transduce(map(inc), apush, [], [0,1,2,3,4,5,6,7,8,9])); 74 | log(transduce(filter(isEven), apush, [], [0,1,2,3,4,5,6,7,8,9])); 75 | log(transduce(comp(map(inc), filter(isEven)), apush, [], [0,1,2,3,4,5,6,7,8,9])); 76 | log(transduce(mapcat(reverse), apush, [], [[0,1,2],[3,4,5],[6,7,8]])); 77 | log(transduce(map(ucKeys), addEntry, {}, {foo: 1, bar:2})); 78 | 79 | var xf = comp(map(inc), map(inc), map(inc)); 80 | 81 | log(transduce(xf, apush, [], [1,2,3])); 82 | 83 | var largeArray = []; 84 | for(var i = 0; i < 1000000; i++) { 85 | largeArray.push(i); 86 | } 87 | 88 | log("for loop, 1 op") 89 | time(function() { 90 | var ret = []; 91 | for(var i = 0; i < largeArray.length; i++) { 92 | ret.push(inc(largeArray[i])); 93 | } 94 | return ret.length; 95 | }); 96 | 97 | log("native map array, 1 op") 98 | time(function() { 99 | return largeArray.map(inc).length; 100 | }); 101 | 102 | log("transduce map large array, 1 op") 103 | time(function() { 104 | return transduce(map(inc), apush, [], largeArray).length; 105 | }); 106 | 107 | log("for loop, 2 ops") 108 | time(function() { 109 | var ret = []; 110 | for(var i = 0; i < largeArray.length; i++) { 111 | var n = inc(largeArray[i]); 112 | if(isEven(n)) { 113 | ret.push(n); 114 | } 115 | } 116 | return ret.length; 117 | }, 10); 118 | 119 | log("native map/filter array, 2 ops") 120 | time(function() { 121 | return largeArray.map(inc).filter(isEven).length; 122 | }, 10); 123 | 124 | log("transduce map/filter large array, 2 ops") 125 | time(function() { 126 | return transduce(comp(map(inc),filter(isEven)), apush, [], largeArray).length; 127 | }, 10); 128 | 129 | if(ld != null) { 130 | log("lodash map/filter large array, 2 ops") 131 | time(function() { 132 | return ld.chain(largeArray).map(inc).filter(isEven).value().length; 133 | }, 10); 134 | } 135 | 136 | log("transduce map/filter large array, 5 ops") 137 | time(function() { 138 | return transduce(comp(map(inc),map(doubleN),map(inc),map(doubleN)), apush, [], largeArray).length; 139 | },10); 140 | 141 | if(ld != null) { 142 | log("lodash map/filter large array, 5 ops") 143 | time(function () { 144 | return ld.chain(largeArray).map(inc).filter(doubleN).map(inc).map(doubleN).value().length; 145 | }, 10); 146 | } 147 | -------------------------------------------------------------------------------- /bin/build_dev_browser: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd `dirname $0`/.. 6 | 7 | mkdir -p target 8 | 9 | prefix=`cat VERSION_PREFIX` 10 | suffix=`build/revision` 11 | version=$prefix.$suffix 12 | prelude=`bin/prelude` 13 | preludenl=$prelude.$'\n' 14 | 15 | java -jar deps/closure-compiler/compiler.jar -O SIMPLE --formatting PRETTY_PRINT \ 16 | --generate_exports --output_wrapper "$preludenl;(function(){%output%})();" \ 17 | -D TRANSDUCERS_BROWSER_TARGET=true --externs=resources/node_externs.js \ 18 | --manage_closure_dependencies --only_closure_dependencies \ 19 | --closure_entry_point=com.cognitect.transducers \ 20 | --js_output_file=target/transducers-$version.js \ 21 | 'deps/closure-library/closure/**.js' 'src/**.js' 22 | -------------------------------------------------------------------------------- /bin/build_dev_browser_amd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd `dirname $0`/.. 6 | 7 | mkdir -p target 8 | 9 | prefix=`cat VERSION_PREFIX` 10 | suffix=`build/revision` 11 | version=$prefix.$suffix 12 | prelude=`bin/prelude` 13 | preludenl=$prelude.$'\n' 14 | 15 | java -jar deps/closure-compiler/compiler.jar -O SIMPLE --formatting PRETTY_PRINT \ 16 | --generate_exports --output_wrapper "$preludenl;(function(){%output%})();" \ 17 | -D TRANSDUCERS_BROWSER_AMD_TARGET=true --manage_closure_dependencies \ 18 | --only_closure_dependencies --closure_entry_point=com.cognitect.transducers.amd \ 19 | --js_output_file=target/transducers-$version-amd.js \ 20 | 'deps/closure-library/closure/**.js' 'src/**.js' 21 | -------------------------------------------------------------------------------- /bin/build_dev_node: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd `dirname $0`/.. 6 | 7 | mkdir -p target 8 | 9 | prefix=`cat VERSION_PREFIX` 10 | suffix=`build/revision` 11 | version=$prefix.$suffix 12 | prelude=`bin/prelude` 13 | preludenl=$prelude.$'\n' 14 | 15 | java -jar deps/closure-compiler/compiler.jar -O SIMPLE --formatting PRETTY_PRINT \ 16 | --generate_exports --output_wrapper "$preludenl%output%" -D TRANSDUCERS_NODE_TARGET=true \ 17 | --externs=resources/node_externs.js --manage_closure_dependencies \ 18 | --only_closure_dependencies --closure_entry_point=com.cognitect.transducers \ 19 | --js_output_file=target/transducers.js \ 20 | 'deps/closure-library/closure/**.js' 'src/**.js' -------------------------------------------------------------------------------- /bin/build_jar: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | cd src 6 | 7 | jar cf transducers-js.jar . 8 | 9 | mkdir -p ../target 10 | 11 | mv transducers-js.jar ../target/ -------------------------------------------------------------------------------- /bin/build_release_browser: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd `dirname $0`/.. 6 | 7 | mkdir -p target 8 | 9 | prefix=`cat VERSION_PREFIX` 10 | suffix=`build/revision` 11 | version=$prefix.$suffix 12 | prelude=`bin/prelude` 13 | preludenl=$prelude.$'\n' 14 | 15 | java -jar deps/closure-compiler/compiler.jar -O ADVANCED --generate_exports \ 16 | --output_wrapper "$preludenl;(function(){%output%})();" \ 17 | -D TRANSDUCERS_BROWSER_TARGET=true -D TRANSDUCERS_DEV=false \ 18 | --externs=resources/externs.js --manage_closure_dependencies \ 19 | --only_closure_dependencies --closure_entry_point=com.cognitect.transducers \ 20 | --js_output_file=target/transducers-$version-min.js \ 21 | 'deps/closure-library/closure/**.js' 'src/**.js' -------------------------------------------------------------------------------- /bin/build_release_browser_amd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd `dirname $0`/.. 6 | 7 | mkdir -p target 8 | 9 | prefix=`cat VERSION_PREFIX` 10 | suffix=`build/revision` 11 | version=$prefix.$suffix 12 | prelude=`bin/prelude` 13 | preludenl=$prelude.$'\n' 14 | 15 | java -jar deps/closure-compiler/compiler.jar -O ADVANCED --generate_exports \ 16 | --output_wrapper "$preludenl;(function(){%output%})();" \ 17 | -D TRANSDUCERS_BROWSER_AMD_TARGET=true -D TRANSDUCERS_DEV=false \ 18 | --externs=resources/amd_externs.js --manage_closure_dependencies \ 19 | --only_closure_dependencies --closure_entry_point=com.cognitect.transducers.amd \ 20 | --js_output_file=target/transducers-$version-amd-min.js \ 21 | 'deps/closure-library/closure/**.js' 'src/**.js' 22 | -------------------------------------------------------------------------------- /bin/build_release_node: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd `dirname $0`/.. 6 | 7 | mkdir -p target 8 | 9 | prefix=`cat VERSION_PREFIX` 10 | suffix=`build/revision` 11 | version=$prefix.$suffix 12 | prelude=`bin/prelude` 13 | preludenl=$prelude.$'\n' 14 | 15 | java -jar deps/closure-compiler/compiler.jar -O ADVANCED --generate_exports \ 16 | --output_wrapper "$preludenl%output%" -D TRANSDUCERS_NODE_TARGET=true \ 17 | -D TRANSDUCERS_DEV=false --externs=resources/node_externs.js \ 18 | --manage_closure_dependencies --only_closure_dependencies \ 19 | --closure_entry_point=com.cognitect.transducers \ 20 | --js_output_file=target/transducers.js \ 21 | 'deps/closure-library/closure/**.js' 'src/**.js' 22 | -------------------------------------------------------------------------------- /bin/closure_deps_graph.clj: -------------------------------------------------------------------------------- 1 | (ns closure-deps-graph 2 | (:require [clojure.java.io :as io]) 3 | (:import [java.io File] 4 | [com.google.javascript.jscomp SourceFile BasicErrorManager] 5 | [com.google.javascript.jscomp.deps DepsGenerator DepsGenerator$InclusionStrategy])) 6 | 7 | (defn js-files-in 8 | "Return a sequence of all .js files in the given directory." 9 | [dir] 10 | (filter 11 | #(let [name (.getName ^File %)] 12 | (and (.endsWith name ".js") 13 | (not= \. (first name)))) 14 | (file-seq dir))) 15 | 16 | (spit (io/file "deps/closure-library/closure/goog/transducers_deps.js") 17 | (.computeDependencyCalls 18 | (DepsGenerator. (map #(SourceFile/fromFile (io/file %)) '("deps/closure-library/closure/goog/deps.js")) 19 | (map #(SourceFile/fromFile %) 20 | (mapcat (comp js-files-in io/file) 21 | ["src"])) 22 | DepsGenerator$InclusionStrategy/ALWAYS 23 | (.getAbsolutePath (io/file "deps/closure-library/closure/goog")) 24 | (proxy [BasicErrorManager] [] 25 | (report [level error] 26 | (println error)) 27 | (println [level error] 28 | (println error)))))) -------------------------------------------------------------------------------- /bin/deps: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd `dirname $0`/.. 6 | 7 | echo "Installing Nodej.s dependencies" 8 | 9 | npm install 10 | npm install grunt-cli 11 | 12 | echo "Installing JVM dependencies" 13 | 14 | rm -rf deps 15 | 16 | mkdir -p deps/closure-compiler 17 | cd deps/closure-compiler 18 | curl -O -s http://dl.google.com/closure-compiler/compiler-latest.zip 19 | unzip -qu compiler-latest.zip 20 | rm compiler-latest.zip 21 | cd ../.. 22 | 23 | git clone https://github.com/google/closure-library.git deps/closure-library 24 | 25 | mkdir -p deps/clojure 26 | curl -O http://repo1.maven.org/maven2/org/clojure/clojure/1.6.0/clojure-1.6.0.zip 27 | unzip -qu clojure-1.6.0.zip 28 | mv clojure-1.6.0/clojure-1.6.0.jar deps/clojure 29 | rm -rf clojure-1.6.0 clojure-1.6.0.zip 30 | -------------------------------------------------------------------------------- /bin/docs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd `dirname $0`/.. 6 | 7 | node_modules/.bin/yuidoc src --themedir doctheme -o docs 8 | -------------------------------------------------------------------------------- /bin/make_deps_js: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | java -cp deps/closure-compiler/compiler.jar:deps/clojure/clojure-1.6.0.jar clojure.main -i bin/closure_deps_graph.clj -------------------------------------------------------------------------------- /bin/prelude: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | prefix=`cat VERSION_PREFIX` 6 | suffix=`build/revision` 7 | version=$prefix.$suffix 8 | 9 | sed "s/\$VERSION/$version/g" resources/prelude.txt 10 | -------------------------------------------------------------------------------- /bin/test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd `dirname $0`/.. 6 | 7 | bin/make_deps_js 8 | node_modules/.bin/grunt nodeunit 9 | -------------------------------------------------------------------------------- /build/package_local: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "Cleaning..." 6 | rm -rf ./target 7 | 8 | echo "Calculating version..." 9 | prefix=`cat VERSION_PREFIX` 10 | suffix=`build/revision` 11 | version=$prefix.$suffix 12 | echo $version 13 | 14 | echo "Packaging..." 15 | bin/build_jar 16 | mvn versions:set -DnewVersion=${version} 17 | mvn install:install-file -Dfile=./target/transducers-js.jar -DpomFile=pom.xml 18 | mvn versions:revert 19 | 20 | echo "Package done!" -------------------------------------------------------------------------------- /build/release: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "Cleaning..." 6 | rm -rf ./target 7 | 8 | echo "Calculating version..." 9 | prefix=`cat VERSION_PREFIX` 10 | suffix=`build/revision` 11 | version=$prefix.$suffix 12 | echo $version 13 | 14 | target_name=transducers-js-${version} 15 | 16 | echo "Releasing..." 17 | mvn versions:set -DnewVersion=${version} 18 | mvn clean deploy 19 | mvn versions:revert 20 | 21 | echo "Tagging..." 22 | git tag -a v${version} -m "Release ${version}" 23 | git push origin v${version} 24 | 25 | echo "Building browser .js to cdn" 26 | bin/build_release_browser 27 | bin/build_release_browser_amd 28 | bin/build_dev_browser 29 | bin/build_dev_browser_amd 30 | 31 | echo "Pushing browser .js to cdn in s3" 32 | aws s3 --profile transit-upload sync ./target s3://cdn.cognitect.com/transducers --exclude "*" --include "transducers-${version}*.js" --content-type text/plain 33 | 34 | echo "Updating README.md versions" 35 | sed -i '' "s/[[:digit:]]\{1,2\}\.[[:digit:]]\{1,2\}\.[[:digit:]]\{2,4\}/${version}/g" README.md 36 | git commit -v -m "Update README.md with ${version}" README.md 37 | git push 38 | 39 | # echo "Building new api docs" 40 | # bin/docs 41 | 42 | echo -e "Updating bower version\n" 43 | rm -rf bower-transducers-js 44 | git clone --quiet git@github.com:cognitect-labs/bower-transducers-js.git bower-transducers-js > /dev/null 45 | cd bower-transducers-js 46 | cp ../target/transducers-${version}.js ./transducers.js 47 | cp ../target/transducers-${version}-min.js ./transducers-min.js 48 | cp ../target/transducers-${version}-amd.js ./transducers-amd.js 49 | cp ../target/transducers-${version}-amd-min.js ./transducers-amd-min.js 50 | git add -f transducers.js 51 | git add -f transducers-min.js 52 | git add -f transducers-amd.js 53 | git add -f transducers-amd-min.js 54 | sed -e "s/\"version\": \"[[:digit:]]\{1,2\}\.[[:digit:]]\{1,2\}\.[[:digit:]]\{2,4\}/\"version\": \"${version}/g" package.json > package.json.tmp 55 | rm package.json 56 | mv package.json.tmp package.json 57 | git add -f package.json 58 | sed -e "s/\"version\": \"[[:digit:]]\{1,2\}\.[[:digit:]]\{1,2\}\.[[:digit:]]\{2,4\}/\"version\": \"${version}/g" bower.json > bower.json.tmp 59 | rm bower.json 60 | mv bower.json.tmp bower.json 61 | git add -f bower.json 62 | git commit -m "${version}" 63 | git push -fq > /dev/null 64 | git tag ${version} 65 | git push --tags > /dev/null 66 | cd .. 67 | rm -rf bower-transducers-js 68 | 69 | echo "Updating npm version\n" 70 | bin/build_dev_node 71 | rm -rf npm-transducers-js 72 | git clone --quiet git@github.com:cognitect-labs/npm-transducers-js.git npm-transducers-js > /dev/null 73 | cd npm-transducers-js 74 | cp ../target/transducers.js ./transducers.js 75 | cp -R ../src/* ./src/ 76 | git add -f transducers.js 77 | sed -e "s/\"version\": \"[[:digit:]]\{1,2\}\.[[:digit:]]\{1,2\}\.[[:digit:]]\{2,4\}/\"version\": \"${version}/g" package.json > package.json.tmp 78 | rm package.json 79 | mv package.json.tmp package.json 80 | git add -f package.json 81 | git commit -m "${version}" 82 | git push -fq > /dev/null 83 | git tag ${version} 84 | git push --tags > /dev/null 85 | echo "Releasing npm package\n" 86 | # Need help on this command! 87 | npm publish 88 | cd .. 89 | rm -rf npm-transducers-js 90 | 91 | echo "Release done!" 92 | -------------------------------------------------------------------------------- /build/revision: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Returns the revision number used for deployment. 4 | 5 | set -e 6 | 7 | REVISION=`git --no-replace-objects describe --tags --match v0.0` 8 | 9 | # Extract the version number from the string. Do this in two steps so 10 | # it is a little easier to understand. 11 | REVISION=${REVISION:5} # drop the first 5 characters 12 | REVISION=${REVISION:0:${#REVISION}-9} # drop the last 9 characters 13 | 14 | echo $REVISION 15 | -------------------------------------------------------------------------------- /doctheme/assets/css/cognitect.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cognitect-labs/transducers-js/f21cb186b6163697fe3c8c6d98125c6f66cb7632/doctheme/assets/css/cognitect.jpg -------------------------------------------------------------------------------- /doctheme/assets/css/external-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cognitect-labs/transducers-js/f21cb186b6163697fe3c8c6d98125c6f66cb7632/doctheme/assets/css/external-small.png -------------------------------------------------------------------------------- /doctheme/assets/css/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cognitect-labs/transducers-js/f21cb186b6163697fe3c8c6d98125c6f66cb7632/doctheme/assets/css/logo.png -------------------------------------------------------------------------------- /doctheme/assets/css/main.css: -------------------------------------------------------------------------------- 1 | /* 2 | Font sizes for all selectors other than the body are given in percentages, 3 | with 100% equal to 13px. To calculate a font size percentage, multiply the 4 | desired size in pixels by 7.6923076923. 5 | 6 | Here's a quick lookup table: 7 | 8 | 10px - 76.923% 9 | 11px - 84.615% 10 | 12px - 92.308% 11 | 13px - 100% 12 | 14px - 107.692% 13 | 15px - 115.385% 14 | 16px - 123.077% 15 | 17px - 130.769% 16 | 18px - 138.462% 17 | 19px - 146.154% 18 | 20px - 153.846% 19 | */ 20 | 21 | html { 22 | background: #fff; 23 | color: #333; 24 | overflow-y: scroll; 25 | } 26 | 27 | body { 28 | font: 13px/1.4 'Lucida Grande', 'Lucida Sans Unicode', 'DejaVu Sans', 'Bitstream Vera Sans', 'Helvetica', 'Arial', sans-serif; 29 | margin: 0; 30 | padding: 0; 31 | } 32 | 33 | /* -- Links ----------------------------------------------------------------- */ 34 | a { 35 | color: #356de4; 36 | text-decoration: none; 37 | } 38 | 39 | a:hover { text-decoration: underline; } 40 | 41 | /* "Jump to Table of Contents" link is shown to assistive tools, but hidden from 42 | sight until it's focused. */ 43 | .jump { 44 | position: absolute; 45 | padding: 3px 6px; 46 | left: -99999px; 47 | top: 0; 48 | } 49 | 50 | .jump:focus { left: 40%; } 51 | 52 | /* -- Paragraphs ------------------------------------------------------------ */ 53 | p { margin: 1.3em 0; } 54 | dd p, td p { margin-bottom: 0; } 55 | dd p:first-child, td p:first-child { margin-top: 0; } 56 | 57 | /* -- Headings -------------------------------------------------------------- */ 58 | h1, h2, h3, h4, h5, h6 { 59 | color: #D98527;/*was #f80*/ 60 | font-family: 'Trebuchet MS', sans-serif; 61 | font-weight: bold; 62 | line-height: 1.1; 63 | margin: 1.1em 0 0.5em; 64 | } 65 | 66 | h1 { 67 | font-size: 184.6%; 68 | color: #30418C; 69 | margin: 0.75em 0 0.5em; 70 | } 71 | 72 | h2 { 73 | font-size: 153.846%; 74 | color: #E48A2B; 75 | } 76 | 77 | h3 { font-size: 138.462%; } 78 | 79 | h4 { 80 | border-bottom: 1px solid #DBDFEA; 81 | color: #E48A2B; 82 | font-size: 115.385%; 83 | font-weight: normal; 84 | padding-bottom: 2px; 85 | } 86 | 87 | h5, h6 { font-size: 107.692%; } 88 | 89 | /* -- Code and examples ----------------------------------------------------- */ 90 | code, kbd, pre, samp { 91 | font-family: Menlo, Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; 92 | font-size: 92.308%; 93 | line-height: 1.35; 94 | } 95 | 96 | p code, p kbd, p samp, li code { 97 | background: #FCFBFA; 98 | border: 1px solid #EFEEED; 99 | padding: 0 3px; 100 | } 101 | 102 | a code, a kbd, a samp, 103 | pre code, pre kbd, pre samp, 104 | table code, table kbd, table samp, 105 | .intro code, .intro kbd, .intro samp, 106 | .toc code, .toc kbd, .toc samp { 107 | background: none; 108 | border: none; 109 | padding: 0; 110 | } 111 | 112 | pre.code, pre.terminal, pre.cmd { 113 | overflow-x: auto; 114 | *overflow-x: scroll; 115 | padding: 0.3em 0.6em; 116 | } 117 | 118 | pre.code { 119 | background: #FCFBFA; 120 | border: 1px solid #EFEEED; 121 | border-left-width: 5px; 122 | } 123 | 124 | pre.terminal, pre.cmd { 125 | background: #F0EFFC; 126 | border: 1px solid #D0CBFB; 127 | border-left: 5px solid #D0CBFB; 128 | } 129 | 130 | /* Don't reduce the font size of // elements inside
131 |    blocks. */
132 | pre code, pre kbd, pre samp { font-size: 100%; }
133 | 
134 | /* Used to denote text that shouldn't be selectable, such as line numbers or
135 |    shell prompts. Guess which browser this doesn't work in. */
136 | .noselect {
137 |     -moz-user-select: -moz-none;
138 |     -khtml-user-select: none;
139 |     -webkit-user-select: none;
140 |     -o-user-select: none;
141 |     user-select: none;
142 | }
143 | 
144 | /* -- Lists ----------------------------------------------------------------- */
145 | dd { margin: 0.2em 0 0.7em 1em; }
146 | dl { margin: 1em 0; }
147 | dt { font-weight: bold; }
148 | 
149 | /* -- Tables ---------------------------------------------------------------- */
150 | caption, th { text-align: left; }
151 | 
152 | table {
153 |     border-collapse: collapse;
154 |     width: 100%;
155 | }
156 | 
157 | td, th {
158 |     border: 1px solid #fff;
159 |     padding: 5px 12px;
160 |     vertical-align: top;
161 | }
162 | 
163 | td { background: #E6E9F5; }
164 | td dl { margin: 0; }
165 | td dl dl { margin: 1em 0; }
166 | td pre:first-child { margin-top: 0; }
167 | 
168 | th {
169 |     background: #D2D7E6;/*#97A0BF*/
170 |     border-bottom: none;
171 |     border-top: none;
172 |     color: #000;/*#FFF1D5*/
173 |     font-family: 'Trebuchet MS', sans-serif;
174 |     font-weight: bold;
175 |     line-height: 1.3;
176 |     white-space: nowrap;
177 | }
178 | 
179 | 
180 | /* -- Layout and Content ---------------------------------------------------- */
181 | #doc {
182 |     margin: auto;
183 |     min-width: 1024px;
184 | }
185 | 
186 | #main { width: 754px; }
187 | #sidebar { width: 270px; margin: 0 15px; }
188 | 
189 | .content { padding: 0 20px 0 25px; }
190 | 
191 | /* -- Sidebar --------------------------------------------------------------- */
192 | .sidebox {
193 |     background: #F9F9FC;/*E6E9F5*/
194 |     border: 1px solid #D4D8EB;
195 | 
196 |     -moz-border-radius: 4px;
197 |     -webkit-border-radius: 4px;
198 |     border-radius: 4px;
199 |     -moz-box-shadow: 0 0 6px rgba(0, 0, 0, 0.15);
200 |     -webkit-box-shadow: 0 0 6px rgba(0, 0, 0, 0.15);
201 |     box-shadow: 0 0 6px rgba(0, 0, 0, 0.15);
202 |     font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', 'Helvetica', 'Arial', sans-serif;
203 |     margin: 0 0 15px 0;
204 |     padding-bottom: 1px;
205 | }
206 | 
207 | .sidebox h2 {
208 |     background: #E5E6F1;
209 |     -moz-border-radius: 4px 4px 0 0;
210 |     -webkit-border-radius: 4px 4px 0 0;
211 |     border-radius: 4px 4px 0 0;
212 |     color: #5E6BA4;
213 |     font-weight: bold;
214 |     font-size: 107.692%;
215 |     margin: 0;
216 |     padding: 4px 7px 5px;
217 | }
218 | 
219 | .sidebox .bd {
220 |     font-size: 84.615%;
221 |     padding: 0 5px 0 8px;
222 | }
223 | 
224 | .sidebox li { list-style-type: disc; color:#D4D5E3; }
225 | 
226 | .sidebox ol, .sidebox ul {
227 |     margin-left: 0;
228 |     padding-left: 16px;
229 | }
230 | 
231 | .sidebox ol ol, .sidebox ol ul,
232 | .sidebox ul ol, .sidebox ul ul {
233 |     margin: 0;
234 |     padding-left: 16px;
235 | }
236 | 
237 | /* -- Table of Contents ----------------------------------------------------- */
238 | 
239 | /* The #toc id refers to the single global table of contents, while the .toc
240 |    class refers to generic TOC lists that could be used throughout the page. */
241 | 
242 | .toc code, .toc kbd, .toc samp { font-size: 100%; }
243 | .toc li { font-weight: bold; }
244 | .toc li li { font-weight: normal; }
245 | 
246 | /* -- Intro and Example Boxes ----------------------------------------------- */
247 | .intro, .example { margin-bottom: 2em; }
248 | 
249 | .example {
250 |     -moz-border-radius: 4px;
251 |     -webkit-border-radius: 4px;
252 |     border-radius: 4px;
253 |     -moz-box-shadow: 0 0 5px #bfbfbf;
254 |     -webkit-box-shadow: 0 0 5px #bfbfbf;
255 |     box-shadow: 0 0 5px #bfbfbf;
256 |     padding: 1em;
257 | }
258 | 
259 | .intro {
260 |     background: none repeat scroll 0 0 #F0F1F8; border: 1px solid #D4D8EB; padding: 0 1em;
261 | }
262 | 
263 | /* -- Other Styles ---------------------------------------------------------- */
264 | 
265 | /* These are probably YUI-specific, and should be moved out of Selleck's default
266 |    theme. */
267 | 
268 | .button {
269 |     border: 1px solid #dadada;
270 |     -moz-border-radius: 3px;
271 |     -webkit-border-radius: 3px;
272 |     border-radius: 3px;
273 |     color: #444;
274 |     display: inline-block;
275 |     font-family: Helvetica, Arial, sans-serif;
276 |     font-size: 92.308%;
277 |     font-weight: bold;
278 |     padding: 4px 13px 3px;
279 |     -moz-text-shadow: 1px 1px 0 #fff;
280 |     -webkit-text-shadow: 1px 1px 0 #fff;
281 |     text-shadow: 1px 1px 0 #fff;
282 |     white-space: nowrap;
283 | 
284 |     background: #EFEFEF; /* old browsers */
285 |     background: -moz-linear-gradient(top, #f5f5f5 0%, #efefef 50%, #e5e5e5 51%, #dfdfdf 100%); /* firefox */
286 |     background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f5f5f5), color-stop(50%,#efefef), color-stop(51%,#e5e5e5), color-stop(100%,#dfdfdf)); /* webkit */
287 |     filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f5f5f5', endColorstr='#dfdfdf',GradientType=0 ); /* ie */
288 | }
289 | 
290 | .button:hover {
291 |     border-color: #466899;
292 |     color: #fff;
293 |     text-decoration: none;
294 |     -moz-text-shadow: 1px 1px 0 #222;
295 |     -webkit-text-shadow: 1px 1px 0 #222;
296 |     text-shadow: 1px 1px 0 #222;
297 | 
298 |     background: #6396D8; /* old browsers */
299 |     background: -moz-linear-gradient(top, #6396D8 0%, #5A83BC 50%, #547AB7 51%, #466899 100%); /* firefox */
300 |     background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6396D8), color-stop(50%,#5A83BC), color-stop(51%,#547AB7), color-stop(100%,#466899)); /* webkit */
301 |     filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6396D8', endColorstr='#466899',GradientType=0 ); /* ie */
302 | }
303 | 
304 | .newwindow { text-align: center; }
305 | 
306 | .header .version em {
307 |     display: block;
308 |     text-align: right;
309 | }
310 | 
311 | .yui3-skin-sam #classdocs .yui3-tabview-panel {
312 |     background-color: transparent;
313 | }
314 | 
315 | .yui3-skin-sam #classdocs .yui3-tabview-panel {
316 |     border: none;
317 | }
318 | 
319 | .yui3-skin-sam .yui3-tabview .yui3-tab,
320 | .yui3-skin-sam .yui3-tabview .yui3-tab-selected,
321 | .yui3-skin-sam .yui3-tabview .yui3-tab-hover {
322 |     background: -moz-linear-gradient(center top , #F4F0EC 0%, #D6D2CE 100%) repeat scroll 0 0 transparent;
323 |     border-bottom: 1px solid #DEDCD9;
324 |     border-right: 1px solid #CDCBC8;
325 |     border-left: 1px solid #CDCBC8;
326 |     border-top: 1px solid #DADADA;
327 |     color: #333333;
328 |     text-decoration: none;
329 | }
330 | .yui3-skin-sam .yui3-tabview .yui3-tab-label,
331 | .yui3-skin-sam .yui3-tabview .yui3-tab-selected .yui3-tab-label {
332 |     border: none;
333 |     background: none;
334 |     font-size: 100%;
335 |     color: #000;
336 | }
337 | 
338 | .yui3-skin-sam .yui3-tabview .yui3-tab-selected,
339 | .yui3-skin-sam .yui3-tabview .yui3-tab-hover {
340 |     background: none;
341 |     background-color: #fff;
342 |     border-bottom-color: #FFFFFF;
343 |     border-top: 2px solid #8193C9;
344 |     font-weight: bold;
345 |     color: #000;
346 | 
347 | }
348 | 
349 | .yui3-skin-sam .yui3-tabview-list {
350 |     border-color: #DFDFDF;
351 |     border-width: 0 0 1px; 
352 | }
353 | 
354 | 
355 | a.external {
356 |     background-image: url(external-small.png);
357 |     background-repeat: no-repeat;
358 |     background-position: 0 0;
359 |     padding-left: 16px;
360 | }
361 | 
362 | #classdocs .item {
363 |     border-bottom: 1px solid #466899;
364 |     margin: 1em 0;
365 |     padding: 1.5em;
366 | }
367 | 
368 | #classdocs .item .params p,
369 |     #classdocs .item .returns p,{
370 |     display: inline;
371 | }
372 | 
373 | #classdocs .item em code, #classdocs .item em.comment {
374 |     color: green;
375 | }
376 | 
377 | #classdocs .item em.comment a {
378 |     color: green;
379 |     text-decoration: underline;
380 | }
381 | 
382 | #classdocs .foundat {
383 |     font-size: 11px;
384 |     font-style: normal;
385 | }
386 | 
387 | .attrs .emits {
388 |     margin-left: 2em;
389 |     padding: .5em;
390 |     border-left: 1px dashed #ccc;
391 | }
392 | 
393 | abbr {
394 |     border-bottom: 1px dashed #ccc;
395 |     font-size: 80%;
396 |     cursor: help;
397 | }
398 | 
399 | .prettyprint li.L0, 
400 | .prettyprint li.L1, 
401 | .prettyprint li.L2, 
402 | .prettyprint li.L3, 
403 | .prettyprint li.L5, 
404 | .prettyprint li.L6, 
405 | .prettyprint li.L7, 
406 | .prettyprint li.L8 {
407 |     list-style: decimal;
408 | }
409 | 
410 | ul li p {
411 |     margin-top: 0;
412 | }
413 | 
414 | .method .name {
415 |     font-size: 110%;
416 | }
417 | 
418 | #hd {
419 |     background: -moz-linear-gradient(center top , #DCDBD9 0%, #F6F5F3 100%) repeat scroll 0 0 transparent;
420 |     border-bottom: 1px solid #DFDFDF;
421 |     padding: 0 15px 1px 20px;
422 |     margin-bottom: 15px;
423 | }
424 | 
425 | #hd img {
426 |     margin-right: 10px;
427 |     vertical-align: middle;
428 | }
429 | 
430 | 


--------------------------------------------------------------------------------
/doctheme/assets/js/tabs.js:
--------------------------------------------------------------------------------
 1 | YUI({
 2 |     insertBefore: 'site_styles'
 3 | }).use('tabview', function(Y) {
 4 |     var classdocs = Y.one('#classdocs'),
 5 |         tabviewIndexTable = {};
 6 |     if (classdocs) {
 7 |         if (classdocs.all('li').size()) {
 8 |             var tabview = new Y.TabView({ srcNode: classdocs });
 9 |             tabview.render();
10 | 			classdocs.all('li a').each(function (item, index) {
11 | 				var hash = item.get(['hash']);
12 | 					type = hash.substring(1);
13 | 				if (!tabviewIndexTable[type]) {
14 | 					tabviewIndexTable[type] = index;
15 | 				}
16 | 			})
17 | 			Y.all('.sidebox.on-page').each(function (item, index) {
18 | 				var children = item.all('li a');
19 | 				children.each(function (cItem, cIndex) {
20 | 					return function () {
21 | 						var handleClick = function (e) {
22 | 							var node      = Y.one(this),
23 | 								hash      = node.get(['hash']),
24 | 								hashValue = hash.substring(1).split('_'),
25 | 								type      = hashValue.shift(),
26 | 								ogKey     = hashValue.join('_'); // in case the hash had other underscores
27 | 							if (tabviewIndexTable[type] > -1 && tabviewIndexTable[type] !== currentTab) {
28 | 								currentTab = tabviewIndexTable[type];
29 | 								tabview.selectChild(tabviewIndexTable[type]);
30 | 							}
31 | 						}
32 | 						Y.on('click', handleClick, cItem)
33 | 					}()
34 | 				})
35 | 			});
36 |         }
37 |     }
38 | });
39 | 


--------------------------------------------------------------------------------
/doctheme/assets/js/yui-prettify.js:
--------------------------------------------------------------------------------
 1 | YUI().use('node', function(Y) {
 2 |     var code = Y.all('.prettyprint.linenums');
 3 |     if (code.size()) {
 4 |         code.each(function(c) {
 5 |             var lis = c.all('ol li'),
 6 |                 l = 1;
 7 |             lis.each(function(n) {
 8 |                 n.prepend('');
 9 |                 l++;
10 |             });
11 |         });
12 |         var h = location.hash;
13 |         location.hash = '';
14 |         h = h.replace('LINE_', 'LINENUM_');
15 |         location.hash = h;
16 |     }
17 | });
18 | 


--------------------------------------------------------------------------------
/doctheme/assets/vendor/prettify/CHANGES.html:
--------------------------------------------------------------------------------
  1 | 
  2 |   
  3 |     
  4 |     Change Log
  5 |   
  6 |   
  7 |     README
  8 | 
  9 |     

Known Issues

10 | 22 | 23 |

Change Log

24 |

29 March 2007

25 | 56 |

4 Jul 2008

57 | 63 |

5 Jul 2008

64 |
67 |

14 Jul 2008

68 | 76 |

6 Jan 2009

77 | 93 |

21 May 2009

94 | 101 |

14 August 2009

102 | 105 |

3 October 2009

106 | 109 |

19 July 2010

110 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /doctheme/assets/vendor/prettify/COPYING: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /doctheme/assets/vendor/prettify/README.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Javascript code prettifier 7 | 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | Languages : CH 20 |

Javascript code prettifier

21 | 22 |

Setup

23 |
    24 |
  1. Download a distribution 25 |
  2. Include the script and stylesheets in your document 26 | (you will need to make sure the css and js file are on your server, and 27 | adjust the paths in the script and link tag) 28 |
     29 | <link href="prettify.css" type="text/css" rel="stylesheet" />
     30 | <script type="text/javascript" src="prettify.js"></script>
    31 |
  3. Add onload="prettyPrint()" to your 32 | document's body tag. 33 |
  4. Modify the stylesheet to get the coloring you prefer
  5. 34 |
35 | 36 |

Usage

37 |

Put code snippets in 38 | <pre class="prettyprint">...</pre> 39 | or <code class="prettyprint">...</code> 40 | and it will automatically be pretty printed. 41 | 42 | 43 | 44 | 47 |
The original 45 | Prettier 46 |
class Voila {
 49 | public:
 50 |   // Voila
 51 |   static const string VOILA = "Voila";
 52 | 
 53 |   // will not interfere with embedded tags.
 54 | }
55 | 56 |
class Voila {
 57 | public:
 58 |   // Voila
 59 |   static const string VOILA = "Voila";
 60 | 
 61 |   // will not interfere with embedded tags.
 62 | }
63 |
64 | 65 |

FAQ

66 |

Which languages does it work for?

67 |

The comments in prettify.js are authoritative but the lexer 68 | should work on a number of languages including C and friends, 69 | Java, Python, Bash, SQL, HTML, XML, CSS, Javascript, and Makefiles. 70 | It works passably on Ruby, PHP, VB, and Awk and a decent subset of Perl 71 | and Ruby, but, because of commenting conventions, doesn't work on 72 | Smalltalk, or CAML-like languages.

73 | 74 |

LISPy languages are supported via an extension: 75 | lang-lisp.js.

77 |

And similarly for 78 | CSS, 80 | Haskell, 82 | Lua, 84 | OCAML, SML, F#, 86 | Visual Basic, 88 | SQL, 90 | Protocol Buffers, and 92 | WikiText.. 94 | 95 |

If you'd like to add an extension for your favorite language, please 96 | look at src/lang-lisp.js and file an 97 | issue including your language extension, and a testcase.

99 | 100 |

How do I specify which language my code is in?

101 |

You don't need to specify the language since prettyprint() 102 | will guess. You can specify a language by specifying the language extension 103 | along with the prettyprint class like so:

104 |
<pre class="prettyprint lang-html">
106 |   The lang-* class specifies the language file extensions.
107 |   File extensions supported by default include
108 |     "bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html",
109 |     "java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh",
110 |     "xhtml", "xml", "xsl".
111 | </pre>
112 | 113 |

It doesn't work on <obfuscated code sample>?

114 |

Yes. Prettifying obfuscated code is like putting lipstick on a pig 115 | — i.e. outside the scope of this tool.

116 | 117 |

Which browsers does it work with?

118 |

It's been tested with IE 6, Firefox 1.5 & 2, and Safari 2.0.4. 119 | Look at the test page to see if it 120 | works in your browser.

121 | 122 |

What's changed?

123 |

See the change log

124 | 125 |

Why doesn't Prettyprinting of strings work on WordPress?

126 |

Apparently wordpress does "smart quoting" which changes close quotes. 127 | This causes end quotes to not match up with open quotes. 128 |

This breaks prettifying as well as copying and pasting of code samples. 129 | See 130 | WordPress's help center for info on how to stop smart quoting of code 132 | snippets.

133 | 134 |

How do I put line numbers in my code?

135 |

You can use the linenums class to turn on line 136 | numbering. If your code doesn't start at line number 1, you can 137 | add a colon and a line number to the end of that class as in 138 | linenums:52. 139 | 140 |

For example 141 |

<pre class="prettyprint linenums:4"
142 | >// This is line 4.
143 | foo();
144 | bar();
145 | baz();
146 | boo();
147 | far();
148 | faz();
149 | <pre>
150 | produces 151 |
// This is line 4.
153 | foo();
154 | bar();
155 | baz();
156 | boo();
157 | far();
158 | faz();
159 | 
160 | 161 |

How do I prevent a portion of markup from being marked as code?

162 |

You can use the nocode class to identify a span of markup 163 | that is not code. 164 |

<pre class=prettyprint>
165 | int x = foo();  /* This is a comment  <span class="nocode">This is not code</span>
166 |   Continuation of comment */
167 | int y = bar();
168 | </pre>
169 | produces 170 |
171 | int x = foo();  /* This is a comment  This is not code
172 |   Continuation of comment */
173 | int y = bar();
174 | 
175 | 176 |

For a more complete example see the issue22 177 | testcase.

178 | 179 |

I get an error message "a is not a function" or "opt_whenDone is not a function"

180 |

If you are calling prettyPrint via an event handler, wrap it in a function. 181 | Instead of doing 182 |

183 | addEventListener('load', prettyPrint, false); 185 |
186 | wrap it in a closure like 187 |
188 | addEventListener('load', function (event) { prettyPrint() }, false); 190 |
191 | so that the browser does not pass an event object to prettyPrint which 192 | will confuse it. 193 | 194 |


195 | 196 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /doctheme/assets/vendor/prettify/prettify-min.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} -------------------------------------------------------------------------------- /doctheme/assets/vendor/prettify/prettify-min.js: -------------------------------------------------------------------------------- 1 | window.PR_SHOULD_USE_CONTINUATION=true;var prettyPrintOne;var prettyPrint;(function(){var O=window;var j=["break,continue,do,else,for,if,return,while"];var v=[j,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var q=[v,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var m=[q,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var y=[q,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var T=[y,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,let,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var,virtual,where"];var s="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes";var x=[q,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var t="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var J=[j,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var g=[j,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var I=[j,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var B=[m,T,x,t+J,g,I];var f=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;var D="str";var A="kwd";var k="com";var Q="typ";var H="lit";var M="pun";var G="pln";var n="tag";var F="dec";var K="src";var R="atn";var o="atv";var P="nocode";var N="(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function l(ab){var af=0;var U=false;var ae=false;for(var X=0,W=ab.length;X122)){if(!(am<65||ai>90)){ah.push([Math.max(65,ai)|32,Math.min(am,90)|32])}if(!(am<97||ai>122)){ah.push([Math.max(97,ai)&~32,Math.min(am,122)&~32])}}}}ah.sort(function(aw,av){return(aw[0]-av[0])||(av[1]-aw[1])});var ak=[];var aq=[];for(var at=0;atau[0]){if(au[1]+1>au[0]){ao.push("-")}ao.push(V(au[1]))}}ao.push("]");return ao.join("")}function Y(an){var al=an.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var aj=al.length;var ap=[];for(var am=0,ao=0;am=2&&ak==="["){al[am]=Z(ai)}else{if(ak!=="\\"){al[am]=ai.replace(/[a-zA-Z]/g,function(aq){var ar=aq.charCodeAt(0);return"["+String.fromCharCode(ar&~32,ar|32)+"]"})}}}}return al.join("")}var ac=[];for(var X=0,W=ab.length;X=0;){U[ae.charAt(ag)]=aa}}var ah=aa[1];var ac=""+ah;if(!ai.hasOwnProperty(ac)){aj.push(ah);ai[ac]=null}}aj.push(/[\0-\uffff]/);X=l(aj)})();var Z=V.length;var Y=function(aj){var ab=aj.sourceCode,aa=aj.basePos;var af=[aa,G];var ah=0;var ap=ab.match(X)||[];var al={};for(var ag=0,at=ap.length;ag=5&&"lang-"===ar.substring(0,5);if(ao&&!(ak&&typeof ak[1]==="string")){ao=false;ar=K}if(!ao){al[ai]=ar}}var ad=ah;ah+=ai.length;if(!ao){af.push(aa+ad,ar)}else{var an=ak[1];var am=ai.indexOf(an);var ae=am+an.length;if(ak[2]){ae=ai.length-ak[2].length;am=ae-an.length}var au=ar.substring(5);C(aa+ad,ai.substring(0,am),Y,af);C(aa+ad+am,an,r(au,an),af);C(aa+ad+ae,ai.substring(ae),Y,af)}}aj.decorations=af};return Y}function i(V){var Y=[],U=[];if(V.tripleQuotedStrings){Y.push([D,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(V.multiLineStrings){Y.push([D,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{Y.push([D,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(V.verbatimStrings){U.push([D,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var ab=V.hashComments;if(ab){if(V.cStyleComments){if(ab>1){Y.push([k,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{Y.push([k,/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}U.push([D,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,null])}else{Y.push([k,/^#[^\r\n]*/,null,"#"])}}if(V.cStyleComments){U.push([k,/^\/\/[^\r\n]*/,null]);U.push([k,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(V.regexLiterals){var aa=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");U.push(["lang-regex",new RegExp("^"+N+"("+aa+")")])}var X=V.types;if(X){U.push([Q,X])}var W=(""+V.keywords).replace(/^ | $/g,"");if(W.length){U.push([A,new RegExp("^(?:"+W.replace(/[\s,]+/g,"|")+")\\b"),null])}Y.push([G,/^\s+/,null," \r\n\t\xA0"]);var Z=/^.[^\s\w\.$@\'\"\`\/\\]*/;U.push([H,/^@[a-z_$][a-z_$@0-9]*/i,null],[Q,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[G,/^[a-z_$][a-z_$@0-9]*/i,null],[H,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[G,/^\\[\s\S]?/,null],[M,Z,null]);return h(Y,U)}var L=i({keywords:B,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function S(W,ah,aa){var V=/(?:^|\s)nocode(?:\s|$)/;var ac=/\r\n?|\n/;var ad=W.ownerDocument;var ag=ad.createElement("li");while(W.firstChild){ag.appendChild(W.firstChild)}var X=[ag];function af(am){switch(am.nodeType){case 1:if(V.test(am.className)){break}if("br"===am.nodeName){ae(am);if(am.parentNode){am.parentNode.removeChild(am)}}else{for(var ao=am.firstChild;ao;ao=ao.nextSibling){af(ao)}}break;case 3:case 4:if(aa){var an=am.nodeValue;var ak=an.match(ac);if(ak){var aj=an.substring(0,ak.index);am.nodeValue=aj;var ai=an.substring(ak.index+ak[0].length);if(ai){var al=am.parentNode;al.insertBefore(ad.createTextNode(ai),am.nextSibling)}ae(am);if(!aj){am.parentNode.removeChild(am)}}}break}}function ae(al){while(!al.nextSibling){al=al.parentNode;if(!al){return}}function aj(am,at){var ar=at?am.cloneNode(false):am;var ap=am.parentNode;if(ap){var aq=aj(ap,1);var ao=am.nextSibling;aq.appendChild(ar);for(var an=ao;an;an=ao){ao=an.nextSibling;aq.appendChild(an)}}return ar}var ai=aj(al.nextSibling,0);for(var ak;(ak=ai.parentNode)&&ak.nodeType===1;){ai=ak}X.push(ai)}for(var Z=0;Z=U){aj+=2}if(Y>=ar){ac+=2}}}finally{if(au){au.style.display=ak}}}var u={};function d(W,X){for(var U=X.length;--U>=0;){var V=X[U];if(!u.hasOwnProperty(V)){u[V]=W}else{if(O.console){console.warn("cannot override language handler %s",V)}}}}function r(V,U){if(!(V&&u.hasOwnProperty(V))){V=/^\s*]*(?:>|$)/],[k,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[M,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);d(h([[G,/^[\s]+/,null," \t\r\n"],[o,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[n,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[R,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[M,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);d(h([],[[o,/^[\s\S]+/]]),["uq.val"]);d(i({keywords:m,hashComments:true,cStyleComments:true,types:f}),["c","cc","cpp","cxx","cyc","m"]);d(i({keywords:"null,true,false"}),["json"]);d(i({keywords:T,hashComments:true,cStyleComments:true,verbatimStrings:true,types:f}),["cs"]);d(i({keywords:y,cStyleComments:true}),["java"]);d(i({keywords:I,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);d(i({keywords:J,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);d(i({keywords:t,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);d(i({keywords:g,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);d(i({keywords:x,cStyleComments:true,regexLiterals:true}),["js"]);d(i({keywords:s,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);d(h([],[[D,/^[\s\S]+/]]),["regex"]);function e(X){var W=X.langExtension;try{var U=b(X.sourceNode,X.pre);var V=U.sourceCode;X.sourceCode=V;X.spans=U.spans;X.basePos=0;r(W,V)(X);E(X)}catch(Y){if(O.console){console.log(Y&&Y.stack?Y.stack:Y)}}}function z(Y,X,W){var U=document.createElement("pre");U.innerHTML=Y;if(W){S(U,W,true)}var V={langExtension:X,numberLines:W,sourceNode:U,pre:1};e(V);return U.innerHTML}function c(aj){function ab(al){return document.getElementsByTagName(al)}var ah=[ab("pre"),ab("code"),ab("xmp")];var V=[];for(var ae=0;ae]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); -------------------------------------------------------------------------------- /doctheme/layouts/main.handlebars: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{htmlTitle}} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 |

{{title}}

17 |
18 |
19 | API Docs for: {{projectVersion}} 20 |
21 |
22 |
23 | 24 | 27 | 28 |
29 |
{{>layout_content}}
30 |
31 |
32 |
33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /doctheme/partials/attrs.handlebars: -------------------------------------------------------------------------------- 1 | 2 |
3 | `{{name}}` {{#if type}}<{{#crossLink type}}{{/crossLink}}>{{/if}} 4 | {{#if extended_from}}`/* Extended from {{extended_from}} */`{{/if}} 5 | {{#if overwritten_from}}`/* Overwritten from {{name}} */`{{/if}} 6 |
7 | `{{file}}:{{line}}` 8 | {{{attrDescription}}} 9 | {{#if emit}} 10 |
11 | Fires: `{{name}}Change(e)` 12 |

Fires when the value for the configuration attribute `{{name}}` is changed. You can listen for the event using the `on` method if you wish to be notified before the attribute's value has changed, or using the `after` method if you wish to be notified after the attribute's value has changed.

13 | Parameters:
14 | `e` <EventFacade> An Event Facade object with the following attribute specific properties added: 15 |
    16 |
  • `prevVal` The value of the attribute, prior to it being set
  • 17 |
  • `newVal` The value the attribute is to be set to
  • 18 |
  • `attrName` The name of the attribute being set
  • 19 |
  • `subAttrName` If setting a property within the attribute's value, the name of the sub-attribute property being set
  • 20 |
21 |
22 | {{/if}} 23 |
24 | -------------------------------------------------------------------------------- /doctheme/partials/classes.handlebars: -------------------------------------------------------------------------------- 1 |

Class {{moduleName}}

2 | {{#if uses}} 3 | Uses: 4 | {{#each uses}} 5 | {{this}} 6 | {{/each}} 7 |
8 | {{/if}} 9 | {{#if extension_for}} 10 | Extension For: 11 | {{#each extension_for}} 12 | {{this}} 13 | {{/each}} 14 |
15 | {{/if}} 16 | {{#if extends}} 17 | Extends: {{#crossLink extends}}{{/crossLink}}
18 | {{/if}} 19 | Class defined in: `{{file}}:{{line}}` 20 |
{{{classDescription}}}
21 | 22 | {{#if is_constructor}} 23 | {{#is_constructor}} 24 | {{>method}} 25 | {{/is_constructor}} 26 | {{/if}} 27 | 28 |
29 |
    30 | {{#if methods}} 31 |
  • Methods
  • 32 | {{/if}} 33 | {{#if properties}} 34 |
  • Properties
  • 35 | {{/if}} 36 | {{#if attrs}} 37 |
  • Attributes
  • 38 | {{/if}} 39 | {{#if events}} 40 |
  • Events
  • 41 | {{/if}} 42 |
43 |
44 | {{#if methods}} 45 |
46 | {{#methods}} 47 | {{>method}} 48 | {{/methods}} 49 |
50 | {{/if}} 51 | {{#if properties}} 52 |
53 | {{#properties}} 54 | {{>props}} 55 | {{/properties}} 56 |
57 | {{/if}} 58 | {{#if attrs}} 59 |
60 | {{#attrs}} 61 | {{>attrs}} 62 | {{/attrs}} 63 |
64 | {{/if}} 65 | {{#if events}} 66 |
67 | {{#events}} 68 | {{>events}} 69 | {{/events}} 70 |
71 | {{/if}} 72 |
73 |
74 | -------------------------------------------------------------------------------- /doctheme/partials/events.handlebars: -------------------------------------------------------------------------------- 1 | 2 |
3 | `{{name}}` {{#if type}}<{{#crossLink type}}{{/crossLink}}>{{/if}} 4 | {{#if extended_from}}`/* Extended from {{extended_from}} */`{{/if}} 5 | {{#if overwritten_from}}`/* Overwritten from {{name}} */`{{/if}} 6 |
7 | `{{file}}:{{line}}` 8 | {{{eventDescription}}} 9 | {{#if params}} 10 | Extra event object properties: 11 |
    12 | {{#params}} 13 |
  • 14 | {{#if optional}} 15 | `[{{name}}{{#if optdefault}}={{optdefault}}{{/if}}]` <{{#crossLink type}}{{/crossLink}}> 16 | {{else}} 17 | `{{name}}` <{{#crossLink type}}{{/crossLink}}> 18 | {{/if}} 19 | {{#if multiple}} 20 | (*..n) 21 | {{/if}} 22 | {{{description}}} 23 | {{#if props}} 24 |
      25 | {{#props}} 26 |
    • `{{name}}` <{{#crossLink type}}{{/crossLink}}> {{{description}}} 27 | {{/props}} 28 |
    29 | {{/if}} 30 |
  • 31 | {{/params}} 32 |
33 | {{/if}} 34 |
35 | 36 | -------------------------------------------------------------------------------- /doctheme/partials/files.handlebars: -------------------------------------------------------------------------------- 1 |

{{fileName}}

2 | 3 |
4 | {{fileData}}
5 | 
6 | 7 | -------------------------------------------------------------------------------- /doctheme/partials/index.handlebars: -------------------------------------------------------------------------------- 1 |

API Docs - Main Index

2 |

Something smart and pretty should probably go here.

3 | -------------------------------------------------------------------------------- /doctheme/partials/method.handlebars: -------------------------------------------------------------------------------- 1 | 2 |
3 | {{#if final}}final {{/if}}{{#if returnType}}{{#crossLink returnType}}{{/crossLink}} {{/if}}`{{name}}`( `{{paramsList}} ` ) {{#if access}}`/* {{access}} method */`{{/if}} 4 |
5 | 6 | {{#if overwritten_from}} 7 | Defined in {{overwritten_from/class}} but overwritten locally: 8 | {{else}} 9 | {{#if extended_from}} Defined in {{extended_from}}: {{/if}} 10 | {{/if}} 11 | `{{file}}:{{line}}` 12 |
13 | {{{methodDescription}}} 14 | {{#if params}} 15 | Parameters: 16 |
    17 | {{#params}} 18 |
  • 19 | {{#if optional}} 20 | `[{{name}}{{#if optdefault}}={{optdefault}}{{/if}}]` <{{#crossLink type}}{{/crossLink}}> 21 | {{else}} 22 | `{{name}}` <{{#crossLink type}}{{/crossLink}}> 23 | {{/if}} 24 | {{#if multiple}} 25 | (*..n) 26 | {{/if}} 27 | {{{description}}} 28 | {{#if props}} 29 |
      30 | {{#props}} 31 |
    • `{{name}}` <{{#crossLink type}}{{/crossLink}}> {{{description}}} 32 | {{#if props}} 33 |
        34 | {{#props}} 35 |
      • `{{name}}` <{{#crossLink type}}{{/crossLink}}> {{{description}}}
      • 36 | {{/props}} 37 |
      38 | {{/if}} 39 |
    • 40 | {{/props}} 41 |
    42 | {{/if}} 43 |
  • 44 | {{/params}} 45 |
46 | {{/if}} 47 | {{#if return}} 48 | {{#return}} 49 |
Returns: {{#if type}}<{{#crossLink type}}{{/crossLink}}> {{/if}}{{{description}}}
50 | {{/return}} 51 | {{/if}} 52 | {{#if throws}} 53 | {{#throws}} 54 |
Throws: {{#if type}}<{{#crossLink type}}{{/crossLink}}> {{/if}}{{{description}}}
55 | {{/throws}} 56 | {{/if}} 57 | {{#if example}} 58 |
Example
59 | {{{example}}} 60 | {{/if}} 61 |
62 | -------------------------------------------------------------------------------- /doctheme/partials/module.handlebars: -------------------------------------------------------------------------------- 1 | 2 |

{{moduleName}}

3 |
{{{moduleDescription}}}
4 | 5 |
6 |
7 | {{#if moduleClasses}} 8 |

This module has the following classes:

9 |
    10 | {{#moduleClasses}} 11 |
  • {{displayName}}
  • 12 | {{/moduleClasses}} 13 |
14 | {{/if}} 15 |
16 |
17 | {{#if subModules}} 18 |

This module has the following submodules:

19 |
    20 | {{#subModules}} 21 |
  • {{displayName}}

    {{{description}}}

  • 22 | {{/subModules}} 23 |
24 | {{/if}} 25 |
26 |
27 |

28 | Module description found: `{{file}}:{{line}}` 29 | -------------------------------------------------------------------------------- /doctheme/partials/props.handlebars: -------------------------------------------------------------------------------- 1 | 2 |
3 | `{{name}}` <{{#crossLink type}}{{/crossLink}}>{{#if final}} (final){{/if}}{{#if static}} (static){{/if}}
4 | `{{file}}:{{line}}` 5 | {{{propertyDescription}}} 6 | {{#if example}} 7 |
Example
8 | {{{example}}} 9 | {{/if}} 10 |
11 | -------------------------------------------------------------------------------- /doctheme/partials/sidebar.handlebars: -------------------------------------------------------------------------------- 1 | 21 | 22 | 34 | 35 | {{#if methods}} 36 | 48 | {{/if}} 49 | 50 | {{#if events}} 51 | 63 | {{/if}} 64 | 65 | {{#if props}} 66 | 78 | {{/if}} 79 | 80 | {{#if attributes}} 81 | 93 | {{/if}} 94 | 95 | {{#if fileTree}} 96 | 104 | {{/if}} 105 | 106 | -------------------------------------------------------------------------------- /doctheme/theme.json: -------------------------------------------------------------------------------- 1 | { 2 | "yuiGridsUrl": "http://yui.yahooapis.com/3.8.0pr2/build/cssgrids/cssgrids-min.css", 3 | "yuiSeedUrl": "http://yui.yahooapis.com/combo?3.8.0pr2/build/yui/yui-min.js" 4 | } 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "transducers-js", 3 | "version": "0.4.180", 4 | "homepage": "https://github.com/cognitect/tranducers-js", 5 | "description": "A high performance transducer implementation for JavaScript", 6 | "keywords": [ 7 | "functional", 8 | "underscore", 9 | "lodash", 10 | "collections" 11 | ], 12 | "author": "Cognitect", 13 | "license": "APL", 14 | "repository": { 15 | "type": "git", 16 | "url": "git://github.com/cognitect/transducers-js.git" 17 | }, 18 | "main": "target/transducers.js", 19 | "bugs": { 20 | "url": "https://github.com/cognitect/transducers-js/issues" 21 | }, 22 | "contributors": [ 23 | "David Nolen (https://github.com/swannodette)" 24 | ], 25 | "engines": { 26 | "node": ">= 0.10.0" 27 | }, 28 | "dependencies": { 29 | }, 30 | "devDependencies": { 31 | "underscore": "1.8.3", 32 | "lodash": "4.17.15", 33 | "immutable": "3.7.4", 34 | "nodeunit": "0.9.1", 35 | "yuidocjs": "0.8.1", 36 | "source-map-support": "0.3.2" 37 | }, 38 | "scripts": { 39 | "test": "echo \"Error: no test specified\" && exit 1" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.cognitect 5 | transducers-js 6 | jar 7 | dev 8 | transducers-js 9 | Transducers for JavaScript 10 | http://github.com/cognitect/transducers-js 11 | 12 | 13 | The Apache Software License, Version 2.0 14 | http://www.apache.org/licenses/LICENSE-2.0.txt 15 | 16 | 17 | 18 | 19 | David Nolen 20 | dnolen@cognitect.com 21 | Cognitect 22 | http://cognitect.com 23 | 24 | 25 | 26 | scm:git:git@github.com:cognitect-labs/transducers-js.git 27 | scm:git:git@github.com:/transducers-js.git 28 | git@github.com:cognitect-labs/transducers-js.git 29 | 30 | 31 | src 32 | 33 | 34 | src 35 | 36 | 37 | 38 | 39 | org.codehaus.mojo 40 | versions-maven-plugin 41 | 2.1 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-javadoc-plugin 46 | 2.9.1 47 | 48 | 49 | attach-javadocs 50 | 51 | jar 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.apache.maven.plugins 60 | maven-source-plugin 61 | 2.2.1 62 | 63 | 64 | attach-sources 65 | 66 | jar-no-fork 67 | 68 | 69 | 70 | 71 | 72 | org.sonatype.plugins 73 | nexus-staging-maven-plugin 74 | 1.6.2 75 | true 76 | 77 | ossrh 78 | https://oss.sonatype.org/ 79 | true 80 | 81 | 82 | 83 | org.apache.maven.plugins 84 | maven-gpg-plugin 85 | 1.5 86 | 87 | 88 | sign-artifacts 89 | verify 90 | 91 | sign 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /resources/amd_externs.js: -------------------------------------------------------------------------------- 1 | Object.init = function() {}; 2 | Object.result = function() {}; 3 | Object.step = function() {}; 4 | Object.next = function() {}; 5 | Object.value; 6 | Object.done; 7 | Object.__transducers_reduced__; 8 | var define = function() {}; 9 | var transducers = {}; 10 | transducers.reduced = function() {}; 11 | transducers.isReduced = function() {}; 12 | transducers.comp = function() {}; 13 | transducers.complement = function() {}; 14 | transducers.identity = function() {}; 15 | 16 | transducers.map = function() {}; 17 | /** 18 | * @constructor 19 | */ 20 | transducers.Map = function() {}; 21 | 22 | transducers.filter = function() {}; 23 | /** 24 | * @constructor 25 | */ 26 | transducers.Filter = function() {}; 27 | 28 | transducers.remove = function() {}; 29 | /** 30 | * @constructor 31 | */ 32 | transducers.Remove = function() {}; 33 | 34 | transducers.keep = function() {}; 35 | /** 36 | * @constructor 37 | */ 38 | transducers.Keep = function() {}; 39 | 40 | transducers.keepIndexed = function() {}; 41 | /** 42 | * @constructor 43 | */ 44 | transducers.KeepIndexed = function() {}; 45 | 46 | transducers.take = function() {}; 47 | /** 48 | * @constructor 49 | */ 50 | transducers.Take = function() {}; 51 | 52 | transducers.takeWhile = function() {}; 53 | /** 54 | * @constructor 55 | */ 56 | transducers.TakeWhile = function() {}; 57 | 58 | transducers.takeNth = function() {}; 59 | /** 60 | * @constructor 61 | */ 62 | transducers.TakeNth = function() {}; 63 | 64 | transducers.drop = function() {}; 65 | /** 66 | * @constructor 67 | */ 68 | transducers.Drop = function() {}; 69 | 70 | transducers.dropWhile = function() {}; 71 | /** 72 | * @constructor 73 | */ 74 | transducers.DropWhile = function() {}; 75 | 76 | transducers.partitionBy = function() {}; 77 | /** 78 | * @constructor 79 | */ 80 | transducers.PartitionBy = function() {}; 81 | 82 | transducers.partitionAll = function() {}; 83 | /** 84 | * @constructor 85 | */ 86 | transducers.PartitionAll = function() {}; 87 | 88 | transducers.completing = function() {}; 89 | /** 90 | * @constructor 91 | */ 92 | transducers.Completing = function() {}; 93 | 94 | transducers.wrap = function() {}; 95 | /** 96 | * @constructor 97 | */ 98 | transducers.Wrap = function() {}; 99 | 100 | transducers.cat = function() {}; 101 | transducers.mapcat = function() {}; 102 | transducers.transduce = function() {}; 103 | transducers.reduce = function() {}; 104 | transducers.into = function() {}; 105 | transducers.toFn = function() {}; 106 | transducers.first = function() {}; 107 | transducers.ensureReduced = function() {}; 108 | transducers.unreduced = function() {}; 109 | transducers.deref = function() {}; 110 | -------------------------------------------------------------------------------- /resources/externs.js: -------------------------------------------------------------------------------- 1 | Object.init = function() {}; 2 | Object.result = function() {}; 3 | Object.step = function() {}; 4 | Object.next = function() {}; 5 | Object.value; 6 | Object.done; 7 | Object.__transducers_reduced__; 8 | -------------------------------------------------------------------------------- /resources/node_externs.js: -------------------------------------------------------------------------------- 1 | Object.init = function() {}; 2 | Object.result = function() {}; 3 | Object.step = function() {}; 4 | Object.next = function() {}; 5 | Object.value; 6 | Object.done; 7 | Object.__transducers_reduced__; 8 | var module = {}; 9 | module.exports = {}; 10 | module.exports.reduced = function() {}; 11 | module.exports.isReduced = function() {}; 12 | module.exports.comp = function() {}; 13 | module.exports.complement = function() {}; 14 | module.exports.identity = function() {}; 15 | 16 | module.exports.map = function() {}; 17 | /** 18 | * @constructor 19 | */ 20 | module.exports.Map = function() {}; 21 | 22 | module.exports.filter = function() {}; 23 | /** 24 | * @constructor 25 | */ 26 | module.exports.Filter = function() {}; 27 | 28 | module.exports.remove = function() {}; 29 | /** 30 | * @constructor 31 | */ 32 | module.exports.Remove = function() {}; 33 | 34 | module.exports.keep = function() {}; 35 | /** 36 | * @constructor 37 | */ 38 | module.exports.Keep = function() {}; 39 | 40 | module.exports.keepIndexed = function() {}; 41 | /** 42 | * @constructor 43 | */ 44 | module.exports.KeepIndexed = function() {}; 45 | 46 | module.exports.take = function() {}; 47 | /** 48 | * @constructor 49 | */ 50 | module.exports.Take = function() {}; 51 | 52 | module.exports.takeWhile = function() {}; 53 | /** 54 | * @constructor 55 | */ 56 | module.exports.TakeWhile = function() {}; 57 | 58 | module.exports.takeNth = function() {}; 59 | /** 60 | * @constructor 61 | */ 62 | module.exports.TakeNth = function() {}; 63 | 64 | module.exports.drop = function() {}; 65 | /** 66 | * @constructor 67 | */ 68 | module.exports.Drop = function() {}; 69 | 70 | module.exports.dropWhile = function() {}; 71 | /** 72 | * @constructor 73 | */ 74 | module.exports.DropWhile = function() {}; 75 | 76 | module.exports.partitionBy = function() {}; 77 | /** 78 | * @constructor 79 | */ 80 | module.exports.PartitionBy = function() {}; 81 | 82 | module.exports.partitionAll = function() {}; 83 | /** 84 | * @constructor 85 | */ 86 | module.exports.PartitionAll = function() {}; 87 | 88 | module.exports.completing = function() {}; 89 | /** 90 | * @constructor 91 | */ 92 | module.exports.Completing = function() {}; 93 | 94 | module.exports.wrap = function() {}; 95 | /** 96 | * @constructor 97 | */ 98 | module.exports.Wrap = function() {}; 99 | 100 | module.exports.cat = function() {}; 101 | module.exports.mapcat = function() {}; 102 | module.exports.transduce = function() {}; 103 | module.exports.reduce = function() {}; 104 | module.exports.into = function() {}; 105 | module.exports.toFn = function() {}; 106 | module.exports.first = function() {}; 107 | module.exports.ensureReduced = function() {}; 108 | module.exports.unreduced = function() {}; 109 | module.exports.deref = function() {}; 110 | -------------------------------------------------------------------------------- /resources/prelude.txt: -------------------------------------------------------------------------------- 1 | // transducers-js $VERSION 2 | // http://github.com/cognitect-labs/transducers-js 3 | // 4 | // Copyright 2014-2015 Cognitect. All Rights Reserved. 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS-IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | -------------------------------------------------------------------------------- /src/com/cognitect/transducers.js: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2015 Cognitect. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS-IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | "use strict"; 16 | 17 | goog.provide("com.cognitect.transducers"); 18 | 19 | // ============================================================================= 20 | // Build target config 21 | 22 | /** @define {boolean} */ 23 | var TRANSDUCERS_DEV = true; 24 | 25 | /** @define {boolean} */ 26 | var TRANSDUCERS_NODE_TARGET = false; 27 | 28 | /** @define {boolean} */ 29 | var TRANSDUCERS_BROWSER_TARGET = false; 30 | 31 | /** @define {boolean} */ 32 | var TRANSDUCERS_BROWSER_AMD_TARGET = false; 33 | 34 | goog.scope(function() { 35 | 36 | /** 37 | * @class transducers 38 | */ 39 | var transducers = com.cognitect.transducers; 40 | 41 | // ========================================================================= 42 | // Definitions 43 | 44 | transducers.ITER_SYMBOL = typeof Symbol != "undefined" ? Symbol.iterator : "@@iterator"; 45 | 46 | /** 47 | * The Transducer protocol 48 | * @interface 49 | */ 50 | transducers.ITransformer = function() {}; 51 | /** 52 | * @returns {Object} 53 | */ 54 | transducers.ITransformer.prototype["@@transducer/init"] = function() {}; 55 | /** 56 | * @param {Object} result 57 | * @returns {Object} 58 | */ 59 | transducers.ITransformer.prototype["@@transducer/result"] = function(result) {}; 60 | /** 61 | * @param {Object} result 62 | * @param {Object} input 63 | * @returns {Object} 64 | */ 65 | transducers.ITransformer.prototype["@@transducer/step"] = function(result, input) {}; 66 | 67 | /** 68 | * The IReduced interface 69 | * @interface 70 | */ 71 | transducers.IReduced = function() {}; 72 | 73 | // ========================================================================= 74 | // Utilities 75 | 76 | transducers.isString = function(x) { 77 | return typeof x == "string"; 78 | }; 79 | 80 | if(typeof Array.isArray != "undefined") { 81 | transducers.isArray = function(x) { 82 | return Array.isArray(x); 83 | } 84 | } else { 85 | transducers.isArray = function(x) { 86 | return goog.typeOf(x) == "array"; 87 | } 88 | } 89 | 90 | transducers.isObject = function(x) { 91 | return goog.typeOf(x) == "object"; 92 | }; 93 | 94 | transducers.isIterable = function(x) { 95 | return x[transducers.ITER_SYMBOL] || x["next"]; 96 | }; 97 | 98 | transducers.slice = function(arrayLike, start, n) { 99 | if(n == null) { 100 | return Array.prototype.slice.call(arrayLike, start); 101 | } else { 102 | return Array.prototype.slice.call(arrayLike, start, n); 103 | } 104 | }; 105 | 106 | /** 107 | * Take a predicate function and return its complement. 108 | * @method transducers.complement 109 | * @param {function} a predicate function 110 | * @return {function} the complement predicate function 111 | * @example 112 | * var isEven = function(n) { return n % 2 == 0; }; 113 | * var isOdd = transducers.complement(isEven); 114 | */ 115 | transducers.complement = function(f) { 116 | return function(varArgs) { 117 | return !f.apply(null, transducers.slice(arguments, 0)); 118 | }; 119 | }; 120 | 121 | /** 122 | * @constructor 123 | * @implements {com.cognitect.transducers.ITransformer} 124 | */ 125 | transducers.Wrap = function(stepFn) { 126 | this.stepFn = stepFn; 127 | }; 128 | transducers.Wrap.prototype["@@transducer/init"] = function() { 129 | throw new Error("init not implemented"); 130 | }; 131 | transducers.Wrap.prototype["@@transducer/result"] = function(result) { 132 | return result; 133 | }; 134 | transducers.Wrap.prototype["@@transducer/step"] = function(result, input) { 135 | return this.stepFn(result, input); 136 | }; 137 | 138 | /** 139 | * Take a two-arity reducing function where the first argument is the 140 | * accumluation and the second argument is the next input and convert 141 | * it into a transducer transformer object. 142 | * @method transducers.wrap 143 | * @param {function} stepFn a two-arity reducing function 144 | * @return {com.cognitect.transducers.Wrap} a transducer transformer object 145 | * @example 146 | * var t = transducers; 147 | * var arrayPush = t.wrap(function(arr, x) { arr.push(x); return arr; }); 148 | */ 149 | transducers.wrap = function(stepFn) { 150 | if(typeof stepFn == "function") { 151 | return new transducers.Wrap(stepFn); 152 | } else { 153 | return stepFn; 154 | } 155 | }; 156 | 157 | // ========================================================================= 158 | // Main 159 | 160 | /** 161 | * @constructor 162 | * @implements {com.cognitect.transducers.IReduced} 163 | */ 164 | transducers.Reduced = function(value) { 165 | this["@@transducer/reduced"] = true; 166 | this["@@transducer/value"] = value; 167 | }; 168 | 169 | /** 170 | * Return a reduced value. Reduced values short circuit transduce. 171 | * @method transducers.reduced 172 | * @param {Object} x any JavaScript value 173 | * @return {com.cognitect.transducers.IReduced} a reduced value 174 | * @example 175 | * var reduced = transducers.reduced(1); 176 | */ 177 | transducers.reduced = function(x) { 178 | return new transducers.Reduced(x); 179 | }; 180 | 181 | /** 182 | * Check if a value is reduced. 183 | * @method transducers.isReduced 184 | * @param {Object} x any JavaScript value 185 | * @return {Boolean} true if the value is an instance of transducers.Reduced 186 | * false otherwise 187 | * @example 188 | * var t = transducers; 189 | * t.isReduced(1); // false 190 | * t.isReduced(t.reduced(1)); // true 191 | */ 192 | transducers.isReduced = function(x) { 193 | return (x instanceof transducers.Reduced) || (x && x["@@transducer/reduced"]); 194 | }; 195 | 196 | /** 197 | * Ensure that a value is reduced. If already reduced will not re-wrap. 198 | * @method transducers.ensureReduced 199 | * @param {Object} x any JavaScript value 200 | * @return {com.cognitect.transducers.IReduced} a reduced value. 201 | * @example 202 | * var t = transducers; 203 | * var x = t.ensureReduced(1); 204 | * var y = t.ensureReduced(x); 205 | * x === y; // true 206 | */ 207 | transducers.ensureReduced = function(x) { 208 | if(transducers.isReduced(x)) { 209 | return x; 210 | } else { 211 | return transducers.reduced(x); 212 | } 213 | }; 214 | 215 | transducers.deref = function(x) { 216 | return x["@@transducer/value"]; 217 | }; 218 | 219 | /** 220 | * Ensure a value is not reduced. Unwraps if reduced. 221 | * @method transducers.unreduced 222 | * @param {Object} x any JavaScript value 223 | * @return {Object} a JavaScript value 224 | * @example 225 | * var t = transducers; 226 | * var x = t.reduced(1); 227 | * t.unreduced(x); // 1 228 | * t.unreduced(t.unreduced(x)); // 1 229 | */ 230 | transducers.unreduced = function(x) { 231 | if(transducers.isReduced(x)) { 232 | return transducers.deref(x); 233 | } else { 234 | return x; 235 | } 236 | }; 237 | 238 | /** 239 | * Identity function. 240 | * @method transducers.identity 241 | * @param {Object} x any JavaScript value 242 | * @return {Object} a JavaScript value 243 | * @example 244 | * transducers.identity(1); // 1 245 | */ 246 | transducers.identity = function(x) { 247 | return x; 248 | }; 249 | 250 | /** 251 | * Function composition. Take N functions and return their composition. 252 | * @method transducers.comp 253 | * @param {Function} varArgs N functions 254 | * @result {Function} a function that represents the composition of the arguments. 255 | * @example 256 | * var t = transducers; 257 | * var inc = function(n) { return n + 1 }; 258 | * var double = function(n) { return n * 2 }; 259 | * var incDouble = t.comp(double, inc); 260 | * incDouble(3); // 8 261 | */ 262 | transducers.comp = function(varArgs) { 263 | var arglen = arguments.length; 264 | if(arglen == 2) { 265 | var f = arguments[0], 266 | g = arguments[1]; 267 | return function(varArgs) { 268 | return f(g.apply(null, transducers.slice(arguments, 0))); 269 | }; 270 | } if(arglen > 2) { 271 | return transducers.reduce(transducers.comp, arguments[0], transducers.slice(arguments, 1)); 272 | } else { 273 | if(TRANSDUCERS_DEV) { 274 | throw new Error("comp must given at least 2 arguments"); 275 | } 276 | } 277 | }; 278 | 279 | /** 280 | * @constructor 281 | * @implements {com.cognitect.transducers.ITransformer} 282 | */ 283 | transducers.Map = function(f, xf) { 284 | this.f = f; 285 | this.xf = xf; 286 | }; 287 | transducers.Map.prototype["@@transducer/init"] = function() { 288 | return this.xf["@@transducer/init"](); 289 | }; 290 | transducers.Map.prototype["@@transducer/result"] = function(result) { 291 | return this.xf["@@transducer/result"](result); 292 | }; 293 | transducers.Map.prototype["@@transducer/step"] = function(result, input) { 294 | return this.xf["@@transducer/step"](result, this.f(input)); 295 | }; 296 | 297 | /** 298 | * Mapping transducer constructor 299 | * @method transducers.map 300 | * @param {Function} f the mapping operation 301 | * @return {com.cognitect.transducers.Map} returns a mapping transducer 302 | * @example 303 | * var t = transducers; 304 | * var inc = function(n) { return n+1; }; 305 | * var xf = t.map(inc); 306 | * t.into([], xf, [1,2,3]); // [2,3,4] 307 | */ 308 | transducers.map = function(f) { 309 | if(TRANSDUCERS_DEV && (f == null)) { 310 | throw new Error("At least one argument must be supplied to map"); 311 | } else { 312 | return function(xf) { 313 | return new transducers.Map(f, xf); 314 | }; 315 | } 316 | }; 317 | 318 | /** 319 | * @constructor 320 | * @implements {com.cognitect.transducers.ITransformer} 321 | */ 322 | transducers.Filter = function(pred, xf) { 323 | this.pred = pred; 324 | this.xf = xf; 325 | }; 326 | transducers.Filter.prototype["@@transducer/init"] = function() { 327 | return this.xf["@@transducer/init"](); 328 | }; 329 | transducers.Filter.prototype["@@transducer/result"] = function(result) { 330 | return this.xf["@@transducer/result"](result); 331 | }; 332 | transducers.Filter.prototype["@@transducer/step"] = function(result, input) { 333 | if(this.pred(input)) { 334 | return this.xf["@@transducer/step"](result, input); 335 | } else { 336 | return result; 337 | } 338 | }; 339 | 340 | /** 341 | * Filtering transducer constructor 342 | * @method transducers.filter 343 | * @param {Function} pred a predicate function 344 | * @return {com.cognitect.transducers.Filter} returns a filtering transducer 345 | * @example 346 | * var t = transducers; 347 | * var isEven = function(n) { return n % 2 == 0; }; 348 | * var xf = t.filter(isEven); 349 | * t.into([], xf, [0,1,2,3,4]); // [0,2,4]; 350 | */ 351 | transducers.filter = function(pred) { 352 | if(TRANSDUCERS_DEV && (typeof pred != "function")) { 353 | throw new Error("filter must be given a function"); 354 | } else { 355 | return function(xf) { 356 | return new transducers.Filter(pred, xf); 357 | }; 358 | } 359 | }; 360 | 361 | /** 362 | * Similar to filter except the predicate is used to 363 | * eliminate values. 364 | * @method transducers.remove 365 | * @param {Function} pred a predicate function 366 | * @return {com.cognitect.transducers.Filter} returns a removing transducer 367 | * @example 368 | * var t = transducers; 369 | * var isEven = function(n) { return n % 2 == 0; }; 370 | * var xf = t.remove(isEven); 371 | * t.into([], xf, [0,1,2,3,4]); // [1,3]; 372 | */ 373 | transducers.remove = function(pred) { 374 | if(TRANSDUCERS_DEV && (typeof pred != "function")) { 375 | throw new Error("remove must be given a function"); 376 | } else { 377 | return transducers.filter(transducers.complement(pred)); 378 | } 379 | }; 380 | 381 | /** 382 | * @constructor 383 | * @implements {com.cognitect.transducers.ITransformer} 384 | */ 385 | transducers.Take = function(n, xf) { 386 | this.n = n; 387 | this.xf = xf; 388 | }; 389 | transducers.Take.prototype["@@transducer/init"] = function() { 390 | return this.xf["@@transducer/init"](); 391 | }; 392 | transducers.Take.prototype["@@transducer/result"] = function(result) { 393 | return this.xf["@@transducer/result"](result); 394 | }; 395 | transducers.Take.prototype["@@transducer/step"] = function(result, input) { 396 | if(this.n > 0) { 397 | result = this.xf["@@transducer/step"](result, input); 398 | } else { 399 | result = transducers.ensureReduced(result); 400 | } 401 | this.n--; 402 | return result; 403 | }; 404 | 405 | /** 406 | * A take transducer constructor. Will take n values before 407 | * returning a reduced result. 408 | * @method transducers.take 409 | * @param {Number} n the number of inputs to receive. 410 | * @return {com.cognitect.transducers.Take} a take transducer 411 | * @example 412 | * var t = transducers; 413 | * var xf = t.take(3); 414 | * t.into([], xf, [0,1,2,3,4,5]); // [0,1,2]; 415 | */ 416 | transducers.take = function(n) { 417 | if(TRANSDUCERS_DEV && (typeof n != "number")) { 418 | throw new Error("take must be given an integer"); 419 | } else { 420 | return function(xf) { 421 | return new transducers.Take(n, xf); 422 | }; 423 | } 424 | }; 425 | 426 | /** 427 | * @constructor 428 | * @implements {com.cognitect.transducers.ITransformer} 429 | */ 430 | transducers.TakeWhile = function(pred, xf) { 431 | this.pred = pred; 432 | this.xf = xf; 433 | }; 434 | transducers.TakeWhile.prototype["@@transducer/init"] = function() { 435 | return this.xf["@@transducer/init"](); 436 | }; 437 | transducers.TakeWhile.prototype["@@transducer/result"] = function(result) { 438 | return this.xf["@@transducer/result"](result); 439 | }; 440 | transducers.TakeWhile.prototype["@@transducer/step"] = function(result, input) { 441 | if(this.pred(input)) { 442 | return this.xf["@@transducer/step"](result, input); 443 | } else { 444 | return transducers.reduced(result); 445 | } 446 | }; 447 | 448 | /** 449 | * Like the take transducer except takes as long as the pred 450 | * return true for inputs. 451 | * @method transducers.takeWhile 452 | * @param {Function} pred a predicate function 453 | * @return {com.cognitect.transducers.TakeWhile} a takeWhile transducer 454 | * @example 455 | * var t = transducers; 456 | * var xf = t.takeWhile(function(n) { return n < 3; }); 457 | * t.into([], xf, [0,1,2,3,4,5]); // [0,1,2]; 458 | */ 459 | transducers.takeWhile = function(pred) { 460 | if(TRANSDUCERS_DEV && (typeof pred != "function")) { 461 | throw new Error("takeWhile must given a function"); 462 | } else { 463 | return function(xf) { 464 | return new transducers.TakeWhile(pred, xf); 465 | }; 466 | } 467 | }; 468 | 469 | /** 470 | * @constructor 471 | * @implements {com.cognitect.transducers.ITransformer} 472 | */ 473 | transducers.TakeNth = function(n, xf) { 474 | this.i = -1; 475 | this.n = n; 476 | this.xf = xf; 477 | }; 478 | transducers.TakeNth.prototype["@@transducer/init"] = function() { 479 | return this.xf["@@transducer/init"](); 480 | }; 481 | transducers.TakeNth.prototype["@@transducer/result"] = function(result) { 482 | return this.xf["@@transducer/result"](result); 483 | }; 484 | transducers.TakeNth.prototype["@@transducer/step"] = function(result, input) { 485 | this.i++; 486 | if((this.i % this.n) == 0) { 487 | return this.xf["@@transducer/step"](result, input); 488 | } else { 489 | return result; 490 | } 491 | }; 492 | 493 | /** 494 | * A transducer that takes every Nth input 495 | * @method transducers.takeNth 496 | * @param {Number} n an integer 497 | * @return {com.cognitect.transducers.TakeNth} a takeNth transducer 498 | * @example 499 | * var t = transducers; 500 | * var xf = t.takeNth(3); 501 | * t.into([], xf, [0,1,2,3,4,5]); // [2,5]; 502 | */ 503 | transducers.takeNth = function(n) { 504 | if(TRANSDUCERS_DEV && (typeof n != "number")) { 505 | throw new Error("takeNth must be given a number"); 506 | } else { 507 | return function(xf) { 508 | return new transducers.TakeNth(n, xf); 509 | }; 510 | } 511 | }; 512 | 513 | /** 514 | * @constructor 515 | * @implements {com.cognitect.transducers.ITransformer} 516 | */ 517 | transducers.Drop = function(n, xf) { 518 | this.n = n; 519 | this.xf = xf; 520 | }; 521 | transducers.Drop.prototype["@@transducer/init"] = function() { 522 | return this.xf["@@transducer/init"](); 523 | }; 524 | transducers.Drop.prototype["@@transducer/result"] = function(result) { 525 | return this.xf["@@transducer/result"](result); 526 | }; 527 | transducers.Drop.prototype["@@transducer/step"] = function(result, input) { 528 | if(this.n > 0) { 529 | this.n--; 530 | return result; 531 | } else { 532 | return this.xf["@@transducer/step"](result, input); 533 | } 534 | }; 535 | 536 | /** 537 | * A dropping transducer constructor 538 | * @method transducers.drop 539 | * @param {Number} n an integer, the number of inputs to drop. 540 | * @return {com.cognitect.transducers.Drop} a dropping transducer 541 | * @example 542 | * var t = transducers; 543 | * var xf = t.drop(3); 544 | * t.into([], xf, [0,1,2,3,4,5]); // [3,4,5]; 545 | */ 546 | transducers.drop = function(n) { 547 | if(TRANSDUCERS_DEV && (typeof n !== "number")) { 548 | throw new Error("drop must be given an integer"); 549 | } else { 550 | return function(xf) { 551 | return new transducers.Drop(n, xf); 552 | }; 553 | } 554 | }; 555 | 556 | /** 557 | * @constructor 558 | * @implements {com.cognitect.transducers.ITransformer} 559 | */ 560 | transducers.DropWhile = function(pred, xf) { 561 | this.drop = true; 562 | this.pred = pred; 563 | this.xf = xf; 564 | }; 565 | transducers.DropWhile.prototype["@@transducer/init"] = function() { 566 | return this.xf["@@transducer/init"](); 567 | }; 568 | transducers.DropWhile.prototype["@@transducer/result"] = function(result) { 569 | return this.xf["@@transducer/result"](result); 570 | }; 571 | transducers.DropWhile.prototype["@@transducer/step"] = function(result, input) { 572 | if(this.drop && this.pred(input)) { 573 | return result; 574 | } else { 575 | if(this.drop) this.drop = false; 576 | return this.xf["@@transducer/step"](result, input); 577 | } 578 | }; 579 | 580 | /** 581 | * A dropping transducer that drop inputs as long as 582 | * pred is true. 583 | * @method transducers.dropWhile 584 | * @param {Function} pred a predicate function 585 | * @return {com.cognitect.transducers.DropWhile} a dropWhile transducer 586 | * @example 587 | * var t = transducers; 588 | * var xf = t.dropWhile(function(n) { return n < 3; }); 589 | * t.into([], xf, [0,1,2,3,4,5]); // [3,4,5]; 590 | */ 591 | transducers.dropWhile = function(pred) { 592 | if(TRANSDUCERS_DEV && (typeof pred != "function")) { 593 | throw new Error("dropWhile must be given a function"); 594 | } else { 595 | return function(xf) { 596 | return new transducers.DropWhile(pred, xf); 597 | }; 598 | } 599 | }; 600 | 601 | transducers.NONE = {}; 602 | 603 | /** 604 | * @constructor 605 | * @implements {com.cognitect.transducers.ITransformer} 606 | */ 607 | transducers.PartitionBy = function(f, xf) { 608 | this.f = f; 609 | this.xf = xf; 610 | this.a = []; 611 | this.pval = transducers.NONE; 612 | }; 613 | transducers.PartitionBy.prototype["@@transducer/init"] = function() { 614 | return this.xf["@@transducer/init"]() 615 | }; 616 | transducers.PartitionBy.prototype["@@transducer/result"] = function(result) { 617 | if(this.a.length > 0) { 618 | result = transducers.unreduced(this.xf["@@transducer/step"](result, this.a)); 619 | this.a = []; 620 | } 621 | return this.xf["@@transducer/result"](result); 622 | }; 623 | transducers.PartitionBy.prototype["@@transducer/step"] = function(result, input) { 624 | var pval = this.pval, 625 | val = this.f(input); 626 | 627 | this.pval = val; 628 | 629 | // NOTE: we should probably allow someone to define 630 | // equality? - David 631 | if((pval == transducers.NONE) || 632 | (pval == val)) { 633 | this.a.push(input); 634 | return result; 635 | } else { 636 | var ret = this.xf["@@transducer/step"](result, this.a); 637 | this.a = []; 638 | if(!transducers.isReduced(ret)) { 639 | this.a.push(input); 640 | } 641 | return ret; 642 | } 643 | }; 644 | 645 | /** 646 | * A partitioning transducer. Collects inputs into 647 | * arrays as long as predicate remains true for contiguous 648 | * inputs. 649 | * @method transducers.partitionBy 650 | * @param {Function} f a partition function. When the result 651 | * for an input changes from the previous result will create 652 | * a partition. 653 | * @return {com.cognitect.transducers.PartitionBy} a partitionBy transducer 654 | * @example 655 | * var t = transducers; 656 | * var xf = t.partitionBy(function(x) { return typeof x == "string"; }); 657 | * t.into([], xf, [0,1,"foo","bar",2,3,"bar","baz"]); // [[0,1],["foo","bar"],[2,3],["bar","baz"]]; 658 | */ 659 | transducers.partitionBy = function(f) { 660 | if(TRANSDUCERS_DEV && (typeof f != "function")) { 661 | throw new Error("partitionBy must be given an function"); 662 | } else { 663 | return function(xf) { 664 | return new transducers.PartitionBy(f, xf); 665 | }; 666 | } 667 | }; 668 | 669 | /** 670 | * @constructor 671 | * @implements {com.cognitect.transducers.ITransformer} 672 | */ 673 | transducers.PartitionAll = function(n, xf) { 674 | this.n = n; 675 | this.xf = xf; 676 | this.a = []; 677 | }; 678 | transducers.PartitionAll.prototype["@@transducer/init"] = function() { 679 | return this.xf["@@transducer/init"](); 680 | }; 681 | transducers.PartitionAll.prototype["@@transducer/result"] = function(result) { 682 | if(this.a.length > 0) { 683 | result = transducers.unreduced(this.xf["@@transducer/step"](result, this.a)); 684 | this.a = []; 685 | } 686 | return this.xf["@@transducer/result"](result); 687 | }; 688 | transducers.PartitionAll.prototype["@@transducer/step"] = function(result, input) { 689 | this.a.push(input); 690 | if(this.n == this.a.length) { 691 | var a = this.a; 692 | this.a = []; 693 | return this.xf["@@transducer/step"](result, a); 694 | } else { 695 | return result; 696 | } 697 | }; 698 | 699 | /** 700 | * A partitioning transducer. Collects inputs into 701 | * arrays of size N. 702 | * @method transducers.partitionAll 703 | * @param {Number} n an integer 704 | * @return {com.cognitect.transducers.PartitionAll} a partitionAll transducer 705 | * @example 706 | * var t = transducers; 707 | * var xf = t.partitionAll(3); 708 | * t.into([], xf, [0,1,2,3,4,5]); // [[0,1,2],[3,4,5]] 709 | */ 710 | transducers.partitionAll = function(n) { 711 | if(TRANSDUCERS_DEV && (typeof n != "number")) { 712 | throw new Error("partitionAll must be given a number"); 713 | } else { 714 | return function(xf) { 715 | return new transducers.PartitionAll(n, xf); 716 | }; 717 | } 718 | }; 719 | 720 | /** 721 | * @constructor 722 | * @implements {com.cognitect.transducers.ITransformer} 723 | */ 724 | transducers.Keep = function(f, xf) { 725 | this.f = f; 726 | this.xf = xf; 727 | }; 728 | transducers.Keep.prototype["@@transducer/init"] = function() { 729 | return this.xf["@@transducer/init"](); 730 | }; 731 | transducers.Keep.prototype["@@transducer/result"] = function(result) { 732 | return this.xf["@@transducer/result"](result); 733 | }; 734 | transducers.Keep.prototype["@@transducer/step"] = function(result, input) { 735 | var v = this.f(input); 736 | if(v == null) { 737 | return result; 738 | } else { 739 | return this.xf["@@transducer/step"](result, input); 740 | } 741 | }; 742 | 743 | /** 744 | * A keeping transducer. Keep inputs as long as the provided 745 | * function does not return null or undefined. 746 | * @method transducers.keep 747 | * @param {Function} f a function 748 | * @return {com.cognitect.transducers.Keep} a keep transducer 749 | * @example 750 | * var t = transducers; 751 | * var xf = t.keep(function(x) { if(typeof x == "string") return "cool"; }); 752 | * t.into([], xf, [0,1,"foo",3,4,"bar"]); // ["foo","bar"] 753 | */ 754 | transducers.keep = function(f) { 755 | if(TRANSDUCERS_DEV && (typeof f != "function")) { 756 | throw new Error("keep must be given a function"); 757 | } else { 758 | return function(xf) { 759 | return new transducers.Keep(f, xf); 760 | }; 761 | } 762 | }; 763 | 764 | /** 765 | * @constructor 766 | * @implements {com.cognitect.transducers.ITransformer} 767 | */ 768 | transducers.KeepIndexed = function(f, xf) { 769 | this.i = -1; 770 | this.f = f; 771 | this.xf = xf; 772 | }; 773 | transducers.KeepIndexed.prototype["@@transducer/init"] = function() { 774 | return this.xf["@@transducer/init"](); 775 | }; 776 | transducers.KeepIndexed.prototype["@@transducer/result"] = function(result) { 777 | return this.xf["@@transducer/result"](result); 778 | }; 779 | transducers.KeepIndexed.prototype["@@transducer/step"] = function(result, input) { 780 | this.i++; 781 | var v = this.f(this.i, input); 782 | if(v == null) { 783 | return result; 784 | } else { 785 | return this.xf["@@transducer/step"](result, input); 786 | } 787 | }; 788 | 789 | /** 790 | * Like keep but the provided function will be passed the 791 | * index as the first argument and the value second. 792 | * @method transducers.keepIndexed 793 | * @param {Function} f a function 794 | * @return {com.cognitect.transducers.KeepIndexed} a keepIndexed transducer 795 | * @example 796 | * var t = transducers; 797 | * var xf = t.keepIndexed(function(i, x) { if(typeof x == "string") return "cool"; }); 798 | * t.into([], xf, [0,1,"foo",3,4,"bar"]); // ["foo","bar"] 799 | */ 800 | transducers.keepIndexed = function(f) { 801 | if(TRANSDUCERS_DEV && (typeof f != "function")) { 802 | throw new Error("keepIndexed must be given a function"); 803 | } else { 804 | return function(xf) { 805 | return new transducers.KeepIndexed(f, xf); 806 | }; 807 | } 808 | }; 809 | 810 | /** 811 | * Given a transformer returns a transformer which preserves 812 | * reduced by wrapping one more time. See cat. 813 | * @method transducers.preservingReduced 814 | * @param {com.cognitect.transducers.ITransformer} xf a transformer 815 | * @return {com.cognitect.transducers.ITransformer} a transformer which preserves reduced 816 | */ 817 | transducers.preservingReduced = function(xf) { 818 | return { 819 | "@@transducer/init": function() { 820 | return xf["@@transducer/init"](); 821 | }, 822 | "@@transducer/result": function(result) { 823 | return result; 824 | }, 825 | "@@transducer/step": function(result, input) { 826 | var ret = xf["@@transducer/step"](result, input); 827 | if(transducers.isReduced(ret)) { 828 | return transducers.reduced(ret); 829 | } else { 830 | return ret; 831 | } 832 | } 833 | }; 834 | }; 835 | 836 | /** 837 | * Given a transformer return a concatenating transformer 838 | * @method transducers.cat 839 | * @param {com.cognitect.transducers.ITransformer} xf a transformer 840 | * @return {com.cognitect.transducers.ITransformer} a concatenating transformer 841 | */ 842 | transducers.cat = function(xf) { 843 | var rxf = transducers.preservingReduced(xf); 844 | return { 845 | "@@transducer/init": function() { 846 | return xf["@@transducer/init"](); 847 | }, 848 | "@@transducer/result": function(result) { 849 | return xf["@@transducer/result"](result); 850 | }, 851 | "@@transducer/step": function(result, input) { 852 | return transducers.reduce(rxf, result, input); 853 | } 854 | }; 855 | }; 856 | 857 | /** 858 | * A mapping concatenating transformer 859 | * @method transducers.mapcat 860 | * @param {Function} f the mapping function 861 | * @return {com.cognitect.transducers.ITransformer} a mapping concatenating transducer 862 | * @example 863 | * var t = transducers; 864 | * var reverse = function(arr) { var arr = Array.prototype.slice.call(arr, 0); arr.reverse(); return arr; } 865 | * var xf = t.mapcat(reverse); 866 | * t.into([], xf, [[3,2,1],[6,5,4]]); // [1,2,3,4,5,6] 867 | */ 868 | transducers.mapcat = function(f) { 869 | return transducers.comp(transducers.map(f), transducers.cat); 870 | }; 871 | 872 | /** 873 | * @param {com.cognitect.transducers.ITransformer} xf 874 | * @param {Object} init 875 | * @param {String} string 876 | * @returns {*} 877 | */ 878 | transducers.stringReduce = function(xf, init, string) { 879 | var acc = init; 880 | for(var i = 0; i < string.length; i++) { 881 | acc = xf["@@transducer/step"](acc, string.charAt(i)); 882 | if(transducers.isReduced(acc)) { 883 | acc = transducers.deref(acc); 884 | break; 885 | } 886 | } 887 | return xf["@@transducer/result"](acc); 888 | }; 889 | 890 | /** 891 | * @param {com.cognitect.transducers.ITransformer} xf 892 | * @param {Object} init 893 | * @param {Array} array 894 | * @returns {*} 895 | */ 896 | transducers.arrayReduce = function(xf, init, array) { 897 | var acc = init; 898 | for(var i = 0; i < array.length; i++) { 899 | acc = xf["@@transducer/step"](acc, array[i]); 900 | if(transducers.isReduced(acc)) { 901 | acc = transducers.deref(acc); 902 | break; 903 | } 904 | } 905 | return xf["@@transducer/result"](acc); 906 | }; 907 | 908 | /** 909 | * @param {com.cognitect.transducers.ITransformer} xf 910 | * @param {Object} init 911 | * @param {Object} obj 912 | * @returns {*} 913 | */ 914 | transducers.objectReduce = function(xf, init, obj) { 915 | var acc = init; 916 | for(var p in obj) { 917 | if(obj.hasOwnProperty(p)) { 918 | acc = xf["@@transducer/step"](acc, [p, obj[p]]); 919 | if(transducers.isReduced(acc)) { 920 | acc = transducers.deref(acc); 921 | break; 922 | } 923 | } 924 | } 925 | return xf["@@transducer/result"](acc); 926 | }; 927 | 928 | /** 929 | * @param {com.cognitect.transducers.ITransformer} xf 930 | * @param {Object} init 931 | * @param {Object} iter 932 | * @returns {*} 933 | */ 934 | transducers.iterableReduce = function(xf, init, iter) { 935 | if(iter[transducers.ITER_SYMBOL]) { 936 | iter = iter[transducers.ITER_SYMBOL](); 937 | } 938 | 939 | var acc = init, 940 | step = iter.next(); 941 | 942 | while(!step.done) { 943 | acc = xf["@@transducer/step"](acc, step.value); 944 | if(transducers.isReduced(acc)) { 945 | acc = transducers.deref(acc); 946 | break; 947 | } 948 | step = iter.next(); 949 | } 950 | 951 | return xf["@@transducer/result"](acc); 952 | }; 953 | 954 | /** 955 | * Given a transducer, an intial value and a 956 | * collection - returns the reduction. 957 | * @method transducers.reduce 958 | * @param {com.cognitect.transducers.ITransformer|Function} xf a transducer or two-arity function 959 | * @param {Object} init any JavaScript value 960 | * @param {String|Array|Object} coll any iterable JavaScript value 961 | * @return {Object} an iterable JavaScript value: string, array 962 | * iterable, or object. 963 | */ 964 | transducers.reduce = function(xf, init, coll) { 965 | if(coll) { 966 | xf = typeof xf == "function" ? transducers.wrap(xf) : xf; 967 | if(transducers.isString(coll)) { 968 | return transducers.stringReduce(xf, init, coll); 969 | } else if(transducers.isArray(coll)) { 970 | return transducers.arrayReduce(xf, init, coll); 971 | } else if(transducers.isIterable(coll)) { 972 | return transducers.iterableReduce(xf, init, coll); 973 | } else if(transducers.isObject(coll)) { 974 | return transducers.objectReduce(xf, init, coll); 975 | } else { 976 | throw new Error("Cannot reduce instance of " + coll.constructor.name); 977 | } 978 | } 979 | }; 980 | 981 | /** 982 | * Given a transducer, a builder function, an initial value 983 | * and a iterable collection - returns the reduction. 984 | * collection - returns the reduction. 985 | * @method transducers.transduce 986 | * @param {com.cognitect.transducers.ITransformer} xf a transducer 987 | * @param {com.cognitect.transducers.ITransformer|Function} f a transducer or two-arity function 988 | * @param {Object=} init any JavaScript value 989 | * @param {String|Array|Object} coll any iterable JavaScript value 990 | * @return {Object} a JavaScript value. 991 | * @example 992 | * var t = transducers; 993 | * var inc = function(n) { return n+1; }; 994 | * var isEven = function(n) { return n % 2 == 0; }; 995 | * var apush = function(arr,x) { arr.push(x); return arr; }; 996 | * var xf = t.comp(t.map(inc),t.filter(isEven)); 997 | * t.transduce(xf, apush, [], [1,2,3,4]); // [2,4] 998 | */ 999 | transducers.transduce = function(xf, f, init, coll) { 1000 | if(arguments.length == 3) { 1001 | coll = init; 1002 | if(typeof f == "function") { 1003 | throw new Error("If given only three arguments f must satisfy "+ 1004 | "the ITransformer interface."); 1005 | } else { 1006 | init = f["@@transducer/init"](); 1007 | } 1008 | } 1009 | f = typeof f == "function" ? transducers.wrap(f) : f; 1010 | xf = xf(f); 1011 | return transducers.reduce(xf, init, coll); 1012 | }; 1013 | 1014 | transducers.stringAppend = function(string, x) { 1015 | return string + x; 1016 | }; 1017 | 1018 | transducers.arrayPush = function(arr, x) { 1019 | arr.push(x); 1020 | return arr; 1021 | }; 1022 | 1023 | transducers.addEntry = function(obj, entry) { 1024 | obj[entry[0]] = entry[1]; 1025 | return obj; 1026 | }; 1027 | 1028 | /** 1029 | * Reduce a value into the given empty value using a transducer. 1030 | * @method transducers.into 1031 | * @param {String|Array|Object} empty a JavaScript collection 1032 | * @param {com.cognitect.transducers.ITransformer} xf a transducer 1033 | * @param {Object} coll any iterable JavaScript value: array, string, 1034 | * object, or iterable. 1035 | * @return {Object} a JavaScript value. 1036 | * @example 1037 | * var t = transducers; 1038 | * var inc = function(n) { return n+1; }; 1039 | * var isEven = function(n) { return n % 2 == 0; }; 1040 | * var apush = function(arr,x) { arr.push(x); return arr; }; 1041 | * var xf = t.comp(t.map(inc),t.filter(isEven)); 1042 | * t.into([], xf, [1,2,3,4]); // [2,4] 1043 | */ 1044 | transducers.into = function(empty, xf, coll) { 1045 | if(transducers.isString(empty)) { 1046 | return transducers.transduce(xf, transducers.stringAppend, empty, coll); 1047 | } else if(transducers.isArray(empty)) { 1048 | return transducers.transduce(xf, transducers.arrayPush, empty, coll); 1049 | } else if(transducers.isObject(empty)) { 1050 | return transducers.transduce(xf, transducers.addEntry, empty, coll); 1051 | } 1052 | }; 1053 | 1054 | /** 1055 | * @constructor 1056 | * @implements {com.cognitect.transducers.ITransformer} 1057 | */ 1058 | transducers.Completing = function(cf, xf) { 1059 | this.cf = cf; 1060 | this.xf = xf; 1061 | }; 1062 | transducers.Completing.prototype["@@transducer/init"] = function() { 1063 | return this.xf["@@transducer/init"](); 1064 | }; 1065 | transducers.Completing.prototype["@@transducer/result"] = function(result) { 1066 | return this.cf(result); 1067 | }; 1068 | transducers.Completing.prototype["@@transducer/step"] = function(result, step) { 1069 | return this.xf["@@transducer/step"](result, step); 1070 | }; 1071 | 1072 | /** 1073 | * A completing transducer constructor. Useful to provide cleanup 1074 | * logic at the end of a reduction/transduction. 1075 | * @method transducers.completing 1076 | * @param {com.cognitect.transducers.ITransformer} xf a transducer 1077 | * @param {Function} cf a function to apply at the end of the reduction/transduction 1078 | * @return {com.cognitect.transducers.ITransformer} a transducer 1079 | */ 1080 | transducers.completing = function(xf, cf) { 1081 | xf = typeof xf == "function" ? transducers.wrap(xf) : xf; 1082 | cf = cf || transducers.identity; 1083 | if(TRANSDUCERS_DEV && (xf != null) && !transducers.isObject(xf)) { 1084 | throw new Error("completing must be given a transducer as first argument"); 1085 | } else { 1086 | return new transducers.Completing(cf, xf); 1087 | } 1088 | }; 1089 | 1090 | /** 1091 | * Convert a transducer transformer object into a function so 1092 | * that it can be used with existing reduce implementation i.e. native, 1093 | * Underscore, lodash 1094 | * @method transducers.toFn 1095 | * @param {com.cognitect.transducers.ITransformer} xf a transducer 1096 | * @param {Function} builder a function which take the accumulator and the 1097 | * the next input and return a new accumulator value. 1098 | * @return {Function} a two-arity function compatible with existing reduce 1099 | * implementations 1100 | * @example 1101 | * var t = transducers; 1102 | * var arr = [0,1,2,3,4,5], 1103 | * var apush = function(arr, x) { arr.push(x); return arr; }, 1104 | * var xf = t.comp(t.map(inc),t.filter(isEven)); 1105 | * arr.reduce(t.toFn(xf, apush), []); // [2,4,6] 1106 | */ 1107 | transducers.toFn = function(xf, builder) { 1108 | if(typeof builder == "function") { 1109 | builder = transducers.wrap(builder); 1110 | } 1111 | var rxf = xf(builder); 1112 | return rxf["@@transducer/step"].bind(rxf); 1113 | }; 1114 | 1115 | // ============================================================================= 1116 | // Utilities 1117 | 1118 | /** 1119 | * A transformer which simply returns the first input. 1120 | * @method transducers.first 1121 | * @return {com.cognitect.transducers.ITransformer} a transducer transformer 1122 | */ 1123 | transducers.first = transducers.wrap(function(result, input) { 1124 | return transducers.reduced(input); 1125 | }); 1126 | 1127 | // ============================================================================= 1128 | // Exporting 1129 | 1130 | if(TRANSDUCERS_BROWSER_TARGET) { 1131 | goog.exportSymbol("transducers.reduced", transducers.reduced); 1132 | goog.exportSymbol("transducers.isReduced", transducers.isReduced); 1133 | goog.exportSymbol("transducers.comp", transducers.comp); 1134 | goog.exportSymbol("transducers.complement", transducers.complement); 1135 | goog.exportSymbol("transducers.identity", transducers.identity); 1136 | goog.exportSymbol("transducers.transduce", transducers.transduce); 1137 | goog.exportSymbol("transducers.reduce", transducers.reduce); 1138 | 1139 | goog.exportSymbol("transducers.map", transducers.map); 1140 | goog.exportSymbol("transducers.Map", transducers.Map); 1141 | 1142 | goog.exportSymbol("transducers.filter", transducers.filter); 1143 | goog.exportSymbol("transducers.Filter", transducers.Filter); 1144 | 1145 | goog.exportSymbol("transducers.remove", transducers.remove); 1146 | goog.exportSymbol("transducers.Remove", transducers.Remove); 1147 | 1148 | goog.exportSymbol("transducers.keep", transducers.keep); 1149 | goog.exportSymbol("transducers.Keep", transducers.Keep); 1150 | 1151 | goog.exportSymbol("transducers.keepIndexed", transducers.keepIndexed); 1152 | goog.exportSymbol("transducers.KeepIndexed", transducers.KeepIndexed); 1153 | 1154 | goog.exportSymbol("transducers.take", transducers.take); 1155 | goog.exportSymbol("transducers.Take", transducers.Take); 1156 | 1157 | goog.exportSymbol("transducers.takeWhile", transducers.takeWhile); 1158 | goog.exportSymbol("transducers.TakeWhile", transducers.TakeWhile); 1159 | 1160 | goog.exportSymbol("transducers.takeNth", transducers.takeNth); 1161 | goog.exportSymbol("transducers.TakeNth", transducers.TakeNth); 1162 | 1163 | goog.exportSymbol("transducers.drop", transducers.drop); 1164 | goog.exportSymbol("transducers.Drop", transducers.Drop); 1165 | 1166 | goog.exportSymbol("transducers.dropWhile", transducers.dropWhile); 1167 | goog.exportSymbol("transducers.DropWhile", transducers.DropWhile); 1168 | 1169 | goog.exportSymbol("transducers.partitionBy", transducers.partitionBy); 1170 | goog.exportSymbol("transducers.PartitionBy", transducers.PartitionBy); 1171 | 1172 | goog.exportSymbol("transducers.partitionAll", transducers.partitionAll); 1173 | goog.exportSymbol("transducers.PartitionAll", transducers.PartitionAll); 1174 | 1175 | goog.exportSymbol("transducers.completing", transducers.completing); 1176 | goog.exportSymbol("transducers.Completing", transducers.Completing); 1177 | 1178 | goog.exportSymbol("transducers.wrap", transducers.wrap); 1179 | goog.exportSymbol("transducers.Wrap", transducers.Wrap); 1180 | 1181 | goog.exportSymbol("transducers.cat", transducers.cat); 1182 | goog.exportSymbol("transducers.mapcat", transducers.mapcat); 1183 | 1184 | goog.exportSymbol("transducers.into", transducers.into); 1185 | goog.exportSymbol("transducers.toFn", transducers.toFn); 1186 | goog.exportSymbol("transducers.first", transducers.first); 1187 | goog.exportSymbol("transducers.ensureReduced", transducers.ensureReduced); 1188 | goog.exportSymbol("transducers.unreduced", transducers.unreduced); 1189 | goog.exportSymbol("transducers.deref", transducers.deref); 1190 | } 1191 | 1192 | if(TRANSDUCERS_NODE_TARGET) { 1193 | module.exports = { 1194 | reduced: transducers.reduced, 1195 | isReduced: transducers.isReduced, 1196 | comp: transducers.comp, 1197 | complement: transducers.complement, 1198 | identity: transducers.identity, 1199 | 1200 | map: transducers.map, 1201 | Map: transducers.Map, 1202 | 1203 | filter: transducers.filter, 1204 | Filter: transducers.Filter, 1205 | 1206 | remove: transducers.remove, 1207 | Remove: transducers.Remove, 1208 | 1209 | keep: transducers.keep, 1210 | Keep: transducers.Keep, 1211 | 1212 | keepIndexed: transducers.keepIndexed, 1213 | KeepIndexed: transducers.KeepIndexed, 1214 | 1215 | take: transducers.take, 1216 | Take: transducers.Take, 1217 | 1218 | takeWhile: transducers.takeWhile, 1219 | TakeWhile: transducers.TakeWhile, 1220 | 1221 | takeNth: transducers.takeNth, 1222 | TakeNth: transducers.TakeNth, 1223 | 1224 | drop: transducers.drop, 1225 | Drop: transducers.Drop, 1226 | 1227 | dropWhile: transducers.dropWhile, 1228 | DropWhile: transducers.DropWhile, 1229 | 1230 | partitionBy: transducers.partitionBy, 1231 | PartitionBy: transducers.PartitionBy, 1232 | 1233 | partitionAll: transducers.partitionAll, 1234 | PartitionAll: transducers.PartitionAll, 1235 | 1236 | completing: transducers.completing, 1237 | Completing: transducers.Completing, 1238 | 1239 | wrap: transducers.wrap, 1240 | Wrap: transducers.Wrap, 1241 | 1242 | cat: transducers.cat, 1243 | mapcat: transducers.mapcat, 1244 | 1245 | transduce: transducers.transduce, 1246 | reduce: transducers.reduce, 1247 | into: transducers.into, 1248 | toFn: transducers.toFn, 1249 | first: transducers.first, 1250 | 1251 | ensureReduced: transducers.ensureReduced, 1252 | unreduced: transducers.unreduced, 1253 | deref: transducers.deref 1254 | }; 1255 | } 1256 | 1257 | }); 1258 | -------------------------------------------------------------------------------- /src/com/cognitect/transducers_amd.js: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2015 Cognitect. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS-IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | "use strict"; 16 | 17 | goog.provide("com.cognitect.transducers.amd"); 18 | goog.require("com.cognitect.transducers"); 19 | 20 | if(TRANSDUCERS_BROWSER_AMD_TARGET) { 21 | define("transducers", [], function() { 22 | return com.cognitect.transducers; 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /test/tests.js: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2015 Cognitect. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS-IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | "use strict"; 16 | 17 | require("../deps/closure-library/closure/goog/bootstrap/nodejs.js"); 18 | require("../deps/closure-library/closure/goog/transducers_deps.js"); 19 | 20 | goog.require("com.cognitect.transducers"); 21 | 22 | var Immutable = require("immutable"), 23 | t = com.cognitect.transducers, 24 | comp = t.comp, 25 | identity = t.identity, 26 | complement = t.complement, 27 | transduce = t.transduce, 28 | reduce = t.reduce, 29 | map = t.map, 30 | filter = t.filter, 31 | remove = t.remove, 32 | keep = t.keep, 33 | keepIndexed = t.keepIndexed, 34 | mapcat = t.mapcat, 35 | take = t.take, 36 | takeWhile = t.takeWhile, 37 | takeNth = t.takeNth, 38 | drop = t.drop, 39 | dropWhile = t.dropWhile, 40 | into = t.into, 41 | partitionBy = t.partitionBy, 42 | partitionAll = t.partitionAll, 43 | completing = t.completing, 44 | toFn = t.toFn, 45 | first = t.first, 46 | wrap = t.wrap; 47 | 48 | var smallArray = [0,1,2,3,4,5,6,7,8,9]; 49 | 50 | var inc = function(n) { 51 | return n+1; 52 | }; 53 | 54 | var isEven = function(n) { 55 | return (n % 2) == 0; 56 | }; 57 | 58 | var square = function(n) { 59 | return n*n; 60 | }; 61 | 62 | var keepEven = function(n) { 63 | return (n % 2 == 0) ? true : null; 64 | }; 65 | 66 | var keepIdxFn = function(i, x) { 67 | switch(i) { 68 | case 0: 69 | case 2: 70 | case 3: 71 | case 6: 72 | case 7: 73 | return true; 74 | break; 75 | default: 76 | return null; 77 | break; 78 | } 79 | }; 80 | 81 | var lessThanFive = function(n) { 82 | return n < 5; 83 | }; 84 | 85 | var arrayClone = function(arr) { 86 | return Array.prototype.slice.call(arr, 0); 87 | }; 88 | 89 | var reverse = function(arr) { 90 | return arrayClone(arr).reverse(); 91 | }; 92 | 93 | var arrayPush = function(arr, x) { 94 | arr.push(x); 95 | return arr; 96 | }; 97 | 98 | exports.testIdentity = function(test) { 99 | test.ok(identity(1) === 1); 100 | test.done(); 101 | }; 102 | 103 | exports.testMap = function(test) { 104 | var res = transduce(map(inc), arrayPush, [], smallArray); 105 | test.deepEqual(res, smallArray.map(inc)); 106 | test.done(); 107 | }; 108 | 109 | exports.testFilter = function(test) { 110 | var res = transduce(filter(isEven), arrayPush, [], smallArray); 111 | test.deepEqual(res, smallArray.filter(isEven)); 112 | test.done(); 113 | }; 114 | 115 | exports.testRemove = function(test) { 116 | var res = transduce(remove(isEven), arrayPush, [], smallArray); 117 | test.deepEqual(res, smallArray.filter(complement(isEven))); 118 | test.done(); 119 | }; 120 | 121 | exports.testKeep = function(test) { 122 | var res = transduce(keep(keepEven), arrayPush, [], smallArray); 123 | test.deepEqual(res, smallArray.filter(isEven)); 124 | test.done(); 125 | }; 126 | 127 | exports.testKeepIndexed = function(test) { 128 | var res = transduce(keepIndexed(keepIdxFn), arrayPush, [], smallArray); 129 | test.deepEqual(res, [0, 2, 3, 6, 7]); 130 | test.done(); 131 | }; 132 | 133 | exports.testMapCat = function(test) { 134 | var res = transduce(mapcat(reverse), arrayPush, [], [[3,2,1],[6,5,4],[9,8,7]]); 135 | test.deepEqual(res, [1,2,3,4,5,6,7,8,9]); 136 | test.done(); 137 | }; 138 | 139 | exports.testInto = function(test) { 140 | var xf = map(inc), 141 | res = into([], xf, smallArray); 142 | test.deepEqual(res, [1,2,3,4,5,6,7,8,9,10]); 143 | test.done(); 144 | }; 145 | 146 | exports.testTake = function(test) { 147 | var res = transduce(take(5), arrayPush, [], smallArray); 148 | test.deepEqual(res, [0,1,2,3,4]); 149 | test.done(); 150 | }; 151 | 152 | exports.testTakeWhile = function(test) { 153 | var res = transduce(takeWhile(lessThanFive), arrayPush, [], smallArray); 154 | test.deepEqual(res, [0,1,2,3,4]); 155 | test.done(); 156 | }; 157 | 158 | exports.testTakeNth = function(test) { 159 | var res = transduce(takeNth(2), arrayPush, [], smallArray); 160 | test.deepEqual(res, smallArray.filter(isEven)); 161 | test.done(); 162 | }; 163 | 164 | exports.testDrop = function(test) { 165 | var res = transduce(drop(5), arrayPush, [], smallArray); 166 | test.deepEqual(res, [5,6,7,8,9]); 167 | test.done(); 168 | }; 169 | 170 | exports.testDropWhile = function(test) { 171 | var res = transduce(dropWhile(lessThanFive), arrayPush, [], smallArray); 172 | test.deepEqual(res, [5,6,7,8,9]); 173 | test.done(); 174 | }; 175 | 176 | exports.testPartitionBy = function(test) { 177 | var res0 = transduce(partitionBy(lessThanFive), arrayPush, [], smallArray); 178 | test.deepEqual(res0, [[0,1,2,3,4],[5,6,7,8,9]]); 179 | 180 | var arr = [1, 1, 1, 2, 2, 3, 3, 3, 3]; 181 | var res1 = into([], comp(partitionBy(function(x) { return x; }), take(2)), arr); 182 | test.deepEqual(res1, [[1,1,1],[2,2]]); 183 | 184 | test.done(); 185 | }; 186 | 187 | exports.testPartitionAll = function(test) { 188 | var res0 = transduce(partitionAll(2), arrayPush, [], smallArray); 189 | test.deepEqual(res0, [[0,1],[2,3],[4,5],[6,7],[8,9]]); 190 | 191 | var res1 = into([], comp(partitionAll(2), take(2)), smallArray); 192 | test.deepEqual(res1, [[0,1],[2,3]]); 193 | 194 | test.done(); 195 | }; 196 | 197 | exports.testComp = function(test) { 198 | var xf = comp(filter(isEven),map(inc),map(square)), 199 | res = transduce(xf, arrayPush, [], smallArray); 200 | test.deepEqual(res, [1,9,25,49,81]); 201 | test.done(); 202 | }; 203 | 204 | exports.testToFn = function(test) { 205 | var f = toFn(comp(filter(isEven),map(inc)),arrayPush), 206 | res = smallArray.reduce(f, []); 207 | test.deepEqual(res, [1,3,5,7,9]); 208 | test.done(); 209 | }; 210 | 211 | exports.testFirst = function(test) { 212 | test.equal(reduce(first, null, [1,2,3]), 1); 213 | test.equal(reduce(map(inc)(first), null, [1,2,3]), 2); 214 | test.done(); 215 | }; 216 | 217 | exports.testCompleting = function(test) { 218 | var arrWrap = function(arr) { return {value: arr}; }, 219 | arrayPushWrap = completing(arrayPush, arrWrap), 220 | xf = comp(map(inc), filter(isEven)); 221 | 222 | test.deepEqual(transduce(xf, arrayPushWrap, [], [0,1,2,3]), {value: [2,4]}); 223 | 224 | test.done(); 225 | }; 226 | 227 | var range = function(n) { 228 | var i = 0; 229 | return { 230 | next: function() { 231 | if(i < n) { 232 | var ret = {done: false, value: i}; 233 | i++; 234 | return ret; 235 | } else { 236 | return {done: true, value: null} 237 | } 238 | } 239 | }; 240 | }; 241 | 242 | exports.testIterableReduce = function(test) { 243 | var ints = range(10), 244 | res = transduce(map(inc), arrayPush, [], ints); 245 | 246 | test.deepEqual(res, [1,2,3,4,5,6,7,8,9,10]); 247 | 248 | test.done(); 249 | }; 250 | 251 | exports.testFirstTakeWhile = function(test) { 252 | test.equal(transduce(dropWhile(lessThanFive), first, null, range(10)), 5); 253 | test.done(); 254 | }; 255 | 256 | exports.testTransduceNoInit = function(test) { 257 | var arrayBuilder = { 258 | "@@transducer/init": function() { return []; }, 259 | "@@transducer/result": function(result) { 260 | return result; 261 | }, 262 | "@@transducer/step": function(result,input) { 263 | result.push(input); 264 | return result; 265 | } 266 | }; 267 | 268 | var ints = range(10), 269 | res = transduce(map(inc), arrayBuilder, ints); 270 | 271 | test.deepEqual(res, [1,2,3,4,5,6,7,8,9,10]); 272 | 273 | test.done(); 274 | }; 275 | 276 | exports.testImmutableList = function(test) { 277 | var inc = function(n) { return n + 1;}, 278 | isEven = function(n) { return n % 2 == 0; }, 279 | sum = function(a,b) { return a+b;}, 280 | bigVec = Immutable.List(); 281 | 282 | for(var i = 0; i < 1000000; i++) { 283 | bigVec = bigVec.push(i); 284 | } 285 | 286 | // faster with transducers 287 | var xf = comp(map(inc),filter(isEven)); 288 | test.equal(bigVec.map(inc).filter(isEven).reduce(sum), transduce(xf, sum, 0, bigVec)); 289 | 290 | test.done(); 291 | }; -------------------------------------------------------------------------------- /transducers-js.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /yuidoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "transducers-js", 3 | "description": "A Transducers implementation for JavaScript", 4 | "version": "0.4.135", 5 | "url": "http://github.com/cognitect-labs/transducers-js", 6 | "options": { 7 | "outdir": "docs" 8 | } 9 | } 10 | --------------------------------------------------------------------------------