├── .gitignore ├── .npmignore ├── README.markdown ├── app ├── public │ ├── .DS_Store │ ├── css │ │ └── wallet.css │ ├── img │ │ ├── background.jpeg │ │ ├── battle.jpeg │ │ └── plus.png │ └── js │ │ ├── MONEYender.js │ │ ├── cabin.js │ │ ├── hijs.js │ │ ├── introspect.js │ │ └── wallet-client.js ├── read.js ├── screenshot.png ├── views │ ├── index.mustache │ └── layout.mustache └── wallet-app.js ├── bin └── ender-wallet ├── package.json ├── test ├── cleanup └── test └── wallet.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /node_modules 3 | /test/node_modules 4 | /test/ender.js 5 | /test/ender.min.js -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | test/* -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | Wallet 2 | === 3 | 4 | See what's inside of your ender $ 5 | ------- 6 | 7 | __To install:__ 8 | 9 | npm install ender-wallet -g 10 | 11 | Easy. If you're using an npm < 1.0, you can leave off the -g. 12 | 13 | __To run:__ 14 | 15 | cd into a directory with an ender build, then run... 16 | 17 | ender-wallet open 18 | 19 | Then hit localhost 8083 (in webkit||firefox) and you'll see what inside's your ender wallet. 20 | 21 | To convince you to try it, here's a screenshot: 22 | 23 | 24 | 25 | Note: 26 | ---- 27 | 28 | Since Ender is purty young and this project is even younger, both are liable to change alot, and probably ender-wallet will break alot. So make sure your Ender is as fresh as possible. -------------------------------------------------------------------------------- /app/public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stenson/wallet/dc028304a88b071d4cabc4f7c38510cdb3805bd3/app/public/.DS_Store -------------------------------------------------------------------------------- /app/public/css/wallet.css: -------------------------------------------------------------------------------- 1 | * { 2 | padding:0; margin:0; list-style:none; 3 | } 4 | 5 | html,body { 6 | height:100%; 7 | } 8 | body { 9 | font-family:Helvetica,Arial,sans-serif; 10 | } 11 | 12 | #container { 13 | height:100%; 14 | overflow:hidden; 15 | background:white; 16 | } 17 | 18 | #modules-container { 19 | width:27%; 20 | height:100%; 21 | position:relative; 22 | float:left; 23 | background:rgba(25,25,25,0.3); 24 | -webkit-box-shadow:0px 0px 5px rgba(0,0,0,0.7); 25 | -moz-box-shadow:0px 0px 5px rgba(0,0,0,0.7); 26 | z-index:5; 27 | overflow:hidden; 28 | background:white url(/img/background.jpeg); 29 | } 30 | #functions-container { 31 | width:73%; 32 | height:100%; 33 | float:right; 34 | position:relative; 35 | background:white url(/img/battle.jpeg) no-repeat center center; 36 | z-index:0; 37 | overflow:hidden; 38 | } 39 | 40 | .title { 41 | width:100%; 42 | z-index:100; 43 | background:white; 44 | font-family:Georgia,serif; 45 | font-style:italic; 46 | -webkit-box-shadow:0px 0px 5px rgba(0,0,0,0.7); 47 | -moz-box-shadow:0px 0px 5px rgba(0,0,0,0.7); 48 | height:6%; 49 | position:relative; 50 | border-top:2px solid #ddd; 51 | border-bottom:1px solid #eee; 52 | } 53 | .title span { 54 | padding:10px 15px; 55 | display:block; 56 | font-size:12px; 57 | } 58 | 59 | .title span.directory { 60 | color:rgb(29,130,124); 61 | position:absolute; 62 | top:0px; right:0px; 63 | } 64 | 65 | #add-a-module { 66 | background:rgb(59,170,154) url(/img/plus.png) no-repeat 4px 4.5px; 67 | position:absolute; 68 | top:10px; 69 | right:10px; 70 | width:20px; 71 | height:20px; 72 | -webkit-border-radius:10px; 73 | -moz-border-radius:10px; 74 | border-radius:10px; 75 | color:white; 76 | cursor:pointer; 77 | } 78 | 79 | #add-popup { 80 | background: hotpink; 81 | z-index:1000; 82 | position:absolute; 83 | top:0px; 84 | left:0px; 85 | display: -webkit-box; 86 | -webkit-box-orient: horizontal; 87 | -webkit-box-pack: center; 88 | -webkit-box-align: center; 89 | display: -moz-box; 90 | -moz-box-orient: horizontal; 91 | -moz-box-pack: center; 92 | -moz-box-align: center; 93 | display: box; 94 | box-orient: horizontal; 95 | box-pack: center; 96 | box-align: center; 97 | width:100%; 98 | height:100%; 99 | background:rgba(215,235,235,0.65); 100 | visibility:hidden; 101 | } 102 | 103 | #popup-stuff { 104 | background:rgba(255,255,255,0.6); 105 | -webkit-box-shadow:0px 0px 25px rgba(0,0,0,0.3); 106 | -moz-box-shadow:0px 0px 25px rgba(0,0,0,0.3); 107 | padding:25px; 108 | width:250px; 109 | } 110 | 111 | #add-form { 112 | border-bottom:1px solid #ccc; 113 | margin-bottom:15px; 114 | } 115 | 116 | #popup-stuff h3 { 117 | color:#777; 118 | font-weight:normal; 119 | font-style:italic; 120 | font-family:Georgia,serif; 121 | font-size:14px; 122 | margin-bottom:15px; 123 | } 124 | 125 | #popup-stuff li a { 126 | display:block; 127 | background:white; 128 | padding:15px; 129 | margin-bottom:1px; 130 | border-bottom:1px solid #eee; 131 | font-weight:bold; 132 | color:rgb(29,130,124); 133 | text-decoration:none; 134 | } 135 | 136 | #popup-stuff li a:hover { 137 | text-decoration:underline; 138 | } 139 | 140 | .scroll-container { 141 | height:100%; 142 | } 143 | 144 | ul#modules { 145 | height:94%; 146 | overflow:auto; 147 | } 148 | 149 | #modules li { 150 | -webkit-box-shadow:0px 0px 4px rgba(0,0,0,0.3); 151 | -moz-box-shadow:0px 0px 4px rgba(0,0,0,0.3); 152 | color:#333; 153 | padding-bottom:0px; 154 | margin:5px 10px; 155 | background:rgba(240,255,250,0.9); 156 | position:relative; 157 | } 158 | 159 | #modules li.depended { 160 | background:rgba(255,240,245,0.9); 161 | } 162 | 163 | #modules li .padding { 164 | padding:10px; 165 | } 166 | 167 | span.name { 168 | display:block; 169 | color:rgb(29,130,124); 170 | font-weight:bold; 171 | border-bottom:1px solid rgba(29,130,124,0.3); 172 | font-size:18px; 173 | padding:0px 0px 5px 5px; 174 | margin-bottom:5px; 175 | } 176 | span.version { 177 | display:block; 178 | color:rgb(255,79,19); 179 | font-size:12px; 180 | font-family:monospace; 181 | padding:5px; 182 | } 183 | a.repository { 184 | font-size:11px; 185 | color:royalblue; 186 | font-weight:bold; 187 | margin:25px 5px 5px 5px; 188 | display:block; 189 | text-decoration:none; 190 | } 191 | a.delete, 192 | .depender { 193 | display:block; 194 | font-size:11px; 195 | color:rgb(255,79,19); 196 | position:absolute; 197 | bottom:15px; 198 | right:15px; 199 | text-decoration:none; 200 | display:none; 201 | } 202 | #modules li:hover a.delete { 203 | display:block; 204 | } 205 | #modules p.depender { 206 | display:block; 207 | color:#aaa; 208 | font-size:10px; 209 | bottom:10px; 210 | } 211 | li.depended .delete, 212 | #ender-js .delete { 213 | display:none !important; 214 | } 215 | 216 | #modules pre { 217 | display:none; 218 | } 219 | 220 | #modules p { 221 | font-family:Georgia,serif; 222 | font-style:italic; 223 | color:#555; 224 | font-size:12px; 225 | padding:5px; 226 | } 227 | 228 | #size { 229 | position:absolute; 230 | top:25%; 231 | left:30px; 232 | font-size:24px; 233 | color:#555; 234 | } 235 | 236 | #searchbox { 237 | position:absolute; 238 | top:10%; 239 | left:25px; 240 | } 241 | 242 | #namesearch, 243 | #modulesearch, 244 | #arbitrary { 245 | font-family:"Helvetica Neue",Helvetica,Arial,sans-serif; 246 | color:#ccc; 247 | padding:7px; 248 | font-size:16px; 249 | font-weight:bold; 250 | width:300px; 251 | display:block; 252 | } 253 | #namesearch.typing, 254 | #modulesearch.typing, 255 | #arbitrary.typing { 256 | color:#555; 257 | } 258 | 259 | #modulesearch { 260 | display:block; 261 | margin-top:5px; 262 | } 263 | 264 | #arbitrary { 265 | font-size:12px; 266 | width:225px; 267 | margin-bottom:15px; 268 | } 269 | 270 | #function-scroller { 271 | height:94%; 272 | overflow:auto; 273 | background:rgba(25,25,25,0.3); 274 | } 275 | 276 | ul#functions { 277 | padding:15px 5px; 278 | } 279 | 280 | ul#functions li { 281 | padding:8px 8px; 282 | margin:5px; 283 | text-align:right; 284 | } 285 | 286 | #functions pre { 287 | text-align:left; 288 | } 289 | 290 | span.notice { 291 | padding:30px 35px 20px 55px; 292 | font-family:Georgia,serif; 293 | font-style:italic; 294 | font-size:15px; 295 | display:block; 296 | color:#333; 297 | } 298 | 299 | span.fn { 300 | font-weight:bold; 301 | font-size:18px; 302 | background:rgba(255,255,255,0.7); 303 | padding:10px 55px 10px 55px; 304 | color:rgb(29,130,124); 305 | -webkit-box-shadow:0px 0px 1px rgba(0,0,0,0.1); 306 | -moz-box-shadow:0px 0px 1px rgba(0,0,0,0.1); 307 | -webkit-border-radius:1px; 308 | -moz-border-radius:1px; 309 | cursor:pointer; 310 | } 311 | span.fn:hover { 312 | background:rgba(255,255,255,0.9); 313 | } 314 | span.fn.open { 315 | background:rgba(240,255,250,0.9); 316 | } 317 | 318 | span.fn em { 319 | color:white; 320 | font-weight:normal; 321 | font-style:normal; 322 | } 323 | 324 | span.fn em.money { 325 | color:white; 326 | font-style:normal; 327 | } 328 | span.fn:hover em.money { 329 | color:rgb(255,79,19); 330 | } 331 | 332 | div.info { 333 | display:none; 334 | background:rgba(255,255,255,0.8); 335 | padding:0px 0px 0px 5px; 336 | text-align:left; 337 | } 338 | div.info.visible { 339 | display:block; 340 | } 341 | 342 | div.info div.docs { 343 | padding:10px 3px; 344 | border-bottom:3px solid #ccc; 345 | } 346 | 347 | div.info span.owner { 348 | font-size:12px; 349 | font-family:monospace; 350 | color:white; 351 | background:rgb(255,79,19); 352 | -webkit-border-radius:3px; 353 | -moz-border-radius:3px; 354 | padding:5px; 355 | } 356 | 357 | div.info pre { 358 | background:rgba(0,0,0,0.7); 359 | overflow:scroll; 360 | color:white; 361 | padding:15px; 362 | } 363 | 364 | ::-webkit-scrollbar { 365 | width: 5px; 366 | height: 5px; 367 | background:#aaa; 368 | } 369 | 370 | ::-webkit-scrollbar-track-piece { 371 | background-color: #ddd; 372 | } 373 | 374 | ::-webkit-scrollbar-thumb { 375 | background-color: #bbb; 376 | background-color:rgb(59,170,154); 377 | } 378 | 379 | /* syntax highlighting */ 380 | .number { 381 | color:#ffff44; 382 | } 383 | 384 | .keyword { 385 | color: #219195; 386 | } 387 | 388 | .string { 389 | color: #fa524f; 390 | } 391 | 392 | .comment { 393 | color: #aaaaaa; 394 | } -------------------------------------------------------------------------------- /app/public/img/background.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stenson/wallet/dc028304a88b071d4cabc4f7c38510cdb3805bd3/app/public/img/background.jpeg -------------------------------------------------------------------------------- /app/public/img/battle.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stenson/wallet/dc028304a88b071d4cabc4f7c38510cdb3805bd3/app/public/img/battle.jpeg -------------------------------------------------------------------------------- /app/public/img/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stenson/wallet/dc028304a88b071d4cabc4f7c38510cdb3805bd3/app/public/img/plus.png -------------------------------------------------------------------------------- /app/public/js/MONEYender.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Ender.js: a small, powerful JavaScript library composed of application agnostic submodules 3 | * copyright Dustin Diaz & Jacob Thornton 2011 (@ded @fat) 4 | * https://github.com/ded/Ender.js 5 | * License MIT 6 | * Build: ender build jeesh 7 | */ 8 | !function (context) { 9 | 10 | function aug(o, o2) { 11 | for (var k in o2) { 12 | o[k] = o2[k]; 13 | } 14 | } 15 | 16 | function _MONEY(s, r) { 17 | this.elements = MONEY._select(s, r); 18 | this.length = this.elements.length; 19 | for (var i = 0; i < this.length; i++) { 20 | this[i] = this.elements[i]; 21 | } 22 | } 23 | 24 | function MONEY(s, r) { 25 | return new _MONEY(s, r); 26 | } 27 | 28 | aug(MONEY, { 29 | ender: function (o, proto) { 30 | aug(proto ? _MONEY.prototype : MONEY, o); 31 | }, 32 | _select: function () { 33 | return []; 34 | } 35 | }); 36 | 37 | var old = context.MONEY; 38 | MONEY.noConflict = function () { 39 | context.MONEY = old; 40 | return this; 41 | }; 42 | 43 | (typeof module !== 'undefined') && module.exports ? 44 | (module.exports = MONEY) : 45 | (context.MONEY = MONEY); 46 | 47 | }(this); 48 | !function () { var module = { exports: {} }; !function (doc) { 49 | var loaded = 0, fns = [], ol, f = false, 50 | testEl = doc.createElement('a'), 51 | domContentLoaded = 'DOMContentLoaded', 52 | addEventListener = 'addEventListener', 53 | onreadystatechange = 'onreadystatechange'; 54 | 55 | /^loade|c/.test(doc.readyState) && (loaded = 1); 56 | 57 | function flush() { 58 | loaded = 1; 59 | for (var i = 0, l = fns.length; i < l; i++) { 60 | fns[i](); 61 | } 62 | } 63 | doc[addEventListener] && doc[addEventListener](domContentLoaded, function fn() { 64 | doc.removeEventListener(domContentLoaded, fn, f); 65 | flush(); 66 | }, f); 67 | 68 | 69 | testEl.doScroll && doc.attachEvent(onreadystatechange, (ol = function ol() { 70 | if (/^c/.test(doc.readyState)) { 71 | doc.detachEvent(onreadystatechange, ol); 72 | flush(); 73 | } 74 | })); 75 | 76 | var domReady = testEl.doScroll ? 77 | function (fn) { 78 | self != top ? 79 | !loaded ? 80 | fns.push(fn) : 81 | fn() : 82 | !function () { 83 | try { 84 | testEl.doScroll('left'); 85 | } catch (e) { 86 | return setTimeout(function() { 87 | domReady(fn); 88 | }, 50); 89 | } 90 | fn(); 91 | }(); 92 | } : 93 | function (fn) { 94 | loaded ? fn() : fns.push(fn); 95 | }; 96 | 97 | (typeof module !== 'undefined') && module.exports ? 98 | (module.exports = {domReady: domReady}) : 99 | (window.domReady = domReady); 100 | 101 | }(document); MONEY.ender(module.exports); }(); 102 | !function () { var module = { exports: {} }; // Underscore.js 1.1.6 103 | // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc. 104 | // Underscore is freely distributable under the MIT license. 105 | // Portions of Underscore are inspired or borrowed from Prototype, 106 | // Oliver Steele's Functional, and John Resig's Micro-Templating. 107 | // For all details and documentation: 108 | // http://documentcloud.github.com/underscore 109 | 110 | (function() { 111 | 112 | // Baseline setup 113 | // -------------- 114 | 115 | // Establish the root object, `window` in the browser, or `global` on the server. 116 | var root = this; 117 | 118 | // Save the previous value of the `_` variable. 119 | var previousUnderscore = root._; 120 | 121 | // Establish the object that gets returned to break out of a loop iteration. 122 | var breaker = {}; 123 | 124 | // Save bytes in the minified (but not gzipped) version: 125 | var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; 126 | 127 | // Create quick reference variables for speed access to core prototypes. 128 | var slice = ArrayProto.slice, 129 | unshift = ArrayProto.unshift, 130 | toString = ObjProto.toString, 131 | hasOwnProperty = ObjProto.hasOwnProperty; 132 | 133 | // All **ECMAScript 5** native function implementations that we hope to use 134 | // are declared here. 135 | var 136 | nativeForEach = ArrayProto.forEach, 137 | nativeMap = ArrayProto.map, 138 | nativeReduce = ArrayProto.reduce, 139 | nativeReduceRight = ArrayProto.reduceRight, 140 | nativeFilter = ArrayProto.filter, 141 | nativeEvery = ArrayProto.every, 142 | nativeSome = ArrayProto.some, 143 | nativeIndexOf = ArrayProto.indexOf, 144 | nativeLastIndexOf = ArrayProto.lastIndexOf, 145 | nativeIsArray = Array.isArray, 146 | nativeKeys = Object.keys, 147 | nativeBind = FuncProto.bind; 148 | 149 | // Create a safe reference to the Underscore object for use below. 150 | var _ = function(obj) { return new wrapper(obj); }; 151 | 152 | // Export the Underscore object for **CommonJS**, with backwards-compatibility 153 | // for the old `require()` API. If we're not in CommonJS, add `_` to the 154 | // global object. 155 | if (typeof module !== 'undefined' && module.exports) { 156 | module.exports = _; 157 | _._ = _; 158 | } else { 159 | root._ = _; 160 | } 161 | 162 | // Current version. 163 | _.VERSION = '1.1.6'; 164 | 165 | // Collection Functions 166 | // -------------------- 167 | 168 | // The cornerstone, an `each` implementation, aka `forEach`. 169 | // Handles objects implementing `forEach`, arrays, and raw objects. 170 | // Delegates to **ECMAScript 5**'s native `forEach` if available. 171 | var each = _.each = _.forEach = function(obj, iterator, context) { 172 | if (obj == null) return; 173 | if (nativeForEach && obj.forEach === nativeForEach) { 174 | obj.forEach(iterator, context); 175 | } else if (_.isNumber(obj.length)) { 176 | for (var i = 0, l = obj.length; i < l; i++) { 177 | if (iterator.call(context, obj[i], i, obj) === breaker) return; 178 | } 179 | } else { 180 | for (var key in obj) { 181 | if (hasOwnProperty.call(obj, key)) { 182 | if (iterator.call(context, obj[key], key, obj) === breaker) return; 183 | } 184 | } 185 | } 186 | }; 187 | 188 | // Return the results of applying the iterator to each element. 189 | // Delegates to **ECMAScript 5**'s native `map` if available. 190 | _.map = function(obj, iterator, context) { 191 | var results = []; 192 | if (obj == null) return results; 193 | if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); 194 | each(obj, function(value, index, list) { 195 | results[results.length] = iterator.call(context, value, index, list); 196 | }); 197 | return results; 198 | }; 199 | 200 | // **Reduce** builds up a single result from a list of values, aka `inject`, 201 | // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. 202 | _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { 203 | var initial = memo !== void 0; 204 | if (obj == null) obj = []; 205 | if (nativeReduce && obj.reduce === nativeReduce) { 206 | if (context) iterator = _.bind(iterator, context); 207 | return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); 208 | } 209 | each(obj, function(value, index, list) { 210 | if (!initial && index === 0) { 211 | memo = value; 212 | initial = true; 213 | } else { 214 | memo = iterator.call(context, memo, value, index, list); 215 | } 216 | }); 217 | if (!initial) throw new TypeError("Reduce of empty array with no initial value"); 218 | return memo; 219 | }; 220 | 221 | // The right-associative version of reduce, also known as `foldr`. 222 | // Delegates to **ECMAScript 5**'s native `reduceRight` if available. 223 | _.reduceRight = _.foldr = function(obj, iterator, memo, context) { 224 | if (obj == null) obj = []; 225 | if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { 226 | if (context) iterator = _.bind(iterator, context); 227 | return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); 228 | } 229 | var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse(); 230 | return _.reduce(reversed, iterator, memo, context); 231 | }; 232 | 233 | // Return the first value which passes a truth test. Aliased as `detect`. 234 | _.find = _.detect = function(obj, iterator, context) { 235 | var result; 236 | any(obj, function(value, index, list) { 237 | if (iterator.call(context, value, index, list)) { 238 | result = value; 239 | return true; 240 | } 241 | }); 242 | return result; 243 | }; 244 | 245 | // Return all the elements that pass a truth test. 246 | // Delegates to **ECMAScript 5**'s native `filter` if available. 247 | // Aliased as `select`. 248 | _.filter = _.select = function(obj, iterator, context) { 249 | var results = []; 250 | if (obj == null) return results; 251 | if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); 252 | each(obj, function(value, index, list) { 253 | if (iterator.call(context, value, index, list)) results[results.length] = value; 254 | }); 255 | return results; 256 | }; 257 | 258 | // Return all the elements for which a truth test fails. 259 | _.reject = function(obj, iterator, context) { 260 | var results = []; 261 | if (obj == null) return results; 262 | each(obj, function(value, index, list) { 263 | if (!iterator.call(context, value, index, list)) results[results.length] = value; 264 | }); 265 | return results; 266 | }; 267 | 268 | // Determine whether all of the elements match a truth test. 269 | // Delegates to **ECMAScript 5**'s native `every` if available. 270 | // Aliased as `all`. 271 | _.every = _.all = function(obj, iterator, context) { 272 | var result = true; 273 | if (obj == null) return result; 274 | if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); 275 | each(obj, function(value, index, list) { 276 | if (!(result = result && iterator.call(context, value, index, list))) return breaker; 277 | }); 278 | return result; 279 | }; 280 | 281 | // Determine if at least one element in the object matches a truth test. 282 | // Delegates to **ECMAScript 5**'s native `some` if available. 283 | // Aliased as `any`. 284 | var any = _.some = _.any = function(obj, iterator, context) { 285 | iterator || (iterator = _.identity); 286 | var result = false; 287 | if (obj == null) return result; 288 | if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); 289 | each(obj, function(value, index, list) { 290 | if (result = iterator.call(context, value, index, list)) return breaker; 291 | }); 292 | return result; 293 | }; 294 | 295 | // Determine if a given value is included in the array or object using `===`. 296 | // Aliased as `contains`. 297 | _.include = _.contains = function(obj, target) { 298 | var found = false; 299 | if (obj == null) return found; 300 | if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; 301 | any(obj, function(value) { 302 | if (found = value === target) return true; 303 | }); 304 | return found; 305 | }; 306 | 307 | // Invoke a method (with arguments) on every item in a collection. 308 | _.invoke = function(obj, method) { 309 | var args = slice.call(arguments, 2); 310 | return _.map(obj, function(value) { 311 | return (method.call ? method || value : value[method]).apply(value, args); 312 | }); 313 | }; 314 | 315 | // Convenience version of a common use case of `map`: fetching a property. 316 | _.pluck = function(obj, key) { 317 | return _.map(obj, function(value){ return value[key]; }); 318 | }; 319 | 320 | // Return the maximum element or (element-based computation). 321 | _.max = function(obj, iterator, context) { 322 | if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj); 323 | var result = {computed : -Infinity}; 324 | each(obj, function(value, index, list) { 325 | var computed = iterator ? iterator.call(context, value, index, list) : value; 326 | computed >= result.computed && (result = {value : value, computed : computed}); 327 | }); 328 | return result.value; 329 | }; 330 | 331 | // Return the minimum element (or element-based computation). 332 | _.min = function(obj, iterator, context) { 333 | if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj); 334 | var result = {computed : Infinity}; 335 | each(obj, function(value, index, list) { 336 | var computed = iterator ? iterator.call(context, value, index, list) : value; 337 | computed < result.computed && (result = {value : value, computed : computed}); 338 | }); 339 | return result.value; 340 | }; 341 | 342 | // Sort the object's values by a criterion produced by an iterator. 343 | _.sortBy = function(obj, iterator, context) { 344 | return _.pluck(_.map(obj, function(value, index, list) { 345 | return { 346 | value : value, 347 | criteria : iterator.call(context, value, index, list) 348 | }; 349 | }).sort(function(left, right) { 350 | var a = left.criteria, b = right.criteria; 351 | return a < b ? -1 : a > b ? 1 : 0; 352 | }), 'value'); 353 | }; 354 | 355 | // Use a comparator function to figure out at what index an object should 356 | // be inserted so as to maintain order. Uses binary search. 357 | _.sortedIndex = function(array, obj, iterator) { 358 | iterator || (iterator = _.identity); 359 | var low = 0, high = array.length; 360 | while (low < high) { 361 | var mid = (low + high) >> 1; 362 | iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; 363 | } 364 | return low; 365 | }; 366 | 367 | // Safely convert anything iterable into a real, live array. 368 | _.toArray = function(iterable) { 369 | if (!iterable) return []; 370 | if (iterable.toArray) return iterable.toArray(); 371 | if (_.isArray(iterable)) return iterable; 372 | if (_.isArguments(iterable)) return slice.call(iterable); 373 | return _.values(iterable); 374 | }; 375 | 376 | // Return the number of elements in an object. 377 | _.size = function(obj) { 378 | return _.toArray(obj).length; 379 | }; 380 | 381 | // Array Functions 382 | // --------------- 383 | 384 | // Get the first element of an array. Passing **n** will return the first N 385 | // values in the array. Aliased as `head`. The **guard** check allows it to work 386 | // with `_.map`. 387 | _.first = _.head = function(array, n, guard) { 388 | return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; 389 | }; 390 | 391 | // Returns everything but the first entry of the array. Aliased as `tail`. 392 | // Especially useful on the arguments object. Passing an **index** will return 393 | // the rest of the values in the array from that index onward. The **guard** 394 | // check allows it to work with `_.map`. 395 | _.rest = _.tail = function(array, index, guard) { 396 | return slice.call(array, (index == null) || guard ? 1 : index); 397 | }; 398 | 399 | // Get the last element of an array. 400 | _.last = function(array) { 401 | return array[array.length - 1]; 402 | }; 403 | 404 | // Trim out all falsy values from an array. 405 | _.compact = function(array) { 406 | return _.filter(array, function(value){ return !!value; }); 407 | }; 408 | 409 | // Return a completely flattened version of an array. 410 | _.flatten = function(array) { 411 | return _.reduce(array, function(memo, value) { 412 | if (_.isArray(value)) return memo.concat(_.flatten(value)); 413 | memo[memo.length] = value; 414 | return memo; 415 | }, []); 416 | }; 417 | 418 | // Return a version of the array that does not contain the specified value(s). 419 | _.without = function(array) { 420 | var values = slice.call(arguments, 1); 421 | return _.filter(array, function(value){ return !_.include(values, value); }); 422 | }; 423 | 424 | // Produce a duplicate-free version of the array. If the array has already 425 | // been sorted, you have the option of using a faster algorithm. 426 | // Aliased as `unique`. 427 | _.uniq = _.unique = function(array, isSorted) { 428 | return _.reduce(array, function(memo, el, i) { 429 | if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el; 430 | return memo; 431 | }, []); 432 | }; 433 | 434 | // Produce an array that contains every item shared between all the 435 | // passed-in arrays. 436 | _.intersect = function(array) { 437 | var rest = slice.call(arguments, 1); 438 | return _.filter(_.uniq(array), function(item) { 439 | return _.every(rest, function(other) { 440 | return _.indexOf(other, item) >= 0; 441 | }); 442 | }); 443 | }; 444 | 445 | // Zip together multiple lists into a single array -- elements that share 446 | // an index go together. 447 | _.zip = function() { 448 | var args = slice.call(arguments); 449 | var length = _.max(_.pluck(args, 'length')); 450 | var results = new Array(length); 451 | for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i); 452 | return results; 453 | }; 454 | 455 | // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), 456 | // we need this function. Return the position of the first occurrence of an 457 | // item in an array, or -1 if the item is not included in the array. 458 | // Delegates to **ECMAScript 5**'s native `indexOf` if available. 459 | // If the array is large and already in sort order, pass `true` 460 | // for **isSorted** to use binary search. 461 | _.indexOf = function(array, item, isSorted) { 462 | if (array == null) return -1; 463 | var i, l; 464 | if (isSorted) { 465 | i = _.sortedIndex(array, item); 466 | return array[i] === item ? i : -1; 467 | } 468 | if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item); 469 | for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i; 470 | return -1; 471 | }; 472 | 473 | 474 | // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. 475 | _.lastIndexOf = function(array, item) { 476 | if (array == null) return -1; 477 | if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item); 478 | var i = array.length; 479 | while (i--) if (array[i] === item) return i; 480 | return -1; 481 | }; 482 | 483 | // Generate an integer Array containing an arithmetic progression. A port of 484 | // the native Python `range()` function. See 485 | // [the Python documentation](http://docs.python.org/library/functions.html#range). 486 | _.range = function(start, stop, step) { 487 | if (arguments.length <= 1) { 488 | stop = start || 0; 489 | start = 0; 490 | } 491 | step = arguments[2] || 1; 492 | 493 | var len = Math.max(Math.ceil((stop - start) / step), 0); 494 | var idx = 0; 495 | var range = new Array(len); 496 | 497 | while(idx < len) { 498 | range[idx++] = start; 499 | start += step; 500 | } 501 | 502 | return range; 503 | }; 504 | 505 | // Function (ahem) Functions 506 | // ------------------ 507 | 508 | // Create a function bound to a given object (assigning `this`, and arguments, 509 | // optionally). Binding with arguments is also known as `curry`. 510 | // Delegates to **ECMAScript 5**'s native `Function.bind` if available. 511 | // We check for `func.bind` first, to fail fast when `func` is undefined. 512 | _.bind = function(func, obj) { 513 | if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); 514 | var args = slice.call(arguments, 2); 515 | return function() { 516 | return func.apply(obj, args.concat(slice.call(arguments))); 517 | }; 518 | }; 519 | 520 | // Bind all of an object's methods to that object. Useful for ensuring that 521 | // all callbacks defined on an object belong to it. 522 | _.bindAll = function(obj) { 523 | var funcs = slice.call(arguments, 1); 524 | if (funcs.length == 0) funcs = _.functions(obj); 525 | each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); 526 | return obj; 527 | }; 528 | 529 | // Memoize an expensive function by storing its results. 530 | _.memoize = function(func, hasher) { 531 | var memo = {}; 532 | hasher || (hasher = _.identity); 533 | return function() { 534 | var key = hasher.apply(this, arguments); 535 | return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); 536 | }; 537 | }; 538 | 539 | // Delays a function for the given number of milliseconds, and then calls 540 | // it with the arguments supplied. 541 | _.delay = function(func, wait) { 542 | var args = slice.call(arguments, 2); 543 | return setTimeout(function(){ return func.apply(func, args); }, wait); 544 | }; 545 | 546 | // Defers a function, scheduling it to run after the current call stack has 547 | // cleared. 548 | _.defer = function(func) { 549 | return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); 550 | }; 551 | 552 | // Internal function used to implement `_.throttle` and `_.debounce`. 553 | var limit = function(func, wait, debounce) { 554 | var timeout; 555 | return function() { 556 | var context = this, args = arguments; 557 | var throttler = function() { 558 | timeout = null; 559 | func.apply(context, args); 560 | }; 561 | if (debounce) clearTimeout(timeout); 562 | if (debounce || !timeout) timeout = setTimeout(throttler, wait); 563 | }; 564 | }; 565 | 566 | // Returns a function, that, when invoked, will only be triggered at most once 567 | // during a given window of time. 568 | _.throttle = function(func, wait) { 569 | return limit(func, wait, false); 570 | }; 571 | 572 | // Returns a function, that, as long as it continues to be invoked, will not 573 | // be triggered. The function will be called after it stops being called for 574 | // N milliseconds. 575 | _.debounce = function(func, wait) { 576 | return limit(func, wait, true); 577 | }; 578 | 579 | // Returns a function that will be executed at most one time, no matter how 580 | // often you call it. Useful for lazy initialization. 581 | _.once = function(func) { 582 | var ran = false, memo; 583 | return function() { 584 | if (ran) return memo; 585 | ran = true; 586 | return memo = func.apply(this, arguments); 587 | }; 588 | }; 589 | 590 | // Returns the first function passed as an argument to the second, 591 | // allowing you to adjust arguments, run code before and after, and 592 | // conditionally execute the original function. 593 | _.wrap = function(func, wrapper) { 594 | return function() { 595 | var args = [func].concat(slice.call(arguments)); 596 | return wrapper.apply(this, args); 597 | }; 598 | }; 599 | 600 | // Returns a function that is the composition of a list of functions, each 601 | // consuming the return value of the function that follows. 602 | _.compose = function() { 603 | var funcs = slice.call(arguments); 604 | return function() { 605 | var args = slice.call(arguments); 606 | for (var i=funcs.length-1; i >= 0; i--) { 607 | args = [funcs[i].apply(this, args)]; 608 | } 609 | return args[0]; 610 | }; 611 | }; 612 | 613 | // Returns a function that will only be executed after being called N times. 614 | _.after = function(times, func) { 615 | return function() { 616 | if (--times < 1) { return func.apply(this, arguments); } 617 | }; 618 | }; 619 | 620 | 621 | // Object Functions 622 | // ---------------- 623 | 624 | // Retrieve the names of an object's properties. 625 | // Delegates to **ECMAScript 5**'s native `Object.keys` 626 | _.keys = nativeKeys || function(obj) { 627 | if (obj !== Object(obj)) throw new TypeError('Invalid object'); 628 | var keys = []; 629 | for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key; 630 | return keys; 631 | }; 632 | 633 | // Retrieve the values of an object's properties. 634 | _.values = function(obj) { 635 | return _.map(obj, _.identity); 636 | }; 637 | 638 | // Return a sorted list of the function names available on the object. 639 | // Aliased as `methods` 640 | _.functions = _.methods = function(obj) { 641 | return _.filter(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort(); 642 | }; 643 | 644 | // Extend a given object with all the properties in passed-in object(s). 645 | _.extend = function(obj) { 646 | each(slice.call(arguments, 1), function(source) { 647 | for (var prop in source) { 648 | if (source[prop] !== void 0) obj[prop] = source[prop]; 649 | } 650 | }); 651 | return obj; 652 | }; 653 | 654 | // Fill in a given object with default properties. 655 | _.defaults = function(obj) { 656 | each(slice.call(arguments, 1), function(source) { 657 | for (var prop in source) { 658 | if (obj[prop] == null) obj[prop] = source[prop]; 659 | } 660 | }); 661 | return obj; 662 | }; 663 | 664 | // Create a (shallow-cloned) duplicate of an object. 665 | _.clone = function(obj) { 666 | return _.isArray(obj) ? obj.slice() : _.extend({}, obj); 667 | }; 668 | 669 | // Invokes interceptor with the obj, and then returns obj. 670 | // The primary purpose of this method is to "tap into" a method chain, in 671 | // order to perform operations on intermediate results within the chain. 672 | _.tap = function(obj, interceptor) { 673 | interceptor(obj); 674 | return obj; 675 | }; 676 | 677 | // Perform a deep comparison to check if two objects are equal. 678 | _.isEqual = function(a, b) { 679 | // Check object identity. 680 | if (a === b) return true; 681 | // Different types? 682 | var atype = typeof(a), btype = typeof(b); 683 | if (atype != btype) return false; 684 | // Basic equality test (watch out for coercions). 685 | if (a == b) return true; 686 | // One is falsy and the other truthy. 687 | if ((!a && b) || (a && !b)) return false; 688 | // Unwrap any wrapped objects. 689 | if (a._chain) a = a._wrapped; 690 | if (b._chain) b = b._wrapped; 691 | // One of them implements an isEqual()? 692 | if (a.isEqual) return a.isEqual(b); 693 | // Check dates' integer values. 694 | if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime(); 695 | // Both are NaN? 696 | if (_.isNaN(a) && _.isNaN(b)) return false; 697 | // Compare regular expressions. 698 | if (_.isRegExp(a) && _.isRegExp(b)) 699 | return a.source === b.source && 700 | a.global === b.global && 701 | a.ignoreCase === b.ignoreCase && 702 | a.multiline === b.multiline; 703 | // If a is not an object by this point, we can't handle it. 704 | if (atype !== 'object') return false; 705 | // Check for different array lengths before comparing contents. 706 | if (a.length && (a.length !== b.length)) return false; 707 | // Nothing else worked, deep compare the contents. 708 | var aKeys = _.keys(a), bKeys = _.keys(b); 709 | // Different object sizes? 710 | if (aKeys.length != bKeys.length) return false; 711 | // Recursive comparison of contents. 712 | for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false; 713 | return true; 714 | }; 715 | 716 | // Is a given array or object empty? 717 | _.isEmpty = function(obj) { 718 | if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; 719 | for (var key in obj) if (hasOwnProperty.call(obj, key)) return false; 720 | return true; 721 | }; 722 | 723 | // Is a given value a DOM element? 724 | _.isElement = function(obj) { 725 | return !!(obj && obj.nodeType == 1); 726 | }; 727 | 728 | // Is a given value an array? 729 | // Delegates to ECMA5's native Array.isArray 730 | _.isArray = nativeIsArray || function(obj) { 731 | return toString.call(obj) === '[object Array]'; 732 | }; 733 | 734 | // Is a given variable an arguments object? 735 | _.isArguments = function(obj) { 736 | return !!(obj && hasOwnProperty.call(obj, 'callee')); 737 | }; 738 | 739 | // Is a given value a function? 740 | _.isFunction = function(obj) { 741 | return !!(obj && obj.constructor && obj.call && obj.apply); 742 | }; 743 | 744 | // Is a given value a string? 745 | _.isString = function(obj) { 746 | return !!(obj === '' || (obj && obj.charCodeAt && obj.substr)); 747 | }; 748 | 749 | // Is a given value a number? 750 | _.isNumber = function(obj) { 751 | return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed)); 752 | }; 753 | 754 | // Is the given value `NaN`? `NaN` happens to be the only value in JavaScript 755 | // that does not equal itself. 756 | _.isNaN = function(obj) { 757 | return obj !== obj; 758 | }; 759 | 760 | // Is a given value a boolean? 761 | _.isBoolean = function(obj) { 762 | return obj === true || obj === false; 763 | }; 764 | 765 | // Is a given value a date? 766 | _.isDate = function(obj) { 767 | return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear); 768 | }; 769 | 770 | // Is the given value a regular expression? 771 | _.isRegExp = function(obj) { 772 | return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false)); 773 | }; 774 | 775 | // Is a given value equal to null? 776 | _.isNull = function(obj) { 777 | return obj === null; 778 | }; 779 | 780 | // Is a given variable undefined? 781 | _.isUndefined = function(obj) { 782 | return obj === void 0; 783 | }; 784 | 785 | // Utility Functions 786 | // ----------------- 787 | 788 | // Run Underscore.js in *noConflict* mode, returning the `_` variable to its 789 | // previous owner. Returns a reference to the Underscore object. 790 | _.noConflict = function() { 791 | root._ = previousUnderscore; 792 | return this; 793 | }; 794 | 795 | // Keep the identity function around for default iterators. 796 | _.identity = function(value) { 797 | return value; 798 | }; 799 | 800 | // Run a function **n** times. 801 | _.times = function (n, iterator, context) { 802 | for (var i = 0; i < n; i++) iterator.call(context, i); 803 | }; 804 | 805 | // Add your own custom functions to the Underscore object, ensuring that 806 | // they're correctly added to the OOP wrapper as well. 807 | _.mixin = function(obj) { 808 | each(_.functions(obj), function(name){ 809 | addToWrapper(name, _[name] = obj[name]); 810 | }); 811 | }; 812 | 813 | // Generate a unique integer id (unique within the entire client session). 814 | // Useful for temporary DOM ids. 815 | var idCounter = 0; 816 | _.uniqueId = function(prefix) { 817 | var id = idCounter++; 818 | return prefix ? prefix + id : id; 819 | }; 820 | 821 | // By default, Underscore uses ERB-style template delimiters, change the 822 | // following template settings to use alternative delimiters. 823 | _.templateSettings = { 824 | evaluate : /<%([\s\S]+?)%>/g, 825 | interpolate : /<%=([\s\S]+?)%>/g 826 | }; 827 | 828 | // JavaScript micro-templating, similar to John Resig's implementation. 829 | // Underscore templating handles arbitrary delimiters, preserves whitespace, 830 | // and correctly escapes quotes within interpolated code. 831 | _.template = function(str, data) { 832 | var c = _.templateSettings; 833 | var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + 834 | 'with(obj||{}){__p.push(\'' + 835 | str.replace(/\\/g, '\\\\') 836 | .replace(/'/g, "\\'") 837 | .replace(c.interpolate, function(match, code) { 838 | return "'," + code.replace(/\\'/g, "'") + ",'"; 839 | }) 840 | .replace(c.evaluate || null, function(match, code) { 841 | return "');" + code.replace(/\\'/g, "'") 842 | .replace(/[\r\n\t]/g, ' ') + "__p.push('"; 843 | }) 844 | .replace(/\r/g, '\\r') 845 | .replace(/\n/g, '\\n') 846 | .replace(/\t/g, '\\t') 847 | + "');}return __p.join('');"; 848 | var func = new Function('obj', tmpl); 849 | return data ? func(data) : func; 850 | }; 851 | 852 | // The OOP Wrapper 853 | // --------------- 854 | 855 | // If Underscore is called as a function, it returns a wrapped object that 856 | // can be used OO-style. This wrapper holds altered versions of all the 857 | // underscore functions. Wrapped objects may be chained. 858 | var wrapper = function(obj) { this._wrapped = obj; }; 859 | 860 | // Expose `wrapper.prototype` as `_.prototype` 861 | _.prototype = wrapper.prototype; 862 | 863 | // Helper function to continue chaining intermediate results. 864 | var result = function(obj, chain) { 865 | return chain ? _(obj).chain() : obj; 866 | }; 867 | 868 | // A method to easily add functions to the OOP wrapper. 869 | var addToWrapper = function(name, func) { 870 | wrapper.prototype[name] = function() { 871 | var args = slice.call(arguments); 872 | unshift.call(args, this._wrapped); 873 | return result(func.apply(_, args), this._chain); 874 | }; 875 | }; 876 | 877 | // Add all of the Underscore functions to the wrapper object. 878 | _.mixin(_); 879 | 880 | // Add all mutator Array functions to the wrapper. 881 | each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { 882 | var method = ArrayProto[name]; 883 | wrapper.prototype[name] = function() { 884 | method.apply(this._wrapped, arguments); 885 | return result(this._wrapped, this._chain); 886 | }; 887 | }); 888 | 889 | // Add all accessor Array functions to the wrapper. 890 | each(['concat', 'join', 'slice'], function(name) { 891 | var method = ArrayProto[name]; 892 | wrapper.prototype[name] = function() { 893 | return result(method.apply(this._wrapped, arguments), this._chain); 894 | }; 895 | }); 896 | 897 | // Start chaining a wrapped Underscore object. 898 | wrapper.prototype.chain = function() { 899 | this._chain = true; 900 | return this; 901 | }; 902 | 903 | // Extracts the result from a wrapped and chained object. 904 | wrapper.prototype.value = function() { 905 | return this._wrapped; 906 | }; 907 | 908 | })(); 909 | MONEY.ender(module.exports); }(); 910 | /** 911 | * Klass.js - copyright @dedfat 912 | * version 1.0 913 | * https://github.com/ded/klass 914 | * Follow our software http://twitter.com/dedfat :) 915 | * MIT License 916 | */ 917 | !function (context, f) { 918 | var fnTest = /xyz/.test(function () { 919 | xyz; 920 | }) ? /\bsupr\b/ : /.*/, 921 | noop = function (){}, 922 | proto = 'prototype', 923 | isFn = function (o) { 924 | return typeof o === f; 925 | }; 926 | 927 | function klass(o) { 928 | return extend.call(typeof o == f ? o : noop, o, 1); 929 | } 930 | 931 | function wrap(k, fn, supr) { 932 | return function () { 933 | var tmp = this.supr; 934 | this.supr = supr[proto][k]; 935 | var ret = fn.apply(this, arguments); 936 | this.supr = tmp; 937 | return ret; 938 | }; 939 | } 940 | 941 | function process(what, o, supr) { 942 | for (var k in o) { 943 | if (o.hasOwnProperty(k)) { 944 | what[k] = typeof o[k] == f 945 | && typeof supr[proto][k] == f 946 | && fnTest.test(o[k]) 947 | ? wrap(k, o[k], supr) : o[k]; 948 | } 949 | } 950 | } 951 | 952 | function extend(o, fromSub) { 953 | noop[proto] = this[proto]; 954 | var supr = this, 955 | prototype = new noop(), 956 | isFunction = typeof o == f, 957 | _constructor = isFunction ? o : this, 958 | _methods = isFunction ? {} : o, 959 | fn = function () { 960 | if (this.initialize) { 961 | this.initialize.apply(this, arguments); 962 | } else { 963 | fromSub || isFn(o) && supr.apply(this, arguments); 964 | _constructor.apply(this, arguments); 965 | } 966 | }; 967 | 968 | fn.methods = function (o) { 969 | process(prototype, o, supr); 970 | fn[proto] = prototype; 971 | return this; 972 | }; 973 | 974 | fn.methods.call(fn, _methods).prototype.constructor = fn; 975 | 976 | fn.extend = arguments.callee; 977 | fn[proto].implement = fn.statics = function (o, optFn) { 978 | o = typeof o == 'string' ? (function () { 979 | var obj = {}; 980 | obj[o] = optFn; 981 | return obj; 982 | }()) : o; 983 | process(this, o, supr); 984 | return this; 985 | }; 986 | 987 | return fn; 988 | } 989 | 990 | if (typeof module !== 'undefined' && module.exports) { 991 | module.exports = klass; 992 | } else { 993 | var old = context.klass; 994 | klass.noConflict = function () { 995 | context.klass = old; 996 | return this; 997 | }; 998 | context.klass = klass; 999 | } 1000 | 1001 | }(this, 'function');MONEY.ender({ 1002 | klass: klass.noConflict() 1003 | }); 1004 | /*! 1005 | * MONEYscript.js v1.3 1006 | * https://github.com/ded/script.js 1007 | * Copyright: @ded & @fat - Dustin Diaz, Jacob Thornton 2011 1008 | * Follow our software http://twitter.com/dedfat 1009 | * License: MIT 1010 | */ 1011 | !function(win, doc, timeout) { 1012 | var script = doc.getElementsByTagName("script")[0], 1013 | list = {}, ids = {}, delay = {}, re = /^i|c/, 1014 | scripts = {}, s = 'string', f = false, i, 1015 | push = 'push', domContentLoaded = 'DOMContentLoaded', readyState = 'readyState', 1016 | addEventListener = 'addEventListener', onreadystatechange = 'onreadystatechange', 1017 | every = function(ar, fn) { 1018 | for (i = 0, j = ar.length; i < j; ++i) { 1019 | if (!fn(ar[i])) { 1020 | return 0; 1021 | } 1022 | } 1023 | return 1; 1024 | }; 1025 | function each(ar, fn) { 1026 | every(ar, function(el) { 1027 | return !fn(el); 1028 | }); 1029 | } 1030 | 1031 | if (!doc[readyState] && doc[addEventListener]) { 1032 | doc[addEventListener](domContentLoaded, function fn() { 1033 | doc.removeEventListener(domContentLoaded, fn, f); 1034 | doc[readyState] = "complete"; 1035 | }, f); 1036 | doc[readyState] = "loading"; 1037 | } 1038 | 1039 | var MONEYscript = function(paths, idOrDone, optDone) { 1040 | paths = paths[push] ? paths : [paths]; 1041 | var idOrDoneIsDone = idOrDone && idOrDone.call, 1042 | done = idOrDoneIsDone ? idOrDone : optDone, 1043 | id = idOrDoneIsDone ? paths.join('') : idOrDone, 1044 | queue = paths.length; 1045 | function loopFn(item) { 1046 | return item.call ? item() : list[item]; 1047 | } 1048 | function callback() { 1049 | if (!--queue) { 1050 | list[id] = 1; 1051 | done && done(); 1052 | for (var dset in delay) { 1053 | every(dset.split('|'), loopFn) && !each(delay[dset], loopFn) && (delay[dset] = []); 1054 | } 1055 | } 1056 | } 1057 | timeout(function() { 1058 | each(paths, function(path) { 1059 | if (scripts[path]) { 1060 | id && (ids[id] = 1); 1061 | callback(); 1062 | return; 1063 | } 1064 | scripts[path] = 1; 1065 | id && (ids[id] = 1); 1066 | create(MONEYscript.path ? 1067 | MONEYscript.path + path + '.js' : 1068 | path, callback); 1069 | }); 1070 | }, 0); 1071 | return MONEYscript; 1072 | }; 1073 | 1074 | function create(path, fn) { 1075 | var el = doc.createElement("script"), 1076 | loaded = 0; 1077 | el.onload = el[onreadystatechange] = function () { 1078 | if ((el[readyState] && !(!re.test(el[readyState]))) || loaded) { 1079 | return; 1080 | } 1081 | el.onload = el[onreadystatechange] = null; 1082 | loaded = 1; 1083 | fn(); 1084 | }; 1085 | el.async = 1; 1086 | el.src = path; 1087 | script.parentNode.insertBefore(el, script); 1088 | } 1089 | 1090 | MONEYscript.get = create; 1091 | 1092 | MONEYscript.ready = function(deps, ready, req) { 1093 | deps = deps[push] ? deps : [deps]; 1094 | var missing = []; 1095 | !each(deps, function(dep) { 1096 | list[dep] || missing[push](dep); 1097 | }) && every(deps, function(dep) { 1098 | return list[dep]; 1099 | }) ? ready() : !function(key) { 1100 | delay[key] = delay[key] || []; 1101 | delay[key][push](ready); 1102 | req && req(missing); 1103 | }(deps.join('|')); 1104 | return MONEYscript; 1105 | }; 1106 | 1107 | var old = win.MONEYscript; 1108 | MONEYscript.noConflict = function () { 1109 | win.MONEYscript = old; 1110 | return this; 1111 | }; 1112 | 1113 | (typeof module !== 'undefined' && module.exports) ? 1114 | (module.exports = MONEYscript) : 1115 | (win.MONEYscript = MONEYscript); 1116 | 1117 | }(this, document, setTimeout);!function () { 1118 | var s = MONEYscript.noConflict(); 1119 | MONEY.ender({ 1120 | script: s, 1121 | ready: s.ready, 1122 | require: s, 1123 | getScript: s.get 1124 | }); 1125 | }(); 1126 | /*! 1127 | * qwery.js - copyright @dedfat 1128 | * https://github.com/ded/qwery 1129 | * Follow our software http://twitter.com/dedfat 1130 | * MIT License 1131 | */ 1132 | !function (context, doc) { 1133 | 1134 | var c, i, j, k, l, m, o, p, r, v, 1135 | el, node, len, found, classes, item, items, token, collection, 1136 | id = /#([\w\-]+)/, 1137 | clas = /\.[\w\-]+/g, 1138 | idOnly = /^#([\w\-]+MONEY)/, 1139 | classOnly = /^\.([\w\-]+)MONEY/, 1140 | tagOnly = /^([\w\-]+)MONEY/, 1141 | tagAndOrClass = /^([\w]+)?\.([\w\-]+)MONEY/, 1142 | html = doc.documentElement, 1143 | tokenizr = /\s(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\MONEY\*\^'"]*\])/, 1144 | simple = /^([a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/, 1145 | attr = /\[([\w\-]+)(?:([\|\^\MONEY\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\MONEY\*\^]+)["']?)?\]/, 1146 | chunker = new RegExp(simple.source + '(' + attr.source + ')?'); 1147 | 1148 | function array(ar) { 1149 | r = []; 1150 | for (i = 0, len = ar.length; i < len; i++) { 1151 | r[i] = ar[i]; 1152 | } 1153 | return r; 1154 | } 1155 | 1156 | var cache = function () { 1157 | this.c = {}; 1158 | }; 1159 | cache.prototype = { 1160 | g: function (k) { 1161 | return this.c[k] || undefined; 1162 | }, 1163 | s: function (k, v) { 1164 | this.c[k] = v; 1165 | return v; 1166 | } 1167 | }; 1168 | 1169 | var classCache = new cache(), 1170 | cleanCache = new cache(), 1171 | attrCache = new cache(), 1172 | tokenCache = new cache(); 1173 | 1174 | function q(query) { 1175 | return query.match(chunker); 1176 | } 1177 | 1178 | function interpret(whole, tag, idsAndClasses, wholeAttribute, attribute, qualifier, value) { 1179 | var m, c, k; 1180 | if (tag && this.tagName.toLowerCase() !== tag) { 1181 | return false; 1182 | } 1183 | if (idsAndClasses && (m = idsAndClasses.match(id)) && m[1] !== this.id) { 1184 | return false; 1185 | } 1186 | if (idsAndClasses && (classes = idsAndClasses.match(clas))) { 1187 | for (i = classes.length; i--;) { 1188 | c = classes[i].slice(1); 1189 | if (!(classCache.g(c) || classCache.s(c, new RegExp('(^|\\s+)' + c + '(\\s+|MONEY)'))).test(this.className)) { 1190 | return false; 1191 | } 1192 | } 1193 | } 1194 | if (wholeAttribute && !value) { 1195 | o = this.attributes; 1196 | for (k in o) { 1197 | if (Object.prototype.hasOwnProperty.call(o, k) && (o[k].name || k) == attribute) { 1198 | return this; 1199 | } 1200 | } 1201 | } 1202 | if (wholeAttribute && !checkAttr(qualifier, this.getAttribute(attribute) || '', value)) { 1203 | return false; 1204 | } 1205 | return this; 1206 | } 1207 | 1208 | function loopAll(tokens) { 1209 | var r = [], token = tokens.pop(), intr = q(token), tag = intr[1] || '*', i, l, els, 1210 | root = tokens.length && (m = tokens[0].match(idOnly)) ? doc.getElementById(m[1]) : doc; 1211 | if (!root) { 1212 | return r; 1213 | } 1214 | els = root.getElementsByTagName(tag); 1215 | for (i = 0, l = els.length; i < l; i++) { 1216 | el = els[i]; 1217 | if (item = interpret.apply(el, intr)) { 1218 | r.push(item); 1219 | } 1220 | } 1221 | return r; 1222 | } 1223 | 1224 | function clean(s) { 1225 | return cleanCache.g(s) || cleanCache.s(s, s.replace(/([.*+?\^=!:MONEY{}()|\[\]\/\\])/g, '\\MONEY1')); 1226 | } 1227 | 1228 | function checkAttr(qualify, actual, val) { 1229 | switch (qualify) { 1230 | case '=': 1231 | return actual == val; 1232 | case '^=': 1233 | return actual.match(attrCache.g('^=' + val) || attrCache.s('^=' + val, new RegExp('^' + clean(val)))); 1234 | case 'MONEY=': 1235 | return actual.match(attrCache.g('MONEY=' + val) || attrCache.s('MONEY=' + val, new RegExp(clean(val) + 'MONEY'))); 1236 | case '*=': 1237 | return actual.match(attrCache.g(val) || attrCache.s(val, new RegExp(clean(val)))); 1238 | case '~=': 1239 | return actual.match(attrCache.g('~=' + val) || attrCache.s('~=' + val, new RegExp('(?:^|\\s+)' + clean(val) + '(?:\\s+|MONEY)'))); 1240 | case '|=': 1241 | return actual.match(attrCache.g('|=' + val) || attrCache.s('|=' + val, new RegExp('^' + clean(val) + '(-|MONEY)'))); 1242 | } 1243 | return false; 1244 | } 1245 | 1246 | function _qwery(selector) { 1247 | var r = [], ret = [], i, l, 1248 | tokens = tokenCache.g(selector) || tokenCache.s(selector, selector.split(tokenizr)); 1249 | tokens = tokens.slice(0); 1250 | if (!tokens.length) { 1251 | return r; 1252 | } 1253 | r = loopAll(tokens); 1254 | if (!tokens.length) { 1255 | return r; 1256 | } 1257 | // loop through all descendent tokens 1258 | for (j = 0, l = r.length, k = 0; j < l; j++) { 1259 | node = r[j]; 1260 | p = node; 1261 | // loop through each token 1262 | for (i = tokens.length; i--;) { 1263 | z: // loop through parent nodes 1264 | while (p !== html && (p = p.parentNode)) { 1265 | if (found = interpret.apply(p, q(tokens[i]))) { 1266 | break z; 1267 | } 1268 | } 1269 | } 1270 | found && (ret[k++] = node); 1271 | } 1272 | return ret; 1273 | } 1274 | 1275 | var isAncestor = 'compareDocumentPosition' in html ? 1276 | function (element, container) { 1277 | return (container.compareDocumentPosition(element) & 16) == 16; 1278 | } : 'contains' in html ? 1279 | function (element, container) { 1280 | return container !== element && container.contains(element); 1281 | } : 1282 | function (element, container) { 1283 | while (element = element.parentNode) { 1284 | if (element === container) { 1285 | return 1; 1286 | } 1287 | } 1288 | return 0; 1289 | }; 1290 | 1291 | function boilerPlate(selector, _root, fn) { 1292 | var root = (typeof _root == 'string') ? fn(_root)[0] : (_root || doc); 1293 | if (isNode(selector)) { 1294 | return !_root || (isNode(root) && isAncestor(selector, root)) ? [selector] : []; 1295 | } 1296 | if (selector && typeof selector === 'object' && selector.length && isFinite(selector.length)) { 1297 | return array(selector); 1298 | } 1299 | if (m = selector.match(idOnly)) { 1300 | return (el = doc.getElementById(m[1])) ? [el] : []; 1301 | } 1302 | if (m = selector.match(tagOnly)) { 1303 | return array(root.getElementsByTagName(m[1])); 1304 | } 1305 | return false; 1306 | } 1307 | 1308 | function isNode(el) { 1309 | return (el === window || el && el.nodeType && el.nodeType.toString().match(/[19]/)); 1310 | } 1311 | 1312 | function qsa(selector, _root) { 1313 | var root = (typeof _root == 'string') ? qsa(_root)[0] : (_root || doc); 1314 | if (!root) { 1315 | return []; 1316 | } 1317 | if (m = boilerPlate(selector, _root, qsa)) { 1318 | return m; 1319 | } 1320 | if (doc.getElementsByClassName && (m = selector.match(classOnly))) { 1321 | return array((root).getElementsByClassName(m[1])); 1322 | } 1323 | return array((root).querySelectorAll(selector)); 1324 | } 1325 | 1326 | function uniq(ar) { 1327 | var a = [], i, j; 1328 | label: 1329 | for (i = 0; i < ar.length; i++) { 1330 | for (j = 0; j < a.length; j++) { 1331 | if (a[j] == ar[i]) { 1332 | continue label; 1333 | } 1334 | } 1335 | a[a.length] = ar[i]; 1336 | } 1337 | return a; 1338 | } 1339 | 1340 | var qwery = function () { 1341 | // return fast. boosh. 1342 | if (doc.querySelector && doc.querySelectorAll) { 1343 | return qsa; 1344 | } 1345 | return function (selector, _root) { 1346 | var root = (typeof _root == 'string') ? qwery(_root)[0] : (_root || doc); 1347 | if (!root) { 1348 | return []; 1349 | } 1350 | var i, l, result = [], collections = [], element; 1351 | if (m = boilerPlate(selector, _root, qwery)) { 1352 | return m; 1353 | } 1354 | if (m = selector.match(tagAndOrClass)) { 1355 | items = root.getElementsByTagName(m[1] || '*'); 1356 | r = classCache.g(m[2]) || classCache.s(m[2], new RegExp('(^|\\s+)' + m[2] + '(\\s+|MONEY)')); 1357 | for (i = 0, l = items.length, j = 0; i < l; i++) { 1358 | r.test(items[i].className) && (result[j++] = items[i]); 1359 | } 1360 | return result; 1361 | } 1362 | for (i = 0, items = selector.split(','), l = items.length; i < l; i++) { 1363 | collections[i] = _qwery(items[i]); 1364 | } 1365 | for (i = 0, l = collections.length; i < l && (collection = collections[i]); i++) { 1366 | var ret = collection; 1367 | if (root !== doc) { 1368 | ret = []; 1369 | for (j = 0, m = collection.length; j < m && (element = collection[j]); j++) { 1370 | // make sure element is a descendent of root 1371 | isAncestor(element, root) && ret.push(element); 1372 | } 1373 | } 1374 | result = result.concat(ret); 1375 | } 1376 | return uniq(result); 1377 | }; 1378 | }(); 1379 | 1380 | qwery.uniq = uniq; 1381 | var oldQwery = context.qwery; 1382 | qwery.noConflict = function () { 1383 | context.qwery = oldQwery; 1384 | return this; 1385 | }; 1386 | context.qwery = qwery; 1387 | 1388 | }(this, document); 1389 | !function () { 1390 | var q = qwery.noConflict(); 1391 | MONEY._select = q; 1392 | MONEY.ender({ 1393 | find: function (s) { 1394 | var r = [], i, l, j, k, els; 1395 | for (i = 0, l = this.length; i < l; i++) { 1396 | els = q(s, this[i]); 1397 | for (j = 0, k = els.length; j < k; j++) { 1398 | r.push(els[j]); 1399 | } 1400 | } 1401 | return MONEY(q.uniq(r)); 1402 | } 1403 | }, true); 1404 | }(); 1405 | /*! 1406 | * bonzo.js - copyright @dedfat 2011 1407 | * https://github.com/ded/bonzo 1408 | * Follow our software http://twitter.com/dedfat 1409 | * MIT License 1410 | */ 1411 | !function (context) { 1412 | 1413 | var doc = document, 1414 | html = doc.documentElement, 1415 | specialAttributes = /^checked|value|selectedMONEY/, 1416 | stateAttributes = /^checked|selectedMONEY/, 1417 | ie = /msie/.test(navigator.userAgent), 1418 | uidList = [], 1419 | uuids = 0; 1420 | 1421 | function classReg(c) { 1422 | return new RegExp("(^|\\s+)" + c + "(\\s+|MONEY)"); 1423 | } 1424 | 1425 | function each(ar, fn) { 1426 | for (i = 0, len = ar.length; i < len; i++) { 1427 | fn(ar[i]); 1428 | } 1429 | } 1430 | 1431 | function trim(s) { 1432 | return s.replace(/(^\s*|\s*MONEY)/g, ''); 1433 | } 1434 | 1435 | function camelize(s) { 1436 | return s.replace(/-(.)/g, function (m, m1) { 1437 | return m1.toUpperCase(); 1438 | }); 1439 | } 1440 | 1441 | function is(node) { 1442 | return node && node.nodeName && node.nodeType == 1; 1443 | } 1444 | 1445 | function some(ar, fn, scope) { 1446 | for (var i = 0, j = ar.length; i < j; ++i) { 1447 | if (fn.call(scope, ar[i], i, ar)) { 1448 | return true; 1449 | } 1450 | } 1451 | return false; 1452 | } 1453 | 1454 | function _bonzo(elements) { 1455 | this.elements = []; 1456 | this.length = 0; 1457 | if (elements) { 1458 | this.elements = Object.prototype.hasOwnProperty.call(elements, 'length') ? elements : [elements]; 1459 | this.length = this.elements.length; 1460 | for (var i = 0; i < this.length; i++) { 1461 | this[i] = this.elements[i]; 1462 | } 1463 | } 1464 | } 1465 | 1466 | _bonzo.prototype = { 1467 | 1468 | each: function (fn) { 1469 | for (var i = 0, l = this.length; i < l; i++) { 1470 | fn.call(this, this[i], i); 1471 | } 1472 | return this; 1473 | }, 1474 | 1475 | map: function (fn, reject) { 1476 | var m = [], n; 1477 | for (var i = 0; i < this.length; i++) { 1478 | n = fn.call(this, this[i]); 1479 | reject ? (reject(n) && m.push(n)) : m.push(n); 1480 | } 1481 | return m; 1482 | }, 1483 | 1484 | first: function () { 1485 | return bonzo(this[0]); 1486 | }, 1487 | 1488 | last: function () { 1489 | return bonzo(this[this.length - 1]); 1490 | }, 1491 | 1492 | html: function (html) { 1493 | return typeof html == 'string' ? 1494 | this.each(function (el) { 1495 | el.innerHTML = html; 1496 | }) : 1497 | this.elements[0] ? this.elements[0].innerHTML : ''; 1498 | }, 1499 | 1500 | addClass: function (c) { 1501 | return this.each(function (el) { 1502 | this.hasClass(el, c) || (el.className = trim(el.className + ' ' + c)); 1503 | }); 1504 | }, 1505 | 1506 | removeClass: function (c) { 1507 | return this.each(function (el) { 1508 | this.hasClass(el, c) && (el.className = trim(el.className.replace(classReg(c), ' '))); 1509 | }); 1510 | }, 1511 | 1512 | hasClass: function (el, c) { 1513 | return typeof c == 'undefined' ? 1514 | some(this.elements, function (i) { 1515 | return classReg(el).test(i.className); 1516 | }) : 1517 | classReg(c).test(el.className); 1518 | }, 1519 | 1520 | toggleClass: function (c) { 1521 | return this.each(function (el) { 1522 | this.hasClass(el, c) ? 1523 | (el.className = trim(el.className.replace(classReg(c), ' '))) : 1524 | (el.className = trim(el.className + ' ' + c)); 1525 | }); 1526 | }, 1527 | 1528 | show: function (elements) { 1529 | return this.each(function (el) { 1530 | el.style.display = ''; 1531 | }); 1532 | }, 1533 | 1534 | hide: function (elements) { 1535 | return this.each(function (el) { 1536 | el.style.display = 'none'; 1537 | }); 1538 | }, 1539 | 1540 | append: function (node) { 1541 | return this.each(function (el) { 1542 | each(bonzo.create(node), function (i) { 1543 | el.appendChild(i); 1544 | }); 1545 | }); 1546 | }, 1547 | 1548 | prepend: function (node) { 1549 | return this.each(function (el) { 1550 | var first = el.firstChild; 1551 | each(bonzo.create(node), function (i) { 1552 | el.insertBefore(i, first); 1553 | }); 1554 | }); 1555 | }, 1556 | 1557 | appendTo: function (target) { 1558 | return this.each(function (el) { 1559 | target.appendChild(el); 1560 | }); 1561 | }, 1562 | 1563 | next: function () { 1564 | return this.related('nextSibling'); 1565 | }, 1566 | 1567 | previous: function () { 1568 | return this.related('previousSibling'); 1569 | }, 1570 | 1571 | related: function (method) { 1572 | return bonzo(this.map( 1573 | function (el) { 1574 | el = el[method]; 1575 | while (el && el.nodeType !== 1) { 1576 | el = el[method]; 1577 | } 1578 | return el || 0; 1579 | }, 1580 | function (el) { 1581 | return el; 1582 | } 1583 | )); 1584 | }, 1585 | 1586 | prependTo: function (target) { 1587 | return this.each(function (el) { 1588 | target.insertBefore(el, bonzo.firstChild(target)); 1589 | }); 1590 | }, 1591 | 1592 | before: function (node) { 1593 | return this.each(function (el) { 1594 | each(bonzo.create(node), function (i) { 1595 | el.parentNode.insertBefore(i, el); 1596 | }); 1597 | }); 1598 | }, 1599 | 1600 | after: function (node) { 1601 | return this.each(function (el) { 1602 | each(bonzo.create(node), function (i) { 1603 | el.parentNode.insertBefore(i, el.nextSibling); 1604 | }); 1605 | }); 1606 | }, 1607 | 1608 | css: function (o, v) { 1609 | if (v === undefined && typeof o == 'string') { 1610 | return this[0].style[camelize(o)]; 1611 | } 1612 | var fn = typeof o == 'string' ? 1613 | function (el) { 1614 | el.style[camelize(o)] = v; 1615 | } : 1616 | function (el) { 1617 | for (var k in o) { 1618 | o.hasOwnProperty(k) && (el.style[camelize(k)] = o[k]); 1619 | } 1620 | }; 1621 | return this.each(fn); 1622 | }, 1623 | 1624 | offset: function () { 1625 | var el = this.elements[0]; 1626 | var width = el.offsetWidth; 1627 | var height = el.offsetHeight; 1628 | var top = el.offsetTop; 1629 | var left = el.offsetLeft; 1630 | while (el = el.offsetParent) { 1631 | top = top + el.offsetTop; 1632 | left = left + el.offsetLeft; 1633 | } 1634 | 1635 | return { 1636 | top: top, 1637 | left: left, 1638 | height: height, 1639 | width: width 1640 | }; 1641 | }, 1642 | 1643 | attr: function (k, v) { 1644 | var el = this.elements[0]; 1645 | return typeof v == 'undefined' ? 1646 | specialAttributes.test(k) ? 1647 | stateAttributes.test(k) && typeof el[k] == 'string' ? 1648 | true : el[k] : el.getAttribute(k) : 1649 | this.each(function (el) { 1650 | el.setAttribute(k, v); 1651 | }); 1652 | }, 1653 | 1654 | removeAttr: function (k) { 1655 | return this.each(function (el) { 1656 | el.removeAttribute(k); 1657 | }); 1658 | }, 1659 | 1660 | data: function (k, v) { 1661 | var el = this.elements[0]; 1662 | if (typeof v === 'undefined') { 1663 | el.getAttribute('data-node-uid') || el.setAttribute('data-node-uid', ++uuids); 1664 | var uid = el.getAttribute('data-node-uid'); 1665 | uidList[uid] || (uidList[uid] = {}); 1666 | return uidList[uid][k]; 1667 | } else { 1668 | return this.each(function (el) { 1669 | el.getAttribute('data-node-uid') || el.setAttribute('data-node-uid', ++uuids); 1670 | var uid = el.getAttribute('data-node-uid'); 1671 | var o = {}; 1672 | o[k] = v; 1673 | uidList[uid] = o; 1674 | }); 1675 | } 1676 | }, 1677 | 1678 | remove: function () { 1679 | return this.each(function (el) { 1680 | el.parentNode && el.parentNode.removeChild(el); 1681 | }); 1682 | }, 1683 | 1684 | empty: function () { 1685 | return this.each(function (el) { 1686 | while (el.firstChild) { 1687 | el.removeChild(el.firstChild); 1688 | } 1689 | }); 1690 | }, 1691 | 1692 | detach: function () { 1693 | return this.map(function (el) { 1694 | return el.parentNode.removeChild(el); 1695 | }); 1696 | }, 1697 | 1698 | scrollTop: function (y) { 1699 | return scroll.call(this, null, y, 'y'); 1700 | }, 1701 | 1702 | scrollLeft: function (x) { 1703 | return scroll.call(this, x, null, 'x'); 1704 | } 1705 | 1706 | }; 1707 | 1708 | function scroll(x, y, type) { 1709 | var el = this.elements[0]; 1710 | if (x == null && y == null) { 1711 | return (isBody(el) ? getWindowScroll() : { x: el.scrollLeft, y: el.scrollTop })[type]; 1712 | } 1713 | if (isBody(el)) { 1714 | window.scrollTo(x, y); 1715 | } else { 1716 | x != null && (el.scrollLeft = x); 1717 | y != null && (el.scrollTop = y); 1718 | } 1719 | return this; 1720 | } 1721 | 1722 | function isBody(element) { 1723 | return element === window || (/^(?:body|html)MONEY/i).test(element.tagName); 1724 | } 1725 | 1726 | function getWindowScroll() { 1727 | return { x: window.pageXOffset || html.scrollLeft, y: window.pageYOffset || html.scrollTop }; 1728 | } 1729 | 1730 | function bonzo(els) { 1731 | return new _bonzo(els); 1732 | } 1733 | 1734 | bonzo.aug = function (o, target) { 1735 | for (var k in o) { 1736 | o.hasOwnProperty(k) && ((target || _bonzo.prototype)[k] = o[k]); 1737 | } 1738 | }; 1739 | 1740 | bonzo.create = function (node) { 1741 | return typeof node == 'string' ? 1742 | function () { 1743 | var el = doc.createElement('div'), els = []; 1744 | el.innerHTML = node; 1745 | var nodes = el.childNodes; 1746 | el = el.firstChild; 1747 | els.push(el); 1748 | while (el = el.nextSibling) { 1749 | (el.nodeType == 1) && els.push(el); 1750 | } 1751 | return els; 1752 | 1753 | }() : is(node) ? [node.cloneNode(true)] : []; 1754 | }; 1755 | 1756 | bonzo.doc = function () { 1757 | var w = html.scrollWidth, 1758 | h = html.scrollHeight, 1759 | vp = this.viewport(); 1760 | return { 1761 | width: Math.max(w, vp.width), 1762 | height: Math.max(h, vp.height) 1763 | }; 1764 | }; 1765 | 1766 | bonzo.firstChild = function (el) { 1767 | for (var c = el.childNodes, i = 0, j = (c && c.length) || 0, e; i < j; i++) { 1768 | if (c[i].nodeType === 1) { 1769 | e = c[j = i]; 1770 | } 1771 | } 1772 | return e; 1773 | }; 1774 | 1775 | bonzo.viewport = function () { 1776 | var h = self.innerHeight, 1777 | w = self.innerWidth; 1778 | ie && (h = html.clientHeight) && (w = html.clientWidth); 1779 | return { 1780 | width: w, 1781 | height: h 1782 | }; 1783 | }; 1784 | 1785 | bonzo.isAncestor = 'compareDocumentPosition' in html ? 1786 | function (container, element) { 1787 | return (container.compareDocumentPosition(element) & 16) == 16; 1788 | } : 'contains' in html ? 1789 | function (container, element) { 1790 | return container !== element && container.contains(element); 1791 | } : 1792 | function (container, element) { 1793 | while (element = element.parentNode) { 1794 | if (element === container) { 1795 | return true; 1796 | } 1797 | } 1798 | return false; 1799 | }; 1800 | 1801 | var old = context.bonzo; 1802 | bonzo.noConflict = function () { 1803 | context.bonzo = old; 1804 | return this; 1805 | }; 1806 | context.bonzo = bonzo; 1807 | 1808 | }(this);!function () { 1809 | var b = bonzo.noConflict(); 1810 | MONEY.ender(b); 1811 | MONEY.ender(b(), true); 1812 | MONEY.ender({ 1813 | create: function (node) { 1814 | return MONEY(b.create(node)); 1815 | } 1816 | }); 1817 | function uniq(ar) { 1818 | var a = [], i, j; 1819 | label: 1820 | for (i = 0; i < ar.length; i++) { 1821 | for (j = 0; j < a.length; j++) { 1822 | if (a[j] == ar[i]) { 1823 | continue label; 1824 | } 1825 | } 1826 | a[a.length] = ar[i]; 1827 | } 1828 | return a; 1829 | } 1830 | MONEY.ender({ 1831 | parents: function (selector) { 1832 | var collection = MONEY(selector), i, l, j, k, r = []; 1833 | collect: 1834 | for (i = 0, l = collection.length; i < l; i++) { 1835 | for (j = 0, k = this.length; j < k; j++) { 1836 | if (b.isAncestor(collection[i], this[j])) { 1837 | r.push(collection[i]); 1838 | continue collect; 1839 | } 1840 | } 1841 | } 1842 | return b(uniq(collection)); 1843 | } 1844 | }, true); 1845 | 1846 | }(); 1847 | 1848 | /*! 1849 | * bean.js - copyright @dedfat 1850 | * https://github.com/fat/bean 1851 | * Follow our software http://twitter.com/dedfat 1852 | * MIT License 1853 | * special thanks to: 1854 | * dean edwards: http://dean.edwards.name/ 1855 | * dperini: https://github.com/dperini/nwevents 1856 | * the entire mootools team: github.com/mootools/mootools-core 1857 | */ 1858 | !function (context) { 1859 | var __uid = 1, registry = {}, collected = {}, 1860 | overOut = /over|out/, 1861 | namespace = /[^\.]*(?=\..*)\.|.*/, 1862 | stripName = /\..*/, 1863 | addEvent = 'addEventListener', 1864 | attachEvent = 'attachEvent', 1865 | removeEvent = 'removeEventListener', 1866 | detachEvent = 'detachEvent'; 1867 | 1868 | function isDescendant(parent, child) { 1869 | var node = child.parentNode; 1870 | while (node != null) { 1871 | if (node == parent) { 1872 | return true; 1873 | } 1874 | node = node.parentNode; 1875 | } 1876 | } 1877 | 1878 | function retrieveEvents(element) { 1879 | var uid = retrieveUid(element); 1880 | return (registry[uid] = registry[uid] || {}); 1881 | } 1882 | 1883 | function retrieveUid(obj, uid) { 1884 | return (obj.__uid = uid || obj.__uid || __uid++); 1885 | } 1886 | 1887 | function listener(element, type, fn, add, custom) { 1888 | if (element[addEvent]) { 1889 | element[add ? addEvent : removeEvent](type, fn, false); 1890 | } else if (element[attachEvent]) { 1891 | custom && add && (element['_on' + custom] = element['_on' + custom] || 0); 1892 | element[add ? attachEvent : detachEvent]('on' + type, fn); 1893 | } 1894 | } 1895 | 1896 | function nativeHandler(element, fn, args) { 1897 | return function (event) { 1898 | event = fixEvent(event || ((this.ownerDocument || this.document || this).parentWindow || context).event); 1899 | return fn.apply(element, [event].concat(args)); 1900 | }; 1901 | } 1902 | 1903 | function customHandler(element, fn, type, condition, args) { 1904 | return function (event) { 1905 | if (condition ? condition.call(this, event) : event && event.propertyName == '_on' + type || !event) { 1906 | fn.apply(element, [event].concat(args)); 1907 | } 1908 | }; 1909 | } 1910 | 1911 | function addListener(element, orgType, fn, args) { 1912 | var type = orgType.replace(stripName, ''), events = retrieveEvents(element), 1913 | handlers = events[type] || (events[type] = {}), 1914 | uid = retrieveUid(fn, orgType.replace(namespace, '')); 1915 | if (handlers[uid]) { 1916 | return element; 1917 | } 1918 | var custom = customEvents[type]; 1919 | fn = custom && custom.condition ? customHandler(element, fn, type, custom.condition) : fn; 1920 | type = custom && custom.base || type; 1921 | var isNative = context[addEvent] || nativeEvents.indexOf(type) > -1; 1922 | fn = isNative ? nativeHandler(element, fn, args) : customHandler(element, fn, type, false, args); 1923 | if (type == 'unload') { 1924 | var org = fn; 1925 | fn = function () { 1926 | removeListener(element, type, fn) && org(); 1927 | }; 1928 | } 1929 | listener(element, isNative ? type : 'propertychange', fn, true, !isNative && true); 1930 | handlers[uid] = fn; 1931 | fn.__uid = uid; 1932 | return type == 'unload' ? element : (collected[retrieveUid(element)] = element); 1933 | } 1934 | 1935 | function removeListener(element, orgType, handler) { 1936 | var uid, names, uids, i, events = retrieveEvents(element), type = orgType.replace(stripName, ''); 1937 | if (!events || !events[type]) { 1938 | return element; 1939 | } 1940 | names = orgType.replace(namespace, ''); 1941 | uids = names ? names.split('.') : [handler.__uid]; 1942 | for (i = uids.length; i--;) { 1943 | uid = uids[i]; 1944 | handler = events[type][uid]; 1945 | delete events[type][uid]; 1946 | type = customEvents[type] ? customEvents[type].base : type; 1947 | var isNative = element[addEvent] || nativeEvents.indexOf(type) > -1; 1948 | listener(element, isNative ? type : 'propertychange', handler, false, !isNative && type); 1949 | } 1950 | return element; 1951 | } 1952 | 1953 | function del(selector, fn, MONEY) { 1954 | return function (e) { 1955 | var array = typeof selector == 'string' ? MONEY(selector, this) : selector; 1956 | for (var target = e.target; target && target != this; target = target.parentNode) { 1957 | for (var i = array.length; i--;) { 1958 | if (array[i] == target) { 1959 | return fn.apply(target, arguments); 1960 | } 1961 | } 1962 | } 1963 | }; 1964 | } 1965 | 1966 | function add(element, events, fn, delfn, MONEY) { 1967 | if (typeof events == 'object' && !fn) { 1968 | for (var type in events) { 1969 | events.hasOwnProperty(type) && add(element, type, events[type]); 1970 | } 1971 | } else { 1972 | var isDel = typeof fn == 'string', types = (isDel ? fn : events).split(' '); 1973 | fn = isDel ? del(events, delfn, MONEY) : fn; 1974 | for (var i = types.length; i--;) { 1975 | addListener(element, types[i], fn, Array.prototype.slice.call(arguments, isDel ? 4 : 3)); 1976 | } 1977 | } 1978 | return element; 1979 | } 1980 | 1981 | function remove(element, orgEvents, fn) { 1982 | var k, type, events, 1983 | isString = typeof(orgEvents) == 'string', 1984 | names = isString && orgEvents.replace(namespace, ''), 1985 | rm = removeListener, 1986 | attached = retrieveEvents(element); 1987 | if (isString && /\s/.test(orgEvents)) { 1988 | orgEvents = orgEvents.split(' '); 1989 | var i = orgEvents.length - 1; 1990 | while (remove(element, orgEvents[i]) && i--) {} 1991 | return element; 1992 | } 1993 | events = isString ? orgEvents.replace(stripName, '') : orgEvents; 1994 | if (!attached || (isString && !attached[events])) { 1995 | return element; 1996 | } 1997 | if (typeof fn == 'function') { 1998 | rm(element, events, fn); 1999 | } else if (names) { 2000 | rm(element, orgEvents); 2001 | } else { 2002 | rm = events ? rm : remove; 2003 | type = isString && events; 2004 | events = events ? (fn || attached[events] || events) : attached; 2005 | for (k in events) { 2006 | events.hasOwnProperty(k) && rm(element, type || k, events[k]); 2007 | } 2008 | } 2009 | return element; 2010 | } 2011 | 2012 | function fire(element, type) { 2013 | var evt, k, i, types = type.split(' '); 2014 | for (i = types.length; i--;) { 2015 | type = types[i].replace(stripName, ''); 2016 | var isNative = nativeEvents.indexOf(type) > -1, 2017 | isNamespace = types[i].replace(namespace, ''), 2018 | handlers = retrieveEvents(element)[type]; 2019 | if (isNamespace) { 2020 | isNamespace = isNamespace.split('.'); 2021 | for (k = isNamespace.length; k--;) { 2022 | handlers[isNamespace[k]] && handlers[isNamespace[k]](); 2023 | } 2024 | } else if (element[addEvent]) { 2025 | evt = document.createEvent(isNative ? "HTMLEvents" : "UIEvents"); 2026 | evt[isNative ? 'initEvent' : 'initUIEvent'](type, true, true, context, 1); 2027 | element.dispatchEvent(evt); 2028 | } else if (element[attachEvent]) { 2029 | isNative ? element.fireEvent('on' + type, document.createEventObject()) : element['_on' + type]++; 2030 | } else { 2031 | for (k in handlers) { 2032 | handlers.hasOwnProperty(k) && handlers[k](); 2033 | } 2034 | } 2035 | } 2036 | return element; 2037 | } 2038 | 2039 | function clone(element, from, type) { 2040 | var events = retrieveEvents(from), obj, k; 2041 | obj = type ? events[type] : events; 2042 | for (k in obj) { 2043 | obj.hasOwnProperty(k) && (type ? add : clone)(element, type || from, type ? obj[k] : k); 2044 | } 2045 | return element; 2046 | } 2047 | 2048 | function fixEvent(e) { 2049 | var result = {}; 2050 | if (!e) { 2051 | return result; 2052 | } 2053 | var type = e.type, target = e.target || e.srcElement; 2054 | result.preventDefault = fixEvent.preventDefault(e); 2055 | result.stopPropagation = fixEvent.stopPropagation(e); 2056 | result.target = target && target.nodeType == 3 ? target.parentNode : target; 2057 | if (type.indexOf('key') != -1) { 2058 | result.keyCode = e.which || e.keyCode; 2059 | } else if ((/click|mouse|menu/i).test(type)) { 2060 | result.rightClick = e.which == 3 || e.button == 2; 2061 | result.pos = { x: 0, y: 0 }; 2062 | if (e.pageX || e.pageY) { 2063 | result.clientX = e.pageX; 2064 | result.clientY = e.pageY; 2065 | } else if (e.clientX || e.clientY) { 2066 | result.clientX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 2067 | result.clientY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; 2068 | } 2069 | overOut.test(type) && (result.relatedTarget = e.relatedTarget || e[(type == 'mouseover' ? 'from' : 'to') + 'Element']); 2070 | } 2071 | for (var k in e) { 2072 | if (!(k in result)) { 2073 | result[k] = e[k]; 2074 | } 2075 | } 2076 | return result; 2077 | } 2078 | 2079 | fixEvent.preventDefault = function (e) { 2080 | return function () { 2081 | if (e.preventDefault) { 2082 | e.preventDefault(); 2083 | } 2084 | else { 2085 | e.returnValue = false; 2086 | } 2087 | }; 2088 | }; 2089 | fixEvent.stopPropagation = function (e) { 2090 | return function () { 2091 | if (e.stopPropagation) { 2092 | e.stopPropagation(); 2093 | } else { 2094 | e.cancelBubble = true; 2095 | } 2096 | }; 2097 | }; 2098 | 2099 | var nativeEvents = 'click,dblclick,mouseup,mousedown,contextmenu,' + //mouse buttons 2100 | 'mousewheel,DOMMouseScroll,' + //mouse wheel 2101 | 'mouseover,mouseout,mousemove,selectstart,selectend,' + //mouse movement 2102 | 'keydown,keypress,keyup,' + //keyboard 2103 | 'orientationchange,' + // mobile 2104 | 'touchstart,touchmove,touchend,touchcancel,' + // touch 2105 | 'gesturestart,gesturechange,gestureend,' + // gesture 2106 | 'focus,blur,change,reset,select,submit,' + //form elements 2107 | 'load,unload,beforeunload,resize,move,DOMContentLoaded,readystatechange,' + //window 2108 | 'error,abort,scroll'.split(','); //misc 2109 | 2110 | function check(event) { 2111 | var related = event.relatedTarget; 2112 | if (!related) { 2113 | return related == null; 2114 | } 2115 | return (related != this && related.prefix != 'xul' && !/document/.test(this.toString()) && !isDescendant(this, related)); 2116 | } 2117 | 2118 | var customEvents = { 2119 | mouseenter: { base: 'mouseover', condition: check }, 2120 | mouseleave: { base: 'mouseout', condition: check }, 2121 | mousewheel: { base: /Firefox/.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel' } 2122 | }; 2123 | 2124 | var bean = { add: add, remove: remove, clone: clone, fire: fire }; 2125 | 2126 | var clean = function (el) { 2127 | var uid = remove(el).__uid; 2128 | if (uid) { 2129 | delete collected[uid]; 2130 | delete registry[uid]; 2131 | } 2132 | }; 2133 | 2134 | if (context[attachEvent]) { 2135 | add(context, 'unload', function () { 2136 | for (var k in collected) { 2137 | collected.hasOwnProperty(k) && clean(collected[k]); 2138 | } 2139 | context.CollectGarbage && CollectGarbage(); 2140 | }); 2141 | } 2142 | 2143 | var oldBean = context.bean; 2144 | bean.noConflict = function () { 2145 | context.bean = oldBean; 2146 | return this; 2147 | }; 2148 | 2149 | (typeof module !== 'undefined' && module.exports) ? 2150 | (module.exports = bean) : 2151 | (context.bean = bean); 2152 | 2153 | }(this);!function () { 2154 | var b = bean.noConflict(), 2155 | integrate = function (method, type, method2) { 2156 | var _args = type ? [type] : []; 2157 | return function () { 2158 | for (var args, i = 0, l = this.elements.length; i < l; i++) { 2159 | args = [this.elements[i]].concat(_args, Array.prototype.slice.call(arguments, 0)); 2160 | args.length == 4 && args.push(MONEY); 2161 | b[method].apply(this, args); 2162 | } 2163 | return this; 2164 | }; 2165 | }; 2166 | 2167 | var add = integrate('add'), 2168 | remove = integrate('remove'), 2169 | fire = integrate('fire'); 2170 | 2171 | var methods = { 2172 | 2173 | on: add, 2174 | addListener: add, 2175 | bind: add, 2176 | listen: add, 2177 | delegate: add, 2178 | 2179 | unbind: remove, 2180 | unlisten: remove, 2181 | removeListener: remove, 2182 | undelegate: remove, 2183 | 2184 | emit: fire, 2185 | trigger: fire, 2186 | 2187 | cloneEvents: integrate('clone'), 2188 | 2189 | hover: function (enter, leave) { 2190 | for (var i = 0, l = this.elements.length; i < l; i++) { 2191 | b.add.call(this, this.elements[i], 'mouseenter', enter); 2192 | b.add.call(this, this.elements[i], 'mouseleave', leave); 2193 | } 2194 | return this; 2195 | } 2196 | }; 2197 | 2198 | var shortcuts = [ 2199 | 'blur', 'change', 'click', 'dbltclick', 'error', 'focus', 'focusin', 2200 | 'focusout', 'keydown', 'keypress', 'keyup', 'load', 'mousedown', 2201 | 'mouseenter', 'mouseleave', 'mouseout', 'mouseover', 'mouseup', 2202 | 'resize', 'scroll', 'select', 'submit', 'unload' 2203 | ]; 2204 | 2205 | for (var i = shortcuts.length; i--;) { 2206 | var shortcut = shortcuts[i]; 2207 | methods[shortcut] = integrate('add', shortcut); 2208 | } 2209 | 2210 | MONEY.ender(methods, true); 2211 | }(); 2212 | /*! 2213 | * Boom. Ajax! Ever heard of it!? 2214 | * copyright 2011 @dedfat 2215 | * https://github.com/ded/reqwest 2216 | * license MIT 2217 | */ 2218 | !function (context) { 2219 | var twoHundo = /^20\dMONEY/, 2220 | xhr = ('XMLHttpRequest' in window) ? 2221 | function () { 2222 | return new XMLHttpRequest(); 2223 | } : 2224 | function () { 2225 | return new ActiveXObject('Microsoft.XMLHTTP'); 2226 | }; 2227 | 2228 | function readyState(o, success, error) { 2229 | return function () { 2230 | if (o && o.readyState == 4) { 2231 | if (twoHundo.test(o.status)) { 2232 | success(o); 2233 | } else { 2234 | error(o); 2235 | } 2236 | } 2237 | }; 2238 | } 2239 | 2240 | function setHeaders(http, options) { 2241 | var headers = options.headers; 2242 | if (headers && options.data) { 2243 | for (var h in headers) { 2244 | http.setRequestHeader(h, headers[h], false); 2245 | } 2246 | } 2247 | } 2248 | 2249 | function getRequest(o, fn, err) { 2250 | var http = xhr(); 2251 | http.open(o.method || 'GET', typeof o == 'string' ? o : o.url, true); 2252 | setHeaders(http, o); 2253 | http.onreadystatechange = readyState(http, fn, err); 2254 | o.before && o.before(http); 2255 | http.send(o.data || null); 2256 | return http; 2257 | } 2258 | 2259 | function Reqwest(o, fn) { 2260 | this.o = o; 2261 | this.fn = fn; 2262 | init.apply(this, arguments); 2263 | } 2264 | 2265 | function setType(url) { 2266 | if (/\.jsonMONEY/.test(url)) { 2267 | return 'json'; 2268 | } 2269 | if (/\.jsMONEY/.test(url)) { 2270 | return 'js'; 2271 | } 2272 | if (/\.html?MONEY/.test(url)) { 2273 | return 'html'; 2274 | } 2275 | if (/\.xmlMONEY/.test(url)) { 2276 | return 'xml'; 2277 | } 2278 | return 'js'; 2279 | } 2280 | 2281 | function init(o, fn) { 2282 | this.url = typeof o == 'string' ? o : o.url; 2283 | this.timeout = null; 2284 | var type = o.type || setType(this.url), self = this; 2285 | fn = fn || function () {}; 2286 | 2287 | if (o.timeout) { 2288 | this.timeout = setTimeout(function () { 2289 | self.abort(); 2290 | error(); 2291 | }, o.timeout); 2292 | } 2293 | 2294 | function complete(resp) { 2295 | o.complete && o.complete(resp); 2296 | } 2297 | 2298 | function success(resp) { 2299 | o.timeout && clearTimeout(self.timeout) && (self.timeout = null); 2300 | var r = resp.responseText, 2301 | val = /jsonMONEY/i.test(type) ? JSON.parse(r) : r; 2302 | /^jsMONEY/i.test(type) && eval(r); 2303 | fn(o); 2304 | o.success && o.success(val); 2305 | complete(val); 2306 | } 2307 | 2308 | function error(resp) { 2309 | o.error && o.error(resp); 2310 | complete(resp); 2311 | } 2312 | 2313 | this.request = getRequest(o, success, error); 2314 | } 2315 | 2316 | Reqwest.prototype = { 2317 | abort: function () { 2318 | this.request.abort(); 2319 | }, 2320 | 2321 | retry: function () { 2322 | init.call(this, this.o, this.fn); 2323 | } 2324 | }; 2325 | 2326 | function reqwest(o, fn) { 2327 | return new Reqwest(o, fn); 2328 | } 2329 | 2330 | var old = context.reqwest; 2331 | reqwest.noConflict = function () { 2332 | context.reqwest = old; 2333 | return this; 2334 | }; 2335 | context.reqwest = reqwest; 2336 | 2337 | }(this);MONEY.ender({ 2338 | ajax: reqwest.noConflict() 2339 | }); 2340 | /*! 2341 | * emile.js (c) 2009 - 2011 Thomas Fuchs 2342 | * Licensed under the terms of the MIT license. 2343 | */ 2344 | !function (context) { 2345 | var parseEl = document.createElement('div'), 2346 | prefixes = ["webkit", "Moz", "O"], 2347 | j = 3, 2348 | prefix, 2349 | _prefix, 2350 | d = /\d+MONEY/, 2351 | animationProperties = {}, 2352 | baseProps = 'backgroundColor borderBottomColor borderLeftColor ' + 2353 | 'borderRightColor borderTopColor color fontWeight lineHeight ' + 2354 | 'opacity outlineColor zIndex', 2355 | pixelProps = 'top bottom left right ' + 2356 | 'borderWidth borderBottomWidth borderLeftWidth borderRightWidth borderTopWidth ' + 2357 | 'borderSpacing borderRadius ' + 2358 | 'marginBottom marginLeft marginRight marginTop ' + 2359 | 'width height ' + 2360 | 'maxHeight maxWidth minHeight minWidth ' + 2361 | 'paddingBottom paddingLeft paddingRight paddingTop ' + 2362 | 'fontSize wordSpacing textIndent letterSpacing ' + 2363 | 'outlineWidth outlineOffset', 2364 | 2365 | props = (baseProps + ' ' + pixelProps).split(' '); 2366 | 2367 | while (j--) { 2368 | _prefix = prefixes[j]; 2369 | parseEl.style.cssText = "-" + _prefix.toLowerCase() + "-transition-property:opacity;"; 2370 | if (typeof parseEl.style[_prefix + "TransitionProperty"] != "undefined") { 2371 | prefix = _prefix; 2372 | } 2373 | } 2374 | var transitionEnd = /^w/.test(prefix) ? 'webkitTransitionEnd' : 'transitionend'; 2375 | for (var p = pixelProps.split(' '), i = p.length; i--;) { 2376 | animationProperties[p[i]] = 1; 2377 | } 2378 | 2379 | function map(o, fn, scope) { 2380 | var a = [], i; 2381 | for (i in o) { 2382 | a.push(fn.call(scope, o[i], i, o)); 2383 | } 2384 | return a; 2385 | } 2386 | 2387 | function camelize(s) { 2388 | return s.replace(/-(.)/g, function (m, m1) { 2389 | return m1.toUpperCase(); 2390 | }); 2391 | } 2392 | 2393 | function serialize(o, modify) { 2394 | return map(o, function (v, k) { 2395 | var kv = modify ? modify(k, v) : [k, v]; 2396 | return kv[0] + ':' + kv[1] + ';'; 2397 | }).join(''); 2398 | } 2399 | 2400 | function camelToDash(s) { 2401 | if (s.toUpperCase() === s) { 2402 | return s; 2403 | } 2404 | return s.replace(/([a-zA-Z0-9])([A-Z])/g, function (m, m1, m2) { 2405 | return (m1 + "-" + m2); 2406 | }).toLowerCase(); 2407 | } 2408 | 2409 | function interpolate(source, target, pos) { 2410 | return (source + (target - source) * pos).toFixed(3); 2411 | } 2412 | 2413 | function s(str, p, c) { 2414 | return str.substr(p, c || 1); 2415 | } 2416 | 2417 | function color(source, target, pos) { 2418 | var i = 2, j, c, tmp, v = [], r = []; 2419 | while ((j = 3) && (c = arguments[i - 1]) && i--) { 2420 | if (s(c, 0) == 'r') { 2421 | c = c.match(/\d+/g); 2422 | while (j--) { 2423 | v.push(~~c[j]); 2424 | } 2425 | } else { 2426 | if (c.length == 4) { 2427 | c = '#' + s(c, 1) + s(c, 1) + s(c, 2) + s(c, 2) + s(c, 3) + s(c, 3); 2428 | } 2429 | while (j--) { 2430 | v.push(parseInt(s(c, 1 + j * 2, 2), 16)); 2431 | } 2432 | } 2433 | } 2434 | while (j--) { 2435 | tmp = ~~(v[j + 3] + (v[j] - v[j + 3]) * pos); 2436 | r.push(tmp < 0 ? 0 : tmp > 255 ? 255 : tmp); 2437 | } 2438 | return 'rgb(' + r.join(',') + ')'; 2439 | } 2440 | 2441 | function parse(prop) { 2442 | var p = parseFloat(prop), q = prop ? prop.replace(/^[\-\d\.]+/, '') : prop; 2443 | return isNaN(p) ? 2444 | { v: q, 2445 | f: color, 2446 | u: '' 2447 | } : 2448 | { 2449 | v: p, 2450 | f: interpolate, 2451 | u: q 2452 | }; 2453 | } 2454 | 2455 | function normalize(style) { 2456 | var css, rules = {}, i = props.length, v; 2457 | parseEl.innerHTML = '
'; 2458 | css = parseEl.childNodes[0].style; 2459 | while (i--) { 2460 | (v = css[props[i]]) && (rules[props[i]] = parse(v)); 2461 | } 2462 | return rules; 2463 | } 2464 | 2465 | function _emile(el, style, opts, after) { 2466 | opts = opts || {}; 2467 | var target = normalize(style), 2468 | comp = el.currentStyle ? el.currentStyle : getComputedStyle(el, null), 2469 | current = {}, start = +new Date(), prop, 2470 | dur = opts.duration || 200, finish = start + dur, interval, 2471 | easing = opts.easing || function (pos) { 2472 | return (-Math.cos(pos * Math.PI) / 2) + 0.5; 2473 | }; 2474 | for (prop in target) { 2475 | current[prop] = parse(comp[prop]); 2476 | } 2477 | interval = setInterval(function () { 2478 | var time = +new Date(), p, pos = time > finish ? 1 : (time - start) / dur; 2479 | for (p in target) { 2480 | el.style[p] = target[p].f(current[p].v, target[p].v, easing(pos)) + target[p].u; 2481 | } 2482 | if (time > finish) { 2483 | clearInterval(interval); 2484 | opts.after && opts.after(); 2485 | after && setTimeout(after, 1); 2486 | } 2487 | }, 10); 2488 | } 2489 | 2490 | function nativeAnim(el, o, opts) { 2491 | var props = [], 2492 | styles = [], 2493 | duration = opts.duration || 1000, 2494 | easing = opts.easing || 'ease-out'; 2495 | duration = duration + 'ms'; 2496 | opts.after && el.addEventListener(transitionEnd, function f() { 2497 | opts.after(); 2498 | el.removeEventListener(transitionEnd, f, true); 2499 | }, true); 2500 | 2501 | setTimeout(function () { 2502 | var k; 2503 | for (k in o) { 2504 | o.hasOwnProperty(k) && props.push(camelToDash(k) + ' ' + duration + ' ' + easing); 2505 | } 2506 | props = props.join(','); 2507 | el.style[prefix + 'Transition'] = props; 2508 | for (k in o) { 2509 | var v = (camelize(k) in animationProperties) && d.test(o[k]) ? o[k] + 'px' : o[k]; 2510 | o.hasOwnProperty(k) && (el.style[camelize(k)] = v); 2511 | } 2512 | }, 10); 2513 | 2514 | } 2515 | 2516 | function clone(o) { 2517 | var r = {}; 2518 | for (var k in o) { 2519 | r[k] = o[k]; 2520 | (k == 'after') && delete o[k]; 2521 | } 2522 | return r; 2523 | } 2524 | 2525 | function emile(el, o) { 2526 | el = typeof el == 'string' ? document.getElementById(el) : el; 2527 | o = clone(o); 2528 | var opts = { 2529 | duration: o.duration, 2530 | easing: o.easing, 2531 | after: o.after 2532 | }; 2533 | delete o.duration; 2534 | delete o.easing; 2535 | delete o.after; 2536 | if (prefix && (typeof opts.easing !== 'function')) { 2537 | return nativeAnim(el, o, opts); 2538 | } 2539 | var serial = serialize(o, function (k, v) { 2540 | k = camelToDash(k); 2541 | return (camelize(k) in animationProperties) && d.test(v) ? 2542 | [k, v + 'px'] : 2543 | [k, v]; 2544 | }); 2545 | _emile(el, serial, opts); 2546 | } 2547 | 2548 | var old = context.emile; 2549 | emile.noConflict = function () { 2550 | context.emile = old; 2551 | return this; 2552 | }; 2553 | context.emile = emile; 2554 | 2555 | }(this); 2556 | !function () { 2557 | var e = emile.noConflict(); 2558 | var getOptions = function (duration, callback) { 2559 | var d = typeof duration == 'number' ? duration : 1000; 2560 | var cb = typeof callback == 'function' ? callback : typeof duration == 'function' ? duration : function(){}; 2561 | return [d, cb] 2562 | }; 2563 | 2564 | function fade(duration, callback, to) { 2565 | var opts = getOptions(duration, callback); 2566 | for (var i = 0, l = this.length; i < l; i++) { 2567 | this[i].style.opacity = to ? 0 : 1; 2568 | this[i].style.filter = 'alpha(opacity=' + (to ? 0 : 1 ) * 100 + ')'; 2569 | this[i].style.display = ''; 2570 | } 2571 | return this.animate({ 2572 | opacity: to, 2573 | duration: opts[0], 2574 | after: opts[1] 2575 | }); 2576 | } 2577 | 2578 | MONEY.ender({ 2579 | animate: function (o) { 2580 | var self = this; 2581 | // quick! look! over there! someone is kicking a puppy! 2582 | setTimeout(function () { 2583 | for (var i = 0, l = self.length; i < l; i++) { 2584 | e(self[i], o); 2585 | } 2586 | }, 0); 2587 | return this; 2588 | }, 2589 | 2590 | fadeIn: function (duration, callback) { 2591 | return fade.call(this, duration, callback, 1); 2592 | }, 2593 | 2594 | fadeOut: function (duration, callback) { 2595 | return fade.call(this, duration, callback, 0); 2596 | } 2597 | }, true); 2598 | }(); -------------------------------------------------------------------------------- /app/public/js/cabin.js: -------------------------------------------------------------------------------- 1 | // github/stenson/cabin 2 | 3 | var cabin = (function(){ 4 | var doc = document 5 | , toA = function(args) { 6 | return Array.prototype.slice.apply(args); 7 | } 8 | , getClasses = function(str) { 9 | var matches = []; 10 | str.replace(classR,function(_,c){ 11 | matches.push(c); 12 | }); 13 | return matches; 14 | } 15 | , white = /^\s+$/ 16 | , elR = /^[^\.#]+/ 17 | , idR = /#([^\.$]+)/ 18 | , classR = /\.([^\.$#]+)/g; 19 | 20 | // the building function 21 | var o = function(selector) { 22 | // whitespace check 23 | if(white.test(selector)) 24 | return doc.createTextNode(selector); 25 | // ok, now proceed as normal 26 | var kids = toA(arguments).slice(1) 27 | , id = idR.exec(selector) 28 | , classes = getClasses(selector) 29 | , el = doc.createElement(elR.exec(selector)); 30 | 31 | if(id) 32 | el.id = id[1]; 33 | if(classes.length) 34 | el.className = classes.join(" "); 35 | if(kids[0].nodeType) { 36 | for(var i = 0, l = kids.length; i < l; i++) { 37 | el.appendChild(kids[i]); 38 | } 39 | } 40 | else 41 | el.appendChild(doc.createTextNode(kids[0])); 42 | return el; 43 | }; 44 | 45 | o.list = function(entries) { 46 | var fragment = doc.createDocumentFragment(); 47 | for(var i = 0, l = entries.length; i < l; i++) { 48 | fragment.appendChild(entries[i]); 49 | } 50 | return fragment; 51 | }; 52 | 53 | // the interface returns a function 54 | var cabinFn = function(fn) { 55 | // the curried function 56 | return function() { 57 | return fn.apply(null,[o].concat(toA(arguments))); 58 | }; 59 | }; 60 | // for easy, non-currying access 61 | cabinFn.o = o; 62 | return cabinFn; 63 | })(); -------------------------------------------------------------------------------- /app/public/js/hijs.js: -------------------------------------------------------------------------------- 1 | var doHijs = (function (hijs) { 2 | // 3 | // hijs - JavaScript Syntax Highlighter 4 | // 5 | // Copyright (c) 2010 Alexis Sellier 6 | // 7 | 8 | // All elements which match this will be syntax highlighted. 9 | var selector = hijs || 'code'; 10 | 11 | var keywords = ('var function if else for while break switch case do new null in with void ' 12 | +'continue delete return this true false throw catch typeof with instanceof').split(' '), 13 | special = ('eval window document undefined NaN Infinity parseInt parseFloat ' 14 | +'encodeURI decodeURI encodeURIComponent decodeURIComponent').split(' '); 15 | 16 | // Syntax definition 17 | // The key becomes the class name of the 18 | // around the matched block of code. 19 | var syntax = [ 20 | ['comment', /(\/\*(?:[^*\n]|\*+[^\/*])*\*+\/)/g], 21 | ['comment', /(\/\/[^\n]*)/g], 22 | ['string' , /("(?:(?!")[^\\\n]|\\.)*"|'(?:(?!')[^\\\n]|\\.)*')/g], 23 | ['regexp' , /(\/.+\/[mgi]*)(?!\s*\w)/g], 24 | ['class' , /\b([A-Z][a-zA-Z]+)\b/g], 25 | ['number' , /\b([0-9]+(?:\.[0-9]+)?)\b/g], 26 | ['keyword', new(RegExp)('\\b(' + keywords.join('|') + ')\\b', 'g')], 27 | ['special', new(RegExp)('\\b(' + special.join('|') + ')\\b', 'g')] 28 | ]; 29 | var nodes, table = {}; 30 | 31 | if (/^[a-z]+$/.test(selector)) { 32 | nodes = document.getElementsByTagName(selector); 33 | } else if (/^\.[\w-]+$/.test(selector)) { 34 | nodes = document.getElementsByClassName(selector.slice(1)); 35 | } else if (document.querySelectorAll) { 36 | nodes = document.querySelectorAll(selector); 37 | } else { 38 | nodes = []; 39 | } 40 | 41 | for (var i = 0, children; i < nodes.length; i++) { 42 | children = nodes[i].childNodes; 43 | 44 | for (var j = 0, str; j < children.length; j++) { 45 | code = children[j]; 46 | 47 | if (code.length >= 0) { // It's a text node 48 | // Don't highlight command-line snippets 49 | if (! /^\$\s/.test(code.nodeValue.trim())) { 50 | syntax.forEach(function (s) { 51 | var k = s[0], v = s[1]; 52 | code.nodeValue = code.nodeValue.replace(v, function (_, m) { 53 | return '\u00ab' + encode(k) + '\u00b7' 54 | + encode(m) + 55 | '\u00b7' + encode(k) + '\u00bb'; 56 | }); 57 | }); 58 | } 59 | } 60 | } 61 | } 62 | for (var i = 0; i < nodes.length; i++) { 63 | nodes[i].innerHTML = 64 | nodes[i].innerHTML.replace(/\u00ab(.+?)\u00b7(.+?)\u00b7\1\u00bb/g, function (_, name, value) { 65 | value = value.replace(/\u00ab[^\u00b7]+\u00b7/g, '').replace(/\u00b7[^\u00bb]+\u00bb/g, ''); 66 | return '' + escape(decode(value)) + ''; 67 | }); 68 | } 69 | 70 | function escape(str) { 71 | return str.replace(//g, '>'); 72 | } 73 | 74 | // Encode ASCII characters to, and from Braille 75 | function encode (str, encoded) { 76 | table[encoded = str.split('').map(function (s) { 77 | if (s.charCodeAt(0) > 127) { return s } 78 | return String.fromCharCode(s.charCodeAt(0) + 0x2800); 79 | }).join('')] = str; 80 | return encoded; 81 | } 82 | function decode (str) { 83 | if (str in table) { 84 | return table[str]; 85 | } else { 86 | return str.trim().split('').map(function (s) { 87 | if (s.charCodeAt(0) - 0x2800 > 127) { return s } 88 | return String.fromCharCode(s.charCodeAt(0) - 0x2800); 89 | }).join(''); 90 | } 91 | } 92 | 93 | })//(window.hijs); -------------------------------------------------------------------------------- /app/public/js/introspect.js: -------------------------------------------------------------------------------- 1 | // code for figuring out who owns what functions 2 | 3 | var introspect = (function(){ 4 | 5 | var annotated = { 6 | top: {}, // top-level functions 7 | selection: {} // functions on the returned selection 8 | }, 9 | codes = {}, 10 | funcs = {}, // final records, written by cull 11 | record = function(owner,func,name) { 12 | return { 13 | owner: owner, func: func, 14 | aliases: [], name: name 15 | } 16 | }, 17 | stubSelect = function(selector,root) { 18 | return (root || document).querySelectorAll(selector); 19 | }, 20 | dependencies = []; 21 | 22 | return { 23 | diff: function(owner) { 24 | // first the top-level 25 | for(var f in $) { 26 | if(!(f in annotated.top)) { 27 | annotated.top[f] = record(owner,$[f],f); 28 | } 29 | } 30 | // then the functions of a returned selection 31 | // (gone need a selector if we ain't got none) 32 | if(!$._select) { 33 | $._select = stubSelect; 34 | } 35 | var testEl = $("div"), 36 | selection = (testEl.__proto__.length > 0) ? testEl.__proto__ : testEl; 37 | for(var p in selection) { 38 | if(!(p in annotated.selection) && !isFinite(p)) { 39 | annotated.selection[p] = record(owner,selection[p],p); 40 | } 41 | } 42 | // if we added a stub, get it gone 43 | if($._select == stubSelect) { 44 | delete $._select; 45 | } 46 | }, 47 | addDependencies: function(owner,deps) { 48 | if(deps) dependencies.push([owner,deps.split(";")]); 49 | }, 50 | cull: function() { 51 | var ok = MONEY.map(annotated,function(hash,level){ 52 | var read = []; 53 | MONEY.each(hash,function(record,name){ 54 | for(var i = 0, l = read.length; i < l; i++) { 55 | if(read[i].func == record.func) { 56 | read[i].aliases.push(name); 57 | return false; 58 | } 59 | } 60 | read.push(record); 61 | }); 62 | return read; 63 | }); 64 | // save 'em 65 | funcs = { top: ok[0], selection: ok[1] }; 66 | }, 67 | alphabetize: function(list) { 68 | return list.sort(function(a,b){ 69 | return (a.name > b.name) ? 1 : -1; 70 | }); 71 | }, 72 | funcs: function() { 73 | return { 74 | top: introspect.alphabetize(funcs.top), 75 | selection: introspect.alphabetize(funcs.selection) 76 | }; 77 | }, 78 | codes: function() { 79 | var parsedCodes = []; 80 | return codes; 81 | }, 82 | dependencies: function() { 83 | return dependencies; 84 | } 85 | } 86 | 87 | })(); -------------------------------------------------------------------------------- /app/public/js/wallet-client.js: -------------------------------------------------------------------------------- 1 | // code for displaying stuff 2 | (function(){ 3 | 4 | var buildEntry = cabin(function(o,prefix,record){ 5 | var fullname = (record.aliases.length) ? 6 | zippedAka(record.name,record.aliases) : 7 | o("strong",record.name); 8 | 9 | return true, 10 | o("li", 11 | o("span.fn", 12 | o("em",prefix), 13 | o("strong",fullname) 14 | ), 15 | o("div.info", 16 | o("div.docs", 17 | o("span.owner",record.owner) 18 | ), 19 | o("pre", 20 | o("code",record.func||"") 21 | ) 22 | ) 23 | ); 24 | }); 25 | 26 | // hmm... this could be nicer... pretty fugly 27 | var zippedAka = cabin(function(o,name,aliases){ 28 | var rest = [o("em"," aka ")]; 29 | for(var i = 0, l = aliases.length; i < l; i++) { 30 | rest.push(o("text",aliases[i])); 31 | if(i+1 < l) rest.push(o("em"," || ")); 32 | } 33 | return o.apply(null,["strong",o("text",name)].concat(rest)); 34 | }); 35 | 36 | var buildNotice = cabin(function(o,text){ 37 | return o("li",o("span.notice",text)); 38 | }); 39 | 40 | function search(input,items,conditionFn) { 41 | var l = items.length; 42 | input.addEventListener(function(){ 43 | var search = input.value.toLowerCase(); 44 | // run through and hide what doesn't match 45 | for(var i = 0; i < l; i++) { 46 | var item = items[i]; 47 | item.el.style.display = (conditionFn(item)) ? "block" : "none"; 48 | } 49 | },false); 50 | } 51 | 52 | var byId = document.getElementById.bind(document) 53 | // some other helpful functions 54 | , hasClass = function(el,className) { 55 | return el[0].className.indexOf(className) >= 0; 56 | } 57 | , removeClass = function(el,className) { 58 | el[0].className = el[0].className.replace(className,""); 59 | } 60 | , toggleClass = function(el,cName) { 61 | hasClass(el,cName) ? removeClass(el,cName) : el.addClass(cName); 62 | }; 63 | 64 | // main function 65 | (function() { 66 | var functions = byId("functions") 67 | , funcs = introspect.funcs() 68 | , els = [] // the lis gone end up in the list 69 | , buildMap = function(_funcs,buildFn) { 70 | _funcs.forEach(function(fn){ 71 | var el = buildFn(fn); 72 | els.push(el); 73 | fn.el = el; 74 | }); 75 | }; 76 | 77 | // push the top-level functions 78 | els.push(buildNotice("top-level functions")); 79 | buildMap(funcs.top, MONEY.bind(buildEntry,null,"$.")); 80 | // push the selection-level functions 81 | els.push(buildNotice("functions on a returned selection")); 82 | buildMap(funcs.selection, MONEY.bind(buildEntry,null,'$("").')); 83 | // add the els to the dom tree 84 | functions.appendChild(cabin.o.list(els)); 85 | 86 | annotateDependencies(introspect.dependencies()); 87 | doHijs(); // syntax highlighting 88 | inlineDocumentation(); 89 | responsiveForms(); 90 | moduleAddition(); 91 | 92 | var searchables = funcs.top.concat(funcs.selection) 93 | , byName = MONEY("#namesearch") 94 | , byModule = MONEY("#modulesearch"); 95 | // by function name 96 | addLivesearch(byName,searchables,function(rec,str){ 97 | return (rec.name + rec.aliases.join("")).toLowerCase().indexOf(str) >= 0; 98 | },[byModule]); 99 | // by module owner name 100 | addLivesearch(byModule,searchables,function(rec,str){ 101 | return rec.owner.toLowerCase().indexOf(str) >= 0; 102 | },[byName]); 103 | })(); 104 | 105 | // functions for cleaning up main ondomready function 106 | 107 | function annotateDependencies(deps) { 108 | var ul = document.getElementById("modules"); 109 | for(var i = 0, l = deps.length; i < l; i++) { 110 | var e = deps[i] 111 | , depender = e[0] 112 | , on = e[1]; 113 | MONEY.each(on,function(o){ 114 | var $li = MONEY("#"+o).addClass("depended"); 115 | $li.append(cabin.o("p.depender","Depended on by "+depender)); 116 | modules.appendChild($li[0]); 117 | }); 118 | } 119 | } 120 | 121 | function inlineDocumentation() { 122 | // accordion stuff 123 | MONEY("span.fn").click(function(){ 124 | var src = MONEY(this); 125 | toggleClass(src.next("div.info"),"visible"); 126 | toggleClass(src,"open"); 127 | }); 128 | } 129 | 130 | function responsiveForms() { 131 | // nice input behavior 132 | MONEY("input") 133 | .focus(function(){ 134 | MONEY(this).addClass("typing"); 135 | if(this.value === this.defaultValue) { 136 | this.value = ""; 137 | } 138 | }) 139 | .blur(function(){ 140 | if(this.value === "") { 141 | this.value = this.defaultValue; 142 | this.className = ""; 143 | } 144 | }) 145 | } 146 | 147 | function addLivesearch(el,listing,comparison,toClear) { 148 | el.keyup(function(){ 149 | var search = this.value.toLowerCase(); 150 | MONEY.each(listing,function(func){ 151 | func.el.style.display = (comparison(func,search)) ? "block" : "none"; 152 | }); 153 | }); 154 | el.mousedown(function(){ 155 | MONEY.each(toClear,function(elm){ 156 | elm[0].value = ""; 157 | elm.trigger("keyup"); 158 | elm.trigger("blur"); 159 | }); 160 | }); 161 | } 162 | 163 | function moduleAddition() { 164 | // so you want to add a module? 165 | var moduleScreen = MONEY("#add-popup"); 166 | MONEY("#add-a-module").click(function(){ 167 | moduleScreen.css("visibility","visible"); 168 | }); 169 | // get rid of the popover if you click anywhere other than the main box 170 | moduleScreen.click(function(e){ 171 | var target = e.target || e.srcElement; 172 | if(target == this) { 173 | moduleScreen.css("visibility","hidden"); 174 | } 175 | }); 176 | // code for adding an arbitrary module 177 | var arbitrary = MONEY("#arbitrary")[0]; 178 | // capture the submit event, redirect as link 179 | MONEY("#add-form form").submit(function(e){ 180 | e.preventDefault(); 181 | var value = arbitrary.value; 182 | if(value) { 183 | window.location.href = "/add/"+value; 184 | } 185 | }); 186 | } 187 | 188 | })(); -------------------------------------------------------------------------------- /app/read.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"), 2 | path = require('path'), 3 | colors = require("colors"), 4 | exec = require("child_process").exec, 5 | ender = { 6 | get: require("ender/lib/ender.get"), 7 | file: require("ender/lib/ender.file"), 8 | util: require("ender/lib/ender.util") 9 | }, 10 | // borrowed from ender 11 | commonJSBridge = { head: '!function () { var exports = {}, module = { exports: exports }; ' 12 | , foot: ' $.ender(module.exports); }();' }, 13 | FILE = ender.file, // aliases for the processPackages function 14 | UTIL = ender.util // which is ripped from the ender CLI source 15 | 16 | function processPackages(_packages, options, callback) { 17 | var result = [], i = 0; 18 | FILE.constructDependencyTree(_packages, 'node_modules', function (tree) { 19 | FILE.flattenDependencyTree(tree, null, function (packages) { 20 | packages.forEach(function (name, j) { 21 | var packagePath = path.join('node_modules', name.replace(/\//g, '/node_modules/')) 22 | , location = path.join(packagePath, 'package.json'); 23 | path.exists(location, function (exists) { 24 | if (!exists) { 25 | console.log('dependency ' + name.red + ' is currently not installed... for details check: ' + '$ ender info'.yellow); 26 | if (packages.length == ++i) { 27 | callback && callback(result); 28 | } 29 | return; 30 | } 31 | fs.readFile(location, 'utf-8', function (err, data) { 32 | if (err) return console.log('something whent wrong trying to read ' + location); 33 | var packageJSON = JSON.parse(data) 34 | , source; 35 | //CONSTRUCT MAIN SOURCE FILE 36 | if (!packageJSON.main) { 37 | packageJSON.main = []; 38 | } else if (typeof packageJSON.main == 'string') { 39 | packageJSON.main = [ packageJSON.main ]; 40 | } 41 | FILE.constructSource(packagePath, packageJSON.main, function (source) { 42 | //CONSTRUCT BRIDGE 43 | FILE.constructBridge(packagePath, packageJSON.ender, function (content) { 44 | if (source && name !== 'ender-js' && !options.noop) { 45 | source = [ 46 | commonJSBridge.head 47 | , source.replace(/\n/g, '\n ') 48 | , 'provide("' + name.replace(/.*(?=\/)\//, '') + '", module.exports);' 49 | ]; 50 | if (packageJSON.ender) source.push(content.replace(/\n/g, '\n ')); 51 | else source.push('$.ender(module.exports);') 52 | source = source.join('\n\n ') + '\n\n}();'; 53 | } 54 | //result[j] = source; 55 | result[j] = [name,source,packageJSON]; 56 | if (packages.length == ++i) { 57 | callback && callback(result); 58 | } 59 | }); 60 | }); 61 | }); 62 | }); 63 | }); 64 | }); 65 | }); 66 | } 67 | 68 | module.exports = { 69 | read: function(callback) { 70 | ender.get.buildHistory(null,function(packages){ 71 | var packs = packages.split(" ").slice(2); 72 | if(packs[0] == "") { 73 | packs = []; 74 | } 75 | if(packs[0] != "ender-js") { 76 | packs.unshift("ender-js"); 77 | } 78 | processPackages(packs,false,function(scripts){ 79 | callback(scripts); 80 | }); 81 | }); 82 | }, 83 | checkEnderExistence: function(callback) { 84 | path.exists('./ender.js',callback); 85 | }, 86 | getSize: function(callback) { 87 | ender.file.enderSize(null,function(size){ 88 | callback(((Math.round((size/1024) * 10) / 10))); 89 | }); 90 | } 91 | } -------------------------------------------------------------------------------- /app/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stenson/wallet/dc028304a88b071d4cabc4f7c38510cdb3805bd3/app/screenshot.png -------------------------------------------------------------------------------- /app/views/index.mustache: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | Your Modules 5 |
6 |
7 |
    8 | {{#modules}} 9 |
  • 10 |
    11 | {{ name }} 12 | {{ version }} 13 |

    {{ description }}

    14 | docs & source 15 | Delete this module 16 | 17 | 22 |
    23 |
  • 24 | {{/modules}} 25 |
26 | 30 |
31 | Add a module to your ender 32 |
33 |
34 |
35 |
36 | 40 |

41 | Size: {{ size }}kb 42 |

43 |
44 | Your Functions 45 | {{ directory }} 46 |
47 |
48 |
    49 |
50 |
51 |
52 | 53 |
54 | 69 |
-------------------------------------------------------------------------------- /app/views/layout.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | What's in yer $ 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | {{{yield}}} 14 |
15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/wallet-app.js: -------------------------------------------------------------------------------- 1 | var express = require("express"), 2 | colors = require("colors"), 3 | enderReads = require("./read"), 4 | exec = require("child_process").exec, 5 | // the default port for wallet 6 | port = 8083, 7 | noPackages = false; // are there no packages installed? 8 | 9 | // run an ender command via the ender cli 10 | function processCommand(verb,req,res) { 11 | var module = req.params.module; 12 | if(module) { 13 | exec("ender "+verb+" "+module,function(err,data,stderr){ 14 | if(err) console.log("ERROR".red,err); 15 | res.redirect("/"); 16 | }); 17 | } 18 | else { 19 | res.send("whoa, fail. excuse: alpha!"); 20 | } 21 | } 22 | 23 | function pluck(arr,key) { 24 | return arr.map(function(t){ return t[key] }); 25 | } 26 | 27 | function without(arr,without) { 28 | return arr.filter(function(x){ 29 | return !without.some(function(y){ 30 | return x == y; 31 | }); 32 | }); 33 | } 34 | 35 | function keys(o) { 36 | var ks = []; 37 | for(var k in o) { 38 | if(o.hasOwnProperty(k)) ks.push(k); 39 | } 40 | return ks; 41 | } 42 | 43 | function serveWallet(req,res) { 44 | enderReads.read(function(scripts){ 45 | var enderPos = 0, 46 | cache = scripts.map(function(script,i){ 47 | var info = script[2]; 48 | info.source = script[1]; 49 | info.deps = keys(info.dependencies).join(";"); 50 | if(info.name == "ender-js") enderPos = i; 51 | return info; 52 | }); 53 | // update global state, little bit hacky 54 | noPackages = cache.length <= 1; 55 | // need to make sure ender-js shows up first 56 | if(enderPos !== 0) { 57 | var enderjs = cache.splice(enderPos,1); 58 | cache.unshift(enderjs[0]); 59 | } 60 | // get the size too, nice to know 61 | enderReads.getSize(function(size){ 62 | res.render("index",{ 63 | locals: { 64 | modules: cache, 65 | directory: process.cwd(), 66 | size: size 67 | } 68 | }); 69 | }); 70 | }); 71 | } 72 | 73 | function run(_port) { 74 | var p = _port || port, 75 | app = express.createServer(), 76 | packages = []; 77 | // stache enabling 78 | app.set('view engine', 'mustache'); 79 | app.set("views", __dirname + '/views'); 80 | app.register(".mustache", require("stache")); 81 | // public folder enabling 82 | app.use(express.static(__dirname + '/public')); 83 | // the only visible route, other than static stuff and the ajax stuff 84 | app.get("/",serveWallet); 85 | // ajax routes for ender commands 86 | // not appropriate http verbs but, like... whatever 87 | app.get("/add/:module",function(req,res){ 88 | var verb = (noPackages) ? "build" : "add"; 89 | processCommand(verb,req,res); 90 | }); 91 | app.get("/remove/:module",processCommand.bind(null,"remove")); 92 | // set it loose if there's any ender around 93 | enderReads.checkEnderExistence(function(exists){ 94 | if(exists) { 95 | app.listen(p); 96 | var greeting = "Howdy! See what's in yer $ at localhost:"+p+""; 97 | console.log(greeting.underline.green); 98 | } 99 | else { 100 | console.log("there's no ender here. gotta have a $ to look inside.".red); 101 | } 102 | }); 103 | } 104 | 105 | module.exports = { 106 | exec: function(cmd) { 107 | run(); 108 | } 109 | }; -------------------------------------------------------------------------------- /bin/ender-wallet: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require("../app/wallet-app").exec(process.argv); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ender-wallet", 3 | "description": "see what's inside your ender $", 4 | "version": "0.1.0", 5 | "authors": ["Rob Stenson <@blickwickle>"], 6 | "keywords": ["ender", "api", "visual", "app"], 7 | "main": "./wallet.js", 8 | "homepage": "https://github.com/stenson/wallet", 9 | "engines": { 10 | "node": ">= 0.4.1" 11 | }, 12 | "dependencies": { 13 | "ender": ">= 0.3.5", 14 | "colors": ">= 0.3.0", 15 | "express": ">= 0.3.0", 16 | "stache": ">= 0.0.2" 17 | }, 18 | "bin": { 19 | "ender-wallet": "./bin/ender-wallet" 20 | } 21 | } -------------------------------------------------------------------------------- /test/cleanup: -------------------------------------------------------------------------------- 1 | rm ender.js 2 | rm ender.min.js 3 | rm -r node_modules/ -------------------------------------------------------------------------------- /test/test: -------------------------------------------------------------------------------- 1 | ender build jeesh 2 | ./../bin/ender-wallet -------------------------------------------------------------------------------- /wallet.js: -------------------------------------------------------------------------------- 1 | module.exports = require("./app/wallet-app"); --------------------------------------------------------------------------------