UNPKG

67.9 kBJavaScriptView Raw
1
2/*
3 Copyright 2014+ Aliaksandr Litskevich, github.com/alitskevich
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 */
17
18
19/*
20
21AXOID. A general-purpose micro-framework that just organizes code as a composition of Entities.
22 */
23
24(function() {
25 "use strict";
26
27 /*
28
29 Calls `fn` in next loop tick.
30
31 @param [int] ms delay in millisec. Optional. Default is 5ms.
32 @param [Object] ctx function context object. Optional. Default is null.
33 @param [Function] fn function to call. Required.
34
35 @example
36 Function.nextTick(100, @, -> doing())
37 */
38 var __hasProp = {}.hasOwnProperty,
39 __slice = [].slice;
40
41 Function.nextTick = function(ms, ctx, fn) {
42 if (arguments.length === 1) {
43 (fn = ms) && (ms = null) && (ctx = null);
44 }
45 if (arguments.length === 2) {
46 (fn = ctx) && (ctx = ms) && (ms = null);
47 }
48 return setTimeout((function() {
49 return fn.call(ctx);
50 }), ms || 5);
51 };
52
53
54 /*
55
56 Manages execution of sequence of functions allowing async and parallel flow.
57
58 @param [Object] ctx function context object. Optional. Default is null.
59 @param [Function] factory function to return operations list. Required.
60
61 @example
62 Function.perform(@, (flow)-> [
63 ->
64 r= doSome1()
65 *next op
66 flow.next(null, r)
67
68 (err, r)->
69 *async with callback
70 doSomeAsync(r, flow.next)
71
72 (err, data)->
73 *parallel flow
74 doSome1(d, flow.cb()) for d in data
75 * next op
76 flow.next(null, 1)
77
78 (err, p1, results...)->
79 *done
80
81 ]
82 */
83
84 Function.perform = function(ctx, factory) {
85 var flow, locked, newCb, results, tick;
86 locked = 1;
87 results = [null, void 0];
88 tick = function() {
89 var ex, op, _args;
90 if (!--locked && (op = flow.operations.shift())) {
91 locked = 1;
92 _args = [].concat(results);
93 results = [null, void 0];
94 try {
95 return op.apply(flow.context, _args);
96 } catch (_error) {
97 ex = _error;
98 return Object.error(('perform: ' + op).slice(0, 151).replace(/\s+/g, ' ')).addDetails(ex).log();
99 }
100 }
101 };
102 newCb = function(pos) {
103 return function(err, v) {
104 if (!(results[pos] === void 0)) {
105 return;
106 }
107 if (err) {
108 results[0] = Object.error(err).log();
109 }
110 results[pos] = v;
111 return tick();
112 };
113 };
114 flow = {
115 context: ctx,
116 _error: new Error(),
117 next: newCb(1),
118 wait: function() {
119 var pos;
120 pos = results.length;
121 results[pos] = void 0;
122 locked += 1;
123 return newCb(pos);
124 }
125 };
126 flow.operations = factory.call(ctx, flow);
127 return tick();
128 };
129
130 Function.create = function(code, params) {
131 if (code) {
132 return Object.parse("function (" + (params ? params.join(', ') : '') + "){ return " + code + "; }");
133 } else {
134 return null;
135 }
136 };
137
138 Function.iterate = function(fn, obj, ctx, opts) {
139 var i, ln, n, x, _i, _len;
140 if (obj) {
141 ln = obj.length;
142 if (ln === +ln) {
143 for (i = _i = 0, _len = obj.length; _i < _len; i = ++_i) {
144 x = obj[i];
145 fn.call(ctx, x, i, opts);
146 }
147 } else {
148 for (n in obj) {
149 if (!__hasProp.call(obj, n)) continue;
150 x = obj[n];
151 fn.call(ctx, x, n, opts);
152 }
153 }
154 }
155 return ctx;
156 };
157
158
159 /*
160 Objects.
161 */
162
163 Object.update = function(obj, extra) {
164 var n;
165 if (obj && extra) {
166 for (n in extra) {
167 if (!__hasProp.call(extra, n)) continue;
168 obj[n] = extra[n];
169 }
170 }
171 return obj;
172 };
173
174 Object.prop = function(obj, key, val) {
175 var k, p, p1;
176 if (!obj) {
177 return null;
178 }
179 p = -1;
180 if (arguments.length > 2) {
181 while ((p = key.indexOf(".", p1 = p + 1)) > -1) {
182 obj = obj[k = key.slice(p1, +(p - 1) + 1 || 9e9)] || (obj[k] = {});
183 }
184 return obj[key.slice(p1)] = val;
185 } else {
186 while (obj && (p = key.indexOf(".", p1 = p + 1)) > -1) {
187 obj = obj[key.slice(p1, +(p - 1) + 1 || 9e9)];
188 }
189 return obj != null ? obj[key.slice(p1)] : void 0;
190 }
191 };
192
193 Object.clone = function(obj, delta) {
194 var n, r;
195 if (!obj) {
196 return null;
197 }
198 r = new obj.constructor();
199 for (n in obj) {
200 if (!__hasProp.call(obj, n)) continue;
201 r[n] = obj[n];
202 }
203 if (delta) {
204 for (n in delta) {
205 if (!__hasProp.call(delta, n)) continue;
206 r[n] = delta[n];
207 }
208 }
209 return r;
210 };
211
212 Object.parse = function(s, opts) {
213 var ex;
214 if (!s) {
215 return null;
216 }
217 try {
218 return Function.call(Function, "return " + s).call(opts != null ? opts.ctx : void 0);
219 } catch (_error) {
220 ex = _error;
221 return Object.error("bad-code: Object.parse: " + ex.message).addDetails(s).log().end(null);
222 }
223 };
224
225 Object.update.mixin = function() {
226 var T, args, fn, m, n, _ref, _super;
227 T = arguments[0], fn = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
228 if (!fn) {
229 return T;
230 }
231 _ref = fn.apply(null, [_super = {}].concat(args));
232 for (n in _ref) {
233 if (!__hasProp.call(_ref, n)) continue;
234 m = _ref[n];
235 _super[n] = T[n] || function() {};
236 T[n] = m;
237 }
238 return T;
239 };
240
241
242 /*
243 Strings.
244 */
245
246 String.LANGUAGE = 'en';
247
248 String.capitalize = function(s) {
249 if (s != null ? s.length : void 0) {
250 return s[0].toUpperCase() + s.slice(1);
251 } else {
252 return "";
253 }
254 };
255
256 String.camelize = function(s, sep) {
257 var i, t;
258 if (sep == null) {
259 sep = '_';
260 }
261 if (s != null ? s.length : void 0) {
262 return ((function() {
263 var _i, _len, _ref, _results;
264 _ref = s.split(sep);
265 _results = [];
266 for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
267 t = _ref[i];
268 _results.push(i ? String.capitalize(t) : t);
269 }
270 return _results;
271 })()).join('');
272 } else {
273 return '';
274 }
275 };
276
277 String.format = function() {
278 var args, s;
279 s = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
280 if (s) {
281 return s.replace(/\{(\d+)\}/g, (function(s, d) {
282 return args[+d] || '';
283 }));
284 } else {
285 return '';
286 }
287 };
288
289 String.localize = (function(_cache) {
290 var $;
291 $ = function(s, l) {
292 var _ref;
293 if (l == null) {
294 l = String.LANGUAGE;
295 }
296 if (s) {
297 return ((_ref = _cache[l]) != null ? _ref[s] : void 0) || String.capitalize(String.camelize(s));
298 } else {
299 return "";
300 }
301 };
302 $.get = function(s, l) {
303 var _ref;
304 if (l == null) {
305 l = String.LANGUAGE;
306 }
307 if (s) {
308 return ((_ref = _cache[l]) != null ? _ref[s] : void 0) || null;
309 } else {
310 return null;
311 }
312 };
313 $.add = function(l, delta) {
314 if (arguments.length === 1) {
315 (delta = l) && (l = null);
316 }
317 if (!l) {
318 l = String.LANGUAGE;
319 }
320 return Object.update(_cache[l] || (_cache[l] = {}), delta);
321 };
322 $.asEnum = function(s, l) {
323 var id, k, r, v, _results;
324 if (!(r = this.get(s, l))) {
325 return null;
326 }
327 _results = [];
328 for (k in r) {
329 v = r[k];
330 if (id = +k || k) {
331 if (typeof v === 'object') {
332 v.id = id;
333 _results.push(v);
334 } else {
335 _results.push({
336 id: id,
337 name: '' + v
338 });
339 }
340 }
341 }
342 return _results;
343 };
344 return $;
345 })({});
346
347 String.tokenize = function(s, re, op) {
348 var e, pastLastIndex, text;
349 if (s == null) {
350 s = '';
351 }
352 if (re == null) {
353 re = /\W/g;
354 }
355 pastLastIndex = 0;
356 while (e = re.exec(s)) {
357 if (e.index && (text = s.slice(pastLastIndex, +(e.index - 1) + 1 || 9e9))) {
358 op(text);
359 }
360 op(e[0], true);
361 pastLastIndex = re.lastIndex;
362 }
363 if ((text = s.slice(pastLastIndex))) {
364 return op(text);
365 }
366 };
367
368
369 /*
370
371 Uri class represents Uri as structure parsed from string.
372
373 Uri grammar: [type:]//host[/path...][?{(key=value)...}][#hash]
374
375 @example usage
376
377 uri = Object.Uri.parse "db://update/doc1?force=true#version2"
378 */
379
380 Object.Uri = (function() {
381 function Uri(params) {
382 this.params = params != null ? params : {};
383 }
384
385 Uri.prototype.isUri = true;
386
387 Uri.prototype.setParams = function(all) {
388 this.params = all;
389 return this;
390 };
391
392 Uri.prototype.updateParams = function(delta) {
393 Object.update(this.params, delta);
394 return this;
395 };
396
397 Uri.prototype.toString = function() {
398 var n, r, sep, v, _ref;
399 r = (this.host ? (this.type ? "" + this.type + "://" + this.host + "/" : "//" + this.host + "/") : '') + this.path.join('/');
400 sep = '?';
401 _ref = this.params;
402 for (n in _ref) {
403 if (!__hasProp.call(_ref, n)) continue;
404 v = _ref[n];
405 r += sep + n + "=" + encodeURIComponent(v);
406 if (sep === '?') {
407 sep = '&';
408 }
409 }
410 if (this.hash) {
411 r += "#" + this.hash;
412 }
413 return r;
414 };
415
416 Uri.parse = function(s, params) {
417 var p, r, v, _i, _len, _ref, _ref1;
418 if (s != null ? s.isUri : void 0) {
419 return s;
420 }
421 r = new Uri(params);
422 if (!s) {
423 return r;
424 }
425 if (!s.split) {
426 s = "" + s;
427 }
428 if ((p = s.indexOf("://")) > -1) {
429 r.type = s.slice(0, +(p - 1) + 1 || 9e9);
430 s = s.slice(p + 1);
431 }
432 if ((p = s.indexOf("#")) > -1) {
433 r.hash = s.slice(p + 1);
434 s = s.slice(0, +(p - 1) + 1 || 9e9);
435 }
436 _ref = s.split("?"), s = _ref[0], r.query = _ref[1];
437 if (r.query) {
438 _ref1 = r.query.split("&");
439 for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
440 v = _ref1[_i];
441 if ((p = v.split("=")).length > 1) {
442 r.params[p[0]] = decodeURIComponent(p[1]);
443 }
444 }
445 }
446 r.id = s;
447 p = s.split("/");
448 if (p[0] === "") {
449 p.shift();
450 if (p[0] === "") {
451 p.shift();
452 r.host = p.shift();
453 }
454 }
455 r.path = p;
456 return r;
457 };
458
459 return Uri;
460
461 })();
462
463 Object.error = (function() {
464 var Err;
465 Err = (function() {
466 function Err(e) {
467 this.details = [];
468 if (typeof e === 'string') {
469 if (e) {
470 this.reason = e.split(':')[0];
471 }
472 if (e) {
473 this.message = e;
474 }
475 } else {
476 if (e.reason) {
477 this.reason = e.reason;
478 }
479 if (e.message) {
480 this.message = e.message;
481 }
482 }
483 }
484
485 Err.prototype.reason = 'unknown';
486
487 Err.prototype.message = '';
488
489 Err.prototype.isError = true;
490
491 Err.prototype.addDetails = function() {
492 var det, _i, _len;
493 for (_i = 0, _len = arguments.length; _i < _len; _i++) {
494 det = arguments[_i];
495 if (!(det)) {
496 continue;
497 }
498 this.details.unshift(det);
499 if (det.stack) {
500 this.stack = det.stack;
501 }
502 }
503 return this;
504 };
505
506 Err.prototype.addPrefix = function(p) {
507 if (p) {
508 this.prefix = '' + p;
509 }
510 return this;
511 };
512
513 Err.prototype.log = function() {
514 Object.log(this);
515 return this;
516 };
517
518 Err.prototype.end = function(x) {
519 return x;
520 };
521
522 Err.prototype.toString = function() {
523 return "" + (this.prefix || '') + " " + this.message;
524 };
525
526 Err.prototype.printIntoLog = function(c) {
527 var details, stack;
528 details = (typeof this.details === "function" ? this.details(length === 1) : void 0) ? this.details[0] : this.details;
529 stack = this.stack || (new Error).stack;
530 return c.error(this.toString(), details, stack);
531 };
532
533 return Err;
534
535 })();
536 return function(err, details) {
537 return ((err != null ? err.isError : void 0) ? err : new Err(err)).addDetails(details);
538 };
539 })();
540
541 Object.log = function(x) {
542 return x;
543 };
544
545}).call(this);
546
547(function() {
548 var $, Entity, Property, STUB, TOTAL, TYPES,
549 __slice = [].slice,
550 __hasProp = {}.hasOwnProperty,
551 __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
552
553 STUB = function() {};
554
555 TOTAL = 0;
556
557 TYPES = (function(ALL) {
558 var r;
559 r = function(id) {
560 return ALL[id];
561 };
562 r.define = function(meta) {
563 return ALL[meta.id] = meta;
564 };
565 r.findUnresolved = function(typeId) {
566 var type;
567 if (!(type = ALL[typeId])) {
568 return typeId;
569 } else {
570 if (type._resolved || !type.superId) {
571 return null;
572 } else {
573 return r.findUnresolved(type.superId);
574 }
575 }
576 };
577 r.resolve = function(typeId, cb) {
578 return Object.fire({
579 uri: 'axoid://require',
580 dependencies: "entity://" + typeId,
581 callback: function(err) {
582 var type, utypeId;
583 if (!(type = ALL[typeId])) {
584 throw new Error("Can't resolve type " + typeId);
585 }
586 if ((utypeId = r.findUnresolved(typeId))) {
587 return r.resolve(utypeId, cb);
588 }
589 type._resolved = true;
590 return cb();
591 }
592 });
593 };
594 return r;
595 })({});
596
597 $ = (function(ALL) {
598 var Perceptor, r;
599 Perceptor = (function() {
600 var PropHandler;
601
602 PropHandler = (function() {
603 function PropHandler(parent, propId, fn) {
604 var reg;
605 this.parent = parent;
606 this.propId = propId;
607 this.fn = fn;
608 reg = this.parent.handlers || (this.parent.handlers = {});
609 (reg[propId] || (reg[propId] = [])).push(this);
610 }
611
612 PropHandler.prototype.handle = function(ev) {
613 var ex;
614 try {
615 return this.fn.call(null, ev);
616 } catch (_error) {
617 ex = _error;
618 return Object.error('notify: ' + ex.message).addDetails(Object.update(ex, {
619 op: ('' + this.fn).replace(/\n+/g, '').slice(9, 151)
620 })).log();
621 }
622 };
623
624 PropHandler.prototype.done = function() {
625 var a, index;
626 if ((a = this.parent.handlers[this.propId]) && ((index = a.indexOf(this)) > -1)) {
627 a.splice(index, 1);
628 }
629 if (!a.length) {
630 delete this.parent.handlers[this.propId];
631 }
632 return this.parent = this.fn = null;
633 };
634
635 return PropHandler;
636
637 })();
638
639 function Perceptor(id) {
640 this.id = id;
641 }
642
643 Perceptor.prototype.startListen = function(handler) {
644 var dfrd, ev, _i, _len, _results;
645 this.handler = handler;
646 if (dfrd = this.defered) {
647 delete this.defered;
648 Object.log("!!! Fire " + dfrd.length + " defered for [" + this.id + "] ");
649 _results = [];
650 for (_i = 0, _len = dfrd.length; _i < _len; _i++) {
651 ev = dfrd[_i];
652 _results.push(this.handler(ev));
653 }
654 return _results;
655 }
656 };
657
658 Perceptor.prototype.fire = function(ev) {
659 if (this.handler) {
660 return this.handler(ev);
661 }
662 (this.defered || (this.defered = [])).push(ev);
663 return Object.log("!!! Defer fire for [" + this.id + "]");
664 };
665
666 Perceptor.prototype.addIncomingHandler = function(h) {
667 return (this.incomings || (this.incomings = [])).push(h);
668 };
669
670 Perceptor.prototype.addPropertyChangedHandler = function(propId, fn, targetId) {
671 var h;
672 h = new PropHandler(this, propId, fn);
673 return $.instance(targetId).addIncomingHandler(h);
674 };
675
676 Perceptor.prototype.notifyPropertyChanged = function(propId, ev) {
677 var h, hh, _i, _len, _ref, _results;
678 if (hh = (_ref = this.handlers) != null ? _ref[propId] : void 0) {
679 _results = [];
680 for (_i = 0, _len = hh.length; _i < _len; _i++) {
681 h = hh[_i];
682 _results.push(h.handle(ev));
683 }
684 return _results;
685 }
686 };
687
688 Perceptor.prototype.done = function() {
689 var h, _i, _len, _ref, _results;
690 this.handler = this.entity = null;
691 if (this.incomings) {
692 _ref = this.incomings;
693 _results = [];
694 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
695 h = _ref[_i];
696 _results.push(h.done());
697 }
698 return _results;
699 }
700 };
701
702 return Perceptor;
703
704 })();
705 r = function(id) {
706 return ALL[id];
707 };
708 r.instance = function(id) {
709 return ALL[id] || (ALL[id] = new Perceptor(id));
710 };
711 r.release = function(id) {
712 var e;
713 if (e = ALL[id]) {
714 delete ALL[id];
715 e.done();
716 }
717 return e;
718 };
719 return r;
720 })({});
721
722
723 /*
724
725 Property class represents logic to access/manipulate a property value of a entity.
726
727 @example [number] property
728
729 Object.fire
730 uri: "axoid://define/Property/Number"
731
732 methods : ->
733 * value comparator
734 comparator: (a, b) -> Number(a) is Number(b)
735
736 * value setter
737 setter: (T, v, ev) -> T[@id] = Number(v)
738
739 *It can also mix in entity type attached to.
740 mixin: (_super, prop) ->
741 r = {}
742
743 propid = prop.id
744
745 * add method that increments value of this property
746 r['increment'+String.capitalize(propid)] = (delta=1) ->
747
748 * use _super
749 _super.log.call @, "increment #{propid}"
750
751 @prop propid, ((@prop propid) or 0)+delta
752
753 r
754 */
755
756 Property = (function() {
757 var ALL, PTYPES;
758
759 ALL = {};
760
761 PTYPES = {};
762
763 Property.Expression = (function() {
764 function Expression() {}
765
766 Expression.prototype.compile = function(message) {
767 var reg, src;
768 this.message = message;
769 reg = {};
770 src = this.sources = [];
771 this.body = this.message.replace(/<(@?[\w\.$ ]+?)>/gm, function(s, path) {
772 var flag, id, prop, _ref, _ref1;
773 _ref = path.split(' '), path = _ref[0], flag = _ref[1];
774 _ref1 = path[0] === '@' ? ['@', path.slice(1)] : path.split("."), id = _ref1[0], prop = _ref1[1];
775 if (!prop) {
776 prop = "value";
777 }
778 path = id + "." + prop;
779 if (!id) {
780 throw new Error("No id for binding source in " + s);
781 }
782 if (!reg[path]) {
783 reg[path] = 1;
784 src.push({
785 id: path,
786 flag: flag,
787 entityId: id,
788 propId: prop
789 });
790 }
791 return "$[\"" + path + "\"]";
792 });
793 this.expression = (Function.create(this.body, ['$'])) || (function() {
794 return Object.error("bad-code: Wrong binding expression: " + this.body).log();
795 });
796 return this;
797 };
798
799 Expression.instance = function(expr) {
800 return (new Expression()).compile(expr);
801 };
802
803 return Expression;
804
805 })();
806
807 function Property(id) {
808 var ftor, k, methods, typeId, v, _ref, _super;
809 this.id = id;
810 _ref = this.id.split(':'), this.id = _ref[0], typeId = _ref[1];
811 if (this.id.slice(-3) === "Uri") {
812 this.asyncTarget = this.id.slice(0, -3);
813 }
814 if (typeId) {
815 if (!(this.type = PTYPES[typeId])) {
816 throw new Error("ERROR: No such property type: " + typeId);
817 }
818 if ((ftor = this.type.methods) && (methods = ftor(_super = {}))) {
819 for (k in methods) {
820 v = methods[k];
821 if (typeof v === "function") {
822 _super[k] = this[k] || STUB;
823 }
824 this[k] = v;
825 }
826 }
827 }
828 }
829
830 Property.prototype.attachToEntityCtor = function(ctor) {
831 var _ref;
832 if ((_ref = this.type) != null ? _ref.mixin : void 0) {
833 return Object.update.mixin(ctor.prototype, this.type.mixin, this);
834 }
835 };
836
837 Property.prototype.extractDefaults = function(T, defaults) {
838 var n;
839 if (T[n = this.id] && (defaults[n] = T[n])) {
840 T[n] = void 0;
841 }
842 if (T[n = this.id + 'Expression'] && (defaults[n] = T[n])) {
843 T[n] = void 0;
844 }
845 if (T[n = this.id + 'Binding'] && (defaults[n] = T[n])) {
846 T[n] = void 0;
847 }
848 if (!this.asyncTarget) {
849 if (T[n = this.id + 'Uri'] && (defaults[n] = T[n])) {
850 T[n] = void 0;
851 }
852 if (T[n = this.id + 'UriExpression'] && (defaults[n] = T[n])) {
853 T[n] = void 0;
854 }
855 }
856 return defaults;
857 };
858
859 Property.prototype.init = function(T, defs) {
860 var expr, monitor, v;
861 monitor = {
862 locked: false
863 };
864 if ((expr = defs["" + this.id + "Binding"])) {
865 Property.bind(T.id, this.id, expr, monitor);
866 }
867 if ((expr = defs["" + this.id + "Expression"])) {
868 Property.bindWithExpression(T, this.id, expr, monitor);
869 }
870 if (!(((v = defs[this.id]) === void 0) || monitor.bound)) {
871 T.prop(this.id, v, {
872 force: true
873 });
874 }
875 if (defs["" + this.id + "Uri"] || defs["" + this.id + "UriExpression"]) {
876 return Property.instance("" + this.id + "Uri").init(T, defs);
877 }
878 };
879
880 Property.prototype.done = function(T) {
881 return T[this.id] = null;
882 };
883
884 Property.prototype.getter = function(T) {
885 return T[this.id];
886 };
887
888 Property.prototype.setter = function(T, v, ev) {
889 return T[this.id] = v;
890 };
891
892 Property.prototype.comparator = function(v1, v2) {
893 return v1 === v2;
894 };
895
896 Property.prototype.asyncAdapter = function(err, value) {
897 if (err) {
898 this.prop('asyncError', err);
899 }
900 return value || null;
901 };
902
903 Property.prototype.createAsyncValueCallback = function(T) {
904 var uuid;
905 if (T._monitor == null) {
906 T._monitor = {};
907 }
908 uuid = T._monitor[this.id] = Object.math.uuid();
909 return (function(_this) {
910 return function(err, value) {
911 if (T.isDone) {
912 T.log("!!! obsolete result at asyncValueCallback for property " + T + "." + _this.id);
913 delete T._monitor[_this.id];
914 return;
915 }
916 if (uuid !== T._monitor[_this.id]) {
917 T.log("!!! out of monitor at asyncValueCallback for property " + T + "." + _this.id);
918 return;
919 }
920 T.prop(_this.id, (T["" + _this.id + "AsyncAdapter"] || _this.asyncAdapter).call(T, err, value));
921 delete T._monitor[_this.id];
922 };
923 })(this);
924 };
925
926 Property.prototype.setValue = function(T, value, opts) {
927 var ev, uri, v;
928 ev = Object.update({
929 value: value
930 }, opts);
931 ev.propId = this.id;
932 ev.entity = T;
933 ev.oldValue = this.getter(T);
934 if (ev.uri) {
935 uri = ev.uri;
936 ev.uri = null;
937 }
938 if (((v = ev.value) !== void 0) && (ev.force || !this.comparator(v, ev.oldValue))) {
939 this.setter(T, v, ev);
940 if (this.asyncTarget && v) {
941 T.prop(this.asyncTarget, null, {
942 uri: v,
943 force: true
944 });
945 }
946 T.propertyChanged(ev);
947 }
948 if (uri) {
949 Object.fire({
950 uri: uri,
951 callback: this.createAsyncValueCallback(T)
952 });
953 }
954 return ev;
955 };
956
957 Property.define = function(meta) {
958 return PTYPES[meta.id] = meta;
959 };
960
961 Property.instance = function(id) {
962 return ALL[id] || (ALL[id] = new Property(id));
963 };
964
965
966 /*
967 binds property value with expression.
968
969 It parses and compiles from given CoffeeScript `expr` containing placeholders in <> brackets.
970
971 Placeholder is a source property reference and an optional triggering modifier.
972
973 Placeholder grammar: "<" (entityId|"@") ["." propertyId] [required|optional] ">"
974
975 Use "@" to refer taget entity itself
976
977 By default, propertyId is "value".
978
979 By default, an expression triggers when all sources are defined.
980
981 Use `required` modifier to triger only for non-empty source value.
982
983 Use `optional` modifier to triger even for undefined source value.
984
985 @example hello world
986
987 * will trigger only if user.name is defined and not empty
988 greetingExpresssion: "'Hello, '+<user.name required>"
989
990 @example readyForEvents
991
992 * will trigger only if both its own property `dataLoaded` and `other.value` are true
993 readyForEventsExpresssion: "<@dataLoaded required> and <other required>"
994
995 @example get users list
996
997 * will trigger even if search value is undefined yet.
998 dataUriExpresssion: "'db://query/users?q='+(<search.value optional> or '')"
999 */
1000
1001 Property.bindWithExpression = function(T, propId, value, monitor) {
1002 var expr, ps, _bind, _i, _len, _log, _ref;
1003 expr = Property.Expression.instance(value);
1004 monitor.locked = false;
1005 _log = function(s) {
1006 if (Object.DEBUG) {
1007 return Object.log("binding: " + T + "[" + propId + "] " + s);
1008 }
1009 };
1010 _bind = function(ev) {
1011 var e, p, val, values, _i, _len, _ref;
1012 if (monitor.locked) {
1013 return;
1014 }
1015 values = {};
1016 _ref = expr.sources;
1017 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1018 p = _ref[_i];
1019 if (!(e = (p.entityId === '@' ? T : $(p.entityId).entity))) {
1020 return _log("No source of " + p.id);
1021 }
1022 if (!(val = e.prop(p.propId)) && ((val === void 0 && p.flag !== 'optional') || (p.flag === 'required'))) {
1023 return _log("No value from " + p.id);
1024 }
1025 values[p.id] = val;
1026 }
1027 monitor.locked = true;
1028 try {
1029 value = expr.expression.call(T, values);
1030 if (Object.LOG_LEVEL > 4) {
1031 _log("= [" + expr.message + "] (" + (('' + value).replace('\n', ' ').slice(0, 31)) + ")");
1032 }
1033 return T.prop(propId, value);
1034 } finally {
1035 monitor.locked = false;
1036 }
1037 };
1038 _ref = expr.sources;
1039 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1040 ps = _ref[_i];
1041 $.instance(ps.entityId === '@' ? T.id : ps.entityId).addPropertyChangedHandler(ps.propId, _bind, T.id);
1042 }
1043 if (!monitor.bound) {
1044 return _bind();
1045 }
1046 };
1047
1048
1049 /*
1050
1051 double binds property.
1052
1053 Placeholder grammar: (entityId|"@") ["." propertyId]
1054
1055 Use "@" to refer taget entity itself
1056
1057 By default, propertyId is "value".
1058
1059 Binding triggers when source is defined.
1060
1061 @example hello world
1062
1063 * will trigger when storage.name is defined
1064 valueBinding: "storage.name"
1065 */
1066
1067 Property.bind = function(tId, tProp, path, monitor) {
1068 var s0, sId, sProp, val, _bind, _log, _ref, _ref1;
1069 _ref = path.split('.'), sId = _ref[0], sProp = _ref[1];
1070 if (!sProp) {
1071 sProp = 'value';
1072 }
1073 _log = function(s) {
1074 if (Object.DEBUG) {
1075 return Object.log("duplex: " + tId + "[" + tProp + "] " + s);
1076 }
1077 };
1078 _bind = function(ev) {
1079 var e, _ref1;
1080 if (monitor.locked) {
1081 return;
1082 }
1083 monitor.locked = true;
1084 if (Object.LOG_LEVEL > 4) {
1085 _log("= [" + sId + "." + sProp + "] (" + (('' + ev.value).replace('\n', ' ').slice(0, 31)) + ")");
1086 }
1087 try {
1088 if (!tId) {
1089 throw new Error("Binding target has no id");
1090 }
1091 if (!(e = (_ref1 = $(tId)) != null ? _ref1.entity : void 0)) {
1092 throw new Error("Lack of binding target with id [" + tId + "]");
1093 }
1094 return e.prop(tProp, ev.value);
1095 } finally {
1096 monitor.locked = false;
1097 }
1098 };
1099 $.instance(sId).addPropertyChangedHandler(sProp, _bind, tId);
1100 if (!monitor.reverse) {
1101 if ((s0 = (_ref1 = $(sId)) != null ? _ref1.entity : void 0) && ((val = s0.prop(sProp)) !== void 0)) {
1102 _bind({
1103 entity: s0,
1104 value: val
1105 });
1106 monitor.bound = true;
1107 }
1108 monitor.reverse = true;
1109 this.bind(sId, sProp, tId + "." + tProp, monitor);
1110 }
1111 return true;
1112 };
1113
1114 return Property;
1115
1116 })();
1117
1118
1119 /*
1120 Entity class
1121
1122 @example custom list view
1123
1124 Object.fire
1125
1126 * extends `D3List`
1127 uri: "axoid://define/D3List/couch.DbList"
1128
1129 *add property `totalCount` of type `Number`
1130 properties:['collection','totalCount:Number']
1131
1132 * set totalCount from length of data
1133 totalCountExpression: '<@data required>.length'
1134
1135 *bind data Uri with expression using `collection` property of itself
1136 dataUriExpression: "'db://getAll/'+<@collection>"
1137
1138 * methods factory:
1139 methods:(_super)->
1140
1141 init: ()->
1142
1143 *use _super
1144 _super.init.apply @, arguments
1145 ...
1146
1147 totalCountChanged: (count, event)->
1148 ...
1149
1150 dataAsyncAdapter:(err, value)->
1151 * try to get data from `items` attribute
1152 value?.items or value or null
1153 */
1154
1155 Entity = (function() {
1156 function Entity() {}
1157
1158 Entity.prototype.launch = function(cb) {
1159 this.init();
1160 return typeof cb === "function" ? cb(null, this) : void 0;
1161 };
1162
1163 Entity.prototype.init = function() {
1164 var defs, n, p, _ref, _ref1;
1165 defs = {};
1166 _ref = this.constructor.properties;
1167 for (n in _ref) {
1168 p = _ref[n];
1169 p.extractDefaults(this, defs);
1170 }
1171 _ref1 = this.constructor.properties;
1172 for (n in _ref1) {
1173 p = _ref1[n];
1174 p.init(this, defs);
1175 }
1176 if (this.onEvent) {
1177 this.listenEvents();
1178 }
1179 return typeof this.onInited === "function" ? this.onInited(this) : void 0;
1180 };
1181
1182 Entity.prototype.done = function() {
1183 var n, p, _ref;
1184 this.isDone = true;
1185 _ref = this.constructor.properties;
1186 for (n in _ref) {
1187 p = _ref[n];
1188 p.done(this);
1189 }
1190 return $.release(this.id);
1191 };
1192
1193 Entity.prototype.prop = function(key, value, opts) {
1194 var p;
1195 if (this.isDone) {
1196 return null;
1197 }
1198 p = this.constructor.properties;
1199 if (arguments.length === 1) {
1200 return (p[key] ? p[key].getter(this) : this[key]);
1201 }
1202 (p[key] || Property.instance(key)).setValue(this, value, opts);
1203 return value;
1204 };
1205
1206 Entity.prototype.propertyChanged = function(ev) {
1207 var _ref, _ref1;
1208 if ((_ref = this["" + ev.propId + "Changed"]) != null) {
1209 _ref.call(this, ev.value, ev);
1210 }
1211 return (_ref1 = $(this.id)) != null ? _ref1.notifyPropertyChanged(ev.propId, ev) : void 0;
1212 };
1213
1214 Entity.prototype.listenEvents = function() {
1215 if (this.id[0] === '#') {
1216 throw new Error("" + this + " attempts to listen events, but has no explicit id");
1217 }
1218 return $.instance(this.id).startListen((function(_this) {
1219 return function(ev) {
1220 return _this.onEvent(ev);
1221 };
1222 })(this));
1223 };
1224
1225 Entity.prototype.error = function(e, details) {
1226 return Object.error(e).addPrefix(this).addDetails(details).log();
1227 };
1228
1229 Entity.prototype.log = function() {
1230 var args;
1231 args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
1232 if (!(Object.LOG_LEVEL > 4)) {
1233 return args[0];
1234 }
1235 args.unshift(this.toString());
1236 Object.log.apply(Object, args);
1237 return args[1];
1238 };
1239
1240 Entity.prototype.toString = function() {
1241 if (this.id[0] === '#') {
1242 return "[" + this.constructor.typeId + ":" + this.id + "]";
1243 } else {
1244 return "[" + this.id + "]";
1245 }
1246 };
1247
1248 Entity.getCtor = function(meta) {
1249 var t;
1250 if (meta.properties || meta.methods) {
1251 return this.createCtor(Object.clone(meta, {
1252 id: "T" + (TOTAL++),
1253 superId: meta.type,
1254 properties: meta.properties || [],
1255 methods: meta.methods
1256 }));
1257 } else {
1258 if ((t = TYPES(meta.type))) {
1259 return t.ctor || (t.ctor = this.createCtor(t));
1260 }
1261 }
1262 };
1263
1264 Entity.createCtor = (function() {
1265 var PKEYS, _applyType;
1266 PKEYS = ['id', 'superId', 'type', 'properties', 'methods', 'callback', 'uri'];
1267 _applyType = function(t, defaults) {
1268 var k, p, pId, v, _i, _len, _ref;
1269 if (t.superId) {
1270 _applyType.call(this, TYPES(t.superId), defaults);
1271 }
1272 if (t.properties) {
1273 _ref = t.properties;
1274 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1275 pId = _ref[_i];
1276 if (this.properties[pId]) {
1277 throw Object.error("bad-code: Duplicate property " + pId + " in type " + t.id).log();
1278 } else {
1279 (this.properties[(p = Property.instance(pId)).id] = p).attachToEntityCtor(this);
1280 }
1281 }
1282 }
1283 for (k in t) {
1284 if (!__hasProp.call(t, k)) continue;
1285 v = t[k];
1286 if (__indexOf.call(PKEYS, k) < 0) {
1287 defaults[k] = v;
1288 }
1289 }
1290 Object.update.mixin(this.prototype, t.methods);
1291 return this;
1292 };
1293 return function(type) {
1294 var ctor, defaults, k, v, _ref;
1295 ctor = function(meta) {
1296 var id, k, v, _ref;
1297 if (id = meta != null ? meta.id : void 0) {
1298 if ((_ref = $(id)) != null ? _ref.entity : void 0) {
1299 throw new Error("Duplicate entity id " + id);
1300 }
1301 this.id = id;
1302 $.instance(this.id).entity = this;
1303 } else {
1304 this.id = "#" + (TOTAL++);
1305 }
1306 if (meta) {
1307 for (k in meta) {
1308 if (!__hasProp.call(meta, k)) continue;
1309 v = meta[k];
1310 if (__indexOf.call(PKEYS, k) < 0) {
1311 this[k] = v;
1312 }
1313 }
1314 }
1315 return this;
1316 };
1317 _ref = Entity.prototype;
1318 for (k in _ref) {
1319 if (!__hasProp.call(_ref, k)) continue;
1320 v = _ref[k];
1321 ctor.prototype[k] = v;
1322 }
1323 ctor.typeId = type.id;
1324 ctor.properties = {};
1325 _applyType.call(ctor, type, defaults = {});
1326 for (k in defaults) {
1327 if (!__hasProp.call(defaults, k)) continue;
1328 v = defaults[k];
1329 ctor.prototype[k] = v;
1330 }
1331 return ctor;
1332 };
1333 })();
1334
1335 Entity.create = function(meta) {
1336 var Ctor, obj, type, utype, _ref;
1337 if (meta.id) {
1338 _ref = meta.id.split(':'), meta.id = _ref[0], type = _ref[1];
1339 }
1340 if (type) {
1341 meta.type = type;
1342 }
1343 if ((utype = TYPES.findUnresolved(meta.type))) {
1344 return TYPES.resolve(utype, ((function(_this) {
1345 return function(err) {
1346 if (!err) {
1347 return _this.create(meta);
1348 }
1349 };
1350 })(this)));
1351 }
1352 Ctor = this.getCtor(meta);
1353 obj = new Ctor(meta);
1354 obj.launch(meta.callback);
1355 return obj;
1356 };
1357
1358 return Entity;
1359
1360 })();
1361
1362 TYPES.define({
1363 id: 'Axoid',
1364 methods: function(_super) {
1365 return {
1366 onEvent: function(ev) {
1367 return this[ev.uri.host](ev);
1368 },
1369 define: function(ev, u) {
1370 var p;
1371 if (u == null) {
1372 u = ev.uri;
1373 }
1374 if (p = u.path[0]) {
1375 ev.id = p;
1376 }
1377 if (p = u.path[1]) {
1378 ev.superId = ev.id;
1379 ev.id = p;
1380 }
1381 if (ev.superId === 'Property') {
1382 Property.define(ev);
1383 } else {
1384 TYPES.define(ev);
1385 }
1386 return ev.callback();
1387 },
1388 create: function(ev, u) {
1389 var p;
1390 if (u == null) {
1391 u = ev.uri;
1392 }
1393 if (p = u.hash) {
1394 ev.id = p;
1395 }
1396 if (p = u.path[0]) {
1397 ev.type = p;
1398 }
1399 return Entity.create(ev);
1400 },
1401 require: (function(_cache) {
1402 var createCb, performRequire;
1403 if (_cache == null) {
1404 _cache = {};
1405 }
1406 createCb = function(ctx) {
1407 return function(err, r) {
1408 var cb;
1409 if (err) {
1410 Object.error(err).log();
1411 }
1412 if (!err) {
1413 ctx.isDone = 1;
1414 }
1415 while ((cb = ctx.q.shift())) {
1416 cb(err, r);
1417 }
1418 return 1;
1419 };
1420 };
1421 return performRequire = function(ev) {
1422 var dependencies;
1423 dependencies = ev.dependencies;
1424 if (typeof dependencies === 'string') {
1425 dependencies = [dependencies];
1426 }
1427 if (!(dependencies != null ? dependencies.length : void 0)) {
1428 return ev.callback(null, 0);
1429 }
1430 return Function.perform(ev, function(flow) {
1431 return [
1432 function() {
1433 var ctx, x, _i, _len;
1434 for (_i = 0, _len = dependencies.length; _i < _len; _i++) {
1435 x = dependencies[_i];
1436 if (x && (ctx = _cache[x] || (_cache[x] = {
1437 q: [],
1438 x: x
1439 })) && !ctx.isDone) {
1440 ctx.q.push(flow.wait());
1441 if (ctx.q.length === 1) {
1442 Object.fire({
1443 uri: x,
1444 callback: createCb(ctx)
1445 });
1446 }
1447 }
1448 }
1449 return flow.next(null, dependencies.length);
1450 }, ev.callback
1451 ];
1452 });
1453 };
1454 })()
1455 };
1456 }
1457 });
1458
1459 Entity.create({
1460 id: 'axoid',
1461 type: 'Axoid'
1462 });
1463
1464
1465 /*
1466 Fires an event.
1467
1468 @param [Object] event event object. Required.
1469
1470 @option event uri [Object.Uri] uri referring target entity (which `entity.id` equals to `uri.type`). Required.
1471 @option event callback [Function] callback to be invoked from target. Optional. Stub by default.
1472
1473 @example
1474
1475 Object.emit
1476 * "db" is id of database entity. Rest of url adresses operation and its parameters:
1477 uri: "db://changes?include_docs=true&since=#{since}"
1478 callback: (err, result)->
1479 * handle with results unless errror
1480 doSome(result) unless err
1481 */
1482
1483 Object.emit = Object.fire = function(event) {
1484 if (!event.uri) {
1485 throw new Error("No uri specified");
1486 }
1487 event.uri = Object.Uri.parse(event.uri);
1488 if (event.callback == null) {
1489 event.callback = STUB;
1490 }
1491 return $.instance(event.uri.type).fire(event);
1492 };
1493
1494}).call(this);
1495
1496
1497/*
1498 * Defines [Cache] entity type that provides caching feature.
1499 * @options
1500 * version
1501 * uriPatterm
1502 * storage
1503 */
1504
1505(function() {
1506 Object.emit({
1507 uri: "axoid://define/EventHandler/Cache",
1508 uriPattern: 'remote://{{host}}/{{path}}?_ver={{version}}',
1509 methods: function(_super) {
1510 var CACHE;
1511 CACHE = {};
1512 return {
1513 resolveUri: function(u) {
1514 u = Object.clone(u, u.params);
1515 u.path = u.path.join('/');
1516 if (!u.version) {
1517 u.version = this.getVersion();
1518 }
1519 return Object.Uri.parse(String.template(this.uriPattern, u));
1520 },
1521 cacheDeserializer: function(s) {
1522 if (!s) {
1523 return null;
1524 }
1525 if (typeof s === "object") {
1526 return s;
1527 } else {
1528 return Object.parse(s);
1529 }
1530 },
1531 cacheSerializer: function(s) {
1532 if (!s) {
1533 return null;
1534 }
1535 s = typeof s === "object" ? JSON.stringify(s) : s;
1536 if (s && s !== "{}") {
1537 return s;
1538 } else {
1539 return null;
1540 }
1541 },
1542 getVersion: function() {
1543 return '' + (this.version || 1);
1544 },
1545 fetch: function(uri, cb) {
1546 return Object.emit({
1547 uri: this.resolveUri(uri),
1548 callback: cb,
1549 unmarshaller: this.fetchUnmarshaller
1550 });
1551 },
1552 restore: function(key) {
1553 var s, ver, _ref;
1554 if (!(s = (_ref = this.storage) != null ? _ref[key] : void 0)) {
1555 return null;
1556 }
1557 ver = this.getVersion();
1558 if (ver === s.slice(0, +(ver.length - 1) + 1 || 9e9)) {
1559 return s.slice(ver.length + 1);
1560 } else {
1561 return null;
1562 }
1563 },
1564 store: function(key, s) {
1565 var _ref;
1566 try {
1567 return (_ref = this.storage) != null ? _ref.setItem(key, this.getVersion() + ":" + s) : void 0;
1568 } catch (_error) {}
1569 },
1570 onEvent: function(ev) {
1571 var key, r, u;
1572 u = ev.uri;
1573 key = this.id + ':' + u.id;
1574 if ((r = CACHE[key] || (CACHE[key] = this.cacheDeserializer(this.restore(key))))) {
1575 return ev.callback(null, r);
1576 }
1577 return this.fetch(u, (function(_this) {
1578 return function(err, data) {
1579 var s;
1580 if ((err = (typeof s !== "undefined" && s !== null ? s.error : void 0) || err)) {
1581 err = _this.error(err, "fetch data for versioned cache");
1582 }
1583 if (!err && (s = _this.cacheSerializer(data))) {
1584 CACHE[key] = data = _this.cacheDeserializer(s);
1585 _this.store(key, s);
1586 }
1587 return ev.callback(err, data);
1588 };
1589 })(this));
1590 }
1591 };
1592 }
1593 });
1594
1595}).call(this);
1596
1597
1598/*
1599Dates.
1600 */
1601
1602(function() {
1603 (function(MAXD, CURR) {
1604 var _nn;
1605 _nn = function(s) {
1606 return s && (s = "" + s) && (s.length < 2 ? "0" + s : s) || "00";
1607 };
1608 Date.PATTERN_PARSE = "yyyy-MM-dd";
1609 Date.PATTERN_FORMAT = "dd MMM yyyy";
1610 Date.daysInMonth = function(m, y) {
1611 return ((m === 1) && ((y % 4) === 0) ? 1 : 0) + MAXD[m];
1612 };
1613 Date.getTimeZone = function() {
1614 var l, m, t;
1615 l = -CURR.getTimezoneOffset();
1616 t = "" + Math.abs(l / 60);
1617 m = "" + Math.abs(l % 60);
1618 return "GMT" + (((l === 0) && "") || ("%2" + (l > 0 ? "B" : "D") + _nn(t) + ":" + _nn(m)));
1619 };
1620 Date.parse = function(s, pattern) {
1621 var d, p, r;
1622 if (pattern == null) {
1623 pattern = Date.PATTERN_PARSE;
1624 }
1625 if (!s) {
1626 return null;
1627 }
1628 if (s instanceof Date) {
1629 return s;
1630 }
1631 d = new Date();
1632 d.setDate(1);
1633 d.setHours(12);
1634 d.setMinutes(0);
1635 d.setSeconds(0);
1636 r = "" + pattern;
1637 if ((p = r.indexOf("yyyy")) > -1) {
1638 d.setFullYear(s.substr(p, 4));
1639 } else {
1640 if ((p = r.indexOf("yy")) > -1) {
1641 d.setFullYear(2000 + s.substr(p, 2));
1642 }
1643 }
1644 if ((p = r.indexOf("MM")) > -1) {
1645 d.setMonth(+s.substr(p, 2) - 1);
1646 }
1647 if ((p = r.indexOf("dd")) > -1) {
1648 d.setDate(+s.substr(p, 2));
1649 }
1650 if ((p = r.indexOf("HH")) > -1) {
1651 d.setHours(+s.substr(p, 2));
1652 if ((p = r.indexOf("mm")) > -1) {
1653 d.setMinutes(+s.substr(p, 2));
1654 }
1655 if ((p = r.indexOf("ss")) > -1) {
1656 d.setSeconds(+s.substr(p, 2));
1657 }
1658 }
1659 return d;
1660 };
1661 Date.shift = function(d, lag) {
1662 var r;
1663 r = new Date();
1664 r.setTime((d || r).getTime() + ((lag || 0) * 86400000));
1665 return r;
1666 };
1667 Date.days = function(d) {
1668 if (!(d && d.getTime)) {
1669 return 0;
1670 }
1671 d = d.getTime();
1672 return (d - d % 86400000) / 86400000;
1673 };
1674 Date.compare = function(x, y) {
1675 if (x && y) {
1676 if (x.getTime && y.getTime) {
1677 if (x.getTime() > y.getTime()) {
1678 return 1;
1679 } else {
1680 return -1;
1681 }
1682 } else {
1683 return 0;
1684 }
1685 } else {
1686 if (!x && !y) {
1687 return 0;
1688 } else {
1689 if (!!x) {
1690 return 1;
1691 } else {
1692 return -1;
1693 }
1694 }
1695 }
1696 };
1697 Date.monthName = function(m, lang, key) {
1698 var _ref;
1699 if (key == null) {
1700 key = "MONTH";
1701 }
1702 return (_ref = String.localize.get(key, lang)) != null ? _ref[_nn(m + 1)] : void 0;
1703 };
1704 Date.format = function(d, pattern, lng) {
1705 var r;
1706 if (pattern == null) {
1707 pattern = Date.PATTERN_FORMAT;
1708 }
1709 r = "";
1710 if (d && d.getFullYear) {
1711 r += pattern || Date.PATTERN_FORMAT;
1712 r = r.replace("yyyy", "" + d.getFullYear());
1713 r = r.replace("yy", "" + d.getFullYear());
1714 r = r.replace("MMMM", Date.monthName(d.getMonth(), lng));
1715 r = r.replace("MMM", Date.monthName(d.getMonth(), lng, "MONTH_SHORT"));
1716 r = r.replace("MM", _nn(d.getMonth() + 1));
1717 r = r.replace("dd", _nn(d.getDate()));
1718 r = r.replace("hh", _nn(d.getHours()));
1719 r = r.replace("mm", _nn(d.getMinutes()));
1720 r = r.replace("ss", _nn(d.getSeconds()));
1721 }
1722 return r;
1723 };
1724 return String.localize.add("en", {
1725 "DOW": {
1726 '1': "Su",
1727 '2': "Mo",
1728 '3': "Tu",
1729 '4': "We",
1730 '5': "Th",
1731 '6': "Fr",
1732 '7': "Sa"
1733 },
1734 "MONTH_SHORT": {
1735 '01': "Jan",
1736 '02': "Feb",
1737 '03': "Mar",
1738 '04': "Apr",
1739 '05': "May",
1740 '06': "Jun",
1741 '07': "Jul",
1742 '08': "Aug",
1743 '09': "Sep",
1744 '10': "Oct",
1745 '11': "Nov",
1746 '12': "Dec"
1747 },
1748 "MONTH": {
1749 '01': "January",
1750 '02': "February",
1751 '03': "March",
1752 '04': "April",
1753 '05': "May",
1754 '06': "June",
1755 '07': "July",
1756 '08': "August",
1757 '09': "September",
1758 '10': "October",
1759 '11': "November",
1760 '12': "December"
1761 }
1762 });
1763 })([31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31], new Date());
1764
1765}).call(this);
1766
1767
1768/*
1769 * Defines [EventHandler] entity type that provides featured event handlig.
1770 * @param readyForEventsExpression [Expression]
1771 */
1772
1773(function() {
1774 Object.emit({
1775 uri: "axoid://define/EventHandler",
1776 properties: ['readyForEvents'],
1777 readyForEventsExpression: 'true',
1778 methods: function(_super) {
1779 return {
1780 listenEvents: function() {},
1781 readyForEventsChanged: function(ready) {
1782 if (ready) {
1783 return _super.listenEvents.call(this);
1784 }
1785 },
1786 onEvent: function(ev) {
1787 return this.dispatchEvent(ev);
1788 },
1789 resolveOperationId: function(ev) {
1790 return (ev.method || 'get') + String.capitalize(ev.uri.path[0] || 'default');
1791 },
1792 dispatchEvent: function(ev) {
1793 var ex, op, opId;
1794 opId = this.resolveOperationId(ev);
1795 if (!(op = this[opId])) {
1796 return typeof ev.callback === "function" ? ev.callback(this.error("not-found: Operation not found: " + opId).log()) : void 0;
1797 }
1798 try {
1799 return op.call(this, ev);
1800 } catch (_error) {
1801 ex = _error;
1802 return typeof ev.callback === "function" ? ev.callback(this.error("Error in " + opId + " ").addDetails(ex).log()) : void 0;
1803 }
1804 }
1805 };
1806 }
1807 });
1808
1809}).call(this);
1810
1811(function() {
1812 Object.emit({
1813 uri: "axoid://define/L10nService/EnumService",
1814 methods: function(_super) {
1815 var CACHE;
1816 CACHE = {};
1817 return {
1818 onEvent: function(ev, u, key) {
1819 var r;
1820 if (u == null) {
1821 u = ev.uri;
1822 }
1823 if (key == null) {
1824 key = u.host;
1825 }
1826 if (r = CACHE[key]) {
1827 return ev.callback(null, r);
1828 }
1829 if (!(r = String.localize.asEnum(key))) {
1830 return ev.callback("not-found: enum [" + key + "]");
1831 }
1832 return ev.callback(null, CACHE[key] = r);
1833 }
1834 };
1835 }
1836 });
1837
1838 Object.emit({
1839 uri: "axoid://define/L10nService",
1840 properties: ["requires:Requires"],
1841 methods: function(_super) {
1842 return {
1843 onRequiredLoaded: function(err) {
1844 var b, _i, _len, _results;
1845 if (err) {
1846 return;
1847 }
1848 _results = [];
1849 for (_i = 0, _len = arguments.length; _i < _len; _i++) {
1850 b = arguments[_i];
1851 if (b) {
1852 _results.push(String.localize.add(b));
1853 }
1854 }
1855 return _results;
1856 },
1857 onEvent: function(ev) {
1858 return ev.callback(null, String.localize(ev.uri.host));
1859 }
1860 };
1861 }
1862 });
1863
1864}).call(this);
1865
1866(function() {
1867 Object.log = (function(c) {
1868 if (c == null) {
1869 c = {
1870 log: function() {}
1871 };
1872 }
1873 if (!c.log.apply) {
1874 c._log = c.log;
1875 c.log = function() {
1876 var s;
1877 return c._log(((function() {
1878 var _i, _len, _results;
1879 _results = [];
1880 for (_i = 0, _len = arguments.length; _i < _len; _i++) {
1881 s = arguments[_i];
1882 _results.push(s);
1883 }
1884 return _results;
1885 }).apply(this, arguments)).join(", "));
1886 };
1887 }
1888 if (!c.error) {
1889 c.error = function() {
1890 var s;
1891 return c.log.apply(c, ['ERROR: '].concat((function() {
1892 var _i, _len, _results;
1893 _results = [];
1894 for (_i = 0, _len = arguments.length; _i < _len; _i++) {
1895 s = arguments[_i];
1896 _results.push(s);
1897 }
1898 return _results;
1899 }).apply(this, arguments)));
1900 };
1901 }
1902 return function(x) {
1903 var e;
1904 if (x != null ? x.printIntoLog : void 0) {
1905 x.printIntoLog(c);
1906 } else {
1907 c.log.apply(c, (function() {
1908 var _i, _len, _results;
1909 _results = [];
1910 for (_i = 0, _len = arguments.length; _i < _len; _i++) {
1911 e = arguments[_i];
1912 _results.push(e);
1913 }
1914 return _results;
1915 }).apply(this, arguments));
1916 }
1917 return x;
1918 };
1919 })((typeof window === 'object' ? window : this).console);
1920
1921}).call(this);
1922
1923
1924/*
1925Math.
1926@mixin
1927 */
1928
1929(function() {
1930 Object.math = {
1931 decimalAdjust: function(type, value, exp) {
1932 if (typeof exp === "undefined" || +exp === 0) {
1933 return Math[type](value);
1934 }
1935 value = +value;
1936 exp = +exp;
1937 if (isNaN(value) || !(typeof exp === "number" && exp % 1 === 0)) {
1938 return NaN;
1939 }
1940 value = value.toString().split("e");
1941 value = Math[type](+(value[0] + "e" + (value[1] ? +value[1] - exp : -exp)));
1942 value = value.toString().split("e");
1943 return +(value[0] + "e" + (value[1] ? +value[1] + exp : exp));
1944 },
1945 round: function(value, exp) {
1946 if (exp == null) {
1947 exp = 0;
1948 }
1949 return this.decimalAdjust("round", value, exp);
1950 },
1951 uuid: function() {
1952 var d;
1953 d = Date.now();
1954 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
1955 var r;
1956 r = (d + Math.random() * 16) % 16 | 0;
1957 d = Math.floor(d / 16);
1958 return (c === 'x' ? r : r & 0x7 | 0x8).toString(16);
1959 });
1960 },
1961 sort: function(a, key, dir) {
1962 var getter, rdir;
1963 if (!dir) {
1964 dir = 1;
1965 }
1966 rdir = dir * -1;
1967 getter = typeof key === "string" ? function(s) {
1968 return s != null ? s[key] : void 0;
1969 } : key || function(s) {
1970 return s;
1971 };
1972 return a.sort(function(s1, s2) {
1973 var v1, v2;
1974 if ((v1 = getter(s1)) > (v2 = getter(s2))) {
1975 return dir;
1976 } else {
1977 if (v1 < v2) {
1978 return rdir;
1979 } else {
1980 return 0;
1981 }
1982 }
1983 });
1984 }
1985 };
1986
1987}).call(this);
1988
1989
1990/*
1991 Very common properties.
1992 */
1993
1994(function() {
1995 Object.emit({
1996 uri: "axoid://define/Property/Liquid",
1997 methods: function() {
1998 return {
1999 comparator: function() {
2000 return false;
2001 }
2002 };
2003 }
2004 });
2005
2006 Object.emit({
2007 uri: "axoid://define/Property/Boolean",
2008 methods: function() {
2009 return {
2010 comparator: function(a, b) {
2011 return (!a) === (!b);
2012 },
2013 setter: function(T, v, ev) {
2014 return T[this.id] = !!v;
2015 }
2016 };
2017 }
2018 });
2019
2020 Object.emit({
2021 uri: "axoid://define/Property/Uri",
2022 methods: function() {
2023 return {
2024 comparator: function(a, b) {
2025 return ('' + a) === ('' + b);
2026 },
2027 setter: function(T, v, ev) {
2028 return T[this.id] = Object.Uri.parse(v);
2029 }
2030 };
2031 }
2032 });
2033
2034 Object.emit({
2035 uri: "axoid://define/Property/Number",
2036 methods: function() {
2037 return {
2038 comparator: function(a, b) {
2039 return Number(a) === Number(b);
2040 },
2041 setter: function(T, v, ev) {
2042 return T[this.id] = Number(v);
2043 }
2044 };
2045 },
2046 mixin: function(_super, prop) {
2047 var propid, r;
2048 r = {};
2049 propid = prop.id;
2050 r['increment' + String.capitalize(propid)] = function(delta) {
2051 if (delta == null) {
2052 delta = 1;
2053 }
2054 return this.prop(propid, ((this.prop(propid)) || 0) + delta);
2055 };
2056 return r;
2057 }
2058 });
2059
2060 Object.emit({
2061 uri: "axoid://define/Property/Date",
2062 methods: function() {
2063 return {
2064 comparator: function(a, b) {
2065 return Date.compare(a, b) === 0;
2066 }
2067 };
2068 }
2069 });
2070
2071}).call(this);
2072
2073(function() {
2074 Object.emit({
2075 uri: "axoid://define/Property/Plugins",
2076 mixin: function(_super) {
2077 return {
2078 launch: function(cb) {
2079 return Function.perform(this, function(flow) {
2080 return [
2081 function() {
2082 var meta, _i, _len, _ref;
2083 if (this.plugins) {
2084 _ref = this.plugins;
2085 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2086 meta = _ref[_i];
2087 Object.emit(Object.clone(meta, {
2088 _parent: this,
2089 uri: "axoid://create",
2090 callback: flow.wait()
2091 }));
2092 }
2093 }
2094 return flow.next();
2095 }, function(err, plugins) {
2096 var e, i, id, p, _i, _len, _ref;
2097 if (err) {
2098 this.error(err, "" + this + ".onPluginsInitializing");
2099 }
2100 this.plugins = (function() {
2101 var _i, _len, _results;
2102 _results = [];
2103 for (i = _i = 0, _len = arguments.length; _i < _len; i = ++_i) {
2104 e = arguments[i];
2105 if (i > 1) {
2106 _results.push(e);
2107 }
2108 }
2109 return _results;
2110 }).apply(this, arguments);
2111 _ref = this.plugins;
2112 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2113 p = _ref[_i];
2114 if (id = p.id) {
2115 this[id] = p;
2116 }
2117 }
2118 return _super.launch.call(this, cb);
2119 }
2120 ];
2121 });
2122 },
2123 done: function() {
2124 var p, _i, _len, _ref, _results;
2125 _super.done.call(this);
2126 if (this.plugins) {
2127 _ref = this.plugins;
2128 _results = [];
2129 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2130 p = _ref[_i];
2131 p.done();
2132 p._parent = null;
2133 if (p.id) {
2134 _results.push(this[p.id] = null);
2135 } else {
2136 _results.push(void 0);
2137 }
2138 }
2139 return _results;
2140 }
2141 }
2142 };
2143 }
2144 });
2145
2146}).call(this);
2147
2148(function() {
2149 Object.emit({
2150 uri: 'axoid://define/Property/Requires',
2151 mixin: function(_super) {
2152 return {
2153 launch: function(cb) {
2154 return Object.emit({
2155 uri: 'axoid://require',
2156 dependencies: this.requires,
2157 callback: (function(_this) {
2158 return function(err) {
2159 var e;
2160 if (err) {
2161 Object.error(err, "" + _this + ".onRequires").log();
2162 }
2163 if (typeof _this.onRequiredLoaded === "function") {
2164 _this.onRequiredLoaded.apply(_this, (function() {
2165 var _i, _len, _results;
2166 _results = [];
2167 for (_i = 0, _len = arguments.length; _i < _len; _i++) {
2168 e = arguments[_i];
2169 _results.push(e);
2170 }
2171 return _results;
2172 }).apply(_this, arguments));
2173 }
2174 return _super.launch.call(_this, cb);
2175 };
2176 })(this)
2177 });
2178 }
2179 };
2180 }
2181 });
2182
2183}).call(this);
2184
2185(function() {
2186 String.template = (function() {
2187 var $, encoder, fn, parse;
2188 parse = function(s, x) {
2189 var RE, e, lastIndex, r, r0, stack, tag, text;
2190 r = {
2191 tag: 'top',
2192 children: []
2193 };
2194 stack = [];
2195 lastIndex = 0;
2196 RE = /{{([?\/:#]?)([a-zA-Z0-9\._]+)(\|[a-z]+)?}}/g;
2197 while (e = RE.exec(s)) {
2198 if (e.index && (text = s.slice(lastIndex, +(e.index - 1) + 1 || 9e9))) {
2199 r.children.push({
2200 tag: '_',
2201 value: text
2202 });
2203 }
2204 tag = e[2];
2205 if ((e[1] === '?') || (e[1] === '#')) {
2206 stack.unshift(r);
2207 r.children.push(r0 = {
2208 tag: tag,
2209 children: [],
2210 flag: e[1]
2211 });
2212 r = r0;
2213 } else if (e[1] === '/') {
2214 r = stack.shift();
2215 } else if (e[1] === ':') {
2216 r = r['_' + tag] = {
2217 children: []
2218 };
2219 } else {
2220 r.children.push({
2221 tag: tag,
2222 opts: e[3]
2223 });
2224 }
2225 lastIndex = RE.lastIndex;
2226 }
2227 if (s = s.slice(lastIndex)) {
2228 r.children.push({
2229 tag: '_',
2230 value: s
2231 });
2232 }
2233 return r;
2234 };
2235 fn = function(node, obj) {
2236 var e, k0, n, r, tag, v, v0, _i, _j, _k, _len, _len1, _len2, _ref;
2237 r = [];
2238 if (node.children) {
2239 _ref = node.children;
2240 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2241 n = _ref[_i];
2242 if ((tag = n.tag) === '_') {
2243 r.push(n.value);
2244 } else {
2245 if ((v = tag === '.' ? obj : Object.prop(obj, tag))) {
2246 if (Array.isArray(v)) {
2247 if (v.length) {
2248 if (n.flag === '?') {
2249 r.push(fn(n, obj));
2250 } else {
2251 for (_j = 0, _len1 = v.length; _j < _len1; _j++) {
2252 e = v[_j];
2253 if (e) {
2254 r.push(fn(n, e));
2255 }
2256 }
2257 }
2258 } else {
2259 if (n._else) {
2260 r.push(fn(n._else, n.flag === '?' ? obj : v));
2261 }
2262 }
2263 } else {
2264 r.push(fn(n, n.flag === '?' ? obj : v));
2265 }
2266 } else {
2267 if (n.flag === '#') {
2268 if (v) {
2269 for (v0 = _k = 0, _len2 = v.length; _k < _len2; v0 = ++_k) {
2270 k0 = v[v0];
2271 if (v0) {
2272 r.push(fn(n, {
2273 id: k0,
2274 value: v0
2275 }));
2276 }
2277 }
2278 }
2279 } else {
2280 if (n._else) {
2281 r.push(fn(n._else, n.flag === '?' ? obj : v));
2282 }
2283 }
2284 }
2285 }
2286 }
2287 } else {
2288 r.push($.writeValue(obj, r, node.opts));
2289 }
2290 return r.join('');
2291 };
2292 $ = function(s, obj) {
2293 return fn(parse(s), obj);
2294 };
2295 $.filters = {
2296 t: function(t) {
2297 return String.localize(t);
2298 },
2299 d: function(d) {
2300 return Date.format(d);
2301 }
2302 };
2303 encoder = function(i) {
2304 return '&#' + i.charCodeAt(0) + ';';
2305 };
2306 $.writeValue = function(obj, r, opts) {
2307 var f, fn0, _i, _len;
2308 if (opts) {
2309 for (_i = 0, _len = opts.length; _i < _len; _i++) {
2310 f = opts[_i];
2311 if (fn0 = this.filters[f]) {
2312 obj = fn0(obj);
2313 }
2314 }
2315 }
2316 r = '' + obj;
2317 if (!(opts && opts.indexOf('u'))) {
2318 r = r.replace(/[\u00A0-\u9999<>\&]/g, encoder);
2319 }
2320 return r;
2321 };
2322 return $;
2323 })();
2324
2325}).call(this);
2326
2327(function() {
2328 var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
2329 __hasProp = {}.hasOwnProperty;
2330
2331 Object.emit({
2332 uri: "axoid://define/Property/Value",
2333 mixin: function(_super) {
2334 return {
2335 getValue: function() {
2336 return this.prop("value");
2337 },
2338 setValue: function(v) {
2339 return this.prop("value", v);
2340 },
2341 isEmptyValue: function(e) {
2342 return !this.getValue();
2343 },
2344 equalsToValue: function(v) {
2345 return v && (this.getValue() === ("" + v));
2346 }
2347 };
2348 }
2349 });
2350
2351 Object.emit({
2352 uri: "axoid://define/Property/MultiValue",
2353 mixin: function(_super) {
2354 return {
2355 valueChanged: function(v) {
2356 this.prop("mvalue", (v ? (v.split && v.length ? v.split(this.mvalueSeparator || ",") : ["" + v]) : []));
2357 _super.valueChanged.apply(this, arguments);
2358 },
2359 getMultiValue: function() {
2360 return this.mvalue || [];
2361 },
2362 equalsValue: function(v) {
2363 var _ref;
2364 return v && (_ref = "" + v, __indexOf.call(this.getMultiValue(), _ref) >= 0);
2365 },
2366 putIntoMultiValue: function(pk, v) {
2367 var changed, contained, i, mv, _i, _len;
2368 if (!pk) {
2369 return;
2370 }
2371 mv = this.getMultiValue();
2372 pk = "" + pk;
2373 contained = __indexOf.call(mv, pk) >= 0;
2374 changed = false;
2375 if (v === -1) {
2376 v = (contained ? 0 : 1);
2377 }
2378 if (v && !contained) {
2379 mv.push(pk);
2380 changed = true;
2381 }
2382 if ((!v) && contained) {
2383 for (i = _i = 0, _len = mv.length; _i < _len; i = ++_i) {
2384 pk = mv[i];
2385 if (pk === mv[i]) {
2386 mv.splice(i, 1);
2387 changed = true;
2388 break;
2389 }
2390 }
2391 }
2392 return changed && this.setValue(mv.sort().join(this.mvalueSeparator));
2393 }
2394 };
2395 }
2396 });
2397
2398
2399 /*
2400 * Defines [Values] property that is a values bundle.
2401 */
2402
2403 Object.emit({
2404 uri: "axoid://define/Property/Values",
2405 methods: function() {
2406 return {
2407 comparator: function() {
2408 return false;
2409 }
2410 };
2411 },
2412 mixin: function(_super, property) {
2413 return {
2414 prop: function(key, value, opts) {
2415 var isRegisteredProperty, _ref;
2416 if (this.isDone) {
2417 return null;
2418 }
2419 isRegisteredProperty = this.constructor.properties[key.slice(-3) === 'Uri' ? key.slice(0, -3) : key];
2420 if (arguments.length === 1) {
2421 return (isRegisteredProperty ? _super.prop.call(this, key) : (_ref = this.value) != null ? _ref[key] : void 0);
2422 }
2423 if (isRegisteredProperty) {
2424 return _super.prop.call(this, key, (key === 'value' ? Object.clone(value) : value), opts);
2425 } else {
2426 if (!this.value) {
2427 this.value = {};
2428 }
2429 if (this.value[key] !== value) {
2430 this.value[key] = value;
2431 return this.propertyChanged.call(this, {
2432 entity: this,
2433 propId: key,
2434 value: value,
2435 oldValue: this.value[key]
2436 });
2437 }
2438 }
2439 },
2440 propertyChanged: function(ev) {
2441 var isRegisteredProperty, key, olds, p, v, _ref, _ref1;
2442 _super.propertyChanged.call(this, ev);
2443 key = ev.propId;
2444 if (key === 'valueUri') {
2445 return;
2446 }
2447 if (key === 'value') {
2448 olds = ev.oldValue;
2449 if (olds) {
2450 for (p in olds) {
2451 if (!__hasProp.call(olds, p)) continue;
2452 v = olds[p];
2453 if (((_ref = ev.value) != null ? _ref[p] : void 0) === void 0) {
2454 _super.propertyChanged.call(this, {
2455 entity: this,
2456 propId: p,
2457 value: null,
2458 oldValue: v
2459 });
2460 }
2461 }
2462 }
2463 if (ev.value) {
2464 _ref1 = ev.value;
2465 for (p in _ref1) {
2466 if (!__hasProp.call(_ref1, p)) continue;
2467 v = _ref1[p];
2468 if (v !== (olds != null ? olds[p] : void 0)) {
2469 _super.propertyChanged.call(this, {
2470 entity: this,
2471 propId: p,
2472 value: v,
2473 oldValue: olds != null ? olds[p] : void 0
2474 });
2475 }
2476 }
2477 }
2478 } else {
2479 if (!(isRegisteredProperty = this.constructor.properties[key.slice(-3) === 'Uri' ? key.slice(0, -3) : key])) {
2480 _super.propertyChanged.call(this, {
2481 entity: this,
2482 propId: 'value',
2483 value: this.value,
2484 oldValue: this.value
2485 });
2486 }
2487 }
2488 return ev;
2489 }
2490 };
2491 }
2492 });
2493
2494}).call(this);