├── .gitignore ├── License ├── README.md ├── docs ├── CNAME ├── _config.yml ├── beginner.html ├── extentions.html ├── index.html ├── index_files │ ├── XRegExp.js.download │ ├── bootstrap-alert.js.download │ ├── bootstrap-button.js.download │ ├── bootstrap-carousel.js.download │ ├── bootstrap-collapse.js.download │ ├── bootstrap-dropdown.js.download │ ├── bootstrap-modal.js.download │ ├── bootstrap-popover.js.download │ ├── bootstrap-responsive.css │ ├── bootstrap-scrollspy.js.download │ ├── bootstrap-tab.js.download │ ├── bootstrap-tooltip.js.download │ ├── bootstrap-transition.js.download │ ├── bootstrap-typeahead.js.download │ ├── bootstrap.css │ ├── ga.js.download │ ├── jquery.js.download │ ├── saved_resource(1).html │ ├── saved_resource.html │ ├── shBrushJScript.js.download │ ├── shCore.js.download │ ├── taffydbboxV3.jpg │ ├── timeline.619317855a58aa2366562a395f9e40ef.js.download │ └── widgets.js.download ├── working_with_data.html └── writing_queries.html ├── package.json ├── taffy-min.js ├── taffy.js └── test └── t.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .git 3 | *.swp 4 | npm-debug.log 5 | node_modules 6 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | Copyright 2018 joe@taffydb.com 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TaffyDB (taffy.js) 2 | 3 | TaffyDB is an open source JavaScript library that provides powerful 4 | in-memory database capabilities to both browser and server applications. 5 | 6 | ## Introduction 7 | 8 | Have you ever noticed how JavaScript object literals look a lot like 9 | records? And that if you wrap a group of them up in an array you have 10 | something that looks a lot like a database table? We did too. 11 | We created TaffyDB easily and efficiently manipulate these 'tables' 12 | with a uniform and familiar SQL-like interface. 13 | 14 | We use TaffyDB instead of ad-hoc data manipulation routines throughout 15 | our applications. This reduces development time, improves performance, 16 | simplifies maintenance, *and* increases quality. 17 | 18 | Please see the [official website](http://www.taffydb.com) for more 19 | complete documentation. 20 | 21 | ## What makes it sticky 22 | 23 | - Extremely fast 24 | - Powerful JavaScript-centric data selection engine 25 | - SQL inspired features such as insert, update, unique, count, and more 26 | - Robust cross browser support 27 | - Easily extended with your own functions 28 | - Compatible with any DOM library (jQuery, YUI, Dojo, etc) 29 | 30 | TaffyDB is compatible with all modern browsers: IE9+, FF3+, Safari 5+, 31 | and Chrome 1.0+. It also works in NodeJS 0.10+. 32 | 33 | ## Create a DB 34 | Just pass in a JSON array: 35 | 36 | ```js 37 | var product_db = TAFFY([ 38 | { "item" : 1, 39 | "name" : "Blue Ray Player", 40 | "price" : 99.99 41 | }, 42 | { "item" : 2, 43 | "name" : "3D TV", 44 | "price" : 1799.99 45 | } 46 | ]); 47 | ``` 48 | 49 | ## Example queries 50 | 51 | ```js 52 | // where item is equal to 1 53 | var item1 = products({item:1}); 54 | 55 | // where price is less than 100 56 | var lowPricedItems = products({price:{lt:100}}); 57 | 58 | // where name is like "Blue Ray" 59 | var blueRayPlayers = products({name:{like:"Blue Ray"}}); 60 | 61 | // get first record 62 | products().first(); 63 | 64 | // get last record 65 | products().last(); 66 | ``` 67 | 68 | ## Example record manipulation 69 | 70 | ```js 71 | // update the price of the Blue Ray Player to 89.99 72 | products({item:1}).update({price:89.99}); 73 | 74 | // loop over the records and call a function 75 | products().each(function (r) {alert(r.name)}); 76 | 77 | // sort the records by price descending 78 | products.sort("price desc"); 79 | 80 | // select only the item names into an array 81 | products().select("name"); // returns ["3D TV","Blue Ray Player"] 82 | 83 | // Inject values from a record into a string template. 84 | // Row value will be set to "3D TV17999.99" 85 | var row = products({item:2}) 86 | .supplant("{name}{price}"); 87 | ``` 88 | 89 | ## Use it in Node.JS 90 | TaffyDB is easy to use in Node.JS. Simply install using `npm` and `require` the 91 | package: 92 | 93 | ```js 94 | $ npm install --production taffy 95 | 96 | # and then in your code 97 | TAFFY = require( 'taffy' ).taffy; 98 | ``` 99 | 100 | The automated regression test file `nodeunit_suite.js` is an excellent 101 | example. 102 | 103 | ## Help improve taffydb 104 | 105 | TaffyDB has been used and refined for years for numerous production tools and 106 | commercial products. It is therefore is quite stable and reliable. However, 107 | we want expand our regression test coverage so we can easily improve the code 108 | with the confidence that we are unlikely to break exising capabilities. 109 | 110 | ### Getting started with development 111 | 112 | Run the `install_dev.sh` script to install development utilities such as `jslint`, 113 | `nodeunit`, and `uglifyjs` to the `bin` directory. 114 | 115 | ```js 116 | ./install_dev.sh 117 | ``` 118 | 119 | 120 | ### Running regression tests 121 | Running the nodeunit regression test suite is simple: 122 | 123 | ```js 124 | cd taffydb 125 | ./install_dev.sh # as above 126 | 127 | bin/nodeunit ./nodeunit_suite.js 128 | ``` 129 | 130 | Please do not send a pull request unless your changes have passed these 131 | tests. We check, you know :) 132 | 133 | ### Adding to regression tests 134 | We wish to substantially expand the number of tests, and your 135 | help is welcome! The code, `nodeunit_suite.js`, should be easy to adjust. 136 | Pull requests that include regression test inclusions are very much 137 | appreciated. Alternately, if you just send along a test scenario, we'd be 138 | happy to include it in the suite, time permitting. 139 | 140 | ## Documentation, support, updates 141 | View more docs and examples, get support, and get notified of updates: 142 | 143 | Web: http://taffydb.com 144 | 145 | ## Software License Agreement (BSD License) 146 | Copyright (c) 147 | All rights reserved. 148 | 149 | 150 | Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following condition is met: 151 | 152 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 153 | 154 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 155 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 156 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | taffydb.com -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate -------------------------------------------------------------------------------- /docs/beginner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | TaffyDB - Beginner's Guide 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 53 | 54 | 55 | 56 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 80 | 81 | 82 | 83 | 84 | 85 | 113 | 114 |
115 |
116 |
117 | 118 | 137 | 138 |
139 |
140 |
141 | 142 | 143 |

Beginner's Guide

144 | 145 |

TaffyDB is very easy to get started with. This brief turtoial will introduce you to a few of the core concepts and should be enough to get started even if you aren't already a web developer.

146 | 147 |

Step 1: Creating a quick sandbox

148 |

It is recmmended that you download and use your own copy of TaffyDB, but for the purposes of playing around you can use the latest version right off of GitHub. If you have never created a web page before you can simply create a text document, include the code below, and save it to your desktop as test.html.

149 |
<html>
150 | 	<head>
151 | 		<script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script>
152 | 	</head>
153 | 	<body>
154 | 	</body>
155 | 				
156 | </html>
157 |

The script tag imports TaffyDB right onto the page.

158 | 159 |

Step 2: Your First DB

160 |

Let's create a DB to store some city information. You'll need another script tag and you'll be writing JavaScript.

161 |
<html>
162 | 	<head>
163 | 		<script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script>
164 | 		<script>
165 | 
166 | 		var cities = TAFFY();
167 | 
168 | 		</script>
169 | 	</head>
170 | 	<body>
171 | 	</body>
172 | 				
173 | </html>
174 |

Step 3: Adding records

175 |

You can add records on creation and via the .insert() method. Below we are doing both.

176 |
<html>
177 | 	<head>
178 | 		<script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script>
179 | 		<script>
180 | 
181 | 		var cities = TAFFY([{name:"New York",state:"WA"},{name:"Las Vegas",state:"NV"},{name:"Boston",state:"MA"}]);
182 | 	
183 | 		cities.insert({name:"Portland",state:"OR"});
184 | 
185 | 		</script>
186 | 	</head>
187 | 	<body>
188 | 	</body>
189 | 				
190 | </html>
191 |

Step 4: Your first query

192 |

Our city db is itself a function that accepts a filter object (an object that will be matched to records). Let's query for Boston. We will alert the .count() method to see our results.

193 |
<html>
194 | 	<head>
195 | 		<script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script>
196 | 		<script>
197 | 
198 | 		var cities = TAFFY([{name:"New York",state:"WA"},{name:"Las Vegas",state:"NV"},{name:"Boston",state:"MA"}]);
199 | 	
200 | 		cities.insert({name:"Portland",state:"OR"});
201 | 
202 | 		alert(cities({name:"Boston"}).count());
203 | 
204 | 		</script>
205 | 	</head>
206 | 	<body>
207 | 	</body>
208 | 				
209 | </html>
210 | 211 |

Step 5: Chaining methods

212 |

You can chain together. Below we will get the first two records from the DB and use the .each() method to alert their names.

213 |
<html>
214 | 	<head>
215 | 		<script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script>
216 | 		<script>
217 | 
218 | 		var cities = TAFFY([{name:"New York",state:"WA"},{name:"Las Vegas",state:"NV"},{name:"Boston",state:"MA"}]);
219 | 	
220 | 		cities.insert({name:"Portland",state:"OR"});
221 | 
222 | 		cities().limit(2).each(function (r) {alert(r.name)});
223 | 
224 | 		</script>
225 | 	</head>
226 | 	<body>
227 | 	</body>
228 | 				
229 | </html>
230 | 231 |

Step 6: Updating data

232 |

You may have noticed that New York is in the wrong state. Let's fix that and alert the new state.

233 |
<html>
234 | 	<head>
235 | 		<script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script>
236 | 		<script>
237 | 
238 | 		var cities = TAFFY([{name:"New York",state:"WA"},{name:"Las Vegas",state:"NV"},{name:"Boston",state:"MA"}]);
239 | 	
240 | 		cities.insert({name:"Portland",state:"OR"});
241 | 
242 | 		cities({name:"New York"}).update({state:"NY"});
243 | 
244 | 		alert(cities({name:"New York"}).first().state);
245 | 
246 | 
247 | 		</script>
248 | 	</head>
249 | 	<body>
250 | 	</body>
251 | 				
252 | </html>
253 | 254 |

Step 7: Sorting

255 |

Sorting is a big part of TaffyDB using the .order() method.

256 |
<html>
257 | 	<head>
258 | 		<script src="https://github.com/typicaljoe/taffydb/raw/master/taffy.js"></script>
259 | 		<script>
260 | 
261 | 		var cities = TAFFY([{name:"New York",state:"WA"},{name:"Las Vegas",state:"NV"},{name:"Boston",state:"MA"}]);
262 | 	
263 | 		cities.insert({name:"Portland",state:"OR"});
264 | 
265 | 		alert(cities().order("name").first().name);
266 | 
267 | 		</script>
268 | 	</head>
269 | 	<body>
270 | 	</body>
271 | 				
272 | </html>
273 |

What's next

274 |

There are a lot of other methods you can use against your data. Some highlights include .remove() to delete records, .get() to get an array of records, and .supplant to merge records with a string template. Continue to browse the docs for more ways to use TaffyDB.

275 | 276 | 277 | 278 | 279 |
280 |
281 | 282 | 283 | 284 |
285 | 286 | 287 |
288 |
289 | 290 |
291 | 292 | 295 | 296 |
297 | 298 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | -------------------------------------------------------------------------------- /docs/extentions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | TaffyDB - Extensions 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 53 | 54 | 55 | 56 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 80 | 81 | 82 | 83 | 84 | 85 | 113 | 114 |
115 |
116 |
117 | 118 | 137 | 138 |
139 |
140 |
141 | 142 | 143 |

Extending TaffyDB

144 | 145 |

TaffyDB is easy to extend. Simply use the extend method to add a new method to all TaffyDB collections on your page.

146 |

Here is an example that creates an "avg" method that takes a column and returns the avg value.

147 |
// Create a new empty database
148 | TAFFY.extend("avg",function (c) {
149 | 	// This runs the query or returns the results if it has already run
150 | 	this.context({
151 |            results: this.getDBI().query(this.context())
152 |     });
153 |     // setup the sum
154 |     var total = 0;
155 |     // loop over every record in the results and sum up the column.
156 |     TAFFY.each(this.context().results,function (r) {
157 | 		total = total + r[c];
158 |     })
159 |     
160 |     // divide the total by the number of records and return
161 |     return total/this.context().results.length;
162 | });
163 | 
164 |

What can you build?

165 | 166 | 167 |
168 |
169 | 170 | 171 | 172 |
173 | 174 | 175 |
176 |
177 | 178 |
179 | 180 | 183 | 184 |
185 | 186 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | TaffyDB - The JavaScript Database 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 53 | 54 | 55 | 56 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 80 | 81 | 82 | 83 | 84 | 85 | 113 | 114 |
115 |
116 |
117 | 118 | 137 | 138 |
139 |
140 |
141 | 142 | 143 |

The JavaScript Database

144 | 145 |

An opensouce library that brings database features into your JavaScript applications.

146 |

Introduction

147 | 148 |

How you ever noticed how JavaScript object literals look a lot like records? And that if you wrap a group of them up in an array you have something that looks a lot like a database table? TaffyDB is a library to bring powerful database funtionality to that concept and rapidly improve the way you work with data inside of JavaScript.

149 | 150 |

What makes it sticky

151 | 152 |
    153 |
  • Small file size, extremely fast queries
  • 154 |
  • Powerful JavaScript centric data selection engine
  • 155 |
  • Database inspired features such as count, update, and insert
  • 156 |
  • Robust cross browser support
  • 157 |
  • Easily extended with your own functions
  • 158 |
  • Compatible with any DOM library (jQuery, YUI, Dojo, etc)
  • 159 |
  • Compatible with Server Side JS
  • 160 |
161 |

Create a Database

162 |
// Create DB and fill it with records
163 | var friends = TAFFY([
164 | 	{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active"},
165 | 	{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active"},
166 | 	{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active"},
167 | 	{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active"}	
168 | ]);
169 | 
170 | 171 |

Filter using the database name and object comparison

172 |
// Find all the friends in Seattle
173 | friends({city:"Seattle, WA"});
174 | 
175 | // Find John Smith, by ID
176 | friends({id:1});
177 | 
178 | // Find John Smith, by Name
179 | friends({first:"John",last:"Smith"});
180 | 
181 | 182 |

Access data easily

183 |
// Kelly's record
184 | var kelly = friends({id:2}).first();
185 | 
186 | // Kelly's last name
187 | var kellyslastname = kelly.last;
188 | 
189 | // Get an array of record ids
190 | var cities = friends().select("id");
191 | 
192 | // Get an array of distinct cities
193 | var cities = friends().distinct("city");
194 | 
195 | // Apply a function to all the male friends
196 | friends({gender:"M"}).each(function (r) {
197 |    alert(r.name + "!");
198 | });
199 | 
200 | 201 |

Modify data on the fly

202 |
// Move John Smith to Las Vegas
203 | friends({first:"John",last:"Smith"}).update({city:"Las Vegas, NV:"});
204 | 
205 | // Remove Jennifer Gill as a friend
206 | friends({id:4}).remove();
207 | 
208 | // insert a new friend
209 | friends.insert({"id":5,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active"});
210 | 
211 | 212 |

Download »

213 | 214 | 215 | 216 |
217 |
218 | 219 |
220 |
221 |

Beginner's Guide

222 |

A quick intro to getting your first DB up in running from scratch.

223 |

View details »

224 |
225 | 226 |
227 |

Writing queries

228 |

The heart of TaffyDB and any database is running queries against your data. This is done after creation of your database by calling the root function and building Filter Objects.

229 |

View details »

230 |
231 |
232 |

Using and modifying data

233 | 234 |

The basics for ordering, inserting, updating, deleting, and using your data in an application.

235 |

View details »

236 |
237 |
238 |
239 |
240 |

Extensions

241 | 242 |

TaffyDB is easy to extend. Write your own plugins or model whole applications with TaffyDB as the backbone.

243 |

View details »

244 |
245 |
246 |

Fork It!

247 |

Use and modify the library for your own projects and contribute code back to the master library

248 |

View details »

249 |
250 |
251 | 252 |
253 | 254 | 255 |
256 |
257 | 258 |
259 | 260 | 263 | 264 |
265 | 266 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | -------------------------------------------------------------------------------- /docs/index_files/XRegExp.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/SyntaxHighlighter/scripts/XRegExp.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-alert.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/bootstrap-alert.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-button.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/bootstrap-button.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-carousel.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/bootstrap-carousel.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-collapse.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/bootstrap-collapse.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-dropdown.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/bootstrap-dropdown.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-modal.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/bootstrap-modal.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-popover.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/bootstrap-popover.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-responsive.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.0.4 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */ 10 | 11 | .clearfix { 12 | *zoom: 1; 13 | } 14 | 15 | .clearfix:before, 16 | .clearfix:after { 17 | display: table; 18 | content: ""; 19 | } 20 | 21 | .clearfix:after { 22 | clear: both; 23 | } 24 | 25 | .hide-text { 26 | font: 0/0 a; 27 | color: transparent; 28 | text-shadow: none; 29 | background-color: transparent; 30 | border: 0; 31 | } 32 | 33 | .input-block-level { 34 | display: block; 35 | width: 100%; 36 | min-height: 28px; 37 | -webkit-box-sizing: border-box; 38 | -moz-box-sizing: border-box; 39 | -ms-box-sizing: border-box; 40 | box-sizing: border-box; 41 | } 42 | 43 | .hidden { 44 | display: none; 45 | visibility: hidden; 46 | } 47 | 48 | .visible-phone { 49 | display: none !important; 50 | } 51 | 52 | .visible-tablet { 53 | display: none !important; 54 | } 55 | 56 | .hidden-desktop { 57 | display: none !important; 58 | } 59 | 60 | @media (max-width: 767px) { 61 | .visible-phone { 62 | display: inherit !important; 63 | } 64 | .hidden-phone { 65 | display: none !important; 66 | } 67 | .hidden-desktop { 68 | display: inherit !important; 69 | } 70 | .visible-desktop { 71 | display: none !important; 72 | } 73 | } 74 | 75 | @media (min-width: 768px) and (max-width: 979px) { 76 | .visible-tablet { 77 | display: inherit !important; 78 | } 79 | .hidden-tablet { 80 | display: none !important; 81 | } 82 | .hidden-desktop { 83 | display: inherit !important; 84 | } 85 | .visible-desktop { 86 | display: none !important ; 87 | } 88 | } 89 | 90 | @media (max-width: 480px) { 91 | .nav-collapse { 92 | -webkit-transform: translate3d(0, 0, 0); 93 | } 94 | .page-header h1 small { 95 | display: block; 96 | line-height: 18px; 97 | } 98 | input[type="checkbox"], 99 | input[type="radio"] { 100 | border: 1px solid #ccc; 101 | } 102 | .form-horizontal .control-group > label { 103 | float: none; 104 | width: auto; 105 | padding-top: 0; 106 | text-align: left; 107 | } 108 | .form-horizontal .controls { 109 | margin-left: 0; 110 | } 111 | .form-horizontal .control-list { 112 | padding-top: 0; 113 | } 114 | .form-horizontal .form-actions { 115 | padding-right: 10px; 116 | padding-left: 10px; 117 | } 118 | .modal { 119 | position: absolute; 120 | top: 10px; 121 | right: 10px; 122 | left: 10px; 123 | width: auto; 124 | margin: 0; 125 | } 126 | .modal.fade.in { 127 | top: auto; 128 | } 129 | .modal-header .close { 130 | padding: 10px; 131 | margin: -10px; 132 | } 133 | .carousel-caption { 134 | position: static; 135 | } 136 | } 137 | 138 | @media (max-width: 767px) { 139 | body { 140 | padding-right: 20px; 141 | padding-left: 20px; 142 | } 143 | .navbar-fixed-top, 144 | .navbar-fixed-bottom { 145 | margin-right: -20px; 146 | margin-left: -20px; 147 | } 148 | .container-fluid { 149 | padding: 0; 150 | } 151 | .dl-horizontal dt { 152 | float: none; 153 | width: auto; 154 | clear: none; 155 | text-align: left; 156 | } 157 | .dl-horizontal dd { 158 | margin-left: 0; 159 | } 160 | .container { 161 | width: auto; 162 | } 163 | .row-fluid { 164 | width: 100%; 165 | } 166 | .row, 167 | .thumbnails { 168 | margin-left: 0; 169 | } 170 | [class*="span"], 171 | .row-fluid [class*="span"] { 172 | display: block; 173 | float: none; 174 | width: auto; 175 | margin-left: 0; 176 | } 177 | .input-large, 178 | .input-xlarge, 179 | .input-xxlarge, 180 | input[class*="span"], 181 | select[class*="span"], 182 | textarea[class*="span"], 183 | .uneditable-input { 184 | display: block; 185 | width: 100%; 186 | min-height: 28px; 187 | -webkit-box-sizing: border-box; 188 | -moz-box-sizing: border-box; 189 | -ms-box-sizing: border-box; 190 | box-sizing: border-box; 191 | } 192 | .input-prepend input, 193 | .input-append input, 194 | .input-prepend input[class*="span"], 195 | .input-append input[class*="span"] { 196 | display: inline-block; 197 | width: auto; 198 | } 199 | } 200 | 201 | @media (min-width: 768px) and (max-width: 979px) { 202 | .row { 203 | margin-left: -20px; 204 | *zoom: 1; 205 | } 206 | .row:before, 207 | .row:after { 208 | display: table; 209 | content: ""; 210 | } 211 | .row:after { 212 | clear: both; 213 | } 214 | [class*="span"] { 215 | float: left; 216 | margin-left: 20px; 217 | } 218 | .container, 219 | .navbar-fixed-top .container, 220 | .navbar-fixed-bottom .container { 221 | width: 724px; 222 | } 223 | .span12 { 224 | width: 724px; 225 | } 226 | .span11 { 227 | width: 662px; 228 | } 229 | .span10 { 230 | width: 600px; 231 | } 232 | .span9 { 233 | width: 538px; 234 | } 235 | .span8 { 236 | width: 476px; 237 | } 238 | .span7 { 239 | width: 414px; 240 | } 241 | .span6 { 242 | width: 352px; 243 | } 244 | .span5 { 245 | width: 290px; 246 | } 247 | .span4 { 248 | width: 228px; 249 | } 250 | .span3 { 251 | width: 166px; 252 | } 253 | .span2 { 254 | width: 104px; 255 | } 256 | .span1 { 257 | width: 42px; 258 | } 259 | .offset12 { 260 | margin-left: 764px; 261 | } 262 | .offset11 { 263 | margin-left: 702px; 264 | } 265 | .offset10 { 266 | margin-left: 640px; 267 | } 268 | .offset9 { 269 | margin-left: 578px; 270 | } 271 | .offset8 { 272 | margin-left: 516px; 273 | } 274 | .offset7 { 275 | margin-left: 454px; 276 | } 277 | .offset6 { 278 | margin-left: 392px; 279 | } 280 | .offset5 { 281 | margin-left: 330px; 282 | } 283 | .offset4 { 284 | margin-left: 268px; 285 | } 286 | .offset3 { 287 | margin-left: 206px; 288 | } 289 | .offset2 { 290 | margin-left: 144px; 291 | } 292 | .offset1 { 293 | margin-left: 82px; 294 | } 295 | .row-fluid { 296 | width: 100%; 297 | *zoom: 1; 298 | } 299 | .row-fluid:before, 300 | .row-fluid:after { 301 | display: table; 302 | content: ""; 303 | } 304 | .row-fluid:after { 305 | clear: both; 306 | } 307 | .row-fluid [class*="span"] { 308 | display: block; 309 | float: left; 310 | width: 100%; 311 | min-height: 28px; 312 | margin-left: 2.762430939%; 313 | *margin-left: 2.709239449638298%; 314 | -webkit-box-sizing: border-box; 315 | -moz-box-sizing: border-box; 316 | -ms-box-sizing: border-box; 317 | box-sizing: border-box; 318 | } 319 | .row-fluid [class*="span"]:first-child { 320 | margin-left: 0; 321 | } 322 | .row-fluid .span12 { 323 | width: 99.999999993%; 324 | *width: 99.9468085036383%; 325 | } 326 | .row-fluid .span11 { 327 | width: 91.436464082%; 328 | *width: 91.38327259263829%; 329 | } 330 | .row-fluid .span10 { 331 | width: 82.87292817100001%; 332 | *width: 82.8197366816383%; 333 | } 334 | .row-fluid .span9 { 335 | width: 74.30939226%; 336 | *width: 74.25620077063829%; 337 | } 338 | .row-fluid .span8 { 339 | width: 65.74585634900001%; 340 | *width: 65.6926648596383%; 341 | } 342 | .row-fluid .span7 { 343 | width: 57.182320438000005%; 344 | *width: 57.129128948638304%; 345 | } 346 | .row-fluid .span6 { 347 | width: 48.618784527%; 348 | *width: 48.5655930376383%; 349 | } 350 | .row-fluid .span5 { 351 | width: 40.055248616%; 352 | *width: 40.0020571266383%; 353 | } 354 | .row-fluid .span4 { 355 | width: 31.491712705%; 356 | *width: 31.4385212156383%; 357 | } 358 | .row-fluid .span3 { 359 | width: 22.928176794%; 360 | *width: 22.874985304638297%; 361 | } 362 | .row-fluid .span2 { 363 | width: 14.364640883%; 364 | *width: 14.311449393638298%; 365 | } 366 | .row-fluid .span1 { 367 | width: 5.801104972%; 368 | *width: 5.747913482638298%; 369 | } 370 | input, 371 | textarea, 372 | .uneditable-input { 373 | margin-left: 0; 374 | } 375 | input.span12, 376 | textarea.span12, 377 | .uneditable-input.span12 { 378 | width: 714px; 379 | } 380 | input.span11, 381 | textarea.span11, 382 | .uneditable-input.span11 { 383 | width: 652px; 384 | } 385 | input.span10, 386 | textarea.span10, 387 | .uneditable-input.span10 { 388 | width: 590px; 389 | } 390 | input.span9, 391 | textarea.span9, 392 | .uneditable-input.span9 { 393 | width: 528px; 394 | } 395 | input.span8, 396 | textarea.span8, 397 | .uneditable-input.span8 { 398 | width: 466px; 399 | } 400 | input.span7, 401 | textarea.span7, 402 | .uneditable-input.span7 { 403 | width: 404px; 404 | } 405 | input.span6, 406 | textarea.span6, 407 | .uneditable-input.span6 { 408 | width: 342px; 409 | } 410 | input.span5, 411 | textarea.span5, 412 | .uneditable-input.span5 { 413 | width: 280px; 414 | } 415 | input.span4, 416 | textarea.span4, 417 | .uneditable-input.span4 { 418 | width: 218px; 419 | } 420 | input.span3, 421 | textarea.span3, 422 | .uneditable-input.span3 { 423 | width: 156px; 424 | } 425 | input.span2, 426 | textarea.span2, 427 | .uneditable-input.span2 { 428 | width: 94px; 429 | } 430 | input.span1, 431 | textarea.span1, 432 | .uneditable-input.span1 { 433 | width: 32px; 434 | } 435 | } 436 | 437 | @media (min-width: 1200px) { 438 | .row { 439 | margin-left: -30px; 440 | *zoom: 1; 441 | } 442 | .row:before, 443 | .row:after { 444 | display: table; 445 | content: ""; 446 | } 447 | .row:after { 448 | clear: both; 449 | } 450 | [class*="span"] { 451 | float: left; 452 | margin-left: 30px; 453 | } 454 | .container, 455 | .navbar-fixed-top .container, 456 | .navbar-fixed-bottom .container { 457 | width: 1170px; 458 | } 459 | .span12 { 460 | width: 1170px; 461 | } 462 | .span11 { 463 | width: 1070px; 464 | } 465 | .span10 { 466 | width: 970px; 467 | } 468 | .span9 { 469 | width: 870px; 470 | } 471 | .span8 { 472 | width: 770px; 473 | } 474 | .span7 { 475 | width: 670px; 476 | } 477 | .span6 { 478 | width: 570px; 479 | } 480 | .span5 { 481 | width: 470px; 482 | } 483 | .span4 { 484 | width: 370px; 485 | } 486 | .span3 { 487 | width: 270px; 488 | } 489 | .span2 { 490 | width: 170px; 491 | } 492 | .span1 { 493 | width: 70px; 494 | } 495 | .offset12 { 496 | margin-left: 1230px; 497 | } 498 | .offset11 { 499 | margin-left: 1130px; 500 | } 501 | .offset10 { 502 | margin-left: 1030px; 503 | } 504 | .offset9 { 505 | margin-left: 930px; 506 | } 507 | .offset8 { 508 | margin-left: 830px; 509 | } 510 | .offset7 { 511 | margin-left: 730px; 512 | } 513 | .offset6 { 514 | margin-left: 630px; 515 | } 516 | .offset5 { 517 | margin-left: 530px; 518 | } 519 | .offset4 { 520 | margin-left: 430px; 521 | } 522 | .offset3 { 523 | margin-left: 330px; 524 | } 525 | .offset2 { 526 | margin-left: 230px; 527 | } 528 | .offset1 { 529 | margin-left: 130px; 530 | } 531 | .row-fluid { 532 | width: 100%; 533 | *zoom: 1; 534 | } 535 | .row-fluid:before, 536 | .row-fluid:after { 537 | display: table; 538 | content: ""; 539 | } 540 | .row-fluid:after { 541 | clear: both; 542 | } 543 | .row-fluid [class*="span"] { 544 | display: block; 545 | float: left; 546 | width: 100%; 547 | min-height: 28px; 548 | margin-left: 2.564102564%; 549 | *margin-left: 2.510911074638298%; 550 | -webkit-box-sizing: border-box; 551 | -moz-box-sizing: border-box; 552 | -ms-box-sizing: border-box; 553 | box-sizing: border-box; 554 | } 555 | .row-fluid [class*="span"]:first-child { 556 | margin-left: 0; 557 | } 558 | .row-fluid .span12 { 559 | width: 100%; 560 | *width: 99.94680851063829%; 561 | } 562 | .row-fluid .span11 { 563 | width: 91.45299145300001%; 564 | *width: 91.3997999636383%; 565 | } 566 | .row-fluid .span10 { 567 | width: 82.905982906%; 568 | *width: 82.8527914166383%; 569 | } 570 | .row-fluid .span9 { 571 | width: 74.358974359%; 572 | *width: 74.30578286963829%; 573 | } 574 | .row-fluid .span8 { 575 | width: 65.81196581200001%; 576 | *width: 65.7587743226383%; 577 | } 578 | .row-fluid .span7 { 579 | width: 57.264957265%; 580 | *width: 57.2117657756383%; 581 | } 582 | .row-fluid .span6 { 583 | width: 48.717948718%; 584 | *width: 48.6647572286383%; 585 | } 586 | .row-fluid .span5 { 587 | width: 40.170940171000005%; 588 | *width: 40.117748681638304%; 589 | } 590 | .row-fluid .span4 { 591 | width: 31.623931624%; 592 | *width: 31.5707401346383%; 593 | } 594 | .row-fluid .span3 { 595 | width: 23.076923077%; 596 | *width: 23.0237315876383%; 597 | } 598 | .row-fluid .span2 { 599 | width: 14.529914530000001%; 600 | *width: 14.4767230406383%; 601 | } 602 | .row-fluid .span1 { 603 | width: 5.982905983%; 604 | *width: 5.929714493638298%; 605 | } 606 | input, 607 | textarea, 608 | .uneditable-input { 609 | margin-left: 0; 610 | } 611 | input.span12, 612 | textarea.span12, 613 | .uneditable-input.span12 { 614 | width: 1160px; 615 | } 616 | input.span11, 617 | textarea.span11, 618 | .uneditable-input.span11 { 619 | width: 1060px; 620 | } 621 | input.span10, 622 | textarea.span10, 623 | .uneditable-input.span10 { 624 | width: 960px; 625 | } 626 | input.span9, 627 | textarea.span9, 628 | .uneditable-input.span9 { 629 | width: 860px; 630 | } 631 | input.span8, 632 | textarea.span8, 633 | .uneditable-input.span8 { 634 | width: 760px; 635 | } 636 | input.span7, 637 | textarea.span7, 638 | .uneditable-input.span7 { 639 | width: 660px; 640 | } 641 | input.span6, 642 | textarea.span6, 643 | .uneditable-input.span6 { 644 | width: 560px; 645 | } 646 | input.span5, 647 | textarea.span5, 648 | .uneditable-input.span5 { 649 | width: 460px; 650 | } 651 | input.span4, 652 | textarea.span4, 653 | .uneditable-input.span4 { 654 | width: 360px; 655 | } 656 | input.span3, 657 | textarea.span3, 658 | .uneditable-input.span3 { 659 | width: 260px; 660 | } 661 | input.span2, 662 | textarea.span2, 663 | .uneditable-input.span2 { 664 | width: 160px; 665 | } 666 | input.span1, 667 | textarea.span1, 668 | .uneditable-input.span1 { 669 | width: 60px; 670 | } 671 | .thumbnails { 672 | margin-left: -30px; 673 | } 674 | .thumbnails > li { 675 | margin-left: 30px; 676 | } 677 | .row-fluid .thumbnails { 678 | margin-left: 0; 679 | } 680 | } 681 | 682 | @media (max-width: 979px) { 683 | body { 684 | padding-top: 0; 685 | } 686 | .navbar-fixed-top, 687 | .navbar-fixed-bottom { 688 | position: static; 689 | } 690 | .navbar-fixed-top { 691 | margin-bottom: 18px; 692 | } 693 | .navbar-fixed-bottom { 694 | margin-top: 18px; 695 | } 696 | .navbar-fixed-top .navbar-inner, 697 | .navbar-fixed-bottom .navbar-inner { 698 | padding: 5px; 699 | } 700 | .navbar .container { 701 | width: auto; 702 | padding: 0; 703 | } 704 | .navbar .brand { 705 | padding-right: 10px; 706 | padding-left: 10px; 707 | margin: 0 0 0 -5px; 708 | } 709 | .nav-collapse { 710 | clear: both; 711 | } 712 | .nav-collapse .nav { 713 | float: none; 714 | margin: 0 0 9px; 715 | } 716 | .nav-collapse .nav > li { 717 | float: none; 718 | } 719 | .nav-collapse .nav > li > a { 720 | margin-bottom: 2px; 721 | } 722 | .nav-collapse .nav > .divider-vertical { 723 | display: none; 724 | } 725 | .nav-collapse .nav .nav-header { 726 | color: #999999; 727 | text-shadow: none; 728 | } 729 | .nav-collapse .nav > li > a, 730 | .nav-collapse .dropdown-menu a { 731 | padding: 6px 15px; 732 | font-weight: bold; 733 | color: #999999; 734 | -webkit-border-radius: 3px; 735 | -moz-border-radius: 3px; 736 | border-radius: 3px; 737 | } 738 | .nav-collapse .btn { 739 | padding: 4px 10px 4px; 740 | font-weight: normal; 741 | -webkit-border-radius: 4px; 742 | -moz-border-radius: 4px; 743 | border-radius: 4px; 744 | } 745 | .nav-collapse .dropdown-menu li + li a { 746 | margin-bottom: 2px; 747 | } 748 | .nav-collapse .nav > li > a:hover, 749 | .nav-collapse .dropdown-menu a:hover { 750 | background-color: #222222; 751 | } 752 | .nav-collapse.in .btn-group { 753 | padding: 0; 754 | margin-top: 5px; 755 | } 756 | .nav-collapse .dropdown-menu { 757 | position: static; 758 | top: auto; 759 | left: auto; 760 | display: block; 761 | float: none; 762 | max-width: none; 763 | padding: 0; 764 | margin: 0 15px; 765 | background-color: transparent; 766 | border: none; 767 | -webkit-border-radius: 0; 768 | -moz-border-radius: 0; 769 | border-radius: 0; 770 | -webkit-box-shadow: none; 771 | -moz-box-shadow: none; 772 | box-shadow: none; 773 | } 774 | .nav-collapse .dropdown-menu:before, 775 | .nav-collapse .dropdown-menu:after { 776 | display: none; 777 | } 778 | .nav-collapse .dropdown-menu .divider { 779 | display: none; 780 | } 781 | .nav-collapse .navbar-form, 782 | .nav-collapse .navbar-search { 783 | float: none; 784 | padding: 9px 15px; 785 | margin: 9px 0; 786 | border-top: 1px solid #222222; 787 | border-bottom: 1px solid #222222; 788 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); 789 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); 790 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); 791 | } 792 | .navbar .nav-collapse .nav.pull-right { 793 | float: none; 794 | margin-left: 0; 795 | } 796 | .nav-collapse, 797 | .nav-collapse.collapse { 798 | height: 0; 799 | overflow: hidden; 800 | } 801 | .navbar .btn-navbar { 802 | display: block; 803 | } 804 | .navbar-static .navbar-inner { 805 | padding-right: 10px; 806 | padding-left: 10px; 807 | } 808 | } 809 | 810 | @media (min-width: 980px) { 811 | .nav-collapse.collapse { 812 | height: auto !important; 813 | overflow: visible !important; 814 | } 815 | } 816 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-scrollspy.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/bootstrap-scrollspy.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-tab.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/bootstrap-tab.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-tooltip.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/bootstrap-tooltip.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-transition.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/bootstrap-transition.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/bootstrap-typeahead.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/bootstrap-typeahead.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/ga.js.download: -------------------------------------------------------------------------------- 1 | (function(){var E;function Aa(a,b){switch(b){case 0:return""+a;case 1:return 1*a;case 2:return!!a;case 3:return 1E3*a}return a}function Ba(a){return"function"==typeof a}function Ca(a){return void 0!=a&&-1<(a.constructor+"").indexOf("String")}function F(a,b){return void 0==a||"-"==a&&!b||""==a}function Da(a){if(!a||""==a)return"";for(;a&&-1<" \n\r\t".indexOf(a.charAt(0));)a=a.substring(1);for(;a&&-1<" \n\r\t".indexOf(a.charAt(a.length-1));)a=a.substring(0,a.length-1);return a} 2 | function Ea(){return Math.round(2147483647*Math.random())}function Fa(){}function G(a,b){if(encodeURIComponent instanceof Function)return b?encodeURI(a):encodeURIComponent(a);H(68);return escape(a)}function I(a){a=a.split("+").join(" ");if(decodeURIComponent instanceof Function)try{return decodeURIComponent(a)}catch(b){H(17)}else H(68);return unescape(a)}var Ga=function(a,b,c,d){a.addEventListener?a.addEventListener(b,c,!!d):a.attachEvent&&a.attachEvent("on"+b,c)}; 3 | function Ia(a,b){if(a){var c=J.createElement("script");c.type="text/javascript";c.async=!0;c.src=a;c.id=b;var d=J.getElementsByTagName("script")[0];d.parentNode.insertBefore(c,d);return c}}function K(a){return a&&0a.split("/")[0].indexOf(":")&&(a=k+f[2].substring(0,f[2].lastIndexOf("/"))+ 8 | "/"+a):a=k+f[2]+(a||Be);d.href=a;e=c(d);return{protocol:(d.protocol||"").toLowerCase(),host:e[0],port:e[1],path:e[2],Oa:d.search||"",url:a||""}}function Na(a,b){function c(b,c){a.contains(b)||a.set(b,[]);a.get(b).push(c)}for(var d=Da(b).split("&"),e=0;ef?c(d[e],"1"):c(d[e].substring(0,f),d[e].substring(f+1))}} 9 | function Pa(a,b){if(F(a)||"["==a.charAt(0)&&"]"==a.charAt(a.length-1))return"-";var c=J.domain;return a.indexOf(c+(b&&"/"!=b?b:""))==(0==a.indexOf("http://")?7:0==a.indexOf("https://")?8:0)?"0":a};var Qa=0;function Ra(a,b,c){1<=Qa||1<=100*Math.random()||ld()||(a=["utmt=error","utmerr="+a,"utmwv=5.6.7","utmn="+Ea(),"utmsp=1"],b&&a.push("api="+b),c&&a.push("msg="+G(c.substring(0,100))),M.w&&a.push("aip=1"),Sa(a.join("&")),Qa++)};var Ta=0,Ua={};function N(a){return Va("x"+Ta++,a)}function Va(a,b){Ua[a]=!!b;return a} 10 | var Wa=N(),Xa=Va("anonymizeIp"),Ya=N(),$a=N(),ab=N(),bb=N(),O=N(),P=N(),cb=N(),db=N(),eb=N(),fb=N(),gb=N(),hb=N(),ib=N(),jb=N(),kb=N(),lb=N(),nb=N(),ob=N(),pb=N(),qb=N(),rb=N(),sb=N(),tb=N(),ub=N(),vb=N(),wb=N(),xb=N(),yb=N(),zb=N(),Ab=N(),Bb=N(),Cb=N(),Db=N(),Eb=N(),Fb=N(!0),Gb=Va("currencyCode"),Hb=Va("page"),Ib=Va("title"),Jb=N(),Kb=N(),Lb=N(),Mb=N(),Nb=N(),Ob=N(),Pb=N(),Qb=N(),Rb=N(),Q=N(!0),Sb=N(!0),Tb=N(!0),Ub=N(!0),Vb=N(!0),Wb=N(!0),Zb=N(!0),$b=N(!0),ac=N(!0),bc=N(!0),cc=N(!0),R=N(!0),dc=N(!0), 11 | ec=N(!0),fc=N(!0),gc=N(!0),hc=N(!0),ic=N(!0),jc=N(!0),S=N(!0),kc=N(!0),lc=N(!0),mc=N(!0),nc=N(!0),oc=N(!0),pc=N(!0),qc=N(!0),rc=Va("campaignParams"),sc=N(),tc=Va("hitCallback"),uc=N();N();var vc=N(),wc=N(),xc=N(),yc=N(),zc=N(),Ac=N(),Bc=N(),Cc=N(),Dc=N(),Ec=N(),Fc=N(),Gc=N(),Hc=N(),Ic=N();N();var Mc=N(),Nc=N(),Yb=N(),Jc=N(),Kc=N(),Lc=Va("utmtCookieName"),Cd=Va("displayFeatures"),Oc=N(),of=Va("gtmid"),Oe=Va("uaName"),Pe=Va("uaDomain"),Qe=Va("uaPath"),pf=Va("linkid");var Re=function(){function a(a,c,d){T(qf.prototype,a,c,d)}a("_createTracker",qf.prototype.hb,55);a("_getTracker",qf.prototype.oa,0);a("_getTrackerByName",qf.prototype.u,51);a("_getTrackers",qf.prototype.pa,130);a("_anonymizeIp",qf.prototype.aa,16);a("_forceSSL",qf.prototype.la,125);a("_getPlugin",Pc,120)},Se=function(){function a(a,c,d){T(U.prototype,a,c,d)}Qc("_getName",$a,58);Qc("_getAccount",Wa,64);Qc("_visitCode",Q,54);Qc("_getClientInfo",ib,53,1);Qc("_getDetectTitle",lb,56,1);Qc("_getDetectFlash", 12 | jb,65,1);Qc("_getLocalGifPath",wb,57);Qc("_getServiceMode",xb,59);V("_setClientInfo",ib,66,2);V("_setAccount",Wa,3);V("_setNamespace",Ya,48);V("_setAllowLinker",fb,11,2);V("_setDetectFlash",jb,61,2);V("_setDetectTitle",lb,62,2);V("_setLocalGifPath",wb,46,0);V("_setLocalServerMode",xb,92,void 0,0);V("_setRemoteServerMode",xb,63,void 0,1);V("_setLocalRemoteServerMode",xb,47,void 0,2);V("_setSampleRate",vb,45,1);V("_setCampaignTrack",kb,36,2);V("_setAllowAnchor",gb,7,2);V("_setCampNameKey",ob,41);V("_setCampContentKey", 13 | tb,38);V("_setCampIdKey",nb,39);V("_setCampMediumKey",rb,40);V("_setCampNOKey",ub,42);V("_setCampSourceKey",qb,43);V("_setCampTermKey",sb,44);V("_setCampCIdKey",pb,37);V("_setCookiePath",P,9,0);V("_setMaxCustomVariables",yb,0,1);V("_setVisitorCookieTimeout",cb,28,1);V("_setSessionCookieTimeout",db,26,1);V("_setCampaignCookieTimeout",eb,29,1);V("_setReferrerOverride",Jb,49);V("_setSiteSpeedSampleRate",Dc,132);a("_trackPageview",U.prototype.Fa,1);a("_trackEvent",U.prototype.F,4);a("_trackPageLoadTime", 14 | U.prototype.Ea,100);a("_trackSocial",U.prototype.Ga,104);a("_trackTrans",U.prototype.Ia,18);a("_sendXEvent",U.prototype.ib,78);a("_createEventTracker",U.prototype.ia,74);a("_getVersion",U.prototype.qa,60);a("_setDomainName",U.prototype.B,6);a("_setAllowHash",U.prototype.va,8);a("_getLinkerUrl",U.prototype.na,52);a("_link",U.prototype.link,101);a("_linkByPost",U.prototype.ua,102);a("_setTrans",U.prototype.za,20);a("_addTrans",U.prototype.$,21);a("_addItem",U.prototype.Y,19);a("_clearTrans",U.prototype.ea, 15 | 105);a("_setTransactionDelim",U.prototype.Aa,82);a("_setCustomVar",U.prototype.wa,10);a("_deleteCustomVar",U.prototype.ka,35);a("_getVisitorCustomVar",U.prototype.ra,50);a("_setXKey",U.prototype.Ca,83);a("_setXValue",U.prototype.Da,84);a("_getXKey",U.prototype.sa,76);a("_getXValue",U.prototype.ta,77);a("_clearXKey",U.prototype.fa,72);a("_clearXValue",U.prototype.ga,73);a("_createXObj",U.prototype.ja,75);a("_addIgnoredOrganic",U.prototype.W,15);a("_clearIgnoredOrganic",U.prototype.ba,97);a("_addIgnoredRef", 16 | U.prototype.X,31);a("_clearIgnoredRef",U.prototype.ca,32);a("_addOrganic",U.prototype.Z,14);a("_clearOrganic",U.prototype.da,70);a("_cookiePathCopy",U.prototype.ha,30);a("_get",U.prototype.ma,106);a("_set",U.prototype.xa,107);a("_addEventListener",U.prototype.addEventListener,108);a("_removeEventListener",U.prototype.removeEventListener,109);a("_addDevId",U.prototype.V);a("_getPlugin",Pc,122);a("_setPageGroup",U.prototype.ya,126);a("_trackTiming",U.prototype.Ha,124);a("_initData",U.prototype.initData, 17 | 2);a("_setVar",U.prototype.Ba,22);V("_setSessionTimeout",db,27,3);V("_setCookieTimeout",eb,25,3);V("_setCookiePersistence",cb,24,1);a("_setAutoTrackOutbound",Fa,79);a("_setTrackOutboundSubdomains",Fa,81);a("_setHrefExamineLimit",Fa,80)};function Pc(a){var b=this.plugins_;if(b)return b.get(a)} 18 | var T=function(a,b,c,d){a[b]=function(){try{return void 0!=d&&H(d),c.apply(this,arguments)}catch(a){throw Ra("exc",b,a&&a.name),a;}}},Qc=function(a,b,c,d){U.prototype[a]=function(){try{return H(c),Aa(this.a.get(b),d)}catch(e){throw Ra("exc",a,e&&e.name),e;}}},V=function(a,b,c,d,e){U.prototype[a]=function(f){try{H(c),void 0==e?this.a.set(b,Aa(f,d)):this.a.set(b,e)}catch(Be){throw Ra("exc",a,Be&&Be.name),Be;}}},Te=function(a,b){return{type:b,target:a,stopPropagation:function(){throw"aborted";}}};var Rc=new RegExp(/(^|\.)doubleclick\.net$/i),Sc=function(a,b){return Rc.test(J.location.hostname)?!0:"/"!==b?!1:0!=a.indexOf("www.google.")&&0!=a.indexOf(".google.")&&0!=a.indexOf("google.")||-1b.length||ad(b[0],c))return!1;b=b.slice(1).join(".").split("|"); 23 | 0=b.length)return!0;b=b[1].split(-1==b[1].indexOf(",")?"^":",");for(c=0;cb.length||ad(b[0],c))return a.set(ec,void 0),a.set(fc,void 0),a.set(gc,void 0),a.set(ic,void 0),a.set(jc,void 0),a.set(nc,void 0),a.set(oc,void 0),a.set(pc,void 0),a.set(qc,void 0),a.set(S,void 0),a.set(kc,void 0),a.set(lc,void 0),a.set(mc,void 0),!1;a.set(ec,1*b[1]);a.set(fc,1*b[2]);a.set(gc,1*b[3]); 25 | Ve(a,b.slice(4).join("."));return!0},Ve=function(a,b){function c(a){return(a=b.match(a+"=(.*?)(?:\\|utm|$)"))&&2==a.length?a[1]:void 0}function d(b,c){c?(c=e?I(c):c.split("%20").join(" "),a.set(b,c)):a.set(b,void 0)}-1==b.indexOf("=")&&(b=I(b));var e="2"==c("utmcvr");d(ic,c("utmcid"));d(jc,c("utmccn"));d(nc,c("utmcsr"));d(oc,c("utmcmd"));d(pc,c("utmctr"));d(qc,c("utmcct"));d(S,c("utmgclid"));d(kc,c("utmgclsrc"));d(lc,c("utmdclid"));d(mc,c("utmdsid"))},ad=function(a,b){return b?a!=b:!/^\d+$/.test(a)};var Uc=function(){this.filters=[]};Uc.prototype.add=function(a,b){this.filters.push({name:a,s:b})};Uc.prototype.cb=function(a){try{for(var b=0;b=100*a.get(vb)&&a.stopPropagation()}function kd(a){ld(a.get(Wa))&&a.stopPropagation()}function md(a){"file:"==J.location.protocol&&a.stopPropagation()}function Ge(a){He()&&a.stopPropagation()} 26 | function nd(a){a.get(Ib)||a.set(Ib,J.title,!0);a.get(Hb)||a.set(Hb,J.location.pathname+J.location.search,!0)}function lf(a){a.get(Wa)&&"UA-XXXXX-X"!=a.get(Wa)||a.stopPropagation()};var od=new function(){var a=[];this.set=function(b){a[b]=!0};this.encode=function(){for(var b=[],c=0;c=b[0]||0>=b[1]?"":b.join("x");a.Wa=d}catch(k){H(135)}qd=a}},td=function(){sd();for(var a=qd,b=W.navigator,a=b.appName+b.version+a.language+b.platform+b.userAgent+a.javaEnabled+a.jb+a.P+(J.cookie?J.cookie:"")+(J.referrer?J.referrer:""),b=a.length,c=W.history.length;0d?(this.i=b.substring(0,d),this.l=b.substring(d+1,c),this.h=b.substring(c+1)):(this.i=b.substring(0,d),this.h=b.substring(d+1));this.Xa=a.slice(1);this.Ma=!this.l&&"_require"==this.h;this.J=!this.i&&!this.l&&"_provide"==this.h}},Y=function(){T(Y.prototype, 32 | "push",Y.prototype.push,5);T(Y.prototype,"_getPlugin",Pc,121);T(Y.prototype,"_createAsyncTracker",Y.prototype.Sa,33);T(Y.prototype,"_getAsyncTracker",Y.prototype.Ta,34);this.I=new nf;this.eb=[]};E=Y.prototype;E.Na=function(a,b,c){var d=this.I.get(a);if(!Ba(d))return!1;b.plugins_=b.plugins_||new nf;b.plugins_.set(a,new d(b,c||{}));return!0};E.push=function(a){var b=Z.Va.apply(this,arguments),b=Z.eb.concat(b);for(Z.eb=[];0e?b+"#"+d:b+"&"+d;c="";f=b.indexOf("?");0f?b+"?"+d+c:b+"&"+d+c},$d=function(a,b,c,d){for(var e=0;3>e;e++){for(var f= 48 | 0;3>f;f++){if(d==Yc(a+b+c))return H(127),[b,c];var Be=b.replace(/ /g,"%20"),k=c.replace(/ /g,"%20");if(d==Yc(a+Be+k))return H(128),[Be,k];Be=Be.replace(/\+/g,"%20");k=k.replace(/\+/g,"%20");if(d==Yc(a+Be+k))return H(129),[Be,k];try{var Ja=b.match("utmctr=(.*?)(?:\\|utm|$)");if(Ja&&2==Ja.length&&(Be=b.replace(Ja[1],G(I(Ja[1]))),d==Yc(a+Be+c)))return H(139),[Be,c]}catch(t){}b=I(b)}c=I(c)}};var de="|",fe=function(a,b,c,d,e,f,Be,k,Ja){var t=ee(a,b);t||(t={},a.get(Cb).push(t));t.id_=b;t.affiliation_=c;t.total_=d;t.tax_=e;t.shipping_=f;t.city_=Be;t.state_=k;t.country_=Ja;t.items_=t.items_||[];return t},ge=function(a,b,c,d,e,f,Be){a=ee(a,b)||fe(a,b,"",0,0,0,"","","");var k;a:{if(a&&a.items_){k=a.items_;for(var Ja=0;Jab.length||!/^\d+$/.test(b[0])||(b[0]=""+c,Fd(a,"__utmx",b.join("."),void 0))},be=function(a,b){var c=$c(a.get(O),pd("__utmx"));"-"==c&&(c="");return b?G(c):c},Ye=function(a){try{var b=La(J.location.href,!1),c=decodeURIComponent(L(b.R.get("utm_referrer")))||"";c&&a.set(Jb,c);var d=decodeURIComponent(K(b.R.get("utm_expid")))||"";d&&(d=d.split(".")[0],a.set(Oc,""+d))}catch(e){H(146)}},l=function(a){var b=W.gaData&&W.gaData.expId;b&&a.set(Oc, 50 | ""+b)};var ke=function(a,b){var c=Math.min(a.b(Dc,0),100);if(a.b(Q,0)%100>=c)return!1;c=Ze()||$e();if(void 0==c)return!1;var d=c[0];if(void 0==d||Infinity==d||isNaN(d))return!1;0a[b])return!1;return!0},le=function(a){return isNaN(a)||0>a?0:5E3>a?10*Math.floor(a/10):5E4>a?100*Math.floor(a/100):41E5>a?1E3*Math.floor(a/1E3):41E5},je=function(a){for(var b=new yd,c=0;cc.length)){for(var d=[],e=0;e=f)return!1;c=1*(""+c);if(""==a||!wd(a)||""==b||!wd(b)||!xd(c)||isNaN(c)||0>c||0>f||100=a||a>e.get(yb))a=!1;else if(!b||!c||128=a&&Ca(b)&&""!=b){var c=this.get(Fc)||[];c[a]=b;this.set(Fc,c)}};E.V=function(a){a=""+a;if(a.match(/^[A-Za-z0-9]{1,5}$/)){var b=this.get(Ic)||[];b.push(a);this.set(Ic,b)}};E.initData=function(){this.a.load()}; 66 | E.Ba=function(a){a&&""!=a&&(this.set(Tb,a),this.a.j("var"))};var ne=function(a){"trans"!==a.get(sc)&&500<=a.b(cc,0)&&a.stopPropagation();if("event"===a.get(sc)){var b=(new Date).getTime(),c=a.b(dc,0),d=a.b(Zb,0),c=Math.floor((b-(c!=d?c:1E3*c))/1E3*1);0=a.b(R,0)&&a.stopPropagation()}},pe=function(a){"event"===a.get(sc)&&a.set(R,Math.max(0,a.b(R,10)-1))};var qe=function(){var a=[];this.add=function(b,c,d){d&&(c=G(""+c));a.push(b+"="+c)};this.toString=function(){return a.join("&")}},re=function(a,b){(b||2!=a.get(xb))&&a.Za(cc)},se=function(a,b){b.add("utmwv","5.6.7");b.add("utms",a.get(cc));b.add("utmn",Ea());var c=J.location.hostname;F(c)||b.add("utmhn",c,!0);c=a.get(vb);100!=c&&b.add("utmsp",c,!0)},te=function(a,b){b.add("utmht",(new Date).getTime());b.add("utmac",Da(a.get(Wa)));a.get(Oc)&&b.add("utmxkey",a.get(Oc),!0);a.get(vc)&&b.add("utmni",1); 67 | a.get(of)&&b.add("utmgtm",a.get(of),!0);var c=a.get(Ic);c&&0=a.length)gf(a,b,c);else if(8192>=a.length){if(0<=W.navigator.userAgent.indexOf("Firefox")&&![].reduce)throw new De(a.length);df(a,b)||ef(a,b)||Ee(a,b)||b()}else throw new Ce(a.length);},gf=function(a,b,c){c=c||Ne()+"/__utm.gif?"; 74 | var d=new Image(1,1);d.src=c+a;d.onload=function(){d.onload=null;d.onerror=null;b()};d.onerror=function(){d.onload=null;d.onerror=null;b()}},ef=function(a,b){if(0!=Ne().indexOf(J.location.protocol))return!1;var c;c=W.XDomainRequest;if(!c)return!1;c=new c;c.open("POST",Ne()+"/p/__utm.gif");c.onerror=function(){b()};c.onload=b;c.send(a);return!0},df=function(a,b){var c=W.XMLHttpRequest;if(!c)return!1;var d=new c;if(!("withCredentials"in d))return!1;d.open("POST",Ne()+"/p/__utm.gif",!0);d.withCredentials= 75 | !0;d.setRequestHeader("Content-Type","text/plain");d.onreadystatechange=function(){4==d.readyState&&(b(),d=null)};d.send(a);return!0},Ee=function(a,b){if(!J.body)return We(function(){Ee(a,b)},100),!0;a=encodeURIComponent(a);try{var c=J.createElement('')}catch(d){c=J.createElement("iframe"),c.name=a}c.height="0";c.width="0";c.style.display="none";c.style.visibility="hidden";var e=Ne()+"/u/post_iframe.html";Ga(W,"beforeunload",function(){c.src="";c.parentNode&&c.parentNode.removeChild(c)}); 76 | setTimeout(b,1E3);J.body.appendChild(c);c.src=e;return!0};var qf=function(){this.G=this.w=!1;0==Ea()%1E4&&(H(142),this.G=!0);this.C={};this.D=[];this.U=0;this.S=[["www.google-analytics.com","","/plugins/"]];this._gasoCPath=this._gasoDomain=this.bb=void 0;Re();Se()};E=qf.prototype;E.oa=function(a,b){return this.hb(a,void 0,b)};E.hb=function(a,b,c){b&&H(23);c&&H(67);void 0==b&&(b="~"+M.U++);a=new U(b,a,c);M.C[b]=a;M.D.push(a);return a};E.u=function(a){a=a||"";return M.C[a]||M.hb(void 0,a)};E.pa=function(){return M.D.slice(0)};E.ab=function(){return M.D.length}; 77 | E.aa=function(){this.w=!0};E.la=function(){this.G=!0};var Fe=function(a){if("prerender"==J.visibilityState)return!1;a();return!0};var M=new qf;var Ha=W._gat;Ha&&Ba(Ha._getTracker)?M=Ha:W._gat=M;var Z=new Y;(function(a){if(!Fe(a)){H(123);var b=!1,c=function(){if(!b&&Fe(a)){b=!0;var d=J,e=c;d.removeEventListener?d.removeEventListener("visibilitychange",e,!1):d.detachEvent&&d.detachEvent("onvisibilitychange",e)}};Ga(J,"visibilitychange",c)}})(function(){var a=W._gaq,b=!1;if(a&&Ba(a.push)&&(b="[object Array]"==Object.prototype.toString.call(Object(a)),!b)){Z=a;return}W._gaq=Z;b&&Z.push.apply(Z,a)});function Yc(a){var b=1,c=0,d;if(a)for(b=0,d=a.length-1;0<=d;d--)c=a.charCodeAt(d),b=(b<<6&268435455)+c+(c<<14),c=b&266338304,b=0!=c?b^c>>21:b;return b};})(); 78 | -------------------------------------------------------------------------------- /docs/index_files/jquery.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/jquery.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/saved_resource(1).html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /docs/index_files/shBrushJScript.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/SyntaxHighlighter/scripts/shBrushJScript.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/shCore.js.download: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 404 Not Found 5 | 6 | 7 |

Error: Not Found

8 |

The requested URL /js/SyntaxHighlighter/scripts/shCore.js was not found on this server.

9 |

10 | 11 | -------------------------------------------------------------------------------- /docs/index_files/taffydbboxV3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/typicaljoe/taffydb/5e208249202e314d8706c49f7895169544b985f1/docs/index_files/taffydbboxV3.jpg -------------------------------------------------------------------------------- /docs/index_files/timeline.619317855a58aa2366562a395f9e40ef.js.download: -------------------------------------------------------------------------------- 1 | __twttrll([6],{189:function(e,t,i){var r=i(84);e.exports=r.build([i(190),i(194),i(149),i(150),i(100),i(96),i(195),i(196),i(139),i(140),i(135),i(138),i(199),i(200),i(201),i(202),i(204),i(207),i(148),i(208),i(210),i(141),i(142),i(152),i(212)],{pageForAudienceImpression:"timeline",productName:"embeddedtimeline",breakpoints:[330,430,550,660,820,970]})},190:function(e,t,i){function r(e){e.params({dataSource:{required:!0},lang:{required:!0,transform:p.matchLanguage,fallback:"en"},useLegacyDefaults:{required:!0,fallback:!1},width:{validate:m,transform:m},height:{validate:m,transform:m},theme:{fallback:[h(o.val,o,"widgets:theme")],validate:g},tweetLimit:{transform:d.asInt},partner:{fallback:h(o.val,o,"partner")},staticContent:{required:!1,transform:d.asBoolean}}),e.selectors({header:".timeline-Header",footer:".timeline-Footer",viewport:".timeline-Viewport",tweetList:".timeline-TweetList",tweetsInStream:".timeline-Tweet"}),e.around("scribeNamespace",function(e){return u.aug(e(),{page:"timeline"})}),e.around("scribeData",function(e){var t=this.params.dataSource.id;return u.aug(e(),{widget_id:d.isNumber(t)?t:void 0,widget_data_source:t,message:this.params.partner,query:this.el&&this.el.getAttribute("data-search-query"),profile_id:this.el&&this.el.getAttribute("data-profile-id")})}),e.around("widgetDataAttributes",function(e){return u.aug({"widget-id":this.params.dataSource.id,"user-id":this.el&&this.el.getAttribute("data-profile-id"),"search-query":this.el&&this.el.getAttribute("data-search-query")},e())}),e.define("updateViewportHeight",function(){var e,t=this.sandbox,i=this.selectOne("header"),r=this.selectOne("footer"),n=this.selectOne("viewport");return a.read(function(){e=t.height-2*A,e-=i?i.offsetHeight:0,e-=r?r.offsetHeight:0}),a.write(function(){n.style.height=e+"px"})}),e.define("adjustWidgetSize",function(){return this.isFullyExpanded?this.sandbox.matchHeightToContent():this.updateViewportHeight()}),e.define("reconfigureWithServerSideParams",function(e){e=e||{},this.params.linkColor=this.params.linkColor||e.linkColor,this.params.theme=this.params.theme||e.theme||"light",this.params.height=m(this.params.height||e.height),this.isFullyExpanded=this.isStaticTimeline||!this.params.useLegacyDefaults&&!this.params.height,this.isFullyExpanded||this.params.height||(this.params.height=y)}),e.define("scribeImpressionsForInitialTweetSet",function(e){var t=f(this.select("tweetsInStream")),i=Object.keys(t),r=i.length?"results":"no_results",n=this.el.getAttribute("data-collection-id");n&&(i.push(n),t[n]={item_type:w.CUSTOM_TIMELINE}),this.scribe({component:"timeline",element:"initial",action:r},{widget_in_viewport:e,item_ids:i,item_details:t})}),e.override("initialize",function(){this.params.width||(this.params.width=this.params.useLegacyDefaults?I:x),this.isStaticTimeline=this.params.staticContent||this.params.tweetLimit>0}),e.override("hydrate",function(){var e=this;return this.params.dataSource.fetch().then(function(t){e.html=t.html,e.reconfigureWithServerSideParams(t.config),v(e,t,b.INITIAL)})}),e.override("render",function(){var e,t=this;return this.el=this.sandbox.htmlToElement(this.html),this.el?(this.el.lang=this.params.lang,this.isFullyExpanded&&this.sandbox.addRootClass("var-fully-expanded"),this.isStaticTimeline&&this.sandbox.addRootClass("var-static"),e=s.timeline(this.params.lang,this.params.theme),n.all([this.sandbox.appendStyleSheet(e),this.sandbox.styleSelf({display:"inline-block",maxWidth:x,width:this.params.width,minWidth:T,marginTop:0,marginBottom:0})]).then(function(){return t.prepForInsertion(t.el),t.sandbox.injectWidgetEl(t.el)})):n.reject(new Error("unable to render"))}),e.override("show",function(){var e=this.sandbox,t=this;return this.sandbox.makeVisible().then(function(){return e.styleSelf({minHeight:t.isStaticTimeline?void 0:C,height:t.params.height})}).then(function(){return t.adjustWidgetSize()}).then(function(){return a.read(function(){var i=l(e.sandboxEl);t.scribeImpressionsForInitialTweetSet(i)})})}),e.last("resize",function(){return this.adjustWidgetSize()})}var n=i(2),s=i(89),a=i(45),o=i(37),l=i(134),d=i(25),u=i(11),c=i(84),h=i(13),f=i(101),m=i(133),p=i(90),g=i(191),v=i(192),w=i(102),b=i(193),T="180px",x="100%",C="200px",I="520px",y="600px",A=1;e.exports=c.couple(i(98),i(114),r)},191:function(e,t){function i(e){return r.test(e)}var r=/^(dark|light)$/;e.exports=i},192:function(e,t,i){function r(e,t,i){switch(e.cursors=e.cursors||{},e.pollInterval=t.pollInterval,i){case n.INITIAL:e.cursors.min=t.minCursorPosition,e.cursors.max=t.maxCursorPosition;break;case n.NEWER:e.cursors.max=t.maxCursorPosition||e.cursors.max;break;case n.OLDER:e.cursors.min=t.minCursorPosition||e.cursors.min}}var n=i(193);e.exports=r},193:function(e,t){e.exports={INITIAL:1,NEWER:2,OLDER:3}},194:function(e,t,i){function r(e){e.params({chrome:{transform:s,fallback:""}}),e.selectors({streamContainer:".timeline-Viewport",tweetStream:".timeline-TweetList"}),e.before("render",function(){this.params.chrome.transparent&&this.sandbox.addRootClass("var-chromeless"),this.params.chrome.hideBorder&&this.sandbox.addRootClass("var-borderless"),this.params.chrome.hideHeader&&this.sandbox.addRootClass("var-headerless"),this.params.chrome.hideFooter&&this.sandbox.addRootClass("var-footerless")}),e.after("render",function(){if(this.params.chrome.hideScrollBar)return this.hideScrollBar()}),e.after("resize",function(){if(this.params.chrome.hideScrollBar)return this.hideScrollBar()}),e.define("hideScrollBar",function(){var e=this.selectOne("streamContainer"),t=this.selectOne("tweetStream");return n.defer(function(){var i,r;e.style.width="",i=e.offsetWidth-t.offsetWidth,r=e.offsetWidth+i,e.style.width=r+"px"})})}var n=i(45),s=i(155);e.exports=r},195:function(e,t){function i(e){e.params({ariaLive:{fallback:""}}),e.selectors({newTweetsNotifier:".new-tweets-bar"}),e.after("render",function(){var e=this.selectOne("newTweetsNotifier");"assertive"===this.params.ariaLive&&e&&e.setAttribute("aria-live","assertive")})}e.exports=i},196:function(e,t,i){function r(e){e.selectors({fullTimestampToLocalize:".long-permalink time",relativeTimestampToLocalize:".permalink time"}),e.after("prepForInsertion",function(e){var t=o(this.el);t&&(this.select(e,"fullTimestampToLocalize").forEach(function(e){var i=e.getAttribute("datetime"),r=i&&t.localTimeStamp(i);r&&(e.innerHTML=r)}),this.select(e,"relativeTimestampToLocalize").forEach(function(e){var i=e.getAttribute("datetime"),r=i&&t.timeAgo(i);r&&(e.innerHTML=r)}))}),e.define("updateRelativeTimestamps",function(){var e=o(this.el);if(e){var t=this.select("relativeTimestampToLocalize").reduce(function(t,i){var r=i.getAttribute("datetime"),n=r&&e.timeAgo(r);return n&&t.push(function(){i.innerHTML=n}),t},[]);return n.all(t.map(s.write))}}),e.after("render",function(){var e=this;a.setInterval(function(){e.updateRelativeTimestamps()},l)})}var n=i(2),s=i(45),a=i(7),o=i(197),l=6e4;e.exports=r},197:function(e,t,i){function r(e){return new s(n.compact({months:(e.getAttribute("data-dt-months")||"").split("|"),phrases:{AM:e.getAttribute("data-dt-am"),PM:e.getAttribute("data-dt-pm"),now:e.getAttribute("data-dt-now"),s:e.getAttribute("data-dt-s"),m:e.getAttribute("data-dt-m"),h:e.getAttribute("data-dt-h"),second:e.getAttribute("data-dt-second"),seconds:e.getAttribute("data-dt-seconds"),minute:e.getAttribute("data-dt-minute"),minutes:e.getAttribute("data-dt-minutes"),hour:e.getAttribute("data-dt-hour"),hours:e.getAttribute("data-dt-hours")},formats:{full:e.getAttribute("data-dt-full"),abbr:e.getAttribute("data-dt-abbr"),shortdate:e.getAttribute("data-dt-short"),longdate:e.getAttribute("data-dt-long")}}))}var n=i(11),s=i(198);e.exports=r},198:function(e,t){function i(e){return e<10?"0"+e:e}function r(e){function t(e,t){return n&&n[e]&&(e=n[e]),e.replace(/%\{([\w_]+)\}/g,function(e,i){return void 0!==t[i]?t[i]:e})}var n=e&&e.phrases,s=e&&e.months||o,a=e&&e.formats||l;this.timeAgo=function(e){var i,n=r.parseDate(e),o=+new Date,l=o-n;return n?isNaN(l)||l<2*d?t("now"):l1?"seconds":"second")})})):l1?"minutes":"minute")})})):l1?"hours":"hour")})})):l<365*h?t(a.shortdate,{day:n.getDate(),month:t(s[n.getMonth()])}):t(a.longdate,{day:n.getDate(),month:t(s[n.getMonth()]),year:n.getFullYear().toString().slice(2)}):""},this.localTimeStamp=function(e){var n=r.parseDate(e),o=n&&n.getHours();return n?t(a.full,{day:n.getDate(),month:t(s[n.getMonth()]),year:n.getFullYear(),hours24:i(o),hours12:o<13?o?o:"12":o-12,minutes:i(n.getMinutes()),seconds:i(n.getSeconds()),amPm:t(o<12?"AM":"PM")}):""}}var n=/(\d{4})-?(\d{2})-?(\d{2})T(\d{2}):?(\d{2}):?(\d{2})(Z|[\+\-]\d{2}:?\d{2})/,s=/[a-z]{3,4} ([a-z]{3}) (\d{1,2}) (\d{1,2}):(\d{2}):(\d{2}) ([\+\-]\d{2}:?\d{2}) (\d{4})/i,a=/^\d+$/,o=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],l={abbr:"%{number}%{symbol}",shortdate:"%{day} %{month}",longdate:"%{day} %{month} %{year}",full:"%{hours12}:%{minutes} %{amPm} - %{day} %{month} %{year}"},d=1e3,u=60*d,c=60*u,h=24*c,f='%{abbr}';r.parseDate=function(e){var t,i,r=e||"",l=r.toString();return!!(t=function(){var e;return a.test(l)?parseInt(l,10):(e=l.match(s))?Date.UTC(e[7],o.indexOf(e[1]),e[2],e[3],e[4],e[5]):(e=l.match(n))?Date.UTC(e[1],e[2]-1,e[3],e[4],e[5],e[6]):void 0}())&&(i=new Date(t),!isNaN(i.getTime())&&i)},e.exports=r},199:function(e,t,i){function r(e){e.selectors({followButton:".follow-button"}),e.define("handleFollowButtonClick",function(e,t){var i=s.intentForFollowURL(t.href),r=a.asBoolean(t.getAttribute("data-age-gate"));r||n.open(i,this.sandbox.sandboxEl,e)}),e.after("render",function(){this.on("click","followButton",function(e,t){this.handleFollowButtonClick(e,t)})})}var n=i(22),s=i(23),a=i(25);e.exports=r},200:function(e,t,i){function r(e){e.selectors({mediaCard:".MediaCard",mediaCardNsfwDismissalTarget:".MediaCard-dismissNsfw"}),e.define("dismissNsfwWarning",function(e,t){var i=n.closest(this.selectors.mediaCard,t,this.el);i&&s.remove(i,"is-nsfw")}),e.after("render",function(){this.on("click","mediaCardNsfwDismissalTarget",this.dismissNsfwWarning)})}var n=i(21),s=i(20);e.exports=r},201:function(e,t,i){function r(e){function t(e){var t=e.createElement("div");return t.className="MediaCard-mediaAsset",t}function i(e){return c.url(e,m)}e.params({lang:{required:!0,transform:d.matchLanguage,fallback:"en"}}),e.selectors({mediaAsset:".MediaCard-mediaAsset",cardInterstitial:".js-cardPlayerInterstitial",wvpInterstitial:".js-playableMediaInterstitial",tweetIdInfo:".js-tweetIdInfo"}),e.define("replaceInterstitialWithMedia",function(e,t){return f.all([this.restoreLastMediaInterstitial(),u.write(function(){n=e,s=e.parentNode,e.parentNode.replaceChild(t,e)})])}),e.define("restoreLastMediaInterstitial",function(){var e;return n&&s?(e=s.firstElementChild,h.remove(e),u.write(function(){s.replaceChild(n,e)})):f.resolve()}),e.define("displayWebVideoPlayerMediaAsset",function(e,i){var r=l.closest(this.selectors.mediaAsset,i,this.el),n=l.closest(this.selectors.tweetIdInfo,i,this.el),s=n.getAttribute("data-tweet-id"),a=(this.scribeNamespace()||{}).page,o=(this.scribeData()||{}).widget_origin,d=this.params.lang,u=t(this.sandbox),c=this.sandbox.createElement("div"),m={widgetOrigin:o};return s?(e.preventDefault(),c.className="wvp-player-container",u.appendChild(c),this.replaceInterstitialWithMedia(r,u).then(function(){return h.insertForTweet(u,s,a,d,m)}).then(function(e){e&&e.on("ready",e.play)})):f.reject(new Error("No Tweet ID for player"))}),e.define("displayIframeMediaAsset",function(e,r){var n,s,d=l.closest(this.selectors.mediaAsset,r,this.el),c=l.closest(this.selectors.cardInterstitial,r,this.el),h=c.getAttribute("data-player-src"),m=c.getAttribute("data-player-width"),g=c.getAttribute("data-player-height"),v=c.getAttribute("data-player-title");return h?(e.preventDefault(),h=i(h),n=t(this.sandbox),s=o({src:h,allowfullscreen:"true",width:m,height:g,title:v||""}),s.className="FilledIframe",n.appendChild(s),this.replaceInterstitialWithMedia(d,n).then(function(){s.focus(),u.write(function(){a.add(n,p),a.add(s,p)})})):f.reject(new Error("No Player frame source"))}),e.after("render",function(){this.on("click","cardInterstitial",this.displayIframeMediaAsset),this.on("click","wvpInterstitial",this.displayWebVideoPlayerMediaAsset)})}var n,s,a=i(20),o=i(52),l=i(21),d=i(90),u=i(45),c=i(24),h=i(144),f=i(2),m={autoplay:"1"},p="js-forceRedraw";e.exports=r},202:function(e,t,i){function r(e){e.override("resizeSandboxDueToCardChange",function(){return this.isFullyExpanded?this.sandbox.matchHeightToContent():n.resolve()})}var n=i(2),s=i(84);e.exports=s.couple(i(203),r)},203:function(e,t,i){function r(e){for(var t="",i=Math.floor(e/h),r=i;r>0;r--)t+="w"+r*h+" ";return t}function n(e){e.selectors({prerenderedCard:".PrerenderedCard",periscopeVideo:".PlayerCard--video",rootCardEl:".TwitterCard .CardContent > *:first-child"}),e.define("scribeCardShown",function(e){var t=2;this.scribe({component:"card",action:"shown"},{items:[{card_name:e.getAttribute("data-card-name")}]},t)}),e.define("resizeSandboxDueToCardChange",function(){return this.sandbox.matchHeightToContent()}),e.define("markCardElAsLoaded",function(e){function t(){r&&i.resizeSandboxDueToCardChange()}var i=this,r=!1;return this.select(e,"img").forEach(function(e){e.addEventListener("load",t,!1)}),this.scribeCardShown(e),a.write(function(){s.add(e,p)}).then(function(){r=!0,i.resizeSandboxDueToCardChange()})}),e.define("updateCardWidthConstraints",function(){var e=this;return d.all(this.select("prerenderedCard").map(function(t){var i=e.selectOne(t,"rootCardEl");return a.defer(function(){var e,n=0;l.ios()?(s.remove(t,g),n=o(t.parentElement).width,t.style.maxWidth=n+"px"):n=o(t.parentElement).width,e=r(n),i.setAttribute(f,e),s.add(t,g)}).then(function(){return e.resizeSandboxDueToCardChange()})}))}),e.define("setCardTheme",function(e){var t=this.selectOne(e,"rootCardEl");this.params.theme&&t.setAttribute(m,this.params.theme)}),e.after("prepForInsertion",function(e){var t=this,i=this.select(e,"prerenderedCard").reduce(function(e,t){var i=t.getAttribute("data-css");return i&&(e[i]=e[i]||[],e[i].push(t)),e},{});u.forIn(i,function(e,i){t.sandbox.prependStyleSheet(e).then(function(){i.forEach(function(e){t.setCardTheme(e),t.markCardElAsLoaded(e)})})})}),e.after("show",function(){var e;return l.anyIE()&&(e=this.selectOne("periscopeVideo"),e&&(e.style.display="none")),this.updateCardWidthConstraints()}),e.after("resize",function(){return this.updateCardWidthConstraints()})}var s=i(20),a=i(45),o=i(69),l=i(8),d=i(2),u=i(11),c=i(84),h=50,f="data-card-breakpoints",m="data-theme",p="is-loaded",g="is-constrainedByMaxWidth";e.exports=c.couple(i(98),n)},204:function(e,t,i){function r(e,t,i){var r={};return e=e||{},i&&e.max?r.minPosition=e.max:!i&&e.min?r.maxPosition=e.min:i?r.sinceId=t:r.maxId=t,r}function n(e){e.params({dataSource:{required:!0},isPreviewTimeline:{required:!1,fallback:!1}}),e.selectors({timelineTweet:".timeline-Tweet",viewport:".timeline-Viewport",tweetList:".timeline-TweetList",tweetsInStream:".timeline-Tweet",newTweetsNotifier:".new-tweets-bar",loadMore:".timeline-LoadMore",loadMoreButton:".timeline-LoadMore-prompt"}),e.define("gcTweetsSync",function(){var e="custom"===this.el.getAttribute("data-timeline-type"),t=this.selectOne("tweetList");return e?a.resolve():void m(t,b)}),e.define("scribeImpressionsForDynamicTweetSet",function(e,t){var i=c.toRealArray(e.querySelectorAll(this.selectors.timelineTweet)),r=f(i),n=Object.keys(r),s=t?"newer":"older",a=t?v.CLIENT_SIDE_APP:v.CLIENT_SIDE_USER;this.scribe({component:"timeline",element:s,action:"results"},{item_ids:n,item_details:r,event_initiator:a})}),e.define("fetchTweets",function(e,t){function i(e){return"404"===e?s.pollInterval=null:"503"===e&&(s.pollInterval*=1.5),a.reject(e)}function n(i){var r,n,a=s.sandbox.createFragment(),o=s.sandbox.createElement("ol"),l=t?w.NEWER:w.OLDER;return p(s,i,l),o.innerHTML=i.html,r=o.firstElementChild,r&&(n=s.selectOne(r,"timelineTweet")),n&&"LI"===r.tagName?(n.getAttribute("data-tweet-id")===e&&o.removeChild(r),s.scribeImpressionsForDynamicTweetSet(o,t),s.prepForInsertion(o),c.toRealArray(o.children).forEach(function(e){a.appendChild(e)}),a):a}var s=this,o=r(this.cursors,e,t);return this.params.dataSource.poll(o,t).then(n,i)}),e.define("loadOldTweets",function(){var e=this,t=this.selectLast("tweetsInStream"),i=t&&t.getAttribute("data-tweet-id");return i?this.fetchTweets(i,!1).then(function(t){var i=e.selectOne("tweetList"),r=e.selectOne("loadMore");return l.write(function(){t.childNodes.length>0?i.appendChild(t):o.add(r,C)})}):a.reject(new Error("unable to load more"))}),e.after("loadOldTweets",function(){return g.trigger("timelineUpdated",{target:this.sandbox.sandboxEl,region:"older"}),this.resize()}),e.define("loadNewTweets",function(){var e=this,t=this.selectOne("tweetsInStream"),i=t&&t.getAttribute("data-tweet-id");return i?this.fetchTweets(i,!0).then(function(t){var i,r,n=e.selectOne("viewport"),s=e.selectOne("tweetList");if(0!==t.childNodes.length)return l.read(function(){i=n.scrollTop,r=n.scrollHeight}),l.defer(function(){var a;s.insertBefore(t,s.firstElementChild),a=i+n.scrollHeight-r,i>40||e.mouseIsOverWidget?(n.scrollTop=a,e.showNewTweetsNotifier()):(n.scrollTop=0,e.gcTweetsSync())})}):a.reject(new Error("unable to load new tweets"))}),e.after("loadNewTweets",function(){return g.trigger("timelineUpdated",{target:this.sandbox.sandboxEl,region:"newer"}),this.resize()}),e.define("showNewTweetsNotifier",function(){var e=this,t=this.selectOne("newTweetsNotifier"),i=t&&t.firstElementChild;return d.setTimeout(function(){e.hideNewTweetsNotifier()},T),l.write(function(){t.removeChild(i),t.appendChild(i),o.add(t,"is-displayed")}),l.defer(function(){o.add(t,"is-opaque")})}),e.define("hideNewTweetsNotifier",function(e){var t=new s,i=this.selectOne("newTweetsNotifier");return e=e||{},!e.force&&this.mouseIsOverNewTweetsNotifier?(t.resolve(),t.promise):(l.write(function(){o.remove(i,"is-opaque")}),d.setTimeout(function(){l.write(function(){o.remove(i,"is-displayed")}).then(t.resolve,t.reject)},x),t.promise)}),e.define("scrollToTopOfViewport",function(){var e=this.selectOne("viewport");return l.write(function(){e.scrollTop=0,e.focus()})}),e.define("schedulePolling",function(){function e(){i.isPollInProgress=!1}function t(){var n=r||i.pollInterval;n&&d.setTimeout(function(){i.isPollInProgress||(i.isPollInProgress=!0,i.loadNewTweets(i.sandbox).then(e,e)),t()},n)}var i=this,r=u.get("timeline.pollInterval");t()}),e.after("initialize",function(){this.isPollInProgress=!1,this.mouseIsOverWidget=!1,this.mouseIsOverNewTweetsNotifier=!1,this.cursors={},this.pollInterval=1e4}),e.after("render",function(){this.isStaticTimeline||this.params.isPreviewTimeline||(this.select("timelineTweet").length>0&&this.schedulePolling(),this.on("mouseover",function(){this.mouseIsOverWidget=!0}),this.on("mouseout",function(){this.mouseIsOverWidget=!1}),this.on("mouseover","newTweetsNotifier",function(){this.mouseIsOverNewTweetsNotifier=!0}),this.on("mouseout","newTweetsNotifier",function(){this.mouseIsOverNewTweetsNotifier=!1}),this.on("click","newTweetsNotifier",function(){this.scrollToTopOfViewport(),this.hideNewTweetsNotifier({force:!0})}),this.on("click","loadMoreButton",function(){this.loadOldTweets()}))})}var s=i(1),a=i(2),o=i(20),l=i(45),d=i(7),u=i(16),c=i(11),h=i(84),f=i(101),m=i(205),p=i(192),g=i(29),v=i(206),w=i(193),b=50,T=5e3,x=500,C="is-atEndOfTimeline";e.exports=h.couple(i(98),n)},205:function(e,t){function i(e,t){var i;if(e)for(;i=e.children[t];)e.removeChild(i)}e.exports=i},206:function(e,t){e.exports={CLIENT_SIDE_USER:0,CLIENT_SIDE_APP:2}},207:function(e,t,i){function r(e){e.selectors({shareMenuOpener:".js-showShareMenu",shareMenu:".timeline-ShareMenu",shareMenuTimelineHeader:".timeline-Header",shareMenuTimelineFooter:".timeline-Footer"}),e.define("getHeaderHeight",function(){var e=this.selectOne("shareMenuTimelineHeader");return e?e.getBoundingClientRect().height:0}),e.define("getFooterHeight",function(){var e=this.selectOne("shareMenuTimelineFooter");return e?e.getBoundingClientRect().height:0}),e.define("getShareMenuPositionClass",function(e){var t=e.getBoundingClientRect(),i=t.top-this.getHeaderHeight(),r=this.sandbox.height-t.bottom-this.getFooterHeight();return r 2 | 3 | 4 | 5 | 6 | TaffyDB - Working with data 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 53 | 54 | 55 | 56 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 80 | 81 | 82 | 83 | 84 | 85 | 113 | 114 |
115 |
116 |
117 | 118 | 138 | 139 |
140 |
141 |
142 | 143 | 144 |

Working with data

145 | 146 |

Creating your database

147 |

You use the global TAFFY function to create a new database.

148 |
// Create a new empty database
149 | var db = TAFFY();
150 | 
151 | // Create a new database a single object (first record)
152 | var db = TAFFY({record:1,text:"example"})
153 | 
154 | // Create a new database using an array
155 | var db = TAFFY([{record:1,text:"example"}])
156 | 
157 | // Create a new database using a JSON string
158 | var db = TAFFY('[{"record":1,"text":"example"}]')
159 | 
160 |

DB Queries

161 |

Once you have a database you'll be able to call your variable as function. This will setup a query and return a collection of methods to work with the results of that query.

162 | 163 | 164 | 167 | 170 | 173 | 176 | 177 | 178 | 182 | 183 |
165 | db() 166 | 168 | Takes:
One or more Strings, Records, A Filter Objects, Arrays, or Functions. 169 |
171 | Returns:
A Query Object 172 |
174 | Used to query the database and return a method collection to start working with the data. 175 |
179 |
db(); // returns all rows
180 | 
181 |
184 |

DB Methods

185 |

In addition to the query function you have a couple of top level methods to use.

186 | 187 | 188 | 191 | 199 | 202 | 205 | 206 | 207 | 210 | 223 | 226 | 229 | 230 | 231 | 236 | 237 | 238 | 241 | 245 | 248 | 252 | 253 | 254 | 257 | 258 | 259 | 262 | 265 | 268 | 275 | 276 | 277 | 280 | 281 | 282 | 285 | 288 | 291 | 305 | 306 | 307 | 314 | 315 |
189 | db.insert() 190 | 192 | Takes:
An object or array of objects/json strings to insert. 193 |
194 |
195 | Optional: Call Event override 196 |
true runs onInsert event (default) 197 |
false does not onInsert event 198 |
200 | Returns:
A query pointing to the inserted records 201 |
203 | Inserts records into the database. 204 |
208 | db.merge() 209 | 211 | Takes:
An object or array of objects/json strings to insert. 212 |
213 |
214 | Optional: Key 215 |
identity column to be used to match records against the existing db. Default "id". 216 |
true runs onInsert for new records and onUpdate for changed records 217 |
218 |
219 | Optional: Call Event override 220 |
false does not run insert or update event (default) 221 |
true runs onInsert for new records and onUpdate for changed records 222 |
224 | Returns:
A query pointing to the changed or inserted records 225 |
227 | Inserts or replaces records in an existing db. 228 |
232 |
db.insert({column:"value"}); // inserts one record
233 | 						
234 | db.insert({column:"value"},false); // insert but do not call onInsert event
235 |
239 | db.order() 240 | 242 | Takes:
A string listing columns to order by separated by commas.
243 | Optional: Use asec, desc, logical, and logicaldesc to influencence sort direction. 244 |
246 | Returns:
true 247 |
249 | Sorts the db by column. Note that logical sorting is default.
250 | Note: db.sort() is different than db().order() in that sort() changes the order of the records in the database while order() only impacts the order of results returned from a query. 251 |
255 |
db.order("columnname"); // orders collection by columnname
256 |
260 | db.store() 261 | 263 | Takes:
A string with the storage name for the DB
264 |
266 | Returns:
true if data was returned from localStorage, false if no data returned 267 |
269 | Sets up a localStorage collection for a given name. If data exists already the data will be loaded into the collection. Changes are auto synced to localStorage.

270 | Pass in false to terminate storing the collection (data in localstorage will be unchanged). 271 |

272 | Note: localStorage is not avaliable in all browsers. If localStorage is not found then .store() will be ignored. 273 | 274 |
278 |
db.store("name"); // starts storing records in local storage
279 |
283 | db.settings() 284 | 286 | Takes:
An object. 287 |
289 | Returns:
The settings object 290 |
292 | Used to modify the following settings on each DB: 293 |
    294 |
  • template: this is a template object {} that is merged with each new record as it is added
  • 295 |
  • forcePropertyCase: (defaults null) Can be "lower" or "higher" and forces properties to a case on insert, update.
  • 296 |
  • onInsert: function to run on record insert. The this keyword will be the new record.
  • 297 |
  • onUpdate: function to run on record update. The this keyword will be the new record. Arg 1 will be old record. Arg 2 will be the changes.
  • 298 |
  • onRemove: function to run on record remove. The this keyword will be the removed record.
  • 299 |
  • onDBChange: function to run on change to the DB. The this keyword will be the entire DB.
  • 300 |
  • cacheSize: size of cached query collection. Default to 100. Set to 0 to turn off caching.
  • 301 |
  • name: string name for the db table to be used at a later date.
  • 302 | 303 |
304 |
308 |
db.settings({template:{show:true}}); // sets the template to have a show value set to true by default on all records
309 | 
310 | db.settings({onUpdate:function () {alert(this)}}); // sets the onUpdate event
311 | 
312 | 					
313 |
316 | 317 |

Query Object Methods

318 | 319 |

Any call to data collections root function will return a new query object. The methods below can be used 320 | to interact with the data.

321 | 322 | 323 | 326 | 337 | 340 | 343 | 344 | 345 | 355 | 356 | 357 | 360 | 367 | 370 | 373 | 374 | 375 | 380 | 381 | 382 | 385 | 389 | 392 | 396 | 397 | 398 | 406 | 407 | 408 | 411 | 415 | 418 | 423 | 424 | 425 | 435 | 436 | 437 | 440 | 443 | 446 | 449 | 450 | 451 | 454 | 455 | 456 | 459 | 462 | 465 | 468 | 469 | 470 | 473 | 474 | 475 | 478 | 481 | 484 | 487 | 488 | 489 | 494 | 495 | 496 | 499 | 502 | 505 | 508 | 509 | 510 | 515 | 516 | 517 | 520 | 523 | 526 | 529 | 530 | 531 | 536 | 537 | 538 | 541 | 544 | 547 | 550 | 551 | 552 | 555 | 556 | 557 | 560 | 563 | 566 | 569 | 570 | 571 | 574 | 575 | 576 | 579 | 582 | 585 | 588 | 589 | 590 | 593 | 594 | 595 | 598 | 601 | 604 | 607 | 608 | 609 | 612 | 613 | 614 | 617 | 620 | 623 | 626 | 627 | 628 | 631 | 632 | 633 | 636 | 639 | 642 | 645 | 646 | 647 | 650 | 651 | 652 | 655 | 658 | 661 | 664 | 665 | 666 | 670 | 671 | 672 | 675 | 678 | 682 | 685 | 686 | 687 | 696 | 697 | 698 | 701 | 704 | 708 | 711 | 712 | 713 | 721 | 722 | 723 | 726 | 730 | 733 | 736 | 737 | 738 | 747 | 748 | 749 | 752 | 758 | 761 | 765 | 766 | 767 | 799 | 800 |
324 | db().update() 325 | 327 | Takes:
Any: 328 |
An object to be merged with the matching objects. 329 |
A function that will return the modified record for update. 330 |
Two arguments: a string column name and a value to set the column to 331 |
332 |
333 | Optional Call Event override 334 |
true runs onUpdate event (default) 335 |
false does not onUpdate event 336 |
338 | Returns:
Query Object 339 |
341 | Updates the records in the query set. 342 |
346 |
db().update({column:"value"}); // sets column to "value" for all matching records
347 | 
348 | db().update("column","value"); // sets column to "value" for all matching records
349 | 
350 | db().update(function () {this.column = "value";return this;}); // sets column to "value" for all matching records
351 | 
352 | 
353 | db().update({column:"value"},false); // update but do not call onUpdate event
354 |
358 | db().remove() 359 | 361 | Takes:
362 |
363 | Optional Call Event override 364 |
true runs onUpdate event (default) 365 |
false does not onUpdate event 366 |
368 | Returns:
Count of removed records. 369 |
371 | Removes records from the database 372 |
376 |
db().remove(); // removes all matching records from the database
377 | 						
378 | db().remove(true); // removes but do not call onRemove event
379 |
383 | db().filter() 384 | 386 | Takes:
One or more Strings, Records, A Filter Objects, Arrays, or Functions. 387 | 388 |
390 | Returns:
Query Object 391 |
393 | See Filtering
394 | Applies a sub filter and returns a new Query Object to let you access the results of the filter. 395 |
399 |
db().filter({column:value});
400 | 						
401 | db().filter({column:value}).count();
402 | 
403 | collection({column:{gte:value}}).filter({column:{lte:value}}).count();
404 | 					
405 |
409 | db().order() 410 | 412 | Takes:
A string listing columns to order by separated by commas.
413 | Optional: Use asec, desc, logical, and logicaldesc to influence sort direction. 414 |
416 | Returns:
Query Object 417 |
419 | Sorts the query results by column based. Note that logical sorting is default. 420 | Note: db.sort() is different than db().order() in that sort() changes the order of the records in the database while order() only impacts the order of results returned from a query. 421 | 422 |
426 |
db().order("col1"); // sorts by col1 using a logical sort
427 | 
428 | db().order("col1 asec, col2 asec"); // sorts by col1 then col2
429 | 
430 | db().order("col1 desc"); // sorts by col1 descending
431 | 
432 | db().order("col1 logicaldesc"); // sorts by col1 using a logical sort descending
433 | 					
434 |
438 | db().limit() 439 | 441 | Takes:
A number. 442 |
444 | Returns:
Query Object 445 |
447 | Limits the number of results in a query set. 448 |
452 |
db().limit(15); // Limits returned results to first 15
453 |
457 | db().start() 458 | 460 | Takes:
A number. 461 |
463 | Returns:
Query Object 464 |
466 | Sets the starting record number. Used for offset and paging. 467 |
471 |
db().start(15); // Starts returning results at record 15
472 |
476 | db().each() 477 | 479 | Takes:
A function. 480 |
482 | Returns:
Query Object 483 |
485 | Runs one or more functions once for every record in the query. 486 |
490 |
db().each(function (record,recordnumber) {
491 | 	alert(record["balance"]);
492 | }); // alerts the value of the balance column for each record
493 |
497 | db().map() 498 | 500 | Takes:
A function. 501 |
503 | Returns:
An array of results from your function being run against the records in the query. 504 |
506 | Runs your function against each record in the query and returns the results as an array. 507 |
511 |
db().map(function (record,recordnumber) {
512 | 	return record.balance*0.2;
513 | }); // returns an array of numbers that are each 20% of the actual balance for each record
514 |
518 | db().callback() 519 | 521 | Takes:
A function and an (optional) delay. 522 |
524 | 525 | 527 | Used for lazy query execution and to prevent blocking. Provided function will be called with current Quote Object after query has run in a setTimeout block. 528 |
532 |
db().callback(function () {
533 |     alert(this.count()); // alert count of matching records					
534 | });
535 |
539 | db().get() 540 | 542 | 543 | 545 | Returns:
An array of all matching records. 546 |
548 | Prefered method for extracting data. Returns an array of matching records. Also used for exporting records form the database. 549 |
553 |
db().get(); // returns an array of all matching records
554 |
558 | db().stringify() 559 | 561 | 562 | 564 | Returns:
A JSON representation of an array of all matching records. 565 |
567 | Used for exporting data as JSON text. Returns a JSON array filled with JSON objects for each record. 568 |
572 |
db().stringify(); // returns a JSON array of all matching records
573 |
577 | db().first() 578 | 580 | 581 | 583 | Returns:
A single record. 584 |
586 | Returns the first record in a record set. 587 |
591 |
db().first(); // returns the first record out of all matching records.
592 |
596 | db().last() 597 | 599 | 600 | 602 | Returns:
A single record. 603 |
605 | Returns the last record in a record set. 606 |
610 |
db().last(); // returns the last record out of all matching records.
611 |
615 | db().sum() 616 | 618 | Takes:
One or more column names. 619 |
621 | Returns:
A number. 622 |
624 | Returns the sum total of the column or columns passed into it. 625 |
629 |
db().last("balance"); // returns the sum of the "balance" column.
630 |
634 | db().min() 635 | 637 | Takes:
Column name. 638 |
640 | Returns:
A number or value. 641 |
643 | Returns the min value for the column passed in. 644 |
648 |
db().min("balance"); // returns the lowest value of the "balance" column.
649 |
653 | db().max() 654 | 656 | Takes:
Column name. 657 |
659 | Returns:
A number or value. 660 |
662 | Returns the max value for the column passed in. 663 |
667 |
db().max("balance"); 
668 | // returns the highest value of the "balance" column.
669 |
673 | db().select() 674 | 676 | Takes:
One or more column names. 677 |
679 | Returns:
For one column: An array of values.
680 | For two or more columns: An array of arrays of values. 681 |
683 | Used to select columns out the database. Pass in column names to get back an array of values. 684 |
688 |
db().select("charges","credits","balance"); 
689 | // returns an array of arrays in this format [[-24,20,-4]]
690 | 
691 | db().select("balance"); 
692 | // returns an array of values in this format [-4,6,7,10]
693 | 					
694 | 695 |
699 | db().distinct() 700 | 702 | Takes:
One or more column names. 703 |
705 | Returns:
For one column: An array of values.
706 | For two or more columns: An array of arrays of values. 707 |
709 | Used to select distinct values from the database for one or more columns. Pass in column names to get back an array of distinct values. 710 |
714 |
db().distinct("title","gender"); 
715 | // returns an array of arrays in this format [["Mr.","Male"],["Ms.","Female"]]
716 | 
717 | db().distinct("title"); 
718 | // returns an array of values in this format ["Mr.","Ms.","Mrs."]
719 | 720 |
724 | db().supplant() 725 | 727 | Takes:
A string template.
728 | Optional return array flag. 729 |
731 | Returns:
Defaults to a string. If return array flag is true then an array of strings with an entry for each record. 732 |
734 | Used to merge records with a template formated with {key} values to be replaced with real values from the records. 735 |
739 |
db().supplant("<tr><td>{balance}</td></tr>"); 
740 | // returns a string in this format "<tr><td>-4</td></tr><tr><td>6</td></tr>"
741 | 
742 | db().supplant("<tr><td>{balance}</td></tr>",true); 
743 | // returns an array of strings format ["<tr><td>-4</td></tr>","<tr><td>6</td></tr>"]
744 | 
745 | 746 |
750 | db().join() 751 | 753 | Takes:
1. A second db or reference to a db query.
754 | 2. One or more functions to be used as join conditions or
755 | An an array of one or more join conditions
756 | 757 |
759 | Returns:
A db query object containing the joined rows. 760 |
762 | Used to join two dbs and/or queries together and produce a hybrid query containing the joined data.

763 | [EXPERIMENTAL FEATURE] 764 |
768 | 769 |
// City DB
770 | city_db = TAFFY([
771 |   {name:'New York',state:'NY'},
772 |   {name:'Las Vegas',state:'NV'},
773 |   {name:'Boston',state:'MA'}
774 | ]);
775 | 
776 | // State DB
777 | state_db = TAFFY([
778 |   {name: 'New York', abbreviation: 'NY'},
779 |   {name: 'Nevada', abbreviation: 'NV'},
780 |   {name: 'Massachusetts', abbreviation: 'MA'}
781 | ]);
782 | 
783 | // Conditional Join
784 | city_db()
785 |   .join( state_db, [ 'state', 'abbreviation' ]);
786 | 
787 | // Conditional Join with optional ===
788 | city_db()
789 |   .join( state_db, [ 'state', '===', 'abbreviation' ]);
790 |   
791 | // Conditional Join using function
792 | city_db()
793 |   .join( state_db, function (l, r) {
794 |       return (l.state === r.abbreviation);
795 |     });
796 | 
797 | 798 |
801 | 802 | 803 |
804 |
805 | 806 | 807 | 808 |
809 | 810 | 811 |
812 |
813 | 814 |
815 | 816 |
817 |
818 |
819 | 820 |
821 | 822 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | -------------------------------------------------------------------------------- /docs/writing_queries.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | TaffyDB - Writing queries 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 53 | 54 | 55 | 56 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 80 | 81 | 82 | 83 | 84 | 85 | 113 | 114 |
115 |
116 |
117 | 118 | 137 | 138 |
139 |
140 |
141 | 142 | 143 |

Writing queries

144 | 145 |

The heart of TaffyDB and any database is running queries against your data. This is done after creation of your database by calling the root function and building Filter Objects.

146 |
// Create a new empty database
147 | var db = TAFFY();
148 | 
149 | // Run a query against the DB to return all rows
150 | db();
151 | 
152 | // Real world example - remove all records
153 | db().remove();
154 | 
155 | 156 |

Looking up individual records

157 |

Every object within a TaffyDB collection has a ___id value set by TaffyDB. This value is not intended for you to know, but is useful when building dynamic applications. This can be used to lookup a record by passing it into the root function as a string.

158 |
// Looks up a record based on its id
159 | db("T000008R000002");
160 | 
161 | // Real world example - update records "status" column
162 | db("T000008R000002").update({status:"Active"});
163 | 
164 |

This also works if you have a copy of the whole record.

165 |
// get the first record
166 | var firstRecord = db().first();
167 | 
168 | // look up this record again
169 | db(firstRecord);
170 | 
171 | // Real world example - update records "status" column
172 | db(firstRecord).update({status:"Active"});
173 | 
174 |

Using functions

175 |

To give you full control over the results of your query you can always pass in a function. Just have it return true if you want the record in your final results.

176 |
// functional example, returns all records
177 | db(function () {
178 | 	return true;
179 | });
180 | 
181 | 
182 | // Real world example - function returns records with a status of active
183 | db(function () {
184 | 	return (this.status == "Active") ? true : false;
185 | });
186 | 
187 | 188 | 189 |

Basic queries

190 |

TaffyDB uses a very JavaScript centric Filter Object for looking up queries. There is no string concatenation and you can quickly compose these by hand or dynamically from within your app. The filter object is compared against each record using some business rules and if it passes the record remains in the results set.

191 | 192 |

The most common Filter Object is used simply to check if a column is equal to value.

193 |
// does a match for column and value
194 | db({column:"value"});
195 | 
196 | 
197 | // Real world example - records with a status of active
198 | db({status:"Active"});
199 | 
200 |

This is the short form of this

201 |
// does a match for column and value
202 | db({column:{is:"value"}});
203 | 
204 | 
205 | // Real world example - records with a status of active
206 | db({status:{is:"Active"}});
207 | 
208 |

The "is" part of this expressions can be swapped out for a variety of other comparisons as listed below.

209 |

Using !(bang)

210 |

For any comparison operator you can quote it and add a ! sign to reverse the meaning.

211 |
// does a match for column that is not a value
212 | db({column:{"!is":"value"}});
213 | 
214 | // Real world example - records with a status other than of active
215 | db({status:{"!is":"Active"}});
216 | 
217 |

Adding additional filters

218 |

Using the almighty comma you can add additional lookups to you Filter Object.

219 |
// does a match for column that is a value and column2 is a value
220 | db({column:"value",column2:"value"});
221 | 
222 | // Real world example - records with a status of active and a role of admin
223 | db({status:"Active",role:"Admin"});
224 | 
225 |

You can also pass in additional Filter Objects into the function

226 |
// does a match for column that is a value and column2 is a value
227 | db({column:"value"},{column2:"value"});
228 | 
229 | // Real world example - records with a status of active and a role of admin
230 | db({status:"Active"},{role:"Admin"});
231 | 
232 |

Using arrays for IN and OR

233 |

In a database you can use "in" to pass in a collection of values to compare against. This is possible in TaffyDB via the array.

234 |
// does a match for column that is one of two values
235 | db({column:["value","value2"]);
236 | 
237 | // Real world example - records with a status of active or pending
238 | db({status:["Active","Pending"]});
239 | 
240 |

You can also pass in an array of Filter Objects with each one being treated as a logical OR.

241 |
// does a match for column that is one of two values
242 | db([{column:"value"},{column:"value2"}]);
243 | 
244 | // Real world example - records with a status of active or pending
245 | db([{status:"Active"},{status:"Pending"}]);
246 | 
247 |

Bringing it all together

248 |

A real world example of a complex query.

249 |
// return records where the role is Admin and the status is Active. 
250 | // Also return records where the role is Admin, the status is Pending, and the manager_review is true
251 | 
252 | db({role:"Admin"},[{status:"Active"},{status:"Pending",manager_review:true}]);
253 | 
254 |

Comparison Operators

255 |

In addition to the default "is" operator there are a lot of other operators you can use to lookup records.

256 | 257 | 258 | 261 | 264 | 267 | 268 | 269 | 272 | 275 | 278 | 279 | 280 | 283 | 286 | 289 | 290 | 291 | 294 | 297 | 300 | 301 | 302 | 305 | 308 | 311 | 312 | 313 | 316 | 319 | 322 | 323 | 324 | 327 | 330 | 333 | 334 | 335 | 338 | 341 | 344 | 345 | 346 | 349 | 352 | 355 | 356 | 357 | 360 | 363 | 366 | 367 | 368 | 371 | 374 | 377 | 378 | 379 | 382 | 385 | 388 | 389 | 390 | 393 | 396 | 399 | 400 | 401 | 404 | 407 | 410 | 411 | 412 | 415 | 418 | 421 | 422 | 423 | 426 | 429 | 432 | 433 | 434 | 437 | 440 | 443 | 444 | 445 | 446 | 449 | 452 | 455 | 456 | 457 | 460 | 463 | 466 | 467 | 468 | 471 | 474 | 477 | 478 | 479 | 482 | 485 | 488 | 489 | 490 | 493 | 496 | 499 | 500 | 501 | 504 | 507 | 510 | 511 | 512 | 515 | 518 | 521 | 522 | 523 | 526 | 529 | 532 | 533 | 534 | 537 | 540 | 543 | 544 | 545 | 548 | 551 | 554 | 555 |
259 | is 260 | 262 | Example:
{column:{is:value}} 263 |
265 | Used to see if a column is of same type and value of supplied value. 266 |
270 | == 271 | 273 | Example:
{column:{'==':value}} 274 |
276 | Used to see if a column matches a supplied value using JavaScript's liberal coercion rules. 277 |
281 | === 282 | 284 | Example:
{column:{'===':value}} 285 |
287 | Used to see if a column is of same type and value of supplied value. 288 |
292 | isnocase 293 | 295 | Example:
{column:{isnocase:value}} 296 |
298 | Used to see if a column value is equal to a supplied value. Ignores case of column and value. 299 |
303 | left 304 | 306 | Example:
{column:{left:value}} 307 |
309 | Used to see if the start of a column is the same as a supplied value. 310 |
314 | leftnocase 315 | 317 | Example:
{column:{leftnocase:value}} 318 |
320 | Used to see if the start of a column is the same as a supplied value. Ignores case of column and value. 321 |
325 | right 326 | 328 | Example:
{column:{right:value}} 329 |
331 | Used to see if the end of a column is the same as a supplied value. 332 |
336 | rightnocase 337 | 339 | Example:
{column:{rightnocase:value}} 340 |
342 | Used to see if the end of a column is the same as a supplied value. Ignores case of column and value 343 |
347 | like 348 | 350 | Example:
{column:{like:value}} 351 |
353 | Used to see if column contains a supplied value. 354 |
358 | likenocase 359 | 361 | Example:
{column:{likenocase:value}} 362 |
364 | Used to see if column contains a supplied value. Ignores case of column and value 365 |
369 | regex 370 | 372 | Example:
{column:{regex:value}} 373 |
375 | Used to see if column matches a supplied regular expression. 376 |
380 | lt 381 | 383 | Example:
{column:{lt:value}} or {column:{'<':value}} 384 |
386 | Used to see if column is less than a supplied value. 387 |
391 | lte 392 | 394 | Example:
{column:{lte:value}} or {column:{'<=':value}} 395 |
397 | Used to see if column is less than or equal to a supplied value. 398 |
402 | gt 403 | 405 | Example:
{column:{gt:value}} or {column:{'>':value}} 406 |
408 | Used to see if column is greater than a supplied value. 409 |
413 | gte 414 | 416 | Example:
{column:{gte:value}} or {column:{'>=':value}} 417 |
419 | Used to see if column is greater than or equal to a supplied value. 420 |
424 | has 425 | 427 | Example:
{column:{has:value}} 428 |
430 | Used to see if column that is an object has a value or object appearing in its tree. 431 |
435 | hasAll 436 | 438 | Example:
{column:{hasAll:value}} 439 |
441 | Used to see if column that is an object has a value or object appearing in its tree. 442 |
447 | isSameArray 448 | 450 | Example:
{column:{isSameArray:value}} 451 |
453 | Used to see if column is an array and is the same as a supplied array. 454 |
458 | isSameObject 459 | 461 | Example:
{column:{isSameObject:value}} 462 |
464 | Used to see if column is an object and is the same as a supplied object. 465 |
469 | isString 470 | 472 | Example:
{column:{isString:true}} 473 |
475 | Used to see if column a string. 476 |
480 | isNumber 481 | 483 | Example:
{column:{isNumber:true}} 484 |
486 | Used to see if column a number. 487 |
491 | isArray 492 | 494 | Example:
{column:{isArray:true}} 495 |
497 | Used to see if column an array. 498 |
502 | isObject 503 | 505 | Example:
{column:{isObject:true}} 506 |
508 | Used to see if column an object. 509 |
513 | isFunction 514 | 516 | Example:
{column:{isFunction:true}} 517 |
519 | Used to see if column a function. 520 |
524 | isBoolean 525 | 527 | Example:
{column:{isBoolean:true}} 528 |
530 | Used to see if column a boolean (true/false). 531 |
535 | isNull 536 | 538 | Example:
{column:{isNull:true}} 539 |
541 | Used to see if column null. 542 |
546 | isUndefined 547 | 549 | Example:
{column:{isUndefined:true}} 550 |
552 | Used to see if column undefined. 553 |
556 | 557 | 558 | 559 | 560 | 561 | 562 |
563 |
564 | 565 | 566 | 567 |
568 | 569 | 570 |
571 |
572 | 573 |
574 | 575 |
576 |
577 |
578 | 579 |
580 | 581 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "taffydb", 3 | "version": "2.7.3", 4 | "description": "TaffyDB is an opensouce library that brings database features into your JavaScript applications.", 5 | "keywords": [ 6 | "database", "browser", "json", "collection", "records", "node", "nodejs" 7 | ], 8 | "main": "taffy.js", 9 | "scripts": { 10 | "test": "node_modules/.bin/nodeunit test/t.js" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/typicaljoe/taffydb.git" 15 | }, 16 | "author": { "name": "Ian Smith" }, 17 | "contributors": [ 18 | { "name": "Ian Smith" }, 19 | { "name": "Todd Chambery", 20 | "email": "todd.chambery@gmail.com" 21 | }, 22 | { "name": "Daniel Ruf", 23 | "email": "kontakt@daniel-ruf.de" 24 | }, 25 | { "name": "Michael Mikowski", 26 | "email": "mike.mikowski@gmail.com" 27 | }, 28 | { "name": "Matthew Chase Whittemore", 29 | "email": "mcwhittemore@gmail.com" 30 | } 31 | ], 32 | "license": "BSD-2-Clause", 33 | "bugs": { 34 | "url": "https://github.com/typicaljoe/taffydb/issues" 35 | }, 36 | "homepage": "http://www.taffydb.com", 37 | "dependencies": {}, 38 | "devDependencies": { 39 | "jslint": "^0.9.3", 40 | "nodeunit": "^0.9.1", 41 | "nodeunit-b": "^4.0.0", 42 | "node-inspector" : "^0.12.5", 43 | "uglifyjs": "^2.4.10" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /taffy-min.js: -------------------------------------------------------------------------------- 1 | var TAFFY,exports,T;!function(){"use strict";var _t_,_e_,_n_,_r_,_i_,_s_,_u_,_o_,_c_,_a_,_l_,_f_,_h_,_T_,_g_,_F_,_p_,_d_,_A_,_v_,_y_,_m_,___,_x_;if(!TAFFY)for(_i_="2.7",_s_=1,_u_="000000",_o_=1e3,_c_={},_x_=function(_t_){var _e_=Array.prototype.slice.call(_t_);return _e_.sort()},_a_=function(_t_){return TAFFY.isArray(_t_)||TAFFY.isObject(_t_)?_t_:JSON.parse(_t_)},_A_=function(_t_,_e_){return _v_(_t_,function(_t_){return _e_.indexOf(_t_)>=0})},_v_=function(_t_,_e_,_n_){var _r_=[];return null==_t_?_r_:Array.prototype.filter&&_t_.filter===Array.prototype.filter?_t_.filter(_e_,_n_):(_l_(_t_,function(_t_,_i_,_s_){_e_.call(_n_,_t_,_i_,_s_)&&(_r_[_r_.length]=_t_)}),_r_)},___=function(_t_){return"[object RegExp]"===Object.prototype.toString.call(_t_)},_m_=function(_t_){var _e_=T.isArray(_t_)?[]:T.isObject(_t_)?{}:null;if(null===_t_)return _t_;for(var _n_ in _t_)_e_[_n_]=___(_t_[_n_])?_t_[_n_].toString():T.isArray(_t_[_n_])||T.isObject(_t_[_n_])?_m_(_t_[_n_]):_t_[_n_];return _e_},_y_=function(_t_){var _e_=JSON.stringify(_t_);return null===_e_.match(/regex/)?_e_:JSON.stringify(_m_(_t_))},_l_=function(_t_,_e_,_n_){var _r_,_i_,_s_,_u_;if(_t_&&(T.isArray(_t_)&&1===_t_.length||!T.isArray(_t_)))_e_(T.isArray(_t_)?_t_[0]:_t_,0);else for(_s_=0,_t_=T.isArray(_t_)?_t_:[_t_],_u_=_t_.length;_u_>_s_&&(_i_=_t_[_s_],T.isUndefined(_i_)&&!_n_||(_r_=_e_(_i_,_s_),_r_!==T.EXIT));_s_++);},_f_=function(_t_,_e_){var _n_,_r_,_i_=0;for(_r_ in _t_)if(_t_.hasOwnProperty(_r_)&&(_n_=_e_(_t_[_r_],_r_,_i_++),_n_===T.EXIT))break},_c_.extend=function(_t_,_e_){_c_[_t_]=function(){return _e_.apply(this,_x_(arguments))}},_h_=function(_t_){var _e_;return T.isString(_t_)&&/[t][0-9]*[r][0-9]*/i.test(_t_)?!0:T.isObject(_t_)&&_t_.___id&&_t_.___s?!0:T.isArray(_t_)?(_e_=!0,_l_(_t_,function(_t_){return _h_(_t_)?void 0:(_e_=!1,TAFFY.EXIT)}),_e_):!1},_g_=function(_t_,_e_){var _n_=!0;return _l_(_e_,function(_e_){switch(T.typeOf(_e_)){case"function":if(!_e_.apply(_t_))return _n_=!1,TAFFY.EXIT;break;case"array":_n_=1===_e_.length?_g_(_t_,_e_[0]):2===_e_.length?_g_(_t_,_e_[0])||_g_(_t_,_e_[1]):3===_e_.length?_g_(_t_,_e_[0])||_g_(_t_,_e_[1])||_g_(_t_,_e_[2]):4===_e_.length?_g_(_t_,_e_[0])||_g_(_t_,_e_[1])||_g_(_t_,_e_[2])||_g_(_t_,_e_[3]):!1,_e_.length>4&&_l_(_e_,function(_e_){_g_(_t_,_e_)&&(_n_=!0)})}}),_n_},_T_=function(_t_){var _e_=[];return T.isString(_t_)&&/[t][0-9]*[r][0-9]*/i.test(_t_)&&(_t_={___id:_t_}),T.isArray(_t_)?(_l_(_t_,function(_t_){_e_.push(_T_(_t_))}),_t_=function(){var _t_=this,_n_=!1;return _l_(_e_,function(_e_){_g_(_t_,_e_)&&(_n_=!0)}),_n_}):T.isObject(_t_)?(T.isObject(_t_)&&_t_.___id&&_t_.___s&&(_t_={___id:_t_.___id}),_f_(_t_,function(_t_,_n_){T.isObject(_t_)||(_t_={is:_t_}),_f_(_t_,function(_t_,_r_){var _i_,_s_=[];_i_="hasAll"===_r_?function(_t_,_e_){_e_(_t_)}:_l_,_i_(_t_,function(_t_){var _e_,_i_=!0;_e_=function(){var _e_,_s_=this[_n_],_u_="==",_o_="!=",_c_="===",_a_="<",_l_=">",_f_="<=",_h_=">=",_T_="!==";return"undefined"==typeof _s_?!1:(0===_r_.indexOf("!")&&_r_!==_o_&&_r_!==_T_&&(_i_=!1,_r_=_r_.substring(1,_r_.length)),_e_="regex"===_r_?_t_.test(_s_):"lt"===_r_||_r_===_a_?_t_>_s_:"gt"===_r_||_r_===_l_?_s_>_t_:"lte"===_r_||_r_===_f_?_t_>=_s_:"gte"===_r_||_r_===_h_?_s_>=_t_:"left"===_r_?0===_s_.indexOf(_t_):"leftnocase"===_r_?0===_s_.toLowerCase().indexOf(_t_.toLowerCase()):"right"===_r_?_s_.substring(_s_.length-_t_.length)===_t_:"rightnocase"===_r_?_s_.toLowerCase().substring(_s_.length-_t_.length)===_t_.toLowerCase():"like"===_r_?_s_.indexOf(_t_)>=0:"likenocase"===_r_?_s_.toLowerCase().indexOf(_t_.toLowerCase())>=0:_r_===_c_||"is"===_r_?_s_===_t_:_r_===_u_?_s_==_t_:_r_===_T_?_s_!==_t_:_r_===_o_?_s_!=_t_:"isnocase"===_r_?_s_.toLowerCase?_s_.toLowerCase()===_t_.toLowerCase():_s_===_t_:"has"===_r_?T.has(_s_,_t_):"hasall"===_r_?T.hasAll(_s_,_t_):"contains"===_r_?TAFFY.isArray(_s_)&&_s_.indexOf(_t_)>-1:-1!==_r_.indexOf("is")||TAFFY.isNull(_s_)||TAFFY.isUndefined(_s_)||TAFFY.isObject(_t_)||TAFFY.isArray(_t_)?T[_r_]&&T.isFunction(T[_r_])&&0===_r_.indexOf("is")?T[_r_](_s_)===_t_:T[_r_]&&T.isFunction(T[_r_])?T[_r_](_s_,_t_):!1:_t_===_s_[_r_],_e_=_e_&&!_i_?!1:_e_||_i_?_e_:!0)},_s_.push(_e_)}),_e_.push(1===_s_.length?_s_[0]:function(){var _t_=this,_e_=!1;return _l_(_s_,function(_n_){_n_.apply(_t_)&&(_e_=!0)}),_e_})})}),_t_=function(){var _t_=this,_n_=!0;return _n_=(1!==_e_.length||_e_[0].apply(_t_))&&(2!==_e_.length||_e_[0].apply(_t_)&&_e_[1].apply(_t_))&&(3!==_e_.length||_e_[0].apply(_t_)&&_e_[1].apply(_t_)&&_e_[2].apply(_t_))&&(4!==_e_.length||_e_[0].apply(_t_)&&_e_[1].apply(_t_)&&_e_[2].apply(_t_)&&_e_[3].apply(_t_))?!0:!1,_e_.length>4&&_l_(_e_,function(_e_){_g_(_t_,_e_)||(_n_=!1)}),_n_}):T.isFunction(_t_)?_t_:void 0},_p_=function(_t_,_e_){var _n_=function(_t_,_n_){var _r_=0;return T.each(_e_,function(_e_){var _i_,_s_,_u_,_o_,_c_;if(_i_=_e_.split(" "),_s_=_i_[0],_u_=1===_i_.length?"logical":_i_[1],"logical"===_u_)_o_=_F_(_t_[_s_]),_c_=_F_(_n_[_s_]),T.each(_o_.length<=_c_.length?_o_:_c_,function(_t_,_e_){return _o_[_e_]<_c_[_e_]?(_r_=-1,TAFFY.EXIT):_o_[_e_]>_c_[_e_]?(_r_=1,TAFFY.EXIT):void 0});else if("logicaldesc"===_u_)_o_=_F_(_t_[_s_]),_c_=_F_(_n_[_s_]),T.each(_o_.length<=_c_.length?_o_:_c_,function(_t_,_e_){return _o_[_e_]>_c_[_e_]?(_r_=-1,TAFFY.EXIT):_o_[_e_]<_c_[_e_]?(_r_=1,TAFFY.EXIT):void 0});else{if("asec"===_u_&&_t_[_s_]<_n_[_s_])return _r_=-1,T.EXIT;if("asec"===_u_&&_t_[_s_]>_n_[_s_])return _r_=1,T.EXIT;if("desc"===_u_&&_t_[_s_]>_n_[_s_])return _r_=-1,T.EXIT;if("desc"===_u_&&_t_[_s_]<_n_[_s_])return _r_=1,T.EXIT}return 0===_r_&&"logical"===_u_&&_o_.length<_c_.length?_r_=-1:0===_r_&&"logical"===_u_&&_o_.length>_c_.length?_r_=1:0===_r_&&"logicaldesc"===_u_&&_o_.length>_c_.length?_r_=-1:0===_r_&&"logicaldesc"===_u_&&_o_.length<_c_.length&&(_r_=1),0!==_r_?T.EXIT:void 0}),_r_};return _t_&&_t_.push?_t_.sort(_n_):_t_},function(){var _t_={},_e_=0;_F_=function(_n_){return _e_>_o_&&(_t_={},_e_=0),_t_["_"+_n_]||function(){var _r_,_i_,_s_,_u_=String(_n_),_o_=[],_c_="_",_a_="";for(_r_=0,_i_=_u_.length;_i_>_r_;_r_++)_s_=_u_.charCodeAt(_r_),_s_>=48&&57>=_s_||46===_s_?("n"!==_a_&&(_a_="n",_o_.push(_c_.toLowerCase()),_c_=""),_c_+=_u_.charAt(_r_)):("s"!==_a_&&(_a_="s",_o_.push(parseFloat(_c_)),_c_=""),_c_+=_u_.charAt(_r_));return _o_.push("n"===_a_?parseFloat(_c_):_c_.toLowerCase()),_o_.shift(),_t_["_"+_n_]=_o_,_e_++,_o_}()}}(),_d_=function(){this.context({results:this.getDBI().query(this.context())})},_c_.extend("filter",function(){var _t_=TAFFY.mergeObj(this.context(),{run:null}),_e_=[];return _l_(_t_.q,function(_t_){_e_.push(_t_)}),_t_.q=_e_,_l_(_x_(arguments),function(_e_){_t_.q.push(_T_(_e_)),_t_.filterRaw.push(_e_)}),this.getroot(_t_)}),_c_.extend("order",function(_t_){_t_=_t_.split(",");var _e_,_n_=[];return _l_(_t_,function(_t_){_n_.push(_t_.replace(/^\s*/,"").replace(/\s*$/,""))}),_e_=TAFFY.mergeObj(this.context(),{sort:null}),_e_.order=_n_,this.getroot(_e_)}),_c_.extend("limit",function(_t_){var _e_,_n_=TAFFY.mergeObj(this.context(),{});return _n_.limit=_t_,_n_.run&&_n_.sort&&(_e_=[],_l_(_n_.results,function(_n_,_r_){return _r_+1>_t_?TAFFY.EXIT:void _e_.push(_n_)}),_n_.results=_e_),this.getroot(_n_)}),_c_.extend("start",function(_t_){var _e_,_n_=TAFFY.mergeObj(this.context(),{});return _n_.start=_t_,_n_.run&&_n_.sort&&!_n_.limit?(_e_=[],_l_(_n_.results,function(_n_,_r_){_r_+1>_t_&&_e_.push(_n_)}),_n_.results=_e_):_n_=TAFFY.mergeObj(this.context(),{run:null,start:_t_}),this.getroot(_n_)}),_c_.extend("update",function(_t_,_e_,_n_){var _r_,_i_=!0,_s_={},_u_=_x_(arguments);return!TAFFY.isString(_t_)||2!==arguments.length&&3!==arguments.length?(_s_=_t_,2===_u_.length&&(_i_=_e_)):(_s_[_t_]=_e_,3===arguments.length&&(_i_=_n_)),_r_=this,_d_.call(this),_l_(this.context().results,function(_t_){var _e_=_s_;TAFFY.isFunction(_e_)?_e_=_e_.apply(TAFFY.mergeObj(_t_,{})):T.isFunction(_e_)&&(_e_=_e_(TAFFY.mergeObj(_t_,{}))),TAFFY.isObject(_e_)&&_r_.getDBI().update(_t_.___id,_e_,_i_)}),this.context().results.length&&this.context({run:null}),this}),_c_.extend("remove",function(_t_){var _e_=this,_n_=0;return _d_.call(this),_l_(this.context().results,function(_t_){_e_.getDBI().remove(_t_.___id),_n_++}),this.context().results.length&&(this.context({run:null}),_e_.getDBI().removeCommit(_t_)),_n_}),_c_.extend("count",function(){return _d_.call(this),this.context().results.length}),_c_.extend("callback",function(_t_,_e_){if(_t_){var _n_=this;setTimeout(function(){_d_.call(_n_),_t_.call(_n_.getroot(_n_.context()))},_e_||0)}return null}),_c_.extend("get",function(){return _d_.call(this),this.context().results}),_c_.extend("stringify",function(){return JSON.stringify(this.get())}),_c_.extend("first",function(){return _d_.call(this),this.context().results[0]||!1}),_c_.extend("last",function(){return _d_.call(this),this.context().results[this.context().results.length-1]||!1}),_c_.extend("sum",function(){var _t_=0,_e_=this;return _d_.call(_e_),_l_(_x_(arguments),function(_n_){_l_(_e_.context().results,function(_e_){_t_+=_e_[_n_]||0})}),_t_}),_c_.extend("min",function(_t_){var _e_=null;return _d_.call(this),_l_(this.context().results,function(_n_){(null===_e_||_n_[_t_]<_e_)&&(_e_=_n_[_t_])}),_e_}),function(){var _t_=function(){var _t_,_e_,_n_;return _t_=function(_t_,_e_,_n_){var _r_,_i_,_s_;switch(2===_n_.length?(_r_=_t_[_n_[0]],_s_="===",_i_=_e_[_n_[1]]):(_r_=_t_[_n_[0]],_s_=_n_[1],_i_=_e_[_n_[2]]),_s_){case"===":return _r_===_i_;case"!==":return _r_!==_i_;case"<":return _i_>_r_;case">":return _r_>_i_;case"<=":return _i_>=_r_;case">=":return _r_>=_i_;case"==":return _r_==_i_;case"!=":return _r_!=_i_;default:throw String(_s_)+" is not supported"}},_e_=function(_t_,_e_){var _n_,_r_,_i_={};for(_n_ in _t_)_t_.hasOwnProperty(_n_)&&(_i_[_n_]=_t_[_n_]);for(_n_ in _e_)_e_.hasOwnProperty(_n_)&&"___id"!==_n_&&"___s"!==_n_&&(_r_=TAFFY.isUndefined(_i_[_n_])?"":"right_",_i_[_r_+String(_n_)]=_e_[_n_]);return _i_},_n_=function(_n_){var _r_,_i_,_s_=_x_(arguments),_u_=_s_.length,_o_=[];if("function"!=typeof _n_.filter){if(!_n_.TAFFY)throw"TAFFY DB or result not supplied";_r_=_n_()}else _r_=_n_;return this.context({results:this.getDBI().query(this.context())}),TAFFY.each(this.context().results,function(_n_){_r_.each(function(_r_){var _c_,_a_=!0;t:for(_i_=1;_u_>_i_&&(_c_=_s_[_i_],_a_="function"==typeof _c_?_c_(_n_,_r_):"object"==typeof _c_&&_c_.length?_t_(_n_,_r_,_c_):!1,_a_);_i_++);_a_&&_o_.push(_e_(_n_,_r_))})}),TAFFY(_o_)()}}();_c_.extend("join",_t_)}(),_c_.extend("max",function(_t_){var _e_=null;return _d_.call(this),_l_(this.context().results,function(_n_){(null===_e_||_n_[_t_]>_e_)&&(_e_=_n_[_t_])}),_e_}),_c_.extend("select",function(){var _t_=[],_e_=_x_(arguments);return _d_.call(this),1===arguments.length?_l_(this.context().results,function(_n_){_t_.push(_n_[_e_[0]])}):_l_(this.context().results,function(_n_){var _r_=[];_l_(_e_,function(_t_){_r_.push(_n_[_t_])}),_t_.push(_r_)}),_t_}),_c_.extend("distinct",function(){var _t_=[],_e_=_x_(arguments);return _d_.call(this),1===arguments.length?_l_(this.context().results,function(_n_){var _r_=_n_[_e_[0]],_i_=!1;_l_(_t_,function(_t_){return _r_===_t_?(_i_=!0,TAFFY.EXIT):void 0}),_i_||_t_.push(_r_)}):_l_(this.context().results,function(_n_){var _r_=[],_i_=!1;_l_(_e_,function(_t_){_r_.push(_n_[_t_])}),_l_(_t_,function(_t_){var _n_=!0;return _l_(_e_,function(_e_,_i_){return _r_[_i_]!==_t_[_i_]?(_n_=!1,TAFFY.EXIT):void 0}),_n_?(_i_=!0,TAFFY.EXIT):void 0}),_i_||_t_.push(_r_)}),_t_}),_c_.extend("supplant",function(_t_,_e_){var _n_=[];return _d_.call(this),_l_(this.context().results,function(_e_){_n_.push(_t_.replace(/\{([^\{\}]*)\}/g,function(_t_,_n_){var _r_=_e_[_n_];return"string"==typeof _r_||"number"==typeof _r_?_r_:_t_}))}),_e_?_n_:_n_.join("")}),_c_.extend("each",function(_t_){return _d_.call(this),_l_(this.context().results,_t_),this}),_c_.extend("map",function(_t_){var _e_=[];return _d_.call(this),_l_(this.context().results,function(_n_){_e_.push(_t_(_n_))}),_e_}),T=function(_t_){var _e_,_n_,_r_,_i_=[],_o_={},_F_=1,_d_={template:!1,onInsert:!1,onUpdate:!1,onRemove:!1,onDBChange:!1,storageName:!1,forcePropertyCase:null,cacheSize:100,name:""},_A_=new Date,_v_=0,_m_=0,___={};return _n_=function(_t_){var _e_=[],_r_=!1;return 0===_t_.length?_i_:(_l_(_t_,function(_t_){T.isString(_t_)&&/[t][0-9]*[r][0-9]*/i.test(_t_)&&_i_[_o_[_t_]]&&(_e_.push(_i_[_o_[_t_]]),_r_=!0),T.isObject(_t_)&&_t_.___id&&_t_.___s&&_i_[_o_[_t_.___id]]&&(_e_.push(_i_[_o_[_t_.___id]]),_r_=!0),T.isArray(_t_)&&_l_(_t_,function(_t_){_l_(_n_(_t_),function(_t_){_e_.push(_t_)})})}),_r_&&_e_.length>1&&(_e_=[]),_e_)},_e_={dm:function(_t_){return _t_&&(_A_=_t_,___={},_v_=0,_m_=0),_d_.onDBChange&&setTimeout(function(){_d_.onDBChange.call(_i_)},0),_d_.storageName&&setTimeout(function(){localStorage.setItem("taffy_"+_d_.storageName,JSON.stringify(_i_))}),_A_},insert:function(_t_,_n_){var _c_=[],_h_=[],_T_=_a_(_t_);return _l_(_T_,function(_t_,_r_){var _a_,_T_;return T.isArray(_t_)&&0===_r_?(_l_(_t_,function(_t_){_c_.push("lower"===_d_.forcePropertyCase?_t_.toLowerCase():"upper"===_d_.forcePropertyCase?_t_.toUpperCase():_t_)}),!0):(T.isArray(_t_)?(_a_={},_l_(_t_,function(_t_,_e_){_a_[_c_[_e_]]=_t_}),_t_=_a_):T.isObject(_t_)&&_d_.forcePropertyCase&&(_T_={},_f_(_t_,function(_e_,_n_){_T_["lower"===_d_.forcePropertyCase?_n_.toLowerCase():"upper"===_d_.forcePropertyCase?_n_.toUpperCase():_n_]=_t_[_n_]}),_t_=_T_),_F_++,_t_.___id="T"+String(_u_+_s_).slice(-6)+"R"+String(_u_+_F_).slice(-6),_t_.___s=!0,_h_.push(_t_.___id),_d_.template&&(_t_=T.mergeObj(_d_.template,_t_)),_i_.push(_t_),_o_[_t_.___id]=_i_.length-1,_d_.onInsert&&(_n_||TAFFY.isUndefined(_n_))&&_d_.onInsert.call(_t_),void _e_.dm(new Date))}),_r_(_h_)},sort:function(_t_){return _i_=_p_(_i_,_t_.split(",")),_o_={},_l_(_i_,function(_t_,_e_){_o_[_t_.___id]=_e_}),_e_.dm(new Date),!0},update:function(_t_,_n_,_r_){var _s_,_u_,_c_,_a_,_l_={};_d_.forcePropertyCase&&(_f_(_n_,function(_t_,_e_){_l_["lower"===_d_.forcePropertyCase?_e_.toLowerCase():"upper"===_d_.forcePropertyCase?_e_.toUpperCase():_e_]=_t_}),_n_=_l_),_s_=_i_[_o_[_t_]],_u_=T.mergeObj(_s_,_n_),_c_={},_a_=!1,_f_(_u_,function(_t_,_e_){(TAFFY.isUndefined(_s_[_e_])||_s_[_e_]!==_t_)&&(_c_[_e_]=_t_,_a_=!0)}),_a_&&(_d_.onUpdate&&(_r_||TAFFY.isUndefined(_r_))&&_d_.onUpdate.call(_u_,_i_[_o_[_t_]],_c_),_i_[_o_[_t_]]=_u_,_e_.dm(new Date))},remove:function(_t_){_i_[_o_[_t_]].___s=!1},removeCommit:function(_t_){var _n_;for(_n_=_i_.length-1;_n_>-1;_n_--)_i_[_n_].___s||(_d_.onRemove&&(_t_||TAFFY.isUndefined(_t_))&&_d_.onRemove.call(_i_[_n_]),_o_[_i_[_n_].___id]=void 0,_i_.splice(_n_,1));_o_={},_l_(_i_,function(_t_,_e_){_o_[_t_.___id]=_e_}),_e_.dm(new Date)},query:function(_t_){var _r_,_s_,_u_,_o_,_c_,_a_;if(_d_.cacheSize&&(_s_="",_l_(_t_.filterRaw,function(_t_){return T.isFunction(_t_)?(_s_="nocache",TAFFY.EXIT):void 0}),""===_s_&&(_s_=_y_(T.mergeObj(_t_,{q:!1,run:!1,sort:!1})))),!_t_.results||!_t_.run||_t_.run&&_e_.dm()>_t_.run){if(_u_=[],_d_.cacheSize&&___[_s_])return ___[_s_].i=_v_++,___[_s_].results;0===_t_.q.length&&0===_t_.index.length?(_l_(_i_,function(_t_){_u_.push(_t_)}),_r_=_u_):(_o_=_n_(_t_.index),_l_(_o_,function(_e_){(0===_t_.q.length||_g_(_e_,_t_.q))&&_u_.push(_e_)}),_r_=_u_)}else _r_=_t_.results;return!(_t_.order.length>0)||_t_.run&&_t_.sort||(_r_=_p_(_r_,_t_.order)),_r_.length&&(_t_.limit&&_t_.limit<_r_.length||_t_.start)&&(_c_=[],_l_(_r_,function(_e_,_n_){if(!_t_.start||_t_.start&&_n_+1>=_t_.start)if(_t_.limit){if(_a_=_t_.start?_n_+1-_t_.start:_n_,_a_<_t_.limit)_c_.push(_e_);else if(_a_>_t_.limit)return TAFFY.EXIT}else _c_.push(_e_)}),_r_=_c_),_d_.cacheSize&&"nocache"!==_s_&&(_m_++,setTimeout(function(){var _t_,_e_;_m_>=2*_d_.cacheSize&&(_m_=0,_t_=_v_-_d_.cacheSize,_e_={},_f_(function(_n_,_r_){_n_.i>=_t_&&(_e_[_r_]=_n_)}),___=_e_)},0),___[_s_]={i:_v_++,results:_r_}),_r_}},_r_=function(){var _t_,_n_;return _t_=TAFFY.mergeObj(TAFFY.mergeObj(_c_,{insert:void 0}),{getDBI:function(){return _e_},getroot:function(_t_){return _r_.call(_t_)},context:function(_t_){return _t_&&(_n_=TAFFY.mergeObj(_n_,_t_.hasOwnProperty("results")?TAFFY.mergeObj(_t_,{run:new Date,sort:new Date}):_t_)),_n_},extend:void 0}),_n_=this&&this.q?this:{limit:!1,start:!1,q:[],filterRaw:[],index:[],order:[],results:!1,run:null,sort:null,settings:_d_},_l_(_x_(arguments),function(_t_){_h_(_t_)?_n_.index.push(_t_):_n_.q.push(_T_(_t_)),_n_.filterRaw.push(_t_)}),_t_},_s_++,_t_&&_e_.insert(_t_),_r_.insert=_e_.insert,_r_.merge=function(_t_,_n_,_i_){var _s_={},_u_=[],_o_={};return _i_=_i_||!1,_n_=_n_||"id",_l_(_t_,function(_t_){var _o_;_s_[_n_]=_t_[_n_],_u_.push(_t_[_n_]),_o_=_r_(_s_).first(),_o_?_e_.update(_o_.___id,_t_,_i_):_e_.insert(_t_,_i_)}),_o_[_n_]=_u_,_r_(_o_)},_r_.TAFFY=!0,_r_.sort=_e_.sort,_r_.settings=function(_t_){return _t_&&(_d_=TAFFY.mergeObj(_d_,_t_),_t_.template&&_r_().update(_t_.template)),_d_},_r_.store=function(_t_){var _e_,_n_=!1;return localStorage&&(_t_&&(_e_=localStorage.getItem("taffy_"+_t_),_e_&&_e_.length>0&&(_r_.insert(_e_),_n_=!0),_i_.length>0&&setTimeout(function(){localStorage.setItem("taffy_"+_d_.storageName,JSON.stringify(_i_))})),_r_.settings({storageName:_t_})),_r_},_r_},TAFFY=T,T.each=_l_,T.eachin=_f_,T.extend=_c_.extend,TAFFY.EXIT="TAFFYEXIT",TAFFY.mergeObj=function(_t_,_e_){var _n_={};return _f_(_t_,function(_e_,_r_){_n_[_r_]=_t_[_r_]}),_f_(_e_,function(_t_,_r_){_n_[_r_]=_e_[_r_]}),_n_},TAFFY.has=function(_t_,_e_){var _n_,_r_=!1;if(_t_.TAFFY)return _r_=_t_(_e_),_r_.length>0?!0:!1;switch(T.typeOf(_t_)){case"object":if(T.isObject(_e_))_f_(_e_,function(_n_,_i_){return _r_!==!0||T.isUndefined(_t_[_i_])||!_t_.hasOwnProperty(_i_)?(_r_=!1,TAFFY.EXIT):void(_r_=T.has(_t_[_i_],_e_[_i_]))});else if(T.isArray(_e_))_l_(_e_,function(_n_,_i_){return _r_=T.has(_t_,_e_[_i_]),_r_?TAFFY.EXIT:void 0});else if(T.isString(_e_))return TAFFY.isUndefined(_t_[_e_])?!1:!0;return _r_;case"array":if(T.isObject(_e_))_l_(_t_,function(_n_,_i_){return _r_=T.has(_t_[_i_],_e_),_r_===!0?TAFFY.EXIT:void 0});else if(T.isArray(_e_))_l_(_e_,function(_n_,_i_){return _l_(_t_,function(_n_,_s_){return _r_=T.has(_t_[_s_],_e_[_i_]),_r_===!0?TAFFY.EXIT:void 0}),_r_===!0?TAFFY.EXIT:void 0});else if(T.isString(_e_)||T.isNumber(_e_))for(_r_=!1,_n_=0;_n_<_t_.length;_n_++)if(_r_=T.has(_t_[_n_],_e_))return!0;return _r_;case"string":if(T.isString(_e_)&&_e_===_t_)return!0;break;default:if(T.typeOf(_t_)===T.typeOf(_e_)&&_t_===_e_)return!0}return!1},TAFFY.hasAll=function(_t_,_e_){var _n_,_r_=TAFFY;return _r_.isArray(_e_)?(_n_=!0,_l_(_e_,function(_e_){return _n_=_r_.has(_t_,_e_),_n_===!1?TAFFY.EXIT:void 0}),_n_):_r_.has(_t_,_e_)},TAFFY.typeOf=function(_t_){var _e_=typeof _t_;return"object"===_e_&&(_t_?"number"!=typeof _t_.length||_t_.propertyIsEnumerable("length")||(_e_="array"):_e_="null"),_e_},TAFFY.getObjectKeys=function(_t_){var _e_=[];return _f_(_t_,function(_t_,_n_){_e_.push(_n_)}),_e_.sort(),_e_},TAFFY.isSameArray=function(_t_,_e_){return TAFFY.isArray(_t_)&&TAFFY.isArray(_e_)&&_t_.join(",")===_e_.join(",")?!0:!1},TAFFY.isSameObject=function(_t_,_e_){var _n_=TAFFY,_r_=!0;return _n_.isObject(_t_)&&_n_.isObject(_e_)&&_n_.isSameArray(_n_.getObjectKeys(_t_),_n_.getObjectKeys(_e_))?_f_(_t_,function(_i_,_s_){return _n_.isObject(_t_[_s_])&&_n_.isObject(_e_[_s_])&&_n_.isSameObject(_t_[_s_],_e_[_s_])||_n_.isArray(_t_[_s_])&&_n_.isArray(_e_[_s_])&&_n_.isSameArray(_t_[_s_],_e_[_s_])||_t_[_s_]===_e_[_s_]?void 0:(_r_=!1,TAFFY.EXIT)}):_r_=!1,_r_},_t_=["String","Number","Object","Array","Boolean","Null","Function","Undefined"],_e_=function(_t_){return function(_e_){return TAFFY.typeOf(_e_)===_t_.toLowerCase()?!0:!1}},_n_=0;_n_<_t_.length;_n_++)_r_=_t_[_n_],TAFFY["is"+_r_]=_e_(_r_)}(),"object"==typeof exports&&(exports.taffy=TAFFY); -------------------------------------------------------------------------------- /test/t.js: -------------------------------------------------------------------------------- 1 | /*jslint node : true, continue : true, 2 | devel : true, indent : 2, maxerr : 50, 3 | newcap : true, nomen : true, plusplus : true, 4 | regexp : true, vars : false, white : true 5 | unparam : true, sloppy : true, todo : true 6 | */ 7 | /*global global, module, require, $, KI, document, window */ 8 | // global global, module, require, $, KI, document, window 9 | 10 | 'use strict'; 11 | // BEGIN module-scope vars 12 | var 13 | TAFFY = require( '../taffy.js' ).taffy, 14 | 15 | // Load libraries 16 | // Declare data sources 17 | cfgMap = { 18 | friend_list : [ 19 | {"id":1,"gender":"M","first":"John","last":"Smith", 20 | "city":"Seattle, WA","status":"Active"}, 21 | {"id":2,"gender":"F","first":"Kelly","last":"Ruth", 22 | "city":"Dallas, TX","status":"Active"}, 23 | {"id":3,"gender":"M","first":"Jeff","last":"Stevenson", 24 | "city":"Washington, D.C.","status":"Active"}, 25 | {"id":4,"gender":"F","first":"Jennifer","last":"Gill", 26 | "city":"Seattle, WA","status":"Active"} 27 | ] 28 | }, 29 | // Declare utlities 30 | getVarType, cloneFriendList, 31 | // Declare init used to reset state for tests 32 | 33 | // Declare tests 34 | testSmoke, testShowBug, testDummy 35 | ; 36 | // END module-scope vars 37 | 38 | // BEGIN public utility /getVarType/ 39 | // Returns 'Function', 'Object', 'Array', 40 | // 'String', 'Number', 'Boolean', or 'Undefined', 41 | getVarType = function ( data ) { 42 | if (undefined === data ){ return 'Undefined'; } 43 | if (data === null ){ return 'Null'; } 44 | return {}.toString.call(data).slice(8, -1); 45 | }; 46 | // END public utility /getVarType/ 47 | 48 | // BEGIN cloneFriendList 49 | cloneFriendList = function () { return cfgMap.friend_list.slice(); }; 50 | // END cloneFriendList 51 | 52 | // BEGIN testSmoke 53 | testSmoke = function ( test_obj ) { 54 | var 55 | friend_db, query_list, query_count, initial_list, expect_map, 56 | idx, bit_list, key_name, val_data, expect_data, actual_str, msg_str, 57 | 58 | partial, chain_list, chain_count, i, chain_map 59 | ; 60 | 61 | friend_db = TAFFY( cloneFriendList() ); 62 | 63 | 64 | // Fast clone; see stackoverflow.com/questions/122102/5344074 65 | initial_list = JSON.parse(JSON.stringify(friend_db().get())); 66 | 67 | // query data 68 | // 69 | query_list = [ 70 | [ 'filter_city', [ { city : "Seattle, WA"}, { key: 'get' } ] ], 71 | [ 'filter_id_num', [ { id : 1 }, { key : 'get' } ] ], 72 | [ 'filter_id_str', [ { id : '1'}, { key : 'get' } ] ], 73 | [ 'filter_name', [ { first : 'John', last : 'Smith' }, { key : 'get' } ] ], 74 | [ 'kelly_by_id', [ { id : 2}, { key : 'first' } ] ], 75 | [ 'kelly_last_name', [ { id : 2}, { key : 'first' }, { _xprop : 'last' } ] ], 76 | [ 'id_list', [ null, { key : 'select', val : 'id' } ] ], 77 | [ 'city_list', [ null, { key : 'distinct', val : 'city' } ] ], 78 | [ 'filter_001', [ null, { key : 'filter', val : { city : "Seattle, WA"} }, { key : 'get' } ] ], 79 | 80 | // should match initial order 81 | [ 'order_001', [ null, { key : 'get' } ] ], 82 | [ 'order_002', [ null, { key : 'order', val : 'gender' }, { key : 'get' } ] ], 83 | [ 'order_003', [ null, { key : 'order', val : 'gender desc' }, { key : 'get' } ] ], 84 | [ 'order_004', [ null, { key : 'order', val : 'gender, last' }, { key : 'get' } ] ], 85 | [ 'order_005', [ null, { key : 'order', val : 'gender desc, last desc' }, { key : 'get' } ] ], 86 | // TODO: asec is not really supported, but is default sort. 87 | // Also should the abbreviation be 'asc' or similar? 88 | [ 'order_006', [ null, { key : 'order', val : 'first' }, { key : 'get' } ] ], 89 | [ 'order_007', [ null, { key : 'order', val : 'last' }, { key : 'get' } ] ], 90 | [ 'order_008', [ null, { key : 'order', val : 'first desc' }, { key : 'get' } ] ], 91 | [ 'order_009', [ null, { key : 'order', val : 'last desc' }, { key : 'get' } ] ], 92 | // should match initial order 93 | [ 'order_001', [ null, { key : 'get' } ] ], 94 | [ 'sort_001_002', [ { _xsort : 'last' }, { key : 'get' } ] ], 95 | // should match changed order 96 | [ 'sort_001_002', [ null, { key : 'get'} ] ], 97 | [ 'get_ruth', [ { "last" : "Ruth" }, { key : 'update', val : { first : 'KelBel' } }, { key : 'first' } ] ] 98 | ]; 99 | 100 | query_count = query_list.length; 101 | test_obj.expect( query_count ); 102 | 103 | expect_map = { 104 | filter_city : [{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true},{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active","___id":"T000002R000005","___s":true}], 105 | filter_id_num : [{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true}], 106 | filter_id_str : [], 107 | filter_name : [{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true}], 108 | kelly_by_id : {"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active","___id":"T000002R000003","___s":true}, 109 | kelly_last_name : 'Ruth', 110 | id_list : [1,2,3,4], 111 | city_list : ["Seattle, WA","Dallas, TX","Washington, D.C."], 112 | filter_001 : [{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true},{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active","___id":"T000002R000005","___s":true}], 113 | order_001 : initial_list, 114 | order_002 : [{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active","___id":"T000002R000003","___s":true},{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active","___id":"T000002R000005","___s":true},{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true},{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active","___id":"T000002R000004","___s":true}], 115 | order_003 : [{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true},{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active","___id":"T000002R000004","___s":true},{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active","___id":"T000002R000003","___s":true},{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active","___id":"T000002R000005","___s":true}], 116 | order_004 : [{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active","___id":"T000002R000005","___s":true},{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active","___id":"T000002R000003","___s":true},{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true},{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active","___id":"T000002R000004","___s":true}], 117 | order_005 : [{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active","___id":"T000002R000004","___s":true},{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true},{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active","___id":"T000002R000003","___s":true},{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active","___id":"T000002R000005","___s":true}], 118 | order_006 : [{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active","___id":"T000002R000004","___s":true},{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active","___id":"T000002R000005","___s":true},{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true},{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active","___id":"T000002R000003","___s":true}], 119 | order_007 : [{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active","___id":"T000002R000005","___s":true},{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active","___id":"T000002R000003","___s":true},{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true},{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active","___id":"T000002R000004","___s":true}], 120 | order_008 : [{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active","___id":"T000002R000003","___s":true},{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true},{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active","___id":"T000002R000005","___s":true},{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active","___id":"T000002R000004","___s":true}], 121 | order_009 : [{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active","___id":"T000002R000004","___s":true},{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true},{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active","___id":"T000002R000003","___s":true},{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active","___id":"T000002R000005","___s":true}], 122 | order_010 : initial_list, 123 | sort_001_002 : [{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Active","___id":"T000002R000005","___s":true},{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active","___id":"T000002R000003","___s":true},{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active","___id":"T000002R000002","___s":true},{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active","___id":"T000002R000004","___s":true}], 124 | get_ruth : {"id":2,"gender":"F","first":"KelBel","last":"Ruth","city":"Dallas, TX","status":"Active","___id":"T000002R000003","___s":true} 125 | }; 126 | 127 | for ( idx = 0; idx < query_count; idx++ ) { 128 | bit_list = query_list[ idx ]; 129 | key_name = bit_list[ 0 ]; 130 | val_data = bit_list[ 1 ]; 131 | expect_data = expect_map[ key_name ] || ''; 132 | 133 | 134 | chain_list = val_data; 135 | chain_count = chain_list.length; 136 | 137 | _PARTIAL_: 138 | for ( i = 0; i < chain_count; i++ ) { 139 | chain_map = chain_list[ i ]; 140 | 141 | if ( i === 0 ) { 142 | if ( ! chain_map ) { 143 | partial = friend_db(); 144 | } 145 | else if ( chain_map._xsort ) { 146 | friend_db.sort( chain_map._xsort ); 147 | partial = friend_db(); 148 | } 149 | else { 150 | partial = friend_db( chain_map ); 151 | } 152 | } 153 | 154 | else { 155 | if ( chain_map._xprop ) { 156 | partial = partial[ chain_map._xprop ]; 157 | } 158 | else if ( chain_map.val ) { 159 | partial = partial[ chain_map.key ]( chain_map.val ); 160 | } 161 | else { 162 | partial = partial[ chain_map.key ](); 163 | } 164 | } 165 | } 166 | 167 | actual_str = JSON.stringify( partial ); 168 | msg_str = actual_str + ' === ' + JSON.stringify( expect_data ); 169 | test_obj.deepEqual( partial, expect_data, msg_str ); 170 | } 171 | test_obj.done(); 172 | }; 173 | // END testSmoke 174 | 175 | // BEGIN testShowBug 176 | testShowBug = function ( test_obj ) { 177 | var friend_db = TAFFY( cloneFriendList() ); 178 | test_obj.expect( 0 ); 179 | 180 | friend_db().each(function ( row_map, idx ) { 181 | if ( row_map.city === 'Seattle, WA' ){ 182 | row_map.city = 'WallaWalla, WA'; 183 | } 184 | }); 185 | 186 | // console.log( 'Example filter bug - rows changed without using ' 187 | // + '.update() will filter by their original values. ' 188 | // ); 189 | // console.log( 'We expect 0 rows, but get 2... ' ); 190 | // console.log( 191 | // friend_db().filter({ city : 'Seattle, WA'}).get() 192 | // ); 193 | // console.log( '...even though the city has changed in the collection.' ); 194 | // console.log( friend_db().get() ); 195 | // console.log( '' ); 196 | // 197 | // console.log( 'Example filter when .update() is used.'); 198 | // friend_db = TAFFY( cloneFriendList() ); 199 | // 200 | // friend_db({ city : 'Seattle, WA' }) 201 | // .update({ city : 'WallaWalla, WA' }); 202 | // 203 | // console.log( 'now we get the correct response (0 rows) ...' ); 204 | // console.log( 205 | // friend_db().filter({ city : 'Seattle, WA'}).get() 206 | // ); 207 | // console.log( friend_db().get() ); 208 | // console.log( '... that reflects the taffy collection.' ); 209 | 210 | test_obj.done(); 211 | }; 212 | // END testShowBug 213 | 214 | testDummy = function ( test_obj ) { 215 | test_obj.expect( 0 ); 216 | test_obj.done(); 217 | 218 | // See http://stackoverflow.com/questions/10952806 219 | // Suprisingly, a non-zero exit value (echo $?) is provided 220 | // when the tests do not pass, which is awesome! 221 | // 222 | setTimeout( function (){ process.exit(0); }, 100 ); 223 | }; 224 | 225 | module.exports = { 226 | testSmoke : testSmoke, 227 | testShowBug : testShowBug, 228 | testDummy : testDummy 229 | }; 230 | --------------------------------------------------------------------------------