diff --git a/.gitignore b/.gitignore index eb4ef50..976567e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,14 @@ node_modules test/config.js -package-lock.json Archiv.zip node.js +**/old_* +.vscode +**/config.ts +**/*.test.js* +**/*.test.d.ts +**/config.ts +**/config.js +**/config.d.ts +**/config.js.map +dist/test/ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..af6434b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib" +} \ No newline at end of file diff --git a/client_testing/index.html b/client_testing/index.html deleted file mode 100644 index 6322723..0000000 --- a/client_testing/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - -
- - - - - - - - - - - - \ No newline at end of file diff --git a/dist/es2015/livingsdk.d.ts b/dist/es2015/livingsdk.d.ts new file mode 100644 index 0000000..aa527ac --- /dev/null +++ b/dist/es2015/livingsdk.d.ts @@ -0,0 +1,26 @@ +import { AxiosResponse } from 'axios'; +export declare type Auth_Token = string; +export declare type LivingApi = any; +export declare type LAPIRecord = any; +export interface LivingSDKOptions { + url?: string; + loginRequired?: boolean; +} +export declare class LivingSDK { + private _password; + private _userName; + private _options; + private hostName; + private session; + constructor(options?: LivingSDKOptions, username?: string, password?: string); + login(): Promise; + get(appId: string, templateName?: string): Promise; + _insert(app: any, values: any): Promise; + _update(record: LAPIRecord, values: any): Promise<{ + HTTPstatusCode: number; + recordid: any; + Record: any; + }>; + _delete(record: LAPIRecord): Promise>; +} +export default LivingSDK; diff --git a/dist/es2015/livingsdk.js b/dist/es2015/livingsdk.js new file mode 100644 index 0000000..f193b30 --- /dev/null +++ b/dist/es2015/livingsdk.js @@ -0,0 +1,150 @@ +import axios from 'axios'; +import livingApi from './modules/livingapi'; +import { ul4 } from './modules/ul4'; +import * as https from 'https'; +let commonjs = (typeof module === 'object' && module.exports); +export class LivingSDK { + constructor(options = {}, username, password) { + this._password = password || ''; + this._userName = username || ''; + this._options = { + url: options.url || 'https://my.living-apps.de', + loginRequired: options.loginRequired !== undefined ? options.loginRequired : true + }; + this._options.url = this._options.url.lastIndexOf('/') === this._options.url.length - 1 ? this._options.url : `${this._options.url}/`; + this.hostName = this._options.url.split('//')[1].substr(0, this._options.url.split('//')[1].length - 1); + if (this._options.loginRequired && !this._userName) { + throw new Error('[LivingSDK] You want to login without a username'); + } + this.session = this.login(); + } + login() { + if (!this._options.loginRequired) { + return Promise.resolve(undefined); + } + let url = `https://${this.hostName}/gateway/login`; + return axios.post(url, { + username: this._userName, + password: this._password + }, { + httpsAgent: commonjs ? new https.Agent({ + ecdhCurve: 'auto' + }) : undefined, + headers: { + "Content-Type": "application/json" + } + }) + .then((a) => a.data.auth_token); + } + get(appId, templateName) { + return this.session.then((auth_token) => { + return axios.get(`https://${this.hostName}/gateway/apps/${appId}${templateName !== undefined ? '?template=' + templateName : ''}`, { + httpsAgent: commonjs ? new https.Agent({ + ecdhCurve: 'auto' + }) : undefined, + headers: { + 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '', + Accept: 'application/la-ul4on' + } + }) + .then((res) => { + let dump; + dump = ul4.loads(res.data); + dump.get('globals').Login = this; + return dump; + }); + }); + } + _insert(app, values) { + return this.session.then((auth_token) => { + let fields = {}; + for (let ident in values) { + if (!app.controls.has(ident)) { + throw new Error(`insert() got an unexpected keyword argument ${ident}`); + } + fields[ident] = app.controls.get(ident).asjson(values[ident]); + } + let data = {}; + { + } + data.id = app.id; + data.data = [{ 'fields': fields }]; + return axios.post(`https://${this.hostName}/gateway/v1/appdd/${app.id}.json`, { + appdd: data + }, { + httpsAgent: commonjs ? new https.Agent({ + ecdhCurve: 'auto' + }) : undefined, + headers: { + 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '', + } + }) + .then((res) => { + return { + HTTPstatusCode: res.status, + recordid: res.data.id, + Record: new livingApi.Record({ + id: res.data.id, + createdat: new Date(Date.now()), + updatedat: null, + updatedby: null, + updatecount: 0 + }) + }; + }); + }); + } + _update(record, values) { + return this.session.then((auth_token) => { + let fields = {}; + let app = record.app; + for (let ident in values) { + if (!app.controls.has(ident)) { + throw new Error(`update() got an unexpected keyword argument ${ident}`); + } + fields[ident] = values[ident]; + } + let data = {}; + data.id = app.id; + data.data = [{ 'id': record.id, 'fields': fields }]; + console.log(`https://${this.hostName}/gateway/v1/appdd/${app.id}.json`); + return axios.post(`https://${this.hostName}/gateway/v1/appdd/${app.id}.json`, { + appdd: data + }, { + httpsAgent: commonjs ? new https.Agent({ + ecdhCurve: 'auto' + }) : undefined, + headers: { + 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '', + 'Content-Type': 'application/json' + } + }) + .then((res) => { + let body = res.data; + for (let ident in values) + record.fields.get(ident).value = values[ident]; + let returnObj = { + HTTPstatusCode: res.status, + recordid: body.id, + Record: record + }; + return returnObj; + }); + }); + } + _delete(record) { + let app = record.app; + return this.session.then((auth_token) => { + return axios.delete(`https://${this.hostName}/gateway/v1/appdd/${app.id}/${record.id}.json`, { + httpsAgent: commonjs ? new https.Agent({ + ecdhCurve: 'auto' + }) : undefined, + headers: { + 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '', + } + }); + }); + } +} +export default LivingSDK; +//# sourceMappingURL=livingsdk.js.map \ No newline at end of file diff --git a/dist/es2015/livingsdk.js.map b/dist/es2015/livingsdk.js.map new file mode 100644 index 0000000..9bb5d3f --- /dev/null +++ b/dist/es2015/livingsdk.js.map @@ -0,0 +1 @@ +{"version":3,"file":"livingsdk.js","sourceRoot":"","sources":["../../src/livingsdk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAE7C,OAAO,SAAS,MAAM,qBAAqB,CAAC;AAE5C,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,IAAI,QAAQ,GAAG,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;AAM9D,MAAM;IAML,YAAY,UAA4B,EAAE,EAAE,QAAiB,EAAE,QAAiB;QAE/E,IAAI,CAAC,SAAS,GAAG,QAAQ,IAAI,EAAE,CAAC;QAEhC,IAAI,CAAC,SAAS,GAAG,QAAQ,IAAI,EAAE,CAAC;QAEhC,IAAI,CAAC,QAAQ,GAAG;YAEf,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,2BAA2B;YAE/C,aAAa,EAAE,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI;SACjF,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC;QACtI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxG,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnD,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;SACnE;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAMD,KAAK;QACJ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE;YACjC,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;SAClC;QACD,IAAI,GAAG,GAAG,WAAW,IAAI,CAAC,QAAQ,gBAAgB,CAAC;QACnD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE;YACtB,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,QAAQ,EAAE,IAAI,CAAC,SAAS;SACxB,EAAE;YACD,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC;gBACtC,SAAS,EAAE,MAAM;aACjB,CAAC,CAAC,CAAC,CAAC,SAAS;YACd,OAAO,EAAE;gBACR,cAAc,EAAE,kBAAkB;aAClC;SACD,CAAC;aACD,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,GAAG,CAAC,KAAa,EAAE,YAAqB;QACvC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAkC,EAAE,EAAE;YAC/D,OAAO,KAAK,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,QAAQ,iBAAiB,KAAK,GAAG,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,EAChI;gBACC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC;oBACtC,SAAS,EAAE,MAAM;iBACjB,CAAC,CAAC,CAAC,CAAC,SAAS;gBACd,OAAO,EAAE;oBACR,iBAAiB,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;oBAC7D,MAAM,EAAE,sBAAsB;iBAC9B;aACD,CAAC;iBACD,IAAI,CAAC,CAAC,GAAkB,EAAE,EAAE;gBAC5B,IAAI,IAAS,CAAC;gBACd,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC3B,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC;gBACjC,OAAkB,IAAI,CAAC;YACxB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAQ,EAAE,MAAW;QAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE;YAEvC,IAAI,MAAM,GAAQ,EAAE,CAAC;YAErB,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE;gBACzB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;oBAC7B,MAAM,IAAI,KAAK,CAAC,+CAA+C,KAAK,EAAE,CAAC,CAAC;iBACxE;gBAED,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;aAC9D;YACD,IAAI,IAAI,GAAQ,EAAE,CAAC;YAAC;aACnB;YACD,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YACnC,OAAO,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,QAAQ,qBAAqB,GAAG,CAAC,EAAE,OAAO,EAAE;gBAC7E,KAAK,EAAE,IAAI;aACX,EAAE;gBACD,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC;oBACtC,SAAS,EAAE,MAAM;iBACjB,CAAC,CAAC,CAAC,CAAC,SAAS;gBACd,OAAO,EAAE;oBACR,iBAAiB,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;iBAC7D;aACD,CAAC;iBACD,IAAI,CAAC,CAAC,GAAkB,EAAE,EAAE;gBAC5B,OAAO;oBACN,cAAc,EAAE,GAAG,CAAC,MAAM;oBAC1B,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE;oBACrB,MAAM,EAAE,IAAI,SAAS,CAAC,MAAM,CAAC;wBAC5B,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE;wBACf,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;wBAC/B,SAAS,EAAE,IAAI;wBACf,SAAS,EAAE,IAAI;wBACf,WAAW,EAAE,CAAC;qBACd,CAAC;iBACF,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IAEH,CAAC;IAED,OAAO,CAAC,MAAkB,EAAE,MAAW;QACtC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAkC,EAAE,EAAE;YAC/D,IAAI,MAAM,GAAQ,EAAE,CAAC;YACrB,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;YACrB,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE;gBACzB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;oBAC7B,MAAM,IAAI,KAAK,CAAC,+CAA+C,KAAK,EAAE,CAAC,CAAC;iBACxE;gBACD,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;aAC9B;YACD,IAAI,IAAI,GAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,QAAQ,qBAAqB,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;YACxE,OAAO,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,QAAQ,qBAAqB,GAAG,CAAC,EAAE,OAAO,EAAE;gBAC7E,KAAK,EAAE,IAAI;aACX,EAAE;gBACD,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC;oBACtC,SAAS,EAAE,MAAM;iBACjB,CAAC,CAAC,CAAC,CAAC,SAAS;gBACd,OAAO,EAAE;oBACR,iBAAiB,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;oBAC7D,cAAc,EAAE,kBAAkB;iBAClC;aACD,CAAC;iBACD,IAAI,CAAC,CAAC,GAAkB,EAAE,EAAE;gBAC5B,IAAI,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;gBACpB,KAAK,IAAI,KAAK,IAAI,MAAM;oBACvB,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChD,IAAI,SAAS,GAAG;oBACf,cAAc,EAAE,GAAG,CAAC,MAAM;oBAC1B,QAAQ,EAAE,IAAI,CAAC,EAAE;oBACjB,MAAM,EAAE,MAAM;iBACd,CAAC;gBACF,OAAO,SAAS,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,MAAkB;QACzB,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QACrB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAkC,EAAE,EAAE;YAC/D,OAAO,KAAK,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,QAAQ,qBAAqB,GAAG,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,OAAO,EAAE;gBAC5F,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC;oBACtC,SAAS,EAAE,MAAM;iBACjB,CAAC,CAAC,CAAC,CAAC,SAAS;gBACd,OAAO,EAAE;oBACR,iBAAiB,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;iBAC7D;aAED,CAAC,CAAA;QACH,CAAC,CAAC,CAAA;IACH,CAAC;CACD;AAED,eAAe,SAAS,CAAC"} \ No newline at end of file diff --git a/dist/es2015/modules/livingapi.js b/dist/es2015/modules/livingapi.js new file mode 100644 index 0000000..8a4cb1f --- /dev/null +++ b/dist/es2015/modules/livingapi.js @@ -0,0 +1,1111 @@ +import { ul4 } from './ul4'; + +let la = {}; + + +la.Base = class Base extends ul4.Proto +{ + constructor() + { + super(); + } + + ul4ondump(encoder) + { + for (let i = 0; i < this._ul4onattrs.length; ++i) + encoder.dump(this._dumpUL4ONAttr(this._ul4onattrs[i])); + } + + _dumpUL4ONAttr(name) + { + return this[name]; + } + + ul4onload(decoder) + { + let i = 0; + for (let iter = decoder.loadcontent(); ; ++i) + { + let iteritem = iter.next(); + if (iteritem.done) + break; + if (i < this._ul4onattrs.length) + this._loadUL4ONAttr(this._ul4onattrs[i], iteritem.value); + } + for (; i < this._ul4onattrs.length; ++i) + this._setDefaultUL4ONAttr(this._ul4onattrs[i]); + } + + _loadUL4ONAttr(name, value) + { + this[name] = value; + } + + _setDefaultUL4ONAttr(name) + { + this[name] = null; + } + + __getattr__(name) + { + if (this._ul4attrs.has(name)) + { + let value = this[name]; + if (typeof(value) === "function") + { + let realvalue = value.bind(this); + realvalue._ul4_name = value._ul4_name || value.name; + realvalue._ul4_signature = value._ul4_signature; + realvalue._ul4_needsobject = value._ul4_needsobject; + realvalue._ul4_needscontext = value._ul4_needscontext; + return realvalue; + } + return value; + } + throw new ul4.AttributeError(this, name); + } + + __repr__() + { + return ""; + } +}; + +la.Handler = class Handler +{ + save(record) + { + } + + delete(record) + { + } +}; + +la.Globals = class Globals extends la.Base +{ + constructor() + { + super(); + this.version = null; + this.platform = null; + this.user = null; + this.maxdbactions = null; + this.maxtemplateruntime = null; + this.flashmessages = null; + this.handler = new la.Handler(); + } + + // distance between two geo coordinates (see https://de.wikipedia.org/wiki/Orthodrome#Genauere_Formel_zur_Abstandsberechnung_auf_der_Erde) + static geodist(geo1, geo2) + { + let sqsin = function sqsin(x) {x = Math.sin(x); return x*x}; + let sqcos = function sqsos(x) {x = Math.cos(x); return x*x}; + const deg2rad = Math.PI/180; // Conversion factor degree -> radians + const radius = 6378.137; // Equatorial radius of earth in km + const flat = 1/298.257223563; // Earth flattening + + const lat1 = geo1.lat * deg2rad; + const long1 = geo1.long * deg2rad; + const lat2 = geo2.lat * deg2rad; + const long2 = geo2.long * deg2rad; + const F = (lat1 + lat2)/2; + const G = (lat1 - lat2)/2; + const l = (long1 - long2)/2; + const S = sqsin(G) * sqcos(l) + sqcos(F) * sqsin(l); + const C = sqcos(G) * sqcos(l) + sqsin(F) * sqsin(l); + const w = Math.atan(Math.sqrt(S/C)); + const D = 2 * w * radius; + const T = Math.sqrt(S*C)/w; + const H1 = (3*T-1)/(2*C); + const H2 = (3*T+1)/(2*S); + const s = D * (1 + flat * H1 * sqsin(F) * sqcos(G) - flat * H2 * sqcos(F) * sqsin(G)); + return s; + } + + __repr__() + { + return ""; + } +}; + +la.Globals.prototype._ul4onattrs = ["version", "platform", "user", "maxdbactions", "maxtemplateruntime", "flashmessages"]; +la.Globals.prototype._ul4attrs = ul4._makeset("version", "platform", "user", "maxdbactions", "maxtemplateruntime", "flashmessages"); + +la.FlashMessage = class FlashMessage extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.FlashMessage.prototype._ul4onattrs = ["timestamp", "type", "title", "message"]; +la.FlashMessage.prototype._ul4attrs = ul4._makeset("timestamp", "type", "title", "message"); + +la.App = class App extends la.Base +{ + __repr__() + { + return ""; + } + + insert(values={}) + { + let record = this.__call__(values); + this.globals.handler.save(this); + return this.globals.Login._insert(this, values); + } + + __call__(values={}) + { + let record = new la.Record(this); + if (ul4._ismap(values)) + { + for (let [key, value] of values.entries()) + { + if (!record.fields.has(key)) + throw new ul4.ArgumentError("update() get an unexpected keyword argument " + ul4._repr(key)); + record.fields.get(key).value = value; + } + } + else if (ul4._isobject(values)) + { + for (let key in values) + { + if (!record.fields.has(key)) + throw new ul4.ArgumentError("update() get an unexpected keyword argument " + ul4._repr(key)); + record.fields.get(key).value = values[key]; + } + } + else + throw new ul4.TypeError("values must be an object or a Map"); + return record; + } + + __getattr__(name) + { + if (name.startsWith("c_")) + { + if (!this.controls.has(name.substr(2))) + throw new ul4.AttributeError(this, name); + return this.controls.get(name.substr(2)); + } + else + return super.__getattr__(name); + } +}; + +la.App.prototype._ul4onattrs = ["id", "globals", "name", "description", "language", "startlink", "iconlarge", "iconsmall", "createdby", "controls", "records", "recordcount", "installation", "categories", "params", "views", "datamanagement_identifier", "basetable", "primarykey", "insertprocedure", "updateprocedure", "deleteprocedure", "templates", "createdat", "updatedat", "updatedby"]; +la.App.prototype._ul4attrs = ul4._makeset("id", "globals", "name", "description", "language", "startlink", "iconlarge", "iconsmall", "createdat", "createdby", "updatedat", "updatedby", "controls", "records", "recordcount", "installation", "categories", "params", "views", "datamanagement_identifier", "insert"); +ul4.expose(la.App.prototype.__call__, ["**values"], {"needsobject": true}); +ul4.expose(la.App.prototype.insert, ["**values"], {"needsobject": true}); + +la.View = class View extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.View.prototype._ul4onattrs = ["id", "name", "app", "order", "width", "height", "start", "end"]; +la.View.prototype._ul4attrs = ul4._makeset("id", "name", "app", "order", "width", "height", "start", "end"); + +la.DataSourceData = class DataSourceData extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.DataSourceData.prototype._ul4onattrs = ["id", "identifier", "app", "apps"]; +la.DataSourceData.prototype._ul4attrs = ul4._makeset("id", "identifier", "app", "apps"); + +la.Record = class Record extends la.Base +{ + constructor(app) + { + super(); + this.id = null; + this.app = app; + this.createdat = null; + this.createdby = null; + this.updatedat = null; + this.updatedby = null; + this.updatecount = 0; + this._sparsevalues = new Map(); + this._values = null; + this._fields = null; + this.children = new Map(); + this.attachments = null; + this.errors = []; + this._is_deleted = false; + } + + + + __repr__() + { + let v = ["") + return v.join(""); + } + + get values() + { + if (this._values === null) + { + this._values = ul4._havemap ? new Map() : {}; + for (let [identifier, control] of this.app.controls.entries()) + { + let fieldvalue = this._sparsevalues.get(identifier); + if (typeof(fieldvalue) === "undefined") + fieldvalue = null; + this._values.set(identifier, fieldvalue); + } + } + return this._values; + } + + get fields() + { + if (this._fields === null) + { + this._fields = ul4._havemap ? new Map() : {}; + for (let [identifier, value] of this.values.entries()) + { + let field = new la.Field(this.app.controls.get(identifier), this, value); + this._fields.set(identifier, field); + } + } + return this._fields; + } + + is_dirty() + { + if (this.id === null) + return true; + for (let field of this.fields.values()) + { + if (field.is_dirty()) + return true; + } + return false; + } + + has_errors() + { + if (this.errors.length !== 0) + return true; + for (let field of this.fields.values()) + { + if (field.has_errors()) + return true; + } + return false; + } + + delete() + { + return this.app.globals.handler.delete(this); + } + + save() + { + this.app.globals.handler.save(this); + } + + update(values={}) + { + if (ul4._ismap(values)) + { + for (let [key, value] of values.entries()) + { + if (!this.fields.has(key)) + throw new ul4.ArgumentError("update() get an unexpected keyword argument " + ul4._repr(key)); + this.fields.get(key).value = value; + } + } + else if (ul4._isobject(values)) + { + for (let key in values) + { + if (!this.fields.has(key)) + throw new ul4.ArgumentError("update() get an unexpected keyword argument " + ul4._repr(key)); + this.fields.get(key).value = values[key]; + } + } + else + throw new ul4.TypeError("values must be an object or a Map"); + + this.app.globals.handler.save(this); + return this.app.globals.Login._update(this, values); + } + + search(search) + { + for (let identifier in search) + { + let fieldsearch = search[identifier]; + if (ul4._bool(fieldsearch)) + { + if (!this.fields.get(identifier).search(fieldsearch)) + return false; + } + } + return true; + } + + _dumpUL4ONAttr(name) + { + if (name === "values") + return this._sparsevalues; + else + return this[name]; + } + + _loadUL4ONAttr(name, value) + { + if (name === "values") + { + this._sparsevalues = value; + this._values = null; + this._fields = null; + } + else + this[name] = value; + } + + __getattr__(name) + { + if (name.startsWith("c_")) + return this.children.get(name.substr(2)) + else if (name.startsWith("f_")) + return this.fields.get(name.substr(2)) + else if (name.startsWith("v_")) + return this.values.get(name.substr(2)) + else + return this[name]; + } + + __setattr__(name, value) + { + if (name.startsWith("c_")) + this.children[name.substr(2)] = value; + else if (name.startsWith("v_")) + this.fields.get(name.substr(2)).value = value; + else + throw new ul4.AttributeError(this, name); + } +}; + +la.Record.prototype._ul4onattrs = ["id", "app", "createdat", "createdby", "updatedat", "updatedby", "updatecount", "values", "attachments", "children"]; +la.Record.prototype._ul4attrs = ul4._makeset("id", "app", "createdat", "createdby", "updatedat", "updatedby", "updatecount", "values", "attachments", "children"); +ul4.expose(la.Record.prototype.is_dirty, []); +ul4.expose(la.Record.prototype.has_errors, []); +ul4.expose(la.Record.prototype.delete, []); +ul4.expose(la.Record.prototype.save, []); +ul4.expose(la.Record.prototype.update, ["**values"], {"needsobject": true}); + +la.Control = class Control extends la.Base +{ + __repr__() + { + return ""; + } + + _logsearch(value, search) + { + //console.log("Searching for " + ul4._repr(search.value) + " in " + ul4._repr(this) + " with operator " + search.operator + " in value " + ul4._repr(value)); + } + + + asjson(value) { + return value; + } + + // base implemntation, always returns ``false`` (i.e. "not found") + // ``value`` is the value of the field + // ``search`` is an object with information what we're searching for + // keys in ``search`` are: ``operator`` (and ``value`` (if required by the operator)) + search(value, search) + { + return false; + } +}; + +la.Control.prototype.type = null; +la.Control.prototype.subtype = null; +la.Control.prototype._ul4onattrs = ["id", "identifier", "field", "app", "label", "priority", "order", "default", "ininsertprocedure", "inupdateprocedure"]; +la.Control.prototype._ul4attrs = ul4._makeset("id", "identifier", "field", "app", "label", "priority", "order", "default", "ininsertprocedure", "inupdateprocedure"); + +la.BoolControl = class BoolControl extends la.Control +{ + // ``search`` must by ``null``, ``false`` or ``true`` + search(value, search) + { + this._logsearch(value, search); + if (search.operator === "equals") + return search.value === value; + else + return false; + } +}; + +la.BoolControl.prototype.type = "bool"; + +la.IntControl = class IntControl extends la.Control +{ + // ``search.value`` must by ``null`` or an integer + search(value, search) + { + this._logsearch(value, search); + if (search.operator === "equals") + return search.value === value; + else + return false; + } +}; + +la.IntControl.prototype.type = "int"; + +la.NumberControl = class NumberControl extends la.Control +{ + // ``search.value`` must by ``null`` or an integer + search(value, search) + { + this._logsearch(value, search); + if (search.operator === "equals") + return search.value === value; + else if (search.operator === "range") + { + if (value === null) + return false; + return (search.minvalue === null || search.minvalue <= value) && (search.maxvalue === null || value < search.maxvalue); + } + else + return false; + } +}; + +la.NumberControl.prototype.type = "number"; + +la.StringControl = class StringControl extends la.Control +{ + + asjson(value) { + return value; + } + + search(value, search) + { + this._logsearch(value, search); + if (search.operator === "equals") + return search.value === value; + else if (search.operator === "contains") + { + if (search.value === null || value === null) + return search.value === value; + else + return value.toLowerCase().indexOf(search.value.toLowerCase()) >= 0; + } + } +}; + +la.StringControl.prototype.type = "string"; + +la.TextControl = class TextControl extends la.StringControl +{ +}; + +la.TextControl.prototype.subtype = "text"; + +la.EmailControl = class EmailControl extends la.StringControl +{ +}; + +la.EmailControl.prototype.subtype = "email"; + +la.URLControl = class URLControl extends la.StringControl +{ +}; + +la.URLControl.prototype.subtype = "url"; + +la.TelControl = class TelControl extends la.StringControl +{ +}; + +la.TelControl.prototype.subtype = "tel"; + +la.PasswordControl = class PasswordControl extends la.StringControl +{ +}; + +la.PasswordControl.prototype.subtype = "password"; + +la.TextAreaControl = class TextAreaControl extends la.StringControl +{ +}; + +la.TextAreaControl.prototype.subtype = "textarea"; +la.TextAreaControl.prototype._ul4onattrs = la.StringControl.prototype._ul4onattrs.concat(["encrypted"]); +la.TextAreaControl.prototype._ul4attrs = ul4._makeset(...la.StringControl.prototype._ul4attrs, "encrypted"); + +la.DateControl = class DateControl extends la.Control +{ + formatstring(language) + { + language = language || this.app.language; + + if (language === "de") + return "%d.%m.%Y"; + else + return "%m/%d/%Y"; + } + + asjson(value) { + return value; + } + + // searchvalue must be ``null``, a ``Date`` object or a string + search(value, search) + { + this._logsearch(value, search); + + let searchvalue = search.value; + if (Object.prototype.toString.call(searchvalue) == "[object Date]") + searchvalue = ul4._format(searchvalue, this.formatstring(), this.app.language); + if (value !== null) + value = ul4._format(value, this.formatstring(), this.app.language); + + if (search.operator === "equals") + return searchvalue === value; + else if (search.operator === "contains") + { + if (searchvalue === null || value === null) + return searchvalue === value; + else + return value.toLowerCase().indexOf(searchvalue.toLowerCase()) >= 0; + } + else + return false; + } +}; + +la.DateControl.prototype.type = "date"; +la.DateControl.prototype.subtype = "date"; + +la.DatetimeMinuteControl = class DatetimeMinuteControl extends la.DateControl +{ + formatstring(language) + { + language = language || this.app.language; + + if (language === "de") + return "%d.%m.%Y %H:%M"; + else + return "%m/%d/%Y %H:%M"; + } +}; + +la.DatetimeMinuteControl.prototype.subtype = "datetimeminute"; + +la.DatetimeSecondControl = class DatetimeSecondControl extends la.DateControl +{ + formatstring(language) + { + language = language || this.app.language; + + if (language === "de") + return "%d.%m.%Y %H:%M:%S"; + else + return "%m/%d/%Y %H:%M:%S"; + } +}; + +la.DatetimeSecondControl.prototype.subtype = "datetimesecond"; + +la.LookupControl = class LookupControl extends la.Control +{ + // ``search.value`` must be ``null`` or a ``LookupItem`` key + search(value, search) + { + if (search.operator === "equals") + { + if (value === null) + return search.value === null; + else + return value.key === search.value; + } + else + return false; + } +}; + +la.LookupControl.prototype.type = "lookup"; +la.LookupControl.prototype._ul4onattrs = la.Control.prototype._ul4onattrs.concat(["lookupdata"]); +la.LookupControl.prototype._ul4attrs = ul4._makeset(...la.Control.prototype._ul4attrs, "lookupdata"); + +la.LookupSelectControl = class LookupSelectControl extends la.LookupControl +{ +}; + +la.LookupSelectControl.prototype.subtype = "select"; + +la.LookupRadioControl = class LookupRadioControl extends la.LookupControl +{ +}; + +la.LookupRadioControl.prototype.subtype = "radio"; + +la.LookupChoiceControl = class LookupChoiceControl extends la.LookupControl +{ +}; + +la.LookupChoiceControl.prototype.subtype = "choice"; + +la.AppLookupControl = class AppLookupControl extends la.Control +{ + // ``search.value`` must be an object containing the search criteria for the referenced record + search(value, search) + { + if (value === null || search.value === null) + return value === search.value; + else + return value.search(search); + } +}; + +la.AppLookupControl.prototype.type = "applookup"; +la.AppLookupControl.prototype._ul4onattrs = la.Control.prototype._ul4onattrs.concat(["lookupapp", "lookupcontrols"]); +la.AppLookupControl.prototype._ul4attrs = ul4._makeset(...la.Control.prototype._ul4attrs, "lookupapp", "lookupcontrols"); + +la.AppLookupSelectControl = class AppLookupSelectControl extends la.AppLookupControl +{ +}; + +la.AppLookupSelectControl.prototype.subtype = "select"; + +la.AppLookupRadioControl = class AppLookupRadioControl extends la.AppLookupControl +{ +}; + +la.AppLookupRadioControl.prototype.subtype = "radio"; + +la.AppLookupChoiceControl = class AppLookupChoiceControl extends la.AppLookupControl +{ +}; + +la.AppLookupChoiceControl.prototype.subtype = "choice"; + +la.MultipleLookupControl = class MultipleLookupControl extends la.LookupControl +{ + // search.value must be ``null`` or a ``LookupItem`` key + search(value, search) + { + if (search.operator === "equals") + { + for (let item of value) + { + if (item.key === search.value) + return true; + } + return false; + } + else + return false; + } +}; + +la.MultipleLookupControl.prototype.subtype = "multiplelookup"; + +la.MultipleLookupSelectControl = class MultipleLookupSelectControl extends la.MultipleLookupControl +{ +}; + +la.MultipleLookupSelectControl.prototype.subtype = "select"; + +la.MultipleLookupCheckboxControl = class MultipleLookupCheckboxControl extends la.MultipleLookupControl +{ +}; + +la.MultipleLookupCheckboxControl.prototype.subtype = "checkbox"; + +la.MultipleLookupChoiceControl = class MultipleLookupChoiceControl extends la.MultipleLookupControl +{ +}; + +la.MultipleLookupChoiceControl.prototype.subtype = "choice"; + +la.MultipleAppLookupControl = class MultipleAppLookupControl extends la.AppLookupControl +{ + // ``search.value`` must be an object containing the search criteria for the referenced record + search(value, search) + { + if (search.operator === "equals") + { + if (search.value === null) + return value.length === 0; + else + { + for (let item of value) + { + if (item.search(search.value)) + return true; + } + return false; + } + } + else + return false; + } +}; + +la.MultipleAppLookupControl.prototype.type = "multipleapplookup"; + +la.MultipleAppLookupSelectControl = class MultipleAppLookupSelectControl extends la.MultipleAppLookupControl +{ +}; + +la.MultipleAppLookupSelectControl.prototype.subtype = "select"; + +la.MultipleAppLookupCheckboxControl = class MultipleAppLookupCheckboxControl extends la.MultipleAppLookupControl +{ +}; + +la.MultipleAppLookupCheckboxControl.prototype.subtype = "checkbox"; + +la.MultipleAppLookupChoiceControl = class MultipleAppLookupChoiceControl extends la.MultipleAppLookupControl +{ +}; + +la.MultipleAppLookupChoiceControl.prototype.subtype = "choice"; + +la.GeoControl = class GeoControl extends la.Control +{ + asjson (value) { + if (value instanceof la.Geo) + value = `${value.lat}, ${value.long}, ${value.info}`; + return value; + } +}; + +la.GeoControl.prototype.type = "geo"; + +la.FileControl = class FileControl extends la.Control +{ +}; + +la.FileControl.prototype.type = "file"; + +la.ButtonControl = class ButtonControl extends la.Control +{ +}; + +la.ButtonControl.prototype.type = "button"; + +la.Field = class Field extends la.Base +{ + constructor(control, record, value) + { + super(); + this.control = control; + this.record = record; + this._value = value; + this._dirty = false; + this.errors = []; + } + + get value() + { + return this._value; + } + + set value(value) + { + let oldvalue = this._value; + + if (ul4._ne(oldvalue, value)) + { + this.record.values.set(this.control.identifier, value); + this._value = value; + this._dirty = true; + } + } + + is_empty() + { + return this._value === null || (ul4._islist(this._value) && this._value.length === 0); + } + + is_dirty() + { + return this._dirty; + } + + has_errors() + { + return this.errors.length !== 0; + } + + search(searchvalue) + { + return this.control.search(this.value, searchvalue); + } + + __repr__() + { + let s = ""; + } +}; + +la.LookupItem.prototype._ul4onattrs = ["key", "label"]; +la.LookupItem.prototype._ul4attrs = ul4._makeset("key", "label"); + +la.User = class User extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.User.prototype._ul4onattrs = ["_id", "id", "gender", "firstname", "surname", "initials", "email", "language", "avatarsmall", "avatarlarge", "keyviews"]; +la.User.prototype._ul4attrs = ul4._makeset("_id", "id", "gender", "firstname", "surname", "initials", "email", "language", "avatarsmall", "avatarlarge", "keyviews"); + +la.File = class File extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.File.prototype._ul4onattrs = ["id", "url", "filename", "mimetype", "width", "height", "internalid", "createdat", "size"]; +la.File.prototype._ul4attrs = ul4._makeset("id", "url", "filename", "mimetype", "width", "height", "size", "createdat"); + +la.Geo = class Geo extends la.Base +{ + constructor(lat, long, info) + { + super(); + this.lat = lat; + this.long = long; + this.info = info; + } + + __repr__() + { + return ""; + } +}; + +la.Geo.prototype._ul4onattrs = ["lat", "long", "info"]; +la.Geo.prototype._ul4attrs = ul4._makeset("lat", "long", "info"); + +la.Attachment = class Attachment extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.Attachment.prototype._ul4onattrs = ["id", "record", "label", "active"]; +la.Attachment.prototype._ul4attrs = ul4._makeset("id", "record", "label", "active"); + +la.NoteAttachment = class NoteAttachment extends la.Attachment +{ +}; + +la.NoteAttachment.prototype.type = "noteattachment"; +la.NoteAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat(["value"]); +la.NoteAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, "value"); + +la.URLAttachment = class URLAttachment extends la.Attachment +{ +}; + +la.URLAttachment.prototype.type = "urlattachment"; +la.URLAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat(["value"]); +la.URLAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, "value"); + +la.FileAttachment = class FileAttachment extends la.Attachment +{ +}; + +la.FileAttachment.prototype.type = "fileattachment"; +la.FileAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat(["value"]); +la.FileAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, "value"); + +la.ImageAttachment = class ImageAttachment extends la.Attachment +{ +}; + +la.ImageAttachment.prototype.type = "imageattachment"; +la.ImageAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat(["original", "thumb", "small", "medium", "large"]); +la.ImageAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, "original", "thumb", "small", "medium", "large"); + +la.JSONAttachment = class JSONAttachment extends la.Attachment +{ + _dumpUL4ONAttr(name) + { + if (name === "value") + return ul4._asjson(this.value); + else + return this[name]; + } + + _loadUL4ONAttr(name, value) + { + if (name === "value") + this.value = ul4._fromjson(value); + else + this[name] = value + } +}; + +la.JSONAttachment.prototype.type = "jsonattachment"; +la.JSONAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat(["value"]); +la.JSONAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, "value"); + +la.Installation = class Installation extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.Installation.prototype._ul4onattrs = ["id", "name"]; +la.Installation.prototype._ul4attrs = ul4._makeset("id", "name"); + +la.Category = class Category extends la.Base +{ + __repr__() + { + let v = []; + let category = this; + while (category !== null) + { + v.splice(0, 0, category.identifier); + category = category.parent; + } + return ""; + } +}; + +la.Category.prototype._ul4onattrs = ["id", "identifier", "name", "order", "parent", "children", "apps"]; +la.Category.prototype._ul4attrs = ul4._makeset("id", "identifier", "name", "order", "parent", "children", "apps"); + +la.KeyView = class KeyView extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.KeyView.prototype._ul4onattrs = ["id", "identifier", "name", "key", "user"]; +la.KeyView.prototype._ul4attrs = ul4._makeset("id", "identifier", "name", "key", "user"); + +la.AppParameter = class AppParameter extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.AppParameter.prototype._ul4onattrs = ["id", "app", "identifier", "description", "value"]; +la.AppParameter.prototype._ul4attrs = ul4._makeset("id", "app", "identifier", "description", "value"); + +let classes = [ + la.Globals, + la.App, + la.View, + la.DataSourceData, + la.Record, + la.BoolControl, + la.IntControl, + la.NumberControl, + la.TextControl, + la.EmailControl, + la.URLControl, + la.TelControl, + la.PasswordControl, + la.TextAreaControl, + la.DateControl, + la.DatetimeMinuteControl, + la.DatetimeSecondControl, + la.LookupControl, + la.LookupSelectControl, + la.LookupRadioControl, + la.LookupChoiceControl, + la.AppLookupControl, + la.AppLookupSelectControl, + la.AppLookupRadioControl, + la.AppLookupChoiceControl, + la.MultipleLookupControl, + la.MultipleLookupSelectControl, + la.MultipleLookupCheckboxControl, + la.MultipleLookupChoiceControl, + la.MultipleAppLookupControl, + la.MultipleAppLookupSelectControl, + la.MultipleAppLookupCheckboxControl, + la.MultipleAppLookupChoiceControl, + la.GeoControl, + la.FileControl, + la.ButtonControl, + la.Field, + la.LookupItem, + la.User, + la.File, + la.Geo, + la.NoteAttachment, + la.URLAttachment, + la.FileAttachment, + la.ImageAttachment, + la.JSONAttachment, + la.Installation, + la.Category, + la.KeyView, + la.AppParameter +]; + +for (let constructor of classes) +{ + // Register under the old name + ul4.register("de.livingapps.appdd." + constructor.name.toLowerCase(), constructor); + // Register under the new name + ul4.register("de.livinglogic.livingapi." + constructor.name.toLowerCase(), constructor); +} +export default la; \ No newline at end of file diff --git a/dist/es2015/modules/ul4.js b/dist/es2015/modules/ul4.js new file mode 100644 index 0000000..d8c3be2 --- /dev/null +++ b/dist/es2015/modules/ul4.js @@ -0,0 +1,9610 @@ +/*! + * UL4/UL4ON JavaScript Library + * http://www.livinglogic.de/Python/ul4c/ + * http://www.livinglogic.de/Python/ul4on/ + * + * Copyright 2011-2018 by LivingLogic AG, Bayreuth/Germany + * Copyright 2011-2018 by Walter Dörwald + * + * All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/*jslint vars: true */ +export let ul4 = {}; + +let iscommon = (typeof module === 'object' && module.exports); + + ul4.version = "46"; + + // + // UL4ON + // + + ul4._registry = {}; + + ul4._havemap = (typeof(Map) === "function" && typeof(Map.prototype.forEach) === "function"); + + ul4._havemapconstructor = (function () + { + if (ul4._havemap) + { + try + { + if (new Map([[1, 2]]).size == 1) + return true; + } + catch (error) + { + } + } + return false; + })(); + + ul4._haveset = (typeof(Set) === "function" && typeof(Set.prototype.forEach) === "function"); + + ul4._havesetconstructor = (function () + { + if (ul4._haveset) + { + try + { + if (new Set([1, 2]).size == 2) + return true; + } + catch (error) + { + } + return false; + } + else + return false; + })(); + + // helper functions that work with Maps and objects + if (ul4._havemap) + { + ul4._makemap = function _makemap(...items) + { + let map = new Map(); + + for (let i = 0; i < items.length; ++i) + { + let [key, value] = items[i]; + map.set(key, value); + } + return map; + }; + + ul4._setmap = function _setmap(map, key, value) + { + if (map.__proto__ === Map.prototype) + map.set(key, value); + else + map[key] = value; + }; + + ul4._emptymap = function _emptymap() + { + return new Map(); + }; + + ul4._getmap = function _getmap(map, key, value) + { + if (map.__proto__ === Map.prototype) + return map.get(key); + else + return map[key]; + }; + } + else + { + ul4._makemap = function _makemap(...items) + { + let map = {}; + + for (let i = 0; i < items.length; ++i) + { + let [key, value] = items[i]; + map[key] = value; + } + return map; + }; + + ul4._setmap = function _setmap(map, key, value) + { + map[key] = value; + }; + + ul4._emptymap = function _emptymap() + { + return {}; + }; + + ul4._getmap = function _getmap(map, key, value) + { + return map[key]; + }; + } + + // Function used for making sets, when the Set constructor doesn't work (or we don't have sets) + if (ul4._haveset) + { + ul4._emptyset = function _emptyset() + { + return new Set(); + }; + } + else + { + ul4._emptyset = function _emptyset() + { + return new ul4._Set(); + }; + } + + ul4._makeset = function _makeset(...items) + { + let set = ul4._emptyset(); + + for (let i = 0; i < items.length; ++i) + set.add(items[i]); + return set; + }; + + // Register the constructor function ``f`` under the name ``name`` with the UL4ON machinery + ul4.register = function register(name, f) + { + f.prototype.ul4onname = name; + ul4._registry[name] = f; + }; + + // Return a string that contains the object ``obj`` in the UL4ON serialization format + ul4.dumps = function dumps(obj, indent) + { + let encoder = new ul4.Encoder(indent); + encoder.dump(obj); + return encoder.finish(); + }; + + // Load an object from the string ``data``. + // ``data`` must contain the object in the UL4ON serialization format + // ``registry`` may be null or a dictionary mapping type names to constructor functions + ul4.loads = function loads(data, registry) + { + let decoder = new ul4.Decoder(data, registry); + return decoder.load(); + }; + + // Helper class for encoding + ul4.Encoder = class Encoder + { + // Create a new Encoder object + constructor(indent=null) + { + this.indent = indent; + this.data = []; + this._level = 0; + this._strings2index = {}; + this._ids2index = {}; + this._backrefs = 0; + } + + _line(line, ...args) + { + if (this.indent !== null) + { + for (let i = 0; i < this._level; ++i) + this.data.push(this.indent); + } + else + { + if (this.data.length) + this.data.push(" "); + } + this.data.push(line); + + if (args.length) + { + let oldindent = this.indent; + this.indent = null; + for (let i = 0; i < args.length; ++i) + this.dump(args[i]); + this.indent = oldindent; + } + + if (this.indent !== null) + this.data.push("\n"); + } + + // Return the complete string written to the buffer + finish() + { + return this.data.join(""); + } + + dump(obj) + { + if (obj === null) + this._line("n"); + else if (typeof(obj) == "boolean") + this._line(obj ? "bT" : "bF"); + else if (typeof(obj) == "number") + { + let type = (Math.round(obj) == obj) ? "i" : "f"; + this._line(type + obj); + } + else if (typeof(obj) == "string") + { + let index = this._strings2index[obj]; + if (typeof(index) !== "undefined") + { + this._line("^" + index); + } + else + { + this._strings2index[obj] = this._backrefs++; + let dump = ul4._str_repr(obj).replace("<", "\\x3c"); + this._line("S" + dump); + } + } + else if (ul4._iscolor(obj)) + this._line("c", obj.r(), obj.g(), obj.b(), obj.a()); + else if (ul4._isdate(obj)) + this._line("x", obj.year(), obj.month(), obj.day()); + else if (ul4._isdatetime(obj)) + this._line("z", obj.getFullYear(), obj.getMonth()+1, obj.getDate(), obj.getHours(), obj.getMinutes(), obj.getSeconds(), obj.getMilliseconds() * 1000); + else if (ul4._istimedelta(obj)) + this._line("t", obj.days(), obj.seconds(), obj.microseconds()); + else if (ul4._ismonthdelta(obj)) + this._line("m", obj.months()); + else if (obj instanceof ul4.slice) + this._line("r", obj.start, obj.stop); + else if (obj.ul4onname && obj.ul4ondump) + { + if (obj.__id__) + { + let index = this._ids2index[obj.__id__]; + if (typeof(index) != "undefined") + { + this._line("^" + index); + return; + } + this._ids2index[obj.__id__] = this._backrefs++; + } + this._line("O", obj.ul4onname); + ++this._level; + obj.ul4ondump(this); + --this._level; + this._line(")"); + } + else if (ul4._islist(obj)) + { + this._line("l"); + ++this._level; + for (let i = 0; i < obj.length; ++i) + this.dump(obj[i]); + --this._level; + this._line("]"); + } + else if (ul4._ismap(obj)) + { + this._line("e"); + ++this._level; + obj.forEach(function(value, key) { + this.dump(key); + this.dump(value); + }, this); + --this._level; + this._line("}"); + } + else if (ul4._isdict(obj)) + { + this._line("d"); + ++this._level; + for (let key in obj) + { + this.dump(key); + this.dump(obj[key]); + } + --this._level; + this._line("}"); + } + else if (ul4._isset(obj)) + { + this._line("y"); + ++this._level; + obj.forEach(function(value) { + this.dump(value); + }, this); + --this._level; + this._line("}"); + } + else + throw new ul4.ValueError("can't create UL4ON dump of object " + ul4._repr(obj)); + } + }; + + // Helper class for decoding + ul4.Decoder = class Decoder + { + // Creates a new decoder for reading from the string ``data`` + constructor(data, registry) + { + this.data = data; + this.pos = 0; + this.backrefs = []; + this.registry = typeof(registry) === "undefined" ? null : registry; + this.stack = []; // Use for informative error messages + } + + // Read a character from the buffer + readchar() + { + if (this.pos >= this.data.length) + throw new ul4.ValueError("UL4 decoder at EOF"); + return this.data.charAt(this.pos++); + } + + // Read a character from the buffer (return null on eof) + readcharoreof() + { + if (this.pos >= this.data.length) + return null; + return this.data.charAt(this.pos++); + } + + // Read next not-whitespace character from the buffer + readblackchar() + { + let re_white = /\s/; + + for (;;) + { + if (this.pos >= this.data.length) + throw new ul4.ValueError("UL4 decoder at EOF at position " + this.pos + " with path " + this.stack.join("/")); + let c = this.data.charAt(this.pos++); + if (!c.match(re_white)) + return c; + } + } + + // Read ``size`` characters from the buffer + read(size) + { + if (this.pos+size > this.length) + size = this.length-this.pos; + let result = this.data.substring(this.pos, this.pos+size); + this.pos += size; + return result; + } + + // "unread" one character + backup() + { + --this.pos; + } + + // Read a number from the buffer + readnumber() + { + let re_digits = /[-+0123456789.eE]/, value = ""; + for (;;) + { + let c = this.readcharoreof(); + if (c !== null && c.match(re_digits)) + value += c; + else + { + let result = parseFloat(value); + if (isNaN(result)) + throw new ul4.ValueError("invalid number, got " + ul4._repr("value") + " at position " + this.pos + " with path " + this.stack.join("/")); + return result; + } + } + } + + _beginfakeloading() + { + let oldpos = this.backrefs.length; + this.backrefs.push(null); + return oldpos; + } + + _endfakeloading(oldpos, value) + { + this.backrefs[oldpos] = value; + } + + _readescape(escapechar, length) + { + let chars = this.read(length); + if (chars.length != length) + throw new ul4.ValueError("broken escape " + ul4._repr("\\" + escapechar + chars) + " at position " + this.pos + " with path " + this.stack.join("/")); + let codepoint = parseInt(chars, 16); + if (isNaN(codepoint)) + throw new ul4.ValueError("broken escape " + ul4._repr("\\" + escapechar + chars) + " at position " + this.pos + " with path " + this.stack.join("/")); + return String.fromCharCode(codepoint); + } + + // Load the next object from the buffer + load() + { + let typecode = this.readblackchar(); + let result; + switch (typecode) + { + case "^": + return this.backrefs[this.readnumber()]; + case "n": + case "N": + if (typecode === "N") + this.backrefs.push(null); + return null; + case "b": + case "B": + result = this.readchar(); + if (result === "T") + result = true; + else if (result === "F") + result = false; + else + throw new ul4.ValueError("wrong value for boolean, expected 'T' or 'F', got " + ul4._repr(result) + " at position " + this.pos + " with path " + this.stack.join("/")); + if (typecode === "B") + this.backrefs.push(result); + return result; + case "i": + case "I": + case "f": + case "F": + result = this.readnumber(); + if (typecode === "I" || typecode === "F") + this.backrefs.push(result); + return result; + case "s": + case "S": + result = []; + let delimiter = this.readblackchar(); + for (;;) + { + let c = this.readchar(); + if (c == delimiter) + break; + if (c == "\\") + { + let c2 = this.readchar(); + if (c2 == "\\") + result.push("\\"); + else if (c2 == "n") + result.push("\n"); + else if (c2 == "r") + result.push("\r"); + else if (c2 == "t") + result.push("\t"); + else if (c2 == "f") + result.push("\u000c"); + else if (c2 == "b") + result.push("\u0008"); + else if (c2 == "a") + result.push("\u0007"); + else if (c2 == "'") + result.push("'"); + else if (c2 == '"') + result.push('"'); + else if (c2 == "x") + result.push(this._readescape("x", 2)); + else if (c2 == "u") + result.push(this._readescape("u", 4)); + else if (c2 == "U") + result.push(this._readescape("U", 8)); + else + result.push("\\" + c2); + } + else + result.push(c); + } + result = result.join(""); + if (typecode === "S") + this.backrefs.push(result); + return result; + case "c": + case "C": + result = new ul4.Color(); + if (typecode === "C") + this.backrefs.push(result); + result._r = this.load(); + result._g = this.load(); + result._b = this.load(); + result._a = this.load(); + return result; + case "x": + case "X": + { + let year = this.load(); + let month = this.load(); + let day = this.load(); + result = new ul4.Date(year, month, day); + if (typecode === "X") + this.backrefs.push(result); + return result; + } + case "z": + case "Z": + result = new Date(); + result.setFullYear(this.load()); + result.setDate(1); + result.setMonth(this.load() - 1); + result.setDate(this.load()); + result.setHours(this.load()); + result.setMinutes(this.load()); + result.setSeconds(this.load()); + result.setMilliseconds(this.load()/1000); + if (typecode === "Z") + this.backrefs.push(result); + return result; + case "t": + case "T": + result = new ul4.TimeDelta(); + result._days = this.load(); + result._seconds = this.load(); + result._microseconds = this.load(); + if (typecode === "T") + this.backrefs.push(result); + return result; + case "r": + case "R": + result = new ul4.slice(); + if (typecode === "R") + this.backrefs.push(result); + result.start = this.load(); + result.stop = this.load(); + return result; + case "m": + case "M": + result = new ul4.MonthDelta(); + if (typecode === "M") + this.backrefs.push(result); + result._months = this.load(); + return result; + case "l": + case "L": + this.stack.push("list"); + result = []; + if (typecode === "L") + this.backrefs.push(result); + for (;;) + { + typecode = this.readblackchar(); + if (typecode === "]") + break; + this.backup(); + result.push(this.load()); + } + this.stack.pop(); + return result; + case "d": + case "D": + case "e": + case "E": + if (!ul4._havemap && (typecode == "e" || typecode == "E")) + throw new ul4.ValueError("ordered dictionaries are not supported at position " + this.pos + " with path " + this.stack.join("/")); + result = ul4._emptymap(); + this.stack.push(typecode === "d" || typecode === "D" ? "dict" : "odict"); + if (typecode === "D" || typecode === "E") + this.backrefs.push(result); + for (;;) + { + typecode = this.readblackchar(); + if (typecode === "}") + break; + this.backup(); + let key = this.load(); + let value = this.load(); + ul4._setmap(result, key, value); + } + this.stack.pop(); + return result; + case "y": + case "Y": + this.stack.push("set"); + result = ul4._makeset(); + if (typecode === "Y") + this.backrefs.push(result); + for (;;) + { + typecode = this.readblackchar(); + if (typecode === "}") + break; + this.backup(); + result.add(this.load()); + } + this.stack.pop(); + return result; + case "o": + case "O": + { + let oldpos; + if (typecode === "O") + oldpos = this._beginfakeloading(); + let name = this.load(); + this.stack.push(name); + let constructor; + if (this.registry !== null) + { + constructor = this.registry[name]; + if (typeof(constructor) === "undefined") + constructor = ul4._registry[name]; + } + else + constructor = ul4._registry[name]; + if (typeof(constructor) === "undefined") + throw new ul4.ValueError("can't load object of type " + ul4._repr(name) + " at position " + this.pos + " with path " + this.stack.join("/")); + result = new constructor(); + if (typecode === "O") + this._endfakeloading(oldpos, result); + result.ul4onload(this); + typecode = this.readblackchar(); + if (typecode !== ")") + throw new ul4.ValueError("object terminator ')' for object of type '" + name + "' expected, got " + ul4._repr(typecode) + " at position " + this.pos + " with path " + this.stack.join("/")); + this.stack.pop(); + return result; + } + default: + throw new ul4.ValueError("unknown typecode " + ul4._repr(typecode) + " at position " + this.pos + " with path " + this.stack.join("/")); + } + } + + // Return an iterator for loading the content of a object + loadcontent() + { + let self = this; + return { + next: function() + { + let typecode = self.readblackchar(); + // Always "unread" the typecode even at the end + // so that at the end of a call to ul4onload() + // the next input is the "end of object" marker + // no matter whether ul4onload() uses loadcontent() or not. + self.backup(); + if (typecode == ")") + return {done: true}; + else + return {done: false, value: self.load()}; + } + }; + } + }; + + // + // UL4 + // + + // REs for parsing JSON + ul4._rvalidchars = /^[\],:{}\s]*$/; + ul4._rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g; + ul4._rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; + ul4._rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g; + + /// Helper functions + + // Clone an object and extend it + ul4._inherit = function _inherit(baseobj, attrs) + { + return Object.assign(Object.create(baseobj), attrs); + }; + + // Convert a map to an object + ul4._map2object = function _map2object(obj) + { + if (ul4._ismap(obj)) + { + let newobj = {}; + obj.forEach(function(value, key){ + if (typeof(key) !== "string") + throw new ul4.TypeError("keys must be strings"); + newobj[key] = value; + }); + return newobj; + } + return obj; + }; + + // Clip a number to the range [0;max) + ul4._bound = function _bound(value, upper) + { + if (value < 0) + return 0; + else if (value > upper) + return upper; + else + return value; + }; + + // Create a pretty stacktrace from an exception + ul4._stacktrace = function _stacktrace(exc) + { + let output = (exc instanceof ul4.Exception ? exc.constructor.name + ": " : "") + exc.toString(); + if (exc.context) + output = ul4._stacktrace(exc.context) + "\n\n" + output; + return output; + }; + + // Call a function ``f`` with UL4 argument handling + ul4._internal_call = function _internal_call(context, f, name, functioncontext, signature, needscontext, needsobject, args, kwargs) + { + let finalargs; + if (needsobject) + { + if (signature === null) + { + if (args.length) + throw new ul4.ArgumentError(ul4._repr(f) + " doesn't support positional arguments!"); + finalargs = [kwargs]; + } + else + finalargs = [signature.bindObject(name, args, kwargs)]; + } + else + { + if (signature === null) + throw new ul4.ArgumentError(ul4._repr(f) + " doesn't support positional arguments!"); + finalargs = signature.bindArray(name, args, kwargs); + } + if (needscontext) + finalargs.unshift(context); + return f.apply(functioncontext, finalargs); + }; + + ul4._callfunction = function _callfunction(context, f, args, kwargs) + { + let name = f._ul4_name || f.name; + if (typeof(f._ul4_signature) === "undefined" || typeof(f._ul4_needsobject) === "undefined" || typeof(f._ul4_needscontext) === "undefined") + throw new ul4.TypeError(ul4._repr(f) + " is not callable by UL4"); + return ul4._internal_call(context, f, name, ul4, f._ul4_signature, f._ul4_needscontext, f._ul4_needsobject, args, kwargs); + }; + + ul4._callobject = function _callobject(context, obj, args, kwargs) + { + if (typeof(obj._ul4_callsignature) === "undefined" || typeof(obj._ul4_callneedsobject) === "undefined" || typeof(obj._ul4_callneedscontext) === "undefined") + throw new ul4.TypeError(ul4._repr(obj) + " is not callable by UL4"); + return ul4._internal_call(context, obj.__call__, obj.name, obj, obj._ul4_callsignature, obj._ul4_callneedscontext, obj._ul4_callneedsobject, args, kwargs); + }; + + ul4._callrender = function _callrender(context, obj, args, kwargs) + { + if (typeof(obj._ul4_rendersignature) === "undefined" || typeof(obj._ul4_renderneedsobject) === "undefined" || typeof(obj._ul4_renderneedscontext) === "undefined") + throw new ul4.TypeError(ul4._repr(obj) + " is not renderable by UL4"); + return ul4._internal_call(context, obj.__render__, obj.name, obj, obj._ul4_rendersignature, obj._ul4_renderneedscontext, obj._ul4_renderneedsobject, args, kwargs); + }; + + ul4._call = function _call(context, f, args, kwargs) + { + if (typeof(f) === "function") + return ul4._callfunction(context, f, args, kwargs); + else if (f && typeof(f.__call__) === "function") + return ul4._callobject(context, f, args, kwargs); + else + throw new ul4.TypeError(ul4._type(f) + " is not callable"); + }; + + ul4._unpackvar = function _unpackvar(lvalue, value) + { + if (!ul4._islist(lvalue)) + return [[lvalue, value]]; + else + { + let newvalue = []; + let iter = ul4._iter(value); + + for (let i = 0;;++i) + { + let item = iter.next(); + + if (item.done) + { + if (i === lvalue.length) + break; + else + throw new ul4.ValueError("need " + lvalue.length + " value" + (lvalue.length === 1 ? "" : "s") + " to unpack, got " + i); + } + else + { + if (i < lvalue.length) + newvalue = newvalue.concat(ul4._unpackvar(lvalue[i], item.value)); + else + throw new ul4.ValueError("too many values to unpack (expected " + lvalue.length + ")"); + } + } + return newvalue; + } + }; + + ul4._formatsource = function _formatsource(out) + { + let finalout = []; + let level = 0, needlf = false; + for (let i = 0; i < out.length; ++i) + { + let part = out[i]; + if (typeof(part) === "number") + { + level += part; + needlf = true; + } + else + { + if (needlf) + { + finalout.push("\n"); + for (let j = 0; j < level; ++j) + finalout.push("\t"); + needlf = false; + } + finalout.push(part); + } + } + if (needlf) + finalout.push("\n"); + return finalout.join(""); + }; + + // Compare ``obj1`` and ``obj2`` if they have the same value + ul4._eq = function _eq(obj1, obj2) + { + let numbertypes = ["boolean", "number"]; + + if (obj1 && typeof(obj1.__eq__) === "function") + return obj1.__eq__(obj2); + else if (obj2 && typeof(obj2.__eq__) === "function") + return obj2.__eq__(obj1); + else if (obj1 === null) + return obj2 === null; + else if (numbertypes.indexOf(typeof(obj1)) != -1) + { + if (numbertypes.indexOf(typeof(obj2)) != -1) + return obj1 == obj2; + else + return false; + } + else if (typeof(obj1) === "string") + { + if (typeof(obj2) === "string") + return obj1 == obj2; + else + return false; + } + else if (ul4._isdatetime(obj1)) + { + if (ul4._isdatetime(obj2)) + return obj1.getTime() == obj2.getTime(); + else + return false; + } + else if (ul4._islist(obj1)) + { + if (ul4._islist(obj2)) + { + // Shortcut, if it's the same object + if (obj1 === obj2) + return true; + if (obj1.length != obj2.length) + return false; + for (let i = 0; i < obj1.length; ++i) + { + if (!ul4._eq(obj1[i], obj2[i])) // This might lead to infinite recursion and a stackoverflow, but it does in all implementations + return false; + } + return true; + } + else + return false; + } + else if (ul4._isobject(obj1)) + { + if (ul4._isobject(obj2)) + { + // Shortcut, if it's the same object + if (obj1 === obj2) + return true; + // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value + for (let key in obj1) + { + if (obj2.hasOwnProperty(key)) + { + if (!ul4._eq(obj1[key], obj2[key])) + return false; + } + else + return false; + } + // Test that each attribute of ``obj2`` is also in ``obj1`` (the value has been tested before) + for (let key in obj2) + { + if (!obj1.hasOwnProperty(key)) + return false; + } + return true; + } + else if (ul4._ismap(obj2)) + { + // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value + for (let key in obj1) + { + if (obj2.has(key)) + { + if (!ul4._eq(obj1[key], obj2.get(key))) + return false; + } + else + return false; + } + // Test that each attribute of ``obj2`` is also in ``obj1`` (the value has been tested before) + let result = true; + obj2.forEach(function(value, key) { + if (!obj1.hasOwnProperty(key)) + result = false; + }, this); + return result; + } + else + return false; + } + else if (ul4._ismap(obj1)) + { + if (ul4._isobject(obj2)) + { + // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value + obj1.forEach(function(value, key) { + if (!obj2.hasOwnProperty(key)) + return false; + else if (!ul4._eq(obj1.get(key), obj2[key])) + return false; + }, this); + // Test that each attribute of ``obj2`` is also in ``obj1`` (the value has been tested before) + for (let key in obj2) + { + if (!obj1.has(key)) + return false; + } + return true; + } + else if (ul4._ismap(obj2)) + { + // Shortcut, if it's the same object + if (obj1 === obj2) + return true; + if (obj1.size != obj2.size) + return false; + let result = true; + // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value + obj1.forEach(function(value, key) { + if (!obj2.has(key)) + result = false; + else if (!ul4._eq(obj1.get(key), obj2.get(key))) + result = false; + }); + return result; + } + else + return false; + } + else if (ul4._isset(obj1)) + { + // We don't have to test for ``ul4._Set`` as ``ul4._Set`` implements ``__eq__`` + if (ul4._isset(obj2)) + { + // Shortcut, if it's the same object + if (obj1 === obj2) + return true; + if (obj1.size != obj2.size) + return false; + let result = true; + obj1.forEach(function(value) { + if (!obj2.has(value)) + result = false; + }); + return result; + } + else + return false; + } + else + return obj1 === obj2; + }; + + // Compare ``obj1`` and ``obj2`` if they don't have the same value + ul4._ne = function _ne(obj1, obj2) + { + if (obj1 && typeof(obj1.__ne__) === "function") + return obj1.__ne__(obj2); + else if (obj2 && typeof(obj2.__ne__) === "function") + return obj2.__ne__(obj1); + else + return !ul4._eq(obj1, obj2); + }; + + ul4._unorderable = function _unorderable(operator, obj1, obj2) + { + throw new ul4.TypeError("unorderable types: " + ul4._type(obj1) + " " + operator + " " + ul4._type(obj2)); + }; + + // Return: + // -1 when ``obj1 < obj2``, + // 0 when ``obj1 == obj2``, + // 1 when ``obj1 > obj2``, + // null when ``obj1`` and ``obj2`` are comparable, but neither of the previous cases holds (only for sets) + // raise TypeError if objects are uncomparable + // This the purpose of ``_cmp`` is to support implementation of <, <=, > and >= + // and dicts/maps are not comparable with the operator ``_cmp`` does not support dicts/maps + + ul4._cmp = function _cmp(operator, obj1, obj2) + { + let numbertypes = ["boolean", "number"]; + + if (numbertypes.indexOf(typeof(obj1)) != -1) + { + if (numbertypes.indexOf(typeof(obj2)) != -1) + return (obj1 > obj2) - (obj1 < obj2); + } + else if (typeof(obj1) === "string") + { + if (typeof(obj2) === "string") + return (obj1 > obj2) - (obj1 < obj2); + } + else if (ul4._isdatetime(obj1)) + { + if (ul4._isdatetime(obj2)) + { + let v1 = obj1.getTime(), v2 = obj2.getTime(); + return (v1 > v2) - (v1 < v2); + } + } + else if (ul4._islist(obj1)) + { + if (ul4._islist(obj2)) + { + if (obj1 === obj2) + return 0; + for (let i = 0; i < obj1.length; ++i) + { + if (i >= obj2.length) + return 1; + let res = ul4._cmp(operator, obj1[i], obj2[i]); + if (res) + return res; + } + return obj2.length > obj1.length ? -1 : 0; + } + } + else if (ul4._isset(obj1) || ul4._isul4set(obj1)) + { + if (ul4._isset(obj2) || ul4._isul4set(obj2)) + { + let in1only = false; + let in2only = false; + + for (let iter = _iter(obj1);;) + { + let item = iter.next(); + if (item.done) + break; + if (!obj2.has(item.value)) + { + in1only = true; + break; + } + } + for (let iter = _iter(obj2);;) + { + let item = iter.next(); + if (item.done) + break; + if (!obj1.has(item.value)) + { + in2only = true; + break; + } + } + + if (in1only) + { + if (in2only) + return null; + else + return 1; + } + else + { + if (in2only) + return -1; + else + return 0; + } + } + } + return ul4._unorderable(operator, obj1, obj2); + }; + + // Return whether ``obj1 < obj2`` + ul4._lt = function _lt(obj1, obj2) + { + let numbertypes = ["boolean", "number"]; + + if (obj1 && typeof(obj1.__lt__) === "function") + return obj1.__lt__(obj2); + else if (numbertypes.indexOf(typeof(obj1)) != -1) + { + if (numbertypes.indexOf(typeof(obj2)) != -1) + return obj1 < obj2; + } + else if (typeof(obj1) === "string") + { + if (typeof(obj2) === "string") + return obj1 < obj2; + } + else if (ul4._isdatetime(obj1)) + { + if (ul4._isdatetime(obj2)) + return obj1.getTime() < obj2.getTime(); + } + else if (ul4._islist(obj1)) + { + if (ul4._islist(obj2)) + { + if (obj1 === obj2) + return false; + for (let i = 0; i < obj1.length; ++i) + { + if (i >= obj2.length) + return false; + let eq = ul4._eq(obj1[i], obj2[i]); + if (!eq) + return ul4._lt(obj1[i], obj2[i]); + } + return obj1.length < obj2.length; + } + } + // FIXME: Set comparison + else if (ul4._isset(obj1)) + { + if (ul4._isset(obj2)) + { + if (ul4._isset(obj2)) + { + for (let key in obj1) + { + if (!obj2.has(obj1[key])) + in1only = true; + } + for (let key in obj2) + { + if (!obj1.has(obj2[key])) + in2only = true; + } + } + else if (ul4._isul4set(obj2)) + { + for (let key in obj1) + { + if (!obj2.items[obj1[key]]) + in1only = true; + } + for (let value in obj2.items) + { + if (!obj1.has(value)) + { + in2only = true; + break; + } + } + } + } + else if (ul4._isul4set(obj2)) + { + if (ul4._isset(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.has(value)) + { + in1only = true; + break; + } + } + for (let key in obj2) + { + if (!obj1.items[obj2[key]]) + in2only = true; + } + } + else if (ul4._isul4set(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.items[value]) + { + in1only = true; + break; + } + } + for (let value in obj2.items) + { + if (!obj1.items[value]) + { + in2only = true; + break; + } + } + } + } + else + ul4._unorderable(operator, obj1, obj2); + + if (in1only) + { + if (in2only) + return null; + else + return 1; + } + else + { + if (in2only) + return -1; + else + return 0; + } + } + ul4._unorderable("<", obj1, obj2); + }; + + // Return whether ``obj1 <= obj2`` + ul4._le = function _le(obj1, obj2) + { + let numbertypes = ["boolean", "number"]; + + if (obj1 && typeof(obj1.__le__) === "function") + return obj1.__le__(obj2); + if (numbertypes.indexOf(typeof(obj1)) != -1) + { + if (numbertypes.indexOf(typeof(obj2)) != -1) + return obj1 <= obj2; + } + else if (typeof(obj1) === "string") + { + if (typeof(obj2) === "string") + return obj1 <= obj2; + } + else if (ul4._isdatetime(obj1)) + { + if (ul4._isdatetime(obj2)) + return obj1.getTime() <= obj2.getTime(); + } + else if (ul4._islist(obj1)) + { + if (ul4._islist(obj2)) + { + if (obj1 === obj2) + return true; + for (let i = 0; i < obj1.length; ++i) + { + if (i >= obj2.length) + return false; + let eq = ul4._eq(obj1[i], obj2[i]); + if (!eq) + return ul4._lt(obj1[i], obj2[i]); + } + return obj1.length <= obj2.length; + } + } + // FIXME: Set comparison + else if (ul4._isset(obj1) || ul4._isul4set(obj1)) + { + let in1only = false; + let in2only = false; + + if (ul4._isset(obj2)) + { + if (ul4._isset(obj2)) + { + obj1.forEach(function(value) { + if (!obj2.has(value)) + in1only = true; + }); + obj2.forEach(function(value) { + if (!obj1.has(value)) + in2only = true; + }); + } + else if (ul4._isul4set(obj2)) + { + obj1.forEach(function(value) { + if (!obj2.items[value]) + in1only = true; + }); + for (let value in obj2.items) + { + if (!obj1.has(value)) + { + in2only = true; + break; + } + } + } + } + else if (ul4._isul4set(obj2)) + { + if (ul4._isset(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.has(value)) + { + in1only = true; + break; + } + } + obj2.forEach(function(value) { + if (!obj1.items[value]) + in2only = true; + }); + } + else if (ul4._isul4set(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.items[value]) + { + in1only = true; + break; + } + } + for (let value in obj2.items) + { + if (!obj1.items[value]) + { + in2only = true; + break; + } + } + } + } + else + ul4._unorderable(operator, obj1, obj2); + + if (in1only) + { + if (in2only) + return null; + else + return 1; + } + else + { + if (in2only) + return -1; + else + return 0; + } + } + ul4._unorderable("<=", obj1, obj2); + }; + + // Return whether ``obj1 > obj2`` + ul4._gt = function _gt(obj1, obj2) + { + let numbertypes = ["boolean", "number"]; + + if (obj1 && typeof(obj1.__gt__) === "function") + return obj1.__gt__(obj2); + if (numbertypes.indexOf(typeof(obj1)) != -1) + { + if (numbertypes.indexOf(typeof(obj2)) != -1) + return obj1 > obj2; + } + else if (typeof(obj1) === "string") + { + if (typeof(obj2) === "string") + return obj1 > obj2; + } + else if (ul4._isdatetime(obj1)) + { + if (ul4._isdatetime(obj2)) + return obj1.getTime() > obj2.getTime(); + } + else if (ul4._islist(obj1)) + { + if (ul4._islist(obj2)) + { + if (obj1 === obj2) + return false; + for (let i = 0; i < obj1.length; ++i) + { + if (i >= obj2.length) + return true; + let eq = ul4._eq(obj1[i], obj2[i]); + if (!eq) + return ul4._gt(obj1[i], obj2[i]); + } + return obj1.length > obj2.length; + } + } + // FIXME: Set comparison + else if (ul4._isset(obj1) || ul4._isul4set(obj1)) + { + let in1only = false; + let in2only = false; + + if (ul4._isset(obj2)) + { + if (ul4._isset(obj2)) + { + obj1.forEach(function(value) { + if (!obj2.has(value)) + in1only = true; + }); + obj2.forEach(function(value) { + if (!obj1.has(value)) + in2only = true; + }); + } + else if (ul4._isul4set(obj2)) + { + obj1.forEach(function(value) { + if (!obj2.items[value]) + in1only = true; + }); + obj2.forEach(function(value) { + if (!obj1.has(value)) + { + in2only = true; + } + }); + } + } + else if (ul4._isul4set(obj2)) + { + if (ul4._isset(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.has(value)) + { + in1only = true; + break; + } + } + obj2.forEach(function(value) { + if (!obj1.items[value]) + in2only = true; + }); + } + else if (ul4._isul4set(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.items[value]) + { + in1only = true; + break; + } + } + for (let value in obj2.items) + { + if (!obj1.items[value]) + { + in2only = true; + break; + } + } + } + } + else + ul4._unorderable(operator, obj1, obj2); + + if (in1only) + { + if (in2only) + return null; + else + return 1; + } + else + { + if (in2only) + return -1; + else + return 0; + } + } + ul4._unorderable(">", obj1, obj2); + }; + + // Return whether ``obj1 >= obj2`` + ul4._ge = function _ge(obj1, obj2) + { + let numbertypes = ["boolean", "number"]; + + if (obj1 && typeof(obj1.__ge__) === "function") + return obj1.__ge__(obj2); + else if (numbertypes.indexOf(typeof(obj1)) != -1) + { + if (numbertypes.indexOf(typeof(obj2)) != -1) + return obj1 >= obj2; + } + else if (typeof(obj1) === "string") + { + if (typeof(obj2) === "string") + return obj1 >= obj2; + } + else if (ul4._isdatetime(obj1)) + { + if (ul4._isdatetime(obj2)) + return obj1.getTime() >= obj2.getTime(); + } + else if (ul4._islist(obj1)) + { + if (ul4._islist(obj2)) + { + if (obj1 === obj2) + return true; + for (let i = 0; i < obj1.length; ++i) + { + if (i >= obj2.length) + return true; + let eq = ul4._eq(obj1[i], obj2[i]); + if (!eq) + return ul4._gt(obj1[i], obj2[i]); + } + return obj1.length >= obj2.length; + } + } + // FIXME: Set comparison + else if (ul4._isset(obj1) || ul4._isul4set(obj1)) + { + let in1only = false; + let in2only = false; + + if (ul4._isset(obj2)) + { + if (ul4._isset(obj2)) + { + obj1.forEach(function(value) { + if (!obj2.has(value)) + in1only = true; + }); + obj2.forEach(function(value) { + if (!obj1.has(value)) + in2only = true; + }); + } + else if (ul4._isul4set(obj2)) + { + obj1.forEach(function(value) { + if (!obj2.items[value]) + in1only = true; + }); + for (let value in obj2.items) + { + if (!obj1.has(value)) + { + in2only = true; + break; + } + } + } + } + else if (ul4._isul4set(obj2)) + { + if (ul4._isset(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.has(value)) + { + in1only = true; + break; + } + } + obj2.forEach(function(value, key) { + if (!obj1.items[value]) + in2only = true; + }); + } + else if (ul4._isul4set(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.items[value]) + { + in1only = true; + break; + } + } + for (let value in obj2.items) + { + if (!obj1.items[value]) + { + in2only = true; + break; + } + } + } + } + else + ul4._unorderable(operator, obj1, obj2); + + if (in1only) + { + if (in2only) + return null; + else + return 1; + } + else + { + if (in2only) + return -1; + else + return 0; + } + } + ul4._unorderable(">=", obj1, obj2); + }; + + // Return an iterator for ``obj`` + ul4._iter = function _iter(obj) + { + if (typeof(obj) === "string" || ul4._islist(obj)) + { + return { + index: 0, + next: function() + { + if (this.index < obj.length) + return {value: obj[this.index++], done: false}; + else + return {done: true}; + } + }; + } + else if (ul4._isiter(obj)) + return obj; + else if (obj !== null && typeof(obj.__iter__) === "function") + return obj.__iter__(); + else if (ul4._ismap(obj)) + { + let keys = []; + obj.forEach(function(value, key) { + keys.push(key); + }); + return { + index: 0, + next: function() + { + if (this.index >= keys.length) + return {done: true}; + return {value: keys[this.index++], done: false}; + } + }; + } + else if (ul4._isset(obj)) + { + let values = []; + obj.forEach(function(item) { + values.push(item); + }); + return { + index: 0, + next: function() + { + if (this.index >= values.length) + return {done: true}; + return {value: values[this.index++], done: false}; + } + }; + } + else if (ul4._isul4set(obj)) + { + return ul4._iter(obj.items); + } + else if (ul4._isobject(obj)) + { + let keys = []; + for (let key in obj) + keys.push(key); + return { + index: 0, + next: function() + { + if (this.index >= keys.length) + return {done: true}; + return {value: keys[this.index++], done: false}; + } + }; + } + throw new ul4.TypeError(ul4._type(obj) + " object is not iterable"); + }; + + ul4._str_repr = function _str_repr(str, ascii) + { + let result = ""; + let squote = false, dquote = false; + + for (let i = 0; i < str.length; ++i) + { + let c = str[i]; + if (c == '"') + { + dquote = true; + if (squote) + break; + } + else if (c == "'") + { + squote = true; + if (dquote) + break; + } + } + + // Prefer single quotes: Only use double quotes if the string contains single quotes, but no double quotes + let quote = (squote && !dquote) ? '"' : "'"; + + for (let i = 0; i < str.length; ++i) + { + let c = str[i]; + switch (c) + { + case '"': + result += (quote == c) ? '\\"' : c; + break; + case "'": + result += (quote == c) ? "\\'" : c; + break; + case "\\": + result += "\\\\"; + break; + case "\t": + result += "\\t"; + break; + case "\n": + result += "\\n"; + break; + case "\r": + result += "\\r"; + break; + default: + let code = c.charCodeAt(0); + let escape; + if (code < 32) + escape = 2; + else if (code < 0x7f) + escape = 0; + else if (!ascii && !/[\u007f-\u00a0\u00ad\u0378-\u0379\u0380-\u0383\u038b\u038d\u03a2\u0530\u0557-\u0558\u0560\u0588\u058b-\u058c\u0590\u05c8-\u05cf\u05eb-\u05ef\u05f5-\u0605\u061c-\u061d\u06dd\u070e-\u070f\u074b-\u074c\u07b2-\u07bf\u07fb-\u07ff\u082e-\u082f\u083f\u085c-\u085d\u085f-\u089f\u08b5-\u08e2\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09bb\u09c5-\u09c6\u09c9-\u09ca\u09cf-\u09d6\u09d8-\u09db\u09de\u09e4-\u09e5\u09fc-\u0a00\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a3b\u0a3d\u0a43-\u0a46\u0a49-\u0a4a\u0a4e-\u0a50\u0a52-\u0a58\u0a5d\u0a5f-\u0a65\u0a76-\u0a80\u0a84\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abb\u0ac6\u0aca\u0ace-\u0acf\u0ad1-\u0adf\u0ae4-\u0ae5\u0af2-\u0af8\u0afa-\u0b00\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34\u0b3a-\u0b3b\u0b45-\u0b46\u0b49-\u0b4a\u0b4e-\u0b55\u0b58-\u0b5b\u0b5e\u0b64-\u0b65\u0b78-\u0b81\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bba-\u0bbd\u0bc3-\u0bc5\u0bc9\u0bce-\u0bcf\u0bd1-\u0bd6\u0bd8-\u0be5\u0bfb-\u0bff\u0c04\u0c0d\u0c11\u0c29\u0c3a-\u0c3c\u0c45\u0c49\u0c4e-\u0c54\u0c57\u0c5b-\u0c5f\u0c64-\u0c65\u0c70-\u0c77\u0c80\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cbb\u0cc5\u0cc9\u0cce-\u0cd4\u0cd7-\u0cdd\u0cdf\u0ce4-\u0ce5\u0cf0\u0cf3-\u0d00\u0d04\u0d0d\u0d11\u0d3b-\u0d3c\u0d45\u0d49\u0d4f-\u0d56\u0d58-\u0d5e\u0d64-\u0d65\u0d76-\u0d78\u0d80-\u0d81\u0d84\u0d97-\u0d99\u0db2\u0dbc\u0dbe-\u0dbf\u0dc7-\u0dc9\u0dcb-\u0dce\u0dd5\u0dd7\u0de0-\u0de5\u0df0-\u0df1\u0df5-\u0e00\u0e3b-\u0e3e\u0e5c-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eba\u0ebe-\u0ebf\u0ec5\u0ec7\u0ece-\u0ecf\u0eda-\u0edb\u0ee0-\u0eff\u0f48\u0f6d-\u0f70\u0f98\u0fbd\u0fcd\u0fdb-\u0fff\u10c6\u10c8-\u10cc\u10ce-\u10cf\u1249\u124e-\u124f\u1257\u1259\u125e-\u125f\u1289\u128e-\u128f\u12b1\u12b6-\u12b7\u12bf\u12c1\u12c6-\u12c7\u12d7\u1311\u1316-\u1317\u135b-\u135c\u137d-\u137f\u139a-\u139f\u13f6-\u13f7\u13fe-\u13ff\u1680\u169d-\u169f\u16f9-\u16ff\u170d\u1715-\u171f\u1737-\u173f\u1754-\u175f\u176d\u1771\u1774-\u177f\u17de-\u17df\u17ea-\u17ef\u17fa-\u17ff\u180e-\u180f\u181a-\u181f\u1878-\u187f\u18ab-\u18af\u18f6-\u18ff\u191f\u192c-\u192f\u193c-\u193f\u1941-\u1943\u196e-\u196f\u1975-\u197f\u19ac-\u19af\u19ca-\u19cf\u19db-\u19dd\u1a1c-\u1a1d\u1a5f\u1a7d-\u1a7e\u1a8a-\u1a8f\u1a9a-\u1a9f\u1aae-\u1aaf\u1abf-\u1aff\u1b4c-\u1b4f\u1b7d-\u1b7f\u1bf4-\u1bfb\u1c38-\u1c3a\u1c4a-\u1c4c\u1c80-\u1cbf\u1cc8-\u1ccf\u1cf7\u1cfa-\u1cff\u1df6-\u1dfb\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fc5\u1fd4-\u1fd5\u1fdc\u1ff0-\u1ff1\u1ff5\u1fff-\u200f\u2028-\u202f\u205f-\u206f\u2072-\u2073\u208f\u209d-\u209f\u20bf-\u20cf\u20f1-\u20ff\u218c-\u218f\u23fb-\u23ff\u2427-\u243f\u244b-\u245f\u2b74-\u2b75\u2b96-\u2b97\u2bba-\u2bbc\u2bc9\u2bd2-\u2beb\u2bf0-\u2bff\u2c2f\u2c5f\u2cf4-\u2cf8\u2d26\u2d28-\u2d2c\u2d2e-\u2d2f\u2d68-\u2d6e\u2d71-\u2d7e\u2d97-\u2d9f\u2da7\u2daf\u2db7\u2dbf\u2dc7\u2dcf\u2dd7\u2ddf\u2e43-\u2e7f\u2e9a\u2ef4-\u2eff\u2fd6-\u2fef\u2ffc-\u3000\u3040\u3097-\u3098\u3100-\u3104\u312e-\u3130\u318f\u31bb-\u31bf\u31e4-\u31ef\u321f\u32ff\u4db6-\u4dbf\u9fd6-\u9fff\ua48d-\ua48f\ua4c7-\ua4cf\ua62c-\ua63f\ua6f8-\ua6ff\ua7ae-\ua7af\ua7b8-\ua7f6\ua82c-\ua82f\ua83a-\ua83f\ua878-\ua87f\ua8c5-\ua8cd\ua8da-\ua8df\ua8fe-\ua8ff\ua954-\ua95e\ua97d-\ua97f\ua9ce\ua9da-\ua9dd\ua9ff\uaa37-\uaa3f\uaa4e-\uaa4f\uaa5a-\uaa5b\uaac3-\uaada\uaaf7-\uab00\uab07-\uab08\uab0f-\uab10\uab17-\uab1f\uab27\uab2f\uab66-\uab6f\uabee-\uabef\uabfa-\uabff\ud7a4-\ud7af\ud7c7-\ud7ca\ud7fc-\uf8ff\ufa6e-\ufa6f\ufada-\ufaff\ufb07-\ufb12\ufb18-\ufb1c\ufb37\ufb3d\ufb3f\ufb42\ufb45\ufbc2-\ufbd2\ufd40-\ufd4f\ufd90-\ufd91\ufdc8-\ufdef\ufdfe-\ufdff\ufe1a-\ufe1f\ufe53\ufe67\ufe6c-\ufe6f\ufe75\ufefd-\uff00\uffbf-\uffc1\uffc8-\uffc9\uffd0-\uffd1\uffd8-\uffd9\uffdd-\uffdf\uffe7\uffef-\ufffb\ufffe-\uffff]/.test(c)) + escape = 0; + else if (code <= 0xff) + escape = 2; + else if (code <= 0xffff) + escape = 4; + else + escape = 8; + + if (escape === 0) + result += c; + else if (escape === 2) + result += "\\x" + ul4._lpad(code.toString(16), "0", 2); + else if (escape === 4) + result += "\\u" + ul4._lpad(code.toString(16), "0", 4); + else + result += "\\U" + ul4._lpad(code.toString(16), "0", 8); + break; + } + } + return quote + result + quote; + }; + + ul4._date_repr = function _date_repr(obj, ascii) + { + let year = obj._date.getFullYear(); + let month = obj._date.getMonth()+1; + let day = obj._date.getDate(); + let result = "@(" + year + "-" + ul4._lpad(month.toString(), "0", 2) + "-" + ul4._lpad(day.toString(), "0", 2) + ")"; + return result; + }; + + ul4._datetime_repr = function _datetime_repr(obj, ascii) + { + let year = obj.getFullYear(); + let month = obj.getMonth()+1; + let day = obj.getDate(); + let hour = obj.getHours(); + let minute = obj.getMinutes(); + let second = obj.getSeconds(); + let ms = obj.getMilliseconds(); + let result = "@(" + year + "-" + ul4._lpad(month.toString(), "0", 2) + "-" + ul4._lpad(day.toString(), "0", 2) + "T"; + + if (hour || minute || second || ms) + { + result += ul4._lpad(hour.toString(), "0", 2) + ":" + ul4._lpad(minute.toString(), "0", 2); + if (second || ms) + { + result += ":" + ul4._lpad(second.toString(), "0", 2); + if (ms) + result += "." + ul4._lpad(ms.toString(), "0", 3) + "000"; + } + } + result += ")"; + + return result; + }; + + ul4._map_repr = function _map_repr(obj, ascii) + { + let v = []; + v.push("{"); + + let i = 0; + obj.forEach(function(value, key) { + if (i++) + v.push(", "); + v.push(ul4._repr_internal(key, ascii)); + v.push(": "); + v.push(ul4._repr_internal(value, ascii)); + }); + + v.push("}"); + return v.join(""); + }; + + ul4._list_repr = function _list_repr(obj, ascii) + { + let v = []; + v.push("["); + for (let i = 0; i < obj.length; ++i) + { + let item = obj[i]; + if (i) + v.push(", "); + v.push(ul4._repr_internal(item, ascii)); + } + v.push("]"); + return v.join(""); + }; + + ul4._set_repr = function _set_repr(obj, ascii) + { + let v = []; + v.push("{"); + if (!obj.size) + v.push("/"); + else + { + let i = 0; + obj.forEach(function(value) { + if (i++) + v.push(", "); + v.push(ul4._repr_internal(value, ascii)); + }); + } + v.push("}"); + return v.join(""); + }; + + ul4._object_repr = function _object_repr(obj, ascii) + { + let v = []; + v.push("{"); + let i = 0; + for (let key in obj) + { + if (!obj.hasOwnProperty(key)) + continue; + if (i++) + v.push(", "); + v.push(ul4._repr_internal(key, ascii)); + v.push(": "); + v.push(ul4._repr_internal(obj[key], ascii)); + } + v.push("}"); + return v.join(""); + }; + + ul4._repr_internal = function _repr_internal(obj, ascii) + { + if (obj === null) + return "None"; + else if (obj === false) + return "False"; + else if (obj === true) + return "True"; + else if (typeof(obj) === "string") + return ul4._str_repr(obj, ascii); + else if (typeof(obj) === "number") + return "" + obj; + else if (typeof(obj) === "function") + if (obj._ul4_name || obj.name) + return ""; + else + return ""; + else if (ul4._isdate(obj)) + return ul4._date_repr(obj, ascii); + else if (ul4._isdatetime(obj)) + return ul4._datetime_repr(obj, ascii); + else if (typeof(obj) === "undefined") + return ""; + else if (typeof(obj) === "object" && typeof(obj.__repr__) === "function") + return obj.__repr__(); + else if (ul4._islist(obj)) + return ul4._list_repr(obj, ascii); + else if (ul4._ismap(obj)) + return ul4._map_repr(obj, ascii); + else if (ul4._isset(obj)) + return ul4._set_repr(obj, ascii); + else if (ul4._isobject(obj)) + return ul4._object_repr(obj, ascii); + return "?"; + }; + + // Return a string representation of ``obj``: If possible this should be an object literal supported by UL4, otherwise the output should be bracketed with ``<`` and ``>`` + ul4._repr = function _repr(obj) + { + return ul4._repr_internal(obj, false); + }; + + ul4._ascii = function _ascii(obj) + { + return ul4._repr_internal(obj, true); + }; + + ul4._date_str = function _date_str(obj) + { + let year = obj._date.getFullYear(); + let month = obj._date.getMonth()+1; + let day = obj._date.getDate(); + + return year + "-" + ul4._lpad(month.toString(), "0", 2) + "-" + ul4._lpad(day.toString(), "0", 2); + }; + + ul4._datetime_str = function _datetime_str(obj) + { + let year = obj.getFullYear(); + let month = obj.getMonth()+1; + let day = obj.getDate(); + let hour = obj.getHours(); + let minute = obj.getMinutes(); + let second = obj.getSeconds(); + let ms = obj.getMilliseconds(); + + let result = year + "-" + ul4._lpad(month.toString(), "0", 2) + "-" + ul4._lpad(day.toString(), "0", 2) + " " + ul4._lpad(hour.toString(), "0", 2) + ":" + ul4._lpad(minute.toString(), "0", 2); + if (second || ms) + { + result += ":" + ul4._lpad(second.toString(), "0", 2); + if (ms) + result += "." + ul4._lpad(ms.toString(), "0", 3) + "000"; + } + return result; + }; + + ul4._str = function _str(obj) + { + if (typeof(obj) === "undefined") + return ""; + else if (obj === null) + return ""; + else if (obj === false) + return "False"; + else if (obj === true) + return "True"; + else if (typeof(obj) === "string") + return obj; + else if (typeof(obj) === "number") + return obj.toString(); + else if (ul4._isdate(obj)) + return ul4._date_str(obj); + else if (ul4._isdatetime(obj)) + return ul4._datetime_str(obj); + else if (ul4._islist(obj)) + return ul4._list_repr(obj); + else if (ul4._isset(obj)) + return ul4._set_repr(obj); + else if (ul4._ismap(obj)) + return ul4._map_repr(obj); + else if (typeof(obj) === "object" && typeof(obj.__str__) === "function") + return obj.__str__(); + else if (typeof(obj) === "object" && typeof(obj.__repr__) === "function") + return obj.__repr__(); + else if (ul4._isobject(obj)) + return ul4._object_repr(obj); + return "?"; + }; + + // Convert ``obj`` to bool, according to its "truth value" + ul4._bool = function _bool(obj) + { + if (typeof(obj) === "undefined" || obj === null || obj === false || obj === 0 || obj === "") + return false; + else + { + if (typeof(obj) === "object", typeof(obj.__bool__) === "function") + return obj.__bool__(); + if (ul4._islist(obj)) + return obj.length !== 0; + else if (ul4._ismap(obj) || ul4._isset(obj)) + return obj.size != 0; + else if (ul4._isobject(obj)) + { + for (let key in obj) + { + if (!obj.hasOwnProperty(key)) + continue; + return true; + } + return false; + } + return true; + } + }; + + // Convert ``obj`` to an integer (if ``base`` is given ``obj`` must be a string and ``base`` is the base for the conversion (default is 10)) + ul4._int = function _int(obj, base) + { + let result; + if (base !== null) + { + if (typeof(obj) !== "string" || !ul4._isint(base)) + throw new ul4.TypeError("int() requires a string and an integer"); + result = parseInt(obj, base); + if (result.toString() == "NaN") + throw new ul4.TypeError("invalid literal for int()"); + return result; + } + else + { + if (typeof(obj) == "string") + { + result = parseInt(obj); + if (result.toString() == "NaN") + throw new ul4.TypeError("invalid literal for int()"); + return result; + } + else if (typeof(obj) == "number") + return Math.floor(obj); + else if (obj === true) + return 1; + else if (obj === false) + return 0; + throw new ul4.TypeError("int() argument must be a string or a number"); + } + }; + + // Convert ``obj`` to a float + ul4._float = function _float(obj) + { + if (typeof(obj) === "string") + return parseFloat(obj); + else if (typeof(obj) === "number") + return obj; + else if (obj === true) + return 1.0; + else if (obj === false) + return 0.0; + throw new ul4.TypeError("float() argument must be a string or a number"); + }; + + // Convert ``obj`` to a list + ul4._list = function _list(obj) + { + let iter = ul4._iter(obj); + + let result = []; + for (;;) + { + let value = iter.next(); + if (value.done) + return result; + result.push(value.value); + } + }; + + // Convert ``obj`` to a set + ul4._set = function _set(obj) + { + let iter = ul4._iter(obj); + + let result = ul4._emptyset(); + for (;;) + { + let value = iter.next(); + if (value.done) + return result; + result.add(value.value); + } + }; + + // Return the length of ``sequence`` + ul4._len = function _len(sequence) + { + if (typeof(sequence) == "string" || ul4._islist(sequence)) + return sequence.length; + else if (ul4._ismap(sequence) || ul4._isset(sequence)) + return sequence.size; + else if (ul4._isobject(sequence)) + { + let i = 0; + for (let key in sequence) + ++i; + return i; + } + throw new ul4.TypeError("object of type '" + ul4._type(sequence) + "' has no len()"); + }; + + ul4._type = function _type(obj) + { + if (obj === null) + return "none"; + else if (obj === false || obj === true) + return "bool"; + else if (typeof(obj) === "undefined") + return "undefined"; + else if (typeof(obj) === "number") + return Math.round(obj) == obj ? "int" : "float"; + else if (typeof(obj) === "function") + return "function"; + else + { + if (typeof(obj.ul4type) === "function") + return obj.ul4type(); + else + return ul4.Protocol.get(obj).ul4type(obj); + } + }; + + // (this is non-trivial, because it follows the Python semantic of ``-5 % 2`` being ``1``) + ul4._mod = function _mod(obj1, obj2) + { + let div = Math.floor(obj1 / obj2); + let mod = obj1 - div * obj2; + + if (mod !== 0 && ((obj2 < 0 && mod > 0) || (obj2 > 0 && mod < 0))) + { + mod += obj2; + --div; + } + return obj1 - div * obj2; + }, + + // Return the attribute with the name ``attrname`` of the object ``obj`` + // If ``obj`` doesn't have such an attribute, return ``default_`` + ul4._getattr = function _getattr(obj, attrname, default_=null) + { + let proto = ul4.Protocol.get(obj); + try + { + return proto.getattr(obj, attrname); + } + catch (exc) + { + if (exc instanceof ul4.AttributeError && exc.obj === obj) + return default_; + else + throw exc; + } + }; + + // Return wether the object ``obj`` has an attribute with the name ``attrname`` + ul4._hasattr = function _hasattr(obj, attrname) + { + let proto = ul4.Protocol.get(obj); + return proto.hasattr(obj, attrname); + }; + + // Return the names of the attributes of the object ``obj`` as a set. + ul4._dir = function _dir(obj) + { + let proto = ul4.Protocol.get(obj); + return proto.dir(); + }; + + // Return whether any of the items in ``iterable`` are true + ul4._any = function _any(iterable) + { + if (typeof(iterable) == "string") + { + for (let i = 0; i < iterable.length; ++i) + { + if (iterable[i] !== '\x00') + return true; + } + return false; + } + else + { + for (let iter = ul4._iter(iterable);;) + { + let item = iter.next(); + if (item.done) + return false; + if (ul4._bool(item.value)) + return true; + } + } + }; + + // Return whether all of the items in ``iterable`` are true + ul4._all = function _all(iterable) + { + if (typeof(iterable) == "string") + { + for (let i = 0; i < iterable.length; ++i) + { + if (iterable[i] === '\x00') + return false; + } + return true; + } + else + { + for (let iter = ul4._iter(iterable);;) + { + let item = iter.next(); + if (item.done) + return true; + if (!ul4._bool(item.value)) + return false; + } + } + }; + + // Check if ``obj`` is undefined + ul4._isundefined = function _isundefined(obj) + { + return typeof(obj) === "undefined"; + }; + + + // Check if ``obj`` is *not* undefined + ul4._isdefined = function _isdefined(obj) + { + return typeof(obj) !== "undefined"; + }; + + // Check if ``obj`` is ``None`` + ul4._isnone = function _isnone(obj) + { + return obj === null; + }; + + // Check if ``obj`` is a boolean + ul4._isbool = function _isbool(obj) + { + return typeof(obj) == "boolean"; + }; + + // Check if ``obj`` is a int + ul4._isint = function _isint(obj) + { + return (typeof(obj) == "number") && Math.round(obj) == obj; + }; + + // Check if ``obj`` is a float + ul4._isfloat = function _isfloat(obj) + { + return (typeof(obj) == "number") && Math.round(obj) != obj; + }; + + // Check if ``obj`` is a string + ul4._isstr = function _isstr(obj) + { + return typeof(obj) == "string"; + }; + + // Check if ``obj`` is a datetime + ul4._isdatetime = function _isdate(obj) + { + return Object.prototype.toString.call(obj) == "[object Date]"; + }; + + ul4._isdate = function _isdate(obj) + { + return (obj instanceof ul4.Date); + }; + + // Check if ``obj`` is a color + ul4._iscolor = function _iscolor(obj) + { + return (obj instanceof ul4.Color); + }; + + // Check if ``obj`` is a timedelta object + ul4._istimedelta = function _istimedelta(obj) + { + return (obj instanceof ul4.TimeDelta); + }; + + // Check if ``obj`` is a monthdelta object + ul4._ismonthdelta = function _ismonthdelta(obj) + { + return (obj instanceof ul4.MonthDelta); + }; + + // Check if ``obj`` is a template + ul4._istemplate = function _istemplate(obj) + { + return (obj instanceof ul4.Template || obj instanceof ul4.TemplateClosure); + }; + + // Check if ``obj`` is a function + ul4._isfunction = function _isfunction(obj) + { + return typeof(obj) === "function" || (Object.prototype.toString.call(obj) == "[object Object]" && (obj instanceof ul4.Template || obj instanceof ul4.TemplateClosure)); + }; + + // Check if ``obj`` is a list + ul4._islist = function _islist(obj) + { + return Object.prototype.toString.call(obj) == "[object Array]"; + }; + + // Check if ``obj`` is a set + ul4._isset = function _isset(obj) + { + return Object.prototype.toString.call(obj) == "[object Set]"; + }; + + // Check if ``obj`` is an exception (at least a UL4 exception) + ul4._isexception = function _isexception(obj) + { + return (obj instanceof ul4.Exception); + }; + + ul4._isul4set = function _isul4set(obj) + { + return (obj instanceof ul4._Set); + }; + + ul4._isanyset = function _isanyset(obj) + { + return (ul4._isset(obj) || ul4._isul4set(obj)); + }; + + // Check if ``obj`` is an iterator + ul4._isiter = function _isiter(obj) + { + return obj !== null && typeof(obj) === "object" && typeof(obj.next) === "function"; + }; + + // Check if ``obj`` is a JS object + ul4._isobject = function _isobject(obj) + { + return Object.prototype.toString.call(obj) == "[object Object]" && typeof(obj.__type__) === "undefined" && !(obj instanceof ul4.Proto); + }; + + if (ul4._havemap) + { + // Check if ``obj`` is a ``Map`` + ul4._ismap = function _ismap(obj) + { + return obj !== null && typeof(obj) === "object" && typeof(obj.__proto__) === "object" && obj.__proto__ === Map.prototype; + }; + + // Check if ``obj`` is a dict (i.e. a normal Javascript object or a ``Map``) + ul4._isdict = function _isdict(obj) + { + return ul4._isobject(obj) || ul4._ismap(obj); + }; + } + else + { + ul4._ismap = function _ismap(obj) + { + return false; + }; + + ul4._isdict = function _isdict(obj) + { + return ul4._isobject(obj); + }; + } + + // Repeat string ``str`` ``rep`` times + ul4._str_repeat = function _str_repeat(str, rep) + { + let result = ""; + for (; rep>0; --rep) + result += str; + return result; + }; + + ul4._list_repeat = function _list_repeat(list, rep) + { + let result = []; + for (; rep>0; --rep) + for (let i = 0; i < list.length; ++i) + result.push(list[i]); + return result; + }; + + ul4._str_json = function _str_json(str) + { + let result = ""; + for (let i = 0; i < str.length; ++i) + { + let c = str[i]; + switch (c) + { + case "\r": + result += "\\r"; + break; + case "\n": + result += "\\n"; + break; + case "\t": + result += "\\t"; + break; + case "\\": + result += "\\\\"; + break; + case '"': + result += '\\"'; + break; + case '<': + result += '\\u003c'; + break; + default: + let code = c.charCodeAt(0); + if (code >= 32 && code < 128) + result += c; + else + result += "\\u" + ul4._lpad(code.toString(16), "0", 4); + break; + } + } + return '"' + result + '"'; + }; + + // Encodes ``obj`` in the Javascript Object Notation (see http://json.org/; with support for dates, colors and templates) + ul4._asjson = function _asjson(obj) + { + if (obj === null) + return "null"; + else if (typeof(obj) === "undefined") + return "undefined"; + else if (obj === false) + return "false"; + else if (obj === true) + return "true"; + else if (typeof(obj) === "string") + return ul4._str_json(obj); + else if (typeof(obj) === "number") + { + return "" + obj; + } + else if (ul4._islist(obj)) + { + let v = []; + v.push("["); + for (let i = 0; i < obj.length; ++i) + { + if (i != 0) + v.push(", "); + v.push(ul4._asjson(obj[i])); + } + v.push("]"); + return v.join(""); + } + else if (ul4._ismap(obj)) + { + let v = []; + v.push("{"); + let i = 0; + obj.forEach(function(value, key) { + if (i++) + v.push(", "); + v.push(ul4._asjson(key)); + v.push(": "); + v.push(ul4._asjson(value)); + }); + v.push("}"); + return v.join(""); + } + else if (ul4._isobject(obj)) + { + let v = []; + v.push("{"); + let i = 0; + for (let key in obj) + { + if (i++) + v.push(", "); + v.push(ul4._asjson(key)); + v.push(": "); + v.push(ul4._asjson(obj[key])); + } + v.push("}"); + return v.join(""); + } + else if (ul4._isdate(obj)) + { + return "new ul4.Date(" + obj._date.getFullYear() + ", " + (obj._date.getMonth()+1) + ", " + obj._date.getDate() + ")"; + } + else if (ul4._isdatetime(obj)) + { + return "new Date(" + obj.getFullYear() + ", " + obj.getMonth() + ", " + obj.getDate() + ", " + obj.getHours() + ", " + obj.getMinutes() + ", " + obj.getSeconds() + ", " + obj.getMilliseconds() + ")"; + } + else if (ul4._istimedelta(obj)) + { + return "new ul4.TimeDelta(" + obj._days + ", " + obj._seconds + ", " + obj._microseconds + ")"; + } + else if (ul4._ismonthdelta(obj)) + { + return "new ul4.MonthDelta(" + obj._months + ")"; + } + else if (ul4._iscolor(obj)) + { + return "new ul4.Color(" + obj._r + ", " + obj._g + ", " + obj._b + ", " + obj._a + ")"; + } + else if (ul4._istemplate(obj)) + { + return "ul4.Template.loads(" + ul4._repr(obj.dumps()) + ")"; + } + throw new ul4.TypeError("asjson() requires a serializable object"); + }; + + // Decodes the string ``string`` from the Javascript Object Notation (see http://json.org/) and returns the resulting object + ul4._fromjson = function _fromjson(string) + { + // The following is from jQuery's parseJSON function + string = ul4.StrProtocol.strip(string); + if (root.JSON && root.JSON.parse) + return root.JSON.parse(string); + if (ul4._rvalidchars.test(string.replace(ul4._rvalidescape, "@").replace(ul4._rvalidtokens, "]").replace(ul4._rvalidbraces, ""))) + return (new Function("return " + string))(); + throw new ul4.TypeError("invalid JSON"); + }; + + // Encodes ``obj`` in the UL4 Object Notation format + ul4._asul4on = function _asul4on(obj) + { + return ul4.dumps(obj); + }; + + // Decodes the string ``string`` from the UL4 Object Notation format and returns the resulting decoded object + ul4._fromul4on = function _fromul4on(string) + { + return ul4.loads(string); + }; + + ul4._format_datetime = function _format_datetime(obj, fmt, lang) + { + let translations = { + de: { + ms: ["Jan", "Feb", "M\u00e4r", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"], + ml: ["Januar", "Februar", "M\u00e4rz", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], + ws: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], + wl: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + en: { + ms: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + ml: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + ws: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + wl: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], + xf: "%m/%d/%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %I:%M:%S %p" + }, + fr: { + ms: ["janv.", "f\u00e9vr.", "mars", "avril", "mai", "juin", "juil.", "ao\u00fbt", "sept.", "oct.", "nov.", "d\u00e9c."], + ml: ["janvier", "f\u00e9vrier", "mars", "avril", "mai", "juin", "juillet", "ao\u00fbt", "septembre", "octobre", "novembre", "d\u00e9cembre"], + ws: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."], + wl: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], + xf: "%d/%m/%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + es: { + ms: ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"], + ml: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"], + ws: ["dom", "lun", "mar", "mi\u00e9", "jue", "vie", "s\u00e1b"], + wl: ["domingo", "lunes", "martes", "mi\u00e9rcoles", "jueves", "viernes", "s\u00e1bado"], + xf: "%d/%m/%y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + it: { + ms: ["gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic"], + ml: ["gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre"], + ws: ["dom", "lun", "mar", "mer", "gio", "ven", "sab"], + wl: ["domenica", "luned\u00ec", "marted\u00ec", "mercoled\u00ec", "gioved\u00ec", "venerd\u00ec", "sabato"], + xf: "%d/%m/%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + da: { + ms: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"], + ml: ["januar", "februar", "marts", "april", "maj", "juni", "juli", "august", "september", "oktober", "november", "december"], + ws: ["s\u00f8n", "man", "tir", "ons", "tor", "fre", "l\u00f8r"], + wl: ["s\u00f8ndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "l\u00f8rdag"], + xf: "%d-%m-%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + sv: { + ms: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"], + ml: ["januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december"], + ws: ["s\u00f6n", "m\u00e5n", "tis", "ons", "tor", "fre", "l\u00f6r"], + wl: ["s\u00f6ndag", "m\u00e5ndag", "tisdag", "onsdag", "torsdag", "fredag", "l\u00f6rdag"], + xf: "%Y-%m-%d", + Xf: "%H.%M.%S", + cf: "%a %d %b %Y %H.%M.%S" + }, + nl: { + ms: ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"], + ml: ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"], + ws: ["zo", "ma", "di", "wo", "do", "vr", "za"], + wl: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"], + xf: "%d-%m-%y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + pt: { + ms: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"], + ml: ["Janeiro", "Fevereiro", "Mar\u00e7o", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"], + ws: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "S\u00e1b"], + wl: ["Domingo", "Segunda", "Ter\u00e7a", "Quarta", "Quinta", "Sexta", "S\u00e1bado"], + xf: "%d-%m-%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + cs: { + ms: ["led", "\u00fano", "b\u0159e", "dub", "kv\u011b", "\u010den", "\u010dec", "srp", "z\u00e1\u0159", "\u0159\u00edj", "lis", "pro"], + ml: ["leden", "\u00fanor", "b\u0159ezen", "duben", "kv\u011bten", "\u010derven", "\u010dervenec", "srpen", "z\u00e1\u0159\u00ed", "\u0159\u00edjen", "listopad", "prosinec"], + ws: ["Ne", "Po", "\u00dat", "St", "\u010ct", "P\u00e1", "So"], + wl: ["Ned\u011ble", "Pond\u011bl\u00ed", "\u00dater\u00fd", "St\u0159eda", "\u010ctvrtek", "P\u00e1tek", "Sobota"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a\u00a0%d.\u00a0%B\u00a0%Y,\u00a0%H:%M:%S" + }, + sk: { + ms: ["jan", "feb", "mar", "apr", "m\u00e1j", "j\u00fan", "j\u00fal", "aug", "sep", "okt", "nov", "dec"], + ml: ["janu\u00e1r", "febru\u00e1r", "marec", "apr\u00edl", "m\u00e1j", "j\u00fan", "j\u00fal", "august", "september", "okt\u00f3ber", "november", "december"], + ws: ["Ne", "Po", "Ut", "St", "\u0160t", "Pi", "So"], + wl: ["Nede\u013ea", "Pondelok", "Utorok", "Streda", "\u0160tvrtok", "Piatok", "Sobota"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a\u00a0%d.\u00a0%B\u00a0%Y,\u00a0%H:%M:%S" + }, + pl: { + ms: ["sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "pa\u017a", "lis", "gru"], + ml: ["stycze\u0144", "luty", "marzec", "kwiecie\u0144", "maj", "czerwiec", "lipiec", "sierpie\u0144", "wrzesie\u0144", "pa\u017adziernik", "listopad", "grudzie\u0144"], + ws: ["nie", "pon", "wto", "\u015bro", "czw", "pi\u0105", "sob"], + wl: ["niedziela", "poniedzia\u0142ek", "wtorek", "\u015broda", "czwartek", "pi\u0105tek", "sobota"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a, %d %b %Y, %H:%M:%S" + }, + hr: { + ms: ["Sij", "Vel", "O\u017eu", "Tra", "Svi", "Lip", "Srp", "Kol", "Ruj", "Lis", "Stu", "Pro"], + ml: ["Sije\u010danj", "Velja\u010da", "O\u017eujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"], + ws: ["Ned", "Pon", "Uto", "Sri", "\u010cet", "Pet", "Sub"], + wl: ["Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "\u010cetvrtak", "Petak", "Subota"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + sr: { + ms: ["\u0458\u0430\u043d", "\u0444\u0435\u0431", "\u043c\u0430\u0440", "\u0430\u043f\u0440", "\u043c\u0430\u0458", "\u0458\u0443\u043d", "\u0458\u0443\u043b", "\u0430\u0432\u0433", "\u0441\u0435\u043f", "\u043e\u043a\u0442", "\u043d\u043e\u0432", "\u0434\u0435\u0446"], + ml: ["\u0458\u0430\u043d\u0443\u0430\u0440", "\u0444\u0435\u0431\u0440\u0443\u0430\u0440", "\u043c\u0430\u0440\u0442", "\u0430\u043f\u0440\u0438\u043b", "\u043c\u0430\u0458", "\u0458\u0443\u043d", "\u0458\u0443\u043b", "\u0430\u0432\u0433\u0443\u0441\u0442", "\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440", "\u043e\u043a\u0442\u043e\u0431\u0430\u0440", "\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440", "\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440"], + ws: ["\u043d\u0435\u0434", "\u043f\u043e\u043d", "\u0443\u0442\u043e", "\u0441\u0440\u0435", "\u0447\u0435\u0442", "\u043f\u0435\u0442", "\u0441\u0443\u0431"], + wl: ["\u043d\u0435\u0434\u0435\u0459\u0430", "\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a", "\u0443\u0442\u043e\u0440\u0430\u043a", "\u0441\u0440\u0435\u0434\u0430", "\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a", "\u043f\u0435\u0442\u0430\u043a", "\u0441\u0443\u0431\u043e\u0442\u0430"], + xf: "%d.%m.%Y.", + Xf: "%H:%M:%S", + cf: "%A, %d. %B %Y. %H:%M:%S" + }, + ro: { + ms: ["ian", "feb", "mar", "apr", "mai", "iun", "iul", "aug", "sep", "oct", "nov", "dec"], + ml: ["ianuarie", "februarie", "martie", "aprilie", "mai", "iunie", "iulie", "august", "septembrie", "octombrie", "noiembrie", "decembrie"], + ws: ["Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sb"], + wl: ["duminic\u0103", "luni", "mar\u0163i", "miercuri", "joi", "vineri", "s\u00e2mb\u0103t\u0103"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + hu: { + ms: ["jan", "febr", "m\u00e1rc", "\u00e1pr", "m\u00e1j", "j\u00fan", "j\u00fal", "aug", "szept", "okt", "nov", "dec"], + ml: ["janu\u00e1r", "febru\u00e1r", "m\u00e1rcius", "\u00e1prilis", "m\u00e1jus", "j\u00fanius", "j\u00falius", "augusztus", "szeptember", "okt\u00f3ber", "november", "december"], + ws: ["v", "h", "k", "sze", "cs", "p", "szo"], + wl: ["vas\u00e1rnap", "h\u00e9tf\u0151", "kedd", "szerda", "cs\u00fct\u00f6rt\u00f6k", "p\u00e9ntek", "szombat"], + xf: "%Y-%m-%d", + Xf: "%H.%M.%S", + cf: "%Y. %b. %d., %A, %H.%M.%S" + }, + tr: { + ms: ["Oca", "\u015eub", "Mar", "Nis", "May", "Haz", "Tem", "A\u011fu", "Eyl", "Eki", "Kas", "Ara"], + ml: ["Ocak", "\u015eubat", "Mart", "Nisan", "May\u0131s", "Haziran", "Temmuz", "A\u011fustos", "Eyl\u00fcl", "Ekim", "Kas\u0131m", "Aral\u0131k"], + ws: ["Paz", "Pzt", "Sal", "\u00c7r\u015f", "Pr\u015f", "Cum", "Cts"], + wl: ["Pazar", "Pazartesi", "Sal\u0131", "\u00c7ar\u015famba", "Per\u015fembe", "Cuma", "Cumartesi"], + xf: "%d-%m-%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + ru: { + ms: ["\u042f\u043d\u0432", "\u0424\u0435\u0432", "\u041c\u0430\u0440", "\u0410\u043f\u0440", "\u041c\u0430\u0439", "\u0418\u044e\u043d", "\u0418\u044e\u043b", "\u0410\u0432\u0433", "\u0421\u0435\u043d", "\u041e\u043a\u0442", "\u041d\u043e\u044f", "\u0414\u0435\u043a"], + ml: ["\u042f\u043d\u0432\u0430\u0440\u044c", "\u0424\u0435\u0432\u0440\u0430\u043b\u044c", "\u041c\u0430\u0440\u0442", "\u0410\u043f\u0440\u0435\u043b\u044c", "\u041c\u0430\u0439", "\u0418\u044e\u043d\u044c", "\u0418\u044e\u043b\u044c", "\u0410\u0432\u0433\u0443\u0441\u0442", "\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c", "\u041e\u043a\u0442\u044f\u0431\u0440\u044c", "\u041d\u043e\u044f\u0431\u0440\u044c", "\u0414\u0435\u043a\u0430\u0431\u0440\u044c"], + ws: ["\u0412\u0441\u043a", "\u041f\u043d\u0434", "\u0412\u0442\u0440", "\u0421\u0440\u0434", "\u0427\u0442\u0432", "\u041f\u0442\u043d", "\u0421\u0431\u0442"], + wl: ["\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435", "\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a", "\u0412\u0442\u043e\u0440\u043d\u0438\u043a", "\u0421\u0440\u0435\u0434\u0430", "\u0427\u0435\u0442\u0432\u0435\u0440\u0433", "\u041f\u044f\u0442\u043d\u0438\u0446\u0430", "\u0421\u0443\u0431\u0431\u043e\u0442\u0430"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + zh: { + ms: [" 1\u6708", " 2\u6708", " 3\u6708", " 4\u6708", " 5\u6708", " 6\u6708", " 7\u6708", " 8\u6708", " 9\u6708", "10\u6708", "11\u6708", "12\u6708"], + ml: ["\u4e00\u6708", "\u4e8c\u6708", "\u4e09\u6708", "\u56db\u6708", "\u4e94\u6708", "\u516d\u6708", "\u4e03\u6708", "\u516b\u6708", "\u4e5d\u6708", "\u5341\u6708", "\u5341\u4e00\u6708", "\u5341\u4e8c\u6708"], + ws: ["\u65e5", "\u4e00", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d"], + wl: ["\u661f\u671f\u65e5", "\u661f\u671f\u4e00", "\u661f\u671f\u4e8c", "\u661f\u671f\u4e09", "\u661f\u671f\u56db", "\u661f\u671f\u4e94", "\u661f\u671f\u516d"], + xf: "%Y\u5e74%b%d\u65e5", + Xf: "%H\u65f6%M\u5206%S\u79d2", + cf: "%Y\u5e74%b%d\u65e5 %A %H\u65f6%M\u5206%S\u79d2" + }, + ko: { + ms: [" 1\uc6d4", " 2\uc6d4", " 3\uc6d4", " 4\uc6d4", " 5\uc6d4", " 6\uc6d4", " 7\uc6d4", " 8\uc6d4", " 9\uc6d4", "10\uc6d4", "11\uc6d4", "12\uc6d4"], + ml: ["1\uc6d4", "2\uc6d4", "3\uc6d4", "4\uc6d4", "5\uc6d4", "6\uc6d4", "7\uc6d4", "8\uc6d4", "9\uc6d4", "10\uc6d4", "11\uc6d4", "12\uc6d4"], + ws: ["\uc77c", "\uc6d4", "\ud654", "\uc218", "\ubaa9", "\uae08", "\ud1a0"], + wl: ["\uc77c\uc694\uc77c", "\uc6d4\uc694\uc77c", "\ud654\uc694\uc77c", "\uc218\uc694\uc77c", "\ubaa9\uc694\uc77c", "\uae08\uc694\uc77c", "\ud1a0\uc694\uc77c"], + xf: "%Y\ub144 %B %d\uc77c", + Xf: "%H\uc2dc %M\ubd84 %S\ucd08", + cf: "%Y\ub144 %B %d\uc77c (%a) %p %I\uc2dc %M\ubd84 %S\ucd08" + }, + ja: { + ms: [" 1\u6708", " 2\u6708", " 3\u6708", " 4\u6708", " 5\u6708", " 6\u6708", " 7\u6708", " 8\u6708", " 9\u6708", "10\u6708", "11\u6708", "12\u6708"], + ml: ["1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708"], + ws: ["\u65e5", "\u6708", "\u706b", "\u6c34", "\u6728", "\u91d1", "\u571f"], + wl: ["\u65e5\u66dc\u65e5", "\u6708\u66dc\u65e5", "\u706b\u66dc\u65e5", "\u6c34\u66dc\u65e5", "\u6728\u66dc\u65e5", "\u91d1\u66dc\u65e5", "\u571f\u66dc\u65e5"], + xf: "%Y\u5e74%B%d\u65e5", + Xf: "%H\u6642%M\u5206%S\u79d2", + cf: "%Y\u5e74%B%d\u65e5 %H\u6642%M\u5206%S\u79d2" + } + }; + + let translation = translations[lang]; + + let result = []; + let inspec = false; + for (let i = 0; i < fmt.length; ++i) + { + let c = fmt[i]; + if (inspec) + { + switch (c) + { + case "a": + c = translation.ws[obj.getDay()]; + break; + case "A": + c = translation.wl[obj.getDay()]; + break; + case "b": + c = translation.ms[obj.getMonth()]; + break; + case "B": + c = translation.ml[obj.getMonth()]; + break; + case "c": + c = ul4._format(obj, translation.cf, lang); + break; + case "d": + c = ul4._lpad(obj.getDate(), "0", 2); + break; + case "f": + c = ul4._lpad(obj.getMilliseconds(), "0", 3) + "000"; + break; + case "H": + c = ul4._lpad(obj.getHours(), "0", 2); + break; + case "I": + c = ul4._lpad(((obj.getHours()-1) % 12)+1, "0", 2); + break; + case "j": + c = ul4._lpad(ul4.DateTimeProtocol.yearday(obj), "0", 3); + break; + case "m": + c = ul4._lpad(obj.getMonth()+1, "0", 2); + break; + case "M": + c = ul4._lpad(obj.getMinutes(), "0", 2); + break; + case "p": + c = obj.getHours() < 12 ? "AM" : "PM"; + break; + case "S": + c = ul4._lpad(obj.getSeconds(), "0", 2); + break; + case "U": + c = ul4._lpad(ul4._week4format(obj, 6), "0", 2); + break; + case "w": + c = obj.getDay(); + break; + case "W": + c = ul4._lpad(ul4._week4format(obj, 0), "0", 2); + break; + case "x": + c = ul4._format(obj, translation.xf, lang); + break; + case "X": + c = ul4._format(obj, translation.Xf, lang); + break; + case "y": + c = (obj.getFullYear() % 100).toString(); + break; + case "Y": + c = obj.getFullYear().toString(); + break; + case "z": + // UTC offset in the form +HHMM or -HHMM + c = ""; + break; + case "Z": + // Time zone name + c = ""; + break; + } + result.push(c); + inspec = false; + } + else + { + if (c == "%") + inspec = true; + else + result.push(c); + } + } + return result.join(""); + }; + + ul4._format_int = function _format_int(obj, fmt, lang) + { + let work = fmt; + + // Defaults + let fill = ' '; + let align = '>'; // '<', '>', '=' or '^' + let sign = '-'; // '+', '-' or ' ' + let alternate = false; + let minimumwidth = 0; + let type = 'd'; // 'b', 'c', 'd', 'o', 'x', 'X' or 'n' + + // Determine output type + if (/[bcdoxXn]$/.test(work)) + { + type = work.substring(work.length-1); + work = work.substring(0, work.length-1); + } + + // Extract minimum width + if (/\d+$/.test(work)) + { + let minimumwidthStr = /\d+$/.exec(work); + work = work.replace(/\d+$/, ""); + if (/^0/.test(minimumwidthStr)) + { + align = '='; + fill = '0'; + } + minimumwidth = parseInt(minimumwidthStr); + } + + // Alternate form? + if (/#$/.test(work)) + { + alternate = true; + work = work.substring(0, work.length-1); + } + + // Determine sign + if (/[+ -]$/.test(work)) + { + if (type == 'c') + throw new ul4.ValueError("sign not allowed for integer format type 'c'"); + sign = work.substring(work.length-1); + work = work.substring(0, work.length-1); + } + + // Extract fill and align char + if (work.length >= 3) + throw new ul4.ValueError("illegal integer format string " + ul4._repr(fmt)); + else if (work.length == 2) + { + if (/[<>=^]$/.test(work)) + { + align = work[1]; + fill = work[0]; + } + else + throw new ul4.ValueError("illegal integer format string " + ul4._repr(fmt)); + } + else if (work.length == 1) + { + if (/^[<>=^]$/.test(work)) + align = work; + else + throw new ul4.ValueError("illegal integer format string " + ul4._repr(fmt)); + } + + // Basic number formatting + let neg = obj < 0; + + if (neg) + obj = -obj; + + let output; + switch (type) + { + case 'b': + output = obj.toString(2); + break; + case 'c': + if (neg || obj > 65535) + throw new ul4.ValueError("value out of bounds for c format"); + output = String.fromCharCode(obj); + break; + case 'd': + output = obj.toString(); + break; + case 'o': + output = obj.toString(8); + break; + case 'x': + output = obj.toString(16); + break; + case 'X': + output = obj.toString(16).toUpperCase(); + break; + case 'n': + // FIXME: locale formatting + output = obj.toString(); + break; + } + + // The rest of the formatting + if (align === '=') + { + if (neg || sign !== '-') + --minimumwidth; + if (alternate && (type === 'b' || type === 'o' || type === 'x' || type === 'X')) + minimumwidth -= 2; + + if (output.length < minimumwidth) + output = ul4._str_repeat(fill, minimumwidth-output.length) + output; + + if (alternate && (type === 'b' || type === 'o' || type === 'x' || type === 'X')) + output = "0" + type + output; + + if (neg) + output = "-" + output; + else if (sign != '-') + output = sign + output; + } + else + { + if (alternate && (type == 'b' || type == 'o' || type == 'x' || type == 'X')) + output = "0" + type + output; + if (neg) + output = "-" + output; + else if (sign != '-') + output = sign + output; + if (output.length < minimumwidth) + { + if (align == '<') + output = output + ul4._str_repeat(fill, minimumwidth-output.length); + else if (align == '>') + output = ul4._str_repeat(fill, minimumwidth-output.length) + output; + else // if (align == '^') + { + let pad = minimumwidth - output.length; + let padBefore = Math.floor(pad/2); + let padAfter = pad-padBefore; + output = ul4._str_repeat(fill, padBefore) + output + ul4._str_repeat(fill, padAfter); + } + } + } + return output; + }; + + // Format ``obj`` using the format string ``fmt`` in the language ``lang`` + ul4._format = function _format(obj, fmt, lang) + { + if (typeof(lang) === "undefined" || lang === null) + lang = "en"; + else + { + let translations = {de: null, en: null, fr: null, es: null, it: null, da: null, sv: null, nl: null, pt: null, cs: null, sk: null, pl: null, hr: null, sr: null, ro: null, hu: null, tr: null, ru: null, zh: null, ko: null, ja: null}; + lang = lang.toLowerCase(); + if (typeof(translations[lang]) === "undefined") + { + lang = lang.split(/_/)[0]; + if (typeof(translations[lang]) === "undefined") + lang = "en"; + } + } + if (ul4._isdate(obj)) + return ul4._format_datetime(obj._date, fmt, lang); + if (ul4._isdatetime(obj)) + return ul4._format_datetime(obj, fmt, lang); + else if (ul4._isint(obj)) + return ul4._format_int(obj, fmt, lang); + else if (obj === true) + return ul4._format_int(1, fmt, lang); + else if (obj === false) + return ul4._format_int(0, fmt, lang); + }; + + ul4._lpad = function _lpad(string, pad, len) + { + if (typeof(string) === "number") + string = string.toString(); + while (string.length < len) + string = pad + string; + return string; + }; + + ul4._rpad = function _rpad(string, pad, len) + { + if (typeof(string) === "number") + string = string.toString(); + while (string.length < len) + string = string + pad; + return string; + }; + + // This is outside of ``Proto`` on purpose + // This way reactive frameworks like ``Vue.js`` don't get to see it + // and complain about mutating render functions when those create new objects. + let _nextid = 1; + + ul4.Proto = class Proto + { + constructor() + { + this.__id__ = _nextid++; + } + + ul4type() + { + return this.constructor.name; + } + + // equality comparison of objects defaults to identity comparison + __eq__(other) + { + return this === other; + } + + // To overwrite equality comparison, you only have to overwrite ``__eq__``, + // ``__ne__`` will be synthesized from that + __ne__(other) + { + return !this.__eq__(other); + } + + // For other comparison operators, each method has to be implemented: + // ``<`` calls ``__lt__``, ``<=`` calls ``__le__``, ``>`` calls ``__gt__`` and + // ``>=`` calls ``__ge__`` + + __bool__() + { + return true; + } + }; + + ul4.Signature = class Signature extends ul4.Proto + { + constructor(...args) + { + super(); + this.args = []; + this.argNames = {}; + this.remargs = null; + this.remkwargs = null; + + let nextDefault = false; + let lastArgname = null; + for (let i = 0; i < args.length; ++i) + { + let argName = args[i]; + if (nextDefault) + { + this.args.push({name: lastArgname, defaultValue: argName}); + this.argNames[lastArgname] = true; + nextDefault = false; + } + else + { + if (argName.substr(argName.length-1) === "=") + { + lastArgname = argName.substr(0, argName.length-1); + nextDefault = true; + } + else if (argName.substr(0, 2) === "**") + this.remkwargs = argName.substr(2); + else if (argName.substr(0, 1) === "*") + this.remargs = argName.substr(1); + else + { + this.args.push({name: argName}); + this.argNames[argName] = true; + } + } + } + } + + // Create the argument array for calling a function with this signature with the arguments available from ``args`` + bindArray(name, args, kwargs) + { + let finalargs = []; + let decname = name !== null ? name + "() " : ""; + + for (let i = 0; i < this.args.length; ++i) + { + let arg = this.args[i]; + if (i < args.length) + { + if (kwargs.hasOwnProperty(arg.name)) + throw new ul4.ArgumentError(decname + "argument " + ul4._repr(arg.name) + " (position " + i + ") specified multiple times"); + finalargs.push(args[i]); + } + else + { + if (kwargs.hasOwnProperty(arg.name)) + finalargs.push(kwargs[arg.name]); + else + { + if (arg.hasOwnProperty("defaultValue")) + finalargs.push(arg.defaultValue); + else + throw new ul4.ArgumentError("required " + decname + "argument " + ul4._repr(arg.name) + " (position " + i + ") missing"); + } + } + } + + // Do we accept additional positional arguments? + if (this.remargs === null) + { + // No, but we have them -> complain + if (args.length > this.args.length) + { + let prefix = name === null ? "expected" : name + "() expects"; + throw new ul4.ArgumentError(prefix + " at most " + this.args.length + " positional argument" + (this.args.length != 1 ? "s" : "") + ", " + args.length + " given"); + } + } + else + { + // Put additional positional arguments in the call into the ``*`` argument (if there are none, this pushes an empty list) + finalargs.push(args.slice(this.args.length)); + } + + // Do we accept arbitrary keyword arguments? + if (this.remkwargs === null) + { + // No => complain about unknown ones + for (let key in kwargs) + { + if (!this.argNames[key]) + { + if (name === null) + throw new ul4.ArgumentError("an argument named " + ul4._repr(key) + " isn't supported"); + else + throw new ul4.ArgumentError(name + "() doesn't support an argument named " + ul4._repr(key)); + } + } + } + else + { + // Yes => Put the unknown ones into an object and add that to the arguments array + let remkwargs = ul4._emptymap(); + for (let key in kwargs) + { + if (!this.argNames[key]) + ul4._setmap(remkwargs, key, kwargs[key]); + } + finalargs.push(remkwargs); + } + + return finalargs; + } + + // Create the argument object for calling a function with this signature with the arguments available from ``args`` + bindObject(name, args, kwargs) + { + args = this.bindArray(name, args, kwargs); + let argObject = {}; + let i; + for (i = 0; i < this.args.length; ++i) + argObject[this.args[i].name] = args[i]; + if (this.remargs !== null) + argObject[this.remargs] = args[i++]; + if (this.remkwargs !== null) + argObject[this.remkwargs] = args[i++]; + return argObject; + } + + __repr__() + { + return ""; + } + + __str__() + { + return this.toString(); + } + + toString() + { + let v = []; + for (let i = 0; i < this.args.length; ++i) + { + let arg = this.args[i]; + if (arg.hasOwnProperty("defaultValue")) + v.push(arg.name + "=" + ul4._repr(arg.defaultValue)); + else + v.push(arg.name); + } + if (this.remargs !== null) + v.push("*" + this.remargs); + if (this.remkwargs !== null) + v.push("**" + this.remkwargs); + return "(" + v.join(", ") + ")"; + } + }; + + // When we don't have a real ``Set`` type, emulate one that supports strings + ul4._Set = class _Set + { + constructor(...items) + { + this.items = {}; + this.add(...items); + } + + add(...items) + { + for (let i = 0; i < items.length; ++i) + this.items[items[i]] = true; + } + + clear() + { + this.items = {}; + } + + __getattr__(attrname) + { + let self = this; + switch (attrname) + { + case "add": + return ul4.expose(function add(items){ self.add(...items); }, ["*items"]); + default: + throw new ul4.AttributeError(this, attrname); + } + } + + __contains__(item) + { + return this.items[item] || false; + } + + has(item) + { + return this.items[item] || false; + } + + __bool__() + { + for (let item in this.items) + { + if (!this.items.hasOwnProperty(item)) + continue; + return true; + } + return false; + } + + __repr__() + { + let v = []; + v.push("{"); + let i = 0; + for (let item in this.items) + { + if (!this.items.hasOwnProperty(item)) + continue; + if (i++) + v.push(", "); + v.push(ul4._repr(item)); + } + if (!i) + v.push("/"); + v.push("}"); + return v.join(""); + } + + __eq__(other) + { + // We'll check that everything in ``this`` is in ``other`` + // and if both have the same number of items they are equal + if (ul4._isset(other)) + { + let count = 0; + for (let item in this.items) + { + if (!other.has(item)) + return false; + // count the number of items we have + ++count; + } + return other.size == count; + } + else if (ul4._isul4set(other)) + { + let count = 0; + for (let item in this.items) + { + if (!other[item]) + return false; + // count the number of items we have + ++count; + } + // Subtract the number of items that ``other`` has + for (let item in other.items) + --count; + return count == 0; + } + else + return false; + } + + __le__(other) + { + // check that ``this`` is a subset of ``other``, + // i.e. everything in ``this`` is also in ``other`` + if (ul4._isset(other)) + { + let count = 0; + for (let item in this.items) + { + if (!other.has(item)) + return false; + } + return true; + } + else if (ul4._isul4set(other)) + { + let count = 0; + for (let item in this.items) + { + if (!other.items[item]) + return false; + } + return true; + } + else + ul4._unorderable("<", this, other); + } + + __ge__(other) + { + // check that ``this`` is a superset of ``other``, + // i.e. everything in ``other`` is also in ``this`` + if (ul4._isset(other)) + { + other.forEach(function(value) { + if (!this.items[value]) + return false; + }, this); + return true; + } + else if (ul4._isul4set(other)) + { + let count = 0; + for (let key in other.items) + { + if (!this.items[key]) + return false; + } + return true; + } + else + ul4._unorderable("<=", this, other); + } + }; + + ul4._Set.prototype.__type__ = "set"; + + // Adds name and signature to a function/method and makes the method callable in templates + ul4.expose = function expose(f, signature, options) + { + options = options || {}; + if (options.name) + f._ul4_name = options.name; + if (ul4._islist(signature)) + signature = new ul4.Signature(...signature); + f._ul4_signature = signature; + f._ul4_needsobject = options.needsobject || false; + f._ul4_needscontext = options.needscontext || false; + }; + + // Protocol objects for all builtin types + // These objects are singleton, so we replace the constructor with the prototype object afterwards + ul4.Protocol = class Protocol + { + ul4type() + { + return this.constructor.name; + } + + dir() + { + return this.attrs; + } + + get(obj) + { + if (ul4._isstr(obj)) + return ul4.StrProtocol; + else if (ul4._islist(obj)) + return ul4.ListProtocol; + else if (ul4._isdate(obj)) + return ul4.DateProtocol; + else if (ul4._isset(obj)) + return ul4.SetProtocol; + else if (ul4._ismap(obj)) + return ul4.MapProtocol; + else if (ul4._isdatetime(obj)) + return ul4.DateTimeProtocol; + else if (ul4._isobject(obj)) + return ul4.ObjectProtocol; + else + return ul4.Protocol; + } + + getattr(obj, attrname) + { + if (obj === null || typeof(obj) === "undefined") + throw new ul4.AttributeError(obj, attrname); + else if (typeof(obj.__getattr__) === "function") + return obj.__getattr__(attrname); + else if (this.attrs.has(attrname)) + { + let attr = this[attrname]; + let realattr = function realattr(...args) { + return attr.apply(this, [obj, ...args]); + }; + realattr.name = attr.name; + realattr._ul4_name = attr._ul4_name || attr.name; + realattr._ul4_signature = attr._ul4_signature; + realattr._ul4_needsobject = attr._ul4_needsobject; + realattr._ul4_needscontext = attr._ul4_needscontext; + return realattr; + } + else + throw new ul4.AttributeError(obj, attrname); + } + + hasattr(obj, attrname) + { + if (obj === null || typeof(obj) === "undefined") + return false; + else if (typeof(obj.__getattr__) === "function") + { + try + { + obj.__getattr__(attrname); + return true; + } + catch (exc) + { + if (exc instanceof ul4.AttributeError && exc.obj === object) + return false; + else + throw exc; + } + } + else + return this.attrs.has(attrname); + } + }; + + ul4.Protocol = ul4.Protocol.prototype; + ul4.Protocol.attrs = ul4._emptyset(); + + ul4.StrProtocol = class StrProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "str"; + } + + count(obj, sub, start=null, end=null) + { + return ul4._count(obj, sub, start, end); + } + + find(obj, sub, start=null, end=null) + { + return ul4._find(obj, sub, start, end); + } + + rfind(obj, sub, start=null, end=null) + { + return ul4._rfind(obj, sub, start, end); + } + + replace(obj, old, new_, count=null) + { + if (count === null) + count = obj.length; + + let result = []; + while (obj.length) + { + let pos = obj.indexOf(old); + if (pos === -1 || !count--) + { + result.push(obj); + break; + } + result.push(obj.substr(0, pos)); + result.push(new_); + obj = obj.substr(pos + old.length); + } + return result.join(""); + } + + strip(obj, chars=null) + { + chars = chars || " \r\n\t"; + if (typeof(chars) !== "string") + throw new ul4.TypeError("strip() requires a string argument"); + + while (obj && chars.indexOf(obj[0]) >= 0) + obj = obj.substr(1); + while (obj && chars.indexOf(obj[obj.length-1]) >= 0) + obj = obj.substr(0, obj.length-1); + return obj; + } + + lstrip(obj, chars=null) + { + chars = chars || " \r\n\t"; + if (typeof(chars) !== "string") + throw new ul4.TypeError("lstrip() requires a string argument"); + + while (obj && chars.indexOf(obj[0]) >= 0) + obj = obj.substr(1); + return obj; + } + + rstrip(obj, chars=null) + { + chars = chars || " \r\n\t"; + if (typeof(chars) !== "string") + throw new ul4.TypeError("rstrip() requires a string argument"); + + while (obj && chars.indexOf(obj[obj.length-1]) >= 0) + obj = obj.substr(0, obj.length-1); + return obj; + } + + split(obj, sep=null, count=null) + { + if (sep !== null && typeof(sep) !== "string") + throw new ul4.TypeError("split() requires a string"); + + if (count === null) + { + let result = obj.split(sep !== null ? sep : /[ \n\r\t]+/); + if (sep === null) + { + if (result.length && !result[0].length) + result.splice(0, 1); + if (result.length && !result[result.length-1].length) + result.splice(-1); + } + return result; + } + else + { + if (sep !== null) + { + let result = []; + while (obj.length) + { + let pos = obj.indexOf(sep); + if (pos === -1 || !count--) + { + result.push(obj); + break; + } + result.push(obj.substr(0, pos)); + obj = obj.substr(pos + sep.length); + } + return result; + } + else + { + let result = []; + while (obj.length) + { + obj = ul4.StrProtocol.lstrip(obj, null); + let part; + if (!count--) + part = obj; // Take the rest of the string + else + part = obj.split(/[ \n\r\t]+/, 1)[0]; + if (part.length) + result.push(part); + obj = obj.substr(part.length); + } + return result; + } + } + } + + rsplit(obj, sep=null, count=null) + { + if (sep !== null && typeof(sep) !== "string") + throw new ul4.TypeError("rsplit() requires a string as second argument"); + + if (count === null) + { + let result = obj.split(sep !== null ? sep : /[ \n\r\t]+/); + if (sep === null) + { + if (result.length && !result[0].length) + result.splice(0, 1); + if (result.length && !result[result.length-1].length) + result.splice(-1); + } + return result; + } + else + { + if (sep !== null) + { + let result = []; + while (obj.length) + { + let pos = obj.lastIndexOf(sep); + if (pos === -1 || !count--) + { + result.unshift(obj); + break; + } + result.unshift(obj.substr(pos+sep.length)); + obj = obj.substr(0, pos); + } + return result; + } + else + { + let result = []; + while (obj.length) + { + obj = ul4.StrProtocol.rstrip(obj); + let part; + if (!count--) + part = obj; // Take the rest of the string + else + { + part = obj.split(/[ \n\r\t]+/); + part = part[part.length-1]; + } + if (part.length) + result.unshift(part); + obj = obj.substr(0, obj.length-part.length); + } + return result; + } + } + } + + splitlines(obj, keepends=false) + { + let pos = 0; + let lookingAtLineEnd = function lookingAtLineEnd() + { + let c = obj[pos]; + if (c === '\n' || c == '\u000B' || c == '\u000C' || c == '\u001C' || c == '\u001D' || c == '\u001E' || c == '\u0085' || c == '\u2028' || c == '\u2029') + return 1; + if (c === '\r') + { + if (pos == length-1) + return 1; + if (obj[pos+1] === '\n') + return 2; + return 1; + } + return 0; + }; + + let result = [], length = obj.length; + + for (pos = 0, startpos = 0;;) + { + if (pos >= length) + { + if (startpos != pos) + result.push(obj.substring(startpos)); + return result; + } + let lineendlen = lookingAtLineEnd(); + if (!lineendlen) + ++pos; + else + { + let endpos = pos + (keepends ? lineendlen : 0); + result.push(obj.substring(startpos, endpos)); + pos += lineendlen; + startpos = pos; + } + } + } + + lower(obj) + { + return obj.toLowerCase(); + } + + upper(obj) + { + return obj.toUpperCase(); + } + + capitalize(obj) + { + if (obj.length) + obj = obj[0].toUpperCase() + obj.slice(1).toLowerCase(); + return obj; + } + + join(obj, iterable) + { + let resultlist = []; + for (let iter = ul4._iter(iterable);;) + { + let item = iter.next(); + if (item.done) + break; + resultlist.push(item.value); + } + return resultlist.join(obj); + } + + startswith(obj, prefix) + { + if (typeof(prefix) === "string") + return obj.substr(0, prefix.length) === prefix; + else if (ul4._islist(prefix)) + { + for (let i = 0; i < prefix.length; ++i) + { + let singlepre = prefix[i]; + if (obj.substr(0, singlepre.length) === singlepre) + return true; + } + return false; + } + else + throw new ul4.TypeError("startswith() argument must be string"); + } + + endswith(obj, suffix) + { + if (typeof(suffix) === "string") + return obj.substr(obj.length-suffix.length) === suffix; + else if (ul4._islist(suffix)) + { + for (let i = 0; i < suffix.length; ++i) + { + let singlesuf = suffix[i]; + if (obj.substr(obj.length-singlesuf.length) === singlesuf) + return true; + } + return false; + } + else + throw new ul4.TypeError("endswith() argument must be string or list of strings"); + } + }; + + ul4.StrProtocol = ul4.StrProtocol.prototype; + ul4.StrProtocol.attrs = ul4._makeset( + "split", + "rsplit", + "splitlines", + "strip", + "lstrip", + "rstrip", + "upper", + "lower", + "capitalize", + "startswith", + "endswith", + "replace", + "count", + "find", + "rfind", + "join" + ); + + ul4.expose(ul4.StrProtocol.count, ["sub", "start=", null, "end=", null]); + ul4.expose(ul4.StrProtocol.find, ["sub", "start=", null, "end=", null]); + ul4.expose(ul4.StrProtocol.rfind, ["sub", "start=", null, "end=", null]); + ul4.expose(ul4.StrProtocol.replace, ["old", "new", "count=", null]); + ul4.expose(ul4.StrProtocol.strip, ["chars=", null]); + ul4.expose(ul4.StrProtocol.lstrip, ["chars=", null]); + ul4.expose(ul4.StrProtocol.rstrip, ["chars=", null]); + ul4.expose(ul4.StrProtocol.split, ["sep=", null, "count=", null]); + ul4.expose(ul4.StrProtocol.rsplit, ["sep=", null, "count=", null]); + ul4.expose(ul4.StrProtocol.splitlines, ["keepends=", false]); + ul4.expose(ul4.StrProtocol.lower, []); + ul4.expose(ul4.StrProtocol.upper, []); + ul4.expose(ul4.StrProtocol.capitalize, []); + ul4.expose(ul4.StrProtocol.join, ["iterable"]); + ul4.expose(ul4.StrProtocol.startswith, ["prefix"]); + ul4.expose(ul4.StrProtocol.endswith, ["suffix"]); + + ul4.ListProtocol = class ListProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "list"; + } + + append(obj, items) + { + for (let i = 0; i < items.length; ++i) + obj.push(items[i]); + return null; + } + + insert(obj, pos, items) + { + if (pos < 0) + pos += obj.length; + + for (let i = 0; i < items.length; ++i) + obj.splice(pos++, 0, items[i]); + return null; + } + + pop(obj, pos) + { + if (pos < 0) + pos += obj.length; + + let result = obj[pos]; + obj.splice(pos, 1); + return result; + } + + count(obj, sub, start=null, end=null) + { + return ul4._count(obj, sub, start, end); + } + + find(obj, sub, start=null, end=null) + { + return ul4._find(obj, sub, start, end); + } + + rfind(obj, sub, start=null, end=null) + { + return ul4._rfind(obj, sub, start, end); + } + }; + + ul4.ListProtocol = ul4.ListProtocol.prototype; + ul4.ListProtocol.attrs = ul4._makeset( + "append", + "insert", + "pop", + "count", + "find", + "rfind" + ); + + ul4.expose(ul4.ListProtocol.append, ["*items"]); + ul4.expose(ul4.ListProtocol.insert, ["pos", "*items"]); + ul4.expose(ul4.ListProtocol.pop, ["pos=", -1]); + ul4.expose(ul4.ListProtocol.count, ["sub", "start=", null, "end=", null]); + ul4.expose(ul4.ListProtocol.find, ["sub", "start=", null, "end=", null]); + ul4.expose(ul4.ListProtocol.rfind, ["sub", "start=", null, "end=", null]); + + ul4.MapProtocol = class MapProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "dict"; + } + + getattr(obj, attrname) + { + if (this.attrs.has(attrname)) + { + let attr = this[attrname]; + let realattr = function realattr(...args) { + return attr.apply(this, [obj, ...args]); + }; + realattr.name = attr.name; + realattr._ul4_name = attr._ul4_name || attr.name; + realattr._ul4_signature = attr._ul4_signature; + realattr._ul4_needsobject = attr._ul4_needsobject; + realattr._ul4_needscontext = attr._ul4_needscontext; + return realattr; + } + else + return obj.get(attrname); + } + + get(obj, key, default_=null) + { + if (obj.has(key)) + return obj.get(key); + return default_; + } + + items(obj) + { + let result = []; + obj.forEach(function(value, key) { + result.push([key, value]); + }); + return result; + } + + values(obj) + { + let result = []; + obj.forEach(function(value, key) { + result.push(value); + }); + return result; + } + + update(obj, other, kwargs) + { + return ul4._update(obj, other, kwargs); + } + + clear(obj) + { + obj.clear(); + return null; + } + }; + + ul4.MapProtocol = ul4.MapProtocol.prototype; + ul4.MapProtocol.attrs = ul4._makeset("get", "items", "values", "update", "clear"); + + ul4.expose(ul4.MapProtocol.get, ["key", "default=", null]); + ul4.expose(ul4.MapProtocol.items, []); + ul4.expose(ul4.MapProtocol.values, []); + ul4.expose(ul4.MapProtocol.update, ["*other", "**kwargs"]); + ul4.expose(ul4.MapProtocol.clear, []); + + ul4.SetProtocol = class SetProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "set"; + } + + add(obj, items) + { + for (let i = 0; i < items.length; ++i) + { + obj.add(items[i]); + } + } + + clear(obj) + { + obj.clear(); + return null; + } + }; + + ul4.SetProtocol = ul4.SetProtocol.prototype; + ul4.SetProtocol.attrs = ul4._makeset("add", "clear"); + + ul4.expose(ul4.SetProtocol.add, ["*items"]); + ul4.expose(ul4.SetProtocol.clear, []); + + ul4.DateProtocol = class DateProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "date"; + } + + weekday(obj) + { + return ul4.DateTimeProtocol.weekday(obj._date); + } + + calendar(obj, firstweekday=0, mindaysinfirstweek=4) + { + return ul4.DateTimeProtocol.calendar(obj._date, firstweekday, mindaysinfirstweek); + } + + week(obj, firstweekday=0, mindaysinfirstweek=4) + { + return ul4.DateProtocol.calendar(obj, firstweekday, mindaysinfirstweek)[1]; + } + + day(obj) + { + return obj._date.getDate(); + } + + month(obj) + { + return obj._date.getMonth()+1; + } + + year(obj) + { + return obj._date.getFullYear(); + } + + mimeformat(obj) + { + let weekdayname = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; + let monthname = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + let d = obj._date; + + return weekdayname[ul4.DateTimeProtocol.weekday(d)] + ", " + ul4._lpad(d.getDate(), "0", 2) + " " + monthname[d.getMonth()] + " " + d.getFullYear(); + } + + isoformat(obj) + { + let d = obj._date; + return d.getFullYear() + "-" + ul4._lpad((d.getMonth()+1).toString(), "0", 2) + "-" + ul4._lpad(d.getDate().toString(), "0", 2); + } + + yearday(obj) + { + return ul4.DateTimeProtocol.yearday(obj._date); + } + }; + + ul4.DateProtocol = ul4.DateProtocol.prototype; + ul4.DateProtocol.attrs = ul4._makeset("weekday", "week", "calendar", "day", "month", "year", "mimeformat", "isoformat", "yearday"); + + ul4.expose(ul4.DateProtocol.weekday, []); + ul4.expose(ul4.DateProtocol.calendar, ["firstweekday=", 0, "mindaysinfirstweek=", 4]); + ul4.expose(ul4.DateProtocol.week, ["firstweekday=", 0, "mindaysinfirstweek=", 4]); + ul4.expose(ul4.DateProtocol.day, []); + ul4.expose(ul4.DateProtocol.month, []); + ul4.expose(ul4.DateProtocol.year, []); + ul4.expose(ul4.DateProtocol.mimeformat, []); + ul4.expose(ul4.DateProtocol.isoformat, []); + ul4.expose(ul4.DateProtocol.yearday, []); + + ul4.DateTimeProtocol = class DatetimeProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "datetime"; + } + + weekday(obj) + { + let d = obj.getDay(); + return d ? d-1 : 6; + } + + calendar(obj, firstweekday=0, mindaysinfirstweek=4) + { + // Normalize parameters + firstweekday = ul4._mod(firstweekday, 7); + if (mindaysinfirstweek < 1) + mindaysinfirstweek = 1; + else if (mindaysinfirstweek > 7) + mindaysinfirstweek = 7; + + // ``obj`` might be in the first week of the next year, or last week of + // the previous year, so we might have to try those too. + for (let offset = +1; offset >= -1; --offset) + { + let year = obj.getFullYear() + offset; + // ``refdate`` will always be in week 1 + let refDate = new Date(year, 0, mindaysinfirstweek); + // Go back to the start of ``refdate``s week (i.e. day 1 of week 1) + let weekDayDiff = ul4._mod(ul4.DateTimeProtocol.weekday(refDate) - firstweekday, 7); + let weekStartYear = refDate.getFullYear(); + let weekStartMonth = refDate.getMonth(); + let weekStartDay = refDate.getDate() - weekDayDiff; + let weekStart = new Date(weekStartYear, weekStartMonth, weekStartDay); + // Is our date ``obj`` at or after day 1 of week 1? + if (obj.getTime() >= weekStart.getTime()) + { + let diff = ul4.SubAST.prototype._do(obj, weekStart); + // Add 1, because the first week is week 1, not week 0 + let week = Math.floor(diff.days()/7) + 1; + return [year, week, ul4.DateTimeProtocol.weekday(obj)]; + } + } + } + + week(obj, firstweekday=0, mindaysinfirstweek=4) + { + return ul4.DateTimeProtocol.calendar(obj, firstweekday, mindaysinfirstweek)[1]; + } + + day(obj) + { + return obj.getDate(); + } + + month(obj) + { + return obj.getMonth()+1; + } + + year(obj) + { + return obj.getFullYear(); + } + + hour(obj) + { + return obj.getHours(); + } + + minute(obj) + { + return obj.getMinutes(); + } + + second(obj) + { + return obj.getSeconds(); + } + + microsecond(obj) + { + return obj.getMilliseconds() * 1000; + } + + mimeformat(obj) + { + let weekdayname = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; + let monthname = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + + return weekdayname[ul4.DateTimeProtocol.weekday(obj)] + ", " + ul4._lpad(obj.getDate(), "0", 2) + " " + monthname[obj.getMonth()] + " " + obj.getFullYear() + " " + ul4._lpad(obj.getHours(), "0", 2) + ":" + ul4._lpad(obj.getMinutes(), "0", 2) + ":" + ul4._lpad(obj.getSeconds(), "0", 2) + " GMT"; + } + + isoformat(obj) + { + let year = obj.getFullYear(); + let month = obj.getMonth()+1; + let day = obj.getDate(); + let hour = obj.getHours(); + let minute = obj.getMinutes(); + let second = obj.getSeconds(); + let ms = obj.getMilliseconds(); + let result = year + "-" + ul4._lpad(month.toString(), "0", 2) + "-" + ul4._lpad(day.toString(), "0", 2) + "T" + ul4._lpad(hour.toString(), "0", 2) + ":" + ul4._lpad(minute.toString(), "0", 2) + ":" + ul4._lpad(second.toString(), "0", 2); + if (ms) + result += "." + ul4._lpad(ms.toString(), "0", 3) + "000"; + return result; + } + + yearday(obj) + { + let leap = ul4._isleap(obj) ? 1 : 0; + let day = obj.getDate(); + switch (obj.getMonth()) + { + case 0: + return day; + case 1: + return 31 + day; + case 2: + return 31 + 28 + leap + day; + case 3: + return 31 + 28 + leap + 31 + day; + case 4: + return 31 + 28 + leap + 31 + 30 + day; + case 5: + return 31 + 28 + leap + 31 + 30 + 31 + day; + case 6: + return 31 + 28 + leap + 31 + 30 + 31 + 30 + day; + case 7: + return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + day; + case 8: + return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + day; + case 9: + return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + day; + case 10: + return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + day; + case 11: + return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + day; + } + } + }; + + ul4.DateTimeProtocol = ul4.DateTimeProtocol.prototype; + ul4.DateTimeProtocol.attrs = ul4._makeset("weekday", "week", "calendar", "day", "month", "year", "hour", "minute", "second", "microsecond", "mimeformat", "isoformat", "yearday"); + + ul4.expose(ul4.DateTimeProtocol.weekday, []); + ul4.expose(ul4.DateTimeProtocol.calendar, ["firstweekday=", 0, "mindaysinfirstweek=", 4]); + ul4.expose(ul4.DateTimeProtocol.week, ["firstweekday=", 0, "mindaysinfirstweek=", 4]); + ul4.expose(ul4.DateTimeProtocol.day, []); + ul4.expose(ul4.DateTimeProtocol.month, []); + ul4.expose(ul4.DateTimeProtocol.year, []); + ul4.expose(ul4.DateTimeProtocol.hour, []); + ul4.expose(ul4.DateTimeProtocol.minute, []); + ul4.expose(ul4.DateTimeProtocol.second, []); + ul4.expose(ul4.DateTimeProtocol.microsecond, []); + ul4.expose(ul4.DateTimeProtocol.mimeformat, []); + ul4.expose(ul4.DateTimeProtocol.isoformat, []); + ul4.expose(ul4.DateTimeProtocol.yearday, []); + + ul4.ObjectProtocol = class ObjectProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "dict"; + } + + getattr(obj, attrname) + { + let result; + if (obj && typeof(obj.__getattr__) === "function") // test this before the generic object test + result = obj.__getattr__(attrname); + else + result = obj[attrname]; + if (typeof(result) !== "function") + return result; + let realresult = function(...args) { + // We can use ``apply`` here, as we know that ``obj`` is a real object. + return result.apply(obj, args); + }; + realresult._ul4_name = result._ul4_name || result.name; + realresult._ul4_signature = result._ul4_signature; + realresult._ul4_needsobject = result._ul4_needsobject; + realresult._ul4_needscontext = result._ul4_needscontext; + return realresult; + } + + get(obj, key, default_=null) + { + let result = obj[key]; + if (typeof(result) === "undefined") + return default_; + return result; + } + + items(obj) + { + let result = []; + for (let key in obj) + result.push([key, obj[key]]); + return result; + } + + values(obj) + { + let result = []; + for (let key in obj) + result.push(obj[key]); + return result; + } + + clear(obj) + { + for (let key in obj) + delete obj[key]; + } + }; + + ul4.ObjectProtocol = ul4.ObjectProtocol.prototype; + ul4.ObjectProtocol.attrs = ul4._makeset("get", "items", "values", "update", "clear"); + + ul4.expose(ul4.ObjectProtocol.get, ["key", "default=", null]); + ul4.expose(ul4.ObjectProtocol.items, []); + ul4.expose(ul4.ObjectProtocol.values, []); + ul4.expose(ul4.ObjectProtocol.clear, []); + + ul4.Context = class Context + { + constructor(vars) + { + if (vars === null || typeof(vars) === "undefined") + vars = {}; + this.vars = vars; + this.indents = []; + this.escapes = []; + this._output = []; + } + + /* Return a clone of the ``Context``, but with a fresh empty ``vars`` objects that inherits from the previous one. + * This is used by the various comprehensions to avoid leaking loop variables. + */ + inheritvars() + { + let context = Object.create(this); + context.vars = Object.create(this.vars); + return context; + } + + /* Return a clone of the ``Context`` with one additional indentation (this is used by ``RenderAST``) */ + withindent(indent) + { + let context = Object.create(this); + if (indent !== null) + { + context.indents = this.indents.slice(); + context.indents.push(indent); + } + return context; + } + + /* Return a clone of the ``Context`` with the output buffer replaced (this is used by ``renders`` to collect the output in a separate buffer) */ + replaceoutput() + { + let context = Object.create(this); + context._output = []; + return context; + } + + clone(vars) + { + return Object.create(this); + } + + output(value) + { + for (let i = 0; i < this.escapes.length; ++i) + { + let escape = this.escapes[i]; + value = escape(value); + } + this._output.push(value); + } + + getoutput() + { + return this._output.join(""); + } + + get(name) + { + return this.vars[name]; + } + + set(name, value) + { + this.vars[name] = value; + } + }; + + /// Exceptions + + // Note that extending ``Error`` doesn't work, so we do it the "classic" way + ul4.Exception = function Exception(message, fileName, lineNumber) + { + let instance = new Error(message, fileName, lineNumber); + Object.setPrototypeOf(instance, Object.getPrototypeOf(this)); + instance.__id__ = _nextid++; + instance.context = null; + return instance; + }; + + ul4.Exception.prototype = Object.create(Error.prototype, { + constructor: { + value: Error, + enumerable: false, + writable: true, + configurable: true + } + }); + + if (Object.setPrototypeOf) + Object.setPrototypeOf(ul4.Exception, Error); + else + ul4.Exception.__proto__ = Error; + + ul4.Exception.prototype.__getattr__ = function __getattr__(attrname) + { + switch (attrname) + { + case "context": + return this.context; + default: + throw new ul4.AttributeError(this, attrname); + } + }; + + // Exceptions used internally by UL4 for flow control + ul4.InternalException = class InternalException extends ul4.Exception + { + }; + + // Control flow exceptions + ul4.ReturnException = class ReturnException extends ul4.InternalException + { + constructor(result) + { + super("return"); + this.result = result; + } + }; + + ul4.BreakException = class BreakException extends ul4.InternalException + { + constructor() + { + super("break"); + } + }; + + ul4.ContinueException = class ContinueException extends ul4.InternalException + { + constructor() + { + super("continue"); + } + }; + + // Real exceptions raised by various parts of UL4 + ul4.SyntaxError = class SyntaxError extends ul4.Exception + { + }; + + ul4.LValueRequiredError = class LValueRequiredError extends ul4.SyntaxError + { + constructor() + { + super("lvalue required"); + } + }; + + ul4.TypeError = class TypeError extends ul4.Exception + { + }; + + ul4.ValueError = class ValueError extends ul4.Exception + { + }; + + ul4.ArgumentError = class ArgumentError extends ul4.Exception + { + }; + + ul4.NotSubscriptableError = class NotSubscriptableError extends ul4.Exception + { + constructor(obj) + { + super("Object of type " + _type(obj) + " is not subscriptable"); + this.obj = obj; + } + + toString() + { + return "Object of type " + _type(this.obj) + " is not subscriptable"; + } + }; + + ul4.ZeroDivisionError = class ZeroDivisionError extends ul4.Exception + { + constructor() + { + super("division by zero"); + } + }; + + ul4.IndexError = class IndexError extends ul4.Exception + { + constructor(obj, index) + { + super("index " + ul4._repr(index) + " out of range"); + this.obj = obj; + this.index = index; + } + + toString() + { + return "index " + this.index + " out of range for " + ul4._type(this.obj); + } + }; + + ul4.AttributeError = class AttributeError extends ul4.Exception + { + constructor(obj, attrname) + { + super("object of type " + ul4._type(obj) + " has no attribute " + ul4._repr(attrname)); + this.obj = obj; + this.attrname = attrname; + } + }; + + /// Exception that wraps other exceptions while they bubble up the stack + ul4.LocationError = class LocationError extends ul4.Exception + { + constructor(location) + { + super("nested exception in " + ul4._repr(location)); + this.location = location; + } + + _templateprefix() + { + let template = this.location.template; + let out = []; + if (template.parenttemplate !== null) + out.push("in local template "); + else + out.push("in template "); + let first = true; + while (template != null) + { + if (first) + first = false; + else + out.push(" in "); + out.push(template.name ? ul4._repr(template.name) : "(unnamed)"); + template = template.parenttemplate; + } + return out.join(""); + } + + toString() + { + let template = this.location.template; + let templateprefix = this._templateprefix(); + + let prefix = this.location.sourceprefix; + let code = this.location.source; + let suffix = this.location.sourcesuffix; + prefix = ul4._repr(prefix).slice(1, -1); + code = ul4._repr(code).slice(1, -1); + suffix = ul4._repr(suffix).slice(1, -1); + + let text = prefix + code + suffix; + let underline = ul4._str_repeat("\u00a0", prefix.length) + ul4._str_repeat("~", code.length); + + let pos = "offset " + this.location.pos.start + ":" + this.location.pos.stop + "; line " + this.location.line + "; col " + this.location.col; + + let message = templateprefix + ": " + pos + "\n" + text + "\n" + underline; + return message; + } + + __getattr__(attrname) + { + switch (attrname) + { + case "context": + return this.context; + case "location": + return this.location; + default: + throw new ul4.AttributeError(this, attrname); + } + } + }; + + /// Classes for the syntax tree + ul4.AST = class AST extends ul4.Proto + { + constructor(template, pos) + { + super(); + this.template = template; + this.pos = pos; + this._line = null; + this._col = null; + } + + get fullsource() + { + return this.template._source; + } + + get source() + { + return this.pos.of(this.template._source); + } + + get sourceprefix() + { + let outerstartpos = this.pos.start; + let innerstartpos = outerstartpos; + let source = this.fullsource; + + let maxprefix = 40; + let preprefix = "\u2026"; + while (maxprefix > 0) + { + // We arrived at the start of the source code + if (outerstartpos === 0) + { + preprefix = ""; + break; + } + // We arrived at the start of the line + if (source.charAt(outerstartpos-1) === "\n") + { + preprefix = ""; + break; + } + --maxprefix; + --outerstartpos; + } + return preprefix + source.substring(outerstartpos, innerstartpos); + } + + get sourcesuffix() + { + let outerstoppos = this.pos.stop; + let innerstoppos = outerstoppos; + let source = this.fullsource; + + let maxsuffix = 40; + let postsuffix = "\u2026"; + while (maxsuffix > 0) + { + // We arrived at the ed of the source code + if (outerstoppos >= source.length) + { + postsuffix = ""; + break; + } + // We arrived at the end of the line + if (source.charAt(outerstoppos) === "\n") + { + postsuffix = ""; + break; + } + --maxsuffix; + ++outerstoppos; + } + return source.substring(innerstoppos, outerstoppos) + postsuffix; + } + + get line() + { + if (this._line === null) + this._calculateLineCol(); + return this._line; + } + + get col() + { + if (this._col === null) + this._calculateLineCol(); + return this._col; + } + + _calculateLineCol() + { + this._line = 1 + this._col = 1; + let stop = this.pos.start; + for (let i = 0; i < stop; ++i) + { + if (this.template.source[i] === "\n") + { + ++this._line; + this._col = 1; + } + else + ++this._col; + } + } + + __getattr__(attrname) + { + if (attrname === "type" || attrname === "fullsource" || attrname === "source" || attrname === "sourceprefix" || attrname === "sourcesuffix" || attrname === "line" || attrname === "col") + return this[attrname]; + else if (this._ul4onattrs.indexOf(attrname) >= 0) + return this[attrname]; + throw new ul4.AttributeError(this, attrname); + } + + __setitem__(attrname, value) + { + throw new ul4.TypeError("object is immutable"); + } + + __str__() + { + let out = []; + this._str(out); + return ul4._formatsource(out); + } + + __repr__() + { + let out = []; + this._repr(out); + return ul4._formatsource(out); + } + + _decorate_exception(exc) + { + while (exc.context !== undefined && exc.context !== null) + exc = exc.context; + exc.context = new ul4.LocationError(this); + } + + _handle_eval(context) + { + try + { + return this._eval(context); + } + catch (exc) + { + if (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + + _handle_eval_set(context, value) + { + try + { + return this._eval_set(context, value); + } + catch (exc) + { + if (!(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + + _eval_set(context, value) + { + throw new ul4.LValueRequiredError(); + } + + _handle_eval_modify(context, operator, value) + { + try + { + return this._eval_modify(context, operator, value); + } + catch (exc) + { + if (!(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + + _eval_modify(context, operator, value) + { + throw new ul4.LValueRequiredError(); + } + + _repr(out) + { + } + + _str(out) + { + out.push(this.source.replace(/\r?\n/g, ' ')); + } + + ul4ondump(encoder) + { + for (let i = 0; i < this._ul4onattrs.length; ++i) + { + let attrname = this._ul4onattrs[i]; + encoder.dump(this[attrname]); + } + } + + ul4onload(decoder) + { + for (let i = 0; i < this._ul4onattrs.length; ++i) + { + let attrname = this._ul4onattrs[i]; + this[attrname] = decoder.load(); + } + } + }; + + // used in ul4ondump/ul4ondump to automatically dump these attributes + ul4.AST.prototype._ul4onattrs = ["template", "pos"]; + + ul4.TextAST = class TextAST extends ul4.AST + { + constructor(template, pos) + { + super(template, pos); + } + + get text() + { + return this.source; + } + + _eval(context) + { + context.output(this.text); + } + + _str(out) + { + out.push("text "); + out.push(ul4._repr(this.text)); + } + + _repr(out) + { + out.push(""); + } + }; + + ul4.IndentAST = class IndentAST extends ul4.TextAST + { + constructor(template, pos, text) + { + super(template, pos); + this._text = text; + } + + get text() + { + if (typeof(this.template) !== "undefined") + return this._text === null ? this.source : this._text; + else + return null; + } + + _eval(context) + { + for (let i = 0; i < context.indents.length; ++i) + { + let indent = context.indents[i]; + context.output(indent); + } + context.output(this.text); + } + + ul4ondump(encoder) + { + super.ul4ondump(encoder); + + if (this._text === this.source) + encoder.dump(null); + else + encoder.dump(this._text); + } + + ul4onload(decoder) + { + super.ul4onload(decoder); + this._text = decoder.load(); + } + + _str(out) + { + out.push("indent "); + out.push(ul4._repr(this.text)); + } + + _repr(out) + { + out.push(""); + } + }; + + ul4.LineEndAST = class LineEndAST extends ul4.TextAST + { + _str(out) + { + out.push("lineend "); + out.push(ul4._repr(this.text)); + } + + _repr(out) + { + out.push(""); + } + }; + + ul4.CodeAST = class CodeAST extends ul4.AST + { + }; + + ul4.ConstAST = class ConstAST extends ul4.CodeAST + { + constructor(template, pos, value) + { + super(template, pos); + this.value = value; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + return this.value; + } + }; + + ul4.ConstAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["value"]); + + ul4.ItemArgBase = class ItemArgBase extends ul4.CodeAST + { + _handle_eval_list(context, result) + { + try + { + return this._eval_list(context, result); + } + catch (exc) + { + if (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + + _handle_eval_set(context, result) + { + try + { + return this._eval_set(context, result); + } + catch (exc) + { + if (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + + _handle_eval_dict(context, result) + { + try + { + return this._eval_dict(context, result); + } + catch (exc) + { + if (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + + _handle_eval_call(context, args, kwargs) + { + try + { + return this._eval_call(context, args, kwargs); + } + catch (exc) + { + if (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + }; + + ul4.SeqItemAST = class SeqItemAST extends ul4.ItemArgBase + { + constructor(template, pos, value) + { + super(template, pos); + this.value = value; + } + + _repr(out) + { + out.push(""); + } + + _eval_list(context, result) + { + let value = this.value._handle_eval(context); + result.push(value); + } + + _eval_set(context, result) + { + let value = this.value._handle_eval(context); + result.add(value); + } + }; + + ul4.SeqItemAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["value"]); + + ul4.UnpackSeqItemAST = class UnpackSeqItemAST extends ul4.ItemArgBase + { + constructor(template, pos, value) + { + super(template, pos); + this.value = value; + } + + _repr(out) + { + out.push(""); + } + + _eval_list(context, result) + { + let value = this.value._handle_eval(context); + for (let iter = ul4._iter(value);;) + { + let item = iter.next(); + if (item.done) + break; + result.push(item.value); + } + } + + _eval_set(context, result) + { + let value = this.value._handle_eval(context); + for (let iter = ul4._iter(value);;) + { + let item = iter.next(); + if (item.done) + break; + result.add(item.value); + } + } + }; + + ul4.UnpackSeqItemAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["value"]); + + ul4.DictItemAST = class DictItemAST extends ul4.ItemArgBase + { + constructor(template, pos, key, value) + { + super(template, pos); + this.key = key; + this.value = value; + } + + _repr(out) + { + out.push(""); + } + + _eval_dict(context, result) + { + let key = this.key._handle_eval(context); + let value = this.value._handle_eval(context); + ul4._setmap(result, key, value); + } + }; + + ul4.DictItemAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["key", "value"]), + + ul4.UnpackDictItemAST = class UnpackDictItemAST extends ul4.ItemArgBase + { + constructor(template, pos, item) + { + super(template, pos); + this.item = item; + } + + _repr(out) + { + out.push(""); + } + + _eval_dict(context, result) + { + let item = this.item._handle_eval(context); + if (ul4._islist(item)) + { + for (let i = 0; i < item.length; ++i) + { + let subitem = item[i]; + if (!ul4._islist(subitem) || subitem.length != 2) + throw new ul4.ArgumentError("** requires a list of (key, value) pairs"); + ul4._setmap(result, subitem[0], subitem[1]); + } + } + else if (ul4._ismap(item)) + { + item.forEach(function(value, key) { + ul4._setmap(result, key, value); + }); + } + else if (ul4._isobject(item)) + { + for (let key in item) + ul4._setmap(result, key, item[key]); + } + } + }; + + ul4.UnpackDictItemAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["item"]); + + ul4.PosArgAST = class PosArgAST extends ul4.ItemArgBase + { + constructor(template, pos, value) + { + super(template, pos); + this.value = value; + } + + _repr(out) + { + out.push(""); + } + + _eval_call(context, args, kwargs) + { + let value = this.value._handle_eval(context); + args.push(value); + } + }; + + ul4.PosArgAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["value"]); + + ul4.KeywordArgAST = class KeywordArgAST extends ul4.ItemArgBase + { + constructor(template, pos, name, value) + { + super(template, pos); + this.name = name; + this.value = value; + } + + _repr(out) + { + out.push(""); + } + + _eval_call(context, args, kwargs) + { + if (kwargs.hasOwnProperty(this.name)) + throw new ul4.ArgumentError("duplicate keyword argument " + this.name); + let value = this.value._handle_eval(context); + kwargs[this.name] = value; + } + }; + + ul4.KeywordArgAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["name", "value"]); + + ul4.UnpackListArgAST = class UnpackListArgAST extends ul4.ItemArgBase + { + constructor(template, pos, item) + { + super(template, pos); + this.item = item; + } + + _repr(out) + { + out.push(""); + } + + _eval_call(context, args, kwargs) + { + let item = this.item._handle_eval(context); + args.push(...item); + } + }; + + ul4.UnpackListArgAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["item"]); + + ul4.UnpackDictArgAST = class UnpackDictArgAST extends ul4.ItemArgBase + { + constructor(template, pos, item) + { + super(template, pos); + this.item = item; + } + + _repr(out) + { + out.push(""); + } + + _eval_call(context, args, kwargs) + { + let item = this.item._handle_eval(context); + if (ul4._islist(item)) + { + for (let i = 0; i < item.length; ++i) + { + let subitem = item[i]; + if (!ul4._islist(subitem) || subitem.length != 2) + throw new ul4.ArgumentError("** requires a list of (key, value) pairs"); + let [key, value] = subitem; + if (kwargs.hasOwnProperty(key)) + throw new ul4.ArgumentError("duplicate keyword argument " + key); + kwargs[key] = value; + } + } + else if (ul4._ismap(item)) + { + item.forEach(function(value, key) { + if (kwargs.hasOwnProperty(key)) + throw new ul4.ArgumentError("duplicate keyword argument " + key); + kwargs[key] = value; + }); + } + else if (ul4._isobject(item)) + { + for (let key in item) + { + if (kwargs.hasOwnProperty(key)) + throw new ul4.ArgumentError("duplicate keyword argument " + key); + kwargs[key] = item[key]; + } + } + } + }; + + ul4.UnpackDictArgAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["item"]); + + ul4.ListAST = class ListAST extends ul4.CodeAST + { + constructor(template, pos) + { + super(template, pos); + this.items = []; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let result = []; + for (let i = 0; i < this.items.length; ++i) + { + let item = this.items[i]; + item._handle_eval_list(context, result); + } + return result; + } + }; + + ul4.ListAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["items"]); + + ul4.ListCompAST = class ListCompAST extends ul4.CodeAST + { + constructor(template, pos, item, varname, container, condition) + { + super(template, pos); + this.item = item; + this.varname = varname; + this.container = container; + this.condition = condition; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let container = this.container._handle_eval(context); + + let localcontext = context.inheritvars(); + + let result = []; + for (let iter = ul4._iter(container);;) + { + let item = iter.next(); + if (item.done) + break; + let varitems = ul4._unpackvar(this.varname, item.value); + for (let i = 0; i < varitems.length; ++i) + { + let [lvalue, value] = varitems[i]; + lvalue._handle_eval_set(localcontext, value); + } + if (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext))) + result.push(this.item._handle_eval(localcontext)); + } + return result; + } + }; + + ul4.ListCompAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["item", "varname", "container", "condition"]); + + ul4.SetAST = class SetAST extends ul4.CodeAST + { + constructor(template, pos) + { + super(template, pos); + this.items = []; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let result = ul4._emptyset(); + + for (let i = 0; i < this.items.length; ++i) + { + let item = this.items[i]; + item._handle_eval_set(context, result); + } + + return result; + } + }; + + ul4.SetAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["items"]); + + ul4.SetCompAST = class SetCompAST extends ul4.CodeAST + { + constructor(template, pos, item, varname, container, condition) + { + super(template, pos); + this.item = item; + this.varname = varname; + this.container = container; + this.condition = condition; + } + + __getattr__(attrname) + { + switch (attrname) + { + case "item": + return this.item; + case "varname": + return this.varname; + case "container": + return this.container; + case "condition": + return this.condition; + default: + return super.__getattr__(attrname); + } + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let container = this.container._handle_eval(context); + + let localcontext = context.inheritvars(); + + let result = ul4._emptyset(); + for (let iter = ul4._iter(container);;) + { + let item = iter.next(); + if (item.done) + break; + let varitems = ul4._unpackvar(this.varname, item.value); + for (let i = 0; i < varitems.length; ++i) + { + let [lvalue, value] = varitems[i]; + lvalue._handle_eval_set(localcontext, value); + } + if (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext))) + result.add(this.item._handle_eval(localcontext)); + } + + return result; + } + }; + + ul4.SetCompAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["item", "varname", "container", "condition"]); + + ul4.DictAST = class DictAST extends ul4.CodeAST + { + constructor(template, pos) + { + super(template, pos); + this.items = []; + } + + __getattr__(attrname) + { + switch (attrname) + { + case "items": + return this.items; + default: + return super.__getattr__(attrname); + } + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let result = ul4._emptymap(); + for (let i = 0; i < this.items.length; ++i) + { + let item = this.items[i]; + item._handle_eval_dict(context, result); + } + return result; + } + }; + + ul4.DictAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["items"]); + + ul4.DictCompAST = class DictCompAST extends ul4.CodeAST + { + constructor(template, pos, key, value, varname, container, condition) + { + super(template, pos); + this.key = key; + this.value = value; + this.varname = varname; + this.container = container; + this.condition = condition; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let container = this.container._handle_eval(context); + + let localcontext = context.inheritvars(); + + let result = ul4._emptymap(); + + for (let iter = ul4._iter(container);;) + { + let item = iter.next(); + if (item.done) + break; + let varitems = ul4._unpackvar(this.varname, item.value); + for (let i = 0; i < varitems.length; ++i) + { + let [lvalue, value] = varitems[i]; + lvalue._handle_eval_set(localcontext, value); + } + if (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext))) + { + let key = this.key._handle_eval(localcontext); + let value = this.value._handle_eval(localcontext); + ul4._setmap(result, key, value); + } + } + + return result; + } + }; + + ul4.DictCompAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["key", "value", "varname", "container", "condition"]); + + ul4.GenExprAST = class GenExprAST extends ul4.CodeAST + { + constructor(template, pos, item, varname, container, condition) + { + super(template, pos); + this.item = item; + this.varname = varname; + this.container = container; + this.condition = condition; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let container = this.container._handle_eval(context); + let iter = ul4._iter(container); + + let localcontext = context.inheritvars(); + + let self = this; + + let result = { + next: function(){ + while (true) + { + let item = iter.next(); + if (item.done) + return item; + let varitems = ul4._unpackvar(self.varname, item.value); + for (let i = 0; i < varitems.length; ++i) + { + let [lvalue, value] = varitems[i]; + lvalue._handle_eval_set(localcontext, value); + } + if (self.condition === null || ul4._bool(self.condition._handle_eval(localcontext))) + { + let value = self.item._handle_eval(localcontext); + return {value: value, done: false}; + } + } + } + }; + + return result; + } + }; + + ul4.GenExprAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["item", "varname", "container", "condition"]); + + ul4.VarAST = class VarAST extends ul4.CodeAST + { + constructor(template, pos, name) + { + super(template, pos); + this.name = name; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + return this._get(context, this.name); + } + + _eval_set(context, value) + { + this._set(context, this.name, value); + } + + _eval_modify(context, operator, value) + { + this._modify(context, operator, this.name, value); + } + + _get(context, name) + { + let result = context.get(name); + if (typeof(result) === "undefined") + result = ul4.functions[name]; + return result; + } + + _set(context, name, value) + { + context.set(name, value); + } + + _modify(context, operator, name, value) + { + let newvalue = operator._ido(context.get(name), value); + context.set(name, newvalue); + } + }; + + ul4.VarAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["name"]); + + ul4.UnaryAST = class UnaryAST extends ul4.CodeAST + { + constructor(template, pos, obj) + { + super(template, pos); + this.obj = obj; + } + + _repr(out) + { + out.push("<"); + out.push(this.constructor.name); + out.push(" obj="); + this.obj._repr(out); + out.push(">"); + } + + _eval(context) + { + let obj = this.obj._handle_eval(context); + return this._do(obj); + } + }; + + ul4.UnaryAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["obj"]); + + // Negation + ul4.NegAST = class NegAST extends ul4.UnaryAST + { + _do(obj) + { + if (obj !== null && typeof(obj.__neg__) === "function") + return obj.__neg__(); + return -obj; + } + }; + + // Bitwise not + ul4.BitNotAST = class BitNotAST extends ul4.UnaryAST + { + _do(obj) + { + return -obj-1; + } + }; + + // Not + ul4.NotAST = class NotAST extends ul4.UnaryAST + { + _do(obj) + { + return !ul4._bool(obj); + } + }; + + // If expression + ul4.IfAST = class IfAST extends ul4.CodeAST + { + constructor(template, pos, objif, objcond, objelse) + { + super(template, pos); + this.objif = objif; + this.objcond = objcond; + this.objelse = objelse; + } + + _repr(out) + { + out.push("<"); + out.push(this.constructor.name); + out.push(+1); + out.push("objif="); + this.objif._repr(out); + out.push(0); + out.push("objcond="); + this.objcond._repr(out); + out.push(0); + out.push("objelse="); + this.objelse._repr(out); + out.push(-1); + out.push(">"); + } + + _eval(context) + { + let result; + let condvalue = this.objcond._handle_eval(context); + if (ul4._bool(condvalue)) + result = this.objif._handle_eval(context); + else + result = this.objelse._handle_eval(context); + return result; + } + }; + + ul4.IfAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["objif", "objcond", "objelse"]); + + ul4.ReturnAST = class ReturnAST extends ul4.UnaryAST + { + _eval(context) + { + let result = this.obj._handle_eval(context); + throw new ul4.ReturnException(result); + } + + _str(out) + { + out.push("return "); + this.obj._str(out); + } + }; + + ul4.PrintAST = class PrintAST extends ul4.UnaryAST + { + _eval(context) + { + let obj = this.obj._handle_eval(context); + let output = ul4._str(obj); + context.output(output); + } + + _str(out) + { + out.push("print "); + this.obj._str(out); + } + }; + + ul4.PrintXAST = class PrintXAST extends ul4.UnaryAST + { + _eval(context) + { + let obj = this.obj._handle_eval(context); + let output = ul4._xmlescape(obj); + context.output(output); + } + + _str(out) + { + out.push("printx "); + this.obj._str(out); + } + }; + + ul4.BinaryAST = class BinaryAST extends ul4.CodeAST + { + constructor(template, pos, obj1, obj2) + { + super(template, pos); + this.obj1 = obj1; + this.obj2 = obj2; + } + + _repr(out) + { + out.push("<"); + out.push(this.constructor.name); + out.push(" obj1="); + this.obj1._repr(out); + out.push(" obj2="); + this.obj2._repr(out); + out.push(">"); + } + + _eval(context) + { + let obj1 = this.obj1._handle_eval(context); + let obj2 = this.obj2._handle_eval(context); + return this._do(obj1, obj2); + } + }; + + ul4.BinaryAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["obj1", "obj2"]); + + // Item access and assignment: dict[key], list[index], string[index], color[index] + ul4.ItemAST = class ItemAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + let result = this._get(obj1, obj2); + return result; + } + + _eval_set(context, value) + { + let obj1 = this.obj1._handle_eval(context); + let obj2 = this.obj2._handle_eval(context); + this._set(obj1, obj2, value); + } + + _eval_modify(context, operator, value) + { + let obj1 = this.obj1._handle_eval(context); + let obj2 = this.obj2._handle_eval(context); + this._modify(operator, obj1, obj2, value); + } + + _get(container, key) + { + if (typeof(container) === "string" || ul4._islist(container)) + { + if (key instanceof ul4.slice) + { + let start = key.start, stop = key.stop; + if (typeof(start) === "undefined" || start === null) + start = 0; + if (typeof(stop) === "undefined" || stop === null) + stop = container.length; + return container.slice(start, stop); + } + else + { + let orgkey = key; + if (key < 0) + key += container.length; + if (key < 0 || key >= container.length) + throw new ul4.IndexError(container, orgkey); + return container[key]; + } + } + else if (container && typeof(container.__getitem__) === "function") // objects without ``_getitem__`` don't support item access + return container.__getitem__(key); + else if (ul4._ismap(container)) + return container.get(key); + else + throw new ul4.TypeError(ul4._type(container) + " object is not subscriptable"); + } + + _set(container, key, value) + { + if (ul4._islist(container)) + { + if (key instanceof ul4.slice) + { + let start = key.start, stop = key.stop; + if (start === null) + start = 0; + else if (start < 0) + start += container.length; + if (start < 0) + start = 0; + else if (start > container.length) + start = container.length; + if (stop === null) + stop = container.length; + else if (stop < 0) + stop += container.length; + if (stop < 0) + stop = 0; + else if (stop > container.length) + stop = container.length; + if (stop < start) + stop = start; + container.splice(start, stop-start); // Remove old element + for (let iter = ul4._iter(value);;) + { + let item = iter.next(); + if (item.done) + break; + container.splice(start++, 0, item.value); + } + } + else + { + let orgkey = key; + if (key < 0) + key += container.length; + if (key < 0 || key >= container.length) + throw new ul4.IndexError(container, orgkey); + container[key] = value; + } + } + else if (container && typeof(container.__setitem__) === "function") // test this before the generic object test + container.__setitem__(key, value); + else if (ul4._ismap(container)) + container.set(key, value); + else if (ul4._isobject(container)) + container[key] = value; + else + throw new ul4.NotSubscriptableError(container); + } + + _modify(operator, container, key, value) + { + this._set(container, key, operator._ido(this._get(container, key), value)); + } + }; + + // Identifty test operator ``is`` + ul4.IsAST = class IsAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return obj1 === obj2; + } + }; + + // Inverted identity test operator ``is not`` + ul4.IsNotAST = class IsNotAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return obj1 !== obj2; + } + }; + + // Comparison operator == + ul4.EQAST = class EQAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._eq(obj1, obj2); + } + }; + + // Comparison operator != + ul4.NEAST = class NEAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._ne(obj1, obj2); + } + }; + + // Comparison operator < + ul4.LTAST = class LTAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._lt(obj1, obj2); + } + }; + + // Comparison operator <= + ul4.LEAST = class LEAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._le(obj1, obj2); + } + }; + + // Comparison operator > + ul4.GTAST = class GTAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._gt(obj1, obj2); + } + }; + + // Comparison operator >= + ul4.GEAST = class GEAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._ge(obj1, obj2); + } + }; + + // Containment test: string in string, obj in list, key in dict, value in rgb + ul4.ContainsAST = class ContainsAST extends ul4.BinaryAST + { + _do(obj, container) + { + if (typeof(obj) === "string" && typeof(container) === "string") + { + return container.indexOf(obj) !== -1; + } + else if (ul4._islist(container)) + { + return container.indexOf(obj) !== -1; + } + else if (container && typeof(container.__contains__) === "function") // test this before the generic object test + return container.__contains__(obj); + else if (ul4._ismap(container) || ul4._isset(container)) + return container.has(obj); + else if (ul4._isobject(container)) + { + for (let key in container) + { + if (key === obj) + return true; + } + return false; + } + else if (ul4._iscolor(container)) + { + return container._r === obj || container._g === obj || container._b === obj || container._a === obj; + } + throw new ul4.TypeError(ul4._type(container) + " object is not iterable"); + } + }; + + // Inverted containment test + ul4.NotContainsAST = class NotContainsAST extends ul4.BinaryAST + { + _do(obj, container) + { + return !ul4.ContainsAST.prototype._do(obj, container); + } + }; + + // Addition: num + num, string + string + ul4.AddAST = class AddAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj1 && typeof(obj1.__add__) === "function") + return obj1.__add__(obj2); + else if (obj2 && typeof(obj2.__radd__) === "function") + return obj2.__radd__(obj1); + if (obj1 === null || obj2 === null) + throw new ul4.TypeError(ul4._type(this.obj1) + " + " + ul4._type(this.obj2) + " is not supported"); + if (ul4._islist(obj1) && ul4._islist(obj2)) + return [...obj1, ...obj2]; + else + return obj1 + obj2; + } + + _ido(obj1, obj2) + { + if (ul4._islist(obj1) && ul4._islist(obj2)) + { + ul4.ListProtocol.append(obj1, obj2); + return obj1; + } + else + return this._do(obj1, obj2); + } + }; + + // Substraction: num - num + ul4.SubAST = class SubAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj1 && typeof(obj1.__sub__) === "function") + return obj1.__sub__(obj2); + else if (obj2 && typeof(obj2.__rsub__) === "function") + return obj2.__rsub__(obj1); + else if (ul4._isdate(obj1) && ul4._isdate(obj2)) + return this._date_sub(obj1, obj2); + else if (ul4._isdatetime(obj1) && ul4._isdatetime(obj2)) + return this._datetime_sub(obj1, obj2); + if (obj1 === null || obj2 === null) + throw new ul4.TypeError(ul4._type(this.obj1) + " - " + ul4._type(this.obj2) + " is not supported"); + return obj1 - obj2; + } + + _date_sub(obj1, obj2) + { + return this._datetime_sub(obj1._date, obj2._date); + } + + _datetime_sub(obj1, obj2) + { + let swap = (obj2 > obj1); + + if (swap) + { + let t = obj1; + obj1 = obj2; + obj2 = t; + } + // From now on obj1 is > than obj2 + + let year1 = obj1.getFullYear(); + let yearday1 = ul4.DateTimeProtocol.yearday(obj1); + let year2 = obj2.getFullYear(); + let yearday2 = ul4.DateTimeProtocol.yearday(obj2); + + let diffdays = 0; + + while (year1 > year2) + { + diffdays += ul4.DateProtocol.yearday(ul4._date(year2, 12, 31)); + ++year2; + } + diffdays += yearday1 - yearday2; + + let hours1 = obj1.getHours(); + let minutes1 = obj1.getMinutes(); + let seconds1 = obj1.getSeconds(); + let hours2 = obj2.getHours(); + let minutes2 = obj2.getMinutes(); + let seconds2 = obj2.getSeconds(); + + let diffseconds = (seconds1 - seconds2) + 60 * ((minutes1 - minutes2) + 60 * (hours1 - hours2)); + + let diffmilliseconds = obj1.getMilliseconds() - obj2.getMilliseconds(); + + if (swap) + { + diffdays = -diffdays; + diffseconds = -diffseconds; + diffmilliseconds = -diffmilliseconds; + } + return new ul4.TimeDelta(diffdays, diffseconds, 1000*diffmilliseconds); + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + + // Multiplication: num * num, int * str, str * int, int * list, list * int + ul4.MulAST = class MulAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj1 && typeof(obj1.__mul__) === "function") + return obj1.__mul__(obj2); + else if (obj2 && typeof(obj2.__rmul__) === "function") + return obj2.__rmul__(obj1); + if (obj1 === null || obj2 === null) + throw new ul4.TypeError(ul4._type(obj1) + " * " + ul4._type(obj2) + " not supported"); + else if (ul4._isint(obj1) || ul4._isbool(obj1)) + { + if (typeof(obj2) === "string") + { + if (obj1 < 0) + throw new ul4.ValueError("repetition counter must be positive"); + return ul4._str_repeat(obj2, obj1); + } + else if (ul4._islist(obj2)) + { + if (obj1 < 0) + throw new ul4.ValueError("repetition counter must be positive"); + return ul4._list_repeat(obj2, obj1); + } + } + else if (ul4._isint(obj2) || ul4._isbool(obj2)) + { + if (typeof(obj1) === "string") + { + if (obj2 < 0) + throw new ul4.ValueError("repetition counter must be positive"); + return ul4._str_repeat(obj1, obj2); + } + else if (ul4._islist(obj1)) + { + if (obj2 < 0) + throw new ul4.ValueError("repetition counter must be positive"); + return ul4._list_repeat(obj1, obj2); + } + } + return obj1 * obj2; + } + + _ido(obj1, obj2) + { + if (ul4._islist(obj1) && ul4._isint(obj2)) + { + if (obj2 > 0) + { + let i = 0; + let targetsize = obj1.length * obj2; + while (obj1.length < targetsize) + obj1.push(obj1[i++]); + } + else + obj1.splice(0, obj1.length); + return obj1; + } + else + return this._do(obj1, obj2); + } + }; + + // Truncating division + ul4.FloorDivAST = class FloorDivAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj1 && typeof(obj1.__floordiv__) === "function") + return obj1.__floordiv__(obj2); + else if (obj2 && typeof(obj2.__rfloordiv__) === "function") + return obj2.__rfloordiv__(obj1); + if (obj1 === null || obj2 === null) + throw new ul4.TypeError(ul4._type(obj1) + " // " + ul4._type(obj2) + " not supported"); + else if (typeof(obj1) === "number" && typeof(obj2) === "number" && obj2 === 0) + throw new ul4.ZeroDivisionError(); + return Math.floor(obj1 / obj2); + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // "Real" division + ul4.TrueDivAST = class TrueDivAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj1 && typeof(obj1.__truediv__) === "function") + return obj1.__truediv__(obj2); + else if (obj2 && typeof(obj2.__rtruediv__) === "function") + return obj2.__rtruediv__(obj1); + if (obj1 === null || obj2 === null) + throw new ul4.TypeError(ul4._type(obj1) + " / " + ul4._type(obj2) + " not supported"); + else if (typeof(obj1) === "number" && typeof(obj2) === "number" && obj2 === 0) + throw new ul4.ZeroDivisionError(); + return obj1 / obj2; + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // Modulo + ul4.ModAST = class ModAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._mod(obj1, obj2); + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // Bitwise left shift + ul4.ShiftLeftAST = class ShiftLeftAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj2 === false) + obj2 = 0; + else if (obj2 === true) + obj2 = 1; + if (obj2 < 0) + return ul4.ShiftRightAST.prototype._do(obj1, -obj2); + if (obj1 === false) + obj1 = 0; + else if (obj1 === true) + obj1 = 1; + while (obj2--) + obj1 *= 2; + return obj1; + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // Bitwise right shift + ul4.ShiftRightAST = class ShiftRightAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj2 === false) + obj2 = 0; + else if (obj2 === true) + obj2 = 1; + if (obj2 < 0) + return ul4.ShiftLeftAST.prototype._do(obj1, -obj2); + if (obj1 === false) + obj1 = 0; + else if (obj1 === true) + obj1 = 1; + while (obj2--) + obj1 /= 2; + return Math.floor(obj1); + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // Bitwise and + ul4.BitAndAST = class BitAndAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj2 === false) + obj2 = 0; + else if (obj2 === true) + obj2 = 1; + return obj1 & obj2; + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // Bitwise exclusive or + ul4.BitXOrAST = class BitXOrAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj2 === false) + obj2 = 0; + else if (obj2 === true) + obj2 = 1; + return obj1 ^ obj2; + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // Bitwise or + ul4.BitOrAST = class BitOrAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj2 === false) + obj2 = 0; + else if (obj2 === true) + obj2 = 1; + return obj1 | obj2; + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + ul4.AndAST = class AndAST extends ul4.BinaryAST + { + _eval(context) + { + let obj1 = this.obj1._handle_eval(context); + if (!ul4._bool(obj1)) + return obj1; + let obj2 = this.obj2._handle_eval(context); + return obj2; + } + }; + + ul4.OrAST = class OrAST extends ul4.BinaryAST + { + _eval(context) + { + let obj1 = this.obj1._handle_eval(context); + if (ul4._bool(obj1)) + return obj1; + let obj2 = this.obj2._handle_eval(context); + return obj2; + } + }; + + ul4.AttrAST = class AttrAST extends ul4.CodeAST + { + constructor(template, pos, obj, attrname) + { + super(template, pos); + this.obj = obj; + this.attrname = attrname; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let obj = this.obj._handle_eval(context); + let result = this._get(obj, this.attrname); + return result; + } + + _eval_set(context, value) + { + let obj = this.obj._handle_eval(context); + this._set(obj, this.attrname, value); + } + + _eval_modify(context, operator, value) + { + let obj = this.obj._handle_eval(context); + this._modify(operator, obj, this.attrname, value); + } + + _get(object, attrname) + { + let proto = ul4.Protocol.get(object); + try + { + return proto.getattr(object, attrname); + } + catch (exc) + { + if (exc instanceof ul4.AttributeError && exc.obj === object) + return undefined; + else + throw exc; + } + } + + _set(object, attrname, value) + { + if (typeof(object) === "object" && typeof(object.__setattr__) === "function") + object.__setattr__(attrname, value); + else if (ul4._ismap(object)) + object.set(attrname, value); + else if (ul4._isobject(object)) + object[attrname] = value; + else + throw new ul4.TypeError(ul4._type(object) + " object has no writable attributes"); + } + + _modify(operator, object, attrname, value) + { + let oldvalue = this._get(object, attrname); + let newvalue = operator._ido(oldvalue, value); + this._set(object, attrname, newvalue); + } + }; + + ul4.AttrAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["obj", "attrname"]); + + ul4.CallAST = class CallAST extends ul4.CodeAST + { + constructor(template, pos, obj, args) + { + super(template, pos); + this.obj = obj; + this.args = args; + } + + _repr(out) + { + out.push(""); + } + + _makeargs(context) + { + let args = [], kwargs = {}; + for (let i = 0; i < this.args.length; ++i) + { + let arg = this.args[i]; + arg._handle_eval_call(context, args, kwargs); + } + return {args: args, kwargs: kwargs}; + } + + _handle_eval(context) + { + try + { + return this._eval(context); + } + catch (exc) + { + this._decorate_exception(exc); + throw exc; + } + } + + _eval(context) + { + let obj = this.obj._handle_eval(context); + let args = this._makeargs(context); + let result = ul4._call(context, obj, args.args, args.kwargs); + return result; + } + }; + + ul4.CallAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["obj", "args"]); + + ul4.RenderAST = class RenderAST extends ul4.CallAST + { + constructor(template, pos, obj, args) + { + super(template, pos, obj, args); + this.indent = null; + } + + _repr(out) + { + out.push("<"); + out.push(this._reprname); + out.push(""); + } + + _str(out) + { + out.push("render "); + out.push(this.tag.code.replace(/\r?\n/g, ' ')); + if (this.indent !== null) + { + out.push(" with indent "); + out.push(ul4._repr(this.indent.text)); + } + } + + _handle_eval(context) + { + let localcontext = context.withindent(this.indent !== null ? this.indent.text : null); + let obj = this.obj._handle_eval(localcontext); + let args = this._makeargs(localcontext); + this._handle_additional_arguments(localcontext, args); + + try + { + let result = ul4._callrender(localcontext, obj, args.args, args.kwargs); + return result; + } + catch (exc) + { + this._decorate_exception(exc); + throw exc; + } + } + + _handle_additional_arguments(context, args) + { + } + }; + + ul4.RenderAST.prototype._ul4onattrs = ul4.CallAST.prototype._ul4onattrs.concat(["indent"]); + ul4.RenderAST.prototype._reprname = "RenderAST"; + + ul4.RenderXAST = class RenderXAST extends ul4.RenderAST + { + _handle_eval(context) + { + context.escapes.push(ul4._xmlescape); + + let result = null; + try + { + result = super._handle_eval(context); + } + finally + { + context.escapes.splice(context.escapes.length-1, 1); + } + return result; + } + }; + + ul4.RenderBlockAST = class RenderBlockAST extends ul4.RenderAST + { + _handle_additional_arguments(context, args) + { + if (args.kwargs.hasOwnProperty("content")) + throw new ul4.ArgumentError("duplicate keyword argument content"); + let closure = new ul4.TemplateClosure(this.content, this.content.signature, context.vars); + args.kwargs.content = closure; + } + }; + + ul4.RenderBlockAST.prototype._ul4onattrs = ul4.RenderAST.prototype._ul4onattrs.concat(["content"]); + + ul4.RenderBlocksAST = class RenderBlocksAST extends ul4.RenderAST + { + _handle_additional_arguments(context, args) + { + let localcontext = context.inheritvars(); + ul4.BlockAST.prototype._eval.call(this, localcontext); + + for (let key in localcontext.vars) + { + if (localcontext.vars.hasOwnProperty(key)) + { + if (key in args.kwargs) + throw new ul4.ArgumentError("duplicate keyword argument " + key); + args.kwargs[key] = localcontext.get(key); + } + } + } + }; + + ul4.RenderBlocksAST.prototype._ul4onattrs = ul4.RenderAST.prototype._ul4onattrs.concat(["content"]); + + // Slice object + ul4.slice = class slice extends ul4.Proto + { + constructor(start, stop) + { + super(); + this.start = start; + this.stop = stop; + } + + of(string) + { + let start = this.start || 0; + let stop = this.stop === null ? string.length : this.stop; + return string.slice(start, stop); + } + + __repr__() + { + return "slice(" + ul4._repr(this.start) + ", " + ul4._repr(this.stop) + ", None)"; + } + + __getattr__(attrname) + { + switch (attrname) + { + case "start": + return this.start; + case "stop": + return this.stop; + default: + throw new ul4.AttributeError(this, attrname); + } + } + }; + + + // List/String slice + ul4.SliceAST = class SliceAST extends ul4.CodeAST + { + constructor(template, pos, index1, index2) + { + super(template, pos); + this.index1 = index1; + this.index2 = index2; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let index1 = this.index1 !== null ? this.index1._handle_eval(context) : null; + let index2 = this.index2 !== null ? this.index2._handle_eval(context) : null; + return new ul4.slice(index1, index2); + } + }; + + ul4.SliceAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["index1", "index2"]); + + ul4.SetVarAST = class SetVarAST extends ul4.CodeAST + { + constructor(template, pos, lvalue, value) + { + super(template, pos); + this.lvalue = lvalue; + this.value = value; + } + + _repr(out) + { + out.push("<"); + out.push(this.constructor.name); + out.push(" lvalue="); + out.push(ul4._repr(this.lvalue)); + out.push(" value="); + this.value._repr(out); + out.push(">"); + } + + _eval(context) + { + let value = this.value._handle_eval(context); + let items = ul4._unpackvar(this.lvalue, value); + for (let i = 0; i < items.length; ++i) + { + let [lvalue, value] = items[i]; + lvalue._handle_eval_set(context, value); + } + } + }; + + ul4.SetVarAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["lvalue", "value"]); + + ul4.ModifyVarAST = class ModifyVarAST extends ul4.SetVarAST + { + _eval(context) + { + let value = this.value._handle_eval(context); + let items = ul4._unpackvar(this.lvalue, value); + for (let i = 0; i < items.length; ++i) + { + let [lvalue, value] = items[i]; + lvalue._handle_eval_modify(context, this._operator, value); + } + } + }; + + ul4.AddVarAST = class AddVarAST extends ul4.ModifyVarAST + { + }; + + ul4.AddVarAST.prototype._operator = ul4.AddAST.prototype; + + ul4.SubVarAST = class SubVarAST extends ul4.ModifyVarAST + { + }; + + ul4.SubVarAST.prototype._operator = ul4.SubAST.prototype; + + ul4.MulVarAST = class MulVarAST extends ul4.ModifyVarAST + { + }; + + ul4.MulVarAST.prototype._operator = ul4.MulAST.prototype; + + ul4.TrueDivVarAST = class TrueDivVarAST extends ul4.ModifyVarAST + { + }; + + ul4.TrueDivVarAST.prototype._operator = ul4.TrueDivAST.prototype; + + ul4.FloorDivVarAST = class FloorDivVarAST extends ul4.ModifyVarAST + { + }; + + ul4.FloorDivVarAST.prototype._operator = ul4.FloorDivAST.prototype; + + ul4.ModVarAST = class ModVarAST extends ul4.ModifyVarAST + { + }; + + ul4.ModVarAST.prototype._operator = ul4.ModAST.prototype; + + ul4.ShiftLeftVarAST = class ShiftLeftVarAST extends ul4.ModifyVarAST + { + }; + + ul4.ShiftLeftVarAST.prototype._operator = ul4.ShiftLeftAST.prototype; + + ul4.ShiftRightVarAST = class ShiftRightVarAST extends ul4.ModifyVarAST + { + }; + + ul4.ShiftRightVarAST.prototype._operator = ul4.ShiftRightAST.prototype; + + ul4.BitAndVarAST = class BitAndVarAST extends ul4.ModifyVarAST + { + }; + + ul4.BitAndVarAST.prototype._operator = ul4.BitAndAST.prototype; + + ul4.BitXOrVarAST = class BitXOrVarAST extends ul4.ModifyVarAST + { + }; + + ul4.BitXOrVarAST.prototype._operator = ul4.BitXOrAST.prototype; + + ul4.BitOrVarAST = class BitOrVarAST extends ul4.ModifyVarAST + { + }; + + ul4.BitOrVarAST.prototype._operator = ul4.BitOrAST.prototype; + + ul4.BlockAST = class BlockAST extends ul4.CodeAST + { + constructor(template, pos) + { + super(template, pos); + this.content = []; + } + + _eval(context) + { + for (let i = 0; i < this.content.length; ++i) + { + let item = this.content[i]; + item._handle_eval(context); + } + } + + _str(out) + { + if (this.content.length) + { + for (let i = 0; i < this.content.length; ++i) + { + let item = this.content[i]; + item._str(out); + out.push(0); + } + } + else + { + out.push("pass"); + out.push(0); + } + } + }; + + ul4.BlockAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["content"]); + + ul4.ForBlockAST = class ForBlockAST extends ul4.BlockAST + { + constructor(template, pos, varname, container) + { + super(template, pos); + this.varname = varname; + this.container = container; + } + + _repr(out) + { + out.push(""); + } + + _str_varname(out, varname) + { + if (ul4._islist(varname)) + { + out.push("("); + for (let i = 0; i < varname.length; ++i) + { + if (i) + out.push(", "); + this._str_varname(out, varname[i]); + } + if (varname.length == 1) + out.push(","); + out.push(")"); + } + else + varname._str(out); + } + + _eval(context) + { + let container = this.container._handle_eval(context); + + for (let iter = ul4._iter(container);;) + { + let value = iter.next(); + if (value.done) + break; + let varitems = ul4._unpackvar(this.varname, value.value); + for (let i = 0; i < varitems.length; ++i) + { + let [lvalue, value] = varitems[i]; + lvalue._handle_eval_set(context, value); + } + try + { + // We can't call _handle_eval() here, as this would in turn call this function again, leading to infinite recursion + // But we don't have to, as wrapping original exception in ``Error`` has already been done by the lower levels + super._eval(context); + } + catch (exc) + { + if (exc instanceof ul4.BreakException) + break; + else if (exc instanceof ul4.ContinueException) + ; + else + throw exc; + } + } + } + + _str(out) + { + out.push("for "); + this._str_varname(out, this.varname); + out.push(" in "); + this.container._str(out); + out.push(":"); + out.push(+1); + ul4.BlockAST.prototype._str.call(this, out); + out.push(-1); + } + }; + + ul4.ForBlockAST.prototype._ul4onattrs = ul4.BlockAST.prototype._ul4onattrs.concat(["varname", "container"]); + + ul4.WhileBlockAST = class WhileBlockAST extends ul4.BlockAST + { + constructor(template, pos, condition) + { + super(template, pos); + this.condition = condition; + } + + _repr(out) + { + out.push(""); + } + + _str(out) + { + out.push("while "); + this.condition._repr(out); + out.push(":"); + out.push(+1); + ul4.BlockAST.prototype._str.call(this, out); + out.push(-1); + } + + _eval(context) + { + while (true) + { + let cond = this.condition._handle_eval(context); + if (!ul4._bool(cond)) + break; + try + { + // We can't call _handle_eval() here, as this would in turn call this function again, leading to infinite recursion + // But we don't have to, as wrapping the original exception in ``Error`` has already been done by the lower levels + super._eval(context); + } + catch (exc) + { + if (exc instanceof ul4.BreakException) + break; + else if (exc instanceof ul4.ContinueException) + ; + else + throw exc; + } + } + } + }; + + ul4.WhileBlockAST.prototype._ul4onattrs = ul4.BlockAST.prototype._ul4onattrs.concat(["condition"]); + + ul4.BreakAST = class BreakAST extends ul4.CodeAST + { + _eval(context) + { + throw new ul4.BreakException(); + } + + _str(out) + { + out.push("break"); + out.push(0); + } + + _repr(out) + { + out.push(""); + } + }; + + ul4.ContinueAST = class ContinueAST extends ul4.CodeAST + { + _eval(context) + { + throw new ul4.ContinueException(); + } + + _str(out) + { + out.push("continue"); + out.push(0); + } + + _repr(out) + { + out.push(""); + } + }; + + ul4.CondBlockAST = class CondBlockAST extends ul4.BlockAST + { + _eval(context) + { + for (let i = 0; i < this.content.length; ++i) + { + let block = this.content[i]; + let execute = block._execute(context); + if (execute) + { + block._handle_eval(context); + break; + } + } + } + }; + + ul4.ConditionalBlockAST = class ConditionalBlockAST extends ul4.BlockAST + { + constructor(template, pos, condition) + { + super(template, pos); + this.condition = condition; + } + + _repr(out) + { + out.push("<"); + out.push(this.constructor.name); + out.push(" condition="); + this.condition._repr(out); + out.push(">"); + } + + _str(out) + { + out.push(this._strname); + out.push(" "); + this.condition._str(out); + out.push(":"); + out.push(+1); + ul4.BlockAST.prototype._str.call(this, out); + out.push(-1); + } + + _execute(context) + { + let cond = this.condition._handle_eval(context); + let result = ul4._bool(cond); + return result; + } + }; + + ul4.ConditionalBlockAST.prototype._ul4onattrs = ul4.BlockAST.prototype._ul4onattrs.concat(["condition"]); + + ul4.IfBlockAST = class IfBlockAST extends ul4.ConditionalBlockAST + { + }; + + ul4.IfBlockAST.prototype._strname = "if"; + + ul4.ElIfBlockAST = class ElIfBlockAST extends ul4.ConditionalBlockAST + { + }; + + ul4.ElIfBlockAST.prototype._strname = "else if"; + + ul4.ElseBlockAST = class ElseBlockAST extends ul4.BlockAST + { + _repr(out) + { + out.push(""); + } + + _str(out) + { + out.push("else:"); + out.push(+1); + ul4.BlockAST.prototype._str.call(this, out); + out.push(-1); + } + + _execute(context) + { + return true; + } + }; + + ul4.Template = class Template extends ul4.BlockAST + { + constructor(template, pos, source, name, whitespace, startdelim, enddelim, signature) + { + super(template, pos); + this._source = source; + this.name = name; + this.whitespace = whitespace; + this.startdelim = startdelim; + this.enddelim = enddelim; + this.docpos = null; + this.signature = signature; + this._asts = null; + this._ul4_callsignature = signature; + this._ul4_rendersignature = signature; + this.parenttemplate = null; + } + + __getattr__(attrname) + { + let self = this; + switch (attrname) + { + case "content": + return this.content; + case "source": + return this.source; + case "name": + return this.name; + case "whitespace": + return this.whitespace; + case "startdelim": + return this.startdelim; + case "enddelim": + return this.enddelim; + case "doc": + return this.doc(); + case "signature": + return this.signature; + case "parenttemplate": + return this.parenttemplate; + case "render": + let render = function render(context, vars){ self._renderbound(context, vars); }; + ul4.expose(render, this.signature, {needscontext: true, needsobject: true}); + return render; + case "renders": + let renders = function renders(context, vars){ return self._rendersbound(context, vars); }; + ul4.expose(renders, this.signature, {needscontext: true, needsobject: true}); + return renders; + default: + return super.__getattr__(attrname); + } + } + + ul4ondump(encoder) + { + let signature; + encoder.dump(ul4.version); + encoder.dump(this.name); + encoder.dump(this._source); + encoder.dump(this.whitespace); + encoder.dump(this.startdelim); + encoder.dump(this.enddelim); + encoder.dump(this.docpos); + encoder.dump(this.parenttemplate); + if (this.signature === null || this.signature instanceof ul4.SignatureAST) + signature = this.signature; + else + { + signature = []; + for (let i = 0; i < this.signature.args.length; ++i) + { + let arg = this.signature.args[i]; + if (typeof(arg.defaultValue) === "undefined") + signature.push(arg.name); + else + signature.push(arg.name+"=", arg.defaultValue); + } + if (this.signature.remargs !== null) + signature.push("*" + this.signature.remargs); + if (this.signature.remkwargs !== null) + signature.push("**" + this.signature.remkwargs); + } + encoder.dump(signature); + super.ul4ondump(encoder); + } + + ul4onload(decoder) + { + let version = decoder.load(); + let signature; + + if (version === null) + throw new ul4.ValueError("UL4ON doesn't support templates in 'source' format in Javascript implementation"); + + if (version !== ul4.version) + throw new ul4.ValueError("invalid version, expected " + ul4.version + ", got " + version); + + this.name = decoder.load(); + this._source = decoder.load(); + this.whitespace = decoder.load(); + this.startdelim = decoder.load(); + this.enddelim = decoder.load(); + this.docpos = decoder.load(); + this.parenttemplate = decoder.load(); + signature = decoder.load(); + if (ul4._islist(signature)) + signature = new ul4.Signature(...signature); + this.signature = signature; + this._ul4_callsignature = signature; + this._ul4_rendersignature = signature; + super.ul4onload(decoder); + } + + loads(string) + { + return ul4.loads(string); + } + + _eval(context) + { + let signature = null; + if (this.signature !== null) + signature = this.signature._handle_eval(context); + let closure = new ul4.TemplateClosure(this, signature, context.vars); + context.set(this.name, closure); + } + + _repr(out) + { + out.push("") + { + out.push(" enddelim="); + out.push(ul4._repr(this.enddelim)); + } + out.push(">"); + } + + _str(out) + { + out.push("def "); + out.push(this.name ? this.name : "unnamed"); + out.push(":"); + out.push(+1); + ul4.BlockAST.prototype._str.call(this, out); + out.push(-1); + } + + _renderbound(context, vars) + { + let localcontext = context.clone(); + localcontext.vars = vars; + try + { + ul4.BlockAST.prototype._eval.call(this, localcontext); + } + catch (exc) + { + if (!(exc instanceof ul4.ReturnException)) + throw exc; + } + } + + __render__(context, vars) + { + this._renderbound(context, vars); + } + + render(context, vars) + { + this._renderbound(context, vars); + } + + _rendersbound(context, vars) + { + let localcontext = context.replaceoutput(); + this._renderbound(localcontext, vars); + return localcontext.getoutput(); + } + + renders(vars) + { + vars = vars || {}; + let context = new ul4.Context(); + if (this.signature !== null) + vars = this.signature.bindObject(this.name, [], vars); + return this._rendersbound(context, vars); + } + + doc() + { + return this.docpos != null ? this.docpos.of(this._source) : null; + } + + _callbound(context, vars) + { + let localcontext = context.clone(); + localcontext.vars = vars; + try + { + ul4.BlockAST.prototype._eval.call(this, localcontext); + } + catch (exc) + { + if (exc instanceof ul4.ReturnException) + return exc.result; + else + throw exc; + } + return null; + } + + call(vars) + { + vars = vars || {}; + let context = new ul4.Context(); + if (this.signature !== null) + vars = this.signature.bindObject(this.name, [], vars); + return this._callbound(context, vars); + } + + __call__(context, vars) + { + return this._callbound(context, vars); + } + + ul4type() + { + return "template"; + } + }; + + ul4.Template.prototype._ul4_callneedsobject = true; + ul4.Template.prototype._ul4_callneedscontext = true; + ul4.Template.prototype._ul4_renderneedsobject = true; + ul4.Template.prototype._ul4_renderneedscontext = true; + + ul4.SignatureAST = class SignatureAST extends ul4.CodeAST + { + constructor(template, pos) + { + super(template, pos); + this.params = []; + } + + ul4ondump(encoder) + { + super.ul4ondump(encoder); + + let dump = []; + + for (let i = 0; i < this.params.length; ++i) + { + let param = this.params[i]; + if (param[1] === null) + dump.push(param[0]); + else + dump.push(param); + } + encoder.dump(dump); + } + + ul4onload(decoder) + { + super.ul4onload(decoder); + let dump = decoder.load(); + this.params = []; + for (let i = 0; i < dump.length; ++i) + { + let param = dump[i]; + if (typeof(param) === "string") + this.params.push([param, null]); + else + this.params.push(param); + } + } + + _eval(context) + { + let args = []; + for (let i = 0; i < this.params.length; ++i) + { + let param = this.params[i]; + if (param[1] === null) + args.push(param[0]); + else + { + args.push(param[0] + "="); + args.push(param[1]._handle_eval(context)); + } + } + return new ul4.Signature(...args); + } + + _repr(out) + { + out.push("<"); + out.push(this.constructor.name); + out.push(" params="); + this.params._repr(out); + out.push(">"); + } + }; + + ul4.TemplateClosure = class TemplateClosure extends ul4.Proto + { + constructor(template, signature, vars) + { + super(); + this.template = template; + this.signature = signature; + this.vars = vars; + this._ul4_callsignature = signature; + this._ul4_rendersignature = signature; + // Copy over the required attribute from the template + this.name = template.name; + this.tag = template.tag; + this.endtag = template.endtag; + this._source = template._source; + this.startdelim = template.startdelim; + this.enddelim = template.enddelim; + this.docpos = template.docpos; + this.content = template.content; + } + + __render__(context, vars) + { + this.template._renderbound(context, ul4._inherit(this.vars, vars)); + } + + render(context, vars) + { + this.template._renderbound(context, ul4._inherit(this.vars, vars)); + } + + __call__(context, vars) + { + return this.template._callbound(context, ul4._inherit(this.vars, vars)); + } + + _renderbound(context, vars) + { + this.template._renderbound(context, ul4._inherit(this.vars, vars)); + } + + _rendersbound(context, vars) + { + return this.template._rendersbound(context, ul4._inherit(this.vars, vars)); + } + + __getattr__(attrname) + { + let self = this; + switch (attrname) + { + case "render": + let render = function render(context, vars){ self._renderbound(context, vars); }; + ul4.expose(render, this.signature, {needscontext: true, needsobject: true}); + return render; + case "renders": + let renders = function renders(context, vars){ return self._rendersbound(context, vars); }; + ul4.expose(renders, this.signature, {needscontext: true, needsobject: true}); + return renders; + case "signature": + return this.signature; + default: + return this.template.__getattr__(attrname); + } + } + + ul4type() + { + return "template"; + } + }; + + ul4.TemplateClosure.prototype._ul4_callneedsobject = true; + ul4.TemplateClosure.prototype._ul4_callneedscontext = true; + ul4.TemplateClosure.prototype._ul4_renderneedsobject = true; + ul4.TemplateClosure.prototype._ul4_renderneedscontext = true; + + // Create a color object from the red, green, blue and alpha values ``r``, ``g``, ``b`` and ``b`` + ul4._rgb = function _rgb(r, g, b, a) + { + return new this.Color(255*r, 255*g, 255*b, 255*a); + }; + + // Convert ``obj`` to a string and escape the characters ``&``, ``<``, ``>``, ``'`` and ``"`` with their XML character/entity reference + ul4._xmlescape = function _xmlescape(obj) + { + obj = ul4._str(obj); + obj = obj.replace(/&/g, "&"); + obj = obj.replace(//g, ">"); + obj = obj.replace(/'/g, "'"); + obj = obj.replace(/"/g, """); + return obj; + }; + + // Convert ``obj`` to a string suitable for output into a CSV file + ul4._csv = function _csv(obj) + { + if (obj === null) + return ""; + else if (typeof(obj) !== "string") + obj = ul4._repr(obj); + if (obj.indexOf(",") !== -1 || obj.indexOf('"') !== -1 || obj.indexOf("\n") !== -1) + obj = '"' + obj.replace(/"/g, '""') + '"'; + return obj; + }; + + // Return a string containing one character with the codepoint ``i`` + ul4._chr = function _chr(i) + { + if (typeof(i) != "number") + throw new ul4.TypeError("chr() requires an int"); + return String.fromCharCode(i); + }; + + // Return the codepoint for the one and only character in the string ``c`` + ul4._ord = function _ord(c) + { + if (typeof(c) != "string" || c.length != 1) + throw new ul4.TypeError("ord() requires a string of length 1"); + return c.charCodeAt(0); + }; + + // Convert an integer to a hexadecimal string + ul4._hex = function _hex(number) + { + if (typeof(number) != "number") + throw new ul4.TypeError("hex() requires an int"); + if (number < 0) + return "-0x" + number.toString(16).substr(1); + else + return "0x" + number.toString(16); + }; + + // Convert an integer to a octal string + ul4._oct = function _oct(number) + { + if (typeof(number) != "number") + throw new ul4.TypeError("oct() requires an int"); + if (number < 0) + return "-0o" + number.toString(8).substr(1); + else + return "0o" + number.toString(8); + }; + + // Convert an integer to a binary string + ul4._bin = function _bin(number) + { + if (typeof(number) != "number") + throw new ul4.TypeError("bin() requires an int"); + if (number < 0) + return "-0b" + number.toString(2).substr(1); + else + return "0b" + number.toString(2); + }; + + // Return the minimum value + ul4._min = function _min(obj) + { + if (obj.length == 0) + throw new ul4.ArgumentError("min() requires at least 1 argument, 0 given"); + else if (obj.length == 1) + obj = obj[0]; + let iter = ul4._iter(obj); + let result; + let first = true; + while (true) + { + let item = iter.next(); + if (item.done) + { + if (first) + throw new ul4.ValueError("min() argument is an empty sequence!"); + return result; + } + if (first || (item.value < result)) + result = item.value; + first = false; + } + }; + + // Return the maximum value + ul4._max = function _max(obj) + { + if (obj.length == 0) + throw new ul4.ArgumentError("max() requires at least 1 argument, 0 given"); + else if (obj.length == 1) + obj = obj[0]; + let iter = ul4._iter(obj); + let result; + let first = true; + while (true) + { + let item = iter.next(); + if (item.done) + { + if (first) + throw new ul4.ValueError("max() argument is an empty sequence!"); + return result; + } + if (first || (item.value > result)) + result = item.value; + first = false; + } + }; + + // Return the of the values from the iterable starting with ``start`` (default ``0``) + ul4._sum = function _sum(iterable, start=0) + { + for (let iter = ul4._iter(iterable);;) + { + let item = iter.next(); + if (item.done) + break; + start += item.value; + } + return start; + }; + + // Return the first value produced by iterating through ``iterable`` (defaulting to ``defaultValue`` if the iterator is empty) + ul4._first = function _first(iterable, defaultValue=null) + { + let item = ul4._iter(iterable).next(); + return item.done ? defaultValue : item.value; + }; + + // Return the last value produced by iterating through ``iterable`` (defaulting to ``defaultValue`` if the iterator is empty) + ul4._last = function _last(iterable, defaultValue=null) + { + let value = defaultValue; + + for (let iter = ul4._iter(iterable);;) + { + let item = iter.next(); + if (item.done) + break; + value = item.value; + } + return value; + }; + + // Return a sorted version of ``iterable`` + ul4._sorted = function _sorted(context, iterable, key=null, reverse=false) + { + if (key === null) + { + // FIXME: stability + let cmp = reverse ? function cmp(a, b) + { + return -ul4._cmp("<=>", a, b); + } : function cmp(a, b) + { + return ul4._cmp("<=>", a, b); + }; + let result = ul4._list(iterable); + result.sort(cmp); + return result; + } + else + { + let sort = []; + + for (let i = 0, iter = ul4._iter(iterable);;++i) + { + let item = iter.next(); + if (item.done) + break; + let keyvalue = ul4._call(context, key, [item.value], {}); + // For a stable sorting we have to use the nagative index if + // reverse sorting is specified + sort.push([keyvalue, reverse ? -i : i, item.value]); + } + cmp = function cmp(s1, s2) + { + let res = ul4._cmp("<=>", s1[0], s2[0]); + if (res) + return reverse ? -res : res; + res = ul4._cmp("<=>", s1[1], s2[1]); + return reverse ? -res : res; + }; + + sort.sort(cmp); + + let result = []; + for (let i = 0; i < sort.length; ++i) + { + let item = sort[i]; + result.push(item[2]); + } + return result; + } + }; + + // Return a iterable object iterating from ``start`` up to (but not including) ``stop`` with a step size of ``step`` + ul4._range = function _range(args) + { + let start, stop, step; + if (args.length < 1) + throw new ul4.ArgumentError("required range() argument missing"); + else if (args.length > 3) + throw new ul4.ArgumentError("range() expects at most 3 positional arguments, " + args.length + " given"); + else if (args.length == 1) + { + start = 0; + stop = args[0]; + step = 1; + } + else if (args.length == 2) + { + start = args[0]; + stop = args[1]; + step = 1; + } + else if (args.length == 3) + { + start = args[0]; + stop = args[1]; + step = args[2]; + } + let lower, higher; + if (step === 0) + throw new ul4.ValueError("range() requires a step argument != 0"); + else if (step > 0) + { + lower = start; + higher = stop; + } + else + { + lower = stop; + higher = start; + } + let length = (lower < higher) ? Math.floor((higher - lower - 1)/Math.abs(step)) + 1 : 0; + + return { + index: 0, + next: function() + { + if (this.index >= length) + return {done: true}; + return {value: start + (this.index++) * step, done: false}; + } + }; + }; + + // Return a iterable object returning a slice from the argument + ul4._slice = function _slice(args) + { + let iterable, start, stop, step; + if (args.length < 2) + throw new ul4.ArgumentError("required slice() argument missing"); + else if (args.length > 4) + throw new ul4.ArgumentError("slice() expects at most 4 positional arguments, " + args.length + " given"); + else if (args.length == 2) + { + iterable = args[0]; + start = 0; + stop = args[1]; + step = 1; + } + else if (args.length == 3) + { + iterable = args[0]; + start = args[1] !== null ? args[1] : 0; + stop = args[2]; + step = 1; + } + else if (args.length == 4) + { + iterable = args[0]; + start = args[1] !== null ? args[1] : 0; + stop = args[2]; + step = args[3] !== null ? args[3] : 1; + } + if (start < 0) + throw new ul4.ValueError("slice() requires a start argument >= 0"); + if (stop < 0) + throw new ul4.ValueError("slice() requires a stop argument >= 0"); + if (step <= 0) + throw new ul4.ValueError("slice() requires a step argument > 0"); + + let next = start, count = 0; + let iter = ul4._iter(iterable); + return { + next: function() { + let result; + while (count < next) + { + result = iter.next(); + if (result.done) + return result; + ++count; + } + if (stop !== null && count >= stop) + return {done: true}; + result = iter.next(); + if (result.done) + return result; + ++count; + next += step; + if (stop !== null && next > stop) + next = stop; + return result; + } + }; + }; + + // ``%`` escape unsafe characters in the string ``string`` + ul4._urlquote = function _urlquote(string) + { + return encodeURIComponent(string); + }; + + // The inverse function of ``urlquote`` + ul4._urlunquote = function _urlunquote(string) + { + return decodeURIComponent(string); + }; + + // Return a reverse iterator over ``sequence`` + ul4._reversed = function _reversed(sequence) + { + if (typeof(sequence) != "string" && !ul4._islist(sequence)) // We don't have to materialize strings or lists + sequence = ul4._list(sequence); + return { + index: sequence.length-1, + next: function() { + return this.index >= 0 ? {value: sequence[this.index--], done: false} : {done: true}; + } + }; + }; + + // Returns a random number in the interval ``[0;1[`` + ul4._random = function _random() + { + return Math.random(); + }; + + // Return a randomly select item from ``range(start, stop, step)`` + ul4._randrange = function _randrange(args) + { + let start, stop, step; + if (args.length < 1) + throw new ul4.ArgumentError("required randrange() argument missing"); + else if (args.length > 3) + throw new ul4.ArgumentError("randrange() expects at most 3 positional arguments, " + args.length + " given"); + else if (args.length == 1) + { + start = 0; + stop = args[0]; + step = 1; + } + else if (args.length == 2) + { + start = args[0]; + stop = args[1]; + step = 1; + } + else if (args.length == 3) + { + start = args[0]; + stop = args[1]; + step = args[2]; + } + let width = stop-start; + + let value = Math.random(); + + let n; + if (step > 0) + n = Math.floor((width + step - 1) / step); + else if (step < 0) + n = Math.floor((width + step + 1) / step); + else + throw new ul4.ValueError("randrange() requires a step argument != 0"); + return start + step*Math.floor(value * n); + }; + + // Return a random item/char from the list/string ``sequence`` + ul4._randchoice = function _randchoice(sequence) + { + let iscolor = ul4._iscolor(sequence); + if (typeof(sequence) !== "string" && !ul4._islist(sequence) && !iscolor) + throw new ul4.TypeError("randchoice() requires a string or list"); + if (iscolor) + sequence = ul4._list(sequence); + return sequence[Math.floor(Math.random() * sequence.length)]; + }; + + // Round a number ``x`` to ``digits`` decimal places (may be negative) + ul4._round = function _round(x, digits=0) + { + if (digits) + { + let threshold = Math.pow(10, digits); + return Math.round(x*threshold)/threshold; + } + else + return Math.round(x); + }; + + // Return a hex-encode MD5 hash of the argument + // This uses the md5 function from https://github.com/blueimp/JavaScript-MD5 + if (iscommon) + { + ul4._md5 = function _md5(string) + { + let md5 = require('blueimp-md5'); + return md5(string); + }; + } + else + { + ul4._md5 = function _md5(string) + { + return md5(string); + }; + } + + // Return an iterator over ``[index, item]`` lists from the iterable object ``iterable``. ``index`` starts at ``start`` (defaulting to 0) + ul4._enumerate = function _enumerate(iterable, start=0) + { + return { + iter: ul4._iter(iterable), + index: start, + next: function() { + let item = this.iter.next(); + return item.done ? item : {value: [this.index++, item.value], done: false}; + } + }; + }; + + // Return an iterator over ``[isfirst, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, false otherwise) + ul4._isfirst = function _isfirst(iterable) + { + let iter = ul4._iter(iterable); + let isfirst = true; + return { + next: function() { + let item = iter.next(); + let result = item.done ? item : {value: [isfirst, item.value], done: false}; + isfirst = false; + return result; + } + }; + }; + + // Return an iterator over ``[islast, item]`` lists from the iterable object ``iterable`` (``islast`` is true for the last item, false otherwise) + ul4._islast = function _islast(iterable) + { + let iter = ul4._iter(iterable); + let lastitem = iter.next(); + return { + next: function() { + if (lastitem.done) + return lastitem; + let item = iter.next(); + let result = {value: [item.done, lastitem.value], done: false}; + lastitem = item; + return result; + } + }; + }; + + // Return an iterator over ``[isfirst, islast, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, ``islast`` is true for the last item. Both are false otherwise) + ul4._isfirstlast = function _isfirstlast(iterable) + { + let iter = ul4._iter(iterable); + let isfirst = true; + let lastitem = iter.next(); + return { + next: function() { + if (lastitem.done) + return lastitem; + let item = iter.next(); + let result = {value: [isfirst, item.done, lastitem.value], done: false}; + lastitem = item; + isfirst = false; + return result; + } + }; + }; + + // Return an iterator over ``[index, isfirst, islast, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, ``islast`` is true for the last item. Both are false otherwise) + ul4._enumfl = function _enumfl(iterable, start=0) + { + let iter = ul4._iter(iterable); + let i = start; + let isfirst = true; + let lastitem = iter.next(); + return { + next: function() { + if (lastitem.done) + return lastitem; + let item = iter.next(); + let result = {value: [i++, isfirst, item.done, lastitem.value], done: false}; + lastitem = item; + isfirst = false; + return result; + } + }; + }; + + // Return an iterator over lists, where the i'th list consists of all i'th items from the arguments (terminating when the shortest argument ends) + ul4._zip = function _zip(iterables) + { + let result; + if (iterables.length) + { + let iters = []; + for (let i = 0; i < iterables.length; ++i) + iters.push(ul4._iter(iterables[i])); + + return { + next: function() { + let items = []; + for (let i = 0; i < iters.length; ++i) + { + let item = iters[i].next(); + if (item.done) + return item; + items.push(item.value); + } + return {value: items, done: false}; + } + }; + } + else + { + return { + next: function() { + return {done: true}; + } + }; + } + }; + + // Return the absolute value for the number ``number`` + ul4._abs = function _abs(number) + { + if (number !== null && typeof(number.__abs__) === "function") + return number.__abs__(); + return Math.abs(number); + }; + + // Return a ``Date`` object from the arguments passed in + ul4._date = function _date(year, month, day) + { + return new ul4.Date(year, month, day); + }; + + ul4._datetime = function _datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0) + { + return new Date(year, month-1, day, hour, minute, second, microsecond/1000); + }; + + // Return a ``TimeDelta`` object from the arguments passed in + ul4._timedelta = function _timedelta(days=0, seconds=0, microseconds=0) + { + return new this.TimeDelta(days, seconds, microseconds); + }; + + // Return a ``MonthDelta`` object from the arguments passed in + ul4._monthdelta = function _monthdelta(months=0) + { + return new this.MonthDelta(months); + }; + + // Return a ``Color`` object from the hue, luminescence, saturation and alpha values ``h``, ``l``, ``s`` and ``a`` (i.e. using the HLS color model) + ul4._hls = function _hls(h, l, s, a) + { + let _v = function(m1, m2, hue) + { + hue = hue % 1.0; + if (hue < 1/6) + return m1 + (m2-m1)*hue*6.0; + else if (hue < 0.5) + return m2; + else if (hue < 2/3) + return m1 + (m2-m1)*(2/3-hue)*6.0; + return m1; + }; + + let m1, m2; + if (typeof(a) === "undefined") + a = 1; + if (s === 0.0) + return ul4._rgb(l, l, l, a); + if (l <= 0.5) + m2 = l * (1.0+s); + else + m2 = l+s-(l*s); + m1 = 2.0*l - m2; + return ul4._rgb(_v(m1, m2, h+1/3), _v(m1, m2, h), _v(m1, m2, h-1/3), a); + }; + + // Return a ``Color`` object from the hue, saturation, value and alpha values ``h``, ``s``, ``v`` and ``a`` (i.e. using the HSV color model) + ul4._hsv = function _hsv(h, s, v, a) + { + if (s === 0.0) + return ul4._rgb(v, v, v, a); + let i = Math.floor(h*6.0); + let f = (h*6.0) - i; + let p = v*(1.0 - s); + let q = v*(1.0 - s*f); + let t = v*(1.0 - s*(1.0-f)); + switch (i%6) + { + case 0: + return ul4._rgb(v, t, p, a); + case 1: + return ul4._rgb(q, v, p, a); + case 2: + return ul4._rgb(p, v, t, a); + case 3: + return ul4._rgb(p, q, v, a); + case 4: + return ul4._rgb(t, p, v, a); + case 5: + return ul4._rgb(v, p, q, a); + } + }; + + // Return the item with the key ``key`` from the dict ``container``. If ``container`` doesn't have this key, return ``defaultvalue`` + ul4._get = function _get(container, key, defaultvalue) + { + if (ul4._ismap(container)) + { + if (container.has(key)) + return container.get(key); + return defaultvalue; + } + else if (ul4._isobject(container)) + { + let result = container[key]; + if (typeof(result) === "undefined") + return defaultvalue; + return result; + } + throw new ul4.TypeError("get() requires a dict"); + }; + + // Return a ``Date`` object for the current time + ul4.now = function now() + { + return new Date(); + }; + + // Return a ``Date`` object for the current time in UTC + ul4.utcnow = function utcnow() + { + let now = new Date(); + // FIXME: The timezone is wrong for the new ``Date`` object. + return new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(), now.getUTCMilliseconds()); + }; + + // Return an ``ul4.Date`` object for today + ul4.today = function today() + { + let now = new Date(); + return new ul4.Date(now.getFullYear(), now.getMonth()+1, now.getDate()); + }; + + ul4.functions = { + repr: ul4._repr, + ascii: ul4._ascii, + str: ul4._str, + int: ul4._int, + float: ul4._float, + list: ul4._list, + set: ul4._set, + bool: ul4._bool, + len: ul4._len, + type: ul4._type, + format: ul4._format, + any: ul4._any, + all: ul4._all, + zip: ul4._zip, + getattr: ul4._getattr, + hasattr: ul4._hasattr, + dir: ul4._dir, + isundefined: ul4._isundefined, + isdefined: ul4._isdefined, + isnone: ul4._isnone, + isbool: ul4._isbool, + isint: ul4._isint, + isfloat: ul4._isfloat, + isstr: ul4._isstr, + isdate: ul4._isdate, + isdatetime: ul4._isdatetime, + iscolor: ul4._iscolor, + istimedelta: ul4._istimedelta, + ismonthdelta: ul4._ismonthdelta, + istemplate: ul4._istemplate, + isfunction: ul4._isfunction, + islist: ul4._islist, + isset: ul4._isanyset, + isdict: ul4._isdict, + isexception: ul4._isexception, + asjson: ul4._asjson, + fromjson: ul4._fromjson, + asul4on: ul4._asul4on, + fromul4on: ul4._fromul4on, + now: ul4.now, + utcnow: ul4.utcnow, + today: ul4.today, + enumerate: ul4._enumerate, + isfirst: ul4._isfirst, + islast: ul4._islast, + isfirstlast: ul4._isfirstlast, + enumfl: ul4._enumfl, + abs: ul4._abs, + date: ul4._date, + datetime: ul4._datetime, + timedelta: ul4._timedelta, + monthdelta: ul4._monthdelta, + rgb: ul4._rgb, + hls: ul4._hls, + hsv: ul4._hsv, + xmlescape: ul4._xmlescape, + csv: ul4._csv, + chr: ul4._chr, + ord: ul4._ord, + hex: ul4._hex, + oct: ul4._oct, + bin: ul4._bin, + min: ul4._min, + max: ul4._max, + sum: ul4._sum, + first: ul4._first, + last: ul4._last, + sorted: ul4._sorted, + range: ul4._range, + slice: ul4._slice, + urlquote: ul4._urlquote, + urlunquote: ul4._urlunquote, + reversed: ul4._reversed, + random: ul4._random, + randrange: ul4._randrange, + randchoice: ul4._randchoice, + round: ul4._round, + md5: ul4._md5 + }; + + ul4.expose(ul4._repr, ["obj"], {name: "repr"}); + ul4.expose(ul4._ascii, ["obj"], {name: "ascii"}); + ul4.expose(ul4._str, ["obj=", ""], {name: "str"}); + ul4.expose(ul4._int, ["obj=", 0, "base=", null], {name: "int"}); + ul4.expose(ul4._float, ["obj=", 0.0], {name: "float"}); + ul4.expose(ul4._list, ["iterable=", []], {name: "list"}); + ul4.expose(ul4._set, ["iterable=", []], {name: "set"}); + ul4.expose(ul4._bool, ["obj=", false], {name: "bool"}); + ul4.expose(ul4._len, ["sequence"], {name: "len"}); + ul4.expose(ul4._type, ["obj"], {name: "type"}); + ul4.expose(ul4._format, ["obj", "fmt", "lang=", null], {name: "format"}); + ul4.expose(ul4._any, ["iterable"], {name: "any"}); + ul4.expose(ul4._all, ["iterable"], {name: "all"}); + ul4.expose(ul4._zip, ["*iterables"], {name: "zip"}); + ul4.expose(ul4._getattr, ["obj", "attrname", "default=", null], {name: "getattr"}); + ul4.expose(ul4._hasattr, ["obj", "attrname"], {name: "hasattr"}); + ul4.expose(ul4._dir, ["obj"], {name: "dir"}); + ul4.expose(ul4._isundefined, ["obj"], {name: "isundefined"}); + ul4.expose(ul4._isdefined, ["obj"], {name: "isdefined"}); + ul4.expose(ul4._isnone, ["obj"], {name: "isnone"}); + ul4.expose(ul4._isbool, ["obj"], {name: "isbool"}); + ul4.expose(ul4._isint, ["obj"], {name: "isint"}); + ul4.expose(ul4._isfloat, ["obj"], {name: "isfloat"}); + ul4.expose(ul4._isstr, ["obj"], {name: "isstr"}); + ul4.expose(ul4._isdate, ["obj"], {name: "isdate"}); + ul4.expose(ul4._isdatetime, ["obj"], {name: "isdatetime"}); + ul4.expose(ul4._iscolor, ["obj"], {name: "iscolor"}); + ul4.expose(ul4._istimedelta, ["obj"], {name: "istimedelta"}); + ul4.expose(ul4._ismonthdelta, ["obj"], {name: "ismonthdelta"}); + ul4.expose(ul4._istemplate, ["obj"], {name: "istemplate"}); + ul4.expose(ul4._isfunction, ["obj"], {name: "isfunction"}); + ul4.expose(ul4._islist, ["obj"], {name: "islist"}); + ul4.expose(ul4._isanyset, ["obj"], {name: "isset"}); + ul4.expose(ul4._isdict, ["obj"], {name: "isdict"}); + ul4.expose(ul4._isexception, ["obj"], {name: "isexception"}); + ul4.expose(ul4._asjson, ["obj"], {name: "asjson"}); + ul4.expose(ul4._fromjson, ["string"], {name: "fromjson"}); + ul4.expose(ul4._asul4on, ["obj"], {name: "asul4on"}); + ul4.expose(ul4._fromul4on, ["string"], {name: "fromul4on"}); + ul4.expose(ul4.now, []); + ul4.expose(ul4.utcnow, []); + ul4.expose(ul4.today, []); + ul4.expose(ul4._enumerate, ["iterable", "start=", 0], {name: "enumerate"}); + ul4.expose(ul4._isfirst, ["iterable"], {name: "isfirst"}); + ul4.expose(ul4._islast, ["iterable"], {name: "islast"}); + ul4.expose(ul4._isfirstlast, ["iterable"], {name: "isfirstlast"}); + ul4.expose(ul4._enumfl, ["iterable", "start=", 0], {name: "enumfl"}); + ul4.expose(ul4._abs, ["number"], {name: "abs"}); + ul4.expose(ul4._date, ["year", "month", "day"], {name: "date"}); + ul4.expose(ul4._datetime, ["year", "month", "day", "hour=", 0, "minute=", 0, "second=", 0, "microsecond=", 0], {name: "datetime"}); + ul4.expose(ul4._timedelta, ["days=", 0, "seconds=", 0, "microseconds=", 0], {name: "timedelta"}); + ul4.expose(ul4._monthdelta, ["months=", 0], {name: "monthdelta"}); + ul4.expose(ul4._rgb, ["r", "g", "b", "a=", 1.0], {name: "rgb"}); + ul4.expose(ul4._hls, ["h", "l", "s", "a=", 1.0], {name: "hls"}); + ul4.expose(ul4._hsv, ["h", "s", "v", "a=", 1.0], {name: "hsv"}); + ul4.expose(ul4._xmlescape, ["obj"], {name: "xmlescape"}); + ul4.expose(ul4._csv, ["obj"], {name: "csv"}); + ul4.expose(ul4._chr, ["i"], {name: "chr"}); + ul4.expose(ul4._ord, ["c"], {name: "ord"}); + ul4.expose(ul4._hex, ["number"], {name: "hex"}); + ul4.expose(ul4._oct, ["number"], {name: "oct"}); + ul4.expose(ul4._bin, ["number"], {name: "bin"}); + ul4.expose(ul4._min, ["*obj"], {name: "min"}); + ul4.expose(ul4._max, ["*obj"], {name: "max"}); + ul4.expose(ul4._sum, ["iterable", "start=", 0], {name: "sum"}); + ul4.expose(ul4._first, ["iterable", "default=", null], {name: "first"}); + ul4.expose(ul4._last, ["iterable", "default=", null], {name: "last"}); + ul4.expose(ul4._sorted, ["iterable", "key=", null, "reverse=", false], {name: "sorted", needscontext: true}); + ul4.expose(ul4._range, ["*args"], {name: "range"}); + ul4.expose(ul4._slice, ["*args"], {name: "slice"}); + ul4.expose(ul4._urlquote, ["string"], {name: "urlquote"}); + ul4.expose(ul4._urlunquote, ["string"], {name: "urlunquote"}); + ul4.expose(ul4._reversed, ["sequence"], {name: "reversed"}); + ul4.expose(ul4._random, [], {name: "random"}); + ul4.expose(ul4._randrange, ["*args"], {name: "randrange"}); + ul4.expose(ul4._randchoice, ["sequence"], {name: "randchoice"}); + ul4.expose(ul4._round, ["x", "digit=", 0], {name: "round"}); + ul4.expose(ul4._md5, ["string"], {name: "md5"}); + + // Functions implementing UL4 methods + ul4._count = function _count(obj, sub, start=null, end=null) + { + if (start < 0) + start += obj.length; + if (start === null) + start = 0; + + if (end < 0) + end += obj.length; + if (end === null) + end = obj.length; + + let isstr = ul4._isstr(obj); + + if (isstr && !sub.length) + { + if (end < 0 || start > obj.length || start > end) + return 0; + let result = end - start + 1; + if (result > obj.length + 1) + result = obj.length + 1; + return result; + } + + start = ul4._bound(start, obj.length); + end = ul4._bound(end, obj.length); + + let count = 0; + if (ul4._islist(obj)) + { + for (let i = start; i < end; ++i) + { + if (ul4._eq(obj[i], sub)) + ++count; + } + return count; + } + else // string + { + let lastIndex = start; + + for (;;) + { + lastIndex = obj.indexOf(sub, lastIndex); + if (lastIndex == -1) + break; + if (lastIndex + sub.length > end) + break; + ++count; + lastIndex += sub.length; + } + return count; + } + }; + + ul4._find = function _find(obj, sub, start=null, end=null) + { + if (start < 0) + start += obj.length; + if (start === null) + start = 0; + if (end < 0) + end += obj.length; + if (end === null) + end = obj.length; + start = ul4._bound(start, obj.length); + end = ul4._bound(end, obj.length); + + if (start !== 0 || end !== obj.length) + { + if (typeof(obj) == "string") + obj = obj.substring(start, end); + else + obj = obj.slice(start, end); + } + let result = obj.indexOf(sub); + if (result !== -1) + result += start; + return result; + }; + + ul4._rfind = function _rfind(obj, sub, start=null, end=null) + { + if (start < 0) + start += obj.length; + if (start === null) + start = 0; + if (end < 0) + end += obj.length; + if (end === null) + end = obj.length; + start = ul4._bound(start, obj.length); + end = ul4._bound(end, obj.length); + + if (start !== 0 || end !== obj.length) + { + if (typeof(obj) == "string") + obj = obj.substring(start, end); + else + obj = obj.slice(start, end); + } + let result = obj.lastIndexOf(sub); + if (result !== -1) + result += start; + return result; + }; + + ul4._week4format = function _week(obj, firstweekday=null) + { + if (firstweekday === null) + firstweekday = 0; + else + firstweekday %= 7; + + let yearday = ul4.DateTimeProtocol.yearday(obj)+6; + let jan1 = new Date(obj.getFullYear(), 0, 1); + let jan1weekday = jan1.getDay(); + if (--jan1weekday < 0) + jan1weekday = 6; + + while (jan1weekday != firstweekday) + { + --yearday; + if (++jan1weekday == 7) + jan1weekday = 0; + } + return Math.floor(yearday/7); + }; + + ul4._isleap = function _isleap(obj) + { + return new Date(obj.getFullYear(), 1, 29).getMonth() === 1; + }; + + ul4._update = function _update(obj, others, kwargs) + { + if (!ul4._isdict(obj)) + throw new ul4.TypeError("update() requires a dict"); + for (let i = 0; i < others.length; ++i) + { + let other = others[i]; + if (ul4._ismap(other)) + { + other.forEach(function(value, key) { + ul4._setmap(obj, key, value); + }); + } + else if (ul4._isobject(other)) + { + for (let key in other) + ul4._setmap(obj, key, other[key]); + } + else if (ul4._islist(other)) + { + for (let i = 0; i < other.length; ++i) + { + let item = other[i]; + if (!ul4._islist(item) || (item.length != 2)) + throw new ul4.TypeError("update() requires a dict or a list of (key, value) pairs"); + ul4._setmap(obj, item[0], item[1]); + } + } + else + throw new ul4.TypeError("update() requires a dict or a list of (key, value) pairs"); + } + kwargs.forEach(function(value, key) { + ul4._setmap(obj, key, value); + }); + return null; + }; + + ul4.Color = class Color extends ul4.Proto + { + constructor(r=0, g=0, b=0, a=255) + { + super(); + this._r = r; + this._g = g; + this._b = b; + this._a = a; + } + + __repr__() + { + let r = ul4._lpad(this._r.toString(16), "0", 2); + let g = ul4._lpad(this._g.toString(16), "0", 2); + let b = ul4._lpad(this._b.toString(16), "0", 2); + let a = ul4._lpad(this._a.toString(16), "0", 2); + if (this._a !== 0xff) + { + if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1] && a[0] === a[1]) + return "#" + r[0] + g[0] + b[0] + a[0]; + else + return "#" + r + g + b + a; + } + else + { + if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1]) + return "#" + r[0] + g[0] + b[0]; + else + return "#" + r + g + b; + } + } + + __str__() + { + if (this._a !== 0xff) + { + return "rgba(" + this._r + ", " + this._g + ", " + this._b + ", " + (this._a/255) + ")"; + } + else + { + let r = ul4._lpad(this._r.toString(16), "0", 2); + let g = ul4._lpad(this._g.toString(16), "0", 2); + let b = ul4._lpad(this._b.toString(16), "0", 2); + if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1]) + return "#" + r[0] + g[0] + b[0]; + else + return "#" + r + g + b; + } + } + + __iter__() + { + return { + obj: this, + index: 0, + next: function() { + if (this.index == 0) + { + ++this.index; + return {value: this.obj._r, done: false}; + } + else if (this.index == 1) + { + ++this.index; + return {value: this.obj._g, done: false}; + } + else if (this.index == 2) + { + ++this.index; + return {value: this.obj._b, done: false}; + } + else if (this.index == 3) + { + ++this.index; + return {value: this.obj._a, done: false}; + } + else + return {done: true}; + } + }; + } + + __getattr__(attrname) + { + let self = this; + switch (attrname) + { + case "r": + let r = function r(){ return self._r; }; + ul4.expose(r, []); + return r; + case "g": + let g = function g(){ return self._g; }; + ul4.expose(g, []); + return g; + case "b": + let b = function b(){ return self._b; }; + ul4.expose(b, []); + return b; + case "a": + let a = function a(){ return self._a; }; + ul4.expose(a, []); + return a; + case "lum": + let lum = function lum(){ return self.lum(); }; + ul4.expose(lum, []); + return lum; + case "hls": + let hls = function hls(){ return self.hls(); }; + ul4.expose(hls, []); + return hls; + case "hlsa": + let hlsa = function hlsa(){ return self.hlsa(); }; + ul4.expose(hlsa, []); + return hlsa; + case "hsv": + let hsv = function hsv(){ return self.hsv(); }; + ul4.expose(hsv, []); + return hsv; + case "hsva": + let hsva = function hsva(){ return self.hsva(); }; + ul4.expose(hsva, []); + return hsva; + case "witha": + let witha = function witha(a){ return self.witha(a); }; + ul4.expose(witha, ["a"]); + return witha; + case "withlum": + let withlum = function withlum(lum){ return self.withlum(lum); }; + ul4.expose(withlum, ["lum"]); + return withlum; + case "abslum": + let abslum = function abslum(lum){ return self.abslum(lum); }; + ul4.expose(abslum, ["lum"]); + return abslum; + case "rellum": + let rellum = function rellum(lum){ return self.rellum(lum); }; + ul4.expose(rellum, ["lum"]); + return rellum; + default: + throw new ul4.AttributeError(this, attrname); + } + } + + __getitem__(key) + { + let orgkey = key; + if (key < 0) + key += 4; + switch (key) + { + case 0: + return this._r; + case 1: + return this._g; + case 2: + return this._b; + case 3: + return this._a; + default: + throw new ul4.IndexError(this, orgkey); + } + } + + __eq__(other) + { + if (other instanceof ul4.Color) + return this._r == other._r && this._g == other._g && this._b == other._b && this._a == other._a; + return false; + } + + r() + { + return this._r; + } + + g() + { + return this._g; + } + + b() + { + return this._b; + } + + a() + { + return this._a; + } + + lum() + { + return this.hls()[1]; + } + + hls() + { + let r = this._r/255.0; + let g = this._g/255.0; + let b = this._b/255.0; + let maxc = Math.max(r, g, b); + let minc = Math.min(r, g, b); + let h, l, s; + let rc, gc, bc; + + l = (minc+maxc)/2.0; + if (minc == maxc) + return [0.0, l, 0.0]; + if (l <= 0.5) + s = (maxc-minc) / (maxc+minc); + else + s = (maxc-minc) / (2.0-maxc-minc); + rc = (maxc-r) / (maxc-minc); + gc = (maxc-g) / (maxc-minc); + bc = (maxc-b) / (maxc-minc); + if (r == maxc) + h = bc-gc; + else if (g == maxc) + h = 2.0+rc-bc; + else + h = 4.0+gc-rc; + h = (h/6.0) % 1.0; + return [h, l, s]; + } + + hlsa() + { + let hls = this.hls(); + return hls.concat(this._a/255.0); + } + + hsv() + { + let r = this._r/255.0; + let g = this._g/255.0; + let b = this._b/255.0; + let maxc = Math.max(r, g, b); + let minc = Math.min(r, g, b); + let v = maxc; + if (minc == maxc) + return [0.0, 0.0, v]; + let s = (maxc-minc) / maxc; + let rc = (maxc-r) / (maxc-minc); + let gc = (maxc-g) / (maxc-minc); + let bc = (maxc-b) / (maxc-minc); + let h; + if (r == maxc) + h = bc-gc; + else if (g == maxc) + h = 2.0+rc-bc; + else + h = 4.0+gc-rc; + h = (h/6.0) % 1.0; + return [h, s, v]; + } + + hsva() + { + let hsv = this.hsv(); + return hsv.concat(this._a/255.0); + } + + witha(a) + { + if (typeof(a) !== "number") + throw new ul4.TypeError("witha() requires a number"); + return new ul4.Color(this._r, this._g, this._b, a); + } + + withlum(lum) + { + if (typeof(lum) !== "number") + throw new ul4.TypeError("witha() requires a number"); + let hlsa = this.hlsa(); + return ul4._hls(hlsa[0], lum, hlsa[2], hlsa[3]); + } + + ul4type() + { + return "color"; + } + }; + + ul4.expose(ul4.Color.prototype.r, []); + ul4.expose(ul4.Color.prototype.g, []); + ul4.expose(ul4.Color.prototype.b, []); + ul4.expose(ul4.Color.prototype.a, []); + ul4.expose(ul4.Color.prototype.lum, []); + ul4.expose(ul4.Color.prototype.hls, []); + ul4.expose(ul4.Color.prototype.hlsa, []); + ul4.expose(ul4.Color.prototype.hsv, []); + ul4.expose(ul4.Color.prototype.hsva, []); + ul4.expose(ul4.Color.prototype.witha, ["a"]); + ul4.expose(ul4.Color.prototype.withlum, ["lum"]); + + const _js_Date = Date; + + ul4.Date = class Date extends ul4.Proto + { + constructor(year, month, day) + { + super(); + this._date = new _js_Date(year, month-1, day); + } + + __repr__() + { + return '@(' + this.__str__() + ")"; + } + + __str__() + { + return ul4._lpad(this._date.getFullYear(), "0", 4) + "-" + ul4._lpad(this._date.getMonth()+1, "0", 2) + "-" + ul4._lpad(this._date.getDate(), "0", 2); + } + + __eq__(other) + { + if (other instanceof ul4.Date) + return this._date.getTime() === other._date.getTime(); + return false; + } + + __lt__(other) + { + if (other instanceof ul4.Date) + return this._date < other._date; + ul4._unorderable("<", this, other); + } + + __le__(other) + { + if (other instanceof ul4.Date) + return this._date <= other._date; + ul4._unorderable("<=", this, other); + } + + __gt__(other) + { + if (other instanceof ul4.Date) + return this._date > other._date; + ul4._unorderable(">", this, other); + } + + __ge__(other) + { + if (other instanceof ul4.Date) + return this._date >= other._date; + ul4._unorderable(">=", this, other); + } + + year() + { + return this._date.getFullYear(); + } + + month() + { + return this._date.getMonth()+1; + } + + day() + { + return this._date.getDate(); + } + + ul4type() + { + return "date"; + } + }; + + + ul4.TimeDelta = class TimeDelta extends ul4.Proto + { + constructor(days=0, seconds=0, microseconds=0) + { + super(); + let total_microseconds = Math.floor((days * 86400 + seconds)*1000000 + microseconds); + + microseconds = ul4.ModAST.prototype._do(total_microseconds, 1000000); + let total_seconds = Math.floor(total_microseconds / 1000000); + seconds = ul4.ModAST.prototype._do(total_seconds, 86400); + days = Math.floor(total_seconds / 86400); + if (seconds < 0) + { + seconds += 86400; + --days; + } + + this._microseconds = microseconds; + this._seconds = seconds; + this._days = days; + } + + __repr__() + { + let v = [], first = true; + v.push("timedelta("); + if (this._days) + { + v.push("days=" + this._days); + first = false; + } + if (this._seconds) + { + if (!first) + v.push(", "); + v.push("seconds=" + this._seconds); + first = false; + } + if (this._microseconds) + { + if (!first) + v.push(", "); + v.push("microseconds=" + this._microseconds); + } + v.push(")"); + return v.join(""); + } + + __str__() + { + let v = []; + if (this._days) + { + v.push(this._days + " day"); + if (this._days !== -1 && this._days !== 1) + v.push("s"); + v.push(", "); + } + let seconds = this._seconds % 60; + let minutes = Math.floor(this._seconds / 60); + let hours = Math.floor(minutes / 60); + minutes = minutes % 60; + + v.push("" + hours); + v.push(":"); + v.push(ul4._lpad(minutes.toString(), "0", 2)); + v.push(":"); + v.push(ul4._lpad(seconds.toString(), "0", 2)); + if (this._microseconds) + { + v.push("."); + v.push(ul4._lpad(this._microseconds.toString(), "0", 6)); + } + return v.join(""); + } + + __bool__() + { + return this._days !== 0 || this._seconds !== 0 || this._microseconds !== 0; + } + + __abs__() + { + return this._days < 0 ? new ul4.TimeDelta(-this._days, -this._seconds, -this._microseconds) : this; + } + + __eq__(other) + { + if (other instanceof ul4.TimeDelta) + return (this._days === other._days) && (this._seconds === other._seconds) && (this._microseconds === other._microseconds); + return false; + } + + __lt__(other) + { + if (other instanceof ul4.TimeDelta) + { + if (this._days != other._days) + return this._days < other._days; + if (this._seconds != other._seconds) + return this._seconds < other._seconds; + return this._microseconds < other._microseconds; + } + ul4._unorderable("<", this, other); + } + + __le__(other) + { + if (other instanceof ul4.TimeDelta) + { + if (this._days != other._days) + return this._days < other._days; + if (this._seconds != other._seconds) + return this._seconds < other._seconds; + return this._microseconds <= other._microseconds; + } + ul4._unorderable("<=", this, other); + } + + __gt__(other) + { + if (other instanceof ul4.TimeDelta) + { + if (this._days != other._days) + return this._days > other._days; + if (this._seconds != other._seconds) + return this._seconds > other._seconds; + return this._microseconds > other._microseconds; + } + ul4._unorderable(">", this, other); + } + + __ge__(other) + { + if (other instanceof ul4.TimeDelta) + { + if (this._days != other._days) + return this._days > other._days; + if (this._seconds != other._seconds) + return this._seconds > other._seconds; + return this._microseconds >= other._microseconds; + } + ul4._unorderable(">=", this, other); + } + + __neg__() + { + return new ul4.TimeDelta(-this._days, -this._seconds, -this._microseconds); + } + + adddate(date, days) + { + let year = date._date.getFullYear(); + let month = date._date.getMonth(); + let day = date._date.getDate() + days; + return new ul4.Date(year, month, day); + } + + _adddatetime(date, days, seconds, microseconds) + { + let year = date.getFullYear(); + let month = date.getMonth(); + let day = date.getDate() + days; + let hour = date.getHours(); + let minute = date.getMinutes(); + let second = date.getSeconds() + seconds; + let millisecond = date.getMilliseconds() + microseconds/1000; + return new Date(year, month, day, hour, minute, second, millisecond); + } + + __add__(other) + { + if (other instanceof ul4.TimeDelta) + return new ul4.TimeDelta(this._days + other._days, this._seconds + other._seconds, this._microseconds + other._microseconds); + else if (ul4._isdate(other)) + return this._adddate(other, this._days); + else if (ul4._isdatetime(other)) + return this._adddatetime(other, this._days, this._seconds, this._microseconds); + throw new ul4.TypeError(ul4._type(this) + " + " + ul4._type(other) + " not supported"); + } + + __radd__(other) + { + if (ul4._isdate(other)) + return this._adddate(other, this._days); + else if (ul4._isdatetime(other)) + return this._adddatetime(other, this._days, this._seconds, this._microseconds); + throw new ul4.TypeError(ul4._type(this) + " + " + ul4._type(other) + " not supported"); + } + + __sub__(other) + { + if (other instanceof ul4.TimeDelta) + return new ul4.TimeDelta(this._days - other._days, this._seconds - other._seconds, this._microseconds - other._microseconds); + throw new ul4.TypeError(ul4._type(this) + " - " + ul4._type(other) + " not supported"); + } + + __rsub__(other) + { + if (ul4._isdate(other)) + return this._adddate(other, -this._days); + else if (ul4._isdatetime(other)) + return this._adddatetime(other, -this._days, -this._seconds, -this._microseconds); + throw new ul4.TypeError(ul4._type(this) + " - " + ul4._type(other) + " not supported"); + } + + __mul__(other) + { + if (typeof(other) === "number") + return new ul4.TimeDelta(this._days * other, this._seconds * other, this._microseconds * other); + throw new ul4.TypeError(ul4._type(this) + " * " + ul4._type(other) + " not supported"); + } + + __rmul__(other) + { + if (typeof(other) === "number") + return new ul4.TimeDelta(this._days * other, this._seconds * other, this._microseconds * other); + throw new ul4.TypeError(ul4._type(this) + " * " + ul4._type(other) + " not supported"); + } + + __truediv__(other) + { + if (typeof(other) === "number") + { + return new ul4.TimeDelta(this._days / other, this._seconds / other, this._microseconds / other); + } + else if (other instanceof ul4.TimeDelta) + { + let myValue = this._days; + let otherValue = other._days; + let hasSeconds = this._seconds || other._seconds; + let hasMicroseconds = this._microseconds || other._microseconds; + if (hasSeconds || hasMicroseconds) + { + myValue = myValue*86400+this._seconds; + otherValue = otherValue*86400 + other._seconds; + if (hasMicroseconds) + { + myValue = myValue * 1000000 + this._microseconds; + otherValue = otherValue * 1000000 + other._microseconds; + } + } + return myValue/otherValue; + } + throw new ul4.TypeError(ul4._type(this) + " / " + ul4._type(other) + " not supported"); + } + + __getattr__(attrname) + { + let self = this; + switch (attrname) + { + case "days": + let days = function days(){ return self._days; }; + ul4.expose(days, []); + return days; + case "seconds": + let seconds = function seconds(){ return self._seconds; }; + ul4.expose(seconds, []); + return seconds; + case "microseconds": + let microseconds = function microseconds(){ return self._microseconds; }; + ul4.expose(microseconds, []); + return microseconds; + default: + throw new ul4.AttributeError(this, attrname); + } + } + + days() + { + return this._days; + } + + seconds() + { + return this._seconds; + } + + microseconds() + { + return this._microseconds; + } + + ul4type() + { + return "timedelta"; + } + }; + + + ul4.MonthDelta = class MonthDelta extends ul4.Proto + { + constructor(months=0) + { + super(); + this._months = months; + } + + __repr__() + { + if (!this._months) + return "monthdelta()"; + return "monthdelta(" + this._months + ")"; + } + + __str__() + { + if (this._months) + { + if (this._months !== -1 && this._months !== 1) + return this._months + " months"; + return this._months + " month"; + } + return "0 months"; + } + + toString() + { + return this.__str__(); + } + + __bool__() + { + return this._months !== 0; + } + + __abs__() + { + return this._months < 0 ? new ul4.MonthDelta(-this._months) : this; + } + + __eq__(other) + { + if (other instanceof MonthDelta) + return this._months === other._months; + return false; + } + + __lt__(other) + { + if (other instanceof ul4.MonthDelta) + return this._months < other._months; + ul4._unorderable("<", this, other); + } + + __le__(other) + { + if (other instanceof ul4.MonthDelta) + return this._months <= other._months; + ul4._unorderable("<=", this, other); + } + + __gt__(other) + { + if (other instanceof ul4.MonthDelta) + return this._months > other._months; + ul4._unorderable(">", this, other); + } + + __ge__(other) + { + if (other instanceof ul4.MonthDelta) + return this._months >= other._months; + ul4._unorderable(">=", this, other); + } + + __neg__() + { + return new ul4.MonthDelta(-this._months); + } + + _adddate(date, months) + { + let result = this._adddatetime(date._date, months); + return new ul4.Date(result.getFullYear(), result.getMonth()+1, result.getDate()); + } + + _adddatetime(date, months) + { + let year = date.getFullYear(); + let month = date.getMonth() + months; + let day = date.getDate(); + let hour = date.getHours(); + let minute = date.getMinutes(); + let second = date.getSeconds(); + let millisecond = date.getMilliseconds(); + + while (true) + { + // As the month might be out of bounds, we have to find out, what the real target month is + let targetmonth = new Date(year, month, 1, hour, minute, second, millisecond).getMonth(); + let result = new Date(year, month, day, hour, minute, second, millisecond); + if (result.getMonth() === targetmonth) + return result; + --day; + } + } + + __add__(other) + { + if (ul4._ismonthdelta(other)) + return new ul4.MonthDelta(this._months + other._months); + else if (ul4._isdate(other)) + return this._adddate(other, this._months); + else if (ul4._isdatetime(other)) + return this._adddatetime(other, this._months); + throw new ul4.ArgumentError(ul4._type(this) + " + " + ul4._type(other) + " not supported"); + } + + __radd__(other) + { + if (ul4._isdate(other)) + return this._adddate(other, this._months); + else if (ul4._isdatetime(other)) + return this._adddatetime(other, this._months); + throw new ul4.ArgumentError(ul4._type(this) + " + " + ul4._type(other) + " not supported"); + } + + __sub__(other) + { + if (ul4._ismonthdelta(other)) + return new ul4.MonthDelta(this._months - other._months); + throw new ul4.ArgumentError(ul4._type(this) + " - " + ul4._type(other) + " not supported"); + } + + __rsub__(other) + { + if (ul4._isdate(other)) + return this._adddate(other, -this._months); + else if (ul4._isdatetime(other)) + return this._adddatetime(other, -this._months); + throw new ul4.ArgumentError(ul4._type(this) + " - " + ul4._type(other) + " not supported"); + } + + __mul__(other) + { + if (typeof(other) === "number") + return new ul4.MonthDelta(this._months * Math.floor(other)); + throw new ul4.ArgumentError(ul4._type(this) + " * " + ul4._type(other) + " not supported"); + } + + __rmul__(other) + { + if (typeof(other) === "number") + return new ul4.MonthDelta(this._months * Math.floor(other)); + throw new ul4.ArgumentError(ul4._type(this) + " * " + ul4._type(other) + " not supported"); + } + + __floordiv__(other) + { + if (typeof(other) === "number") + return new ul4.MonthDelta(Math.floor(this._months / other)); + else if (ul4._ismonthdelta(other)) + return Math.floor(this._months / other._months); + throw new ul4.ArgumentError(ul4._type(this) + " // " + ul4._type(other) + " not supported"); + } + + __truediv__(other) + { + if (ul4._ismonthdelta(other)) + return this._months / other._months; + throw new ul4.ArgumentError(ul4._type(this) + " / " + ul4._type(other) + " not supported"); + } + + __getattr__(attrname) + { + let self = this; + switch (attrname) + { + case "months": + let months = function months(){ return self._months; }; + ul4.expose(months, []); + return months; + default: + throw new ul4.AttributeError(this, attrname); + } + } + + months() + { + return this._months; + } + + ul4type() + { + return "monthdelta"; + } + }; + + const classes = [ + ul4.TextAST, + ul4.IndentAST, + ul4.LineEndAST, + ul4.ConstAST, + ul4.SeqItemAST, + ul4.UnpackSeqItemAST, + ul4.DictItemAST, + ul4.UnpackDictItemAST, + ul4.PosArgAST, + ul4.KeywordArgAST, + ul4.UnpackListArgAST, + ul4.UnpackDictArgAST, + ul4.ListAST, + ul4.ListCompAST, + ul4.DictAST, + ul4.DictCompAST, + ul4.SetAST, + ul4.SetCompAST, + ul4.GenExprAST, + ul4.VarAST, + ul4.NotAST, + ul4.NegAST, + ul4.BitNotAST, + ul4.IfAST, + ul4.ReturnAST, + ul4.PrintAST, + ul4.PrintXAST, + ul4.ItemAST, + ul4.IsAST, + ul4.IsNotAST, + ul4.EQAST, + ul4.NEAST, + ul4.LTAST, + ul4.LEAST, + ul4.GTAST, + ul4.GEAST, + ul4.NotContainsAST, + ul4.ContainsAST, + ul4.AddAST, + ul4.SubAST, + ul4.MulAST, + ul4.FloorDivAST, + ul4.TrueDivAST, + ul4.ModAST, + ul4.ShiftLeftAST, + ul4.ShiftRightAST, + ul4.BitAndAST, + ul4.BitXOrAST, + ul4.BitOrAST, + ul4.AndAST, + ul4.OrAST, + ul4.SliceAST, + ul4.AttrAST, + ul4.CallAST, + ul4.RenderAST, + ul4.RenderXAST, + ul4.RenderBlockAST, + ul4.RenderBlocksAST, + ul4.SetVarAST, + ul4.AddVarAST, + ul4.SubVarAST, + ul4.MulVarAST, + ul4.TrueDivVarAST, + ul4.FloorDivVarAST, + ul4.ModVarAST, + ul4.ShiftLeftVarAST, + ul4.ShiftRightVarAST, + ul4.BitAndVarAST, + ul4.BitXOrVarAST, + ul4.BitOrVarAST, + ul4.ForBlockAST, + ul4.WhileBlockAST, + ul4.BreakAST, + ul4.ContinueAST, + ul4.CondBlockAST, + ul4.IfBlockAST, + ul4.ElIfBlockAST, + ul4.ElseBlockAST, + ul4.SignatureAST, + ul4.Template + ]; + + for (let i = 0; i < classes.length; ++i) + { + let constructor = classes[i]; + let ul4onname = constructor.name; + if (ul4onname.substr(ul4onname.length-3) === "AST") + ul4onname = ul4onname.substr(0, ul4onname.length-3); + ul4onname = ul4onname.toLowerCase(); + constructor.prototype.type = ul4onname; + ul4.register("de.livinglogic.ul4." + ul4onname, constructor); + } \ No newline at end of file diff --git a/dist/umd/livingsdk.d.ts b/dist/umd/livingsdk.d.ts new file mode 100644 index 0000000..aa527ac --- /dev/null +++ b/dist/umd/livingsdk.d.ts @@ -0,0 +1,26 @@ +import { AxiosResponse } from 'axios'; +export declare type Auth_Token = string; +export declare type LivingApi = any; +export declare type LAPIRecord = any; +export interface LivingSDKOptions { + url?: string; + loginRequired?: boolean; +} +export declare class LivingSDK { + private _password; + private _userName; + private _options; + private hostName; + private session; + constructor(options?: LivingSDKOptions, username?: string, password?: string); + login(): Promise; + get(appId: string, templateName?: string): Promise; + _insert(app: any, values: any): Promise; + _update(record: LAPIRecord, values: any): Promise<{ + HTTPstatusCode: number; + recordid: any; + Record: any; + }>; + _delete(record: LAPIRecord): Promise>; +} +export default LivingSDK; diff --git a/dist/umd/livingsdk.js b/dist/umd/livingsdk.js new file mode 100644 index 0000000..eb13791 --- /dev/null +++ b/dist/umd/livingsdk.js @@ -0,0 +1,2 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("core-js/modules/es6.array.sort"),require("core-js/modules/es6.object.set-prototype-of"),require("core-js/modules/es6.array.find"),require("core-js/modules/es6.array.last-index-of"),require("core-js/modules/es6.regexp.split"),require("core-js/modules/es6.array.index-of"),require("core-js/modules/es6.regexp.to-string"),require("core-js/modules/es6.date.to-string"),require("core-js/modules/es6.object.create"),require("core-js/modules/es6.object.assign"),require("core-js/modules/es6.function.name"),require("core-js/modules/es6.regexp.match"),require("core-js/modules/es6.regexp.replace"),require("core-js/modules/es6.set"),require("core-js/modules/es6.array.for-each"),require("core-js/modules/web.dom.iterable"),require("core-js/modules/es6.array.iterator"),require("core-js/modules/es6.string.iterator"),require("core-js/modules/es6.map"),require("core-js/modules/es6.regexp.search"),require("core-js/modules/es6.string.starts-with"),require("core-js/modules/es7.symbol.async-iterator"),require("core-js/modules/es6.symbol"),require("core-js/modules/es6.function.bind"),require("core-js/modules/es6.date.now"),require("core-js/modules/es6.promise"),require("axios"),require("https")):"function"==typeof define&&define.amd?define(["exports","core-js/modules/es6.array.sort","core-js/modules/es6.object.set-prototype-of","core-js/modules/es6.array.find","core-js/modules/es6.array.last-index-of","core-js/modules/es6.regexp.split","core-js/modules/es6.array.index-of","core-js/modules/es6.regexp.to-string","core-js/modules/es6.date.to-string","core-js/modules/es6.object.create","core-js/modules/es6.object.assign","core-js/modules/es6.function.name","core-js/modules/es6.regexp.match","core-js/modules/es6.regexp.replace","core-js/modules/es6.set","core-js/modules/es6.array.for-each","core-js/modules/web.dom.iterable","core-js/modules/es6.array.iterator","core-js/modules/es6.string.iterator","core-js/modules/es6.map","core-js/modules/es6.regexp.search","core-js/modules/es6.string.starts-with","core-js/modules/es7.symbol.async-iterator","core-js/modules/es6.symbol","core-js/modules/es6.function.bind","core-js/modules/es6.date.now","core-js/modules/es6.promise","axios","https"],e):e(t.livingsdk={},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,t.axios,t.https)}(this,function(t,e,r,n,o,i,a,u,s,l,c,h,p,_,f,d,v,m,y,g,b,k,S,w,A,x,T,j,C){"use strict";function M(t){return(M="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function E(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function D(t,e){for(var r=0;r=this.data.length)throw new R.ValueError("UL4 decoder at EOF");return this.data.charAt(this.pos++)}},{key:"readcharoreof",value:function(){return this.pos>=this.data.length?null:this.data.charAt(this.pos++)}},{key:"readblackchar",value:function(){for(var t=/\s/;;){if(this.pos>=this.data.length)throw new R.ValueError("UL4 decoder at EOF at position "+this.pos+" with path "+this.stack.join("/"));var e=this.data.charAt(this.pos++);if(!e.match(t))return e}}},{key:"read",value:function(t){this.pos+t>this.length&&(t=this.length-this.pos);var e=this.data.substring(this.pos,this.pos+t);return this.pos+=t,e}},{key:"backup",value:function(){--this.pos}},{key:"readnumber",value:function(){for(var t=/[-+0123456789.eE]/,e="";;){var r=this.readcharoreof();if(null===r||!r.match(t)){var n=parseFloat(e);if(isNaN(n))throw new R.ValueError("invalid number, got "+R._repr("value")+" at position "+this.pos+" with path "+this.stack.join("/"));return n}e+=r}}},{key:"_beginfakeloading",value:function(){var t=this.backrefs.length;return this.backrefs.push(null),t}},{key:"_endfakeloading",value:function(t,e){this.backrefs[t]=e}},{key:"_readescape",value:function(t,e){var r=this.read(e);if(r.length!=e)throw new R.ValueError("broken escape "+R._repr("\\"+t+r)+" at position "+this.pos+" with path "+this.stack.join("/"));var n=parseInt(r,16);if(isNaN(n))throw new R.ValueError("broken escape "+R._repr("\\"+t+r)+" at position "+this.pos+" with path "+this.stack.join("/"));return String.fromCharCode(n)}},{key:"load",value:function(){var t,e=this.readblackchar();switch(e){case"^":return this.backrefs[this.readnumber()];case"n":case"N":return"N"===e&&this.backrefs.push(null),null;case"b":case"B":if("T"===(t=this.readchar()))t=!0;else{if("F"!==t)throw new R.ValueError("wrong value for boolean, expected 'T' or 'F', got "+R._repr(t)+" at position "+this.pos+" with path "+this.stack.join("/"));t=!1}return"B"===e&&this.backrefs.push(t),t;case"i":case"I":case"f":case"F":return t=this.readnumber(),"I"!==e&&"F"!==e||this.backrefs.push(t),t;case"s":case"S":t=[];for(var r=this.readblackchar();;){var n=this.readchar();if(n==r)break;if("\\"==n){var o=this.readchar();"\\"==o?t.push("\\"):"n"==o?t.push("\n"):"r"==o?t.push("\r"):"t"==o?t.push("\t"):"f"==o?t.push("\f"):"b"==o?t.push("\b"):"a"==o?t.push(""):"'"==o?t.push("'"):'"'==o?t.push('"'):"x"==o?t.push(this._readescape("x",2)):"u"==o?t.push(this._readescape("u",4)):"U"==o?t.push(this._readescape("U",8)):t.push("\\"+o)}else t.push(n)}return t=t.join(""),"S"===e&&this.backrefs.push(t),t;case"c":case"C":return t=new R.Color,"C"===e&&this.backrefs.push(t),t._r=this.load(),t._g=this.load(),t._b=this.load(),t._a=this.load(),t;case"x":case"X":var i=this.load(),a=this.load(),u=this.load();return t=new R.Date(i,a,u),"X"===e&&this.backrefs.push(t),t;case"z":case"Z":return(t=new Date).setFullYear(this.load()),t.setDate(1),t.setMonth(this.load()-1),t.setDate(this.load()),t.setHours(this.load()),t.setMinutes(this.load()),t.setSeconds(this.load()),t.setMilliseconds(this.load()/1e3),"Z"===e&&this.backrefs.push(t),t;case"t":case"T":return(t=new R.TimeDelta)._days=this.load(),t._seconds=this.load(),t._microseconds=this.load(),"T"===e&&this.backrefs.push(t),t;case"r":case"R":return t=new R.slice,"R"===e&&this.backrefs.push(t),t.start=this.load(),t.stop=this.load(),t;case"m":case"M":return t=new R.MonthDelta,"M"===e&&this.backrefs.push(t),t._months=this.load(),t;case"l":case"L":for(this.stack.push("list"),t=[],"L"===e&&this.backrefs.push(t);"]"!==(e=this.readblackchar());)this.backup(),t.push(this.load());return this.stack.pop(),t;case"d":case"D":case"e":case"E":if(!R._havemap&&("e"==e||"E"==e))throw new R.ValueError("ordered dictionaries are not supported at position "+this.pos+" with path "+this.stack.join("/"));for(t=R._emptymap(),this.stack.push("d"===e||"D"===e?"dict":"odict"),"D"!==e&&"E"!==e||this.backrefs.push(t);"}"!==(e=this.readblackchar());){this.backup();var s=this.load(),l=this.load();R._setmap(t,s,l)}return this.stack.pop(),t;case"y":case"Y":for(this.stack.push("set"),t=R._makeset(),"Y"===e&&this.backrefs.push(t);"}"!==(e=this.readblackchar());)this.backup(),t.add(this.load());return this.stack.pop(),t;case"o":case"O":var c;"O"===e&&(c=this._beginfakeloading());var h,p=this.load();if(this.stack.push(p),null!==this.registry?void 0===(h=this.registry[p])&&(h=R._registry[p]):h=R._registry[p],void 0===h)throw new R.ValueError("can't load object of type "+R._repr(p)+" at position "+this.pos+" with path "+this.stack.join("/"));if(t=new h,"O"===e&&this._endfakeloading(c,t),t.ul4onload(this),")"!==(e=this.readblackchar()))throw new R.ValueError("object terminator ')' for object of type '"+p+"' expected, got "+R._repr(e)+" at position "+this.pos+" with path "+this.stack.join("/"));return this.stack.pop(),t;default:throw new R.ValueError("unknown typecode "+R._repr(e)+" at position "+this.pos+" with path "+this.stack.join("/"))}}},{key:"loadcontent",value:function(){var e=this;return{next:function(){var t=e.readblackchar();return e.backup(),")"==t?{done:!0}:{done:!1,value:e.load()}}}}}]),r}(),R._rvalidchars=/^[\],:{}\s]*$/,R._rvalidescape=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,R._rvalidtokens=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,R._rvalidbraces=/(?:^|:|,)(?:\s*\[)+/g,R._inherit=function(t,e){return Object.assign(Object.create(t),e)},R._map2object=function(t){if(R._ismap(t)){var r={};return t.forEach(function(t,e){if("string"!=typeof e)throw new R.TypeError("keys must be strings");r[e]=t}),r}return t},R._bound=function(t,e){return t<0?0:e=r.length)return 1;var u=R._cmp(t,e[a],r[a]);if(u)return u}return r.length>e.length?-1:0}}else if((R._isset(e)||R._isul4set(e))&&(R._isset(r)||R._isul4set(r))){for(var s=!1,l=!1,c=_iter(e);;){var h=c.next();if(h.done)break;if(!r.has(h.value)){s=!0;break}}for(var p=_iter(r);;){var _=p.next();if(_.done)break;if(!e.has(_.value)){l=!0;break}}return s?l?null:1:l?-1:0}return R._unorderable(t,e,r)},R._lt=function(t,e){var r=["boolean","number"];if(t&&"function"==typeof t.__lt__)return t.__lt__(e);if(-1!=r.indexOf(M(t))){if(-1!=r.indexOf(M(e)))return t=e.length)return!1;if(!R._eq(t[n],e[n]))return R._lt(t[n],e[n])}return t.length=r.length)return!1;if(!R._eq(e[n],r[n]))return R._lt(e[n],r[n])}return e.length<=r.length}}else if(R._isset(e)||R._isul4set(e)){var o=!1,i=!1;if(R._isset(r)){if(R._isset(r))e.forEach(function(t){r.has(t)||(o=!0)}),r.forEach(function(t){e.has(t)||(i=!0)});else if(R._isul4set(r))for(var a in e.forEach(function(t){r.items[t]||(o=!0)}),r.items)if(!e.has(a)){i=!0;break}}else if(R._isul4set(r)){if(R._isset(r)){for(var u in e.items)if(!r.has(u)){o=!0;break}r.forEach(function(t){e.items[t]||(i=!0)})}else if(R._isul4set(r)){for(var s in e.items)if(!r.items[s]){o=!0;break}for(var l in r.items)if(!e.items[l]){i=!0;break}}}else R._unorderable(operator,e,r);return o?i?null:1:i?-1:0}R._unorderable("<=",e,r)},R._gt=function(e,r){var t=["boolean","number"];if(e&&"function"==typeof e.__gt__)return e.__gt__(r);if(-1!=t.indexOf(M(e))){if(-1!=t.indexOf(M(r)))return rr.getTime()}else if(R._islist(e)){if(R._islist(r)){if(e===r)return!1;for(var n=0;n=r.length)return!0;if(!R._eq(e[n],r[n]))return R._gt(e[n],r[n])}return e.length>r.length}}else if(R._isset(e)||R._isul4set(e)){var o=!1,i=!1;if(R._isset(r))R._isset(r)?(e.forEach(function(t){r.has(t)||(o=!0)}),r.forEach(function(t){e.has(t)||(i=!0)})):R._isul4set(r)&&(e.forEach(function(t){r.items[t]||(o=!0)}),r.forEach(function(t){e.has(t)||(i=!0)}));else if(R._isul4set(r)){if(R._isset(r)){for(var a in e.items)if(!r.has(a)){o=!0;break}r.forEach(function(t){e.items[t]||(i=!0)})}else if(R._isul4set(r)){for(var u in e.items)if(!r.items[u]){o=!0;break}for(var s in r.items)if(!e.items[s]){i=!0;break}}}else R._unorderable(operator,e,r);return o?i?null:1:i?-1:0}R._unorderable(">",e,r)},R._ge=function(r,e){var t=["boolean","number"];if(r&&"function"==typeof r.__ge__)return r.__ge__(e);if(-1!=t.indexOf(M(r))){if(-1!=t.indexOf(M(e)))return e<=r}else if("string"==typeof r){if("string"==typeof e)return e<=r}else if(R._isdatetime(r)){if(R._isdatetime(e))return r.getTime()>=e.getTime()}else if(R._islist(r)){if(R._islist(e)){if(r===e)return!0;for(var n=0;n=e.length)return!0;if(!R._eq(r[n],e[n]))return R._gt(r[n],e[n])}return r.length>=e.length}}else if(R._isset(r)||R._isul4set(r)){var o=!1,i=!1;if(R._isset(e)){if(R._isset(e))r.forEach(function(t){e.has(t)||(o=!0)}),e.forEach(function(t){r.has(t)||(i=!0)});else if(R._isul4set(e))for(var a in r.forEach(function(t){e.items[t]||(o=!0)}),e.items)if(!r.has(a)){i=!0;break}}else if(R._isul4set(e)){if(R._isset(e)){for(var u in r.items)if(!e.has(u)){o=!0;break}e.forEach(function(t,e){r.items[t]||(i=!0)})}else if(R._isul4set(e)){for(var s in r.items)if(!e.items[s]){o=!0;break}for(var l in e.items)if(!r.items[l]){i=!0;break}}}else R._unorderable(operator,r,e);return o?i?null:1:i?-1:0}R._unorderable(">=",r,e)},R._iter=function(t){if("string"==typeof t||R._islist(t))return{index:0,next:function(){return this.index=r.length?{done:!0}:{value:r[this.index++],done:!1}}}}if(R._isset(t)){var e=[];return t.forEach(function(t){e.push(t)}),{index:0,next:function(){return this.index>=e.length?{done:!0}:{value:e[this.index++],done:!1}}}}if(R._isul4set(t))return R._iter(t.items);if(R._isobject(t)){var n=[];for(var o in t)n.push(o);return{index:0,next:function(){return this.index>=n.length?{done:!0}:{value:n[this.index++],done:!1}}}}throw new R.TypeError(R._type(t)+" object is not iterable")},R._str_repr=function(t,e){for(var r="",n=!1,o=!1,i=0;i":"":R._isdate(t)?R._date_repr(t,e):R._isdatetime(t)?R._datetime_repr(t,e):void 0===t?"":"object"===M(t)&&"function"==typeof t.__repr__?t.__repr__():R._islist(t)?R._list_repr(t,e):R._ismap(t)?R._map_repr(t,e):R._isset(t)?R._set_repr(t,e):R._isobject(t)?R._object_repr(t,e):"?"},R._repr=function(t){return R._repr_internal(t,!1)},R._ascii=function(t){return R._repr_internal(t,!0)},R._date_str=function(t){var e=t._date.getFullYear(),r=t._date.getMonth()+1,n=t._date.getDate();return e+"-"+R._lpad(r.toString(),"0",2)+"-"+R._lpad(n.toString(),"0",2)},R._datetime_str=function(t){var e=t.getFullYear(),r=t.getMonth()+1,n=t.getDate(),o=t.getHours(),i=t.getMinutes(),a=t.getSeconds(),u=t.getMilliseconds(),s=e+"-"+R._lpad(r.toString(),"0",2)+"-"+R._lpad(n.toString(),"0",2)+" "+R._lpad(o.toString(),"0",2)+":"+R._lpad(i.toString(),"0",2);return(a||u)&&(s+=":"+R._lpad(a.toString(),"0",2),u&&(s+="."+R._lpad(u.toString(),"0",3)+"000")),s},R._str=function(t){return void 0===t?"":null===t?"":!1===t?"False":!0===t?"True":"string"==typeof t?t:"number"==typeof t?t.toString():R._isdate(t)?R._date_str(t):R._isdatetime(t)?R._datetime_str(t):R._islist(t)?R._list_repr(t):R._isset(t)?R._set_repr(t):R._ismap(t)?R._map_repr(t):"object"===M(t)&&"function"==typeof t.__str__?t.__str__():"object"===M(t)&&"function"==typeof t.__repr__?t.__repr__():R._isobject(t)?R._object_repr(t):"?"},R._bool=function(t){if(null==t||!1===t||0===t||""===t)return!1;if(M(t),"function"==typeof t.__bool__)return t.__bool__();if(R._islist(t))return 0!==t.length;if(R._ismap(t)||R._isset(t))return 0!=t.size;if(R._isobject(t)){for(var e in t)if(t.hasOwnProperty(e))return!0;return!1}return!0},R._int=function(t,e){var r;if(null!==e){if("string"!=typeof t||!R._isint(e))throw new R.TypeError("int() requires a string and an integer");if("NaN"==(r=parseInt(t,e)).toString())throw new R.TypeError("invalid literal for int()");return r}if("string"==typeof t){if("NaN"==(r=parseInt(t)).toString())throw new R.TypeError("invalid literal for int()");return r}if("number"==typeof t)return Math.floor(t);if(!0===t)return 1;if(!1===t)return 0;throw new R.TypeError("int() argument must be a string or a number")},R._float=function(t){if("string"==typeof t)return parseFloat(t);if("number"==typeof t)return t;if(!0===t)return 1;if(!1===t)return 0;throw new R.TypeError("float() argument must be a string or a number")},R._list=function(t){for(var e=R._iter(t),r=[];;){var n=e.next();if(n.done)return r;r.push(n.value)}},R._set=function(t){for(var e=R._iter(t),r=R._emptyset();;){var n=e.next();if(n.done)return r;r.add(n.value)}},R._len=function(t){if("string"==typeof t||R._islist(t))return t.length;if(R._ismap(t)||R._isset(t))return t.size;if(R._isobject(t)){var e=0;for(var r in t)++e;return e}throw new R.TypeError("object of type '"+R._type(t)+"' has no len()")},R._type=function(t){return null===t?"none":!1===t||!0===t?"bool":void 0===t?"undefined":"number"==typeof t?Math.round(t)==t?"int":"float":"function"==typeof t?"function":"function"==typeof t.ul4type?t.ul4type():R.Protocol.get(t).ul4type(t)},R._mod=function(t,e){var r=Math.floor(t/e),n=t-r*e;return 0!==n&&(e<0&&0=^]$/.test(n))throw new R.ValueError("illegal integer format string "+R._repr(e));i=n[1],o=n[0]}else if(1==n.length){if(!/^[<>=^]$/.test(n))throw new R.ValueError("illegal integer format string "+R._repr(e));i=n}var h,p=t<0;switch(p&&(t=-t),l){case"b":h=t.toString(2);break;case"c":if(p||65535"==i)h=R._str_repeat(o,s-h.length)+h;else{var _=s-h.length,f=Math.floor(_/2),d=_-f;h=R._str_repeat(o,f)+h+R._str_repeat(o,d)}return h},R._format=function(t,e,r){if(null==r)r="en";else{var n={de:null,en:null,fr:null,es:null,it:null,da:null,sv:null,nl:null,pt:null,cs:null,sk:null,pl:null,hr:null,sr:null,ro:null,hu:null,tr:null,ru:null,zh:null,ko:null,ja:null};void 0===n[r=r.toLowerCase()]&&void 0===n[r=r.split(/_/)[0]]&&(r="en")}return R._isdate(t)?R._format_datetime(t._date,e,r):R._isdatetime(t)?R._format_datetime(t,e,r):R._isint(t)?R._format_int(t,e,r):!0===t?R._format_int(1,e,r):!1===t?R._format_int(0,e,r):void 0},R._lpad=function(t,e,r){for("number"==typeof t&&(t=t.toString());t.lengththis.args.length){var u=null===t?"expected":t+"() expects";throw new R.ArgumentError(u+" at most "+this.args.length+" positional argument"+(1!=this.args.length?"s":"")+", "+e.length+" given")}}else n.push(e.slice(this.args.length));if(null===this.remkwargs){for(var s in r)if(!this.argNames[s])throw null===t?new R.ArgumentError("an argument named "+R._repr(s)+" isn't supported"):new R.ArgumentError(t+"() doesn't support an argument named "+R._repr(s))}else{var l=R._emptymap();for(var c in r)this.argNames[c]||R._setmap(l,c,r[c]);n.push(l)}return n}},{key:"bindObject",value:function(t,e,r){e=this.bindArray(t,e,r);var n,o={};for(n=0;n"}},{key:"__str__",value:function(){return this.toString()}},{key:"toString",value:function(){for(var t=[],e=0;e=c.getTime()){var h=R.SubAST.prototype._do(t,c);return[o,Math.floor(h.days()/7)+1,R.DateTimeProtocol.weekday(t)]}}}},{key:"week",value:function(t){var e=1=r.length){o="";break}if("\n"===r.charAt(t)){o="";break}--n,++t}return r.substring(e,t)+o}},{key:"line",get:function(){return null===this._line&&this._calculateLineCol(),this._line}},{key:"col",get:function(){return null===this._col&&this._calculateLineCol(),this._col}}]),n}(),R.AST.prototype._ul4onattrs=["template","pos"],R.TextAST=function(t){function r(t,e){return E(this,r),V(this,O(r).call(this,t,e))}return L(r,R.AST),P(r,[{key:"_eval",value:function(t){t.output(this.text)}},{key:"_str",value:function(t){t.push("text "),t.push(R._repr(this.text))}},{key:"_repr",value:function(t){t.push("")}},{key:"text",get:function(){return this.source}}]),r}(),R.IndentAST=function(t){function o(t,e,r){var n;return E(this,o),(n=V(this,O(o).call(this,t,e)))._text=r,n}return L(o,R.TextAST),P(o,[{key:"_eval",value:function(t){for(var e=0;e")}},{key:"text",get:function(){return void 0!==this.template?null===this._text?this.source:this._text:null}}]),o}(),R.LineEndAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.TextAST),P(e,[{key:"_str",value:function(t){t.push("lineend "),t.push(R._repr(this.text))}},{key:"_repr",value:function(t){t.push("")}}]),e}(),R.CodeAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.AST),e}(),R.ConstAST=function(t){function o(t,e,r){var n;return E(this,o),(n=V(this,O(o).call(this,t,e))).value=r,n}return L(o,R.CodeAST),P(o,[{key:"_repr",value:function(t){t.push("")}},{key:"_eval",value:function(t){return this.value}}]),o}(),R.ConstAST.prototype._ul4onattrs=R.CodeAST.prototype._ul4onattrs.concat(["value"]),R.ItemArgBase=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.CodeAST),P(e,[{key:"_handle_eval_list",value:function(t,e){try{return this._eval_list(t,e)}catch(t){throw t instanceof R.InternalException||t instanceof R.LocationError||this._decorate_exception(t),t}}},{key:"_handle_eval_set",value:function(t,e){try{return this._eval_set(t,e)}catch(t){throw t instanceof R.InternalException||t instanceof R.LocationError||this._decorate_exception(t),t}}},{key:"_handle_eval_dict",value:function(t,e){try{return this._eval_dict(t,e)}catch(t){throw t instanceof R.InternalException||t instanceof R.LocationError||this._decorate_exception(t),t}}},{key:"_handle_eval_call",value:function(t,e,r){try{return this._eval_call(t,e,r)}catch(t){throw t instanceof R.InternalException||t instanceof R.LocationError||this._decorate_exception(t),t}}}]),e}(),R.SeqItemAST=function(t){function o(t,e,r){var n;return E(this,o),(n=V(this,O(o).call(this,t,e))).value=r,n}return L(o,R.ItemArgBase),P(o,[{key:"_repr",value:function(t){t.push("")}},{key:"_eval_list",value:function(t,e){var r=this.value._handle_eval(t);e.push(r)}},{key:"_eval_set",value:function(t,e){var r=this.value._handle_eval(t);e.add(r)}}]),o}(),R.SeqItemAST.prototype._ul4onattrs=R.ItemArgBase.prototype._ul4onattrs.concat(["value"]),R.UnpackSeqItemAST=function(t){function o(t,e,r){var n;return E(this,o),(n=V(this,O(o).call(this,t,e))).value=r,n}return L(o,R.ItemArgBase),P(o,[{key:"_repr",value:function(t){t.push("")}},{key:"_eval_list",value:function(t,e){for(var r=this.value._handle_eval(t),n=R._iter(r);;){var o=n.next();if(o.done)break;e.push(o.value)}}},{key:"_eval_set",value:function(t,e){for(var r=this.value._handle_eval(t),n=R._iter(r);;){var o=n.next();if(o.done)break;e.add(o.value)}}}]),o}(),R.UnpackSeqItemAST.prototype._ul4onattrs=R.ItemArgBase.prototype._ul4onattrs.concat(["value"]),R.DictItemAST=function(t){function i(t,e,r,n){var o;return E(this,i),(o=V(this,O(i).call(this,t,e))).key=r,o.value=n,o}return L(i,R.ItemArgBase),P(i,[{key:"_repr",value:function(t){t.push("")}},{key:"_eval_dict",value:function(t,e){var r=this.key._handle_eval(t),n=this.value._handle_eval(t);R._setmap(e,r,n)}}]),i}(),R.DictItemAST.prototype._ul4onattrs=R.ItemArgBase.prototype._ul4onattrs.concat(["key","value"]),R.UnpackDictItemAST=function(t){function o(t,e,r){var n;return E(this,o),(n=V(this,O(o).call(this,t,e))).item=r,n}return L(o,R.ItemArgBase),P(o,[{key:"_repr",value:function(t){t.push("")}},{key:"_eval_dict",value:function(t,r){var e=this.item._handle_eval(t);if(R._islist(e))for(var n=0;n")}},{key:"_eval_call",value:function(t,e,r){var n=this.value._handle_eval(t);e.push(n)}}]),o}(),R.PosArgAST.prototype._ul4onattrs=R.ItemArgBase.prototype._ul4onattrs.concat(["value"]),R.KeywordArgAST=function(t){function i(t,e,r,n){var o;return E(this,i),(o=V(this,O(i).call(this,t,e))).name=r,o.value=n,o}return L(i,R.ItemArgBase),P(i,[{key:"_repr",value:function(t){t.push("")}},{key:"_eval_call",value:function(t,e,r){if(r.hasOwnProperty(this.name))throw new R.ArgumentError("duplicate keyword argument "+this.name);var n=this.value._handle_eval(t);r[this.name]=n}}]),i}(),R.KeywordArgAST.prototype._ul4onattrs=R.ItemArgBase.prototype._ul4onattrs.concat(["name","value"]),R.UnpackListArgAST=function(t){function o(t,e,r){var n;return E(this,o),(n=V(this,O(o).call(this,t,e))).item=r,n}return L(o,R.ItemArgBase),P(o,[{key:"_repr",value:function(t){t.push("")}},{key:"_eval_call",value:function(t,e,r){var n=this.item._handle_eval(t);e.push.apply(e,N(n))}}]),o}(),R.UnpackListArgAST.prototype._ul4onattrs=R.ItemArgBase.prototype._ul4onattrs.concat(["item"]),R.UnpackDictArgAST=function(t){function o(t,e,r){var n;return E(this,o),(n=V(this,O(o).call(this,t,e))).item=r,n}return L(o,R.ItemArgBase),P(o,[{key:"_repr",value:function(t){t.push("")}},{key:"_eval_call",value:function(t,e,r){var n=this.item._handle_eval(t);if(R._islist(n))for(var o=0;o")}},{key:"_eval",value:function(t){for(var e=[],r=0;r")}},{key:"_eval",value:function(t){for(var e=this.container._handle_eval(t),r=t.inheritvars(),n=[],o=R._iter(e);;){var i=o.next();if(i.done)break;for(var a=R._unpackvar(this.varname,i.value),u=0;u")}},{key:"_eval",value:function(t){for(var e=R._emptyset(),r=0;r")}},{key:"_eval",value:function(t){for(var e=this.container._handle_eval(t),r=t.inheritvars(),n=R._emptyset(),o=R._iter(e);;){var i=o.next();if(i.done)break;for(var a=R._unpackvar(this.varname,i.value),u=0;u")}},{key:"_eval",value:function(t){for(var e=R._emptymap(),r=0;r")}},{key:"_eval",value:function(t){for(var e=this.container._handle_eval(t),r=t.inheritvars(),n=R._emptymap(),o=R._iter(e);;){var i=o.next();if(i.done)break;for(var a=R._unpackvar(this.varname,i.value),u=0;u")}},{key:"_eval",value:function(t){var e=this.container._handle_eval(t),a=R._iter(e),u=t.inheritvars(),s=this;return{next:function(){for(;;){var t=a.next();if(t.done)return t;for(var e=R._unpackvar(s.varname,t.value),r=0;r")}},{key:"_eval",value:function(t){return this._get(t,this.name)}},{key:"_eval_set",value:function(t,e){this._set(t,this.name,e)}},{key:"_eval_modify",value:function(t,e,r){this._modify(t,e,this.name,r)}},{key:"_get",value:function(t,e){var r=t.get(e);return void 0===r&&(r=R.functions[e]),r}},{key:"_set",value:function(t,e,r){t.set(e,r)}},{key:"_modify",value:function(t,e,r,n){var o=e._ido(t.get(r),n);t.set(r,o)}}]),o}(),R.VarAST.prototype._ul4onattrs=R.CodeAST.prototype._ul4onattrs.concat(["name"]),R.UnaryAST=function(t){function o(t,e,r){var n;return E(this,o),(n=V(this,O(o).call(this,t,e))).obj=r,n}return L(o,R.CodeAST),P(o,[{key:"_repr",value:function(t){t.push("<"),t.push(this.constructor.name),t.push(" obj="),this.obj._repr(t),t.push(">")}},{key:"_eval",value:function(t){var e=this.obj._handle_eval(t);return this._do(e)}}]),o}(),R.UnaryAST.prototype._ul4onattrs=R.CodeAST.prototype._ul4onattrs.concat(["obj"]),R.NegAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.UnaryAST),P(e,[{key:"_do",value:function(t){return null!==t&&"function"==typeof t.__neg__?t.__neg__():-t}}]),e}(),R.BitNotAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.UnaryAST),P(e,[{key:"_do",value:function(t){return-t-1}}]),e}(),R.NotAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.UnaryAST),P(e,[{key:"_do",value:function(t){return!R._bool(t)}}]),e}(),R.IfAST=function(t){function a(t,e,r,n,o){var i;return E(this,a),(i=V(this,O(a).call(this,t,e))).objif=r,i.objcond=n,i.objelse=o,i}return L(a,R.CodeAST),P(a,[{key:"_repr",value:function(t){t.push("<"),t.push(this.constructor.name),t.push(1),t.push("objif="),this.objif._repr(t),t.push(0),t.push("objcond="),this.objcond._repr(t),t.push(0),t.push("objelse="),this.objelse._repr(t),t.push(-1),t.push(">")}},{key:"_eval",value:function(t){var e=this.objcond._handle_eval(t);return R._bool(e)?this.objif._handle_eval(t):this.objelse._handle_eval(t)}}]),a}(),R.IfAST.prototype._ul4onattrs=R.CodeAST.prototype._ul4onattrs.concat(["objif","objcond","objelse"]),R.ReturnAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.UnaryAST),P(e,[{key:"_eval",value:function(t){var e=this.obj._handle_eval(t);throw new R.ReturnException(e)}},{key:"_str",value:function(t){t.push("return "),this.obj._str(t)}}]),e}(),R.PrintAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.UnaryAST),P(e,[{key:"_eval",value:function(t){var e=this.obj._handle_eval(t),r=R._str(e);t.output(r)}},{key:"_str",value:function(t){t.push("print "),this.obj._str(t)}}]),e}(),R.PrintXAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.UnaryAST),P(e,[{key:"_eval",value:function(t){var e=this.obj._handle_eval(t),r=R._xmlescape(e);t.output(r)}},{key:"_str",value:function(t){t.push("printx "),this.obj._str(t)}}]),e}(),R.BinaryAST=function(t){function i(t,e,r,n){var o;return E(this,i),(o=V(this,O(i).call(this,t,e))).obj1=r,o.obj2=n,o}return L(i,R.CodeAST),P(i,[{key:"_repr",value:function(t){t.push("<"),t.push(this.constructor.name),t.push(" obj1="),this.obj1._repr(t),t.push(" obj2="),this.obj2._repr(t),t.push(">")}},{key:"_eval",value:function(t){var e=this.obj1._handle_eval(t),r=this.obj2._handle_eval(t);return this._do(e,r)}}]),i}(),R.BinaryAST.prototype._ul4onattrs=R.CodeAST.prototype._ul4onattrs.concat(["obj1","obj2"]),R.ItemAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){return this._get(t,e)}},{key:"_eval_set",value:function(t,e){var r=this.obj1._handle_eval(t),n=this.obj2._handle_eval(t);this._set(r,n,e)}},{key:"_eval_modify",value:function(t,e,r){var n=this.obj1._handle_eval(t),o=this.obj2._handle_eval(t);this._modify(e,n,o,r)}},{key:"_get",value:function(t,e){if("string"==typeof t||R._islist(t)){if(e instanceof R.slice){var r=e.start,n=e.stop;return null==r&&(r=0),null==n&&(n=t.length),t.slice(r,n)}var o=e;if(e<0&&(e+=t.length),e<0||e>=t.length)throw new R.IndexError(t,o);return t[e]}if(t&&"function"==typeof t.__getitem__)return t.__getitem__(e);if(R._ismap(t))return t.get(e);throw new R.TypeError(R._type(t)+" object is not subscriptable")}},{key:"_set",value:function(t,e,r){if(R._islist(t))if(e instanceof R.slice){var n=e.start,o=e.stop;null===n?n=0:n<0&&(n+=t.length),n<0?n=0:n>t.length&&(n=t.length),null===o?o=t.length:o<0&&(o+=t.length),o<0?o=0:o>t.length&&(o=t.length),o=t.length)throw new R.IndexError(t,u);t[e]=r}else if(t&&"function"==typeof t.__setitem__)t.__setitem__(e,r);else if(R._ismap(t))t.set(e,r);else{if(!R._isobject(t))throw new R.NotSubscriptableError(t);t[e]=r}}},{key:"_modify",value:function(t,e,r,n){this._set(e,r,t._ido(this._get(e,r),n))}}]),e}(),R.IsAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){return t===e}}]),e}(),R.IsNotAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){return t!==e}}]),e}(),R.EQAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){return R._eq(t,e)}}]),e}(),R.NEAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){return R._ne(t,e)}}]),e}(),R.LTAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){return R._lt(t,e)}}]),e}(),R.LEAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){return R._le(t,e)}}]),e}(),R.GTAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){return R._gt(t,e)}}]),e}(),R.GEAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){return R._ge(t,e)}}]),e}(),R.ContainsAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){if("string"==typeof t&&"string"==typeof e)return-1!==e.indexOf(t);if(R._islist(e))return-1!==e.indexOf(t);if(e&&"function"==typeof e.__contains__)return e.__contains__(t);if(R._ismap(e)||R._isset(e))return e.has(t);if(R._isobject(e)){for(var r in e)if(r===t)return!0;return!1}if(R._iscolor(e))return e._r===t||e._g===t||e._b===t||e._a===t;throw new R.TypeError(R._type(e)+" object is not iterable")}}]),e}(),R.NotContainsAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){return!R.ContainsAST.prototype._do(t,e)}}]),e}(),R.AddAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){if(t&&"function"==typeof t.__add__)return t.__add__(e);if(e&&"function"==typeof e.__radd__)return e.__radd__(t);if(null===t||null===e)throw new R.TypeError(R._type(this.obj1)+" + "+R._type(this.obj2)+" is not supported");return R._islist(t)&&R._islist(e)?N(t).concat(N(e)):t+e}},{key:"_ido",value:function(t,e){return R._islist(t)&&R._islist(e)?(R.ListProtocol.append(t,e),t):this._do(t,e)}}]),e}(),R.SubAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BinaryAST),P(e,[{key:"_do",value:function(t,e){if(t&&"function"==typeof t.__sub__)return t.__sub__(e);if(e&&"function"==typeof e.__rsub__)return e.__rsub__(t);if(R._isdate(t)&&R._isdate(e))return this._date_sub(t,e);if(R._isdatetime(t)&&R._isdatetime(e))return this._datetime_sub(t,e);if(null===t||null===e)throw new R.TypeError(R._type(this.obj1)+" - "+R._type(this.obj2)+" is not supported");return t-e}},{key:"_date_sub",value:function(t,e){return this._datetime_sub(t._date,e._date)}},{key:"_datetime_sub",value:function(t,e){var r=t")}},{key:"_eval",value:function(t){var e=this.obj._handle_eval(t);return this._get(e,this.attrname)}},{key:"_eval_set",value:function(t,e){var r=this.obj._handle_eval(t);this._set(r,this.attrname,e)}},{key:"_eval_modify",value:function(t,e,r){var n=this.obj._handle_eval(t);this._modify(e,n,this.attrname,r)}},{key:"_get",value:function(e,t){var r=R.Protocol.get(e);try{return r.getattr(e,t)}catch(t){if(t instanceof R.AttributeError&&t.obj===e)return;throw t}}},{key:"_set",value:function(t,e,r){if("object"===M(t)&&"function"==typeof t.__setattr__)t.__setattr__(e,r);else if(R._ismap(t))t.set(e,r);else{if(!R._isobject(t))throw new R.TypeError(R._type(t)+" object has no writable attributes");t[e]=r}}},{key:"_modify",value:function(t,e,r,n){var o=this._get(e,r),i=t._ido(o,n);this._set(e,r,i)}}]),i}(),R.AttrAST.prototype._ul4onattrs=R.CodeAST.prototype._ul4onattrs.concat(["obj","attrname"]),R.CallAST=function(t){function i(t,e,r,n){var o;return E(this,i),(o=V(this,O(i).call(this,t,e))).obj=r,o.args=n,o}return L(i,R.CodeAST),P(i,[{key:"_repr",value:function(t){t.push("")}},{key:"_makeargs",value:function(t){for(var e=[],r={},n=0;n")}},{key:"_str",value:function(t){t.push("render "),t.push(this.tag.code.replace(/\r?\n/g," ")),null!==this.indent&&(t.push(" with indent "),t.push(R._repr(this.indent.text)))}},{key:"_handle_eval",value:function(t){var e=t.withindent(null!==this.indent?this.indent.text:null),r=this.obj._handle_eval(e),n=this._makeargs(e);this._handle_additional_arguments(e,n);try{return R._callrender(e,r,n.args,n.kwargs)}catch(t){throw this._decorate_exception(t),t}}},{key:"_handle_additional_arguments",value:function(t,e){}}]),i}(),R.RenderAST.prototype._ul4onattrs=R.CallAST.prototype._ul4onattrs.concat(["indent"]),R.RenderAST.prototype._reprname="RenderAST",R.RenderXAST=function(t){function r(){return E(this,r),V(this,O(r).apply(this,arguments))}return L(r,R.RenderAST),P(r,[{key:"_handle_eval",value:function(t){t.escapes.push(R._xmlescape);var e=null;try{e=I(O(r.prototype),"_handle_eval",this).call(this,t)}finally{t.escapes.splice(t.escapes.length-1,1)}return e}}]),r}(),R.RenderBlockAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.RenderAST),P(e,[{key:"_handle_additional_arguments",value:function(t,e){if(e.kwargs.hasOwnProperty("content"))throw new R.ArgumentError("duplicate keyword argument content");var r=new R.TemplateClosure(this.content,this.content.signature,t.vars);e.kwargs.content=r}}]),e}(),R.RenderBlockAST.prototype._ul4onattrs=R.RenderAST.prototype._ul4onattrs.concat(["content"]),R.RenderBlocksAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.RenderAST),P(e,[{key:"_handle_additional_arguments",value:function(t,e){var r=t.inheritvars();for(var n in R.BlockAST.prototype._eval.call(this,r),r.vars)if(r.vars.hasOwnProperty(n)){if(n in e.kwargs)throw new R.ArgumentError("duplicate keyword argument "+n);e.kwargs[n]=r.get(n)}}}]),e}(),R.RenderBlocksAST.prototype._ul4onattrs=R.RenderAST.prototype._ul4onattrs.concat(["content"]),R.slice=function(t){function n(t,e){var r;return E(this,n),(r=V(this,O(n).call(this))).start=t,r.stop=e,r}return L(n,R.Proto),P(n,[{key:"of",value:function(t){var e=this.start||0,r=null===this.stop?t.length:this.stop;return t.slice(e,r)}},{key:"__repr__",value:function(){return"slice("+R._repr(this.start)+", "+R._repr(this.stop)+", None)"}},{key:"__getattr__",value:function(t){switch(t){case"start":return this.start;case"stop":return this.stop;default:throw new R.AttributeError(this,t)}}}]),n}(),R.SliceAST=function(t){function i(t,e,r,n){var o;return E(this,i),(o=V(this,O(i).call(this,t,e))).index1=r,o.index2=n,o}return L(i,R.CodeAST),P(i,[{key:"_repr",value:function(t){t.push("")}},{key:"_eval",value:function(t){var e=null!==this.index1?this.index1._handle_eval(t):null,r=null!==this.index2?this.index2._handle_eval(t):null;return new R.slice(e,r)}}]),i}(),R.SliceAST.prototype._ul4onattrs=R.CodeAST.prototype._ul4onattrs.concat(["index1","index2"]),R.SetVarAST=function(t){function i(t,e,r,n){var o;return E(this,i),(o=V(this,O(i).call(this,t,e))).lvalue=r,o.value=n,o}return L(i,R.CodeAST),P(i,[{key:"_repr",value:function(t){t.push("<"),t.push(this.constructor.name),t.push(" lvalue="),t.push(R._repr(this.lvalue)),t.push(" value="),this.value._repr(t),t.push(">")}},{key:"_eval",value:function(t){for(var e=this.value._handle_eval(t),r=R._unpackvar(this.lvalue,e),n=0;n")}},{key:"_str_varname",value:function(t,e){if(R._islist(e)){t.push("(");for(var r=0;r")}},{key:"_str",value:function(t){t.push("while "),this.condition._repr(t),t.push(":"),t.push(1),R.BlockAST.prototype._str.call(this,t),t.push(-1)}},{key:"_eval",value:function(t){for(;;){var e=this.condition._handle_eval(t);if(!R._bool(e))break;try{I(O(o.prototype),"_eval",this).call(this,t)}catch(t){if(t instanceof R.BreakException)break;if(!(t instanceof R.ContinueException))throw t}}}}]),o}(),R.WhileBlockAST.prototype._ul4onattrs=R.BlockAST.prototype._ul4onattrs.concat(["condition"]),R.BreakAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.CodeAST),P(e,[{key:"_eval",value:function(t){throw new R.BreakException}},{key:"_str",value:function(t){t.push("break"),t.push(0)}},{key:"_repr",value:function(t){t.push("")}}]),e}(),R.ContinueAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.CodeAST),P(e,[{key:"_eval",value:function(t){throw new R.ContinueException}},{key:"_str",value:function(t){t.push("continue"),t.push(0)}},{key:"_repr",value:function(t){t.push("")}}]),e}(),R.CondBlockAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BlockAST),P(e,[{key:"_eval",value:function(t){for(var e=0;e")}},{key:"_str",value:function(t){t.push(this._strname),t.push(" "),this.condition._str(t),t.push(":"),t.push(1),R.BlockAST.prototype._str.call(this,t),t.push(-1)}},{key:"_execute",value:function(t){var e=this.condition._handle_eval(t);return R._bool(e)}}]),o}(),R.ConditionalBlockAST.prototype._ul4onattrs=R.BlockAST.prototype._ul4onattrs.concat(["condition"]),R.IfBlockAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.ConditionalBlockAST),e}(),R.IfBlockAST.prototype._strname="if",R.ElIfBlockAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.ConditionalBlockAST),e}(),R.ElIfBlockAST.prototype._strname="else if",R.ElseBlockAST=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,R.BlockAST),P(e,[{key:"_repr",value:function(t){t.push("")}},{key:"_str",value:function(t){t.push("else:"),t.push(1),R.BlockAST.prototype._str.call(this,t),t.push(-1)}},{key:"_execute",value:function(t){return!0}}]),e}(),R.Template=function(t){function l(t,e,r,n,o,i,a,u){var s;return E(this,l),(s=V(this,O(l).call(this,t,e)))._source=r,s.name=n,s.whitespace=o,s.startdelim=i,s.enddelim=a,s.docpos=null,s.signature=u,s._asts=null,s._ul4_callsignature=u,s._ul4_rendersignature=u,s.parenttemplate=null,s}return L(l,R.BlockAST),P(l,[{key:"__getattr__",value:function(t){var r=this;switch(t){case"content":return this.content;case"source":return this.source;case"name":return this.name;case"whitespace":return this.whitespace;case"startdelim":return this.startdelim;case"enddelim":return this.enddelim;case"doc":return this.doc();case"signature":return this.signature;case"parenttemplate":return this.parenttemplate;case"render":var e=function(t,e){r._renderbound(t,e)};return R.expose(e,this.signature,{needscontext:!0,needsobject:!0}),e;case"renders":var n=function(t,e){return r._rendersbound(t,e)};return R.expose(n,this.signature,{needscontext:!0,needsobject:!0}),n;default:return I(O(l.prototype),"__getattr__",this).call(this,t)}}},{key:"ul4ondump",value:function(t){var e;if(t.dump(R.version),t.dump(this.name),t.dump(this._source),t.dump(this.whitespace),t.dump(this.startdelim),t.dump(this.enddelim),t.dump(this.docpos),t.dump(this.parenttemplate),null===this.signature||this.signature instanceof R.SignatureAST)e=this.signature;else{e=[];for(var r=0;r"!==this.enddelim&&(t.push(" enddelim="),t.push(R._repr(this.enddelim))),t.push(">")}},{key:"_str",value:function(t){t.push("def "),t.push(this.name?this.name:"unnamed"),t.push(":"),t.push(1),R.BlockAST.prototype._str.call(this,t),t.push(-1)}},{key:"_renderbound",value:function(t,e){var r=t.clone();r.vars=e;try{R.BlockAST.prototype._eval.call(this,r)}catch(t){if(!(t instanceof R.ReturnException))throw t}}},{key:"__render__",value:function(t,e){this._renderbound(t,e)}},{key:"render",value:function(t,e){this._renderbound(t,e)}},{key:"_rendersbound",value:function(t,e){var r=t.replaceoutput();return this._renderbound(r,e),r.getoutput()}},{key:"renders",value:function(t){t=t||{};var e=new R.Context;return null!==this.signature&&(t=this.signature.bindObject(this.name,[],t)),this._rendersbound(e,t)}},{key:"doc",value:function(){return null!=this.docpos?this.docpos.of(this._source):null}},{key:"_callbound",value:function(t,e){var r=t.clone();r.vars=e;try{R.BlockAST.prototype._eval.call(this,r)}catch(t){if(t instanceof R.ReturnException)return t.result;throw t}return null}},{key:"call",value:function(t){t=t||{};var e=new R.Context;return null!==this.signature&&(t=this.signature.bindObject(this.name,[],t)),this._callbound(e,t)}},{key:"__call__",value:function(t,e){return this._callbound(t,e)}},{key:"ul4type",value:function(){return"template"}}]),l}(),R.Template.prototype._ul4_callneedsobject=!0,R.Template.prototype._ul4_callneedscontext=!0,R.Template.prototype._ul4_renderneedsobject=!0,R.Template.prototype._ul4_renderneedscontext=!0,R.SignatureAST=function(t){function o(t,e){var r;return E(this,o),(r=V(this,O(o).call(this,t,e))).params=[],r}return L(o,R.CodeAST),P(o,[{key:"ul4ondump",value:function(t){I(O(o.prototype),"ul4ondump",this).call(this,t);for(var e=[],r=0;r")}}]),o}(),R.TemplateClosure=function(t){function o(t,e,r){var n;return E(this,o),(n=V(this,O(o).call(this))).template=t,n.signature=e,n.vars=r,n._ul4_callsignature=e,n._ul4_rendersignature=e,n.name=t.name,n.tag=t.tag,n.endtag=t.endtag,n._source=t._source,n.startdelim=t.startdelim,n.enddelim=t.enddelim,n.docpos=t.docpos,n.content=t.content,n}return L(o,R.Proto),P(o,[{key:"__render__",value:function(t,e){this.template._renderbound(t,R._inherit(this.vars,e))}},{key:"render",value:function(t,e){this.template._renderbound(t,R._inherit(this.vars,e))}},{key:"__call__",value:function(t,e){return this.template._callbound(t,R._inherit(this.vars,e))}},{key:"_renderbound",value:function(t,e){this.template._renderbound(t,R._inherit(this.vars,e))}},{key:"_rendersbound",value:function(t,e){return this.template._rendersbound(t,R._inherit(this.vars,e))}},{key:"__getattr__",value:function(t){var r=this;switch(t){case"render":var e=function(t,e){r._renderbound(t,e)};return R.expose(e,this.signature,{needscontext:!0,needsobject:!0}),e;case"renders":var n=function(t,e){return r._rendersbound(t,e)};return R.expose(n,this.signature,{needscontext:!0,needsobject:!0}),n;case"signature":return this.signature;default:return this.template.__getattr__(t)}}},{key:"ul4type",value:function(){return"template"}}]),o}(),R.TemplateClosure.prototype._ul4_callneedsobject=!0,R.TemplateClosure.prototype._ul4_callneedscontext=!0,R.TemplateClosure.prototype._ul4_renderneedsobject=!0,R.TemplateClosure.prototype._ul4_renderneedscontext=!0,R._rgb=function(t,e,r,n){return new this.Color(255*t,255*e,255*r,255*n)},R._xmlescape=function(t){return t=(t=(t=(t=(t=(t=R._str(t)).replace(/&/g,"&")).replace(//g,">")).replace(/'/g,"'")).replace(/"/g,""")},R._csv=function(t){return null===t?"":("string"!=typeof t&&(t=R._repr(t)),-1===t.indexOf(",")&&-1===t.indexOf('"')&&-1===t.indexOf("\n")||(t='"'+t.replace(/"/g,'""')+'"'),t)},R._chr=function(t){if("number"!=typeof t)throw new R.TypeError("chr() requires an int");return String.fromCharCode(t)},R._ord=function(t){if("string"!=typeof t||1!=t.length)throw new R.TypeError("ord() requires a string of length 1");return t.charCodeAt(0)},R._hex=function(t){if("number"!=typeof t)throw new R.TypeError("hex() requires an int");return t<0?"-0x"+t.toString(16).substr(1):"0x"+t.toString(16)},R._oct=function(t){if("number"!=typeof t)throw new R.TypeError("oct() requires an int");return t<0?"-0o"+t.toString(8).substr(1):"0o"+t.toString(8)},R._bin=function(t){if("number"!=typeof t)throw new R.TypeError("bin() requires an int");return t<0?"-0b"+t.toString(2).substr(1):"0b"+t.toString(2)},R._min=function(t){if(0==t.length)throw new R.ArgumentError("min() requires at least 1 argument, 0 given");1==t.length&&(t=t[0]);for(var e,r=R._iter(t),n=!0;;){var o=r.next();if(o.done){if(n)throw new R.ValueError("min() argument is an empty sequence!");return e}(n||o.valuee)&&(e=o.value),n=!1}},R._sum=function(t){for(var e=1",t,e)}:function(t,e){return R._cmp("<=>",t,e)},i=R._list(e);return i.sort(o),i}for(var a=[],u=0,s=R._iter(e);;++u){var l=s.next();if(l.done)break;var c=R._call(t,r,[l.value],{});a.push([c,n?-u:u,l.value])}cmp=function(t,e){var r=R._cmp("<=>",t[0],e[0]);return r||(r=R._cmp("<=>",t[1],e[1])),n?-r:r},a.sort(cmp);for(var h=[],p=0;p=a?{done:!0}:{value:e+this.index++*n,done:!1}}}},R._slice=function(t){var e,r,n,o;if(t.length<2)throw new R.ArgumentError("required slice() argument missing");if(4= 0");if(n<0)throw new R.ValueError("slice() requires a stop argument >= 0");if(o<=0)throw new R.ValueError("slice() requires a step argument > 0");var i=r,a=0,u=R._iter(e);return{next:function(){for(var t;at.length||nt.length+1&&(o=t.length+1),o}r=R._bound(r,t.length),n=R._bound(n,t.length);var i=0;if(R._islist(t)){for(var a=r;an);)++i,u+=e.length;return i},R._find=function(t,e){var r=2t._date;R._unorderable(">",this,t)}},{key:"__ge__",value:function(t){if(t instanceof R.Date)return this._date>=t._date;R._unorderable(">=",this,t)}},{key:"year",value:function(){return this._date.getFullYear()}},{key:"month",value:function(){return this._date.getMonth()+1}},{key:"day",value:function(){return this._date.getDate()}},{key:"ul4type",value:function(){return"date"}}]),o}(),R.TimeDelta=function(t){function a(){var t,e=0t._days:this._seconds!=t._seconds?this._seconds>t._seconds:this._microseconds>t._microseconds;R._unorderable(">",this,t)}},{key:"__ge__",value:function(t){if(t instanceof R.TimeDelta)return this._days!=t._days?this._days>t._days:this._seconds!=t._seconds?this._seconds>t._seconds:this._microseconds>=t._microseconds;R._unorderable(">=",this,t)}},{key:"__neg__",value:function(){return new R.TimeDelta(-this._days,-this._seconds,-this._microseconds)}},{key:"adddate",value:function(t,e){var r=t._date.getFullYear(),n=t._date.getMonth(),o=t._date.getDate()+e;return new R.Date(r,n,o)}},{key:"_adddatetime",value:function(t,e,r,n){var o=t.getFullYear(),i=t.getMonth(),a=t.getDate()+e,u=t.getHours(),s=t.getMinutes(),l=t.getSeconds()+r,c=t.getMilliseconds()+n/1e3;return new Date(o,i,a,u,s,l,c)}},{key:"__add__",value:function(t){if(t instanceof R.TimeDelta)return new R.TimeDelta(this._days+t._days,this._seconds+t._seconds,this._microseconds+t._microseconds);if(R._isdate(t))return this._adddate(t,this._days);if(R._isdatetime(t))return this._adddatetime(t,this._days,this._seconds,this._microseconds);throw new R.TypeError(R._type(this)+" + "+R._type(t)+" not supported")}},{key:"__radd__",value:function(t){if(R._isdate(t))return this._adddate(t,this._days);if(R._isdatetime(t))return this._adddatetime(t,this._days,this._seconds,this._microseconds);throw new R.TypeError(R._type(this)+" + "+R._type(t)+" not supported")}},{key:"__sub__",value:function(t){if(t instanceof R.TimeDelta)return new R.TimeDelta(this._days-t._days,this._seconds-t._seconds,this._microseconds-t._microseconds);throw new R.TypeError(R._type(this)+" - "+R._type(t)+" not supported")}},{key:"__rsub__",value:function(t){if(R._isdate(t))return this._adddate(t,-this._days);if(R._isdatetime(t))return this._adddatetime(t,-this._days,-this._seconds,-this._microseconds);throw new R.TypeError(R._type(this)+" - "+R._type(t)+" not supported")}},{key:"__mul__",value:function(t){if("number"==typeof t)return new R.TimeDelta(this._days*t,this._seconds*t,this._microseconds*t);throw new R.TypeError(R._type(this)+" * "+R._type(t)+" not supported")}},{key:"__rmul__",value:function(t){if("number"==typeof t)return new R.TimeDelta(this._days*t,this._seconds*t,this._microseconds*t);throw new R.TypeError(R._type(this)+" * "+R._type(t)+" not supported")}},{key:"__truediv__",value:function(t){if("number"==typeof t)return new R.TimeDelta(this._days/t,this._seconds/t,this._microseconds/t);if(t instanceof R.TimeDelta){var e=this._days,r=t._days,n=this._seconds||t._seconds,o=this._microseconds||t._microseconds;return(n||o)&&(e=86400*e+this._seconds,r=86400*r+t._seconds,o&&(e=1e6*e+this._microseconds,r=1e6*r+t._microseconds)),e/r}throw new R.TypeError(R._type(this)+" / "+R._type(t)+" not supported")}},{key:"__getattr__",value:function(t){var e=this;switch(t){case"days":var r=function(){return e._days};return R.expose(r,[]),r;case"seconds":var n=function(){return e._seconds};return R.expose(n,[]),n;case"microseconds":var o=function(){return e._microseconds};return R.expose(o,[]),o;default:throw new R.AttributeError(this,t)}}},{key:"days",value:function(){return this._days}},{key:"seconds",value:function(){return this._seconds}},{key:"microseconds",value:function(){return this._microseconds}},{key:"ul4type",value:function(){return"timedelta"}}]),a}(),R.MonthDelta=function(t){function r(){var t,e=0t._months;R._unorderable(">",this,t)}},{key:"__ge__",value:function(t){if(t instanceof R.MonthDelta)return this._months>=t._months;R._unorderable(">=",this,t)}},{key:"__neg__",value:function(){return new R.MonthDelta(-this._months)}},{key:"_adddate",value:function(t,e){var r=this._adddatetime(t._date,e);return new R.Date(r.getFullYear(),r.getMonth()+1,r.getDate())}},{key:"_adddatetime",value:function(t,e){for(var r=t.getFullYear(),n=t.getMonth()+e,o=t.getDate(),i=t.getHours(),a=t.getMinutes(),u=t.getSeconds(),s=t.getMilliseconds();;){var l=new Date(r,n,1,i,a,u,s).getMonth(),c=new Date(r,n,o,i,a,u,s);if(c.getMonth()===l)return c;--o}}},{key:"__add__",value:function(t){if(R._ismonthdelta(t))return new R.MonthDelta(this._months+t._months);if(R._isdate(t))return this._adddate(t,this._months);if(R._isdatetime(t))return this._adddatetime(t,this._months);throw new R.ArgumentError(R._type(this)+" + "+R._type(t)+" not supported")}},{key:"__radd__",value:function(t){if(R._isdate(t))return this._adddate(t,this._months);if(R._isdatetime(t))return this._adddatetime(t,this._months);throw new R.ArgumentError(R._type(this)+" + "+R._type(t)+" not supported")}},{key:"__sub__",value:function(t){if(R._ismonthdelta(t))return new R.MonthDelta(this._months-t._months);throw new R.ArgumentError(R._type(this)+" - "+R._type(t)+" not supported")}},{key:"__rsub__",value:function(t){if(R._isdate(t))return this._adddate(t,-this._months);if(R._isdatetime(t))return this._adddatetime(t,-this._months);throw new R.ArgumentError(R._type(this)+" - "+R._type(t)+" not supported")}},{key:"__mul__",value:function(t){if("number"==typeof t)return new R.MonthDelta(this._months*Math.floor(t));throw new R.ArgumentError(R._type(this)+" * "+R._type(t)+" not supported")}},{key:"__rmul__",value:function(t){if("number"==typeof t)return new R.MonthDelta(this._months*Math.floor(t));throw new R.ArgumentError(R._type(this)+" * "+R._type(t)+" not supported")}},{key:"__floordiv__",value:function(t){if("number"==typeof t)return new R.MonthDelta(Math.floor(this._months/t));if(R._ismonthdelta(t))return Math.floor(this._months/t._months);throw new R.ArgumentError(R._type(this)+" // "+R._type(t)+" not supported")}},{key:"__truediv__",value:function(t){if(R._ismonthdelta(t))return this._months/t._months;throw new R.ArgumentError(R._type(this)+" / "+R._type(t)+" not supported")}},{key:"__getattr__",value:function(t){var e=this;switch(t){case"months":var r=function(){return e._months};return R.expose(r,[]),r;default:throw new R.AttributeError(this,t)}}},{key:"months",value:function(){return this._months}},{key:"ul4type",value:function(){return"monthdelta"}}]),r}();for(var H=[R.TextAST,R.IndentAST,R.LineEndAST,R.ConstAST,R.SeqItemAST,R.UnpackSeqItemAST,R.DictItemAST,R.UnpackDictItemAST,R.PosArgAST,R.KeywordArgAST,R.UnpackListArgAST,R.UnpackDictArgAST,R.ListAST,R.ListCompAST,R.DictAST,R.DictCompAST,R.SetAST,R.SetCompAST,R.GenExprAST,R.VarAST,R.NotAST,R.NegAST,R.BitNotAST,R.IfAST,R.ReturnAST,R.PrintAST,R.PrintXAST,R.ItemAST,R.IsAST,R.IsNotAST,R.EQAST,R.NEAST,R.LTAST,R.LEAST,R.GTAST,R.GEAST,R.NotContainsAST,R.ContainsAST,R.AddAST,R.SubAST,R.MulAST,R.FloorDivAST,R.TrueDivAST,R.ModAST,R.ShiftLeftAST,R.ShiftRightAST,R.BitAndAST,R.BitXOrAST,R.BitOrAST,R.AndAST,R.OrAST,R.SliceAST,R.AttrAST,R.CallAST,R.RenderAST,R.RenderXAST,R.RenderBlockAST,R.RenderBlocksAST,R.SetVarAST,R.AddVarAST,R.SubVarAST,R.MulVarAST,R.TrueDivVarAST,R.FloorDivVarAST,R.ModVarAST,R.ShiftLeftVarAST,R.ShiftRightVarAST,R.BitAndVarAST,R.BitXOrVarAST,R.BitOrVarAST,R.ForBlockAST,R.WhileBlockAST,R.BreakAST,R.ContinueAST,R.CondBlockAST,R.IfBlockAST,R.ElIfBlockAST,R.ElseBlockAST,R.SignatureAST,R.Template],X=0;X"}}]),e}(),K.Handler=function(){function t(){E(this,t)}return P(t,[{key:"save",value:function(t){}},{key:"delete",value:function(t){}}]),t}(),K.Globals=function(t){function e(){var t;return E(this,e),(t=V(this,O(e).call(this))).version=null,t.platform=null,t.user=null,t.maxdbactions=null,t.maxtemplateruntime=null,t.flashmessages=null,t.handler=new K.Handler,t}return L(e,K.Base),P(e,[{key:"__repr__",value:function(){return""}}],[{key:"geodist",value:function(t,e){var r=function(t){return(t=Math.sin(t))*t},n=function(t){return(t=Math.cos(t))*t},o=Math.PI/180,i=1/298.257223563,a=t.lat*o,u=t.long*o,s=e.lat*o,l=(a+s)/2,c=(a-s)/2,h=(u-e.long*o)/2,p=r(c)*n(h)+n(l)*r(h),_=n(c)*n(h)+r(l)*r(h),f=Math.atan(Math.sqrt(p/_)),d=2*f*6378.137,v=Math.sqrt(p*_)/f,m=(3*v+1)/(2*p);return d*(1+i*((3*v-1)/(2*_))*r(l)*n(c)-i*m*n(l)*r(c))}}]),e}(),K.Globals.prototype._ul4onattrs=["version","platform","user","maxdbactions","maxtemplateruntime","flashmessages"],K.Globals.prototype._ul4attrs=R._makeset("version","platform","user","maxdbactions","maxtemplateruntime","flashmessages"),K.FlashMessage=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Base),P(e,[{key:"__repr__",value:function(){return""}}]),e}(),K.FlashMessage.prototype._ul4onattrs=["timestamp","type","title","message"],K.FlashMessage.prototype._ul4attrs=R._makeset("timestamp","type","title","message"),K.App=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Base),P(e,[{key:"__repr__",value:function(){return""}},{key:"insert",value:function(){var t=0"}}]),e}(),K.View.prototype._ul4onattrs=["id","name","app","order","width","height","start","end"],K.View.prototype._ul4attrs=R._makeset("id","name","app","order","width","height","start","end"),K.DataSourceData=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Base),P(e,[{key:"__repr__",value:function(){return""}}]),e}(),K.DataSourceData.prototype._ul4onattrs=["id","identifier","app","apps"],K.DataSourceData.prototype._ul4attrs=R._makeset("id","identifier","app","apps"),K.Record=function(t){function r(t){var e;return E(this,r),(e=V(this,O(r).call(this))).id=null,e.app=t,e.createdat=null,e.createdby=null,e.updatedat=null,e.updatedby=null,e.updatecount=0,e._sparsevalues=new Map,e._values=null,e._fields=null,e.children=new Map,e.attachments=null,e.errors=[],e._is_deleted=!1,e}return L(r,K.Base),P(r,[{key:"__repr__",value:function(){var t=[""),t.join("")}},{key:"is_dirty",value:function(){if(null===this.id)return!0;var t=!0,e=!1,r=void 0;try{for(var n,o=this.fields.values()[Symbol.iterator]();!(t=(n=o.next()).done);t=!0){if(n.value.is_dirty())return!0}}catch(t){e=!0,r=t}finally{try{t||null==o.return||o.return()}finally{if(e)throw r}}return!1}},{key:"has_errors",value:function(){if(0!==this.errors.length)return!0;var t=!0,e=!1,r=void 0;try{for(var n,o=this.fields.values()[Symbol.iterator]();!(t=(n=o.next()).done);t=!0){if(n.value.has_errors())return!0}}catch(t){e=!0,r=t}finally{try{t||null==o.return||o.return()}finally{if(e)throw r}}return!1}},{key:"delete",value:function(){return this.app.globals.handler.delete(this)}},{key:"save",value:function(){this.app.globals.handler.save(this)}},{key:"update",value:function(){var t=0"}},{key:"_logsearch",value:function(t,e){}},{key:"asjson",value:function(t){return t}},{key:"search",value:function(t,e){return!1}}]),e}(),K.Control.prototype.type=null,K.Control.prototype.subtype=null,K.Control.prototype._ul4onattrs=["id","identifier","field","app","label","priority","order","default","ininsertprocedure","inupdateprocedure"],K.Control.prototype._ul4attrs=R._makeset("id","identifier","field","app","label","priority","order","default","ininsertprocedure","inupdateprocedure"),K.BoolControl=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Control),P(e,[{key:"search",value:function(t,e){return this._logsearch(t,e),"equals"===e.operator&&e.value===t}}]),e}(),K.BoolControl.prototype.type="bool",K.IntControl=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Control),P(e,[{key:"search",value:function(t,e){return this._logsearch(t,e),"equals"===e.operator&&e.value===t}}]),e}(),K.IntControl.prototype.type="int",K.NumberControl=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Control),P(e,[{key:"search",value:function(t,e){return this._logsearch(t,e),"equals"===e.operator?e.value===t:"range"===e.operator&&(null!==t&&((null===e.minvalue||e.minvalue<=t)&&(null===e.maxvalue||t"}},{key:"value",get:function(){return this._value},set:function(t){var e=this._value;R._ne(e,t)&&(this.record.values.set(this.control.identifier,t),this._value=t,this._dirty=!0)}}]),o}(),K.LookupItem=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Base),P(e,[{key:"__repr__",value:function(){return""}}]),e}(),K.LookupItem.prototype._ul4onattrs=["key","label"],K.LookupItem.prototype._ul4attrs=R._makeset("key","label"),K.User=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Base),P(e,[{key:"__repr__",value:function(){return""}}]),e}(),K.User.prototype._ul4onattrs=["_id","id","gender","firstname","surname","initials","email","language","avatarsmall","avatarlarge","keyviews"],K.User.prototype._ul4attrs=R._makeset("_id","id","gender","firstname","surname","initials","email","language","avatarsmall","avatarlarge","keyviews"),K.File=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Base),P(e,[{key:"__repr__",value:function(){return""}}]),e}(),K.File.prototype._ul4onattrs=["id","url","filename","mimetype","width","height","internalid","createdat","size"],K.File.prototype._ul4attrs=R._makeset("id","url","filename","mimetype","width","height","size","createdat"),K.Geo=function(t){function o(t,e,r){var n;return E(this,o),(n=V(this,O(o).call(this))).lat=t,n.long=e,n.info=r,n}return L(o,K.Base),P(o,[{key:"__repr__",value:function(){return""}}]),o}(),K.Geo.prototype._ul4onattrs=["lat","long","info"],K.Geo.prototype._ul4attrs=R._makeset("lat","long","info"),K.Attachment=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Base),P(e,[{key:"__repr__",value:function(){return""}}]),e}(),K.Attachment.prototype._ul4onattrs=["id","record","label","active"],K.Attachment.prototype._ul4attrs=R._makeset("id","record","label","active"),K.NoteAttachment=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Attachment),e}(),K.NoteAttachment.prototype.type="noteattachment",K.NoteAttachment.prototype._ul4onattrs=K.Attachment.prototype._ul4onattrs.concat(["value"]),K.NoteAttachment.prototype._ul4attrs=R._makeset.apply(R,N(K.Attachment.prototype._ul4onattrs).concat(["value"])),K.URLAttachment=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Attachment),e}(),K.URLAttachment.prototype.type="urlattachment",K.URLAttachment.prototype._ul4onattrs=K.Attachment.prototype._ul4onattrs.concat(["value"]),K.URLAttachment.prototype._ul4attrs=R._makeset.apply(R,N(K.Attachment.prototype._ul4onattrs).concat(["value"])),K.FileAttachment=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Attachment),e}(),K.FileAttachment.prototype.type="fileattachment",K.FileAttachment.prototype._ul4onattrs=K.Attachment.prototype._ul4onattrs.concat(["value"]),K.FileAttachment.prototype._ul4attrs=R._makeset.apply(R,N(K.Attachment.prototype._ul4onattrs).concat(["value"])),K.ImageAttachment=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Attachment),e}(),K.ImageAttachment.prototype.type="imageattachment",K.ImageAttachment.prototype._ul4onattrs=K.Attachment.prototype._ul4onattrs.concat(["original","thumb","small","medium","large"]),K.ImageAttachment.prototype._ul4attrs=R._makeset.apply(R,N(K.Attachment.prototype._ul4onattrs).concat(["original","thumb","small","medium","large"])),K.JSONAttachment=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Attachment),P(e,[{key:"_dumpUL4ONAttr",value:function(t){return"value"===t?R._asjson(this.value):this[t]}},{key:"_loadUL4ONAttr",value:function(t,e){"value"===t?this.value=R._fromjson(e):this[t]=e}}]),e}(),K.JSONAttachment.prototype.type="jsonattachment",K.JSONAttachment.prototype._ul4onattrs=K.Attachment.prototype._ul4onattrs.concat(["value"]),K.JSONAttachment.prototype._ul4attrs=R._makeset.apply(R,N(K.Attachment.prototype._ul4onattrs).concat(["value"])),K.Installation=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Base),P(e,[{key:"__repr__",value:function(){return""}}]),e}(),K.Installation.prototype._ul4onattrs=["id","name"],K.Installation.prototype._ul4attrs=R._makeset("id","name"),K.Category=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Base),P(e,[{key:"__repr__",value:function(){for(var t=[],e=this;null!==e;)t.splice(0,0,e.identifier),e=e.parent;return""}}]),e}(),K.Category.prototype._ul4onattrs=["id","identifier","name","order","parent","children","apps"],K.Category.prototype._ul4attrs=R._makeset("id","identifier","name","order","parent","children","apps"),K.KeyView=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Base),P(e,[{key:"__repr__",value:function(){return""}}]),e}(),K.KeyView.prototype._ul4onattrs=["id","identifier","name","key","user"],K.KeyView.prototype._ul4attrs=R._makeset("id","identifier","name","key","user"),K.AppParameter=function(t){function e(){return E(this,e),V(this,O(e).apply(this,arguments))}return L(e,K.Base),P(e,[{key:"__repr__",value:function(){return""}}]),e}(),K.AppParameter.prototype._ul4onattrs=["id","app","identifier","description","value"],K.AppParameter.prototype._ul4attrs=R._makeset("id","app","identifier","description","value");for(var W=[K.Globals,K.App,K.View,K.DataSourceData,K.Record,K.BoolControl,K.IntControl,K.NumberControl,K.TextControl,K.EmailControl,K.URLControl,K.TelControl,K.PasswordControl,K.TextAreaControl,K.DateControl,K.DatetimeMinuteControl,K.DatetimeSecondControl,K.LookupControl,K.LookupSelectControl,K.LookupRadioControl,K.LookupChoiceControl,K.AppLookupControl,K.AppLookupSelectControl,K.AppLookupRadioControl,K.AppLookupChoiceControl,K.MultipleLookupControl,K.MultipleLookupSelectControl,K.MultipleLookupCheckboxControl,K.MultipleLookupChoiceControl,K.MultipleAppLookupControl,K.MultipleAppLookupSelectControl,K.MultipleAppLookupCheckboxControl,K.MultipleAppLookupChoiceControl,K.GeoControl,K.FileControl,K.ButtonControl,K.Field,K.LookupItem,K.User,K.File,K.Geo,K.NoteAttachment,K.URLAttachment,K.FileAttachment,K.ImageAttachment,K.JSONAttachment,K.Installation,K.Category,K.KeyView,K.AppParameter],$=0;$= this.data.length)\n\t\t\t\tthrow new ul4.ValueError(\"UL4 decoder at EOF\");\n\t\t\treturn this.data.charAt(this.pos++);\n\t\t}\n\n\t\t// Read a character from the buffer (return null on eof)\n\t\treadcharoreof()\n\t\t{\n\t\t\tif (this.pos >= this.data.length)\n\t\t\t\treturn null;\n\t\t\treturn this.data.charAt(this.pos++);\n\t\t}\n\n\t\t// Read next not-whitespace character from the buffer\n\t\treadblackchar()\n\t\t{\n\t\t\tlet re_white = /\\s/;\n\n\t\t\tfor (;;)\n\t\t\t{\n\t\t\t\tif (this.pos >= this.data.length)\n\t\t\t\t\tthrow new ul4.ValueError(\"UL4 decoder at EOF at position \" + this.pos + \" with path \" + this.stack.join(\"/\"));\n\t\t\t\tlet c = this.data.charAt(this.pos++);\n\t\t\t\tif (!c.match(re_white))\n\t\t\t\t\treturn c;\n\t\t\t}\n\t\t}\n\n\t\t// Read ``size`` characters from the buffer\n\t\tread(size)\n\t\t{\n\t\t\tif (this.pos+size > this.length)\n\t\t\t\tsize = this.length-this.pos;\n\t\t\tlet result = this.data.substring(this.pos, this.pos+size);\n\t\t\tthis.pos += size;\n\t\t\treturn result;\n\t\t}\n\n\t\t// \"unread\" one character\n\t\tbackup()\n\t\t{\n\t\t\t--this.pos;\n\t\t}\n\n\t\t// Read a number from the buffer\n\t\treadnumber()\n\t\t{\n\t\t\tlet re_digits = /[-+0123456789.eE]/, value = \"\";\n\t\t\tfor (;;)\n\t\t\t{\n\t\t\t\tlet c = this.readcharoreof();\n\t\t\t\tif (c !== null && c.match(re_digits))\n\t\t\t\t\tvalue += c;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlet result = parseFloat(value);\n\t\t\t\t\tif (isNaN(result))\n\t\t\t\t\t\tthrow new ul4.ValueError(\"invalid number, got \" + ul4._repr(\"value\") + \" at position \" + this.pos + \" with path \" + this.stack.join(\"/\"));\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t_beginfakeloading()\n\t\t{\n\t\t\tlet oldpos = this.backrefs.length;\n\t\t\tthis.backrefs.push(null);\n\t\t\treturn oldpos;\n\t\t}\n\n\t\t_endfakeloading(oldpos, value)\n\t\t{\n\t\t\tthis.backrefs[oldpos] = value;\n\t\t}\n\n\t\t_readescape(escapechar, length)\n\t\t{\n\t\t\tlet chars = this.read(length);\n\t\t\tif (chars.length != length)\n\t\t\t\tthrow new ul4.ValueError(\"broken escape \" + ul4._repr(\"\\\\\" + escapechar + chars) + \" at position \" + this.pos + \" with path \" + this.stack.join(\"/\"));\n\t\t\tlet codepoint = parseInt(chars, 16);\n\t\t\tif (isNaN(codepoint))\n\t\t\t\tthrow new ul4.ValueError(\"broken escape \" + ul4._repr(\"\\\\\" + escapechar + chars) + \" at position \" + this.pos + \" with path \" + this.stack.join(\"/\"));\n\t\t\treturn String.fromCharCode(codepoint);\n\t\t}\n\n\t\t// Load the next object from the buffer\n\t\tload()\n\t\t{\n\t\t\tlet typecode = this.readblackchar();\n\t\t\tlet result;\n\t\t\tswitch (typecode)\n\t\t\t{\n\t\t\t\tcase \"^\":\n\t\t\t\t\treturn this.backrefs[this.readnumber()];\n\t\t\t\tcase \"n\":\n\t\t\t\tcase \"N\":\n\t\t\t\t\tif (typecode === \"N\")\n\t\t\t\t\t\tthis.backrefs.push(null);\n\t\t\t\t\treturn null;\n\t\t\t\tcase \"b\":\n\t\t\t\tcase \"B\":\n\t\t\t\t\tresult = this.readchar();\n\t\t\t\t\tif (result === \"T\")\n\t\t\t\t\t\tresult = true;\n\t\t\t\t\telse if (result === \"F\")\n\t\t\t\t\t\tresult = false;\n\t\t\t\t\telse\n\t\t\t\t\t\tthrow new ul4.ValueError(\"wrong value for boolean, expected 'T' or 'F', got \" + ul4._repr(result) + \" at position \" + this.pos + \" with path \" + this.stack.join(\"/\"));\n\t\t\t\t\tif (typecode === \"B\")\n\t\t\t\t\t\tthis.backrefs.push(result);\n\t\t\t\t\treturn result;\n\t\t\t\tcase \"i\":\n\t\t\t\tcase \"I\":\n\t\t\t\tcase \"f\":\n\t\t\t\tcase \"F\":\n\t\t\t\t\tresult = this.readnumber();\n\t\t\t\t\tif (typecode === \"I\" || typecode === \"F\")\n\t\t\t\t\t\tthis.backrefs.push(result);\n\t\t\t\t\treturn result;\n\t\t\t\tcase \"s\":\n\t\t\t\tcase \"S\":\n\t\t\t\t\tresult = [];\n\t\t\t\t\tlet delimiter = this.readblackchar();\n\t\t\t\t\tfor (;;)\n\t\t\t\t\t{\n\t\t\t\t\t\tlet c = this.readchar();\n\t\t\t\t\t\tif (c == delimiter)\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tif (c == \"\\\\\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlet c2 = this.readchar();\n\t\t\t\t\t\t\tif (c2 == \"\\\\\")\n\t\t\t\t\t\t\t\tresult.push(\"\\\\\");\n\t\t\t\t\t\t\telse if (c2 == \"n\")\n\t\t\t\t\t\t\t\tresult.push(\"\\n\");\n\t\t\t\t\t\t\telse if (c2 == \"r\")\n\t\t\t\t\t\t\t\tresult.push(\"\\r\");\n\t\t\t\t\t\t\telse if (c2 == \"t\")\n\t\t\t\t\t\t\t\tresult.push(\"\\t\");\n\t\t\t\t\t\t\telse if (c2 == \"f\")\n\t\t\t\t\t\t\t\tresult.push(\"\\u000c\");\n\t\t\t\t\t\t\telse if (c2 == \"b\")\n\t\t\t\t\t\t\t\tresult.push(\"\\u0008\");\n\t\t\t\t\t\t\telse if (c2 == \"a\")\n\t\t\t\t\t\t\t\tresult.push(\"\\u0007\");\n\t\t\t\t\t\t\telse if (c2 == \"'\")\n\t\t\t\t\t\t\t\tresult.push(\"'\");\n\t\t\t\t\t\t\telse if (c2 == '\"')\n\t\t\t\t\t\t\t\tresult.push('\"');\n\t\t\t\t\t\t\telse if (c2 == \"x\")\n\t\t\t\t\t\t\t\tresult.push(this._readescape(\"x\", 2));\n\t\t\t\t\t\t\telse if (c2 == \"u\")\n\t\t\t\t\t\t\t\tresult.push(this._readescape(\"u\", 4));\n\t\t\t\t\t\t\telse if (c2 == \"U\")\n\t\t\t\t\t\t\t\tresult.push(this._readescape(\"U\", 8));\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tresult.push(\"\\\\\" + c2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tresult.push(c);\n\t\t\t\t\t}\n\t\t\t\t\tresult = result.join(\"\");\n\t\t\t\t\tif (typecode === \"S\")\n\t\t\t\t\t\tthis.backrefs.push(result);\n\t\t\t\t\treturn result;\n\t\t\t\tcase \"c\":\n\t\t\t\tcase \"C\":\n\t\t\t\t\tresult = new ul4.Color();\n\t\t\t\t\tif (typecode === \"C\")\n\t\t\t\t\t\tthis.backrefs.push(result);\n\t\t\t\t\tresult._r = this.load();\n\t\t\t\t\tresult._g = this.load();\n\t\t\t\t\tresult._b = this.load();\n\t\t\t\t\tresult._a = this.load();\n\t\t\t\t\treturn result;\n\t\t\t\tcase \"x\":\n\t\t\t\tcase \"X\":\n\t\t\t\t{\n\t\t\t\t\tlet year = this.load();\n\t\t\t\t\tlet month = this.load();\n\t\t\t\t\tlet day = this.load();\n\t\t\t\t\tresult = new ul4.Date(year, month, day);\n\t\t\t\t\tif (typecode === \"X\")\n\t\t\t\t\t\tthis.backrefs.push(result);\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\tcase \"z\":\n\t\t\t\tcase \"Z\":\n\t\t\t\t\tresult = new Date();\n\t\t\t\t\tresult.setFullYear(this.load());\n\t\t\t\t\tresult.setDate(1);\n\t\t\t\t\tresult.setMonth(this.load() - 1);\n\t\t\t\t\tresult.setDate(this.load());\n\t\t\t\t\tresult.setHours(this.load());\n\t\t\t\t\tresult.setMinutes(this.load());\n\t\t\t\t\tresult.setSeconds(this.load());\n\t\t\t\t\tresult.setMilliseconds(this.load()/1000);\n\t\t\t\t\tif (typecode === \"Z\")\n\t\t\t\t\t\tthis.backrefs.push(result);\n\t\t\t\t\treturn result;\n\t\t\t\tcase \"t\":\n\t\t\t\tcase \"T\":\n\t\t\t\t\tresult = new ul4.TimeDelta();\n\t\t\t\t\tresult._days = this.load();\n\t\t\t\t\tresult._seconds = this.load();\n\t\t\t\t\tresult._microseconds = this.load();\n\t\t\t\t\tif (typecode === \"T\")\n\t\t\t\t\t\tthis.backrefs.push(result);\n\t\t\t\t\treturn result;\n\t\t\t\tcase \"r\":\n\t\t\t\tcase \"R\":\n\t\t\t\t\tresult = new ul4.slice();\n\t\t\t\t\tif (typecode === \"R\")\n\t\t\t\t\t\tthis.backrefs.push(result);\n\t\t\t\t\tresult.start = this.load();\n\t\t\t\t\tresult.stop = this.load();\n\t\t\t\t\treturn result;\n\t\t\t\tcase \"m\":\n\t\t\t\tcase \"M\":\n\t\t\t\t\tresult = new ul4.MonthDelta();\n\t\t\t\t\tif (typecode === \"M\")\n\t\t\t\t\t\tthis.backrefs.push(result);\n\t\t\t\t\tresult._months = this.load();\n\t\t\t\t\treturn result;\n\t\t\t\tcase \"l\":\n\t\t\t\tcase \"L\":\n\t\t\t\t\tthis.stack.push(\"list\");\n\t\t\t\t\tresult = [];\n\t\t\t\t\tif (typecode === \"L\")\n\t\t\t\t\t\tthis.backrefs.push(result);\n\t\t\t\t\tfor (;;)\n\t\t\t\t\t{\n\t\t\t\t\t\ttypecode = this.readblackchar();\n\t\t\t\t\t\tif (typecode === \"]\")\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tthis.backup();\n\t\t\t\t\t\tresult.push(this.load());\n\t\t\t\t\t}\n\t\t\t\t\tthis.stack.pop();\n\t\t\t\t\treturn result;\n\t\t\t\tcase \"d\":\n\t\t\t\tcase \"D\":\n\t\t\t\tcase \"e\":\n\t\t\t\tcase \"E\":\n\t\t\t\t\tif (!ul4._havemap && (typecode == \"e\" || typecode == \"E\"))\n\t\t\t\t\t\tthrow new ul4.ValueError(\"ordered dictionaries are not supported at position \" + this.pos + \" with path \" + this.stack.join(\"/\"));\n\t\t\t\t\tresult = ul4._emptymap();\n\t\t\t\t\tthis.stack.push(typecode === \"d\" || typecode === \"D\" ? \"dict\" : \"odict\");\n\t\t\t\t\tif (typecode === \"D\" || typecode === \"E\")\n\t\t\t\t\t\tthis.backrefs.push(result);\n\t\t\t\t\tfor (;;)\n\t\t\t\t\t{\n\t\t\t\t\t\ttypecode = this.readblackchar();\n\t\t\t\t\t\tif (typecode === \"}\")\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tthis.backup();\n\t\t\t\t\t\tlet key = this.load();\n\t\t\t\t\t\tlet value = this.load();\n\t\t\t\t\t\tul4._setmap(result, key, value);\n\t\t\t\t\t}\n\t\t\t\t\tthis.stack.pop();\n\t\t\t\t\treturn result;\n\t\t\t\tcase \"y\":\n\t\t\t\tcase \"Y\":\n\t\t\t\t\tthis.stack.push(\"set\");\n\t\t\t\t\tresult = ul4._makeset();\n\t\t\t\t\tif (typecode === \"Y\")\n\t\t\t\t\t\tthis.backrefs.push(result);\n\t\t\t\t\tfor (;;)\n\t\t\t\t\t{\n\t\t\t\t\t\ttypecode = this.readblackchar();\n\t\t\t\t\t\tif (typecode === \"}\")\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tthis.backup();\n\t\t\t\t\t\tresult.add(this.load());\n\t\t\t\t\t}\n\t\t\t\t\tthis.stack.pop();\n\t\t\t\t\treturn result;\n\t\t\t\tcase \"o\":\n\t\t\t\tcase \"O\":\n\t\t\t\t{\n\t\t\t\t\tlet oldpos;\n\t\t\t\t\tif (typecode === \"O\")\n\t\t\t\t\t\toldpos = this._beginfakeloading();\n\t\t\t\t\tlet name = this.load();\n\t\t\t\t\tthis.stack.push(name);\n\t\t\t\t\tlet constructor;\n\t\t\t\t\tif (this.registry !== null)\n\t\t\t\t\t{\n\t\t\t\t\t\tconstructor = this.registry[name];\n\t\t\t\t\t\tif (typeof(constructor) === \"undefined\")\n\t\t\t\t\t\t\tconstructor = ul4._registry[name];\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tconstructor = ul4._registry[name];\n\t\t\t\t\tif (typeof(constructor) === \"undefined\")\n\t\t\t\t\t\tthrow new ul4.ValueError(\"can't load object of type \" + ul4._repr(name) + \" at position \" + this.pos + \" with path \" + this.stack.join(\"/\"));\n\t\t\t\t\tresult = new constructor();\n\t\t\t\t\tif (typecode === \"O\")\n\t\t\t\t\t\tthis._endfakeloading(oldpos, result);\n\t\t\t\t\tresult.ul4onload(this);\n\t\t\t\t\ttypecode = this.readblackchar();\n\t\t\t\t\tif (typecode !== \")\")\n\t\t\t\t\t\tthrow new ul4.ValueError(\"object terminator ')' for object of type '\" + name + \"' expected, got \" + ul4._repr(typecode) + \" at position \" + this.pos + \" with path \" + this.stack.join(\"/\"));\n\t\t\t\t\tthis.stack.pop();\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ul4.ValueError(\"unknown typecode \" + ul4._repr(typecode) + \" at position \" + this.pos + \" with path \" + this.stack.join(\"/\"));\n\t\t\t}\n\t\t}\n\n\t\t// Return an iterator for loading the content of a object\n\t\tloadcontent()\n\t\t{\n\t\t\tlet self = this;\n\t\t\treturn {\n\t\t\t\tnext: function()\n\t\t\t\t{\n\t\t\t\t\tlet typecode = self.readblackchar();\n\t\t\t\t\t// Always \"unread\" the typecode even at the end\n\t\t\t\t\t// so that at the end of a call to ul4onload()\n\t\t\t\t\t// the next input is the \"end of object\" marker\n\t\t\t\t\t// no matter whether ul4onload() uses loadcontent() or not.\n\t\t\t\t\tself.backup();\n\t\t\t\t\tif (typecode == \")\")\n\t\t\t\t\t\treturn {done: true};\n\t\t\t\t\telse\n\t\t\t\t\t\treturn {done: false, value: self.load()};\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t};\n\n\t//\n\t// UL4\n\t//\n\n\t// REs for parsing JSON\n\tul4._rvalidchars = /^[\\],:{}\\s]*$/;\n\tul4._rvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g;\n\tul4._rvalidtokens = /\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g;\n\tul4._rvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g;\n\n\t/// Helper functions\n\n\t// Clone an object and extend it\n\tul4._inherit = function _inherit(baseobj, attrs)\n\t{\n\t\treturn Object.assign(Object.create(baseobj), attrs);\n\t};\n\n\t// Convert a map to an object\n\tul4._map2object = function _map2object(obj)\n\t{\n\t\tif (ul4._ismap(obj))\n\t\t{\n\t\t\tlet newobj = {};\n\t\t\tobj.forEach(function(value, key){\n\t\t\t\tif (typeof(key) !== \"string\")\n\t\t\t\t\tthrow new ul4.TypeError(\"keys must be strings\");\n\t\t\t\tnewobj[key] = value;\n\t\t\t});\n\t\t\treturn newobj;\n\t\t}\n\t\treturn obj;\n\t};\n\n\t// Clip a number to the range [0;max)\n\tul4._bound = function _bound(value, upper)\n\t{\n\t\tif (value < 0)\n\t\t\treturn 0;\n\t\telse if (value > upper)\n\t\t\treturn upper;\n\t\telse\n\t\t\treturn value;\n\t};\n\n\t// Create a pretty stacktrace from an exception\n\tul4._stacktrace = function _stacktrace(exc)\n\t{\n\t\tlet output = (exc instanceof ul4.Exception ? exc.constructor.name + \": \" : \"\") + exc.toString();\n\t\tif (exc.context)\n\t\t\toutput = ul4._stacktrace(exc.context) + \"\\n\\n\" + output;\n\t\treturn output;\n\t};\n\n\t// Call a function ``f`` with UL4 argument handling\n\tul4._internal_call = function _internal_call(context, f, name, functioncontext, signature, needscontext, needsobject, args, kwargs)\n\t{\n\t\tlet finalargs;\n\t\tif (needsobject)\n\t\t{\n\t\t\tif (signature === null)\n\t\t\t{\n\t\t\t\tif (args.length)\n\t\t\t\t\tthrow new ul4.ArgumentError(ul4._repr(f) + \" doesn't support positional arguments!\");\n\t\t\t\tfinalargs = [kwargs];\n\t\t\t}\n\t\t\telse\n\t\t\t\tfinalargs = [signature.bindObject(name, args, kwargs)];\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (signature === null)\n\t\t\t\tthrow new ul4.ArgumentError(ul4._repr(f) + \" doesn't support positional arguments!\");\n\t\t\tfinalargs = signature.bindArray(name, args, kwargs);\n\t\t}\n\t\tif (needscontext)\n\t\t\tfinalargs.unshift(context);\n\t\treturn f.apply(functioncontext, finalargs);\n\t};\n\n\tul4._callfunction = function _callfunction(context, f, args, kwargs)\n\t{\n\t\tlet name = f._ul4_name || f.name;\n\t\tif (typeof(f._ul4_signature) === \"undefined\" || typeof(f._ul4_needsobject) === \"undefined\" || typeof(f._ul4_needscontext) === \"undefined\")\n\t\t\tthrow new ul4.TypeError(ul4._repr(f) + \" is not callable by UL4\");\n\t\treturn ul4._internal_call(context, f, name, ul4, f._ul4_signature, f._ul4_needscontext, f._ul4_needsobject, args, kwargs);\n\t};\n\n\tul4._callobject = function _callobject(context, obj, args, kwargs)\n\t{\n\t\tif (typeof(obj._ul4_callsignature) === \"undefined\" || typeof(obj._ul4_callneedsobject) === \"undefined\" || typeof(obj._ul4_callneedscontext) === \"undefined\")\n\t\t\tthrow new ul4.TypeError(ul4._repr(obj) + \" is not callable by UL4\");\n\t\treturn ul4._internal_call(context, obj.__call__, obj.name, obj, obj._ul4_callsignature, obj._ul4_callneedscontext, obj._ul4_callneedsobject, args, kwargs);\n\t};\n\n\tul4._callrender = function _callrender(context, obj, args, kwargs)\n\t{\n\t\tif (typeof(obj._ul4_rendersignature) === \"undefined\" || typeof(obj._ul4_renderneedsobject) === \"undefined\" || typeof(obj._ul4_renderneedscontext) === \"undefined\")\n\t\t\tthrow new ul4.TypeError(ul4._repr(obj) + \" is not renderable by UL4\");\n\t\treturn ul4._internal_call(context, obj.__render__, obj.name, obj, obj._ul4_rendersignature, obj._ul4_renderneedscontext, obj._ul4_renderneedsobject, args, kwargs);\n\t};\n\n\tul4._call = function _call(context, f, args, kwargs)\n\t{\n\t\tif (typeof(f) === \"function\")\n\t\t\treturn ul4._callfunction(context, f, args, kwargs);\n\t\telse if (f && typeof(f.__call__) === \"function\")\n\t\t\treturn ul4._callobject(context, f, args, kwargs);\n\t\telse\n\t\t\tthrow new ul4.TypeError(ul4._type(f) + \" is not callable\");\n\t};\n\n\tul4._unpackvar = function _unpackvar(lvalue, value)\n\t{\n\t\tif (!ul4._islist(lvalue))\n\t\t\treturn [[lvalue, value]];\n\t\telse\n\t\t{\n\t\t\tlet newvalue = [];\n\t\t\tlet iter = ul4._iter(value);\n\n\t\t\tfor (let i = 0;;++i)\n\t\t\t{\n\t\t\t\tlet item = iter.next();\n\n\t\t\t\tif (item.done)\n\t\t\t\t{\n\t\t\t\t\tif (i === lvalue.length)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\telse\n\t\t\t\t\t\tthrow new ul4.ValueError(\"need \" + lvalue.length + \" value\" + (lvalue.length === 1 ? \"\" : \"s\") + \" to unpack, got \" + i);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (i < lvalue.length)\n\t\t\t\t\t\tnewvalue = newvalue.concat(ul4._unpackvar(lvalue[i], item.value));\n\t\t\t\t\telse\n\t\t\t\t\t\tthrow new ul4.ValueError(\"too many values to unpack (expected \" + lvalue.length + \")\");\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn newvalue;\n\t\t}\n\t};\n\n\tul4._formatsource = function _formatsource(out)\n\t{\n\t\tlet finalout = [];\n\t\tlet level = 0, needlf = false;\n\t\tfor (let i = 0; i < out.length; ++i)\n\t\t{\n\t\t\tlet part = out[i];\n\t\t\tif (typeof(part) === \"number\")\n\t\t\t{\n\t\t\t\tlevel += part;\n\t\t\t\tneedlf = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (needlf)\n\t\t\t\t{\n\t\t\t\t\tfinalout.push(\"\\n\");\n\t\t\t\t\tfor (let j = 0; j < level; ++j)\n\t\t\t\t\t\tfinalout.push(\"\\t\");\n\t\t\t\t\tneedlf = false;\n\t\t\t\t}\n\t\t\t\tfinalout.push(part);\n\t\t\t}\n\t\t}\n\t\tif (needlf)\n\t\t\tfinalout.push(\"\\n\");\n\t\treturn finalout.join(\"\");\n\t};\n\n\t// Compare ``obj1`` and ``obj2`` if they have the same value\n\tul4._eq = function _eq(obj1, obj2)\n\t{\n\t\tlet numbertypes = [\"boolean\", \"number\"];\n\n\t\tif (obj1 && typeof(obj1.__eq__) === \"function\")\n\t\t\treturn obj1.__eq__(obj2);\n\t\telse if (obj2 && typeof(obj2.__eq__) === \"function\")\n\t\t\treturn obj2.__eq__(obj1);\n\t\telse if (obj1 === null)\n\t\t\treturn obj2 === null;\n\t\telse if (numbertypes.indexOf(typeof(obj1)) != -1)\n\t\t{\n\t\t\tif (numbertypes.indexOf(typeof(obj2)) != -1)\n\t\t\t\treturn obj1 == obj2;\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (typeof(obj1) === \"string\")\n\t\t{\n\t\t\tif (typeof(obj2) === \"string\")\n\t\t\t\treturn obj1 == obj2;\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (ul4._isdatetime(obj1))\n\t\t{\n\t\t\tif (ul4._isdatetime(obj2))\n\t\t\t\treturn obj1.getTime() == obj2.getTime();\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (ul4._islist(obj1))\n\t\t{\n\t\t\tif (ul4._islist(obj2))\n\t\t\t{\n\t\t\t\t// Shortcut, if it's the same object\n\t\t\t\tif (obj1 === obj2)\n\t\t\t\t\treturn true;\n\t\t\t\tif (obj1.length != obj2.length)\n\t\t\t\t\treturn false;\n\t\t\t\tfor (let i = 0; i < obj1.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tif (!ul4._eq(obj1[i], obj2[i])) // This might lead to infinite recursion and a stackoverflow, but it does in all implementations\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (ul4._isobject(obj1))\n\t\t{\n\t\t\tif (ul4._isobject(obj2))\n\t\t\t{\n\t\t\t\t// Shortcut, if it's the same object\n\t\t\t\tif (obj1 === obj2)\n\t\t\t\t\treturn true;\n\t\t\t\t// Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value\n\t\t\t\tfor (let key in obj1)\n\t\t\t\t{\n\t\t\t\t\tif (obj2.hasOwnProperty(key))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!ul4._eq(obj1[key], obj2[key]))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// Test that each attribute of ``obj2`` is also in ``obj1`` (the value has been tested before)\n\t\t\t\tfor (let key in obj2)\n\t\t\t\t{\n\t\t\t\t\tif (!obj1.hasOwnProperty(key))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (ul4._ismap(obj2))\n\t\t\t{\n\t\t\t\t// Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value\n\t\t\t\tfor (let key in obj1)\n\t\t\t\t{\n\t\t\t\t\tif (obj2.has(key))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!ul4._eq(obj1[key], obj2.get(key)))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// Test that each attribute of ``obj2`` is also in ``obj1`` (the value has been tested before)\n\t\t\t\tlet result = true;\n\t\t\t\tobj2.forEach(function(value, key) {\n\t\t\t\t\tif (!obj1.hasOwnProperty(key))\n\t\t\t\t\t\tresult = false;\n\t\t\t\t}, this);\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (ul4._ismap(obj1))\n\t\t{\n\t\t\tif (ul4._isobject(obj2))\n\t\t\t{\n\t\t\t\t// Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value\n\t\t\t\tobj1.forEach(function(value, key) {\n\t\t\t\t\tif (!obj2.hasOwnProperty(key))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\telse if (!ul4._eq(obj1.get(key), obj2[key]))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}, this);\n\t\t\t\t// Test that each attribute of ``obj2`` is also in ``obj1`` (the value has been tested before)\n\t\t\t\tfor (let key in obj2)\n\t\t\t\t{\n\t\t\t\t\tif (!obj1.has(key))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (ul4._ismap(obj2))\n\t\t\t{\n\t\t\t\t// Shortcut, if it's the same object\n\t\t\t\tif (obj1 === obj2)\n\t\t\t\t\treturn true;\n\t\t\t\tif (obj1.size != obj2.size)\n\t\t\t\t\treturn false;\n\t\t\t\tlet result = true;\n\t\t\t\t// Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value\n\t\t\t\tobj1.forEach(function(value, key) {\n\t\t\t\t\tif (!obj2.has(key))\n\t\t\t\t\t\tresult = false;\n\t\t\t\t\telse if (!ul4._eq(obj1.get(key), obj2.get(key)))\n\t\t\t\t\t\tresult = false;\n\t\t\t\t});\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse if (ul4._isset(obj1))\n\t\t{\n\t\t\t// We don't have to test for ``ul4._Set`` as ``ul4._Set`` implements ``__eq__``\n\t\t\tif (ul4._isset(obj2))\n\t\t\t{\n\t\t\t\t// Shortcut, if it's the same object\n\t\t\t\tif (obj1 === obj2)\n\t\t\t\t\treturn true;\n\t\t\t\tif (obj1.size != obj2.size)\n\t\t\t\t\treturn false;\n\t\t\t\tlet result = true;\n\t\t\t\tobj1.forEach(function(value) {\n\t\t\t\t\tif (!obj2.has(value))\n\t\t\t\t\t\tresult = false;\n\t\t\t\t});\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t\treturn obj1 === obj2;\n\t};\n\n\t// Compare ``obj1`` and ``obj2`` if they don't have the same value\n\tul4._ne = function _ne(obj1, obj2)\n\t{\n\t\tif (obj1 && typeof(obj1.__ne__) === \"function\")\n\t\t\treturn obj1.__ne__(obj2);\n\t\telse if (obj2 && typeof(obj2.__ne__) === \"function\")\n\t\t\treturn obj2.__ne__(obj1);\n\t\telse\n\t\t\treturn !ul4._eq(obj1, obj2);\n\t};\n\n\tul4._unorderable = function _unorderable(operator, obj1, obj2)\n\t{\n\t\tthrow new ul4.TypeError(\"unorderable types: \" + ul4._type(obj1) + \" \" + operator + \" \" + ul4._type(obj2));\n\t};\n\n\t// Return:\n\t// -1 when ``obj1 < obj2``,\n\t// 0 when ``obj1 == obj2``,\n\t// 1 when ``obj1 > obj2``,\n\t// null when ``obj1`` and ``obj2`` are comparable, but neither of the previous cases holds (only for sets)\n\t// raise TypeError if objects are uncomparable\n\t// This the purpose of ``_cmp`` is to support implementation of <, <=, > and >=\n\t// and dicts/maps are not comparable with the operator ``_cmp`` does not support dicts/maps\n\n\tul4._cmp = function _cmp(operator, obj1, obj2)\n\t{\n\t\tlet numbertypes = [\"boolean\", \"number\"];\n\n\t\tif (numbertypes.indexOf(typeof(obj1)) != -1)\n\t\t{\n\t\t\tif (numbertypes.indexOf(typeof(obj2)) != -1)\n\t\t\t\treturn (obj1 > obj2) - (obj1 < obj2);\n\t\t}\n\t\telse if (typeof(obj1) === \"string\")\n\t\t{\n\t\t\tif (typeof(obj2) === \"string\")\n\t\t\t\treturn (obj1 > obj2) - (obj1 < obj2);\n\t\t}\n\t\telse if (ul4._isdatetime(obj1))\n\t\t{\n\t\t\tif (ul4._isdatetime(obj2))\n\t\t\t{\n\t\t\t\tlet v1 = obj1.getTime(), v2 = obj2.getTime();\n\t\t\t\treturn (v1 > v2) - (v1 < v2);\n\t\t\t}\n\t\t}\n\t\telse if (ul4._islist(obj1))\n\t\t{\n\t\t\tif (ul4._islist(obj2))\n\t\t\t{\n\t\t\t\tif (obj1 === obj2)\n\t\t\t\t\treturn 0;\n\t\t\t\tfor (let i = 0; i < obj1.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tif (i >= obj2.length)\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\tlet res = ul4._cmp(operator, obj1[i], obj2[i]);\n\t\t\t\t\tif (res)\n\t\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t\treturn obj2.length > obj1.length ? -1 : 0;\n\t\t\t}\n\t\t}\n\t\telse if (ul4._isset(obj1) || ul4._isul4set(obj1))\n\t\t{\n\t\t\tif (ul4._isset(obj2) || ul4._isul4set(obj2))\n\t\t\t{\n\t\t\t\tlet in1only = false;\n\t\t\t\tlet in2only = false;\n\n\t\t\t\tfor (let iter = _iter(obj1);;)\n\t\t\t\t{\n\t\t\t\t\tlet item = iter.next();\n\t\t\t\t\tif (item.done)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (!obj2.has(item.value))\n\t\t\t\t\t{\n\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (let iter = _iter(obj2);;)\n\t\t\t\t{\n\t\t\t\t\tlet item = iter.next();\n\t\t\t\t\tif (item.done)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (!obj1.has(item.value))\n\t\t\t\t\t{\n\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (in1only)\n\t\t\t\t{\n\t\t\t\t\tif (in2only)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (in2only)\n\t\t\t\t\t\treturn -1;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ul4._unorderable(operator, obj1, obj2);\n\t};\n\n\t// Return whether ``obj1 < obj2``\n\tul4._lt = function _lt(obj1, obj2)\n\t{\n\t\tlet numbertypes = [\"boolean\", \"number\"];\n\n\t\tif (obj1 && typeof(obj1.__lt__) === \"function\")\n\t\t\treturn obj1.__lt__(obj2);\n\t\telse if (numbertypes.indexOf(typeof(obj1)) != -1)\n\t\t{\n\t\t\tif (numbertypes.indexOf(typeof(obj2)) != -1)\n\t\t\t\treturn obj1 < obj2;\n\t\t}\n\t\telse if (typeof(obj1) === \"string\")\n\t\t{\n\t\t\tif (typeof(obj2) === \"string\")\n\t\t\t\treturn obj1 < obj2;\n\t\t}\n\t\telse if (ul4._isdatetime(obj1))\n\t\t{\n\t\t\tif (ul4._isdatetime(obj2))\n\t\t\t\treturn obj1.getTime() < obj2.getTime();\n\t\t}\n\t\telse if (ul4._islist(obj1))\n\t\t{\n\t\t\tif (ul4._islist(obj2))\n\t\t\t{\n\t\t\t\tif (obj1 === obj2)\n\t\t\t\t\treturn false;\n\t\t\t\tfor (let i = 0; i < obj1.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tif (i >= obj2.length)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tlet eq = ul4._eq(obj1[i], obj2[i]);\n\t\t\t\t\tif (!eq)\n\t\t\t\t\t\treturn ul4._lt(obj1[i], obj2[i]);\n\t\t\t\t}\n\t\t\t\treturn obj1.length < obj2.length;\n\t\t\t}\n\t\t}\n\t\t// FIXME: Set comparison\n\t\telse if (ul4._isset(obj1))\n\t\t{\n\t\t\tif (ul4._isset(obj2))\n\t\t\t{\n\t\t\t\tif (ul4._isset(obj2))\n\t\t\t\t{\n\t\t\t\t\tfor (let key in obj1)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj2.has(obj1[key]))\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t}\n\t\t\t\t\tfor (let key in obj2)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj1.has(obj2[key]))\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (ul4._isul4set(obj2))\n\t\t\t\t{\n\t\t\t\t\tfor (let key in obj1)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj2.items[obj1[key]])\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t}\n\t\t\t\t\tfor (let value in obj2.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj1.has(value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (ul4._isul4set(obj2))\n\t\t\t{\n\t\t\t\tif (ul4._isset(obj2))\n\t\t\t\t{\n\t\t\t\t\tfor (let value in obj1.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj2.has(value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (let key in obj2)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj1.items[obj2[key]])\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (ul4._isul4set(obj2))\n\t\t\t\t{\n\t\t\t\t\tfor (let value in obj1.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj2.items[value])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (let value in obj2.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj1.items[value])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tul4._unorderable(operator, obj1, obj2);\n\n\t\t\tif (in1only)\n\t\t\t{\n\t\t\t\tif (in2only)\n\t\t\t\t\treturn null;\n\t\t\t\telse\n\t\t\t\t\treturn 1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (in2only)\n\t\t\t\t\treturn -1;\n\t\t\t\telse\n\t\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t\tul4._unorderable(\"<\", obj1, obj2);\n\t};\n\n\t// Return whether ``obj1 <= obj2``\n\tul4._le = function _le(obj1, obj2)\n\t{\n\t\tlet numbertypes = [\"boolean\", \"number\"];\n\n\t\tif (obj1 && typeof(obj1.__le__) === \"function\")\n\t\t\treturn obj1.__le__(obj2);\n\t\tif (numbertypes.indexOf(typeof(obj1)) != -1)\n\t\t{\n\t\t\tif (numbertypes.indexOf(typeof(obj2)) != -1)\n\t\t\t\treturn obj1 <= obj2;\n\t\t}\n\t\telse if (typeof(obj1) === \"string\")\n\t\t{\n\t\t\tif (typeof(obj2) === \"string\")\n\t\t\t\treturn obj1 <= obj2;\n\t\t}\n\t\telse if (ul4._isdatetime(obj1))\n\t\t{\n\t\t\tif (ul4._isdatetime(obj2))\n\t\t\t\treturn obj1.getTime() <= obj2.getTime();\n\t\t}\n\t\telse if (ul4._islist(obj1))\n\t\t{\n\t\t\tif (ul4._islist(obj2))\n\t\t\t{\n\t\t\t\tif (obj1 === obj2)\n\t\t\t\t\treturn true;\n\t\t\t\tfor (let i = 0; i < obj1.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tif (i >= obj2.length)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tlet eq = ul4._eq(obj1[i], obj2[i]);\n\t\t\t\t\tif (!eq)\n\t\t\t\t\t\treturn ul4._lt(obj1[i], obj2[i]);\n\t\t\t\t}\n\t\t\t\treturn obj1.length <= obj2.length;\n\t\t\t}\n\t\t}\n\t\t// FIXME: Set comparison\n\t\telse if (ul4._isset(obj1) || ul4._isul4set(obj1))\n\t\t{\n\t\t\tlet in1only = false;\n\t\t\tlet in2only = false;\n\n\t\t\tif (ul4._isset(obj2))\n\t\t\t{\n\t\t\t\tif (ul4._isset(obj2))\n\t\t\t\t{\n\t\t\t\t\tobj1.forEach(function(value) {\n\t\t\t\t\t\tif (!obj2.has(value))\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t});\n\t\t\t\t\tobj2.forEach(function(value) {\n\t\t\t\t\t\tif (!obj1.has(value))\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse if (ul4._isul4set(obj2))\n\t\t\t\t{\n\t\t\t\t\tobj1.forEach(function(value) {\n\t\t\t\t\t\tif (!obj2.items[value])\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t});\n\t\t\t\t\tfor (let value in obj2.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj1.has(value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (ul4._isul4set(obj2))\n\t\t\t{\n\t\t\t\tif (ul4._isset(obj2))\n\t\t\t\t{\n\t\t\t\t\tfor (let value in obj1.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj2.has(value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tobj2.forEach(function(value) {\n\t\t\t\t\t\tif (!obj1.items[value])\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse if (ul4._isul4set(obj2))\n\t\t\t\t{\n\t\t\t\t\tfor (let value in obj1.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj2.items[value])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (let value in obj2.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj1.items[value])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tul4._unorderable(operator, obj1, obj2);\n\n\t\t\tif (in1only)\n\t\t\t{\n\t\t\t\tif (in2only)\n\t\t\t\t\treturn null;\n\t\t\t\telse\n\t\t\t\t\treturn 1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (in2only)\n\t\t\t\t\treturn -1;\n\t\t\t\telse\n\t\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t\tul4._unorderable(\"<=\", obj1, obj2);\n\t};\n\n\t// Return whether ``obj1 > obj2``\n\tul4._gt = function _gt(obj1, obj2)\n\t{\n\t\tlet numbertypes = [\"boolean\", \"number\"];\n\n\t\tif (obj1 && typeof(obj1.__gt__) === \"function\")\n\t\t\treturn obj1.__gt__(obj2);\n\t\tif (numbertypes.indexOf(typeof(obj1)) != -1)\n\t\t{\n\t\t\tif (numbertypes.indexOf(typeof(obj2)) != -1)\n\t\t\t\treturn obj1 > obj2;\n\t\t}\n\t\telse if (typeof(obj1) === \"string\")\n\t\t{\n\t\t\tif (typeof(obj2) === \"string\")\n\t\t\t\treturn obj1 > obj2;\n\t\t}\n\t\telse if (ul4._isdatetime(obj1))\n\t\t{\n\t\t\tif (ul4._isdatetime(obj2))\n\t\t\t\treturn obj1.getTime() > obj2.getTime();\n\t\t}\n\t\telse if (ul4._islist(obj1))\n\t\t{\n\t\t\tif (ul4._islist(obj2))\n\t\t\t{\n\t\t\t\tif (obj1 === obj2)\n\t\t\t\t\treturn false;\n\t\t\t\tfor (let i = 0; i < obj1.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tif (i >= obj2.length)\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tlet eq = ul4._eq(obj1[i], obj2[i]);\n\t\t\t\t\tif (!eq)\n\t\t\t\t\t\treturn ul4._gt(obj1[i], obj2[i]);\n\t\t\t\t}\n\t\t\t\treturn obj1.length > obj2.length;\n\t\t\t}\n\t\t}\n\t\t// FIXME: Set comparison\n\t\telse if (ul4._isset(obj1) || ul4._isul4set(obj1))\n\t\t{\n\t\t\tlet in1only = false;\n\t\t\tlet in2only = false;\n\n\t\t\tif (ul4._isset(obj2))\n\t\t\t{\n\t\t\t\tif (ul4._isset(obj2))\n\t\t\t\t{\n\t\t\t\t\tobj1.forEach(function(value) {\n\t\t\t\t\t\tif (!obj2.has(value))\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t});\n\t\t\t\t\tobj2.forEach(function(value) {\n\t\t\t\t\t\tif (!obj1.has(value))\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse if (ul4._isul4set(obj2))\n\t\t\t\t{\n\t\t\t\t\tobj1.forEach(function(value) {\n\t\t\t\t\t\tif (!obj2.items[value])\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t});\n\t\t\t\t\tobj2.forEach(function(value) {\n\t\t\t\t\t\tif (!obj1.has(value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (ul4._isul4set(obj2))\n\t\t\t{\n\t\t\t\tif (ul4._isset(obj2))\n\t\t\t\t{\n\t\t\t\t\tfor (let value in obj1.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj2.has(value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tobj2.forEach(function(value) {\n\t\t\t\t\t\tif (!obj1.items[value])\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse if (ul4._isul4set(obj2))\n\t\t\t\t{\n\t\t\t\t\tfor (let value in obj1.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj2.items[value])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (let value in obj2.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj1.items[value])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tul4._unorderable(operator, obj1, obj2);\n\n\t\t\tif (in1only)\n\t\t\t{\n\t\t\t\tif (in2only)\n\t\t\t\t\treturn null;\n\t\t\t\telse\n\t\t\t\t\treturn 1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (in2only)\n\t\t\t\t\treturn -1;\n\t\t\t\telse\n\t\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t\tul4._unorderable(\">\", obj1, obj2);\n\t};\n\n\t// Return whether ``obj1 >= obj2``\n\tul4._ge = function _ge(obj1, obj2)\n\t{\n\t\tlet numbertypes = [\"boolean\", \"number\"];\n\n\t\tif (obj1 && typeof(obj1.__ge__) === \"function\")\n\t\t\treturn obj1.__ge__(obj2);\n\t\telse if (numbertypes.indexOf(typeof(obj1)) != -1)\n\t\t{\n\t\t\tif (numbertypes.indexOf(typeof(obj2)) != -1)\n\t\t\t\treturn obj1 >= obj2;\n\t\t}\n\t\telse if (typeof(obj1) === \"string\")\n\t\t{\n\t\t\tif (typeof(obj2) === \"string\")\n\t\t\t\treturn obj1 >= obj2;\n\t\t}\n\t\telse if (ul4._isdatetime(obj1))\n\t\t{\n\t\t\tif (ul4._isdatetime(obj2))\n\t\t\t\treturn obj1.getTime() >= obj2.getTime();\n\t\t}\n\t\telse if (ul4._islist(obj1))\n\t\t{\n\t\t\tif (ul4._islist(obj2))\n\t\t\t{\n\t\t\t\tif (obj1 === obj2)\n\t\t\t\t\treturn true;\n\t\t\t\tfor (let i = 0; i < obj1.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tif (i >= obj2.length)\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tlet eq = ul4._eq(obj1[i], obj2[i]);\n\t\t\t\t\tif (!eq)\n\t\t\t\t\t\treturn ul4._gt(obj1[i], obj2[i]);\n\t\t\t\t}\n\t\t\t\treturn obj1.length >= obj2.length;\n\t\t\t}\n\t\t}\n\t\t// FIXME: Set comparison\n\t\telse if (ul4._isset(obj1) || ul4._isul4set(obj1))\n\t\t{\n\t\t\tlet in1only = false;\n\t\t\tlet in2only = false;\n\n\t\t\tif (ul4._isset(obj2))\n\t\t\t{\n\t\t\t\tif (ul4._isset(obj2))\n\t\t\t\t{\n\t\t\t\t\tobj1.forEach(function(value) {\n\t\t\t\t\t\tif (!obj2.has(value))\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t});\n\t\t\t\t\tobj2.forEach(function(value) {\n\t\t\t\t\t\tif (!obj1.has(value))\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse if (ul4._isul4set(obj2))\n\t\t\t\t{\n\t\t\t\t\tobj1.forEach(function(value) {\n\t\t\t\t\t\tif (!obj2.items[value])\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t});\n\t\t\t\t\tfor (let value in obj2.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj1.has(value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (ul4._isul4set(obj2))\n\t\t\t{\n\t\t\t\tif (ul4._isset(obj2))\n\t\t\t\t{\n\t\t\t\t\tfor (let value in obj1.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj2.has(value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tobj2.forEach(function(value, key) {\n\t\t\t\t\t\tif (!obj1.items[value])\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse if (ul4._isul4set(obj2))\n\t\t\t\t{\n\t\t\t\t\tfor (let value in obj1.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj2.items[value])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin1only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (let value in obj2.items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!obj1.items[value])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tin2only = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tul4._unorderable(operator, obj1, obj2);\n\n\t\t\tif (in1only)\n\t\t\t{\n\t\t\t\tif (in2only)\n\t\t\t\t\treturn null;\n\t\t\t\telse\n\t\t\t\t\treturn 1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (in2only)\n\t\t\t\t\treturn -1;\n\t\t\t\telse\n\t\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t\tul4._unorderable(\">=\", obj1, obj2);\n\t};\n\n\t// Return an iterator for ``obj``\n\tul4._iter = function _iter(obj)\n\t{\n\t\tif (typeof(obj) === \"string\" || ul4._islist(obj))\n\t\t{\n\t\t\treturn {\n\t\t\t\tindex: 0,\n\t\t\t\tnext: function()\n\t\t\t\t{\n\t\t\t\t\tif (this.index < obj.length)\n\t\t\t\t\t\treturn {value: obj[this.index++], done: false};\n\t\t\t\t\telse\n\t\t\t\t\t\treturn {done: true};\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\telse if (ul4._isiter(obj))\n\t\t\treturn obj;\n\t\telse if (obj !== null && typeof(obj.__iter__) === \"function\")\n\t\t\treturn obj.__iter__();\n\t\telse if (ul4._ismap(obj))\n\t\t{\n\t\t\tlet keys = [];\n\t\t\tobj.forEach(function(value, key) {\n\t\t\t\tkeys.push(key);\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tindex: 0,\n\t\t\t\tnext: function()\n\t\t\t\t{\n\t\t\t\t\tif (this.index >= keys.length)\n\t\t\t\t\t\treturn {done: true};\n\t\t\t\t\treturn {value: keys[this.index++], done: false};\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\telse if (ul4._isset(obj))\n\t\t{\n\t\t\tlet values = [];\n\t\t\tobj.forEach(function(item) {\n\t\t\t\tvalues.push(item);\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tindex: 0,\n\t\t\t\tnext: function()\n\t\t\t\t{\n\t\t\t\t\tif (this.index >= values.length)\n\t\t\t\t\t\treturn {done: true};\n\t\t\t\t\treturn {value: values[this.index++], done: false};\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\telse if (ul4._isul4set(obj))\n\t\t{\n\t\t\treturn ul4._iter(obj.items);\n\t\t}\n\t\telse if (ul4._isobject(obj))\n\t\t{\n\t\t\tlet keys = [];\n\t\t\tfor (let key in obj)\n\t\t\t\tkeys.push(key);\n\t\t\treturn {\n\t\t\t\tindex: 0,\n\t\t\t\tnext: function()\n\t\t\t\t{\n\t\t\t\t\tif (this.index >= keys.length)\n\t\t\t\t\t\treturn {done: true};\n\t\t\t\t\treturn {value: keys[this.index++], done: false};\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tthrow new ul4.TypeError(ul4._type(obj) + \" object is not iterable\");\n\t};\n\n\tul4._str_repr = function _str_repr(str, ascii)\n\t{\n\t\tlet result = \"\";\n\t\tlet squote = false, dquote = false;\n\n\t\tfor (let i = 0; i < str.length; ++i)\n\t\t{\n\t\t\tlet c = str[i];\n\t\t\tif (c == '\"')\n\t\t\t{\n\t\t\t\tdquote = true;\n\t\t\t\tif (squote)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse if (c == \"'\")\n\t\t\t{\n\t\t\t\tsquote = true;\n\t\t\t\tif (dquote)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Prefer single quotes: Only use double quotes if the string contains single quotes, but no double quotes\n\t\tlet quote = (squote && !dquote) ? '\"' : \"'\";\n\n\t\tfor (let i = 0; i < str.length; ++i)\n\t\t{\n\t\t\tlet c = str[i];\n\t\t\tswitch (c)\n\t\t\t{\n\t\t\t\tcase '\"':\n\t\t\t\t\tresult += (quote == c) ? '\\\\\"' : c;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"'\":\n\t\t\t\t\tresult += (quote == c) ? \"\\\\'\" : c;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"\\\\\":\n\t\t\t\t\tresult += \"\\\\\\\\\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"\\t\":\n\t\t\t\t\tresult += \"\\\\t\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"\\n\":\n\t\t\t\t\tresult += \"\\\\n\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"\\r\":\n\t\t\t\t\tresult += \"\\\\r\";\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tlet code = c.charCodeAt(0);\n\t\t\t\t\tlet escape;\n\t\t\t\t\tif (code < 32)\n\t\t\t\t\t\tescape = 2;\n\t\t\t\t\telse if (code < 0x7f)\n\t\t\t\t\t\tescape = 0;\n\t\t\t\t\telse if (!ascii && !/[\\u007f-\\u00a0\\u00ad\\u0378-\\u0379\\u0380-\\u0383\\u038b\\u038d\\u03a2\\u0530\\u0557-\\u0558\\u0560\\u0588\\u058b-\\u058c\\u0590\\u05c8-\\u05cf\\u05eb-\\u05ef\\u05f5-\\u0605\\u061c-\\u061d\\u06dd\\u070e-\\u070f\\u074b-\\u074c\\u07b2-\\u07bf\\u07fb-\\u07ff\\u082e-\\u082f\\u083f\\u085c-\\u085d\\u085f-\\u089f\\u08b5-\\u08e2\\u0984\\u098d-\\u098e\\u0991-\\u0992\\u09a9\\u09b1\\u09b3-\\u09b5\\u09ba-\\u09bb\\u09c5-\\u09c6\\u09c9-\\u09ca\\u09cf-\\u09d6\\u09d8-\\u09db\\u09de\\u09e4-\\u09e5\\u09fc-\\u0a00\\u0a04\\u0a0b-\\u0a0e\\u0a11-\\u0a12\\u0a29\\u0a31\\u0a34\\u0a37\\u0a3a-\\u0a3b\\u0a3d\\u0a43-\\u0a46\\u0a49-\\u0a4a\\u0a4e-\\u0a50\\u0a52-\\u0a58\\u0a5d\\u0a5f-\\u0a65\\u0a76-\\u0a80\\u0a84\\u0a8e\\u0a92\\u0aa9\\u0ab1\\u0ab4\\u0aba-\\u0abb\\u0ac6\\u0aca\\u0ace-\\u0acf\\u0ad1-\\u0adf\\u0ae4-\\u0ae5\\u0af2-\\u0af8\\u0afa-\\u0b00\\u0b04\\u0b0d-\\u0b0e\\u0b11-\\u0b12\\u0b29\\u0b31\\u0b34\\u0b3a-\\u0b3b\\u0b45-\\u0b46\\u0b49-\\u0b4a\\u0b4e-\\u0b55\\u0b58-\\u0b5b\\u0b5e\\u0b64-\\u0b65\\u0b78-\\u0b81\\u0b84\\u0b8b-\\u0b8d\\u0b91\\u0b96-\\u0b98\\u0b9b\\u0b9d\\u0ba0-\\u0ba2\\u0ba5-\\u0ba7\\u0bab-\\u0bad\\u0bba-\\u0bbd\\u0bc3-\\u0bc5\\u0bc9\\u0bce-\\u0bcf\\u0bd1-\\u0bd6\\u0bd8-\\u0be5\\u0bfb-\\u0bff\\u0c04\\u0c0d\\u0c11\\u0c29\\u0c3a-\\u0c3c\\u0c45\\u0c49\\u0c4e-\\u0c54\\u0c57\\u0c5b-\\u0c5f\\u0c64-\\u0c65\\u0c70-\\u0c77\\u0c80\\u0c84\\u0c8d\\u0c91\\u0ca9\\u0cb4\\u0cba-\\u0cbb\\u0cc5\\u0cc9\\u0cce-\\u0cd4\\u0cd7-\\u0cdd\\u0cdf\\u0ce4-\\u0ce5\\u0cf0\\u0cf3-\\u0d00\\u0d04\\u0d0d\\u0d11\\u0d3b-\\u0d3c\\u0d45\\u0d49\\u0d4f-\\u0d56\\u0d58-\\u0d5e\\u0d64-\\u0d65\\u0d76-\\u0d78\\u0d80-\\u0d81\\u0d84\\u0d97-\\u0d99\\u0db2\\u0dbc\\u0dbe-\\u0dbf\\u0dc7-\\u0dc9\\u0dcb-\\u0dce\\u0dd5\\u0dd7\\u0de0-\\u0de5\\u0df0-\\u0df1\\u0df5-\\u0e00\\u0e3b-\\u0e3e\\u0e5c-\\u0e80\\u0e83\\u0e85-\\u0e86\\u0e89\\u0e8b-\\u0e8c\\u0e8e-\\u0e93\\u0e98\\u0ea0\\u0ea4\\u0ea6\\u0ea8-\\u0ea9\\u0eac\\u0eba\\u0ebe-\\u0ebf\\u0ec5\\u0ec7\\u0ece-\\u0ecf\\u0eda-\\u0edb\\u0ee0-\\u0eff\\u0f48\\u0f6d-\\u0f70\\u0f98\\u0fbd\\u0fcd\\u0fdb-\\u0fff\\u10c6\\u10c8-\\u10cc\\u10ce-\\u10cf\\u1249\\u124e-\\u124f\\u1257\\u1259\\u125e-\\u125f\\u1289\\u128e-\\u128f\\u12b1\\u12b6-\\u12b7\\u12bf\\u12c1\\u12c6-\\u12c7\\u12d7\\u1311\\u1316-\\u1317\\u135b-\\u135c\\u137d-\\u137f\\u139a-\\u139f\\u13f6-\\u13f7\\u13fe-\\u13ff\\u1680\\u169d-\\u169f\\u16f9-\\u16ff\\u170d\\u1715-\\u171f\\u1737-\\u173f\\u1754-\\u175f\\u176d\\u1771\\u1774-\\u177f\\u17de-\\u17df\\u17ea-\\u17ef\\u17fa-\\u17ff\\u180e-\\u180f\\u181a-\\u181f\\u1878-\\u187f\\u18ab-\\u18af\\u18f6-\\u18ff\\u191f\\u192c-\\u192f\\u193c-\\u193f\\u1941-\\u1943\\u196e-\\u196f\\u1975-\\u197f\\u19ac-\\u19af\\u19ca-\\u19cf\\u19db-\\u19dd\\u1a1c-\\u1a1d\\u1a5f\\u1a7d-\\u1a7e\\u1a8a-\\u1a8f\\u1a9a-\\u1a9f\\u1aae-\\u1aaf\\u1abf-\\u1aff\\u1b4c-\\u1b4f\\u1b7d-\\u1b7f\\u1bf4-\\u1bfb\\u1c38-\\u1c3a\\u1c4a-\\u1c4c\\u1c80-\\u1cbf\\u1cc8-\\u1ccf\\u1cf7\\u1cfa-\\u1cff\\u1df6-\\u1dfb\\u1f16-\\u1f17\\u1f1e-\\u1f1f\\u1f46-\\u1f47\\u1f4e-\\u1f4f\\u1f58\\u1f5a\\u1f5c\\u1f5e\\u1f7e-\\u1f7f\\u1fb5\\u1fc5\\u1fd4-\\u1fd5\\u1fdc\\u1ff0-\\u1ff1\\u1ff5\\u1fff-\\u200f\\u2028-\\u202f\\u205f-\\u206f\\u2072-\\u2073\\u208f\\u209d-\\u209f\\u20bf-\\u20cf\\u20f1-\\u20ff\\u218c-\\u218f\\u23fb-\\u23ff\\u2427-\\u243f\\u244b-\\u245f\\u2b74-\\u2b75\\u2b96-\\u2b97\\u2bba-\\u2bbc\\u2bc9\\u2bd2-\\u2beb\\u2bf0-\\u2bff\\u2c2f\\u2c5f\\u2cf4-\\u2cf8\\u2d26\\u2d28-\\u2d2c\\u2d2e-\\u2d2f\\u2d68-\\u2d6e\\u2d71-\\u2d7e\\u2d97-\\u2d9f\\u2da7\\u2daf\\u2db7\\u2dbf\\u2dc7\\u2dcf\\u2dd7\\u2ddf\\u2e43-\\u2e7f\\u2e9a\\u2ef4-\\u2eff\\u2fd6-\\u2fef\\u2ffc-\\u3000\\u3040\\u3097-\\u3098\\u3100-\\u3104\\u312e-\\u3130\\u318f\\u31bb-\\u31bf\\u31e4-\\u31ef\\u321f\\u32ff\\u4db6-\\u4dbf\\u9fd6-\\u9fff\\ua48d-\\ua48f\\ua4c7-\\ua4cf\\ua62c-\\ua63f\\ua6f8-\\ua6ff\\ua7ae-\\ua7af\\ua7b8-\\ua7f6\\ua82c-\\ua82f\\ua83a-\\ua83f\\ua878-\\ua87f\\ua8c5-\\ua8cd\\ua8da-\\ua8df\\ua8fe-\\ua8ff\\ua954-\\ua95e\\ua97d-\\ua97f\\ua9ce\\ua9da-\\ua9dd\\ua9ff\\uaa37-\\uaa3f\\uaa4e-\\uaa4f\\uaa5a-\\uaa5b\\uaac3-\\uaada\\uaaf7-\\uab00\\uab07-\\uab08\\uab0f-\\uab10\\uab17-\\uab1f\\uab27\\uab2f\\uab66-\\uab6f\\uabee-\\uabef\\uabfa-\\uabff\\ud7a4-\\ud7af\\ud7c7-\\ud7ca\\ud7fc-\\uf8ff\\ufa6e-\\ufa6f\\ufada-\\ufaff\\ufb07-\\ufb12\\ufb18-\\ufb1c\\ufb37\\ufb3d\\ufb3f\\ufb42\\ufb45\\ufbc2-\\ufbd2\\ufd40-\\ufd4f\\ufd90-\\ufd91\\ufdc8-\\ufdef\\ufdfe-\\ufdff\\ufe1a-\\ufe1f\\ufe53\\ufe67\\ufe6c-\\ufe6f\\ufe75\\ufefd-\\uff00\\uffbf-\\uffc1\\uffc8-\\uffc9\\uffd0-\\uffd1\\uffd8-\\uffd9\\uffdd-\\uffdf\\uffe7\\uffef-\\ufffb\\ufffe-\\uffff]/.test(c))\n\t\t\t\t\t\tescape = 0;\n\t\t\t\t\telse if (code <= 0xff)\n\t\t\t\t\t\tescape = 2;\n\t\t\t\t\telse if (code <= 0xffff)\n\t\t\t\t\t\tescape = 4;\n\t\t\t\t\telse\n\t\t\t\t\t\tescape = 8;\n\n\t\t\t\t\tif (escape === 0)\n\t\t\t\t\t\tresult += c;\n\t\t\t\t\telse if (escape === 2)\n\t\t\t\t\t\tresult += \"\\\\x\" + ul4._lpad(code.toString(16), \"0\", 2);\n\t\t\t\t\telse if (escape === 4)\n\t\t\t\t\t\tresult += \"\\\\u\" + ul4._lpad(code.toString(16), \"0\", 4);\n\t\t\t\t\telse\n\t\t\t\t\t\tresult += \"\\\\U\" + ul4._lpad(code.toString(16), \"0\", 8);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn quote + result + quote;\n\t};\n\n\tul4._date_repr = function _date_repr(obj, ascii)\n\t{\n\t\tlet year = obj._date.getFullYear();\n\t\tlet month = obj._date.getMonth()+1;\n\t\tlet day = obj._date.getDate();\n\t\tlet result = \"@(\" + year + \"-\" + ul4._lpad(month.toString(), \"0\", 2) + \"-\" + ul4._lpad(day.toString(), \"0\", 2) + \")\";\n\t\treturn result;\n\t};\n\n\tul4._datetime_repr = function _datetime_repr(obj, ascii)\n\t{\n\t\tlet year = obj.getFullYear();\n\t\tlet month = obj.getMonth()+1;\n\t\tlet day = obj.getDate();\n\t\tlet hour = obj.getHours();\n\t\tlet minute = obj.getMinutes();\n\t\tlet second = obj.getSeconds();\n\t\tlet ms = obj.getMilliseconds();\n\t\tlet result = \"@(\" + year + \"-\" + ul4._lpad(month.toString(), \"0\", 2) + \"-\" + ul4._lpad(day.toString(), \"0\", 2) + \"T\";\n\n\t\tif (hour || minute || second || ms)\n\t\t{\n\t\t\tresult += ul4._lpad(hour.toString(), \"0\", 2) + \":\" + ul4._lpad(minute.toString(), \"0\", 2);\n\t\t\tif (second || ms)\n\t\t\t{\n\t\t\t\tresult += \":\" + ul4._lpad(second.toString(), \"0\", 2);\n\t\t\t\tif (ms)\n\t\t\t\t\tresult += \".\" + ul4._lpad(ms.toString(), \"0\", 3) + \"000\";\n\t\t\t}\n\t\t}\n\t\tresult += \")\";\n\n\t\treturn result;\n\t};\n\n\tul4._map_repr = function _map_repr(obj, ascii)\n\t{\n\t\tlet v = [];\n\t\tv.push(\"{\");\n\n\t\tlet i = 0;\n\t\tobj.forEach(function(value, key) {\n\t\t\tif (i++)\n\t\t\t\tv.push(\", \");\n\t\t\tv.push(ul4._repr_internal(key, ascii));\n\t\t\tv.push(\": \");\n\t\t\tv.push(ul4._repr_internal(value, ascii));\n\t\t});\n\n\t\tv.push(\"}\");\n\t\treturn v.join(\"\");\n\t};\n\n\tul4._list_repr = function _list_repr(obj, ascii)\n\t{\n\t\tlet v = [];\n\t\tv.push(\"[\");\n\t\tfor (let i = 0; i < obj.length; ++i)\n\t\t{\n\t\t\tlet item = obj[i];\n\t\t\tif (i)\n\t\t\t\tv.push(\", \");\n\t\t\tv.push(ul4._repr_internal(item, ascii));\n\t\t}\n\t\tv.push(\"]\");\n\t\treturn v.join(\"\");\n\t};\n\n\tul4._set_repr = function _set_repr(obj, ascii)\n\t{\n\t\tlet v = [];\n\t\tv.push(\"{\");\n\t\tif (!obj.size)\n\t\t\tv.push(\"/\");\n\t\telse\n\t\t{\n\t\t\tlet i = 0;\n\t\t\tobj.forEach(function(value) {\n\t\t\t\tif (i++)\n\t\t\t\t\tv.push(\", \");\n\t\t\t\tv.push(ul4._repr_internal(value, ascii));\n\t\t\t});\n\t\t}\n\t\tv.push(\"}\");\n\t\treturn v.join(\"\");\n\t};\n\n\tul4._object_repr = function _object_repr(obj, ascii)\n\t{\n\t\tlet v = [];\n\t\tv.push(\"{\");\n\t\tlet i = 0;\n\t\tfor (let key in obj)\n\t\t{\n\t\t\tif (!obj.hasOwnProperty(key))\n\t\t\t\tcontinue;\n\t\t\tif (i++)\n\t\t\t\tv.push(\", \");\n\t\t\tv.push(ul4._repr_internal(key, ascii));\n\t\t\tv.push(\": \");\n\t\t\tv.push(ul4._repr_internal(obj[key], ascii));\n\t\t}\n\t\tv.push(\"}\");\n\t\treturn v.join(\"\");\n\t};\n\n\tul4._repr_internal = function _repr_internal(obj, ascii)\n\t{\n\t\tif (obj === null)\n\t\t\treturn \"None\";\n\t\telse if (obj === false)\n\t\t\treturn \"False\";\n\t\telse if (obj === true)\n\t\t\treturn \"True\";\n\t\telse if (typeof(obj) === \"string\")\n\t\t\treturn ul4._str_repr(obj, ascii);\n\t\telse if (typeof(obj) === \"number\")\n\t\t\treturn \"\" + obj;\n\t\telse if (typeof(obj) === \"function\")\n\t\t\tif (obj._ul4_name || obj.name)\n\t\t\t\treturn \"\";\n\t\t\telse\n\t\t\t\treturn \"\";\n\t\telse if (ul4._isdate(obj))\n\t\t\treturn ul4._date_repr(obj, ascii);\n\t\telse if (ul4._isdatetime(obj))\n\t\t\treturn ul4._datetime_repr(obj, ascii);\n\t\telse if (typeof(obj) === \"undefined\")\n\t\t\treturn \"\";\n\t\telse if (typeof(obj) === \"object\" && typeof(obj.__repr__) === \"function\")\n\t\t\treturn obj.__repr__();\n\t\telse if (ul4._islist(obj))\n\t\t\treturn ul4._list_repr(obj, ascii);\n\t\telse if (ul4._ismap(obj))\n\t\t\treturn ul4._map_repr(obj, ascii);\n\t\telse if (ul4._isset(obj))\n\t\t\treturn ul4._set_repr(obj, ascii);\n\t\telse if (ul4._isobject(obj))\n\t\t\treturn ul4._object_repr(obj, ascii);\n\t\treturn \"?\";\n\t};\n\n\t// Return a string representation of ``obj``: If possible this should be an object literal supported by UL4, otherwise the output should be bracketed with ``<`` and ``>``\n\tul4._repr = function _repr(obj)\n\t{\n\t\treturn ul4._repr_internal(obj, false);\n\t};\n\n\tul4._ascii = function _ascii(obj)\n\t{\n\t\treturn ul4._repr_internal(obj, true);\n\t};\n\n\tul4._date_str = function _date_str(obj)\n\t{\n\t\tlet year = obj._date.getFullYear();\n\t\tlet month = obj._date.getMonth()+1;\n\t\tlet day = obj._date.getDate();\n\n\t\treturn year + \"-\" + ul4._lpad(month.toString(), \"0\", 2) + \"-\" + ul4._lpad(day.toString(), \"0\", 2);\n\t};\n\n\tul4._datetime_str = function _datetime_str(obj)\n\t{\n\t\tlet year = obj.getFullYear();\n\t\tlet month = obj.getMonth()+1;\n\t\tlet day = obj.getDate();\n\t\tlet hour = obj.getHours();\n\t\tlet minute = obj.getMinutes();\n\t\tlet second = obj.getSeconds();\n\t\tlet ms = obj.getMilliseconds();\n\n\t\tlet result = year + \"-\" + ul4._lpad(month.toString(), \"0\", 2) + \"-\" + ul4._lpad(day.toString(), \"0\", 2) + \" \" + ul4._lpad(hour.toString(), \"0\", 2) + \":\" + ul4._lpad(minute.toString(), \"0\", 2);\n\t\tif (second || ms)\n\t\t{\n\t\t\tresult += \":\" + ul4._lpad(second.toString(), \"0\", 2);\n\t\t\tif (ms)\n\t\t\t\tresult += \".\" + ul4._lpad(ms.toString(), \"0\", 3) + \"000\";\n\t\t}\n\t\treturn result;\n\t};\n\n\tul4._str = function _str(obj)\n\t{\n\t\tif (typeof(obj) === \"undefined\")\n\t\t\treturn \"\";\n\t\telse if (obj === null)\n\t\t\treturn \"\";\n\t\telse if (obj === false)\n\t\t\treturn \"False\";\n\t\telse if (obj === true)\n\t\t\treturn \"True\";\n\t\telse if (typeof(obj) === \"string\")\n\t\t\treturn obj;\n\t\telse if (typeof(obj) === \"number\")\n\t\t\treturn obj.toString();\n\t\telse if (ul4._isdate(obj))\n\t\t\treturn ul4._date_str(obj);\n\t\telse if (ul4._isdatetime(obj))\n\t\t\treturn ul4._datetime_str(obj);\n\t\telse if (ul4._islist(obj))\n\t\t\treturn ul4._list_repr(obj);\n\t\telse if (ul4._isset(obj))\n\t\t\treturn ul4._set_repr(obj);\n\t\telse if (ul4._ismap(obj))\n\t\t\treturn ul4._map_repr(obj);\n\t\telse if (typeof(obj) === \"object\" && typeof(obj.__str__) === \"function\")\n\t\t\treturn obj.__str__();\n\t\telse if (typeof(obj) === \"object\" && typeof(obj.__repr__) === \"function\")\n\t\t\treturn obj.__repr__();\n\t\telse if (ul4._isobject(obj))\n\t\t\treturn ul4._object_repr(obj);\n\t\treturn \"?\";\n\t};\n\n\t// Convert ``obj`` to bool, according to its \"truth value\"\n\tul4._bool = function _bool(obj)\n\t{\n\t\tif (typeof(obj) === \"undefined\" || obj === null || obj === false || obj === 0 || obj === \"\")\n\t\t\treturn false;\n\t\telse\n\t\t{\n\t\t\tif (typeof(obj) === \"object\", typeof(obj.__bool__) === \"function\")\n\t\t\t\treturn obj.__bool__();\n\t\t\tif (ul4._islist(obj))\n\t\t\t\treturn obj.length !== 0;\n\t\t\telse if (ul4._ismap(obj) || ul4._isset(obj))\n\t\t\t\treturn obj.size != 0;\n\t\t\telse if (ul4._isobject(obj))\n\t\t\t{\n\t\t\t\tfor (let key in obj)\n\t\t\t\t{\n\t\t\t\t\tif (!obj.hasOwnProperty(key))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t};\n\n\t// Convert ``obj`` to an integer (if ``base`` is given ``obj`` must be a string and ``base`` is the base for the conversion (default is 10))\n\tul4._int = function _int(obj, base)\n\t{\n\t\tlet result;\n\t\tif (base !== null)\n\t\t{\n\t\t\tif (typeof(obj) !== \"string\" || !ul4._isint(base))\n\t\t\t\tthrow new ul4.TypeError(\"int() requires a string and an integer\");\n\t\t\tresult = parseInt(obj, base);\n\t\t\tif (result.toString() == \"NaN\")\n\t\t\t\tthrow new ul4.TypeError(\"invalid literal for int()\");\n\t\t\treturn result;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (typeof(obj) == \"string\")\n\t\t\t{\n\t\t\t\tresult = parseInt(obj);\n\t\t\t\tif (result.toString() == \"NaN\")\n\t\t\t\tthrow new ul4.TypeError(\"invalid literal for int()\");\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\telse if (typeof(obj) == \"number\")\n\t\t\t\treturn Math.floor(obj);\n\t\t\telse if (obj === true)\n\t\t\t\treturn 1;\n\t\t\telse if (obj === false)\n\t\t\t\treturn 0;\n\t\t\tthrow new ul4.TypeError(\"int() argument must be a string or a number\");\n\t\t}\n\t};\n\n\t// Convert ``obj`` to a float\n\tul4._float = function _float(obj)\n\t{\n\t\tif (typeof(obj) === \"string\")\n\t\t\treturn parseFloat(obj);\n\t\telse if (typeof(obj) === \"number\")\n\t\t\treturn obj;\n\t\telse if (obj === true)\n\t\t\treturn 1.0;\n\t\telse if (obj === false)\n\t\t\treturn 0.0;\n\t\tthrow new ul4.TypeError(\"float() argument must be a string or a number\");\n\t};\n\n\t// Convert ``obj`` to a list\n\tul4._list = function _list(obj)\n\t{\n\t\tlet iter = ul4._iter(obj);\n\n\t\tlet result = [];\n\t\tfor (;;)\n\t\t{\n\t\t\tlet value = iter.next();\n\t\t\tif (value.done)\n\t\t\t\treturn result;\n\t\t\tresult.push(value.value);\n\t\t}\n\t};\n\n\t// Convert ``obj`` to a set\n\tul4._set = function _set(obj)\n\t{\n\t\tlet iter = ul4._iter(obj);\n\n\t\tlet result = ul4._emptyset();\n\t\tfor (;;)\n\t\t{\n\t\t\tlet value = iter.next();\n\t\t\tif (value.done)\n\t\t\t\treturn result;\n\t\t\tresult.add(value.value);\n\t\t}\n\t};\n\n\t// Return the length of ``sequence``\n\tul4._len = function _len(sequence)\n\t{\n\t\tif (typeof(sequence) == \"string\" || ul4._islist(sequence))\n\t\t\treturn sequence.length;\n\t\telse if (ul4._ismap(sequence) || ul4._isset(sequence))\n\t\t\treturn sequence.size;\n\t\telse if (ul4._isobject(sequence))\n\t\t{\n\t\t\tlet i = 0;\n\t\t\tfor (let key in sequence)\n\t\t\t\t++i;\n\t\t\treturn i;\n\t\t}\n\t\tthrow new ul4.TypeError(\"object of type '\" + ul4._type(sequence) + \"' has no len()\");\n\t};\n\n\tul4._type = function _type(obj)\n\t{\n\t\tif (obj === null)\n\t\t\treturn \"none\";\n\t\telse if (obj === false || obj === true)\n\t\t\treturn \"bool\";\n\t\telse if (typeof(obj) === \"undefined\")\n\t\t\treturn \"undefined\";\n\t\telse if (typeof(obj) === \"number\")\n\t\t\treturn Math.round(obj) == obj ? \"int\" : \"float\";\n\t\telse if (typeof(obj) === \"function\")\n\t\t\treturn \"function\";\n\t\telse\n\t\t{\n\t\t\tif (typeof(obj.ul4type) === \"function\")\n\t\t\t\treturn obj.ul4type();\n\t\t\telse\n\t\t\t\treturn ul4.Protocol.get(obj).ul4type(obj);\n\t\t}\n\t};\n\n\t// (this is non-trivial, because it follows the Python semantic of ``-5 % 2`` being ``1``)\n\tul4._mod = function _mod(obj1, obj2)\n\t{\n\t\tlet div = Math.floor(obj1 / obj2);\n\t\tlet mod = obj1 - div * obj2;\n\n\t\tif (mod !== 0 && ((obj2 < 0 && mod > 0) || (obj2 > 0 && mod < 0)))\n\t\t{\n\t\t\tmod += obj2;\n\t\t\t--div;\n\t\t}\n\t\treturn obj1 - div * obj2;\n\t},\n\n\t// Return the attribute with the name ``attrname`` of the object ``obj``\n\t// If ``obj`` doesn't have such an attribute, return ``default_``\n\tul4._getattr = function _getattr(obj, attrname, default_=null)\n\t{\n\t\tlet proto = ul4.Protocol.get(obj);\n\t\ttry\n\t\t{\n\t\t\treturn proto.getattr(obj, attrname);\n\t\t}\n\t\tcatch (exc)\n\t\t{\n\t\t\tif (exc instanceof ul4.AttributeError && exc.obj === obj)\n\t\t\t\treturn default_;\n\t\t\telse\n\t\t\t\tthrow exc;\n\t\t}\n\t};\n\n\t// Return wether the object ``obj`` has an attribute with the name ``attrname``\n\tul4._hasattr = function _hasattr(obj, attrname)\n\t{\n\t\tlet proto = ul4.Protocol.get(obj);\n\t\treturn proto.hasattr(obj, attrname);\n\t};\n\n\t// Return the names of the attributes of the object ``obj`` as a set.\n\tul4._dir = function _dir(obj)\n\t{\n\t\tlet proto = ul4.Protocol.get(obj);\n\t\treturn proto.dir();\n\t};\n\n\t// Return whether any of the items in ``iterable`` are true\n\tul4._any = function _any(iterable)\n\t{\n\t\tif (typeof(iterable) == \"string\")\n\t\t{\n\t\t\tfor (let i = 0; i < iterable.length; ++i)\n\t\t\t{\n\t\t\t\tif (iterable[i] !== '\\x00')\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (let iter = ul4._iter(iterable);;)\n\t\t\t{\n\t\t\t\tlet item = iter.next();\n\t\t\t\tif (item.done)\n\t\t\t\t\treturn false;\n\t\t\t\tif (ul4._bool(item.value))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t};\n\n\t// Return whether all of the items in ``iterable`` are true\n\tul4._all = function _all(iterable)\n\t{\n\t\tif (typeof(iterable) == \"string\")\n\t\t{\n\t\t\tfor (let i = 0; i < iterable.length; ++i)\n\t\t\t{\n\t\t\t\tif (iterable[i] === '\\x00')\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (let iter = ul4._iter(iterable);;)\n\t\t\t{\n\t\t\t\tlet item = iter.next();\n\t\t\t\tif (item.done)\n\t\t\t\t\treturn true;\n\t\t\t\tif (!ul4._bool(item.value))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t};\n\n\t// Check if ``obj`` is undefined\n\tul4._isundefined = function _isundefined(obj)\n\t{\n\t\treturn typeof(obj) === \"undefined\";\n\t};\n\n\n\t// Check if ``obj`` is *not* undefined\n\tul4._isdefined = function _isdefined(obj)\n\t{\n\t\treturn typeof(obj) !== \"undefined\";\n\t};\n\n\t// Check if ``obj`` is ``None``\n\tul4._isnone = function _isnone(obj)\n\t{\n\t\treturn obj === null;\n\t};\n\n\t// Check if ``obj`` is a boolean\n\tul4._isbool = function _isbool(obj)\n\t{\n\t\treturn typeof(obj) == \"boolean\";\n\t};\n\n\t// Check if ``obj`` is a int\n\tul4._isint = function _isint(obj)\n\t{\n\t\treturn (typeof(obj) == \"number\") && Math.round(obj) == obj;\n\t};\n\n\t// Check if ``obj`` is a float\n\tul4._isfloat = function _isfloat(obj)\n\t{\n\t\treturn (typeof(obj) == \"number\") && Math.round(obj) != obj;\n\t};\n\n\t// Check if ``obj`` is a string\n\tul4._isstr = function _isstr(obj)\n\t{\n\t\treturn typeof(obj) == \"string\";\n\t};\n\n\t// Check if ``obj`` is a datetime\n\tul4._isdatetime = function _isdate(obj)\n\t{\n\t\treturn Object.prototype.toString.call(obj) == \"[object Date]\";\n\t};\n\n\tul4._isdate = function _isdate(obj)\n\t{\n\t\treturn (obj instanceof ul4.Date);\n\t};\n\n\t// Check if ``obj`` is a color\n\tul4._iscolor = function _iscolor(obj)\n\t{\n\t\treturn (obj instanceof ul4.Color);\n\t};\n\n\t// Check if ``obj`` is a timedelta object\n\tul4._istimedelta = function _istimedelta(obj)\n\t{\n\t\treturn (obj instanceof ul4.TimeDelta);\n\t};\n\n\t// Check if ``obj`` is a monthdelta object\n\tul4._ismonthdelta = function _ismonthdelta(obj)\n\t{\n\t\treturn (obj instanceof ul4.MonthDelta);\n\t};\n\n\t// Check if ``obj`` is a template\n\tul4._istemplate = function _istemplate(obj)\n\t{\n\t\treturn (obj instanceof ul4.Template || obj instanceof ul4.TemplateClosure);\n\t};\n\n\t// Check if ``obj`` is a function\n\tul4._isfunction = function _isfunction(obj)\n\t{\n\t\treturn typeof(obj) === \"function\" || (Object.prototype.toString.call(obj) == \"[object Object]\" && (obj instanceof ul4.Template || obj instanceof ul4.TemplateClosure));\n\t};\n\n\t// Check if ``obj`` is a list\n\tul4._islist = function _islist(obj)\n\t{\n\t\treturn Object.prototype.toString.call(obj) == \"[object Array]\";\n\t};\n\n\t// Check if ``obj`` is a set\n\tul4._isset = function _isset(obj)\n\t{\n\t\treturn Object.prototype.toString.call(obj) == \"[object Set]\";\n\t};\n\n\t// Check if ``obj`` is an exception (at least a UL4 exception)\n\tul4._isexception = function _isexception(obj)\n\t{\n\t\treturn (obj instanceof ul4.Exception);\n\t};\n\n\tul4._isul4set = function _isul4set(obj)\n\t{\n\t\treturn (obj instanceof ul4._Set);\n\t};\n\n\tul4._isanyset = function _isanyset(obj)\n\t{\n\t\treturn (ul4._isset(obj) || ul4._isul4set(obj));\n\t};\n\n\t// Check if ``obj`` is an iterator\n\tul4._isiter = function _isiter(obj)\n\t{\n\t\treturn obj !== null && typeof(obj) === \"object\" && typeof(obj.next) === \"function\";\n\t};\n\n\t// Check if ``obj`` is a JS object\n\tul4._isobject = function _isobject(obj)\n\t{\n\t\treturn Object.prototype.toString.call(obj) == \"[object Object]\" && typeof(obj.__type__) === \"undefined\" && !(obj instanceof ul4.Proto);\n\t};\n\n\tif (ul4._havemap)\n\t{\n\t\t// Check if ``obj`` is a ``Map``\n\t\tul4._ismap = function _ismap(obj)\n\t\t{\n\t\t\treturn obj !== null && typeof(obj) === \"object\" && typeof(obj.__proto__) === \"object\" && obj.__proto__ === Map.prototype;\n\t\t};\n\n\t\t// Check if ``obj`` is a dict (i.e. a normal Javascript object or a ``Map``)\n\t\tul4._isdict = function _isdict(obj)\n\t\t{\n\t\t\treturn ul4._isobject(obj) || ul4._ismap(obj);\n\t\t};\n\t}\n\telse\n\t{\n\t\tul4._ismap = function _ismap(obj)\n\t\t{\n\t\t\treturn false;\n\t\t};\n\n\t\tul4._isdict = function _isdict(obj)\n\t\t{\n\t\t\treturn ul4._isobject(obj);\n\t\t};\n\t}\n\n\t// Repeat string ``str`` ``rep`` times\n\tul4._str_repeat = function _str_repeat(str, rep)\n\t{\n\t\tlet result = \"\";\n\t\tfor (; rep>0; --rep)\n\t\t\tresult += str;\n\t\treturn result;\n\t};\n\n\tul4._list_repeat = function _list_repeat(list, rep)\n\t{\n\t\tlet result = [];\n\t\tfor (; rep>0; --rep)\n\t\t\tfor (let i = 0; i < list.length; ++i)\n\t\t\t\tresult.push(list[i]);\n\t\treturn result;\n\t};\n\n\tul4._str_json = function _str_json(str)\n\t{\n\t\tlet result = \"\";\n\t\tfor (let i = 0; i < str.length; ++i)\n\t\t{\n\t\t\tlet c = str[i];\n\t\t\tswitch (c)\n\t\t\t{\n\t\t\t\tcase \"\\r\":\n\t\t\t\t\tresult += \"\\\\r\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"\\n\":\n\t\t\t\t\tresult += \"\\\\n\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"\\t\":\n\t\t\t\t\tresult += \"\\\\t\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"\\\\\":\n\t\t\t\t\tresult += \"\\\\\\\\\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase '\"':\n\t\t\t\t\tresult += '\\\\\"';\n\t\t\t\t\tbreak;\n\t\t\t\tcase '<':\n\t\t\t\t\tresult += '\\\\u003c';\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tlet code = c.charCodeAt(0);\n\t\t\t\t\tif (code >= 32 && code < 128)\n\t\t\t\t\t\tresult += c;\n\t\t\t\t\telse\n\t\t\t\t\t\tresult += \"\\\\u\" + ul4._lpad(code.toString(16), \"0\", 4);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn '\"' + result + '\"';\n\t};\n\n\t// Encodes ``obj`` in the Javascript Object Notation (see http://json.org/; with support for dates, colors and templates)\n\tul4._asjson = function _asjson(obj)\n\t{\n\t\tif (obj === null)\n\t\t\treturn \"null\";\n\t\telse if (typeof(obj) === \"undefined\")\n\t\t\treturn \"undefined\";\n\t\telse if (obj === false)\n\t\t\treturn \"false\";\n\t\telse if (obj === true)\n\t\t\treturn \"true\";\n\t\telse if (typeof(obj) === \"string\")\n\t\t\treturn ul4._str_json(obj);\n\t\telse if (typeof(obj) === \"number\")\n\t\t{\n\t\t\treturn \"\" + obj;\n\t\t}\n\t\telse if (ul4._islist(obj))\n\t\t{\n\t\t\tlet v = [];\n\t\t\tv.push(\"[\");\n\t\t\tfor (let i = 0; i < obj.length; ++i)\n\t\t\t{\n\t\t\t\tif (i != 0)\n\t\t\t\t\tv.push(\", \");\n\t\t\t\tv.push(ul4._asjson(obj[i]));\n\t\t\t}\n\t\t\tv.push(\"]\");\n\t\t\treturn v.join(\"\");\n\t\t}\n\t\telse if (ul4._ismap(obj))\n\t\t{\n\t\t\tlet v = [];\n\t\t\tv.push(\"{\");\n\t\t\tlet i = 0;\n\t\t\tobj.forEach(function(value, key) {\n\t\t\t\tif (i++)\n\t\t\t\t\tv.push(\", \");\n\t\t\t\tv.push(ul4._asjson(key));\n\t\t\t\tv.push(\": \");\n\t\t\t\tv.push(ul4._asjson(value));\n\t\t\t});\n\t\t\tv.push(\"}\");\n\t\t\treturn v.join(\"\");\n\t\t}\n\t\telse if (ul4._isobject(obj))\n\t\t{\n\t\t\tlet v = [];\n\t\t\tv.push(\"{\");\n\t\t\tlet i = 0;\n\t\t\tfor (let key in obj)\n\t\t\t{\n\t\t\t\tif (i++)\n\t\t\t\t\tv.push(\", \");\n\t\t\t\tv.push(ul4._asjson(key));\n\t\t\t\tv.push(\": \");\n\t\t\t\tv.push(ul4._asjson(obj[key]));\n\t\t\t}\n\t\t\tv.push(\"}\");\n\t\t\treturn v.join(\"\");\n\t\t}\n\t\telse if (ul4._isdate(obj))\n\t\t{\n\t\t\treturn \"new ul4.Date(\" + obj._date.getFullYear() + \", \" + (obj._date.getMonth()+1) + \", \" + obj._date.getDate() + \")\";\n\t\t}\n\t\telse if (ul4._isdatetime(obj))\n\t\t{\n\t\t\treturn \"new Date(\" + obj.getFullYear() + \", \" + obj.getMonth() + \", \" + obj.getDate() + \", \" + obj.getHours() + \", \" + obj.getMinutes() + \", \" + obj.getSeconds() + \", \" + obj.getMilliseconds() + \")\";\n\t\t}\n\t\telse if (ul4._istimedelta(obj))\n\t\t{\n\t\t\treturn \"new ul4.TimeDelta(\" + obj._days + \", \" + obj._seconds + \", \" + obj._microseconds + \")\";\n\t\t}\n\t\telse if (ul4._ismonthdelta(obj))\n\t\t{\n\t\t\treturn \"new ul4.MonthDelta(\" + obj._months + \")\";\n\t\t}\n\t\telse if (ul4._iscolor(obj))\n\t\t{\n\t\t\treturn \"new ul4.Color(\" + obj._r + \", \" + obj._g + \", \" + obj._b + \", \" + obj._a + \")\";\n\t\t}\n\t\telse if (ul4._istemplate(obj))\n\t\t{\n\t\t\treturn \"ul4.Template.loads(\" + ul4._repr(obj.dumps()) + \")\";\n\t\t}\n\t\tthrow new ul4.TypeError(\"asjson() requires a serializable object\");\n\t};\n\n\t// Decodes the string ``string`` from the Javascript Object Notation (see http://json.org/) and returns the resulting object\n\tul4._fromjson = function _fromjson(string)\n\t{\n\t\t// The following is from jQuery's parseJSON function\n\t\tstring = ul4.StrProtocol.strip(string);\n\t\tif (root.JSON && root.JSON.parse)\n\t\t\treturn root.JSON.parse(string);\n\t\tif (ul4._rvalidchars.test(string.replace(ul4._rvalidescape, \"@\").replace(ul4._rvalidtokens, \"]\").replace(ul4._rvalidbraces, \"\")))\n\t\t\treturn (new Function(\"return \" + string))();\n\t\tthrow new ul4.TypeError(\"invalid JSON\");\n\t};\n\n\t// Encodes ``obj`` in the UL4 Object Notation format\n\tul4._asul4on = function _asul4on(obj)\n\t{\n\t\treturn ul4.dumps(obj);\n\t};\n\n\t// Decodes the string ``string`` from the UL4 Object Notation format and returns the resulting decoded object\n\tul4._fromul4on = function _fromul4on(string)\n\t{\n\t\treturn ul4.loads(string);\n\t};\n\n\tul4._format_datetime = function _format_datetime(obj, fmt, lang)\n\t{\n\t\tlet translations = {\n\t\t\tde: {\n\t\t\t\tms: [\"Jan\", \"Feb\", \"M\\u00e4r\", \"Apr\", \"Mai\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dez\"],\n\t\t\t\tml: [\"Januar\", \"Februar\", \"M\\u00e4rz\", \"April\", \"Mai\", \"Juni\", \"Juli\", \"August\", \"September\", \"Oktober\", \"November\", \"Dezember\"],\n\t\t\t\tws: [\"So\", \"Mo\", \"Di\", \"Mi\", \"Do\", \"Fr\", \"Sa\"],\n\t\t\t\twl: [\"Sonntag\", \"Montag\", \"Dienstag\", \"Mittwoch\", \"Donnerstag\", \"Freitag\", \"Samstag\"],\n\t\t\t\txf: \"%d.%m.%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a %d %b %Y %H:%M:%S\"\n\t\t\t},\n\t\t\ten: {\n\t\t\t\tms: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n\t\t\t\tml: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n\t\t\t\tws: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n\t\t\t\twl: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n\t\t\t\txf: \"%m/%d/%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a %d %b %Y %I:%M:%S %p\"\n\t\t\t},\n\t\t\tfr: {\n\t\t\t\tms: [\"janv.\", \"f\\u00e9vr.\", \"mars\", \"avril\", \"mai\", \"juin\", \"juil.\", \"ao\\u00fbt\", \"sept.\", \"oct.\", \"nov.\", \"d\\u00e9c.\"],\n\t\t\t\tml: [\"janvier\", \"f\\u00e9vrier\", \"mars\", \"avril\", \"mai\", \"juin\", \"juillet\", \"ao\\u00fbt\", \"septembre\", \"octobre\", \"novembre\", \"d\\u00e9cembre\"],\n\t\t\t\tws: [\"dim.\", \"lun.\", \"mar.\", \"mer.\", \"jeu.\", \"ven.\", \"sam.\"],\n\t\t\t\twl: [\"dimanche\", \"lundi\", \"mardi\", \"mercredi\", \"jeudi\", \"vendredi\", \"samedi\"],\n\t\t\t\txf: \"%d/%m/%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a %d %b %Y %H:%M:%S\"\n\t\t\t},\n\t\t\tes: {\n\t\t\t\tms: [\"ene\", \"feb\", \"mar\", \"abr\", \"may\", \"jun\", \"jul\", \"ago\", \"sep\", \"oct\", \"nov\", \"dic\"],\n\t\t\t\tml: [\"enero\", \"febrero\", \"marzo\", \"abril\", \"mayo\", \"junio\", \"julio\", \"agosto\", \"septiembre\", \"octubre\", \"noviembre\", \"diciembre\"],\n\t\t\t\tws: [\"dom\", \"lun\", \"mar\", \"mi\\u00e9\", \"jue\", \"vie\", \"s\\u00e1b\"],\n\t\t\t\twl: [\"domingo\", \"lunes\", \"martes\", \"mi\\u00e9rcoles\", \"jueves\", \"viernes\", \"s\\u00e1bado\"],\n\t\t\t\txf: \"%d/%m/%y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a %d %b %Y %H:%M:%S\"\n\t\t\t},\n\t\t\tit: {\n\t\t\t\tms: [\"gen\", \"feb\", \"mar\", \"apr\", \"mag\", \"giu\", \"lug\", \"ago\", \"set\", \"ott\", \"nov\", \"dic\"],\n\t\t\t\tml: [\"gennaio\", \"febbraio\", \"marzo\", \"aprile\", \"maggio\", \"giugno\", \"luglio\", \"agosto\", \"settembre\", \"ottobre\", \"novembre\", \"dicembre\"],\n\t\t\t\tws: [\"dom\", \"lun\", \"mar\", \"mer\", \"gio\", \"ven\", \"sab\"],\n\t\t\t\twl: [\"domenica\", \"luned\\u00ec\", \"marted\\u00ec\", \"mercoled\\u00ec\", \"gioved\\u00ec\", \"venerd\\u00ec\", \"sabato\"],\n\t\t\t\txf: \"%d/%m/%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a %d %b %Y %H:%M:%S\"\n\t\t\t},\n\t\t\tda: {\n\t\t\t\tms: [\"jan\", \"feb\", \"mar\", \"apr\", \"maj\", \"jun\", \"jul\", \"aug\", \"sep\", \"okt\", \"nov\", \"dec\"],\n\t\t\t\tml: [\"januar\", \"februar\", \"marts\", \"april\", \"maj\", \"juni\", \"juli\", \"august\", \"september\", \"oktober\", \"november\", \"december\"],\n\t\t\t\tws: [\"s\\u00f8n\", \"man\", \"tir\", \"ons\", \"tor\", \"fre\", \"l\\u00f8r\"],\n\t\t\t\twl: [\"s\\u00f8ndag\", \"mandag\", \"tirsdag\", \"onsdag\", \"torsdag\", \"fredag\", \"l\\u00f8rdag\"],\n\t\t\t\txf: \"%d-%m-%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a %d %b %Y %H:%M:%S\"\n\t\t\t},\n\t\t\tsv: {\n\t\t\t\tms: [\"jan\", \"feb\", \"mar\", \"apr\", \"maj\", \"jun\", \"jul\", \"aug\", \"sep\", \"okt\", \"nov\", \"dec\"],\n\t\t\t\tml: [\"januari\", \"februari\", \"mars\", \"april\", \"maj\", \"juni\", \"juli\", \"augusti\", \"september\", \"oktober\", \"november\", \"december\"],\n\t\t\t\tws: [\"s\\u00f6n\", \"m\\u00e5n\", \"tis\", \"ons\", \"tor\", \"fre\", \"l\\u00f6r\"],\n\t\t\t\twl: [\"s\\u00f6ndag\", \"m\\u00e5ndag\", \"tisdag\", \"onsdag\", \"torsdag\", \"fredag\", \"l\\u00f6rdag\"],\n\t\t\t\txf: \"%Y-%m-%d\",\n\t\t\t\tXf: \"%H.%M.%S\",\n\t\t\t\tcf: \"%a %d %b %Y %H.%M.%S\"\n\t\t\t},\n\t\t\tnl: {\n\t\t\t\tms: [\"jan\", \"feb\", \"mrt\", \"apr\", \"mei\", \"jun\", \"jul\", \"aug\", \"sep\", \"okt\", \"nov\", \"dec\"],\n\t\t\t\tml: [\"januari\", \"februari\", \"maart\", \"april\", \"mei\", \"juni\", \"juli\", \"augustus\", \"september\", \"oktober\", \"november\", \"december\"],\n\t\t\t\tws: [\"zo\", \"ma\", \"di\", \"wo\", \"do\", \"vr\", \"za\"],\n\t\t\t\twl: [\"zondag\", \"maandag\", \"dinsdag\", \"woensdag\", \"donderdag\", \"vrijdag\", \"zaterdag\"],\n\t\t\t\txf: \"%d-%m-%y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a %d %b %Y %H:%M:%S\"\n\t\t\t},\n\t\t\tpt: {\n\t\t\t\tms: [\"Jan\", \"Fev\", \"Mar\", \"Abr\", \"Mai\", \"Jun\", \"Jul\", \"Ago\", \"Set\", \"Out\", \"Nov\", \"Dez\"],\n\t\t\t\tml: [\"Janeiro\", \"Fevereiro\", \"Mar\\u00e7o\", \"Abril\", \"Maio\", \"Junho\", \"Julho\", \"Agosto\", \"Setembro\", \"Outubro\", \"Novembro\", \"Dezembro\"],\n\t\t\t\tws: [\"Dom\", \"Seg\", \"Ter\", \"Qua\", \"Qui\", \"Sex\", \"S\\u00e1b\"],\n\t\t\t\twl: [\"Domingo\", \"Segunda\", \"Ter\\u00e7a\", \"Quarta\", \"Quinta\", \"Sexta\", \"S\\u00e1bado\"],\n\t\t\t\txf: \"%d-%m-%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a %d %b %Y %H:%M:%S\"\n\t\t\t},\n\t\t\tcs: {\n\t\t\t\tms: [\"led\", \"\\u00fano\", \"b\\u0159e\", \"dub\", \"kv\\u011b\", \"\\u010den\", \"\\u010dec\", \"srp\", \"z\\u00e1\\u0159\", \"\\u0159\\u00edj\", \"lis\", \"pro\"],\n\t\t\t\tml: [\"leden\", \"\\u00fanor\", \"b\\u0159ezen\", \"duben\", \"kv\\u011bten\", \"\\u010derven\", \"\\u010dervenec\", \"srpen\", \"z\\u00e1\\u0159\\u00ed\", \"\\u0159\\u00edjen\", \"listopad\", \"prosinec\"],\n\t\t\t\tws: [\"Ne\", \"Po\", \"\\u00dat\", \"St\", \"\\u010ct\", \"P\\u00e1\", \"So\"],\n\t\t\t\twl: [\"Ned\\u011ble\", \"Pond\\u011bl\\u00ed\", \"\\u00dater\\u00fd\", \"St\\u0159eda\", \"\\u010ctvrtek\", \"P\\u00e1tek\", \"Sobota\"],\n\t\t\t\txf: \"%d.%m.%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a\\u00a0%d.\\u00a0%B\\u00a0%Y,\\u00a0%H:%M:%S\"\n\t\t\t},\n\t\t\tsk: {\n\t\t\t\tms: [\"jan\", \"feb\", \"mar\", \"apr\", \"m\\u00e1j\", \"j\\u00fan\", \"j\\u00fal\", \"aug\", \"sep\", \"okt\", \"nov\", \"dec\"],\n\t\t\t\tml: [\"janu\\u00e1r\", \"febru\\u00e1r\", \"marec\", \"apr\\u00edl\", \"m\\u00e1j\", \"j\\u00fan\", \"j\\u00fal\", \"august\", \"september\", \"okt\\u00f3ber\", \"november\", \"december\"],\n\t\t\t\tws: [\"Ne\", \"Po\", \"Ut\", \"St\", \"\\u0160t\", \"Pi\", \"So\"],\n\t\t\t\twl: [\"Nede\\u013ea\", \"Pondelok\", \"Utorok\", \"Streda\", \"\\u0160tvrtok\", \"Piatok\", \"Sobota\"],\n\t\t\t\txf: \"%d.%m.%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a\\u00a0%d.\\u00a0%B\\u00a0%Y,\\u00a0%H:%M:%S\"\n\t\t\t},\n\t\t\tpl: {\n\t\t\t\tms: [\"sty\", \"lut\", \"mar\", \"kwi\", \"maj\", \"cze\", \"lip\", \"sie\", \"wrz\", \"pa\\u017a\", \"lis\", \"gru\"],\n\t\t\t\tml: [\"stycze\\u0144\", \"luty\", \"marzec\", \"kwiecie\\u0144\", \"maj\", \"czerwiec\", \"lipiec\", \"sierpie\\u0144\", \"wrzesie\\u0144\", \"pa\\u017adziernik\", \"listopad\", \"grudzie\\u0144\"],\n\t\t\t\tws: [\"nie\", \"pon\", \"wto\", \"\\u015bro\", \"czw\", \"pi\\u0105\", \"sob\"],\n\t\t\t\twl: [\"niedziela\", \"poniedzia\\u0142ek\", \"wtorek\", \"\\u015broda\", \"czwartek\", \"pi\\u0105tek\", \"sobota\"],\n\t\t\t\txf: \"%d.%m.%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a, %d %b %Y, %H:%M:%S\"\n\t\t\t},\n\t\t\thr: {\n\t\t\t\tms: [\"Sij\", \"Vel\", \"O\\u017eu\", \"Tra\", \"Svi\", \"Lip\", \"Srp\", \"Kol\", \"Ruj\", \"Lis\", \"Stu\", \"Pro\"],\n\t\t\t\tml: [\"Sije\\u010danj\", \"Velja\\u010da\", \"O\\u017eujak\", \"Travanj\", \"Svibanj\", \"Lipanj\", \"Srpanj\", \"Kolovoz\", \"Rujan\", \"Listopad\", \"Studeni\", \"Prosinac\"],\n\t\t\t\tws: [\"Ned\", \"Pon\", \"Uto\", \"Sri\", \"\\u010cet\", \"Pet\", \"Sub\"],\n\t\t\t\twl: [\"Nedjelja\", \"Ponedjeljak\", \"Utorak\", \"Srijeda\", \"\\u010cetvrtak\", \"Petak\", \"Subota\"],\n\t\t\t\txf: \"%d.%m.%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a %d %b %Y %H:%M:%S\"\n\t\t\t},\n\t\t\tsr: {\n\t\t\t\tms: [\"\\u0458\\u0430\\u043d\", \"\\u0444\\u0435\\u0431\", \"\\u043c\\u0430\\u0440\", \"\\u0430\\u043f\\u0440\", \"\\u043c\\u0430\\u0458\", \"\\u0458\\u0443\\u043d\", \"\\u0458\\u0443\\u043b\", \"\\u0430\\u0432\\u0433\", \"\\u0441\\u0435\\u043f\", \"\\u043e\\u043a\\u0442\", \"\\u043d\\u043e\\u0432\", \"\\u0434\\u0435\\u0446\"],\n\t\t\t\tml: [\"\\u0458\\u0430\\u043d\\u0443\\u0430\\u0440\", \"\\u0444\\u0435\\u0431\\u0440\\u0443\\u0430\\u0440\", \"\\u043c\\u0430\\u0440\\u0442\", \"\\u0430\\u043f\\u0440\\u0438\\u043b\", \"\\u043c\\u0430\\u0458\", \"\\u0458\\u0443\\u043d\", \"\\u0458\\u0443\\u043b\", \"\\u0430\\u0432\\u0433\\u0443\\u0441\\u0442\", \"\\u0441\\u0435\\u043f\\u0442\\u0435\\u043c\\u0431\\u0430\\u0440\", \"\\u043e\\u043a\\u0442\\u043e\\u0431\\u0430\\u0440\", \"\\u043d\\u043e\\u0432\\u0435\\u043c\\u0431\\u0430\\u0440\", \"\\u0434\\u0435\\u0446\\u0435\\u043c\\u0431\\u0430\\u0440\"],\n\t\t\t\tws: [\"\\u043d\\u0435\\u0434\", \"\\u043f\\u043e\\u043d\", \"\\u0443\\u0442\\u043e\", \"\\u0441\\u0440\\u0435\", \"\\u0447\\u0435\\u0442\", \"\\u043f\\u0435\\u0442\", \"\\u0441\\u0443\\u0431\"],\n\t\t\t\twl: [\"\\u043d\\u0435\\u0434\\u0435\\u0459\\u0430\", \"\\u043f\\u043e\\u043d\\u0435\\u0434\\u0435\\u0459\\u0430\\u043a\", \"\\u0443\\u0442\\u043e\\u0440\\u0430\\u043a\", \"\\u0441\\u0440\\u0435\\u0434\\u0430\", \"\\u0447\\u0435\\u0442\\u0432\\u0440\\u0442\\u0430\\u043a\", \"\\u043f\\u0435\\u0442\\u0430\\u043a\", \"\\u0441\\u0443\\u0431\\u043e\\u0442\\u0430\"],\n\t\t\t\txf: \"%d.%m.%Y.\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%A, %d. %B %Y. %H:%M:%S\"\n\t\t\t},\n\t\t\tro: {\n\t\t\t\tms: [\"ian\", \"feb\", \"mar\", \"apr\", \"mai\", \"iun\", \"iul\", \"aug\", \"sep\", \"oct\", \"nov\", \"dec\"],\n\t\t\t\tml: [\"ianuarie\", \"februarie\", \"martie\", \"aprilie\", \"mai\", \"iunie\", \"iulie\", \"august\", \"septembrie\", \"octombrie\", \"noiembrie\", \"decembrie\"],\n\t\t\t\tws: [\"Du\", \"Lu\", \"Ma\", \"Mi\", \"Jo\", \"Vi\", \"Sb\"],\n\t\t\t\twl: [\"duminic\\u0103\", \"luni\", \"mar\\u0163i\", \"miercuri\", \"joi\", \"vineri\", \"s\\u00e2mb\\u0103t\\u0103\"],\n\t\t\t\txf: \"%d.%m.%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a %d %b %Y %H:%M:%S\"\n\t\t\t},\n\t\t\thu: {\n\t\t\t\tms: [\"jan\", \"febr\", \"m\\u00e1rc\", \"\\u00e1pr\", \"m\\u00e1j\", \"j\\u00fan\", \"j\\u00fal\", \"aug\", \"szept\", \"okt\", \"nov\", \"dec\"],\n\t\t\t\tml: [\"janu\\u00e1r\", \"febru\\u00e1r\", \"m\\u00e1rcius\", \"\\u00e1prilis\", \"m\\u00e1jus\", \"j\\u00fanius\", \"j\\u00falius\", \"augusztus\", \"szeptember\", \"okt\\u00f3ber\", \"november\", \"december\"],\n\t\t\t\tws: [\"v\", \"h\", \"k\", \"sze\", \"cs\", \"p\", \"szo\"],\n\t\t\t\twl: [\"vas\\u00e1rnap\", \"h\\u00e9tf\\u0151\", \"kedd\", \"szerda\", \"cs\\u00fct\\u00f6rt\\u00f6k\", \"p\\u00e9ntek\", \"szombat\"],\n\t\t\t\txf: \"%Y-%m-%d\",\n\t\t\t\tXf: \"%H.%M.%S\",\n\t\t\t\tcf: \"%Y. %b. %d., %A, %H.%M.%S\"\n\t\t\t},\n\t\t\ttr: {\n\t\t\t\tms: [\"Oca\", \"\\u015eub\", \"Mar\", \"Nis\", \"May\", \"Haz\", \"Tem\", \"A\\u011fu\", \"Eyl\", \"Eki\", \"Kas\", \"Ara\"],\n\t\t\t\tml: [\"Ocak\", \"\\u015eubat\", \"Mart\", \"Nisan\", \"May\\u0131s\", \"Haziran\", \"Temmuz\", \"A\\u011fustos\", \"Eyl\\u00fcl\", \"Ekim\", \"Kas\\u0131m\", \"Aral\\u0131k\"],\n\t\t\t\tws: [\"Paz\", \"Pzt\", \"Sal\", \"\\u00c7r\\u015f\", \"Pr\\u015f\", \"Cum\", \"Cts\"],\n\t\t\t\twl: [\"Pazar\", \"Pazartesi\", \"Sal\\u0131\", \"\\u00c7ar\\u015famba\", \"Per\\u015fembe\", \"Cuma\", \"Cumartesi\"],\n\t\t\t\txf: \"%d-%m-%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a %d %b %Y %H:%M:%S\"\n\t\t\t},\n\t\t\tru: {\n\t\t\t\tms: [\"\\u042f\\u043d\\u0432\", \"\\u0424\\u0435\\u0432\", \"\\u041c\\u0430\\u0440\", \"\\u0410\\u043f\\u0440\", \"\\u041c\\u0430\\u0439\", \"\\u0418\\u044e\\u043d\", \"\\u0418\\u044e\\u043b\", \"\\u0410\\u0432\\u0433\", \"\\u0421\\u0435\\u043d\", \"\\u041e\\u043a\\u0442\", \"\\u041d\\u043e\\u044f\", \"\\u0414\\u0435\\u043a\"],\n\t\t\t\tml: [\"\\u042f\\u043d\\u0432\\u0430\\u0440\\u044c\", \"\\u0424\\u0435\\u0432\\u0440\\u0430\\u043b\\u044c\", \"\\u041c\\u0430\\u0440\\u0442\", \"\\u0410\\u043f\\u0440\\u0435\\u043b\\u044c\", \"\\u041c\\u0430\\u0439\", \"\\u0418\\u044e\\u043d\\u044c\", \"\\u0418\\u044e\\u043b\\u044c\", \"\\u0410\\u0432\\u0433\\u0443\\u0441\\u0442\", \"\\u0421\\u0435\\u043d\\u0442\\u044f\\u0431\\u0440\\u044c\", \"\\u041e\\u043a\\u0442\\u044f\\u0431\\u0440\\u044c\", \"\\u041d\\u043e\\u044f\\u0431\\u0440\\u044c\", \"\\u0414\\u0435\\u043a\\u0430\\u0431\\u0440\\u044c\"],\n\t\t\t\tws: [\"\\u0412\\u0441\\u043a\", \"\\u041f\\u043d\\u0434\", \"\\u0412\\u0442\\u0440\", \"\\u0421\\u0440\\u0434\", \"\\u0427\\u0442\\u0432\", \"\\u041f\\u0442\\u043d\", \"\\u0421\\u0431\\u0442\"],\n\t\t\t\twl: [\"\\u0412\\u043e\\u0441\\u043a\\u0440\\u0435\\u0441\\u0435\\u043d\\u044c\\u0435\", \"\\u041f\\u043e\\u043d\\u0435\\u0434\\u0435\\u043b\\u044c\\u043d\\u0438\\u043a\", \"\\u0412\\u0442\\u043e\\u0440\\u043d\\u0438\\u043a\", \"\\u0421\\u0440\\u0435\\u0434\\u0430\", \"\\u0427\\u0435\\u0442\\u0432\\u0435\\u0440\\u0433\", \"\\u041f\\u044f\\u0442\\u043d\\u0438\\u0446\\u0430\", \"\\u0421\\u0443\\u0431\\u0431\\u043e\\u0442\\u0430\"],\n\t\t\t\txf: \"%d.%m.%Y\",\n\t\t\t\tXf: \"%H:%M:%S\",\n\t\t\t\tcf: \"%a %d %b %Y %H:%M:%S\"\n\t\t\t},\n\t\t\tzh: {\n\t\t\t\tms: [\" 1\\u6708\", \" 2\\u6708\", \" 3\\u6708\", \" 4\\u6708\", \" 5\\u6708\", \" 6\\u6708\", \" 7\\u6708\", \" 8\\u6708\", \" 9\\u6708\", \"10\\u6708\", \"11\\u6708\", \"12\\u6708\"],\n\t\t\t\tml: [\"\\u4e00\\u6708\", \"\\u4e8c\\u6708\", \"\\u4e09\\u6708\", \"\\u56db\\u6708\", \"\\u4e94\\u6708\", \"\\u516d\\u6708\", \"\\u4e03\\u6708\", \"\\u516b\\u6708\", \"\\u4e5d\\u6708\", \"\\u5341\\u6708\", \"\\u5341\\u4e00\\u6708\", \"\\u5341\\u4e8c\\u6708\"],\n\t\t\t\tws: [\"\\u65e5\", \"\\u4e00\", \"\\u4e8c\", \"\\u4e09\", \"\\u56db\", \"\\u4e94\", \"\\u516d\"],\n\t\t\t\twl: [\"\\u661f\\u671f\\u65e5\", \"\\u661f\\u671f\\u4e00\", \"\\u661f\\u671f\\u4e8c\", \"\\u661f\\u671f\\u4e09\", \"\\u661f\\u671f\\u56db\", \"\\u661f\\u671f\\u4e94\", \"\\u661f\\u671f\\u516d\"],\n\t\t\t\txf: \"%Y\\u5e74%b%d\\u65e5\",\n\t\t\t\tXf: \"%H\\u65f6%M\\u5206%S\\u79d2\",\n\t\t\t\tcf: \"%Y\\u5e74%b%d\\u65e5 %A %H\\u65f6%M\\u5206%S\\u79d2\"\n\t\t\t},\n\t\t\tko: {\n\t\t\t\tms: [\" 1\\uc6d4\", \" 2\\uc6d4\", \" 3\\uc6d4\", \" 4\\uc6d4\", \" 5\\uc6d4\", \" 6\\uc6d4\", \" 7\\uc6d4\", \" 8\\uc6d4\", \" 9\\uc6d4\", \"10\\uc6d4\", \"11\\uc6d4\", \"12\\uc6d4\"],\n\t\t\t\tml: [\"1\\uc6d4\", \"2\\uc6d4\", \"3\\uc6d4\", \"4\\uc6d4\", \"5\\uc6d4\", \"6\\uc6d4\", \"7\\uc6d4\", \"8\\uc6d4\", \"9\\uc6d4\", \"10\\uc6d4\", \"11\\uc6d4\", \"12\\uc6d4\"],\n\t\t\t\tws: [\"\\uc77c\", \"\\uc6d4\", \"\\ud654\", \"\\uc218\", \"\\ubaa9\", \"\\uae08\", \"\\ud1a0\"],\n\t\t\t\twl: [\"\\uc77c\\uc694\\uc77c\", \"\\uc6d4\\uc694\\uc77c\", \"\\ud654\\uc694\\uc77c\", \"\\uc218\\uc694\\uc77c\", \"\\ubaa9\\uc694\\uc77c\", \"\\uae08\\uc694\\uc77c\", \"\\ud1a0\\uc694\\uc77c\"],\n\t\t\t\txf: \"%Y\\ub144 %B %d\\uc77c\",\n\t\t\t\tXf: \"%H\\uc2dc %M\\ubd84 %S\\ucd08\",\n\t\t\t\tcf: \"%Y\\ub144 %B %d\\uc77c (%a) %p %I\\uc2dc %M\\ubd84 %S\\ucd08\"\n\t\t\t},\n\t\t\tja: {\n\t\t\t\tms: [\" 1\\u6708\", \" 2\\u6708\", \" 3\\u6708\", \" 4\\u6708\", \" 5\\u6708\", \" 6\\u6708\", \" 7\\u6708\", \" 8\\u6708\", \" 9\\u6708\", \"10\\u6708\", \"11\\u6708\", \"12\\u6708\"],\n\t\t\t\tml: [\"1\\u6708\", \"2\\u6708\", \"3\\u6708\", \"4\\u6708\", \"5\\u6708\", \"6\\u6708\", \"7\\u6708\", \"8\\u6708\", \"9\\u6708\", \"10\\u6708\", \"11\\u6708\", \"12\\u6708\"],\n\t\t\t\tws: [\"\\u65e5\", \"\\u6708\", \"\\u706b\", \"\\u6c34\", \"\\u6728\", \"\\u91d1\", \"\\u571f\"],\n\t\t\t\twl: [\"\\u65e5\\u66dc\\u65e5\", \"\\u6708\\u66dc\\u65e5\", \"\\u706b\\u66dc\\u65e5\", \"\\u6c34\\u66dc\\u65e5\", \"\\u6728\\u66dc\\u65e5\", \"\\u91d1\\u66dc\\u65e5\", \"\\u571f\\u66dc\\u65e5\"],\n\t\t\t\txf: \"%Y\\u5e74%B%d\\u65e5\",\n\t\t\t\tXf: \"%H\\u6642%M\\u5206%S\\u79d2\",\n\t\t\t\tcf: \"%Y\\u5e74%B%d\\u65e5 %H\\u6642%M\\u5206%S\\u79d2\"\n\t\t\t}\n\t\t};\n\n\t\tlet translation = translations[lang];\n\n\t\tlet result = [];\n\t\tlet inspec = false;\n\t\tfor (let i = 0; i < fmt.length; ++i)\n\t\t{\n\t\t\tlet c = fmt[i];\n\t\t\tif (inspec)\n\t\t\t{\n\t\t\t\tswitch (c)\n\t\t\t\t{\n\t\t\t\t\tcase \"a\":\n\t\t\t\t\t\tc = translation.ws[obj.getDay()];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"A\":\n\t\t\t\t\t\tc = translation.wl[obj.getDay()];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"b\":\n\t\t\t\t\t\tc = translation.ms[obj.getMonth()];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"B\":\n\t\t\t\t\t\tc = translation.ml[obj.getMonth()];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"c\":\n\t\t\t\t\t\tc = ul4._format(obj, translation.cf, lang);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"d\":\n\t\t\t\t\t\tc = ul4._lpad(obj.getDate(), \"0\", 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"f\":\n\t\t\t\t\t\tc = ul4._lpad(obj.getMilliseconds(), \"0\", 3) + \"000\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"H\":\n\t\t\t\t\t\tc = ul4._lpad(obj.getHours(), \"0\", 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"I\":\n\t\t\t\t\t\tc = ul4._lpad(((obj.getHours()-1) % 12)+1, \"0\", 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"j\":\n\t\t\t\t\t\tc = ul4._lpad(ul4.DateTimeProtocol.yearday(obj), \"0\", 3);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"m\":\n\t\t\t\t\t\tc = ul4._lpad(obj.getMonth()+1, \"0\", 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"M\":\n\t\t\t\t\t\tc = ul4._lpad(obj.getMinutes(), \"0\", 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"p\":\n\t\t\t\t\t\tc = obj.getHours() < 12 ? \"AM\" : \"PM\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"S\":\n\t\t\t\t\t\tc = ul4._lpad(obj.getSeconds(), \"0\", 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"U\":\n\t\t\t\t\t\tc = ul4._lpad(ul4._week4format(obj, 6), \"0\", 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"w\":\n\t\t\t\t\t\tc = obj.getDay();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"W\":\n\t\t\t\t\t\tc = ul4._lpad(ul4._week4format(obj, 0), \"0\", 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"x\":\n\t\t\t\t\t\tc = ul4._format(obj, translation.xf, lang);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"X\":\n\t\t\t\t\t\tc = ul4._format(obj, translation.Xf, lang);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"y\":\n\t\t\t\t\t\tc = (obj.getFullYear() % 100).toString();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Y\":\n\t\t\t\t\t\tc = obj.getFullYear().toString();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"z\":\n\t\t\t\t\t\t// UTC offset in the form +HHMM or -HHMM\n\t\t\t\t\t\tc = \"\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Z\":\n\t\t\t\t\t\t// Time zone name\n\t\t\t\t\t\tc = \"\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tresult.push(c);\n\t\t\t\tinspec = false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (c == \"%\")\n\t\t\t\t\tinspec = true;\n\t\t\t\telse\n\t\t\t\t\tresult.push(c);\n\t\t\t}\n\t\t}\n\t\treturn result.join(\"\");\n\t};\n\n\tul4._format_int = function _format_int(obj, fmt, lang)\n\t{\n\t\tlet work = fmt;\n\n\t\t// Defaults\n\t\tlet fill = ' ';\n\t\tlet align = '>'; // '<', '>', '=' or '^'\n\t\tlet sign = '-'; // '+', '-' or ' '\n\t\tlet alternate = false;\n\t\tlet minimumwidth = 0;\n\t\tlet type = 'd'; // 'b', 'c', 'd', 'o', 'x', 'X' or 'n'\n\n\t\t// Determine output type\n\t\tif (/[bcdoxXn]$/.test(work))\n\t\t{\n\t\t\ttype = work.substring(work.length-1);\n\t\t\twork = work.substring(0, work.length-1);\n\t\t}\n\n\t\t// Extract minimum width\n\t\tif (/\\d+$/.test(work))\n\t\t{\n\t\t\tlet minimumwidthStr = /\\d+$/.exec(work);\n\t\t\twork = work.replace(/\\d+$/, \"\");\n\t\t\tif (/^0/.test(minimumwidthStr))\n\t\t\t{\n\t\t\t\talign = '=';\n\t\t\t\tfill = '0';\n\t\t\t}\n\t\t\tminimumwidth = parseInt(minimumwidthStr);\n\t\t}\n\n\t\t// Alternate form?\n\t\tif (/#$/.test(work))\n\t\t{\n\t\t\talternate = true;\n\t\t\twork = work.substring(0, work.length-1);\n\t\t}\n\n\t\t// Determine sign\n\t\tif (/[+ -]$/.test(work))\n\t\t{\n\t\t\tif (type == 'c')\n\t\t\t\tthrow new ul4.ValueError(\"sign not allowed for integer format type 'c'\");\n\t\t\tsign = work.substring(work.length-1);\n\t\t\twork = work.substring(0, work.length-1);\n\t\t}\n\n\t\t// Extract fill and align char\n\t\tif (work.length >= 3)\n\t\t\tthrow new ul4.ValueError(\"illegal integer format string \" + ul4._repr(fmt));\n\t\telse if (work.length == 2)\n\t\t{\n\t\t\tif (/[<>=^]$/.test(work))\n\t\t\t{\n\t\t\t\talign = work[1];\n\t\t\t\tfill = work[0];\n\t\t\t}\n\t\t\telse\n\t\t\t\tthrow new ul4.ValueError(\"illegal integer format string \" + ul4._repr(fmt));\n\t\t}\n\t\telse if (work.length == 1)\n\t\t{\n\t\t\tif (/^[<>=^]$/.test(work))\n\t\t\t\talign = work;\n\t\t\telse\n\t\t\t\tthrow new ul4.ValueError(\"illegal integer format string \" + ul4._repr(fmt));\n\t\t}\n\n\t\t// Basic number formatting\n\t\tlet neg = obj < 0;\n\n\t\tif (neg)\n\t\t\tobj = -obj;\n\n\t\tlet output;\n\t\tswitch (type)\n\t\t{\n\t\t\tcase 'b':\n\t\t\t\toutput = obj.toString(2);\n\t\t\t\tbreak;\n\t\t\tcase 'c':\n\t\t\t\tif (neg || obj > 65535)\n\t\t\t\t\tthrow new ul4.ValueError(\"value out of bounds for c format\");\n\t\t\t\toutput = String.fromCharCode(obj);\n\t\t\t\tbreak;\n\t\t\tcase 'd':\n\t\t\t\toutput = obj.toString();\n\t\t\t\tbreak;\n\t\t\tcase 'o':\n\t\t\t\toutput = obj.toString(8);\n\t\t\t\tbreak;\n\t\t\tcase 'x':\n\t\t\t\toutput = obj.toString(16);\n\t\t\t\tbreak;\n\t\t\tcase 'X':\n\t\t\t\toutput = obj.toString(16).toUpperCase();\n\t\t\t\tbreak;\n\t\t\tcase 'n':\n\t\t\t\t// FIXME: locale formatting\n\t\t\t\toutput = obj.toString();\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// The rest of the formatting\n\t\tif (align === '=')\n\t\t{\n\t\t\tif (neg || sign !== '-')\n\t\t\t\t--minimumwidth;\n\t\t\tif (alternate && (type === 'b' || type === 'o' || type === 'x' || type === 'X'))\n\t\t\t\tminimumwidth -= 2;\n\n\t\t\tif (output.length < minimumwidth)\n\t\t\t\toutput = ul4._str_repeat(fill, minimumwidth-output.length) + output;\n\n\t\t\tif (alternate && (type === 'b' || type === 'o' || type === 'x' || type === 'X'))\n\t\t\t\toutput = \"0\" + type + output;\n\n\t\t\tif (neg)\n\t\t\t\toutput = \"-\" + output;\n\t\t\telse if (sign != '-')\n\t\t\t\toutput = sign + output;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (alternate && (type == 'b' || type == 'o' || type == 'x' || type == 'X'))\n\t\t\t\toutput = \"0\" + type + output;\n\t\t\tif (neg)\n\t\t\t\toutput = \"-\" + output;\n\t\t\telse if (sign != '-')\n\t\t\t\toutput = sign + output;\n\t\t\tif (output.length < minimumwidth)\n\t\t\t{\n\t\t\t\tif (align == '<')\n\t\t\t\t\toutput = output + ul4._str_repeat(fill, minimumwidth-output.length);\n\t\t\t\telse if (align == '>')\n\t\t\t\t\toutput = ul4._str_repeat(fill, minimumwidth-output.length) + output;\n\t\t\t\telse // if (align == '^')\n\t\t\t\t{\n\t\t\t\t\tlet pad = minimumwidth - output.length;\n\t\t\t\t\tlet padBefore = Math.floor(pad/2);\n\t\t\t\t\tlet padAfter = pad-padBefore;\n\t\t\t\t\toutput = ul4._str_repeat(fill, padBefore) + output + ul4._str_repeat(fill, padAfter);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t};\n\n\t// Format ``obj`` using the format string ``fmt`` in the language ``lang``\n\tul4._format = function _format(obj, fmt, lang)\n\t{\n\t\tif (typeof(lang) === \"undefined\" || lang === null)\n\t\t\tlang = \"en\";\n\t\telse\n\t\t{\n\t\t\tlet translations = {de: null, en: null, fr: null, es: null, it: null, da: null, sv: null, nl: null, pt: null, cs: null, sk: null, pl: null, hr: null, sr: null, ro: null, hu: null, tr: null, ru: null, zh: null, ko: null, ja: null};\n\t\t\tlang = lang.toLowerCase();\n\t\t\tif (typeof(translations[lang]) === \"undefined\")\n\t\t\t{\n\t\t\t\tlang = lang.split(/_/)[0];\n\t\t\t\tif (typeof(translations[lang]) === \"undefined\")\n\t\t\t\t\tlang = \"en\";\n\t\t\t}\n\t\t}\n\t\tif (ul4._isdate(obj))\n\t\t\treturn ul4._format_datetime(obj._date, fmt, lang);\n\t\tif (ul4._isdatetime(obj))\n\t\t\treturn ul4._format_datetime(obj, fmt, lang);\n\t\telse if (ul4._isint(obj))\n\t\t\treturn ul4._format_int(obj, fmt, lang);\n\t\telse if (obj === true)\n\t\t\treturn ul4._format_int(1, fmt, lang);\n\t\telse if (obj === false)\n\t\t\treturn ul4._format_int(0, fmt, lang);\n\t};\n\n\tul4._lpad = function _lpad(string, pad, len)\n\t{\n\t\tif (typeof(string) === \"number\")\n\t\t\tstring = string.toString();\n\t\twhile (string.length < len)\n\t\t\tstring = pad + string;\n\t\treturn string;\n\t};\n\n\tul4._rpad = function _rpad(string, pad, len)\n\t{\n\t\tif (typeof(string) === \"number\")\n\t\t\tstring = string.toString();\n\t\twhile (string.length < len)\n\t\t\tstring = string + pad;\n\t\treturn string;\n\t};\n\n\t// This is outside of ``Proto`` on purpose\n\t// This way reactive frameworks like ``Vue.js`` don't get to see it\n\t// and complain about mutating render functions when those create new objects.\n\tlet _nextid = 1;\n\n\tul4.Proto = class Proto\n\t{\n\t\tconstructor()\n\t\t{\n\t\t\tthis.__id__ = _nextid++;\n\t\t}\n\n\t\tul4type()\n\t\t{\n\t\t\treturn this.constructor.name;\n\t\t}\n\n\t\t// equality comparison of objects defaults to identity comparison\n\t\t__eq__(other)\n\t\t{\n\t\t\treturn this === other;\n\t\t}\n\n\t\t// To overwrite equality comparison, you only have to overwrite ``__eq__``,\n\t\t// ``__ne__`` will be synthesized from that\n\t\t__ne__(other)\n\t\t{\n\t\t\treturn !this.__eq__(other);\n\t\t}\n\n\t\t// For other comparison operators, each method has to be implemented:\n\t\t// ``<`` calls ``__lt__``, ``<=`` calls ``__le__``, ``>`` calls ``__gt__`` and\n\t\t// ``>=`` calls ``__ge__``\n\n\t\t__bool__()\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t};\n\n\tul4.Signature = class Signature extends ul4.Proto\n\t{\n\t\tconstructor(...args)\n\t\t{\n\t\t\tsuper();\n\t\t\tthis.args = [];\n\t\t\tthis.argNames = {};\n\t\t\tthis.remargs = null;\n\t\t\tthis.remkwargs = null;\n\n\t\t\tlet nextDefault = false;\n\t\t\tlet lastArgname = null;\n\t\t\tfor (let i = 0; i < args.length; ++i)\n\t\t\t{\n\t\t\t\tlet argName = args[i];\n\t\t\t\tif (nextDefault)\n\t\t\t\t{\n\t\t\t\t\tthis.args.push({name: lastArgname, defaultValue: argName});\n\t\t\t\t\tthis.argNames[lastArgname] = true;\n\t\t\t\t\tnextDefault = false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (argName.substr(argName.length-1) === \"=\")\n\t\t\t\t\t{\n\t\t\t\t\t\tlastArgname = argName.substr(0, argName.length-1);\n\t\t\t\t\t\tnextDefault = true;\n\t\t\t\t\t}\n\t\t\t\t\telse if (argName.substr(0, 2) === \"**\")\n\t\t\t\t\t\tthis.remkwargs = argName.substr(2);\n\t\t\t\t\telse if (argName.substr(0, 1) === \"*\")\n\t\t\t\t\t\tthis.remargs = argName.substr(1);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tthis.args.push({name: argName});\n\t\t\t\t\t\tthis.argNames[argName] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Create the argument array for calling a function with this signature with the arguments available from ``args``\n\t\tbindArray(name, args, kwargs)\n\t\t{\n\t\t\tlet finalargs = [];\n\t\t\tlet decname = name !== null ? name + \"() \" : \"\";\n\n\t\t\tfor (let i = 0; i < this.args.length; ++i)\n\t\t\t{\n\t\t\t\tlet arg = this.args[i];\n\t\t\t\tif (i < args.length)\n\t\t\t\t{\n\t\t\t\t\tif (kwargs.hasOwnProperty(arg.name))\n\t\t\t\t\t\tthrow new ul4.ArgumentError(decname + \"argument \" + ul4._repr(arg.name) + \" (position \" + i + \") specified multiple times\");\n\t\t\t\t\tfinalargs.push(args[i]);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (kwargs.hasOwnProperty(arg.name))\n\t\t\t\t\t\tfinalargs.push(kwargs[arg.name]);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (arg.hasOwnProperty(\"defaultValue\"))\n\t\t\t\t\t\t\tfinalargs.push(arg.defaultValue);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tthrow new ul4.ArgumentError(\"required \" + decname + \"argument \" + ul4._repr(arg.name) + \" (position \" + i + \") missing\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Do we accept additional positional arguments?\n\t\t\tif (this.remargs === null)\n\t\t\t{\n\t\t\t\t// No, but we have them -> complain\n\t\t\t\tif (args.length > this.args.length)\n\t\t\t\t{\n\t\t\t\t\tlet prefix = name === null ? \"expected\" : name + \"() expects\";\n\t\t\t\t\tthrow new ul4.ArgumentError(prefix + \" at most \" + this.args.length + \" positional argument\" + (this.args.length != 1 ? \"s\" : \"\") + \", \" + args.length + \" given\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Put additional positional arguments in the call into the ``*`` argument (if there are none, this pushes an empty list)\n\t\t\t\tfinalargs.push(args.slice(this.args.length));\n\t\t\t}\n\n\t\t\t// Do we accept arbitrary keyword arguments?\n\t\t\tif (this.remkwargs === null)\n\t\t\t{\n\t\t\t\t// No => complain about unknown ones\n\t\t\t\tfor (let key in kwargs)\n\t\t\t\t{\n\t\t\t\t\tif (!this.argNames[key])\n\t\t\t\t\t{\n\t\t\t\t\t\tif (name === null)\n\t\t\t\t\t\t\tthrow new ul4.ArgumentError(\"an argument named \" + ul4._repr(key) + \" isn't supported\");\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tthrow new ul4.ArgumentError(name + \"() doesn't support an argument named \" + ul4._repr(key));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Yes => Put the unknown ones into an object and add that to the arguments array\n\t\t\t\tlet remkwargs = ul4._emptymap();\n\t\t\t\tfor (let key in kwargs)\n\t\t\t\t{\n\t\t\t\t\tif (!this.argNames[key])\n\t\t\t\t\t\tul4._setmap(remkwargs, key, kwargs[key]);\n\t\t\t\t}\n\t\t\t\tfinalargs.push(remkwargs);\n\t\t\t}\n\n\t\t\treturn finalargs;\n\t\t}\n\n\t\t// Create the argument object for calling a function with this signature with the arguments available from ``args``\n\t\tbindObject(name, args, kwargs)\n\t\t{\n\t\t\targs = this.bindArray(name, args, kwargs);\n\t\t\tlet argObject = {};\n\t\t\tlet i;\n\t\t\tfor (i = 0; i < this.args.length; ++i)\n\t\t\t\targObject[this.args[i].name] = args[i];\n\t\t\tif (this.remargs !== null)\n\t\t\t\targObject[this.remargs] = args[i++];\n\t\t\tif (this.remkwargs !== null)\n\t\t\t\targObject[this.remkwargs] = args[i++];\n\t\t\treturn argObject;\n\t\t}\n\n\t\t__repr__()\n\t\t{\n\t\t\treturn \"\";\n\t\t}\n\n\t\t__str__()\n\t\t{\n\t\t\treturn this.toString();\n\t\t}\n\n\t\ttoString()\n\t\t{\n\t\t\tlet v = [];\n\t\t\tfor (let i = 0; i < this.args.length; ++i)\n\t\t\t{\n\t\t\t\tlet arg = this.args[i];\n\t\t\t\tif (arg.hasOwnProperty(\"defaultValue\"))\n\t\t\t\t\tv.push(arg.name + \"=\" + ul4._repr(arg.defaultValue));\n\t\t\t\telse\n\t\t\t\t\tv.push(arg.name);\n\t\t\t}\n\t\t\tif (this.remargs !== null)\n\t\t\t\tv.push(\"*\" + this.remargs);\n\t\t\tif (this.remkwargs !== null)\n\t\t\t\tv.push(\"**\" + this.remkwargs);\n\t\t\treturn \"(\" + v.join(\", \") + \")\";\n\t\t}\n\t};\n\n\t// When we don't have a real ``Set`` type, emulate one that supports strings\n\tul4._Set = class _Set\n\t{\n\t\tconstructor(...items)\n\t\t{\n\t\t\tthis.items = {};\n\t\t\tthis.add(...items);\n\t\t}\n\n\t\tadd(...items)\n\t\t{\n\t\t\tfor (let i = 0; i < items.length; ++i)\n\t\t\t\tthis.items[items[i]] = true;\n\t\t}\n\n\t\tclear()\n\t\t{\n\t\t\tthis.items = {};\n\t\t}\n\n\t\t__getattr__(attrname)\n\t\t{\n\t\t\tlet self = this;\n\t\t\tswitch (attrname)\n\t\t\t{\n\t\t\t\tcase \"add\":\n\t\t\t\t\treturn ul4.expose(function add(items){ self.add(...items); }, [\"*items\"]);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ul4.AttributeError(this, attrname);\n\t\t\t}\n\t\t}\n\n\t\t__contains__(item)\n\t\t{\n\t\t\treturn this.items[item] || false;\n\t\t}\n\n\t\thas(item)\n\t\t{\n\t\t\treturn this.items[item] || false;\n\t\t}\n\n\t\t__bool__()\n\t\t{\n\t\t\tfor (let item in this.items)\n\t\t\t{\n\t\t\t\tif (!this.items.hasOwnProperty(item))\n\t\t\t\t\tcontinue;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t__repr__()\n\t\t{\n\t\t\tlet v = [];\n\t\t\tv.push(\"{\");\n\t\t\tlet i = 0;\n\t\t\tfor (let item in this.items)\n\t\t\t{\n\t\t\t\tif (!this.items.hasOwnProperty(item))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (i++)\n\t\t\t\t\tv.push(\", \");\n\t\t\t\tv.push(ul4._repr(item));\n\t\t\t}\n\t\t\tif (!i)\n\t\t\t\tv.push(\"/\");\n\t\t\tv.push(\"}\");\n\t\t\treturn v.join(\"\");\n\t\t}\n\n\t\t__eq__(other)\n\t\t{\n\t\t\t// We'll check that everything in ``this`` is in ``other``\n\t\t\t// and if both have the same number of items they are equal\n\t\t\tif (ul4._isset(other))\n\t\t\t{\n\t\t\t\tlet count = 0;\n\t\t\t\tfor (let item in this.items)\n\t\t\t\t{\n\t\t\t\t\tif (!other.has(item))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t// count the number of items we have\n\t\t\t\t\t++count;\n\t\t\t\t}\n\t\t\t\treturn other.size == count;\n\t\t\t}\n\t\t\telse if (ul4._isul4set(other))\n\t\t\t{\n\t\t\t\tlet count = 0;\n\t\t\t\tfor (let item in this.items)\n\t\t\t\t{\n\t\t\t\t\tif (!other[item])\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t// count the number of items we have\n\t\t\t\t\t++count;\n\t\t\t\t}\n\t\t\t\t// Subtract the number of items that ``other`` has\n\t\t\t\tfor (let item in other.items)\n\t\t\t\t\t--count;\n\t\t\t\treturn count == 0;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\n\t\t__le__(other)\n\t\t{\n\t\t\t// check that ``this`` is a subset of ``other``,\n\t\t\t// i.e. everything in ``this`` is also in ``other``\n\t\t\tif (ul4._isset(other))\n\t\t\t{\n\t\t\t\tlet count = 0;\n\t\t\t\tfor (let item in this.items)\n\t\t\t\t{\n\t\t\t\t\tif (!other.has(item))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (ul4._isul4set(other))\n\t\t\t{\n\t\t\t\tlet count = 0;\n\t\t\t\tfor (let item in this.items)\n\t\t\t\t{\n\t\t\t\t\tif (!other.items[item])\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\tul4._unorderable(\"<\", this, other);\n\t\t}\n\n\t\t__ge__(other)\n\t\t{\n\t\t\t// check that ``this`` is a superset of ``other``,\n\t\t\t// i.e. everything in ``other`` is also in ``this``\n\t\t\tif (ul4._isset(other))\n\t\t\t{\n\t\t\t\tother.forEach(function(value) {\n\t\t\t\t\tif (!this.items[value])\n\t\t\t\t\t\treturn false;\n\t\t\t\t}, this);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (ul4._isul4set(other))\n\t\t\t{\n\t\t\t\tlet count = 0;\n\t\t\t\tfor (let key in other.items)\n\t\t\t\t{\n\t\t\t\t\tif (!this.items[key])\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t\tul4._unorderable(\"<=\", this, other);\n\t\t}\n\t};\n\n\tul4._Set.prototype.__type__ = \"set\";\n\n\t// Adds name and signature to a function/method and makes the method callable in templates\n\tul4.expose = function expose(f, signature, options)\n\t{\n\t\toptions = options || {};\n\t\tif (options.name)\n\t\t\tf._ul4_name = options.name;\n\t\tif (ul4._islist(signature))\n\t\t\tsignature = new ul4.Signature(...signature);\n\t\tf._ul4_signature = signature;\n\t\tf._ul4_needsobject = options.needsobject || false;\n\t\tf._ul4_needscontext = options.needscontext || false;\n\t};\n\n\t// Protocol objects for all builtin types\n\t// These objects are singleton, so we replace the constructor with the prototype object afterwards\n\tul4.Protocol = class Protocol\n\t{\n\t\tul4type()\n\t\t{\n\t\t\treturn this.constructor.name;\n\t\t}\n\n\t\tdir()\n\t\t{\n\t\t\treturn this.attrs;\n\t\t}\n\n\t\tget(obj)\n\t\t{\n\t\t\tif (ul4._isstr(obj))\n\t\t\t\treturn ul4.StrProtocol;\n\t\t\telse if (ul4._islist(obj))\n\t\t\t\treturn ul4.ListProtocol;\n\t\t\telse if (ul4._isdate(obj))\n\t\t\t\treturn ul4.DateProtocol;\n\t\t\telse if (ul4._isset(obj))\n\t\t\t\treturn ul4.SetProtocol;\n\t\t\telse if (ul4._ismap(obj))\n\t\t\t\treturn ul4.MapProtocol;\n\t\t\telse if (ul4._isdatetime(obj))\n\t\t\t\treturn ul4.DateTimeProtocol;\n\t\t\telse if (ul4._isobject(obj))\n\t\t\t\treturn ul4.ObjectProtocol;\n\t\t\telse\n\t\t\t\treturn ul4.Protocol;\n\t\t}\n\n\t\tgetattr(obj, attrname)\n\t\t{\n\t\t\tif (obj === null || typeof(obj) === \"undefined\")\n\t\t\t\tthrow new ul4.AttributeError(obj, attrname);\n\t\t\telse if (typeof(obj.__getattr__) === \"function\")\n\t\t\t\treturn obj.__getattr__(attrname);\n\t\t\telse if (this.attrs.has(attrname))\n\t\t\t{\n\t\t\t\tlet attr = this[attrname];\n\t\t\t\tlet realattr = function realattr(...args) {\n\t\t\t\t\treturn attr.apply(this, [obj, ...args]);\n\t\t\t\t};\n\t\t\t\trealattr.name = attr.name;\n\t\t\t\trealattr._ul4_name = attr._ul4_name || attr.name;\n\t\t\t\trealattr._ul4_signature = attr._ul4_signature;\n\t\t\t\trealattr._ul4_needsobject = attr._ul4_needsobject;\n\t\t\t\trealattr._ul4_needscontext = attr._ul4_needscontext;\n\t\t\t\treturn realattr;\n\t\t\t}\n\t\t\telse\n\t\t\t\tthrow new ul4.AttributeError(obj, attrname);\n\t\t}\n\n\t\thasattr(obj, attrname)\n\t\t{\n\t\t\tif (obj === null || typeof(obj) === \"undefined\")\n\t\t\t\treturn false;\n\t\t\telse if (typeof(obj.__getattr__) === \"function\")\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tobj.__getattr__(attrname);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tcatch (exc)\n\t\t\t\t{\n\t\t\t\t\tif (exc instanceof ul4.AttributeError && exc.obj === object)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\telse\n\t\t\t\t\t\tthrow exc;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn this.attrs.has(attrname);\n\t\t}\n\t};\n\n\tul4.Protocol = ul4.Protocol.prototype;\n\tul4.Protocol.attrs = ul4._emptyset();\n\n\tul4.StrProtocol = class StrProtocol extends ul4.Protocol.constructor\n\t{\n\t\tul4type(obj)\n\t\t{\n\t\t\treturn \"str\";\n\t\t}\n\n\t\tcount(obj, sub, start=null, end=null)\n\t\t{\n\t\t\treturn ul4._count(obj, sub, start, end);\n\t\t}\n\n\t\tfind(obj, sub, start=null, end=null)\n\t\t{\n\t\t\treturn ul4._find(obj, sub, start, end);\n\t\t}\n\n\t\trfind(obj, sub, start=null, end=null)\n\t\t{\n\t\t\treturn ul4._rfind(obj, sub, start, end);\n\t\t}\n\n\t\treplace(obj, old, new_, count=null)\n\t\t{\n\t\t\tif (count === null)\n\t\t\t\tcount = obj.length;\n\n\t\t\tlet result = [];\n\t\t\twhile (obj.length)\n\t\t\t{\n\t\t\t\tlet pos = obj.indexOf(old);\n\t\t\t\tif (pos === -1 || !count--)\n\t\t\t\t{\n\t\t\t\t\tresult.push(obj);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tresult.push(obj.substr(0, pos));\n\t\t\t\tresult.push(new_);\n\t\t\t\tobj = obj.substr(pos + old.length);\n\t\t\t}\n\t\t\treturn result.join(\"\");\n\t\t}\n\n\t\tstrip(obj, chars=null)\n\t\t{\n\t\t\tchars = chars || \" \\r\\n\\t\";\n\t\t\tif (typeof(chars) !== \"string\")\n\t\t\t\tthrow new ul4.TypeError(\"strip() requires a string argument\");\n\n\t\t\twhile (obj && chars.indexOf(obj[0]) >= 0)\n\t\t\t\tobj = obj.substr(1);\n\t\t\twhile (obj && chars.indexOf(obj[obj.length-1]) >= 0)\n\t\t\t\tobj = obj.substr(0, obj.length-1);\n\t\t\treturn obj;\n\t\t}\n\n\t\tlstrip(obj, chars=null)\n\t\t{\n\t\t\tchars = chars || \" \\r\\n\\t\";\n\t\t\tif (typeof(chars) !== \"string\")\n\t\t\t\tthrow new ul4.TypeError(\"lstrip() requires a string argument\");\n\n\t\t\twhile (obj && chars.indexOf(obj[0]) >= 0)\n\t\t\t\tobj = obj.substr(1);\n\t\t\treturn obj;\n\t\t}\n\n\t\trstrip(obj, chars=null)\n\t\t{\n\t\t\tchars = chars || \" \\r\\n\\t\";\n\t\t\tif (typeof(chars) !== \"string\")\n\t\t\t\tthrow new ul4.TypeError(\"rstrip() requires a string argument\");\n\n\t\t\twhile (obj && chars.indexOf(obj[obj.length-1]) >= 0)\n\t\t\t\tobj = obj.substr(0, obj.length-1);\n\t\t\treturn obj;\n\t\t}\n\n\t\tsplit(obj, sep=null, count=null)\n\t\t{\n\t\t\tif (sep !== null && typeof(sep) !== \"string\")\n\t\t\t\tthrow new ul4.TypeError(\"split() requires a string\");\n\n\t\t\tif (count === null)\n\t\t\t{\n\t\t\t\tlet result = obj.split(sep !== null ? sep : /[ \\n\\r\\t]+/);\n\t\t\t\tif (sep === null)\n\t\t\t\t{\n\t\t\t\t\tif (result.length && !result[0].length)\n\t\t\t\t\t\tresult.splice(0, 1);\n\t\t\t\t\tif (result.length && !result[result.length-1].length)\n\t\t\t\t\t\tresult.splice(-1);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (sep !== null)\n\t\t\t\t{\n\t\t\t\t\tlet result = [];\n\t\t\t\t\twhile (obj.length)\n\t\t\t\t\t{\n\t\t\t\t\t\tlet pos = obj.indexOf(sep);\n\t\t\t\t\t\tif (pos === -1 || !count--)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tresult.push(obj);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresult.push(obj.substr(0, pos));\n\t\t\t\t\t\tobj = obj.substr(pos + sep.length);\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlet result = [];\n\t\t\t\t\twhile (obj.length)\n\t\t\t\t\t{\n\t\t\t\t\t\tobj = ul4.StrProtocol.lstrip(obj, null);\n\t\t\t\t\t\tlet part;\n\t\t\t\t\t\tif (!count--)\n\t\t\t\t\t\t\t part = obj; // Take the rest of the string\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tpart = obj.split(/[ \\n\\r\\t]+/, 1)[0];\n\t\t\t\t\t\tif (part.length)\n\t\t\t\t\t\t\tresult.push(part);\n\t\t\t\t\t\tobj = obj.substr(part.length);\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\trsplit(obj, sep=null, count=null)\n\t\t{\n\t\t\tif (sep !== null && typeof(sep) !== \"string\")\n\t\t\t\tthrow new ul4.TypeError(\"rsplit() requires a string as second argument\");\n\n\t\t\tif (count === null)\n\t\t\t{\n\t\t\t\tlet result = obj.split(sep !== null ? sep : /[ \\n\\r\\t]+/);\n\t\t\t\tif (sep === null)\n\t\t\t\t{\n\t\t\t\t\tif (result.length && !result[0].length)\n\t\t\t\t\t\tresult.splice(0, 1);\n\t\t\t\t\tif (result.length && !result[result.length-1].length)\n\t\t\t\t\t\tresult.splice(-1);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (sep !== null)\n\t\t\t\t{\n\t\t\t\t\tlet result = [];\n\t\t\t\t\twhile (obj.length)\n\t\t\t\t\t{\n\t\t\t\t\t\tlet pos = obj.lastIndexOf(sep);\n\t\t\t\t\t\tif (pos === -1 || !count--)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tresult.unshift(obj);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresult.unshift(obj.substr(pos+sep.length));\n\t\t\t\t\t\tobj = obj.substr(0, pos);\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlet result = [];\n\t\t\t\t\twhile (obj.length)\n\t\t\t\t\t{\n\t\t\t\t\t\tobj = ul4.StrProtocol.rstrip(obj);\n\t\t\t\t\t\tlet part;\n\t\t\t\t\t\tif (!count--)\n\t\t\t\t\t\t\t part = obj; // Take the rest of the string\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpart = obj.split(/[ \\n\\r\\t]+/);\n\t\t\t\t\t\t\tpart = part[part.length-1];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (part.length)\n\t\t\t\t\t\t\tresult.unshift(part);\n\t\t\t\t\t\tobj = obj.substr(0, obj.length-part.length);\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsplitlines(obj, keepends=false)\n\t\t{\n\t\t\tlet pos = 0;\n\t\t\tlet lookingAtLineEnd = function lookingAtLineEnd()\n\t\t\t{\n\t\t\t\tlet c = obj[pos];\n\t\t\t\tif (c === '\\n' || c == '\\u000B' || c == '\\u000C' || c == '\\u001C' || c == '\\u001D' || c == '\\u001E' || c == '\\u0085' || c == '\\u2028' || c == '\\u2029')\n\t\t\t\t\treturn 1;\n\t\t\t\tif (c === '\\r')\n\t\t\t\t{\n\t\t\t\t\tif (pos == length-1)\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\tif (obj[pos+1] === '\\n')\n\t\t\t\t\t\treturn 2;\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\treturn 0;\n\t\t\t};\n\n\t\t\tlet result = [], length = obj.length;\n\n\t\t\tfor (pos = 0, startpos = 0;;)\n\t\t\t{\n\t\t\t\tif (pos >= length)\n\t\t\t\t{\n\t\t\t\t\tif (startpos != pos)\n\t\t\t\t\t\tresult.push(obj.substring(startpos));\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\tlet lineendlen = lookingAtLineEnd();\n\t\t\t\tif (!lineendlen)\n\t\t\t\t\t++pos;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlet endpos = pos + (keepends ? lineendlen : 0);\n\t\t\t\t\tresult.push(obj.substring(startpos, endpos));\n\t\t\t\t\tpos += lineendlen;\n\t\t\t\t\tstartpos = pos;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlower(obj)\n\t\t{\n\t\t\treturn obj.toLowerCase();\n\t\t}\n\n\t\tupper(obj)\n\t\t{\n\t\t\treturn obj.toUpperCase();\n\t\t}\n\n\t\tcapitalize(obj)\n\t\t{\n\t\t\tif (obj.length)\n\t\t\t\tobj = obj[0].toUpperCase() + obj.slice(1).toLowerCase();\n\t\t\treturn obj;\n\t\t}\n\n\t\tjoin(obj, iterable)\n\t\t{\n\t\t\tlet resultlist = [];\n\t\t\tfor (let iter = ul4._iter(iterable);;)\n\t\t\t{\n\t\t\t\tlet item = iter.next();\n\t\t\t\tif (item.done)\n\t\t\t\t\tbreak;\n\t\t\t\tresultlist.push(item.value);\n\t\t\t}\n\t\t\treturn resultlist.join(obj);\n\t\t}\n\n\t\tstartswith(obj, prefix)\n\t\t{\n\t\t\tif (typeof(prefix) === \"string\")\n\t\t\t\treturn obj.substr(0, prefix.length) === prefix;\n\t\t\telse if (ul4._islist(prefix))\n\t\t\t{\n\t\t\t\tfor (let i = 0; i < prefix.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tlet singlepre = prefix[i];\n\t\t\t\t\tif (obj.substr(0, singlepre.length) === singlepre)\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t\tthrow new ul4.TypeError(\"startswith() argument must be string\");\n\t\t}\n\n\t\tendswith(obj, suffix)\n\t\t{\n\t\t\tif (typeof(suffix) === \"string\")\n\t\t\t\treturn obj.substr(obj.length-suffix.length) === suffix;\n\t\t\telse if (ul4._islist(suffix))\n\t\t\t{\n\t\t\t\tfor (let i = 0; i < suffix.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tlet singlesuf = suffix[i];\n\t\t\t\t\tif (obj.substr(obj.length-singlesuf.length) === singlesuf)\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t\tthrow new ul4.TypeError(\"endswith() argument must be string or list of strings\");\n\t\t}\n\t};\n\n\tul4.StrProtocol = ul4.StrProtocol.prototype;\n\tul4.StrProtocol.attrs = ul4._makeset(\n\t\t\"split\",\n\t\t\"rsplit\",\n\t\t\"splitlines\",\n\t\t\"strip\",\n\t\t\"lstrip\",\n\t\t\"rstrip\",\n\t\t\"upper\",\n\t\t\"lower\",\n\t\t\"capitalize\",\n\t\t\"startswith\",\n\t\t\"endswith\",\n\t\t\"replace\",\n\t\t\"count\",\n\t\t\"find\",\n\t\t\"rfind\",\n\t\t\"join\"\n\t);\n\n\tul4.expose(ul4.StrProtocol.count, [\"sub\", \"start=\", null, \"end=\", null]);\n\tul4.expose(ul4.StrProtocol.find, [\"sub\", \"start=\", null, \"end=\", null]);\n\tul4.expose(ul4.StrProtocol.rfind, [\"sub\", \"start=\", null, \"end=\", null]);\n\tul4.expose(ul4.StrProtocol.replace, [\"old\", \"new\", \"count=\", null]);\n\tul4.expose(ul4.StrProtocol.strip, [\"chars=\", null]);\n\tul4.expose(ul4.StrProtocol.lstrip, [\"chars=\", null]);\n\tul4.expose(ul4.StrProtocol.rstrip, [\"chars=\", null]);\n\tul4.expose(ul4.StrProtocol.split, [\"sep=\", null, \"count=\", null]);\n\tul4.expose(ul4.StrProtocol.rsplit, [\"sep=\", null, \"count=\", null]);\n\tul4.expose(ul4.StrProtocol.splitlines, [\"keepends=\", false]);\n\tul4.expose(ul4.StrProtocol.lower, []);\n\tul4.expose(ul4.StrProtocol.upper, []);\n\tul4.expose(ul4.StrProtocol.capitalize, []);\n\tul4.expose(ul4.StrProtocol.join, [\"iterable\"]);\n\tul4.expose(ul4.StrProtocol.startswith, [\"prefix\"]);\n\tul4.expose(ul4.StrProtocol.endswith, [\"suffix\"]);\n\n\tul4.ListProtocol = class ListProtocol extends ul4.Protocol.constructor\n\t{\n\t\tul4type(obj)\n\t\t{\n\t\t\treturn \"list\";\n\t\t}\n\n\t\tappend(obj, items)\n\t\t{\n\t\t\tfor (let i = 0; i < items.length; ++i)\n\t\t\t\tobj.push(items[i]);\n\t\t\treturn null;\n\t\t}\n\n\t\tinsert(obj, pos, items)\n\t\t{\n\t\t\tif (pos < 0)\n\t\t\t\tpos += obj.length;\n\n\t\t\tfor (let i = 0; i < items.length; ++i)\n\t\t\t\tobj.splice(pos++, 0, items[i]);\n\t\t\treturn null;\n\t\t}\n\n\t\tpop(obj, pos)\n\t\t{\n\t\t\tif (pos < 0)\n\t\t\t\tpos += obj.length;\n\n\t\t\tlet result = obj[pos];\n\t\t\tobj.splice(pos, 1);\n\t\t\treturn result;\n\t\t}\n\n\t\tcount(obj, sub, start=null, end=null)\n\t\t{\n\t\t\treturn ul4._count(obj, sub, start, end);\n\t\t}\n\n\t\tfind(obj, sub, start=null, end=null)\n\t\t{\n\t\t\treturn ul4._find(obj, sub, start, end);\n\t\t}\n\n\t\trfind(obj, sub, start=null, end=null)\n\t\t{\n\t\t\treturn ul4._rfind(obj, sub, start, end);\n\t\t}\n\t};\n\n\tul4.ListProtocol = ul4.ListProtocol.prototype;\n\tul4.ListProtocol.attrs = ul4._makeset(\n\t\t\"append\",\n\t\t\"insert\",\n\t\t\"pop\",\n\t\t\"count\",\n\t\t\"find\",\n\t\t\"rfind\"\n\t);\n\n\tul4.expose(ul4.ListProtocol.append, [\"*items\"]);\n\tul4.expose(ul4.ListProtocol.insert, [\"pos\", \"*items\"]);\n\tul4.expose(ul4.ListProtocol.pop, [\"pos=\", -1]);\n\tul4.expose(ul4.ListProtocol.count, [\"sub\", \"start=\", null, \"end=\", null]);\n\tul4.expose(ul4.ListProtocol.find, [\"sub\", \"start=\", null, \"end=\", null]);\n\tul4.expose(ul4.ListProtocol.rfind, [\"sub\", \"start=\", null, \"end=\", null]);\n\n\tul4.MapProtocol = class MapProtocol extends ul4.Protocol.constructor\n\t{\n\t\tul4type(obj)\n\t\t{\n\t\t\treturn \"dict\";\n\t\t}\n\n\t\tgetattr(obj, attrname)\n\t\t{\n\t\t\tif (this.attrs.has(attrname))\n\t\t\t{\n\t\t\t\tlet attr = this[attrname];\n\t\t\t\tlet realattr = function realattr(...args) {\n\t\t\t\t\treturn attr.apply(this, [obj, ...args]);\n\t\t\t\t};\n\t\t\t\trealattr.name = attr.name;\n\t\t\t\trealattr._ul4_name = attr._ul4_name || attr.name;\n\t\t\t\trealattr._ul4_signature = attr._ul4_signature;\n\t\t\t\trealattr._ul4_needsobject = attr._ul4_needsobject;\n\t\t\t\trealattr._ul4_needscontext = attr._ul4_needscontext;\n\t\t\t\treturn realattr;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn obj.get(attrname);\n\t\t}\n\n\t\tget(obj, key, default_=null)\n\t\t{\n\t\t\tif (obj.has(key))\n\t\t\t\treturn obj.get(key);\n\t\t\treturn default_;\n\t\t}\n\n\t\titems(obj)\n\t\t{\n\t\t\tlet result = [];\n\t\t\tobj.forEach(function(value, key) {\n\t\t\t\tresult.push([key, value]);\n\t\t\t});\n\t\t\treturn result;\n\t\t}\n\n\t\tvalues(obj)\n\t\t{\n\t\t\tlet result = [];\n\t\t\tobj.forEach(function(value, key) {\n\t\t\t\tresult.push(value);\n\t\t\t});\n\t\t\treturn result;\n\t\t}\n\n\t\tupdate(obj, other, kwargs)\n\t\t{\n\t\t\treturn ul4._update(obj, other, kwargs);\n\t\t}\n\n\t\tclear(obj)\n\t\t{\n\t\t\tobj.clear();\n\t\t\treturn null;\n\t\t}\n\t};\n\n\tul4.MapProtocol = ul4.MapProtocol.prototype;\n\tul4.MapProtocol.attrs = ul4._makeset(\"get\", \"items\", \"values\", \"update\", \"clear\");\n\n\tul4.expose(ul4.MapProtocol.get, [\"key\", \"default=\", null]);\n\tul4.expose(ul4.MapProtocol.items, []);\n\tul4.expose(ul4.MapProtocol.values, []);\n\tul4.expose(ul4.MapProtocol.update, [\"*other\", \"**kwargs\"]);\n\tul4.expose(ul4.MapProtocol.clear, []);\n\n\tul4.SetProtocol = class SetProtocol extends ul4.Protocol.constructor\n\t{\n\t\tul4type(obj)\n\t\t{\n\t\t\treturn \"set\";\n\t\t}\n\n\t\tadd(obj, items)\n\t\t{\n\t\t\tfor (let i = 0; i < items.length; ++i)\n\t\t\t{\n\t\t\t\tobj.add(items[i]);\n\t\t\t}\n\t\t}\n\n\t\tclear(obj)\n\t\t{\n\t\t\tobj.clear();\n\t\t\treturn null;\n\t\t}\n\t};\n\n\tul4.SetProtocol = ul4.SetProtocol.prototype;\n\tul4.SetProtocol.attrs = ul4._makeset(\"add\", \"clear\");\n\n\tul4.expose(ul4.SetProtocol.add, [\"*items\"]);\n\tul4.expose(ul4.SetProtocol.clear, []);\n\n\tul4.DateProtocol = class DateProtocol extends ul4.Protocol.constructor\n\t{\n\t\tul4type(obj)\n\t\t{\n\t\t\treturn \"date\";\n\t\t}\n\n\t\tweekday(obj)\n\t\t{\n\t\t\treturn ul4.DateTimeProtocol.weekday(obj._date);\n\t\t}\n\n\t\tcalendar(obj, firstweekday=0, mindaysinfirstweek=4)\n\t\t{\n\t\t\treturn ul4.DateTimeProtocol.calendar(obj._date, firstweekday, mindaysinfirstweek);\n\t\t}\n\n\t\tweek(obj, firstweekday=0, mindaysinfirstweek=4)\n\t\t{\n\t\t\treturn ul4.DateProtocol.calendar(obj, firstweekday, mindaysinfirstweek)[1];\n\t\t}\n\n\t\tday(obj)\n\t\t{\n\t\t\treturn obj._date.getDate();\n\t\t}\n\n\t\tmonth(obj)\n\t\t{\n\t\t\treturn obj._date.getMonth()+1;\n\t\t}\n\n\t\tyear(obj)\n\t\t{\n\t\t\treturn obj._date.getFullYear();\n\t\t}\n\n\t\tmimeformat(obj)\n\t\t{\n\t\t\tlet weekdayname = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"];\n\t\t\tlet monthname = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n\t\t\tlet d = obj._date;\n\n\t\t\treturn weekdayname[ul4.DateTimeProtocol.weekday(d)] + \", \" + ul4._lpad(d.getDate(), \"0\", 2) + \" \" + monthname[d.getMonth()] + \" \" + d.getFullYear();\n\t\t}\n\n\t\tisoformat(obj)\n\t\t{\n\t\t\tlet d = obj._date;\n\t\t\treturn d.getFullYear() + \"-\" + ul4._lpad((d.getMonth()+1).toString(), \"0\", 2) + \"-\" + ul4._lpad(d.getDate().toString(), \"0\", 2);\n\t\t}\n\n\t\tyearday(obj)\n\t\t{\n\t\t\treturn ul4.DateTimeProtocol.yearday(obj._date);\n\t\t}\n\t};\n\n\tul4.DateProtocol = ul4.DateProtocol.prototype;\n\tul4.DateProtocol.attrs = ul4._makeset(\"weekday\", \"week\", \"calendar\", \"day\", \"month\", \"year\", \"mimeformat\", \"isoformat\", \"yearday\");\n\n\tul4.expose(ul4.DateProtocol.weekday, []);\n\tul4.expose(ul4.DateProtocol.calendar, [\"firstweekday=\", 0, \"mindaysinfirstweek=\", 4]);\n\tul4.expose(ul4.DateProtocol.week, [\"firstweekday=\", 0, \"mindaysinfirstweek=\", 4]);\n\tul4.expose(ul4.DateProtocol.day, []);\n\tul4.expose(ul4.DateProtocol.month, []);\n\tul4.expose(ul4.DateProtocol.year, []);\n\tul4.expose(ul4.DateProtocol.mimeformat, []);\n\tul4.expose(ul4.DateProtocol.isoformat, []);\n\tul4.expose(ul4.DateProtocol.yearday, []);\n\n\tul4.DateTimeProtocol = class DatetimeProtocol extends ul4.Protocol.constructor\n\t{\n\t\tul4type(obj)\n\t\t{\n\t\t\treturn \"datetime\";\n\t\t}\n\n\t\tweekday(obj)\n\t\t{\n\t\t\tlet d = obj.getDay();\n\t\t\treturn d ? d-1 : 6;\n\t\t}\n\n\t\tcalendar(obj, firstweekday=0, mindaysinfirstweek=4)\n\t\t{\n\t\t\t// Normalize parameters\n\t\t\tfirstweekday = ul4._mod(firstweekday, 7);\n\t\t\tif (mindaysinfirstweek < 1)\n\t\t\t\tmindaysinfirstweek = 1;\n\t\t\telse if (mindaysinfirstweek > 7)\n\t\t\t\tmindaysinfirstweek = 7;\n\n\t\t\t// ``obj`` might be in the first week of the next year, or last week of\n\t\t\t// the previous year, so we might have to try those too.\n\t\t\tfor (let offset = +1; offset >= -1; --offset)\n\t\t\t{\n\t\t\t\tlet year = obj.getFullYear() + offset;\n\t\t\t\t// ``refdate`` will always be in week 1\n\t\t\t\tlet refDate = new Date(year, 0, mindaysinfirstweek);\n\t\t\t\t// Go back to the start of ``refdate``s week (i.e. day 1 of week 1)\n\t\t\t\tlet weekDayDiff = ul4._mod(ul4.DateTimeProtocol.weekday(refDate) - firstweekday, 7);\n\t\t\t\tlet weekStartYear = refDate.getFullYear();\n\t\t\t\tlet weekStartMonth = refDate.getMonth();\n\t\t\t\tlet weekStartDay = refDate.getDate() - weekDayDiff;\n\t\t\t\tlet weekStart = new Date(weekStartYear, weekStartMonth, weekStartDay);\n\t\t\t\t// Is our date ``obj`` at or after day 1 of week 1?\n\t\t\t\tif (obj.getTime() >= weekStart.getTime())\n\t\t\t\t{\n\t\t\t\t\tlet diff = ul4.SubAST.prototype._do(obj, weekStart);\n\t\t\t\t\t// Add 1, because the first week is week 1, not week 0\n\t\t\t\t\tlet week = Math.floor(diff.days()/7) + 1;\n\t\t\t\t\treturn [year, week, ul4.DateTimeProtocol.weekday(obj)];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tweek(obj, firstweekday=0, mindaysinfirstweek=4)\n\t\t{\n\t\t\treturn ul4.DateTimeProtocol.calendar(obj, firstweekday, mindaysinfirstweek)[1];\n\t\t}\n\n\t\tday(obj)\n\t\t{\n\t\t\treturn obj.getDate();\n\t\t}\n\n\t\tmonth(obj)\n\t\t{\n\t\t\treturn obj.getMonth()+1;\n\t\t}\n\n\t\tyear(obj)\n\t\t{\n\t\t\treturn obj.getFullYear();\n\t\t}\n\n\t\thour(obj)\n\t\t{\n\t\t\treturn obj.getHours();\n\t\t}\n\n\t\tminute(obj)\n\t\t{\n\t\t\treturn obj.getMinutes();\n\t\t}\n\n\t\tsecond(obj)\n\t\t{\n\t\t\treturn obj.getSeconds();\n\t\t}\n\n\t\tmicrosecond(obj)\n\t\t{\n\t\t\treturn obj.getMilliseconds() * 1000;\n\t\t}\n\n\t\tmimeformat(obj)\n\t\t{\n\t\t\tlet weekdayname = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"];\n\t\t\tlet monthname = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n\n\t\t\treturn weekdayname[ul4.DateTimeProtocol.weekday(obj)] + \", \" + ul4._lpad(obj.getDate(), \"0\", 2) + \" \" + monthname[obj.getMonth()] + \" \" + obj.getFullYear() + \" \" + ul4._lpad(obj.getHours(), \"0\", 2) + \":\" + ul4._lpad(obj.getMinutes(), \"0\", 2) + \":\" + ul4._lpad(obj.getSeconds(), \"0\", 2) + \" GMT\";\n\t\t}\n\n\t\tisoformat(obj)\n\t\t{\n\t\t\tlet year = obj.getFullYear();\n\t\t\tlet month = obj.getMonth()+1;\n\t\t\tlet day = obj.getDate();\n\t\t\tlet hour = obj.getHours();\n\t\t\tlet minute = obj.getMinutes();\n\t\t\tlet second = obj.getSeconds();\n\t\t\tlet ms = obj.getMilliseconds();\n\t\t\tlet result = year + \"-\" + ul4._lpad(month.toString(), \"0\", 2) + \"-\" + ul4._lpad(day.toString(), \"0\", 2) + \"T\" + ul4._lpad(hour.toString(), \"0\", 2) + \":\" + ul4._lpad(minute.toString(), \"0\", 2) + \":\" + ul4._lpad(second.toString(), \"0\", 2);\n\t\t\tif (ms)\n\t\t\t\tresult += \".\" + ul4._lpad(ms.toString(), \"0\", 3) + \"000\";\n\t\t\treturn result;\n\t\t}\n\n\t\tyearday(obj)\n\t\t{\n\t\t\tlet leap = ul4._isleap(obj) ? 1 : 0;\n\t\t\tlet day = obj.getDate();\n\t\t\tswitch (obj.getMonth())\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn day;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn 31 + day;\n\t\t\t\tcase 2:\n\t\t\t\t\treturn 31 + 28 + leap + day;\n\t\t\t\tcase 3:\n\t\t\t\t\treturn 31 + 28 + leap + 31 + day;\n\t\t\t\tcase 4:\n\t\t\t\t\treturn 31 + 28 + leap + 31 + 30 + day;\n\t\t\t\tcase 5:\n\t\t\t\t\treturn 31 + 28 + leap + 31 + 30 + 31 + day;\n\t\t\t\tcase 6:\n\t\t\t\t\treturn 31 + 28 + leap + 31 + 30 + 31 + 30 + day;\n\t\t\t\tcase 7:\n\t\t\t\t\treturn 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + day;\n\t\t\t\tcase 8:\n\t\t\t\t\treturn 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + day;\n\t\t\t\tcase 9:\n\t\t\t\t\treturn 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + day;\n\t\t\t\tcase 10:\n\t\t\t\t\treturn 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + day;\n\t\t\t\tcase 11:\n\t\t\t\t\treturn 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + day;\n\t\t\t}\n\t\t}\n\t};\n\n\tul4.DateTimeProtocol = ul4.DateTimeProtocol.prototype;\n\tul4.DateTimeProtocol.attrs = ul4._makeset(\"weekday\", \"week\", \"calendar\", \"day\", \"month\", \"year\", \"hour\", \"minute\", \"second\", \"microsecond\", \"mimeformat\", \"isoformat\", \"yearday\");\n\n\tul4.expose(ul4.DateTimeProtocol.weekday, []);\n\tul4.expose(ul4.DateTimeProtocol.calendar, [\"firstweekday=\", 0, \"mindaysinfirstweek=\", 4]);\n\tul4.expose(ul4.DateTimeProtocol.week, [\"firstweekday=\", 0, \"mindaysinfirstweek=\", 4]);\n\tul4.expose(ul4.DateTimeProtocol.day, []);\n\tul4.expose(ul4.DateTimeProtocol.month, []);\n\tul4.expose(ul4.DateTimeProtocol.year, []);\n\tul4.expose(ul4.DateTimeProtocol.hour, []);\n\tul4.expose(ul4.DateTimeProtocol.minute, []);\n\tul4.expose(ul4.DateTimeProtocol.second, []);\n\tul4.expose(ul4.DateTimeProtocol.microsecond, []);\n\tul4.expose(ul4.DateTimeProtocol.mimeformat, []);\n\tul4.expose(ul4.DateTimeProtocol.isoformat, []);\n\tul4.expose(ul4.DateTimeProtocol.yearday, []);\n\n\tul4.ObjectProtocol = class ObjectProtocol extends ul4.Protocol.constructor\n\t{\n\t\tul4type(obj)\n\t\t{\n\t\t\treturn \"dict\";\n\t\t}\n\n\t\tgetattr(obj, attrname)\n\t\t{\n\t\t\tlet result;\n\t\t\tif (obj && typeof(obj.__getattr__) === \"function\") // test this before the generic object test\n\t\t\t\tresult = obj.__getattr__(attrname);\n\t\t\telse\n\t\t\t\tresult = obj[attrname];\n\t\t\tif (typeof(result) !== \"function\")\n\t\t\t\treturn result;\n\t\t\tlet realresult = function(...args) {\n\t\t\t\t// We can use ``apply`` here, as we know that ``obj`` is a real object.\n\t\t\t\treturn result.apply(obj, args);\n\t\t\t};\n\t\t\trealresult._ul4_name = result._ul4_name || result.name;\n\t\t\trealresult._ul4_signature = result._ul4_signature;\n\t\t\trealresult._ul4_needsobject = result._ul4_needsobject;\n\t\t\trealresult._ul4_needscontext = result._ul4_needscontext;\n\t\t\treturn realresult;\n\t\t}\n\n\t\tget(obj, key, default_=null)\n\t\t{\n\t\t\tlet result = obj[key];\n\t\t\tif (typeof(result) === \"undefined\")\n\t\t\t\treturn default_;\n\t\t\treturn result;\n\t\t}\n\n\t\titems(obj)\n\t\t{\n\t\t\tlet result = [];\n\t\t\tfor (let key in obj)\n\t\t\t\tresult.push([key, obj[key]]);\n\t\t\treturn result;\n\t\t}\n\n\t\tvalues(obj)\n\t\t{\n\t\t\tlet result = [];\n\t\t\tfor (let key in obj)\n\t\t\t\tresult.push(obj[key]);\n\t\t\treturn result;\n\t\t}\n\n\t\tclear(obj)\n\t\t{\n\t\t\tfor (let key in obj)\n\t\t\t\tdelete obj[key];\n\t\t}\n\t};\n\n\tul4.ObjectProtocol = ul4.ObjectProtocol.prototype;\n\tul4.ObjectProtocol.attrs = ul4._makeset(\"get\", \"items\", \"values\", \"update\", \"clear\");\n\n\tul4.expose(ul4.ObjectProtocol.get, [\"key\", \"default=\", null]);\n\tul4.expose(ul4.ObjectProtocol.items, []);\n\tul4.expose(ul4.ObjectProtocol.values, []);\n\tul4.expose(ul4.ObjectProtocol.clear, []);\n\n\tul4.Context = class Context\n\t{\n\t\tconstructor(vars)\n\t\t{\n\t\t\tif (vars === null || typeof(vars) === \"undefined\")\n\t\t\t\tvars = {};\n\t\t\tthis.vars = vars;\n\t\t\tthis.indents = [];\n\t\t\tthis.escapes = [];\n\t\t\tthis._output = [];\n\t\t}\n\n\t\t/* Return a clone of the ``Context``, but with a fresh empty ``vars`` objects that inherits from the previous one.\n\t\t * This is used by the various comprehensions to avoid leaking loop variables.\n\t\t */\n\t\tinheritvars()\n\t\t{\n\t\t\tlet context = Object.create(this);\n\t\t\tcontext.vars = Object.create(this.vars);\n\t\t\treturn context;\n\t\t}\n\n\t\t/* Return a clone of the ``Context`` with one additional indentation (this is used by ``RenderAST``) */\n\t\twithindent(indent)\n\t\t{\n\t\t\tlet context = Object.create(this);\n\t\t\tif (indent !== null)\n\t\t\t{\n\t\t\t\tcontext.indents = this.indents.slice();\n\t\t\t\tcontext.indents.push(indent);\n\t\t\t}\n\t\t\treturn context;\n\t\t}\n\n\t\t/* Return a clone of the ``Context`` with the output buffer replaced (this is used by ``renders`` to collect the output in a separate buffer) */\n\t\treplaceoutput()\n\t\t{\n\t\t\tlet context = Object.create(this);\n\t\t\tcontext._output = [];\n\t\t\treturn context;\n\t\t}\n\n\t\tclone(vars)\n\t\t{\n\t\t\treturn Object.create(this);\n\t\t}\n\n\t\toutput(value)\n\t\t{\n\t\t\tfor (let i = 0; i < this.escapes.length; ++i)\n\t\t\t{\n\t\t\t\tlet escape = this.escapes[i];\n\t\t\t\tvalue = escape(value);\n\t\t\t}\n\t\t\tthis._output.push(value);\n\t\t}\n\n\t\tgetoutput()\n\t\t{\n\t\t\treturn this._output.join(\"\");\n\t\t}\n\n\t\tget(name)\n\t\t{\n\t\t\treturn this.vars[name];\n\t\t}\n\n\t\tset(name, value)\n\t\t{\n\t\t\tthis.vars[name] = value;\n\t\t}\n\t};\n\n\t/// Exceptions\n\n\t// Note that extending ``Error`` doesn't work, so we do it the \"classic\" way\n\tul4.Exception = function Exception(message, fileName, lineNumber)\n\t{\n\t\tlet instance = new Error(message, fileName, lineNumber);\n\t\tObject.setPrototypeOf(instance, Object.getPrototypeOf(this));\n\t\tinstance.__id__ = _nextid++;\n\t\tinstance.context = null;\n\t\treturn instance;\n\t};\n\n\tul4.Exception.prototype = Object.create(Error.prototype, {\n\t\tconstructor: {\n\t\t\tvalue: Error,\n\t\t\tenumerable: false,\n\t\t\twritable: true,\n\t\t\tconfigurable: true\n\t\t}\n\t});\n\n\tif (Object.setPrototypeOf)\n\t\tObject.setPrototypeOf(ul4.Exception, Error);\n\telse\n\t\tul4.Exception.__proto__ = Error;\n\n\tul4.Exception.prototype.__getattr__ = function __getattr__(attrname)\n\t{\n\t\tswitch (attrname)\n\t\t{\n\t\t\tcase \"context\":\n\t\t\t\treturn this.context;\n\t\t\tdefault:\n\t\t\t\tthrow new ul4.AttributeError(this, attrname);\n\t\t}\n\t};\n\n\t// Exceptions used internally by UL4 for flow control\n\tul4.InternalException = class InternalException extends ul4.Exception\n\t{\n\t};\n\n\t// Control flow exceptions\n\tul4.ReturnException = class ReturnException extends ul4.InternalException\n\t{\n\t\tconstructor(result)\n\t\t{\n\t\t\tsuper(\"return\");\n\t\t\tthis.result = result;\n\t\t}\n\t};\n\n\tul4.BreakException = class BreakException extends ul4.InternalException\n\t{\n\t\tconstructor()\n\t\t{\n\t\t\tsuper(\"break\");\n\t\t}\n\t};\n\n\tul4.ContinueException = class ContinueException extends ul4.InternalException\n\t{\n\t\tconstructor()\n\t\t{\n\t\t\tsuper(\"continue\");\n\t\t}\n\t};\n\n\t// Real exceptions raised by various parts of UL4\n\tul4.SyntaxError = class SyntaxError extends ul4.Exception\n\t{\n\t};\n\n\tul4.LValueRequiredError = class LValueRequiredError extends ul4.SyntaxError\n\t{\n\t\tconstructor()\n\t\t{\n\t\t\tsuper(\"lvalue required\");\n\t\t}\n\t};\n\n\tul4.TypeError = class TypeError extends ul4.Exception\n\t{\n\t};\n\n\tul4.ValueError = class ValueError extends ul4.Exception\n\t{\n\t};\n\n\tul4.ArgumentError = class ArgumentError extends ul4.Exception\n\t{\n\t};\n\n\tul4.NotSubscriptableError = class NotSubscriptableError extends ul4.Exception\n\t{\n\t\tconstructor(obj)\n\t\t{\n\t\t\tsuper(\"Object of type \" + _type(obj) + \" is not subscriptable\");\n\t\t\tthis.obj = obj;\n\t\t}\n\n\t\ttoString()\n\t\t{\n\t\t\treturn \"Object of type \" + _type(this.obj) + \" is not subscriptable\";\n\t\t}\n\t};\n\n\tul4.ZeroDivisionError = class ZeroDivisionError extends ul4.Exception\n\t{\n\t\tconstructor()\n\t\t{\n\t\t\tsuper(\"division by zero\");\n\t\t}\n\t};\n\n\tul4.IndexError = class IndexError extends ul4.Exception\n\t{\n\t\tconstructor(obj, index)\n\t\t{\n\t\t\tsuper(\"index \" + ul4._repr(index) + \" out of range\");\n\t\t\tthis.obj = obj;\n\t\t\tthis.index = index;\n\t\t}\n\n\t\ttoString()\n\t\t{\n\t\t\treturn \"index \" + this.index + \" out of range for \" + ul4._type(this.obj);\n\t\t}\n\t};\n\n\tul4.AttributeError = class AttributeError extends ul4.Exception\n\t{\n\t\tconstructor(obj, attrname)\n\t\t{\n\t\t\tsuper(\"object of type \" + ul4._type(obj) + \" has no attribute \" + ul4._repr(attrname));\n\t\t\tthis.obj = obj;\n\t\t\tthis.attrname = attrname;\n\t\t}\n\t};\n\n\t/// Exception that wraps other exceptions while they bubble up the stack\n\tul4.LocationError = class LocationError extends ul4.Exception\n\t{\n\t\tconstructor(location)\n\t\t{\n\t\t\tsuper(\"nested exception in \" + ul4._repr(location));\n\t\t\tthis.location = location;\n\t\t}\n\n\t\t_templateprefix()\n\t\t{\n\t\t\tlet template = this.location.template;\n\t\t\tlet out = [];\n\t\t\tif (template.parenttemplate !== null)\n\t\t\t\tout.push(\"in local template \");\n\t\t\telse\n\t\t\t\tout.push(\"in template \");\n\t\t\tlet first = true;\n\t\t\twhile (template != null)\n\t\t\t{\n\t\t\t\tif (first)\n\t\t\t\t\tfirst = false;\n\t\t\t\telse\n\t\t\t\t\tout.push(\" in \");\n\t\t\t\tout.push(template.name ? ul4._repr(template.name) : \"(unnamed)\");\n\t\t\t\ttemplate = template.parenttemplate;\n\t\t\t}\n\t\t\treturn out.join(\"\");\n\t\t}\n\n\t\ttoString()\n\t\t{\n\t\t\tlet template = this.location.template;\n\t\t\tlet templateprefix = this._templateprefix();\n\n\t\t\tlet prefix = this.location.sourceprefix;\n\t\t\tlet code = this.location.source;\n\t\t\tlet suffix = this.location.sourcesuffix;\n\t\t\tprefix = ul4._repr(prefix).slice(1, -1);\n\t\t\tcode = ul4._repr(code).slice(1, -1);\n\t\t\tsuffix = ul4._repr(suffix).slice(1, -1);\n\n\t\t\tlet text = prefix + code + suffix;\n\t\t\tlet underline = ul4._str_repeat(\"\\u00a0\", prefix.length) + ul4._str_repeat(\"~\", code.length);\n\n\t\t\tlet pos = \"offset \" + this.location.pos.start + \":\" + this.location.pos.stop + \"; line \" + this.location.line + \"; col \" + this.location.col;\n\n\t\t\tlet message = templateprefix + \": \" + pos + \"\\n\" + text + \"\\n\" + underline;\n\t\t\treturn message;\n\t\t}\n\n\t\t__getattr__(attrname)\n\t\t{\n\t\t\tswitch (attrname)\n\t\t\t{\n\t\t\t\tcase \"context\":\n\t\t\t\t\treturn this.context;\n\t\t\t\tcase \"location\":\n\t\t\t\t\treturn this.location;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ul4.AttributeError(this, attrname);\n\t\t\t}\n\t\t}\n\t};\n\n\t/// Classes for the syntax tree\n\tul4.AST = class AST extends ul4.Proto\n\t{\n\t\tconstructor(template, pos)\n\t\t{\n\t\t\tsuper();\n\t\t\tthis.template = template;\n\t\t\tthis.pos = pos;\n\t\t\tthis._line = null;\n\t\t\tthis._col = null;\n\t\t}\n\n\t\tget fullsource()\n\t\t{\n\t\t\treturn this.template._source;\n\t\t}\n\n\t\tget source()\n\t\t{\n\t\t\treturn this.pos.of(this.template._source);\n\t\t}\n\n\t\tget sourceprefix()\n\t\t{\n\t\t\tlet outerstartpos = this.pos.start;\n\t\t\tlet innerstartpos = outerstartpos;\n\t\t\tlet source = this.fullsource;\n\n\t\t\tlet maxprefix = 40;\n\t\t\tlet preprefix = \"\\u2026\";\n\t\t\twhile (maxprefix > 0)\n\t\t\t{\n\t\t\t\t// We arrived at the start of the source code\n\t\t\t\tif (outerstartpos === 0)\n\t\t\t\t{\n\t\t\t\t\tpreprefix = \"\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t// We arrived at the start of the line\n\t\t\t\tif (source.charAt(outerstartpos-1) === \"\\n\")\n\t\t\t\t{\n\t\t\t\t\tpreprefix = \"\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t--maxprefix;\n\t\t\t\t--outerstartpos;\n\t\t\t}\n\t\t\treturn preprefix + source.substring(outerstartpos, innerstartpos);\n\t\t}\n\n\t\tget sourcesuffix()\n\t\t{\n\t\t\tlet outerstoppos = this.pos.stop;\n\t\t\tlet innerstoppos = outerstoppos;\n\t\t\tlet source = this.fullsource;\n\n\t\t\tlet maxsuffix = 40;\n\t\t\tlet postsuffix = \"\\u2026\";\n\t\t\twhile (maxsuffix > 0)\n\t\t\t{\n\t\t\t\t// We arrived at the ed of the source code\n\t\t\t\tif (outerstoppos >= source.length)\n\t\t\t\t{\n\t\t\t\t\tpostsuffix = \"\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t// We arrived at the end of the line\n\t\t\t\tif (source.charAt(outerstoppos) === \"\\n\")\n\t\t\t\t{\n\t\t\t\t\tpostsuffix = \"\";\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t--maxsuffix;\n\t\t\t\t++outerstoppos;\n\t\t\t}\n\t\t\treturn source.substring(innerstoppos, outerstoppos) + postsuffix;\n\t\t}\n\n\t\tget line()\n\t\t{\n\t\t\tif (this._line === null)\n\t\t\t\tthis._calculateLineCol();\n\t\t\treturn this._line;\n\t\t}\n\n\t\tget col()\n\t\t{\n\t\t\tif (this._col === null)\n\t\t\t\tthis._calculateLineCol();\n\t\t\treturn this._col;\n\t\t}\n\n\t\t_calculateLineCol()\n\t\t{\n\t\t\tthis._line = 1\n\t\t\tthis._col = 1;\n\t\t\tlet stop = this.pos.start;\n\t\t\tfor (let i = 0; i < stop; ++i)\n\t\t\t{\n\t\t\t\tif (this.template.source[i] === \"\\n\")\n\t\t\t\t{\n\t\t\t\t\t++this._line;\n\t\t\t\t\tthis._col = 1;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\t++this._col;\n\t\t\t}\n\t\t}\n\n\t\t__getattr__(attrname)\n\t\t{\n\t\t\tif (attrname === \"type\" || attrname === \"fullsource\" || attrname === \"source\" || attrname === \"sourceprefix\" || attrname === \"sourcesuffix\" || attrname === \"line\" || attrname === \"col\")\n\t\t\t\treturn this[attrname];\n\t\t\telse if (this._ul4onattrs.indexOf(attrname) >= 0)\n\t\t\t\treturn this[attrname];\n\t\t\tthrow new ul4.AttributeError(this, attrname);\n\t\t}\n\n\t\t__setitem__(attrname, value)\n\t\t{\n\t\t\tthrow new ul4.TypeError(\"object is immutable\");\n\t\t}\n\n\t\t__str__()\n\t\t{\n\t\t\tlet out = [];\n\t\t\tthis._str(out);\n\t\t\treturn ul4._formatsource(out);\n\t\t}\n\n\t\t__repr__()\n\t\t{\n\t\t\tlet out = [];\n\t\t\tthis._repr(out);\n\t\t\treturn ul4._formatsource(out);\n\t\t}\n\n\t\t_decorate_exception(exc)\n\t\t{\n\t\t\twhile (exc.context !== undefined && exc.context !== null)\n\t\t\t\texc = exc.context;\n\t\t\texc.context = new ul4.LocationError(this);\n\t\t}\n\n\t\t_handle_eval(context)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn this._eval(context);\n\t\t\t}\n\t\t\tcatch (exc)\n\t\t\t{\n\t\t\t\tif (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError))\n\t\t\t\t\tthis._decorate_exception(exc);\n\t\t\t\tthrow exc;\n\t\t\t}\n\t\t}\n\n\t\t_handle_eval_set(context, value)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn this._eval_set(context, value);\n\t\t\t}\n\t\t\tcatch (exc)\n\t\t\t{\n\t\t\t\tif (!(exc instanceof ul4.LocationError))\n\t\t\t\t\tthis._decorate_exception(exc);\n\t\t\t\tthrow exc;\n\t\t\t}\n\t\t}\n\n\t\t_eval_set(context, value)\n\t\t{\n\t\t\tthrow new ul4.LValueRequiredError();\n\t\t}\n\n\t\t_handle_eval_modify(context, operator, value)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn this._eval_modify(context, operator, value);\n\t\t\t}\n\t\t\tcatch (exc)\n\t\t\t{\n\t\t\t\tif (!(exc instanceof ul4.LocationError))\n\t\t\t\t\tthis._decorate_exception(exc);\n\t\t\t\tthrow exc;\n\t\t\t}\n\t\t}\n\n\t\t_eval_modify(context, operator, value)\n\t\t{\n\t\t\tthrow new ul4.LValueRequiredError();\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(this.source.replace(/\\r?\\n/g, ' '));\n\t\t}\n\n\t\tul4ondump(encoder)\n\t\t{\n\t\t\tfor (let i = 0; i < this._ul4onattrs.length; ++i)\n\t\t\t{\n\t\t\t\tlet attrname = this._ul4onattrs[i];\n\t\t\t\tencoder.dump(this[attrname]);\n\t\t\t}\n\t\t}\n\n\t\tul4onload(decoder)\n\t\t{\n\t\t\tfor (let i = 0; i < this._ul4onattrs.length; ++i)\n\t\t\t{\n\t\t\t\tlet attrname = this._ul4onattrs[i];\n\t\t\t\tthis[attrname] = decoder.load();\n\t\t\t}\n\t\t}\n\t};\n\n\t// used in ul4ondump/ul4ondump to automatically dump these attributes\n\tul4.AST.prototype._ul4onattrs = [\"template\", \"pos\"];\n\n\tul4.TextAST = class TextAST extends ul4.AST\n\t{\n\t\tconstructor(template, pos)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t}\n\n\t\tget text()\n\t\t{\n\t\t\treturn this.source;\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tcontext.output(this.text);\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"text \");\n\t\t\tout.push(ul4._repr(this.text));\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\t};\n\n\tul4.IndentAST = class IndentAST extends ul4.TextAST\n\t{\n\t\tconstructor(template, pos, text)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis._text = text;\n\t\t}\n\n\t\tget text()\n\t\t{\n\t\t\tif (typeof(this.template) !== \"undefined\")\n\t\t\t\treturn this._text === null ? this.source : this._text;\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tfor (let i = 0; i < context.indents.length; ++i)\n\t\t\t{\n\t\t\t\tlet indent = context.indents[i];\n\t\t\t\tcontext.output(indent);\n\t\t\t}\n\t\t\tcontext.output(this.text);\n\t\t}\n\n\t\tul4ondump(encoder)\n\t\t{\n\t\t\tsuper.ul4ondump(encoder);\n\n\t\t\tif (this._text === this.source)\n\t\t\t\tencoder.dump(null);\n\t\t\telse\n\t\t\t\tencoder.dump(this._text);\n\t\t}\n\n\t\tul4onload(decoder)\n\t\t{\n\t\t\tsuper.ul4onload(decoder);\n\t\t\tthis._text = decoder.load();\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"indent \");\n\t\t\tout.push(ul4._repr(this.text));\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\t};\n\n\tul4.LineEndAST = class LineEndAST extends ul4.TextAST\n\t{\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"lineend \");\n\t\t\tout.push(ul4._repr(this.text));\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\t};\n\n\tul4.CodeAST = class CodeAST extends ul4.AST\n\t{\n\t};\n\n\tul4.ConstAST = class ConstAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, value)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.value = value;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\treturn this.value;\n\t\t}\n\t};\n\n\tul4.ConstAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"value\"]);\n\n\tul4.ItemArgBase = class ItemArgBase extends ul4.CodeAST\n\t{\n\t\t_handle_eval_list(context, result)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn this._eval_list(context, result);\n\t\t\t}\n\t\t\tcatch (exc)\n\t\t\t{\n\t\t\t\tif (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError))\n\t\t\t\t\tthis._decorate_exception(exc);\n\t\t\t\tthrow exc;\n\t\t\t}\n\t\t}\n\n\t\t_handle_eval_set(context, result)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn this._eval_set(context, result);\n\t\t\t}\n\t\t\tcatch (exc)\n\t\t\t{\n\t\t\t\tif (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError))\n\t\t\t\t\tthis._decorate_exception(exc);\n\t\t\t\tthrow exc;\n\t\t\t}\n\t\t}\n\n\t\t_handle_eval_dict(context, result)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn this._eval_dict(context, result);\n\t\t\t}\n\t\t\tcatch (exc)\n\t\t\t{\n\t\t\t\tif (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError))\n\t\t\t\t\tthis._decorate_exception(exc);\n\t\t\t\tthrow exc;\n\t\t\t}\n\t\t}\n\n\t\t_handle_eval_call(context, args, kwargs)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn this._eval_call(context, args, kwargs);\n\t\t\t}\n\t\t\tcatch (exc)\n\t\t\t{\n\t\t\t\tif (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError))\n\t\t\t\t\tthis._decorate_exception(exc);\n\t\t\t\tthrow exc;\n\t\t\t}\n\t\t}\n\t};\n\n\tul4.SeqItemAST = class SeqItemAST extends ul4.ItemArgBase\n\t{\n\t\tconstructor(template, pos, value)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.value = value;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval_list(context, result)\n\t\t{\n\t\t\tlet value = this.value._handle_eval(context);\n\t\t\tresult.push(value);\n\t\t}\n\n\t\t_eval_set(context, result)\n\t\t{\n\t\t\tlet value = this.value._handle_eval(context);\n\t\t\tresult.add(value);\n\t\t}\n\t};\n\n\tul4.SeqItemAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat([\"value\"]);\n\n\tul4.UnpackSeqItemAST = class UnpackSeqItemAST extends ul4.ItemArgBase\n\t{\n\t\tconstructor(template, pos, value)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.value = value;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval_list(context, result)\n\t\t{\n\t\t\tlet value = this.value._handle_eval(context);\n\t\t\tfor (let iter = ul4._iter(value);;)\n\t\t\t{\n\t\t\t\tlet item = iter.next();\n\t\t\t\tif (item.done)\n\t\t\t\t\tbreak;\n\t\t\t\tresult.push(item.value);\n\t\t\t}\n\t\t}\n\n\t\t_eval_set(context, result)\n\t\t{\n\t\t\tlet value = this.value._handle_eval(context);\n\t\t\tfor (let iter = ul4._iter(value);;)\n\t\t\t{\n\t\t\t\tlet item = iter.next();\n\t\t\t\tif (item.done)\n\t\t\t\t\tbreak;\n\t\t\t\tresult.add(item.value);\n\t\t\t}\n\t\t}\n\t};\n\n\tul4.UnpackSeqItemAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat([\"value\"]);\n\n\tul4.DictItemAST = class DictItemAST extends ul4.ItemArgBase\n\t{\n\t\tconstructor(template, pos, key, value)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.key = key;\n\t\t\tthis.value = value;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval_dict(context, result)\n\t\t{\n\t\t\tlet key = this.key._handle_eval(context);\n\t\t\tlet value = this.value._handle_eval(context);\n\t\t\tul4._setmap(result, key, value);\n\t\t}\n\t};\n\n\tul4.DictItemAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat([\"key\", \"value\"]),\n\n\tul4.UnpackDictItemAST = class UnpackDictItemAST extends ul4.ItemArgBase\n\t{\n\t\tconstructor(template, pos, item)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.item = item;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval_dict(context, result)\n\t\t{\n\t\t\tlet item = this.item._handle_eval(context);\n\t\t\tif (ul4._islist(item))\n\t\t\t{\n\t\t\t\tfor (let i = 0; i < item.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tlet subitem = item[i];\n\t\t\t\t\tif (!ul4._islist(subitem) || subitem.length != 2)\n\t\t\t\t\t\tthrow new ul4.ArgumentError(\"** requires a list of (key, value) pairs\");\n\t\t\t\t\tul4._setmap(result, subitem[0], subitem[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (ul4._ismap(item))\n\t\t\t{\n\t\t\t\titem.forEach(function(value, key) {\n\t\t\t\t\tul4._setmap(result, key, value);\n\t\t\t\t});\n\t\t\t}\n\t\t\telse if (ul4._isobject(item))\n\t\t\t{\n\t\t\t\tfor (let key in item)\n\t\t\t\t\tul4._setmap(result, key, item[key]);\n\t\t\t}\n\t\t}\n\t};\n\n\tul4.UnpackDictItemAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat([\"item\"]);\n\n\tul4.PosArgAST = class PosArgAST extends ul4.ItemArgBase\n\t{\n\t\tconstructor(template, pos, value)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.value = value;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval_call(context, args, kwargs)\n\t\t{\n\t\t\tlet value = this.value._handle_eval(context);\n\t\t\targs.push(value);\n\t\t}\n\t};\n\n\tul4.PosArgAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat([\"value\"]);\n\n\tul4.KeywordArgAST = class KeywordArgAST extends ul4.ItemArgBase\n\t{\n\t\tconstructor(template, pos, name, value)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.name = name;\n\t\t\tthis.value = value;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval_call(context, args, kwargs)\n\t\t{\n\t\t\tif (kwargs.hasOwnProperty(this.name))\n\t\t\t\tthrow new ul4.ArgumentError(\"duplicate keyword argument \" + this.name);\n\t\t\tlet value = this.value._handle_eval(context);\n\t\t\tkwargs[this.name] = value;\n\t\t}\n\t};\n\n\tul4.KeywordArgAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat([\"name\", \"value\"]);\n\n\tul4.UnpackListArgAST = class UnpackListArgAST extends ul4.ItemArgBase\n\t{\n\t\tconstructor(template, pos, item)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.item = item;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval_call(context, args, kwargs)\n\t\t{\n\t\t\tlet item = this.item._handle_eval(context);\n\t\t\targs.push(...item);\n\t\t}\n\t};\n\n\tul4.UnpackListArgAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat([\"item\"]);\n\n\tul4.UnpackDictArgAST = class UnpackDictArgAST extends ul4.ItemArgBase\n\t{\n\t\tconstructor(template, pos, item)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.item = item;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval_call(context, args, kwargs)\n\t\t{\n\t\t\tlet item = this.item._handle_eval(context);\n\t\t\tif (ul4._islist(item))\n\t\t\t{\n\t\t\t\tfor (let i = 0; i < item.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tlet subitem = item[i];\n\t\t\t\t\tif (!ul4._islist(subitem) || subitem.length != 2)\n\t\t\t\t\t\tthrow new ul4.ArgumentError(\"** requires a list of (key, value) pairs\");\n\t\t\t\t\tlet [key, value] = subitem;\n\t\t\t\t\tif (kwargs.hasOwnProperty(key))\n\t\t\t\t\t\tthrow new ul4.ArgumentError(\"duplicate keyword argument \" + key);\n\t\t\t\t\tkwargs[key] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (ul4._ismap(item))\n\t\t\t{\n\t\t\t\titem.forEach(function(value, key) {\n\t\t\t\t\tif (kwargs.hasOwnProperty(key))\n\t\t\t\t\t\tthrow new ul4.ArgumentError(\"duplicate keyword argument \" + key);\n\t\t\t\t\tkwargs[key] = value;\n\t\t\t\t});\n\t\t\t}\n\t\t\telse if (ul4._isobject(item))\n\t\t\t{\n\t\t\t\tfor (let key in item)\n\t\t\t\t{\n\t\t\t\t\tif (kwargs.hasOwnProperty(key))\n\t\t\t\t\t\tthrow new ul4.ArgumentError(\"duplicate keyword argument \" + key);\n\t\t\t\t\tkwargs[key] = item[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tul4.UnpackDictArgAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat([\"item\"]);\n\n\tul4.ListAST = class ListAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.items = [];\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet result = [];\n\t\t\tfor (let i = 0; i < this.items.length; ++i)\n\t\t\t{\n\t\t\t\tlet item = this.items[i];\n\t\t\t\titem._handle_eval_list(context, result);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tul4.ListAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"items\"]);\n\n\tul4.ListCompAST = class ListCompAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, item, varname, container, condition)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.item = item;\n\t\t\tthis.varname = varname;\n\t\t\tthis.container = container;\n\t\t\tthis.condition = condition;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet container = this.container._handle_eval(context);\n\n\t\t\tlet localcontext = context.inheritvars();\n\n\t\t\tlet result = [];\n\t\t\tfor (let iter = ul4._iter(container);;)\n\t\t\t{\n\t\t\t\tlet item = iter.next();\n\t\t\t\tif (item.done)\n\t\t\t\t\tbreak;\n\t\t\t\tlet varitems = ul4._unpackvar(this.varname, item.value);\n\t\t\t\tfor (let i = 0; i < varitems.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tlet [lvalue, value] = varitems[i];\n\t\t\t\t\tlvalue._handle_eval_set(localcontext, value);\n\t\t\t\t}\n\t\t\t\tif (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext)))\n\t\t\t\t\tresult.push(this.item._handle_eval(localcontext));\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tul4.ListCompAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"item\", \"varname\", \"container\", \"condition\"]);\n\n\tul4.SetAST = class SetAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.items = [];\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet result = ul4._emptyset();\n\n\t\t\tfor (let i = 0; i < this.items.length; ++i)\n\t\t\t{\n\t\t\t\tlet item = this.items[i];\n\t\t\t\titem._handle_eval_set(context, result);\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tul4.SetAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"items\"]);\n\n\tul4.SetCompAST = class SetCompAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, item, varname, container, condition)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.item = item;\n\t\t\tthis.varname = varname;\n\t\t\tthis.container = container;\n\t\t\tthis.condition = condition;\n\t\t}\n\n\t\t__getattr__(attrname)\n\t\t{\n\t\t\tswitch (attrname)\n\t\t\t{\n\t\t\t\tcase \"item\":\n\t\t\t\t\treturn this.item;\n\t\t\t\tcase \"varname\":\n\t\t\t\t\treturn this.varname;\n\t\t\t\tcase \"container\":\n\t\t\t\t\treturn this.container;\n\t\t\t\tcase \"condition\":\n\t\t\t\t\treturn this.condition;\n\t\t\t\tdefault:\n\t\t\t\t\treturn super.__getattr__(attrname);\n\t\t\t}\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet container = this.container._handle_eval(context);\n\n\t\t\tlet localcontext = context.inheritvars();\n\n\t\t\tlet result = ul4._emptyset();\n\t\t\tfor (let iter = ul4._iter(container);;)\n\t\t\t{\n\t\t\t\tlet item = iter.next();\n\t\t\t\tif (item.done)\n\t\t\t\t\tbreak;\n\t\t\t\tlet varitems = ul4._unpackvar(this.varname, item.value);\n\t\t\t\tfor (let i = 0; i < varitems.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tlet [lvalue, value] = varitems[i];\n\t\t\t\t\tlvalue._handle_eval_set(localcontext, value);\n\t\t\t\t}\n\t\t\t\tif (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext)))\n\t\t\t\t\tresult.add(this.item._handle_eval(localcontext));\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tul4.SetCompAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"item\", \"varname\", \"container\", \"condition\"]);\n\n\tul4.DictAST = class DictAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.items = [];\n\t\t}\n\n\t\t__getattr__(attrname)\n\t\t{\n\t\t\tswitch (attrname)\n\t\t\t{\n\t\t\t\tcase \"items\":\n\t\t\t\t\treturn this.items;\n\t\t\t\tdefault:\n\t\t\t\t\treturn super.__getattr__(attrname);\n\t\t\t}\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet result = ul4._emptymap();\n\t\t\tfor (let i = 0; i < this.items.length; ++i)\n\t\t\t{\n\t\t\t\tlet item = this.items[i];\n\t\t\t\titem._handle_eval_dict(context, result);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tul4.DictAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"items\"]);\n\n\tul4.DictCompAST = class DictCompAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, key, value, varname, container, condition)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.key = key;\n\t\t\tthis.value = value;\n\t\t\tthis.varname = varname;\n\t\t\tthis.container = container;\n\t\t\tthis.condition = condition;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet container = this.container._handle_eval(context);\n\n\t\t\tlet localcontext = context.inheritvars();\n\n\t\t\tlet result = ul4._emptymap();\n\n\t\t\tfor (let iter = ul4._iter(container);;)\n\t\t\t{\n\t\t\t\tlet item = iter.next();\n\t\t\t\tif (item.done)\n\t\t\t\t\tbreak;\n\t\t\t\tlet varitems = ul4._unpackvar(this.varname, item.value);\n\t\t\t\tfor (let i = 0; i < varitems.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tlet [lvalue, value] = varitems[i];\n\t\t\t\t\tlvalue._handle_eval_set(localcontext, value);\n\t\t\t\t}\n\t\t\t\tif (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext)))\n\t\t\t\t{\n\t\t\t\t\tlet key = this.key._handle_eval(localcontext);\n\t\t\t\t\tlet value = this.value._handle_eval(localcontext);\n\t\t\t\t\tul4._setmap(result, key, value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tul4.DictCompAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"key\", \"value\", \"varname\", \"container\", \"condition\"]);\n\n\tul4.GenExprAST = class GenExprAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, item, varname, container, condition)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.item = item;\n\t\t\tthis.varname = varname;\n\t\t\tthis.container = container;\n\t\t\tthis.condition = condition;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet container = this.container._handle_eval(context);\n\t\t\tlet iter = ul4._iter(container);\n\n\t\t\tlet localcontext = context.inheritvars();\n\n\t\t\tlet self = this;\n\n\t\t\tlet result = {\n\t\t\t\tnext: function(){\n\t\t\t\t\twhile (true)\n\t\t\t\t\t{\n\t\t\t\t\t\tlet item = iter.next();\n\t\t\t\t\t\tif (item.done)\n\t\t\t\t\t\t\treturn item;\n\t\t\t\t\t\tlet varitems = ul4._unpackvar(self.varname, item.value);\n\t\t\t\t\t\tfor (let i = 0; i < varitems.length; ++i)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlet [lvalue, value] = varitems[i];\n\t\t\t\t\t\t\tlvalue._handle_eval_set(localcontext, value);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (self.condition === null || ul4._bool(self.condition._handle_eval(localcontext)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlet value = self.item._handle_eval(localcontext);\n\t\t\t\t\t\t\treturn {value: value, done: false};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tul4.GenExprAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"item\", \"varname\", \"container\", \"condition\"]);\n\n\tul4.VarAST = class VarAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, name)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.name = name;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\treturn this._get(context, this.name);\n\t\t}\n\n\t\t_eval_set(context, value)\n\t\t{\n\t\t\tthis._set(context, this.name, value);\n\t\t}\n\n\t\t_eval_modify(context, operator, value)\n\t\t{\n\t\t\tthis._modify(context, operator, this.name, value);\n\t\t}\n\n\t\t_get(context, name)\n\t\t{\n\t\t\tlet result = context.get(name);\n\t\t\tif (typeof(result) === \"undefined\")\n\t\t\t\tresult = ul4.functions[name];\n\t\t\treturn result;\n\t\t}\n\n\t\t_set(context, name, value)\n\t\t{\n\t\t\tcontext.set(name, value);\n\t\t}\n\n\t\t_modify(context, operator, name, value)\n\t\t{\n\t\t\tlet newvalue = operator._ido(context.get(name), value);\n\t\t\tcontext.set(name, newvalue);\n\t\t}\n\t};\n\n\tul4.VarAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"name\"]);\n\n\tul4.UnaryAST = class UnaryAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, obj)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.obj = obj;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"<\");\n\t\t\tout.push(this.constructor.name);\n\t\t\tout.push(\" obj=\");\n\t\t\tthis.obj._repr(out);\n\t\t\tout.push(\">\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet obj = this.obj._handle_eval(context);\n\t\t\treturn this._do(obj);\n\t\t}\n\t};\n\n\tul4.UnaryAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"obj\"]);\n\n\t// Negation\n\tul4.NegAST = class NegAST extends ul4.UnaryAST\n\t{\n\t\t_do(obj)\n\t\t{\n\t\t\tif (obj !== null && typeof(obj.__neg__) === \"function\")\n\t\t\t\treturn obj.__neg__();\n\t\t\treturn -obj;\n\t\t}\n\t};\n\n\t// Bitwise not\n\tul4.BitNotAST = class BitNotAST extends ul4.UnaryAST\n\t{\n\t\t_do(obj)\n\t\t{\n\t\t\treturn -obj-1;\n\t\t}\n\t};\n\n\t// Not\n\tul4.NotAST = class NotAST extends ul4.UnaryAST\n\t{\n\t\t_do(obj)\n\t\t{\n\t\t\treturn !ul4._bool(obj);\n\t\t}\n\t};\n\n\t// If expression\n\tul4.IfAST = class IfAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, objif, objcond, objelse)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.objif = objif;\n\t\t\tthis.objcond = objcond;\n\t\t\tthis.objelse = objelse;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"<\");\n\t\t\tout.push(this.constructor.name);\n\t\t\tout.push(+1);\n\t\t\tout.push(\"objif=\");\n\t\t\tthis.objif._repr(out);\n\t\t\tout.push(0);\n\t\t\tout.push(\"objcond=\");\n\t\t\tthis.objcond._repr(out);\n\t\t\tout.push(0);\n\t\t\tout.push(\"objelse=\");\n\t\t\tthis.objelse._repr(out);\n\t\t\tout.push(-1);\n\t\t\tout.push(\">\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet result;\n\t\t\tlet condvalue = this.objcond._handle_eval(context);\n\t\t\tif (ul4._bool(condvalue))\n\t\t\t\tresult = this.objif._handle_eval(context);\n\t\t\telse\n\t\t\t\tresult = this.objelse._handle_eval(context);\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tul4.IfAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"objif\", \"objcond\", \"objelse\"]);\n\n\tul4.ReturnAST = class ReturnAST extends ul4.UnaryAST\n\t{\n\t\t_eval(context)\n\t\t{\n\t\t\tlet result = this.obj._handle_eval(context);\n\t\t\tthrow new ul4.ReturnException(result);\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"return \");\n\t\t\tthis.obj._str(out);\n\t\t}\n\t};\n\n\tul4.PrintAST = class PrintAST extends ul4.UnaryAST\n\t{\n\t\t_eval(context)\n\t\t{\n\t\t\tlet obj = this.obj._handle_eval(context);\n\t\t\tlet output = ul4._str(obj);\n\t\t\tcontext.output(output);\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"print \");\n\t\t\tthis.obj._str(out);\n\t\t}\n\t};\n\n\tul4.PrintXAST = class PrintXAST extends ul4.UnaryAST\n\t{\n\t\t_eval(context)\n\t\t{\n\t\t\tlet obj = this.obj._handle_eval(context);\n\t\t\tlet output = ul4._xmlescape(obj);\n\t\t\tcontext.output(output);\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"printx \");\n\t\t\tthis.obj._str(out);\n\t\t}\n\t};\n\n\tul4.BinaryAST = class BinaryAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, obj1, obj2)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.obj1 = obj1;\n\t\t\tthis.obj2 = obj2;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"<\");\n\t\t\tout.push(this.constructor.name);\n\t\t\tout.push(\" obj1=\");\n\t\t\tthis.obj1._repr(out);\n\t\t\tout.push(\" obj2=\");\n\t\t\tthis.obj2._repr(out);\n\t\t\tout.push(\">\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet obj1 = this.obj1._handle_eval(context);\n\t\t\tlet obj2 = this.obj2._handle_eval(context);\n\t\t\treturn this._do(obj1, obj2);\n\t\t}\n\t};\n\n\tul4.BinaryAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"obj1\", \"obj2\"]);\n\n\t// Item access and assignment: dict[key], list[index], string[index], color[index]\n\tul4.ItemAST = class ItemAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\tlet result = this._get(obj1, obj2);\n\t\t\treturn result;\n\t\t}\n\n\t\t_eval_set(context, value)\n\t\t{\n\t\t\tlet obj1 = this.obj1._handle_eval(context);\n\t\t\tlet obj2 = this.obj2._handle_eval(context);\n\t\t\tthis._set(obj1, obj2, value);\n\t\t}\n\n\t\t_eval_modify(context, operator, value)\n\t\t{\n\t\t\tlet obj1 = this.obj1._handle_eval(context);\n\t\t\tlet obj2 = this.obj2._handle_eval(context);\n\t\t\tthis._modify(operator, obj1, obj2, value);\n\t\t}\n\n\t\t_get(container, key)\n\t\t{\n\t\t\tif (typeof(container) === \"string\" || ul4._islist(container))\n\t\t\t{\n\t\t\t\tif (key instanceof ul4.slice)\n\t\t\t\t{\n\t\t\t\t\tlet start = key.start, stop = key.stop;\n\t\t\t\t\tif (typeof(start) === \"undefined\" || start === null)\n\t\t\t\t\t\tstart = 0;\n\t\t\t\t\tif (typeof(stop) === \"undefined\" || stop === null)\n\t\t\t\t\t\tstop = container.length;\n\t\t\t\t\treturn container.slice(start, stop);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlet orgkey = key;\n\t\t\t\t\tif (key < 0)\n\t\t\t\t\t\tkey += container.length;\n\t\t\t\t\tif (key < 0 || key >= container.length)\n\t\t\t\t\t\tthrow new ul4.IndexError(container, orgkey);\n\t\t\t\t\treturn container[key];\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (container && typeof(container.__getitem__) === \"function\") // objects without ``_getitem__`` don't support item access\n\t\t\t\treturn container.__getitem__(key);\n\t\t\telse if (ul4._ismap(container))\n\t\t\t\treturn container.get(key);\n\t\t\telse\n\t\t\t\tthrow new ul4.TypeError(ul4._type(container) + \" object is not subscriptable\");\n\t\t}\n\n\t\t_set(container, key, value)\n\t\t{\n\t\t\tif (ul4._islist(container))\n\t\t\t{\n\t\t\t\tif (key instanceof ul4.slice)\n\t\t\t\t{\n\t\t\t\t\tlet start = key.start, stop = key.stop;\n\t\t\t\t\tif (start === null)\n\t\t\t\t\t\tstart = 0;\n\t\t\t\t\telse if (start < 0)\n\t\t\t\t\t\tstart += container.length;\n\t\t\t\t\tif (start < 0)\n\t\t\t\t\t\tstart = 0;\n\t\t\t\t\telse if (start > container.length)\n\t\t\t\t\t\tstart = container.length;\n\t\t\t\t\tif (stop === null)\n\t\t\t\t\t\tstop = container.length;\n\t\t\t\t\telse if (stop < 0)\n\t\t\t\t\t\tstop += container.length;\n\t\t\t\t\tif (stop < 0)\n\t\t\t\t\t\tstop = 0;\n\t\t\t\t\telse if (stop > container.length)\n\t\t\t\t\t\tstop = container.length;\n\t\t\t\t\tif (stop < start)\n\t\t\t\t\t\tstop = start;\n\t\t\t\t\tcontainer.splice(start, stop-start); // Remove old element\n\t\t\t\t\tfor (let iter = ul4._iter(value);;)\n\t\t\t\t\t{\n\t\t\t\t\t\tlet item = iter.next();\n\t\t\t\t\t\tif (item.done)\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcontainer.splice(start++, 0, item.value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlet orgkey = key;\n\t\t\t\t\tif (key < 0)\n\t\t\t\t\t\tkey += container.length;\n\t\t\t\t\tif (key < 0 || key >= container.length)\n\t\t\t\t\t\tthrow new ul4.IndexError(container, orgkey);\n\t\t\t\t\tcontainer[key] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (container && typeof(container.__setitem__) === \"function\") // test this before the generic object test\n\t\t\t\tcontainer.__setitem__(key, value);\n\t\t\telse if (ul4._ismap(container))\n\t\t\t\tcontainer.set(key, value);\n\t\t\telse if (ul4._isobject(container))\n\t\t\t\tcontainer[key] = value;\n\t\t\telse\n\t\t\t\tthrow new ul4.NotSubscriptableError(container);\n\t\t}\n\n\t\t_modify(operator, container, key, value)\n\t\t{\n\t\t\tthis._set(container, key, operator._ido(this._get(container, key), value));\n\t\t}\n\t};\n\n\t// Identifty test operator ``is``\n\tul4.IsAST = class IsAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\treturn obj1 === obj2;\n\t\t}\n\t};\n\n\t// Inverted identity test operator ``is not``\n\tul4.IsNotAST = class IsNotAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\treturn obj1 !== obj2;\n\t\t}\n\t};\n\n\t// Comparison operator ==\n\tul4.EQAST = class EQAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\treturn ul4._eq(obj1, obj2);\n\t\t}\n\t};\n\n\t// Comparison operator !=\n\tul4.NEAST = class NEAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\treturn ul4._ne(obj1, obj2);\n\t\t}\n\t};\n\n\t// Comparison operator <\n\tul4.LTAST = class LTAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\treturn ul4._lt(obj1, obj2);\n\t\t}\n\t};\n\n\t// Comparison operator <=\n\tul4.LEAST = class LEAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\treturn ul4._le(obj1, obj2);\n\t\t}\n\t};\n\n\t// Comparison operator >\n\tul4.GTAST = class GTAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\treturn ul4._gt(obj1, obj2);\n\t\t}\n\t};\n\n\t// Comparison operator >=\n\tul4.GEAST = class GEAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\treturn ul4._ge(obj1, obj2);\n\t\t}\n\t};\n\n\t// Containment test: string in string, obj in list, key in dict, value in rgb\n\tul4.ContainsAST = class ContainsAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj, container)\n\t\t{\n\t\t\tif (typeof(obj) === \"string\" && typeof(container) === \"string\")\n\t\t\t{\n\t\t\t\treturn container.indexOf(obj) !== -1;\n\t\t\t}\n\t\t\telse if (ul4._islist(container))\n\t\t\t{\n\t\t\t\treturn container.indexOf(obj) !== -1;\n\t\t\t}\n\t\t\telse if (container && typeof(container.__contains__) === \"function\") // test this before the generic object test\n\t\t\t\treturn container.__contains__(obj);\n\t\t\telse if (ul4._ismap(container) || ul4._isset(container))\n\t\t\t\treturn container.has(obj);\n\t\t\telse if (ul4._isobject(container))\n\t\t\t{\n\t\t\t\tfor (let key in container)\n\t\t\t\t{\n\t\t\t\t\tif (key === obj)\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (ul4._iscolor(container))\n\t\t\t{\n\t\t\t\treturn container._r === obj || container._g === obj || container._b === obj || container._a === obj;\n\t\t\t}\n\t\t\tthrow new ul4.TypeError(ul4._type(container) + \" object is not iterable\");\n\t\t}\n\t};\n\n\t// Inverted containment test\n\tul4.NotContainsAST = class NotContainsAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj, container)\n\t\t{\n\t\t\treturn !ul4.ContainsAST.prototype._do(obj, container);\n\t\t}\n\t};\n\n\t// Addition: num + num, string + string\n\tul4.AddAST = class AddAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\tif (obj1 && typeof(obj1.__add__) === \"function\")\n\t\t\t\treturn obj1.__add__(obj2);\n\t\t\telse if (obj2 && typeof(obj2.__radd__) === \"function\")\n\t\t\t\treturn obj2.__radd__(obj1);\n\t\t\tif (obj1 === null || obj2 === null)\n\t\t\t\tthrow new ul4.TypeError(ul4._type(this.obj1) + \" + \" + ul4._type(this.obj2) + \" is not supported\");\n\t\t\tif (ul4._islist(obj1) && ul4._islist(obj2))\n\t\t\t\treturn [...obj1, ...obj2];\n\t\t\telse\n\t\t\t\treturn obj1 + obj2;\n\t\t}\n\n\t\t_ido(obj1, obj2)\n\t\t{\n\t\t\tif (ul4._islist(obj1) && ul4._islist(obj2))\n\t\t\t{\n\t\t\t\tul4.ListProtocol.append(obj1, obj2);\n\t\t\t\treturn obj1;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn this._do(obj1, obj2);\n\t\t}\n\t};\n\n\t// Substraction: num - num\n\tul4.SubAST = class SubAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\tif (obj1 && typeof(obj1.__sub__) === \"function\")\n\t\t\t\treturn obj1.__sub__(obj2);\n\t\t\telse if (obj2 && typeof(obj2.__rsub__) === \"function\")\n\t\t\t\treturn obj2.__rsub__(obj1);\n\t\t\telse if (ul4._isdate(obj1) && ul4._isdate(obj2))\n\t\t\t\treturn this._date_sub(obj1, obj2);\n\t\t\telse if (ul4._isdatetime(obj1) && ul4._isdatetime(obj2))\n\t\t\t\treturn this._datetime_sub(obj1, obj2);\n\t\t\tif (obj1 === null || obj2 === null)\n\t\t\t\tthrow new ul4.TypeError(ul4._type(this.obj1) + \" - \" + ul4._type(this.obj2) + \" is not supported\");\n\t\t\treturn obj1 - obj2;\n\t\t}\n\n\t\t_date_sub(obj1, obj2)\n\t\t{\n\t\t\treturn this._datetime_sub(obj1._date, obj2._date);\n\t\t}\n\n\t\t_datetime_sub(obj1, obj2)\n\t\t{\n\t\t\tlet swap = (obj2 > obj1);\n\n\t\t\tif (swap)\n\t\t\t{\n\t\t\t\tlet t = obj1;\n\t\t\t\tobj1 = obj2;\n\t\t\t\tobj2 = t;\n\t\t\t}\n\t\t\t// From now on obj1 is > than obj2\n\n\t\t\tlet year1 = obj1.getFullYear();\n\t\t\tlet yearday1 = ul4.DateTimeProtocol.yearday(obj1);\n\t\t\tlet year2 = obj2.getFullYear();\n\t\t\tlet yearday2 = ul4.DateTimeProtocol.yearday(obj2);\n\n\t\t\tlet diffdays = 0;\n\n\t\t\twhile (year1 > year2)\n\t\t\t{\n\t\t\t\tdiffdays += ul4.DateProtocol.yearday(ul4._date(year2, 12, 31));\n\t\t\t\t++year2;\n\t\t\t}\n\t\t\tdiffdays += yearday1 - yearday2;\n\n\t\t\tlet hours1 = obj1.getHours();\n\t\t\tlet minutes1 = obj1.getMinutes();\n\t\t\tlet seconds1 = obj1.getSeconds();\n\t\t\tlet hours2 = obj2.getHours();\n\t\t\tlet minutes2 = obj2.getMinutes();\n\t\t\tlet seconds2 = obj2.getSeconds();\n\n\t\t\tlet diffseconds = (seconds1 - seconds2) + 60 * ((minutes1 - minutes2) + 60 * (hours1 - hours2));\n\n\t\t\tlet diffmilliseconds = obj1.getMilliseconds() - obj2.getMilliseconds();\n\n\t\t\tif (swap)\n\t\t\t{\n\t\t\t\tdiffdays = -diffdays;\n\t\t\t\tdiffseconds = -diffseconds;\n\t\t\t\tdiffmilliseconds = -diffmilliseconds;\n\t\t\t}\n\t\t\treturn new ul4.TimeDelta(diffdays, diffseconds, 1000*diffmilliseconds);\n\t\t}\n\n\t\t_ido(obj1, obj2)\n\t\t{\n\t\t\treturn this._do(obj1, obj2);\n\t\t}\n\t};\n\n\n\t// Multiplication: num * num, int * str, str * int, int * list, list * int\n\tul4.MulAST = class MulAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\tif (obj1 && typeof(obj1.__mul__) === \"function\")\n\t\t\t\treturn obj1.__mul__(obj2);\n\t\t\telse if (obj2 && typeof(obj2.__rmul__) === \"function\")\n\t\t\t\treturn obj2.__rmul__(obj1);\n\t\t\tif (obj1 === null || obj2 === null)\n\t\t\t\tthrow new ul4.TypeError(ul4._type(obj1) + \" * \" + ul4._type(obj2) + \" not supported\");\n\t\t\telse if (ul4._isint(obj1) || ul4._isbool(obj1))\n\t\t\t{\n\t\t\t\tif (typeof(obj2) === \"string\")\n\t\t\t\t{\n\t\t\t\t\tif (obj1 < 0)\n\t\t\t\t\t\tthrow new ul4.ValueError(\"repetition counter must be positive\");\n\t\t\t\t\treturn ul4._str_repeat(obj2, obj1);\n\t\t\t\t}\n\t\t\t\telse if (ul4._islist(obj2))\n\t\t\t\t{\n\t\t\t\t\tif (obj1 < 0)\n\t\t\t\t\t\tthrow new ul4.ValueError(\"repetition counter must be positive\");\n\t\t\t\t\treturn ul4._list_repeat(obj2, obj1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (ul4._isint(obj2) || ul4._isbool(obj2))\n\t\t\t{\n\t\t\t\tif (typeof(obj1) === \"string\")\n\t\t\t\t{\n\t\t\t\t\tif (obj2 < 0)\n\t\t\t\t\t\tthrow new ul4.ValueError(\"repetition counter must be positive\");\n\t\t\t\t\treturn ul4._str_repeat(obj1, obj2);\n\t\t\t\t}\n\t\t\t\telse if (ul4._islist(obj1))\n\t\t\t\t{\n\t\t\t\t\tif (obj2 < 0)\n\t\t\t\t\t\tthrow new ul4.ValueError(\"repetition counter must be positive\");\n\t\t\t\t\treturn ul4._list_repeat(obj1, obj2);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn obj1 * obj2;\n\t\t}\n\n\t\t_ido(obj1, obj2)\n\t\t{\n\t\t\tif (ul4._islist(obj1) && ul4._isint(obj2))\n\t\t\t{\n\t\t\t\tif (obj2 > 0)\n\t\t\t\t{\n\t\t\t\t\tlet i = 0;\n\t\t\t\t\tlet targetsize = obj1.length * obj2;\n\t\t\t\t\twhile (obj1.length < targetsize)\n\t\t\t\t\t\tobj1.push(obj1[i++]);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tobj1.splice(0, obj1.length);\n\t\t\t\treturn obj1;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn this._do(obj1, obj2);\n\t\t}\n\t};\n\n\t// Truncating division\n\tul4.FloorDivAST = class FloorDivAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\tif (obj1 && typeof(obj1.__floordiv__) === \"function\")\n\t\t\t\treturn obj1.__floordiv__(obj2);\n\t\t\telse if (obj2 && typeof(obj2.__rfloordiv__) === \"function\")\n\t\t\t\treturn obj2.__rfloordiv__(obj1);\n\t\t\tif (obj1 === null || obj2 === null)\n\t\t\t\tthrow new ul4.TypeError(ul4._type(obj1) + \" // \" + ul4._type(obj2) + \" not supported\");\n\t\t\telse if (typeof(obj1) === \"number\" && typeof(obj2) === \"number\" && obj2 === 0)\n\t\t\t\tthrow new ul4.ZeroDivisionError();\n\t\t\treturn Math.floor(obj1 / obj2);\n\t\t}\n\n\t\t_ido(obj1, obj2)\n\t\t{\n\t\t\treturn this._do(obj1, obj2);\n\t\t}\n\t};\n\n\t// \"Real\" division\n\tul4.TrueDivAST = class TrueDivAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\tif (obj1 && typeof(obj1.__truediv__) === \"function\")\n\t\t\t\treturn obj1.__truediv__(obj2);\n\t\t\telse if (obj2 && typeof(obj2.__rtruediv__) === \"function\")\n\t\t\t\treturn obj2.__rtruediv__(obj1);\n\t\t\tif (obj1 === null || obj2 === null)\n\t\t\t\tthrow new ul4.TypeError(ul4._type(obj1) + \" / \" + ul4._type(obj2) + \" not supported\");\n\t\t\telse if (typeof(obj1) === \"number\" && typeof(obj2) === \"number\" && obj2 === 0)\n\t\t\t\tthrow new ul4.ZeroDivisionError();\n\t\t\treturn obj1 / obj2;\n\t\t}\n\n\t\t_ido(obj1, obj2)\n\t\t{\n\t\t\treturn this._do(obj1, obj2);\n\t\t}\n\t};\n\n\t// Modulo\n\tul4.ModAST = class ModAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\treturn ul4._mod(obj1, obj2);\n\t\t}\n\n\t\t_ido(obj1, obj2)\n\t\t{\n\t\t\treturn this._do(obj1, obj2);\n\t\t}\n\t};\n\n\t// Bitwise left shift\n\tul4.ShiftLeftAST = class ShiftLeftAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\tif (obj2 === false)\n\t\t\t\tobj2 = 0;\n\t\t\telse if (obj2 === true)\n\t\t\t\tobj2 = 1;\n\t\t\tif (obj2 < 0)\n\t\t\t\treturn ul4.ShiftRightAST.prototype._do(obj1, -obj2);\n\t\t\tif (obj1 === false)\n\t\t\t\tobj1 = 0;\n\t\t\telse if (obj1 === true)\n\t\t\t\tobj1 = 1;\n\t\t\twhile (obj2--)\n\t\t\t\tobj1 *= 2;\n\t\t\treturn obj1;\n\t\t}\n\n\t\t_ido(obj1, obj2)\n\t\t{\n\t\t\treturn this._do(obj1, obj2);\n\t\t}\n\t};\n\n\t// Bitwise right shift\n\tul4.ShiftRightAST = class ShiftRightAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\tif (obj2 === false)\n\t\t\t\tobj2 = 0;\n\t\t\telse if (obj2 === true)\n\t\t\t\tobj2 = 1;\n\t\t\tif (obj2 < 0)\n\t\t\t\treturn ul4.ShiftLeftAST.prototype._do(obj1, -obj2);\n\t\t\tif (obj1 === false)\n\t\t\t\tobj1 = 0;\n\t\t\telse if (obj1 === true)\n\t\t\t\tobj1 = 1;\n\t\t\twhile (obj2--)\n\t\t\t\tobj1 /= 2;\n\t\t\treturn Math.floor(obj1);\n\t\t}\n\n\t\t_ido(obj1, obj2)\n\t\t{\n\t\t\treturn this._do(obj1, obj2);\n\t\t}\n\t};\n\n\t// Bitwise and\n\tul4.BitAndAST = class BitAndAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\tif (obj2 === false)\n\t\t\t\tobj2 = 0;\n\t\t\telse if (obj2 === true)\n\t\t\t\tobj2 = 1;\n\t\t\treturn obj1 & obj2;\n\t\t}\n\n\t\t_ido(obj1, obj2)\n\t\t{\n\t\t\treturn this._do(obj1, obj2);\n\t\t}\n\t};\n\n\t// Bitwise exclusive or\n\tul4.BitXOrAST = class BitXOrAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\tif (obj2 === false)\n\t\t\t\tobj2 = 0;\n\t\t\telse if (obj2 === true)\n\t\t\t\tobj2 = 1;\n\t\t\treturn obj1 ^ obj2;\n\t\t}\n\n\t\t_ido(obj1, obj2)\n\t\t{\n\t\t\treturn this._do(obj1, obj2);\n\t\t}\n\t};\n\n\t// Bitwise or\n\tul4.BitOrAST = class BitOrAST extends ul4.BinaryAST\n\t{\n\t\t_do(obj1, obj2)\n\t\t{\n\t\t\tif (obj2 === false)\n\t\t\t\tobj2 = 0;\n\t\t\telse if (obj2 === true)\n\t\t\t\tobj2 = 1;\n\t\t\treturn obj1 | obj2;\n\t\t}\n\n\t\t_ido(obj1, obj2)\n\t\t{\n\t\t\treturn this._do(obj1, obj2);\n\t\t}\n\t};\n\n\tul4.AndAST = class AndAST extends ul4.BinaryAST\n\t{\n\t\t_eval(context)\n\t\t{\n\t\t\tlet obj1 = this.obj1._handle_eval(context);\n\t\t\tif (!ul4._bool(obj1))\n\t\t\t\treturn obj1;\n\t\t\tlet obj2 = this.obj2._handle_eval(context);\n\t\t\treturn obj2;\n\t\t}\n\t};\n\n\tul4.OrAST = class OrAST extends ul4.BinaryAST\n\t{\n\t\t_eval(context)\n\t\t{\n\t\t\tlet obj1 = this.obj1._handle_eval(context);\n\t\t\tif (ul4._bool(obj1))\n\t\t\t\treturn obj1;\n\t\t\tlet obj2 = this.obj2._handle_eval(context);\n\t\t\treturn obj2;\n\t\t}\n\t};\n\n\tul4.AttrAST = class AttrAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, obj, attrname)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.obj = obj;\n\t\t\tthis.attrname = attrname;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet obj = this.obj._handle_eval(context);\n\t\t\tlet result = this._get(obj, this.attrname);\n\t\t\treturn result;\n\t\t}\n\n\t\t_eval_set(context, value)\n\t\t{\n\t\t\tlet obj = this.obj._handle_eval(context);\n\t\t\tthis._set(obj, this.attrname, value);\n\t\t}\n\n\t\t_eval_modify(context, operator, value)\n\t\t{\n\t\t\tlet obj = this.obj._handle_eval(context);\n\t\t\tthis._modify(operator, obj, this.attrname, value);\n\t\t}\n\n\t\t_get(object, attrname)\n\t\t{\n\t\t\tlet proto = ul4.Protocol.get(object);\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn proto.getattr(object, attrname);\n\t\t\t}\n\t\t\tcatch (exc)\n\t\t\t{\n\t\t\t\tif (exc instanceof ul4.AttributeError && exc.obj === object)\n\t\t\t\t\treturn undefined;\n\t\t\t\telse\n\t\t\t\t\tthrow exc;\n\t\t\t}\n\t\t}\n\n\t\t_set(object, attrname, value)\n\t\t{\n\t\t\tif (typeof(object) === \"object\" && typeof(object.__setattr__) === \"function\")\n\t\t\t\tobject.__setattr__(attrname, value);\n\t\t\telse if (ul4._ismap(object))\n\t\t\t\tobject.set(attrname, value);\n\t\t\telse if (ul4._isobject(object))\n\t\t\t\tobject[attrname] = value;\n\t\t\telse\n\t\t\t\tthrow new ul4.TypeError(ul4._type(object) + \" object has no writable attributes\");\n\t\t}\n\n\t\t_modify(operator, object, attrname, value)\n\t\t{\n\t\t\tlet oldvalue = this._get(object, attrname);\n\t\t\tlet newvalue = operator._ido(oldvalue, value);\n\t\t\tthis._set(object, attrname, newvalue);\n\t\t}\n\t};\n\n\tul4.AttrAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"obj\", \"attrname\"]);\n\n\tul4.CallAST = class CallAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, obj, args)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.obj = obj;\n\t\t\tthis.args = args;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_makeargs(context)\n\t\t{\n\t\t\tlet args = [], kwargs = {};\n\t\t\tfor (let i = 0; i < this.args.length; ++i)\n\t\t\t{\n\t\t\t\tlet arg = this.args[i];\n\t\t\t\targ._handle_eval_call(context, args, kwargs);\n\t\t\t}\n\t\t\treturn {args: args, kwargs: kwargs};\n\t\t}\n\n\t\t_handle_eval(context)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn this._eval(context);\n\t\t\t}\n\t\t\tcatch (exc)\n\t\t\t{\n\t\t\t\tthis._decorate_exception(exc);\n\t\t\t\tthrow exc;\n\t\t\t}\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet obj = this.obj._handle_eval(context);\n\t\t\tlet args = this._makeargs(context);\n\t\t\tlet result = ul4._call(context, obj, args.args, args.kwargs);\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tul4.CallAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"obj\", \"args\"]);\n\n\tul4.RenderAST = class RenderAST extends ul4.CallAST\n\t{\n\t\tconstructor(template, pos, obj, args)\n\t\t{\n\t\t\tsuper(template, pos, obj, args);\n\t\t\tthis.indent = null;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"<\");\n\t\t\tout.push(this._reprname);\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"render \");\n\t\t\tout.push(this.tag.code.replace(/\\r?\\n/g, ' '));\n\t\t\tif (this.indent !== null)\n\t\t\t{\n\t\t\t\tout.push(\" with indent \");\n\t\t\t\tout.push(ul4._repr(this.indent.text));\n\t\t\t}\n\t\t}\n\n\t\t_handle_eval(context)\n\t\t{\n\t\t\tlet localcontext = context.withindent(this.indent !== null ? this.indent.text : null);\n\t\t\tlet obj = this.obj._handle_eval(localcontext);\n\t\t\tlet args = this._makeargs(localcontext);\n\t\t\tthis._handle_additional_arguments(localcontext, args);\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tlet result = ul4._callrender(localcontext, obj, args.args, args.kwargs);\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\tcatch (exc)\n\t\t\t{\n\t\t\t\tthis._decorate_exception(exc);\n\t\t\t\tthrow exc;\n\t\t\t}\n\t\t}\n\n\t\t_handle_additional_arguments(context, args)\n\t\t{\n\t\t}\n\t};\n\n\tul4.RenderAST.prototype._ul4onattrs = ul4.CallAST.prototype._ul4onattrs.concat([\"indent\"]);\n\tul4.RenderAST.prototype._reprname = \"RenderAST\";\n\n\tul4.RenderXAST = class RenderXAST extends ul4.RenderAST\n\t{\n\t\t_handle_eval(context)\n\t\t{\n\t\t\tcontext.escapes.push(ul4._xmlescape);\n\n\t\t\tlet result = null;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tresult = super._handle_eval(context);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tcontext.escapes.splice(context.escapes.length-1, 1);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tul4.RenderBlockAST = class RenderBlockAST extends ul4.RenderAST\n\t{\n\t\t_handle_additional_arguments(context, args)\n\t\t{\n\t\t\tif (args.kwargs.hasOwnProperty(\"content\"))\n\t\t\t\tthrow new ul4.ArgumentError(\"duplicate keyword argument content\");\n\t\t\tlet closure = new ul4.TemplateClosure(this.content, this.content.signature, context.vars);\n\t\t\targs.kwargs.content = closure;\n\t\t}\n\t};\n\n\tul4.RenderBlockAST.prototype._ul4onattrs = ul4.RenderAST.prototype._ul4onattrs.concat([\"content\"]);\n\n\tul4.RenderBlocksAST = class RenderBlocksAST extends ul4.RenderAST\n\t{\n\t\t_handle_additional_arguments(context, args)\n\t\t{\n\t\t\tlet localcontext = context.inheritvars();\n\t\t\tul4.BlockAST.prototype._eval.call(this, localcontext);\n\n\t\t\tfor (let key in localcontext.vars)\n\t\t\t{\n\t\t\t\tif (localcontext.vars.hasOwnProperty(key))\n\t\t\t\t{\n\t\t\t\t\tif (key in args.kwargs)\n\t\t\t\t\t\tthrow new ul4.ArgumentError(\"duplicate keyword argument \" + key);\n\t\t\t\t\targs.kwargs[key] = localcontext.get(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tul4.RenderBlocksAST.prototype._ul4onattrs = ul4.RenderAST.prototype._ul4onattrs.concat([\"content\"]);\n\n\t// Slice object\n\tul4.slice = class slice extends ul4.Proto\n\t{\n\t\tconstructor(start, stop)\n\t\t{\n\t\t\tsuper();\n\t\t\tthis.start = start;\n\t\t\tthis.stop = stop;\n\t\t}\n\n\t\tof(string)\n\t\t{\n\t\t\tlet start = this.start || 0;\n\t\t\tlet stop = this.stop === null ? string.length : this.stop;\n\t\t\treturn string.slice(start, stop);\n\t\t}\n\n\t\t__repr__()\n\t\t{\n\t\t\treturn \"slice(\" + ul4._repr(this.start) + \", \" + ul4._repr(this.stop) + \", None)\";\n\t\t}\n\n\t\t__getattr__(attrname)\n\t\t{\n\t\t\tswitch (attrname)\n\t\t\t{\n\t\t\t\tcase \"start\":\n\t\t\t\t\treturn this.start;\n\t\t\t\tcase \"stop\":\n\t\t\t\t\treturn this.stop;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ul4.AttributeError(this, attrname);\n\t\t\t}\n\t\t}\n\t};\n\n\n\t// List/String slice\n\tul4.SliceAST = class SliceAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, index1, index2)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.index1 = index1;\n\t\t\tthis.index2 = index2;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet index1 = this.index1 !== null ? this.index1._handle_eval(context) : null;\n\t\t\tlet index2 = this.index2 !== null ? this.index2._handle_eval(context) : null;\n\t\t\treturn new ul4.slice(index1, index2);\n\t\t}\n\t};\n\n\tul4.SliceAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"index1\", \"index2\"]);\n\n\tul4.SetVarAST = class SetVarAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos, lvalue, value)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.lvalue = lvalue;\n\t\t\tthis.value = value;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"<\");\n\t\t\tout.push(this.constructor.name);\n\t\t\tout.push(\" lvalue=\");\n\t\t\tout.push(ul4._repr(this.lvalue));\n\t\t\tout.push(\" value=\");\n\t\t\tthis.value._repr(out);\n\t\t\tout.push(\">\");\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet value = this.value._handle_eval(context);\n\t\t\tlet items = ul4._unpackvar(this.lvalue, value);\n\t\t\tfor (let i = 0; i < items.length; ++i)\n\t\t\t{\n\t\t\t\tlet [lvalue, value] = items[i];\n\t\t\t\tlvalue._handle_eval_set(context, value);\n\t\t\t}\n\t\t}\n\t};\n\n\tul4.SetVarAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"lvalue\", \"value\"]);\n\n\tul4.ModifyVarAST = class ModifyVarAST extends ul4.SetVarAST\n\t{\n\t\t_eval(context)\n\t\t{\n\t\t\tlet value = this.value._handle_eval(context);\n\t\t\tlet items = ul4._unpackvar(this.lvalue, value);\n\t\t\tfor (let i = 0; i < items.length; ++i)\n\t\t\t{\n\t\t\t\tlet [lvalue, value] = items[i];\n\t\t\t\tlvalue._handle_eval_modify(context, this._operator, value);\n\t\t\t}\n\t\t}\n\t};\n\n\tul4.AddVarAST = class AddVarAST extends ul4.ModifyVarAST\n\t{\n\t};\n\n\tul4.AddVarAST.prototype._operator = ul4.AddAST.prototype;\n\n\tul4.SubVarAST = class SubVarAST extends ul4.ModifyVarAST\n\t{\n\t};\n\n\tul4.SubVarAST.prototype._operator = ul4.SubAST.prototype;\n\n\tul4.MulVarAST = class MulVarAST extends ul4.ModifyVarAST\n\t{\n\t};\n\n\tul4.MulVarAST.prototype._operator = ul4.MulAST.prototype;\n\n\tul4.TrueDivVarAST = class TrueDivVarAST extends ul4.ModifyVarAST\n\t{\n\t};\n\n\tul4.TrueDivVarAST.prototype._operator = ul4.TrueDivAST.prototype;\n\n\tul4.FloorDivVarAST = class FloorDivVarAST extends ul4.ModifyVarAST\n\t{\n\t};\n\n\tul4.FloorDivVarAST.prototype._operator = ul4.FloorDivAST.prototype;\n\n\tul4.ModVarAST = class ModVarAST extends ul4.ModifyVarAST\n\t{\n\t};\n\n\tul4.ModVarAST.prototype._operator = ul4.ModAST.prototype;\n\n\tul4.ShiftLeftVarAST = class ShiftLeftVarAST extends ul4.ModifyVarAST\n\t{\n\t};\n\n\tul4.ShiftLeftVarAST.prototype._operator = ul4.ShiftLeftAST.prototype;\n\n\tul4.ShiftRightVarAST = class ShiftRightVarAST extends ul4.ModifyVarAST\n\t{\n\t};\n\n\tul4.ShiftRightVarAST.prototype._operator = ul4.ShiftRightAST.prototype;\n\n\tul4.BitAndVarAST = class BitAndVarAST extends ul4.ModifyVarAST\n\t{\n\t};\n\n\tul4.BitAndVarAST.prototype._operator = ul4.BitAndAST.prototype;\n\n\tul4.BitXOrVarAST = class BitXOrVarAST extends ul4.ModifyVarAST\n\t{\n\t};\n\n\tul4.BitXOrVarAST.prototype._operator = ul4.BitXOrAST.prototype;\n\n\tul4.BitOrVarAST = class BitOrVarAST extends ul4.ModifyVarAST\n\t{\n\t};\n\n\tul4.BitOrVarAST.prototype._operator = ul4.BitOrAST.prototype;\n\n\tul4.BlockAST = class BlockAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.content = [];\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tfor (let i = 0; i < this.content.length; ++i)\n\t\t\t{\n\t\t\t\tlet item = this.content[i];\n\t\t\t\titem._handle_eval(context);\n\t\t\t}\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tif (this.content.length)\n\t\t\t{\n\t\t\t\tfor (let i = 0; i < this.content.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tlet item = this.content[i];\n\t\t\t\t\titem._str(out);\n\t\t\t\t\tout.push(0);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tout.push(\"pass\");\n\t\t\t\tout.push(0);\n\t\t\t}\n\t\t}\n\t};\n\n\tul4.BlockAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat([\"content\"]);\n\n\tul4.ForBlockAST = class ForBlockAST extends ul4.BlockAST\n\t{\n\t\tconstructor(template, pos, varname, container)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.varname = varname;\n\t\t\tthis.container = container;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_str_varname(out, varname)\n\t\t{\n\t\t\tif (ul4._islist(varname))\n\t\t\t{\n\t\t\t\tout.push(\"(\");\n\t\t\t\tfor (let i = 0; i < varname.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tif (i)\n\t\t\t\t\t\tout.push(\", \");\n\t\t\t\t\tthis._str_varname(out, varname[i]);\n\t\t\t\t}\n\t\t\t\tif (varname.length == 1)\n\t\t\t\t\tout.push(\",\");\n\t\t\t\tout.push(\")\");\n\t\t\t}\n\t\t\telse\n\t\t\t\tvarname._str(out);\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet container = this.container._handle_eval(context);\n\n\t\t\tfor (let iter = ul4._iter(container);;)\n\t\t\t{\n\t\t\t\tlet value = iter.next();\n\t\t\t\tif (value.done)\n\t\t\t\t\tbreak;\n\t\t\t\tlet varitems = ul4._unpackvar(this.varname, value.value);\n\t\t\t\tfor (let i = 0; i < varitems.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tlet [lvalue, value] = varitems[i];\n\t\t\t\t\tlvalue._handle_eval_set(context, value);\n\t\t\t\t}\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\t// We can't call _handle_eval() here, as this would in turn call this function again, leading to infinite recursion\n\t\t\t\t\t// But we don't have to, as wrapping original exception in ``Error`` has already been done by the lower levels\n\t\t\t\t\tsuper._eval(context);\n\t\t\t\t}\n\t\t\t\tcatch (exc)\n\t\t\t\t{\n\t\t\t\t\tif (exc instanceof ul4.BreakException)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\telse if (exc instanceof ul4.ContinueException)\n\t\t\t\t\t\t;\n\t\t\t\t\telse\n\t\t\t\t\t\tthrow exc;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"for \");\n\t\t\tthis._str_varname(out, this.varname);\n\t\t\tout.push(\" in \");\n\t\t\tthis.container._str(out);\n\t\t\tout.push(\":\");\n\t\t\tout.push(+1);\n\t\t\tul4.BlockAST.prototype._str.call(this, out);\n\t\t\tout.push(-1);\n\t\t}\n\t};\n\n\tul4.ForBlockAST.prototype._ul4onattrs = ul4.BlockAST.prototype._ul4onattrs.concat([\"varname\", \"container\"]);\n\n\tul4.WhileBlockAST = class WhileBlockAST extends ul4.BlockAST\n\t{\n\t\tconstructor(template, pos, condition)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.condition = condition;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"while \");\n\t\t\tthis.condition._repr(out);\n\t\t\tout.push(\":\");\n\t\t\tout.push(+1);\n\t\t\tul4.BlockAST.prototype._str.call(this, out);\n\t\t\tout.push(-1);\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tlet cond = this.condition._handle_eval(context);\n\t\t\t\tif (!ul4._bool(cond))\n\t\t\t\t\tbreak;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\t// We can't call _handle_eval() here, as this would in turn call this function again, leading to infinite recursion\n\t\t\t\t\t// But we don't have to, as wrapping the original exception in ``Error`` has already been done by the lower levels\n\t\t\t\t\tsuper._eval(context);\n\t\t\t\t}\n\t\t\t\tcatch (exc)\n\t\t\t\t{\n\t\t\t\t\tif (exc instanceof ul4.BreakException)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\telse if (exc instanceof ul4.ContinueException)\n\t\t\t\t\t\t;\n\t\t\t\t\telse\n\t\t\t\t\t\tthrow exc;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tul4.WhileBlockAST.prototype._ul4onattrs = ul4.BlockAST.prototype._ul4onattrs.concat([\"condition\"]);\n\n\tul4.BreakAST = class BreakAST extends ul4.CodeAST\n\t{\n\t\t_eval(context)\n\t\t{\n\t\t\tthrow new ul4.BreakException();\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"break\");\n\t\t\tout.push(0);\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\t};\n\n\tul4.ContinueAST = class ContinueAST extends ul4.CodeAST\n\t{\n\t\t_eval(context)\n\t\t{\n\t\t\tthrow new ul4.ContinueException();\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"continue\");\n\t\t\tout.push(0);\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\t};\n\n\tul4.CondBlockAST = class CondBlockAST extends ul4.BlockAST\n\t{\n\t\t_eval(context)\n\t\t{\n\t\t\tfor (let i = 0; i < this.content.length; ++i)\n\t\t\t{\n\t\t\t\tlet block = this.content[i];\n\t\t\t\tlet execute = block._execute(context);\n\t\t\t\tif (execute)\n\t\t\t\t{\n\t\t\t\t\tblock._handle_eval(context);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tul4.ConditionalBlockAST = class ConditionalBlockAST extends ul4.BlockAST\n\t{\n\t\tconstructor(template, pos, condition)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.condition = condition;\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"<\");\n\t\t\tout.push(this.constructor.name);\n\t\t\tout.push(\" condition=\");\n\t\t\tthis.condition._repr(out);\n\t\t\tout.push(\">\");\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(this._strname);\n\t\t\tout.push(\" \");\n\t\t\tthis.condition._str(out);\n\t\t\tout.push(\":\");\n\t\t\tout.push(+1);\n\t\t\tul4.BlockAST.prototype._str.call(this, out);\n\t\t\tout.push(-1);\n\t\t}\n\n\t\t_execute(context)\n\t\t{\n\t\t\tlet cond = this.condition._handle_eval(context);\n\t\t\tlet result = ul4._bool(cond);\n\t\t\treturn result;\n\t\t}\n\t};\n\n\tul4.ConditionalBlockAST.prototype._ul4onattrs = ul4.BlockAST.prototype._ul4onattrs.concat([\"condition\"]);\n\n\tul4.IfBlockAST = class IfBlockAST extends ul4.ConditionalBlockAST\n\t{\n\t};\n\n\tul4.IfBlockAST.prototype._strname = \"if\";\n\n\tul4.ElIfBlockAST = class ElIfBlockAST extends ul4.ConditionalBlockAST\n\t{\n\t};\n\n\tul4.ElIfBlockAST.prototype._strname = \"else if\";\n\n\tul4.ElseBlockAST = class ElseBlockAST extends ul4.BlockAST\n\t{\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\");\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"else:\");\n\t\t\tout.push(+1);\n\t\t\tul4.BlockAST.prototype._str.call(this, out);\n\t\t\tout.push(-1);\n\t\t}\n\n\t\t_execute(context)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t};\n\n\tul4.Template = class Template extends ul4.BlockAST\n\t{\n\t\tconstructor(template, pos, source, name, whitespace, startdelim, enddelim, signature)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis._source = source;\n\t\t\tthis.name = name;\n\t\t\tthis.whitespace = whitespace;\n\t\t\tthis.startdelim = startdelim;\n\t\t\tthis.enddelim = enddelim;\n\t\t\tthis.docpos = null;\n\t\t\tthis.signature = signature;\n\t\t\tthis._asts = null;\n\t\t\tthis._ul4_callsignature = signature;\n\t\t\tthis._ul4_rendersignature = signature;\n\t\t\tthis.parenttemplate = null;\n\t\t}\n\n\t\t__getattr__(attrname)\n\t\t{\n\t\t\tlet self = this;\n\t\t\tswitch (attrname)\n\t\t\t{\n\t\t\t\tcase \"content\":\n\t\t\t\t\treturn this.content;\n\t\t\t\tcase \"source\":\n\t\t\t\t\treturn this.source;\n\t\t\t\tcase \"name\":\n\t\t\t\t\treturn this.name;\n\t\t\t\tcase \"whitespace\":\n\t\t\t\t\treturn this.whitespace;\n\t\t\t\tcase \"startdelim\":\n\t\t\t\t\treturn this.startdelim;\n\t\t\t\tcase \"enddelim\":\n\t\t\t\t\treturn this.enddelim;\n\t\t\t\tcase \"doc\":\n\t\t\t\t\treturn this.doc();\n\t\t\t\tcase \"signature\":\n\t\t\t\t\treturn this.signature;\n\t\t\t\tcase \"parenttemplate\":\n\t\t\t\t\treturn this.parenttemplate;\n\t\t\t\tcase \"render\":\n\t\t\t\t\tlet render = function render(context, vars){ self._renderbound(context, vars); };\n\t\t\t\t\tul4.expose(render, this.signature, {needscontext: true, needsobject: true});\n\t\t\t\t\treturn render;\n\t\t\t\tcase \"renders\":\n\t\t\t\t\tlet renders = function renders(context, vars){ return self._rendersbound(context, vars); };\n\t\t\t\t\tul4.expose(renders, this.signature, {needscontext: true, needsobject: true});\n\t\t\t\t\treturn renders;\n\t\t\t\tdefault:\n\t\t\t\t\treturn super.__getattr__(attrname);\n\t\t\t}\n\t\t}\n\n\t\tul4ondump(encoder)\n\t\t{\n\t\t\tlet signature;\n\t\t\tencoder.dump(ul4.version);\n\t\t\tencoder.dump(this.name);\n\t\t\tencoder.dump(this._source);\n\t\t\tencoder.dump(this.whitespace);\n\t\t\tencoder.dump(this.startdelim);\n\t\t\tencoder.dump(this.enddelim);\n\t\t\tencoder.dump(this.docpos);\n\t\t\tencoder.dump(this.parenttemplate);\n\t\t\tif (this.signature === null || this.signature instanceof ul4.SignatureAST)\n\t\t\t\tsignature = this.signature;\n\t\t\telse\n\t\t\t{\n\t\t\t\tsignature = [];\n\t\t\t\tfor (let i = 0; i < this.signature.args.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tlet arg = this.signature.args[i];\n\t\t\t\t\tif (typeof(arg.defaultValue) === \"undefined\")\n\t\t\t\t\t\tsignature.push(arg.name);\n\t\t\t\t\telse\n\t\t\t\t\t\tsignature.push(arg.name+\"=\", arg.defaultValue);\n\t\t\t\t}\n\t\t\t\tif (this.signature.remargs !== null)\n\t\t\t\t\tsignature.push(\"*\" + this.signature.remargs);\n\t\t\t\tif (this.signature.remkwargs !== null)\n\t\t\t\t\tsignature.push(\"**\" + this.signature.remkwargs);\n\t\t\t}\n\t\t\tencoder.dump(signature);\n\t\t\tsuper.ul4ondump(encoder);\n\t\t}\n\n\t\tul4onload(decoder)\n\t\t{\n\t\t\tlet version = decoder.load();\n\t\t\tlet signature;\n\n\t\t\tif (version === null)\n\t\t\t\tthrow new ul4.ValueError(\"UL4ON doesn't support templates in 'source' format in Javascript implementation\");\n\n\t\t\tif (version !== ul4.version)\n\t\t\t\tthrow new ul4.ValueError(\"invalid version, expected \" + ul4.version + \", got \" + version);\n\n\t\t\tthis.name = decoder.load();\n\t\t\tthis._source = decoder.load();\n\t\t\tthis.whitespace = decoder.load();\n\t\t\tthis.startdelim = decoder.load();\n\t\t\tthis.enddelim = decoder.load();\n\t\t\tthis.docpos = decoder.load();\n\t\t\tthis.parenttemplate = decoder.load();\n\t\t\tsignature = decoder.load();\n\t\t\tif (ul4._islist(signature))\n\t\t\t\tsignature = new ul4.Signature(...signature);\n\t\t\tthis.signature = signature;\n\t\t\tthis._ul4_callsignature = signature;\n\t\t\tthis._ul4_rendersignature = signature;\n\t\t\tsuper.ul4onload(decoder);\n\t\t}\n\n\t\tloads(string)\n\t\t{\n\t\t\treturn ul4.loads(string);\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet signature = null;\n\t\t\tif (this.signature !== null)\n\t\t\t\tsignature = this.signature._handle_eval(context);\n\t\t\tlet closure = new ul4.TemplateClosure(this, signature, context.vars);\n\t\t\tcontext.set(this.name, closure);\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"\")\n\t\t\t{\n\t\t\t\tout.push(\" enddelim=\");\n\t\t\t\tout.push(ul4._repr(this.enddelim));\n\t\t\t}\n\t\t\tout.push(\">\");\n\t\t}\n\n\t\t_str(out)\n\t\t{\n\t\t\tout.push(\"def \");\n\t\t\tout.push(this.name ? this.name : \"unnamed\");\n\t\t\tout.push(\":\");\n\t\t\tout.push(+1);\n\t\t\tul4.BlockAST.prototype._str.call(this, out);\n\t\t\tout.push(-1);\n\t\t}\n\n\t\t_renderbound(context, vars)\n\t\t{\n\t\t\tlet localcontext = context.clone();\n\t\t\tlocalcontext.vars = vars;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tul4.BlockAST.prototype._eval.call(this, localcontext);\n\t\t\t}\n\t\t\tcatch (exc)\n\t\t\t{\n\t\t\t\tif (!(exc instanceof ul4.ReturnException))\n\t\t\t\t\tthrow exc;\n\t\t\t}\n\t\t}\n\n\t\t__render__(context, vars)\n\t\t{\n\t\t\tthis._renderbound(context, vars);\n\t\t}\n\n\t\trender(context, vars)\n\t\t{\n\t\t\tthis._renderbound(context, vars);\n\t\t}\n\n\t\t_rendersbound(context, vars)\n\t\t{\n\t\t\tlet localcontext = context.replaceoutput();\n\t\t\tthis._renderbound(localcontext, vars);\n\t\t\treturn localcontext.getoutput();\n\t\t}\n\n\t\trenders(vars)\n\t\t{\n\t\t\tvars = vars || {};\n\t\t\tlet context = new ul4.Context();\n\t\t\tif (this.signature !== null)\n\t\t\t\tvars = this.signature.bindObject(this.name, [], vars);\n\t\t\treturn this._rendersbound(context, vars);\n\t\t}\n\n\t\tdoc()\n\t\t{\n\t\t\treturn this.docpos != null ? this.docpos.of(this._source) : null;\n\t\t}\n\n\t\t_callbound(context, vars)\n\t\t{\n\t\t\tlet localcontext = context.clone();\n\t\t\tlocalcontext.vars = vars;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tul4.BlockAST.prototype._eval.call(this, localcontext);\n\t\t\t}\n\t\t\tcatch (exc)\n\t\t\t{\n\t\t\t\tif (exc instanceof ul4.ReturnException)\n\t\t\t\t\treturn exc.result;\n\t\t\t\telse\n\t\t\t\t\tthrow exc;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tcall(vars)\n\t\t{\n\t\t\tvars = vars || {};\n\t\t\tlet context = new ul4.Context();\n\t\t\tif (this.signature !== null)\n\t\t\t\tvars = this.signature.bindObject(this.name, [], vars);\n\t\t\treturn this._callbound(context, vars);\n\t\t}\n\n\t\t__call__(context, vars)\n\t\t{\n\t\t\treturn this._callbound(context, vars);\n\t\t}\n\n\t\tul4type()\n\t\t{\n\t\t\treturn \"template\";\n\t\t}\n\t};\n\n\tul4.Template.prototype._ul4_callneedsobject = true;\n\tul4.Template.prototype._ul4_callneedscontext = true;\n\tul4.Template.prototype._ul4_renderneedsobject = true;\n\tul4.Template.prototype._ul4_renderneedscontext = true;\n\n\tul4.SignatureAST = class SignatureAST extends ul4.CodeAST\n\t{\n\t\tconstructor(template, pos)\n\t\t{\n\t\t\tsuper(template, pos);\n\t\t\tthis.params = [];\n\t\t}\n\n\t\tul4ondump(encoder)\n\t\t{\n\t\t\tsuper.ul4ondump(encoder);\n\n\t\t\tlet dump = [];\n\n\t\t\tfor (let i = 0; i < this.params.length; ++i)\n\t\t\t{\n\t\t\t\tlet param = this.params[i];\n\t\t\t\tif (param[1] === null)\n\t\t\t\t\tdump.push(param[0]);\n\t\t\t\telse\n\t\t\t\t\tdump.push(param);\n\t\t\t}\n\t\t\tencoder.dump(dump);\n\t\t}\n\n\t\tul4onload(decoder)\n\t\t{\n\t\t\tsuper.ul4onload(decoder);\n\t\t\tlet dump = decoder.load();\n\t\t\tthis.params = [];\n\t\t\tfor (let i = 0; i < dump.length; ++i)\n\t\t\t{\n\t\t\t\tlet param = dump[i];\n\t\t\t\tif (typeof(param) === \"string\")\n\t\t\t\t\tthis.params.push([param, null]);\n\t\t\t\telse\n\t\t\t\t\tthis.params.push(param);\n\t\t\t}\n\t\t}\n\n\t\t_eval(context)\n\t\t{\n\t\t\tlet args = [];\n\t\t\tfor (let i = 0; i < this.params.length; ++i)\n\t\t\t{\n\t\t\t\tlet param = this.params[i];\n\t\t\t\tif (param[1] === null)\n\t\t\t\t\targs.push(param[0]);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\targs.push(param[0] + \"=\");\n\t\t\t\t\targs.push(param[1]._handle_eval(context));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new ul4.Signature(...args);\n\t\t}\n\n\t\t_repr(out)\n\t\t{\n\t\t\tout.push(\"<\");\n\t\t\tout.push(this.constructor.name);\n\t\t\tout.push(\" params=\");\n\t\t\tthis.params._repr(out);\n\t\t\tout.push(\">\");\n\t\t}\n\t};\n\n\tul4.TemplateClosure = class TemplateClosure extends ul4.Proto\n\t{\n\t\tconstructor(template, signature, vars)\n\t\t{\n\t\t\tsuper();\n\t\t\tthis.template = template;\n\t\t\tthis.signature = signature;\n\t\t\tthis.vars = vars;\n\t\t\tthis._ul4_callsignature = signature;\n\t\t\tthis._ul4_rendersignature = signature;\n\t\t\t// Copy over the required attribute from the template\n\t\t\tthis.name = template.name;\n\t\t\tthis.tag = template.tag;\n\t\t\tthis.endtag = template.endtag;\n\t\t\tthis._source = template._source;\n\t\t\tthis.startdelim = template.startdelim;\n\t\t\tthis.enddelim = template.enddelim;\n\t\t\tthis.docpos = template.docpos;\n\t\t\tthis.content = template.content;\n\t\t}\n\n\t\t__render__(context, vars)\n\t\t{\n\t\t\tthis.template._renderbound(context, ul4._inherit(this.vars, vars));\n\t\t}\n\n\t\trender(context, vars)\n\t\t{\n\t\t\tthis.template._renderbound(context, ul4._inherit(this.vars, vars));\n\t\t}\n\n\t\t__call__(context, vars)\n\t\t{\n\t\t\treturn this.template._callbound(context, ul4._inherit(this.vars, vars));\n\t\t}\n\n\t\t_renderbound(context, vars)\n\t\t{\n\t\t\tthis.template._renderbound(context, ul4._inherit(this.vars, vars));\n\t\t}\n\n\t\t_rendersbound(context, vars)\n\t\t{\n\t\t\treturn this.template._rendersbound(context, ul4._inherit(this.vars, vars));\n\t\t}\n\n\t\t__getattr__(attrname)\n\t\t{\n\t\t\tlet self = this;\n\t\t\tswitch (attrname)\n\t\t\t{\n\t\t\t\tcase \"render\":\n\t\t\t\t\tlet render = function render(context, vars){ self._renderbound(context, vars); };\n\t\t\t\t\tul4.expose(render, this.signature, {needscontext: true, needsobject: true});\n\t\t\t\t\treturn render;\n\t\t\t\tcase \"renders\":\n\t\t\t\t\tlet renders = function renders(context, vars){ return self._rendersbound(context, vars); };\n\t\t\t\t\tul4.expose(renders, this.signature, {needscontext: true, needsobject: true});\n\t\t\t\t\treturn renders;\n\t\t\t\tcase \"signature\":\n\t\t\t\t\treturn this.signature;\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.template.__getattr__(attrname);\n\t\t\t}\n\t\t}\n\n\t\tul4type()\n\t\t{\n\t\t\treturn \"template\";\n\t\t}\n\t};\n\n\tul4.TemplateClosure.prototype._ul4_callneedsobject = true;\n\tul4.TemplateClosure.prototype._ul4_callneedscontext = true;\n\tul4.TemplateClosure.prototype._ul4_renderneedsobject = true;\n\tul4.TemplateClosure.prototype._ul4_renderneedscontext = true;\n\n\t// Create a color object from the red, green, blue and alpha values ``r``, ``g``, ``b`` and ``b``\n\tul4._rgb = function _rgb(r, g, b, a)\n\t{\n\t\treturn new this.Color(255*r, 255*g, 255*b, 255*a);\n\t};\n\n\t// Convert ``obj`` to a string and escape the characters ``&``, ``<``, ``>``, ``'`` and ``\"`` with their XML character/entity reference\n\tul4._xmlescape = function _xmlescape(obj)\n\t{\n\t\tobj = ul4._str(obj);\n\t\tobj = obj.replace(/&/g, \"&\");\n\t\tobj = obj.replace(//g, \">\");\n\t\tobj = obj.replace(/'/g, \"'\");\n\t\tobj = obj.replace(/\"/g, \""\");\n\t\treturn obj;\n\t};\n\n\t// Convert ``obj`` to a string suitable for output into a CSV file\n\tul4._csv = function _csv(obj)\n\t{\n\t\tif (obj === null)\n\t\t\treturn \"\";\n\t\telse if (typeof(obj) !== \"string\")\n\t\t\tobj = ul4._repr(obj);\n\t\tif (obj.indexOf(\",\") !== -1 || obj.indexOf('\"') !== -1 || obj.indexOf(\"\\n\") !== -1)\n\t\t\tobj = '\"' + obj.replace(/\"/g, '\"\"') + '\"';\n\t\treturn obj;\n\t};\n\n\t// Return a string containing one character with the codepoint ``i``\n\tul4._chr = function _chr(i)\n\t{\n\t\tif (typeof(i) != \"number\")\n\t\t\tthrow new ul4.TypeError(\"chr() requires an int\");\n\t\treturn String.fromCharCode(i);\n\t};\n\n\t// Return the codepoint for the one and only character in the string ``c``\n\tul4._ord = function _ord(c)\n\t{\n\t\tif (typeof(c) != \"string\" || c.length != 1)\n\t\t\tthrow new ul4.TypeError(\"ord() requires a string of length 1\");\n\t\treturn c.charCodeAt(0);\n\t};\n\n\t// Convert an integer to a hexadecimal string\n\tul4._hex = function _hex(number)\n\t{\n\t\tif (typeof(number) != \"number\")\n\t\t\tthrow new ul4.TypeError(\"hex() requires an int\");\n\t\tif (number < 0)\n\t\t\treturn \"-0x\" + number.toString(16).substr(1);\n\t\telse\n\t\t\treturn \"0x\" + number.toString(16);\n\t};\n\n\t// Convert an integer to a octal string\n\tul4._oct = function _oct(number)\n\t{\n\t\tif (typeof(number) != \"number\")\n\t\t\tthrow new ul4.TypeError(\"oct() requires an int\");\n\t\tif (number < 0)\n\t\t\treturn \"-0o\" + number.toString(8).substr(1);\n\t\telse\n\t\t\treturn \"0o\" + number.toString(8);\n\t};\n\n\t// Convert an integer to a binary string\n\tul4._bin = function _bin(number)\n\t{\n\t\tif (typeof(number) != \"number\")\n\t\t\tthrow new ul4.TypeError(\"bin() requires an int\");\n\t\tif (number < 0)\n\t\t\treturn \"-0b\" + number.toString(2).substr(1);\n\t\telse\n\t\t\treturn \"0b\" + number.toString(2);\n\t};\n\n\t// Return the minimum value\n\tul4._min = function _min(obj)\n\t{\n\t\tif (obj.length == 0)\n\t\t\tthrow new ul4.ArgumentError(\"min() requires at least 1 argument, 0 given\");\n\t\telse if (obj.length == 1)\n\t\t\tobj = obj[0];\n\t\tlet iter = ul4._iter(obj);\n\t\tlet result;\n\t\tlet first = true;\n\t\twhile (true)\n\t\t{\n\t\t\tlet item = iter.next();\n\t\t\tif (item.done)\n\t\t\t{\n\t\t\t\tif (first)\n\t\t\t\t\tthrow new ul4.ValueError(\"min() argument is an empty sequence!\");\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\tif (first || (item.value < result))\n\t\t\t\tresult = item.value;\n\t\t\tfirst = false;\n\t\t}\n\t};\n\n\t// Return the maximum value\n\tul4._max = function _max(obj)\n\t{\n\t\tif (obj.length == 0)\n\t\t\tthrow new ul4.ArgumentError(\"max() requires at least 1 argument, 0 given\");\n\t\telse if (obj.length == 1)\n\t\t\tobj = obj[0];\n\t\tlet iter = ul4._iter(obj);\n\t\tlet result;\n\t\tlet first = true;\n\t\twhile (true)\n\t\t{\n\t\t\tlet item = iter.next();\n\t\t\tif (item.done)\n\t\t\t{\n\t\t\t\tif (first)\n\t\t\t\t\tthrow new ul4.ValueError(\"max() argument is an empty sequence!\");\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\tif (first || (item.value > result))\n\t\t\t\tresult = item.value;\n\t\t\tfirst = false;\n\t\t}\n\t};\n\n\t// Return the of the values from the iterable starting with ``start`` (default ``0``)\n\tul4._sum = function _sum(iterable, start=0)\n\t{\n\t\tfor (let iter = ul4._iter(iterable);;)\n\t\t{\n\t\t\tlet item = iter.next();\n\t\t\tif (item.done)\n\t\t\t\tbreak;\n\t\t\tstart += item.value;\n\t\t}\n\t\treturn start;\n\t};\n\n\t// Return the first value produced by iterating through ``iterable`` (defaulting to ``defaultValue`` if the iterator is empty)\n\tul4._first = function _first(iterable, defaultValue=null)\n\t{\n\t\tlet item = ul4._iter(iterable).next();\n\t\treturn item.done ? defaultValue : item.value;\n\t};\n\n\t// Return the last value produced by iterating through ``iterable`` (defaulting to ``defaultValue`` if the iterator is empty)\n\tul4._last = function _last(iterable, defaultValue=null)\n\t{\n\t\tlet value = defaultValue;\n\n\t\tfor (let iter = ul4._iter(iterable);;)\n\t\t{\n\t\t\tlet item = iter.next();\n\t\t\tif (item.done)\n\t\t\t\tbreak;\n\t\t\tvalue = item.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t// Return a sorted version of ``iterable``\n\tul4._sorted = function _sorted(context, iterable, key=null, reverse=false)\n\t{\n\t\tif (key === null)\n\t\t{\n\t\t\t// FIXME: stability\n\t\t\tlet cmp = reverse ? function cmp(a, b)\n\t\t\t{\n\t\t\t\treturn -ul4._cmp(\"<=>\", a, b);\n\t\t\t} : function cmp(a, b)\n\t\t\t{\n\t\t\t\treturn ul4._cmp(\"<=>\", a, b);\n\t\t\t};\n\t\t\tlet result = ul4._list(iterable);\n\t\t\tresult.sort(cmp);\n\t\t\treturn result;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tlet sort = [];\n\n\t\t\tfor (let i = 0, iter = ul4._iter(iterable);;++i)\n\t\t\t{\n\t\t\t\tlet item = iter.next();\n\t\t\t\tif (item.done)\n\t\t\t\t\tbreak;\n\t\t\t\tlet keyvalue = ul4._call(context, key, [item.value], {});\n\t\t\t\t// For a stable sorting we have to use the nagative index if\n\t\t\t\t// reverse sorting is specified\n\t\t\t\tsort.push([keyvalue, reverse ? -i : i, item.value]);\n\t\t\t}\n\t\t\tcmp = function cmp(s1, s2)\n\t\t\t{\n\t\t\t\tlet res = ul4._cmp(\"<=>\", s1[0], s2[0]);\n\t\t\t\tif (res)\n\t\t\t\t\treturn reverse ? -res : res;\n\t\t\t\tres = ul4._cmp(\"<=>\", s1[1], s2[1]);\n\t\t\t\treturn reverse ? -res : res;\n\t\t\t};\n\n\t\t\tsort.sort(cmp);\n\n\t\t\tlet result = [];\n\t\t\tfor (let i = 0; i < sort.length; ++i)\n\t\t\t{\n\t\t\t\tlet item = sort[i];\n\t\t\t\tresult.push(item[2]);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t};\n\n\t// Return a iterable object iterating from ``start`` up to (but not including) ``stop`` with a step size of ``step``\n\tul4._range = function _range(args)\n\t{\n\t\tlet start, stop, step;\n\t\tif (args.length < 1)\n\t\t\tthrow new ul4.ArgumentError(\"required range() argument missing\");\n\t\telse if (args.length > 3)\n\t\t\tthrow new ul4.ArgumentError(\"range() expects at most 3 positional arguments, \" + args.length + \" given\");\n\t\telse if (args.length == 1)\n\t\t{\n\t\t\tstart = 0;\n\t\t\tstop = args[0];\n\t\t\tstep = 1;\n\t\t}\n\t\telse if (args.length == 2)\n\t\t{\n\t\t\tstart = args[0];\n\t\t\tstop = args[1];\n\t\t\tstep = 1;\n\t\t}\n\t\telse if (args.length == 3)\n\t\t{\n\t\t\tstart = args[0];\n\t\t\tstop = args[1];\n\t\t\tstep = args[2];\n\t\t}\n\t\tlet lower, higher;\n\t\tif (step === 0)\n\t\t\tthrow new ul4.ValueError(\"range() requires a step argument != 0\");\n\t\telse if (step > 0)\n\t\t{\n\t\t\tlower = start;\n\t\t\thigher = stop;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tlower = stop;\n\t\t\thigher = start;\n\t\t}\n\t\tlet length = (lower < higher) ? Math.floor((higher - lower - 1)/Math.abs(step)) + 1 : 0;\n\n\t\treturn {\n\t\t\tindex: 0,\n\t\t\tnext: function()\n\t\t\t{\n\t\t\t\tif (this.index >= length)\n\t\t\t\t\treturn {done: true};\n\t\t\t\treturn {value: start + (this.index++) * step, done: false};\n\t\t\t}\n\t\t};\n\t};\n\n\t// Return a iterable object returning a slice from the argument\n\tul4._slice = function _slice(args)\n\t{\n\t\tlet iterable, start, stop, step;\n\t\tif (args.length < 2)\n\t\t\tthrow new ul4.ArgumentError(\"required slice() argument missing\");\n\t\telse if (args.length > 4)\n\t\t\tthrow new ul4.ArgumentError(\"slice() expects at most 4 positional arguments, \" + args.length + \" given\");\n\t\telse if (args.length == 2)\n\t\t{\n\t\t\titerable = args[0];\n\t\t\tstart = 0;\n\t\t\tstop = args[1];\n\t\t\tstep = 1;\n\t\t}\n\t\telse if (args.length == 3)\n\t\t{\n\t\t\titerable = args[0];\n\t\t\tstart = args[1] !== null ? args[1] : 0;\n\t\t\tstop = args[2];\n\t\t\tstep = 1;\n\t\t}\n\t\telse if (args.length == 4)\n\t\t{\n\t\t\titerable = args[0];\n\t\t\tstart = args[1] !== null ? args[1] : 0;\n\t\t\tstop = args[2];\n\t\t\tstep = args[3] !== null ? args[3] : 1;\n\t\t}\n\t\tif (start < 0)\n\t\t\tthrow new ul4.ValueError(\"slice() requires a start argument >= 0\");\n\t\tif (stop < 0)\n\t\t\tthrow new ul4.ValueError(\"slice() requires a stop argument >= 0\");\n\t\tif (step <= 0)\n\t\t\tthrow new ul4.ValueError(\"slice() requires a step argument > 0\");\n\n\t\tlet next = start, count = 0;\n\t\tlet iter = ul4._iter(iterable);\n\t\treturn {\n\t\t\tnext: function() {\n\t\t\t\tlet result;\n\t\t\t\twhile (count < next)\n\t\t\t\t{\n\t\t\t\t\tresult = iter.next();\n\t\t\t\t\tif (result.done)\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t++count;\n\t\t\t\t}\n\t\t\t\tif (stop !== null && count >= stop)\n\t\t\t\t\treturn {done: true};\n\t\t\t\tresult = iter.next();\n\t\t\t\tif (result.done)\n\t\t\t\t\treturn result;\n\t\t\t\t++count;\n\t\t\t\tnext += step;\n\t\t\t\tif (stop !== null && next > stop)\n\t\t\t\t\tnext = stop;\n\t\t\t\treturn result;\n\t\t\t}\n\t\t};\n\t};\n\n\t// ``%`` escape unsafe characters in the string ``string``\n\tul4._urlquote = function _urlquote(string)\n\t{\n\t\treturn encodeURIComponent(string);\n\t};\n\n\t// The inverse function of ``urlquote``\n\tul4._urlunquote = function _urlunquote(string)\n\t{\n\t\treturn decodeURIComponent(string);\n\t};\n\n\t// Return a reverse iterator over ``sequence``\n\tul4._reversed = function _reversed(sequence)\n\t{\n\t\tif (typeof(sequence) != \"string\" && !ul4._islist(sequence)) // We don't have to materialize strings or lists\n\t\t\tsequence = ul4._list(sequence);\n\t\treturn {\n\t\t\tindex: sequence.length-1,\n\t\t\tnext: function() {\n\t\t\t\treturn this.index >= 0 ? {value: sequence[this.index--], done: false} : {done: true};\n\t\t\t}\n\t\t};\n\t};\n\n\t// Returns a random number in the interval ``[0;1[``\n\tul4._random = function _random()\n\t{\n\t\treturn Math.random();\n\t};\n\n\t// Return a randomly select item from ``range(start, stop, step)``\n\tul4._randrange = function _randrange(args)\n\t{\n\t\tlet start, stop, step;\n\t\tif (args.length < 1)\n\t\t\tthrow new ul4.ArgumentError(\"required randrange() argument missing\");\n\t\telse if (args.length > 3)\n\t\t\tthrow new ul4.ArgumentError(\"randrange() expects at most 3 positional arguments, \" + args.length + \" given\");\n\t\telse if (args.length == 1)\n\t\t{\n\t\t\tstart = 0;\n\t\t\tstop = args[0];\n\t\t\tstep = 1;\n\t\t}\n\t\telse if (args.length == 2)\n\t\t{\n\t\t\tstart = args[0];\n\t\t\tstop = args[1];\n\t\t\tstep = 1;\n\t\t}\n\t\telse if (args.length == 3)\n\t\t{\n\t\t\tstart = args[0];\n\t\t\tstop = args[1];\n\t\t\tstep = args[2];\n\t\t}\n\t\tlet width = stop-start;\n\n\t\tlet value = Math.random();\n\n\t\tlet n;\n\t\tif (step > 0)\n\t\t\tn = Math.floor((width + step - 1) / step);\n\t\telse if (step < 0)\n\t\t\tn = Math.floor((width + step + 1) / step);\n\t\telse\n\t\t\tthrow new ul4.ValueError(\"randrange() requires a step argument != 0\");\n\t\treturn start + step*Math.floor(value * n);\n\t};\n\n\t// Return a random item/char from the list/string ``sequence``\n\tul4._randchoice = function _randchoice(sequence)\n\t{\n\t\tlet iscolor = ul4._iscolor(sequence);\n\t\tif (typeof(sequence) !== \"string\" && !ul4._islist(sequence) && !iscolor)\n\t\t\tthrow new ul4.TypeError(\"randchoice() requires a string or list\");\n\t\tif (iscolor)\n\t\t\tsequence = ul4._list(sequence);\n\t\treturn sequence[Math.floor(Math.random() * sequence.length)];\n\t};\n\n\t// Round a number ``x`` to ``digits`` decimal places (may be negative)\n\tul4._round = function _round(x, digits=0)\n\t{\n\t\tif (digits)\n\t\t{\n\t\t\tlet threshold = Math.pow(10, digits);\n\t\t\treturn Math.round(x*threshold)/threshold;\n\t\t}\n\t\telse\n\t\t\treturn Math.round(x);\n\t};\n\n\t// Return a hex-encode MD5 hash of the argument\n\t// This uses the md5 function from https://github.com/blueimp/JavaScript-MD5\n\tif (iscommon)\n\t{\n\t\tul4._md5 = function _md5(string)\n\t\t{\n\t\t\tlet md5 = require('blueimp-md5');\n\t\t\treturn md5(string);\n\t\t};\n\t}\n\telse\n\t{\n\t\tul4._md5 = function _md5(string)\n\t\t{\n\t\t\treturn md5(string);\n\t\t};\n\t}\n\n\t// Return an iterator over ``[index, item]`` lists from the iterable object ``iterable``. ``index`` starts at ``start`` (defaulting to 0)\n\tul4._enumerate = function _enumerate(iterable, start=0)\n\t{\n\t\treturn {\n\t\t\titer: ul4._iter(iterable),\n\t\t\tindex: start,\n\t\t\tnext: function() {\n\t\t\t\tlet item = this.iter.next();\n\t\t\t\treturn item.done ? item : {value: [this.index++, item.value], done: false};\n\t\t\t}\n\t\t};\n\t};\n\n\t// Return an iterator over ``[isfirst, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, false otherwise)\n\tul4._isfirst = function _isfirst(iterable)\n\t{\n\t\tlet iter = ul4._iter(iterable);\n\t\tlet isfirst = true;\n\t\treturn {\n\t\t\tnext: function() {\n\t\t\t\tlet item = iter.next();\n\t\t\t\tlet result = item.done ? item : {value: [isfirst, item.value], done: false};\n\t\t\t\tisfirst = false;\n\t\t\t\treturn result;\n\t\t\t}\n\t\t};\n\t};\n\n\t// Return an iterator over ``[islast, item]`` lists from the iterable object ``iterable`` (``islast`` is true for the last item, false otherwise)\n\tul4._islast = function _islast(iterable)\n\t{\n\t\tlet iter = ul4._iter(iterable);\n\t\tlet lastitem = iter.next();\n\t\treturn {\n\t\t\tnext: function() {\n\t\t\t\tif (lastitem.done)\n\t\t\t\t\treturn lastitem;\n\t\t\t\tlet item = iter.next();\n\t\t\t\tlet result = {value: [item.done, lastitem.value], done: false};\n\t\t\t\tlastitem = item;\n\t\t\t\treturn result;\n\t\t\t}\n\t\t};\n\t};\n\n\t// Return an iterator over ``[isfirst, islast, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, ``islast`` is true for the last item. Both are false otherwise)\n\tul4._isfirstlast = function _isfirstlast(iterable)\n\t{\n\t\tlet iter = ul4._iter(iterable);\n\t\tlet isfirst = true;\n\t\tlet lastitem = iter.next();\n\t\treturn {\n\t\t\tnext: function() {\n\t\t\t\tif (lastitem.done)\n\t\t\t\t\treturn lastitem;\n\t\t\t\tlet item = iter.next();\n\t\t\t\tlet result = {value: [isfirst, item.done, lastitem.value], done: false};\n\t\t\t\tlastitem = item;\n\t\t\t\tisfirst = false;\n\t\t\t\treturn result;\n\t\t\t}\n\t\t};\n\t};\n\n\t// Return an iterator over ``[index, isfirst, islast, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, ``islast`` is true for the last item. Both are false otherwise)\n\tul4._enumfl = function _enumfl(iterable, start=0)\n\t{\n\t\tlet iter = ul4._iter(iterable);\n\t\tlet i = start;\n\t\tlet isfirst = true;\n\t\tlet lastitem = iter.next();\n\t\treturn {\n\t\t\tnext: function() {\n\t\t\t\tif (lastitem.done)\n\t\t\t\t\treturn lastitem;\n\t\t\t\tlet item = iter.next();\n\t\t\t\tlet result = {value: [i++, isfirst, item.done, lastitem.value], done: false};\n\t\t\t\tlastitem = item;\n\t\t\t\tisfirst = false;\n\t\t\t\treturn result;\n\t\t\t}\n\t\t};\n\t};\n\n\t// Return an iterator over lists, where the i'th list consists of all i'th items from the arguments (terminating when the shortest argument ends)\n\tul4._zip = function _zip(iterables)\n\t{\n\t\tlet result;\n\t\tif (iterables.length)\n\t\t{\n\t\t\tlet iters = [];\n\t\t\tfor (let i = 0; i < iterables.length; ++i)\n\t\t\t\titers.push(ul4._iter(iterables[i]));\n\n\t\t\treturn {\n\t\t\t\tnext: function() {\n\t\t\t\t\tlet items = [];\n\t\t\t\t\tfor (let i = 0; i < iters.length; ++i)\n\t\t\t\t\t{\n\t\t\t\t\t\tlet item = iters[i].next();\n\t\t\t\t\t\tif (item.done)\n\t\t\t\t\t\t\treturn item;\n\t\t\t\t\t\titems.push(item.value);\n\t\t\t\t\t}\n\t\t\t\t\treturn {value: items, done: false};\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn {\n\t\t\t\tnext: function() {\n\t\t\t\t\treturn {done: true};\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t};\n\n\t// Return the absolute value for the number ``number``\n\tul4._abs = function _abs(number)\n\t{\n\t\tif (number !== null && typeof(number.__abs__) === \"function\")\n\t\t\treturn number.__abs__();\n\t\treturn Math.abs(number);\n\t};\n\n\t// Return a ``Date`` object from the arguments passed in\n\tul4._date = function _date(year, month, day)\n\t{\n\t\treturn new ul4.Date(year, month, day);\n\t};\n\n\tul4._datetime = function _datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0)\n\t{\n\t\treturn new Date(year, month-1, day, hour, minute, second, microsecond/1000);\n\t};\n\n\t// Return a ``TimeDelta`` object from the arguments passed in\n\tul4._timedelta = function _timedelta(days=0, seconds=0, microseconds=0)\n\t{\n\t\treturn new this.TimeDelta(days, seconds, microseconds);\n\t};\n\n\t// Return a ``MonthDelta`` object from the arguments passed in\n\tul4._monthdelta = function _monthdelta(months=0)\n\t{\n\t\treturn new this.MonthDelta(months);\n\t};\n\n\t// Return a ``Color`` object from the hue, luminescence, saturation and alpha values ``h``, ``l``, ``s`` and ``a`` (i.e. using the HLS color model)\n\tul4._hls = function _hls(h, l, s, a)\n\t{\n\t\tlet _v = function(m1, m2, hue)\n\t\t{\n\t\t\thue = hue % 1.0;\n\t\t\tif (hue < 1/6)\n\t\t\t\treturn m1 + (m2-m1)*hue*6.0;\n\t\t\telse if (hue < 0.5)\n\t\t\t\treturn m2;\n\t\t\telse if (hue < 2/3)\n\t\t\t\treturn m1 + (m2-m1)*(2/3-hue)*6.0;\n\t\t\treturn m1;\n\t\t};\n\n\t\tlet m1, m2;\n\t\tif (typeof(a) === \"undefined\")\n\t\t\ta = 1;\n\t\tif (s === 0.0)\n\t\t\treturn ul4._rgb(l, l, l, a);\n\t\tif (l <= 0.5)\n\t\t\tm2 = l * (1.0+s);\n\t\telse\n\t\t\tm2 = l+s-(l*s);\n\t\tm1 = 2.0*l - m2;\n\t\treturn ul4._rgb(_v(m1, m2, h+1/3), _v(m1, m2, h), _v(m1, m2, h-1/3), a);\n\t};\n\n\t// Return a ``Color`` object from the hue, saturation, value and alpha values ``h``, ``s``, ``v`` and ``a`` (i.e. using the HSV color model)\n\tul4._hsv = function _hsv(h, s, v, a)\n\t{\n\t\tif (s === 0.0)\n\t\t\treturn ul4._rgb(v, v, v, a);\n\t\tlet i = Math.floor(h*6.0);\n\t\tlet f = (h*6.0) - i;\n\t\tlet p = v*(1.0 - s);\n\t\tlet q = v*(1.0 - s*f);\n\t\tlet t = v*(1.0 - s*(1.0-f));\n\t\tswitch (i%6)\n\t\t{\n\t\t\tcase 0:\n\t\t\t\treturn ul4._rgb(v, t, p, a);\n\t\t\tcase 1:\n\t\t\t\treturn ul4._rgb(q, v, p, a);\n\t\t\tcase 2:\n\t\t\t\treturn ul4._rgb(p, v, t, a);\n\t\t\tcase 3:\n\t\t\t\treturn ul4._rgb(p, q, v, a);\n\t\t\tcase 4:\n\t\t\t\treturn ul4._rgb(t, p, v, a);\n\t\t\tcase 5:\n\t\t\t\treturn ul4._rgb(v, p, q, a);\n\t\t}\n\t};\n\n\t// Return the item with the key ``key`` from the dict ``container``. If ``container`` doesn't have this key, return ``defaultvalue``\n\tul4._get = function _get(container, key, defaultvalue)\n\t{\n\t\tif (ul4._ismap(container))\n\t\t{\n\t\t\tif (container.has(key))\n\t\t\t\treturn container.get(key);\n\t\t\treturn defaultvalue;\n\t\t}\n\t\telse if (ul4._isobject(container))\n\t\t{\n\t\t\tlet result = container[key];\n\t\t\tif (typeof(result) === \"undefined\")\n\t\t\t\treturn defaultvalue;\n\t\t\treturn result;\n\t\t}\n\t\tthrow new ul4.TypeError(\"get() requires a dict\");\n\t};\n\n\t// Return a ``Date`` object for the current time\n\tul4.now = function now()\n\t{\n\t\treturn new Date();\n\t};\n\n\t// Return a ``Date`` object for the current time in UTC\n\tul4.utcnow = function utcnow()\n\t{\n\t\tlet now = new Date();\n\t\t// FIXME: The timezone is wrong for the new ``Date`` object.\n\t\treturn new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(), now.getUTCMilliseconds());\n\t};\n\n\t// Return an ``ul4.Date`` object for today\n\tul4.today = function today()\n\t{\n\t\tlet now = new Date();\n\t\treturn new ul4.Date(now.getFullYear(), now.getMonth()+1, now.getDate());\n\t};\n\n\tul4.functions = {\n\t\trepr: ul4._repr,\n\t\tascii: ul4._ascii,\n\t\tstr: ul4._str,\n\t\tint: ul4._int,\n\t\tfloat: ul4._float,\n\t\tlist: ul4._list,\n\t\tset: ul4._set,\n\t\tbool: ul4._bool,\n\t\tlen: ul4._len,\n\t\ttype: ul4._type,\n\t\tformat: ul4._format,\n\t\tany: ul4._any,\n\t\tall: ul4._all,\n\t\tzip: ul4._zip,\n\t\tgetattr: ul4._getattr,\n\t\thasattr: ul4._hasattr,\n\t\tdir: ul4._dir,\n\t\tisundefined: ul4._isundefined,\n\t\tisdefined: ul4._isdefined,\n\t\tisnone: ul4._isnone,\n\t\tisbool: ul4._isbool,\n\t\tisint: ul4._isint,\n\t\tisfloat: ul4._isfloat,\n\t\tisstr: ul4._isstr,\n\t\tisdate: ul4._isdate,\n\t\tisdatetime: ul4._isdatetime,\n\t\tiscolor: ul4._iscolor,\n\t\tistimedelta: ul4._istimedelta,\n\t\tismonthdelta: ul4._ismonthdelta,\n\t\tistemplate: ul4._istemplate,\n\t\tisfunction: ul4._isfunction,\n\t\tislist: ul4._islist,\n\t\tisset: ul4._isanyset,\n\t\tisdict: ul4._isdict,\n\t\tisexception: ul4._isexception,\n\t\tasjson: ul4._asjson,\n\t\tfromjson: ul4._fromjson,\n\t\tasul4on: ul4._asul4on,\n\t\tfromul4on: ul4._fromul4on,\n\t\tnow: ul4.now,\n\t\tutcnow: ul4.utcnow,\n\t\ttoday: ul4.today,\n\t\tenumerate: ul4._enumerate,\n\t\tisfirst: ul4._isfirst,\n\t\tislast: ul4._islast,\n\t\tisfirstlast: ul4._isfirstlast,\n\t\tenumfl: ul4._enumfl,\n\t\tabs: ul4._abs,\n\t\tdate: ul4._date,\n\t\tdatetime: ul4._datetime,\n\t\ttimedelta: ul4._timedelta,\n\t\tmonthdelta: ul4._monthdelta,\n\t\trgb: ul4._rgb,\n\t\thls: ul4._hls,\n\t\thsv: ul4._hsv,\n\t\txmlescape: ul4._xmlescape,\n\t\tcsv: ul4._csv,\n\t\tchr: ul4._chr,\n\t\tord: ul4._ord,\n\t\thex: ul4._hex,\n\t\toct: ul4._oct,\n\t\tbin: ul4._bin,\n\t\tmin: ul4._min,\n\t\tmax: ul4._max,\n\t\tsum: ul4._sum,\n\t\tfirst: ul4._first,\n\t\tlast: ul4._last,\n\t\tsorted: ul4._sorted,\n\t\trange: ul4._range,\n\t\tslice: ul4._slice,\n\t\turlquote: ul4._urlquote,\n\t\turlunquote: ul4._urlunquote,\n\t\treversed: ul4._reversed,\n\t\trandom: ul4._random,\n\t\trandrange: ul4._randrange,\n\t\trandchoice: ul4._randchoice,\n\t\tround: ul4._round,\n\t\tmd5: ul4._md5\n\t};\n\n\tul4.expose(ul4._repr, [\"obj\"], {name: \"repr\"});\n\tul4.expose(ul4._ascii, [\"obj\"], {name: \"ascii\"});\n\tul4.expose(ul4._str, [\"obj=\", \"\"], {name: \"str\"});\n\tul4.expose(ul4._int, [\"obj=\", 0, \"base=\", null], {name: \"int\"});\n\tul4.expose(ul4._float, [\"obj=\", 0.0], {name: \"float\"});\n\tul4.expose(ul4._list, [\"iterable=\", []], {name: \"list\"});\n\tul4.expose(ul4._set, [\"iterable=\", []], {name: \"set\"});\n\tul4.expose(ul4._bool, [\"obj=\", false], {name: \"bool\"});\n\tul4.expose(ul4._len, [\"sequence\"], {name: \"len\"});\n\tul4.expose(ul4._type, [\"obj\"], {name: \"type\"});\n\tul4.expose(ul4._format, [\"obj\", \"fmt\", \"lang=\", null], {name: \"format\"});\n\tul4.expose(ul4._any, [\"iterable\"], {name: \"any\"});\n\tul4.expose(ul4._all, [\"iterable\"], {name: \"all\"});\n\tul4.expose(ul4._zip, [\"*iterables\"], {name: \"zip\"});\n\tul4.expose(ul4._getattr, [\"obj\", \"attrname\", \"default=\", null], {name: \"getattr\"});\n\tul4.expose(ul4._hasattr, [\"obj\", \"attrname\"], {name: \"hasattr\"});\n\tul4.expose(ul4._dir, [\"obj\"], {name: \"dir\"});\n\tul4.expose(ul4._isundefined, [\"obj\"], {name: \"isundefined\"});\n\tul4.expose(ul4._isdefined, [\"obj\"], {name: \"isdefined\"});\n\tul4.expose(ul4._isnone, [\"obj\"], {name: \"isnone\"});\n\tul4.expose(ul4._isbool, [\"obj\"], {name: \"isbool\"});\n\tul4.expose(ul4._isint, [\"obj\"], {name: \"isint\"});\n\tul4.expose(ul4._isfloat, [\"obj\"], {name: \"isfloat\"});\n\tul4.expose(ul4._isstr, [\"obj\"], {name: \"isstr\"});\n\tul4.expose(ul4._isdate, [\"obj\"], {name: \"isdate\"});\n\tul4.expose(ul4._isdatetime, [\"obj\"], {name: \"isdatetime\"});\n\tul4.expose(ul4._iscolor, [\"obj\"], {name: \"iscolor\"});\n\tul4.expose(ul4._istimedelta, [\"obj\"], {name: \"istimedelta\"});\n\tul4.expose(ul4._ismonthdelta, [\"obj\"], {name: \"ismonthdelta\"});\n\tul4.expose(ul4._istemplate, [\"obj\"], {name: \"istemplate\"});\n\tul4.expose(ul4._isfunction, [\"obj\"], {name: \"isfunction\"});\n\tul4.expose(ul4._islist, [\"obj\"], {name: \"islist\"});\n\tul4.expose(ul4._isanyset, [\"obj\"], {name: \"isset\"});\n\tul4.expose(ul4._isdict, [\"obj\"], {name: \"isdict\"});\n\tul4.expose(ul4._isexception, [\"obj\"], {name: \"isexception\"});\n\tul4.expose(ul4._asjson, [\"obj\"], {name: \"asjson\"});\n\tul4.expose(ul4._fromjson, [\"string\"], {name: \"fromjson\"});\n\tul4.expose(ul4._asul4on, [\"obj\"], {name: \"asul4on\"});\n\tul4.expose(ul4._fromul4on, [\"string\"], {name: \"fromul4on\"});\n\tul4.expose(ul4.now, []);\n\tul4.expose(ul4.utcnow, []);\n\tul4.expose(ul4.today, []);\n\tul4.expose(ul4._enumerate, [\"iterable\", \"start=\", 0], {name: \"enumerate\"});\n\tul4.expose(ul4._isfirst, [\"iterable\"], {name: \"isfirst\"});\n\tul4.expose(ul4._islast, [\"iterable\"], {name: \"islast\"});\n\tul4.expose(ul4._isfirstlast, [\"iterable\"], {name: \"isfirstlast\"});\n\tul4.expose(ul4._enumfl, [\"iterable\", \"start=\", 0], {name: \"enumfl\"});\n\tul4.expose(ul4._abs, [\"number\"], {name: \"abs\"});\n\tul4.expose(ul4._date, [\"year\", \"month\", \"day\"], {name: \"date\"});\n\tul4.expose(ul4._datetime, [\"year\", \"month\", \"day\", \"hour=\", 0, \"minute=\", 0, \"second=\", 0, \"microsecond=\", 0], {name: \"datetime\"});\n\tul4.expose(ul4._timedelta, [\"days=\", 0, \"seconds=\", 0, \"microseconds=\", 0], {name: \"timedelta\"});\n\tul4.expose(ul4._monthdelta, [\"months=\", 0], {name: \"monthdelta\"});\n\tul4.expose(ul4._rgb, [\"r\", \"g\", \"b\", \"a=\", 1.0], {name: \"rgb\"});\n\tul4.expose(ul4._hls, [\"h\", \"l\", \"s\", \"a=\", 1.0], {name: \"hls\"});\n\tul4.expose(ul4._hsv, [\"h\", \"s\", \"v\", \"a=\", 1.0], {name: \"hsv\"});\n\tul4.expose(ul4._xmlescape, [\"obj\"], {name: \"xmlescape\"});\n\tul4.expose(ul4._csv, [\"obj\"], {name: \"csv\"});\n\tul4.expose(ul4._chr, [\"i\"], {name: \"chr\"});\n\tul4.expose(ul4._ord, [\"c\"], {name: \"ord\"});\n\tul4.expose(ul4._hex, [\"number\"], {name: \"hex\"});\n\tul4.expose(ul4._oct, [\"number\"], {name: \"oct\"});\n\tul4.expose(ul4._bin, [\"number\"], {name: \"bin\"});\n\tul4.expose(ul4._min, [\"*obj\"], {name: \"min\"});\n\tul4.expose(ul4._max, [\"*obj\"], {name: \"max\"});\n\tul4.expose(ul4._sum, [\"iterable\", \"start=\", 0], {name: \"sum\"});\n\tul4.expose(ul4._first, [\"iterable\", \"default=\", null], {name: \"first\"});\n\tul4.expose(ul4._last, [\"iterable\", \"default=\", null], {name: \"last\"});\n\tul4.expose(ul4._sorted, [\"iterable\", \"key=\", null, \"reverse=\", false], {name: \"sorted\", needscontext: true});\n\tul4.expose(ul4._range, [\"*args\"], {name: \"range\"});\n\tul4.expose(ul4._slice, [\"*args\"], {name: \"slice\"});\n\tul4.expose(ul4._urlquote, [\"string\"], {name: \"urlquote\"});\n\tul4.expose(ul4._urlunquote, [\"string\"], {name: \"urlunquote\"});\n\tul4.expose(ul4._reversed, [\"sequence\"], {name: \"reversed\"});\n\tul4.expose(ul4._random, [], {name: \"random\"});\n\tul4.expose(ul4._randrange, [\"*args\"], {name: \"randrange\"});\n\tul4.expose(ul4._randchoice, [\"sequence\"], {name: \"randchoice\"});\n\tul4.expose(ul4._round, [\"x\", \"digit=\", 0], {name: \"round\"});\n\tul4.expose(ul4._md5, [\"string\"], {name: \"md5\"});\n\n\t// Functions implementing UL4 methods\n\tul4._count = function _count(obj, sub, start=null, end=null)\n\t{\n\t\tif (start < 0)\n\t\t\tstart += obj.length;\n\t\tif (start === null)\n\t\t\tstart = 0;\n\n\t\tif (end < 0)\n\t\t\tend += obj.length;\n\t\tif (end === null)\n\t\t\tend = obj.length;\n\n\t\tlet isstr = ul4._isstr(obj);\n\n\t\tif (isstr && !sub.length)\n\t\t{\n\t\t\tif (end < 0 || start > obj.length || start > end)\n\t\t\t\treturn 0;\n\t\t\tlet result = end - start + 1;\n\t\t\tif (result > obj.length + 1)\n\t\t\t\tresult = obj.length + 1;\n\t\t\treturn result;\n\t\t}\n\n\t\tstart = ul4._bound(start, obj.length);\n\t\tend = ul4._bound(end, obj.length);\n\n\t\tlet count = 0;\n\t\tif (ul4._islist(obj))\n\t\t{\n\t\t\tfor (let i = start; i < end; ++i)\n\t\t\t{\n\t\t\t\tif (ul4._eq(obj[i], sub))\n\t\t\t\t\t++count;\n\t\t\t}\n\t\t\treturn count;\n\t\t}\n\t\telse // string\n\t\t{\n\t\t\tlet lastIndex = start;\n\n\t\t\tfor (;;)\n\t\t\t{\n\t\t\t\tlastIndex = obj.indexOf(sub, lastIndex);\n\t\t\t\tif (lastIndex == -1)\n\t\t\t\t\tbreak;\n\t\t\t\tif (lastIndex + sub.length > end)\n\t\t\t\t\tbreak;\n\t\t\t\t++count;\n\t\t\t\tlastIndex += sub.length;\n\t\t\t}\n\t\t\treturn count;\n\t\t}\n\t};\n\n\tul4._find = function _find(obj, sub, start=null, end=null)\n\t{\n\t\tif (start < 0)\n\t\t\tstart += obj.length;\n\t\tif (start === null)\n\t\t\tstart = 0;\n\t\tif (end < 0)\n\t\t\tend += obj.length;\n\t\tif (end === null)\n\t\t\tend = obj.length;\n\t\tstart = ul4._bound(start, obj.length);\n\t\tend = ul4._bound(end, obj.length);\n\n\t\tif (start !== 0 || end !== obj.length)\n\t\t{\n\t\t\tif (typeof(obj) == \"string\")\n\t\t\t\tobj = obj.substring(start, end);\n\t\t\telse\n\t\t\t\tobj = obj.slice(start, end);\n\t\t}\n\t\tlet result = obj.indexOf(sub);\n\t\tif (result !== -1)\n\t\t\tresult += start;\n\t\treturn result;\n\t};\n\n\tul4._rfind = function _rfind(obj, sub, start=null, end=null)\n\t{\n\t\tif (start < 0)\n\t\t\tstart += obj.length;\n\t\tif (start === null)\n\t\t\tstart = 0;\n\t\tif (end < 0)\n\t\t\tend += obj.length;\n\t\tif (end === null)\n\t\t\tend = obj.length;\n\t\tstart = ul4._bound(start, obj.length);\n\t\tend = ul4._bound(end, obj.length);\n\n\t\tif (start !== 0 || end !== obj.length)\n\t\t{\n\t\t\tif (typeof(obj) == \"string\")\n\t\t\t\tobj = obj.substring(start, end);\n\t\t\telse\n\t\t\t\tobj = obj.slice(start, end);\n\t\t}\n\t\tlet result = obj.lastIndexOf(sub);\n\t\tif (result !== -1)\n\t\t\tresult += start;\n\t\treturn result;\n\t};\n\n\tul4._week4format = function _week(obj, firstweekday=null)\n\t{\n\t\tif (firstweekday === null)\n\t\t\tfirstweekday = 0;\n\t\telse\n\t\t\tfirstweekday %= 7;\n\n\t\tlet yearday = ul4.DateTimeProtocol.yearday(obj)+6;\n\t\tlet jan1 = new Date(obj.getFullYear(), 0, 1);\n\t\tlet jan1weekday = jan1.getDay();\n\t\tif (--jan1weekday < 0)\n\t\t\tjan1weekday = 6;\n\n\t\twhile (jan1weekday != firstweekday)\n\t\t{\n\t\t\t--yearday;\n\t\t\tif (++jan1weekday == 7)\n\t\t\t\tjan1weekday = 0;\n\t\t}\n\t\treturn Math.floor(yearday/7);\n\t};\n\n\tul4._isleap = function _isleap(obj)\n\t{\n\t\treturn new Date(obj.getFullYear(), 1, 29).getMonth() === 1;\n\t};\n\n\tul4._update = function _update(obj, others, kwargs)\n\t{\n\t\tif (!ul4._isdict(obj))\n\t\t\tthrow new ul4.TypeError(\"update() requires a dict\");\n\t\tfor (let i = 0; i < others.length; ++i)\n\t\t{\n\t\t\tlet other = others[i];\n\t\t\tif (ul4._ismap(other))\n\t\t\t{\n\t\t\t\tother.forEach(function(value, key) {\n\t\t\t\t\tul4._setmap(obj, key, value);\n\t\t\t\t});\n\t\t\t}\n\t\t\telse if (ul4._isobject(other))\n\t\t\t{\n\t\t\t\tfor (let key in other)\n\t\t\t\t\tul4._setmap(obj, key, other[key]);\n\t\t\t}\n\t\t\telse if (ul4._islist(other))\n\t\t\t{\n\t\t\t\tfor (let i = 0; i < other.length; ++i)\n\t\t\t\t{\n\t\t\t\t\tlet item = other[i];\n\t\t\t\t\tif (!ul4._islist(item) || (item.length != 2))\n\t\t\t\t\t\tthrow new ul4.TypeError(\"update() requires a dict or a list of (key, value) pairs\");\n\t\t\t\t\tul4._setmap(obj, item[0], item[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tthrow new ul4.TypeError(\"update() requires a dict or a list of (key, value) pairs\");\n\t\t}\n\t\tkwargs.forEach(function(value, key) {\n\t\t\tul4._setmap(obj, key, value);\n\t\t});\n\t\treturn null;\n\t};\n\n\tul4.Color = class Color extends ul4.Proto\n\t{\n\t\tconstructor(r=0, g=0, b=0, a=255)\n\t\t{\n\t\t\tsuper();\n\t\t\tthis._r = r;\n\t\t\tthis._g = g;\n\t\t\tthis._b = b;\n\t\t\tthis._a = a;\n\t\t}\n\n\t\t__repr__()\n\t\t{\n\t\t\tlet r = ul4._lpad(this._r.toString(16), \"0\", 2);\n\t\t\tlet g = ul4._lpad(this._g.toString(16), \"0\", 2);\n\t\t\tlet b = ul4._lpad(this._b.toString(16), \"0\", 2);\n\t\t\tlet a = ul4._lpad(this._a.toString(16), \"0\", 2);\n\t\t\tif (this._a !== 0xff)\n\t\t\t{\n\t\t\t\tif (r[0] === r[1] && g[0] === g[1] && b[0] === b[1] && a[0] === a[1])\n\t\t\t\t\treturn \"#\" + r[0] + g[0] + b[0] + a[0];\n\t\t\t\telse\n\t\t\t\t\treturn \"#\" + r + g + b + a;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (r[0] === r[1] && g[0] === g[1] && b[0] === b[1])\n\t\t\t\t\treturn \"#\" + r[0] + g[0] + b[0];\n\t\t\t\telse\n\t\t\t\t\treturn \"#\" + r + g + b;\n\t\t\t}\n\t\t}\n\n\t\t__str__()\n\t\t{\n\t\t\tif (this._a !== 0xff)\n\t\t\t{\n\t\t\t\treturn \"rgba(\" + this._r + \", \" + this._g + \", \" + this._b + \", \" + (this._a/255) + \")\";\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlet r = ul4._lpad(this._r.toString(16), \"0\", 2);\n\t\t\t\tlet g = ul4._lpad(this._g.toString(16), \"0\", 2);\n\t\t\t\tlet b = ul4._lpad(this._b.toString(16), \"0\", 2);\n\t\t\t\tif (r[0] === r[1] && g[0] === g[1] && b[0] === b[1])\n\t\t\t\t\treturn \"#\" + r[0] + g[0] + b[0];\n\t\t\t\telse\n\t\t\t\t\treturn \"#\" + r + g + b;\n\t\t\t}\n\t\t}\n\n\t\t__iter__()\n\t\t{\n\t\t\treturn {\n\t\t\t\tobj: this,\n\t\t\t\tindex: 0,\n\t\t\t\tnext: function() {\n\t\t\t\t\tif (this.index == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t++this.index;\n\t\t\t\t\t\treturn {value: this.obj._r, done: false};\n\t\t\t\t\t}\n\t\t\t\t\telse if (this.index == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\t++this.index;\n\t\t\t\t\t\treturn {value: this.obj._g, done: false};\n\t\t\t\t\t}\n\t\t\t\t\telse if (this.index == 2)\n\t\t\t\t\t{\n\t\t\t\t\t\t++this.index;\n\t\t\t\t\t\treturn {value: this.obj._b, done: false};\n\t\t\t\t\t}\n\t\t\t\t\telse if (this.index == 3)\n\t\t\t\t\t{\n\t\t\t\t\t\t++this.index;\n\t\t\t\t\t\treturn {value: this.obj._a, done: false};\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\treturn {done: true};\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\t__getattr__(attrname)\n\t\t{\n\t\t\tlet self = this;\n\t\t\tswitch (attrname)\n\t\t\t{\n\t\t\t\tcase \"r\":\n\t\t\t\t\tlet r = function r(){ return self._r; };\n\t\t\t\t\tul4.expose(r, []);\n\t\t\t\t\treturn r;\n\t\t\t\tcase \"g\":\n\t\t\t\t\tlet g = function g(){ return self._g; };\n\t\t\t\t\tul4.expose(g, []);\n\t\t\t\t\treturn g;\n\t\t\t\tcase \"b\":\n\t\t\t\t\tlet b = function b(){ return self._b; };\n\t\t\t\t\tul4.expose(b, []);\n\t\t\t\t\treturn b;\n\t\t\t\tcase \"a\":\n\t\t\t\t\tlet a = function a(){ return self._a; };\n\t\t\t\t\tul4.expose(a, []);\n\t\t\t\t\treturn a;\n\t\t\t\tcase \"lum\":\n\t\t\t\t\tlet lum = function lum(){ return self.lum(); };\n\t\t\t\t\tul4.expose(lum, []);\n\t\t\t\t\treturn lum;\n\t\t\t\tcase \"hls\":\n\t\t\t\t\tlet hls = function hls(){ return self.hls(); };\n\t\t\t\t\tul4.expose(hls, []);\n\t\t\t\t\treturn hls;\n\t\t\t\tcase \"hlsa\":\n\t\t\t\t\tlet hlsa = function hlsa(){ return self.hlsa(); };\n\t\t\t\t\tul4.expose(hlsa, []);\n\t\t\t\t\treturn hlsa;\n\t\t\t\tcase \"hsv\":\n\t\t\t\t\tlet hsv = function hsv(){ return self.hsv(); };\n\t\t\t\t\tul4.expose(hsv, []);\n\t\t\t\t\treturn hsv;\n\t\t\t\tcase \"hsva\":\n\t\t\t\t\tlet hsva = function hsva(){ return self.hsva(); };\n\t\t\t\t\tul4.expose(hsva, []);\n\t\t\t\t\treturn hsva;\n\t\t\t\tcase \"witha\":\n\t\t\t\t\tlet witha = function witha(a){ return self.witha(a); };\n\t\t\t\t\tul4.expose(witha, [\"a\"]);\n\t\t\t\t\treturn witha;\n\t\t\t\tcase \"withlum\":\n\t\t\t\t\tlet withlum = function withlum(lum){ return self.withlum(lum); };\n\t\t\t\t\tul4.expose(withlum, [\"lum\"]);\n\t\t\t\t\treturn withlum;\n\t\t\t\tcase \"abslum\":\n\t\t\t\t\tlet abslum = function abslum(lum){ return self.abslum(lum); };\n\t\t\t\t\tul4.expose(abslum, [\"lum\"]);\n\t\t\t\t\treturn abslum;\n\t\t\t\tcase \"rellum\":\n\t\t\t\t\tlet rellum = function rellum(lum){ return self.rellum(lum); };\n\t\t\t\t\tul4.expose(rellum, [\"lum\"]);\n\t\t\t\t\treturn rellum;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ul4.AttributeError(this, attrname);\n\t\t\t}\n\t\t}\n\n\t\t__getitem__(key)\n\t\t{\n\t\t\tlet orgkey = key;\n\t\t\tif (key < 0)\n\t\t\t\tkey += 4;\n\t\t\tswitch (key)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this._r;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this._g;\n\t\t\t\tcase 2:\n\t\t\t\t\treturn this._b;\n\t\t\t\tcase 3:\n\t\t\t\t\treturn this._a;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ul4.IndexError(this, orgkey);\n\t\t\t}\n\t\t}\n\n\t\t__eq__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.Color)\n\t\t\t\treturn this._r == other._r && this._g == other._g && this._b == other._b && this._a == other._a;\n\t\t\treturn false;\n\t\t}\n\n\t\tr()\n\t\t{\n\t\t\t\treturn this._r;\n\t\t}\n\n\t\tg()\n\t\t{\n\t\t\treturn this._g;\n\t\t}\n\n\t\tb()\n\t\t{\n\t\t\treturn this._b;\n\t\t}\n\n\t\ta()\n\t\t{\n\t\t\treturn this._a;\n\t\t}\n\n\t\tlum()\n\t\t{\n\t\t\treturn this.hls()[1];\n\t\t}\n\n\t\thls()\n\t\t{\n\t\t\tlet r = this._r/255.0;\n\t\t\tlet g = this._g/255.0;\n\t\t\tlet b = this._b/255.0;\n\t\t\tlet maxc = Math.max(r, g, b);\n\t\t\tlet minc = Math.min(r, g, b);\n\t\t\tlet h, l, s;\n\t\t\tlet rc, gc, bc;\n\n\t\t\tl = (minc+maxc)/2.0;\n\t\t\tif (minc == maxc)\n\t\t\t\treturn [0.0, l, 0.0];\n\t\t\tif (l <= 0.5)\n\t\t\t\ts = (maxc-minc) / (maxc+minc);\n\t\t\telse\n\t\t\t\ts = (maxc-minc) / (2.0-maxc-minc);\n\t\t\trc = (maxc-r) / (maxc-minc);\n\t\t\tgc = (maxc-g) / (maxc-minc);\n\t\t\tbc = (maxc-b) / (maxc-minc);\n\t\t\tif (r == maxc)\n\t\t\t\th = bc-gc;\n\t\t\telse if (g == maxc)\n\t\t\t\th = 2.0+rc-bc;\n\t\t\telse\n\t\t\t\th = 4.0+gc-rc;\n\t\t\th = (h/6.0) % 1.0;\n\t\t\treturn [h, l, s];\n\t\t}\n\n\t\thlsa()\n\t\t{\n\t\t\tlet hls = this.hls();\n\t\t\treturn hls.concat(this._a/255.0);\n\t\t}\n\n\t\thsv()\n\t\t{\n\t\t\tlet r = this._r/255.0;\n\t\t\tlet g = this._g/255.0;\n\t\t\tlet b = this._b/255.0;\n\t\t\tlet maxc = Math.max(r, g, b);\n\t\t\tlet minc = Math.min(r, g, b);\n\t\t\tlet v = maxc;\n\t\t\tif (minc == maxc)\n\t\t\t\treturn [0.0, 0.0, v];\n\t\t\tlet s = (maxc-minc) / maxc;\n\t\t\tlet rc = (maxc-r) / (maxc-minc);\n\t\t\tlet gc = (maxc-g) / (maxc-minc);\n\t\t\tlet bc = (maxc-b) / (maxc-minc);\n\t\t\tlet h;\n\t\t\tif (r == maxc)\n\t\t\t\th = bc-gc;\n\t\t\telse if (g == maxc)\n\t\t\t\th = 2.0+rc-bc;\n\t\t\telse\n\t\t\t\th = 4.0+gc-rc;\n\t\t\th = (h/6.0) % 1.0;\n\t\t\treturn [h, s, v];\n\t\t}\n\n\t\thsva()\n\t\t{\n\t\t\tlet hsv = this.hsv();\n\t\t\treturn hsv.concat(this._a/255.0);\n\t\t}\n\n\t\twitha(a)\n\t\t{\n\t\t\tif (typeof(a) !== \"number\")\n\t\t\t\tthrow new ul4.TypeError(\"witha() requires a number\");\n\t\t\treturn new ul4.Color(this._r, this._g, this._b, a);\n\t\t}\n\n\t\twithlum(lum)\n\t\t{\n\t\t\tif (typeof(lum) !== \"number\")\n\t\t\t\tthrow new ul4.TypeError(\"witha() requires a number\");\n\t\t\tlet hlsa = this.hlsa();\n\t\t\treturn ul4._hls(hlsa[0], lum, hlsa[2], hlsa[3]);\n\t\t}\n\n\t\tul4type()\n\t\t{\n\t\t\treturn \"color\";\n\t\t}\n\t};\n\n\tul4.expose(ul4.Color.prototype.r, []);\n\tul4.expose(ul4.Color.prototype.g, []);\n\tul4.expose(ul4.Color.prototype.b, []);\n\tul4.expose(ul4.Color.prototype.a, []);\n\tul4.expose(ul4.Color.prototype.lum, []);\n\tul4.expose(ul4.Color.prototype.hls, []);\n\tul4.expose(ul4.Color.prototype.hlsa, []);\n\tul4.expose(ul4.Color.prototype.hsv, []);\n\tul4.expose(ul4.Color.prototype.hsva, []);\n\tul4.expose(ul4.Color.prototype.witha, [\"a\"]);\n\tul4.expose(ul4.Color.prototype.withlum, [\"lum\"]);\n\n\tconst _js_Date = Date;\n\n\tul4.Date = class Date extends ul4.Proto\n\t{\n\t\tconstructor(year, month, day)\n\t\t{\n\t\t\tsuper();\n\t\t\tthis._date = new _js_Date(year, month-1, day);\n\t\t}\n\n\t\t__repr__()\n\t\t{\n\t\t\treturn '@(' + this.__str__() + \")\";\n\t\t}\n\n\t\t__str__()\n\t\t{\n\t\t\treturn ul4._lpad(this._date.getFullYear(), \"0\", 4) + \"-\" + ul4._lpad(this._date.getMonth()+1, \"0\", 2) + \"-\" + ul4._lpad(this._date.getDate(), \"0\", 2);\n\t\t}\n\n\t\t__eq__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.Date)\n\t\t\t\treturn this._date.getTime() === other._date.getTime();\n\t\t\treturn false;\n\t\t}\n\n\t\t__lt__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.Date)\n\t\t\t\treturn this._date < other._date;\n\t\t\tul4._unorderable(\"<\", this, other);\n\t\t}\n\n\t\t__le__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.Date)\n\t\t\t\treturn this._date <= other._date;\n\t\t\tul4._unorderable(\"<=\", this, other);\n\t\t}\n\n\t\t__gt__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.Date)\n\t\t\t\treturn this._date > other._date;\n\t\t\tul4._unorderable(\">\", this, other);\n\t\t}\n\n\t\t__ge__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.Date)\n\t\t\t\treturn this._date >= other._date;\n\t\t\tul4._unorderable(\">=\", this, other);\n\t\t}\n\n\t\tyear()\n\t\t{\n\t\t\treturn this._date.getFullYear();\n\t\t}\n\n\t\tmonth()\n\t\t{\n\t\t\treturn this._date.getMonth()+1;\n\t\t}\n\n\t\tday()\n\t\t{\n\t\t\treturn this._date.getDate();\n\t\t}\n\n\t\tul4type()\n\t\t{\n\t\t\treturn \"date\";\n\t\t}\n\t};\n\n\n\tul4.TimeDelta = class TimeDelta extends ul4.Proto\n\t{\n\t\tconstructor(days=0, seconds=0, microseconds=0)\n\t\t{\n\t\t\tsuper();\n\t\t\tlet total_microseconds = Math.floor((days * 86400 + seconds)*1000000 + microseconds);\n\n\t\t\tmicroseconds = ul4.ModAST.prototype._do(total_microseconds, 1000000);\n\t\t\tlet total_seconds = Math.floor(total_microseconds / 1000000);\n\t\t\tseconds = ul4.ModAST.prototype._do(total_seconds, 86400);\n\t\t\tdays = Math.floor(total_seconds / 86400);\n\t\t\tif (seconds < 0)\n\t\t\t{\n\t\t\t\tseconds += 86400;\n\t\t\t\t--days;\n\t\t\t}\n\n\t\t\tthis._microseconds = microseconds;\n\t\t\tthis._seconds = seconds;\n\t\t\tthis._days = days;\n\t\t}\n\n\t\t__repr__()\n\t\t{\n\t\t\tlet v = [], first = true;\n\t\t\tv.push(\"timedelta(\");\n\t\t\tif (this._days)\n\t\t\t{\n\t\t\t\tv.push(\"days=\" + this._days);\n\t\t\t\tfirst = false;\n\t\t\t}\n\t\t\tif (this._seconds)\n\t\t\t{\n\t\t\t\tif (!first)\n\t\t\t\t\tv.push(\", \");\n\t\t\t\tv.push(\"seconds=\" + this._seconds);\n\t\t\t\tfirst = false;\n\t\t\t}\n\t\t\tif (this._microseconds)\n\t\t\t{\n\t\t\t\tif (!first)\n\t\t\t\t\tv.push(\", \");\n\t\t\t\tv.push(\"microseconds=\" + this._microseconds);\n\t\t\t}\n\t\t\tv.push(\")\");\n\t\t\treturn v.join(\"\");\n\t\t}\n\n\t\t__str__()\n\t\t{\n\t\t\tlet v = [];\n\t\t\tif (this._days)\n\t\t\t{\n\t\t\t\tv.push(this._days + \" day\");\n\t\t\t\tif (this._days !== -1 && this._days !== 1)\n\t\t\t\t\tv.push(\"s\");\n\t\t\t\tv.push(\", \");\n\t\t\t}\n\t\t\tlet seconds = this._seconds % 60;\n\t\t\tlet minutes = Math.floor(this._seconds / 60);\n\t\t\tlet hours = Math.floor(minutes / 60);\n\t\t\tminutes = minutes % 60;\n\n\t\t\tv.push(\"\" + hours);\n\t\t\tv.push(\":\");\n\t\t\tv.push(ul4._lpad(minutes.toString(), \"0\", 2));\n\t\t\tv.push(\":\");\n\t\t\tv.push(ul4._lpad(seconds.toString(), \"0\", 2));\n\t\t\tif (this._microseconds)\n\t\t\t{\n\t\t\t\tv.push(\".\");\n\t\t\t\tv.push(ul4._lpad(this._microseconds.toString(), \"0\", 6));\n\t\t\t}\n\t\t\treturn v.join(\"\");\n\t\t}\n\n\t\t__bool__()\n\t\t{\n\t\t\treturn this._days !== 0 || this._seconds !== 0 || this._microseconds !== 0;\n\t\t}\n\n\t\t__abs__()\n\t\t{\n\t\t\treturn this._days < 0 ? new ul4.TimeDelta(-this._days, -this._seconds, -this._microseconds) : this;\n\t\t}\n\n\t\t__eq__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.TimeDelta)\n\t\t\t\treturn (this._days === other._days) && (this._seconds === other._seconds) && (this._microseconds === other._microseconds);\n\t\t\treturn false;\n\t\t}\n\n\t\t__lt__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.TimeDelta)\n\t\t\t{\n\t\t\t\tif (this._days != other._days)\n\t\t\t\t\treturn this._days < other._days;\n\t\t\t\tif (this._seconds != other._seconds)\n\t\t\t\t\treturn this._seconds < other._seconds;\n\t\t\t\treturn this._microseconds < other._microseconds;\n\t\t\t}\n\t\t\tul4._unorderable(\"<\", this, other);\n\t\t}\n\n\t\t__le__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.TimeDelta)\n\t\t\t{\n\t\t\t\tif (this._days != other._days)\n\t\t\t\t\treturn this._days < other._days;\n\t\t\t\tif (this._seconds != other._seconds)\n\t\t\t\t\treturn this._seconds < other._seconds;\n\t\t\t\treturn this._microseconds <= other._microseconds;\n\t\t\t}\n\t\t\tul4._unorderable(\"<=\", this, other);\n\t\t}\n\n\t\t__gt__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.TimeDelta)\n\t\t\t{\n\t\t\t\tif (this._days != other._days)\n\t\t\t\t\treturn this._days > other._days;\n\t\t\t\tif (this._seconds != other._seconds)\n\t\t\t\t\treturn this._seconds > other._seconds;\n\t\t\t\treturn this._microseconds > other._microseconds;\n\t\t\t}\n\t\t\tul4._unorderable(\">\", this, other);\n\t\t}\n\n\t\t__ge__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.TimeDelta)\n\t\t\t{\n\t\t\t\tif (this._days != other._days)\n\t\t\t\t\treturn this._days > other._days;\n\t\t\t\tif (this._seconds != other._seconds)\n\t\t\t\t\treturn this._seconds > other._seconds;\n\t\t\t\treturn this._microseconds >= other._microseconds;\n\t\t\t}\n\t\t\tul4._unorderable(\">=\", this, other);\n\t\t}\n\n\t\t__neg__()\n\t\t{\n\t\t\treturn new ul4.TimeDelta(-this._days, -this._seconds, -this._microseconds);\n\t\t}\n\n\t\tadddate(date, days)\n\t\t{\n\t\t\tlet year = date._date.getFullYear();\n\t\t\tlet month = date._date.getMonth();\n\t\t\tlet day = date._date.getDate() + days;\n\t\t\treturn new ul4.Date(year, month, day);\n\t\t}\n\n\t\t_adddatetime(date, days, seconds, microseconds)\n\t\t{\n\t\t\tlet year = date.getFullYear();\n\t\t\tlet month = date.getMonth();\n\t\t\tlet day = date.getDate() + days;\n\t\t\tlet hour = date.getHours();\n\t\t\tlet minute = date.getMinutes();\n\t\t\tlet second = date.getSeconds() + seconds;\n\t\t\tlet millisecond = date.getMilliseconds() + microseconds/1000;\n\t\t\treturn new Date(year, month, day, hour, minute, second, millisecond);\n\t\t}\n\n\t\t__add__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.TimeDelta)\n\t\t\t\treturn new ul4.TimeDelta(this._days + other._days, this._seconds + other._seconds, this._microseconds + other._microseconds);\n\t\t\telse if (ul4._isdate(other))\n\t\t\t\treturn this._adddate(other, this._days);\n\t\t\telse if (ul4._isdatetime(other))\n\t\t\t\treturn this._adddatetime(other, this._days, this._seconds, this._microseconds);\n\t\t\tthrow new ul4.TypeError(ul4._type(this) + \" + \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__radd__(other)\n\t\t{\n\t\t\tif (ul4._isdate(other))\n\t\t\t\treturn this._adddate(other, this._days);\n\t\t\telse if (ul4._isdatetime(other))\n\t\t\t\treturn this._adddatetime(other, this._days, this._seconds, this._microseconds);\n\t\t\tthrow new ul4.TypeError(ul4._type(this) + \" + \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__sub__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.TimeDelta)\n\t\t\t\treturn new ul4.TimeDelta(this._days - other._days, this._seconds - other._seconds, this._microseconds - other._microseconds);\n\t\t\tthrow new ul4.TypeError(ul4._type(this) + \" - \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__rsub__(other)\n\t\t{\n\t\t\tif (ul4._isdate(other))\n\t\t\t\treturn this._adddate(other, -this._days);\n\t\t\telse if (ul4._isdatetime(other))\n\t\t\t\treturn this._adddatetime(other, -this._days, -this._seconds, -this._microseconds);\n\t\t\tthrow new ul4.TypeError(ul4._type(this) + \" - \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__mul__(other)\n\t\t{\n\t\t\tif (typeof(other) === \"number\")\n\t\t\t\treturn new ul4.TimeDelta(this._days * other, this._seconds * other, this._microseconds * other);\n\t\t\tthrow new ul4.TypeError(ul4._type(this) + \" * \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__rmul__(other)\n\t\t{\n\t\t\tif (typeof(other) === \"number\")\n\t\t\t\treturn new ul4.TimeDelta(this._days * other, this._seconds * other, this._microseconds * other);\n\t\t\tthrow new ul4.TypeError(ul4._type(this) + \" * \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__truediv__(other)\n\t\t{\n\t\t\tif (typeof(other) === \"number\")\n\t\t\t{\n\t\t\t\treturn new ul4.TimeDelta(this._days / other, this._seconds / other, this._microseconds / other);\n\t\t\t}\n\t\t\telse if (other instanceof ul4.TimeDelta)\n\t\t\t{\n\t\t\t\tlet myValue = this._days;\n\t\t\t\tlet otherValue = other._days;\n\t\t\t\tlet hasSeconds = this._seconds || other._seconds;\n\t\t\t\tlet hasMicroseconds = this._microseconds || other._microseconds;\n\t\t\t\tif (hasSeconds || hasMicroseconds)\n\t\t\t\t{\n\t\t\t\t\tmyValue = myValue*86400+this._seconds;\n\t\t\t\t\totherValue = otherValue*86400 + other._seconds;\n\t\t\t\t\tif (hasMicroseconds)\n\t\t\t\t\t{\n\t\t\t\t\t\tmyValue = myValue * 1000000 + this._microseconds;\n\t\t\t\t\t\totherValue = otherValue * 1000000 + other._microseconds;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn myValue/otherValue;\n\t\t\t}\n\t\t\tthrow new ul4.TypeError(ul4._type(this) + \" / \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__getattr__(attrname)\n\t\t{\n\t\t\tlet self = this;\n\t\t\tswitch (attrname)\n\t\t\t{\n\t\t\t\tcase \"days\":\n\t\t\t\t\tlet days = function days(){ return self._days; };\n\t\t\t\t\tul4.expose(days, []);\n\t\t\t\t\treturn days;\n\t\t\t\tcase \"seconds\":\n\t\t\t\t\tlet seconds = function seconds(){ return self._seconds; };\n\t\t\t\t\tul4.expose(seconds, []);\n\t\t\t\t\treturn seconds;\n\t\t\t\tcase \"microseconds\":\n\t\t\t\t\tlet microseconds = function microseconds(){ return self._microseconds; };\n\t\t\t\t\tul4.expose(microseconds, []);\n\t\t\t\t\treturn microseconds;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ul4.AttributeError(this, attrname);\n\t\t\t}\n\t\t}\n\n\t\tdays()\n\t\t{\n\t\t\treturn this._days;\n\t\t}\n\n\t\tseconds()\n\t\t{\n\t\t\treturn this._seconds;\n\t\t}\n\n\t\tmicroseconds()\n\t\t{\n\t\t\treturn this._microseconds;\n\t\t}\n\n\t\tul4type()\n\t\t{\n\t\t\treturn \"timedelta\";\n\t\t}\n\t};\n\n\n\tul4.MonthDelta = class MonthDelta extends ul4.Proto\n\t{\n\t\tconstructor(months=0)\n\t\t{\n\t\t\tsuper();\n\t\t\tthis._months = months;\n\t\t}\n\n\t\t__repr__()\n\t\t{\n\t\t\tif (!this._months)\n\t\t\t\treturn \"monthdelta()\";\n\t\t\treturn \"monthdelta(\" + this._months + \")\";\n\t\t}\n\n\t\t__str__()\n\t\t{\n\t\t\tif (this._months)\n\t\t\t{\n\t\t\t\tif (this._months !== -1 && this._months !== 1)\n\t\t\t\t\treturn this._months + \" months\";\n\t\t\t\treturn this._months + \" month\";\n\t\t\t}\n\t\t\treturn \"0 months\";\n\t\t}\n\n\t\ttoString()\n\t\t{\n\t\t\treturn this.__str__();\n\t\t}\n\n\t\t__bool__()\n\t\t{\n\t\t\treturn this._months !== 0;\n\t\t}\n\n\t\t__abs__()\n\t\t{\n\t\t\treturn this._months < 0 ? new ul4.MonthDelta(-this._months) : this;\n\t\t}\n\n\t\t__eq__(other)\n\t\t{\n\t\t\tif (other instanceof MonthDelta)\n\t\t\t\treturn this._months === other._months;\n\t\t\treturn false;\n\t\t}\n\n\t\t__lt__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.MonthDelta)\n\t\t\t\treturn this._months < other._months;\n\t\t\tul4._unorderable(\"<\", this, other);\n\t\t}\n\n\t\t__le__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.MonthDelta)\n\t\t\t\treturn this._months <= other._months;\n\t\t\tul4._unorderable(\"<=\", this, other);\n\t\t}\n\n\t\t__gt__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.MonthDelta)\n\t\t\t\treturn this._months > other._months;\n\t\t\tul4._unorderable(\">\", this, other);\n\t\t}\n\n\t\t__ge__(other)\n\t\t{\n\t\t\tif (other instanceof ul4.MonthDelta)\n\t\t\t\treturn this._months >= other._months;\n\t\t\tul4._unorderable(\">=\", this, other);\n\t\t}\n\n\t\t__neg__()\n\t\t{\n\t\t\treturn new ul4.MonthDelta(-this._months);\n\t\t}\n\n\t\t_adddate(date, months)\n\t\t{\n\t\t\tlet result = this._adddatetime(date._date, months);\n\t\t\treturn new ul4.Date(result.getFullYear(), result.getMonth()+1, result.getDate());\n\t\t}\n\n\t\t_adddatetime(date, months)\n\t\t{\n\t\t\tlet year = date.getFullYear();\n\t\t\tlet month = date.getMonth() + months;\n\t\t\tlet day = date.getDate();\n\t\t\tlet hour = date.getHours();\n\t\t\tlet minute = date.getMinutes();\n\t\t\tlet second = date.getSeconds();\n\t\t\tlet millisecond = date.getMilliseconds();\n\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\t// As the month might be out of bounds, we have to find out, what the real target month is\n\t\t\t\tlet targetmonth = new Date(year, month, 1, hour, minute, second, millisecond).getMonth();\n\t\t\t\tlet result = new Date(year, month, day, hour, minute, second, millisecond);\n\t\t\t\tif (result.getMonth() === targetmonth)\n\t\t\t\t\treturn result;\n\t\t\t\t--day;\n\t\t\t}\n\t\t}\n\n\t\t__add__(other)\n\t\t{\n\t\t\tif (ul4._ismonthdelta(other))\n\t\t\t\treturn new ul4.MonthDelta(this._months + other._months);\n\t\t\telse if (ul4._isdate(other))\n\t\t\t\treturn this._adddate(other, this._months);\n\t\t\telse if (ul4._isdatetime(other))\n\t\t\t\treturn this._adddatetime(other, this._months);\n\t\t\tthrow new ul4.ArgumentError(ul4._type(this) + \" + \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__radd__(other)\n\t\t{\n\t\t\tif (ul4._isdate(other))\n\t\t\t\treturn this._adddate(other, this._months);\n\t\t\telse if (ul4._isdatetime(other))\n\t\t\t\treturn this._adddatetime(other, this._months);\n\t\t\tthrow new ul4.ArgumentError(ul4._type(this) + \" + \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__sub__(other)\n\t\t{\n\t\t\tif (ul4._ismonthdelta(other))\n\t\t\t\treturn new ul4.MonthDelta(this._months - other._months);\n\t\t\tthrow new ul4.ArgumentError(ul4._type(this) + \" - \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__rsub__(other)\n\t\t{\n\t\t\tif (ul4._isdate(other))\n\t\t\t\treturn this._adddate(other, -this._months);\n\t\t\telse if (ul4._isdatetime(other))\n\t\t\t\treturn this._adddatetime(other, -this._months);\n\t\t\tthrow new ul4.ArgumentError(ul4._type(this) + \" - \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__mul__(other)\n\t\t{\n\t\t\tif (typeof(other) === \"number\")\n\t\t\t\treturn new ul4.MonthDelta(this._months * Math.floor(other));\n\t\t\tthrow new ul4.ArgumentError(ul4._type(this) + \" * \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__rmul__(other)\n\t\t{\n\t\t\tif (typeof(other) === \"number\")\n\t\t\t\treturn new ul4.MonthDelta(this._months * Math.floor(other));\n\t\t\tthrow new ul4.ArgumentError(ul4._type(this) + \" * \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__floordiv__(other)\n\t\t{\n\t\t\tif (typeof(other) === \"number\")\n\t\t\t\treturn new ul4.MonthDelta(Math.floor(this._months / other));\n\t\t\telse if (ul4._ismonthdelta(other))\n\t\t\t\treturn Math.floor(this._months / other._months);\n\t\t\tthrow new ul4.ArgumentError(ul4._type(this) + \" // \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__truediv__(other)\n\t\t{\n\t\t\tif (ul4._ismonthdelta(other))\n\t\t\t\treturn this._months / other._months;\n\t\t\tthrow new ul4.ArgumentError(ul4._type(this) + \" / \" + ul4._type(other) + \" not supported\");\n\t\t}\n\n\t\t__getattr__(attrname)\n\t\t{\n\t\t\tlet self = this;\n\t\t\tswitch (attrname)\n\t\t\t{\n\t\t\t\tcase \"months\":\n\t\t\t\t\tlet months = function months(){ return self._months; };\n\t\t\t\t\tul4.expose(months, []);\n\t\t\t\t\treturn months;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ul4.AttributeError(this, attrname);\n\t\t\t}\n\t\t}\n\n\t\tmonths()\n\t\t{\n\t\t\treturn this._months;\n\t\t}\n\n\t\tul4type()\n\t\t{\n\t\t\treturn \"monthdelta\";\n\t\t}\n\t};\n\n\tconst classes = [\n\t\tul4.TextAST,\n\t\tul4.IndentAST,\n\t\tul4.LineEndAST,\n\t\tul4.ConstAST,\n\t\tul4.SeqItemAST,\n\t\tul4.UnpackSeqItemAST,\n\t\tul4.DictItemAST,\n\t\tul4.UnpackDictItemAST,\n\t\tul4.PosArgAST,\n\t\tul4.KeywordArgAST,\n\t\tul4.UnpackListArgAST,\n\t\tul4.UnpackDictArgAST,\n\t\tul4.ListAST,\n\t\tul4.ListCompAST,\n\t\tul4.DictAST,\n\t\tul4.DictCompAST,\n\t\tul4.SetAST,\n\t\tul4.SetCompAST,\n\t\tul4.GenExprAST,\n\t\tul4.VarAST,\n\t\tul4.NotAST,\n\t\tul4.NegAST,\n\t\tul4.BitNotAST,\n\t\tul4.IfAST,\n\t\tul4.ReturnAST,\n\t\tul4.PrintAST,\n\t\tul4.PrintXAST,\n\t\tul4.ItemAST,\n\t\tul4.IsAST,\n\t\tul4.IsNotAST,\n\t\tul4.EQAST,\n\t\tul4.NEAST,\n\t\tul4.LTAST,\n\t\tul4.LEAST,\n\t\tul4.GTAST,\n\t\tul4.GEAST,\n\t\tul4.NotContainsAST,\n\t\tul4.ContainsAST,\n\t\tul4.AddAST,\n\t\tul4.SubAST,\n\t\tul4.MulAST,\n\t\tul4.FloorDivAST,\n\t\tul4.TrueDivAST,\n\t\tul4.ModAST,\n\t\tul4.ShiftLeftAST,\n\t\tul4.ShiftRightAST,\n\t\tul4.BitAndAST,\n\t\tul4.BitXOrAST,\n\t\tul4.BitOrAST,\n\t\tul4.AndAST,\n\t\tul4.OrAST,\n\t\tul4.SliceAST,\n\t\tul4.AttrAST,\n\t\tul4.CallAST,\n\t\tul4.RenderAST,\n\t\tul4.RenderXAST,\n\t\tul4.RenderBlockAST,\n\t\tul4.RenderBlocksAST,\n\t\tul4.SetVarAST,\n\t\tul4.AddVarAST,\n\t\tul4.SubVarAST,\n\t\tul4.MulVarAST,\n\t\tul4.TrueDivVarAST,\n\t\tul4.FloorDivVarAST,\n\t\tul4.ModVarAST,\n\t\tul4.ShiftLeftVarAST,\n\t\tul4.ShiftRightVarAST,\n\t\tul4.BitAndVarAST,\n\t\tul4.BitXOrVarAST,\n\t\tul4.BitOrVarAST,\n\t\tul4.ForBlockAST,\n\t\tul4.WhileBlockAST,\n\t\tul4.BreakAST,\n\t\tul4.ContinueAST,\n\t\tul4.CondBlockAST,\n\t\tul4.IfBlockAST,\n\t\tul4.ElIfBlockAST,\n\t\tul4.ElseBlockAST,\n\t\tul4.SignatureAST,\n\t\tul4.Template\n\t];\n\n\tfor (let i = 0; i < classes.length; ++i)\n\t{\n\t\tlet constructor = classes[i];\n\t\tlet ul4onname = constructor.name;\n\t\tif (ul4onname.substr(ul4onname.length-3) === \"AST\")\n\t\t\tul4onname = ul4onname.substr(0, ul4onname.length-3);\n\t\tul4onname = ul4onname.toLowerCase();\n\t\tconstructor.prototype.type = ul4onname;\n\t\tul4.register(\"de.livinglogic.ul4.\" + ul4onname, constructor);\n\t}","import { ul4 } from './ul4';\n\nlet la = {};\n\n\nla.Base = class Base extends ul4.Proto\n{\n\tconstructor()\n\t{\n\t\tsuper();\n\t}\n\n\tul4ondump(encoder)\n\t{\n\t\tfor (let i = 0; i < this._ul4onattrs.length; ++i)\n\t\t\tencoder.dump(this._dumpUL4ONAttr(this._ul4onattrs[i]));\n\t}\n\n\t_dumpUL4ONAttr(name)\n\t{\n\t\treturn this[name];\n\t}\n\n\tul4onload(decoder)\n\t{\n\t\tlet i = 0;\n\t\tfor (let iter = decoder.loadcontent(); ; ++i)\n\t\t{\n\t\t\tlet iteritem = iter.next();\n\t\t\tif (iteritem.done)\n\t\t\t\tbreak;\n\t\t\tif (i < this._ul4onattrs.length)\n\t\t\t\tthis._loadUL4ONAttr(this._ul4onattrs[i], iteritem.value);\n\t\t}\n\t\tfor (; i < this._ul4onattrs.length; ++i)\n\t\t\tthis._setDefaultUL4ONAttr(this._ul4onattrs[i]);\n\t}\n\n\t_loadUL4ONAttr(name, value)\n\t{\n\t\tthis[name] = value;\n\t}\n\n\t_setDefaultUL4ONAttr(name)\n\t{\n\t\tthis[name] = null;\n\t}\n\n\t__getattr__(name)\n\t{\n\t\tif (this._ul4attrs.has(name))\n\t\t{\n\t\t\tlet value = this[name];\n\t\t\tif (typeof(value) === \"function\")\n\t\t\t{\n\t\t\t\tlet realvalue = value.bind(this);\n\t\t\t\trealvalue._ul4_name = value._ul4_name || value.name;\n\t\t\t\trealvalue._ul4_signature = value._ul4_signature;\n\t\t\t\trealvalue._ul4_needsobject = value._ul4_needsobject;\n\t\t\t\trealvalue._ul4_needscontext = value._ul4_needscontext;\n\t\t\t\treturn realvalue;\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t\tthrow new ul4.AttributeError(this, name);\n\t}\n\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.Handler = class Handler\n{\n\tsave(record)\n\t{\n\t}\n\n\tdelete(record)\n\t{\n\t}\n};\n\nla.Globals = class Globals extends la.Base\n{\n\tconstructor()\n\t{\n\t\tsuper();\n\t\tthis.version = null;\n\t\tthis.platform = null;\n\t\tthis.user = null;\n\t\tthis.maxdbactions = null;\n\t\tthis.maxtemplateruntime = null;\n\t\tthis.flashmessages = null;\n\t\tthis.handler = new la.Handler();\n\t}\n\n\t// distance between two geo coordinates (see https://de.wikipedia.org/wiki/Orthodrome#Genauere_Formel_zur_Abstandsberechnung_auf_der_Erde)\n\tstatic geodist(geo1, geo2)\n\t{\n\t\tlet sqsin = function sqsin(x) {x = Math.sin(x); return x*x};\n\t\tlet sqcos = function sqsos(x) {x = Math.cos(x); return x*x};\n\t\tconst deg2rad = Math.PI/180; // Conversion factor degree -> radians\n\t\tconst radius = 6378.137; // Equatorial radius of earth in km\n\t\tconst flat = 1/298.257223563; // Earth flattening\n\n\t\tconst lat1 = geo1.lat * deg2rad;\n\t\tconst long1 = geo1.long * deg2rad;\n\t\tconst lat2 = geo2.lat * deg2rad;\n\t\tconst long2 = geo2.long * deg2rad;\n\t\tconst F = (lat1 + lat2)/2;\n\t\tconst G = (lat1 - lat2)/2;\n\t\tconst l = (long1 - long2)/2;\n\t\tconst S = sqsin(G) * sqcos(l) + sqcos(F) * sqsin(l);\n\t\tconst C = sqcos(G) * sqcos(l) + sqsin(F) * sqsin(l);\n\t\tconst w = Math.atan(Math.sqrt(S/C));\n\t\tconst D = 2 * w * radius;\n\t\tconst T = Math.sqrt(S*C)/w;\n\t\tconst H1 = (3*T-1)/(2*C);\n\t\tconst H2 = (3*T+1)/(2*S);\n\t\tconst s = D * (1 + flat * H1 * sqsin(F) * sqcos(G) - flat * H2 * sqcos(F) * sqsin(G));\n\t\treturn s;\n\t}\n\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.Globals.prototype._ul4onattrs = [\"version\", \"platform\", \"user\", \"maxdbactions\", \"maxtemplateruntime\", \"flashmessages\"];\nla.Globals.prototype._ul4attrs = ul4._makeset(\"version\", \"platform\", \"user\", \"maxdbactions\", \"maxtemplateruntime\", \"flashmessages\");\n\nla.FlashMessage = class FlashMessage extends la.Base\n{\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.FlashMessage.prototype._ul4onattrs = [\"timestamp\", \"type\", \"title\", \"message\"];\nla.FlashMessage.prototype._ul4attrs = ul4._makeset(\"timestamp\", \"type\", \"title\", \"message\");\n\nla.App = class App extends la.Base\n{\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n\n\tinsert(values={})\n\t{\n\t\tlet record = this.__call__(values);\n\t\tthis.globals.handler.save(this);\n\t\treturn this.globals.Login._insert(this, values);\n\t}\n\n\t__call__(values={})\n\t{\n\t\tlet record = new la.Record(this);\n\t\tif (ul4._ismap(values))\n\t\t{\n\t\t\tfor (let [key, value] of values.entries())\n\t\t\t{\n\t\t\t\tif (!record.fields.has(key))\n\t\t\t\t\tthrow new ul4.ArgumentError(\"update() get an unexpected keyword argument \" + ul4._repr(key));\n\t\t\t\trecord.fields.get(key).value = value;\n\t\t\t}\n\t\t}\n\t\telse if (ul4._isobject(values))\n\t\t{\n\t\t\tfor (let key in values)\n\t\t\t{\n\t\t\t\tif (!record.fields.has(key))\n\t\t\t\t\tthrow new ul4.ArgumentError(\"update() get an unexpected keyword argument \" + ul4._repr(key));\n\t\t\t\trecord.fields.get(key).value = values[key];\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tthrow new ul4.TypeError(\"values must be an object or a Map\");\n\t\treturn record;\n\t}\n\n\t__getattr__(name)\n\t{\n\t\tif (name.startsWith(\"c_\"))\n\t\t{\n\t\t\tif (!this.controls.has(name.substr(2)))\n\t\t\t\tthrow new ul4.AttributeError(this, name);\n\t\t\treturn this.controls.get(name.substr(2));\n\t\t}\n\t\telse\n\t\t\treturn super.__getattr__(name);\n\t}\n};\n\nla.App.prototype._ul4onattrs = [\"id\", \"globals\", \"name\", \"description\", \"language\", \"startlink\", \"iconlarge\", \"iconsmall\", \"createdby\", \"controls\", \"records\", \"recordcount\", \"installation\", \"categories\", \"params\", \"views\", \"datamanagement_identifier\", \"basetable\", \"primarykey\", \"insertprocedure\", \"updateprocedure\", \"deleteprocedure\", \"templates\", \"createdat\", \"updatedat\", \"updatedby\"];\nla.App.prototype._ul4attrs = ul4._makeset(\"id\", \"globals\", \"name\", \"description\", \"language\", \"startlink\", \"iconlarge\", \"iconsmall\", \"createdat\", \"createdby\", \"updatedat\", \"updatedby\", \"controls\", \"records\", \"recordcount\", \"installation\", \"categories\", \"params\", \"views\", \"datamanagement_identifier\", \"insert\");\nul4.expose(la.App.prototype.__call__, [\"**values\"], {\"needsobject\": true});\nul4.expose(la.App.prototype.insert, [\"**values\"], {\"needsobject\": true});\n\nla.View = class View extends la.Base\n{\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.View.prototype._ul4onattrs = [\"id\", \"name\", \"app\", \"order\", \"width\", \"height\", \"start\", \"end\"];\nla.View.prototype._ul4attrs = ul4._makeset(\"id\", \"name\", \"app\", \"order\", \"width\", \"height\", \"start\", \"end\");\n\nla.DataSourceData = class DataSourceData extends la.Base\n{\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.DataSourceData.prototype._ul4onattrs = [\"id\", \"identifier\", \"app\", \"apps\"];\nla.DataSourceData.prototype._ul4attrs = ul4._makeset(\"id\", \"identifier\", \"app\", \"apps\");\n\nla.Record = class Record extends la.Base\n{\n\tconstructor(app)\n\t{\n\t\tsuper();\n\t\tthis.id = null;\n\t\tthis.app = app;\n\t\tthis.createdat = null;\n\t\tthis.createdby = null;\n\t\tthis.updatedat = null;\n\t\tthis.updatedby = null;\n\t\tthis.updatecount = 0;\n\t\tthis._sparsevalues = new Map();\n\t\tthis._values = null;\n\t\tthis._fields = null;\n\t\tthis.children = new Map();\n\t\tthis.attachments = null;\n\t\tthis.errors = [];\n\t\tthis._is_deleted = false;\n\t}\n\n\t\n\n\t__repr__()\n\t{\n\t\tlet v = [\"\")\n\t\treturn v.join(\"\");\n\t}\n\n\tget values()\n\t{\n\t\tif (this._values === null)\n\t\t{\n\t\t\tthis._values = ul4._havemap ? new Map() : {};\n\t\t\tfor (let [identifier, control] of this.app.controls.entries())\n\t\t\t{\n\t\t\t\tlet fieldvalue = this._sparsevalues.get(identifier);\n\t\t\t\tif (typeof(fieldvalue) === \"undefined\")\n\t\t\t\t\tfieldvalue = null;\n\t\t\t\tthis._values.set(identifier, fieldvalue);\n\t\t\t}\n\t\t}\n\t\treturn this._values;\n\t}\n\n\tget fields()\n\t{\n\t\tif (this._fields === null)\n\t\t{\n\t\t\tthis._fields = ul4._havemap ? new Map() : {};\n\t\t\tfor (let [identifier, value] of this.values.entries())\n\t\t\t{\n\t\t\t\tlet field = new la.Field(this.app.controls.get(identifier), this, value);\n\t\t\t\tthis._fields.set(identifier, field);\n\t\t\t}\n\t\t}\n\t\treturn this._fields;\n\t}\n\n\tis_dirty()\n\t{\n\t\tif (this.id === null)\n\t\t\treturn true;\n\t\tfor (let field of this.fields.values())\n\t\t{\n\t\t\tif (field.is_dirty())\n\t\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\thas_errors()\n\t{\n\t\tif (this.errors.length !== 0)\n\t\t\treturn true;\n\t\tfor (let field of this.fields.values())\n\t\t{\n\t\t\tif (field.has_errors())\n\t\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tdelete()\n\t{\n\t\treturn this.app.globals.handler.delete(this);\n\t}\n\n\tsave()\n\t{\n\t\tthis.app.globals.handler.save(this);\n\t}\n\n\tupdate(values={})\n\t{\n\t\tif (ul4._ismap(values))\n\t\t{\n\t\t\tfor (let [key, value] of values.entries())\n\t\t\t{\n\t\t\t\tif (!this.fields.has(key))\n\t\t\t\t\tthrow new ul4.ArgumentError(\"update() get an unexpected keyword argument \" + ul4._repr(key));\n\t\t\t\tthis.fields.get(key).value = value;\n\t\t\t}\n\t\t}\n\t\telse if (ul4._isobject(values))\n\t\t{\n\t\t\tfor (let key in values)\n\t\t\t{\n\t\t\t\tif (!this.fields.has(key))\n\t\t\t\t\tthrow new ul4.ArgumentError(\"update() get an unexpected keyword argument \" + ul4._repr(key));\n\t\t\t\tthis.fields.get(key).value = values[key];\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\tthrow new ul4.TypeError(\"values must be an object or a Map\");\n\n\t\tthis.app.globals.handler.save(this);\n\t\treturn this.app.globals.Login._update(this, values);\n\t}\n\n\tsearch(search)\n\t{\n\t\tfor (let identifier in search)\n\t\t{\n\t\t\tlet fieldsearch = search[identifier];\n\t\t\tif (ul4._bool(fieldsearch))\n\t\t\t{\n\t\t\t\tif (!this.fields.get(identifier).search(fieldsearch))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t_dumpUL4ONAttr(name)\n\t{\n\t\tif (name === \"values\")\n\t\t\treturn this._sparsevalues;\n\t\telse\n\t\t\treturn this[name];\n\t}\n\n\t_loadUL4ONAttr(name, value)\n\t{\n\t\tif (name === \"values\")\n\t\t{\n\t\t\tthis._sparsevalues = value;\n\t\t\tthis._values = null;\n\t\t\tthis._fields = null;\n\t\t}\n\t\telse\n\t\t\tthis[name] = value;\n\t}\n\n\t__getattr__(name)\n\t{\n\t\tif (name.startsWith(\"c_\"))\n\t\t\treturn this.children.get(name.substr(2))\n\t\telse if (name.startsWith(\"f_\"))\n\t\t\treturn this.fields.get(name.substr(2))\n\t\telse if (name.startsWith(\"v_\"))\n\t\t\treturn this.values.get(name.substr(2))\n\t\telse\n\t\t\treturn this[name];\n\t}\n\n\t__setattr__(name, value)\n\t{\n\t\tif (name.startsWith(\"c_\"))\n\t\t\tthis.children[name.substr(2)] = value;\n\t\telse if (name.startsWith(\"v_\"))\n\t\t\tthis.fields.get(name.substr(2)).value = value;\n\t\telse\n\t\t\tthrow new ul4.AttributeError(this, name);\n\t}\n};\n\nla.Record.prototype._ul4onattrs = [\"id\", \"app\", \"createdat\", \"createdby\", \"updatedat\", \"updatedby\", \"updatecount\", \"values\", \"attachments\", \"children\"];\nla.Record.prototype._ul4attrs = ul4._makeset(\"id\", \"app\", \"createdat\", \"createdby\", \"updatedat\", \"updatedby\", \"updatecount\", \"values\", \"attachments\", \"children\");\nul4.expose(la.Record.prototype.is_dirty, []);\nul4.expose(la.Record.prototype.has_errors, []);\nul4.expose(la.Record.prototype.delete, []);\nul4.expose(la.Record.prototype.save, []);\nul4.expose(la.Record.prototype.update, [\"**values\"], {\"needsobject\": true});\n\nla.Control = class Control extends la.Base\n{\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n\n\t_logsearch(value, search)\n\t{\n\t\t//console.log(\"Searching for \" + ul4._repr(search.value) + \" in \" + ul4._repr(this) + \" with operator \" + search.operator + \" in value \" + ul4._repr(value));\n\t}\n\n\n\tasjson(value) {\n\t\treturn value;\n\t}\n\n\t// base implemntation, always returns ``false`` (i.e. \"not found\")\n\t// ``value`` is the value of the field\n\t// ``search`` is an object with information what we're searching for\n\t// keys in ``search`` are: ``operator`` (and ``value`` (if required by the operator))\n\tsearch(value, search)\n\t{\n\t\treturn false;\n\t}\n};\n\nla.Control.prototype.type = null;\nla.Control.prototype.subtype = null;\nla.Control.prototype._ul4onattrs = [\"id\", \"identifier\", \"field\", \"app\", \"label\", \"priority\", \"order\", \"default\", \"ininsertprocedure\", \"inupdateprocedure\"];\nla.Control.prototype._ul4attrs = ul4._makeset(\"id\", \"identifier\", \"field\", \"app\", \"label\", \"priority\", \"order\", \"default\", \"ininsertprocedure\", \"inupdateprocedure\");\n\nla.BoolControl = class BoolControl extends la.Control\n{\n\t// ``search`` must by ``null``, ``false`` or ``true``\n\tsearch(value, search)\n\t{\n\t\tthis._logsearch(value, search);\n\t\tif (search.operator === \"equals\")\n\t\t\treturn search.value === value;\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nla.BoolControl.prototype.type = \"bool\";\n\nla.IntControl = class IntControl extends la.Control\n{\n\t// ``search.value`` must by ``null`` or an integer\n\tsearch(value, search)\n\t{\n\t\tthis._logsearch(value, search);\n\t\tif (search.operator === \"equals\")\n\t\t\treturn search.value === value;\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nla.IntControl.prototype.type = \"int\";\n\nla.NumberControl = class NumberControl extends la.Control\n{\n\t// ``search.value`` must by ``null`` or an integer\n\tsearch(value, search)\n\t{\n\t\tthis._logsearch(value, search);\n\t\tif (search.operator === \"equals\")\n\t\t\treturn search.value === value;\n\t\telse if (search.operator === \"range\")\n\t\t{\n\t\t\tif (value === null)\n\t\t\t\treturn false;\n\t\t\treturn (search.minvalue === null || search.minvalue <= value) && (search.maxvalue === null || value < search.maxvalue);\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nla.NumberControl.prototype.type = \"number\";\n\nla.StringControl = class StringControl extends la.Control\n{\n\n\tasjson(value) {\n\t\treturn value;\n\t}\n\n\tsearch(value, search)\n\t{\n\t\tthis._logsearch(value, search);\n\t\tif (search.operator === \"equals\")\n\t\t\treturn search.value === value;\n\t\telse if (search.operator === \"contains\")\n\t\t{\n\t\t\tif (search.value === null || value === null)\n\t\t\t\treturn search.value === value;\n\t\t\telse\n\t\t\t\treturn value.toLowerCase().indexOf(search.value.toLowerCase()) >= 0;\n\t\t}\n\t}\n};\n\nla.StringControl.prototype.type = \"string\";\n\nla.TextControl = class TextControl extends la.StringControl\n{\n};\n\nla.TextControl.prototype.subtype = \"text\";\n\nla.EmailControl = class EmailControl extends la.StringControl\n{\n};\n\nla.EmailControl.prototype.subtype = \"email\";\n\nla.URLControl = class URLControl extends la.StringControl\n{\n};\n\nla.URLControl.prototype.subtype = \"url\";\n\nla.TelControl = class TelControl extends la.StringControl\n{\n};\n\nla.TelControl.prototype.subtype = \"tel\";\n\nla.PasswordControl = class PasswordControl extends la.StringControl\n{\n};\n\nla.PasswordControl.prototype.subtype = \"password\";\n\nla.TextAreaControl = class TextAreaControl extends la.StringControl\n{\n};\n\nla.TextAreaControl.prototype.subtype = \"textarea\";\nla.TextAreaControl.prototype._ul4onattrs = la.StringControl.prototype._ul4onattrs.concat([\"encrypted\"]);\nla.TextAreaControl.prototype._ul4attrs = ul4._makeset(...la.StringControl.prototype._ul4attrs, \"encrypted\");\n\nla.DateControl = class DateControl extends la.Control\n{\n\tformatstring(language)\n\t{\n\t\tlanguage = language || this.app.language;\n\n\t\tif (language === \"de\")\n\t\t\treturn \"%d.%m.%Y\";\n\t\telse\n\t\t\treturn \"%m/%d/%Y\";\n\t}\n\n\tasjson(value) {\n\t\treturn value;\n\t}\n\n\t// searchvalue must be ``null``, a ``Date`` object or a string\n\tsearch(value, search)\n\t{\n\t\tthis._logsearch(value, search);\n\n\t\tlet searchvalue = search.value;\n\t\tif (Object.prototype.toString.call(searchvalue) == \"[object Date]\")\n\t\t\tsearchvalue = ul4._format(searchvalue, this.formatstring(), this.app.language);\n\t\tif (value !== null)\n\t\t\tvalue = ul4._format(value, this.formatstring(), this.app.language);\n\n\t\tif (search.operator === \"equals\")\n\t\t\treturn searchvalue === value;\n\t\telse if (search.operator === \"contains\")\n\t\t{\n\t\t\tif (searchvalue === null || value === null)\n\t\t\t\treturn searchvalue === value;\n\t\t\telse\n\t\t\t\treturn value.toLowerCase().indexOf(searchvalue.toLowerCase()) >= 0;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nla.DateControl.prototype.type = \"date\";\nla.DateControl.prototype.subtype = \"date\";\n\nla.DatetimeMinuteControl = class DatetimeMinuteControl extends la.DateControl\n{\n\tformatstring(language)\n\t{\n\t\tlanguage = language || this.app.language;\n\n\t\tif (language === \"de\")\n\t\t\treturn \"%d.%m.%Y %H:%M\";\n\t\telse\n\t\t\treturn \"%m/%d/%Y %H:%M\";\n\t}\n};\n\nla.DatetimeMinuteControl.prototype.subtype = \"datetimeminute\";\n\nla.DatetimeSecondControl = class DatetimeSecondControl extends la.DateControl\n{\n\tformatstring(language)\n\t{\n\t\tlanguage = language || this.app.language;\n\n\t\tif (language === \"de\")\n\t\t\treturn \"%d.%m.%Y %H:%M:%S\";\n\t\telse\n\t\t\treturn \"%m/%d/%Y %H:%M:%S\";\n\t}\n};\n\nla.DatetimeSecondControl.prototype.subtype = \"datetimesecond\";\n\nla.LookupControl = class LookupControl extends la.Control\n{\n\t// ``search.value`` must be ``null`` or a ``LookupItem`` key\n\tsearch(value, search)\n\t{\n\t\tif (search.operator === \"equals\")\n\t\t{\n\t\t\tif (value === null)\n\t\t\t\treturn search.value === null;\n\t\t\telse\n\t\t\t\treturn value.key === search.value;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nla.LookupControl.prototype.type = \"lookup\";\nla.LookupControl.prototype._ul4onattrs = la.Control.prototype._ul4onattrs.concat([\"lookupdata\"]);\nla.LookupControl.prototype._ul4attrs = ul4._makeset(...la.Control.prototype._ul4attrs, \"lookupdata\");\n\nla.LookupSelectControl = class LookupSelectControl extends la.LookupControl\n{\n};\n\nla.LookupSelectControl.prototype.subtype = \"select\";\n\nla.LookupRadioControl = class LookupRadioControl extends la.LookupControl\n{\n};\n\nla.LookupRadioControl.prototype.subtype = \"radio\";\n\nla.LookupChoiceControl = class LookupChoiceControl extends la.LookupControl\n{\n};\n\nla.LookupChoiceControl.prototype.subtype = \"choice\";\n\nla.AppLookupControl = class AppLookupControl extends la.Control\n{\n\t// ``search.value`` must be an object containing the search criteria for the referenced record\n\tsearch(value, search)\n\t{\n\t\tif (value === null || search.value === null)\n\t\t\treturn value === search.value;\n\t\telse\n\t\t\treturn value.search(search);\n\t}\n};\n\nla.AppLookupControl.prototype.type = \"applookup\";\nla.AppLookupControl.prototype._ul4onattrs = la.Control.prototype._ul4onattrs.concat([\"lookupapp\", \"lookupcontrols\"]);\nla.AppLookupControl.prototype._ul4attrs = ul4._makeset(...la.Control.prototype._ul4attrs, \"lookupapp\", \"lookupcontrols\");\n\nla.AppLookupSelectControl = class AppLookupSelectControl extends la.AppLookupControl\n{\n};\n\nla.AppLookupSelectControl.prototype.subtype = \"select\";\n\nla.AppLookupRadioControl = class AppLookupRadioControl extends la.AppLookupControl\n{\n};\n\nla.AppLookupRadioControl.prototype.subtype = \"radio\";\n\nla.AppLookupChoiceControl = class AppLookupChoiceControl extends la.AppLookupControl\n{\n};\n\nla.AppLookupChoiceControl.prototype.subtype = \"choice\";\n\nla.MultipleLookupControl = class MultipleLookupControl extends la.LookupControl\n{\n\t// search.value must be ``null`` or a ``LookupItem`` key\n\tsearch(value, search)\n\t{\n\t\tif (search.operator === \"equals\")\n\t\t{\n\t\t\tfor (let item of value)\n\t\t\t{\n\t\t\t\tif (item.key === search.value)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nla.MultipleLookupControl.prototype.subtype = \"multiplelookup\";\n\nla.MultipleLookupSelectControl = class MultipleLookupSelectControl extends la.MultipleLookupControl\n{\n};\n\nla.MultipleLookupSelectControl.prototype.subtype = \"select\";\n\nla.MultipleLookupCheckboxControl = class MultipleLookupCheckboxControl extends la.MultipleLookupControl\n{\n};\n\nla.MultipleLookupCheckboxControl.prototype.subtype = \"checkbox\";\n\nla.MultipleLookupChoiceControl = class MultipleLookupChoiceControl extends la.MultipleLookupControl\n{\n};\n\nla.MultipleLookupChoiceControl.prototype.subtype = \"choice\";\n\nla.MultipleAppLookupControl = class MultipleAppLookupControl extends la.AppLookupControl\n{\n\t// ``search.value`` must be an object containing the search criteria for the referenced record\n\tsearch(value, search)\n\t{\n\t\tif (search.operator === \"equals\")\n\t\t{\n\t\t\tif (search.value === null)\n\t\t\t\treturn value.length === 0;\n\t\t\telse\n\t\t\t{\n\t\t\t\tfor (let item of value)\n\t\t\t\t{\n\t\t\t\t\tif (item.search(search.value))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n};\n\nla.MultipleAppLookupControl.prototype.type = \"multipleapplookup\";\n\nla.MultipleAppLookupSelectControl = class MultipleAppLookupSelectControl extends la.MultipleAppLookupControl\n{\n};\n\nla.MultipleAppLookupSelectControl.prototype.subtype = \"select\";\n\nla.MultipleAppLookupCheckboxControl = class MultipleAppLookupCheckboxControl extends la.MultipleAppLookupControl\n{\n};\n\nla.MultipleAppLookupCheckboxControl.prototype.subtype = \"checkbox\";\n\nla.MultipleAppLookupChoiceControl = class MultipleAppLookupChoiceControl extends la.MultipleAppLookupControl\n{\n};\n\nla.MultipleAppLookupChoiceControl.prototype.subtype = \"choice\";\n\nla.GeoControl = class GeoControl extends la.Control\n{\n\tasjson (value) {\n\t\tif (value instanceof la.Geo)\n\t\t\tvalue = `${value.lat}, ${value.long}, ${value.info}`;\n\t\treturn value;\n\t}\n};\n\nla.GeoControl.prototype.type = \"geo\";\n\nla.FileControl = class FileControl extends la.Control\n{\n};\n\nla.FileControl.prototype.type = \"file\";\n\nla.ButtonControl = class ButtonControl extends la.Control\n{\n};\n\nla.ButtonControl.prototype.type = \"button\";\n\nla.Field = class Field extends la.Base\n{\n\tconstructor(control, record, value)\n\t{\n\t\tsuper();\n\t\tthis.control = control;\n\t\tthis.record = record;\n\t\tthis._value = value;\n\t\tthis._dirty = false;\n\t\tthis.errors = [];\n\t}\n\n\tget value()\n\t{\n\t\treturn this._value;\n\t}\n\n\tset value(value)\n\t{\n\t\tlet oldvalue = this._value;\n\n\t\tif (ul4._ne(oldvalue, value))\n\t\t{\n\t\t\tthis.record.values.set(this.control.identifier, value);\n\t\t\tthis._value = value;\n\t\t\tthis._dirty = true;\n\t\t}\n\t}\n\n\tis_empty()\n\t{\n\t\treturn this._value === null || (ul4._islist(this._value) && this._value.length === 0);\n\t}\n\n\tis_dirty()\n\t{\n\t\treturn this._dirty;\n\t}\n\n\thas_errors()\n\t{\n\t\treturn this.errors.length !== 0;\n\t}\n\n\tsearch(searchvalue)\n\t{\n\t\treturn this.control.search(this.value, searchvalue);\n\t}\n\n\t__repr__()\n\t{\n\t\tlet s = \"\"\n\t\treturn s;\n\t}\n};\n\nla.LookupItem = class LookupItem extends la.Base\n{\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.LookupItem.prototype._ul4onattrs = [\"key\", \"label\"];\nla.LookupItem.prototype._ul4attrs = ul4._makeset(\"key\", \"label\");\n\nla.User = class User extends la.Base\n{\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.User.prototype._ul4onattrs = [\"_id\", \"id\", \"gender\", \"firstname\", \"surname\", \"initials\", \"email\", \"language\", \"avatarsmall\", \"avatarlarge\", \"keyviews\"];\nla.User.prototype._ul4attrs = ul4._makeset(\"_id\", \"id\", \"gender\", \"firstname\", \"surname\", \"initials\", \"email\", \"language\", \"avatarsmall\", \"avatarlarge\", \"keyviews\");\n\nla.File = class File extends la.Base\n{\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.File.prototype._ul4onattrs = [\"id\", \"url\", \"filename\", \"mimetype\", \"width\", \"height\", \"internalid\", \"createdat\", \"size\"];\nla.File.prototype._ul4attrs = ul4._makeset(\"id\", \"url\", \"filename\", \"mimetype\", \"width\", \"height\", \"size\", \"createdat\");\n\nla.Geo = class Geo extends la.Base\n{\n\tconstructor(lat, long, info)\n\t{\n\t\tsuper();\n\t\tthis.lat = lat;\n\t\tthis.long = long;\n\t\tthis.info = info;\n\t}\n\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.Geo.prototype._ul4onattrs = [\"lat\", \"long\", \"info\"];\nla.Geo.prototype._ul4attrs = ul4._makeset(\"lat\", \"long\", \"info\");\n\nla.Attachment = class Attachment extends la.Base\n{\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.Attachment.prototype._ul4onattrs = [\"id\", \"record\", \"label\", \"active\"];\nla.Attachment.prototype._ul4attrs = ul4._makeset(\"id\", \"record\", \"label\", \"active\");\n\nla.NoteAttachment = class NoteAttachment extends la.Attachment\n{\n};\n\nla.NoteAttachment.prototype.type = \"noteattachment\";\nla.NoteAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat([\"value\"]);\nla.NoteAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, \"value\");\n\nla.URLAttachment = class URLAttachment extends la.Attachment\n{\n};\n\nla.URLAttachment.prototype.type = \"urlattachment\";\nla.URLAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat([\"value\"]);\nla.URLAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, \"value\");\n\nla.FileAttachment = class FileAttachment extends la.Attachment\n{\n};\n\nla.FileAttachment.prototype.type = \"fileattachment\";\nla.FileAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat([\"value\"]);\nla.FileAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, \"value\");\n\nla.ImageAttachment = class ImageAttachment extends la.Attachment\n{\n};\n\nla.ImageAttachment.prototype.type = \"imageattachment\";\nla.ImageAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat([\"original\", \"thumb\", \"small\", \"medium\", \"large\"]);\nla.ImageAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, \"original\", \"thumb\", \"small\", \"medium\", \"large\");\n\nla.JSONAttachment = class JSONAttachment extends la.Attachment\n{\n\t_dumpUL4ONAttr(name)\n\t{\n\t\tif (name === \"value\")\n\t\t\treturn ul4._asjson(this.value);\n\t\telse\n\t\t\treturn this[name];\n\t}\n\n\t_loadUL4ONAttr(name, value)\n\t{\n\t\tif (name === \"value\")\n\t\t\tthis.value = ul4._fromjson(value);\n\t\telse\n\t\t\tthis[name] = value\n\t}\n};\n\nla.JSONAttachment.prototype.type = \"jsonattachment\";\nla.JSONAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat([\"value\"]);\nla.JSONAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, \"value\");\n\nla.Installation = class Installation extends la.Base\n{\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.Installation.prototype._ul4onattrs = [\"id\", \"name\"];\nla.Installation.prototype._ul4attrs = ul4._makeset(\"id\", \"name\");\n\nla.Category = class Category extends la.Base\n{\n\t__repr__()\n\t{\n\t\tlet v = [];\n\t\tlet category = this;\n\t\twhile (category !== null)\n\t\t{\n\t\t\tv.splice(0, 0, category.identifier);\n\t\t\tcategory = category.parent;\n\t\t}\n\t\treturn \"\";\n\t}\n};\n\nla.Category.prototype._ul4onattrs = [\"id\", \"identifier\", \"name\", \"order\", \"parent\", \"children\", \"apps\"];\nla.Category.prototype._ul4attrs = ul4._makeset(\"id\", \"identifier\", \"name\", \"order\", \"parent\", \"children\", \"apps\");\n\nla.KeyView = class KeyView extends la.Base\n{\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.KeyView.prototype._ul4onattrs = [\"id\", \"identifier\", \"name\", \"key\", \"user\"];\nla.KeyView.prototype._ul4attrs = ul4._makeset(\"id\", \"identifier\", \"name\", \"key\", \"user\");\n\nla.AppParameter = class AppParameter extends la.Base\n{\n\t__repr__()\n\t{\n\t\treturn \"\";\n\t}\n};\n\nla.AppParameter.prototype._ul4onattrs = [\"id\", \"app\", \"identifier\", \"description\", \"value\"];\nla.AppParameter.prototype._ul4attrs = ul4._makeset(\"id\", \"app\", \"identifier\", \"description\", \"value\");\n\nlet classes = [\n\tla.Globals,\n\tla.App,\n\tla.View,\n\tla.DataSourceData,\n\tla.Record,\n\tla.BoolControl,\n\tla.IntControl,\n\tla.NumberControl,\n\tla.TextControl,\n\tla.EmailControl,\n\tla.URLControl,\n\tla.TelControl,\n\tla.PasswordControl,\n\tla.TextAreaControl,\n\tla.DateControl,\n\tla.DatetimeMinuteControl,\n\tla.DatetimeSecondControl,\n\tla.LookupControl,\n\tla.LookupSelectControl,\n\tla.LookupRadioControl,\n\tla.LookupChoiceControl,\n\tla.AppLookupControl,\n\tla.AppLookupSelectControl,\n\tla.AppLookupRadioControl,\n\tla.AppLookupChoiceControl,\n\tla.MultipleLookupControl,\n\tla.MultipleLookupSelectControl,\n\tla.MultipleLookupCheckboxControl,\n\tla.MultipleLookupChoiceControl,\n\tla.MultipleAppLookupControl,\n\tla.MultipleAppLookupSelectControl,\n\tla.MultipleAppLookupCheckboxControl,\n\tla.MultipleAppLookupChoiceControl,\n\tla.GeoControl,\n\tla.FileControl,\n\tla.ButtonControl,\n\tla.Field,\n\tla.LookupItem,\n\tla.User,\n\tla.File,\n\tla.Geo,\n\tla.NoteAttachment,\n\tla.URLAttachment,\n\tla.FileAttachment,\n\tla.ImageAttachment,\n\tla.JSONAttachment,\n\tla.Installation,\n\tla.Category,\n\tla.KeyView,\n\tla.AppParameter\n];\n\nfor (let constructor of classes)\n{\n\t// Register under the old name\n\tul4.register(\"de.livingapps.appdd.\" + constructor.name.toLowerCase(), constructor);\n\t// Register under the new name\n\tul4.register(\"de.livinglogic.livingapi.\" + constructor.name.toLowerCase(), constructor);\n}\nexport default la;","import axios, { AxiosResponse } from 'axios';\n///@ts-ignore\nimport livingApi from './modules/livingapi';\n///@ts-ignore\nimport { ul4 } from './modules/ul4';\nimport * as https from 'https';\n\nexport type Auth_Token = string;\nexport type LivingApi = any;\nexport type LAPIRecord = any;\nlet commonjs = (typeof module === 'object' && module.exports);\nexport interface LivingSDKOptions {\n\turl?: string;\n\tloginRequired?: boolean;\n}\n\nexport class LivingSDK {\n\tprivate _password: string;\n\tprivate _userName: string;\n\tprivate _options: LivingSDKOptions\n\tprivate hostName: string;\n\tprivate session: Promise;\n\tconstructor(options: LivingSDKOptions = {}, username?: string, password?: string) {\n\t\t/** @type {String} */\n\t\tthis._password = password || '';\n\t\t/** @type {String} */\n\t\tthis._userName = username || '';\n\t\t/** @type {Object} */\n\t\tthis._options = {\n\t\t\t/** @type {String} */\n\t\t\turl: options.url || 'https://my.living-apps.de',\n\t\t\t/** @type {Boolean} */\n\t\t\tloginRequired: options.loginRequired !== undefined ? options.loginRequired : true\n\t\t};\n\t\tthis._options.url = this._options.url.lastIndexOf('/') === this._options.url.length - 1 ? this._options.url : `${this._options.url}/`;\n\t\tthis.hostName = this._options.url.split('//')[1].substr(0, this._options.url.split('//')[1].length - 1);\n\t\tif (this._options.loginRequired && !this._userName) {\n\t\t\tthrow new Error('[LivingSDK] You want to login without a username')\n\t\t}\n\t\tthis.session = this.login();\n\t}\n\n\t/**\n\t * get token for Session\n\t * @return {Promise.}\n\t */\n\tlogin(): Promise {\n\t\tif (!this._options.loginRequired) {\n\t\t\treturn Promise.resolve(undefined);\n\t\t}\n\t\tlet url = `https://${this.hostName}/gateway/login`;\n\t\treturn axios.post(url, {\n\t\t\tusername: this._userName,\n\t\t\tpassword: this._password\n\t\t}, {\n\t\t\t\thttpsAgent: commonjs ? new https.Agent({\n\t\t\t\t\tecdhCurve: 'auto'\n\t\t\t\t}) : undefined,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\"\n\t\t\t\t}\n\t\t\t})\n\t\t\t.then((a: any) => a.data.auth_token);\n\t}\n\n\tget(appId: string, templateName?: string): Promise {\n\t\treturn this.session.then((auth_token: Auth_Token | undefined) => {\n\t\t\treturn axios.get(`https://${this.hostName}/gateway/apps/${appId}${templateName !== undefined ? '?template=' + templateName : ''}`,\n\t\t\t\t{\n\t\t\t\t\thttpsAgent: commonjs ? new https.Agent({\n\t\t\t\t\t\tecdhCurve: 'auto'\n\t\t\t\t\t}) : undefined,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'X-La-Auth-Token': auth_token !== undefined ? auth_token : '',\n\t\t\t\t\t\tAccept: 'application/la-ul4on'\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.then((res: AxiosResponse) => {\n\t\t\t\t\tlet dump: any;\n\t\t\t\t\tdump = ul4.loads(res.data);\n\t\t\t\t\tdump.get('globals').Login = this;\n\t\t\t\t\treturn dump;\n\t\t\t\t});\n\t\t});\n\t}\n\n\t_insert(app: any, values: any): Promise {\n\t\treturn this.session.then((auth_token) => {\n\n\t\t\tlet fields: any = {};\n\n\t\t\tfor (let ident in values) {\n\t\t\t\tif (!app.controls.has(ident)) {\n\t\t\t\t\tthrow new Error(`insert() got an unexpected keyword argument ${ident}`);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tfields[ident] = app.controls.get(ident).asjson(values[ident]);\n\t\t\t}\n\t\t\tlet data: any = {}; {\n\t\t\t}\n\t\t\tdata.id = app.id; \n\t\t\tdata.data = [{ 'fields': fields }];\n\t\t\treturn axios.post(`https://${this.hostName}/gateway/v1/appdd/${app.id}.json`, {\n\t\t\t\tappdd: data\n\t\t\t}, {\n\t\t\t\t\thttpsAgent: commonjs ? new https.Agent({\n\t\t\t\t\t\tecdhCurve: 'auto'\n\t\t\t\t\t}) : undefined,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'X-La-Auth-Token': auth_token !== undefined ? auth_token : '',\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.then((res: AxiosResponse) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tHTTPstatusCode: res.status,\n\t\t\t\t\t\trecordid: res.data.id,\n\t\t\t\t\t\tRecord: new livingApi.Record({\n\t\t\t\t\t\t\tid: res.data.id,\n\t\t\t\t\t\t\tcreatedat: new Date(Date.now()),\n\t\t\t\t\t\t\tupdatedat: null,\n\t\t\t\t\t\t\tupdatedby: null,\n\t\t\t\t\t\t\tupdatecount: 0\n\t\t\t\t\t\t})\n\t\t\t\t\t};\n\t\t\t\t})\n\t\t})\n\n\t}\n\n\t_update(record: LAPIRecord, values: any) {\n\t\treturn this.session.then((auth_token: Auth_Token | undefined) => {\n\t\t\tlet fields: any = {};\n\t\t\tlet app = record.app;\n\t\t\tfor (let ident in values) {\n\t\t\t\tif (!app.controls.has(ident)) {\n\t\t\t\t\tthrow new Error(`update() got an unexpected keyword argument ${ident}`);\n\t\t\t\t}\n\t\t\t\tfields[ident] = values[ident];\n\t\t\t}\n\t\t\tlet data: any = {};\n\t\t\tdata.id = app.id;\n\t\t\tdata.data = [{ 'id': record.id, 'fields': fields }];\n\t\t\tconsole.log(`https://${this.hostName}/gateway/v1/appdd/${app.id}.json`);\n\t\t\treturn axios.post(`https://${this.hostName}/gateway/v1/appdd/${app.id}.json`, {\n\t\t\t\tappdd: data\n\t\t\t}, {\n\t\t\t\t\thttpsAgent: commonjs ? new https.Agent({\n\t\t\t\t\t\tecdhCurve: 'auto'\n\t\t\t\t\t}) : undefined,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'X-La-Auth-Token': auth_token !== undefined ? auth_token : '',\n\t\t\t\t\t\t'Content-Type': 'application/json'\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.then((res: AxiosResponse) => {\n\t\t\t\t\tlet body = res.data;\n\t\t\t\t\tfor (let ident in values)\n\t\t\t\t\t\trecord.fields.get(ident).value = values[ident];\n\t\t\t\t\tlet returnObj = {\n\t\t\t\t\t\tHTTPstatusCode: res.status,\n\t\t\t\t\t\trecordid: body.id,\n\t\t\t\t\t\tRecord: record\n\t\t\t\t\t};\n\t\t\t\t\treturn returnObj;\n\t\t\t\t});\n\t\t});\n\t}\n\n\t_delete(record: LAPIRecord) {\n\t\tlet app = record.app;\n\t\treturn this.session.then((auth_token: Auth_Token | undefined) => {\n\t\t\treturn axios.delete(`https://${this.hostName}/gateway/v1/appdd/${app.id}/${record.id}.json`, {\n\t\t\t\thttpsAgent: commonjs ? new https.Agent({\n\t\t\t\t\tecdhCurve: 'auto'\n\t\t\t\t}) : undefined,\n\t\t\t\theaders: {\n\t\t\t\t\t'X-La-Auth-Token': auth_token !== undefined ? auth_token : '',\n\t\t\t\t}\n\t\t\n\t\t\t})\n\t\t})\n\t}\n}\n\t\nexport default LivingSDK;"],"names":["ul4","iscommon","module","exports","version","_registry","_havemap","Map","prototype","forEach","_havemapconstructor","size","error","_haveset","Set","_havesetconstructor","_makemap","map","i","arguments","length","key","value","set","_setmap","__proto__","_emptymap","_getmap","get","_emptyset","_Set","_makeset","add","register","name","f","ul4onname","dumps","obj","indent","encoder","Encoder","dump","finish","loads","data","registry","Decoder","load","_level","_strings2index","_ids2index","_backrefs","line","this","push","oldindent","join","_line","type","Math","round","index","_str_repr","replace","_iscolor","r","g","b","a","_isdate","year","month","day","_isdatetime","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","getMilliseconds","_istimedelta","days","seconds","microseconds","_ismonthdelta","months","slice","start","stop","ul4ondump","__id__","_islist","_ismap","_isdict","_isset","ValueError","_repr","pos","backrefs","stack","charAt","re_white","c","match","result","substring","re_digits","readcharoreof","parseFloat","isNaN","oldpos","escapechar","chars","read","codepoint","parseInt","String","fromCharCode","typecode","readblackchar","readnumber","readchar","delimiter","c2","_readescape","Color","_r","_g","_b","_a","Date","setFullYear","setDate","setMonth","setHours","setMinutes","setSeconds","setMilliseconds","TimeDelta","_days","_seconds","_microseconds","MonthDelta","_months","backup","pop","_beginfakeloading","constructor","_endfakeloading","ul4onload","self","next","done","_rvalidchars","_rvalidescape","_rvalidtokens","_rvalidbraces","_inherit","baseobj","attrs","Object","assign","create","_map2object","newobj","TypeError","_bound","upper","_stacktrace","exc","output","Exception","toString","context","_internal_call","functioncontext","signature","needscontext","needsobject","args","kwargs","finalargs","ArgumentError","bindObject","bindArray","unshift","apply","_callfunction","_ul4_name","_ul4_signature","_ul4_needsobject","_ul4_needscontext","_callobject","_ul4_callsignature","_ul4_callneedsobject","_ul4_callneedscontext","__call__","_callrender","_ul4_rendersignature","_ul4_renderneedsobject","_ul4_renderneedscontext","__render__","_call","_type","_unpackvar","lvalue","newvalue","iter","_iter","item","concat","_formatsource","out","finalout","level","needlf","part","j","_eq","obj1","obj2","numbertypes","__eq__","indexOf","getTime","_isobject","hasOwnProperty","has","_ne","__ne__","_unorderable","operator","_cmp","v1","v2","res","_isul4set","in1only","in2only","_lt","__lt__","items","_le","__le__","_gt","__gt__","_ge","__ge__","_isiter","__iter__","keys","values","str","ascii","squote","dquote","quote","code","charCodeAt","escape","test","_lpad","_date_repr","_date","_datetime_repr","hour","minute","second","ms","_map_repr","v","_repr_internal","_list_repr","_set_repr","_object_repr","_typeof","__repr__","_ascii","_date_str","_datetime_str","_str","__str__","_bool","__bool__","_int","base","_isint","floor","_float","_list","_set","_len","sequence","ul4type","Protocol","_mod","div","mod","_getattr","attrname","default_","proto","getattr","AttributeError","_hasattr","hasattr","_dir","dir","_any","iterable","_all","_isundefined","_isdefined","_isnone","_isbool","_isfloat","_isstr","call","_istemplate","Template","TemplateClosure","_isfunction","_isexception","_isanyset","__type__","Proto","_str_repeat","rep","_list_repeat","list","_str_json","_asjson","_fromjson","string","StrProtocol","strip","root","JSON","parse","Function","_asul4on","_fromul4on","_format_datetime","fmt","lang","translation","de","ml","ws","wl","xf","Xf","cf","en","fr","es","it","da","sv","nl","pt","cs","sk","pl","hr","sr","ro","hu","tr","ru","zh","ko","ja","inspec","getDay","_format","DateTimeProtocol","yearday","_week4format","_format_int","work","fill","align","sign","alternate","minimumwidth","minimumwidthStr","exec","neg","toUpperCase","pad","padBefore","padAfter","translations","toLowerCase","split","len","_rpad","_nextid","other","Signature","argNames","remargs","nextDefault","lastArgname","remkwargs","argName","defaultValue","substr","_this","decname","arg","prefix","argObject","expose","count","options","ListProtocol","DateProtocol","SetProtocol","MapProtocol","ObjectProtocol","__getattr__","attr","realattr","object","sub","end","_count","_find","_rfind","old","new_","sep","splice","lstrip","lastIndexOf","rstrip","keepends","startpos","lineendlen","endpos","resultlist","singlepre","suffix","singlesuf","find","rfind","rsplit","splitlines","lower","capitalize","startswith","endswith","append","insert","_update","clear","update","weekday","firstweekday","mindaysinfirstweek","calendar","d","week","mimeformat","isoformat","offset","refDate","weekDayDiff","weekStartYear","weekStartMonth","weekStartDay","weekStart","diff","SubAST","_do","leap","_isleap","microsecond","realresult","Context","vars","indents","escapes","_output","message","fileName","lineNumber","instance","Error","setPrototypeOf","getPrototypeOf","enumerable","writable","configurable","InternalException","ReturnException","BreakException","ContinueException","SyntaxError","LValueRequiredError","NotSubscriptableError","ZeroDivisionError","IndexError","LocationError","location","template","parenttemplate","first","templateprefix","_templateprefix","sourceprefix","source","sourcesuffix","text","underline","col","AST","_col","_ul4onattrs","undefined","_eval","_decorate_exception","_eval_set","_eval_modify","decoder","_source","of","outerstartpos","innerstartpos","fullsource","maxprefix","preprefix","outerstoppos","innerstoppos","maxsuffix","postsuffix","_calculateLineCol","TextAST","IndentAST","_text","LineEndAST","CodeAST","ConstAST","ItemArgBase","_eval_list","_eval_dict","_eval_call","SeqItemAST","_handle_eval","UnpackSeqItemAST","DictItemAST","UnpackDictItemAST","subitem","PosArgAST","KeywordArgAST","UnpackListArgAST","UnpackDictArgAST","ListAST","_handle_eval_list","ListCompAST","varname","container","condition","localcontext","inheritvars","varitems","_handle_eval_set","SetAST","SetCompAST","DictAST","_handle_eval_dict","DictCompAST","GenExprAST","VarAST","_get","_modify","functions","_ido","UnaryAST","NegAST","__neg__","BitNotAST","NotAST","IfAST","objif","objcond","objelse","condvalue","ReturnAST","PrintAST","PrintXAST","_xmlescape","BinaryAST","ItemAST","orgkey","__getitem__","__setitem__","IsAST","IsNotAST","EQAST","NEAST","LTAST","LEAST","GTAST","GEAST","ContainsAST","__contains__","NotContainsAST","AddAST","__add__","__radd__","__sub__","__rsub__","_date_sub","_datetime_sub","swap","t","year1","yearday1","year2","yearday2","diffdays","hours1","minutes1","seconds1","hours2","minutes2","diffseconds","diffmilliseconds","MulAST","__mul__","__rmul__","targetsize","FloorDivAST","__floordiv__","__rfloordiv__","TrueDivAST","__truediv__","__rtruediv__","ModAST","ShiftLeftAST","ShiftRightAST","BitAndAST","BitXOrAST","BitOrAST","AndAST","OrAST","AttrAST","__setattr__","oldvalue","CallAST","_handle_eval_call","_makeargs","RenderAST","_reprname","tag","withindent","_handle_additional_arguments","RenderXAST","RenderBlockAST","closure","content","RenderBlocksAST","BlockAST","SliceAST","index1","index2","SetVarAST","ModifyVarAST","_handle_eval_modify","_operator","AddVarAST","SubVarAST","MulVarAST","TrueDivVarAST","FloorDivVarAST","ModVarAST","ShiftLeftVarAST","ShiftRightVarAST","BitAndVarAST","BitXOrVarAST","BitOrVarAST","ForBlockAST","_str_varname","WhileBlockAST","cond","BreakAST","ContinueAST","CondBlockAST","block","_execute","ConditionalBlockAST","_strname","IfBlockAST","ElIfBlockAST","ElseBlockAST","whitespace","startdelim","enddelim","docpos","_asts","doc","render","_renderbound","renders","_rendersbound","SignatureAST","clone","replaceoutput","getoutput","_callbound","params","param","endtag","_rgb","_csv","_chr","_ord","_hex","number","_oct","_bin","_min","_max","_sum","_first","_last","_sorted","reverse","cmp","sort","keyvalue","s1","s2","_range","step","higher","abs","_slice","_urlquote","encodeURIComponent","_urlunquote","decodeURIComponent","_reversed","_random","random","_randrange","n","width","_randchoice","iscolor","_round","x","digits","threshold","pow","_md5","require","md5","_enumerate","_isfirst","isfirst","_islast","lastitem","_isfirstlast","_enumfl","_zip","iterables","iters","_abs","__abs__","_datetime","_timedelta","_monthdelta","_hls","h","l","s","m1","m2","_v","hue","_hsv","p","q","defaultvalue","now","utcnow","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","getUTCMilliseconds","today","repr","int","float","bool","format","any","all","zip","isundefined","isdefined","isnone","isbool","isint","isfloat","isstr","isdate","isdatetime","istimedelta","ismonthdelta","istemplate","isfunction","islist","isset","isdict","isexception","asjson","fromjson","asul4on","fromul4on","enumerate","islast","isfirstlast","enumfl","date","datetime","timedelta","monthdelta","rgb","hls","hsv","xmlescape","csv","chr","ord","hex","oct","bin","min","max","sum","last","sorted","range","urlquote","urlunquote","reversed","randrange","randchoice","lastIndex","jan1weekday","others","lum","hlsa","hsva","witha","withlum","abslum","rellum","rc","gc","bc","maxc","minc","_js_Date","total_microseconds","total_seconds","minutes","hours","millisecond","_adddate","_adddatetime","myValue","otherValue","hasSeconds","hasMicroseconds","targetmonth","classes","la","Base","_dumpUL4ONAttr","loadcontent","iteritem","_loadUL4ONAttr","_setDefaultUL4ONAttr","_ul4attrs","realvalue","bind","Handler","record","Globals","platform","user","maxdbactions","maxtemplateruntime","flashmessages","handler","geo1","geo2","sqsin","sin","sqcos","cos","deg2rad","PI","flat","lat1","lat","long1","long","lat2","F","G","S","C","w","atan","sqrt","D","T","H2","FlashMessage","title","App","id","globals","save","Login","_insert","Record","entries","fields","startsWith","controls","View","DataSourceData","identifier","app","createdat","createdby","updatedat","updatedby","updatecount","_sparsevalues","_values","_fields","children","attachments","errors","_is_deleted","field","control","priority","is_dirty","has_errors","delete","search","fieldsearch","fieldvalue","Field","Control","subtype","BoolControl","_logsearch","IntControl","NumberControl","minvalue","maxvalue","StringControl","TextControl","EmailControl","URLControl","TelControl","PasswordControl","TextAreaControl","DateControl","language","searchvalue","formatstring","DatetimeMinuteControl","DatetimeSecondControl","LookupControl","LookupSelectControl","LookupRadioControl","LookupChoiceControl","AppLookupControl","AppLookupSelectControl","AppLookupRadioControl","AppLookupChoiceControl","MultipleLookupControl","MultipleLookupSelectControl","MultipleLookupCheckboxControl","MultipleLookupChoiceControl","MultipleAppLookupControl","MultipleAppLookupSelectControl","MultipleAppLookupCheckboxControl","MultipleAppLookupChoiceControl","GeoControl","Geo","info","FileControl","ButtonControl","_value","_dirty","LookupItem","label","User","firstname","surname","email","File","url","filename","Attachment","NoteAttachment","URLAttachment","FileAttachment","ImageAttachment","JSONAttachment","Installation","Category","category","parent","KeyView","AppParameter","username","loginRequired","_userName","ecdhCurve","commonjs","ident","httpsAgent"],"mappings":"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"} \ No newline at end of file diff --git a/docs/JavascriptSDK.rst b/docs/JavascriptSDK.rst deleted file mode 100644 index 62fed3c..0000000 --- a/docs/JavascriptSDK.rst +++ /dev/null @@ -1,176 +0,0 @@ -Javascript-SDK -============== - -Mit dem Javascript-SDK können sie mithilfe der Programmiersprache Javascript mit -LivingApps interagieren. - -Das SDK erlaubt Ihnen, die Daten die Sie in den Datenquellen für eines Ihrer -Anzeige-Templates konfiguriert haben, abzurufen, neue Datensätze anzulegen, -sowie existierende zu ändern und zu löschen. - -Die folgenden Beispiele wurde mit ``node.js`` Version 8.4 auf Ubuntu 16.04 -getestet. - - -Installation ------------- - -Das Javascript-SDK steht auf Github zur Verfügung und kann folgendermaßen -geklont werden: - -.. sourcecode:: bash - - $ git clone https://github.com/LivingLogic/LivingApps.Javascript.LivingAPI - -Danach können die benötigten Packete installiert werden: - -.. sourcecode:: bash - - $ cd LivingApps.Javascript.LivingAPI - $ npm install - -Sollten Sie bereits ein Projekt mit Node.js haben, können Sie das Javascript-SDK -verwenden indem sie die benötigten Packete separat installieren: - -.. sourcecode:: bash - - $ npm install blueimp-md5 - $ npm install request - -und dann die Dateien aus dem `src`-Verzeichnis in Ihr Projekt-Verzeichnis -kopieren. -Sollten Sie allerdings das SDK im Client einsetzen müssen Sie jQuery -in ihr HTML einbinden. - -.. sourcecode:: HTML - - - - - - - -Einloggen ---------- - -Als erstes müssen die benötigten Module eingebunden werden (Clientseitig haben Sie das bereits schon im Codeblock darüber getan): - -.. sourcecode:: javascript - - let livingSDK = require('src/livapp'); - let ul4 = require('src/modules/ul4.js'); - -Nun können Sie ein ``livingSDK``-Objekt anlegen, und sich damit in LivingApps -einloggen: - -.. sourcecode:: javascript - - let loginOptions = [ - {}, // setzt URL automatisch - 'me@example.org', // Ihr Benutzername - 'password' // Ihr Passwort - ]; - let lsdk = livingSDK(...loginOptions); - - -Beispiele ---------- - -Das ``Globals``-Objekt und die Datenquellen auslesen: - -.. sourcecode:: javascript - - let loginOptions = [ - {}, // setzt URL automatisch - 'me@example.org', // Ihr Benutzername - 'password' // Ihr Passwort - ]; - let lsdk = livingSDK(...loginOptions); - let data = lsdk.get('59b02548af9e99d525d316b4'); // appid - return data.then((LAAPI) => { - let globals = LAAPI.get('globals'); - let datasources = LAAPI.get('datasources'); - // Das App-Objekt aus der Datenquelle holen - let app = datasources.get('persons').app; - console.log(ul4._repr(app)); - // out: - }) - -Einen Datensatz anlegen: - -.. sourcecode:: javascript - - let loginOptions = [ - {}, // setzt URL automatisch - 'me@example.org', // Ihr Benutzername - 'password' // Ihr Passwortf - ]; - let lsdk = livingSDK(...loginOptions); - let data = lsdk.get('59b02548af9e99d525d316b4'); // appid - return data.then((LAAPI) => { - let globals = LAAPI.get('globals'); - let datasources = LAAPI.get('datasources'); - // get app - let app = datasources.get('persons').app; - // set content of new Record - let newInsert = { - "text": "das ist ein Text", - date: new Date(Date.now()) - } - return app.insert(newInsert); - }) - -Einen Datensatz ändern: - -.. sourcecode:: javascript - - let loginOptions = [ - {}, // setzt URL automatisch - 'me@example.org', // Ihr Benutzername - 'password' // Ihr Passwort - ]; - let lsdk = livingSDK(...loginOptions); - let data = lsdk.get("59b02548af9e99d525d316b4"); - return data.then((LAAPI) => { - let globals = LAAPI.get('globals'); - let datasources = LAAPI.get('datasources'); - let app = datasources.get('test').app; - let r = app.records.values(); - let last; - let counter = 0; - // Letzten Datensatz holen - for (let d of r) { - last = d; - } - return last.update({ - text: "Neuer Text", - date: new Date(Date.now()) - }); - }) - -Einen Datensatz löschen: - -.. sourcecode:: javascript - - let loginOptions = [ - {}, // setzt URL automatisch - 'me@example.org', // Ihr Benutzername - 'password' // Ihr Passwort - ]; - let lsdk = livingSDK(...loginOptions); - let data = lsdk.get("59b02548af9e99d525d316b4"); - return data.then((LAAPI) => { - let globals = LAAPI.get('globals'); - let datasources = LAAPI.get('datasources'); - let app = datasources.get('test').app; - let r = app.records.values(); - let last; - // Letzten Datensatz holen - for (let d of r) { - last = d; - } - return last.delete(); - }) diff --git a/docs/demos/App_erstellen_Ionic/README.md b/docs/demos/App_erstellen_Ionic/README.md deleted file mode 100644 index 3abd33b..0000000 --- a/docs/demos/App_erstellen_Ionic/README.md +++ /dev/null @@ -1,364 +0,0 @@ -# Apps erstellen mit Ionic und Living-Apps - -Hmm, lecker dieser Mocha. - -Kaffee ist eine wichtige Resource in einem Softwareunternehmen, -deshalb verfolgen wir mithilfe einer Living-App wieviel Kaffee -konsumiert wird. Allerdings gibt es keine zentrale Station an der -der Kaffeekonsum eingetragen wird, es wird stattdessen jeweils Arbeitsplatz- -Rechner nachgetragen. Nun wollen wir in diesem Beitrag -eine App erstellen, die auf einem in der Küche aufgestellten Tablet -installiert werden könnte und eine zentrale Anlaufstelle zum Eintragen des -Kaffees ist. -Für diesen Beitrag benötigen Sie etwas Kenntnisse über HTML, SCSS, Javascript -und Ionic. - -## Todo-Liste -- eine Living-App -- ein Formular zur Eingabe des Kaffeekonsums - -## eine Living-App erstellen -Zuerst benötigen Sie ein Living-Apps Konto mit erweiterten Rechten, -um später Datenquellen freizuschalten. Folgen Sie einfach der Anleitung -und falls bei ihnen etwas anders aufscheint schreiben Sie uns. - -![alt](./src/assets/Screenshot_20171208_154847.png) - -Erstellen Sie eine App in Living-Apps, ihr Fenster sollte nun wie -oben Aussehen. Nun ziehen Sie mehrere Textfelder und benennen -diese bitte wie im Bild darunter zu sehen. Bitte vergessen Sie -nicht auch einen Absenden-Button zu erstellen. - -![alt](./src/assets/Screenshot_20171208_155022.png) -![alt](./src/assets/Screenshot_20171208_155049.png) - -Damit Sie später die App besser erkennen können benennen Sie die Living-App. -Öffnen Sie nun bei Ihrer App den Reiter Erweitert und Konfiguration. - -![alt](./src/assets/Screenshot_20171208_155142.png) - -Falls ihr Bildschirm nicht so aussieht wie auf dem Bild oben -(Sie benötigen die Anzeigetemplates) fragen Sie bitte nach -einem erweiterten Account. - -Falls Sie bei ihnen alles bisher funktioniert erstellen Sie ein Anzeigetemplate und füllen den Identifizierer ein und für setzen -ein Häkchen bei Standard? und setzen Sie die Berechtigung auf "User mit Rechten auf der Applikation", dami nur Sie und eingeladene Personen später direkten Zugriff darauf haben und keine Dritten. - -![alt](./src/assets/Screenshot_20171208_155205.png) -![alt](./src/assets/Screenshot_20171208_155227.png) - -Anschließend müssen Sie Datenquellen hinzufügen, denn auf diese greifen -Sie später über das SDK zu. Gehen Sie dazu so vor wie in den nächsten zwei Bildern abgebildet. - -![alt](./src/assets/Screenshot_20171208_155323.png) -![alt](./src/assets/Screenshot_20171208_155356.png) - -Wenn Sie diese Schritte abgeschlossen haben, können Sie mithilfe -des SDKs auf die Datenquellen zugreifen, wie Sie in einem -späteren Kapitel sehen können. - -## Formular zur Eingabe -In der Living-App habe Sie bereits ein Formular erstellt, das Sie online -aufrufen können, allerdings benötigen wir ein Formular in Ihrer App. -Um das möglichst schnell Realisieren können Sie Ionic vordefinierte -Elemente benutzen. -Erstellen Sie aber zuerst einmal Ihr Ionic (falls Sie Ionic noch nicht installiert haben können Sie das mit npm i -g Ionic) Projekt mit - -```bash -ionic start -``` - -Während der Initialisierung des Projekts werden Sie nach einem Template -gefragt, Sie können ein beliebigen nutzen, im Blog verwenden wir aber -das Blank Template, falls Sie aber die App erweitern wollen können Sie -auch sofort mit einem anderen Template mit einem Menü beginnen. - -![alt](./src/assets/mobile_screenshot.png) - -Die Gestaltung soll nahe einer Vorgängerversion (darüber zu sehen) -nahe kommen mit einer Auwahlbox für die -Kaffeesorte, eine Möglichkeit die Rundenzahl (von 1-5) zu erniedrigen und -erhöhen und schließlich ein Textfeld wo Sie Ihren Namen eintragen -können. Darunter soll noch eine Liste aller bereits eingegeben -Namen erscheinen, um eine Schnellauswahl zu ermöglichen. - -### Schritt 1. -Führen Sie folgenden Befehl aus: -```bash -ionic serve -``` -Dieser Befehl started einen Webserver, der alle gespeicherten Veränderungen -live nachlädt. - -### Schritt 2. -öffnen Sie den Editor ihrer Wahl, in dem Beitrag wird Visual Studio Code verwendet. -```bash -code . -``` -Sie sehen nun eine Menge von Ordner und Dateien, für den Beitrag wichtig -ist nur der "src"-Ordner. In diesem Bearbeiten Sie die Seiten, die später -der App angezeigt werden sollen, während der "www"-Ordner nur den fertig -kompilierten Code beinhaltet. Verändern Sie deshalb nie den Inhalt des -"www"-Ordners, weil Ihre Änderungen nach dem nächstem "build"-Vorgang -überschrieben werden. -Im "src"-Ordner sind folgenden Ordner und -Dateien wichtig: -- app Ordner -- pages Ordner -- assets Ordner -- providers Ordner (dieser Ordner sollte noch -nicht existieren, falls er schon existiert, -desto besser) -- index.html - -### Schritt 3. -klonen Sie sich das aktuelle offizielle Javascript Livingapi Repository in den "assets"-Ordner -```bash -git clone https://github.com/LivingLogic/LivingApps.Javascript.LivingAPI.git -``` -Kopieren Sie die Dateien aus dem "src" Folder -des soeben geklonten Repositories und fügen -Sie in dem assets Ordner ein. Löschen Sie anschließend den Ordner des geklonten -Repositories, da Sie sonst in ihrem Projekt -Dateien wie den Unittest und diese Dokumentation -in ihrem Projekt dabei haben. - -Schritt 4. -Binden Sie nun die einzelnen Dateien im index.html ein. -```html - - - - - - ``` - Sie haben, wenn Sie den Code kopiert haben neben dem Einbinden der Dateien - eine Abfrage des Usernames und des Passwortes - eingerichtet, Sie können natürlich auf Ihren - Benutzernamen und ihr Passwort direkt in - den Variablen hinterlegen, dann müssen Sie - es nicht immer neu eingeben. Falls Sie die App - aber veröffentlichen möchten sollten Sie keinesfalls ihre Nutzerdaten im Code stehen haben. - - ### Schritt 5. - Erzeugen Sie nun einen Provider. Es handelt sich dabei um ein Skript, das später mit LivingApps kommuniziert, damit Sie nicht später bei jeder Seite es neu implementieren müssen. - ```bash - ionic g provider la - ``` - Der erzeugte Provider heißt la und nun sollte bei ihnen der Ordner provider im src-Ordner erstellt worden sein. - -### Schritt 6. -Betrachten Sie den soeben erzeugten Provider, die Datei liegt unter "src/providers/la/la.ts". -Löschen Sie aus dem Konstruktor den automatisch erzeugten Parameter und die erste Zeile, -die HttpClient einbindet, da dieser nicht benötigt wird. -Erzeugen Sie die Instanzvariable window folgendermaßen: -```Javascript -private window: any; -constructor() { - this.window = window; -} -``` -Nun können Sie mit this.window.livingSDK auf das SDK zugreifen. Würden Sie versuchen über window.livingSDK auf das SDK zuzugreifen wird der Typescriptcompiler "meckern", da livingSDK -keine Eigenschaft von Window (dem Interface) ist. - -## Kurzes Revue: -Die Schritte 1-6 sind Schritte die Sie absolvieren müssen, bevor Sie mit der eigentlichen Oberfläche -und Logik (in Verbindung mit LivingApps) beginnen. -- Sie haben eine App angelegt -- Sie haben eine LivingApp angelegt -- Sie haben das livingSDK in index.html eingebunden -- Sie haben einen Provider angelegt -- Sie beobachen alle Veränderungen an ihrem Script im Browser dank ihres gestartet Webservers (Schritt 1) - -### Schritt 7. -Lassen Sie uns nun mit der Verbindung zwischen LivingApps und ihrer App beginnen. Betrachten -Sie hierzu zuerst diesen Codeschnipsel und fügen ihn in ihrer Klasse LaProvider ein. -```Javascript -addCoffee (input) { - return new Promise((resolve, reject) => { - let lsdk = new this.window.livingSDK({},this.window.username, this.window.password); - lsdk.get("appid of your Livingapp").then((LAAPI) => { - let app = LAAPI.get('datasources').get('coffee').app; - app.insert(input).then((res) => { - console.log(res); - resolve(res); - }) - }) - }); - } -``` -Diese Funktion soll die Variable input an Livingapps schicken und dort abspeichern. -Vielleicht ist ihnen schon aufgefallen, das die Funktion asynchon ist, Sie liefert also ein Promise zurück. Es wird eine Instanz (lsdk) des SDKs erzeugt, welches Sie automatisch mit den übergebenen Daten -einloggt. Falls Sie die falschen Daten angegeben haben müssen Sie das Programm abbrechen. -Sie können nun die Daten einer App vom LivingApps-Server abfragen indem Sie lsdk.get("ihre App Id") -aufrufen. Da diese Funktion ebenfalls Asynchron ist, erhalten Sie ein Promise, welches, falls die -Anfrage erfolgreich war, das die Map LAAPI enthält. Von dieser können Sie die "datasources", die sie -vor Schritt 1 angelegt haben abrufen. Diese "datasources" enthalten die Eigenschaft "app", welches wiederum die Funktion "insert" hat, welcher Sie die ihre Daten, die Sie in ihrer LivingApp speichern -wollen, übergeben. "insert" liefert einen Eintrag zurück. -Sie können diesen im nachhinein auf seine Korrektheit überprüfen. - -Hier ist noch ein Codebeispiel, falls Sie Daten abfragen möchten, anstatt Sie wie oben hinzuzufügen. - -```Javascript - - listWorkers () { - return new Promise ((resolve, reject) => { - let workers = []; - let lsdk = new this.window.livingSDK({}, this.window.username, this.window.password); - lsdk.get('ihr App Id').then((LAAPI) => { - let datasources = LAAPI.get('datasources'); - let app = datasources.get('default').app; - let records = app.records; - for (let record of Array.from(records)) { - let workerMetaData = { - name: record[1].fields.get('mitarbeiter').value, - interests: record[1].fields.get('interessensgebiete').value, - picture: record[1].fields.get('picture').value - }; - workers.push(workerMetaData); - } - resolve(workers); - }) - }); - } - ``` - -Und schon haben Sie ihre gewünschte Verbindung zwischen LivingApps und ihrer App hergestellt, -ab jetzt folgt nur noch UI. - -### Schritt 8. -Öffnen Sie nun home.html und löschen den Inhalt des Tags "ion-content". Ändern Sie den Inhalt -des Tags "ion-title" zu "mein Kaffee" oder einem anderen Titel. -Sie haben dadurch einen leeren Contenbereich, dem Sie nun folgendes Element hinzufügen können. -```html - - ... - -``` -Sie haben eine Liste erstellt, in der der erste Eintrag (Tag: "ion-item") die Auswahlbox für die Kaffeesorte sein soll. -```html -Kaffeesorte: - - Mocha - -``` -Das zweite Element der Liste ist ein Zähler, wieviele Kaffees heute getrunken wurden. -Fügen Sie folgenden Code in ein zweites ion-item. -```html - - - - - - - -``` -Als drittes Element fügen Sie ein Eingabefeld zur Eingabe des Konsumenten hinzu. -```html -Konsument - - -``` - -Zuguter letzt benötigen Sie noch einen Absendebutton. -```html - -``` - -![Bild kann nicht geladen werden](./src/assets/Screenshot_20171215_120146.png) - -Ihre App solte nun so aussehen wie auf dem Bild. -Allerdings fehlt noch ein Zähler und wenn Sie bestimmte -Elemente anklicken erscheint eine Fehlermeldung. -Das liegt daran, dass diese Oberfläche mit ein paar Logiken -verbunden ist, die Sie noch nicht erstellt haben, was Sie -aber im nächsten Schritt nachholen. - -### Schritt 9. -Die Auswahl des Kaffees beinhaltet folgenden Code, der bei einer -Veränderung des Wertes der Selectbox aufgerufen wird. -```Javascript -(input)="coffee = $event.target.value" -``` -Der Code weist den Wert, den Ihre Option besitzt der Instanzvariablen -coffee zu. Aber moment mal, Sie haben doch noch keine Instanzvariable -coffee erzeugt. Genau das holen Sie jetzt nach, öffnen Sie dazu die -Datei home.ts und fügen Sie der Klasse HomePage die Variable coffee hinzu. -```Javascript -private coffee: any = "Mocha"; // schonmal vorinitialisiert; -``` -Damit ist jetzt der erste Teil vollständig nutzbar. -Für den zweiten Teil benötigen Sie ebenfalls eine solche Variable: -```Javascript -private number: number = 1; -``` -und schon erscheint die 1 im zweiten Button der Reihe. -Mit den Plus- und Minusbutton können Sie die Zahl noch nicht verändern. -Legen Sie dazu eine Funktion, die number verändert und begrenzt. Bspw so: -```Javascript -changeNumber (diffrence: number) { - if ((this.number <= 1 && diffrence < 0) || (this.number >= 5 && diffrence > 0)) { - return; - } - this.number += diffrence; - } -``` -Sie können nun die die Anzahl getrunkener Kaffee am Tag auch verändern. -Jetzt müssen Sie noch den Namen des Konsumenten abfragen, fügen Sie dazu -wieder eine Variable ein: -```Javascript - private consumer: any = "Der Herr des Kaffees"; -``` -Es folgt hier wieder dem Schema der Eingabe des Kaffees, die Wertzuweisung -an die Instanzvariable erfolgt im HTML -```Javascript -(input)="consumer = $event.target.value" -``` -Nun können Sie mit der App Daten vom User abfragen, aber noch nicht -abschicken, da wenn Sie den Abschickenbutton klicken, dann rufen -Sie die nicht existente Funktion add() auf. -Für add() benötigen Sie aber noch zugriff auf ihren vorhin erstellten -Provider, den Sie mit -```Javascript -import { LaProvider }from '../../providers/la/la'; -``` -in home.ts einbinden und durch Anpassen ihres Konstruktors, instanziieren. -```Javascript -constructor(public navCtrl: NavController, private laProv: LaProvider) { -``` -(Achtung !!! Besonderheit von TypeScript, in Javascript verwenden Sie weiterhin -new -- Ionic nutzt TS) - -Anschließen können Sie mit der Funktion add() beginnen. -Die Funktion gibt im Codebeispiel zur Kontrolle auf der Konsole -die zu übermittelnden Daten aus und ruft dann den Provider auf. -```Javascript - add(){ - console.log("add entry" + JSON.stringify({ - kaffeesorte: this.coffee, - runde: this.number, - mitarbeiter: this.consumer - })); - this.laProv.addCoffee({ - kaffeesorte: this.coffee, - runde: this.number.toString(), - mitarbeiter: this.consumer - }).then((res)=>{ - alert("erfolgreich einen Datensatz hinzugefügt"); - }); - } -``` - -### FIN - -Damit haben Sie nun ihre App erstellt und können Sie für die Produktion -noch etwas anpassen und dann ausliefern. - -Wir hoffen Sie hatten Spaß. -Für Fragen und Verbesserungen stehen Wir gerne für Sie zur Verfügung. diff --git a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_154847.png b/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_154847.png deleted file mode 100644 index dddc332..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_154847.png and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155022.png b/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155022.png deleted file mode 100644 index e7d9e9b..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155022.png and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155049.png b/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155049.png deleted file mode 100644 index b9f985e..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155049.png and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155142.png b/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155142.png deleted file mode 100644 index 2a4271e..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155142.png and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155205.png b/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155205.png deleted file mode 100644 index ba36949..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155205.png and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155227.png b/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155227.png deleted file mode 100644 index ba27499..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155227.png and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155323.png b/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155323.png deleted file mode 100644 index cde866c..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155323.png and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155356.png b/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155356.png deleted file mode 100644 index a7d0790..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155356.png and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155521.png b/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155521.png deleted file mode 100644 index a7d0790..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171208_155521.png and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171215_120146.png b/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171215_120146.png deleted file mode 100644 index 5f6fab2..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/assets/Screenshot_20171215_120146.png and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/assets/mobile_screenshot.png b/docs/demos/App_erstellen_Ionic/src/assets/mobile_screenshot.png deleted file mode 100644 index a3b91e7..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/assets/mobile_screenshot.png and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/.editorconfig b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/.editorconfig deleted file mode 100644 index 51873bc..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/.editorconfig +++ /dev/null @@ -1,17 +0,0 @@ -# EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs -# editorconfig.org - -root = true - -[*] -indent_style = space -indent_size = 2 - -# We recommend you to keep these unchanged -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.md] -trim_trailing_whitespace = false \ No newline at end of file diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/.gitignore b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/.gitignore deleted file mode 100644 index 38344b1..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -resources -www -.sourcemaps \ No newline at end of file diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/config.xml b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/config.xml deleted file mode 100644 index 7290d53..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/config.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - kaffeeapp - An awesome Ionic/Cordova app. - Ionic Framework Team - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/ionic.config.json b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/ionic.config.json deleted file mode 100644 index 07cdedd..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/ionic.config.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "kaffeeapp", - "app_id": "", - "type": "ionic-angular", - "integrations": { - "cordova": {} - } -} diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/package.json b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/package.json deleted file mode 100644 index 092cc06..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "kaffeeapp", - "version": "0.0.1", - "author": "Ionic Framework", - "homepage": "http://ionicframework.com/", - "private": true, - "scripts": { - "clean": "ionic-app-scripts clean", - "build": "ionic-app-scripts build", - "lint": "ionic-app-scripts lint", - "ionic:build": "ionic-app-scripts build", - "ionic:serve": "ionic-app-scripts serve" - }, - "dependencies": { - "@angular/common": "5.0.3", - "@angular/compiler": "5.0.3", - "@angular/compiler-cli": "5.0.3", - "@angular/core": "5.0.3", - "@angular/forms": "5.0.3", - "@angular/http": "5.0.3", - "@angular/platform-browser": "5.0.3", - "@angular/platform-browser-dynamic": "5.0.3", - "@ionic-native/core": "4.4.0", - "@ionic-native/splash-screen": "4.4.0", - "@ionic-native/status-bar": "4.4.0", - "@ionic/storage": "2.1.3", - "ionic-angular": "3.9.2", - "ionicons": "3.0.0", - "rxjs": "5.5.2", - "sw-toolbox": "3.6.0", - "zone.js": "0.8.18" - }, - "devDependencies": { - "@ionic/app-scripts": "3.1.5", - "typescript": "2.4.2" - }, - "description": "An Ionic project" -} diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/app.component.ts b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/app.component.ts deleted file mode 100644 index ab78376..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/app.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Component } from '@angular/core'; -import { Platform } from 'ionic-angular'; -import { StatusBar } from '@ionic-native/status-bar'; -import { SplashScreen } from '@ionic-native/splash-screen'; - -import { HomePage } from '../pages/home/home'; -@Component({ - templateUrl: 'app.html' -}) -export class MyApp { - rootPage:any = HomePage; - - constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) { - platform.ready().then(() => { - // Okay, so the platform is ready and our plugins are available. - // Here you can do any higher level native things you might need. - statusBar.styleDefault(); - splashScreen.hide(); - }); - } -} - diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/app.html b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/app.html deleted file mode 100644 index 7b88c96..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/app.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/app.module.ts b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/app.module.ts deleted file mode 100644 index f1af90a..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/app.module.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { BrowserModule } from '@angular/platform-browser'; -import { ErrorHandler, NgModule } from '@angular/core'; -import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular'; -import { SplashScreen } from '@ionic-native/splash-screen'; -import { StatusBar } from '@ionic-native/status-bar'; - -import { MyApp } from './app.component'; -import { HomePage } from '../pages/home/home'; -import { LaProvider } from '../providers/la/la'; - -@NgModule({ - declarations: [ - MyApp, - HomePage - ], - imports: [ - BrowserModule, - IonicModule.forRoot(MyApp) - ], - bootstrap: [IonicApp], - entryComponents: [ - MyApp, - HomePage - ], - providers: [ - StatusBar, - SplashScreen, - {provide: ErrorHandler, useClass: IonicErrorHandler}, - LaProvider - ] -}) -export class AppModule {} diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/app.scss b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/app.scss deleted file mode 100644 index 1392a6e..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/app.scss +++ /dev/null @@ -1,16 +0,0 @@ -// http://ionicframework.com/docs/theming/ - - -// App Global Sass -// -------------------------------------------------- -// Put style rules here that you want to apply globally. These -// styles are for the entire app and not just one component. -// Additionally, this file can be also used as an entry point -// to import other Sass files to be included in the output CSS. -// -// Shared Sass variables, which can be used to adjust Ionic's -// default Sass variables, belong in "theme/variables.scss". -// -// To declare rules for a specific mode, create a child rule -// for the .md, .ios, or .wp mode classes. The mode class is -// automatically applied to the element in the app. diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/main.ts b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/main.ts deleted file mode 100644 index 6af7a5b..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/app/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; - -import { AppModule } from './app.module'; - -platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/icon/favicon.ico b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/icon/favicon.ico deleted file mode 100644 index d76fa29..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/icon/favicon.ico and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/imgs/logo.png b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/imgs/logo.png deleted file mode 100644 index 80f631d..0000000 Binary files a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/imgs/logo.png and /dev/null differ diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/scripts/src/livingSDK.js b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/scripts/src/livingSDK.js deleted file mode 100644 index c9c2c45..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/scripts/src/livingSDK.js +++ /dev/null @@ -1,475 +0,0 @@ -;(function (root) { - // amd is not implemented yet - let amd = (typeof define === 'function' && define.amd); - let commonjs = (typeof module === 'object' && module.exports); - - let livingApi, ul4on, request, http; - if (commonjs) { - livingApi = require('./modules/livingapi'); - ul4on = require('./modules/ul4').ul4on; - http = require('https'); - } else { - livingApi = root.livingapi; - ul4on = root.ul4on; - } - - class livingSDK { - /** - * @param {String} [username] - * @param {String} [password] - * @param {Object} [options={}] - * @param {String} [options.url] - */ - constructor(options = {}, username, password) { - /** @type {String} */ - this._password = password; - /** @type {String} */ - this._userName = username; - /** @type {Object} */ - this._options = { - /** @type {String} */ - url: options.url !== undefined ? options.url : 'https://my.living-apps.de', - /** @type {Boolean} */ - loginRequired: options.loginRequired !== undefined ? options.loginRequired : true - }; - - this._options.url = this._options.url.lastIndexOf('/') === this._options.url.length - 1 ? this._options.url : `${this._options.url}/`; - if (this._options.loginRequired && !this._userName) { - throw new Error('[livingSDK] You want to login without a username') - } - this.session = this.login(); - } - - /** - * get token for Session - * @return {Promise.} - */ - login() { - if (!this._options.loginRequired) { - return undefined; - } - return new Promise((resolve, reject) => { - if (commonjs) { - let options = { - "ecdhCurve": 'auto', - "method": "POST", - "hostname": "my.living-apps.de", - "port": 443, - "path": "/gateway/login", - "headers": { - "content-type": "application/json" - } - }; - let req = http.request(options, (res) => { - let chunks = [];; - res.on("data", (chunk) => { - chunks.push(chunk); - }); - - res.on("end", () => { - let body = Buffer.concat(chunks); - resolve(JSON.parse(body.toString()).auth_token); - }); - }); - req.write(JSON.stringify({ username: 'rene.schwarzinger@milleniumfrog.de', - password: 'Kl9BgZriXzxmLdpo' })); - req.end(); - } else { - $.ajax(`${this._options.url}gateway/login`, { - dataType: "json", - data: JSON.stringify({ - 'username': this._userName, - 'password': this._password - }), - method: 'POST', - error: function (error) { - reject(error); - }, - success: function (body) { - resolve(body.auth_token); - } - }); - } - }); - } - - /** - * - */ - get(appID, templateName) { - return new Promise((resolve, reject) => { - this.session.then((auth_token) => { - if (commonjs) { - // let options = { - // headers: { - // 'accept': 'application/la-ul4on', - // 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - // }, - // method: 'GET', - // url: `${this._options.url}gateway/apps/${appID}${templateName !== undefined ? '/' + templateName : '' }`, - // }; - // request(options, (error, response, body) => { - // if (error) - // reject(error); - // switch (response.statusCode) { - // case 200: - // let dump = ul4on.loads(body); - // dump.get('globals').Login = this; - // dump.set('datasources', dump.get('viewtemplates').entries().next().value[1].get('datasources')); - - // resolve(dump); - // break; - // case 403: - // this.session = this.login(); - // console.log("token is not valid"); - // resolve(this.get(appID, templateName)); - // break; - // default: - // reject("an error happend"); - // } - // }) - let options = { - "ecdhCurve": 'auto', - "method": "GET", - "hostname": this._options.url.split('//')[1].substr(0, this._options.url.split('//')[1].length-1), - "port": 443, - "path": `/gateway/apps/${appID}${templateName !== undefined ? '/' + templateName : '' }`, - "headers": { - 'accept': 'application/la-ul4on', - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - } - }; - let req = http.request(options, (res) => { - let chunks = []; - res.on("data", function (chunk) { - chunks.push(chunk); - }); - - res.on("end", () => { - if (res.statusCode === 200) { - let body = Buffer.concat(chunks).toString(); - let dump = ul4on.loads(body.toString()); - dump.get('globals').Login = this; - dump.set('datasources', dump.get('viewtemplates').entries().next().value[1].get('datasources')); - - resolve(dump); - } else if (res.statusCode === 403) { - this.session = this.login(); - console.log("token is not valid"); - resolve(this.get(appID, templateName)); - } - }); - }); - req.end(); - } else { - $.ajax(`${this._options.url}gateway/apps/${appID}${templateName !== undefined ? '/' + templateName : '' }`, { - headers: { - 'accept': 'application/la-ul4on', - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - }, - method: 'GET', - statusCode: { - 500: () => { - reject('internal error httpStatus: 500'); - }, - 403: () => { - this.session = this.login(); - console.log("token is not valid"); - resolve(this.get(appID, templateName)); - }, - 200: (body) => { - let dump = ul4on.loads(body); - dump.get('globals').Login = this; - dump.set('datasources', dump.get('viewtemplates').entries().next().value[1].get('datasources')); - resolve(dump); - } - } - }) - } - }); - }); - } - - _insert(app, values) { - return new Promise((resolve, reject) => { - this.session.then((auth_token) => { - let fields = {}; - - for (let ident in values) { - if (!app.controls.has(ident)) { - reject(`insert() got an unexpected keyword argument ${ident}`); - } - // add data to fields - - fields[ident] = app.controls.get(ident).asjson(values[ident]); - } - let data = {};{ - - } - data.id = app.id; - data.data = [{"fields": fields}]; - if (commonjs) { - // let options = { - // url: `${this._options.url}gateway/v1/appdd/${app.id}.json`, - // form: {"appdd": JSON.stringify(data)}, - // headers: { - // 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - // }, - // method: 'post' - // }; - - // request(options, (error, response, body) => { - // //console.log(response); - // if (error) reject(error); - // //console.log(response.statusCode); - // if (response.statusCode !== 200) { - // reject('HTTP Code ' + response.statusCode); - // } - // let returnObj = { - // HTTPstatusCode: response.statusCode, - // recordid: JSON.parse(body).id, - // Record: livingApi.Record.create({ - // id: JSON.parse(body).id, - // createdat: new Date(Date.now()), - // updatedat: null, - // updatedby: null, - // updatecount: 0 - // }) - // }; - // resolve(returnObj); - // }) - let options = { - "ecdhCurve": 'auto', - "method": "POST", - "hostname": this._options.url.split('//')[1].substr(0, this._options.url.split('//')[1].length-1), - "port": 443, - "path": `/gateway/v1/appdd/${app.id}.json`, - "headers": { - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - } - }; - let req = http.request(options, (res) => { - let chunks = []; - res.on("data", (chunk) => { - chunks.push(chunk); - }); - - res.on("end", () => { - let body = Buffer.concat(chunks).toString(); - let returnObj = { - HTTPstatusCode: res.statusCode, - recordid: JSON.parse(body).id, - Record: livingApi.Record.create({ - id: JSON.parse(body).id, - createdat: new Date(Date.now()), - updatedat: null, - updatedby: null, - updatecount: 0 - }) - }; - resolve(returnObj); - }); - }); - req.write(JSON.stringify({"appdd": data})); - req.end(); - } else { - $.ajax(`${this._options.url}gateway/v1/appdd/${app.id}.json`, { - method: 'post', - data: {"appdd": JSON.stringify(data)}, - headers: { - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - }, - statusCode: { - 200: function (body) { - let returnObj = { - recordid:body.id, - Record: livingApi.Record.create({ - id: body.id, - createdat: new Date(Date.now()), - updatedat: null, - updatedby: null, - updatecount: 0 - }) - }; - resolve(returnObj); - } - } - }); - } - }) - }); - } - - _update(record, values) { - return new Promise((resolve, reject) => { - this.session.then((auth_token) => { - let fields = {}; - let app = record.app; - for (let ident in values) { - if (!app.controls.has(ident)) { - reject(`update() got an unexpected keyword argument ${ident}`); - } - fields[ident] = values[ident]; - } - let data = {}; - data.id = app.id; - data.data = [{"id": record.id, "fields": fields}]; - if (commonjs) { - // let options = { - // url: `${this._options.url}gateway/v1/appdd/${app.id}.json`, - // form: {"appdd": JSON.stringify(data)}, - // headers: { - // 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - // }, - // method: 'post' - // }; - // request(options, (error, response, body) => { - // //console.log("hello"); - // if (error) { - // reject(error); - // } - // switch (response.statusCode) { - // case 200: - // for (let ident in values) - // record.fields.get(ident).value = values[ident]; - // let returnObj = { - // HTTPstatusCode: response.statusCode, - // recordid: JSON.parse(body).id, - // Record: record - // }; - // resolve(returnObj); - // break; - // default: - // reject(`an unexpexted error happend, Statuscode ${response.statusCode}`); - // } - // }); - let options = { - "ecdhCurve": 'auto', - "method": "POST", - "hostname": this._options.url.split('//')[1].substr(0, this._options.url.split('//')[1].length-1), - "port": 443, - "path": `/gateway/v1/appdd/${app.id}.json`, - "headers": { - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - } - }; - let req = http.request(options, (res) => { - let chunks = []; - res.on("data", (chunk) => { - chunks.push(chunk); - }); - - res.on("end", () => { - let body = Buffer.concat(chunks).toString(); - for (let ident in values) - record.fields.get(ident).value = values[ident]; - let returnObj = { - HTTPstatusCode: res.statusCode, - recordid: JSON.parse(body).id, - Record: record - }; - resolve(returnObj); - }); - }); - req.write(JSON.stringify({"appdd": data})); - req.end(); - - } else { - $.ajax(`${this._options.url}gateway/v1/appdd/${app.id}.json`, { - data: {"appdd": JSON.stringify(data)}, - headers: { - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - }, - method: 'post', - statusCode: { - 200: (body) => { - for (let ident in values) - record.fields.get(ident).value = values[ident]; - let returnObj = { - HTTPstatusCode: 200, - recordid: body.id, - Record: record - }; - resolve(returnObj); - } - } - }) - } - }); - }); - } - - _delete (record) { - return new Promise ((resolve, reject) => { - this.session.then((auth_token) => { - let app = record.app; - let recordId = record.id; - if (commonjs) { - // let options = { - // headers: { - // 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - // }, - // url: `${this._options.url}gateway/v1/appdd/${app.id}/${recordId}.json`, - // method: 'delete' - // }; - // request(options, (error, response, reject) => { - // if (error) - // reject(error); - // switch (response.statusCode) { - // case 200: - // resolve (response.statusCode); - // break; - // default: - // reject ('an unexpexted error happend'); - // } - // }) - let options = { - "ecdhCurve": 'auto', - "method": "DELETE", - "hostname": this._options.url.split('//')[1].substr(0, this._options.url.split('//')[1].length-1), - "port": 443, - "path": `/gateway/v1/appdd/${app.id}/${recordId}.json`, - "headers": { - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - } - }; - let req = http.request(options, (res) => { - let chunks = []; - res.on("data", (chunk) => { - chunks.push(chunk); - }); - - res.on("end", () => { - if (res.statusCode === 200) - resolve(200); - }); - }); - req.end(); - - } else { - $.ajax(`${this._options.url}gateway/v1/appdd/${app.id}/${recordId}.json`, { - method: 'delete', - headers: { - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - }, - statusCode: { - 200: () => { - resolve (200); - } - } - }); - } - }) - }) - } - } - - // export livingsdk - if (commonjs) { - module.exports = livingSDK; - } else { - root.livingSDK = livingSDK; - } - - -})(this); diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/scripts/src/modules/livingapi.js b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/scripts/src/modules/livingapi.js deleted file mode 100644 index 962f0dc..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/scripts/src/modules/livingapi.js +++ /dev/null @@ -1,916 +0,0 @@ -;(function(root){ - - let amd = (typeof define === 'function' && define.amd); - let commonjs = (typeof module === 'object' && module.exports); - - let la = {}; - - let ul4, ul4on; - - if (commonjs) { - ul4 = require('./ul4').ul4; - ul4on = require('./ul4').ul4on; - module.exports = la; - } else { - ul4 = root.ul4; - ul4on = root.ul4on; - root.livingapi = la; - } - -la.Base = ul4._inherit( - ul4.Proto, - { - create: function() - { - return ul4._clone(this); - }, - - ul4ondump: function ul4ondump(encoder) - { - for (var i = 0; i < this._ul4onattrs.length; ++i) - encoder.dump(this[this._ul4onattrs[i]]); - }, - - ul4onload: function ul4onload(decoder) - { - for (var i = 0; i < this._ul4onattrs.length; ++i) - this[this._ul4onattrs[i]] = decoder.load(); - } - } -); - -la.Globals = ul4._inherit( - la.Base, - { - _ul4onattrs: ["version", "platform", "user", "maxdbactions", "maxtemplateruntime", "flashmessages"], - - __repr__: function repr() - { - return ""; - } - } -); - -la.FlashMessage = ul4._inherit( - la.Base, - { - _ul4onattrs: ["timestamp", "type", "title", "message"], - - __repr__: function repr() - { - return ""; - } - } -); - -la.App = ul4._inherit( - la.Base, - { - insert: function (values) { - return this.globals.Login._insert(this, values); - }, - - _ul4onattrs: ["id", "globals", "name", "description", "language", "startlink", "iconlarge", "iconsmall", "owner", "controls", "records", "recordcount", "installation", "categories", "params", "views", "datamanagment_identifier"], - - __repr__: function repr() - { - return ""; - } - } -); - -la.View = ul4._inherit( - la.Base, - { - _ul4onattrs: ["id", "name", "app", "order", "width", "height", "start", "end"], - - __repr__: function repr() - { - return ""; - } - } -); - -la.DataSource = ul4._inherit( - la.Base, - { - _ul4onattrs: ["id", "identifier", "app", "apps"], - - __repr__: function repr() - { - return ""; - } - } -); - -la.Record = ul4._inherit( - la.Base, - { - delete: function () { - return this.app.globals.Login._delete(this); - }, - - update: function (values) { - return this.app.globals.Login._update(this, values); - }, - - __repr__: function repr() - { - return ""; - }, - - search: function search(search) - { - for (var identifier in search) - { - var fieldsearch = search[identifier]; - if (ul4._bool(fieldsearch)) - { - if (!this.fields.get(identifier).search(fieldsearch)) - return false; - } - } - return true; - }, - - ul4ondump: function ul4ondump(encoder) - { - encoder.dump(this.id); - encoder.dump(this.app); - encoder.dump(this.createdat); - encoder.dump(this.createdby); - encoder.dump(this.updatedat); - encoder.dump(this.updatedby); - encoder.dump(this.updatecount); - - var fieldvalues = {}; - for (var id in this.fields) - { - var field = this.fields[id]; - - if (field.value !== null) - fieldvalues[id] = field.value; - } - encoder.dump(fieldvalues); - - encoder.dump(this.attachments); - }, - - ul4onload: function ul4onload(decoder) - { - this.id = decoder.load(); - this.app = decoder.load(); - this.createdat = decoder.load(); - this.createdby = decoder.load(); - this.updatedat = decoder.load(); - this.updatedby = decoder.load(); - this.updatecount = decoder.load(); - var self = this; - this.fields = ul4on._havemap ? new Map() : {}; - - var fieldvalues = decoder.load(); - - this.app.controls.forEach(function(control, id){ - var fieldvalue = fieldvalues.get(control.identifier); - if (typeof(fieldvalue) === "undefined") - fieldvalue = null; - - var field = la.Field.create(control, self.app, fieldvalue); - self.fields.set(id, field); - }); - - this.attachments = decoder.load(); - }, - } -); - -la.Control = ul4._inherit( - la.Base, - { - type: null, - subtype: null, - _ul4onattrs: ["id", "identifier", "field", "app", "label", "priority", "order", "default"], - - __repr__: function repr() - { - return ""; - }, - - asjson: function asjson(value) { - return value; - }, - - _logsearch: function _logsearch(value, search) - { - //console.log("Searching for " + ul4._repr(search.value) + " in " + ul4._repr(this) + " with operator " + search.operator + " in value " + ul4._repr(value)); - }, - - // base implemntation, always returns ``false`` (i.e. "not found") - // ``value`` is the value of the field - // ``search`` is an object with information what we're searching for - // keys in ``search`` are: ``operator`` (and ``value`` (if required by the operator)) - search: function search(value, search) - { - return false; - } - } -); - -la.BoolControl = ul4._inherit( - la.Control, - { - type: "bool", - __type__: "BoolControl", - - // ``search`` must by ``null``, ``false`` or ``true`` - search: function search(value, search) - { - this._logsearch(value, search); - if (search.operator === "equals") - return search.value === value; - else - return false; - } - } -); - -la.IntControl = ul4._inherit( - la.Control, - { - type: "int", - __type__: "IntControl", - - // ``search.value`` must by ``null`` or an integer - search: function search(value, search) - { - this._logsearch(value, search); - if (search.operator === "equals") - return search.value === value; - else - return false; - } - } -); - -la.NumberControl = ul4._inherit( - la.Control, - { - type: "number", - __type__: "NumberControl", - - // ``search.value`` must by ``null`` or an integer - search: function search(value, search) - { - this._logsearch(value, search); - if (search.operator === "equals") - return search.value === value; - else - return false; - } - } -); - -la.StringControl = ul4._inherit( - la.Control, - { - type: "string", - - asjson: function (value) { - return value; - }, - - search: function search(value, search) - { - this._logsearch(value, search); - if (search.operator === "equals") - return search.value === value; - else if (search.operator === "contains") - { - if (search.value === null || value === null) - return search.value === value; - else - return value.toLowerCase().indexOf(search.value.toLowerCase()) >= 0; - } - } - } -); - -la.TextControl = ul4._inherit( - la.StringControl, - { - subtype: "text", - __type__: "TextControl" - } -); - -la.EmailControl = ul4._inherit( - la.StringControl, - { - subtype: "email", - __type__: "EmailControl" - } -); - -la.URLControl = ul4._inherit( - la.StringControl, - { - subtype: "url", - __type__: "URLControl" - } -); - -la.TelControl = ul4._inherit( - la.StringControl, - { - subtype: "tel" - } -); - -la.PasswordControl = ul4._inherit( - la.StringControl, - { - subtype: "password" - } -); - -la.TextAreaControl = ul4._inherit( - la.StringControl, - { - subtype: "textarea", - __type__: "TextAreaControl" - } -); - -la.DateControl = ul4._inherit( - la.Control, - { - type: "date", - subtype: "date", - __type__: "DateControl", - - formatstring: function formatstring(language) - { - language = language || this.app.language; - - if (language === "de") - return "%d.%m.%Y"; - else - return "%m/%d/%Y"; - }, - - /** - * @param {Date} value - */ - asjson: function asjson(value) { - if (value instanceof Date){ - value = `${value.getFullYear()}-${value.getMonth()+1}-${value.getDate()} ${value.getHours()}:${value.getMinutes()}:${value.getSeconds()}`; - } - return value; - }, - - // searchvalue must be ``null``, a ``Date`` object or a string - search: function search(value, search) - { - this._logsearch(value, search); - - var searchvalue = search.value; - if (Object.prototype.toString.call(searchvalue) == "[object Date]") - searchvalue = ul4._format(searchvalue, this.formatstring(), this.app.language); - if (value !== null) - value = ul4._format(value, this.formatstring(), this.app.language); - - if (search.operator === "equals") - return searchvalue === value; - else if (search.operator === "contains") - { - if (searchvalue === null || value === null) - return searchvalue === value; - else - return value.toLowerCase().indexOf(searchvalue.toLowerCase()) >= 0; - } - else - return false; - } - } -); - -la.DatetimeMinuteControl = ul4._inherit( - la.DateControl, - { - subtype: "datetimeminute", - __type__: "DatetimeMinuteControl", - - formatstring: function formatstring(language) - { - language = language || this.app.language; - - if (language === "de") - return "%d.%m.%Y %H:%M"; - else - return "%m/%d/%Y %H:%M"; - } - } -); - -la.DatetimeSecondControl = ul4._inherit( - la.DateControl, - { - subtype: "datetimesecond", - __type__: "DatetimeMinuteSecond", - - formatstring: function formatstring(language) - { - language = language || this.app.language; - - if (language === "de") - return "%d.%m.%Y %H:%M:%S"; - else - return "%m/%d/%Y %H:%M:%S"; - } - } -); - -la.LookupControl = ul4._inherit( - la.Control, - { - type: "lookup", - - _ul4onattrs: la.Control._ul4onattrs.concat(["lookupdata"]), - - // ``search.value`` must be ``null`` or a ``LookupItem`` key - // if this control is an applookup ``search.value`` must be an object containing the search criteria for the referenced record - search: function search(value, search) - { - if (this.lookupapp === null) - { - if (search.operator === "equals") - { - if (value === null) - return search.value === null; - else - return value.key === search.value; - } - else - return false; - } - else - { - if (value === null || search.value === null) - return value === search.value; - else - return value.search(search); - } - } - } -); - -la.LookupSelectControl = ul4._inherit( - la.LookupControl, - { - subtype: "select", - __type__: "LookupSelectControl" - } -); - -la.LookupRadioControl = ul4._inherit( - la.LookupControl, - { - subtype: "radio", - __type__: "LookupRadioControl" - } -); - -la.LookupChoiceControl = ul4._inherit( - la.LookupControl, - { - subtype: "choice", - __type__: "LookupChoiceControl" - } -); - -la.AppLookupControl = ul4._inherit( - la.Control, - { - type: "applookup", - _ul4onattrs: la.Control._ul4onattrs.concat(["lookupapp", "lookupcontrols"]), - - // ``search.value`` must be an object containing the search criteria for the referenced record - search: function search(value, search) - { - if (value === null || search.value === null) - return value === search.value; - else - return value.search(search); - } - } -); - -la.AppLookupSelectControl = ul4._inherit( - la.AppLookupControl, - { - subtype: "select", - __type__: "AppLookupSelectControl" - } -); - -la.AppLookupRadioControl = ul4._inherit( - la.AppLookupControl, - { - subtype: "radio", - __type__: "AppLookupRadioControl" - } -); - -la.AppLookupChoiceControl = ul4._inherit( - la.AppLookupControl, - { - subtype: "choice", - __type__: "AppLookupChoiceControl" - } -); - -la.MultipleLookupControl = ul4._inherit( - la.LookupControl, - { - type: "multiplelookup", - - // search.value must be ``null`` or a ``LookupItem`` key - // if this control is an applookup ``search.value`` must be an object containing the search criteria for the referenced record - search: function search(value, search) - { - if (search.operator === "equals") - { - if (this.lookupapp === null) - { - for (var i = 0; i < value.length; ++i) - { - if (value[i].key === search.value) - return true; - } - return false; - } - else - { - if (search.value === null) - return value.length === 0; - else - { - for (var i = 0; i < value.length; ++i) - { - if (value[i].search(search.value)) - return true; - } - return false; - } - } - } - else - return false; - } - } -); - -la.MultipleLookupSelectControl = ul4._inherit( - la.MultipleLookupControl, - { - subtype: "select", - __type__: "MultipleLookupSelectControl" - } -); - -la.MultipleLookupCheckboxControl = ul4._inherit( - la.MultipleLookupControl, - { - subtype: "checkbox", - __type__: "MultipleLookupCheckboxControl" - } -); - -la.MultipleAppLookupControl = ul4._inherit( - la.AppLookupControl, - { - type: "multipleapplookup", - - // ``search.value`` must be an object containing the search criteria for the referenced record - search: function search(value, search) - { - if (search.operator === "equals") - { - if (search.value === null) - return value.length === 0; - else - { - for (var i = 0; i < value.length; ++i) - { - if (value[i].search(search.value)) - return true; - } - return false; - } - } - else - return false; - } - } -); - -la.MultipleAppLookupSelectControl = ul4._inherit( - la.MultipleAppLookupControl, - { - subtype: "select", - __type__: "MultipleAppLookupSelectControl" - } -); - -la.MultipleAppLookupCheckboxControl = ul4._inherit( - la.MultipleAppLookupControl, - { - subtype: "checkbox", - __type__: "MultipleAppLookupCheckboxControl" - } -); - -la.GeoControl = ul4._inherit( - la.Control, - { - type: "geo", - __type__: "GeoControl", - - asjson: function asjson(value) - { - if (la.Geo.isprotoof(value)) - value = `${value.lat}, ${value.long}, ${value.info}`; - return value; - } - } -); - -la.FileControl = ul4._inherit( - la.Control, - { - type: "file", - __type__: "FileControl" - } -); - -la.ButtonControl = ul4._inherit( - la.Control, - { - type: "button", - __type__: "ButtonControl" - } -); - -la.Field = ul4._inherit( - la.Base, - { - create: function create(control, record, value) - { - var field = la.Base.create.call(this); - field.control = control; - field.record = record; - field.value = value; - return field; - }, - - search: function search(searchvalue) - { - return this.control.search(this.value, searchvalue); - }, - - __repr__: function repr() - { - return ""; - } - } -); - -la.LookupItem = ul4._inherit( - la.Base, - { - _ul4onattrs: ["key", "label"], - - __repr__: function repr() - { - return ""; - } - } -); - -la.User = ul4._inherit( - la.Base, - { - _ul4onattrs: ["_id", "id", "gender", "firstname", "surname", "initials", "email", "language", "avatarsmall", "avatarlarge", "keyviews"], - //_ul4onattrs: ["id", "gender", "firstname", "surname", "initials", "email", "language", "avatarsmall", "avatarlarge", "keyviews"], - - __repr__: function repr() - { - return ""; - } - } -); - -la.File = ul4._inherit( - la.Base, - { - _ul4onattrs: ["id", "url", "filename", "mimetype", "width", "height"], - - __repr__: function repr() - { - return ""; - } - } -); - -la.Geo = ul4._inherit( - la.Base, - { - create: function create(lat, long, info) - { - var geo = la.Base.create.call(this); - geo.lat = lat; - geo.long = long; - geo.info = info; - return geo; - }, - - _ul4onattrs: ["lat", "long", "info"], - - __repr__: function repr() - { - return ""; - } - } -); - -la.Attachment = ul4._inherit( - la.Base, - { - _ul4onattrs: ["id", "record", "label", "active"], - - __repr__: function repr() - { - return ""; - } - } -); - -la.NoteAttachment = ul4._inherit( - la.Attachment, - { - type: "noteattachment", - __type__: "NoteAttachment", - _ul4onattrs: la.Attachment._ul4onattrs.concat(["value"]) - } -); - -la.URLAttachment = ul4._inherit( - la.Attachment, - { - type: "urlattachment", - __type__: "URLAttachment", - _ul4onattrs: la.Attachment._ul4onattrs.concat(["value"]) - } -); - -la.FileAttachment = ul4._inherit( - la.Attachment, - { - type: "fileattachment", - __type__: "FileAttachment", - _ul4onattrs: la.Attachment._ul4onattrs.concat(["value"]) - } -); - -la.ImageAttachment = ul4._inherit( - la.Attachment, - { - type: "imageattachment", - __type__: "ImageAttachment", - _ul4onattrs: la.Attachment._ul4onattrs.concat(["original", "thumb", "small", "medium", "large"]) - } -); - -la.JSONAttachment = ul4._inherit( - la.Attachment, - { - type: "jsonattachment", - __type__: "JSONAttachment", - ul4ondump: function ul4ondump(encoder) - { - la.Attachment.ul4ondump.call(this, encoder); - encoder.dump(ul4._asjson(this.value)); - }, - ul4onload: function ul4onload(decoder) - { - la.Attachment.ul4onload.call(this, decoder); - this.value = ul4._fromjson(decoder.load()); - } - } -); - -la.Installation = ul4._inherit( - la.Base, - { - _ul4onattrs: ["id", "name"], - - __repr__: function repr() - { - return ""; - } - } -); - -la.Category = ul4._inherit( - la.Base, - { - _ul4onattrs: ["id", "identifier", "name", "order", "parent", "children", "apps"], - - __repr__: function repr() - { - var v = []; - var category = this; - while (category !== null) - { - v.splice(0, 0, category.identifier); - category = category.parent; - } - return ""; - } - } -); - -la.KeyView = ul4._inherit( - la.Base, - { - _ul4onattrs: ["id", "identifier", "name", "key", "user"], - - __repr__: function repr() - { - return ""; - } - } -); - -la.AppParameter = ul4._inherit( - la.Base, - { - _ul4onattrs: ["id", "app", "identifier", "description", "value"], - - __repr__: function repr() - { - return ""; - } - } -); - -var classes = [ - "Globals", - "App", - "View", - "DataSource", - "Record", - "BoolControl", - "IntControl", - "NumberControl", - "TextControl", - "EmailControl", - "URLControl", - "TelControl", - "PasswordControl", - "TextAreaControl", - "DateControl", - "DatetimeMinuteControl", - "DatetimeSecondControl", - "LookupSelectControl", - "LookupRadioControl", - "LookupChoiceControl", - "MultipleLookupSelectControl", - "MultipleLookupCheckboxControl", - "GeoControl", - "FileControl", - "ButtonControl", - "Field", - "LookupItem", - "User", - "File", - "Geo", - "NoteAttachment", - "URLAttachment", - "FileAttachment", - "ImageAttachment", - "JSONAttachment", - "Installation", - "Category", - "KeyView", - "AppParameter" -]; - -for (var i = 0; i < classes.length; ++i) -{ - var name = classes[i]; - var object = la[name]; - ul4on.register("de.livingapps.appdd." + name.toLowerCase(), object); -} - -})(this); diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/scripts/src/modules/ul4.js b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/scripts/src/modules/ul4.js deleted file mode 100644 index 0ca2b53..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/scripts/src/modules/ul4.js +++ /dev/null @@ -1,9049 +0,0 @@ -/*! - * UL4/UL4ON JavaScript Library - * http://www.livinglogic.de/Python/ul4c/ - * http://www.livinglogic.de/Python/ul4on/ - * - * Copyright 2011-2017 by LivingLogic AG, Bayreuth/Germany - * Copyright 2011-2017 by Walter Dörwald - * - * All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/*jslint vars: true */ - - -;(function(undefined){ - - var root = this, ul4 = {}, ul4on = {}; - - var isamd = typeof(define) === "function" && define.amd; - var iscommon = typeof(module) === "object" && module.exports; - - if (isamd) - { - // AMD - define(['../../node_modules/blueimp-md5/js/md5.min'], function (md5F) - { - window.md5 = md5F; - - return {ul4: ul4, ul4on: ul4on}; - }); - } - else if (iscommon) - { - // COMMONJS - module.exports.ul4 = ul4; - module.exports.ul4on = ul4on; - } - else - { - // DEFAULT - root.ul4 = ul4; - root.ul4on = ul4on; - } - - ul4.version = "42"; - - // - // UL4ON - // - - ul4on._registry = {}; - - ul4on._havemap = (typeof(Map) === "function" && typeof(Map.prototype.forEach) === "function"); - - ul4on._havemapconstructor = false; - - if (ul4on._havemap) - { - try - { - if (new Map([[1, 2]]).size == 1) - ul4on._havemapconstructor = true; - } - catch (error) - { - } - } - - ul4on._haveset = (typeof(Set) === "function" && typeof(Set.prototype.forEach) === "function"); - - ul4on._havesetconstructor = false; - - if (ul4on._haveset) - { - try - { - if (new Set([1, 2]).size == 2) - ul4on._havesetconstructor = true; - } - catch (error) - { - } - } - - // helper functions that work with Maps and objects - if (ul4on._havemap) - { - ul4on._makemap = function _makemap(...items) - { - let map = new Map(); - - for (let i = 0; i < items.length; ++i) - map.set(items[i][0], items[i][1]); - return map; - }; - - ul4on._setmap = function _setmap(map, key, value) - { - if (map.__proto__ === Map.prototype) - map.set(key, value); - else - map[key] = value; - }; - - ul4on._emptymap = function _emptymap() - { - return new Map(); - }; - - ul4on._getmap = function _getmap(map, key, value) - { - if (map.__proto__ === Map.prototype) - return map.get(key); - else - return map[key]; - }; - } - else - { - ul4on._makemap = function _makemap(...items) - { - let map = {}; - - for (let i = 0; i < items.length; ++i) - map[items[i][0]] = items[i][1]; - return map; - }; - - ul4on._setmap = function _setmap(map, key, value) - { - map[key] = value; - }; - - ul4on._emptymap = function _emptymap() - { - return {}; - }; - - ul4on._getmap = function _getmap(map, key, value) - { - return map[key]; - }; - } - - // Function used for making sets, when the Set constructor doesn't work (or we don't have sets) - if (ul4on._haveset) - { - ul4on._emptyset = function _emptyset() - { - return new Set(); - }; - } - else - { - ul4on._emptyset = function _emptyset() - { - return ul4._Set.create(); - }; - } - - ul4on._makeset = function _makeset(...items) - { - let set = ul4on._emptyset(); - - for (let i = 0; i < items.length; ++i) - set.add(items[i]); - return set; - }; - - // Register the object ``obj`` under the name ``name`` with the UL4ON machinery - ul4on.register = function register(name, obj) - { - obj.ul4onname = name; - ul4on._registry[name] = function(){return obj.create();}; - }; - - // Return a string that contains the object ``obj`` in the UL4ON serialization format - ul4on.dumps = function dumps(obj, indent) - { - let encoder = ul4on.Encoder.create(indent); - encoder.dump(obj); - return encoder.finish(); - }; - - // Load an object from the string ``data``. - // ``data`` must contain the object in the UL4ON serialization format - // ``registry`` may be null or a dictionary mapping type names to objects with a create method - ul4on.loads = function loads(data, registry) - { - let decoder = ul4on.Decoder.create(data, registry); - return decoder.load(); - }; - - // Helper "class" for encoding - ul4on.Encoder = { - // Create a new Encoder object - create: function create(indent) - { - let encoder = ul4._clone(this); - encoder.indent = indent || null; - encoder.data = []; - encoder._level = 0; - encoder._strings2index = {}; - encoder._ids2index = {}; - encoder._backrefs = 0; - return encoder; - }, - - _line: function _line(line, ...args) - { - if (this.indent !== null) - { - for (let i = 0; i < this._level; ++i) - this.data.push(this.indent); - } - else - { - if (this.data.length) - this.data.push(" "); - } - this.data.push(line); - - if (args.length) - { - let oldindent = this.indent; - this.indent = null; - for (let i = 0; i < args.length; ++i) - this.dump(args[i]); - this.indent = oldindent; - } - - if (this.indent !== null) - this.data.push("\n"); - }, - - // Return the complete string written to the buffer - finish: function finish() - { - return this.data.join(""); - }, - - dump: function dump(obj) - { - if (obj === null) - this._line("n"); - else if (typeof(obj) == "boolean") - this._line(obj ? "bT" : "bF"); - else if (typeof(obj) == "number") - { - let type = (Math.round(obj) == obj) ? "i" : "f"; - this._line(type + obj); - } - else if (typeof(obj) == "string") - { - let index = this._strings2index[obj]; - if (typeof(index) !== "undefined") - { - this._line("^" + index); - } - else - { - this._strings2index[obj] = this._backrefs++; - let dump = ul4._str_repr(obj).replace("<", "\\x3c"); - this._line("S" + dump); - } - } - else if (ul4._iscolor(obj)) - this._line("c", obj.r(), obj.g(), obj.b(), obj.a()); - else if (ul4._isdate(obj)) - this._line("z", obj.getFullYear(), obj.getMonth()+1, obj.getDate(), obj.getHours(), obj.getMinutes(), obj.getSeconds(), obj.getMilliseconds() * 1000); - else if (ul4._istimedelta(obj)) - this._line("t", obj.days(), obj.seconds(), obj.microseconds()); - else if (ul4._ismonthdelta(obj)) - this._line("m", obj.months()); - else if (typeof(obj) === "object" && typeof(obj.isa) === "function" && obj.isa(ul4.slice)) - this._line("r", obj.start, obj.stop); - else if (obj.ul4onname && obj.ul4ondump) - { - if (obj.__id__) - { - let index = this._ids2index[obj.__id__]; - if (typeof(index) != "undefined") - { - this._line("^" + index); - return; - } - } - if (obj.__id__) - this._ids2index[obj.__id__] = this._backrefs++; - this._line("O", obj.ul4onname); - ++this._level; - obj.ul4ondump(this); - --this._level; - this._line(")"); - } - else if (ul4._islist(obj)) - { - this._line("l"); - ++this._level; - for (let i = 0; i < obj.length; ++i) - this.dump(obj[i]); - --this._level; - this._line("]"); - } - else if (ul4._ismap(obj)) - { - this._line("e"); - ++this._level; - obj.forEach(function(value, key) { - this.dump(key); - this.dump(value); - }, this); - --this._level; - this._line("}"); - } - else if (ul4._isdict(obj)) - { - this._line("d"); - ++this._level; - for (let key in obj) - { - this.dump(key); - this.dump(obj[key]); - } - --this._level; - this._line("}"); - } - else if (ul4._isset(obj)) - { - this._line("y"); - ++this._level; - obj.forEach(function(value) { - this.dump(value); - }, this); - --this._level; - this._line("}"); - } - else - throw "can't handle object"; - } - }; - - // Helper "class" for decoding - ul4on.Decoder = { - // Creates a new decoder for reading from the string ``data`` - create: function create(data, registry) - { - let decoder = ul4._clone(this); - decoder.data = data; - decoder.pos = 0; - decoder.backrefs = []; - decoder.registry = typeof(registry) === "undefined" ? null : registry; - return decoder; - }, - - // Read a character from the buffer - readchar: function readchar() - { - if (this.pos >= this.data.length) - throw "UL4 decoder at EOF"; - return this.data.charAt(this.pos++); - }, - - // Read a character from the buffer (return null on eof) - readcharoreof: function readcharoreof() - { - if (this.pos >= this.data.length) - return null; - return this.data.charAt(this.pos++); - }, - - // Read next not-whitespace character from the buffer - readblackchar: function readblackchar() - { - let re_white = /\s/; - - for (;;) - { - if (this.pos >= this.data.length) - throw "UL4 decoder at EOF"; - let c = this.data.charAt(this.pos++); - if (!c.match(re_white)) - return c; - } - }, - - // Read ``size`` characters from the buffer - read: function read(size) - { - if (this.pos+size > this.length) - size = this.length-this.pos; - let result = this.data.substring(this.pos, this.pos+size); - this.pos += size; - return result; - }, - - // "unread" one character - backup: function backup() - { - --this.pos; - }, - - // Read a number from the buffer - readnumber: function readnumber() - { - let re_digits = /[-+0123456789.eE]/, value = ""; - for (;;) - { - let c = this.readcharoreof(); - if (c !== null && c.match(re_digits)) - value += c; - else - { - let result = parseFloat(value); - if (isNaN(result)) - throw "invalid number, got " + ul4._repr("value") + " at position " + this.pos; - return result; - } - } - }, - - _beginfakeloading: function _beginfakeloading() - { - let oldpos = this.backrefs.length; - this.backrefs.push(null); - return oldpos; - }, - - _endfakeloading: function _endfakeloading(oldpos, value) - { - this.backrefs[oldpos] = value; - }, - - _readescape: function _readescape(escapechar, length) - { - let chars = this.read(length); - if (chars.length != length) - throw "broken escape " + ul4._repr("\\" + escapechar + chars) + " at position " + this.pos; - let codepoint = parseInt(chars, 16); - if (isNaN(codepoint)) - throw "broken escape " + ul4._repr("\\" + escapechar + chars) + " at position " + this.pos; - return String.fromCharCode(codepoint); - }, - - // Load the next object from the buffer - load: function load() - { - let typecode = this.readblackchar(); - let result; - switch (typecode) - { - case "^": - return this.backrefs[this.readnumber()]; - case "n": - case "N": - if (typecode === "N") - this.backrefs.push(null); - return null; - case "b": - case "B": - result = this.readchar(); - if (result === "T") - result = true; - else if (result === "F") - result = false; - else - throw "wrong value for boolean, expected 'T' or 'F', got " + ul4._repr(result) + " at position " + this.pos; - if (typecode === "B") - this.backrefs.push(result); - return result; - case "i": - case "I": - case "f": - case "F": - result = this.readnumber(); - if (typecode === "I" || typecode === "F") - this.backrefs.push(result); - return result; - case "s": - case "S": - result = []; - let delimiter = this.readblackchar(); - for (;;) - { - let c = this.readchar(); - if (c == delimiter) - break; - if (c == "\\") - { - let c2 = this.readchar(); - if (c2 == "\\") - result.push("\\"); - else if (c2 == "n") - result.push("\n"); - else if (c2 == "r") - result.push("\r"); - else if (c2 == "t") - result.push("\t"); - else if (c2 == "f") - result.push("\u000c"); - else if (c2 == "b") - result.push("\u0008"); - else if (c2 == "a") - result.push("\u0007"); - else if (c2 == "'") - result.push("'"); - else if (c2 == '"') - result.push('"'); - else if (c2 == "x") - result.push(this._readescape("x", 2)); - else if (c2 == "u") - result.push(this._readescape("u", 4)); - else if (c2 == "U") - result.push(this._readescape("U", 8)); - else - result.push("\\" + c2); - } - else - result.push(c); - } - result = result.join(""); - if (typecode === "S") - this.backrefs.push(result); - return result; - case "c": - case "C": - result = ul4.Color.create(); - if (typecode === "C") - this.backrefs.push(result); - result._r = this.load(); - result._g = this.load(); - result._b = this.load(); - result._a = this.load(); - return result; - case "z": - case "Z": - result = new Date(); - result.setFullYear(this.load()); - result.setDate(1); - result.setMonth(this.load() - 1); - result.setDate(this.load()); - result.setHours(this.load()); - result.setMinutes(this.load()); - result.setSeconds(this.load()); - result.setMilliseconds(this.load()/1000); - if (typecode === "Z") - this.backrefs.push(result); - return result; - case "t": - case "T": - result = ul4.TimeDelta.create(); - result._days = this.load(); - result._seconds = this.load(); - result._microseconds = this.load(); - if (typecode === "T") - this.backrefs.push(result); - return result; - case "r": - case "R": - result = ul4.slice.create(); - if (typecode === "R") - this.backrefs.push(result); - result.start = this.load(); - result.stop = this.load(); - return result; - case "m": - case "M": - result = ul4.MonthDelta.create(); - if (typecode === "M") - this.backrefs.push(result); - result._months = this.load(); - return result; - case "l": - case "L": - result = []; - if (typecode === "L") - this.backrefs.push(result); - for (;;) - { - typecode = this.readblackchar(); - if (typecode === "]") - return result; - this.backup(); - result.push(this.load()); - } - return result; - case "d": - case "D": - case "e": - case "E": - if (!ul4on._havemap && (typecode == "e" || typecode == "E")) - throw "ordered dictionaries are not supported!"; - result = ul4on._emptymap(); - if (typecode === "D" || typecode === "E") - this.backrefs.push(result); - for (;;) - { - typecode = this.readblackchar(); - if (typecode === "}") - return result; - this.backup(); - let key = this.load(); - let value = this.load(); - ul4on._setmap(result, key, value); - } - return result; - case "y": - case "Y": - result = ul4on._makeset(); - if (typecode === "Y") - this.backrefs.push(result); - for (;;) - { - typecode = this.readblackchar(); - if (typecode === "}") - return result; - this.backup(); - result.add(this.load()); - } - return result; - case "o": - case "O": - let oldpos; - if (typecode === "O") - oldpos = this._beginfakeloading(); - let name = this.load(); - let proto; - if (this.registry !== null) - { - proto = this.registry[name]; - if (typeof(proto) === "undefined") - proto = ul4on._registry[name]; - } - else - proto = ul4on._registry[name]; - if (typeof(proto) === "undefined") - throw "can't load object of type " + ul4._repr(name); - result = proto(); - if (typecode === "O") - this._endfakeloading(oldpos, result); - result.ul4onload(this); - typecode = this.readblackchar(); - if (typecode !== ")") - throw "object terminator ')' for object of type '" + name + "' expected, got " + ul4._repr(typecode) + " at position " + this.pos; - return result; - default: - throw "unknown typecode " + ul4._repr(typecode) + " at position " + this.pos; - } - } - }; - - - // - // UL4 - // - - // REs for parsing JSON - ul4._rvalidchars = /^[\],:{}\s]*$/; - ul4._rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g; - ul4._rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; - ul4._rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g; - - /// Helper functions - - // Crockford style object creation - ul4._simpleclone = function _simpleclone(obj) - { - function F(){}; - F.prototype = obj; - let result = new F(); - return result; - }; - - // Crockford style object creation + prototype chain + object ids - ul4._clone = function _clone(obj) - { - let result = ul4._simpleclone(obj); - result.__prototype__ = obj; - result.__id__ = ul4.Proto._nextid++; - return result; - }; - - // Adds attributes from on object to another and returns it - ul4._extend = function _extend(obj, attrs) - { - for (let name in attrs) - obj[name] = attrs[name]; - return obj; - }; - - // Clone an object via ``_simpleclone`` and extend it - ul4._simpleinherit = function _simpleinherit(baseobj, attrs) - { - return ul4._extend(ul4._simpleclone(baseobj), attrs); - }; - - // Clone an object via ``_clone`` and extend it - ul4._inherit = function _inherit(baseobj, attrs) - { - return ul4._extend(ul4._clone(baseobj), attrs); - }; - - // Convert a map to an object - ul4._map2object = function _map2object(obj) - { - if (ul4._ismap(obj)) - { - let newobj = {}; - obj.forEach(function(value, key){ - if (typeof(key) !== "string") - throw ul4.TypeError.create("keys must be strings"); - newobj[key] = value; - }); - return newobj; - } - return obj; - }; - - // Clip a number to the range [0;max) - ul4._bound = function _bound(value, upper) - { - if (value < 0) - return 0; - else if (value > upper) - return upper; - else - return value; - }; - - // Create a pretty stacktrace from an exception - ul4._stacktrace = function _stacktrace(exc) - { - let output = ul4._type(exc); - let s = exc.toString(); - if (s) - output += ": " + s; - if (exc.cause) - output += "\n\n" + ul4._stacktrace(exc.cause); - return output; - }; - - // Call a function ``f`` with UL4 argument handling - ul4._internal_call = function _internal_call(context, f, name, functioncontext, signature, needscontext, needsobject, args, kwargs) - { - let finalargs; - if (needsobject) - { - if (signature === null) - { - if (args.length) - throw ul4.ArgumentError.create(ul4._repr(f) + " doesn't support positional arguments!"); - finalargs = [kwargs]; - } - else - finalargs = [signature.bindObject(name, args, kwargs)]; - } - else - { - if (signature === null) - throw ul4.ArgumentError.create(ul4._repr(f) + " doesn't support positional arguments!"); - finalargs = signature.bindArray(name, args, kwargs); - } - if (needscontext) - finalargs.unshift(context); - return f.apply(functioncontext, finalargs); - }; - - ul4._callfunction = function _callfunction(context, f, args, kwargs) - { - let name = f._ul4_name || f.name; - if (typeof(f._ul4_signature) === "undefined" || typeof(f._ul4_needsobject) === "undefined" || typeof(f._ul4_needscontext) === "undefined") - throw ul4.TypeError.create("call", ul4._repr(f) + " is not callable by UL4"); - return ul4._internal_call(context, f, name, ul4, f._ul4_signature, f._ul4_needscontext, f._ul4_needsobject, args, kwargs); - }; - - ul4._callobject = function _callobject(context, obj, args, kwargs) - { - if (typeof(obj._ul4_callsignature) === "undefined" || typeof(obj._ul4_callneedsobject) === "undefined" || typeof(obj._ul4_callneedscontext) === "undefined") - throw ul4.TypeError.create("call", ul4._repr(obj) + " is not callable by UL4"); - return ul4._internal_call(context, obj.__call__, obj.name, obj, obj._ul4_callsignature, obj._ul4_callneedscontext, obj._ul4_callneedsobject, args, kwargs); - }; - - ul4._callrender = function _callrender(context, obj, args, kwargs) - { - if (typeof(obj._ul4_rendersignature) === "undefined" || typeof(obj._ul4_renderneedsobject) === "undefined" || typeof(obj._ul4_renderneedscontext) === "undefined") - throw ul4.TypeError.create("render", ul4._repr(obj) + " is not renderable by UL4"); - return ul4._internal_call(context, obj.__render__, obj.name, obj, obj._ul4_rendersignature, obj._ul4_renderneedscontext, obj._ul4_renderneedsobject, args, kwargs); - }; - - ul4._call = function _call(context, f, args, kwargs) - { - if (typeof(f) === "function") - return ul4._callfunction(context, f, args, kwargs); - else if (f && typeof(f.__call__) === "function") - return ul4._callobject(context, f, args, kwargs); - else - throw ul4.TypeError.create("call", ul4._type(f) + " is not callable"); - }; - - ul4._unpackvar = function _unpackvar(lvalue, value) - { - if (!ul4._islist(lvalue)) - return [[lvalue, value]]; - else - { - let newvalue = []; - let iter = ul4._iter(value); - - for (let i = 0;;++i) - { - let item = iter.next(); - - if (item.done) - { - if (i === lvalue.length) - break; - else - throw ul4.ValueError.create("need " + lvalue.length + " value" + (lvalue.length === 1 ? "" : "s") + " to unpack, got " + i); - } - else - { - if (i < lvalue.length) - newvalue = newvalue.concat(ul4._unpackvar(lvalue[i], item.value)); - else - throw ul4.ValueError.create("too many values to unpack (expected " + lvalue.length + ")"); - } - } - return newvalue; - } - }; - - ul4._formatsource = function _formatsource(out) - { - let finalout = []; - let level = 0, needlf = false; - for (let i = 0; i < out.length; ++i) - { - if (typeof(out[i]) === "number") - { - level += out[i]; - needlf = true; - } - else - { - if (needlf) - { - finalout.push("\n"); - for (let j = 0; j < level; ++j) - finalout.push("\t"); - needlf = false; - } - finalout.push(out[i]); - } - } - if (needlf) - finalout.push("\n"); - return finalout.join(""); - }; - - // Compare ``obj1`` and ``obj2`` if they have the same value - ul4._eq = function _eq(obj1, obj2) - { - let numbertypes = ["boolean", "number"]; - - if (obj1 && typeof(obj1.__eq__) === "function") - return obj1.__eq__(obj2); - else if (obj2 && typeof(obj2.__eq__) === "function") - return obj2.__eq__(obj1); - else if (obj1 === null) - return obj2 === null; - else if (numbertypes.indexOf(typeof(obj1)) != -1) - { - if (numbertypes.indexOf(typeof(obj2)) != -1) - return obj1 == obj2; - else - return false; - } - else if (typeof(obj1) === "string") - { - if (typeof(obj2) === "string") - return obj1 == obj2; - else - return false; - } - else if (ul4._isdate(obj1)) - { - if (ul4._isdate(obj2)) - return obj1.getTime() == obj2.getTime(); - else - return false; - } - else if (ul4._islist(obj1)) - { - if (ul4._islist(obj2)) - { - // Shortcut, if it's the same object - if (obj1 === obj2) - return true; - if (obj1.length != obj2.length) - return false; - for (let i = 0; i < obj1.length; ++i) - { - if (!ul4._eq(obj1[i], obj2[i])) // This might lead to infinite recursion and a stackoverflow, but it does in all implementations - return false; - } - return true; - } - else - return false; - } - else if (ul4._isobject(obj1)) - { - if (ul4._isobject(obj2)) - { - // Shortcut, if it's the same object - if (obj1 === obj2) - return true; - // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value - for (let key in obj1) - { - if (obj2.hasOwnProperty(key)) - { - if (!ul4._eq(obj1[key], obj2[key])) - return false; - } - else - return false; - } - // Test that each attribute of ``obj2`` is alos in ``obj1`` (the value has been tested before) - for (let key in obj2) - { - if (!obj1.hasOwnProperty(key)) - return false; - } - return true; - } - else if (ul4._ismap(obj2)) - { - // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value - for (let key in obj1) - { - if (obj2.has(key)) - { - if (!ul4._eq(obj1[key], obj2.get(key))) - return false; - } - else - return false; - } - // Test that each attribute of ``obj2`` is alos in ``obj1`` (the value has been tested before) - let result = true; - obj2.forEach(function(value, key){ - if (!obj1.hasOwnProperty(key)) - result = false; - }); - return result; - } - else - return false; - } - else if (ul4._ismap(obj1)) - { - if (ul4._isobject(obj2)) - { - // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value - let result = true; - obj1.forEach(function(value, key){ - if (result) // Skip code, if result is already ``false`` - { - if (!obj2.hasOwnProperty(key)) - result = false; - else if (!ul4._eq(obj1.get(key), obj2[key])) - result = false; - } - }); - if (!result) - return false; - // Test that each attribute of ``obj2`` is alos in ``obj1`` (the value has been tested before) - for (let key in obj2) - { - if (!obj1.has(key)) - return false; - } - return true; - } - else if (ul4._ismap(obj2)) - { - // Shortcut, if it's the same object - if (obj1 === obj2) - return true; - if (obj1.size != obj2.size) - return false; - // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value - let result = true; - obj1.forEach(function(value, key){ - if (result) // Skip code, if result is already ``false`` - { - if (!obj2.has(key)) - result = false; - else if (!ul4._eq(obj1.get(key), obj2.get(key))) - result = false; - } - }); - return result; - } - else - return false; - } - else if (ul4._isset(obj1)) - { - // We don't have to test for ``ul4._Set`` as ``ul4._Set`` implements ``__eq__`` - if (ul4._isset(obj2)) - { - // Shortcut, if it's the same object - if (obj1 === obj2) - return true; - if (obj1.size != obj2.size) - return false; - let result = true; - obj1.forEach(function(value){ - if (result) // Skip code, if result is already ``false`` - { - if (!obj2.has(value)) - result = false; - } - }); - return result; - } - else - return false; - } - else - return obj1 === obj2; - }; - - // Compare ``obj1`` and ``obj2`` if they don't have the same value - ul4._ne = function _ne(obj1, obj2) - { - if (obj1 && typeof(obj1.__ne__) === "function") - return obj1.__ne__(obj2); - else if (obj2 && typeof(obj2.__ne__) === "function") - return obj2.__ne__(obj1); - else - return !ul4._eq(obj1, obj2); - }; - - ul4._unorderable = function _unorderable(operator, obj1, obj2) - { - throw ul4.TypeError.create(operator, "unorderable types: " + ul4._type(obj1) + " " + operator + " " + ul4._type(obj2)); - }; - - // Return: - // -1 when ``obj1 < obj2``, - // 0 when ``obj1 == obj2``, - // 1 when ``obj1 > obj2``, - // null when ``obj1`` and ``obj2`` are comparable, but neither of the previous cases holds (only for sets) - // raise TypeError if objects are uncomparable - // This the purpose of ``_cmp`` is to support implementation of <, <=, > and >= - // and dicts/maps are not comparable with the operator ``_cmp`` does not support dicts/maps - - ul4._cmp = function _cmp(operator, obj1, obj2) - { - let numbertypes = ["boolean", "number"]; - - if (numbertypes.indexOf(typeof(obj1)) != -1) - { - if (numbertypes.indexOf(typeof(obj2)) != -1) - return (obj1 > obj2) - (obj1 < obj2); - } - else if (typeof(obj1) === "string") - { - if (typeof(obj2) === "string") - return (obj1 > obj2) - (obj1 < obj2); - } - else if (ul4._isdate(obj1)) - { - if (ul4._isdate(obj2)) - { - let v1 = obj1.getTime(), v2 = obj2.getTime(); - return (v1 > v2) - (v1 < v2); - } - } - else if (ul4._islist(obj1)) - { - if (ul4._islist(obj2)) - { - if (obj1 === obj2) - return 0; - for (let i = 0; i < obj1.length; ++i) - { - if (i >= obj2.length) - return 1; - let res = ul4._cmp(operator, obj1[i], obj2[i]); - if (res) - return res; - } - return obj2.length > obj1.length ? -1 : 0; - } - } - else if (ul4._isset(obj1) || ul4._isul4set(obj1)) - { - let in1only = false; - let in2only = false; - - if (ul4._isset(obj2)) - { - if (ul4._isset(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.has(value)) - in1only = true; - }); - obj2.forEach(function(value){ - if (!obj1.has(value)) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.items[value]) - in1only = true; - }); - for (let value in obj2.items) - { - if (!obj1.has(value)) - { - in2only = true; - break; - } - } - } - } - else if (ul4._isul4set(obj2)) - { - if (ul4._isset(obj2)) - { - for (let value in obj1.items) - { - if (!obj2.has(value)) - { - in1only = true; - break; - } - } - obj2.forEach(function(value){ - if (!obj1.items[value]) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - for (let value in obj1.items) - { - if (!obj2.items[value]) - { - in1only = true; - break; - } - } - for (let value in obj2.items) - { - if (!obj1.items[value]) - { - in2only = true; - break; - } - } - } - } - else - ul4._unorderable(operator, obj1, obj2); - - if (in1only) - { - if (in2only) - return null; - else - return 1; - } - else - { - if (in2only) - return -1; - else - return 0; - } - } - else - ul4._unorderable(operator, obj1, obj2); - }; - - // Return whether ``obj1 < obj2`` - ul4._lt = function _lt(obj1, obj2) - { - var numbertypes = ["boolean", "number"]; - - if (obj1 && typeof(obj1.__lt__) === "function") - return obj1.__lt__(obj2); - else if (numbertypes.indexOf(typeof(obj1)) != -1) - { - if (numbertypes.indexOf(typeof(obj2)) != -1) - return obj1 < obj2; - } - else if (typeof(obj1) === "string") - { - if (typeof(obj2) === "string") - return obj1 < obj2; - } - else if (ul4._isdate(obj1)) - { - if (ul4._isdate(obj2)) - return obj1.getTime() < obj2.getTime(); - } - else if (ul4._islist(obj1)) - { - if (ul4._islist(obj2)) - { - if (obj1 === obj2) - return false; - for (let i = 0; i < obj1.length; ++i) - { - if (i >= obj2.length) - return false; - let eq = ul4._eq(obj1[i], obj2[i]); - if (!eq) - return ul4._lt(obj1[i], obj2[i]); - } - return obj1.length < obj2.length; - } - } - // FIXME: Set comparison - else if (ul4._isset(obj1)) - { - if (ul4._isset(obj2)) - { - if (ul4._isset(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.has(value)) - in1only = true; - }); - obj2.forEach(function(value){ - if (!obj1.has(value)) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.items[value]) - in1only = true; - }); - for (let value in obj2.items) - { - if (!obj1.has(value)) - { - in2only = true; - break; - } - } - } - } - else if (ul4._isul4set(obj2)) - { - if (ul4._isset(obj2)) - { - for (let value in obj1.items) - { - if (!obj2.has(value)) - { - in1only = true; - break; - } - } - obj2.forEach(function(value){ - if (!obj1.items[value]) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - for (let value in obj1.items) - { - if (!obj2.items[value]) - { - in1only = true; - break; - } - } - for (let value in obj2.items) - { - if (!obj1.items[value]) - { - in2only = true; - break; - } - } - } - } - else - ul4._unorderable(operator, obj1, obj2); - - if (in1only) - { - if (in2only) - return null; - else - return 1; - } - else - { - if (in2only) - return -1; - else - return 0; - } - } - ul4._unorderable("<", obj1, obj2); - }; - - // Return whether ``obj1 <= obj2`` - ul4._le = function _le(obj1, obj2) - { - let numbertypes = ["boolean", "number"]; - - if (obj1 && typeof(obj1.__le__) === "function") - return obj1.__le__(obj2); - if (numbertypes.indexOf(typeof(obj1)) != -1) - { - if (numbertypes.indexOf(typeof(obj2)) != -1) - return obj1 <= obj2; - } - else if (typeof(obj1) === "string") - { - if (typeof(obj2) === "string") - return obj1 <= obj2; - } - else if (ul4._isdate(obj1)) - { - if (ul4._isdate(obj2)) - return obj1.getTime() <= obj2.getTime(); - } - else if (ul4._islist(obj1)) - { - if (ul4._islist(obj2)) - { - if (obj1 === obj2) - return true; - for (let i = 0; i < obj1.length; ++i) - { - if (i >= obj2.length) - return false; - let eq = ul4._eq(obj1[i], obj2[i]); - if (!eq) - return ul4._lt(obj1[i], obj2[i]); - } - return obj1.length <= obj2.length; - } - } - // FIXME: Set comparison - else if (ul4._isset(obj1) || ul4._isul4set(obj1)) - { - let in1only = false; - let in2only = false; - - if (ul4._isset(obj2)) - { - if (ul4._isset(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.has(value)) - in1only = true; - }); - obj2.forEach(function(value){ - if (!obj1.has(value)) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.items[value]) - in1only = true; - }); - for (let value in obj2.items) - { - if (!obj1.has(value)) - { - in2only = true; - break; - } - } - } - } - else if (ul4._isul4set(obj2)) - { - if (ul4._isset(obj2)) - { - for (let value in obj1.items) - { - if (!obj2.has(value)) - { - in1only = true; - break; - } - } - obj2.forEach(function(value){ - if (!obj1.items[value]) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - for (let value in obj1.items) - { - if (!obj2.items[value]) - { - in1only = true; - break; - } - } - for (let value in obj2.items) - { - if (!obj1.items[value]) - { - in2only = true; - break; - } - } - } - } - else - ul4._unorderable(operator, obj1, obj2); - - if (in1only) - { - if (in2only) - return null; - else - return 1; - } - else - { - if (in2only) - return -1; - else - return 0; - } - } - ul4._unorderable("<=", obj1, obj2); - }; - - // Return whether ``obj1 > obj2`` - ul4._gt = function _gt(obj1, obj2) - { - let numbertypes = ["boolean", "number"]; - - if (obj1 && typeof(obj1.__gt__) === "function") - return obj1.__gt__(obj2); - if (numbertypes.indexOf(typeof(obj1)) != -1) - { - if (numbertypes.indexOf(typeof(obj2)) != -1) - return obj1 > obj2; - } - else if (typeof(obj1) === "string") - { - if (typeof(obj2) === "string") - return obj1 > obj2; - } - else if (ul4._isdate(obj1)) - { - if (ul4._isdate(obj2)) - return obj1.getTime() > obj2.getTime(); - } - else if (ul4._islist(obj1)) - { - if (ul4._islist(obj2)) - { - if (obj1 === obj2) - return false; - for (let i = 0; i < obj1.length; ++i) - { - if (i >= obj2.length) - return true; - let eq = ul4._eq(obj1[i], obj2[i]); - if (!eq) - return ul4._gt(obj1[i], obj2[i]); - } - return obj1.length > obj2.length; - } - } - // FIXME: Set comparison - else if (ul4._isset(obj1) || ul4._isul4set(obj1)) - { - let in1only = false; - let in2only = false; - - if (ul4._isset(obj2)) - { - if (ul4._isset(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.has(value)) - in1only = true; - }); - obj2.forEach(function(value){ - if (!obj1.has(value)) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.items[value]) - in1only = true; - }); - for (let value in obj2.items) - { - if (!obj1.has(value)) - { - in2only = true; - break; - } - } - } - } - else if (ul4._isul4set(obj2)) - { - if (ul4._isset(obj2)) - { - for (let value in obj1.items) - { - if (!obj2.has(value)) - { - in1only = true; - break; - } - } - obj2.forEach(function(value){ - if (!obj1.items[value]) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - for (let value in obj1.items) - { - if (!obj2.items[value]) - { - in1only = true; - break; - } - } - for (let value in obj2.items) - { - if (!obj1.items[value]) - { - in2only = true; - break; - } - } - } - } - else - ul4._unorderable(operator, obj1, obj2); - - if (in1only) - { - if (in2only) - return null; - else - return 1; - } - else - { - if (in2only) - return -1; - else - return 0; - } - } - ul4._unorderable(">", obj1, obj2); - }; - - // Return whether ``obj1 >= obj2`` - ul4._ge = function _ge(obj1, obj2) - { - let numbertypes = ["boolean", "number"]; - - if (obj1 && typeof(obj1.__ge__) === "function") - return obj1.__ge__(obj2); - else if (numbertypes.indexOf(typeof(obj1)) != -1) - { - if (numbertypes.indexOf(typeof(obj2)) != -1) - return obj1 >= obj2; - } - else if (typeof(obj1) === "string") - { - if (typeof(obj2) === "string") - return obj1 >= obj2; - } - else if (ul4._isdate(obj1)) - { - if (ul4._isdate(obj2)) - return obj1.getTime() >= obj2.getTime(); - } - else if (ul4._islist(obj1)) - { - if (ul4._islist(obj2)) - { - if (obj1 === obj2) - return true; - for (let i = 0; i < obj1.length; ++i) - { - if (i >= obj2.length) - return true; - let eq = ul4._eq(obj1[i], obj2[i]); - if (!eq) - return ul4._gt(obj1[i], obj2[i]); - } - return obj1.length >= obj2.length; - } - } - // FIXME: Set comparison - else if (ul4._isset(obj1) || ul4._isul4set(obj1)) - { - let in1only = false; - let in2only = false; - - if (ul4._isset(obj2)) - { - if (ul4._isset(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.has(value)) - in1only = true; - }); - obj2.forEach(function(value){ - if (!obj1.has(value)) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.items[value]) - in1only = true; - }); - for (let value in obj2.items) - { - if (!obj1.has(value)) - { - in2only = true; - break; - } - } - } - } - else if (ul4._isul4set(obj2)) - { - if (ul4._isset(obj2)) - { - for (let value in obj1.items) - { - if (!obj2.has(value)) - { - in1only = true; - break; - } - } - obj2.forEach(function(value){ - if (!obj1.items[value]) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - for (let value in obj1.items) - { - if (!obj2.items[value]) - { - in1only = true; - break; - } - } - for (let value in obj2.items) - { - if (!obj1.items[value]) - { - in2only = true; - break; - } - } - } - } - else - ul4._unorderable(operator, obj1, obj2); - - if (in1only) - { - if (in2only) - return null; - else - return 1; - } - else - { - if (in2only) - return -1; - else - return 0; - } - } - ul4._unorderable(">=", obj1, obj2); - }; - - // Return an iterator for ``obj`` - ul4._iter = function _iter(obj) - { - if (typeof(obj) === "string" || ul4._islist(obj)) - { - return { - index: 0, - next: function() - { - if (this.index < obj.length) - return {value: obj[this.index++], done: false}; - else - return {done: true}; - } - }; - } - else if (ul4._isiter(obj)) - return obj; - else if (obj !== null && typeof(obj.__iter__) === "function") - return obj.__iter__(); - else if (ul4._ismap(obj)) - { - var keys = []; - obj.forEach(function(value, key){ - keys.push(key); - }); - return { - index: 0, - next: function() - { - if (this.index >= keys.length) - return {done: true}; - return {value: keys[this.index++], done: false}; - } - }; - } - else if (ul4._isset(obj)) - { - let values = []; - obj.forEach(function(value, key){ - values.push(value); - }); - return { - index: 0, - next: function() - { - if (this.index >= values.length) - return {done: true}; - return {value: values[this.index++], done: false}; - } - }; - } - else if (ul4._isul4set(obj)) - { - return ul4._iter(obj.items); - } - else if (ul4._isobject(obj)) - { - let keys = []; - for (let key in obj) - keys.push(key); - return { - index: 0, - next: function() - { - if (this.index >= keys.length) - return {done: true}; - return {value: keys[this.index++], done: false}; - } - }; - } - throw ul4.TypeError.create("iter", ul4._type(obj) + " object is not iterable"); - }; - - ul4._str_repr = function _str_repr(str, ascii) - { - let result = ""; - let squote = false, dquote = false; - - for (let i = 0; i "; - else - return ""; - else if (ul4._isdate(obj)) - return ul4._date_repr(obj, ascii); - else if (typeof(obj) === "undefined") - return ""; - else if (typeof(obj) === "object" && typeof(obj.__repr__) === "function") - return obj.__repr__(); - else if (ul4._islist(obj)) - return ul4._list_repr(obj, ascii); - else if (ul4._ismap(obj)) - return ul4._map_repr(obj, ascii); - else if (ul4._isset(obj)) - return ul4._set_repr(obj, ascii); - else if (ul4._isobject(obj)) - return ul4._object_repr(obj, ascii); - return "?"; - }; - - // Return a string representation of ``obj``: If possible this should be an object literal supported by UL4, otherwise the output should be bracketed with ``<`` and ``>`` - ul4._repr = function _repr(obj) - { - return ul4._repr_internal(obj, false); - }; - - ul4._ascii = function _ascii(obj) - { - return ul4._repr_internal(obj, true); - }; - - ul4._date_str = function _date_str(obj) - { - let year = obj.getFullYear(); - let month = obj.getMonth()+1; - let day = obj.getDate(); - let hour = obj.getHours(); - let minute = obj.getMinutes(); - let second = obj.getSeconds(); - let ms = obj.getMilliseconds(); - - let result = year + "-" + ul4._lpad(month.toString(), "0", 2) + "-" + ul4._lpad(day.toString(), "0", 2) + " " + ul4._lpad(hour.toString(), "0", 2) + ":" + ul4._lpad(minute.toString(), "0", 2) + ":" + ul4._lpad(second.toString(), "0", 2); - if (ms) - result += "." + ul4._lpad(ms.toString(), "0", 3) + "000"; - return result; - }; - - ul4._str = function _str(obj) - { - if (typeof(obj) === "undefined") - return ""; - else if (obj === null) - return ""; - else if (obj === false) - return "False"; - else if (obj === true) - return "True"; - else if (typeof(obj) === "string") - return obj; - else if (typeof(obj) === "number") - return obj.toString(); - else if (ul4._isdate(obj)) - return ul4._date_str(obj); - else if (ul4._islist(obj)) - return ul4._list_repr(obj); - else if (ul4._isset(obj)) - return ul4._set_repr(obj); - else if (ul4._ismap(obj)) - return ul4._map_repr(obj); - else if (typeof(obj) === "object" && typeof(obj.__str__) === "function") - return obj.__str__(); - else if (typeof(obj) === "object" && typeof(obj.__repr__) === "function") - return obj.__repr__(); - else if (ul4._isobject(obj)) - return ul4._object_repr(obj); - return "?"; - }; - - // Convert ``obj`` to bool, according to its "truth value" - ul4._bool = function _bool(obj) - { - if (typeof(obj) === "undefined" || obj === null || obj === false || obj === 0 || obj === "") - return false; - else - { - if (typeof(obj) === "object", typeof(obj.__bool__) === "function") - return obj.__bool__(); - if (ul4._islist(obj)) - return obj.length !== 0; - else if (ul4._ismap(obj) || ul4._isset(obj)) - return obj.size != 0; - else if (ul4._isobject(obj)) - { - for (var key in obj) - { - if (!obj.hasOwnProperty(key)) - continue; - return true; - } - return false; - } - return true; - } - }; - - // Convert ``obj`` to an integer (if ``base`` is given ``obj`` must be a string and ``base`` is the base for the conversion (default is 10)) - ul4._int = function _int(obj, base) - { - var result; - if (base !== null) - { - if (typeof(obj) !== "string" || !ul4._isint(base)) - throw ul4.TypeError.create("int()", "int() requires a string and an integer"); - result = parseInt(obj, base); - if (result.toString() == "NaN") - throw ul4.TypeError.create("int()", "invalid literal for int()"); - return result; - } - else - { - if (typeof(obj) == "string") - { - result = parseInt(obj); - if (result.toString() == "NaN") - throw ul4.TypeError.create("int()", "invalid literal for int()"); - return result; - } - else if (typeof(obj) == "number") - return Math.floor(obj); - else if (obj === true) - return 1; - else if (obj === false) - return 0; - throw ul4.TypeError.create("int()", "int() argument must be a string or a number"); - } - }; - - // Convert ``obj`` to a float - ul4._float = function _float(obj) - { - if (typeof(obj) === "string") - return parseFloat(obj); - else if (typeof(obj) === "number") - return obj; - else if (obj === true) - return 1.0; - else if (obj === false) - return 0.0; - throw ul4.TypeError.create("float()", "float() argument must be a string or a number"); - }; - - // Convert ``obj`` to a list - ul4._list = function _list(obj) - { - var iter = ul4._iter(obj); - - var result = []; - for (;;) - { - var value = iter.next(); - if (value.done) - return result; - result.push(value.value); - } - }; - - // Convert ``obj`` to a set - ul4._set = function _set(obj) - { - var iter = ul4._iter(obj); - - var result = ul4on._haveset ? new Set() : ul4._Set.create(); - for (;;) - { - var value = iter.next(); - if (value.done) - return result; - result.add(value.value); - } - }; - - // Return the length of ``sequence`` - ul4._len = function _len(sequence) - { - if (typeof(sequence) == "string" || ul4._islist(sequence)) - return sequence.length; - else if (ul4._ismap(sequence) || ul4._isset(sequence)) - return sequence.size; - else if (ul4._isobject(sequence)) - { - var i = 0; - for (var key in sequence) - ++i; - return i; - } - throw ul4.TypeError.create("len", "object of type '" + ul4._type(sequence) + "' has no len()"); - }; - - ul4._type = function _type(obj) - { - if (obj === null) - return "none"; - else if (obj === false || obj === true) - return "bool"; - else if (typeof(obj) === "undefined") - return "undefined"; - else if (typeof(obj) === "string") - return "str"; - else if (typeof(obj) === "number") - return Math.round(obj) == obj ? "int" : "float"; - else if (ul4._islist(obj)) - return "list"; - else if (ul4._isset(obj)) - return "set"; - else if (ul4._isdate(obj)) - return "date"; - else if (typeof(obj.__type__) !== "undefined") - return obj.__type__; - else if (ul4._istimedelta(obj)) - return "timedelta"; - else if (ul4._isdict(obj)) - return "dict"; - else if (ul4._istemplate(obj)) - return "template"; - else if (ul4._isfunction(obj)) - return "function"; - return null; - }; - - - // Return the attribute with the name ``attrname`` of the object ``obj`` - // If ``obj`` doesn't have such an attribute, return ``default_`` - ul4._getattr = function _getattr(obj, attrname, default_=null) - { - var proto = ul4.Protocol.get(obj); - try - { - return proto.getattr(obj, attrname); - } - catch (exc) - { - if (ul4.AttributeError.isprotoof(exc) && exc.obj === obj) - return default_; - else - throw exc; - } - }; - - // Return wether the object ``obj`` has an attribute with the name ``attrname`` - ul4._hasattr = function _hasattr(obj, attrname) - { - var proto = ul4.Protocol.get(obj); - return proto.hasattr(obj, attrname); - }; - - // Return the names of the attributes of the object ``obj`` as a set. - ul4._dir = function _dir(obj) - { - var proto = ul4.Protocol.get(obj); - return proto.dir(); - }; - - // Return whether any of the items in ``iterable`` are true - ul4._any = function _any(iterable) - { - if (typeof(iterable) == "string") - { - for (var i = 0; i < iterable.length; ++i) - { - if (iterable[i] !== '\x00') - return true; - } - return false; - } - else - { - for (var iter = ul4._iter(iterable);;) - { - var item = iter.next(); - if (item.done) - return false; - if (ul4._bool(item.value)) - return true; - } - } - }; - - // Return whether all of the items in ``iterable`` are true - ul4._all = function _all(iterable) - { - if (typeof(iterable) == "string") - { - for (var i = 0; i < iterable.length; ++i) - { - if (iterable[i] === '\x00') - return false; - } - return true; - } - else - { - for (var iter = ul4._iter(iterable);;) - { - var item = iter.next(); - if (item.done) - return true; - if (!ul4._bool(item.value)) - return false; - } - } - }; - - // Check if ``obj`` is undefined - ul4._isundefined = function _isundefined(obj) - { - return typeof(obj) === "undefined"; - }; - - - // Check if ``obj`` is *not* undefined - ul4._isdefined = function _isdefined(obj) - { - return typeof(obj) !== "undefined"; - }; - - // Check if ``obj`` is ``None`` - ul4._isnone = function _isnone(obj) - { - return obj === null; - }; - - // Check if ``obj`` is a boolean - ul4._isbool = function _isbool(obj) - { - return typeof(obj) == "boolean"; - }; - - // Check if ``obj`` is a int - ul4._isint = function _isint(obj) - { - return (typeof(obj) == "number") && Math.round(obj) == obj; - }; - - // Check if ``obj`` is a float - ul4._isfloat = function _isfloat(obj) - { - return (typeof(obj) == "number") && Math.round(obj) != obj; - }; - - // Check if ``obj`` is a string - ul4._isstr = function _isstr(obj) - { - return typeof(obj) == "string"; - }; - - // Check if ``obj`` is a date - ul4._isdate = function _isdate(obj) - { - return Object.prototype.toString.call(obj) == "[object Date]"; - }; - - // Check if ``obj`` is a color - ul4._iscolor = function _iscolor(obj) - { - return (obj !== null && typeof(obj) === "object" && typeof(obj.isa) === "function" && obj.isa(ul4.Color)); - }; - - // Check if ``obj`` is a timedelta object - ul4._istimedelta = function _istimedelta(obj) - { - return (obj !== null && typeof(obj) === "object" && typeof(obj.isa) === "function" && obj.isa(ul4.TimeDelta)); - }; - - // Check if ``obj`` is a monthdelta object - ul4._ismonthdelta = function _ismonthdelta(obj) - { - return obj !== null && typeof(obj) === "object" && typeof(obj.isa) === "function" && obj.isa(ul4.MonthDelta); - }; - - // Check if ``obj`` is a template - ul4._istemplate = function _istemplate(obj) - { - return Object.prototype.toString.call(obj) == "[object Object]" && (obj.__type__ === "ul4.Template" || obj.__type__ === "ul4.TemplateClosure"); - }; - - // Check if ``obj`` is a function - ul4._isfunction = function _isfunction(obj) - { - return typeof(obj) === "function" || (Object.prototype.toString.call(obj) == "[object Object]" && (obj.__type__ === "ul4.Template" || obj.__type__ === "ul4.TemplateClosure")); - }; - - // Check if ``obj`` is a list - ul4._islist = function _islist(obj) - { - return Object.prototype.toString.call(obj) == "[object Array]"; - }; - - // Check if ``obj`` is a set - ul4._isset = function _isset(obj) - { - return Object.prototype.toString.call(obj) == "[object Set]"; - }; - - // Check if ``obj`` is an exception (at least a UL4 exception) - ul4._isexception = function _isexception(obj) - { - return obj !== null && typeof(obj) === "object" && typeof(obj.isa) === "function" && obj.isa(ul4.Error); - }; - - ul4._isul4set = function _isul4set(obj) - { - return obj !== null && typeof(obj) === "object" && typeof(obj.isa) === "function" && obj.isa(ul4._Set); - }; - - // Check if ``obj`` is an iterator - ul4._isiter = function _isiter(obj) - { - return obj !== null && typeof(obj) === "object" && typeof(obj.next) === "function"; - }; - - // Check if ``obj`` is a JS object - ul4._isobject = function _isobject(obj) - { - return Object.prototype.toString.call(obj) == "[object Object]" && typeof(obj.__type__) === "undefined"; - }; - - if (ul4on._havemap) - { - // Check if ``obj`` is a ``Map`` - ul4._ismap = function _ismap(obj) - { - return obj !== null && typeof(obj) === "object" && typeof(obj.__proto__) === "object" && obj.__proto__ === Map.prototype; - }; - - // Check if ``obj`` is a dict (i.e. a normal Javascript object or a ``Map``) - ul4._isdict = function _isdict(obj) - { - return ul4._isobject(obj) || ul4._ismap(obj); - }; - } - else - { - ul4._ismap = function _ismap(obj) - { - return false; - }; - - ul4._isdict = function _isdict(obj) - { - return ul4._isobject(obj); - }; - } - - // Repeat string ``str`` ``rep`` times - ul4._str_repeat = function _str_repeat(str, rep) - { - let result = ""; - for (; rep>0; --rep) - result += str; - return result; - }; - - ul4._list_repeat = function _list_repeat(list, rep) - { - let result = []; - for (; rep>0; --rep) - for (let i = 0; i < list.length; ++i) - result.push(list[i]); - return result; - }; - - ul4._str_json = function _str_json(str) - { - let result = ""; - for (let i = 0; i < str.length; ++i) - { - let c = str[i]; - switch (c) - { - case "\r": - result += "\\r"; - break; - case "\n": - result += "\\n"; - break; - case "\t": - result += "\\t"; - break; - case "\\": - result += "\\\\"; - break; - case '"': - result += '\\"'; - break; - case '<': - result += '\\u003c'; - break; - default: - let code = str.charCodeAt(i); - if (code >= 32 && code < 128) - result += c; - else - result += "\\u" + ul4._lpad(code.toString(16), "0", 4); - break; - } - } - return '"' + result + '"'; - }; - - // Encodes ``obj`` in the Javascript Object Notation (see http://json.org/; with support for dates, colors and templates) - ul4._asjson = function _asjson(obj) - { - if (obj === null) - return "null"; - else if (typeof(obj) === "undefined") - return "{}.undefined"; - else if (obj === false) - return "false"; - else if (obj === true) - return "true"; - else if (typeof(obj) === "string") - return ul4._str_json(obj); - else if (typeof(obj) === "number") - { - return "" + obj; - } - else if (ul4._islist(obj)) - { - let v = []; - v.push("["); - for (let i = 0; i < obj.length; ++i) - { - if (i != 0) - v.push(", "); - v.push(ul4._asjson(obj[i])); - } - v.push("]"); - return v.join(""); - } - else if (ul4._ismap(obj)) - { - let v = []; - v.push("{"); - let i = 0; - obj.forEach(function(value, key){ - if (i++) - v.push(", "); - v.push(ul4._asjson(key)); - v.push(": "); - v.push(ul4._asjson(value)); - }); - v.push("}"); - return v.join(""); - } - else if (ul4._isobject(obj)) - { - let v = []; - v.push("{"); - let i = 0; - for (let key in obj) - { - if (i++) - v.push(", "); - v.push(ul4._asjson(key)); - v.push(": "); - v.push(ul4._asjson(obj[key])); - } - v.push("}"); - return v.join(""); - } - else if (ul4._isdate(obj)) - { - return "new Date(" + obj.getFullYear() + ", " + obj.getMonth() + ", " + obj.getDate() + ", " + obj.getHours() + ", " + obj.getMinutes() + ", " + obj.getSeconds() + ", " + obj.getMilliseconds() + ")"; - } - else if (ul4._istimedelta(obj)) - { - return "ul4.TimeDelta.create(" + obj.days + ", " + obj.seconds + ", " + obj.microseconds + ")"; - } - else if (ul4._ismonthdelta(obj)) - { - return "ul4.MonthDelta.create(" + obj.months + ")"; - } - else if (ul4._iscolor(obj)) - { - return "ul4.Color.create(" + obj._r + ", " + obj._g + ", " + obj._b + ", " + obj._a + ")"; - } - else if (ul4._istemplate(obj)) - { - return "ul4.Template.loads(" + ul4._repr(obj.dumps()) + ")"; - } - throw ul4.TypeError.create("asjson()", "asjson() requires a serializable object"); - }; - - // Decodes the string ``string`` from the Javascript Object Notation (see http://json.org/) and returns the resulting object - ul4._fromjson = function _fromjson(string) - { - // The following is from jQuery's parseJSON function - string = ul4._strip(string); - if (root.JSON && root.JSON.parse) - return root.JSON.parse(string); - if (ul4._rvalidchars.test(string.replace(ul4._rvalidescape, "@").replace(ul4._rvalidtokens, "]").replace(ul4._rvalidbraces, ""))) - return (new Function("return " + string))(); - throw ul4.TypeError.create("fromjson()", "invalid JSON"); - }; - - // Encodes ``obj`` in the UL4 Object Notation format - ul4._asul4on = function _asul4on(obj) - { - return ul4on.dumps(obj); - }; - - // Decodes the string ``string`` from the UL4 Object Notation format and returns the resulting decoded object - ul4._fromul4on = function _fromul4on(string) - { - return ul4on.loads(string); - }; - - ul4._format_date = function _format_date(obj, fmt, lang) - { - let translations = { - de: { - ms: ["Jan", "Feb", "M\u00e4r", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"], - ml: ["Januar", "Februar", "M\u00e4rz", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], - ws: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], - wl: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - en: { - ms: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], - ml: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], - ws: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], - wl: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], - xf: "%m/%d/%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %I:%M:%S %p " - }, - fr: { - ms: ["janv.", "f\u00e9vr.", "mars", "avril", "mai", "juin", "juil.", "ao\u00fbt", "sept.", "oct.", "nov.", "d\u00e9c."], - ml: ["janvier", "f\u00e9vrier", "mars", "avril", "mai", "juin", "juillet", "ao\u00fbt", "septembre", "octobre", "novembre", "d\u00e9cembre"], - ws: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."], - wl: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], - xf: "%d/%m/%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - es: { - ms: ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"], - ml: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"], - ws: ["dom", "lun", "mar", "mi\u00e9", "jue", "vie", "s\u00e1b"], - wl: ["domingo", "lunes", "martes", "mi\u00e9rcoles", "jueves", "viernes", "s\u00e1bado"], - xf: "%d/%m/%y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - it: { - ms: ["gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic"], - ml: ["gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre"], - ws: ["dom", "lun", "mar", "mer", "gio", "ven", "sab"], - wl: ["domenica", "luned\u00ec", "marted\u00ec", "mercoled\u00ec", "gioved\u00ec", "venerd\u00ec", "sabato"], - xf: "%d/%m/%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - da: { - ms: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"], - ml: ["januar", "februar", "marts", "april", "maj", "juni", "juli", "august", "september", "oktober", "november", "december"], - ws: ["s\u00f8n", "man", "tir", "ons", "tor", "fre", "l\u00f8r"], - wl: ["s\u00f8ndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "l\u00f8rdag"], - xf: "%d-%m-%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - sv: { - ms: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"], - ml: ["januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december"], - ws: ["s\u00f6n", "m\u00e5n", "tis", "ons", "tor", "fre", "l\u00f6r"], - wl: ["s\u00f6ndag", "m\u00e5ndag", "tisdag", "onsdag", "torsdag", "fredag", "l\u00f6rdag"], - xf: "%Y-%m-%d", - Xf: "%H.%M.%S", - cf: "%a %d %b %Y %H.%M.%S" - }, - nl: { - ms: ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"], - ml: ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"], - ws: ["zo", "ma", "di", "wo", "do", "vr", "za"], - wl: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"], - xf: "%d-%m-%y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - pt: { - ms: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"], - ml: ["Janeiro", "Fevereiro", "Mar\u00e7o", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"], - ws: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "S\u00e1b"], - wl: ["Domingo", "Segunda", "Ter\u00e7a", "Quarta", "Quinta", "Sexta", "S\u00e1bado"], - xf: "%d-%m-%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - cs: { - ms: ["led", "\u00fano", "b\u0159e", "dub", "kv\u011b", "\u010den", "\u010dec", "srp", "z\u00e1\u0159", "\u0159\u00edj", "lis", "pro"], - ml: ["leden", "\u00fanor", "b\u0159ezen", "duben", "kv\u011bten", "\u010derven", "\u010dervenec", "srpen", "z\u00e1\u0159\u00ed", "\u0159\u00edjen", "listopad", "prosinec"], - ws: ["Ne", "Po", "\u00dat", "St", "\u010ct", "P\u00e1", "So"], - wl: ["Ned\u011ble", "Pond\u011bl\u00ed", "\u00dater\u00fd", "St\u0159eda", "\u010ctvrtek", "P\u00e1tek", "Sobota"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a\u00a0%d.\u00a0%B\u00a0%Y,\u00a0%H:%M:%S" - }, - sk: { - ms: ["jan", "feb", "mar", "apr", "m\u00e1j", "j\u00fan", "j\u00fal", "aug", "sep", "okt", "nov", "dec"], - ml: ["janu\u00e1r", "febru\u00e1r", "marec", "apr\u00edl", "m\u00e1j", "j\u00fan", "j\u00fal", "august", "september", "okt\u00f3ber", "november", "december"], - ws: ["Ne", "Po", "Ut", "St", "\u0160t", "Pi", "So"], - wl: ["Nede\u013ea", "Pondelok", "Utorok", "Streda", "\u0160tvrtok", "Piatok", "Sobota"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a\u00a0%d.\u00a0%B\u00a0%Y,\u00a0%H:%M:%S" - }, - pl: { - ms: ["sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "pa\u017a", "lis", "gru"], - ml: ["stycze\u0144", "luty", "marzec", "kwiecie\u0144", "maj", "czerwiec", "lipiec", "sierpie\u0144", "wrzesie\u0144", "pa\u017adziernik", "listopad", "grudzie\u0144"], - ws: ["nie", "pon", "wto", "\u015bro", "czw", "pi\u0105", "sob"], - wl: ["niedziela", "poniedzia\u0142ek", "wtorek", "\u015broda", "czwartek", "pi\u0105tek", "sobota"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a, %d %b %Y, %H:%M:%S" - }, - hr: { - ms: ["Sij", "Vel", "O\u017eu", "Tra", "Svi", "Lip", "Srp", "Kol", "Ruj", "Lis", "Stu", "Pro"], - ml: ["Sije\u010danj", "Velja\u010da", "O\u017eujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"], - ws: ["Ned", "Pon", "Uto", "Sri", "\u010cet", "Pet", "Sub"], - wl: ["Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "\u010cetvrtak", "Petak", "Subota"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - sr: { - ms: ["\u0458\u0430\u043d", "\u0444\u0435\u0431", "\u043c\u0430\u0440", "\u0430\u043f\u0440", "\u043c\u0430\u0458", "\u0458\u0443\u043d", "\u0458\u0443\u043b", "\u0430\u0432\u0433", "\u0441\u0435\u043f", "\u043e\u043a\u0442", "\u043d\u043e\u0432", "\u0434\u0435\u0446"], - ml: ["\u0458\u0430\u043d\u0443\u0430\u0440", "\u0444\u0435\u0431\u0440\u0443\u0430\u0440", "\u043c\u0430\u0440\u0442", "\u0430\u043f\u0440\u0438\u043b", "\u043c\u0430\u0458", "\u0458\u0443\u043d", "\u0458\u0443\u043b", "\u0430\u0432\u0433\u0443\u0441\u0442", "\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440", "\u043e\u043a\u0442\u043e\u0431\u0430\u0440", "\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440", "\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440"], - ws: ["\u043d\u0435\u0434", "\u043f\u043e\u043d", "\u0443\u0442\u043e", "\u0441\u0440\u0435", "\u0447\u0435\u0442", "\u043f\u0435\u0442", "\u0441\u0443\u0431"], - wl: ["\u043d\u0435\u0434\u0435\u0459\u0430", "\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a", "\u0443\u0442\u043e\u0440\u0430\u043a", "\u0441\u0440\u0435\u0434\u0430", "\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a", "\u043f\u0435\u0442\u0430\u043a", "\u0441\u0443\u0431\u043e\u0442\u0430"], - xf: "%d.%m.%Y.", - Xf: "%H:%M:%S", - cf: "%A, %d. %B %Y. %H:%M:%S" - }, - ro: { - ms: ["ian", "feb", "mar", "apr", "mai", "iun", "iul", "aug", "sep", "oct", "nov", "dec"], - ml: ["ianuarie", "februarie", "martie", "aprilie", "mai", "iunie", "iulie", "august", "septembrie", "octombrie", "noiembrie", "decembrie"], - ws: ["Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sb"], - wl: ["duminic\u0103", "luni", "mar\u0163i", "miercuri", "joi", "vineri", "s\u00e2mb\u0103t\u0103"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - hu: { - ms: ["jan", "febr", "m\u00e1rc", "\u00e1pr", "m\u00e1j", "j\u00fan", "j\u00fal", "aug", "szept", "okt", "nov", "dec"], - ml: ["janu\u00e1r", "febru\u00e1r", "m\u00e1rcius", "\u00e1prilis", "m\u00e1jus", "j\u00fanius", "j\u00falius", "augusztus", "szeptember", "okt\u00f3ber", "november", "december"], - ws: ["v", "h", "k", "sze", "cs", "p", "szo"], - wl: ["vas\u00e1rnap", "h\u00e9tf\u0151", "kedd", "szerda", "cs\u00fct\u00f6rt\u00f6k", "p\u00e9ntek", "szombat"], - xf: "%Y-%m-%d", - Xf: "%H.%M.%S", - cf: "%Y. %b. %d., %A, %H.%M.%S" - }, - tr: { - ms: ["Oca", "\u015eub", "Mar", "Nis", "May", "Haz", "Tem", "A\u011fu", "Eyl", "Eki", "Kas", "Ara"], - ml: ["Ocak", "\u015eubat", "Mart", "Nisan", "May\u0131s", "Haziran", "Temmuz", "A\u011fustos", "Eyl\u00fcl", "Ekim", "Kas\u0131m", "Aral\u0131k"], - ws: ["Paz", "Pzt", "Sal", "\u00c7r\u015f", "Pr\u015f", "Cum", "Cts"], - wl: ["Pazar", "Pazartesi", "Sal\u0131", "\u00c7ar\u015famba", "Per\u015fembe", "Cuma", "Cumartesi"], - xf: "%d-%m-%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - ru: { - ms: ["\u042f\u043d\u0432", "\u0424\u0435\u0432", "\u041c\u0430\u0440", "\u0410\u043f\u0440", "\u041c\u0430\u0439", "\u0418\u044e\u043d", "\u0418\u044e\u043b", "\u0410\u0432\u0433", "\u0421\u0435\u043d", "\u041e\u043a\u0442", "\u041d\u043e\u044f", "\u0414\u0435\u043a"], - ml: ["\u042f\u043d\u0432\u0430\u0440\u044c", "\u0424\u0435\u0432\u0440\u0430\u043b\u044c", "\u041c\u0430\u0440\u0442", "\u0410\u043f\u0440\u0435\u043b\u044c", "\u041c\u0430\u0439", "\u0418\u044e\u043d\u044c", "\u0418\u044e\u043b\u044c", "\u0410\u0432\u0433\u0443\u0441\u0442", "\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c", "\u041e\u043a\u0442\u044f\u0431\u0440\u044c", "\u041d\u043e\u044f\u0431\u0440\u044c", "\u0414\u0435\u043a\u0430\u0431\u0440\u044c"], - ws: ["\u0412\u0441\u043a", "\u041f\u043d\u0434", "\u0412\u0442\u0440", "\u0421\u0440\u0434", "\u0427\u0442\u0432", "\u041f\u0442\u043d", "\u0421\u0431\u0442"], - wl: ["\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435", "\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a", "\u0412\u0442\u043e\u0440\u043d\u0438\u043a", "\u0421\u0440\u0435\u0434\u0430", "\u0427\u0435\u0442\u0432\u0435\u0440\u0433", "\u041f\u044f\u0442\u043d\u0438\u0446\u0430", "\u0421\u0443\u0431\u0431\u043e\u0442\u0430"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - zh: { - ms: [" 1\u6708", " 2\u6708", " 3\u6708", " 4\u6708", " 5\u6708", " 6\u6708", " 7\u6708", " 8\u6708", " 9\u6708", "10\u6708", "11\u6708", "12\u6708"], - ml: ["\u4e00\u6708", "\u4e8c\u6708", "\u4e09\u6708", "\u56db\u6708", "\u4e94\u6708", "\u516d\u6708", "\u4e03\u6708", "\u516b\u6708", "\u4e5d\u6708", "\u5341\u6708", "\u5341\u4e00\u6708", "\u5341\u4e8c\u6708"], - ws: ["\u65e5", "\u4e00", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d"], - wl: ["\u661f\u671f\u65e5", "\u661f\u671f\u4e00", "\u661f\u671f\u4e8c", "\u661f\u671f\u4e09", "\u661f\u671f\u56db", "\u661f\u671f\u4e94", "\u661f\u671f\u516d"], - xf: "%Y\u5e74%b%d\u65e5", - Xf: "%H\u65f6%M\u5206%S\u79d2", - cf: "%Y\u5e74%b%d\u65e5 %A %H\u65f6%M\u5206%S\u79d2" - }, - ko: { - ms: [" 1\uc6d4", " 2\uc6d4", " 3\uc6d4", " 4\uc6d4", " 5\uc6d4", " 6\uc6d4", " 7\uc6d4", " 8\uc6d4", " 9\uc6d4", "10\uc6d4", "11\uc6d4", "12\uc6d4"], - ml: ["1\uc6d4", "2\uc6d4", "3\uc6d4", "4\uc6d4", "5\uc6d4", "6\uc6d4", "7\uc6d4", "8\uc6d4", "9\uc6d4", "10\uc6d4", "11\uc6d4", "12\uc6d4"], - ws: ["\uc77c", "\uc6d4", "\ud654", "\uc218", "\ubaa9", "\uae08", "\ud1a0"], - wl: ["\uc77c\uc694\uc77c", "\uc6d4\uc694\uc77c", "\ud654\uc694\uc77c", "\uc218\uc694\uc77c", "\ubaa9\uc694\uc77c", "\uae08\uc694\uc77c", "\ud1a0\uc694\uc77c"], - xf: "%Y\ub144 %B %d\uc77c", - Xf: "%H\uc2dc %M\ubd84 %S\ucd08", - cf: "%Y\ub144 %B %d\uc77c (%a) %p %I\uc2dc %M\ubd84 %S\ucd08" - }, - ja: { - ms: [" 1\u6708", " 2\u6708", " 3\u6708", " 4\u6708", " 5\u6708", " 6\u6708", " 7\u6708", " 8\u6708", " 9\u6708", "10\u6708", "11\u6708", "12\u6708"], - ml: ["1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708"], - ws: ["\u65e5", "\u6708", "\u706b", "\u6c34", "\u6728", "\u91d1", "\u571f"], - wl: ["\u65e5\u66dc\u65e5", "\u6708\u66dc\u65e5", "\u706b\u66dc\u65e5", "\u6c34\u66dc\u65e5", "\u6728\u66dc\u65e5", "\u91d1\u66dc\u65e5", "\u571f\u66dc\u65e5"], - xf: "%Y\u5e74%B%d\u65e5", - Xf: "%H\u6642%M\u5206%S\u79d2", - cf: "%Y\u5e74%B%d\u65e5 %H\u6642%M\u5206%S\u79d2" - } - }; - - let translation = translations[lang]; - - let firstday; - - let result = []; - let inspec = false; - for (let i = 0; i < fmt.length; ++i) - { - let c = fmt[i]; - if (inspec) - { - switch (c) - { - case "a": - c = translation.ws[obj.getDay()]; - break; - case "A": - c = translation.wl[obj.getDay()]; - break; - case "b": - c = translation.ms[obj.getMonth()]; - break; - case "B": - c = translation.ml[obj.getMonth()]; - break; - case "c": - c = ul4._format(obj, translation.cf, lang); - break; - case "d": - c = ul4._lpad(obj.getDate(), "0", 2); - break; - case "f": - c = ul4._lpad(obj.getMilliseconds(), "0", 3) + "000"; - break; - case "H": - c = ul4._lpad(obj.getHours(), "0", 2); - break; - case "I": - c = ul4._lpad(((obj.getHours()-1) % 12)+1, "0", 2); - break; - case "j": - c = ul4._lpad(ul4._yearday(obj), "0", 3); - break; - case "m": - c = ul4._lpad(obj.getMonth()+1, "0", 2); - break; - case "M": - c = ul4._lpad(obj.getMinutes(), "0", 2); - break; - case "p": - c = obj.getHours() < 12 ? "AM" : "PM"; - break; - case "S": - c = ul4._lpad(obj.getSeconds(), "0", 2); - break; - case "U": - c = ul4._lpad(ul4._week(obj, 6), "0", 2); - break; - case "w": - c = obj.getDay(); - break; - case "W": - c = ul4._lpad(ul4._week(obj, 0), "0", 2); - break; - case "x": - c = ul4._format(obj, translation.xf, lang); - break; - case "X": - c = ul4._format(obj, translation.Xf, lang); - break; - case "y": - c = (obj.getFullYear() % 100).toString(); - break; - case "Y": - c = obj.getFullYear().toString(); - break; - case "z": - // UTC offset in the form +HHMM or -HHMM - c = ""; - break; - case "Z": - // Time zone name - c = ""; - break; - } - result.push(c); - inspec = false; - } - else - { - if (c == "%") - inspec = true; - else - result.push(c); - } - } - return result.join(""); - }; - - ul4._format_int = function _format_int(obj, fmt, lang) - { - let work = fmt; - - // Defaults - let fill = ' '; - let align = '>'; // '<', '>', '=' or '^' - let sign = '-'; // '+', '-' or ' ' - let alternate = false; - let minimumwidth = 0; - let type = 'd'; // 'b', 'c', 'd', 'o', 'x', 'X' or 'n' - - // Determine output type - if (/[bcdoxXn]$/.test(work)) - { - type = work.substring(work.length-1); - work = work.substring(0, work.length-1); - } - - // Extract minimum width - if (/\d+$/.test(work)) - { - let minimumwidthStr = /\d+$/.exec(work); - work = work.replace(/\d+$/, ""); - if (/^0/.test(minimumwidthStr)) - { - align = '='; - fill = '0'; - } - minimumwidth = parseInt(minimumwidthStr); - } - - // Alternate form? - if (/#$/.test(work)) - { - alternate = true; - work = work.substring(0, work.length-1); - } - - // Determine sign - if (/[+ -]$/.test(work)) - { - if (type == 'c') - throw ul4.ValueError.create("sign not allowed for integer format type 'c'"); - sign = work.substring(work.length-1); - work = work.substring(0, work.length-1); - } - - // Extract fill and align char - if (work.length >= 3) - throw ul4.ValueError.create("illegal integer format string " + ul4._repr(fmt)); - else if (work.length == 2) - { - if (/[<>=^]$/.test(work)) - { - align = work[1]; - fill = work[0]; - } - else - throw ul4.ValueError.create("illegal integer format string " + ul4._repr(fmt)); - } - else if (work.length == 1) - { - if (/^[<>=^]$/.test(work)) - align = work; - else - throw ul4.ValueError.create("illegal integer format string " + ul4._repr(fmt)); - } - - // Basic number formatting - let neg = obj < 0; - - if (neg) - obj = -obj; - - let output; - switch (type) - { - case 'b': - output = obj.toString(2); - break; - case 'c': - if (neg || obj > 65535) - throw ul4.ValueError.create("value out of bounds for c format"); - output = String.fromCharCode(obj); - break; - case 'd': - output = obj.toString(); - break; - case 'o': - output = obj.toString(8); - break; - case 'x': - output = obj.toString(16); - break; - case 'X': - output = obj.toString(16).toUpperCase(); - break; - case 'n': - // FIXME: locale formatting - output = obj.toString(); - break; - } - - // The rest of the formatting - if (align === '=') - { - if (neg || sign !== '-') - --minimumwidth; - if (alternate && (type === 'b' || type === 'o' || type === 'x' || type === 'X')) - minimumwidth -= 2; - - if (output.length < minimumwidth) - output = ul4._str_repeat(fill, minimumwidth-output.length) + output; - - if (alternate && (type === 'b' || type === 'o' || type === 'x' || type === 'X')) - output = "0" + type + output; - - if (neg) - output = "-" + output; - else if (sign != '-') - output = sign + output; - } - else - { - if (alternate && (type == 'b' || type == 'o' || type == 'x' || type == 'X')) - output = "0" + type + output; - if (neg) - output = "-" + output; - else if (sign != '-') - output = sign + output; - if (output.length < minimumwidth) - { - if (align == '<') - output = output + ul4._str_repeat(fill, minimumwidth-output.length); - else if (align == '>') - output = ul4._str_repeat(fill, minimumwidth-output.length) + output; - else // if (align == '^') - { - let pad = minimumwidth - output.length; - let padBefore = Math.floor(pad/2); - let padAfter = pad-padBefore; - output = ul4._str_repeat(fill, padBefore) + output + ul4._str_repeat(fill, padAfter); - } - } - } - return output; - }; - - // Format ``obj`` using the format string ``fmt`` in the language ``lang`` - ul4._format = function _format(obj, fmt, lang) - { - if (typeof(lang) === "undefined" || lang === null) - lang = "en"; - else - { - let translations = {de: null, en: null, fr: null, es: null, it: null, da: null, sv: null, nl: null, pt: null, cs: null, sk: null, pl: null, hr: null, sr: null, ro: null, hu: null, tr: null, ru: null, zh: null, ko: null, ja: null}; - lang = lang.toLowerCase(); - if (typeof(translations[lang]) === "undefined") - { - lang = lang.split(/_/)[0]; - if (typeof(translations[lang]) === "undefined") - lang = "en"; - } - } - if (ul4._isdate(obj)) - return ul4._format_date(obj, fmt, lang); - else if (ul4._isint(obj)) - return ul4._format_int(obj, fmt, lang); - else if (obj === true) - return ul4._format_int(1, fmt, lang); - else if (obj === false) - return ul4._format_int(0, fmt, lang); - }; - - ul4._lpad = function _lpad(string, pad, len) - { - if (typeof(string) === "number") - string = string.toString(); - while (string.length < len) - string = pad + string; - return string; - }; - - ul4._rpad = function _rpad(string, pad, len) - { - if (typeof(string) === "number") - string = string.toString(); - while (string.length < len) - string = string + pad; - return string; - }; - - ul4.Proto = { - __prototype__: null, - __id__: 0, - _nextid: 1, - isa: function isa(type) - { - if (this === type) - return true; - if (this.__prototype__ === null) - return false; - return this.__prototype__.isa(type); - }, - - isprotoof: function isprotoof(obj) - { - while (true) - { - if (obj === null || Object.prototype.toString.call(obj) !== "[object Object]" || typeof(obj.__prototype__) === "undefined") - return false; - if (obj === this) - return true; - obj = obj.__prototype__; - } - }, - - // equality comparison of objects defaults to identity comparison - __eq__: function __eq__(other) - { - return this === other; - }, - - // To overwrite equality comparison, you only have to overwrite ``__eq__``, - // ``__ne__`` will be synthesized from that - __ne__: function __ne__(other) - { - return !this.__eq__(other); - }, - - // For other comparison operators, each method has to be implemented: - // ``<`` calls ``__lt__``, ``<=`` calls ``__le__``, ``>`` calls ``__gt__`` and - // ``>=`` calls ``__ge__`` - - __bool__: function __bool__() - { - return true; - } - }; - - ul4.Signature = ul4._inherit( - ul4.Proto, - { - create: function create(...args) - { - let signature = ul4._clone(this); - signature.args = []; - signature.argNames = {}; - signature.remargs = null; - signature.remkwargs = null; - - let nextDefault = false; - let lastArgname = null; - for (let i = 0; i < args.length; ++i) - { - let argName = args[i]; - if (nextDefault) - { - signature.args.push({name: lastArgname, defaultValue: argName}); - signature.argNames[lastArgname] = true; - nextDefault = false; - } - else - { - if (argName.substr(argName.length-1) === "=") - { - lastArgname = argName.substr(0, argName.length-1); - nextDefault = true; - } - else if (argName.substr(0, 2) === "**") - signature.remkwargs = argName.substr(2); - else if (argName.substr(0, 1) === "*") - signature.remargs = argName.substr(1); - else - { - signature.args.push({name: argName}); - signature.argNames[argName] = true; - } - } - } - return signature; - }, - - // Create the argument array for calling a function with this signature with the arguments available from ``args`` - bindArray: function bindArray(name, args, kwargs) - { - let finalargs = []; - let decname = name !== null ? name + "() " : ""; - - for (let i = 0; i < this.args.length; ++i) - { - let arg = this.args[i]; - if (i < args.length) - { - if (kwargs.hasOwnProperty(arg.name)) - throw ul4.ArgumentError.create(decname + "argument " + ul4._repr(arg.name) + " (position " + i + ") specified multiple times"); - finalargs.push(args[i]); - } - else - { - if (kwargs.hasOwnProperty(arg.name)) - finalargs.push(kwargs[arg.name]); - else - { - if (arg.hasOwnProperty("defaultValue")) - finalargs.push(arg.defaultValue); - else - throw ul4.ArgumentError.create("required " + decname + "argument " + ul4._repr(arg.name) + " (position " + i + ") missing"); - } - } - } - - // Do we accept additional positional arguments? - if (this.remargs === null) - { - // No, but we have them -> complain - if (args.length > this.args.length) - { - let prefix = name === null ? "expected" : name + "() expects"; - throw ul4.ArgumentError.create(prefix + " at most " + this.args.length + " positional argument" + (this.args.length != 1 ? "s" : "") + ", " + args.length + " given"); - } - } - else - { - // Put additional positional arguments in the call into the ``*`` argument (if there are none, this pushes an empty list) - finalargs.push(args.slice(this.args.length)); - } - - // Do we accept arbitrary keyword arguments? - if (this.remkwargs === null) - { - // No => complain about unknown ones - for (let key in kwargs) - { - if (!this.argNames[key]) - { - if (name === null) - throw ul4.ArgumentError.create("an argument named " + ul4._repr(key) + " isn't supported"); - else - throw ul4.ArgumentError.create(name + "() doesn't support an argument named " + ul4._repr(key)); - } - } - } - else - { - // Yes => Put the unknown ones into an object and add that to the arguments array - let remkwargs = ul4on._emptymap(); - for (let key in kwargs) - { - if (!this.argNames[key]) - ul4on._setmap(remkwargs, key, kwargs[key]); - } - finalargs.push(remkwargs); - } - - return finalargs; - }, - - // Create the argument object for calling a function with this signature with the arguments available from ``args`` - bindObject: function bindObject(name, args, kwargs) - { - args = this.bindArray(name, args, kwargs); - let argObject = {}; - let i; - for (i = 0; i < this.args.length; ++i) - argObject[this.args[i].name] = args[i]; - if (this.remargs !== null) - argObject[this.remargs] = args[i++]; - if (this.remkwargs !== null) - argObject[this.remkwargs] = args[i++]; - return argObject; - }, - - __repr__: function __repr__() - { - return ""; - }, - - __str__: function __str__() - { - return this.toString(); - }, - - toString: function toString() - { - let v = []; - for (let i = 0; i < this.args.length; ++i) - { - let arg = this.args[i]; - - if (arg.hasOwnProperty("defaultValue")) - v.push(arg.name + "=" + ul4._repr(arg.defaultValue)); - else - v.push(arg.name); - } - if (this.remargs !== null) - v.push("*" + this.remargs); - if (this.remkwargs !== null) - v.push("**" + this.remkwargs); - return "(" + v.join(", ") + ")"; - } - } - ); - - // Adds name and signature to a function/method and makes the method callable in templates - ul4.expose = function expose(signature, options, f) - { - if (typeof(f) === "undefined") - { - f = options; - options = {}; - } - if (options.name) - f._ul4_name = options.name; - if (ul4._islist(signature)) - signature = ul4.Signature.create.apply(ul4.Signature, signature); - f._ul4_signature = signature; - f._ul4_needsobject = options.needsobject || false; - f._ul4_needscontext = options.needscontext || false; - - return f; - }; - - // Protocol objects for all builtin types - ul4.Protocol = { - attrs: ul4on._emptyset(), - - dir: function dir() { - return this.attrs; - }, - - get: function get(obj) - { - if (ul4._isstr(obj)) - return ul4.StrProtocol; - else if (ul4._islist(obj)) - return ul4.ListProtocol; - else if (ul4._isset(obj)) - return ul4.SetProtocol; - else if (ul4._ismap(obj)) - return ul4.MapProtocol; - else if (ul4._isobject(obj)) - return ul4.ObjectProtocol; - else if (ul4._isdate(obj)) - return ul4.DateProtocol; - else - return ul4.Protocol; - }, - - getattr: function getattr(obj, attrname) - { - if (obj === null || typeof(obj) === "undefined") - throw ul4.AttributeError.create(obj, attrname); - else if (typeof(obj.__getattr__) === "function") - return obj.__getattr__(attrname); - else if (this.attrs.has(attrname)) - { - let attr = this[attrname]; - let realattr = function realattr(...args) { - return attr.apply(this, [obj, ...args]); - }; - realattr.name = attr.name; - realattr._ul4_name = attr._ul4_name || attr.name; - realattr._ul4_signature = attr._ul4_signature; - realattr._ul4_needsobject = attr._ul4_needsobject; - realattr._ul4_needscontext = attr._ul4_needscontext; - return realattr; - } - else - throw ul4.AttributeError.create(obj, attrname); - }, - - hasattr: function hasattr(obj, attrname) - { - if (obj === null || typeof(obj) === "undefined") - return false; - else if (typeof(obj.__getattr__) === "function") - { - try - { - obj.__getattr__(attrname); - return true; - } - catch (exc) - { - if (ul4.AttributeError.isprotoof(exc) && exc.obj === object) - return false; - else - throw exc; - } - } - else - return this.attrs.has(attrname); - } - }; - - ul4.StrProtocol = ul4._inherit(ul4.Protocol, { - name: "str", - - attrs: ul4on._makeset( - "split", - "rsplit", - "splitlines", - "strip", - "lstrip", - "rstrip", - "upper", - "lower", - "capitalize", - "startswith", - "endswith", - "replace", - "count", - "find", - "rfind", - "join" - ), - - count: ul4.expose(["sub", "start=", null, "end=", null], function count(obj, sub, start, end){ - return ul4._count(obj, sub, start, end); - }), - - find: ul4.expose(["sub", "start=", null, "end=", null], function find(obj, sub, start, end){ - return ul4._find(obj, sub, start, end); - }), - - rfind: ul4.expose(["sub", "start=", null, "end=", null], function rfind(obj, sub, start, end){ - return ul4._rfind(obj, sub, start, end); - }), - - replace: ul4.expose(["old", "new", "count=", null], function replace(obj, old, new_, count){ - return ul4._replace(obj, old, new_, count); - }), - - strip: ul4.expose(["chars=", null], function strip(obj, chars){ - return ul4._strip(obj, chars); - }), - - lstrip: ul4.expose(["chars=", null], function lstrip(obj, chars){ - return ul4._lstrip(obj, chars); - }), - - rstrip: ul4.expose(["chars=", null], function rstrip(obj, chars){ - return ul4._rstrip(obj, chars); - }), - - split: ul4.expose(["sep=", null, "count=", null], function split(obj, sep, count){ - return ul4._split(obj, sep, count); - }), - - rsplit: ul4.expose(["sep=", null, "count=", null], function rsplit(obj, sep, count){ - return ul4._rsplit(obj, sep, count); - }), - - splitlines: ul4.expose(["keepends=", false], function splitlines(obj, keepends){ - return ul4._splitlines(obj, keepends); - }), - - lower: ul4.expose([], function lower(obj){ - return obj.toLowerCase(); - }), - - upper: ul4.expose([], function upper(obj){ - return obj.toUpperCase(); - }), - - capitalize: ul4.expose([], function capitalize(obj){ - return ul4._capitalize(obj); - }), - - join: ul4.expose(["iterable"], function join(obj, iterable){ - return ul4._join(obj, iterable); - }), - - startswith: ul4.expose(["prefix"], function startswith(obj, prefix){ - return ul4._startswith(obj, prefix); - }), - - endswith: ul4.expose(["suffix"], function endswith(obj, suffix){ - return ul4._endswith(obj, suffix); - }) - }); - - ul4.ListProtocol = ul4._inherit(ul4.Protocol, { - name: "list", - - attrs: ul4on._makeset("append", "insert", "pop", "count", "find", "rfind"), - - append: ul4.expose(["*items"], function append(obj, items){ - return ul4._append(obj, ...items); - }), - - insert: ul4.expose(["pos", "*items"], function insert(obj, pos, items){ - return ul4._insert(obj, pos, ...items); - }), - - pop: ul4.expose(["pos=", -1], function pop(obj, pos){ - return ul4._pop(obj, pos); - }), - - count: ul4.expose(["sub", "start=", null, "end=", null], function count(obj, sub, start, end){ - return ul4._count(obj, sub, start, end); - }), - - find: ul4.expose(["sub", "start=", null, "end=", null], function find(obj, sub, start, end){ - return ul4._find(obj, sub, start, end); - }), - - rfind: ul4.expose(["sub", "start=", null, "end=", null], function rfind(obj, sub, start, end){ - return ul4._rfind(obj, sub, start, end); - }) - }); - - - ul4.MapProtocol = ul4._inherit(ul4.Protocol, { - name: "dict", - - attrs: ul4on._makeset("get", "items", "values", "update", "clear"), - - getattr: function getattr(obj, attrname) - { - if (this.attrs.has(attrname)) - { - let attr = this[attrname]; - let realattr = function realattr(...args) { - return attr.apply(this, [obj, ...args]); - }; - realattr.name = attr.name; - realattr._ul4_name = attr._ul4_name || attr.name; - realattr._ul4_signature = attr._ul4_signature; - realattr._ul4_needsobject = attr._ul4_needsobject; - realattr._ul4_needscontext = attr._ul4_needscontext; - return realattr; - } - else - return obj.get(attrname); - }, - - get: ul4.expose(["key", "default=", null], function get(obj, key, default_){ - return ul4._get(obj, key, default_); - }), - - items: ul4.expose([], function items(obj){ - return ul4._items(obj); - }), - - values: ul4.expose([], function values(obj){ - return ul4._values(obj); - }), - - update: ul4.expose(["*other", "**kwargs"], function update(obj, other, kwargs){ - return ul4._update(obj, other, kwargs); - }), - - clear: ul4.expose([], function clear(obj){ - return ul4._clear(obj); - }) - }); - - ul4.SetProtocol = ul4._inherit(ul4.Protocol, { - name: "set", - - attrs: ul4on._makeset("add", "clear"), - - add: ul4.expose(["*items"], function add(obj, items){ - for (let i = 0; i < items.length; ++i) - obj.add(items[i]); - }), - - clear: ul4.expose([], function clear(obj){ - return ul4._clear(obj); - }) - }); - - ul4.DateProtocol = ul4._inherit(ul4.Protocol, { - name: "date", - - attrs: ul4on._makeset("weekday", "week", "day", "month", "year", "hour", "minute", "second", "microsecond", "mimeformat", "isoformat", "yearday"), - - weekday: ul4.expose([], function weekday(obj){ - return ul4._weekday(obj); - }), - - week: ul4.expose(["firstweekday=", null], function week(obj, firstweekday){ - return ul4._week(obj, firstweekday); - }), - - day: ul4.expose([], function day(obj){ - return obj.getDate(); - }), - - month: ul4.expose([], function month(obj){ - return obj.getMonth()+1; - }), - - year: ul4.expose([], function year(obj){ - return obj.getFullYear(); - }), - - hour: ul4.expose([], function hour(obj){ - return obj.getHours(); - }), - - minute: ul4.expose([], function minute(obj){ - return obj.getMinutes(); - }), - - second: ul4.expose([], function second(obj){ - return obj.getSeconds(); - }), - - microsecond: ul4.expose([], function microsecond(obj){ - return obj.getMilliseconds() * 1000; - }), - - mimeformat: ul4.expose([], function mimeformat(obj){ - return ul4._mimeformat(obj); - }), - - isoformat: ul4.expose([], function isoformat(obj){ - return ul4._isoformat(obj); - }), - - yearday: ul4.expose([], function yearday(obj){ - return ul4._yearday(obj); - }) - }); - - ul4.ObjectProtocol = ul4._inherit(ul4.Protocol, { - name: "dict", - - getattr: function getattr(obj, attrname) - { - let result; - if (obj && typeof(obj.__getattr__) === "function") // test this before the generic object test - result = obj.__getattr__(attrname); - else - result = obj[attrname]; - if (typeof(result) !== "function") - return result; - let realresult = function(...args) { - // We can use ``apply`` here, as we know that ``obj`` is a real object. - return result.apply(obj, args); - }; - realresult._ul4_name = result._ul4_name || result.name; - realresult._ul4_signature = result._ul4_signature; - realresult._ul4_needsobject = result._ul4_needsobject; - realresult._ul4_needscontext = result._ul4_needscontext; - return realresult; - } - }); - - ul4.Context = ul4._inherit( - ul4.Proto, - { - create: function create(vars) - { - if (vars === null || typeof(vars) === "undefined") - vars = {}; - let context = ul4._clone(this); - context.vars = vars; - context.indents = []; - context._output = []; - return context; - }, - - /* Return a clone of the ``Context``, but with a fresh empty ``vars`` objects that inherits from the previous one. - * This is used by the various comprehensions to avoid leaking loop variables. - */ - inheritvars: function inheritvars() - { - let context = ul4._clone(this); - context.vars = ul4._simpleclone(this.vars); - return context; - }, - - /* Return a clone of the ``Context`` with one additional indentation (this is used by ``RenderAST``) */ - withindent: function withindent(indent) - { - let context = ul4._clone(this); - if (indent !== null) - { - context.indents = this.indents.slice(); - context.indents.push(indent); - } - return context; - }, - - /* Return a clone of the ``Context`` with the output buffer replaced (this is used by ``renders`` to collect the output in a separate buffer) */ - replaceoutput: function replaceoutput() - { - let context = ul4._clone(this); - context._output = []; - return context; - }, - - clone: function clone(vars) - { - return ul4._clone(this); - }, - - output: function output(value) - { - this._output.push(value); - }, - - getoutput: function getoutput() - { - return this._output.join(""); - }, - - get: function get(name) - { - return this.vars[name]; - }, - - set: function set(name, value) - { - this.vars[name] = value; - } - } - ); - - /// Exceptions - - ul4.Exception = ul4._inherit( - ul4.Proto, - { - __type__: "ul4.Exception", - "cause": null, - - create: function create(result) - { - let exception = ul4._clone(this); - return exception; - }, - - __getattr__: function __getattr__(attrname) - { - switch (attrname) - { - case "cause": - return this.cause; - default: - throw ul4.AttributeError.create(this, attrname); - } - } - } - ); - - // Exceptions used internally by UL4 for flow control - ul4.InternalException = ul4._inherit(ul4.Exception, {}); - - // Control flow exceptions - ul4.ReturnException = ul4._inherit( - ul4.InternalException, - { - __type__: "ul4.ReturnException", - - create: function create(result) - { - let exception = ul4.InternalException.create.call(this); - exception.result = result; - return exception; - } - } - ); - - ul4.BreakException = ul4._inherit( - ul4.InternalException, - { - __type__: "ul4.BreakException" - } - ); - - ul4.ContinueException = ul4._inherit( - ul4.InternalException, - { - __type__: "ul4.ContinueException" - } - ); - - // Real exceptions raised by various parts of UL4 - ul4.SyntaxError = ul4._inherit( - ul4.Exception, - { - __type__: "ul4.SyntaxError" - } - ); - - ul4.LValueRequiredError = ul4._inherit( - ul4.SyntaxError, - { - __type__: "ul4.LValueRequiredError", - - toString: function toString() - { - return "lvalue required!"; - } - } - ); - - ul4.TypeError = ul4._inherit( - ul4.Exception, - { - __type__: "ul4.TypeError", - - create: function create(operation, message) - { - let exception = ul4._clone(this); - exception.operation = operation; - exception.message = message; - return exception; - }, - toString: function toString() - { - return this.message; - } - } - ); - - ul4.ValueError = ul4._inherit( - ul4.Exception, - { - __type__: "ul4.ValueError", - - create: function create(message) - { - let exception = ul4._clone(this); - exception.message = message; - return exception; - }, - toString: function toString() - { - return this.message; - } - } - ); - - ul4.ArgumentError = ul4._inherit( - ul4.Exception, - { - __type__: "ul4.ArgumentError", - - create: function create(message) - { - let exception = ul4._clone(this); - exception.message = message; - return exception; - }, - toString: function toString() - { - return this.message; - } - } - ); - - ul4.IndexError = ul4._inherit( - ul4.Exception, - { - __type__: "ul4.IndexError", - - create: function create(obj, index) - { - let exception = ul4._clone(this); - exception.obj = obj; - exception.index = index; - return exception; - }, - - toString: function toString() - { - return "index " + this.index + " out of range for " + ul4._type(this.obj); - } - } - ); - - ul4.AttributeError = ul4._inherit( - ul4.Exception, - { - __type__: "ul4.AttributeError", - - create: function create(obj, attrname) - { - let exception = ul4._clone(this); - exception.obj = obj; - exception.attrname = attrname; - return exception; - }, - toString: function toString() - { - return "object of type " + ul4._type(this.obj) + " has no attribute " + ul4._repr(this.attrname); - } - } - ); - - /// Exception that wraps other exceptions while they bubble up the stack - ul4.LocationError = ul4._inherit( - ul4.Exception, - { - __type__: "ul4.LocationError", - - create: function create(location, cause) - { - let exception = ul4._clone(this); - exception.location = location; - exception.cause = cause; - return exception; - }, - - _templateprefix: function(template) - { - let out = []; - if (template.parenttemplate !== null) - out.push("in local template "); - else - out.push("in template "); - let first = true; - while (template != null) - { - if (first) - first = false; - else - out.push(" in "); - out.push(template.name !== null ? ul4._repr(template.name) : "(unnamed)"); - template = template.parenttemplate; - } - return out.join(""); - }, - - _template: function _template() - { - if (ul4.Tag.isprotoof(this.location)) - return this.location.template; - else - return this.location.tag.template; - }, - - _outerpos: function _outerpos() - { - if (ul4.Tag.isprotoof(this.location)) - return this.location.pos; - else - { - let tag = this.location.tag; - if (tag === null) // A top level template as no tag - return this.location.pos; - else - return tag.pos; - } - }, - - _innerpos: function _innerpos() - { - return this.location.pos; - }, - - toString: function toString() - { - let template = this._template(); - let templateprefix = this._templateprefix(template); - let outerpos = this._outerpos(); - let innerpos = this._innerpos(); - - let prefix = template.source.substring(outerpos.start, innerpos.start); - let code = template.source.substring(innerpos.start, innerpos.stop); - let suffix = template.source.substring(innerpos.stop, outerpos.stop); - prefix = ul4._repr(prefix).slice(1, -1); - code = ul4._repr(code).slice(1, -1); - suffix = ul4._repr(suffix).slice(1, -1); - let text = prefix + code + suffix; - let underline = ul4._str_repeat("\u00a0", prefix.length) + ul4._str_repeat("~", code.length); - - // find line numbers - let lineno = 1, colno = 1; - for (let i = 0; i < innerpos.start; ++i) - { - if (template.source[i] === "\n") - { - ++lineno; - colno = 1; - } - else - ++colno; - } - - pos = "offset " + this.location.pos.start + ":" + this.location.pos.stop + "; line " + lineno + "; col " + colno; - - var message = templateprefix + ": " + pos + "\n" + text + "\n" + underline; - if (this.cause !== null) - message += "\n\n" + this.cause.toString(); - return message; - }, - - __getattr__: function __getattr__(attrname) - { - switch (attrname) - { - case "cause": - return this.cause; - case "location": - return this.location; - case "template": - return this._template; - case "outerpos": - return this._outerpos; - case "innerpos": - return this._innerpos; - default: - throw ul4.AttributeError.create(this, attrname); - } - } - } - ); - - - /// Classes for the syntax tree - ul4.AST = ul4._inherit( - ul4.Proto, - { - create: function create(pos) - { - let ast = ul4._clone(this); - ast.pos = pos; - return ast; - }, - __str__: function __str__() - { - let out = []; - this._str(out); - return ul4._formatsource(out); - }, - __repr__: function __repr__() - { - let out = []; - this._repr(out); - return ul4._formatsource(out); - }, - _handle_eval: function _handle_eval(context) - { - try - { - return this._eval(context); - } - catch (exc) - { - if (!ul4.InternalException.isprotoof(exc) && !ul4.LocationError.isprotoof(exc)) - throw ul4.LocationError.create(this, exc); - throw exc; - } - }, - _handle_eval_set: function _handle_eval_set(context, value) - { - try - { - return this._eval_set(context, value); - } - catch (exc) - { - if (!ul4.LocationError.isprotoof(exc)) - throw ul4.LocationError.create(this, exc); - throw exc; - } - }, - _eval_set: function _eval_set(context, value) - { - throw ul4.LValueRequiredError; - }, - _handle_eval_modify: function _handle_eval_modify(context, operator, value) - { - try - { - return this._eval_modify(context, operator, value); - } - catch (exc) - { - if (!ul4.LocationError.isprotoof(exc)) - throw ul4.LocationError.create(this, exc); - throw exc; - } - }, - _eval_modify: function _eval_modify(context, operator, value) - { - throw ul4.LValueRequiredError; - }, - _repr: function _repr(out) - { - }, - _str: function _str(out) - { - }, - ul4ondump: function ul4ondump(encoder) - { - for (let i = 0; i < this._ul4onattrs.length; ++i) - encoder.dump(this[this._ul4onattrs[i]]); - }, - ul4onload: function ul4onload(decoder) - { - for (let i = 0; i < this._ul4onattrs.length; ++i) - this[this._ul4onattrs[i]] = decoder.load(); - }, - __setitem__: function __setitem__(attrname, value) - { - throw ul4.TypeError.create("mutate", "object is immutable"); - }, - // used in ul4ondump/ul4ondump to automatically dump these attributes - _ul4onattrs: ["pos"] - } - ); - - ul4.TextAST = ul4._inherit( - ul4.AST, - { - create: function create(template, pos) - { - let text = ul4.AST.create.call(this, pos); - text.template = template; - return text; - }, - _ul4onattrs: ul4.AST._ul4onattrs.concat(["template"]), - _text: function _text() - { - return this.template.source.substring(this.pos.start, this.pos.stop); - }, - _eval: function _eval(context) - { - context.output(this._text()); - }, - _str: function _str(out) - { - out.push("text "); - out.push(ul4._repr(this._text())); - }, - _repr: function _repr(out) - { - out.push(""); - } - } - ); - - ul4.IndentAST = ul4._inherit( - ul4.TextAST, - { - create: function create(template, pos, text) - { - let indent = ul4.TextAST.create.call(this, template, pos); - indent._maketext(text); - return indent; - }, - _maketext: function _maketext(text) - { - if (typeof(this.template) !== "undefined") - { - if (text === null) - this.text = this.template.source.substring(this.pos.start, this.pos.stop); - else - this.text = text; - } - else - this.text = null; - }, - _text: function _text() - { - if (this.text === null) - return this.template.source.substring(this.pos.start, this.pos.stop); - else - return this.text; - }, - _eval: function _eval(context) - { - for (let i = 0; i < context.indents.length; ++i) - context.output(context.indents[i]); - context.output(this._text()); - }, - ul4ondump: function ul4ondump(encoder) - { - ul4.TextAST.ul4ondump.call(this, encoder); - - if (this.text === this.template.source.substring(this.pos.start, this.pos.stop)) - encoder.dump(null); - else - encoder.dump(this.text); - }, - ul4onload: function ul4onload(decoder) - { - ul4.TextAST.ul4onload.call(this, decoder); - // Recreate ``text`` attribute - this._maketext(decoder.load()); - }, - _str: function _str(out) - { - out.push("indent "); - out.push(ul4._repr(this._text())); - }, - _repr: function _repr(out) - { - out.push(""); - } - } - ); - - ul4.LineEndAST = ul4._inherit( - ul4.TextAST, - { - _str: function _str(out) - { - out.push("lineend "); - out.push(ul4._repr(this._text())); - }, - _repr: function _repr(out) - { - out.push(""); - } - } - ); - - ul4.Tag = ul4._inherit( - ul4.AST, - { - create: function create(template, tag, tagpos, codepos) - { - let tago = ul4.AST.create.call(this, tagpos); - tago.template = template; - tago.tag = tag; - tago.codepos = codepos; - tago._maketext(); - return tago; - }, - _maketext: function _maketext() - { - if (typeof(this.template) !== "undefined") - { - this.text = this.template.source.substring(this.pos.start, this.pos.stop); - this.code = this.template.source.substring(this.codepos.start, this.codepos.stop); - } - else - { - this.text = null; - this.code = null; - } - }, - ul4ondump: function ul4ondump(encoder) - { - ul4.AST.ul4ondump.call(this, encoder); - encoder.dump(this.template); - encoder.dump(this.tag); - encoder.dump(this.codepos); - }, - ul4onload: function ul4onload(decoder) - { - ul4.TextAST.ul4onload.call(this, decoder); - this.template = decoder.load(); - this.tag = decoder.load(); - this.codepos = decoder.load(); - // Recreate ``text`` attribute - this._maketext(); - } - } - ); - - ul4.CodeAST = ul4._inherit( - ul4.AST, - { - create: function create(tag, pos) - { - let code = ul4.AST.create.call(this, pos); - code.tag = tag; - return code; - }, - _ul4onattrs: ul4.AST._ul4onattrs.concat(["tag"]), - _str: function _str(out) - { - out.push(this.tag.source.substring(this.pos.start, this.pos.stop).replace(/\r?\n/g, ' ')); - } - } - ); - - ul4.ConstAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, value) - { - let constant = ul4.CodeAST.create.call(this, tag, pos); - constant.value = value; - return constant; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["value"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - return this.value; - } - } - ); - - ul4.ItemArgBase = ul4._inherit( - ul4.CodeAST, - { - _handle_eval_list: function _handle_eval_list(context, result) - { - try - { - return this._eval_list(context, result); - } - catch (exc) - { - if (!ul4.InternalException.isprotoof(exc) && !ul4.LocationError.isprotoof(exc)) - throw ul4.LocationError.create(this, exc); - throw exc; - } - }, - _handle_eval_set: function _handle_eval_set(context, result) - { - try - { - return this._eval_set(context, result); - } - catch (exc) - { - if (!ul4.InternalException.isprotoof(exc) && !ul4.LocationError.isprotoof(exc)) - throw ul4.LocationError.create(this, exc); - throw exc; - } - }, - _handle_eval_dict: function _handle_eval_dict(context, result) - { - try - { - return this._eval_dict(context, result); - } - catch (exc) - { - if (!ul4.InternalException.isprotoof(exc) && !ul4.LocationError.isprotoof(exc)) - throw ul4.LocationError.create(this, exc); - throw exc; - } - }, - _handle_eval_call: function _handle_eval_call(context, args, kwargs) - { - try - { - return this._eval_call(context, args, kwargs); - } - catch (exc) - { - if (!ul4.InternalException.isprotoof(exc) && !ul4.LocationError.isprotoof(exc)) - throw ul4.LocationError.create(this, exc); - throw exc; - } - } - } - ); - - ul4.SeqItemAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, value) - { - let seqitem = ul4.ItemArgBase.create.call(this, tag, pos); - seqitem.value = value; - return seqitem; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["value"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_list: function _eval_list(context, result) - { - let value = this.value._handle_eval(context); - result.push(value); - }, - _eval_set: function _eval_set(context, result) - { - let value = this.value._handle_eval(context); - result.add(value); - } - } - ); - - - ul4.UnpackSeqItemAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, value) - { - let unpackseqitem = ul4.ItemArgBase.create.call(this, tag, pos); - unpackseqitem.value = value; - return unpackseqitem; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["value"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_list: function _eval_list(context, result) - { - let value = this.value._handle_eval(context); - for (let iter = ul4._iter(value);;) - { - let item = iter.next(); - if (item.done) - break; - result.push(item.value); - } - }, - _eval_set: function _eval_set(context, result) - { - let value = this.value._handle_eval(context); - for (let iter = ul4._iter(value);;) - { - let item = iter.next(); - if (item.done) - break; - result.add(item.value); - } - } - } - ); - - ul4.DictItemAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, key, value) - { - let dictitem = ul4.ItemArgBase.create.call(this, tag, pos); - dictitem.key = key; - dictitem.value = value; - return dictitem; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["key", "value"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_dict: function _eval_dict(context, result) - { - let key = this.key._handle_eval(context); - let value = this.value._handle_eval(context); - ul4on._setmap(result, key, value); - } - } - ); - - ul4.UnpackDictItemAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, item) - { - let unpackdictitem = ul4.ItemArgBase.create.call(this, tag, pos); - unpackdictitem.item = item; - return unpackdictitem; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["item"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_dict: function _eval_dict(context, result) - { - let item = this.item._handle_eval(context); - if (ul4._islist(item)) - { - for (let i = 0; i < item.length; ++i) - { - if (!ul4._islist(item[i]) || item[i].length != 2) - throw ul4.ArgumentError.create("** requires a list of (key, value) pairs"); - let key = item[i][0], value = item[i][1]; - ul4on._setmap(result, key, value); - } - } - else if (ul4._ismap(item)) - { - item.forEach(function(value, key){ - ul4on._setmap(result, key, value); - }); - } - else if (ul4._isobject(item)) - { - for (let key in item) - ul4on._setmap(result, key, item[key]); - } - } - } - ); - - ul4.PosArgAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, value) - { - let arg = ul4.ItemArgBase.create.call(this, tag, pos); - arg.value = value; - return arg; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["value"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_call: function _eval_call(context, args, kwargs) - { - let value = this.value._handle_eval(context); - args.push(value); - } - } - ); - - ul4.KeywordArgAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, name, value) - { - let arg = ul4.ItemArgBase.create.call(this, tag, pos); - arg.name = name; - arg.value = value; - return arg; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["name", "value"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_call: function _eval_call(context, args, kwargs) - { - if (kwargs.hasOwnProperty(this.name)) - throw ul4.ArgumentError.create("duplicate keyword argument " + this.name); - let value = this.value._handle_eval(context); - kwargs[this.name] = value; - } - } - ); - - ul4.UnpackListArgAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, item) - { - let arg = ul4.ItemArgBase.create.call(this, tag, pos); - arg.item = item; - return arg; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["item"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_call: function _eval_call(context, args, kwargs) - { - let item = this.item._handle_eval(context); - args.push(...item); - } - } - ); - - ul4.UnpackDictArgAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, item) - { - let arg = ul4.ItemArgBase.create.call(this, tag, pos); - arg.item = item; - return arg; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["item"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_call: function _eval_call(context, args, kwargs) - { - let item = this.item._handle_eval(context); - if (ul4._islist(item)) - { - for (let i = 0; i < item.length; ++i) - { - if (!ul4._islist(item[i]) || item[i].length != 2) - throw ul4.ArgumentError.create("** requires a list of (key, value) pairs"); - let key = item[i][0], value = item[i][1]; - if (kwargs.hasOwnProperty(key)) - throw ul4.ArgumentError.create("duplicate keyword argument " + key); - kwargs[key] = value; - } - } - else if (ul4._ismap(item)) - { - item.forEach(function(value, key){ - if (kwargs.hasOwnProperty(key)) - throw ul4.ArgumentError.create("duplicate keyword argument " + key); - kwargs[key] = value; - }); - } - else if (ul4._isobject(item)) - { - for (let key in item) - { - if (kwargs.hasOwnProperty(key)) - throw ul4.ArgumentError.create("duplicate keyword argument " + key); - kwargs[key] = item[key]; - } - } - } - } - ); - - ul4.ListAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos) - { - let list = ul4.CodeAST.create.call(this, tag, pos); - list.items = []; - return list; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["items"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - let result = []; - for (let i = 0; i < this.items.length; ++i) - this.items[i]._handle_eval_list(context, result); - return result; - } - } - ); - - ul4.ListCompAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, item, varname, container, condition) - { - let listcomp = ul4.CodeAST.create.call(this, tag, pos); - listcomp.item = item; - listcomp.varname = varname; - listcomp.container = container; - listcomp.condition = condition; - return listcomp; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["item", "varname", "container", "condition"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - let container = this.container._handle_eval(context); - - let localcontext = context.inheritvars(); - - let result = []; - for (let iter = ul4._iter(container);;) - { - let item = iter.next(); - if (item.done) - break; - let varitems = ul4._unpackvar(this.varname, item.value); - for (let i = 0; i < varitems.length; ++i) - varitems[i][0]._handle_eval_set(localcontext, varitems[i][1]); - if (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext))) - result.push(this.item._handle_eval(localcontext)); - } - return result; - } - } - ); - - ul4.DictAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos) - { - let dict = ul4.CodeAST.create.call(this, tag, pos); - dict.items = []; - return dict; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["items"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - let result = ul4on._emptymap(); - for (let i = 0; i < this.items.length; ++i) - this.items[i]._handle_eval_dict(context, result); - return result; - } - } - ); - - ul4.DictCompAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, key, value, varname, container, condition) - { - let listcomp = ul4.CodeAST.create.call(this, tag, pos); - listcomp.key = key; - listcomp.value = value; - listcomp.varname = varname; - listcomp.container = container; - listcomp.condition = condition; - return listcomp; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["key", "value", "varname", "container", "condition"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - let container = this.container._handle_eval(context); - - let localcontext = context.inheritvars(); - - let result = ul4on._emptymap(); - - for (let iter = ul4._iter(container);;) - { - let item = iter.next(); - if (item.done) - break; - let varitems = ul4._unpackvar(this.varname, item.value); - for (let i = 0; i < varitems.length; ++i) - varitems[i][0]._handle_eval_set(localcontext, varitems[i][1]); - if (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext))) - { - let key = this.key._handle_eval(localcontext); - let value = this.value._handle_eval(localcontext); - ul4on._setmap(result, key, value); - } - } - - return result; - } - } - ); - - ul4.SetAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos) - { - let set = ul4.CodeAST.create.call(this, tag, pos); - set.items = []; - return set; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["items"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - let result = ul4on._haveset ? new Set() : ul4._Set.create(); - - for (let i = 0; i < this.items.length; ++i) - this.items[i]._handle_eval_set(context, result); - - return result; - } - } - ); - - ul4.SetCompAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, item, varname, container, condition) - { - let setcomp = ul4.CodeAST.create.call(this, tag, pos); - setcomp.item = item; - setcomp.container = container; - setcomp.condition = condition; - return setcomp; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["item", "varname", "container", "condition"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - let container = this.container._handle_eval(context); - - let localcontext = context.inheritvars(); - - let result = ul4on._haveset ? new Set() : ul4._Set.create(); - for (let iter = ul4._iter(container);;) - { - let item = iter.next(); - if (item.done) - break; - let varitems = ul4._unpackvar(this.varname, item.value); - for (let i = 0; i < varitems.length; ++i) - varitems[i][0]._handle_eval_set(localcontext, varitems[i][1]); - if (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext))) - result.add(this.item._handle_eval(localcontext)); - } - - return result; - } - } - ); - - ul4.GenExprAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, item, varname, container, condition) - { - let genexp = ul4.CodeAST.create.call(this, tag, pos); - genexp.item = item; - genexp.varname = varname; - genexp.container = container; - genexp.condition = condition; - return genexp; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["item", "varname", "container", "condition"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - let container = this.container._handle_eval(context); - let iter = ul4._iter(container); - - let localcontext = context.inheritvars(); - - let self = this; - - let result = { - next: function(){ - while (true) - { - let item = iter.next(); - if (item.done) - return item; - let varitems = ul4._unpackvar(self.varname, item.value); - for (let i = 0; i < varitems.length; ++i) - varitems[i][0]._handle_eval_set(localcontext, varitems[i][1]); - if (self.condition === null || ul4._bool(self.condition._handle_eval(localcontext))) - { - let value = self.item._handle_eval(localcontext); - return {value: value, done: false}; - } - } - } - }; - - return result; - } - } - ); - - ul4.VarAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, name) - { - let variable = ul4.CodeAST.create.call(this, tag, pos); - variable.name = name; - return variable; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["name"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - return this._get(context, this.name); - }, - _eval_set: function _eval_set(context, value) - { - this._set(context, this.name, value); - }, - _eval_modify: function _eval_modify(context, operator, value) - { - this._modify(context, operator, this.name, value); - }, - _get: function _get(context, name) - { - let result = context.get(name); - if (typeof(result) === "undefined") - result = ul4.functions[name]; - return result; - }, - _set: function _set(context, name, value) - { - context.set(name, value); - }, - _modify: function _modify(context, operator, name, value) - { - var newvalue = operator._ido(context.get(name), value); - context.set(name, newvalue); - } - } - ); - - ul4.UnaryAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, obj) - { - let unary = ul4.CodeAST.create.call(this, tag, pos); - unary.obj = obj; - return unary; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["obj"]), - _repr: function _repr(out) - { - out.push("<"); - out.push(this.typename); - out.push(" obj="); - this.obj._repr(out); - out.push(">"); - }, - _eval: function _eval(context) - { - let obj = this.obj._handle_eval(context); - return this._do(obj); - } - } - ); - - // Negation - ul4.NegAST = ul4._inherit( - ul4.UnaryAST, - { - _do: function _do(obj) - { - if (obj !== null && typeof(obj.__neg__) === "function") - return obj.__neg__(); - return -obj; - } - } - ); - - // Bitwise not - ul4.BitNotAST = ul4._inherit( - ul4.UnaryAST, - { - _do: function _do(obj) - { - return -obj-1; - } - } - ); - - // Not - ul4.NotAST = ul4._inherit( - ul4.UnaryAST, - { - _do: function _do(obj) - { - return !ul4._bool(obj); - } - } - ); - - // If expression - ul4.IfAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, objif, objcond, objelse) - { - let ifexpr = ul4.CodeAST.create.call(this, tag, pos); - ifexpr.objif = objif; - ifexpr.objcond = objcond; - ifexpr.objelse = objelse; - return ifexpr; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["objif", "objcond", "objelse"]), - _repr: function _repr(out) - { - out.push("<"); - out.push(this.typename); - out.push(+1); - out.push("objif="); - this.objif._repr(out); - out.push(0); - out.push("objcond="); - this.objcond._repr(out); - out.push(0); - out.push("objelse="); - this.objelse._repr(out); - out.push(-1); - out.push(">"); - }, - _eval: function _eval(context) - { - let result; - var condvalue = this.objcond._handle_eval(context); - if (ul4._bool(condvalue)) - result = this.objif._handle_eval(context); - else - result = this.objelse._handle_eval(context); - return result; - } - } - ); - - ul4.ReturnAST = ul4._inherit( - ul4.UnaryAST, - { - _eval: function _eval(context) - { - let result = this.obj._handle_eval(context); - throw ul4.ReturnException.create(result); - }, - _str: function _str(out) - { - out.push("return "); - this.obj._str(out); - } - } - ); - - ul4.PrintAST = ul4._inherit( - ul4.UnaryAST, - { - _eval: function _eval(context) - { - let obj = this.obj._handle_eval(context); - let output = ul4._str(obj); - context.output(output); - }, - _str: function _str(out) - { - out.push("print "); - this.obj._str(out); - } - } - ); - - ul4.PrintXAST = ul4._inherit( - ul4.UnaryAST, - { - _eval: function _eval(context) - { - let obj = this.obj._handle_eval(context); - let output = ul4._xmlescape(obj); - context.output(output); - }, - _str: function _str(out) - { - out.push("printx "); - this.obj._str(out); - } - } - ); - - ul4.BinaryAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, obj1, obj2) - { - let binary = ul4.CodeAST.create.call(this, tag, pos); - binary.obj1 = obj1; - binary.obj2 = obj2; - return binary; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["obj1", "obj2"]), - _repr: function _repr(out) - { - out.push("<"); - out.push(this.type); - out.push(" obj1="); - this.obj1._repr(out); - out.push(" obj2="); - this.obj2._repr(out); - out.push(">"); - }, - _eval: function _eval(context) - { - let obj1 = this.obj1._handle_eval(context); - let obj2 = this.obj2._handle_eval(context); - return this._do(obj1, obj2); - } - } - ); - - // Item access and assignment: dict[key], list[index], string[index], color[index] - ul4.ItemAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - let result = this._get(obj1, obj2); - return result; - }, - _eval_set: function _eval_set(context, value) - { - let obj1 = this.obj1._handle_eval(context); - let obj2 = this.obj2._handle_eval(context); - this._set(obj1, obj2, value); - }, - _eval_modify: function _eval_modify(context, operator, value) - { - let obj1 = this.obj1._handle_eval(context); - let obj2 = this.obj2._handle_eval(context); - this._modify(operator, obj1, obj2, value); - }, - _get: function _get(container, key) - { - if (typeof(container) === "string" || ul4._islist(container)) - { - if (ul4.slice.isprotoof(key)) - { - let start = key.start, stop = key.stop; - if (typeof(start) === "undefined" || start === null) - start = 0; - if (typeof(stop) === "undefined" || stop === null) - stop = container.length; - return container.slice(start, stop); - } - else - { - let orgkey = key; - if (key < 0) - key += container.length; - if (key < 0 || key >= container.length) - throw ul4.IndexError.create(container, orgkey); - return container[key]; - } - } - else if (container && typeof(container.__getitem__) === "function") // objects without ``_getitem__`` don't support item access - return container.__getitem__(key); - else if (ul4._ismap(container)) - return container.get(key); - else if (ul4._isobject(container)) - return container[key]; - else - throw ul4.TypeError.create("[]", ul4._type(container) + " object is not subscriptable"); - }, - _set: function _set(container, key, value) - { - if (ul4._islist(container)) - { - if (ul4.slice.isprotoof(key)) - { - let start = key.start, stop = key.stop; - if (start === null) - start = 0; - else if (start < 0) - start += container.length; - if (start < 0) - start = 0; - else if (start > container.length) - start = container.length; - if (stop === null) - stop = container.length; - else if (stop < 0) - stop += container.length; - if (stop < 0) - stop = 0; - else if (stop > container.length) - stop = container.length; - if (stop < start) - stop = start; - container.splice(start, stop-start); // Remove old element - for (let iter = ul4._iter(value);;) - { - let item = iter.next(); - if (item.done) - break; - container.splice(start++, 0, item.value); - } - } - else - { - let orgkey = key; - if (key < 0) - key += container.length; - if (key < 0 || key >= container.length) - throw ul4.IndexError.create(container, orgkey); - container[key] = value; - } - } - else if (container && typeof(container.__setitem__) === "function") // test this before the generic object test - container.__setitem__(key, value); - else if (ul4._ismap(container)) - container.set(key, value); - else if (ul4._isobject(container)) - container[key] = value; - else - throw ul4.NotSubscriptableError.create(container); - }, - _modify: function _modify(operator, container, key, value) - { - this._set(container, key, operator._ido(this._get(container, key), value)); - } - } - ); - - // Identifty test operator ``is`` - ul4.IsAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return obj1 === obj2; - } - } - ); - - // Inverted tdentifty test operator ``is not`` - ul4.IsNotAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return obj1 !== obj2; - } - } - ); - - // Comparison operator == - ul4.EQAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return ul4._eq(obj1, obj2); - } - } - ); - - // Comparison operator != - ul4.NEAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return ul4._ne(obj1, obj2); - } - } - ); - - // Comparison operator < - ul4.LTAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return ul4._lt(obj1, obj2); - } - } - ); - - // Comparison operator <= - ul4.LEAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return ul4._le(obj1, obj2); - } - } - ); - - // Comparison operator > - ul4.GTAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return ul4._gt(obj1, obj2); - } - } - ); - - // Comparison operator >= - ul4.GEAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return ul4._ge(obj1, obj2); - } - } - ); - - // Containment test: string in string, obj in list, key in dict, value in rgb - ul4.ContainsAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj, container) - { - if (typeof(obj) === "string" && typeof(container) === "string") - { - return container.indexOf(obj) !== -1; - } - else if (ul4._islist(container)) - { - return container.indexOf(obj) !== -1; - } - else if (container && typeof(container.__contains__) === "function") // test this before the generic object test - return container.__contains__(obj); - else if (ul4._ismap(container) || ul4._isset(container)) - return container.has(obj); - else if (ul4._isobject(container)) - { - for (let key in container) - { - if (key === obj) - return true; - } - return false; - } - else if (ul4._iscolor(container)) - { - return container._r === obj || container._g === obj || container._b === obj || container._a === obj; - } - throw ul4.TypeError.create("in", ul4._type(container) + " object is not iterable"); - } - } - ); - - // Inverted containment test - ul4.NotContainsAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj, container) - { - return !ul4.ContainsAST._do(obj, container); - } - } - ); - - // Addition: num + num, string + string - ul4.AddAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj1 && typeof(obj1.__add__) === "function") - return obj1.__add__(obj2); - else if (obj2 && typeof(obj2.__radd__) === "function") - return obj2.__radd__(obj1); - if (obj1 === null || obj2 === null) - throw ul4.TypeError.create("+", ul4._type(this.obj1) + " + " + ul4._type(this.obj2) + " is not supported"); - if (ul4._islist(obj1) && ul4._islist(obj2)) - return [...obj1, ...obj2]; - else - return obj1 + obj2; - }, - _ido: function _ido(obj1, obj2) - { - if (ul4._islist(obj1) && ul4._islist(obj2)) - { - ul4._append(obj1, ...obj2); - return obj1; - } - else - return this._do(obj1, obj2); - } - } - ); - - // Substraction: num - num - ul4.SubAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj1 && typeof(obj1.__sub__) === "function") - return obj1.__sub__(obj2); - else if (obj2 && typeof(obj2.__rsub__) === "function") - return obj2.__rsub__(obj1); - else if (ul4._isdate(obj1) && ul4._isdate(obj2)) - return this._date_sub(obj1, obj2); - if (obj1 === null || obj2 === null) - throw ul4.TypeError.create("-", ul4._type(this.obj1) + " - " + ul4._type(this.obj2) + " is not supported"); - return obj1 - obj2; - }, - _date_sub: function _date_sub(obj1, obj2) - { - let swap = (obj2 > obj1); - - if (swap) - { - let t = obj1; - obj1 = obj2; - obj2 = t; - } - // From now on obj1 is > than obj2 - - let year1 = obj1.getFullYear(); - let yearday1 = ul4._yearday(obj1); - let year2 = obj2.getFullYear(); - let yearday2 = ul4._yearday(obj2); - - let diffdays = 0; - - while (year1 > year2) - { - diffdays += ul4._yearday(ul4._date(year2, 12, 31)); - ++year2; - } - diffdays += yearday1 - yearday2; - - let hours1 = obj1.getHours(); - let minutes1 = obj1.getMinutes(); - let seconds1 = obj1.getSeconds(); - let hours2 = obj2.getHours(); - let minutes2 = obj2.getMinutes(); - let seconds2 = obj2.getSeconds(); - - let diffseconds = (seconds1 - seconds2) + 60 * ((minutes1 - minutes2) + 60 * (hours1 - hours2)); - - let diffmilliseconds = obj1.getMilliseconds() - obj2.getMilliseconds(); - - if (swap) - { - diffdays = -diffdays; - diffseconds = -diffseconds; - diffmilliseconds = -diffmilliseconds; - } - return ul4.TimeDelta.create(diffdays, diffseconds, 1000*diffmilliseconds); - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Multiplication: num * num, int * str, str * int, int * list, list * int - ul4.MulAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj1 && typeof(obj1.__mul__) === "function") - return obj1.__mul__(obj2); - else if (obj2 && typeof(obj2.__rmul__) === "function") - return obj2.__rmul__(obj1); - if (obj1 === null || obj2 === null) - throw ul4.TypeError.create("*", ul4._type(obj1) + " * " + ul4._type(obj2) + " not supported"); - else if (ul4._isint(obj1) || ul4._isbool(obj1)) - { - if (typeof(obj2) === "string") - { - if (obj1 < 0) - throw ul4.ValueError.create("repetition counter must be positive"); - return ul4._str_repeat(obj2, obj1); - } - else if (ul4._islist(obj2)) - { - if (obj1 < 0) - throw ul4.ValueError.create("repetition counter must be positive"); - return ul4._list_repeat(obj2, obj1); - } - } - else if (ul4._isint(obj2) || ul4._isbool(obj2)) - { - if (typeof(obj1) === "string") - { - if (obj2 < 0) - throw ul4.ValueError.create("repetition counter must be positive"); - return ul4._str_repeat(obj1, obj2); - } - else if (ul4._islist(obj1)) - { - if (obj2 < 0) - throw ul4.ValueError.create("repetition counter must be positive"); - return ul4._list_repeat(obj1, obj2); - } - } - return obj1 * obj2; - }, - _ido: function _ido(obj1, obj2) - { - if (ul4._islist(obj1) && ul4._isint(obj2)) - { - if (obj2 > 0) - { - let i = 0; - let targetsize = obj1.length * obj2; - while (obj1.length < targetsize) - obj1.push(obj1[i++]); - } - else - obj1.splice(0, obj1.length); - return obj1; - } - else - return this._do(obj1, obj2); - } - } - ); - - // Truncating division - ul4.FloorDivAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj1 && typeof(obj1.__floordiv__) === "function") - return obj1.__floordiv__(obj2); - else if (obj2 && typeof(obj2.__rfloordiv__) === "function") - return obj2.__rfloordiv__(obj1); - if (obj1 === null || obj2 === null) - throw ul4.TypeError.create("//", ul4._type(obj1) + " // " + ul4._type(obj2) + " not supported"); - return Math.floor(obj1 / obj2); - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // "Real" division - ul4.TrueDivAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj1 && typeof(obj1.__truediv__) === "function") - return obj1.__truediv__(obj2); - else if (obj2 && typeof(obj2.__rtruediv__) === "function") - return obj2.__rtruediv__(obj1); - if (obj1 === null || obj2 === null) - throw ul4.TypeError.create("/", ul4._type(obj1) + " / " + ul4._type(obj2) + " not supported"); - return obj1 / obj2; - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Modulo - ul4.ModAST = ul4._inherit( - ul4.BinaryAST, - { - // (this is non-trivial, because it follows the Python semantic of ``-5 % 2`` being ``1``) - _do: function _do(obj1, obj2) - { - let div = Math.floor(obj1 / obj2); - let mod = obj1 - div * obj2; - - if (mod !== 0 && ((obj2 < 0 && mod > 0) || (obj2 > 0 && mod < 0))) - { - mod += obj2; - --div; - } - return obj1 - div * obj2; - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Bitwise left shift - ul4.ShiftLeftAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj2 === false) - obj2 = 0; - else if (obj2 === true) - obj2 = 1; - if (obj2 < 0) - return ul4.ShiftRightAST._do(obj1, -obj2); - if (obj1 === false) - obj1 = 0; - else if (obj1 === true) - obj1 = 1; - while (obj2--) - obj1 *= 2; - return obj1; - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Bitwise right shift - ul4.ShiftRightAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj2 === false) - obj2 = 0; - else if (obj2 === true) - obj2 = 1; - if (obj2 < 0) - return ul4.ShiftLeftAST._do(obj1, -obj2); - if (obj1 === false) - obj1 = 0; - else if (obj1 === true) - obj1 = 1; - while (obj2--) - obj1 /= 2; - return Math.floor(obj1); - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Bitwise and - ul4.BitAndAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj2 === false) - obj2 = 0; - else if (obj2 === true) - obj2 = 1; - return obj1 & obj2; - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Bitwise exclusive or - ul4.BitXOrAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj2 === false) - obj2 = 0; - else if (obj2 === true) - obj2 = 1; - return obj1 ^ obj2; - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Bitwise or - ul4.BitOrAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj2 === false) - obj2 = 0; - else if (obj2 === true) - obj2 = 1; - return obj1 | obj2; - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - ul4.AndAST = ul4._inherit( - ul4.BinaryAST, - { - _eval: function _eval(context) - { - let obj1 = this.obj1._handle_eval(context); - if (!ul4._bool(obj1)) - return obj1; - let obj2 = this.obj2._handle_eval(context); - return obj2; - } - } - ); - - ul4.OrAST = ul4._inherit( - ul4.BinaryAST, - { - _eval: function _eval(context) - { - let obj1 = this.obj1._handle_eval(context); - if (ul4._bool(obj1)) - return obj1; - let obj2 = this.obj2._handle_eval(context); - return obj2; - } - } - ); - - ul4.AttrAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, obj, attrname) - { - let attr = ul4.CodeAST.create.call(this, tag, pos); - attr.obj = obj; - attr.attrname = attrname; - return attr; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["obj", "attrname"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - let obj = this.obj._handle_eval(context); - let result = this._get(obj, this.attrname); - return result; - }, - _eval_set: function _eval_set(context, value) - { - let obj = this.obj._handle_eval(context); - this._set(obj, this.attrname, value); - }, - _eval_modify: function _eval_modify(context, operator, value) - { - let obj = this.obj._handle_eval(context); - this._modify(operator, obj, this.attrname, value); - }, - _get: function _get(object, attrname) - { - let proto = ul4.Protocol.get(object); - try - { - return proto.getattr(object, attrname); - } - catch (exc) - { - if (ul4.AttributeError.isprotoof(exc) && exc.obj === object) - return undefined; - else - throw exc; - } - }, - _set: function _set(object, attrname, value) - { - if (typeof(object) === "object" && typeof(object.__setattr__) === "function") - object.__setattr__(attrname, value); - else if (ul4._ismap(object)) - object.set(attrname, value); - else if (ul4._isobject(object)) - object[attrname] = value; - else - throw ul4.TypeError.create("set", ul4._type(object) + " object has no writable attributes"); - }, - _modify: function _modify(operator, object, attrname, value) - { - let oldvalue = this._get(object, attrname); - let newvalue = operator._ido(oldvalue, value); - this._set(object, attrname, newvalue); - } - } - ); - - ul4.CallAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, obj, args) - { - let call = ul4.CodeAST.create.call(this, tag, pos); - call.obj = obj; - call.args = args; - return call; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["obj", "args"]), - _repr: function _repr(out) - { - out.push(""); - }, - _makeargs: function _makeargs(context) - { - let args = [], kwargs = {}; - for (let i = 0; i < this.args.length; ++i) - this.args[i]._handle_eval_call(context, args, kwargs); - return {args: args, kwargs: kwargs}; - }, - _handle_eval: function _handle_eval(context) - { - try - { - return this._eval(context); - } - catch (exc) - { - throw ul4.LocationError.create(this, exc); - } - }, - _eval: function _eval(context) - { - let obj = this.obj._handle_eval(context); - let args = this._makeargs(context); - let result = ul4._call(context, obj, args.args, args.kwargs); - return result; - } - } - ); - - ul4.RenderAST = ul4._inherit( - ul4.CallAST, - { - create: function create(tag, pos, obj, args) - { - let render = ul4.CallAST.create.call(this, tag, pos, obj, args); - render.indent = null; - return render; - }, - _ul4onattrs: ul4.CallAST._ul4onattrs.concat(["indent"]), - _repr: function _repr(out) - { - out.push(""); - }, - _str: function _str(out) - { - out.push("render "); - out.push(this.tag.source.substring(this.pos.start, this.pos.stop).replace(/\r?\n/g, ' ')); - if (this.indent !== null) - { - out.push(" with indent "); - out.push(ul4._repr(this.indent._text())); - } - }, - _handle_eval: function _handle_eval(context) - { - let localcontext = context.withindent(this.indent !== null ? this.indent._text() : null); - let obj = this.obj._handle_eval(localcontext); - let args = this._makeargs(localcontext); - - try - { - let result = ul4._callrender(localcontext, obj, args.args, args.kwargs); - return result; - } - catch (exc) - { - throw ul4.LocationError.create(this, exc); - } - } - } - ); - - // Slice object - ul4.slice = ul4._inherit( - ul4.Proto, - { - create: function create(start, stop) - { - let slice = ul4._clone(this); - slice.start = start; - slice.stop = stop; - return slice; - }, - __repr__: function __repr__() - { - return "slice(" + ul4._repr(this.start) + ", " + ul4._repr(this.stop) + ")"; - } - } - ); - - - // List/String slice - ul4.SliceAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, index1, index2) - { - let slice = ul4.CodeAST.create.call(this, tag, pos); - slice.index1 = index1; - slice.index2 = index2; - return slice; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["index1", "index2"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - let index1 = this.index1 !== null ? this.index1._handle_eval(context) : null; - let index2 = this.index2 !== null ? this.index2._handle_eval(context) : null; - return ul4.slice.create(index1, index2); - } - } - ); - - - ul4.SetVarAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, lvalue, value) - { - let changevar = ul4.CodeAST.create.call(this, tag, pos); - changevar.lvalue = lvalue; - changevar.value = value; - return changevar; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["lvalue", "value"]), - _repr: function _repr(out) - { - out.push("<"); - out.push(this.typename); - out.push(" lvalue="); - out.push(ul4._repr(this.lvalue)); - out.push(" value="); - this.value._repr(out); - out.push(">"); - }, - _eval: function _eval(context) - { - let value = this.value._handle_eval(context); - let items = ul4._unpackvar(this.lvalue, value); - for (let i = 0; i < items.length; ++i) - { - let item = items[i]; - item[0]._handle_eval_set(context, item[1]); - } - } - } - ); - - ul4.ModifyVarAST = ul4._inherit( - ul4.SetVarAST, - { - _eval: function _eval(context) - { - let value = this.value._handle_eval(context); - let items = ul4._unpackvar(this.lvalue, value); - for (let i = 0; i < items.length; ++i) - { - let item = items[i]; - item[0]._handle_eval_modify(context, this._operator, item[1]); - } - } - } - ); - - ul4.AddVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.AddAST }); - - ul4.SubVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.SubAST }); - - ul4.MulVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.MulAST }); - - ul4.TrueDivVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.TrueDivAST }); - - ul4.FloorDivVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.FloorDivAST }); - - ul4.ModVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.ModAST }); - - ul4.ShiftLeftVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.ShiftLeftAST }); - - ul4.ShiftRightVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.ShiftRightAST }); - - ul4.BitAndVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.BitAndAST }); - - ul4.BitXOrVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.BitXOrAST }); - - ul4.BitOrVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.BitOrAST }); - - ul4.BlockAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos) - { - let block = ul4.CodeAST.create.call(this, tag, pos); - block.endtag = null; - block.content = []; - return block; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["endtag", "content"]), - _eval: function _eval(context) - { - for (let i = 0; i < this.content.length; ++i) - this.content[i]._handle_eval(context); - }, - _str: function _str(out) - { - if (this.content.length) - { - for (let i = 0; i < this.content.length; ++i) - { - this.content[i]._str(out); - out.push(0); - } - } - else - { - out.push("pass"); - out.push(0); - } - } - } - ); - - ul4.ForBlockAST = ul4._inherit( - ul4.BlockAST, - { - create: function create(tag, pos, varname, container) - { - let for_ = ul4.BlockAST.create.call(this, tag, pos); - for_.varname = varname; - for_.container = container; - return for_; - }, - _ul4onattrs: ul4.BlockAST._ul4onattrs.concat(["varname", "container"]), - _repr: function _repr(out) - { - out.push(""); - }, - _str_varname: function _str_varname(out, varname) - { - if (ul4._islist(varname)) - { - out.push("("); - for (let i = 0; i < varname.length; ++i) - { - if (i) - out.push(", "); - this._str_varname(out, varname[i]); - } - if (varname.length == 1) - out.push(","); - out.push(")"); - } - else - varname._str(out); - }, - _eval: function _eval(context) - { - let container = this.container._handle_eval(context); - - for (let iter = ul4._iter(container);;) - { - let value = iter.next(); - if (value.done) - break; - let varitems = ul4._unpackvar(this.varname, value.value); - for (let i = 0; i < varitems.length; ++i) - varitems[i][0]._handle_eval_set(context, varitems[i][1]); - try - { - // We can't call _handle_eval() here, as this would in turn call this function again, leading to infinite recursion - // But we don't have to, as wrapping original exception in ``Error`` has already been done by the lower levels - ul4.BlockAST._eval.call(this, context); - } - catch (exc) - { - if (exc === ul4.BreakException) - break; - else if (exc === ul4.ContinueException) - ; - else - throw exc; - } - } - }, - _str: function _str(out) - { - out.push("for "); - this._str_varname(out, this.varname); - out.push(" in "); - this.container._str(out); - out.push(":"); - out.push(+1); - ul4.BlockAST._str.call(this, out); - out.push(-1); - } - } - ); - - ul4.WhileBlockAST = ul4._inherit( - ul4.BlockAST, - { - create: function create(tag, pos, condition) - { - let while_ = ul4.BlockAST.create.call(this, tag, pos); - while_.condition = condition; - return while_; - }, - _ul4onattrs: ul4.BlockAST._ul4onattrs.concat(["condition"]), - _repr: function _repr(out) - { - out.push(""); - }, - _str: function _str(out) - { - out.push("while "); - this.container._repr(out); - out.push(":"); - out.push(+1); - ul4.BlockAST._str.call(this, out); - out.push(-1); - }, - _eval: function _eval(context) - { - while (true) - { - let cond = this.condition._handle_eval(context); - if (!ul4._bool(cond)) - break; - try - { - // We can't call _handle_eval() here, as this would in turn call this function again, leading to infinite recursion - // But we don't have to, as wrapping original exception in ``Error`` has already been done by the lower levels - ul4.BlockAST._eval.call(this, context); - } - catch (exc) - { - if (exc === ul4.BreakException) - break; - else if (exc === ul4.ContinueException) - ; - else - throw exc; - } - } - } - } - ); - - ul4.BreakAST = ul4._inherit( - ul4.CodeAST, - { - _eval: function _eval(context) - { - throw ul4.BreakException; - }, - _str: function _str(out) - { - out.push("break"); - out.push(0); - }, - _repr: function _repr(out) - { - out.push(""); - } - } - ); - - ul4.ContinueAST = ul4._inherit( - ul4.CodeAST, - { - _eval: function _eval(context) - { - throw ul4.ContinueException; - }, - _str: function _str(out) - { - out.push("continue"); - out.push(0); - }, - _repr: function _repr(out) - { - out.push(""); - } - } - ); - - ul4.CondBlockAST = ul4._inherit( - ul4.BlockAST, - { - _eval: function _eval(context) - { - for (let i = 0; i < this.content.length; ++i) - { - let block = this.content[i]; - let execute = block._execute(context); - if (execute) - { - block._handle_eval(context); - break; - } - } - } - } - ); - - ul4.ConditionalBlockAST = ul4._inherit( - ul4.BlockAST, - { - create: function create(tag, pos, condition) - { - let block = ul4.BlockAST.create.call(this, tag, pos); - block.condition = condition; - return block; - }, - _ul4onattrs: ul4.BlockAST._ul4onattrs.concat(["condition"]), - _repr: function _repr(out) - { - out.push("<"); - out.push(this.typename); - out.push(" condition="); - this.condition._repr(out); - out.push(">"); - }, - _str: function _str(out) - { - out.push(this._strname); - out.push(" "); - this.condition._str(out); - out.push(":"); - out.push(+1); - ul4.BlockAST._str.call(this, out); - out.push(-1); - }, - _execute: function _execute(context) - { - let cond = this.condition._handle_eval(context); - let result = ul4._bool(cond); - return result; - } - } - ); - - ul4.IfBlockAST = ul4._inherit(ul4.ConditionalBlockAST, {_strname: "if"}); - - ul4.ElIfBlockAST = ul4._inherit(ul4.ConditionalBlockAST, {_strname: "else if"}); - - ul4.ElseBlockAST = ul4._inherit( - ul4.BlockAST, - { - _repr: function _repr(out) - { - out.push(""); - }, - _str: function _str(out) - { - out.push("else:"); - out.push(+1); - ul4.BlockAST._str.call(this, out); - out.push(-1); - }, - _execute: function _execute(context) - { - return true; - } - } - ); - - ul4.Template = ul4._inherit( - ul4.BlockAST, - { - create: function create(tag, pos, source, name, whitespace, startdelim, enddelim, signature) - { - let template = ul4.BlockAST.create.call(this, tag, pos); - template.source = source; - template.name = name; - template.whitespace = whitespace; - template.startdelim = startdelim; - template.enddelim = enddelim; - template.docpos = null; - template.signature = signature; - template._jsfunction = null; - template._asts = null; - template._ul4_callsignature = signature; - template._ul4_rendersignature = signature; - template.parenttemplate = null; - return template; - }, - ul4ondump: function ul4ondump(encoder) - { - let signature; - encoder.dump(ul4.version); - encoder.dump(this.name); - encoder.dump(this.source); - encoder.dump(this.whitespace); - encoder.dump(this.startdelim); - encoder.dump(this.enddelim); - encoder.dump(this.docpos); - encoder.dump(this.parenttemplate); - if (this.signature === null || ul4.SignatureAST.isprotoof(this.signature)) - signature = this.signature; - else - { - signature = []; - for (let i = 0; i < this.signature.args.length; ++i) - { - let arg = this.signature.args[i]; - if (typeof(arg.defaultValue) === "undefined") - signature.push(arg.name); - else - signature.push(arg.name+"=", arg.defaultValue); - } - if (this.signature.remargs !== null) - signature.push("*" + this.signature.remargs); - if (this.signature.remkwargs !== null) - signature.push("**" + this.signature.remkwargs); - } - encoder.dump(signature); - ul4.BlockAST.ul4ondump.call(this, encoder); - }, - ul4onload: function ul4onload(decoder) - { - let version = decoder.load(); - let signature; - - if (version === null) - throw ul4.ValueError.create("UL4ON doesn't support templates in 'source' format in Javascript implementation"); - - if (version !== ul4.version) - throw ul4.ValueError.create("invalid version, expected " + ul4.version + ", got " + version); - this.name = decoder.load(); - this.source = decoder.load(); - this.whitespace = decoder.load(); - this.startdelim = decoder.load(); - this.enddelim = decoder.load(); - this.docpos = decoder.load(); - this.parenttemplate = decoder.load(); - signature = decoder.load(); - if (ul4._islist(signature)) - signature = ul4.Signature.create.apply(ul4.Signature, signature); - this.signature = signature; - this._ul4_callsignature = signature; - this._ul4_rendersignature = signature; - ul4.BlockAST.ul4onload.call(this, decoder); - }, - loads: function loads(string) - { - return ul4on.loads(string); - }, - _eval: function _eval(context) - { - let signature = null; - if (this.signature !== null) - signature = this.signature._handle_eval(context); - let closure = ul4.TemplateClosure.create(this, signature, context.vars); - context.set(this.name, closure); - }, - _repr: function _repr(out) - { - out.push("") - { - out.push(" enddelim="); - out.push(ul4._repr(this.enddelim)); - } - out.push(">"); - }, - _str: function _str(out) - { - out.push("def "); - out.push(this.name ? this.name : "unnamed"); - out.push(":"); - out.push(+1); - ul4.BlockAST._str.call(this, out); - out.push(-1); - }, - _ul4_callneedsobject: true, - _ul4_callneedscontext: true, - _ul4_renderneedsobject: true, - _ul4_renderneedscontext: true, - _renderbound: function _renderbound(context, vars) - { - let localcontext = context.clone(); - localcontext.vars = vars; - try - { - ul4.BlockAST._eval.call(this, localcontext); - } - catch (exc) - { - if (!ul4.ReturnException.isprotoof(exc)) - throw exc; - } - }, - __render__: function __render__(context, vars) - { - this._renderbound(context, vars); - }, - render: function render(context, vars) - { - this._renderbound(context, vars); - }, - _rendersbound: function _rendersbound(context, vars) - { - let localcontext = context.replaceoutput(); - this._renderbound(localcontext, vars); - return localcontext.getoutput(); - }, - renders: function renders(vars) - { - vars = vars || {}; - let context = ul4.Context.create(); - if (this.signature !== null) - vars = this.signature.bindObject(this.name, [], vars); - return this._rendersbound(context, vars); - }, - doc: function doc() - { - return this.docpos != null ? this.source.substring(this.docpos.start, this.docpos.stop) : null; - }, - __getattr__: function __getattr__(attrname) - { - var self = this; - switch (attrname) - { - case "tag": - return this.tag; - case "endtag": - return this.endtag; - case "content": - return this.content; - case "source": - return this.source; - case "name": - return this.name; - case "whitespace": - return this.whitespace; - case "startdelim": - return this.startdelim; - case "enddelim": - return this.enddelim; - case "doc": - return this.doc(); - case "signature": - return this.signature; - case "parenttemplate": - return this.parenttemplate; - case "render": - return ul4.expose(this.signature, {needscontext: true, needsobject: true}, function render(context, vars){ self._renderbound(context, vars); }); - case "renders": - return ul4.expose(this.signature, {needscontext: true, needsobject: true}, function renders(context, vars){ return self._rendersbound(context, vars); }); - default: - throw ul4.AttributeError.create(this, attrname); - } - }, - _callbound: function _callbound(context, vars) - { - let localcontext = context.clone(); - localcontext.vars = vars; - try - { - ul4.BlockAST._eval.call(this, localcontext); - } - catch (exc) - { - if (ul4.ReturnException.isprotoof(exc)) - return exc.result; - else - throw exc; - } - return null; - }, - call: function call(vars) - { - vars = vars || {}; - let context = ul4.Context.create(); - if (this.signature !== null) - vars = this.signature.bindObject(this.name, [], vars); - return this._callbound(context, vars); - }, - __call__: function __call__(context, vars) - { - return this._callbound(context, vars); - }, - __type__: "ul4.Template" // used by ``istemplate()`` - } - ); - - ul4.SignatureAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos) - { - let signature = ul4.CodeAST.create.call(this, tag, pos); - signature.params = []; - return signature; - }, - ul4ondump: function ul4ondump(encoder) - { - ul4.CodeAST.ul4ondump.call(this, encoder); - - let dump = []; - - for (let i = 0; i < this.params.length; ++i) - { - let param = this.params[i]; - if (param[1] === null) - dump.push(param[0]); - else - dump.push(param); - } - encoder.dump(dump); - }, - ul4onload: function ul4onload(decoder) - { - ul4.AST.ul4onload.call(this, decoder); - let dump = decoder.load(); - this.params = []; - for (let i = 0; i < dump.length; ++i) - { - let param = dump[i]; - if (typeof(param) === "string") - this.params.push([param, null]); - else - this.params.push(param); - } - }, - _eval: function _eval(context) - { - let args = []; - for (let i = 0; i < this.params.length; ++i) - { - let param = this.params[i]; - if (param[1] === null) - args.push(param[0]); - else - { - args.push(param[0] + "="); - args.push(param[1]._handle_eval(context)); - } - } - return ul4.Signature.create(...args); - }, - _repr: function _repr(out) - { - out.push("<"); - out.push(this.typename); - out.push(" params="); - this.params._repr(out); - out.push(">"); - } - } - ); - - ul4.TemplateClosure = ul4._inherit( - ul4.Proto, - { - create: function create(template, signature, vars) - { - let closure = ul4._clone(this); - closure.template = template; - closure.signature = signature; - closure.vars = vars; - closure._ul4_callsignature = signature; - closure._ul4_rendersignature = signature; - // Copy over the required attribute from the template - closure.name = template.name; - closure.tag = template.tag; - closure.endtag = template.endtag; - closure.source = template.source; - closure.startdelim = template.startdelim; - closure.enddelim = template.enddelim; - closure.docpos = template.docpos; - closure.content = template.content; - return closure; - }, - _ul4_callneedsobject: true, - _ul4_callneedscontext: true, - _ul4_renderneedsobject: true, - _ul4_renderneedscontext: true, - __render__: function __render__(context, vars) - { - this.template._renderbound(context, ul4._simpleinherit(this.vars, vars)); - }, - render: function render(context, vars) - { - this.template._renderbound(context, ul4._simpleinherit(this.vars, vars)); - }, - __call__: function __call__(context, vars) - { - return this.template._callbound(context, ul4._simpleinherit(this.vars, vars)); - }, - _renderbound: function _renderbound(context, vars) - { - this.template._renderbound(context, ul4._simpleinherit(this.vars, vars)); - }, - _rendersbound: function _rendersbound(context, vars) - { - return this.template._rendersbound(context, ul4._simpleinherit(this.vars, vars)); - }, - __getattr__: function __getattr__(attrname) - { - let self = this; - switch (attrname) - { - case "render": - return ul4.expose(this.signature, {needscontext: true, needsobject: true}, function render(context, vars){ self._renderbound(context, vars); }); - case "renders": - return ul4.expose(this.signature, {needscontext: true, needsobject: true}, function renders(context, vars){ return self._rendersbound(context, vars); }); - case "signature": - return this.signature; - default: - return this.template.__getattr__(attrname); - } - }, - __type__: "ul4.TemplateClosure" // used by ``istemplate()`` - } - ); - - // Create a color object from the red, green, blue and alpha values ``r``, ``g``, ``b`` and ``b`` - ul4._rgb = function _rgb(r, g, b, a) - { - return this.Color.create(255*r, 255*g, 255*b, 255*a); - }; - - // Convert ``obj`` to a string and escape the characters ``&``, ``<``, ``>``, ``'`` and ``"`` with their XML character/entity reference - ul4._xmlescape = function _xmlescape(obj) - { - obj = ul4._str(obj); - obj = obj.replace(/&/g, "&"); - obj = obj.replace(//g, ">"); - obj = obj.replace(/'/g, "'"); - obj = obj.replace(/"/g, """); - return obj; - }; - - // Convert ``obj`` to a string suitable for output into a CSV file - ul4._csv = function _csv(obj) - { - if (obj === null) - return ""; - else if (typeof(obj) !== "string") - obj = ul4._repr(obj); - if (obj.indexOf(",") !== -1 || obj.indexOf('"') !== -1 || obj.indexOf("\n") !== -1) - obj = '"' + obj.replace(/"/g, '""') + '"'; - return obj; - }; - - // Return a string containing one character with the codepoint ``i`` - ul4._chr = function _chr(i) - { - if (typeof(i) != "number") - throw ul4.TypeError.create("chr()", "chr() requires an int"); - return String.fromCharCode(i); - }; - - // Return the codepoint for the one and only character in the string ``c`` - ul4._ord = function _ord(c) - { - if (typeof(c) != "string" || c.length != 1) - throw ul4.TypeError.create("ord()", "ord() requires a string of length 1"); - return c.charCodeAt(0); - }; - - // Convert an integer to a hexadecimal string - ul4._hex = function _hex(number) - { - if (typeof(number) != "number") - throw ul4.TypeError.create("hex()", "hex() requires an int"); - if (number < 0) - return "-0x" + number.toString(16).substr(1); - else - return "0x" + number.toString(16); - }; - - // Convert an integer to a octal string - ul4._oct = function _oct(number) - { - if (typeof(number) != "number") - throw ul4.TypeError.create("oct()", "oct() requires an int"); - if (number < 0) - return "-0o" + number.toString(8).substr(1); - else - return "0o" + number.toString(8); - }; - - // Convert an integer to a binary string - ul4._bin = function _bin(number) - { - if (typeof(number) != "number") - throw ul4.TypeError.create("bin()", "bin() requires an int"); - if (number < 0) - return "-0b" + number.toString(2).substr(1); - else - return "0b" + number.toString(2); - }; - - // Return the minimum value - ul4._min = function _min(obj) - { - if (obj.length == 0) - throw ul4.ArgumentError.create("min() requires at least 1 argument, 0 given"); - else if (obj.length == 1) - obj = obj[0]; - let iter = ul4._iter(obj); - let result; - let first = true; - while (true) - { - let item = iter.next(); - if (item.done) - { - if (first) - throw ul4.ValueError.create("min() argument is an empty sequence!"); - return result; - } - if (first || (item.value < result)) - result = item.value; - first = false; - } - }; - - // Return the maximum value - ul4._max = function _max(obj) - { - if (obj.length == 0) - throw ul4.ArgumentError.create("max() requires at least 1 argument, 0 given"); - else if (obj.length == 1) - obj = obj[0]; - let iter = ul4._iter(obj); - let result; - let first = true; - while (true) - { - let item = iter.next(); - if (item.done) - { - if (first) - throw ul4.ValueError.create("max() argument is an empty sequence!"); - return result; - } - if (first || (item.value > result)) - result = item.value; - first = false; - } - }; - - // Return the of the values from the iterable starting with ``start`` (default ``0``) - ul4._sum = function _sum(iterable, start=0) - { - for (let iter = ul4._iter(iterable);;) - { - let item = iter.next(); - if (item.done) - break; - start += item.value; - } - return start; - }; - - // Return the first value produced by iterating through ``iterable`` (defaulting to ``defaultValue`` if the iterator is empty) - ul4._first = function _first(iterable, defaultValue=null) - { - let item = ul4._iter(iterable).next(); - return item.done ? defaultValue : item.value; - }; - - // Return the last value produced by iterating through ``iterable`` (defaulting to ``defaultValue`` if the iterator is empty) - ul4._last = function _last(iterable, defaultValue=null) - { - let value = defaultValue; - - for (let iter = ul4._iter(iterable);;) - { - let item = iter.next(); - if (item.done) - break; - value = item.value; - } - return value; - }; - - // Return a sorted version of ``iterable`` - ul4._sorted = function _sorted(context, iterable, key=null, reverse=false) - { - if (key === null) - { - // FIXME: stability - let cmp = reverse ? function cmp(a, b) - { - return -ul4._cmp("<=>", a, b); - } : function cmp(a, b) - { - return ul4._cmp("<=>", a, b); - }; - let result = ul4._list(iterable); - result.sort(cmp); - return result; - } - else - { - var sort = []; - - for (var i = 0, iter = ul4._iter(iterable);;++i) - { - var item = iter.next(); - if (item.done) - break; - var keyvalue = ul4._call(context, key, [item.value], {}); - sort.push([keyvalue, i, item.value]); - } - cmp = function cmp(s1, s2) - { - let res = ul4._cmp("<=>", s1[0], s2[0]); - if (res) - return reverse ? -res : res; - res = ul4._cmp(s1[1], s2[1]); - return reverse ? -res : res; - }; - - sort.sort(cmp); - - let result = []; - for (let i = 0; i < sort.length; ++i) - result.push(sort[i][2]); - return result; - } - }; - - // Return a iterable object iterating from ``start`` upto (but not including) ``stop`` with a step size of ``step`` - ul4._range = function _range(args) - { - let start, stop, step; - if (args.length < 1) - throw ul4.ArgumentError.create("required range() argument missing"); - else if (args.length > 3) - throw ul4.ArgumentError.create("range() expects at most 3 positional arguments, " + args.length + " given"); - else if (args.length == 1) - { - start = 0; - stop = args[0]; - step = 1; - } - else if (args.length == 2) - { - start = args[0]; - stop = args[1]; - step = 1; - } - else if (args.length == 3) - { - start = args[0]; - stop = args[1]; - step = args[2]; - } - let lower, higher; - if (step === 0) - throw ul4.ValueError.create("range() requires a step argument != 0"); - else if (step > 0) - { - lower = start; - heigher = stop; - } - else - { - lower = stop; - heigher = start; - } - let length = (lower < heigher) ? Math.floor((heigher - lower - 1)/Math.abs(step)) + 1 : 0; - - return { - index: 0, - next: function() - { - if (this.index >= length) - return {done: true}; - return {value: start + (this.index++) * step, done: false}; - } - }; - }; - - // Return a iterable object returning a slice from the argument - ul4._slice = function _slice(args) - { - let iterable, start, stop, step; - if (args.length < 2) - throw ul4.ArgumentError.create("required slice() argument missing"); - else if (args.length > 4) - throw ul4.ArgumentError.create("slice() expects at most 4 positional arguments, " + args.length + " given"); - else if (args.length == 2) - { - iterable = args[0]; - start = 0; - stop = args[1]; - step = 1; - } - else if (args.length == 3) - { - iterable = args[0]; - start = args[1] !== null ? args[1] : 0; - stop = args[2]; - step = 1; - } - else if (args.length == 4) - { - iterable = args[0]; - start = args[1] !== null ? args[1] : 0; - stop = args[2]; - step = args[3] !== null ? args[3] : 1; - } - if (start < 0) - throw ul4.ValueError.create("slice() requires a start argument >= 0"); - if (stop < 0) - throw ul4.ValueError.create("slice() requires a stop argument >= 0"); - if (step <= 0) - throw ul4.ValueError.create("slice() requires a step argument > 0"); - - let next = start, count = 0; - let iter = ul4._iter(iterable); - return { - next: function() { - let result; - while (count < next) - { - result = iter.next(); - if (result.done) - return result; - ++count; - } - if (stop !== null && count >= stop) - return {done: true}; - result = iter.next(); - if (result.done) - return result; - ++count; - next += step; - if (stop !== null && next > stop) - next = stop; - return result; - } - }; - }; - - // ``%`` escape unsafe characters in the string ``string`` - ul4._urlquote = function _urlquote(string) - { - return encodeURIComponent(string); - }; - - // The inverse function of ``urlquote`` - ul4._urlunquote = function _urlunquote(string) - { - return decodeURIComponent(string); - }; - - // Return a reverse iterator over ``sequence`` - ul4._reversed = function _reversed(sequence) - { - if (typeof(sequence) != "string" && !ul4._islist(sequence)) // We don't have to materialize strings or lists - sequence = ul4._list(sequence); - return { - index: sequence.length-1, - next: function() { - return this.index >= 0 ? {value: sequence[this.index--], done: false} : {done: true}; - } - }; - }; - - // Returns a random number in the interval ``[0;1[`` - ul4._random = function _random() - { - return Math.random(); - }; - - // Return a randomly select item from ``range(start, stop, step)`` - ul4._randrange = function _randrange(args) - { - let start, stop, step; - if (args.length < 1) - throw ul4.ArgumentError.create("required randrange() argument missing"); - else if (args.length > 3) - throw ul4.ArgumentError.create("randrange() expects at most 3 positional arguments, " + args.length + " given"); - else if (args.length == 1) - { - start = 0; - stop = args[0]; - step = 1; - } - else if (args.length == 2) - { - start = args[0]; - stop = args[1]; - step = 1; - } - else if (args.length == 3) - { - start = args[0]; - stop = args[1]; - step = args[2]; - } - let width = stop-start; - - let value = Math.random(); - - let n; - if (step > 0) - n = Math.floor((width + step - 1) / step); - else if (step < 0) - n = Math.floor((width + step + 1) / step); - else - throw ul4.ValueError.create("randrange() requires a step argument != 0"); - return start + step*Math.floor(value * n); - }; - - // Return a random item/char from the list/string ``sequence`` - ul4._randchoice = function _randchoice(sequence) - { - let iscolor = ul4._iscolor(sequence); - if (typeof(sequence) !== "string" && !ul4._islist(sequence) && !iscolor) - throw ul4.TypeError.create("randchoice() requires a string or list"); - if (iscolor) - sequence = ul4._list(sequence); - return sequence[Math.floor(Math.random() * sequence.length)]; - }; - - // Round a number ``x`` to ``digits`` decimal places (may be negative) - ul4._round = function _round(x, digits=0) - { - if (digits) - { - let threshhold = Math.pow(10, digits); - return Math.round(x*threshhold)/threshhold; - } - else - return Math.round(x); - }; - - // Return a hex-encode MD5 hash of the argument - // This uses the md5 function from https://github.com/blueimp/JavaScript-MD5 - if (iscommon) { - ul4._md5 = function _md5(string) - { - let md5 = require('blueimp-md5'); - return md5(string); - }; - } else { - ul4._md5 = function _md5(string) - { - return md5(string); - }; - } - - // Return an iterator over ``[index, item]`` lists from the iterable object ``iterable``. ``index`` starts at ``start`` (defaulting to 0) - ul4._enumerate = function _enumerate(iterable, start=0) - { - return { - iter: ul4._iter(iterable), - index: start, - next: function() { - let item = this.iter.next(); - return item.done ? item : {value: [this.index++, item.value], done: false}; - } - }; - }; - - // Return an iterator over ``[isfirst, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, false otherwise) - ul4._isfirst = function _isfirst(iterable) - { - let iter = ul4._iter(iterable); - let isfirst = true; - return { - next: function() { - let item = iter.next(); - let result = item.done ? item : {value: [isfirst, item.value], done: false}; - isfirst = false; - return result; - } - }; - }; - - // Return an iterator over ``[islast, item]`` lists from the iterable object ``iterable`` (``islast`` is true for the last item, false otherwise) - ul4._islast = function _islast(iterable) - { - let iter = ul4._iter(iterable); - let lastitem = iter.next(); - return { - next: function() { - if (lastitem.done) - return lastitem; - let item = iter.next(); - let result = {value: [item.done, lastitem.value], done: false}; - lastitem = item; - return result; - } - }; - }; - - // Return an iterator over ``[isfirst, islast, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, ``islast`` is true for the last item. Both are false otherwise) - ul4._isfirstlast = function _isfirstlast(iterable) - { - let iter = ul4._iter(iterable); - let isfirst = true; - let lastitem = iter.next(); - return { - next: function() { - if (lastitem.done) - return lastitem; - let item = iter.next(); - let result = {value: [isfirst, item.done, lastitem.value], done: false}; - lastitem = item; - isfirst = false; - return result; - } - }; - }; - - // Return an iterator over ``[index, isfirst, islast, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, ``islast`` is true for the last item. Both are false otherwise) - ul4._enumfl = function _enumfl(iterable, start=0) - { - let iter = ul4._iter(iterable); - let i = start; - let isfirst = true; - let lastitem = iter.next(); - return { - next: function() { - if (lastitem.done) - return lastitem; - let item = iter.next(); - let result = {value: [i++, isfirst, item.done, lastitem.value], done: false}; - lastitem = item; - isfirst = false; - return result; - } - }; - }; - - // Return an iterator over lists, where the i'th list consists of all i'th items from the arguments (terminating when the shortest argument ends) - ul4._zip = function _zip(iterables) - { - let result; - if (iterables.length) - { - let iters = []; - for (let i = 0; i < iterables.length; ++i) - iters.push(ul4._iter(iterables[i])); - - return { - next: function() { - let items = []; - for (let i = 0; i < iters.length; ++i) - { - let item = iters[i].next(); - if (item.done) - return item; - items.push(item.value); - } - return {value: items, done: false}; - } - }; - } - else - { - return { - next: function() { - return {done: true}; - } - }; - } - }; - - // Return the absolute value for the number ``number`` - ul4._abs = function _abs(number) - { - if (number !== null && typeof(number.__abs__) === "function") - return number.__abs__(); - return Math.abs(number); - }; - - // Return a ``Date`` object from the arguments passed in - ul4._date = function _date(year, month, day, hour=0, minute=0, second=0, microsecond=0) - { - return new Date(year, month-1, day, hour, minute, second, microsecond/1000); - }; - - // Return a ``TimeDelta`` object from the arguments passed in - ul4._timedelta = function _timedelta(days=0, seconds=0, microseconds=0) - { - return this.TimeDelta.create(days, seconds, microseconds); - }; - - // Return a ``MonthDelta`` object from the arguments passed in - ul4._monthdelta = function _monthdelta(months=0) - { - return this.MonthDelta.create(months); - }; - - // Return a ``Color`` object from the hue, luminescence, saturation and alpha values ``h``, ``l``, ``s`` and ``a`` (i.e. using the HLS color model) - ul4._hls = function _hls(h, l, s, a) - { - let _v = function(m1, m2, hue) - { - hue = hue % 1.0; - if (hue < 1/6) - return m1 + (m2-m1)*hue*6.0; - else if (hue < 0.5) - return m2; - else if (hue < 2/3) - return m1 + (m2-m1)*(2/3-hue)*6.0; - return m1; - }; - - let m1, m2; - if (typeof(a) === "undefined") - a = 1; - if (s === 0.0) - return ul4._rgb(l, l, l, a); - if (l <= 0.5) - m2 = l * (1.0+s); - else - m2 = l+s-(l*s); - m1 = 2.0*l - m2; - return ul4._rgb(_v(m1, m2, h+1/3), _v(m1, m2, h), _v(m1, m2, h-1/3), a); - }; - - // Return a ``Color`` object from the hue, saturation, value and alpha values ``h``, ``s``, ``v`` and ``a`` (i.e. using the HSV color model) - ul4._hsv = function _hsv(h, s, v, a) - { - if (s === 0.0) - return ul4._rgb(v, v, v, a); - let i = Math.floor(h*6.0); - let f = (h*6.0) - i; - let p = v*(1.0 - s); - let q = v*(1.0 - s*f); - let t = v*(1.0 - s*(1.0-f)); - switch (i%6) - { - case 0: - return ul4._rgb(v, t, p, a); - case 1: - return ul4._rgb(q, v, p, a); - case 2: - return ul4._rgb(p, v, t, a); - case 3: - return ul4._rgb(p, q, v, a); - case 4: - return ul4._rgb(t, p, v, a); - case 5: - return ul4._rgb(v, p, q, a); - } - }; - - // Return the item with the key ``key`` from the dict ``container``. If ``container`` doesn't have this key, return ``defaultvalue`` - ul4._get = function _get(container, key, defaultvalue) - { - if (ul4._ismap(container)) - { - if (container.has(key)) - return container.get(key); - return defaultvalue; - } - else if (ul4._isobject(container)) - { - var result = container[key]; - if (typeof(result) === "undefined") - return defaultvalue; - return result; - } - throw ul4.TypeError.create("get()", "get() requires a dict"); - }; - - // Return a ``Date`` object for the current time - ul4.now = function now() - { - return new Date(); - }; - - // Return a ``Date`` object for the current time in UTC - ul4.utcnow = function utcnow() - { - var now = new Date(); - // FIXME: The timezone is wrong for the new ``Date`` object. - return new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(), now.getUTCMilliseconds()); - }; - - ul4.functions = { - repr: ul4.expose(["obj"], {name: "repr"}, ul4._repr), - ascii: ul4.expose(["obj"], {name: "ascii"}, ul4._ascii), - str: ul4.expose(["obj=", ""], {name: "str"}, ul4._str), - int: ul4.expose(["obj=", 0, "base=", null], {name: "int"}, ul4._int), - float: ul4.expose(["obj=", 0.0], {name: "float"}, ul4._float), - list: ul4.expose(["iterable=", []], {name: "list"}, ul4._list), - set: ul4.expose(["iterable=", []], {name: "set"}, ul4._set), - bool: ul4.expose(["obj=", false], {name: "bool"}, ul4._bool), - len: ul4.expose(["sequence"], {name: "len"}, ul4._len), - type: ul4.expose(["obj"], {name: "type"}, ul4._type), - format: ul4.expose(["obj", "fmt", "lang=", null], {name: "format"}, ul4._format), - any: ul4.expose(["iterable"], {name: "any"}, ul4._any), - all: ul4.expose(["iterable"], {name: "all"}, ul4._all), - zip: ul4.expose(["*iterables"], {name: "zip"}, ul4._zip), - getattr: ul4.expose(["obj", "attrname", "default=", null], {name: "getattr"}, ul4._getattr), - hasattr: ul4.expose(["obj", "attrname"], {name: "hasattr"}, ul4._hasattr), - dir: ul4.expose(["obj"], {name: "dir"}, ul4._dir), - isundefined: ul4.expose(["obj"], {name: "isundefined"}, ul4._isundefined), - isdefined: ul4.expose(["obj"], {name: "isdefined"}, ul4._isdefined), - isnone: ul4.expose(["obj"], {name: "isnone"}, ul4._isnone), - isbool: ul4.expose(["obj"], {name: "isbool"}, ul4._isbool), - isint: ul4.expose(["obj"], {name: "isint"}, ul4._isint), - isfloat: ul4.expose(["obj"], {name: "isfloat"}, ul4._isfloat), - isstr: ul4.expose(["obj"], {name: "isstr"}, ul4._isstr), - isdate: ul4.expose(["obj"], {name: "isdate"}, ul4._isdate), - iscolor: ul4.expose(["obj"], {name: "iscolor"}, ul4._iscolor), - istimedelta: ul4.expose(["obj"], {name: "istimedelta"}, ul4._istimedelta), - ismonthdelta: ul4.expose(["obj"], {name: "ismonthdelta"}, ul4._ismonthdelta), - istemplate: ul4.expose(["obj"], {name: "istemplate"}, ul4._istemplate), - isfunction: ul4.expose(["obj"], {name: "isfunction"}, ul4._isfunction), - islist: ul4.expose(["obj"], {name: "islist"}, ul4._islist), - isset: ul4.expose(["obj"], {name: "isset"}, ul4on._haveset ? ul4._isset : ul4._isul4set), - isdict: ul4.expose(["obj"], {name: "isdict"}, ul4._isdict), - isexception: ul4.expose(["obj"], {name: "isexception"}, ul4._isexception), - asjson: ul4.expose(["obj"], {name: "asjson"}, ul4._asjson), - fromjson: ul4.expose(["string"], {name: "fromjson"}, ul4._fromjson), - asul4on: ul4.expose(["obj"], {name: "asul4on"}, ul4._asul4on), - fromul4on: ul4.expose(["string"], {name: "fromul4on"}, ul4._fromul4on), - now: ul4.expose([], ul4.now), - utcnow: ul4.expose([], ul4.utcnow), - enumerate: ul4.expose(["iterable", "start=", 0], {name: "enumerate"}, ul4._enumerate), - isfirst: ul4.expose(["iterable"], {name: "isfirst"}, ul4._isfirst), - islast: ul4.expose(["iterable"], {name: "islast"}, ul4._islast), - isfirstlast: ul4.expose(["iterable"], {name: "isfirstlast"}, ul4._isfirstlast), - enumfl: ul4.expose(["iterable", "start=", 0], {name: "enumfl"}, ul4._enumfl), - abs: ul4.expose(["number"], {name: "abs"}, ul4._abs), - date: ul4.expose(["year", "month", "day", "hour=", 0, "minute=", 0, "second=", 0, "microsecond=", 0], {name: "date"}, ul4._date), - timedelta: ul4.expose(["days=", 0, "seconds=", 0, "microseconds=", 0], {name: "timedelta"}, ul4._timedelta), - monthdelta: ul4.expose(["months=", 0], {name: "monthdelta"}, ul4._monthdelta), - rgb: ul4.expose(["r", "g", "b", "a=", 1.0], {name: "rgb"}, ul4._rgb), - hls: ul4.expose(["h", "l", "s", "a=", 1.0], {name: "hls"}, ul4._hls), - hsv: ul4.expose(["h", "s", "v", "a=", 1.0], {name: "hsv"}, ul4._hsv), - xmlescape: ul4.expose(["obj"], {name: "xmlescape"}, ul4._xmlescape), - csv: ul4.expose(["obj"], {name: "csv"}, ul4._csv), - chr: ul4.expose(["i"], {name: "chr"}, ul4._chr), - ord: ul4.expose(["c"], {name: "ord"}, ul4._ord), - hex: ul4.expose(["number"], {name: "hex"}, ul4._hex), - oct: ul4.expose(["number"], {name: "oct"}, ul4._oct), - bin: ul4.expose(["number"], {name: "bin"}, ul4._bin), - min: ul4.expose(["*obj"], {name: "min"}, ul4._min), - max: ul4.expose(["*obj"], {name: "max"}, ul4._max), - sum: ul4.expose(["iterable", "start=", 0], {name: "sum"}, ul4._sum), - first: ul4.expose(["iterable", "default=", null], {name: "first"}, ul4._first), - last: ul4.expose(["iterable", "default=", null], {name: "last"}, ul4._last), - sorted: ul4.expose(["iterable", "key=", null, "reverse=", false], {name: "sorted", needscontext: true}, ul4._sorted), - range: ul4.expose(["*args"], {name: "range"}, ul4._range), - slice: ul4.expose(["*args"], {name: "slice"}, ul4._slice), - urlquote: ul4.expose(["string"], {name: "urlquote"}, ul4._urlquote), - urlunquote: ul4.expose(["string"], {name: "urlunquote"}, ul4._urlunquote), - reversed: ul4.expose(["sequence"], {name: "reversed"}, ul4._reversed), - random: ul4.expose([], {name: "random"}, ul4._random), - randrange: ul4.expose(["*args"], {name: "randrange"}, ul4._randrange), - randchoice: ul4.expose(["sequence"], {name: "randchoice"}, ul4._randchoice), - round: ul4.expose(["x", "digit=", 0], {name: "round"}, ul4._round), - md5: ul4.expose(["string"], {name: "md5"}, ul4._md5) - }; - - // Functions implementing UL4 methods - ul4._replace = function _replace(string, old, new_, count=null) - { - if (count === null) - count = string.length; - - let result = []; - while (string.length) - { - let pos = string.indexOf(old); - if (pos === -1 || !count--) - { - result.push(string); - break; - } - result.push(string.substr(0, pos)); - result.push(new_); - string = string.substr(pos + old.length); - } - return result.join(""); - }; - - ul4._strip = function _strip(string, chars=null) - { - chars = chars || " \r\n\t"; - if (typeof(chars) !== "string") - throw ul4.TypeError.create("strip()", "strip() requires two strings"); - - while (string && chars.indexOf(string[0]) >= 0) - string = string.substr(1); - while (string && chars.indexOf(string[string.length-1]) >= 0) - string = string.substr(0, string.length-1); - return string; - }; - - ul4._lstrip = function _lstrip(string, chars=null) - { - chars = chars || " \r\n\t"; - if (typeof(chars) !== "string") - throw ul4.TypeError.create("lstrip()", "lstrip() requires two strings"); - - while (string && chars.indexOf(string[0]) >= 0) - string = string.substr(1); - return string; - }; - - ul4._rstrip = function _rstrip(string, chars=null) - { - chars = chars || " \r\n\t"; - if (typeof(chars) !== "string") - throw ul4.TypeError.create("rstrip()", "rstrip() requires two strings"); - - while (string && chars.indexOf(string[string.length-1]) >= 0) - string = string.substr(0, string.length-1); - return string; - }; - - ul4._split = function _split(string, sep=null, count=null) - { - if (sep !== null && typeof(sep) !== "string") - throw ul4.TypeError.create("split()", "split() requires a string"); - - if (count === null) - { - let result = string.split(sep !== null ? sep : /[ \n\r\t]+/); - if (sep === null) - { - if (result.length && !result[0].length) - result.splice(0, 1); - if (result.length && !result[result.length-1].length) - result.splice(-1); - } - return result; - } - else - { - if (sep !== null) - { - let result = []; - while (string.length) - { - let pos = string.indexOf(sep); - if (pos === -1 || !count--) - { - result.push(string); - break; - } - result.push(string.substr(0, pos)); - string = string.substr(pos + sep.length); - } - return result; - } - else - { - let result = []; - while (string.length) - { - string = ul4._lstrip(string, null); - let part; - if (!count--) - part = string; // Take the rest of the string - else - part = string.split(/[ \n\r\t]+/, 1)[0]; - if (part.length) - result.push(part); - string = string.substr(part.length); - } - return result; - } - } - }; - - ul4._rsplit = function _rsplit(string, sep=null, count=null) - { - if (sep !== null && typeof(sep) !== "string") - throw ul4.TypeError.create("rsplit()", "rsplit() requires a string as second argument"); - - if (count === null) - { - let result = string.split(sep !== null ? sep : /[ \n\r\t]+/); - if (sep === null) - { - if (result.length && !result[0].length) - result.splice(0, 1); - if (result.length && !result[result.length-1].length) - result.splice(-1); - } - return result; - } - else - { - if (sep !== null) - { - let result = []; - while (string.length) - { - let pos = string.lastIndexOf(sep); - if (pos === -1 || !count--) - { - result.unshift(string); - break; - } - result.unshift(string.substr(pos+sep.length)); - string = string.substr(0, pos); - } - return result; - } - else - { - let result = []; - while (string.length) - { - string = ul4._rstrip(string); - let part; - if (!count--) - part = string; // Take the rest of the string - else - { - part = string.split(/[ \n\r\t]+/); - part = part[part.length-1]; - } - if (part.length) - result.unshift(part); - string = string.substr(0, string.length-part.length); - } - return result; - } - } - }; - - ul4._splitlines = function _splitlines(string, keepends=false) - { - let pos = 0; - let lookingAtLineEnd = function lookingAtLineEnd() - { - let c = string[pos]; - if (c === '\n' || c == '\u000B' || c == '\u000C' || c == '\u001C' || c == '\u001D' || c == '\u001E' || c == '\u0085' || c == '\u2028' || c == '\u2029') - return 1; - if (c === '\r') - { - if (pos == length-1) - return 1; - if (string[pos+1] === '\n') - return 2; - return 1; - } - return 0; - }; - - let result = [], length = string.length; - - for (pos = 0, startpos = 0;;) - { - if (pos >= length) - { - if (startpos != pos) - result.push(string.substring(startpos)); - return result; - } - let lineendlen = lookingAtLineEnd(); - if (!lineendlen) - ++pos; - else - { - let endpos = pos + (keepends ? lineendlen : 0); - result.push(string.substring(startpos, endpos)); - pos += lineendlen; - startpos = pos; - } - } - }; - - ul4._count = function _count(obj, sub, start=null, end=null) - { - if (start < 0) - start += obj.length; - if (start === null) - start = 0; - - if (end < 0) - end += obj.length; - if (end === null) - end = obj.length; - - let isstr = ul4._isstr(obj); - - if (isstr && !sub.length) - { - if (end < 0 || start > obj.length || start > end) - return 0; - let result = end - start + 1; - if (result > obj.length + 1) - result = obj.length + 1; - return result; - } - - start = ul4._bound(start, obj.length); - end = ul4._bound(end, obj.length); - - let count = 0; - if (ul4._islist(obj)) - { - for (let i = start; i < end; ++i) - { - if (ul4._eq(obj[i], sub)) - ++count; - } - return count; - } - else // string - { - let lastIndex = start; - - for (;;) - { - lastIndex = obj.indexOf(sub, lastIndex); - if (lastIndex == -1) - break; - if (lastIndex + sub.length > end) - break; - ++count; - lastIndex += sub.length; - } - return count; - } - }; - - ul4._find = function _find(obj, sub, start=null, end=null) - { - if (start < 0) - start += obj.length; - if (start === null) - start = 0; - if (end < 0) - end += obj.length; - if (end === null) - end = obj.length; - start = ul4._bound(start, obj.length); - end = ul4._bound(end, obj.length); - - if (start !== 0 || end !== obj.length) - { - if (typeof(obj) == "string") - obj = obj.substring(start, end); - else - obj = obj.slice(start, end); - } - let result = obj.indexOf(sub); - if (result !== -1) - result += start; - return result; - }; - - ul4._rfind = function _rfind(obj, sub, start=null, end=null) - { - if (start < 0) - start += obj.length; - if (start === null) - start = 0; - if (end < 0) - end += obj.length; - if (end === null) - end = obj.length; - start = ul4._bound(start, obj.length); - end = ul4._bound(end, obj.length); - - if (start !== 0 || end !== obj.length) - { - if (typeof(obj) == "string") - obj = obj.substring(start, end); - else - obj = obj.slice(start, end); - } - let result = obj.lastIndexOf(sub); - if (result !== -1) - result += start; - return result; - }; - - ul4._capitalize = function _capitalize(obj) - { - if (typeof(obj) != "string") - throw ul4.TypeError.create("capitalize()", "capitalize() requires a string"); - - if (obj.length) - obj = obj[0].toUpperCase() + obj.slice(1).toLowerCase(); - return obj; - }; - - ul4._items = function _items(obj) - { - if (ul4._ismap(obj)) - { - let result = []; - obj.forEach(function(value, key){ - result.push([key, value]); - }); - return result; - } - else if (ul4._isobject(obj)) - { - let result = []; - for (let key in obj) - result.push([key, obj[key]]); - return result; - } - throw ul4.TypeError.create("items()", "items() requires a dict"); - }; - - ul4._values = function _values(obj) - { - if (ul4._ismap(obj)) - { - let result = []; - obj.forEach(function(value, key){ - result.push(value); - }); - return result; - } - else if (ul4._isobject(obj)) - { - let result = []; - for (let key in obj) - result.push(obj[key]); - return result; - } - throw ul4.TypeError.create("values()", "values() requires a dict"); - }; - - ul4._join = function _join(sep, iterable) - { - let resultlist = []; - for (let iter = ul4._iter(iterable);;) - { - let item = iter.next(); - if (item.done) - break; - resultlist.push(item.value); - } - return resultlist.join(sep); - }; - - ul4._startswith = function _startswith(string, prefix) - { - if (typeof(prefix) !== "string") - throw ul4.TypeError.create("startswith()", "startswith() argument must be string"); - - return string.substr(0, prefix.length) === prefix; - }; - - ul4._endswith = function _endswith(string, suffix) - { - if (typeof(suffix) !== "string") - throw ul4.TypeError.create("endswith()", "endswith() argument must be string"); - - return string.substr(string.length-suffix.length) === suffix; - }; - - ul4._isoformat = function _isoformat(obj) - { - if (!ul4._isdate(obj)) - throw ul4.TypeError.create("isoformat()", "isoformat() requires a date"); - - let result = obj.getFullYear() + "-" + ul4._lpad((obj.getMonth()+1).toString(), "0", 2) + "-" + ul4._lpad(obj.getDate().toString(), "0", 2); - let hour = obj.getHours(); - let minute = obj.getMinutes(); - let second = obj.getSeconds(); - let ms = obj.getMilliseconds(); - if (hour || minute || second || ms) - { - result += "T" + ul4._lpad(hour.toString(), "0", 2) + ":" + ul4._lpad(minute.toString(), "0", 2) + ":" + ul4._lpad(second.toString(), "0", 2); - if (ms) - result += "." + ul4._lpad(ms.toString(), "0", 3) + "000"; - } - return result; - }; - - ul4._mimeformat = function _mimeformat(obj) - { - let weekdayname = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - let monthname = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; - - return weekdayname[ul4._weekday(obj)] + ", " + ul4._lpad(obj.getDate(), "0", 2) + " " + monthname[obj.getMonth()] + " " + obj.getFullYear() + " " + ul4._lpad(obj.getHours(), "0", 2) + ":" + ul4._lpad(obj.getMinutes(), "0", 2) + ":" + ul4._lpad(obj.getSeconds(), "0", 2) + " GMT"; - }; - - ul4._weekday = function _weekday(obj) - { - let d = obj.getDay(); - return d ? d-1 : 6; - }; - - ul4._week = function _week(obj, firstweekday=null) - { - if (firstweekday === null) - firstweekday = 0; - else - firstweekday %= 7; - - let yearday = ul4._yearday(obj)+6; - let jan1 = new Date(obj.getFullYear(), 0, 1); - let jan1weekday = jan1.getDay(); - if (--jan1weekday < 0) - jan1weekday = 6; - - while (jan1weekday != firstweekday) - { - --yearday; - if (++jan1weekday == 7) - jan1weekday = 0; - } - return Math.floor(yearday/7); - }; - - ul4._isleap = function _isleap(obj) - { - return new Date(obj.getFullYear(), 1, 29).getMonth() === 1; - }; - - ul4._yearday = function _yearday(obj) - { - let leap = ul4._isleap(obj) ? 1 : 0; - let day = obj.getDate(); - switch (obj.getMonth()) - { - case 0: - return day; - case 1: - return 31 + day; - case 2: - return 31 + 28 + leap + day; - case 3: - return 31 + 28 + leap + 31 + day; - case 4: - return 31 + 28 + leap + 31 + 30 + day; - case 5: - return 31 + 28 + leap + 31 + 30 + 31 + day; - case 6: - return 31 + 28 + leap + 31 + 30 + 31 + 30 + day; - case 7: - return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + day; - case 8: - return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + day; - case 9: - return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + day; - case 10: - return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + day; - case 11: - return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + day; - } - }; - - ul4._append = function _append(obj, ...items) - { - for (let i = 0; i < items.length; ++i) - obj.push(items[i]); - return null; - }; - - ul4._insert = function _insert(obj, pos, ...items) - { - if (pos < 0) - pos += obj.length; - - for (let i = 0; i < items.length; ++i) - obj.splice(pos++, 0, items[i]); - return null; - }; - - ul4._pop = function _pop(obj, pos) - { - if (pos < 0) - pos += obj.length; - - let result = obj[pos]; - obj.splice(pos, 1); - return result; - }; - - ul4._update = function _update(obj, others, kwargs) - { - if (!ul4._isdict(obj)) - throw ul4.TypeError.create("update()", "update() requires a dict"); - for (let i = 0; i < others.length; ++i) - { - let other = others[i]; - if (ul4._ismap(other)) - { - other.forEach(function(value, key){ - ul4on._setmap(obj, key, value); - }); - } - else if (ul4._isobject(other)) - { - for (let key in other) - ul4on._setmap(obj, key, other[key]); - } - else if (ul4._islist(other)) - { - for (let j = 0; j < other.length; ++j) - { - if (!ul4._islist(other[j]) || (other[j].length != 2)) - throw ul4.TypeError.create("update()", "update() requires a dict or a list of (key, value) pairs"); - ul4on._setmap(obj, other[j][0], other[j][1]); - } - } - else - throw ul4.TypeError.create("update()", "update() requires a dict or a list of (key, value) pairs"); - } - kwargs.forEach(function(value, key) { - ul4on._setmap(obj, key, value); - }); - return null; - }; - - ul4._clear = function _clear(obj) - { - if (ul4._ismap(obj)) - obj.clear(); - else if (ul4._isset(obj)) - obj.clear(); - else if (ul4._isobject(obj)) - { - for (let key in obj) - delete obj[key]; - } - else - throw ul4.TypeError.create("clear()", "clear() requires a dict or set"); - return null; - }; - - ul4.Color = ul4._inherit( - ul4.Proto, - { - __type__: "ul4.Color", - - create: function create(r=0, g=0, b=0, a=255) - { - let c = ul4._clone(this); - c._r = r; - c._g = g; - c._b = b; - c._a = a; - return c; - }, - - __repr__: function __repr__() - { - let r = ul4._lpad(this._r.toString(16), "0", 2); - let g = ul4._lpad(this._g.toString(16), "0", 2); - let b = ul4._lpad(this._b.toString(16), "0", 2); - let a = ul4._lpad(this._a.toString(16), "0", 2); - if (this._a !== 0xff) - { - if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1] && a[0] === a[1]) - return "#" + r[0] + g[0] + b[0] + a[0]; - else - return "#" + r + g + b + a; - } - else - { - if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1]) - return "#" + r[0] + g[0] + b[0]; - else - return "#" + r + g + b; - } - }, - - __str__: function __str__() - { - if (this._a !== 0xff) - { - return "rgba(" + this._r + ", " + this._g + ", " + this._b + ", " + (this._a/255) + ")"; - } - else - { - let r = ul4._lpad(this._r.toString(16), "0", 2); - let g = ul4._lpad(this._g.toString(16), "0", 2); - let b = ul4._lpad(this._b.toString(16), "0", 2); - let a = ul4._lpad(this._a.toString(16), "0", 2); - if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1]) - return "#" + r[0] + g[0] + b[0]; - else - return "#" + r + g + b; - } - }, - - __iter__: function __iter__() - { - return { - obj: this, - index: 0, - next: function() { - if (this.index == 0) - { - ++this.index; - return {value: this.obj._r, done: false}; - } - else if (this.index == 1) - { - ++this.index; - return {value: this.obj._g, done: false}; - } - else if (this.index == 2) - { - ++this.index; - return {value: this.obj._b, done: false}; - } - else if (this.index == 3) - { - ++this.index; - return {value: this.obj._a, done: false}; - } - else - return {done: true}; - } - }; - }, - - __getattr__: function __getattr__(attrname) - { - let self = this; - switch (attrname) - { - case "r": - return ul4.expose([], function r(){ return self._r; }); - case "g": - return ul4.expose([], function g(){ return self._g; }); - case "b": - return ul4.expose([], function b(){ return self._b; }); - case "a": - return ul4.expose([], function a(){ return self._a; }); - case "lum": - return ul4.expose([], function lum(){ return self.lum(); }); - case "hls": - return ul4.expose([], function hls(){ return self.hls(); }); - case "hlsa": - return ul4.expose([], function hlsa(){ return self.hlsa(); }); - case "hsv": - return ul4.expose([], function hsv(){ return self.hsv(); }); - case "hsva": - return ul4.expose([], function hsva(){ return self.hsva(); }); - case "witha": - return ul4.expose(["a"], function witha(a){ return self.witha(a); }); - case "withlum": - return ul4.expose(["lum"], function withlum(lum){ return self.withlum(lum); }); - case "abslum": - return ul4.expose(["lum"], function abslum(lum){ return self.abslum(lum); }); - case "rellum": - return ul4.expose(["lum"], function rellum(lum){ return self.rellum(lum); }); - default: - throw ul4.AttributeError.create(this, attrname); - } - }, - - __getitem__: function __getitem__(key) - { - let orgkey = key; - if (key < 0) - key += 4; - switch (key) - { - case 0: - return this._r; - case 1: - return this._g; - case 2: - return this._b; - case 3: - return this._a; - default: - return undefined; - } - }, - - __eq__: function __eq__(other) - { - if (ul4._iscolor(other)) - return this._r == other._r && this._g == other._g && this._b == other._b && this._a == other._a; - return false; - }, - - r: ul4.expose([], function r() { return this._r; }), - - g: ul4.expose([], function g() { return this._g; }), - - b: ul4.expose([], function b() { return this._b; }), - - a: ul4.expose([], function a() { return this._a; }), - - lum: ul4.expose([], function lum() {return this.hls()[1]; }), - - hls: ul4.expose([], - function hls() - { - let r = this._r/255.0; - let g = this._g/255.0; - let b = this._b/255.0; - let maxc = Math.max(r, g, b); - let minc = Math.min(r, g, b); - let h, l, s; - let rc, gc, bc; - - l = (minc+maxc)/2.0; - if (minc == maxc) - return [0.0, l, 0.0]; - if (l <= 0.5) - s = (maxc-minc) / (maxc+minc); - else - s = (maxc-minc) / (2.0-maxc-minc); - rc = (maxc-r) / (maxc-minc); - gc = (maxc-g) / (maxc-minc); - bc = (maxc-b) / (maxc-minc); - if (r == maxc) - h = bc-gc; - else if (g == maxc) - h = 2.0+rc-bc; - else - h = 4.0+gc-rc; - h = (h/6.0) % 1.0; - return [h, l, s]; - } - ), - - hlsa: ul4.expose([], - function hlsa() - { - let hls = this.hls(); - return hls.concat(this._a/255.0); - } - ), - - hsv: ul4.expose([], - function hsv() - { - let r = this._r/255.0; - let g = this._g/255.0; - let b = this._b/255.0; - let maxc = Math.max(r, g, b); - let minc = Math.min(r, g, b); - let v = maxc; - if (minc == maxc) - return [0.0, 0.0, v]; - let s = (maxc-minc) / maxc; - let rc = (maxc-r) / (maxc-minc); - let gc = (maxc-g) / (maxc-minc); - let bc = (maxc-b) / (maxc-minc); - let h; - if (r == maxc) - h = bc-gc; - else if (g == maxc) - h = 2.0+rc-bc; - else - h = 4.0+gc-rc; - h = (h/6.0) % 1.0; - return [h, s, v]; - } - ), - - hsva: ul4.expose([], - function hsva() - { - var hsv = this.hsv(); - return hsv.concat(this._a/255.0); - } - ), - - witha: ul4.expose(["a"], - function witha(a) - { - if (typeof(a) !== "number") - throw ul4.TypeError.create("witha()", "witha() requires a number"); - return ul4.Color.create(this._r, this._g, this._b, a); - } - ), - - withlum: ul4.expose(["lum"], - function withlum(lum) - { - if (typeof(lum) !== "number") - throw ul4.TypeError.create("witha()", "witha() requires a number"); - let hlsa = this.hlsa(); - return ul4._hls(hlsa[0], lum, hlsa[2], hlsa[3]); - } - ) - } - ); - - ul4.TimeDelta = ul4._inherit( - ul4.Proto, - { - __type__: "ul4.TimeDelta", - - create: function create(days=0, seconds=0, microseconds=0) - { - let td = ul4._clone(this); - let total_microseconds = Math.floor((days * 86400 + seconds)*1000000 + microseconds); - - microseconds = ul4.ModAST._do(total_microseconds, 1000000); - let total_seconds = Math.floor(total_microseconds / 1000000); - seconds = ul4.ModAST._do(total_seconds, 86400); - days = Math.floor(total_seconds / 86400); - if (seconds < 0) - { - seconds += 86400; - --days; - } - - td._microseconds = microseconds; - td._seconds = seconds; - td._days = days; - - return td; - }, - - __repr__: function __repr__() - { - if (!this._microseconds) - { - if (!this._seconds) - { - if (!this._days) - return "timedelta()"; - return "timedelta(" + this._days + ")"; - } - return "timedelta(" + this._days + ", " + this._seconds + ")"; - } - return "timedelta(" + this._days + ", " + this._seconds + ", " + this._microseconds + ")"; - }, - - __str__: function __str__() - { - let v = []; - if (this._days) - { - v.push(this._days + " day"); - if (this._days !== -1 && this._days !== 1) - v.push("s"); - v.push(", "); - } - let seconds = this._seconds % 60; - let minutes = Math.floor(this._seconds / 60); - let hours = Math.floor(minutes / 60); - minutes = minutes % 60; - - v.push("" + hours); - v.push(":"); - v.push(ul4._lpad(minutes.toString(), "0", 2)); - v.push(":"); - v.push(ul4._lpad(seconds.toString(), "0", 2)); - if (this._microseconds) - { - v.push("."); - v.push(ul4._lpad(this._microseconds.toString(), "0", 6)); - } - return v.join(""); - }, - - __bool__: function __bool__() - { - return this._days !== 0 || this._seconds !== 0 || this._microseconds !== 0; - }, - - __abs__: function __abs__() - { - return this._days < 0 ? ul4.TimeDelta.create(-this._days, -this._seconds, -this._microseconds) : this; - }, - - __eq__: function __eq__(other) - { - if (ul4._istimedelta(other)) - return (this._days === other._days) && (this._seconds === other._seconds) && (this._microseconds === other._microseconds); - return false; - }, - - __lt__: function __lt__(other) - { - if (ul4._istimedelta(other)) - { - if (this._days != other._days) - return this._days < other._days; - if (this._seconds != other._seconds) - return this._seconds < other._seconds; - return this._microseconds < other._microseconds; - } - ul4._unorderable("<", this, other); - }, - - __le__: function __le__(other) - { - if (ul4._istimedelta(other)) - { - if (this._days != other._days) - return this._days < other._days; - if (this._seconds != other._seconds) - return this._seconds < other._seconds; - return this._microseconds <= other._microseconds; - } - ul4._unorderable("<=", this, other); - }, - - __gt__: function __gt__(other) - { - if (ul4._istimedelta(other)) - { - if (this._days != other._days) - return this._days > other._days; - if (this._seconds != other._seconds) - return this._seconds > other._seconds; - return this._microseconds > other._microseconds; - } - ul4._unorderable(">", this, other); - }, - - __ge__: function __ge__(other) - { - if (ul4._istimedelta(other)) - { - if (this._days != other._days) - return this._days > other._days; - if (this._seconds != other._seconds) - return this._seconds > other._seconds; - return this._microseconds >= other._microseconds; - } - ul4._unorderable(">=", this, other); - }, - - __neg__: function __neg__() - { - return ul4.TimeDelta.create(-this._days, -this._seconds, -this._microseconds); - }, - - _add: function _add(date, days, seconds, microseconds) - { - let year = date.getFullYear(); - let month = date.getMonth(); - let day = date.getDate() + days; - let hour = date.getHours(); - let minute = date.getMinutes(); - let second = date.getSeconds() + seconds; - let millisecond = date.getMilliseconds() + microseconds/1000; - return new Date(year, month, day, hour, minute, second, millisecond); - }, - - __add__: function __add__(other) - { - if (ul4._istimedelta(other)) - return ul4.TimeDelta.create(this._days + other._days, this._seconds + other._seconds, this._microseconds + other._microseconds); - else if (ul4._isdate(other)) - return this._add(other, this._days, this._seconds, this._microseconds); - throw ul4.TypeError.create("+", ul4._type(this) + " + " + ul4._type(other) + " not supported"); - }, - - __radd__: function __radd__(other) - { - if (ul4._isdate(other)) - return this._add(other, this._days, this._seconds, this._microseconds); - throw ul4.TypeError.create("+", ul4._type(this) + " + " + ul4._type(other) + " not supported"); - }, - - __sub__: function __sub__(other) - { - if (ul4._istimedelta(other)) - return ul4.TimeDelta.create(this._days - other._days, this._seconds - other._seconds, this._microseconds - other._microseconds); - throw ul4.TypeError.create("-", ul4._type(this) + " - " + ul4._type(other) + " not supported"); - }, - - __rsub__: function __rsub__(other) - { - if (ul4._isdate(other)) - return this._add(other, -this._days, -this._seconds, -this._microseconds); - throw ul4.TypeError.create("-", ul4._type(this) + " - " + ul4._type(other) + " not supported"); - }, - - __mul__: function __mul__(other) - { - if (typeof(other) === "number") - { - return ul4.TimeDelta.create(this._days * other, this._seconds * other, this._microseconds * other); - } - throw ul4.TypeError.create("*", ul4._type(this) + " * " + ul4._type(other) + " not supported"); - }, - - __rmul__: function __rmul__(other) - { - if (typeof(other) === "number") - { - return ul4.TimeDelta.create(this._days * other, this._seconds * other, this._microseconds * other); - } - throw ul4.TypeError.create("*", ul4._type(this) + " * " + ul4._type(other) + " not supported"); - }, - - __truediv__: function __truediv__(other) - { - if (typeof(other) === "number") - { - return ul4.TimeDelta.create(this._days / other, this._seconds / other, this._microseconds / other); - } - else if (ul4._istimedelta(other)) - { - let myValue = this._days; - let otherValue = other._days; - let hasSeconds = this._seconds || other._seconds; - let hasMicroseconds = this._microseconds || other._microseconds; - if (hasSeconds || hasMicroseconds) - { - myValue = myValue*86400+this._seconds; - otherValue = otherValue*86400 + other._seconds; - if (hasMicroseconds) - { - myValue = myValue * 1000000 + this._microseconds; - otherValue = otherValue * 1000000 + other._microseconds; - } - } - return myValue/otherValue; - } - throw ul4.TypeError.create("/", ul4._type(this) + " / " + ul4._type(other) + " not supported"); - }, - - __getattr__: function __getattr__(attrname) - { - let self = this; - switch (attrname) - { - case "days": - return ul4.expose([], function days(){ return self._days; }); - case "seconds": - return ul4.expose([], function seconds(){ return self._seconds; }); - case "microseconds": - return ul4.expose([], function microseconds(){ return self._microseconds; }); - default: - throw ul4.AttributeError.create(this, attrname); - } - }, - - days: function days() - { - return this._days; - }, - - seconds: function seconds() - { - return this._seconds; - }, - - microseconds: function microseconds() - { - return this._microseconds; - } - } - ); - - ul4.MonthDelta = ul4._inherit( - ul4.Proto, - { - __type__: "ul4.MonthDelta", - - create: function create(months=0) - { - let md = ul4._clone(this); - md._months = months; - return md; - }, - - __repr__: function __repr__() - { - if (!this._months) - return "monthdelta()"; - return "monthdelta(" + this._months + ")"; - }, - - __str__: function __str__() - { - if (this._months) - { - if (this._months !== -1 && this._months !== 1) - return this._months + " months"; - return this._months + " month"; - } - return "0 months"; - }, - - __bool__: function __bool__() - { - return this._months !== 0; - }, - - __abs__: function __abs__() - { - return this._months < 0 ? ul4.MonthDelta.create(-this._months) : this; - }, - - __eq__: function __eq__(other) - { - if (ul4._ismonthdelta(other)) - return this._months === other._months; - return false; - }, - - __lt__: function __lt__(other) - { - if (ul4._ismonthdelta(other)) - return this._months < other._months; - ul4._unorderable("<", this, other); - }, - - __le__: function __le__(other) - { - if (ul4._ismonthdelta(other)) - return this._months <= other._months; - ul4._unorderable("<=", this, other); - }, - - __gt__: function __gt__(other) - { - if (ul4._ismonthdelta(other)) - return this._months > other._months; - ul4._unorderable(">", this, other); - }, - - __ge__: function __ge__(other) - { - if (ul4._ismonthdelta(other)) - return this._months >= other._months; - ul4._unorderable(">=", this, other); - }, - - __neg__: function __neg__() - { - return ul4.MonthDelta.create(-this._months); - }, - - _add: function _add(date, months) - { - let year = date.getFullYear(); - let month = date.getMonth() + months; - let day = date.getDate(); - let hour = date.getHours(); - let minute = date.getMinutes(); - let second = date.getSeconds(); - let millisecond = date.getMilliseconds(); - - while (true) - { - // As the month might be out of bounds, we have to find out, what the real target month is - let targetmonth = new Date(year, month, 1, hour, minute, second, millisecond).getMonth(); - let result = new Date(year, month, day, hour, minute, second, millisecond); - if (result.getMonth() === targetmonth) - return result; - --day; - } - }, - - __add__: function __add__(other) - { - if (ul4._ismonthdelta(other)) - return ul4.MonthDelta.create(this._months + other._months); - else if (ul4._isdate(other)) - return this._add(other, this._months); - throw ul4._type(this) + " + " + ul4._type(other) + " not supported"; - }, - - __radd__: function __radd__(other) - { - if (ul4._isdate(other)) - return this._add(other, this._months); - throw ul4._type(this) + " + " + ul4._type(other) + " not supported"; - }, - - __sub__: function __sub__(other) - { - if (ul4._ismonthdelta(other)) - return ul4.MonthDelta.create(this._months - other._months); - throw ul4._type(this) + " - " + ul4._type(other) + " not supported"; - }, - - __rsub__: function __rsub__(other) - { - if (ul4._isdate(other)) - return this._add(other, -this._months); - throw ul4._type(this) + " - " + ul4._type(other) + " not supported"; - }, - - __mul__: function __mul__(other) - { - if (typeof(other) === "number") - return ul4.MonthDelta.create(this._months * Math.floor(other)); - throw ul4._type(this) + " * " + ul4._type(other) + " not supported"; - }, - - __rmul__: function __rmul__(other) - { - if (typeof(other) === "number") - return ul4.MonthDelta.create(this._months * Math.floor(other)); - throw ul4._type(this) + " * " + ul4._type(other) + " not supported"; - }, - - __floordiv__: function __floordiv__(other) - { - if (typeof(other) === "number") - return ul4.MonthDelta.create(Math.floor(this._months / other)); - else if (ul4._ismonthdelta(other)) - return Math.floor(this._months / other._months); - throw ul4._type(this) + " // " + ul4._type(other) + " not supported"; - }, - - __truediv__: function __truediv__(other) - { - if (ul4._ismonthdelta(other)) - return this._months / other._months; - throw ul4._type(this) + " / " + ul4._type(other) + " not supported"; - }, - - __getattr__: function __getattr__(attrname) - { - let self = this; - switch (attrname) - { - case "months": - return ul4.expose([], function months(){ return self._months; }); - default: - throw ul4.AttributeError.create(this, attrname); - } - }, - - months: function months() - { - return this._months; - } - } - ); - - // When we don't have a real ``Set`` type, emulate one that supports strings - ul4._Set = ul4._inherit( - ul4.Proto, - { - __type__: "ul4._Set", - - create: function create(...items) - { - let set = ul4._clone(this); - set.items = {}; - set.add(...items); - return set; - }, - - add: function add(...items) - { - for (let i = 0; i < items.length; ++i) - { - this.items[items[i]] = true; - } - }, - - __getattr__: function __getattr__(attrname) - { - let self = this; - switch (attrname) - { - case "add": - return ul4.expose(["*items"], function add(items){ self.add(...items); }); - default: - throw ul4.AttributeError.create(this, attrname); - } - }, - - __contains__: function __contains__(item) - { - return this.items[item] || false; - }, - - __bool__: function __bool__() - { - for (let item in this.items) - { - if (!this.items.hasOwnProperty(item)) - continue; - return true; - } - return false; - }, - - __repr__: function __repr__() - { - let v = []; - v.push("{"); - let i = 0; - for (let item in this.items) - { - if (!this.items.hasOwnProperty(item)) - continue; - if (i++) - v.push(", "); - v.push(ul4._repr(item)); - } - if (!i) - v.push("/"); - v.push("}"); - return v.join(""); - }, - - __eq__: function(other) - { - // We'll check that everything in ``this`` is in ``other`` - // and if both have the same number of items they are equal - if (ul4._isset(other)) - { - let count = 0; - for (let item in this.items) - { - if (!other.has(item)) - return false; - // count the number of items we have - ++count; - } - return other.size == count; - } - else if (ul4._isul4set(other)) - { - let count = 0; - for (let item in this.items) - { - if (!other[item]) - return false; - // count the number of items we have - ++count; - } - // Substract the number of items that ``other`` has - for (let item in other.items) - --count; - return count == 0; - } - else - return false; - }, - - __le__: function(other) - { - // check that ``this`` is a subset of ``other``, - // i.e. everything in ``this`` is also in ``other`` - if (ul4._isset(other)) - { - let count = 0; - for (let item in this.items) - { - if (!other.has(item)) - return false; - } - return true; - } - else if (ul4._isul4set(other)) - { - let count = 0; - for (let item in this.items) - { - if (!other.items[item]) - return false; - } - return true; - } - else - ul4._unorderable("<", this, other); - }, - - __ge__: function(other) - { - // check that ``this`` is a superset of ``other``, - // i.e. everything in ``other`` is also in ``this`` - if (ul4._isset(other)) - { - let result = true; - other.forEach(function(value) { - if (!this.items[value]) - result = false; - }); - return result; - } - else if (ul4._isul4set(other)) - { - let count = 0; - for (let item in other.items) - { - if (!this.items[item]) - return false; - } - return true; - } - else - ul4._unorderable("<=", this, other); - } - } - ); - - const classes = [ - "TextAST", - "IndentAST", - "LineEndAST", - "Tag", - "ConstAST", - "SeqItemAST", - "UnpackSeqItemAST", - "DictItemAST", - "UnpackDictItemAST", - "PosArgAST", - "KeywordArgAST", - "UnpackListArgAST", - "UnpackDictArgAST", - "ListAST", - "ListCompAST", - "DictAST", - "DictCompAST", - "SetAST", - "SetCompAST", - "GenExprAST", - "VarAST", - "NotAST", - "NegAST", - "BitNotAST", - "IfAST", - "ReturnAST", - "PrintAST", - "PrintXAST", - "ItemAST", - "IsAST", - "IsNotAST", - "EQAST", - "NEAST", - "LTAST", - "LEAST", - "GTAST", - "GEAST", - "NotContainsAST", - "ContainsAST", - "AddAST", - "SubAST", - "MulAST", - "FloorDivAST", - "TrueDivAST", - "ModAST", - "ShiftLeftAST", - "ShiftRightAST", - "BitAndAST", - "BitXOrAST", - "BitOrAST", - "AndAST", - "OrAST", - "SliceAST", - "AttrAST", - "CallAST", - "RenderAST", - "SetVarAST", - "AddVarAST", - "SubVarAST", - "MulVarAST", - "TrueDivVarAST", - "FloorDivVarAST", - "ModVarAST", - "ShiftLeftVarAST", - "ShiftRightVarAST", - "BitAndVarAST", - "BitXOrVarAST", - "BitOrVarAST", - "ForBlockAST", - "WhileBlockAST", - "BreakAST", - "ContinueAST", - "CondBlockAST", - "IfBlockAST", - "ElIfBlockAST", - "ElseBlockAST", - "SignatureAST", - "Template" - ]; - - for (let i = 0; i < classes.length; ++i) - { - let name = classes[i]; - let ul4onname = name; - if (ul4onname.substr(ul4onname.length-3) === "AST") - ul4onname = ul4onname.substr(0, ul4onname.length-3); - ul4onname = ul4onname.toLowerCase(); - let object = ul4[name]; - object.typename = name; - object.type = ul4onname; - ul4on.register("de.livinglogic.ul4." + ul4onname, object); - } - - })(); diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/index.html b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/index.html deleted file mode 100644 index dda05fd..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/index.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - Ionic App - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/manifest.json b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/manifest.json deleted file mode 100644 index f6456bb..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/manifest.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "Ionic", - "short_name": "Ionic", - "start_url": "index.html", - "display": "standalone", - "icons": [{ - "src": "assets/imgs/logo.png", - "sizes": "512x512", - "type": "image/png" - }], - "background_color": "#4e8ef7", - "theme_color": "#4e8ef7" -} \ No newline at end of file diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/pages/home/home.html b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/pages/home/home.html deleted file mode 100644 index 2682126..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/pages/home/home.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - Mein Kaffee - - - - - - - - Kaffeesorte: - - Mocha - - - - - - - - - - - - - Konsument - - - - - - - diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/pages/home/home.scss b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/pages/home/home.scss deleted file mode 100644 index d4cc8fc..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/pages/home/home.scss +++ /dev/null @@ -1,3 +0,0 @@ -page-home { - -} diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/pages/home/home.ts b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/pages/home/home.ts deleted file mode 100644 index 181b94c..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/pages/home/home.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Component } from '@angular/core'; -import { NavController } from 'ionic-angular'; -import { LaProvider }from '../../providers/la/la'; - - -@Component({ - selector: 'page-home', - templateUrl: 'home.html' -}) -export class HomePage { - - private coffee: any = "Mocha"; - private number: number = 1; - private consumer: any = "Der Herr des Kaffees"; - constructor(public navCtrl: NavController, private laProv: LaProvider) { - - - } - changeNumber (diffrence: number) { - if ((this.number <= 1 && diffrence < 0) || (this.number >= 5 && diffrence > 0)) { - return; - } - this.number += diffrence; - } - - - add(){ - console.log("add entry" + JSON.stringify({ - kaffeesorte: this.coffee, - runde: this.number, - mitarbeiter: this.consumer - })); - this.laProv.addCoffee({ - kaffeesorte: this.coffee, - runde: this.number.toString(), - mitarbeiter: this.consumer - }).then((res)=>{ - alert("erfolgreich einen Datensatz hinzugefügt"); - }); - } - -} diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/providers/la/la.ts b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/providers/la/la.ts deleted file mode 100644 index 97b7e6a..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/providers/la/la.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class LaProvider { - private window: any; - constructor() { - this.window = window; - } - - addCoffee (input) { - return new Promise((resolve, reject) => { - let lsdk = new this.window.livingSDK({},this.window.username, this.window.password); - lsdk.get("appid of your Livingapp").then((LAAPI) => { - let app = LAAPI.get('datasources').get('coffee').app; - app.insert(input).then((res) => { - console.log(res); - resolve(res); - }) - }) - }); - } - -} diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/service-worker.js b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/service-worker.js deleted file mode 100644 index ffbbb06..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/service-worker.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Check out https://googlechromelabs.github.io/sw-toolbox/ for - * more info on how to use sw-toolbox to custom configure your service worker. - */ - - -'use strict'; -importScripts('./build/sw-toolbox.js'); - -self.toolbox.options.cache = { - name: 'ionic-cache' -}; - -// pre-cache our key assets -self.toolbox.precache( - [ - './build/main.js', - './build/vendor.js', - './build/main.css', - './build/polyfills.js', - 'index.html', - 'manifest.json' - ] -); - -// dynamically cache any other local assets -self.toolbox.router.any('/*', self.toolbox.fastest); - -// for any other requests go to the network, cache, -// and then only use that cached resource if your user goes offline -self.toolbox.router.default = self.toolbox.networkFirst; diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/theme/variables.scss b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/theme/variables.scss deleted file mode 100644 index 18276a4..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/src/theme/variables.scss +++ /dev/null @@ -1,88 +0,0 @@ -// Ionic Variables and Theming. For more info, please see: -// http://ionicframework.com/docs/theming/ - -// Font path is used to include ionicons, -// roboto, and noto sans fonts -$font-path: "../assets/fonts"; - - -// The app direction is used to include -// rtl styles in your app. For more info, please see: -// http://ionicframework.com/docs/theming/rtl-support/ -$app-direction: ltr; - - -@import "ionic.globals"; - - -// Shared Variables -// -------------------------------------------------- -// To customize the look and feel of this app, you can override -// the Sass variables found in Ionic's source scss files. -// To view all the possible Ionic variables, see: -// http://ionicframework.com/docs/theming/overriding-ionic-variables/ - - - - -// Named Color Variables -// -------------------------------------------------- -// Named colors makes it easy to reuse colors on various components. -// It's highly recommended to change the default colors -// to match your app's branding. Ionic uses a Sass map of -// colors so you can add, rename and remove colors as needed. -// The "primary" color is the only required color in the map. - -$colors: ( - primary: #488aff, - secondary: #32db64, - danger: #f53d3d, - light: #f4f4f4, - dark: #222 -); - - -// App iOS Variables -// -------------------------------------------------- -// iOS only Sass variables can go here - - - - -// App Material Design Variables -// -------------------------------------------------- -// Material Design only Sass variables can go here - - - - -// App Windows Variables -// -------------------------------------------------- -// Windows only Sass variables can go here - - - - -// App Theme -// -------------------------------------------------- -// Ionic apps can have different themes applied, which can -// then be future customized. This import comes last -// so that the above variables are used and Ionic's -// default are overridden. - -@import "ionic.theme.default"; - - -// Ionicons -// -------------------------------------------------- -// The premium icon font for Ionic. For more info, please see: -// http://ionicframework.com/docs/ionicons/ - -@import "ionic.ionicons"; - - -// Fonts -// -------------------------------------------------- - -@import "roboto"; -@import "noto-sans"; diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/tsconfig.json b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/tsconfig.json deleted file mode 100644 index 2d2df92..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/tsconfig.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "compilerOptions": { - "allowSyntheticDefaultImports": true, - "declaration": false, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "lib": [ - "dom", - "es2015" - ], - "module": "es2015", - "moduleResolution": "node", - "sourceMap": true, - "target": "es5", - "typeRoots": [ - "../node_modules/@types" - ] - }, - "include": [ - "src/**/*.ts" - ], - "exclude": [ - "node_modules", - "src/**/*.spec.ts", - "src/**/__tests__/*.ts" - ], - "compileOnSave": false, - "atom": { - "rewriteTsconfig": false - } -} diff --git a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/tslint.json b/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/tslint.json deleted file mode 100644 index dd8e8d8..0000000 --- a/docs/demos/App_erstellen_Ionic/src/kaffeeapp_ionic/tslint.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "rules": { - "no-duplicate-variable": true, - "no-unused-variable": [ - true - ] - }, - "rulesDirectory": [ - "node_modules/tslint-eslint-rules/dist/rules" - ] -} diff --git a/docs/demos/Gruesse_nodejs/README.md b/docs/demos/Gruesse_nodejs/README.md deleted file mode 100644 index 4c11b04..0000000 --- a/docs/demos/Gruesse_nodejs/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Schöne Grüße an A, B, C, D und Z -Tja, eine Namensliste ist doch etwas praktisches, Sie können -in ihr Emailadressen hinterlegen, Sonderwünsche abspeichern -und Namen abfragen. Aber die alten Papierlisten sind schon -schwer UpToDate zu halten oder falls sich eine Sache ändert -muss sich eine ganze Menge drum herum ändern, da die Liste -ansonsten sehr unübersichtlich wird. -Heute wollen wir Ihnen eine gute Alternative zu dem Zettelchaos -vorstellen, LivingApps. -In diesem Beitrag soll es darum gehen, wie Sie mit nodejs mit -LivingApps kommunizieren können. -Am Ende des Beitrags sollen Sie ein Skript haben, das alle -auf Namen in ihrer LivingApp grüßt. - -## Todo Liste -- eine LivingApp anlegen (Siehe App_erstellen_ionic) -- Daten von LivingApps abholen - -## eine LivingApp anlegen -Das wird in dem Beitrag nicht weiter erläutert, -da dazu bereits eine detailierte Anleitung im -Beitrag App_erstellen_Ionic ist. -[Siehe hier](https://github.com/milleniumfrog/LivingApps.Javascript.LivingAPI/tree/updatedoc/docs/demos/App_erstellen_Ionic) - -## Daten von LivingApps abholen -Binden Sie hierzu livingSDK.js ein. Klonen Sie dazu das letzte, -offizielle Repository von Github und kopieren dessen src Ordner in ihren -Projektordner und binden es mit: -```Javascript -const LivingSDK = require('path to livingSDK.js'); -``` - -Instanziieren Sie das SDK mit -```Javascript -let lsdk = new LivingSDK({}, 'username', 'password'); -``` - -Sie haben sich soeben mit dem SDK bei LivingApps angemeldet und können -mit -```Javascript -lsdk.get('appid').then((LAAPI) => {...}); -``` - -den Zugang zu den Datenquellen holen. In den nächsten Schritten -wird im ... Bereich eingesetzt. - -Zunächst wollen Sie auf die Datenquelle, die Sie vorhin im Anzeigetemplate -hinterlegt haben zugreifen und von dort aus auf die App. -Kombiniert sähe das folgendermaßen aus: -```Javascript - let app = LAAPI.get('datasources').get('Datenquellenidentifizierer').app; -``` - -Von dort haben Sie dann Zugriff auf alle Einträge/Records: -```Javascript - let records = app.records.values(); // app.records ist ein dictonary, in JS eine Map -``` - -Jetzt müssen Sie das ganze nur noch ausgeben. -```Javascript - console.log('Schöne Grüße an: '); - for(let record of records) { - console.log(record.fields.get('name').value); // Sie fragen den Wert von Name von der Liste ab - } -``` - -und schon gibt das Skript folgendes aus: -```bash - Schöne Grüße an: - Name3 - Name2 - Name1 -``` - -So einfach ist es Daten von LivingApps als Backend zu -benutzen und Leute via Konsole zu Grüßen - -Viel Spaß mit dem SDK \ No newline at end of file diff --git a/docs/demos/Gruesse_nodejs/src/index.js b/docs/demos/Gruesse_nodejs/src/index.js deleted file mode 100644 index 962b3fc..0000000 --- a/docs/demos/Gruesse_nodejs/src/index.js +++ /dev/null @@ -1,13 +0,0 @@ -const config = require('../../../../test/config'); -const LivingSDK = require('../../App_erstellen_Ionic/src/kaffeeapp_ionic/src/assets/scripts/src/livingSDK'); - -console.log("started script"); -let lsdk = new LivingSDK({}, config.username, config.password); -lsdk.get('5a33c42ac10bb04e6cf76e1c').then((LAAPI) => { - let app = LAAPI.get('datasources').get('default').app; - let records = app.records.values(); - console.log('Schöne Grüße an: '); - for(let record of records) { - console.log(record.fields.get('name').value); - } -}) \ No newline at end of file diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..5367dd3 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,25 @@ +// Karma configuration +// Generated on Thu Jul 12 2018 19:50:02 GMT+0200 (CEST) +const resolve = require( 'rollup-plugin-node-resolve' ); +const commonjs = require( 'rollup-plugin-commonjs' ); + + +module.exports = function(config) { + config.set({ + + frameworks: ["mocha", "karma-typescript"], + + files: [ + 'https://unpkg.com/axios/dist/axios.min.js', + './node_modules/chai/chai.js', + { pattern: "dist/test/**/*.test.js" } + ], + + + reporters: ["progress"], + + browsers: ["Chrome"], + + singleRun: true + }); + }; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..9386f3d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,8135 @@ +{ + "name": "livingsdk", + "version": "0.3.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/core": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.0.0.tgz", + "integrity": "sha512-nrvxS5u6QUN5gLl1GEakIcmOeoUHT1/gQtdMRq18WFURJ5osn4ppJLVSseMQo4zVWKJfBTF4muIYijXUnKlRLQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.0.0", + "@babel/helpers": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "convert-source-map": "^1.1.0", + "debug": "^3.1.0", + "json5": "^0.5.0", + "lodash": "^4.17.10", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0.tgz", + "integrity": "sha512-/BM2vupkpbZXq22l1ALO7MqXJZH2k8bKVv8Y+pABFnzWdztDB/ZLveP5At21vLz5c2YtSE6p7j2FZEsqafMz5Q==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "jsesc": "^2.5.1", + "lodash": "^4.17.10", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", + "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0.tgz", + "integrity": "sha512-9HdU8lrAc4FUZOy+y2w//kUhynSpkGIRYDzJW1oKJx7+v8m6UEAbAd2tSvxirsq2kJTXJZZS6Eo8FnUDUH0ZWw==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.0.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-call-delegate": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0.tgz", + "integrity": "sha512-HdYG6vr4KgXHK0q1QRZ8guoYCF5rZjIdPlhcVY+j4EBK/FDR+cXRM5/6lQr3NIWDc7dO1KfgjG5rfH6lM89VBw==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-define-map": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.0.0.tgz", + "integrity": "sha512-acbCxYS9XufWxsBiclmXMK1CFz7en/XSYvHFcbb3Jb8BqjFEBrA46WlIsoSQTRG/eYN60HciUnzdyQxOZhrHfw==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.0.0", + "@babel/types": "^7.0.0", + "lodash": "^4.17.10" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0.tgz", + "integrity": "sha512-5gLPwdDnYf8GfPsjS+UmZUtYE1jaXTFm1P+ymGobqvXbA0q3ANgpH60+C6zDrRAWXYbQXYvzzQC/r0gJVNNltQ==", + "dev": true, + "requires": { + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-function-name": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0.tgz", + "integrity": "sha512-Zo+LGvfYp4rMtz84BLF3bavFTdf8y4rJtMPTe2J+rxYmnDOIeH8le++VFI/pRJU+rQhjqiXxE4LMaIau28Tv1Q==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz", + "integrity": "sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", + "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", + "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0.tgz", + "integrity": "sha512-QdwmTTlPmT7TZcf30dnqm8pem+o48tVt991xXogE5CQCwqSpWKuzH2E9v8VWeccQ66a6/CmrLZ+bwp66JYeM5A==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.0.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/types": "^7.0.0", + "lodash": "^4.17.10" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", + "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0.tgz", + "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0.tgz", + "integrity": "sha512-3o4sYLOsK6m0A7t1P0saTanBPmk5MAlxVnp9773Of4L8PMVLukU7loZix5KoJgflxSo2c2ETTzseptc0rQEp7A==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0.tgz", + "integrity": "sha512-fsSv7VogxzMSmGch6DwhKHGsciVXo7hbfhBgH9ZrgJMXKMjO7ASQTUfbVL7MU1uCfviyqjucazGK7TWPT9weuQ==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.0.0.tgz", + "integrity": "sha512-CNeuX52jbQSq4j1n+R+21xrjbTjsnXa9n1aERbgHRD/p9h4Udkxr1n24yPMQmnTETHdnQDvkVSYWFw/ETAymYg==", + "dev": true, + "requires": { + "@babel/template": "^7.0.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-wrap-function": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0.tgz", + "integrity": "sha512-kjprWPDNVPZ/9pyLRXcZBvfjnFwqokmXTPTaC4AV8Ns7WRl7ewSxrB19AWZzQsC/WSPQLOw1ciR8uPYkAM1znA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helpers": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.0.0.tgz", + "integrity": "sha512-jbvgR8iLZPnyk6m/UqdXYsSxbVtRi7Pd3CzB4OPwPBnmhNG1DWjiiy777NTuoyIcniszK51R40L5pgfXAfHDtw==", + "dev": true, + "requires": { + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.0.0.tgz", + "integrity": "sha512-RgJhNdRinpO8zibnoHbzTTexNs4c8ROkXFBanNDZTLHjwbdLk8J5cJSKulx/bycWTLYmKVNCkxRtVCoJnqPk+g==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0.tgz", + "integrity": "sha512-QsXmmjLrFADCcDQAfdQn7tfBRLjpTzRWaDpKpW4ZXW1fahPG4SvjcF1xfvVnXGC662RSExYXL+6DAqbtgqMXeA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.0.0", + "@babel/plugin-syntax-async-generators": "^7.0.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz", + "integrity": "sha512-kfVdUkIAGJIVmHmtS/40i/fg/AGnw/rsZBCaapY5yjeO5RA9m165Xbw9KMOu2nqXP5dTFjEjHdfNdoVcHv133Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-json-strings": "^7.0.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz", + "integrity": "sha512-14fhfoPcNu7itSen7Py1iGN0gEm87hX/B+8nZPqkdmANyyYWYMY2pjA3r8WXbWVKMzfnSNS0xY8GVS0IjXi/iw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz", + "integrity": "sha512-JPqAvLG1s13B/AuoBjdBYvn38RqW6n1TzrQO839/sIpqLpbnXKacsAgpZHzLD83Sm8SDXMkkrAvEnJ25+0yIpw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.0.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0.tgz", + "integrity": "sha512-tM3icA6GhC3ch2SkmSxv7J/hCWKISzwycub6eGsDrFDgukD4dZ/I+x81XgW0YslS6mzNuQ1Cbzh5osjIMgepPQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.2.0" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz", + "integrity": "sha512-im7ged00ddGKAjcZgewXmp1vxSZQQywuQXe2B1A7kajjZmDeY/ekMPmWr9zJgveSaQH0k7BcGrojQhcK06l0zA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0.tgz", + "integrity": "sha512-UlSfNydC+XLj4bw7ijpldc1uZ/HB84vw+U6BTuqMdIEmz/LDe63w/GHtpQMdXWdqQZFeAI9PjnHe/vDhwirhKA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz", + "integrity": "sha512-5A0n4p6bIiVe5OvQPxBnesezsgFJdHhSs3uFSvaPdMqtsovajLZ+G2vZyvNe10EzJBWWo3AcHGKhAFUxqwp2dw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz", + "integrity": "sha512-Wc+HVvwjcq5qBg1w5RG9o9RVzmCaAg/Vp0erHCKpAYV8La6I94o4GQAmFYNmkzoMO6gzoOSulpKeSSz6mPEoZw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz", + "integrity": "sha512-2EZDBl1WIO/q4DIkIp4s86sdp4ZifL51MoIviLY/gG/mLSuOIEg7J8o6mhbxOTvUJkaN50n+8u41FVsr5KLy/w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.0.0.tgz", + "integrity": "sha512-CiWNhSMZzj1n3uEKUUS/oL+a7Xi8hnPQB6GpC1WfL/ZYvxBLDBn14sHMo5EyOaeArccSonyk5jFIKMRRbrHOnQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.0.0" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0.tgz", + "integrity": "sha512-AOBiyUp7vYTqz2Jibe1UaAWL0Hl9JUXEgjFvvvcSc9MVDItv46ViXFw2F7SVt1B5k+KWjl44eeXOAk3UDEaJjQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0.tgz", + "integrity": "sha512-GWEMCrmHQcYWISilUrk9GDqH4enf3UmhOEbNbNrlNAX1ssH3MsS1xLOS6rdjRVPgA7XXVPn87tRkdTEoA/dxEg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.10" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0.tgz", + "integrity": "sha512-8LBm7XsHQiNISEmb+ejBiHi1pUihwUf+lrIwyVsXVbQ1vLqgkvhgayK5JnW3WXvQD2rmM0qxFAIyDE5vtMem2A==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.0.0", + "@babel/helper-function-name": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.0.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz", + "integrity": "sha512-ubouZdChNAv4AAWAgU7QKbB93NU5sHwInEWfp+/OzJKA02E6Woh9RVoX4sZrbRwtybky/d7baTUqwFx+HgbvMA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0.tgz", + "integrity": "sha512-Fr2GtF8YJSXGTyFPakPFB4ODaEKGU04bPsAllAIabwoXdFrPxL0LVXQX5dQWoxOjjgozarJcC9eWGsj0fD6Zsg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0.tgz", + "integrity": "sha512-00THs8eJxOJUFVx1w8i1MBF4XH4PsAjKjQ1eqN/uCH3YKwP21GCKfrn6YZFZswbOk9+0cw1zGQPHVc1KBlSxig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0.tgz", + "integrity": "sha512-w2vfPkMqRkdxx+C71ATLJG30PpwtTpW7DDdLqYt2acXU7YjztzeWW2Jk1T6hKqCLYCcEA5UQM/+xTAm+QCSnuQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0.tgz", + "integrity": "sha512-Ig74elCuFQ0mvHkWUq5qDCNI3qHWlop5w4TcDxdtJiOk8Egqe2uxDRY9XnXGSlmWClClmnixcoYumyvbAuj4dA==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz", + "integrity": "sha512-TlxKecN20X2tt2UEr2LNE6aqA0oPeMT1Y3cgz8k4Dn1j5ObT8M3nl9aA37LLklx0PBZKETC9ZAf9n/6SujTuXA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0.tgz", + "integrity": "sha512-mR7JN9vkwsAIot74pSwzn/2Gq4nn2wN0HKtQyJLc1ghAarsymdBMTfh+Q/aeR2N3heXs3URQscTLrKe3yUU7Yw==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz", + "integrity": "sha512-1NTDBWkeNXgpUcyoVFxbr9hS57EpZYXpje92zv0SUzjdu3enaRwF/l3cmyRnXLtIdyJASyiS6PtybK+CgKf7jA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.0.0.tgz", + "integrity": "sha512-CtSVpT/0tty/4405qczoIHm41YfFbPChplsmfBwsi3RTq/M9cHgVb3ixI5bqqgdKkqWwSX2sXqejvMKLuTVU+Q==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0.tgz", + "integrity": "sha512-BIcQLgPFCxi7YygtNpz5xj+7HxhOprbCGZKeLW6Kxsn1eHS6sJZMw4MfmqFZagl/v6IVa0AJoMHdDXLVrpd3Aw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.0.0.tgz", + "integrity": "sha512-8EDKMAsitLkiF/D4Zhe9CHEE2XLh4bfLbb9/Zf3FgXYQOZyZYyg7EAel/aT2A7bHv62jwHf09q2KU/oEexr83g==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.0.0.tgz", + "integrity": "sha512-EMyKpzgugxef+R1diXDwqw/Hmt5ls8VxfI8Gq5Lo8Qp3oKIepkYG4L/mvE2dmZSRalgL9sguoPKbnQ1m96hVFw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz", + "integrity": "sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.0.0.tgz", + "integrity": "sha512-BfAiF1l18Xr1shy1NyyQgLiHDvh/S7APiEM5+0wxTsQ+e3fgXO+NA47u4PvppzH0meJS21y0gZHcjnvUAJj8tQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.0.0" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0.tgz", + "integrity": "sha512-eWngvRBWx0gScot0xa340JzrkA+8HGAk1OaCHDfXAjkrTFkp73Lcf+78s7AStSdRML5nzx5aXpnjN1MfrjkBoA==", + "dev": true, + "requires": { + "@babel/helper-call-delegate": "^7.0.0", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz", + "integrity": "sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw==", + "dev": true, + "requires": { + "regenerator-transform": "^0.13.3" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz", + "integrity": "sha512-g/99LI4vm5iOf5r1Gdxq5Xmu91zvjhEG5+yZDJW268AZELAu4J1EiFLnkSG3yuUsZyOipVOVUKoGPYwfsTymhw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz", + "integrity": "sha512-L702YFy2EvirrR4shTj0g2xQp7aNwZoWNCkNu2mcoU0uyzMl0XRwDSwzB/xp6DSUFiBmEXuyAyEN16LsgVqGGQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz", + "integrity": "sha512-LFUToxiyS/WD+XEWpkx/XJBrUXKewSZpzX68s+yEOtIbdnsRjpryDw9U06gYc6klYEij/+KQVRnD3nz3AoKmjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz", + "integrity": "sha512-vA6rkTCabRZu7Nbl9DfLZE1imj4tzdWcg5vtdQGvj+OH9itNNB6hxuRMHuIY8SGnEt1T9g5foqs9LnrHzsqEFg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0.tgz", + "integrity": "sha512-1r1X5DO78WnaAIvs5uC48t41LLckxsYklJrZjNKcevyz83sF2l4RHbw29qrCPr/6ksFsdfRpT/ZgxNWHXRnffg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz", + "integrity": "sha512-uJBrJhBOEa3D033P95nPHu3nbFwFE9ZgXsfEitzoIXIwqAZWk7uXcg06yFKXz9FSxBH5ucgU/cYdX0IV8ldHKw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" + } + }, + "@babel/preset-env": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.0.0.tgz", + "integrity": "sha512-Fnx1wWaWv2w2rl+VHxA9si//Da40941IQ29fKiRejVR7oN1FxSEL8+SyAX/2oKIye2gPvY/GBbJVEKQ/oi43zQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.0.0", + "@babel/plugin-proposal-json-strings": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.0.0", + "@babel/plugin-syntax-async-generators": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.0.0", + "@babel/plugin-transform-block-scoped-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-dotall-regex": "^7.0.0", + "@babel/plugin-transform-duplicate-keys": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-amd": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-modules-systemjs": "^7.0.0", + "@babel/plugin-transform-modules-umd": "^7.0.0", + "@babel/plugin-transform-new-target": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typeof-symbol": "^7.0.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "browserslist": "^4.1.0", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.3.0" + } + }, + "@babel/template": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0.tgz", + "integrity": "sha512-VLQZik/G5mjYJ6u19U3W2u7eM+rA/NGzH+GtHDFFkLTKLW66OasFrxZ/yK7hkyQcswrmvugFyZpDFRW0DjcjCw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/traverse": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0.tgz", + "integrity": "sha512-ka/lwaonJZTlJyn97C4g5FYjPOx+Oxd3ab05hbDr1Mx9aP1FclJ+SUHyLx3Tx40sGmOVJApDxE6puJhd3ld2kw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.0.0", + "@babel/helper-function-name": "^7.0.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/types": "^7.0.0", + "debug": "^3.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@babel/types": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0.tgz", + "integrity": "sha512-5tPDap4bGKTLPtci2SUl/B7Gv8RnuJFuQoWx26RJobS0fFrz4reUA3JnwIM+HVHEmWE0C1mzKhDtTp8NsWY02Q==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.10", + "to-fast-properties": "^2.0.0" + } + }, + "@types/chai": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.3.tgz", + "integrity": "sha512-f5dXGzOJycyzSMdaXVhiBhauL4dYydXwVpavfQ1mVCaGjR56a9QfklXObUxlIY9bGTmCPHEEZ04I16BZ/8w5ww==", + "dev": true + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "@types/mocha": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.1.tgz", + "integrity": "sha512-dOrgprHnkDaj1pmrwdcMAf0QRNQzqTB5rxJph+iIQshSmIvtgRqJ0nim8u1vvXU8iOXZrH96+M46JDFTPLingA==", + "dev": true + }, + "@types/node": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.2.tgz", + "integrity": "sha512-9NfEUDp3tgRhmoxzTpTo+lq+KIVFxZahuRX0LHF/9IzKHaWuoWsIrrJ61zw5cnnlGINX8lqJzXYfQTOICS5Q+A==", + "dev": true + }, + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "dev": true, + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + }, + "addressparser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", + "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=", + "dev": true, + "optional": true + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "dev": true, + "optional": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "optional": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "amqplib": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz", + "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==", + "dev": true, + "optional": true, + "requires": { + "bitsyntax": "~0.0.4", + "bluebird": "^3.4.6", + "buffer-more-ints": "0.0.2", + "readable-stream": "1.x >=1.1.9", + "safe-buffer": "^5.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true, + "optional": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true, + "optional": true + } + } + }, + "ansi-cyan": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", + "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-red": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", + "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "optional": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "dev": true + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "optional": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "ast-types": { + "version": "0.11.5", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.5.tgz", + "integrity": "sha512-oJjo+5e7/vEc2FBK8gUalV0pba4L3VdBIs2EKhOLHLcOd2FgQIVQN9xb0eZ9IjEWyAL7vq6fGJxOvVvdCHNyMw==", + "dev": true, + "optional": true + }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true, + "optional": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true, + "optional": true + }, + "axios": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz", + "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", + "requires": { + "follow-redirects": "^1.3.0", + "is-buffer": "^1.1.5" + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "bitsyntax": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.0.4.tgz", + "integrity": "sha1-6xDMb4K4xJDj6FaY8H6D1G4MuoI=", + "dev": true, + "optional": true, + "requires": { + "buffer-more-ints": "0.0.2" + } + }, + "bl": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", + "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=", + "dev": true, + "optional": true, + "requires": { + "readable-stream": "~2.0.5" + }, + "dependencies": { + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true, + "optional": true + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true, + "optional": true + } + } + }, + "blob": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", + "dev": true + }, + "bluebird": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", + "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==", + "dev": true + }, + "blueimp-md5": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.10.0.tgz", + "integrity": "sha512-EkNUOi7tpV68TqjpiUz9D9NcT8um2+qtgntmMbi5UKssVX2m/2PLqotcric0RE63pB3HPN/fjf3cKHN2ufGSUQ==" + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.1", + "http-errors": "~1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "~2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "~1.6.15" + } + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "optional": true, + "requires": { + "hoek": "2.x.x" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.1.1.tgz", + "integrity": "sha512-VBorw+tgpOtZ1BYhrVSVTzTt/3+vSE3eFUh0N2GCFK1HffceOaf32YS/bs6WiFhjDAblAFrx85jMy3BG9fBK2Q==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000884", + "electron-to-chromium": "^1.3.62", + "node-releases": "^1.0.0-alpha.11" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-more-ints": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz", + "integrity": "sha1-JrOIXRD6E9t/wBquOquHAZngEkw=", + "dev": true, + "optional": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "buildmail": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-4.0.1.tgz", + "integrity": "sha1-h393OLeHKYccmhBeO4N9K+EaenI=", + "dev": true, + "optional": true, + "requires": { + "addressparser": "1.0.1", + "libbase64": "0.1.0", + "libmime": "3.0.0", + "libqp": "1.1.0", + "nodemailer-fetch": "1.6.0", + "nodemailer-shared": "1.1.0", + "punycode": "1.4.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + } + }, + "caniuse-lite": { + "version": "1.0.30000884", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000884.tgz", + "integrity": "sha512-ibROerckpTH6U5zReSjbaitlH4gl5V4NWNCBzRNCa3GEDmzzkfStk+2k5mO4ZDM6pwtdjbZ3hjvsYhPGVLWgNw==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true, + "optional": true + }, + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "^1.0.1", + "check-error": "^1.0.1", + "deep-eql": "^3.0.0", + "get-func-name": "^2.0.0", + "pathval": "^1.0.0", + "type-detect": "^4.0.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.5" + }, + "dependencies": { + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "circular-json": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.5.tgz", + "integrity": "sha512-13YaR6kiz0kBNmIVM87Io8Hp7bWOo4r61vkEANy8iH9R9bc6avud/1FT0SBpqR1RpIQADOh/Q+yHZDA1iL6ysA==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "optional": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz", + "integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ==", + "dev": true + }, + "combine-lists": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", + "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", + "dev": true, + "requires": { + "lodash": "^4.5.0" + } + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + }, + "dependencies": { + "convert-source-map": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "combined-stream": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "dev": true, + "optional": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "connect": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", + "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.0", + "parseurl": "~1.3.2", + "utils-merge": "1.0.1" + }, + "dependencies": { + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.3.1", + "unpipe": "~1.0.0" + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + } + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "^0.1.4" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", + "dev": true + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "optional": true, + "requires": { + "boom": "2.x.x" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-uri-to-buffer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", + "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", + "dev": true, + "optional": true + }, + "date-format": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz", + "integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg=", + "dev": true + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1", + "meow": "^3.3.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "degenerator": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", + "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", + "dev": true, + "optional": true, + "requires": { + "ast-types": "0.x.x", + "escodegen": "1.x.x", + "esprima": "3.x.x" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "optional": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "diff": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "double-ended-queue": { + "version": "2.1.0-0", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=", + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.62", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.62.tgz", + "integrity": "sha512-x09ndL/Gjnuk3unlAyoGyUg3wbs4w/bXurgL7wL913vXHAOWmMhrLf1VNGRaMLngmadd5Q8gsV9BFuIr6rP+Xg==", + "dev": true + }, + "elliptic": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "engine.io": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", + "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "uws": "~9.14.0", + "ws": "~3.3.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "engine.io-client": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", + "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~3.3.1", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", + "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.4", + "has-binary2": "~1.0.2" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-promise": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "dev": true, + "optional": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "optional": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", + "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", + "dev": true, + "optional": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true, + "optional": true + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true, + "optional": true + }, + "estree-walker": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.2.tgz", + "integrity": "sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "expand-braces": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", + "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", + "dev": true, + "requires": { + "array-slice": "^0.2.3", + "array-unique": "^0.2.1", + "braces": "^0.1.2" + }, + "dependencies": { + "braces": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", + "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", + "dev": true, + "requires": { + "expand-range": "^0.1.0" + } + }, + "expand-range": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", + "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", + "dev": true, + "requires": { + "is-number": "^0.1.1", + "repeat-string": "^0.2.2" + } + }, + "is-number": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", + "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", + "dev": true + }, + "repeat-string": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", + "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", + "dev": true + } + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "^2.1.0" + } + }, + "express": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", + "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.3", + "qs": "6.5.1", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "optional": true + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "dev": true, + "optional": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true, + "optional": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dev": true, + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "follow-redirects": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz", + "integrity": "sha512-uxYePVPogtya1ktGnAAXOacnbIuRMB4dkvqeNz2qTtTQsuzSfbDolV+wMMKxAmCx0bLgAKLbBOkjItMbbkR1vg==", + "requires": { + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "dev": true, + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "^1.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "^2.1.0" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "ftp": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "dev": true, + "optional": true, + "requires": { + "readable-stream": "1.1.x", + "xregexp": "2.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true, + "optional": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true, + "optional": true + } + } + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, + "optional": true, + "requires": { + "is-property": "^1.0.2" + } + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "optional": true, + "requires": { + "is-property": "^1.0.0" + } + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-uri": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.2.tgz", + "integrity": "sha512-ZD325dMZOgerGqF/rF6vZXyFGTAay62svjQIT+X/oU2PtxYpFxvSkbsdi+oxIrsNxlZVd4y8wUDqkaExWTI/Cw==", + "dev": true, + "optional": true, + "requires": { + "data-uri-to-buffer": "1", + "debug": "2", + "extend": "3", + "file-uri-to-path": "1", + "ftp": "~0.3.10", + "readable-stream": "2" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "globals": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", + "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", + "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "optional": true + }, + "har-validator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", + "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "dev": true, + "optional": true, + "requires": { + "ajv": "^5.3.0", + "har-schema": "^2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", + "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "optional": true, + "requires": { + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hipchat-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hipchat-notifier/-/hipchat-notifier-1.1.0.tgz", + "integrity": "sha1-ttJJdVQ3wZEII2d5nTupoPI7Ix4=", + "dev": true, + "optional": true, + "requires": { + "lodash": "^4.0.0", + "request": "^2.0.0" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true, + "optional": true + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": ">= 1.3.1 < 2" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true + } + } + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "dev": true, + "optional": true, + "requires": { + "agent-base": "4", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "httpntlm": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz", + "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=", + "dev": true, + "optional": true, + "requires": { + "httpreq": ">=0.4.22", + "underscore": "~1.7.0" + } + }, + "httpreq": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz", + "integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=", + "dev": true, + "optional": true + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "https-proxy-agent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "dev": true, + "optional": true, + "requires": { + "agent-base": "^4.1.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflection": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", + "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=", + "dev": true, + "optional": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "~0.5.3" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true, + "optional": true + }, + "ipaddr.js": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", + "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true, + "optional": true + }, + "is-my-json-valid": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz", + "integrity": "sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q==", + "dev": true, + "optional": true, + "requires": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true, + "optional": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "optional": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true, + "optional": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isbinaryfile": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", + "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", + "dev": true, + "requires": { + "buffer-alloc": "^1.2.0" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true, + "optional": true + }, + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", + "dev": true, + "requires": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "jest-worker": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-23.2.0.tgz", + "integrity": "sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk=", + "dev": true, + "requires": { + "merge-stream": "^1.0.1" + } + }, + "js-levenshtein": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.3.tgz", + "integrity": "sha512-/812MXr9RBtMObviZ8gQBhHO8MOrGj8HlEE+4ccMTElNA/6I3u39u+bhny55Lk921yn44nSZFy9naNLElL5wgQ==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + } + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "jsesc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz", + "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true, + "optional": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true, + "optional": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true, + "optional": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "karma": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/karma/-/karma-2.0.5.tgz", + "integrity": "sha512-rECezBeY7mjzGUWhFlB7CvPHgkHJLXyUmWg+6vHCEsdWNUTnmiS6jRrIMcJEWgU2DUGZzGWG0bTRVky8fsDTOA==", + "dev": true, + "requires": { + "bluebird": "^3.3.0", + "body-parser": "^1.16.1", + "chokidar": "^2.0.3", + "colors": "^1.1.0", + "combine-lists": "^1.0.0", + "connect": "^3.6.0", + "core-js": "^2.2.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.0", + "expand-braces": "^0.1.1", + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "http-proxy": "^1.13.0", + "isbinaryfile": "^3.0.0", + "lodash": "^4.17.4", + "log4js": "^2.5.3", + "mime": "^1.3.4", + "minimatch": "^3.0.2", + "optimist": "^0.6.1", + "qjobs": "^1.1.4", + "range-parser": "^1.2.0", + "rimraf": "^2.6.0", + "safe-buffer": "^5.0.1", + "socket.io": "2.0.4", + "source-map": "^0.6.1", + "tmp": "0.0.33", + "useragent": "2.2.1" + } + }, + "karma-chrome-launcher": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", + "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "dev": true, + "requires": { + "fs-access": "^1.0.0", + "which": "^1.2.1" + } + }, + "karma-coverage": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.2.tgz", + "integrity": "sha512-eQawj4Cl3z/CjxslYy9ariU4uDh7cCNFZHNWXWRpl0pNeblY/4wHR7M7boTYXWrn9bY0z2pZmr11eKje/S/hIw==", + "dev": true, + "requires": { + "dateformat": "^1.0.6", + "istanbul": "^0.4.0", + "lodash": "^4.17.0", + "minimatch": "^3.0.0", + "source-map": "^0.5.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "karma-mocha": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz", + "integrity": "sha1-7qrH/8DiAetjxGdEDStpx883eL8=", + "dev": true, + "requires": { + "minimist": "1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "karma-rollup-preprocessor": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/karma-rollup-preprocessor/-/karma-rollup-preprocessor-6.0.1.tgz", + "integrity": "sha512-tDs2wngYVO7D6sOGie8Mep+b073p7Mvawyu4UFvXxFjkKcjHTOVFvVywA8QR13zhy4dZ6Z3WPsz/nVLuS06lBg==", + "dev": true, + "requires": { + "chokidar": "^2.0.0" + } + }, + "karma-typescript": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/karma-typescript/-/karma-typescript-3.0.13.tgz", + "integrity": "sha1-iUivvRA6wZh6WWGg9DoboocQZ80=", + "dev": true, + "requires": { + "acorn": "^4.0.4", + "assert": "^1.4.1", + "async": "^2.1.4", + "browser-resolve": "^1.11.0", + "browserify-zlib": "^0.2.0", + "buffer": "^5.0.6", + "combine-source-map": "^0.8.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "convert-source-map": "^1.5.0", + "crypto-browserify": "^3.11.1", + "diff": "^3.2.0", + "domain-browser": "^1.1.7", + "events": "^1.1.1", + "glob": "^7.1.1", + "https-browserify": "^1.0.0", + "istanbul": "0.4.5", + "json-stringify-safe": "^5.0.1", + "karma-coverage": "^1.1.1", + "lodash": "^4.17.4", + "log4js": "^1.1.1", + "minimatch": "^3.0.3", + "os-browserify": "^0.3.0", + "pad": "^2.0.0", + "path-browserify": "0.0.0", + "process": "^0.11.10", + "punycode": "^1.4.1", + "querystring-es3": "^0.2.1", + "readable-stream": "^2.3.3", + "remap-istanbul": "^0.10.1", + "source-map": "0.6.1", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.3", + "timers-browserify": "^2.0.2", + "tmp": "0.0.29", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.10.3", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "date-format": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-0.0.0.tgz", + "integrity": "sha1-CSBoY6sHDrRZrOpVQsvYVrEZZrM=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "log4js": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-1.1.1.tgz", + "integrity": "sha1-wh0px2BAieTyVYM+f5SzRh3h/0M=", + "dev": true, + "requires": { + "debug": "^2.2.0", + "semver": "^5.3.0", + "streamroller": "^0.4.0" + } + }, + "streamroller": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.4.1.tgz", + "integrity": "sha1-1DW9WXQ3Or2b2QaDWVEwhRBswF8=", + "dev": true, + "requires": { + "date-format": "^0.0.0", + "debug": "^0.7.2", + "mkdirp": "^0.5.1", + "readable-stream": "^1.1.7" + }, + "dependencies": { + "debug": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.7.4.tgz", + "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "tmp": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", + "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "libbase64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz", + "integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=", + "dev": true, + "optional": true + }, + "libmime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz", + "integrity": "sha1-UaGp50SOy9Ms2lRCFnW7IbwJPaY=", + "dev": true, + "optional": true, + "requires": { + "iconv-lite": "0.4.15", + "libbase64": "0.1.0", + "libqp": "1.1.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", + "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", + "dev": true, + "optional": true + } + } + }, + "libqp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz", + "integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=", + "dev": true, + "optional": true + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true, + "requires": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "dev": true, + "requires": { + "lodash._baseassign": "^3.0.0", + "lodash._basecreate": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" + } + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "log4js": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.11.0.tgz", + "integrity": "sha512-z1XdwyGFg8/WGkOyF6DPJjivCWNLKrklGdViywdYnSKOvgtEBo2UyEMZS5sD2mZrQlU3TvO8wDWLc8mzE1ncBQ==", + "dev": true, + "requires": { + "amqplib": "^0.5.2", + "axios": "^0.15.3", + "circular-json": "^0.5.4", + "date-format": "^1.2.0", + "debug": "^3.1.0", + "hipchat-notifier": "^1.1.0", + "loggly": "^1.1.0", + "mailgun-js": "^0.18.0", + "nodemailer": "^2.5.0", + "redis": "^2.7.1", + "semver": "^5.5.0", + "slack-node": "~0.2.0", + "streamroller": "0.7.0" + }, + "dependencies": { + "axios": { + "version": "0.15.3", + "resolved": "http://registry.npmjs.org/axios/-/axios-0.15.3.tgz", + "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=", + "dev": true, + "optional": true, + "requires": { + "follow-redirects": "1.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "follow-redirects": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", + "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=", + "dev": true, + "optional": true, + "requires": { + "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + } + } + } + } + }, + "loggly": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/loggly/-/loggly-1.1.1.tgz", + "integrity": "sha1-Cg/B0/o6XsRP3HuJe+uipGlc6+4=", + "dev": true, + "optional": true, + "requires": { + "json-stringify-safe": "5.0.x", + "request": "2.75.x", + "timespan": "2.3.x" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true, + "optional": true + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "dev": true, + "optional": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "form-data": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz", + "integrity": "sha1-bwrrrcxdoWwT4ezBETfYX5uIOyU=", + "dev": true, + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.11" + } + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dev": true, + "optional": true, + "requires": { + "chalk": "^1.1.1", + "commander": "^2.9.0", + "is-my-json-valid": "^2.12.4", + "pinkie-promise": "^2.0.0" + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", + "dev": true, + "optional": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true, + "optional": true + }, + "qs": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", + "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", + "dev": true, + "optional": true + }, + "request": { + "version": "2.75.0", + "resolved": "http://registry.npmjs.org/request/-/request-2.75.0.tgz", + "integrity": "sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM=", + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "bl": "~1.1.2", + "caseless": "~0.11.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.0.0", + "har-validator": "~2.0.6", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "node-uuid": "~1.4.7", + "oauth-sign": "~0.8.1", + "qs": "~6.2.0", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "~0.4.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "optional": true + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dev": true, + "optional": true, + "requires": { + "punycode": "^1.4.1" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true, + "optional": true + } + } + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, + "optional": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "magic-string": { + "version": "0.22.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", + "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", + "dev": true, + "requires": { + "vlq": "^0.2.2" + } + }, + "mailcomposer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz", + "integrity": "sha1-DhxEsqB890DuF9wUm6AJ8Zyt/rQ=", + "dev": true, + "optional": true, + "requires": { + "buildmail": "4.0.1", + "libmime": "3.0.0" + } + }, + "mailgun-js": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.18.1.tgz", + "integrity": "sha512-lvuMP14u24HS2uBsJEnzSyPMxzU2b99tQsIx1o6QNjqxjk8b3WvR+vq5oG1mjqz/IBYo+5gF+uSoDS0RkMVHmg==", + "dev": true, + "optional": true, + "requires": { + "async": "~2.6.0", + "debug": "~3.1.0", + "form-data": "~2.3.0", + "inflection": "~1.12.0", + "is-stream": "^1.1.0", + "path-proxy": "~1.0.0", + "promisify-call": "^2.0.2", + "proxy-agent": "~3.0.0", + "tsscmp": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "make-error": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", + "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", + "dev": true + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", + "dev": true + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true + }, + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dev": true, + "requires": { + "mime-db": "~1.33.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", + "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.6.8", + "diff": "3.2.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.1", + "growl": "1.9.2", + "he": "1.1.1", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nan": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.0.tgz", + "integrity": "sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, + "netmask": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", + "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=", + "dev": true, + "optional": true + }, + "node-releases": { + "version": "1.0.0-alpha.11", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.0.0-alpha.11.tgz", + "integrity": "sha512-CaViu+2FqTNYOYNihXa5uPS/zry92I3vPU4nCB6JB3OeZ2UGtOpF5gRwuN4+m3hbEcL47bOXyun1jX2iC+3uEQ==", + "dev": true, + "requires": { + "semver": "^5.3.0" + } + }, + "nodemailer": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-2.7.2.tgz", + "integrity": "sha1-8kLmSa7q45tsftdA73sGHEBNMPk=", + "dev": true, + "optional": true, + "requires": { + "libmime": "3.0.0", + "mailcomposer": "4.0.1", + "nodemailer-direct-transport": "3.3.2", + "nodemailer-shared": "1.1.0", + "nodemailer-smtp-pool": "2.8.2", + "nodemailer-smtp-transport": "2.7.2", + "socks": "1.1.9" + }, + "dependencies": { + "socks": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.9.tgz", + "integrity": "sha1-Yo1+TQSRJDVEWsC25Fk3bLPm1pE=", + "dev": true, + "optional": true, + "requires": { + "ip": "^1.1.2", + "smart-buffer": "^1.0.4" + } + } + } + }, + "nodemailer-direct-transport": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-3.3.2.tgz", + "integrity": "sha1-6W+vuQNYVglH5WkBfZfmBzilCoY=", + "dev": true, + "optional": true, + "requires": { + "nodemailer-shared": "1.1.0", + "smtp-connection": "2.12.0" + } + }, + "nodemailer-fetch": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz", + "integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q=", + "dev": true, + "optional": true + }, + "nodemailer-shared": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz", + "integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=", + "dev": true, + "optional": true, + "requires": { + "nodemailer-fetch": "1.6.0" + } + }, + "nodemailer-smtp-pool": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/nodemailer-smtp-pool/-/nodemailer-smtp-pool-2.8.2.tgz", + "integrity": "sha1-LrlNbPhXgLG0clzoU7nL1ejajHI=", + "dev": true, + "optional": true, + "requires": { + "nodemailer-shared": "1.1.0", + "nodemailer-wellknown": "0.1.10", + "smtp-connection": "2.12.0" + } + }, + "nodemailer-smtp-transport": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/nodemailer-smtp-transport/-/nodemailer-smtp-transport-2.7.2.tgz", + "integrity": "sha1-A9ccdjFPFKx9vHvwM6am0W1n+3c=", + "dev": true, + "optional": true, + "requires": { + "nodemailer-shared": "1.1.0", + "nodemailer-wellknown": "0.1.10", + "smtp-connection": "2.12.0" + } + }, + "nodemailer-wellknown": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz", + "integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=", + "dev": true, + "optional": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "pac-proxy-agent": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-2.0.2.tgz", + "integrity": "sha512-cDNAN1Ehjbf5EHkNY5qnRhGPUCp6SnpyVof5fRzN800QV1Y2OkzbH9rmjZkbBRa8igof903yOnjIl6z0SlAhxA==", + "dev": true, + "optional": true, + "requires": { + "agent-base": "^4.2.0", + "debug": "^3.1.0", + "get-uri": "^2.0.0", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.1", + "pac-resolver": "^3.0.0", + "raw-body": "^2.2.0", + "socks-proxy-agent": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "socks-proxy-agent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz", + "integrity": "sha512-ZwEDymm204mTzvdqyUqOdovVr2YRd2NYskrYrF2LXyZ9qDiMAoFESGK8CRphiO7rtbo2Y757k2Nia3x2hGtalA==", + "dev": true, + "optional": true, + "requires": { + "agent-base": "^4.1.0", + "socks": "^1.1.10" + } + } + } + }, + "pac-resolver": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", + "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", + "dev": true, + "optional": true, + "requires": { + "co": "^4.6.0", + "degenerator": "^1.0.4", + "ip": "^1.1.5", + "netmask": "^1.0.6", + "thunkify": "^2.1.2" + } + }, + "pad": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/pad/-/pad-2.2.1.tgz", + "integrity": "sha512-lVia7rFne82Flf8V5Szzw2oP2zcQBGtCUXvo0pF1c6CmUHc9QLSZ1NQM/YujaM5YdQBsLJ1u90om+T1zKF42HQ==", + "dev": true, + "requires": { + "wcwidth": "^1.0.1" + } + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "dev": true + }, + "parse-asn1": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", + "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-proxy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-proxy/-/path-proxy-1.0.0.tgz", + "integrity": "sha1-GOijaFn8nS8aU7SN7hOFQ8Ag3l4=", + "dev": true, + "optional": true, + "requires": { + "inflection": "~1.3.0" + }, + "dependencies": { + "inflection": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.3.8.tgz", + "integrity": "sha1-y9Fg2p91sUw8xjV41POWeEvzAU4=", + "dev": true, + "optional": true + } + } + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", + "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true, + "optional": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "plugin-error": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", + "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", + "dev": true, + "requires": { + "ansi-cyan": "^0.1.1", + "ansi-red": "^0.1.1", + "arr-diff": "^1.0.1", + "arr-union": "^2.0.1", + "extend-shallow": "^1.1.2" + }, + "dependencies": { + "arr-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", + "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1", + "array-slice": "^0.2.3" + } + }, + "arr-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", + "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", + "dev": true + }, + "extend-shallow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", + "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", + "dev": true, + "requires": { + "kind-of": "^1.1.0" + } + }, + "kind-of": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", + "dev": true + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "promisify-call": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/promisify-call/-/promisify-call-2.0.4.tgz", + "integrity": "sha1-1IwtRWUszM1SgB3ey9UzptS9X7o=", + "dev": true, + "optional": true, + "requires": { + "with-callback": "^1.0.2" + } + }, + "proxy-addr": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", + "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.6.0" + } + }, + "proxy-agent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-3.0.1.tgz", + "integrity": "sha512-mAZexaz9ZxQhYPWfAjzlrloEjW+JHiBFryE4AJXFDTnaXfmH/FKqC1swTRKuEPbHWz02flQNXFOyDUF7zfEG6A==", + "dev": true, + "optional": true, + "requires": { + "agent-base": "^4.2.0", + "debug": "^3.1.0", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.1", + "lru-cache": "^4.1.2", + "pac-proxy-agent": "^2.0.1", + "proxy-from-env": "^1.0.0", + "socks-proxy-agent": "^4.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", + "dev": true, + "optional": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true, + "optional": true + }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "dev": true, + "optional": true + }, + "public-encrypt": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", + "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randomatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", + "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==", + "dev": true, + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "redis": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", + "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", + "dev": true, + "optional": true, + "requires": { + "double-ended-queue": "^2.1.0-0", + "redis-commands": "^1.2.0", + "redis-parser": "^2.6.0" + } + }, + "redis-commands": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", + "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==", + "dev": true, + "optional": true + }, + "redis-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", + "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=", + "dev": true, + "optional": true + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz", + "integrity": "sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-transform": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.3.tgz", + "integrity": "sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA==", + "dev": true, + "requires": { + "private": "^0.1.6" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpu-core": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.2.0.tgz", + "integrity": "sha512-Z835VSnJJ46CNBttalHD/dB+Sj2ezmY6Xp38npwU87peK6mqOzOpV8eYktdkLTEkzzD+JsTcxd84ozd8I14+rw==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^7.0.0", + "regjsgen": "^0.4.0", + "regjsparser": "^0.3.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.0.2" + } + }, + "regjsgen": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.4.0.tgz", + "integrity": "sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA==", + "dev": true + }, + "regjsparser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.3.0.tgz", + "integrity": "sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remap-istanbul": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/remap-istanbul/-/remap-istanbul-0.10.1.tgz", + "integrity": "sha512-gsNQXs5kJLhErICSyYhzVZ++C8LBW8dgwr874Y2QvzAUS75zBlD/juZgXs39nbYJ09fZDlX2AVLVJAY2jbFJoQ==", + "dev": true, + "requires": { + "amdefine": "^1.0.0", + "istanbul": "0.4.5", + "minimatch": "^3.0.3", + "plugin-error": "^0.1.2", + "source-map": "^0.6.1", + "through2": "2.0.1" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "mime-db": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", + "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==", + "dev": true, + "optional": true + }, + "mime-types": { + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", + "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", + "dev": true, + "optional": true, + "requires": { + "mime-db": "~1.36.0" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "optional": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "optional": true + } + } + }, + "requestretry": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz", + "integrity": "sha512-Lmh9qMvnQXADGAQxsXHP4rbgO6pffCfuR8XUBdP9aitJcLQJxhp7YZK4xAVYXnPJ5E52mwrfiKQtKonPL8xsmg==", + "dev": true, + "optional": true, + "requires": { + "extend": "^3.0.0", + "lodash": "^4.15.0", + "request": "^2.74.0", + "when": "^3.7.7" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rollup": { + "version": "0.65.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.65.1.tgz", + "integrity": "sha512-46SzczqVygjcFVWsTBEg5x6hYVab9D/SFXWMkRgkGrBYxaUDvc442wwciO8Ow5DK4VCTwAC2CsX2Tpb89U9sXA==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "@types/node": "*" + } + }, + "rollup-plugin-babel": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.0.3.tgz", + "integrity": "sha512-/PP0MgbPQyRywI4zRIJim6ySjTcOLo4kQbEbROqp9kOR3kHC3FeU++QpBDZhS2BcHtJTVZMVbBV46flbBN5zxQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "rollup-pluginutils": "^2.3.0" + } + }, + "rollup-plugin-commonjs": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-9.1.6.tgz", + "integrity": "sha512-J7GOJm9uzEeLqkVxYSgjyoieh34hATWpa9G2M1ilGzWOLYGfQx5IDQ9ewG8QUj/Z2dzgV+d0/AyloAzElkABAA==", + "dev": true, + "requires": { + "estree-walker": "^0.5.1", + "magic-string": "^0.22.4", + "resolve": "^1.5.0", + "rollup-pluginutils": "^2.0.1" + } + }, + "rollup-plugin-node-resolve": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.4.0.tgz", + "integrity": "sha512-PJcd85dxfSBWih84ozRtBkB731OjXk0KnzN0oGp7WOWcarAFkVa71cV5hTJg2qpVsV2U8EUwrzHP3tvy9vS3qg==", + "dev": true, + "requires": { + "builtin-modules": "^2.0.0", + "is-module": "^1.0.0", + "resolve": "^1.1.6" + }, + "dependencies": { + "builtin-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-2.0.0.tgz", + "integrity": "sha512-3U5kUA5VPsRUA3nofm/BXX7GVHKfxz0hOBAPxXrIvHzlDRkQVqEn6yi8QJegxl4LzOHLdvb7XF5dVawa/VVYBg==", + "dev": true + } + } + }, + "rollup-plugin-sourcemaps": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-sourcemaps/-/rollup-plugin-sourcemaps-0.4.2.tgz", + "integrity": "sha1-YhJaqUCHqt97g+9N+vYptHMTXoc=", + "dev": true, + "requires": { + "rollup-pluginutils": "^2.0.1", + "source-map-resolve": "^0.5.0" + } + }, + "rollup-plugin-uglify": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-uglify/-/rollup-plugin-uglify-5.0.2.tgz", + "integrity": "sha512-CRRyMgKjTwTx1GXnn+v1VYV+6De5NyPB1UBStsQIQ+asrxvP7dK43cg2pf1vyFNr/NIHGvfYAR9Yo4j+5ZMQsw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "jest-worker": "^23.2.0", + "uglify-js": "^3.4.8" + } + }, + "rollup-pluginutils": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.3.1.tgz", + "integrity": "sha512-JZS8aJMHEHhqmY2QVPMXwKP6lsD1ShkrcGYjhAIvqKKdXQyPHw/9NF0tl3On/xOJ4ACkxfeG7AF+chfCN1NpBg==", + "dev": true, + "requires": { + "estree-walker": "^0.5.2", + "micromatch": "^2.3.11" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "optional": true + }, + "semver": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", + "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "dev": true + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slack-node": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/slack-node/-/slack-node-0.2.0.tgz", + "integrity": "sha1-3kuN3aqLeT9h29KTgQT9q/N9+jA=", + "dev": true, + "optional": true, + "requires": { + "requestretry": "^1.2.2" + } + }, + "smart-buffer": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", + "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=", + "dev": true, + "optional": true + }, + "smtp-connection": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz", + "integrity": "sha1-1275EnyyPCJZ7bHoNJwujV4tdME=", + "dev": true, + "optional": true, + "requires": { + "httpntlm": "1.6.1", + "nodemailer-shared": "1.1.0" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + } + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "optional": true, + "requires": { + "hoek": "2.x.x" + } + }, + "socket.io": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz", + "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=", + "dev": true, + "requires": { + "debug": "~2.6.6", + "engine.io": "~3.1.0", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.0.4", + "socket.io-parser": "~3.1.1" + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "dev": true + }, + "socket.io-client": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz", + "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~2.6.4", + "engine.io-client": "~3.1.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.1.1", + "to-array": "0.1.4" + } + }, + "socket.io-parser": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", + "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "has-binary2": "~1.0.2", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "socks": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.10.tgz", + "integrity": "sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=", + "dev": true, + "optional": true, + "requires": { + "ip": "^1.1.4", + "smart-buffer": "^1.0.13" + } + }, + "socks-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz", + "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", + "dev": true, + "optional": true, + "requires": { + "agent-base": "~4.2.0", + "socks": "~2.2.0" + }, + "dependencies": { + "smart-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.1.tgz", + "integrity": "sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg==", + "dev": true, + "optional": true + }, + "socks": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.1.tgz", + "integrity": "sha512-0GabKw7n9mI46vcNrVfs0o6XzWzjVa3h6GaSo2UPxtWAROXUWavfJWh1M4PR5tnE0dcnQXZIDFP4yrAysLze/w==", + "dev": true, + "optional": true, + "requires": { + "ip": "^1.1.5", + "smart-buffer": "^4.0.1" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", + "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", + "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "dev": true, + "optional": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "streamroller": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", + "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", + "dev": true, + "requires": { + "date-format": "^1.2.0", + "debug": "^3.1.0", + "mkdirp": "^0.5.1", + "readable-stream": "^2.3.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "supports-color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + }, + "through2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.1.tgz", + "integrity": "sha1-OE51MU1J8y3hLuu4E2uOtrXVnak=", + "dev": true, + "requires": { + "readable-stream": "~2.0.0", + "xtend": "~4.0.0" + }, + "dependencies": { + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "thunkify": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", + "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=", + "dev": true, + "optional": true + }, + "timers-browserify": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", + "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "timespan": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", + "integrity": "sha1-SQLOBAvRPYRcj1myfp1ZutbzmSk=", + "dev": true, + "optional": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "optional": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "ts-node": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-6.1.0.tgz", + "integrity": "sha512-mw11Bq08RZgrU/bzcVw/Ti9wNyefpOanXgWsHg008wyVHjvFhWxNatVVrciOAu8BcWSECoNOSunRzUokKH8Mmw==", + "dev": true, + "requires": { + "arrify": "^1.0.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "dev": true, + "optional": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "typescript": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.1.tgz", + "integrity": "sha512-h6pM2f/GDchCFlldnriOhs1QHuwbnmj6/v7499eMHqPeW4V2G0elua2eIc2nu8v2NdHV0Gm+tzX83Hr6nUFjQA==", + "dev": true + }, + "uglify-js": { + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", + "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", + "dev": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + } + } + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "underscore": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", + "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", + "dev": true, + "optional": true + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz", + "integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz", + "integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==", + "dev": true + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "upath": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "dev": true + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "useragent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.2.1.tgz", + "integrity": "sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4=", + "dev": true, + "requires": { + "lru-cache": "2.2.x", + "tmp": "0.0.x" + }, + "dependencies": { + "lru-cache": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.2.4.tgz", + "integrity": "sha1-bGWGGb7PFAMdDQtZSxYELOTcBj0=", + "dev": true + } + } + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true, + "optional": true + }, + "uws": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", + "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", + "dev": true, + "optional": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "dev": true + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "when": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", + "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=", + "dev": true, + "optional": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "with-callback": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/with-callback/-/with-callback-1.0.2.tgz", + "integrity": "sha1-oJYpuakgAo1yFAT7Q1vc/1yRvCE=", + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "dev": true + }, + "xregexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", + "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", + "dev": true, + "optional": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true, + "optional": true + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "dev": true + } + } +} diff --git a/package.json b/package.json index df832c8..15eb44c 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,46 @@ { - "name": "livingapps", - "version": "0.2.0", - "description": "the livingapps api for nodejs", - "main": "src/livingSDK.js", + "name": "livingsdk", + "version": "0.3.0", + "description": "livingapps api for javascript (nodjs and browser) written in typescript", + "main": "dist/es2015/livingsdk.js", + "types": "dist/es2015/livingsdk.d.ts", "repository": { "type": "git", "url": "https://github.com/LivingLogic/LivingApps.Javascript.LivingAPI.git" }, "scripts": { - "test": "mocha" + "test": "sh shellscripts/build.sh && mocha -r source-map-support/register dist/test/**/*.test.js", + "build": "sh shellscripts/build.sh", + "karma": "sh shellscripts/build.sh && karma start" }, - "author": "", + "author": "Living Logic AG", "license": "ISC", "dependencies": { + "axios": "^0.18.0", "blueimp-md5": "^2.10.0" }, "devDependencies": { + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "@types/chai": "^4.1.3", + "@types/mocha": "^5.2.1", + "@types/node": "^10.3.2", "chai": "^4.1.2", "express": "^4.15.4", - "mocha": "^3.5.2" + "karma": "^2.0.5", + "karma-chrome-launcher": "^2.2.0", + "karma-mocha": "^1.3.0", + "karma-rollup-preprocessor": "^6.0.1", + "karma-typescript": "^3.0.13", + "mocha": "^3.5.2", + "rollup": "^0.65.0", + "rollup-plugin-babel": "^4.0.2", + "rollup-plugin-commonjs": "^9.1.6", + "rollup-plugin-node-resolve": "^3.4.0", + "rollup-plugin-sourcemaps": "^0.4.2", + "rollup-plugin-uglify": "^5.0.2", + "source-map-support": "^0.5.12", + "ts-node": "^6.1.0", + "typescript": "^2.9.1" } } diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..b8ba3eb --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,55 @@ +const uglify = require('rollup-plugin-uglify'); +const sourcemaps = require('rollup-plugin-sourcemaps'); +const babel = require('rollup-plugin-babel'); +const resolve = require( 'rollup-plugin-node-resolve' ); +const commonjs = require( 'rollup-plugin-commonjs' ); + +export default [ + { + input: './dist/es2015/livingsdk.js', + output: { + file: './dist/umd/livingsdk.js', + format: 'umd', + name: 'livingsdk', + sourcemap: true, + globals: { + axios: 'axios', + https: 'https', + } + }, + plugins: [ + uglify.uglify(), + sourcemaps(), + babel( + { + "presets": [ + [ + "@babel/preset-env", + { + "useBuiltIns": "usage" + } + ] + ] + } + ) + ] + }, + { + input: './dist/es2015/livingsdk.test.js', + output: { + file: './dist/test/livingsdk.test.js', + format: 'umd', + name: 'livingsdk', + sourcemap: true, + globals: { + axios: 'axios', + https: 'https', + chai: 'chai', + mocha: 'mocha' + } + }, + plugins: [ + sourcemaps() + ] + }, +] \ No newline at end of file diff --git a/shellscripts/build.sh b/shellscripts/build.sh new file mode 100644 index 0000000..00aadf5 --- /dev/null +++ b/shellscripts/build.sh @@ -0,0 +1,10 @@ +rm -Rf ./dist +echo build LivingApps.Javascript.LivingAPI +./node_modules/typescript/bin/tsc +wait +echo copy modules +cp -R ./src/modules ./dist/es2015/ +echo run rollup +./node_modules/rollup/bin/rollup -c +echo copy d.ts file +cp ./dist/es2015/livingsdk.d.ts ./dist/umd/livingsdk.d.ts \ No newline at end of file diff --git a/src/livingSDK.js b/src/livingSDK.js deleted file mode 100644 index 7548ffc..0000000 --- a/src/livingSDK.js +++ /dev/null @@ -1,408 +0,0 @@ -;(function (root) { - let livingAppsVersion = 0.2; - // amd is not implemented yet - let amd = (typeof define === 'function' && define.amd); - let commonjs = (typeof module === 'object' && module.exports); - - let livingApi, ul4on, request, http; - if (commonjs) { - livingApi = require('./modules/livingapi'); - ul4on = require('./modules/ul4.js').ul4on; - http = require('https'); - } else { - livingApi = root.livingapi; - ul4on = root.ul4on; - } - - class livingSDK { - /** - * @param {String} [username] - * @param {String} [password] - * @param {Object} [options={}] - * @param {String} [options.url] - */ - constructor(options = {}, username, password) { - /** @type {String} */ - this._password = password; - /** @type {String} */ - this._userName = username; - /** @type {Object} */ - this._options = { - /** @type {String} */ - url: options.url !== undefined ? options.url : 'https://my.living-apps.de', - /** @type {Boolean} */ - loginRequired: options.loginRequired !== undefined ? options.loginRequired : true - }; - this._options.url = this._options.url.lastIndexOf('/') === this._options.url.length - 1 ? this._options.url : `${this._options.url}/`; - this.hostName = this._options.url.split('//')[1].substr(0, this._options.url.split('//')[1].length - 1); - if (this._options.loginRequired && !this._userName) { - throw new Error('[livingSDK] You want to login without a username') - } - this.session = this.login(); - } - - /** - * get token for Session - * @return {Promise.} - */ - login() { - if (!this._options.loginRequired) { - return undefined; - } - return new Promise((resolve, reject) => { - - - if (commonjs) { - let options = { - "ecdhCurve": 'auto', - "method": "POST", - "hostname": this._options.url.split('//')[1].substr(0, this._options.url.split('//')[1].length-1), - "port": 443, - "path": "/gateway/login", - "headers": { - "Content-Type": "application/json" - } - }; - let req = http.request(options, (res) => { - let chunks = [];; - if (res.statusCode !== 200) { - reject(new Error('Http Statuscode ' + res.statusCode)); - } - res.on('data', (chunk) => { - chunks.push(chunk); - }); - - res.on('end', () => { - let body = Buffer.concat(chunks); - resolve(JSON.parse(body.toString()).auth_token); - }); - }); - req.write(JSON.stringify({ - username: this._userName, - password: this._password - })); - req.end(); - } else { - $.ajax(`${this._options.url}gateway/login`, { - dataType: 'json', - data: JSON.stringify({ - 'username': this._userName, - 'password': this._password - }), - method: 'POST', - error: function (error) { - reject(error); - }, - success: function (body) { - resolve(body.auth_token); - } - }); - } - }); - } - - get(appID, templateName) { - return new Promise((resolve, reject) => { - this.session.then((auth_token) => { - if (commonjs) { - let options = { - "ecdhCurve": 'auto', - "method": "GET", - "hostname": this._options.url.split('//')[1].substr(0, this._options.url.split('//')[1].length-1), - "port": 443, - "path": `/gateway/apps/${appID}${templateName !== undefined ? '/' + templateName : '' }`, - "headers": { - 'Accept': 'application/la-ul4on', - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - } - }; - let req = http.request(options, (res) => { - let chunks = []; - res.on('data', function (chunk) { - chunks.push(chunk); - }); - - res.on('end', () => { - if (res.statusCode === 200) { - let body = Buffer.concat(chunks).toString(); - let dump; - try{ - dump = ul4on.loads(body.toString()); - } - catch(err) { - reject(err); - return; - } - dump.get('globals').Login = this; -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> fix: viewtemplates are not required anymore -======= ->>>>>>> eda86940027a5eb38483741b9138d6ad4d7c68d6 - -======= ->>>>>>> Remove outdated code. - resolve(dump); - } else if (res.statusCode === 403) { - this.session = this.login(); - console.log('token is not valid'); - resolve(this.get(appID, templateName)); - } else { - reject(new Error('Http Statuscode ' + res.statusCode)); - } - }); - }); - console.log(req); - req.end(); - } else { - $.ajax(`${this._options.url}gateway/apps/${appID}${templateName !== undefined ? '/' + templateName : ''}`, { - headers: { - 'Accept': 'application/la-ul4on', - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - }, - method: 'GET', - error: (error) => { - if (error.status === 403) { - this.session = this.login(); - console.log('token is not valid'); - resolve(this.get(appID, templateName)); - } - reject(error); - }, - success: (body) => { - let dump = ul4on.loads(body); - dump.get('globals').Login = this; - resolve(dump); - } - }) - } - }); - }); - } - - _insert(app, values) { - return new Promise((resolve, reject) => { - this.session.then((auth_token) => { - let fields = {}; - - for (let ident in values) { - if (!app.controls.has(ident)) { - reject(`insert() got an unexpected keyword argument ${ident}`); - } - - fields[ident] = app.controls.get(ident).asjson(values[ident]); - } - let data = {}; { - - } - data.id = app.id; - data.data = [{ 'fields': fields }]; - if (commonjs) { - let options = { - "ecdhCurve": 'auto', - "method": "POST", - "hostname": this._options.url.split('//')[1].substr(0, this._options.url.split('//')[1].length-1), - "port": 443, - "path": `/gateway/v1/appdd/${app.id}.json`, - "headers": { - "Content-Type": "application/json", - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - } - }; - let req = http.request(options, (res) => { - if (res.statusCode !== 200) { - reject(new Error('Http Statuscode ' + res.statusCode)); - } - let chunks = []; - res.on('data', (chunk) => { - chunks.push(chunk); - }); - - res.on('end', () => { - if (res.statusCode !== 200) { - reject(res.statusCode); - return; - } - let body = Buffer.concat(chunks).toString(); - let returnObj = { - HTTPstatusCode: res.statusCode, - recordid: JSON.parse(body).id, - Record: livingApi.Record.create({ - id: JSON.parse(body).id, - createdat: new Date(Date.now()), - updatedat: null, - updatedby: null, - updatecount: 0 - }) - }; - resolve(returnObj); - }); - }); - req.write(JSON.stringify({ 'appdd': data })); - req.end(); - } else { - $.ajax(`${this._options.url}gateway/v1/appdd/${app.id}.json`, { - method: 'post', - data: { 'appdd': JSON.stringify(data) }, - headers: { - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - }, - success: (body) => { - let returnObj = { - recordid: body.id, - Record: livingApi.Record.create({ - id: body.id, - createdat: new Date(Date.now()), - updatedat: null, - updatedby: null, - updatecount: 0 - }) - }; - resolve(returnObj); - }, - error: (error) => { - reject(error); - } - }); - } - }) - }); - } - - _update(record, values) { - return new Promise((resolve, reject) => { - this.session.then((auth_token) => { - let fields = {}; - let app = record.app; - for (let ident in values) { - if (!app.controls.has(ident)) { - reject(`update() got an unexpected keyword argument ${ident}`); - } - fields[ident] = values[ident]; - } - let data = {}; - data.id = app.id; - data.data = [{ 'id': record.id, 'fields': fields }]; - if (commonjs) { - let options = { - "ecdhCurve": 'auto', - "method": "POST", - "hostname": this._options.url.split('//')[1].substr(0, this._options.url.split('//')[1].length-1), - "port": 443, - "path": `/gateway/v1/appdd/${app.id}.json`, - "headers": { - "Content-Type": "application/json", - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - } - }; - let req = http.request(options, (res) => { - if (res.statusCode !== 200) { - reject(new Error('Http Statuscode ' + res.statusCode)); - } - let chunks = []; - res.on('data', (chunk) => { - chunks.push(chunk); - }); - - res.on('end', () => { - let body = Buffer.concat(chunks).toString(); - for (let ident in values) - record.fields.get(ident).value = values[ident]; - let returnObj = { - HTTPstatusCode: res.statusCode, - recordid: JSON.parse(body).id, - Record: record - }; - resolve(returnObj); - }); - }); - req.write(JSON.stringify({ 'appdd': data })); - req.end(); - - } else { - $.ajax(`${this._options.url}gateway/v1/appdd/${app.id}.json`, { - data: { 'appdd': JSON.stringify(data) }, - headers: { - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - }, - method: 'post', - success: (body) => { - for (let ident in values) - record.fields.get(ident).value = values[ident]; - let returnObj = { - HTTPstatusCode: 200, - recordid: body.id, - Record: record - }; - resolve(returnObj); - }, - error: (error) => { - reject(error); - } - }) - } - }); - }); - } - - _delete(record) { - return new Promise((resolve, reject) => { - this.session.then((auth_token) => { - let app = record.app; - let recordId = record.id; - if (commonjs) { - let options = { - 'ecdhCurve': 'auto', - 'method': 'DELETE', - 'hostname': this.hostName, - 'port': 443, - 'path': `/gateway/v1/appdd/${app.id}/${recordId}.json`, - 'headers': { - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - } - }; - let req = http.request(options, (res) => { - if (res.statusCode !== 200) { - reject(new Error('Http Statuscode ' + res.statusCode)); - } - let chunks = []; - res.on('data', (chunk) => { - chunks.push(chunk); - }); - - res.on('end', () => { - if (res.statusCode === 200) - resolve(200); - }); - }); - req.end(); - - } else { - $.ajax(`${this._options.url}gateway/v1/appdd/${app.id}/${recordId}.json`, { - method: 'delete', - headers: { - 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '' - }, - success: () => { - resolve(200); - }, - error: () => { - reject(error); - } - }); - } - }) - }) - } - } - - if (commonjs) { - module.exports = livingSDK; - } else { - root.livingSDK = livingSDK; - } - - -})(this); diff --git a/src/livingsdk.test.ts b/src/livingsdk.test.ts new file mode 100644 index 0000000..4035315 --- /dev/null +++ b/src/livingsdk.test.ts @@ -0,0 +1,356 @@ +import { LivingSDK, LivingSDKOptions, Auth_Token } from './livingsdk'; +import { expect } from 'chai'; +import {livingappsData as lsd, removeData } from './config' +import { AxiosError } from 'axios'; + +let SERVER = lsd.url; + + +enum lsdktemplates { + default= 'default', + loggedIn = 'loggedInUsers', + admin = 'withAdminPrivileges', + permissions = 'withPermissions', + workpriv = 'withWorkingPrivileges' +} + +type LAAPI = any; + +// not logged in user +function createMinLSDK () { + return new LivingSDK({loginRequired: false, url: SERVER}); +} +// logged in user +function createMaxLSDK () { + return new LivingSDK({url: SERVER}, lsd.username, lsd.password); +} + +describe('LivingSDK: ', () => { + beforeEach( () => { + // time out for not ddos server + return new Promise( (resolve, reject ) => { + setTimeout( () => { + resolve(); + }, 1000); + }) + } ); + /* + * test login + * - getAuthToken + */ + describe('.login()', () => { + + it('no login', () => { + let lsdk = new LivingSDK({loginRequired: false, url: SERVER}); + return lsdk.login().then((auth_token: Auth_Token) => { + // expect(typeof auth_token).to.equal('undefined'); + console.log( auth_token ); + }); + }).timeout( 10000 ); + + it('login with correct username and password', () => { + let lsdk = new LivingSDK({ url: SERVER}, lsd.username, lsd.password); + return lsdk.login().then((auth_token: Auth_Token) => { + console.log(auth_token); + expect(typeof auth_token).to.equal('string'); + }); + }).timeout( 10000 ); + + it('change auth_token', () => { + let lsdk = new LivingSDK({ url: SERVER}, lsd.username, lsd.password); + return lsdk.login().then(() => { + // session is private -> cast lsdk to any + (lsdk).session = Promise.resolve("10"); + return (lsdk).session; + }).then(() => { + return lsdk.get(lsd.appId, lsdktemplates.loggedIn); + }) + .then(() => { + throw new Error("user still logged in"); + }).catch((err: any) => { + expect(err.message).to.equal("Request failed with status code 403"); + }); + }).timeout( 10000 ); + + it('login with wrong data', () => { + let lsdk = new LivingSDK({ url: SERVER}, "foo", "bar"); + return lsdk.login().then((auth_token: Auth_Token) => { + // teste ob ergebnis leer ist + expect(auth_token).to.equal(undefined); + }); + }).timeout( 10000 ); + }); + + + describe('.get()', () => { + + describe('permissions without login', () => { + + it('request default', () => { + return createMinLSDK().get(lsd.appId); + }).timeout( 10000 ); + + it('request loggedInUsers', () => { + return createMinLSDK().get(lsd.appId, lsdktemplates.loggedIn) + .then(() => { + throw new Error('should not reach this part of code'); + }) + .catch((err: any) => { + expect(err.message).to.equal('Request failed with status code 403'); + }) + }).timeout( 10000 ); + + it('request withPermissionsForApp', () => { + return createMinLSDK().get(lsd.appId, lsdktemplates.permissions) + .then(() => { + throw new Error('should not reach this part of code'); + }) + .catch((err: any) => { + expect(err.message).to.equal('Request failed with status code 403'); + }) + }).timeout( 10000 ); + + it('request withWorkingPrivilegesApp', () => { + return createMinLSDK().get(lsd.appId, lsdktemplates.workpriv) + .then(() => { + throw new Error('should not reach this part of code'); + }) + .catch((err: any) => { + expect(err.message).to.equal('Request failed with status code 403'); + }) + }).timeout( 10000 ); + + it('request withAdminPrivileges', () => { + return createMinLSDK().get(lsd.appId, lsdktemplates.admin) + .then(() => { + throw new Error('should not reach this part of code'); + }) + .catch((err: any) => { + expect(err.message).to.equal('Request failed with status code 403'); + }) + }).timeout( 10000 ) + + }); + + describe('permissions with admin login', () => { + + it('request default', () => { + return createMaxLSDK().get(lsd.appId); + }).timeout( 10000 ); + + it('request loggedInUsers', () => { + return createMaxLSDK().get(lsd.appId, lsdktemplates.loggedIn); + }).timeout( 10000 ); + + it('request withPermissionsForApp', () => { + return createMaxLSDK().get(lsd.appId, lsdktemplates.permissions); + }).timeout( 10000 ); + + it('request withWorkingPrivilegesApp', () => { + return createMaxLSDK().get(lsd.appId, lsdktemplates.workpriv); + }).timeout( 10000 ); + + it('request withAdminPrivileges', () => { + return createMaxLSDK().get(lsd.appId, lsdktemplates.admin); + }).timeout( 10000 ); + + }); + + it('request not existing app', () => { + return createMaxLSDK().get('template-unknown-test') + .then(() => { + throw new Error('should not reach this part of code'); + }) + .catch((err: any) => { + expect(err.message).to.equal('Request failed with status code 404'); + }) + }).timeout( 10000 ); + + }); + + describe('._insert()', () => { + + it('insert in unknown Datasource', () => { + return createMaxLSDK().get(lsd.appId, lsdktemplates.admin) + .then((LAAPI: LAAPI) => { + return LAAPI.get('datasources').get('unknown'); + }) + .then((storage: any) => { + expect(storage).to.equal(undefined); + }); + }).timeout( 10000 ); + + it('insert an ID to StorageApp', () => { + return createMaxLSDK().get(lsd.appId, lsdktemplates.admin) + .then((LAAPI: LAAPI) => { + return LAAPI.get('datasources').get('storage'); + }) + .then((storage: any) => { + return storage.app.insert({id: `[JS]${(new Date()).toDateString()}`}); + }); + }).timeout( 10000 ); + + it('insert to self', () => { + return createMaxLSDK().get(lsd.appId, lsdktemplates.admin) + .then((LAAPI: LAAPI) => { + return LAAPI.get('datasources').get('self'); + }) + .then((storage: any) => { + // ignore file upload + return storage.app.insert({ + text: '[JS] this is a text', + number: 42, + phone: '+49 0000 0000000000', + url: 'https://milleniumfrog.de', + mail: 'web@example.com', + date: new Date(), + textarea: '[JS] this is even more text', + selection: 'option_1', + options: '_1', + multiple_options: ['_1'], + checkmark: true, + geodata: '0.0,0.0,' + }); + }); + }).timeout( 10000 ); + + it('auto relog login', () => { + let lsdk = createMaxLSDK(); + return lsdk.get(lsd.appId, lsdktemplates.admin) + .then((LAAPI: LAAPI) => { + (lsdk).session = Promise.resolve('undefined'); + return LAAPI.get('datasources').get('storage'); + }) + .then((storage: any) => { + return storage.app.insert({id: '[JS] before relogged'}) + .then(() => { + return storage; + }) + .catch((err: AxiosError) => { + if (err.response.status === 403) { + (lsdk).session = lsdk.login(); + return storage; + } else { + return storage; + } + }) + }) + .then((storage) => { + return storage.app.insert({id: '[JS] relogged'}) + }); + }).timeout( 10000 ); + + }); + + describe('._update()', () => { + + it('update in storage', () => { + return createMaxLSDK().get(lsd.appId, lsdktemplates.admin) + .then((LAAPI: LAAPI) => { + return LAAPI.get('datasources').get('storage').app; + }) + .then((storage: any) => { + return storage.records.values(); + }) + .then((records: any) => { + for (let i of records) { + return i.update({id: '[JS] updated'}); + } + }); + }).timeout(5000); + + it('update in self', () => { + return createMaxLSDK().get(lsd.appId, lsdktemplates.admin) + .then((LAAPI: LAAPI) => { + return LAAPI.get('datasources').get('self').app; + }) + .then((storage: any) => { + return storage.records.values(); + }) + .then((records: any) => { + for (let i of records) { + return i.update({ + text: '[JS] this is a updated text', + number: 84, + phone: '+49 0000 0000000001', + url: 'https://dev.milleniumfrog.de', + mail: 'update@example.com', + date: new Date(), + textarea: '[JS] this is an even more updated text', + selection: 'option_2', + options: '_3', + multiple_options: ['_2'], + checkmark: true, + geodata: '0.1,1.0,' + }); + } + }); + }).timeout( 10000 ) + it('auto relog update', () => { + let lsdk = createMaxLSDK(); + return lsdk.get(lsd.appId, lsdktemplates.admin) + .then((LAAPI: LAAPI) => { + return LAAPI.get('datasources').get('storage').app; + }) + .then((storage: any) => { + (lsdk).session = Promise.resolve('undefined'); + return storage.records.values(); + }) + .then((records: any) => { + for (let i of records) { + return i.update({id: '[JS] updated'}).catch((err: AxiosError) => { + if (err.response.status === 403) { + (lsdk).session = lsdk.login(); + return i; + } + throw err; + }); + } + }) + .then((record: any) => { + return record.update({id: '[JS] updated after relog'}); + }); + }).timeout(5000); + + }); + + if (removeData) { + describe('._delete()', () => { + + it('remove all records from storage', () => { + return createMaxLSDK().get(lsd.appId, lsdktemplates.admin) + .then((LAAPI: LAAPI) => { + return LAAPI.get('datasources').get('storage').app; + }) + .then((storage: any) => { + return storage.records.values(); + }) + .then((records: any) => { + let arr: Array> = [] + for (let i of records) { + arr.push(i.delete()); + } + return Promise.all(arr); + }); + }).timeout(10000); + + it('remove all records from self', () => { + return createMaxLSDK().get(lsd.appId, lsdktemplates.admin) + .then((LAAPI: LAAPI) => { + return LAAPI.get('datasources').get('self').app; + }) + .then((storage: any) => { + return storage.records.values(); + }) + .then((records: any) => { + let arr: Array> = [] + for (let i of records) { + arr.push(i.delete()); + } + return Promise.all(arr); + }); + }).timeout(10000); + + }); + } +}); \ No newline at end of file diff --git a/src/livingsdk.ts b/src/livingsdk.ts new file mode 100644 index 0000000..4cad096 --- /dev/null +++ b/src/livingsdk.ts @@ -0,0 +1,185 @@ +import axios, { AxiosResponse } from 'axios'; +///@ts-ignore +import livingApi from './modules/livingapi'; +///@ts-ignore +import { ul4 } from './modules/ul4'; +import * as https from 'https'; + +export type Auth_Token = string; +export type LivingApi = any; +export type LAPIRecord = any; +let commonjs = (typeof module === 'object' && module.exports); +export interface LivingSDKOptions { + url?: string; + loginRequired?: boolean; +} + +export class LivingSDK { + private _password: string; + private _userName: string; + private _options: LivingSDKOptions + private hostName: string; + private session: Promise; + constructor(options: LivingSDKOptions = {}, username?: string, password?: string) { + /** @type {String} */ + this._password = password || ''; + /** @type {String} */ + this._userName = username || ''; + /** @type {Object} */ + this._options = { + /** @type {String} */ + url: options.url || 'https://my.living-apps.de', + /** @type {Boolean} */ + loginRequired: options.loginRequired !== undefined ? options.loginRequired : true + }; + this._options.url = this._options.url.lastIndexOf('/') === this._options.url.length - 1 ? this._options.url : `${this._options.url}/`; + this.hostName = this._options.url.split('//')[1].substr(0, this._options.url.split('//')[1].length - 1); + if (this._options.loginRequired && !this._userName) { + throw new Error('[LivingSDK] You want to login without a username') + } + this.session = this.login(); + } + + /** + * get token for Session + * @return {Promise.} + */ + login(): Promise { + if (!this._options.loginRequired) { + return Promise.resolve(undefined); + } + let url = `https://${this.hostName}/gateway/login`; + return axios.post(url, { + username: this._userName, + password: this._password + }, { + httpsAgent: commonjs ? new https.Agent({ + ecdhCurve: 'auto' + }) : undefined, + headers: { + "Content-Type": "application/json" + } + }) + .then((a: any) => a.data.auth_token); + } + + get(appId: string, templateName?: string): Promise { + return this.session.then((auth_token: Auth_Token | undefined) => { + return axios.get(`https://${this.hostName}/gateway/apps/${appId}${templateName !== undefined ? '?template=' + templateName : ''}`, + { + httpsAgent: commonjs ? new https.Agent({ + ecdhCurve: 'auto' + }) : undefined, + headers: { + 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '', + Accept: 'application/la-ul4on' + } + }) + .then((res: AxiosResponse) => { + let dump: any; + dump = ul4.loads(res.data); + dump.get('globals').Login = this; + return dump; + }); + }); + } + + _insert(app: any, values: any): Promise { + return this.session.then((auth_token) => { + + let fields: any = {}; + + for (let ident in values) { + if (!app.controls.has(ident)) { + throw new Error(`insert() got an unexpected keyword argument ${ident}`); + } + + fields[ident] = app.controls.get(ident).asjson(values[ident]); + } + let data: any = {}; { + } + data.id = app.id; + data.data = [{ 'fields': fields }]; + return axios.post(`https://${this.hostName}/gateway/v1/appdd/${app.id}.json`, { + appdd: data + }, { + httpsAgent: commonjs ? new https.Agent({ + ecdhCurve: 'auto' + }) : undefined, + headers: { + 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '', + } + }) + .then((res: AxiosResponse) => { + return { + HTTPstatusCode: res.status, + recordid: res.data.id, + Record: new livingApi.Record({ + id: res.data.id, + createdat: new Date(Date.now()), + updatedat: null, + updatedby: null, + updatecount: 0 + }) + }; + }) + }) + + } + + _update(record: LAPIRecord, values: any) { + return this.session.then((auth_token: Auth_Token | undefined) => { + let fields: any = {}; + let app = record.app; + for (let ident in values) { + if (!app.controls.has(ident)) { + throw new Error(`update() got an unexpected keyword argument ${ident}`); + } + fields[ident] = values[ident]; + } + let data: any = {}; + data.id = app.id; + data.data = [{ 'id': record.id, 'fields': fields }]; + console.log(`https://${this.hostName}/gateway/v1/appdd/${app.id}.json`); + return axios.post(`https://${this.hostName}/gateway/v1/appdd/${app.id}.json`, { + appdd: data + }, { + httpsAgent: commonjs ? new https.Agent({ + ecdhCurve: 'auto' + }) : undefined, + headers: { + 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '', + 'Content-Type': 'application/json' + } + }) + .then((res: AxiosResponse) => { + let body = res.data; + for (let ident in values) + record.fields.get(ident).value = values[ident]; + let returnObj = { + HTTPstatusCode: res.status, + recordid: body.id, + Record: record + }; + return returnObj; + }); + }); + } + + _delete(record: LAPIRecord) { + let app = record.app; + return this.session.then((auth_token: Auth_Token | undefined) => { + return axios.delete(`https://${this.hostName}/gateway/v1/appdd/${app.id}/${record.id}.json`, { + httpsAgent: commonjs ? new https.Agent({ + ecdhCurve: 'auto' + }) : undefined, + headers: { + 'X-La-Auth-Token': auth_token !== undefined ? auth_token : '', + } + + }) + }) + } +} + +export default LivingSDK; \ No newline at end of file diff --git a/src/modules/livingapi.js b/src/modules/livingapi.js index a5d6faa..8a4cb1f 100644 --- a/src/modules/livingapi.js +++ b/src/modules/livingapi.js @@ -1,1060 +1,1111 @@ -(function(root){ +import { ul4 } from './ul4'; +let la = {}; - let amd = (typeof define === 'function' && define.amd); - let commonjs = (typeof module === 'object' && module.exports); - let la = {}; +la.Base = class Base extends ul4.Proto +{ + constructor() + { + super(); + } - let ul4, ul4on; + ul4ondump(encoder) + { + for (let i = 0; i < this._ul4onattrs.length; ++i) + encoder.dump(this._dumpUL4ONAttr(this._ul4onattrs[i])); + } - if (commonjs) { - ul4 = require('./ul4.js').ul4; - ul4on = require('./ul4').ul4on; - module.exports = la; - } else { - ul4 = root.ul4; - ul4on = root.ul4on; - root.livingapi = la; + _dumpUL4ONAttr(name) + { + return this[name]; } - la.Base = ul4._inherit( - ul4.Proto, + + ul4onload(decoder) + { + let i = 0; + for (let iter = decoder.loadcontent(); ; ++i) { - create: function() - { - return ul4._clone(this); - }, - - ul4ondump: function ul4ondump(encoder) - { - for (var i = 0; i < this._ul4onattrs.length; ++i) - encoder.dump(this._dumpUL4ONAttr(this._ul4onattrs[i])); - }, - - _dumpUL4ONAttr: function _dumpUL4ONAttr(name) - { - return this[name]; - }, - - ul4onload: function ul4onload(decoder) - { - for (var i = 0, iter = decoder.loadcontent();; ++i) - { - var iteritem = iter.next(); - if (iteritem.done) - break; - if (i < this._ul4onattrs.length) - this._loadUL4ONAttr(this._ul4onattrs[i], iteritem.value); - } - for (; i < this._ul4onattrs.length; ++i) - { - this._setDefaultUL4ONAttr(this._ul4onattrs[i]); - } - }, - - _loadUL4ONAttr: function _loadUL4ONAttr(name, value) - { - this[name] = value; - }, - - _setDefaultUL4ONAttr: function _setDefaultUL4ONAttr(name) - { - this[name] = null; - } + let iteritem = iter.next(); + if (iteritem.done) + break; + if (i < this._ul4onattrs.length) + this._loadUL4ONAttr(this._ul4onattrs[i], iteritem.value); } - ); - - la.Globals = ul4._inherit( - la.Base, + for (; i < this._ul4onattrs.length; ++i) + this._setDefaultUL4ONAttr(this._ul4onattrs[i]); + } + + _loadUL4ONAttr(name, value) + { + this[name] = value; + } + + _setDefaultUL4ONAttr(name) + { + this[name] = null; + } + + __getattr__(name) + { + if (this._ul4attrs.has(name)) { - _ul4onattrs: ["version", "platform", "user", "maxdbactions", "maxtemplateruntime", "flashmessages"], - - __repr__: function repr() - { - return ""; - }, - - // distance between two geo coordinates (see https://de.wikipedia.org/wiki/Orthodrome#Genauere_Formel_zur_Abstandsberechnung_auf_der_Erde) - geodist: function geodist(geo1, geo2) + let value = this[name]; + if (typeof(value) === "function") { - var sqsin = function sqsin(x) {x = Math.sin(x); return x*x}; - var sqcos = function sqsos(x) {x = Math.cos(x); return x*x}; - var deg2rad = Math.PI/180; // Conversion factor degree -> radians - var radius = 6378.137; // Equatorial radius of earth in km - var flat = 1/298.257223563; // Earth flattening - - var lat1 = geo1.lat * deg2rad; - var long1 = geo1.long * deg2rad; - var lat2 = geo2.lat * deg2rad; - var long2 = geo2.long * deg2rad; - var F = (lat1 + lat2)/2; - var G = (lat1 - lat2)/2; - var l = (long1 - long2)/2; - var S = sqsin(G) * sqcos(l) + sqcos(F) * sqsin(l); - var C = sqcos(G) * sqcos(l) + sqsin(F) * sqsin(l); - var w = Math.atan(Math.sqrt(S/C)); - var D = 2 * w * radius; - var T = Math.sqrt(S*C)/w; - var H1 = (3*T-1)/(2*C); - var H2 = (3*T+1)/(2*S); - var s = D * (1 + flat * H1 * sqsin(F) * sqcos(G) - flat * H2 * sqcos(F) * sqsin(G)); - return s; + let realvalue = value.bind(this); + realvalue._ul4_name = value._ul4_name || value.name; + realvalue._ul4_signature = value._ul4_signature; + realvalue._ul4_needsobject = value._ul4_needsobject; + realvalue._ul4_needscontext = value._ul4_needscontext; + return realvalue; } + return value; } - ); - - la.FlashMessage = ul4._inherit( - la.Base, + throw new ul4.AttributeError(this, name); + } + + __repr__() + { + return ""; + } +}; + +la.Handler = class Handler +{ + save(record) + { + } + + delete(record) + { + } +}; + +la.Globals = class Globals extends la.Base +{ + constructor() + { + super(); + this.version = null; + this.platform = null; + this.user = null; + this.maxdbactions = null; + this.maxtemplateruntime = null; + this.flashmessages = null; + this.handler = new la.Handler(); + } + + // distance between two geo coordinates (see https://de.wikipedia.org/wiki/Orthodrome#Genauere_Formel_zur_Abstandsberechnung_auf_der_Erde) + static geodist(geo1, geo2) + { + let sqsin = function sqsin(x) {x = Math.sin(x); return x*x}; + let sqcos = function sqsos(x) {x = Math.cos(x); return x*x}; + const deg2rad = Math.PI/180; // Conversion factor degree -> radians + const radius = 6378.137; // Equatorial radius of earth in km + const flat = 1/298.257223563; // Earth flattening + + const lat1 = geo1.lat * deg2rad; + const long1 = geo1.long * deg2rad; + const lat2 = geo2.lat * deg2rad; + const long2 = geo2.long * deg2rad; + const F = (lat1 + lat2)/2; + const G = (lat1 - lat2)/2; + const l = (long1 - long2)/2; + const S = sqsin(G) * sqcos(l) + sqcos(F) * sqsin(l); + const C = sqcos(G) * sqcos(l) + sqsin(F) * sqsin(l); + const w = Math.atan(Math.sqrt(S/C)); + const D = 2 * w * radius; + const T = Math.sqrt(S*C)/w; + const H1 = (3*T-1)/(2*C); + const H2 = (3*T+1)/(2*S); + const s = D * (1 + flat * H1 * sqsin(F) * sqcos(G) - flat * H2 * sqcos(F) * sqsin(G)); + return s; + } + + __repr__() + { + return ""; + } +}; + +la.Globals.prototype._ul4onattrs = ["version", "platform", "user", "maxdbactions", "maxtemplateruntime", "flashmessages"]; +la.Globals.prototype._ul4attrs = ul4._makeset("version", "platform", "user", "maxdbactions", "maxtemplateruntime", "flashmessages"); + +la.FlashMessage = class FlashMessage extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.FlashMessage.prototype._ul4onattrs = ["timestamp", "type", "title", "message"]; +la.FlashMessage.prototype._ul4attrs = ul4._makeset("timestamp", "type", "title", "message"); + +la.App = class App extends la.Base +{ + __repr__() + { + return ""; + } + + insert(values={}) + { + let record = this.__call__(values); + this.globals.handler.save(this); + return this.globals.Login._insert(this, values); + } + + __call__(values={}) + { + let record = new la.Record(this); + if (ul4._ismap(values)) { - _ul4onattrs: ["timestamp", "type", "title", "message"], - - __repr__: function repr() + for (let [key, value] of values.entries()) { - return ""; + if (!record.fields.has(key)) + throw new ul4.ArgumentError("update() get an unexpected keyword argument " + ul4._repr(key)); + record.fields.get(key).value = value; } } - ); - - la.App = ul4._inherit( - la.Base, + else if (ul4._isobject(values)) { - _ul4onattrs: ["id", "globals", "name", "description", "language", "startlink", "iconlarge", "iconsmall", "owner", "controls", "records", "recordcount", "installation", "categories", "params", "views", "datamanagement_identifier"], - - insert: function (values) - { - return this.globals.Login._insert(this, values); - }, - - __repr__: function repr() + for (let key in values) { - return ""; + if (!record.fields.has(key)) + throw new ul4.ArgumentError("update() get an unexpected keyword argument " + ul4._repr(key)); + record.fields.get(key).value = values[key]; } } - ); - - la.View = ul4._inherit( - la.Base, + else + throw new ul4.TypeError("values must be an object or a Map"); + return record; + } + + __getattr__(name) + { + if (name.startsWith("c_")) { - _ul4onattrs: ["id", "name", "app", "order", "width", "height", "start", "end"], - - __repr__: function repr() - { - return ""; - } + if (!this.controls.has(name.substr(2))) + throw new ul4.AttributeError(this, name); + return this.controls.get(name.substr(2)); } - ); + else + return super.__getattr__(name); + } +}; + +la.App.prototype._ul4onattrs = ["id", "globals", "name", "description", "language", "startlink", "iconlarge", "iconsmall", "createdby", "controls", "records", "recordcount", "installation", "categories", "params", "views", "datamanagement_identifier", "basetable", "primarykey", "insertprocedure", "updateprocedure", "deleteprocedure", "templates", "createdat", "updatedat", "updatedby"]; +la.App.prototype._ul4attrs = ul4._makeset("id", "globals", "name", "description", "language", "startlink", "iconlarge", "iconsmall", "createdat", "createdby", "updatedat", "updatedby", "controls", "records", "recordcount", "installation", "categories", "params", "views", "datamanagement_identifier", "insert"); +ul4.expose(la.App.prototype.__call__, ["**values"], {"needsobject": true}); +ul4.expose(la.App.prototype.insert, ["**values"], {"needsobject": true}); + +la.View = class View extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.View.prototype._ul4onattrs = ["id", "name", "app", "order", "width", "height", "start", "end"]; +la.View.prototype._ul4attrs = ul4._makeset("id", "name", "app", "order", "width", "height", "start", "end"); + +la.DataSourceData = class DataSourceData extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.DataSourceData.prototype._ul4onattrs = ["id", "identifier", "app", "apps"]; +la.DataSourceData.prototype._ul4attrs = ul4._makeset("id", "identifier", "app", "apps"); + +la.Record = class Record extends la.Base +{ + constructor(app) + { + super(); + this.id = null; + this.app = app; + this.createdat = null; + this.createdby = null; + this.updatedat = null; + this.updatedby = null; + this.updatecount = 0; + this._sparsevalues = new Map(); + this._values = null; + this._fields = null; + this.children = new Map(); + this.attachments = null; + this.errors = []; + this._is_deleted = false; + } + - la.DataSource = ul4._inherit( - la.Base, + + __repr__() + { + let v = [""; + v.push(" v_"); + v.push(field.control.identifier); + v.push("="); + v.push(ul4._repr(field.value)); // FIXME: This might lead to infinite recursions } } - ); - - la.Record = ul4._inherit( - la.Base, - { - _ul4onattrs: ["id", "app", "createdat", "createdby", "updatedat", "updatedby", "updatecount", "values", "attachments", "children"], - - delete: function () - { - return this.app.globals.Login._delete(this); - }, + v.push(">") + return v.join(""); + } - update: function (values) + get values() + { + if (this._values === null) { - return this.app.globals.Login._update(this, values); - }, - - __repr__: function repr() - { - return ""; - }, - - search: function search(search) - { - for (var identifier in search) - { - var fieldsearch = search[identifier]; - if (ul4._bool(fieldsearch)) - { - if (!this.fields.get(identifier).search(fieldsearch)) - return false; - } - } - return true; - }, - - _dumpUL4ONAttr: function _dumpUL4ONAttr(name) - { - if (name === "values") - return this._sparsevalues; - else - return this[name]; - }, - - _loadUL4ONAttr: function _loadUL4ONAttr(name, value) + this._values = ul4._havemap ? new Map() : {}; + for (let [identifier, control] of this.app.controls.entries()) { - if (name === "values") - { - this._sparsevalues = value; - this._values = null; - this._fields = null; - } - else - this[name] = value; + let fieldvalue = this._sparsevalues.get(identifier); + if (typeof(fieldvalue) === "undefined") + fieldvalue = null; + this._values.set(identifier, fieldvalue); } } - ); - - Object.defineProperty(la.Record, "values", { - get: function() + return this._values; + } + + get fields() + { + if (this._fields === null) { - if (this._values === null) + this._fields = ul4._havemap ? new Map() : {}; + for (let [identifier, value] of this.values.entries()) { - this._values = ul4on._havemap ? new Map() : {}; - var self = this; - this.app.controls.forEach(function(control, id){ - var fieldvalue = self._sparsevalues.get(control.identifier); - if (typeof(fieldvalue) === "undefined") - fieldvalue = null; - self._values.set(id, fieldvalue); - }); + let field = new la.Field(this.app.controls.get(identifier), this, value); + this._fields.set(identifier, field); } - return this._values; } - }); - - Object.defineProperty(la.Record, "fields", { - get: function() + return this._fields; + } + + is_dirty() + { + if (this.id === null) + return true; + for (let field of this.fields.values()) { - if (this._fields === null) - { - this._fields = ul4on._havemap ? new Map() : {}; - var self = this; - this.values.forEach(function(value, id){ - var field = la.Field.create(self.app.controls.get(id), self.app, value); - self._fields.set(id, field); - }); - } - return this._fields; + if (field.is_dirty()) + return true; } - }); - - la.Control = ul4._inherit( - la.Base, - { - type: null, - subtype: null, - _ul4onattrs: ["id", "identifier", "field", "app", "label", "priority", "order", "default"], - - ul4onload: function ul4onload(decoder) - { - ul4onattrs = this._ul4onattrs.slice(); - for (var i = 0, iter = decoder.loadcontent(); i < ul4onattrs.length; ++i) - { - var iteritem = iter.next(); - if (iteritem.done) - break; - this._loadUL4ONAttr(ul4onattrs[i], iteritem.value); - if (ul4onattrs[i] === "app" && this.app.globals.version != "6") - { - ul4onattrs.push("ininsertprocedure"); - ul4onattrs.push("inupdateprocedure"); - } - } - for (; i < ul4onattrs.length; ++i) - this._setDefaultUL4ONAttr(ul4onattrs[i]); - }, - - __repr__: function repr() - { - return ""; - }, + return false; + } - asjson: function(value) - { - return value; - }, - - _logsearch: function _logsearch(value, search) - { - //console.log("Searching for " + ul4._repr(search.value) + " in " + ul4._repr(this) + " with operator " + search.operator + " in value " + ul4._repr(value)); - }, - - // base implemntation, always returns ``false`` (i.e. "not found") - // ``value`` is the value of the field - // ``search`` is an object with information what we're searching for - // keys in ``search`` are: ``operator`` (and ``value`` (if required by the operator)) - search: function search(value, search) - { - return false; - } + has_errors() + { + if (this.errors.length !== 0) + return true; + for (let field of this.fields.values()) + { + if (field.has_errors()) + return true; } - ); - - la.BoolControl = ul4._inherit( - la.Control, + return false; + } + + delete() + { + return this.app.globals.handler.delete(this); + } + + save() + { + this.app.globals.handler.save(this); + } + + update(values={}) + { + if (ul4._ismap(values)) { - type: "bool", - __type__: "BoolControl", - - // ``search`` must by ``null``, ``false`` or ``true`` - search: function search(value, search) + for (let [key, value] of values.entries()) { - this._logsearch(value, search); - if (search.operator === "equals") - return search.value === value; - else - return false; + if (!this.fields.has(key)) + throw new ul4.ArgumentError("update() get an unexpected keyword argument " + ul4._repr(key)); + this.fields.get(key).value = value; } } - ); - - la.IntControl = ul4._inherit( - la.Control, + else if (ul4._isobject(values)) { - type: "int", - __type__: "IntControl", - - // ``search.value`` must by ``null`` or an integer - search: function search(value, search) + for (let key in values) { - this._logsearch(value, search); - if (search.operator === "equals") - return search.value === value; - else - return false; + if (!this.fields.has(key)) + throw new ul4.ArgumentError("update() get an unexpected keyword argument " + ul4._repr(key)); + this.fields.get(key).value = values[key]; } } - ); - - la.NumberControl = ul4._inherit( - la.Control, + else + throw new ul4.TypeError("values must be an object or a Map"); + + this.app.globals.handler.save(this); + return this.app.globals.Login._update(this, values); + } + + search(search) + { + for (let identifier in search) { - type: "number", - __type__: "NumberControl", - - // ``search.value`` must by ``null`` or an integer - search: function search(value, search) + let fieldsearch = search[identifier]; + if (ul4._bool(fieldsearch)) { - this._logsearch(value, search); - if (search.operator === "equals") - return search.value === value; - else if (search.operator === "range") - { - if (value === null) - return false; - return (search.minvalue === null || search.minvalue <= value) && (search.maxvalue === null || value < search.maxvalue); - } - else + if (!this.fields.get(identifier).search(fieldsearch)) return false; } } - ); - - la.StringControl = ul4._inherit( - la.Control, - { - type: "string", + return true; + } - asjson: function (value) - { - return value; - }, + _dumpUL4ONAttr(name) + { + if (name === "values") + return this._sparsevalues; + else + return this[name]; + } - search: function search(value, search) - { - this._logsearch(value, search); - if (search.operator === "equals") - return search.value === value; - else if (search.operator === "contains") - { - if (search.value === null || value === null) - return search.value === value; - else - return value.toLowerCase().indexOf(search.value.toLowerCase()) >= 0; - } - } - } - ); - - la.TextControl = ul4._inherit( - la.StringControl, - { - subtype: "text", - __type__: "TextControl" - } - ); - - la.EmailControl = ul4._inherit( - la.StringControl, - { - subtype: "email", - __type__: "EmailControl" - } - ); - - la.URLControl = ul4._inherit( - la.StringControl, + _loadUL4ONAttr(name, value) + { + if (name === "values") { - subtype: "url", - __type__: "URLControl" + this._sparsevalues = value; + this._values = null; + this._fields = null; } - ); - - la.TelControl = ul4._inherit( - la.StringControl, + else + this[name] = value; + } + + __getattr__(name) + { + if (name.startsWith("c_")) + return this.children.get(name.substr(2)) + else if (name.startsWith("f_")) + return this.fields.get(name.substr(2)) + else if (name.startsWith("v_")) + return this.values.get(name.substr(2)) + else + return this[name]; + } + + __setattr__(name, value) + { + if (name.startsWith("c_")) + this.children[name.substr(2)] = value; + else if (name.startsWith("v_")) + this.fields.get(name.substr(2)).value = value; + else + throw new ul4.AttributeError(this, name); + } +}; + +la.Record.prototype._ul4onattrs = ["id", "app", "createdat", "createdby", "updatedat", "updatedby", "updatecount", "values", "attachments", "children"]; +la.Record.prototype._ul4attrs = ul4._makeset("id", "app", "createdat", "createdby", "updatedat", "updatedby", "updatecount", "values", "attachments", "children"); +ul4.expose(la.Record.prototype.is_dirty, []); +ul4.expose(la.Record.prototype.has_errors, []); +ul4.expose(la.Record.prototype.delete, []); +ul4.expose(la.Record.prototype.save, []); +ul4.expose(la.Record.prototype.update, ["**values"], {"needsobject": true}); + +la.Control = class Control extends la.Base +{ + __repr__() + { + return ""; + } + + _logsearch(value, search) + { + //console.log("Searching for " + ul4._repr(search.value) + " in " + ul4._repr(this) + " with operator " + search.operator + " in value " + ul4._repr(value)); + } + + + asjson(value) { + return value; + } + + // base implemntation, always returns ``false`` (i.e. "not found") + // ``value`` is the value of the field + // ``search`` is an object with information what we're searching for + // keys in ``search`` are: ``operator`` (and ``value`` (if required by the operator)) + search(value, search) + { + return false; + } +}; + +la.Control.prototype.type = null; +la.Control.prototype.subtype = null; +la.Control.prototype._ul4onattrs = ["id", "identifier", "field", "app", "label", "priority", "order", "default", "ininsertprocedure", "inupdateprocedure"]; +la.Control.prototype._ul4attrs = ul4._makeset("id", "identifier", "field", "app", "label", "priority", "order", "default", "ininsertprocedure", "inupdateprocedure"); + +la.BoolControl = class BoolControl extends la.Control +{ + // ``search`` must by ``null``, ``false`` or ``true`` + search(value, search) + { + this._logsearch(value, search); + if (search.operator === "equals") + return search.value === value; + else + return false; + } +}; + +la.BoolControl.prototype.type = "bool"; + +la.IntControl = class IntControl extends la.Control +{ + // ``search.value`` must by ``null`` or an integer + search(value, search) + { + this._logsearch(value, search); + if (search.operator === "equals") + return search.value === value; + else + return false; + } +}; + +la.IntControl.prototype.type = "int"; + +la.NumberControl = class NumberControl extends la.Control +{ + // ``search.value`` must by ``null`` or an integer + search(value, search) + { + this._logsearch(value, search); + if (search.operator === "equals") + return search.value === value; + else if (search.operator === "range") { - subtype: "tel" + if (value === null) + return false; + return (search.minvalue === null || search.minvalue <= value) && (search.maxvalue === null || value < search.maxvalue); } - ); - - la.PasswordControl = ul4._inherit( - la.StringControl, + else + return false; + } +}; + +la.NumberControl.prototype.type = "number"; + +la.StringControl = class StringControl extends la.Control +{ + + asjson(value) { + return value; + } + + search(value, search) + { + this._logsearch(value, search); + if (search.operator === "equals") + return search.value === value; + else if (search.operator === "contains") { - subtype: "password" + if (search.value === null || value === null) + return search.value === value; + else + return value.toLowerCase().indexOf(search.value.toLowerCase()) >= 0; } - ); - - la.TextAreaControl = ul4._inherit( - la.StringControl, + } +}; + +la.StringControl.prototype.type = "string"; + +la.TextControl = class TextControl extends la.StringControl +{ +}; + +la.TextControl.prototype.subtype = "text"; + +la.EmailControl = class EmailControl extends la.StringControl +{ +}; + +la.EmailControl.prototype.subtype = "email"; + +la.URLControl = class URLControl extends la.StringControl +{ +}; + +la.URLControl.prototype.subtype = "url"; + +la.TelControl = class TelControl extends la.StringControl +{ +}; + +la.TelControl.prototype.subtype = "tel"; + +la.PasswordControl = class PasswordControl extends la.StringControl +{ +}; + +la.PasswordControl.prototype.subtype = "password"; + +la.TextAreaControl = class TextAreaControl extends la.StringControl +{ +}; + +la.TextAreaControl.prototype.subtype = "textarea"; +la.TextAreaControl.prototype._ul4onattrs = la.StringControl.prototype._ul4onattrs.concat(["encrypted"]); +la.TextAreaControl.prototype._ul4attrs = ul4._makeset(...la.StringControl.prototype._ul4attrs, "encrypted"); + +la.DateControl = class DateControl extends la.Control +{ + formatstring(language) + { + language = language || this.app.language; + + if (language === "de") + return "%d.%m.%Y"; + else + return "%m/%d/%Y"; + } + + asjson(value) { + return value; + } + + // searchvalue must be ``null``, a ``Date`` object or a string + search(value, search) + { + this._logsearch(value, search); + + let searchvalue = search.value; + if (Object.prototype.toString.call(searchvalue) == "[object Date]") + searchvalue = ul4._format(searchvalue, this.formatstring(), this.app.language); + if (value !== null) + value = ul4._format(value, this.formatstring(), this.app.language); + + if (search.operator === "equals") + return searchvalue === value; + else if (search.operator === "contains") { - subtype: "textarea", - __type__: "TextAreaControl" + if (searchvalue === null || value === null) + return searchvalue === value; + else + return value.toLowerCase().indexOf(searchvalue.toLowerCase()) >= 0; } - ); - - la.DateControl = ul4._inherit( - la.Control, - { - type: "date", - subtype: "date", - __type__: "DateControl", - - asjson: function (value) - { - if (value instanceof Date){ - value = `${value.getFullYear()}-${value.getMonth()+1}-${value.getDate()} ${value.getHours()}:${value.getMinutes()}:${value.getSeconds()}`; - } - return value; - }, - - formatstring: function formatstring(language) - { - language = language || this.app.language; - - if (language === "de") - return "%d.%m.%Y"; - else - return "%m/%d/%Y"; - }, - - // searchvalue must be ``null``, a ``Date`` object or a string - search: function search(value, search) - { - this._logsearch(value, search); - - var searchvalue = search.value; - if (Object.prototype.toString.call(searchvalue) == "[object Date]") - searchvalue = ul4._format(searchvalue, this.formatstring(), this.app.language); - if (value !== null) - value = ul4._format(value, this.formatstring(), this.app.language); - - if (search.operator === "equals") - return searchvalue === value; - else if (search.operator === "contains") - { - if (searchvalue === null || value === null) - return searchvalue === value; - else - return value.toLowerCase().indexOf(searchvalue.toLowerCase()) >= 0; - } - else - return false; - } - } - ); - - la.DatetimeMinuteControl = ul4._inherit( - la.DateControl, - { - subtype: "datetimeminute", - __type__: "DatetimeMinuteControl", - - formatstring: function formatstring(language) - { - language = language || this.app.language; - - if (language === "de") - return "%d.%m.%Y %H:%M"; - else - return "%m/%d/%Y %H:%M"; - } - } - ); - - la.DatetimeSecondControl = ul4._inherit( - la.DateControl, - { - subtype: "datetimesecond", - __type__: "DatetimeMinuteSecond", - - formatstring: function formatstring(language) - { - language = language || this.app.language; - - if (language === "de") - return "%d.%m.%Y %H:%M:%S"; - else - return "%m/%d/%Y %H:%M:%S"; - } - } - ); - - la.LookupControl = ul4._inherit( - la.Control, - { - type: "lookup", - - ul4onload: function ul4onload(decoder) - { - ul4onattrs = this._ul4onattrs.slice(); - for (var i = 0, iter = decoder.loadcontent(); i < ul4onattrs.length; ++i) - { - var iteritem = iter.next(); - if (iteritem.done) - break; - this._loadUL4ONAttr(ul4onattrs[i], iteritem.value); - if (ul4onattrs[i] === "app") - { - if (this.app.globals.version != "6") - { - ul4onattrs.push("ininsertprocedure"); - ul4onattrs.push("inupdateprocedure"); - } - ul4onattrs.push("lookupdata"); - } - } - for (; i < ul4onattrs.length; ++i) - this._setDefaultUL4ONAttr(ul4onattrs[i]); - }, - - // ``search.value`` must be ``null`` or a ``LookupItem`` key - // if this control is an applookup ``search.value`` must be an object containing the search criteria for the referenced record - search: function search(value, search) - { - if (this.lookupapp === null) - { - if (search.operator === "equals") - { - if (value === null) - return search.value === null; - else - return value.key === search.value; - } - else - return false; - } - else - { - if (value === null || search.value === null) - return value === search.value; - else - return value.search(search); - } - } - } - ); - - la.LookupSelectControl = ul4._inherit( - la.LookupControl, - { - subtype: "select", - __type__: "LookupSelectControl" - } - ); - - la.LookupRadioControl = ul4._inherit( - la.LookupControl, - { - subtype: "radio", - __type__: "LookupRadioControl" - } - ); - - la.LookupChoiceControl = ul4._inherit( - la.LookupControl, - { - subtype: "choice", - __type__: "LookupChoiceControl" - } - ); - - la.AppLookupControl = ul4._inherit( - la.Control, - { - type: "applookup", - - ul4onload: function ul4onload(decoder) - { - ul4onattrs = this._ul4onattrs.slice(); - for (var i = 0, iter = decoder.loadcontent(); i < ul4onattrs.length; ++i) - { - var iteritem = iter.next(); - if (iteritem.done) - break; - this._loadUL4ONAttr(ul4onattrs[i], iteritem.value); - if (ul4onattrs[i] === "app") - { - if (this.app.globals.version != "6") - { - ul4onattrs.push("ininsertprocedure"); - ul4onattrs.push("inupdateprocedure"); - } - ul4onattrs.push("lookupapp"); - ul4onattrs.push("lookupcontrols"); - } - } - for (; i < ul4onattrs.length; ++i) - this._setDefaultUL4ONAttr(ul4onattrs[i]); - }, - - ul4onattrs: function ul4onattrs() - { - var ul4onattrs = la.Control.ul4onattrs.call(this); - return ul4onattrs; - }, - - // ``search.value`` must be an object containing the search criteria for the referenced record - search: function search(value, search) - { - if (value === null || search.value === null) - return value === search.value; - else - return value.search(search); - } - } - ); - - la.AppLookupSelectControl = ul4._inherit( - la.AppLookupControl, - { - subtype: "select", - __type__: "AppLookupSelectControl" - } - ); - - la.AppLookupRadioControl = ul4._inherit( - la.AppLookupControl, - { - subtype: "radio", - __type__: "AppLookupRadioControl" - } - ); - - la.AppLookupChoiceControl = ul4._inherit( - la.AppLookupControl, - { - subtype: "choice", - __type__: "AppLookupChoiceControl" - } - ); - - la.MultipleLookupControl = ul4._inherit( - la.LookupControl, - { - type: "multiplelookup", - - // search.value must be ``null`` or a ``LookupItem`` key - // if this control is an applookup ``search.value`` must be an object containing the search criteria for the referenced record - search: function search(value, search) - { - if (search.operator === "equals") - { - if (this.lookupapp === null) - { - for (var i = 0; i < value.length; ++i) - { - if (value[i].key === search.value) - return true; - } - return false; - } - else - { - if (search.value === null) - return value.length === 0; - else - { - for (var i = 0; i < value.length; ++i) - { - if (value[i].search(search.value)) - return true; - } - return false; - } - } - } - else - return false; - } - } - ); - - la.MultipleLookupSelectControl = ul4._inherit( - la.MultipleLookupControl, - { - subtype: "select", - __type__: "MultipleLookupSelectControl" - } - ); - - la.MultipleLookupCheckboxControl = ul4._inherit( - la.MultipleLookupControl, - { - subtype: "checkbox", - __type__: "MultipleLookupCheckboxControl" - } - ); - - la.MultipleAppLookupControl = ul4._inherit( - la.AppLookupControl, - { - type: "multipleapplookup", - - // ``search.value`` must be an object containing the search criteria for the referenced record - search: function search(value, search) - { - if (search.operator === "equals") - { - if (search.value === null) - return value.length === 0; - else - { - for (var i = 0; i < value.length; ++i) - { - if (value[i].search(search.value)) - return true; - } - return false; - } - } - else - return false; - } - } - ); - - la.MultipleAppLookupSelectControl = ul4._inherit( - la.MultipleAppLookupControl, - { - subtype: "select", - __type__: "MultipleAppLookupSelectControl" - } - ); - - la.MultipleAppLookupCheckboxControl = ul4._inherit( - la.MultipleAppLookupControl, - { - subtype: "checkbox", - __type__: "MultipleAppLookupCheckboxControl" - } - ); - - la.GeoControl = ul4._inherit( - la.Control, - { - type: "geo", + else + return false; + } +}; +la.DateControl.prototype.type = "date"; +la.DateControl.prototype.subtype = "date"; - asjson: function(value) - { - if (la.Geo.isprotoof(value)) - value = `${value.lat}, ${value.long}, ${value.info}`; - return value; - }, +la.DatetimeMinuteControl = class DatetimeMinuteControl extends la.DateControl +{ + formatstring(language) + { + language = language || this.app.language; - __type__: "GeoControl" - } - ); - - la.FileControl = ul4._inherit( - la.Control, - { - type: "file", - __type__: "FileControl" - } - ); - - la.ButtonControl = ul4._inherit( - la.Control, - { - type: "button", - __type__: "ButtonControl" - } - ); - - la.Field = ul4._inherit( - la.Base, - { - create: function create(control, record, value) - { - var field = la.Base.create.call(this); - field.control = control; - field.record = record; - field.value = value; - return field; - }, - - search: function search(searchvalue) - { - return this.control.search(this.value, searchvalue); - }, - - __repr__: function repr() - { - return ""; - } - } - ); - - la.LookupItem = ul4._inherit( - la.Base, - { - _ul4onattrs: ["key", "label"], - - __repr__: function repr() - { - return ""; - } - } - ); - - la.User = ul4._inherit( - la.Base, - { - _ul4onattrs: ["_id", "id", "gender", "firstname", "surname", "initials", "email", "language", "avatarsmall", "avatarlarge", "keyviews"], - - __repr__: function repr() - { - return ""; - } - } - ); - - la.File = ul4._inherit( - la.Base, - { - _ul4onattrs: ["id", "url", "filename", "mimetype", "width", "height"], - - __repr__: function repr() - { - return ""; - } - } - ); - - la.Geo = ul4._inherit( - la.Base, - { - _ul4onattrs: ["lat", "long", "info"], - - __repr__: function repr() - { - return ""; - } - } - ); - - la.Attachment = ul4._inherit( - la.Base, - { - _ul4onattrs: ["id", "record", "label", "active"], - - __repr__: function repr() - { - return ""; - } - } - ); - - la.NoteAttachment = ul4._inherit( - la.Attachment, - { - type: "noteattachment", - __type__: "NoteAttachment", - _ul4onattrs: la.Attachment._ul4onattrs.concat(["value"]) - } - ); - - la.URLAttachment = ul4._inherit( - la.Attachment, - { - type: "urlattachment", - __type__: "URLAttachment", - _ul4onattrs: la.Attachment._ul4onattrs.concat(["value"]) - } - ); - - la.FileAttachment = ul4._inherit( - la.Attachment, - { - type: "fileattachment", - __type__: "FileAttachment", - _ul4onattrs: la.Attachment._ul4onattrs.concat(["value"]) - } - ); - - la.ImageAttachment = ul4._inherit( - la.Attachment, - { - type: "imageattachment", - __type__: "ImageAttachment", - _ul4onattrs: la.Attachment._ul4onattrs.concat(["original", "thumb", "small", "medium", "large"]) - } - ); - - la.JSONAttachment = ul4._inherit( - la.Attachment, + if (language === "de") + return "%d.%m.%Y %H:%M"; + else + return "%m/%d/%Y %H:%M"; + } +}; + +la.DatetimeMinuteControl.prototype.subtype = "datetimeminute"; + +la.DatetimeSecondControl = class DatetimeSecondControl extends la.DateControl +{ + formatstring(language) + { + language = language || this.app.language; + + if (language === "de") + return "%d.%m.%Y %H:%M:%S"; + else + return "%m/%d/%Y %H:%M:%S"; + } +}; + +la.DatetimeSecondControl.prototype.subtype = "datetimesecond"; + +la.LookupControl = class LookupControl extends la.Control +{ + // ``search.value`` must be ``null`` or a ``LookupItem`` key + search(value, search) + { + if (search.operator === "equals") { - type: "jsonattachment", - __type__: "JSONAttachment", - _ul4onattrs: la.Attachment._ul4onattrs.concat(["value"]), - _dumpUL4ONAttr: function _dumpUL4ONAttr(name) - { - if (name === "value") - return ul4._asjson(this.value); - else - return this[name]; - }, - - _loadUL4ONAttr: function _loadUL4ONAttr(name, value) - { - if (name === "value") - this.value = ul4._fromjson(value); - else - this[name] = value - } + if (value === null) + return search.value === null; + else + return value.key === search.value; } - ); - - la.Installation = ul4._inherit( - la.Base, + else + return false; + } +}; + +la.LookupControl.prototype.type = "lookup"; +la.LookupControl.prototype._ul4onattrs = la.Control.prototype._ul4onattrs.concat(["lookupdata"]); +la.LookupControl.prototype._ul4attrs = ul4._makeset(...la.Control.prototype._ul4attrs, "lookupdata"); + +la.LookupSelectControl = class LookupSelectControl extends la.LookupControl +{ +}; + +la.LookupSelectControl.prototype.subtype = "select"; + +la.LookupRadioControl = class LookupRadioControl extends la.LookupControl +{ +}; + +la.LookupRadioControl.prototype.subtype = "radio"; + +la.LookupChoiceControl = class LookupChoiceControl extends la.LookupControl +{ +}; + +la.LookupChoiceControl.prototype.subtype = "choice"; + +la.AppLookupControl = class AppLookupControl extends la.Control +{ + // ``search.value`` must be an object containing the search criteria for the referenced record + search(value, search) + { + if (value === null || search.value === null) + return value === search.value; + else + return value.search(search); + } +}; + +la.AppLookupControl.prototype.type = "applookup"; +la.AppLookupControl.prototype._ul4onattrs = la.Control.prototype._ul4onattrs.concat(["lookupapp", "lookupcontrols"]); +la.AppLookupControl.prototype._ul4attrs = ul4._makeset(...la.Control.prototype._ul4attrs, "lookupapp", "lookupcontrols"); + +la.AppLookupSelectControl = class AppLookupSelectControl extends la.AppLookupControl +{ +}; + +la.AppLookupSelectControl.prototype.subtype = "select"; + +la.AppLookupRadioControl = class AppLookupRadioControl extends la.AppLookupControl +{ +}; + +la.AppLookupRadioControl.prototype.subtype = "radio"; + +la.AppLookupChoiceControl = class AppLookupChoiceControl extends la.AppLookupControl +{ +}; + +la.AppLookupChoiceControl.prototype.subtype = "choice"; + +la.MultipleLookupControl = class MultipleLookupControl extends la.LookupControl +{ + // search.value must be ``null`` or a ``LookupItem`` key + search(value, search) + { + if (search.operator === "equals") { - _ul4onattrs: ["id", "name"], - - __repr__: function repr() + for (let item of value) { - return ""; + if (item.key === search.value) + return true; } + return false; } - ); - - la.Category = ul4._inherit( - la.Base, + else + return false; + } +}; + +la.MultipleLookupControl.prototype.subtype = "multiplelookup"; + +la.MultipleLookupSelectControl = class MultipleLookupSelectControl extends la.MultipleLookupControl +{ +}; + +la.MultipleLookupSelectControl.prototype.subtype = "select"; + +la.MultipleLookupCheckboxControl = class MultipleLookupCheckboxControl extends la.MultipleLookupControl +{ +}; + +la.MultipleLookupCheckboxControl.prototype.subtype = "checkbox"; + +la.MultipleLookupChoiceControl = class MultipleLookupChoiceControl extends la.MultipleLookupControl +{ +}; + +la.MultipleLookupChoiceControl.prototype.subtype = "choice"; + +la.MultipleAppLookupControl = class MultipleAppLookupControl extends la.AppLookupControl +{ + // ``search.value`` must be an object containing the search criteria for the referenced record + search(value, search) + { + if (search.operator === "equals") { - _ul4onattrs: ["id", "identifier", "name", "order", "parent", "children", "apps"], - - __repr__: function repr() + if (search.value === null) + return value.length === 0; + else { - var v = []; - var category = this; - while (category !== null) + for (let item of value) { - v.splice(0, 0, category.identifier); - category = category.parent; + if (item.search(search.value)) + return true; } - return ""; + return false; } } - ); - - la.KeyView = ul4._inherit( - la.Base, + else + return false; + } +}; + +la.MultipleAppLookupControl.prototype.type = "multipleapplookup"; + +la.MultipleAppLookupSelectControl = class MultipleAppLookupSelectControl extends la.MultipleAppLookupControl +{ +}; + +la.MultipleAppLookupSelectControl.prototype.subtype = "select"; + +la.MultipleAppLookupCheckboxControl = class MultipleAppLookupCheckboxControl extends la.MultipleAppLookupControl +{ +}; + +la.MultipleAppLookupCheckboxControl.prototype.subtype = "checkbox"; + +la.MultipleAppLookupChoiceControl = class MultipleAppLookupChoiceControl extends la.MultipleAppLookupControl +{ +}; + +la.MultipleAppLookupChoiceControl.prototype.subtype = "choice"; + +la.GeoControl = class GeoControl extends la.Control +{ + asjson (value) { + if (value instanceof la.Geo) + value = `${value.lat}, ${value.long}, ${value.info}`; + return value; + } +}; + +la.GeoControl.prototype.type = "geo"; + +la.FileControl = class FileControl extends la.Control +{ +}; + +la.FileControl.prototype.type = "file"; + +la.ButtonControl = class ButtonControl extends la.Control +{ +}; + +la.ButtonControl.prototype.type = "button"; + +la.Field = class Field extends la.Base +{ + constructor(control, record, value) + { + super(); + this.control = control; + this.record = record; + this._value = value; + this._dirty = false; + this.errors = []; + } + + get value() + { + return this._value; + } + + set value(value) + { + let oldvalue = this._value; + + if (ul4._ne(oldvalue, value)) { - _ul4onattrs: ["id", "identifier", "name", "key", "user"], - - __repr__: function repr() - { - return ""; - } + this.record.values.set(this.control.identifier, value); + this._value = value; + this._dirty = true; } - ); - - la.AppParameter = ul4._inherit( - la.Base, + } + + is_empty() + { + return this._value === null || (ul4._islist(this._value) && this._value.length === 0); + } + + is_dirty() + { + return this._dirty; + } + + has_errors() + { + return this.errors.length !== 0; + } + + search(searchvalue) + { + return this.control.search(this.value, searchvalue); + } + + __repr__() + { + let s = ""; + } +}; + +la.LookupItem.prototype._ul4onattrs = ["key", "label"]; +la.LookupItem.prototype._ul4attrs = ul4._makeset("key", "label"); + +la.User = class User extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.User.prototype._ul4onattrs = ["_id", "id", "gender", "firstname", "surname", "initials", "email", "language", "avatarsmall", "avatarlarge", "keyviews"]; +la.User.prototype._ul4attrs = ul4._makeset("_id", "id", "gender", "firstname", "surname", "initials", "email", "language", "avatarsmall", "avatarlarge", "keyviews"); + +la.File = class File extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.File.prototype._ul4onattrs = ["id", "url", "filename", "mimetype", "width", "height", "internalid", "createdat", "size"]; +la.File.prototype._ul4attrs = ul4._makeset("id", "url", "filename", "mimetype", "width", "height", "size", "createdat"); + +la.Geo = class Geo extends la.Base +{ + constructor(lat, long, info) + { + super(); + this.lat = lat; + this.long = long; + this.info = info; + } + + __repr__() + { + return ""; + } +}; + +la.Geo.prototype._ul4onattrs = ["lat", "long", "info"]; +la.Geo.prototype._ul4attrs = ul4._makeset("lat", "long", "info"); + +la.Attachment = class Attachment extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.Attachment.prototype._ul4onattrs = ["id", "record", "label", "active"]; +la.Attachment.prototype._ul4attrs = ul4._makeset("id", "record", "label", "active"); + +la.NoteAttachment = class NoteAttachment extends la.Attachment +{ +}; + +la.NoteAttachment.prototype.type = "noteattachment"; +la.NoteAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat(["value"]); +la.NoteAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, "value"); + +la.URLAttachment = class URLAttachment extends la.Attachment +{ +}; + +la.URLAttachment.prototype.type = "urlattachment"; +la.URLAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat(["value"]); +la.URLAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, "value"); + +la.FileAttachment = class FileAttachment extends la.Attachment +{ +}; + +la.FileAttachment.prototype.type = "fileattachment"; +la.FileAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat(["value"]); +la.FileAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, "value"); + +la.ImageAttachment = class ImageAttachment extends la.Attachment +{ +}; + +la.ImageAttachment.prototype.type = "imageattachment"; +la.ImageAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat(["original", "thumb", "small", "medium", "large"]); +la.ImageAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, "original", "thumb", "small", "medium", "large"); + +la.JSONAttachment = class JSONAttachment extends la.Attachment +{ + _dumpUL4ONAttr(name) + { + if (name === "value") + return ul4._asjson(this.value); + else + return this[name]; + } + + _loadUL4ONAttr(name, value) + { + if (name === "value") + this.value = ul4._fromjson(value); + else + this[name] = value + } +}; + +la.JSONAttachment.prototype.type = "jsonattachment"; +la.JSONAttachment.prototype._ul4onattrs = la.Attachment.prototype._ul4onattrs.concat(["value"]); +la.JSONAttachment.prototype._ul4attrs = ul4._makeset(...la.Attachment.prototype._ul4onattrs, "value"); + +la.Installation = class Installation extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.Installation.prototype._ul4onattrs = ["id", "name"]; +la.Installation.prototype._ul4attrs = ul4._makeset("id", "name"); + +la.Category = class Category extends la.Base +{ + __repr__() + { + let v = []; + let category = this; + while (category !== null) { - _ul4onattrs: ["id", "app", "identifier", "description", "value"], - - __repr__: function repr() - { - return ""; - } + v.splice(0, 0, category.identifier); + category = category.parent; } - ); - - var classes = [ - "Globals", - "App", - "View", - "DataSource", - "Record", - "BoolControl", - "IntControl", - "NumberControl", - "TextControl", - "EmailControl", - "URLControl", - "TelControl", - "PasswordControl", - "TextAreaControl", - "DateControl", - "DatetimeMinuteControl", - "DatetimeSecondControl", - "LookupControl", - "LookupSelectControl", - "LookupRadioControl", - "LookupChoiceControl", - "AppLookupControl", - "AppLookupSelectControl", - "AppLookupRadioControl", - "AppLookupChoiceControl", - "MultipleLookupControl", - "MultipleLookupSelectControl", - "MultipleLookupCheckboxControl", - "MultipleAppLookupControl", - "MultipleAppLookupSelectControl", - "MultipleAppLookupCheckboxControl", - "GeoControl", - "FileControl", - "ButtonControl", - "Field", - "LookupItem", - "User", - "File", - "Geo", - "NoteAttachment", - "URLAttachment", - "FileAttachment", - "ImageAttachment", - "JSONAttachment", - "Installation", - "Category", - "KeyView", - "AppParameter" - ]; - - for (var i = 0; i < classes.length; ++i) + return ""; + } +}; + +la.Category.prototype._ul4onattrs = ["id", "identifier", "name", "order", "parent", "children", "apps"]; +la.Category.prototype._ul4attrs = ul4._makeset("id", "identifier", "name", "order", "parent", "children", "apps"); + +la.KeyView = class KeyView extends la.Base +{ + __repr__() { - var name = classes[i]; - var object = la[name]; - ul4on.register("de.livingapps.appdd." + name.toLowerCase(), object); + return ""; } - - })(this); \ No newline at end of file +}; + +la.KeyView.prototype._ul4onattrs = ["id", "identifier", "name", "key", "user"]; +la.KeyView.prototype._ul4attrs = ul4._makeset("id", "identifier", "name", "key", "user"); + +la.AppParameter = class AppParameter extends la.Base +{ + __repr__() + { + return ""; + } +}; + +la.AppParameter.prototype._ul4onattrs = ["id", "app", "identifier", "description", "value"]; +la.AppParameter.prototype._ul4attrs = ul4._makeset("id", "app", "identifier", "description", "value"); + +let classes = [ + la.Globals, + la.App, + la.View, + la.DataSourceData, + la.Record, + la.BoolControl, + la.IntControl, + la.NumberControl, + la.TextControl, + la.EmailControl, + la.URLControl, + la.TelControl, + la.PasswordControl, + la.TextAreaControl, + la.DateControl, + la.DatetimeMinuteControl, + la.DatetimeSecondControl, + la.LookupControl, + la.LookupSelectControl, + la.LookupRadioControl, + la.LookupChoiceControl, + la.AppLookupControl, + la.AppLookupSelectControl, + la.AppLookupRadioControl, + la.AppLookupChoiceControl, + la.MultipleLookupControl, + la.MultipleLookupSelectControl, + la.MultipleLookupCheckboxControl, + la.MultipleLookupChoiceControl, + la.MultipleAppLookupControl, + la.MultipleAppLookupSelectControl, + la.MultipleAppLookupCheckboxControl, + la.MultipleAppLookupChoiceControl, + la.GeoControl, + la.FileControl, + la.ButtonControl, + la.Field, + la.LookupItem, + la.User, + la.File, + la.Geo, + la.NoteAttachment, + la.URLAttachment, + la.FileAttachment, + la.ImageAttachment, + la.JSONAttachment, + la.Installation, + la.Category, + la.KeyView, + la.AppParameter +]; + +for (let constructor of classes) +{ + // Register under the old name + ul4.register("de.livingapps.appdd." + constructor.name.toLowerCase(), constructor); + // Register under the new name + ul4.register("de.livinglogic.livingapi." + constructor.name.toLowerCase(), constructor); +} +export default la; \ No newline at end of file diff --git a/src/modules/ul4.js b/src/modules/ul4.js index f2ac8e2..d8c3be2 100644 --- a/src/modules/ul4.js +++ b/src/modules/ul4.js @@ -3,8 +3,8 @@ * http://www.livinglogic.de/Python/ul4c/ * http://www.livinglogic.de/Python/ul4on/ * - * Copyright 2011-2017 by LivingLogic AG, Bayreuth/Germany - * Copyright 2011-2017 by Walter Dörwald + * Copyright 2011-2018 by LivingLogic AG, Bayreuth/Germany + * Copyright 2011-2018 by Walter Dörwald * * All Rights Reserved * @@ -28,8778 +28,9583 @@ */ /*jslint vars: true */ +export let ul4 = {}; -(function(undefined){ - - let amd = (typeof define === 'function' && define.amd); - let commonjs = (typeof module === 'object' && module.exports); - - var root = this, ul4 = {}, ul4on = {}; - - root.ul4 = ul4; - - root.ul4on = ul4on; - - - if (commonjs) { - module.exports.ul4 = ul4; - module.exports.ul4on = ul4on; - } else { - ul4 = root.ul4; - ul4on = root.ul4on; - root.livingapi = la; +let iscommon = (typeof module === 'object' && module.exports); + + ul4.version = "46"; + + // + // UL4ON + // + + ul4._registry = {}; + + ul4._havemap = (typeof(Map) === "function" && typeof(Map.prototype.forEach) === "function"); + + ul4._havemapconstructor = (function () + { + if (ul4._havemap) + { + try + { + if (new Map([[1, 2]]).size == 1) + return true; + } + catch (error) + { + } + } + return false; + })(); + + ul4._haveset = (typeof(Set) === "function" && typeof(Set.prototype.forEach) === "function"); + + ul4._havesetconstructor = (function () + { + if (ul4._haveset) + { + try + { + if (new Set([1, 2]).size == 2) + return true; + } + catch (error) + { + } + return false; + } + else + return false; + })(); + + // helper functions that work with Maps and objects + if (ul4._havemap) + { + ul4._makemap = function _makemap(...items) + { + let map = new Map(); + + for (let i = 0; i < items.length; ++i) + { + let [key, value] = items[i]; + map.set(key, value); + } + return map; + }; + + ul4._setmap = function _setmap(map, key, value) + { + if (map.__proto__ === Map.prototype) + map.set(key, value); + else + map[key] = value; + }; + + ul4._emptymap = function _emptymap() + { + return new Map(); + }; + + ul4._getmap = function _getmap(map, key, value) + { + if (map.__proto__ === Map.prototype) + return map.get(key); + else + return map[key]; + }; + } + else + { + ul4._makemap = function _makemap(...items) + { + let map = {}; + + for (let i = 0; i < items.length; ++i) + { + let [key, value] = items[i]; + map[key] = value; + } + return map; + }; + + ul4._setmap = function _setmap(map, key, value) + { + map[key] = value; + }; + + ul4._emptymap = function _emptymap() + { + return {}; + }; + + ul4._getmap = function _getmap(map, key, value) + { + return map[key]; + }; + } + + // Function used for making sets, when the Set constructor doesn't work (or we don't have sets) + if (ul4._haveset) + { + ul4._emptyset = function _emptyset() + { + return new Set(); + }; + } + else + { + ul4._emptyset = function _emptyset() + { + return new ul4._Set(); + }; + } + + ul4._makeset = function _makeset(...items) + { + let set = ul4._emptyset(); + + for (let i = 0; i < items.length; ++i) + set.add(items[i]); + return set; + }; + + // Register the constructor function ``f`` under the name ``name`` with the UL4ON machinery + ul4.register = function register(name, f) + { + f.prototype.ul4onname = name; + ul4._registry[name] = f; + }; + + // Return a string that contains the object ``obj`` in the UL4ON serialization format + ul4.dumps = function dumps(obj, indent) + { + let encoder = new ul4.Encoder(indent); + encoder.dump(obj); + return encoder.finish(); + }; + + // Load an object from the string ``data``. + // ``data`` must contain the object in the UL4ON serialization format + // ``registry`` may be null or a dictionary mapping type names to constructor functions + ul4.loads = function loads(data, registry) + { + let decoder = new ul4.Decoder(data, registry); + return decoder.load(); + }; + + // Helper class for encoding + ul4.Encoder = class Encoder + { + // Create a new Encoder object + constructor(indent=null) + { + this.indent = indent; + this.data = []; + this._level = 0; + this._strings2index = {}; + this._ids2index = {}; + this._backrefs = 0; + } + + _line(line, ...args) + { + if (this.indent !== null) + { + for (let i = 0; i < this._level; ++i) + this.data.push(this.indent); + } + else + { + if (this.data.length) + this.data.push(" "); + } + this.data.push(line); + + if (args.length) + { + let oldindent = this.indent; + this.indent = null; + for (let i = 0; i < args.length; ++i) + this.dump(args[i]); + this.indent = oldindent; + } + + if (this.indent !== null) + this.data.push("\n"); + } + + // Return the complete string written to the buffer + finish() + { + return this.data.join(""); + } + + dump(obj) + { + if (obj === null) + this._line("n"); + else if (typeof(obj) == "boolean") + this._line(obj ? "bT" : "bF"); + else if (typeof(obj) == "number") + { + let type = (Math.round(obj) == obj) ? "i" : "f"; + this._line(type + obj); + } + else if (typeof(obj) == "string") + { + let index = this._strings2index[obj]; + if (typeof(index) !== "undefined") + { + this._line("^" + index); + } + else + { + this._strings2index[obj] = this._backrefs++; + let dump = ul4._str_repr(obj).replace("<", "\\x3c"); + this._line("S" + dump); + } + } + else if (ul4._iscolor(obj)) + this._line("c", obj.r(), obj.g(), obj.b(), obj.a()); + else if (ul4._isdate(obj)) + this._line("x", obj.year(), obj.month(), obj.day()); + else if (ul4._isdatetime(obj)) + this._line("z", obj.getFullYear(), obj.getMonth()+1, obj.getDate(), obj.getHours(), obj.getMinutes(), obj.getSeconds(), obj.getMilliseconds() * 1000); + else if (ul4._istimedelta(obj)) + this._line("t", obj.days(), obj.seconds(), obj.microseconds()); + else if (ul4._ismonthdelta(obj)) + this._line("m", obj.months()); + else if (obj instanceof ul4.slice) + this._line("r", obj.start, obj.stop); + else if (obj.ul4onname && obj.ul4ondump) + { + if (obj.__id__) + { + let index = this._ids2index[obj.__id__]; + if (typeof(index) != "undefined") + { + this._line("^" + index); + return; + } + this._ids2index[obj.__id__] = this._backrefs++; + } + this._line("O", obj.ul4onname); + ++this._level; + obj.ul4ondump(this); + --this._level; + this._line(")"); + } + else if (ul4._islist(obj)) + { + this._line("l"); + ++this._level; + for (let i = 0; i < obj.length; ++i) + this.dump(obj[i]); + --this._level; + this._line("]"); + } + else if (ul4._ismap(obj)) + { + this._line("e"); + ++this._level; + obj.forEach(function(value, key) { + this.dump(key); + this.dump(value); + }, this); + --this._level; + this._line("}"); + } + else if (ul4._isdict(obj)) + { + this._line("d"); + ++this._level; + for (let key in obj) + { + this.dump(key); + this.dump(obj[key]); + } + --this._level; + this._line("}"); + } + else if (ul4._isset(obj)) + { + this._line("y"); + ++this._level; + obj.forEach(function(value) { + this.dump(value); + }, this); + --this._level; + this._line("}"); + } + else + throw new ul4.ValueError("can't create UL4ON dump of object " + ul4._repr(obj)); + } + }; + + // Helper class for decoding + ul4.Decoder = class Decoder + { + // Creates a new decoder for reading from the string ``data`` + constructor(data, registry) + { + this.data = data; + this.pos = 0; + this.backrefs = []; + this.registry = typeof(registry) === "undefined" ? null : registry; + this.stack = []; // Use for informative error messages + } + + // Read a character from the buffer + readchar() + { + if (this.pos >= this.data.length) + throw new ul4.ValueError("UL4 decoder at EOF"); + return this.data.charAt(this.pos++); + } + + // Read a character from the buffer (return null on eof) + readcharoreof() + { + if (this.pos >= this.data.length) + return null; + return this.data.charAt(this.pos++); + } + + // Read next not-whitespace character from the buffer + readblackchar() + { + let re_white = /\s/; + + for (;;) + { + if (this.pos >= this.data.length) + throw new ul4.ValueError("UL4 decoder at EOF at position " + this.pos + " with path " + this.stack.join("/")); + let c = this.data.charAt(this.pos++); + if (!c.match(re_white)) + return c; + } + } + + // Read ``size`` characters from the buffer + read(size) + { + if (this.pos+size > this.length) + size = this.length-this.pos; + let result = this.data.substring(this.pos, this.pos+size); + this.pos += size; + return result; + } + + // "unread" one character + backup() + { + --this.pos; + } + + // Read a number from the buffer + readnumber() + { + let re_digits = /[-+0123456789.eE]/, value = ""; + for (;;) + { + let c = this.readcharoreof(); + if (c !== null && c.match(re_digits)) + value += c; + else + { + let result = parseFloat(value); + if (isNaN(result)) + throw new ul4.ValueError("invalid number, got " + ul4._repr("value") + " at position " + this.pos + " with path " + this.stack.join("/")); + return result; + } + } + } + + _beginfakeloading() + { + let oldpos = this.backrefs.length; + this.backrefs.push(null); + return oldpos; + } + + _endfakeloading(oldpos, value) + { + this.backrefs[oldpos] = value; + } + + _readescape(escapechar, length) + { + let chars = this.read(length); + if (chars.length != length) + throw new ul4.ValueError("broken escape " + ul4._repr("\\" + escapechar + chars) + " at position " + this.pos + " with path " + this.stack.join("/")); + let codepoint = parseInt(chars, 16); + if (isNaN(codepoint)) + throw new ul4.ValueError("broken escape " + ul4._repr("\\" + escapechar + chars) + " at position " + this.pos + " with path " + this.stack.join("/")); + return String.fromCharCode(codepoint); + } + + // Load the next object from the buffer + load() + { + let typecode = this.readblackchar(); + let result; + switch (typecode) + { + case "^": + return this.backrefs[this.readnumber()]; + case "n": + case "N": + if (typecode === "N") + this.backrefs.push(null); + return null; + case "b": + case "B": + result = this.readchar(); + if (result === "T") + result = true; + else if (result === "F") + result = false; + else + throw new ul4.ValueError("wrong value for boolean, expected 'T' or 'F', got " + ul4._repr(result) + " at position " + this.pos + " with path " + this.stack.join("/")); + if (typecode === "B") + this.backrefs.push(result); + return result; + case "i": + case "I": + case "f": + case "F": + result = this.readnumber(); + if (typecode === "I" || typecode === "F") + this.backrefs.push(result); + return result; + case "s": + case "S": + result = []; + let delimiter = this.readblackchar(); + for (;;) + { + let c = this.readchar(); + if (c == delimiter) + break; + if (c == "\\") + { + let c2 = this.readchar(); + if (c2 == "\\") + result.push("\\"); + else if (c2 == "n") + result.push("\n"); + else if (c2 == "r") + result.push("\r"); + else if (c2 == "t") + result.push("\t"); + else if (c2 == "f") + result.push("\u000c"); + else if (c2 == "b") + result.push("\u0008"); + else if (c2 == "a") + result.push("\u0007"); + else if (c2 == "'") + result.push("'"); + else if (c2 == '"') + result.push('"'); + else if (c2 == "x") + result.push(this._readescape("x", 2)); + else if (c2 == "u") + result.push(this._readescape("u", 4)); + else if (c2 == "U") + result.push(this._readescape("U", 8)); + else + result.push("\\" + c2); + } + else + result.push(c); + } + result = result.join(""); + if (typecode === "S") + this.backrefs.push(result); + return result; + case "c": + case "C": + result = new ul4.Color(); + if (typecode === "C") + this.backrefs.push(result); + result._r = this.load(); + result._g = this.load(); + result._b = this.load(); + result._a = this.load(); + return result; + case "x": + case "X": + { + let year = this.load(); + let month = this.load(); + let day = this.load(); + result = new ul4.Date(year, month, day); + if (typecode === "X") + this.backrefs.push(result); + return result; + } + case "z": + case "Z": + result = new Date(); + result.setFullYear(this.load()); + result.setDate(1); + result.setMonth(this.load() - 1); + result.setDate(this.load()); + result.setHours(this.load()); + result.setMinutes(this.load()); + result.setSeconds(this.load()); + result.setMilliseconds(this.load()/1000); + if (typecode === "Z") + this.backrefs.push(result); + return result; + case "t": + case "T": + result = new ul4.TimeDelta(); + result._days = this.load(); + result._seconds = this.load(); + result._microseconds = this.load(); + if (typecode === "T") + this.backrefs.push(result); + return result; + case "r": + case "R": + result = new ul4.slice(); + if (typecode === "R") + this.backrefs.push(result); + result.start = this.load(); + result.stop = this.load(); + return result; + case "m": + case "M": + result = new ul4.MonthDelta(); + if (typecode === "M") + this.backrefs.push(result); + result._months = this.load(); + return result; + case "l": + case "L": + this.stack.push("list"); + result = []; + if (typecode === "L") + this.backrefs.push(result); + for (;;) + { + typecode = this.readblackchar(); + if (typecode === "]") + break; + this.backup(); + result.push(this.load()); + } + this.stack.pop(); + return result; + case "d": + case "D": + case "e": + case "E": + if (!ul4._havemap && (typecode == "e" || typecode == "E")) + throw new ul4.ValueError("ordered dictionaries are not supported at position " + this.pos + " with path " + this.stack.join("/")); + result = ul4._emptymap(); + this.stack.push(typecode === "d" || typecode === "D" ? "dict" : "odict"); + if (typecode === "D" || typecode === "E") + this.backrefs.push(result); + for (;;) + { + typecode = this.readblackchar(); + if (typecode === "}") + break; + this.backup(); + let key = this.load(); + let value = this.load(); + ul4._setmap(result, key, value); + } + this.stack.pop(); + return result; + case "y": + case "Y": + this.stack.push("set"); + result = ul4._makeset(); + if (typecode === "Y") + this.backrefs.push(result); + for (;;) + { + typecode = this.readblackchar(); + if (typecode === "}") + break; + this.backup(); + result.add(this.load()); + } + this.stack.pop(); + return result; + case "o": + case "O": + { + let oldpos; + if (typecode === "O") + oldpos = this._beginfakeloading(); + let name = this.load(); + this.stack.push(name); + let constructor; + if (this.registry !== null) + { + constructor = this.registry[name]; + if (typeof(constructor) === "undefined") + constructor = ul4._registry[name]; + } + else + constructor = ul4._registry[name]; + if (typeof(constructor) === "undefined") + throw new ul4.ValueError("can't load object of type " + ul4._repr(name) + " at position " + this.pos + " with path " + this.stack.join("/")); + result = new constructor(); + if (typecode === "O") + this._endfakeloading(oldpos, result); + result.ul4onload(this); + typecode = this.readblackchar(); + if (typecode !== ")") + throw new ul4.ValueError("object terminator ')' for object of type '" + name + "' expected, got " + ul4._repr(typecode) + " at position " + this.pos + " with path " + this.stack.join("/")); + this.stack.pop(); + return result; + } + default: + throw new ul4.ValueError("unknown typecode " + ul4._repr(typecode) + " at position " + this.pos + " with path " + this.stack.join("/")); + } + } + + // Return an iterator for loading the content of a object + loadcontent() + { + let self = this; + return { + next: function() + { + let typecode = self.readblackchar(); + // Always "unread" the typecode even at the end + // so that at the end of a call to ul4onload() + // the next input is the "end of object" marker + // no matter whether ul4onload() uses loadcontent() or not. + self.backup(); + if (typecode == ")") + return {done: true}; + else + return {done: false, value: self.load()}; + } + }; + } + }; + + // + // UL4 + // + + // REs for parsing JSON + ul4._rvalidchars = /^[\],:{}\s]*$/; + ul4._rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g; + ul4._rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; + ul4._rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g; + + /// Helper functions + + // Clone an object and extend it + ul4._inherit = function _inherit(baseobj, attrs) + { + return Object.assign(Object.create(baseobj), attrs); + }; + + // Convert a map to an object + ul4._map2object = function _map2object(obj) + { + if (ul4._ismap(obj)) + { + let newobj = {}; + obj.forEach(function(value, key){ + if (typeof(key) !== "string") + throw new ul4.TypeError("keys must be strings"); + newobj[key] = value; + }); + return newobj; + } + return obj; + }; + + // Clip a number to the range [0;max) + ul4._bound = function _bound(value, upper) + { + if (value < 0) + return 0; + else if (value > upper) + return upper; + else + return value; + }; + + // Create a pretty stacktrace from an exception + ul4._stacktrace = function _stacktrace(exc) + { + let output = (exc instanceof ul4.Exception ? exc.constructor.name + ": " : "") + exc.toString(); + if (exc.context) + output = ul4._stacktrace(exc.context) + "\n\n" + output; + return output; + }; + + // Call a function ``f`` with UL4 argument handling + ul4._internal_call = function _internal_call(context, f, name, functioncontext, signature, needscontext, needsobject, args, kwargs) + { + let finalargs; + if (needsobject) + { + if (signature === null) + { + if (args.length) + throw new ul4.ArgumentError(ul4._repr(f) + " doesn't support positional arguments!"); + finalargs = [kwargs]; + } + else + finalargs = [signature.bindObject(name, args, kwargs)]; + } + else + { + if (signature === null) + throw new ul4.ArgumentError(ul4._repr(f) + " doesn't support positional arguments!"); + finalargs = signature.bindArray(name, args, kwargs); + } + if (needscontext) + finalargs.unshift(context); + return f.apply(functioncontext, finalargs); + }; + + ul4._callfunction = function _callfunction(context, f, args, kwargs) + { + let name = f._ul4_name || f.name; + if (typeof(f._ul4_signature) === "undefined" || typeof(f._ul4_needsobject) === "undefined" || typeof(f._ul4_needscontext) === "undefined") + throw new ul4.TypeError(ul4._repr(f) + " is not callable by UL4"); + return ul4._internal_call(context, f, name, ul4, f._ul4_signature, f._ul4_needscontext, f._ul4_needsobject, args, kwargs); + }; + + ul4._callobject = function _callobject(context, obj, args, kwargs) + { + if (typeof(obj._ul4_callsignature) === "undefined" || typeof(obj._ul4_callneedsobject) === "undefined" || typeof(obj._ul4_callneedscontext) === "undefined") + throw new ul4.TypeError(ul4._repr(obj) + " is not callable by UL4"); + return ul4._internal_call(context, obj.__call__, obj.name, obj, obj._ul4_callsignature, obj._ul4_callneedscontext, obj._ul4_callneedsobject, args, kwargs); + }; + + ul4._callrender = function _callrender(context, obj, args, kwargs) + { + if (typeof(obj._ul4_rendersignature) === "undefined" || typeof(obj._ul4_renderneedsobject) === "undefined" || typeof(obj._ul4_renderneedscontext) === "undefined") + throw new ul4.TypeError(ul4._repr(obj) + " is not renderable by UL4"); + return ul4._internal_call(context, obj.__render__, obj.name, obj, obj._ul4_rendersignature, obj._ul4_renderneedscontext, obj._ul4_renderneedsobject, args, kwargs); + }; + + ul4._call = function _call(context, f, args, kwargs) + { + if (typeof(f) === "function") + return ul4._callfunction(context, f, args, kwargs); + else if (f && typeof(f.__call__) === "function") + return ul4._callobject(context, f, args, kwargs); + else + throw new ul4.TypeError(ul4._type(f) + " is not callable"); + }; + + ul4._unpackvar = function _unpackvar(lvalue, value) + { + if (!ul4._islist(lvalue)) + return [[lvalue, value]]; + else + { + let newvalue = []; + let iter = ul4._iter(value); + + for (let i = 0;;++i) + { + let item = iter.next(); + + if (item.done) + { + if (i === lvalue.length) + break; + else + throw new ul4.ValueError("need " + lvalue.length + " value" + (lvalue.length === 1 ? "" : "s") + " to unpack, got " + i); + } + else + { + if (i < lvalue.length) + newvalue = newvalue.concat(ul4._unpackvar(lvalue[i], item.value)); + else + throw new ul4.ValueError("too many values to unpack (expected " + lvalue.length + ")"); + } + } + return newvalue; + } + }; + + ul4._formatsource = function _formatsource(out) + { + let finalout = []; + let level = 0, needlf = false; + for (let i = 0; i < out.length; ++i) + { + let part = out[i]; + if (typeof(part) === "number") + { + level += part; + needlf = true; + } + else + { + if (needlf) + { + finalout.push("\n"); + for (let j = 0; j < level; ++j) + finalout.push("\t"); + needlf = false; + } + finalout.push(part); + } + } + if (needlf) + finalout.push("\n"); + return finalout.join(""); + }; + + // Compare ``obj1`` and ``obj2`` if they have the same value + ul4._eq = function _eq(obj1, obj2) + { + let numbertypes = ["boolean", "number"]; + + if (obj1 && typeof(obj1.__eq__) === "function") + return obj1.__eq__(obj2); + else if (obj2 && typeof(obj2.__eq__) === "function") + return obj2.__eq__(obj1); + else if (obj1 === null) + return obj2 === null; + else if (numbertypes.indexOf(typeof(obj1)) != -1) + { + if (numbertypes.indexOf(typeof(obj2)) != -1) + return obj1 == obj2; + else + return false; + } + else if (typeof(obj1) === "string") + { + if (typeof(obj2) === "string") + return obj1 == obj2; + else + return false; + } + else if (ul4._isdatetime(obj1)) + { + if (ul4._isdatetime(obj2)) + return obj1.getTime() == obj2.getTime(); + else + return false; + } + else if (ul4._islist(obj1)) + { + if (ul4._islist(obj2)) + { + // Shortcut, if it's the same object + if (obj1 === obj2) + return true; + if (obj1.length != obj2.length) + return false; + for (let i = 0; i < obj1.length; ++i) + { + if (!ul4._eq(obj1[i], obj2[i])) // This might lead to infinite recursion and a stackoverflow, but it does in all implementations + return false; + } + return true; + } + else + return false; + } + else if (ul4._isobject(obj1)) + { + if (ul4._isobject(obj2)) + { + // Shortcut, if it's the same object + if (obj1 === obj2) + return true; + // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value + for (let key in obj1) + { + if (obj2.hasOwnProperty(key)) + { + if (!ul4._eq(obj1[key], obj2[key])) + return false; + } + else + return false; + } + // Test that each attribute of ``obj2`` is also in ``obj1`` (the value has been tested before) + for (let key in obj2) + { + if (!obj1.hasOwnProperty(key)) + return false; + } + return true; + } + else if (ul4._ismap(obj2)) + { + // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value + for (let key in obj1) + { + if (obj2.has(key)) + { + if (!ul4._eq(obj1[key], obj2.get(key))) + return false; + } + else + return false; + } + // Test that each attribute of ``obj2`` is also in ``obj1`` (the value has been tested before) + let result = true; + obj2.forEach(function(value, key) { + if (!obj1.hasOwnProperty(key)) + result = false; + }, this); + return result; + } + else + return false; + } + else if (ul4._ismap(obj1)) + { + if (ul4._isobject(obj2)) + { + // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value + obj1.forEach(function(value, key) { + if (!obj2.hasOwnProperty(key)) + return false; + else if (!ul4._eq(obj1.get(key), obj2[key])) + return false; + }, this); + // Test that each attribute of ``obj2`` is also in ``obj1`` (the value has been tested before) + for (let key in obj2) + { + if (!obj1.has(key)) + return false; + } + return true; + } + else if (ul4._ismap(obj2)) + { + // Shortcut, if it's the same object + if (obj1 === obj2) + return true; + if (obj1.size != obj2.size) + return false; + let result = true; + // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value + obj1.forEach(function(value, key) { + if (!obj2.has(key)) + result = false; + else if (!ul4._eq(obj1.get(key), obj2.get(key))) + result = false; + }); + return result; + } + else + return false; + } + else if (ul4._isset(obj1)) + { + // We don't have to test for ``ul4._Set`` as ``ul4._Set`` implements ``__eq__`` + if (ul4._isset(obj2)) + { + // Shortcut, if it's the same object + if (obj1 === obj2) + return true; + if (obj1.size != obj2.size) + return false; + let result = true; + obj1.forEach(function(value) { + if (!obj2.has(value)) + result = false; + }); + return result; + } + else + return false; + } + else + return obj1 === obj2; + }; + + // Compare ``obj1`` and ``obj2`` if they don't have the same value + ul4._ne = function _ne(obj1, obj2) + { + if (obj1 && typeof(obj1.__ne__) === "function") + return obj1.__ne__(obj2); + else if (obj2 && typeof(obj2.__ne__) === "function") + return obj2.__ne__(obj1); + else + return !ul4._eq(obj1, obj2); + }; + + ul4._unorderable = function _unorderable(operator, obj1, obj2) + { + throw new ul4.TypeError("unorderable types: " + ul4._type(obj1) + " " + operator + " " + ul4._type(obj2)); + }; + + // Return: + // -1 when ``obj1 < obj2``, + // 0 when ``obj1 == obj2``, + // 1 when ``obj1 > obj2``, + // null when ``obj1`` and ``obj2`` are comparable, but neither of the previous cases holds (only for sets) + // raise TypeError if objects are uncomparable + // This the purpose of ``_cmp`` is to support implementation of <, <=, > and >= + // and dicts/maps are not comparable with the operator ``_cmp`` does not support dicts/maps + + ul4._cmp = function _cmp(operator, obj1, obj2) + { + let numbertypes = ["boolean", "number"]; + + if (numbertypes.indexOf(typeof(obj1)) != -1) + { + if (numbertypes.indexOf(typeof(obj2)) != -1) + return (obj1 > obj2) - (obj1 < obj2); + } + else if (typeof(obj1) === "string") + { + if (typeof(obj2) === "string") + return (obj1 > obj2) - (obj1 < obj2); + } + else if (ul4._isdatetime(obj1)) + { + if (ul4._isdatetime(obj2)) + { + let v1 = obj1.getTime(), v2 = obj2.getTime(); + return (v1 > v2) - (v1 < v2); + } + } + else if (ul4._islist(obj1)) + { + if (ul4._islist(obj2)) + { + if (obj1 === obj2) + return 0; + for (let i = 0; i < obj1.length; ++i) + { + if (i >= obj2.length) + return 1; + let res = ul4._cmp(operator, obj1[i], obj2[i]); + if (res) + return res; + } + return obj2.length > obj1.length ? -1 : 0; + } + } + else if (ul4._isset(obj1) || ul4._isul4set(obj1)) + { + if (ul4._isset(obj2) || ul4._isul4set(obj2)) + { + let in1only = false; + let in2only = false; + + for (let iter = _iter(obj1);;) + { + let item = iter.next(); + if (item.done) + break; + if (!obj2.has(item.value)) + { + in1only = true; + break; + } + } + for (let iter = _iter(obj2);;) + { + let item = iter.next(); + if (item.done) + break; + if (!obj1.has(item.value)) + { + in2only = true; + break; + } + } + + if (in1only) + { + if (in2only) + return null; + else + return 1; + } + else + { + if (in2only) + return -1; + else + return 0; + } + } + } + return ul4._unorderable(operator, obj1, obj2); + }; + + // Return whether ``obj1 < obj2`` + ul4._lt = function _lt(obj1, obj2) + { + let numbertypes = ["boolean", "number"]; + + if (obj1 && typeof(obj1.__lt__) === "function") + return obj1.__lt__(obj2); + else if (numbertypes.indexOf(typeof(obj1)) != -1) + { + if (numbertypes.indexOf(typeof(obj2)) != -1) + return obj1 < obj2; + } + else if (typeof(obj1) === "string") + { + if (typeof(obj2) === "string") + return obj1 < obj2; + } + else if (ul4._isdatetime(obj1)) + { + if (ul4._isdatetime(obj2)) + return obj1.getTime() < obj2.getTime(); + } + else if (ul4._islist(obj1)) + { + if (ul4._islist(obj2)) + { + if (obj1 === obj2) + return false; + for (let i = 0; i < obj1.length; ++i) + { + if (i >= obj2.length) + return false; + let eq = ul4._eq(obj1[i], obj2[i]); + if (!eq) + return ul4._lt(obj1[i], obj2[i]); + } + return obj1.length < obj2.length; + } + } + // FIXME: Set comparison + else if (ul4._isset(obj1)) + { + if (ul4._isset(obj2)) + { + if (ul4._isset(obj2)) + { + for (let key in obj1) + { + if (!obj2.has(obj1[key])) + in1only = true; + } + for (let key in obj2) + { + if (!obj1.has(obj2[key])) + in2only = true; + } + } + else if (ul4._isul4set(obj2)) + { + for (let key in obj1) + { + if (!obj2.items[obj1[key]]) + in1only = true; + } + for (let value in obj2.items) + { + if (!obj1.has(value)) + { + in2only = true; + break; + } + } + } + } + else if (ul4._isul4set(obj2)) + { + if (ul4._isset(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.has(value)) + { + in1only = true; + break; + } + } + for (let key in obj2) + { + if (!obj1.items[obj2[key]]) + in2only = true; + } + } + else if (ul4._isul4set(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.items[value]) + { + in1only = true; + break; + } + } + for (let value in obj2.items) + { + if (!obj1.items[value]) + { + in2only = true; + break; + } + } + } + } + else + ul4._unorderable(operator, obj1, obj2); + + if (in1only) + { + if (in2only) + return null; + else + return 1; + } + else + { + if (in2only) + return -1; + else + return 0; + } + } + ul4._unorderable("<", obj1, obj2); + }; + + // Return whether ``obj1 <= obj2`` + ul4._le = function _le(obj1, obj2) + { + let numbertypes = ["boolean", "number"]; + + if (obj1 && typeof(obj1.__le__) === "function") + return obj1.__le__(obj2); + if (numbertypes.indexOf(typeof(obj1)) != -1) + { + if (numbertypes.indexOf(typeof(obj2)) != -1) + return obj1 <= obj2; + } + else if (typeof(obj1) === "string") + { + if (typeof(obj2) === "string") + return obj1 <= obj2; + } + else if (ul4._isdatetime(obj1)) + { + if (ul4._isdatetime(obj2)) + return obj1.getTime() <= obj2.getTime(); + } + else if (ul4._islist(obj1)) + { + if (ul4._islist(obj2)) + { + if (obj1 === obj2) + return true; + for (let i = 0; i < obj1.length; ++i) + { + if (i >= obj2.length) + return false; + let eq = ul4._eq(obj1[i], obj2[i]); + if (!eq) + return ul4._lt(obj1[i], obj2[i]); + } + return obj1.length <= obj2.length; + } + } + // FIXME: Set comparison + else if (ul4._isset(obj1) || ul4._isul4set(obj1)) + { + let in1only = false; + let in2only = false; + + if (ul4._isset(obj2)) + { + if (ul4._isset(obj2)) + { + obj1.forEach(function(value) { + if (!obj2.has(value)) + in1only = true; + }); + obj2.forEach(function(value) { + if (!obj1.has(value)) + in2only = true; + }); + } + else if (ul4._isul4set(obj2)) + { + obj1.forEach(function(value) { + if (!obj2.items[value]) + in1only = true; + }); + for (let value in obj2.items) + { + if (!obj1.has(value)) + { + in2only = true; + break; + } + } + } + } + else if (ul4._isul4set(obj2)) + { + if (ul4._isset(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.has(value)) + { + in1only = true; + break; + } + } + obj2.forEach(function(value) { + if (!obj1.items[value]) + in2only = true; + }); + } + else if (ul4._isul4set(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.items[value]) + { + in1only = true; + break; + } + } + for (let value in obj2.items) + { + if (!obj1.items[value]) + { + in2only = true; + break; + } + } + } + } + else + ul4._unorderable(operator, obj1, obj2); + + if (in1only) + { + if (in2only) + return null; + else + return 1; + } + else + { + if (in2only) + return -1; + else + return 0; + } + } + ul4._unorderable("<=", obj1, obj2); + }; + + // Return whether ``obj1 > obj2`` + ul4._gt = function _gt(obj1, obj2) + { + let numbertypes = ["boolean", "number"]; + + if (obj1 && typeof(obj1.__gt__) === "function") + return obj1.__gt__(obj2); + if (numbertypes.indexOf(typeof(obj1)) != -1) + { + if (numbertypes.indexOf(typeof(obj2)) != -1) + return obj1 > obj2; + } + else if (typeof(obj1) === "string") + { + if (typeof(obj2) === "string") + return obj1 > obj2; + } + else if (ul4._isdatetime(obj1)) + { + if (ul4._isdatetime(obj2)) + return obj1.getTime() > obj2.getTime(); + } + else if (ul4._islist(obj1)) + { + if (ul4._islist(obj2)) + { + if (obj1 === obj2) + return false; + for (let i = 0; i < obj1.length; ++i) + { + if (i >= obj2.length) + return true; + let eq = ul4._eq(obj1[i], obj2[i]); + if (!eq) + return ul4._gt(obj1[i], obj2[i]); + } + return obj1.length > obj2.length; + } + } + // FIXME: Set comparison + else if (ul4._isset(obj1) || ul4._isul4set(obj1)) + { + let in1only = false; + let in2only = false; + + if (ul4._isset(obj2)) + { + if (ul4._isset(obj2)) + { + obj1.forEach(function(value) { + if (!obj2.has(value)) + in1only = true; + }); + obj2.forEach(function(value) { + if (!obj1.has(value)) + in2only = true; + }); + } + else if (ul4._isul4set(obj2)) + { + obj1.forEach(function(value) { + if (!obj2.items[value]) + in1only = true; + }); + obj2.forEach(function(value) { + if (!obj1.has(value)) + { + in2only = true; + } + }); + } + } + else if (ul4._isul4set(obj2)) + { + if (ul4._isset(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.has(value)) + { + in1only = true; + break; + } + } + obj2.forEach(function(value) { + if (!obj1.items[value]) + in2only = true; + }); + } + else if (ul4._isul4set(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.items[value]) + { + in1only = true; + break; + } + } + for (let value in obj2.items) + { + if (!obj1.items[value]) + { + in2only = true; + break; + } + } + } + } + else + ul4._unorderable(operator, obj1, obj2); + + if (in1only) + { + if (in2only) + return null; + else + return 1; + } + else + { + if (in2only) + return -1; + else + return 0; + } + } + ul4._unorderable(">", obj1, obj2); + }; + + // Return whether ``obj1 >= obj2`` + ul4._ge = function _ge(obj1, obj2) + { + let numbertypes = ["boolean", "number"]; + + if (obj1 && typeof(obj1.__ge__) === "function") + return obj1.__ge__(obj2); + else if (numbertypes.indexOf(typeof(obj1)) != -1) + { + if (numbertypes.indexOf(typeof(obj2)) != -1) + return obj1 >= obj2; + } + else if (typeof(obj1) === "string") + { + if (typeof(obj2) === "string") + return obj1 >= obj2; + } + else if (ul4._isdatetime(obj1)) + { + if (ul4._isdatetime(obj2)) + return obj1.getTime() >= obj2.getTime(); + } + else if (ul4._islist(obj1)) + { + if (ul4._islist(obj2)) + { + if (obj1 === obj2) + return true; + for (let i = 0; i < obj1.length; ++i) + { + if (i >= obj2.length) + return true; + let eq = ul4._eq(obj1[i], obj2[i]); + if (!eq) + return ul4._gt(obj1[i], obj2[i]); + } + return obj1.length >= obj2.length; + } + } + // FIXME: Set comparison + else if (ul4._isset(obj1) || ul4._isul4set(obj1)) + { + let in1only = false; + let in2only = false; + + if (ul4._isset(obj2)) + { + if (ul4._isset(obj2)) + { + obj1.forEach(function(value) { + if (!obj2.has(value)) + in1only = true; + }); + obj2.forEach(function(value) { + if (!obj1.has(value)) + in2only = true; + }); + } + else if (ul4._isul4set(obj2)) + { + obj1.forEach(function(value) { + if (!obj2.items[value]) + in1only = true; + }); + for (let value in obj2.items) + { + if (!obj1.has(value)) + { + in2only = true; + break; + } + } + } + } + else if (ul4._isul4set(obj2)) + { + if (ul4._isset(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.has(value)) + { + in1only = true; + break; + } + } + obj2.forEach(function(value, key) { + if (!obj1.items[value]) + in2only = true; + }); + } + else if (ul4._isul4set(obj2)) + { + for (let value in obj1.items) + { + if (!obj2.items[value]) + { + in1only = true; + break; + } + } + for (let value in obj2.items) + { + if (!obj1.items[value]) + { + in2only = true; + break; + } + } + } + } + else + ul4._unorderable(operator, obj1, obj2); + + if (in1only) + { + if (in2only) + return null; + else + return 1; + } + else + { + if (in2only) + return -1; + else + return 0; + } + } + ul4._unorderable(">=", obj1, obj2); + }; + + // Return an iterator for ``obj`` + ul4._iter = function _iter(obj) + { + if (typeof(obj) === "string" || ul4._islist(obj)) + { + return { + index: 0, + next: function() + { + if (this.index < obj.length) + return {value: obj[this.index++], done: false}; + else + return {done: true}; + } + }; + } + else if (ul4._isiter(obj)) + return obj; + else if (obj !== null && typeof(obj.__iter__) === "function") + return obj.__iter__(); + else if (ul4._ismap(obj)) + { + let keys = []; + obj.forEach(function(value, key) { + keys.push(key); + }); + return { + index: 0, + next: function() + { + if (this.index >= keys.length) + return {done: true}; + return {value: keys[this.index++], done: false}; + } + }; + } + else if (ul4._isset(obj)) + { + let values = []; + obj.forEach(function(item) { + values.push(item); + }); + return { + index: 0, + next: function() + { + if (this.index >= values.length) + return {done: true}; + return {value: values[this.index++], done: false}; + } + }; + } + else if (ul4._isul4set(obj)) + { + return ul4._iter(obj.items); + } + else if (ul4._isobject(obj)) + { + let keys = []; + for (let key in obj) + keys.push(key); + return { + index: 0, + next: function() + { + if (this.index >= keys.length) + return {done: true}; + return {value: keys[this.index++], done: false}; + } + }; + } + throw new ul4.TypeError(ul4._type(obj) + " object is not iterable"); + }; + + ul4._str_repr = function _str_repr(str, ascii) + { + let result = ""; + let squote = false, dquote = false; + + for (let i = 0; i < str.length; ++i) + { + let c = str[i]; + if (c == '"') + { + dquote = true; + if (squote) + break; + } + else if (c == "'") + { + squote = true; + if (dquote) + break; + } + } + + // Prefer single quotes: Only use double quotes if the string contains single quotes, but no double quotes + let quote = (squote && !dquote) ? '"' : "'"; + + for (let i = 0; i < str.length; ++i) + { + let c = str[i]; + switch (c) + { + case '"': + result += (quote == c) ? '\\"' : c; + break; + case "'": + result += (quote == c) ? "\\'" : c; + break; + case "\\": + result += "\\\\"; + break; + case "\t": + result += "\\t"; + break; + case "\n": + result += "\\n"; + break; + case "\r": + result += "\\r"; + break; + default: + let code = c.charCodeAt(0); + let escape; + if (code < 32) + escape = 2; + else if (code < 0x7f) + escape = 0; + else if (!ascii && !/[\u007f-\u00a0\u00ad\u0378-\u0379\u0380-\u0383\u038b\u038d\u03a2\u0530\u0557-\u0558\u0560\u0588\u058b-\u058c\u0590\u05c8-\u05cf\u05eb-\u05ef\u05f5-\u0605\u061c-\u061d\u06dd\u070e-\u070f\u074b-\u074c\u07b2-\u07bf\u07fb-\u07ff\u082e-\u082f\u083f\u085c-\u085d\u085f-\u089f\u08b5-\u08e2\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09bb\u09c5-\u09c6\u09c9-\u09ca\u09cf-\u09d6\u09d8-\u09db\u09de\u09e4-\u09e5\u09fc-\u0a00\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a3b\u0a3d\u0a43-\u0a46\u0a49-\u0a4a\u0a4e-\u0a50\u0a52-\u0a58\u0a5d\u0a5f-\u0a65\u0a76-\u0a80\u0a84\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abb\u0ac6\u0aca\u0ace-\u0acf\u0ad1-\u0adf\u0ae4-\u0ae5\u0af2-\u0af8\u0afa-\u0b00\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34\u0b3a-\u0b3b\u0b45-\u0b46\u0b49-\u0b4a\u0b4e-\u0b55\u0b58-\u0b5b\u0b5e\u0b64-\u0b65\u0b78-\u0b81\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bba-\u0bbd\u0bc3-\u0bc5\u0bc9\u0bce-\u0bcf\u0bd1-\u0bd6\u0bd8-\u0be5\u0bfb-\u0bff\u0c04\u0c0d\u0c11\u0c29\u0c3a-\u0c3c\u0c45\u0c49\u0c4e-\u0c54\u0c57\u0c5b-\u0c5f\u0c64-\u0c65\u0c70-\u0c77\u0c80\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cbb\u0cc5\u0cc9\u0cce-\u0cd4\u0cd7-\u0cdd\u0cdf\u0ce4-\u0ce5\u0cf0\u0cf3-\u0d00\u0d04\u0d0d\u0d11\u0d3b-\u0d3c\u0d45\u0d49\u0d4f-\u0d56\u0d58-\u0d5e\u0d64-\u0d65\u0d76-\u0d78\u0d80-\u0d81\u0d84\u0d97-\u0d99\u0db2\u0dbc\u0dbe-\u0dbf\u0dc7-\u0dc9\u0dcb-\u0dce\u0dd5\u0dd7\u0de0-\u0de5\u0df0-\u0df1\u0df5-\u0e00\u0e3b-\u0e3e\u0e5c-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eba\u0ebe-\u0ebf\u0ec5\u0ec7\u0ece-\u0ecf\u0eda-\u0edb\u0ee0-\u0eff\u0f48\u0f6d-\u0f70\u0f98\u0fbd\u0fcd\u0fdb-\u0fff\u10c6\u10c8-\u10cc\u10ce-\u10cf\u1249\u124e-\u124f\u1257\u1259\u125e-\u125f\u1289\u128e-\u128f\u12b1\u12b6-\u12b7\u12bf\u12c1\u12c6-\u12c7\u12d7\u1311\u1316-\u1317\u135b-\u135c\u137d-\u137f\u139a-\u139f\u13f6-\u13f7\u13fe-\u13ff\u1680\u169d-\u169f\u16f9-\u16ff\u170d\u1715-\u171f\u1737-\u173f\u1754-\u175f\u176d\u1771\u1774-\u177f\u17de-\u17df\u17ea-\u17ef\u17fa-\u17ff\u180e-\u180f\u181a-\u181f\u1878-\u187f\u18ab-\u18af\u18f6-\u18ff\u191f\u192c-\u192f\u193c-\u193f\u1941-\u1943\u196e-\u196f\u1975-\u197f\u19ac-\u19af\u19ca-\u19cf\u19db-\u19dd\u1a1c-\u1a1d\u1a5f\u1a7d-\u1a7e\u1a8a-\u1a8f\u1a9a-\u1a9f\u1aae-\u1aaf\u1abf-\u1aff\u1b4c-\u1b4f\u1b7d-\u1b7f\u1bf4-\u1bfb\u1c38-\u1c3a\u1c4a-\u1c4c\u1c80-\u1cbf\u1cc8-\u1ccf\u1cf7\u1cfa-\u1cff\u1df6-\u1dfb\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fc5\u1fd4-\u1fd5\u1fdc\u1ff0-\u1ff1\u1ff5\u1fff-\u200f\u2028-\u202f\u205f-\u206f\u2072-\u2073\u208f\u209d-\u209f\u20bf-\u20cf\u20f1-\u20ff\u218c-\u218f\u23fb-\u23ff\u2427-\u243f\u244b-\u245f\u2b74-\u2b75\u2b96-\u2b97\u2bba-\u2bbc\u2bc9\u2bd2-\u2beb\u2bf0-\u2bff\u2c2f\u2c5f\u2cf4-\u2cf8\u2d26\u2d28-\u2d2c\u2d2e-\u2d2f\u2d68-\u2d6e\u2d71-\u2d7e\u2d97-\u2d9f\u2da7\u2daf\u2db7\u2dbf\u2dc7\u2dcf\u2dd7\u2ddf\u2e43-\u2e7f\u2e9a\u2ef4-\u2eff\u2fd6-\u2fef\u2ffc-\u3000\u3040\u3097-\u3098\u3100-\u3104\u312e-\u3130\u318f\u31bb-\u31bf\u31e4-\u31ef\u321f\u32ff\u4db6-\u4dbf\u9fd6-\u9fff\ua48d-\ua48f\ua4c7-\ua4cf\ua62c-\ua63f\ua6f8-\ua6ff\ua7ae-\ua7af\ua7b8-\ua7f6\ua82c-\ua82f\ua83a-\ua83f\ua878-\ua87f\ua8c5-\ua8cd\ua8da-\ua8df\ua8fe-\ua8ff\ua954-\ua95e\ua97d-\ua97f\ua9ce\ua9da-\ua9dd\ua9ff\uaa37-\uaa3f\uaa4e-\uaa4f\uaa5a-\uaa5b\uaac3-\uaada\uaaf7-\uab00\uab07-\uab08\uab0f-\uab10\uab17-\uab1f\uab27\uab2f\uab66-\uab6f\uabee-\uabef\uabfa-\uabff\ud7a4-\ud7af\ud7c7-\ud7ca\ud7fc-\uf8ff\ufa6e-\ufa6f\ufada-\ufaff\ufb07-\ufb12\ufb18-\ufb1c\ufb37\ufb3d\ufb3f\ufb42\ufb45\ufbc2-\ufbd2\ufd40-\ufd4f\ufd90-\ufd91\ufdc8-\ufdef\ufdfe-\ufdff\ufe1a-\ufe1f\ufe53\ufe67\ufe6c-\ufe6f\ufe75\ufefd-\uff00\uffbf-\uffc1\uffc8-\uffc9\uffd0-\uffd1\uffd8-\uffd9\uffdd-\uffdf\uffe7\uffef-\ufffb\ufffe-\uffff]/.test(c)) + escape = 0; + else if (code <= 0xff) + escape = 2; + else if (code <= 0xffff) + escape = 4; + else + escape = 8; + + if (escape === 0) + result += c; + else if (escape === 2) + result += "\\x" + ul4._lpad(code.toString(16), "0", 2); + else if (escape === 4) + result += "\\u" + ul4._lpad(code.toString(16), "0", 4); + else + result += "\\U" + ul4._lpad(code.toString(16), "0", 8); + break; + } + } + return quote + result + quote; + }; + + ul4._date_repr = function _date_repr(obj, ascii) + { + let year = obj._date.getFullYear(); + let month = obj._date.getMonth()+1; + let day = obj._date.getDate(); + let result = "@(" + year + "-" + ul4._lpad(month.toString(), "0", 2) + "-" + ul4._lpad(day.toString(), "0", 2) + ")"; + return result; + }; + + ul4._datetime_repr = function _datetime_repr(obj, ascii) + { + let year = obj.getFullYear(); + let month = obj.getMonth()+1; + let day = obj.getDate(); + let hour = obj.getHours(); + let minute = obj.getMinutes(); + let second = obj.getSeconds(); + let ms = obj.getMilliseconds(); + let result = "@(" + year + "-" + ul4._lpad(month.toString(), "0", 2) + "-" + ul4._lpad(day.toString(), "0", 2) + "T"; + + if (hour || minute || second || ms) + { + result += ul4._lpad(hour.toString(), "0", 2) + ":" + ul4._lpad(minute.toString(), "0", 2); + if (second || ms) + { + result += ":" + ul4._lpad(second.toString(), "0", 2); + if (ms) + result += "." + ul4._lpad(ms.toString(), "0", 3) + "000"; + } + } + result += ")"; + + return result; + }; + + ul4._map_repr = function _map_repr(obj, ascii) + { + let v = []; + v.push("{"); + + let i = 0; + obj.forEach(function(value, key) { + if (i++) + v.push(", "); + v.push(ul4._repr_internal(key, ascii)); + v.push(": "); + v.push(ul4._repr_internal(value, ascii)); + }); + + v.push("}"); + return v.join(""); + }; + + ul4._list_repr = function _list_repr(obj, ascii) + { + let v = []; + v.push("["); + for (let i = 0; i < obj.length; ++i) + { + let item = obj[i]; + if (i) + v.push(", "); + v.push(ul4._repr_internal(item, ascii)); + } + v.push("]"); + return v.join(""); + }; + + ul4._set_repr = function _set_repr(obj, ascii) + { + let v = []; + v.push("{"); + if (!obj.size) + v.push("/"); + else + { + let i = 0; + obj.forEach(function(value) { + if (i++) + v.push(", "); + v.push(ul4._repr_internal(value, ascii)); + }); + } + v.push("}"); + return v.join(""); + }; + + ul4._object_repr = function _object_repr(obj, ascii) + { + let v = []; + v.push("{"); + let i = 0; + for (let key in obj) + { + if (!obj.hasOwnProperty(key)) + continue; + if (i++) + v.push(", "); + v.push(ul4._repr_internal(key, ascii)); + v.push(": "); + v.push(ul4._repr_internal(obj[key], ascii)); + } + v.push("}"); + return v.join(""); + }; + + ul4._repr_internal = function _repr_internal(obj, ascii) + { + if (obj === null) + return "None"; + else if (obj === false) + return "False"; + else if (obj === true) + return "True"; + else if (typeof(obj) === "string") + return ul4._str_repr(obj, ascii); + else if (typeof(obj) === "number") + return "" + obj; + else if (typeof(obj) === "function") + if (obj._ul4_name || obj.name) + return ""; + else + return ""; + else if (ul4._isdate(obj)) + return ul4._date_repr(obj, ascii); + else if (ul4._isdatetime(obj)) + return ul4._datetime_repr(obj, ascii); + else if (typeof(obj) === "undefined") + return ""; + else if (typeof(obj) === "object" && typeof(obj.__repr__) === "function") + return obj.__repr__(); + else if (ul4._islist(obj)) + return ul4._list_repr(obj, ascii); + else if (ul4._ismap(obj)) + return ul4._map_repr(obj, ascii); + else if (ul4._isset(obj)) + return ul4._set_repr(obj, ascii); + else if (ul4._isobject(obj)) + return ul4._object_repr(obj, ascii); + return "?"; + }; + + // Return a string representation of ``obj``: If possible this should be an object literal supported by UL4, otherwise the output should be bracketed with ``<`` and ``>`` + ul4._repr = function _repr(obj) + { + return ul4._repr_internal(obj, false); + }; + + ul4._ascii = function _ascii(obj) + { + return ul4._repr_internal(obj, true); + }; + + ul4._date_str = function _date_str(obj) + { + let year = obj._date.getFullYear(); + let month = obj._date.getMonth()+1; + let day = obj._date.getDate(); + + return year + "-" + ul4._lpad(month.toString(), "0", 2) + "-" + ul4._lpad(day.toString(), "0", 2); + }; + + ul4._datetime_str = function _datetime_str(obj) + { + let year = obj.getFullYear(); + let month = obj.getMonth()+1; + let day = obj.getDate(); + let hour = obj.getHours(); + let minute = obj.getMinutes(); + let second = obj.getSeconds(); + let ms = obj.getMilliseconds(); + + let result = year + "-" + ul4._lpad(month.toString(), "0", 2) + "-" + ul4._lpad(day.toString(), "0", 2) + " " + ul4._lpad(hour.toString(), "0", 2) + ":" + ul4._lpad(minute.toString(), "0", 2); + if (second || ms) + { + result += ":" + ul4._lpad(second.toString(), "0", 2); + if (ms) + result += "." + ul4._lpad(ms.toString(), "0", 3) + "000"; + } + return result; + }; + + ul4._str = function _str(obj) + { + if (typeof(obj) === "undefined") + return ""; + else if (obj === null) + return ""; + else if (obj === false) + return "False"; + else if (obj === true) + return "True"; + else if (typeof(obj) === "string") + return obj; + else if (typeof(obj) === "number") + return obj.toString(); + else if (ul4._isdate(obj)) + return ul4._date_str(obj); + else if (ul4._isdatetime(obj)) + return ul4._datetime_str(obj); + else if (ul4._islist(obj)) + return ul4._list_repr(obj); + else if (ul4._isset(obj)) + return ul4._set_repr(obj); + else if (ul4._ismap(obj)) + return ul4._map_repr(obj); + else if (typeof(obj) === "object" && typeof(obj.__str__) === "function") + return obj.__str__(); + else if (typeof(obj) === "object" && typeof(obj.__repr__) === "function") + return obj.__repr__(); + else if (ul4._isobject(obj)) + return ul4._object_repr(obj); + return "?"; + }; + + // Convert ``obj`` to bool, according to its "truth value" + ul4._bool = function _bool(obj) + { + if (typeof(obj) === "undefined" || obj === null || obj === false || obj === 0 || obj === "") + return false; + else + { + if (typeof(obj) === "object", typeof(obj.__bool__) === "function") + return obj.__bool__(); + if (ul4._islist(obj)) + return obj.length !== 0; + else if (ul4._ismap(obj) || ul4._isset(obj)) + return obj.size != 0; + else if (ul4._isobject(obj)) + { + for (let key in obj) + { + if (!obj.hasOwnProperty(key)) + continue; + return true; + } + return false; + } + return true; + } + }; + + // Convert ``obj`` to an integer (if ``base`` is given ``obj`` must be a string and ``base`` is the base for the conversion (default is 10)) + ul4._int = function _int(obj, base) + { + let result; + if (base !== null) + { + if (typeof(obj) !== "string" || !ul4._isint(base)) + throw new ul4.TypeError("int() requires a string and an integer"); + result = parseInt(obj, base); + if (result.toString() == "NaN") + throw new ul4.TypeError("invalid literal for int()"); + return result; + } + else + { + if (typeof(obj) == "string") + { + result = parseInt(obj); + if (result.toString() == "NaN") + throw new ul4.TypeError("invalid literal for int()"); + return result; + } + else if (typeof(obj) == "number") + return Math.floor(obj); + else if (obj === true) + return 1; + else if (obj === false) + return 0; + throw new ul4.TypeError("int() argument must be a string or a number"); + } + }; + + // Convert ``obj`` to a float + ul4._float = function _float(obj) + { + if (typeof(obj) === "string") + return parseFloat(obj); + else if (typeof(obj) === "number") + return obj; + else if (obj === true) + return 1.0; + else if (obj === false) + return 0.0; + throw new ul4.TypeError("float() argument must be a string or a number"); + }; + + // Convert ``obj`` to a list + ul4._list = function _list(obj) + { + let iter = ul4._iter(obj); + + let result = []; + for (;;) + { + let value = iter.next(); + if (value.done) + return result; + result.push(value.value); + } + }; + + // Convert ``obj`` to a set + ul4._set = function _set(obj) + { + let iter = ul4._iter(obj); + + let result = ul4._emptyset(); + for (;;) + { + let value = iter.next(); + if (value.done) + return result; + result.add(value.value); + } + }; + + // Return the length of ``sequence`` + ul4._len = function _len(sequence) + { + if (typeof(sequence) == "string" || ul4._islist(sequence)) + return sequence.length; + else if (ul4._ismap(sequence) || ul4._isset(sequence)) + return sequence.size; + else if (ul4._isobject(sequence)) + { + let i = 0; + for (let key in sequence) + ++i; + return i; + } + throw new ul4.TypeError("object of type '" + ul4._type(sequence) + "' has no len()"); + }; + + ul4._type = function _type(obj) + { + if (obj === null) + return "none"; + else if (obj === false || obj === true) + return "bool"; + else if (typeof(obj) === "undefined") + return "undefined"; + else if (typeof(obj) === "number") + return Math.round(obj) == obj ? "int" : "float"; + else if (typeof(obj) === "function") + return "function"; + else + { + if (typeof(obj.ul4type) === "function") + return obj.ul4type(); + else + return ul4.Protocol.get(obj).ul4type(obj); + } + }; + + // (this is non-trivial, because it follows the Python semantic of ``-5 % 2`` being ``1``) + ul4._mod = function _mod(obj1, obj2) + { + let div = Math.floor(obj1 / obj2); + let mod = obj1 - div * obj2; + + if (mod !== 0 && ((obj2 < 0 && mod > 0) || (obj2 > 0 && mod < 0))) + { + mod += obj2; + --div; + } + return obj1 - div * obj2; + }, + + // Return the attribute with the name ``attrname`` of the object ``obj`` + // If ``obj`` doesn't have such an attribute, return ``default_`` + ul4._getattr = function _getattr(obj, attrname, default_=null) + { + let proto = ul4.Protocol.get(obj); + try + { + return proto.getattr(obj, attrname); + } + catch (exc) + { + if (exc instanceof ul4.AttributeError && exc.obj === obj) + return default_; + else + throw exc; + } + }; + + // Return wether the object ``obj`` has an attribute with the name ``attrname`` + ul4._hasattr = function _hasattr(obj, attrname) + { + let proto = ul4.Protocol.get(obj); + return proto.hasattr(obj, attrname); + }; + + // Return the names of the attributes of the object ``obj`` as a set. + ul4._dir = function _dir(obj) + { + let proto = ul4.Protocol.get(obj); + return proto.dir(); + }; + + // Return whether any of the items in ``iterable`` are true + ul4._any = function _any(iterable) + { + if (typeof(iterable) == "string") + { + for (let i = 0; i < iterable.length; ++i) + { + if (iterable[i] !== '\x00') + return true; + } + return false; + } + else + { + for (let iter = ul4._iter(iterable);;) + { + let item = iter.next(); + if (item.done) + return false; + if (ul4._bool(item.value)) + return true; + } + } + }; + + // Return whether all of the items in ``iterable`` are true + ul4._all = function _all(iterable) + { + if (typeof(iterable) == "string") + { + for (let i = 0; i < iterable.length; ++i) + { + if (iterable[i] === '\x00') + return false; + } + return true; + } + else + { + for (let iter = ul4._iter(iterable);;) + { + let item = iter.next(); + if (item.done) + return true; + if (!ul4._bool(item.value)) + return false; + } + } + }; + + // Check if ``obj`` is undefined + ul4._isundefined = function _isundefined(obj) + { + return typeof(obj) === "undefined"; + }; + + + // Check if ``obj`` is *not* undefined + ul4._isdefined = function _isdefined(obj) + { + return typeof(obj) !== "undefined"; + }; + + // Check if ``obj`` is ``None`` + ul4._isnone = function _isnone(obj) + { + return obj === null; + }; + + // Check if ``obj`` is a boolean + ul4._isbool = function _isbool(obj) + { + return typeof(obj) == "boolean"; + }; + + // Check if ``obj`` is a int + ul4._isint = function _isint(obj) + { + return (typeof(obj) == "number") && Math.round(obj) == obj; + }; + + // Check if ``obj`` is a float + ul4._isfloat = function _isfloat(obj) + { + return (typeof(obj) == "number") && Math.round(obj) != obj; + }; + + // Check if ``obj`` is a string + ul4._isstr = function _isstr(obj) + { + return typeof(obj) == "string"; + }; + + // Check if ``obj`` is a datetime + ul4._isdatetime = function _isdate(obj) + { + return Object.prototype.toString.call(obj) == "[object Date]"; + }; + + ul4._isdate = function _isdate(obj) + { + return (obj instanceof ul4.Date); + }; + + // Check if ``obj`` is a color + ul4._iscolor = function _iscolor(obj) + { + return (obj instanceof ul4.Color); + }; + + // Check if ``obj`` is a timedelta object + ul4._istimedelta = function _istimedelta(obj) + { + return (obj instanceof ul4.TimeDelta); + }; + + // Check if ``obj`` is a monthdelta object + ul4._ismonthdelta = function _ismonthdelta(obj) + { + return (obj instanceof ul4.MonthDelta); + }; + + // Check if ``obj`` is a template + ul4._istemplate = function _istemplate(obj) + { + return (obj instanceof ul4.Template || obj instanceof ul4.TemplateClosure); + }; + + // Check if ``obj`` is a function + ul4._isfunction = function _isfunction(obj) + { + return typeof(obj) === "function" || (Object.prototype.toString.call(obj) == "[object Object]" && (obj instanceof ul4.Template || obj instanceof ul4.TemplateClosure)); + }; + + // Check if ``obj`` is a list + ul4._islist = function _islist(obj) + { + return Object.prototype.toString.call(obj) == "[object Array]"; + }; + + // Check if ``obj`` is a set + ul4._isset = function _isset(obj) + { + return Object.prototype.toString.call(obj) == "[object Set]"; + }; + + // Check if ``obj`` is an exception (at least a UL4 exception) + ul4._isexception = function _isexception(obj) + { + return (obj instanceof ul4.Exception); + }; + + ul4._isul4set = function _isul4set(obj) + { + return (obj instanceof ul4._Set); + }; + + ul4._isanyset = function _isanyset(obj) + { + return (ul4._isset(obj) || ul4._isul4set(obj)); + }; + + // Check if ``obj`` is an iterator + ul4._isiter = function _isiter(obj) + { + return obj !== null && typeof(obj) === "object" && typeof(obj.next) === "function"; + }; + + // Check if ``obj`` is a JS object + ul4._isobject = function _isobject(obj) + { + return Object.prototype.toString.call(obj) == "[object Object]" && typeof(obj.__type__) === "undefined" && !(obj instanceof ul4.Proto); + }; + + if (ul4._havemap) + { + // Check if ``obj`` is a ``Map`` + ul4._ismap = function _ismap(obj) + { + return obj !== null && typeof(obj) === "object" && typeof(obj.__proto__) === "object" && obj.__proto__ === Map.prototype; + }; + + // Check if ``obj`` is a dict (i.e. a normal Javascript object or a ``Map``) + ul4._isdict = function _isdict(obj) + { + return ul4._isobject(obj) || ul4._ismap(obj); + }; + } + else + { + ul4._ismap = function _ismap(obj) + { + return false; + }; + + ul4._isdict = function _isdict(obj) + { + return ul4._isobject(obj); + }; + } + + // Repeat string ``str`` ``rep`` times + ul4._str_repeat = function _str_repeat(str, rep) + { + let result = ""; + for (; rep>0; --rep) + result += str; + return result; + }; + + ul4._list_repeat = function _list_repeat(list, rep) + { + let result = []; + for (; rep>0; --rep) + for (let i = 0; i < list.length; ++i) + result.push(list[i]); + return result; + }; + + ul4._str_json = function _str_json(str) + { + let result = ""; + for (let i = 0; i < str.length; ++i) + { + let c = str[i]; + switch (c) + { + case "\r": + result += "\\r"; + break; + case "\n": + result += "\\n"; + break; + case "\t": + result += "\\t"; + break; + case "\\": + result += "\\\\"; + break; + case '"': + result += '\\"'; + break; + case '<': + result += '\\u003c'; + break; + default: + let code = c.charCodeAt(0); + if (code >= 32 && code < 128) + result += c; + else + result += "\\u" + ul4._lpad(code.toString(16), "0", 4); + break; + } + } + return '"' + result + '"'; + }; + + // Encodes ``obj`` in the Javascript Object Notation (see http://json.org/; with support for dates, colors and templates) + ul4._asjson = function _asjson(obj) + { + if (obj === null) + return "null"; + else if (typeof(obj) === "undefined") + return "undefined"; + else if (obj === false) + return "false"; + else if (obj === true) + return "true"; + else if (typeof(obj) === "string") + return ul4._str_json(obj); + else if (typeof(obj) === "number") + { + return "" + obj; + } + else if (ul4._islist(obj)) + { + let v = []; + v.push("["); + for (let i = 0; i < obj.length; ++i) + { + if (i != 0) + v.push(", "); + v.push(ul4._asjson(obj[i])); + } + v.push("]"); + return v.join(""); + } + else if (ul4._ismap(obj)) + { + let v = []; + v.push("{"); + let i = 0; + obj.forEach(function(value, key) { + if (i++) + v.push(", "); + v.push(ul4._asjson(key)); + v.push(": "); + v.push(ul4._asjson(value)); + }); + v.push("}"); + return v.join(""); + } + else if (ul4._isobject(obj)) + { + let v = []; + v.push("{"); + let i = 0; + for (let key in obj) + { + if (i++) + v.push(", "); + v.push(ul4._asjson(key)); + v.push(": "); + v.push(ul4._asjson(obj[key])); + } + v.push("}"); + return v.join(""); + } + else if (ul4._isdate(obj)) + { + return "new ul4.Date(" + obj._date.getFullYear() + ", " + (obj._date.getMonth()+1) + ", " + obj._date.getDate() + ")"; + } + else if (ul4._isdatetime(obj)) + { + return "new Date(" + obj.getFullYear() + ", " + obj.getMonth() + ", " + obj.getDate() + ", " + obj.getHours() + ", " + obj.getMinutes() + ", " + obj.getSeconds() + ", " + obj.getMilliseconds() + ")"; + } + else if (ul4._istimedelta(obj)) + { + return "new ul4.TimeDelta(" + obj._days + ", " + obj._seconds + ", " + obj._microseconds + ")"; + } + else if (ul4._ismonthdelta(obj)) + { + return "new ul4.MonthDelta(" + obj._months + ")"; + } + else if (ul4._iscolor(obj)) + { + return "new ul4.Color(" + obj._r + ", " + obj._g + ", " + obj._b + ", " + obj._a + ")"; + } + else if (ul4._istemplate(obj)) + { + return "ul4.Template.loads(" + ul4._repr(obj.dumps()) + ")"; + } + throw new ul4.TypeError("asjson() requires a serializable object"); + }; + + // Decodes the string ``string`` from the Javascript Object Notation (see http://json.org/) and returns the resulting object + ul4._fromjson = function _fromjson(string) + { + // The following is from jQuery's parseJSON function + string = ul4.StrProtocol.strip(string); + if (root.JSON && root.JSON.parse) + return root.JSON.parse(string); + if (ul4._rvalidchars.test(string.replace(ul4._rvalidescape, "@").replace(ul4._rvalidtokens, "]").replace(ul4._rvalidbraces, ""))) + return (new Function("return " + string))(); + throw new ul4.TypeError("invalid JSON"); + }; + + // Encodes ``obj`` in the UL4 Object Notation format + ul4._asul4on = function _asul4on(obj) + { + return ul4.dumps(obj); + }; + + // Decodes the string ``string`` from the UL4 Object Notation format and returns the resulting decoded object + ul4._fromul4on = function _fromul4on(string) + { + return ul4.loads(string); + }; + + ul4._format_datetime = function _format_datetime(obj, fmt, lang) + { + let translations = { + de: { + ms: ["Jan", "Feb", "M\u00e4r", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"], + ml: ["Januar", "Februar", "M\u00e4rz", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], + ws: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], + wl: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + en: { + ms: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + ml: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + ws: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + wl: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], + xf: "%m/%d/%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %I:%M:%S %p" + }, + fr: { + ms: ["janv.", "f\u00e9vr.", "mars", "avril", "mai", "juin", "juil.", "ao\u00fbt", "sept.", "oct.", "nov.", "d\u00e9c."], + ml: ["janvier", "f\u00e9vrier", "mars", "avril", "mai", "juin", "juillet", "ao\u00fbt", "septembre", "octobre", "novembre", "d\u00e9cembre"], + ws: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."], + wl: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], + xf: "%d/%m/%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + es: { + ms: ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"], + ml: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"], + ws: ["dom", "lun", "mar", "mi\u00e9", "jue", "vie", "s\u00e1b"], + wl: ["domingo", "lunes", "martes", "mi\u00e9rcoles", "jueves", "viernes", "s\u00e1bado"], + xf: "%d/%m/%y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + it: { + ms: ["gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic"], + ml: ["gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre"], + ws: ["dom", "lun", "mar", "mer", "gio", "ven", "sab"], + wl: ["domenica", "luned\u00ec", "marted\u00ec", "mercoled\u00ec", "gioved\u00ec", "venerd\u00ec", "sabato"], + xf: "%d/%m/%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + da: { + ms: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"], + ml: ["januar", "februar", "marts", "april", "maj", "juni", "juli", "august", "september", "oktober", "november", "december"], + ws: ["s\u00f8n", "man", "tir", "ons", "tor", "fre", "l\u00f8r"], + wl: ["s\u00f8ndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "l\u00f8rdag"], + xf: "%d-%m-%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + sv: { + ms: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"], + ml: ["januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december"], + ws: ["s\u00f6n", "m\u00e5n", "tis", "ons", "tor", "fre", "l\u00f6r"], + wl: ["s\u00f6ndag", "m\u00e5ndag", "tisdag", "onsdag", "torsdag", "fredag", "l\u00f6rdag"], + xf: "%Y-%m-%d", + Xf: "%H.%M.%S", + cf: "%a %d %b %Y %H.%M.%S" + }, + nl: { + ms: ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"], + ml: ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"], + ws: ["zo", "ma", "di", "wo", "do", "vr", "za"], + wl: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"], + xf: "%d-%m-%y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + pt: { + ms: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"], + ml: ["Janeiro", "Fevereiro", "Mar\u00e7o", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"], + ws: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "S\u00e1b"], + wl: ["Domingo", "Segunda", "Ter\u00e7a", "Quarta", "Quinta", "Sexta", "S\u00e1bado"], + xf: "%d-%m-%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + cs: { + ms: ["led", "\u00fano", "b\u0159e", "dub", "kv\u011b", "\u010den", "\u010dec", "srp", "z\u00e1\u0159", "\u0159\u00edj", "lis", "pro"], + ml: ["leden", "\u00fanor", "b\u0159ezen", "duben", "kv\u011bten", "\u010derven", "\u010dervenec", "srpen", "z\u00e1\u0159\u00ed", "\u0159\u00edjen", "listopad", "prosinec"], + ws: ["Ne", "Po", "\u00dat", "St", "\u010ct", "P\u00e1", "So"], + wl: ["Ned\u011ble", "Pond\u011bl\u00ed", "\u00dater\u00fd", "St\u0159eda", "\u010ctvrtek", "P\u00e1tek", "Sobota"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a\u00a0%d.\u00a0%B\u00a0%Y,\u00a0%H:%M:%S" + }, + sk: { + ms: ["jan", "feb", "mar", "apr", "m\u00e1j", "j\u00fan", "j\u00fal", "aug", "sep", "okt", "nov", "dec"], + ml: ["janu\u00e1r", "febru\u00e1r", "marec", "apr\u00edl", "m\u00e1j", "j\u00fan", "j\u00fal", "august", "september", "okt\u00f3ber", "november", "december"], + ws: ["Ne", "Po", "Ut", "St", "\u0160t", "Pi", "So"], + wl: ["Nede\u013ea", "Pondelok", "Utorok", "Streda", "\u0160tvrtok", "Piatok", "Sobota"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a\u00a0%d.\u00a0%B\u00a0%Y,\u00a0%H:%M:%S" + }, + pl: { + ms: ["sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "pa\u017a", "lis", "gru"], + ml: ["stycze\u0144", "luty", "marzec", "kwiecie\u0144", "maj", "czerwiec", "lipiec", "sierpie\u0144", "wrzesie\u0144", "pa\u017adziernik", "listopad", "grudzie\u0144"], + ws: ["nie", "pon", "wto", "\u015bro", "czw", "pi\u0105", "sob"], + wl: ["niedziela", "poniedzia\u0142ek", "wtorek", "\u015broda", "czwartek", "pi\u0105tek", "sobota"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a, %d %b %Y, %H:%M:%S" + }, + hr: { + ms: ["Sij", "Vel", "O\u017eu", "Tra", "Svi", "Lip", "Srp", "Kol", "Ruj", "Lis", "Stu", "Pro"], + ml: ["Sije\u010danj", "Velja\u010da", "O\u017eujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"], + ws: ["Ned", "Pon", "Uto", "Sri", "\u010cet", "Pet", "Sub"], + wl: ["Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "\u010cetvrtak", "Petak", "Subota"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + sr: { + ms: ["\u0458\u0430\u043d", "\u0444\u0435\u0431", "\u043c\u0430\u0440", "\u0430\u043f\u0440", "\u043c\u0430\u0458", "\u0458\u0443\u043d", "\u0458\u0443\u043b", "\u0430\u0432\u0433", "\u0441\u0435\u043f", "\u043e\u043a\u0442", "\u043d\u043e\u0432", "\u0434\u0435\u0446"], + ml: ["\u0458\u0430\u043d\u0443\u0430\u0440", "\u0444\u0435\u0431\u0440\u0443\u0430\u0440", "\u043c\u0430\u0440\u0442", "\u0430\u043f\u0440\u0438\u043b", "\u043c\u0430\u0458", "\u0458\u0443\u043d", "\u0458\u0443\u043b", "\u0430\u0432\u0433\u0443\u0441\u0442", "\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440", "\u043e\u043a\u0442\u043e\u0431\u0430\u0440", "\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440", "\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440"], + ws: ["\u043d\u0435\u0434", "\u043f\u043e\u043d", "\u0443\u0442\u043e", "\u0441\u0440\u0435", "\u0447\u0435\u0442", "\u043f\u0435\u0442", "\u0441\u0443\u0431"], + wl: ["\u043d\u0435\u0434\u0435\u0459\u0430", "\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a", "\u0443\u0442\u043e\u0440\u0430\u043a", "\u0441\u0440\u0435\u0434\u0430", "\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a", "\u043f\u0435\u0442\u0430\u043a", "\u0441\u0443\u0431\u043e\u0442\u0430"], + xf: "%d.%m.%Y.", + Xf: "%H:%M:%S", + cf: "%A, %d. %B %Y. %H:%M:%S" + }, + ro: { + ms: ["ian", "feb", "mar", "apr", "mai", "iun", "iul", "aug", "sep", "oct", "nov", "dec"], + ml: ["ianuarie", "februarie", "martie", "aprilie", "mai", "iunie", "iulie", "august", "septembrie", "octombrie", "noiembrie", "decembrie"], + ws: ["Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sb"], + wl: ["duminic\u0103", "luni", "mar\u0163i", "miercuri", "joi", "vineri", "s\u00e2mb\u0103t\u0103"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + hu: { + ms: ["jan", "febr", "m\u00e1rc", "\u00e1pr", "m\u00e1j", "j\u00fan", "j\u00fal", "aug", "szept", "okt", "nov", "dec"], + ml: ["janu\u00e1r", "febru\u00e1r", "m\u00e1rcius", "\u00e1prilis", "m\u00e1jus", "j\u00fanius", "j\u00falius", "augusztus", "szeptember", "okt\u00f3ber", "november", "december"], + ws: ["v", "h", "k", "sze", "cs", "p", "szo"], + wl: ["vas\u00e1rnap", "h\u00e9tf\u0151", "kedd", "szerda", "cs\u00fct\u00f6rt\u00f6k", "p\u00e9ntek", "szombat"], + xf: "%Y-%m-%d", + Xf: "%H.%M.%S", + cf: "%Y. %b. %d., %A, %H.%M.%S" + }, + tr: { + ms: ["Oca", "\u015eub", "Mar", "Nis", "May", "Haz", "Tem", "A\u011fu", "Eyl", "Eki", "Kas", "Ara"], + ml: ["Ocak", "\u015eubat", "Mart", "Nisan", "May\u0131s", "Haziran", "Temmuz", "A\u011fustos", "Eyl\u00fcl", "Ekim", "Kas\u0131m", "Aral\u0131k"], + ws: ["Paz", "Pzt", "Sal", "\u00c7r\u015f", "Pr\u015f", "Cum", "Cts"], + wl: ["Pazar", "Pazartesi", "Sal\u0131", "\u00c7ar\u015famba", "Per\u015fembe", "Cuma", "Cumartesi"], + xf: "%d-%m-%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + ru: { + ms: ["\u042f\u043d\u0432", "\u0424\u0435\u0432", "\u041c\u0430\u0440", "\u0410\u043f\u0440", "\u041c\u0430\u0439", "\u0418\u044e\u043d", "\u0418\u044e\u043b", "\u0410\u0432\u0433", "\u0421\u0435\u043d", "\u041e\u043a\u0442", "\u041d\u043e\u044f", "\u0414\u0435\u043a"], + ml: ["\u042f\u043d\u0432\u0430\u0440\u044c", "\u0424\u0435\u0432\u0440\u0430\u043b\u044c", "\u041c\u0430\u0440\u0442", "\u0410\u043f\u0440\u0435\u043b\u044c", "\u041c\u0430\u0439", "\u0418\u044e\u043d\u044c", "\u0418\u044e\u043b\u044c", "\u0410\u0432\u0433\u0443\u0441\u0442", "\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c", "\u041e\u043a\u0442\u044f\u0431\u0440\u044c", "\u041d\u043e\u044f\u0431\u0440\u044c", "\u0414\u0435\u043a\u0430\u0431\u0440\u044c"], + ws: ["\u0412\u0441\u043a", "\u041f\u043d\u0434", "\u0412\u0442\u0440", "\u0421\u0440\u0434", "\u0427\u0442\u0432", "\u041f\u0442\u043d", "\u0421\u0431\u0442"], + wl: ["\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435", "\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a", "\u0412\u0442\u043e\u0440\u043d\u0438\u043a", "\u0421\u0440\u0435\u0434\u0430", "\u0427\u0435\u0442\u0432\u0435\u0440\u0433", "\u041f\u044f\u0442\u043d\u0438\u0446\u0430", "\u0421\u0443\u0431\u0431\u043e\u0442\u0430"], + xf: "%d.%m.%Y", + Xf: "%H:%M:%S", + cf: "%a %d %b %Y %H:%M:%S" + }, + zh: { + ms: [" 1\u6708", " 2\u6708", " 3\u6708", " 4\u6708", " 5\u6708", " 6\u6708", " 7\u6708", " 8\u6708", " 9\u6708", "10\u6708", "11\u6708", "12\u6708"], + ml: ["\u4e00\u6708", "\u4e8c\u6708", "\u4e09\u6708", "\u56db\u6708", "\u4e94\u6708", "\u516d\u6708", "\u4e03\u6708", "\u516b\u6708", "\u4e5d\u6708", "\u5341\u6708", "\u5341\u4e00\u6708", "\u5341\u4e8c\u6708"], + ws: ["\u65e5", "\u4e00", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d"], + wl: ["\u661f\u671f\u65e5", "\u661f\u671f\u4e00", "\u661f\u671f\u4e8c", "\u661f\u671f\u4e09", "\u661f\u671f\u56db", "\u661f\u671f\u4e94", "\u661f\u671f\u516d"], + xf: "%Y\u5e74%b%d\u65e5", + Xf: "%H\u65f6%M\u5206%S\u79d2", + cf: "%Y\u5e74%b%d\u65e5 %A %H\u65f6%M\u5206%S\u79d2" + }, + ko: { + ms: [" 1\uc6d4", " 2\uc6d4", " 3\uc6d4", " 4\uc6d4", " 5\uc6d4", " 6\uc6d4", " 7\uc6d4", " 8\uc6d4", " 9\uc6d4", "10\uc6d4", "11\uc6d4", "12\uc6d4"], + ml: ["1\uc6d4", "2\uc6d4", "3\uc6d4", "4\uc6d4", "5\uc6d4", "6\uc6d4", "7\uc6d4", "8\uc6d4", "9\uc6d4", "10\uc6d4", "11\uc6d4", "12\uc6d4"], + ws: ["\uc77c", "\uc6d4", "\ud654", "\uc218", "\ubaa9", "\uae08", "\ud1a0"], + wl: ["\uc77c\uc694\uc77c", "\uc6d4\uc694\uc77c", "\ud654\uc694\uc77c", "\uc218\uc694\uc77c", "\ubaa9\uc694\uc77c", "\uae08\uc694\uc77c", "\ud1a0\uc694\uc77c"], + xf: "%Y\ub144 %B %d\uc77c", + Xf: "%H\uc2dc %M\ubd84 %S\ucd08", + cf: "%Y\ub144 %B %d\uc77c (%a) %p %I\uc2dc %M\ubd84 %S\ucd08" + }, + ja: { + ms: [" 1\u6708", " 2\u6708", " 3\u6708", " 4\u6708", " 5\u6708", " 6\u6708", " 7\u6708", " 8\u6708", " 9\u6708", "10\u6708", "11\u6708", "12\u6708"], + ml: ["1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708"], + ws: ["\u65e5", "\u6708", "\u706b", "\u6c34", "\u6728", "\u91d1", "\u571f"], + wl: ["\u65e5\u66dc\u65e5", "\u6708\u66dc\u65e5", "\u706b\u66dc\u65e5", "\u6c34\u66dc\u65e5", "\u6728\u66dc\u65e5", "\u91d1\u66dc\u65e5", "\u571f\u66dc\u65e5"], + xf: "%Y\u5e74%B%d\u65e5", + Xf: "%H\u6642%M\u5206%S\u79d2", + cf: "%Y\u5e74%B%d\u65e5 %H\u6642%M\u5206%S\u79d2" + } + }; + + let translation = translations[lang]; + + let result = []; + let inspec = false; + for (let i = 0; i < fmt.length; ++i) + { + let c = fmt[i]; + if (inspec) + { + switch (c) + { + case "a": + c = translation.ws[obj.getDay()]; + break; + case "A": + c = translation.wl[obj.getDay()]; + break; + case "b": + c = translation.ms[obj.getMonth()]; + break; + case "B": + c = translation.ml[obj.getMonth()]; + break; + case "c": + c = ul4._format(obj, translation.cf, lang); + break; + case "d": + c = ul4._lpad(obj.getDate(), "0", 2); + break; + case "f": + c = ul4._lpad(obj.getMilliseconds(), "0", 3) + "000"; + break; + case "H": + c = ul4._lpad(obj.getHours(), "0", 2); + break; + case "I": + c = ul4._lpad(((obj.getHours()-1) % 12)+1, "0", 2); + break; + case "j": + c = ul4._lpad(ul4.DateTimeProtocol.yearday(obj), "0", 3); + break; + case "m": + c = ul4._lpad(obj.getMonth()+1, "0", 2); + break; + case "M": + c = ul4._lpad(obj.getMinutes(), "0", 2); + break; + case "p": + c = obj.getHours() < 12 ? "AM" : "PM"; + break; + case "S": + c = ul4._lpad(obj.getSeconds(), "0", 2); + break; + case "U": + c = ul4._lpad(ul4._week4format(obj, 6), "0", 2); + break; + case "w": + c = obj.getDay(); + break; + case "W": + c = ul4._lpad(ul4._week4format(obj, 0), "0", 2); + break; + case "x": + c = ul4._format(obj, translation.xf, lang); + break; + case "X": + c = ul4._format(obj, translation.Xf, lang); + break; + case "y": + c = (obj.getFullYear() % 100).toString(); + break; + case "Y": + c = obj.getFullYear().toString(); + break; + case "z": + // UTC offset in the form +HHMM or -HHMM + c = ""; + break; + case "Z": + // Time zone name + c = ""; + break; + } + result.push(c); + inspec = false; + } + else + { + if (c == "%") + inspec = true; + else + result.push(c); + } + } + return result.join(""); + }; + + ul4._format_int = function _format_int(obj, fmt, lang) + { + let work = fmt; + + // Defaults + let fill = ' '; + let align = '>'; // '<', '>', '=' or '^' + let sign = '-'; // '+', '-' or ' ' + let alternate = false; + let minimumwidth = 0; + let type = 'd'; // 'b', 'c', 'd', 'o', 'x', 'X' or 'n' + + // Determine output type + if (/[bcdoxXn]$/.test(work)) + { + type = work.substring(work.length-1); + work = work.substring(0, work.length-1); + } + + // Extract minimum width + if (/\d+$/.test(work)) + { + let minimumwidthStr = /\d+$/.exec(work); + work = work.replace(/\d+$/, ""); + if (/^0/.test(minimumwidthStr)) + { + align = '='; + fill = '0'; + } + minimumwidth = parseInt(minimumwidthStr); + } + + // Alternate form? + if (/#$/.test(work)) + { + alternate = true; + work = work.substring(0, work.length-1); + } + + // Determine sign + if (/[+ -]$/.test(work)) + { + if (type == 'c') + throw new ul4.ValueError("sign not allowed for integer format type 'c'"); + sign = work.substring(work.length-1); + work = work.substring(0, work.length-1); + } + + // Extract fill and align char + if (work.length >= 3) + throw new ul4.ValueError("illegal integer format string " + ul4._repr(fmt)); + else if (work.length == 2) + { + if (/[<>=^]$/.test(work)) + { + align = work[1]; + fill = work[0]; + } + else + throw new ul4.ValueError("illegal integer format string " + ul4._repr(fmt)); + } + else if (work.length == 1) + { + if (/^[<>=^]$/.test(work)) + align = work; + else + throw new ul4.ValueError("illegal integer format string " + ul4._repr(fmt)); + } + + // Basic number formatting + let neg = obj < 0; + + if (neg) + obj = -obj; + + let output; + switch (type) + { + case 'b': + output = obj.toString(2); + break; + case 'c': + if (neg || obj > 65535) + throw new ul4.ValueError("value out of bounds for c format"); + output = String.fromCharCode(obj); + break; + case 'd': + output = obj.toString(); + break; + case 'o': + output = obj.toString(8); + break; + case 'x': + output = obj.toString(16); + break; + case 'X': + output = obj.toString(16).toUpperCase(); + break; + case 'n': + // FIXME: locale formatting + output = obj.toString(); + break; + } + + // The rest of the formatting + if (align === '=') + { + if (neg || sign !== '-') + --minimumwidth; + if (alternate && (type === 'b' || type === 'o' || type === 'x' || type === 'X')) + minimumwidth -= 2; + + if (output.length < minimumwidth) + output = ul4._str_repeat(fill, minimumwidth-output.length) + output; + + if (alternate && (type === 'b' || type === 'o' || type === 'x' || type === 'X')) + output = "0" + type + output; + + if (neg) + output = "-" + output; + else if (sign != '-') + output = sign + output; + } + else + { + if (alternate && (type == 'b' || type == 'o' || type == 'x' || type == 'X')) + output = "0" + type + output; + if (neg) + output = "-" + output; + else if (sign != '-') + output = sign + output; + if (output.length < minimumwidth) + { + if (align == '<') + output = output + ul4._str_repeat(fill, minimumwidth-output.length); + else if (align == '>') + output = ul4._str_repeat(fill, minimumwidth-output.length) + output; + else // if (align == '^') + { + let pad = minimumwidth - output.length; + let padBefore = Math.floor(pad/2); + let padAfter = pad-padBefore; + output = ul4._str_repeat(fill, padBefore) + output + ul4._str_repeat(fill, padAfter); + } + } + } + return output; + }; + + // Format ``obj`` using the format string ``fmt`` in the language ``lang`` + ul4._format = function _format(obj, fmt, lang) + { + if (typeof(lang) === "undefined" || lang === null) + lang = "en"; + else + { + let translations = {de: null, en: null, fr: null, es: null, it: null, da: null, sv: null, nl: null, pt: null, cs: null, sk: null, pl: null, hr: null, sr: null, ro: null, hu: null, tr: null, ru: null, zh: null, ko: null, ja: null}; + lang = lang.toLowerCase(); + if (typeof(translations[lang]) === "undefined") + { + lang = lang.split(/_/)[0]; + if (typeof(translations[lang]) === "undefined") + lang = "en"; + } + } + if (ul4._isdate(obj)) + return ul4._format_datetime(obj._date, fmt, lang); + if (ul4._isdatetime(obj)) + return ul4._format_datetime(obj, fmt, lang); + else if (ul4._isint(obj)) + return ul4._format_int(obj, fmt, lang); + else if (obj === true) + return ul4._format_int(1, fmt, lang); + else if (obj === false) + return ul4._format_int(0, fmt, lang); + }; + + ul4._lpad = function _lpad(string, pad, len) + { + if (typeof(string) === "number") + string = string.toString(); + while (string.length < len) + string = pad + string; + return string; + }; + + ul4._rpad = function _rpad(string, pad, len) + { + if (typeof(string) === "number") + string = string.toString(); + while (string.length < len) + string = string + pad; + return string; + }; + + // This is outside of ``Proto`` on purpose + // This way reactive frameworks like ``Vue.js`` don't get to see it + // and complain about mutating render functions when those create new objects. + let _nextid = 1; + + ul4.Proto = class Proto + { + constructor() + { + this.__id__ = _nextid++; + } + + ul4type() + { + return this.constructor.name; + } + + // equality comparison of objects defaults to identity comparison + __eq__(other) + { + return this === other; + } + + // To overwrite equality comparison, you only have to overwrite ``__eq__``, + // ``__ne__`` will be synthesized from that + __ne__(other) + { + return !this.__eq__(other); + } + + // For other comparison operators, each method has to be implemented: + // ``<`` calls ``__lt__``, ``<=`` calls ``__le__``, ``>`` calls ``__gt__`` and + // ``>=`` calls ``__ge__`` + + __bool__() + { + return true; + } + }; + + ul4.Signature = class Signature extends ul4.Proto + { + constructor(...args) + { + super(); + this.args = []; + this.argNames = {}; + this.remargs = null; + this.remkwargs = null; + + let nextDefault = false; + let lastArgname = null; + for (let i = 0; i < args.length; ++i) + { + let argName = args[i]; + if (nextDefault) + { + this.args.push({name: lastArgname, defaultValue: argName}); + this.argNames[lastArgname] = true; + nextDefault = false; + } + else + { + if (argName.substr(argName.length-1) === "=") + { + lastArgname = argName.substr(0, argName.length-1); + nextDefault = true; + } + else if (argName.substr(0, 2) === "**") + this.remkwargs = argName.substr(2); + else if (argName.substr(0, 1) === "*") + this.remargs = argName.substr(1); + else + { + this.args.push({name: argName}); + this.argNames[argName] = true; + } + } + } + } + + // Create the argument array for calling a function with this signature with the arguments available from ``args`` + bindArray(name, args, kwargs) + { + let finalargs = []; + let decname = name !== null ? name + "() " : ""; + + for (let i = 0; i < this.args.length; ++i) + { + let arg = this.args[i]; + if (i < args.length) + { + if (kwargs.hasOwnProperty(arg.name)) + throw new ul4.ArgumentError(decname + "argument " + ul4._repr(arg.name) + " (position " + i + ") specified multiple times"); + finalargs.push(args[i]); + } + else + { + if (kwargs.hasOwnProperty(arg.name)) + finalargs.push(kwargs[arg.name]); + else + { + if (arg.hasOwnProperty("defaultValue")) + finalargs.push(arg.defaultValue); + else + throw new ul4.ArgumentError("required " + decname + "argument " + ul4._repr(arg.name) + " (position " + i + ") missing"); + } + } + } + + // Do we accept additional positional arguments? + if (this.remargs === null) + { + // No, but we have them -> complain + if (args.length > this.args.length) + { + let prefix = name === null ? "expected" : name + "() expects"; + throw new ul4.ArgumentError(prefix + " at most " + this.args.length + " positional argument" + (this.args.length != 1 ? "s" : "") + ", " + args.length + " given"); + } + } + else + { + // Put additional positional arguments in the call into the ``*`` argument (if there are none, this pushes an empty list) + finalargs.push(args.slice(this.args.length)); + } + + // Do we accept arbitrary keyword arguments? + if (this.remkwargs === null) + { + // No => complain about unknown ones + for (let key in kwargs) + { + if (!this.argNames[key]) + { + if (name === null) + throw new ul4.ArgumentError("an argument named " + ul4._repr(key) + " isn't supported"); + else + throw new ul4.ArgumentError(name + "() doesn't support an argument named " + ul4._repr(key)); + } + } + } + else + { + // Yes => Put the unknown ones into an object and add that to the arguments array + let remkwargs = ul4._emptymap(); + for (let key in kwargs) + { + if (!this.argNames[key]) + ul4._setmap(remkwargs, key, kwargs[key]); + } + finalargs.push(remkwargs); + } + + return finalargs; + } + + // Create the argument object for calling a function with this signature with the arguments available from ``args`` + bindObject(name, args, kwargs) + { + args = this.bindArray(name, args, kwargs); + let argObject = {}; + let i; + for (i = 0; i < this.args.length; ++i) + argObject[this.args[i].name] = args[i]; + if (this.remargs !== null) + argObject[this.remargs] = args[i++]; + if (this.remkwargs !== null) + argObject[this.remkwargs] = args[i++]; + return argObject; + } + + __repr__() + { + return ""; + } + + __str__() + { + return this.toString(); + } + + toString() + { + let v = []; + for (let i = 0; i < this.args.length; ++i) + { + let arg = this.args[i]; + if (arg.hasOwnProperty("defaultValue")) + v.push(arg.name + "=" + ul4._repr(arg.defaultValue)); + else + v.push(arg.name); + } + if (this.remargs !== null) + v.push("*" + this.remargs); + if (this.remkwargs !== null) + v.push("**" + this.remkwargs); + return "(" + v.join(", ") + ")"; + } + }; + + // When we don't have a real ``Set`` type, emulate one that supports strings + ul4._Set = class _Set + { + constructor(...items) + { + this.items = {}; + this.add(...items); + } + + add(...items) + { + for (let i = 0; i < items.length; ++i) + this.items[items[i]] = true; + } + + clear() + { + this.items = {}; + } + + __getattr__(attrname) + { + let self = this; + switch (attrname) + { + case "add": + return ul4.expose(function add(items){ self.add(...items); }, ["*items"]); + default: + throw new ul4.AttributeError(this, attrname); + } + } + + __contains__(item) + { + return this.items[item] || false; + } + + has(item) + { + return this.items[item] || false; + } + + __bool__() + { + for (let item in this.items) + { + if (!this.items.hasOwnProperty(item)) + continue; + return true; + } + return false; + } + + __repr__() + { + let v = []; + v.push("{"); + let i = 0; + for (let item in this.items) + { + if (!this.items.hasOwnProperty(item)) + continue; + if (i++) + v.push(", "); + v.push(ul4._repr(item)); + } + if (!i) + v.push("/"); + v.push("}"); + return v.join(""); + } + + __eq__(other) + { + // We'll check that everything in ``this`` is in ``other`` + // and if both have the same number of items they are equal + if (ul4._isset(other)) + { + let count = 0; + for (let item in this.items) + { + if (!other.has(item)) + return false; + // count the number of items we have + ++count; + } + return other.size == count; + } + else if (ul4._isul4set(other)) + { + let count = 0; + for (let item in this.items) + { + if (!other[item]) + return false; + // count the number of items we have + ++count; + } + // Subtract the number of items that ``other`` has + for (let item in other.items) + --count; + return count == 0; + } + else + return false; + } + + __le__(other) + { + // check that ``this`` is a subset of ``other``, + // i.e. everything in ``this`` is also in ``other`` + if (ul4._isset(other)) + { + let count = 0; + for (let item in this.items) + { + if (!other.has(item)) + return false; + } + return true; + } + else if (ul4._isul4set(other)) + { + let count = 0; + for (let item in this.items) + { + if (!other.items[item]) + return false; + } + return true; + } + else + ul4._unorderable("<", this, other); + } + + __ge__(other) + { + // check that ``this`` is a superset of ``other``, + // i.e. everything in ``other`` is also in ``this`` + if (ul4._isset(other)) + { + other.forEach(function(value) { + if (!this.items[value]) + return false; + }, this); + return true; + } + else if (ul4._isul4set(other)) + { + let count = 0; + for (let key in other.items) + { + if (!this.items[key]) + return false; + } + return true; + } + else + ul4._unorderable("<=", this, other); + } + }; + + ul4._Set.prototype.__type__ = "set"; + + // Adds name and signature to a function/method and makes the method callable in templates + ul4.expose = function expose(f, signature, options) + { + options = options || {}; + if (options.name) + f._ul4_name = options.name; + if (ul4._islist(signature)) + signature = new ul4.Signature(...signature); + f._ul4_signature = signature; + f._ul4_needsobject = options.needsobject || false; + f._ul4_needscontext = options.needscontext || false; + }; + + // Protocol objects for all builtin types + // These objects are singleton, so we replace the constructor with the prototype object afterwards + ul4.Protocol = class Protocol + { + ul4type() + { + return this.constructor.name; + } + + dir() + { + return this.attrs; + } + + get(obj) + { + if (ul4._isstr(obj)) + return ul4.StrProtocol; + else if (ul4._islist(obj)) + return ul4.ListProtocol; + else if (ul4._isdate(obj)) + return ul4.DateProtocol; + else if (ul4._isset(obj)) + return ul4.SetProtocol; + else if (ul4._ismap(obj)) + return ul4.MapProtocol; + else if (ul4._isdatetime(obj)) + return ul4.DateTimeProtocol; + else if (ul4._isobject(obj)) + return ul4.ObjectProtocol; + else + return ul4.Protocol; + } + + getattr(obj, attrname) + { + if (obj === null || typeof(obj) === "undefined") + throw new ul4.AttributeError(obj, attrname); + else if (typeof(obj.__getattr__) === "function") + return obj.__getattr__(attrname); + else if (this.attrs.has(attrname)) + { + let attr = this[attrname]; + let realattr = function realattr(...args) { + return attr.apply(this, [obj, ...args]); + }; + realattr.name = attr.name; + realattr._ul4_name = attr._ul4_name || attr.name; + realattr._ul4_signature = attr._ul4_signature; + realattr._ul4_needsobject = attr._ul4_needsobject; + realattr._ul4_needscontext = attr._ul4_needscontext; + return realattr; + } + else + throw new ul4.AttributeError(obj, attrname); + } + + hasattr(obj, attrname) + { + if (obj === null || typeof(obj) === "undefined") + return false; + else if (typeof(obj.__getattr__) === "function") + { + try + { + obj.__getattr__(attrname); + return true; + } + catch (exc) + { + if (exc instanceof ul4.AttributeError && exc.obj === object) + return false; + else + throw exc; + } + } + else + return this.attrs.has(attrname); + } + }; + + ul4.Protocol = ul4.Protocol.prototype; + ul4.Protocol.attrs = ul4._emptyset(); + + ul4.StrProtocol = class StrProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "str"; + } + + count(obj, sub, start=null, end=null) + { + return ul4._count(obj, sub, start, end); + } + + find(obj, sub, start=null, end=null) + { + return ul4._find(obj, sub, start, end); + } + + rfind(obj, sub, start=null, end=null) + { + return ul4._rfind(obj, sub, start, end); + } + + replace(obj, old, new_, count=null) + { + if (count === null) + count = obj.length; + + let result = []; + while (obj.length) + { + let pos = obj.indexOf(old); + if (pos === -1 || !count--) + { + result.push(obj); + break; + } + result.push(obj.substr(0, pos)); + result.push(new_); + obj = obj.substr(pos + old.length); + } + return result.join(""); + } + + strip(obj, chars=null) + { + chars = chars || " \r\n\t"; + if (typeof(chars) !== "string") + throw new ul4.TypeError("strip() requires a string argument"); + + while (obj && chars.indexOf(obj[0]) >= 0) + obj = obj.substr(1); + while (obj && chars.indexOf(obj[obj.length-1]) >= 0) + obj = obj.substr(0, obj.length-1); + return obj; + } + + lstrip(obj, chars=null) + { + chars = chars || " \r\n\t"; + if (typeof(chars) !== "string") + throw new ul4.TypeError("lstrip() requires a string argument"); + + while (obj && chars.indexOf(obj[0]) >= 0) + obj = obj.substr(1); + return obj; + } + + rstrip(obj, chars=null) + { + chars = chars || " \r\n\t"; + if (typeof(chars) !== "string") + throw new ul4.TypeError("rstrip() requires a string argument"); + + while (obj && chars.indexOf(obj[obj.length-1]) >= 0) + obj = obj.substr(0, obj.length-1); + return obj; + } + + split(obj, sep=null, count=null) + { + if (sep !== null && typeof(sep) !== "string") + throw new ul4.TypeError("split() requires a string"); + + if (count === null) + { + let result = obj.split(sep !== null ? sep : /[ \n\r\t]+/); + if (sep === null) + { + if (result.length && !result[0].length) + result.splice(0, 1); + if (result.length && !result[result.length-1].length) + result.splice(-1); + } + return result; + } + else + { + if (sep !== null) + { + let result = []; + while (obj.length) + { + let pos = obj.indexOf(sep); + if (pos === -1 || !count--) + { + result.push(obj); + break; + } + result.push(obj.substr(0, pos)); + obj = obj.substr(pos + sep.length); + } + return result; + } + else + { + let result = []; + while (obj.length) + { + obj = ul4.StrProtocol.lstrip(obj, null); + let part; + if (!count--) + part = obj; // Take the rest of the string + else + part = obj.split(/[ \n\r\t]+/, 1)[0]; + if (part.length) + result.push(part); + obj = obj.substr(part.length); + } + return result; + } + } + } + + rsplit(obj, sep=null, count=null) + { + if (sep !== null && typeof(sep) !== "string") + throw new ul4.TypeError("rsplit() requires a string as second argument"); + + if (count === null) + { + let result = obj.split(sep !== null ? sep : /[ \n\r\t]+/); + if (sep === null) + { + if (result.length && !result[0].length) + result.splice(0, 1); + if (result.length && !result[result.length-1].length) + result.splice(-1); + } + return result; + } + else + { + if (sep !== null) + { + let result = []; + while (obj.length) + { + let pos = obj.lastIndexOf(sep); + if (pos === -1 || !count--) + { + result.unshift(obj); + break; + } + result.unshift(obj.substr(pos+sep.length)); + obj = obj.substr(0, pos); + } + return result; + } + else + { + let result = []; + while (obj.length) + { + obj = ul4.StrProtocol.rstrip(obj); + let part; + if (!count--) + part = obj; // Take the rest of the string + else + { + part = obj.split(/[ \n\r\t]+/); + part = part[part.length-1]; + } + if (part.length) + result.unshift(part); + obj = obj.substr(0, obj.length-part.length); + } + return result; + } + } + } + + splitlines(obj, keepends=false) + { + let pos = 0; + let lookingAtLineEnd = function lookingAtLineEnd() + { + let c = obj[pos]; + if (c === '\n' || c == '\u000B' || c == '\u000C' || c == '\u001C' || c == '\u001D' || c == '\u001E' || c == '\u0085' || c == '\u2028' || c == '\u2029') + return 1; + if (c === '\r') + { + if (pos == length-1) + return 1; + if (obj[pos+1] === '\n') + return 2; + return 1; + } + return 0; + }; + + let result = [], length = obj.length; + + for (pos = 0, startpos = 0;;) + { + if (pos >= length) + { + if (startpos != pos) + result.push(obj.substring(startpos)); + return result; + } + let lineendlen = lookingAtLineEnd(); + if (!lineendlen) + ++pos; + else + { + let endpos = pos + (keepends ? lineendlen : 0); + result.push(obj.substring(startpos, endpos)); + pos += lineendlen; + startpos = pos; + } + } + } + + lower(obj) + { + return obj.toLowerCase(); + } + + upper(obj) + { + return obj.toUpperCase(); + } + + capitalize(obj) + { + if (obj.length) + obj = obj[0].toUpperCase() + obj.slice(1).toLowerCase(); + return obj; + } + + join(obj, iterable) + { + let resultlist = []; + for (let iter = ul4._iter(iterable);;) + { + let item = iter.next(); + if (item.done) + break; + resultlist.push(item.value); + } + return resultlist.join(obj); + } + + startswith(obj, prefix) + { + if (typeof(prefix) === "string") + return obj.substr(0, prefix.length) === prefix; + else if (ul4._islist(prefix)) + { + for (let i = 0; i < prefix.length; ++i) + { + let singlepre = prefix[i]; + if (obj.substr(0, singlepre.length) === singlepre) + return true; + } + return false; + } + else + throw new ul4.TypeError("startswith() argument must be string"); + } + + endswith(obj, suffix) + { + if (typeof(suffix) === "string") + return obj.substr(obj.length-suffix.length) === suffix; + else if (ul4._islist(suffix)) + { + for (let i = 0; i < suffix.length; ++i) + { + let singlesuf = suffix[i]; + if (obj.substr(obj.length-singlesuf.length) === singlesuf) + return true; + } + return false; + } + else + throw new ul4.TypeError("endswith() argument must be string or list of strings"); + } + }; + + ul4.StrProtocol = ul4.StrProtocol.prototype; + ul4.StrProtocol.attrs = ul4._makeset( + "split", + "rsplit", + "splitlines", + "strip", + "lstrip", + "rstrip", + "upper", + "lower", + "capitalize", + "startswith", + "endswith", + "replace", + "count", + "find", + "rfind", + "join" + ); + + ul4.expose(ul4.StrProtocol.count, ["sub", "start=", null, "end=", null]); + ul4.expose(ul4.StrProtocol.find, ["sub", "start=", null, "end=", null]); + ul4.expose(ul4.StrProtocol.rfind, ["sub", "start=", null, "end=", null]); + ul4.expose(ul4.StrProtocol.replace, ["old", "new", "count=", null]); + ul4.expose(ul4.StrProtocol.strip, ["chars=", null]); + ul4.expose(ul4.StrProtocol.lstrip, ["chars=", null]); + ul4.expose(ul4.StrProtocol.rstrip, ["chars=", null]); + ul4.expose(ul4.StrProtocol.split, ["sep=", null, "count=", null]); + ul4.expose(ul4.StrProtocol.rsplit, ["sep=", null, "count=", null]); + ul4.expose(ul4.StrProtocol.splitlines, ["keepends=", false]); + ul4.expose(ul4.StrProtocol.lower, []); + ul4.expose(ul4.StrProtocol.upper, []); + ul4.expose(ul4.StrProtocol.capitalize, []); + ul4.expose(ul4.StrProtocol.join, ["iterable"]); + ul4.expose(ul4.StrProtocol.startswith, ["prefix"]); + ul4.expose(ul4.StrProtocol.endswith, ["suffix"]); + + ul4.ListProtocol = class ListProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "list"; + } + + append(obj, items) + { + for (let i = 0; i < items.length; ++i) + obj.push(items[i]); + return null; + } + + insert(obj, pos, items) + { + if (pos < 0) + pos += obj.length; + + for (let i = 0; i < items.length; ++i) + obj.splice(pos++, 0, items[i]); + return null; + } + + pop(obj, pos) + { + if (pos < 0) + pos += obj.length; + + let result = obj[pos]; + obj.splice(pos, 1); + return result; + } + + count(obj, sub, start=null, end=null) + { + return ul4._count(obj, sub, start, end); + } + + find(obj, sub, start=null, end=null) + { + return ul4._find(obj, sub, start, end); + } + + rfind(obj, sub, start=null, end=null) + { + return ul4._rfind(obj, sub, start, end); + } + }; + + ul4.ListProtocol = ul4.ListProtocol.prototype; + ul4.ListProtocol.attrs = ul4._makeset( + "append", + "insert", + "pop", + "count", + "find", + "rfind" + ); + + ul4.expose(ul4.ListProtocol.append, ["*items"]); + ul4.expose(ul4.ListProtocol.insert, ["pos", "*items"]); + ul4.expose(ul4.ListProtocol.pop, ["pos=", -1]); + ul4.expose(ul4.ListProtocol.count, ["sub", "start=", null, "end=", null]); + ul4.expose(ul4.ListProtocol.find, ["sub", "start=", null, "end=", null]); + ul4.expose(ul4.ListProtocol.rfind, ["sub", "start=", null, "end=", null]); + + ul4.MapProtocol = class MapProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "dict"; + } + + getattr(obj, attrname) + { + if (this.attrs.has(attrname)) + { + let attr = this[attrname]; + let realattr = function realattr(...args) { + return attr.apply(this, [obj, ...args]); + }; + realattr.name = attr.name; + realattr._ul4_name = attr._ul4_name || attr.name; + realattr._ul4_signature = attr._ul4_signature; + realattr._ul4_needsobject = attr._ul4_needsobject; + realattr._ul4_needscontext = attr._ul4_needscontext; + return realattr; + } + else + return obj.get(attrname); + } + + get(obj, key, default_=null) + { + if (obj.has(key)) + return obj.get(key); + return default_; + } + + items(obj) + { + let result = []; + obj.forEach(function(value, key) { + result.push([key, value]); + }); + return result; + } + + values(obj) + { + let result = []; + obj.forEach(function(value, key) { + result.push(value); + }); + return result; + } + + update(obj, other, kwargs) + { + return ul4._update(obj, other, kwargs); + } + + clear(obj) + { + obj.clear(); + return null; + } + }; + + ul4.MapProtocol = ul4.MapProtocol.prototype; + ul4.MapProtocol.attrs = ul4._makeset("get", "items", "values", "update", "clear"); + + ul4.expose(ul4.MapProtocol.get, ["key", "default=", null]); + ul4.expose(ul4.MapProtocol.items, []); + ul4.expose(ul4.MapProtocol.values, []); + ul4.expose(ul4.MapProtocol.update, ["*other", "**kwargs"]); + ul4.expose(ul4.MapProtocol.clear, []); + + ul4.SetProtocol = class SetProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "set"; + } + + add(obj, items) + { + for (let i = 0; i < items.length; ++i) + { + obj.add(items[i]); + } + } + + clear(obj) + { + obj.clear(); + return null; + } + }; + + ul4.SetProtocol = ul4.SetProtocol.prototype; + ul4.SetProtocol.attrs = ul4._makeset("add", "clear"); + + ul4.expose(ul4.SetProtocol.add, ["*items"]); + ul4.expose(ul4.SetProtocol.clear, []); + + ul4.DateProtocol = class DateProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "date"; + } + + weekday(obj) + { + return ul4.DateTimeProtocol.weekday(obj._date); + } + + calendar(obj, firstweekday=0, mindaysinfirstweek=4) + { + return ul4.DateTimeProtocol.calendar(obj._date, firstweekday, mindaysinfirstweek); + } + + week(obj, firstweekday=0, mindaysinfirstweek=4) + { + return ul4.DateProtocol.calendar(obj, firstweekday, mindaysinfirstweek)[1]; + } + + day(obj) + { + return obj._date.getDate(); + } + + month(obj) + { + return obj._date.getMonth()+1; + } + + year(obj) + { + return obj._date.getFullYear(); + } + + mimeformat(obj) + { + let weekdayname = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; + let monthname = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + let d = obj._date; + + return weekdayname[ul4.DateTimeProtocol.weekday(d)] + ", " + ul4._lpad(d.getDate(), "0", 2) + " " + monthname[d.getMonth()] + " " + d.getFullYear(); + } + + isoformat(obj) + { + let d = obj._date; + return d.getFullYear() + "-" + ul4._lpad((d.getMonth()+1).toString(), "0", 2) + "-" + ul4._lpad(d.getDate().toString(), "0", 2); + } + + yearday(obj) + { + return ul4.DateTimeProtocol.yearday(obj._date); + } + }; + + ul4.DateProtocol = ul4.DateProtocol.prototype; + ul4.DateProtocol.attrs = ul4._makeset("weekday", "week", "calendar", "day", "month", "year", "mimeformat", "isoformat", "yearday"); + + ul4.expose(ul4.DateProtocol.weekday, []); + ul4.expose(ul4.DateProtocol.calendar, ["firstweekday=", 0, "mindaysinfirstweek=", 4]); + ul4.expose(ul4.DateProtocol.week, ["firstweekday=", 0, "mindaysinfirstweek=", 4]); + ul4.expose(ul4.DateProtocol.day, []); + ul4.expose(ul4.DateProtocol.month, []); + ul4.expose(ul4.DateProtocol.year, []); + ul4.expose(ul4.DateProtocol.mimeformat, []); + ul4.expose(ul4.DateProtocol.isoformat, []); + ul4.expose(ul4.DateProtocol.yearday, []); + + ul4.DateTimeProtocol = class DatetimeProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "datetime"; + } + + weekday(obj) + { + let d = obj.getDay(); + return d ? d-1 : 6; + } + + calendar(obj, firstweekday=0, mindaysinfirstweek=4) + { + // Normalize parameters + firstweekday = ul4._mod(firstweekday, 7); + if (mindaysinfirstweek < 1) + mindaysinfirstweek = 1; + else if (mindaysinfirstweek > 7) + mindaysinfirstweek = 7; + + // ``obj`` might be in the first week of the next year, or last week of + // the previous year, so we might have to try those too. + for (let offset = +1; offset >= -1; --offset) + { + let year = obj.getFullYear() + offset; + // ``refdate`` will always be in week 1 + let refDate = new Date(year, 0, mindaysinfirstweek); + // Go back to the start of ``refdate``s week (i.e. day 1 of week 1) + let weekDayDiff = ul4._mod(ul4.DateTimeProtocol.weekday(refDate) - firstweekday, 7); + let weekStartYear = refDate.getFullYear(); + let weekStartMonth = refDate.getMonth(); + let weekStartDay = refDate.getDate() - weekDayDiff; + let weekStart = new Date(weekStartYear, weekStartMonth, weekStartDay); + // Is our date ``obj`` at or after day 1 of week 1? + if (obj.getTime() >= weekStart.getTime()) + { + let diff = ul4.SubAST.prototype._do(obj, weekStart); + // Add 1, because the first week is week 1, not week 0 + let week = Math.floor(diff.days()/7) + 1; + return [year, week, ul4.DateTimeProtocol.weekday(obj)]; + } + } + } + + week(obj, firstweekday=0, mindaysinfirstweek=4) + { + return ul4.DateTimeProtocol.calendar(obj, firstweekday, mindaysinfirstweek)[1]; + } + + day(obj) + { + return obj.getDate(); + } + + month(obj) + { + return obj.getMonth()+1; + } + + year(obj) + { + return obj.getFullYear(); + } + + hour(obj) + { + return obj.getHours(); + } + + minute(obj) + { + return obj.getMinutes(); + } + + second(obj) + { + return obj.getSeconds(); + } + + microsecond(obj) + { + return obj.getMilliseconds() * 1000; + } + + mimeformat(obj) + { + let weekdayname = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; + let monthname = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + + return weekdayname[ul4.DateTimeProtocol.weekday(obj)] + ", " + ul4._lpad(obj.getDate(), "0", 2) + " " + monthname[obj.getMonth()] + " " + obj.getFullYear() + " " + ul4._lpad(obj.getHours(), "0", 2) + ":" + ul4._lpad(obj.getMinutes(), "0", 2) + ":" + ul4._lpad(obj.getSeconds(), "0", 2) + " GMT"; + } + + isoformat(obj) + { + let year = obj.getFullYear(); + let month = obj.getMonth()+1; + let day = obj.getDate(); + let hour = obj.getHours(); + let minute = obj.getMinutes(); + let second = obj.getSeconds(); + let ms = obj.getMilliseconds(); + let result = year + "-" + ul4._lpad(month.toString(), "0", 2) + "-" + ul4._lpad(day.toString(), "0", 2) + "T" + ul4._lpad(hour.toString(), "0", 2) + ":" + ul4._lpad(minute.toString(), "0", 2) + ":" + ul4._lpad(second.toString(), "0", 2); + if (ms) + result += "." + ul4._lpad(ms.toString(), "0", 3) + "000"; + return result; + } + + yearday(obj) + { + let leap = ul4._isleap(obj) ? 1 : 0; + let day = obj.getDate(); + switch (obj.getMonth()) + { + case 0: + return day; + case 1: + return 31 + day; + case 2: + return 31 + 28 + leap + day; + case 3: + return 31 + 28 + leap + 31 + day; + case 4: + return 31 + 28 + leap + 31 + 30 + day; + case 5: + return 31 + 28 + leap + 31 + 30 + 31 + day; + case 6: + return 31 + 28 + leap + 31 + 30 + 31 + 30 + day; + case 7: + return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + day; + case 8: + return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + day; + case 9: + return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + day; + case 10: + return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + day; + case 11: + return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + day; + } + } + }; + + ul4.DateTimeProtocol = ul4.DateTimeProtocol.prototype; + ul4.DateTimeProtocol.attrs = ul4._makeset("weekday", "week", "calendar", "day", "month", "year", "hour", "minute", "second", "microsecond", "mimeformat", "isoformat", "yearday"); + + ul4.expose(ul4.DateTimeProtocol.weekday, []); + ul4.expose(ul4.DateTimeProtocol.calendar, ["firstweekday=", 0, "mindaysinfirstweek=", 4]); + ul4.expose(ul4.DateTimeProtocol.week, ["firstweekday=", 0, "mindaysinfirstweek=", 4]); + ul4.expose(ul4.DateTimeProtocol.day, []); + ul4.expose(ul4.DateTimeProtocol.month, []); + ul4.expose(ul4.DateTimeProtocol.year, []); + ul4.expose(ul4.DateTimeProtocol.hour, []); + ul4.expose(ul4.DateTimeProtocol.minute, []); + ul4.expose(ul4.DateTimeProtocol.second, []); + ul4.expose(ul4.DateTimeProtocol.microsecond, []); + ul4.expose(ul4.DateTimeProtocol.mimeformat, []); + ul4.expose(ul4.DateTimeProtocol.isoformat, []); + ul4.expose(ul4.DateTimeProtocol.yearday, []); + + ul4.ObjectProtocol = class ObjectProtocol extends ul4.Protocol.constructor + { + ul4type(obj) + { + return "dict"; + } + + getattr(obj, attrname) + { + let result; + if (obj && typeof(obj.__getattr__) === "function") // test this before the generic object test + result = obj.__getattr__(attrname); + else + result = obj[attrname]; + if (typeof(result) !== "function") + return result; + let realresult = function(...args) { + // We can use ``apply`` here, as we know that ``obj`` is a real object. + return result.apply(obj, args); + }; + realresult._ul4_name = result._ul4_name || result.name; + realresult._ul4_signature = result._ul4_signature; + realresult._ul4_needsobject = result._ul4_needsobject; + realresult._ul4_needscontext = result._ul4_needscontext; + return realresult; + } + + get(obj, key, default_=null) + { + let result = obj[key]; + if (typeof(result) === "undefined") + return default_; + return result; + } + + items(obj) + { + let result = []; + for (let key in obj) + result.push([key, obj[key]]); + return result; + } + + values(obj) + { + let result = []; + for (let key in obj) + result.push(obj[key]); + return result; + } + + clear(obj) + { + for (let key in obj) + delete obj[key]; + } + }; + + ul4.ObjectProtocol = ul4.ObjectProtocol.prototype; + ul4.ObjectProtocol.attrs = ul4._makeset("get", "items", "values", "update", "clear"); + + ul4.expose(ul4.ObjectProtocol.get, ["key", "default=", null]); + ul4.expose(ul4.ObjectProtocol.items, []); + ul4.expose(ul4.ObjectProtocol.values, []); + ul4.expose(ul4.ObjectProtocol.clear, []); + + ul4.Context = class Context + { + constructor(vars) + { + if (vars === null || typeof(vars) === "undefined") + vars = {}; + this.vars = vars; + this.indents = []; + this.escapes = []; + this._output = []; + } + + /* Return a clone of the ``Context``, but with a fresh empty ``vars`` objects that inherits from the previous one. + * This is used by the various comprehensions to avoid leaking loop variables. + */ + inheritvars() + { + let context = Object.create(this); + context.vars = Object.create(this.vars); + return context; + } + + /* Return a clone of the ``Context`` with one additional indentation (this is used by ``RenderAST``) */ + withindent(indent) + { + let context = Object.create(this); + if (indent !== null) + { + context.indents = this.indents.slice(); + context.indents.push(indent); + } + return context; + } + + /* Return a clone of the ``Context`` with the output buffer replaced (this is used by ``renders`` to collect the output in a separate buffer) */ + replaceoutput() + { + let context = Object.create(this); + context._output = []; + return context; + } + + clone(vars) + { + return Object.create(this); + } + + output(value) + { + for (let i = 0; i < this.escapes.length; ++i) + { + let escape = this.escapes[i]; + value = escape(value); + } + this._output.push(value); + } + + getoutput() + { + return this._output.join(""); + } + + get(name) + { + return this.vars[name]; + } + + set(name, value) + { + this.vars[name] = value; + } + }; + + /// Exceptions + + // Note that extending ``Error`` doesn't work, so we do it the "classic" way + ul4.Exception = function Exception(message, fileName, lineNumber) + { + let instance = new Error(message, fileName, lineNumber); + Object.setPrototypeOf(instance, Object.getPrototypeOf(this)); + instance.__id__ = _nextid++; + instance.context = null; + return instance; + }; + + ul4.Exception.prototype = Object.create(Error.prototype, { + constructor: { + value: Error, + enumerable: false, + writable: true, + configurable: true + } + }); + + if (Object.setPrototypeOf) + Object.setPrototypeOf(ul4.Exception, Error); + else + ul4.Exception.__proto__ = Error; + + ul4.Exception.prototype.__getattr__ = function __getattr__(attrname) + { + switch (attrname) + { + case "context": + return this.context; + default: + throw new ul4.AttributeError(this, attrname); + } + }; + + // Exceptions used internally by UL4 for flow control + ul4.InternalException = class InternalException extends ul4.Exception + { + }; + + // Control flow exceptions + ul4.ReturnException = class ReturnException extends ul4.InternalException + { + constructor(result) + { + super("return"); + this.result = result; + } + }; + + ul4.BreakException = class BreakException extends ul4.InternalException + { + constructor() + { + super("break"); + } + }; + + ul4.ContinueException = class ContinueException extends ul4.InternalException + { + constructor() + { + super("continue"); + } + }; + + // Real exceptions raised by various parts of UL4 + ul4.SyntaxError = class SyntaxError extends ul4.Exception + { + }; + + ul4.LValueRequiredError = class LValueRequiredError extends ul4.SyntaxError + { + constructor() + { + super("lvalue required"); + } + }; + + ul4.TypeError = class TypeError extends ul4.Exception + { + }; + + ul4.ValueError = class ValueError extends ul4.Exception + { + }; + + ul4.ArgumentError = class ArgumentError extends ul4.Exception + { + }; + + ul4.NotSubscriptableError = class NotSubscriptableError extends ul4.Exception + { + constructor(obj) + { + super("Object of type " + _type(obj) + " is not subscriptable"); + this.obj = obj; + } + + toString() + { + return "Object of type " + _type(this.obj) + " is not subscriptable"; + } + }; + + ul4.ZeroDivisionError = class ZeroDivisionError extends ul4.Exception + { + constructor() + { + super("division by zero"); + } + }; + + ul4.IndexError = class IndexError extends ul4.Exception + { + constructor(obj, index) + { + super("index " + ul4._repr(index) + " out of range"); + this.obj = obj; + this.index = index; + } + + toString() + { + return "index " + this.index + " out of range for " + ul4._type(this.obj); + } + }; + + ul4.AttributeError = class AttributeError extends ul4.Exception + { + constructor(obj, attrname) + { + super("object of type " + ul4._type(obj) + " has no attribute " + ul4._repr(attrname)); + this.obj = obj; + this.attrname = attrname; + } + }; + + /// Exception that wraps other exceptions while they bubble up the stack + ul4.LocationError = class LocationError extends ul4.Exception + { + constructor(location) + { + super("nested exception in " + ul4._repr(location)); + this.location = location; + } + + _templateprefix() + { + let template = this.location.template; + let out = []; + if (template.parenttemplate !== null) + out.push("in local template "); + else + out.push("in template "); + let first = true; + while (template != null) + { + if (first) + first = false; + else + out.push(" in "); + out.push(template.name ? ul4._repr(template.name) : "(unnamed)"); + template = template.parenttemplate; + } + return out.join(""); + } + + toString() + { + let template = this.location.template; + let templateprefix = this._templateprefix(); + + let prefix = this.location.sourceprefix; + let code = this.location.source; + let suffix = this.location.sourcesuffix; + prefix = ul4._repr(prefix).slice(1, -1); + code = ul4._repr(code).slice(1, -1); + suffix = ul4._repr(suffix).slice(1, -1); + + let text = prefix + code + suffix; + let underline = ul4._str_repeat("\u00a0", prefix.length) + ul4._str_repeat("~", code.length); + + let pos = "offset " + this.location.pos.start + ":" + this.location.pos.stop + "; line " + this.location.line + "; col " + this.location.col; + + let message = templateprefix + ": " + pos + "\n" + text + "\n" + underline; + return message; + } + + __getattr__(attrname) + { + switch (attrname) + { + case "context": + return this.context; + case "location": + return this.location; + default: + throw new ul4.AttributeError(this, attrname); + } + } + }; + + /// Classes for the syntax tree + ul4.AST = class AST extends ul4.Proto + { + constructor(template, pos) + { + super(); + this.template = template; + this.pos = pos; + this._line = null; + this._col = null; + } + + get fullsource() + { + return this.template._source; + } + + get source() + { + return this.pos.of(this.template._source); + } + + get sourceprefix() + { + let outerstartpos = this.pos.start; + let innerstartpos = outerstartpos; + let source = this.fullsource; + + let maxprefix = 40; + let preprefix = "\u2026"; + while (maxprefix > 0) + { + // We arrived at the start of the source code + if (outerstartpos === 0) + { + preprefix = ""; + break; + } + // We arrived at the start of the line + if (source.charAt(outerstartpos-1) === "\n") + { + preprefix = ""; + break; + } + --maxprefix; + --outerstartpos; + } + return preprefix + source.substring(outerstartpos, innerstartpos); + } + + get sourcesuffix() + { + let outerstoppos = this.pos.stop; + let innerstoppos = outerstoppos; + let source = this.fullsource; + + let maxsuffix = 40; + let postsuffix = "\u2026"; + while (maxsuffix > 0) + { + // We arrived at the ed of the source code + if (outerstoppos >= source.length) + { + postsuffix = ""; + break; + } + // We arrived at the end of the line + if (source.charAt(outerstoppos) === "\n") + { + postsuffix = ""; + break; + } + --maxsuffix; + ++outerstoppos; + } + return source.substring(innerstoppos, outerstoppos) + postsuffix; + } + + get line() + { + if (this._line === null) + this._calculateLineCol(); + return this._line; + } + + get col() + { + if (this._col === null) + this._calculateLineCol(); + return this._col; + } + + _calculateLineCol() + { + this._line = 1 + this._col = 1; + let stop = this.pos.start; + for (let i = 0; i < stop; ++i) + { + if (this.template.source[i] === "\n") + { + ++this._line; + this._col = 1; + } + else + ++this._col; + } + } + + __getattr__(attrname) + { + if (attrname === "type" || attrname === "fullsource" || attrname === "source" || attrname === "sourceprefix" || attrname === "sourcesuffix" || attrname === "line" || attrname === "col") + return this[attrname]; + else if (this._ul4onattrs.indexOf(attrname) >= 0) + return this[attrname]; + throw new ul4.AttributeError(this, attrname); + } + + __setitem__(attrname, value) + { + throw new ul4.TypeError("object is immutable"); + } + + __str__() + { + let out = []; + this._str(out); + return ul4._formatsource(out); + } + + __repr__() + { + let out = []; + this._repr(out); + return ul4._formatsource(out); + } + + _decorate_exception(exc) + { + while (exc.context !== undefined && exc.context !== null) + exc = exc.context; + exc.context = new ul4.LocationError(this); + } + + _handle_eval(context) + { + try + { + return this._eval(context); + } + catch (exc) + { + if (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + + _handle_eval_set(context, value) + { + try + { + return this._eval_set(context, value); + } + catch (exc) + { + if (!(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + + _eval_set(context, value) + { + throw new ul4.LValueRequiredError(); + } + + _handle_eval_modify(context, operator, value) + { + try + { + return this._eval_modify(context, operator, value); + } + catch (exc) + { + if (!(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + + _eval_modify(context, operator, value) + { + throw new ul4.LValueRequiredError(); + } + + _repr(out) + { + } + + _str(out) + { + out.push(this.source.replace(/\r?\n/g, ' ')); + } + + ul4ondump(encoder) + { + for (let i = 0; i < this._ul4onattrs.length; ++i) + { + let attrname = this._ul4onattrs[i]; + encoder.dump(this[attrname]); + } + } + + ul4onload(decoder) + { + for (let i = 0; i < this._ul4onattrs.length; ++i) + { + let attrname = this._ul4onattrs[i]; + this[attrname] = decoder.load(); + } + } + }; + + // used in ul4ondump/ul4ondump to automatically dump these attributes + ul4.AST.prototype._ul4onattrs = ["template", "pos"]; + + ul4.TextAST = class TextAST extends ul4.AST + { + constructor(template, pos) + { + super(template, pos); + } + + get text() + { + return this.source; + } + + _eval(context) + { + context.output(this.text); + } + + _str(out) + { + out.push("text "); + out.push(ul4._repr(this.text)); + } + + _repr(out) + { + out.push(""); + } + }; + + ul4.IndentAST = class IndentAST extends ul4.TextAST + { + constructor(template, pos, text) + { + super(template, pos); + this._text = text; + } + + get text() + { + if (typeof(this.template) !== "undefined") + return this._text === null ? this.source : this._text; + else + return null; + } + + _eval(context) + { + for (let i = 0; i < context.indents.length; ++i) + { + let indent = context.indents[i]; + context.output(indent); + } + context.output(this.text); + } + + ul4ondump(encoder) + { + super.ul4ondump(encoder); + + if (this._text === this.source) + encoder.dump(null); + else + encoder.dump(this._text); + } + + ul4onload(decoder) + { + super.ul4onload(decoder); + this._text = decoder.load(); + } + + _str(out) + { + out.push("indent "); + out.push(ul4._repr(this.text)); + } + + _repr(out) + { + out.push(""); + } + }; + + ul4.LineEndAST = class LineEndAST extends ul4.TextAST + { + _str(out) + { + out.push("lineend "); + out.push(ul4._repr(this.text)); + } + + _repr(out) + { + out.push(""); + } + }; + + ul4.CodeAST = class CodeAST extends ul4.AST + { + }; + + ul4.ConstAST = class ConstAST extends ul4.CodeAST + { + constructor(template, pos, value) + { + super(template, pos); + this.value = value; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + return this.value; + } + }; + + ul4.ConstAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["value"]); + + ul4.ItemArgBase = class ItemArgBase extends ul4.CodeAST + { + _handle_eval_list(context, result) + { + try + { + return this._eval_list(context, result); + } + catch (exc) + { + if (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + + _handle_eval_set(context, result) + { + try + { + return this._eval_set(context, result); + } + catch (exc) + { + if (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + + _handle_eval_dict(context, result) + { + try + { + return this._eval_dict(context, result); + } + catch (exc) + { + if (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + + _handle_eval_call(context, args, kwargs) + { + try + { + return this._eval_call(context, args, kwargs); + } + catch (exc) + { + if (!(exc instanceof ul4.InternalException) && !(exc instanceof ul4.LocationError)) + this._decorate_exception(exc); + throw exc; + } + } + }; + + ul4.SeqItemAST = class SeqItemAST extends ul4.ItemArgBase + { + constructor(template, pos, value) + { + super(template, pos); + this.value = value; + } + + _repr(out) + { + out.push(""); + } + + _eval_list(context, result) + { + let value = this.value._handle_eval(context); + result.push(value); + } + + _eval_set(context, result) + { + let value = this.value._handle_eval(context); + result.add(value); + } + }; + + ul4.SeqItemAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["value"]); + + ul4.UnpackSeqItemAST = class UnpackSeqItemAST extends ul4.ItemArgBase + { + constructor(template, pos, value) + { + super(template, pos); + this.value = value; + } + + _repr(out) + { + out.push(""); + } + + _eval_list(context, result) + { + let value = this.value._handle_eval(context); + for (let iter = ul4._iter(value);;) + { + let item = iter.next(); + if (item.done) + break; + result.push(item.value); + } + } + + _eval_set(context, result) + { + let value = this.value._handle_eval(context); + for (let iter = ul4._iter(value);;) + { + let item = iter.next(); + if (item.done) + break; + result.add(item.value); + } + } + }; + + ul4.UnpackSeqItemAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["value"]); + + ul4.DictItemAST = class DictItemAST extends ul4.ItemArgBase + { + constructor(template, pos, key, value) + { + super(template, pos); + this.key = key; + this.value = value; + } + + _repr(out) + { + out.push(""); + } + + _eval_dict(context, result) + { + let key = this.key._handle_eval(context); + let value = this.value._handle_eval(context); + ul4._setmap(result, key, value); + } + }; + + ul4.DictItemAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["key", "value"]), + + ul4.UnpackDictItemAST = class UnpackDictItemAST extends ul4.ItemArgBase + { + constructor(template, pos, item) + { + super(template, pos); + this.item = item; + } + + _repr(out) + { + out.push(""); + } + + _eval_dict(context, result) + { + let item = this.item._handle_eval(context); + if (ul4._islist(item)) + { + for (let i = 0; i < item.length; ++i) + { + let subitem = item[i]; + if (!ul4._islist(subitem) || subitem.length != 2) + throw new ul4.ArgumentError("** requires a list of (key, value) pairs"); + ul4._setmap(result, subitem[0], subitem[1]); + } + } + else if (ul4._ismap(item)) + { + item.forEach(function(value, key) { + ul4._setmap(result, key, value); + }); + } + else if (ul4._isobject(item)) + { + for (let key in item) + ul4._setmap(result, key, item[key]); + } + } + }; + + ul4.UnpackDictItemAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["item"]); + + ul4.PosArgAST = class PosArgAST extends ul4.ItemArgBase + { + constructor(template, pos, value) + { + super(template, pos); + this.value = value; + } + + _repr(out) + { + out.push(""); + } + + _eval_call(context, args, kwargs) + { + let value = this.value._handle_eval(context); + args.push(value); + } + }; + + ul4.PosArgAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["value"]); + + ul4.KeywordArgAST = class KeywordArgAST extends ul4.ItemArgBase + { + constructor(template, pos, name, value) + { + super(template, pos); + this.name = name; + this.value = value; + } + + _repr(out) + { + out.push(""); + } + + _eval_call(context, args, kwargs) + { + if (kwargs.hasOwnProperty(this.name)) + throw new ul4.ArgumentError("duplicate keyword argument " + this.name); + let value = this.value._handle_eval(context); + kwargs[this.name] = value; + } + }; + + ul4.KeywordArgAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["name", "value"]); + + ul4.UnpackListArgAST = class UnpackListArgAST extends ul4.ItemArgBase + { + constructor(template, pos, item) + { + super(template, pos); + this.item = item; + } + + _repr(out) + { + out.push(""); + } + + _eval_call(context, args, kwargs) + { + let item = this.item._handle_eval(context); + args.push(...item); + } + }; + + ul4.UnpackListArgAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["item"]); + + ul4.UnpackDictArgAST = class UnpackDictArgAST extends ul4.ItemArgBase + { + constructor(template, pos, item) + { + super(template, pos); + this.item = item; + } + + _repr(out) + { + out.push(""); + } + + _eval_call(context, args, kwargs) + { + let item = this.item._handle_eval(context); + if (ul4._islist(item)) + { + for (let i = 0; i < item.length; ++i) + { + let subitem = item[i]; + if (!ul4._islist(subitem) || subitem.length != 2) + throw new ul4.ArgumentError("** requires a list of (key, value) pairs"); + let [key, value] = subitem; + if (kwargs.hasOwnProperty(key)) + throw new ul4.ArgumentError("duplicate keyword argument " + key); + kwargs[key] = value; + } + } + else if (ul4._ismap(item)) + { + item.forEach(function(value, key) { + if (kwargs.hasOwnProperty(key)) + throw new ul4.ArgumentError("duplicate keyword argument " + key); + kwargs[key] = value; + }); + } + else if (ul4._isobject(item)) + { + for (let key in item) + { + if (kwargs.hasOwnProperty(key)) + throw new ul4.ArgumentError("duplicate keyword argument " + key); + kwargs[key] = item[key]; + } + } + } + }; + + ul4.UnpackDictArgAST.prototype._ul4onattrs = ul4.ItemArgBase.prototype._ul4onattrs.concat(["item"]); + + ul4.ListAST = class ListAST extends ul4.CodeAST + { + constructor(template, pos) + { + super(template, pos); + this.items = []; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let result = []; + for (let i = 0; i < this.items.length; ++i) + { + let item = this.items[i]; + item._handle_eval_list(context, result); + } + return result; + } + }; + + ul4.ListAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["items"]); + + ul4.ListCompAST = class ListCompAST extends ul4.CodeAST + { + constructor(template, pos, item, varname, container, condition) + { + super(template, pos); + this.item = item; + this.varname = varname; + this.container = container; + this.condition = condition; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let container = this.container._handle_eval(context); + + let localcontext = context.inheritvars(); + + let result = []; + for (let iter = ul4._iter(container);;) + { + let item = iter.next(); + if (item.done) + break; + let varitems = ul4._unpackvar(this.varname, item.value); + for (let i = 0; i < varitems.length; ++i) + { + let [lvalue, value] = varitems[i]; + lvalue._handle_eval_set(localcontext, value); + } + if (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext))) + result.push(this.item._handle_eval(localcontext)); + } + return result; + } + }; + + ul4.ListCompAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["item", "varname", "container", "condition"]); + + ul4.SetAST = class SetAST extends ul4.CodeAST + { + constructor(template, pos) + { + super(template, pos); + this.items = []; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let result = ul4._emptyset(); + + for (let i = 0; i < this.items.length; ++i) + { + let item = this.items[i]; + item._handle_eval_set(context, result); + } + + return result; + } + }; + + ul4.SetAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["items"]); + + ul4.SetCompAST = class SetCompAST extends ul4.CodeAST + { + constructor(template, pos, item, varname, container, condition) + { + super(template, pos); + this.item = item; + this.varname = varname; + this.container = container; + this.condition = condition; + } + + __getattr__(attrname) + { + switch (attrname) + { + case "item": + return this.item; + case "varname": + return this.varname; + case "container": + return this.container; + case "condition": + return this.condition; + default: + return super.__getattr__(attrname); + } + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let container = this.container._handle_eval(context); + + let localcontext = context.inheritvars(); + + let result = ul4._emptyset(); + for (let iter = ul4._iter(container);;) + { + let item = iter.next(); + if (item.done) + break; + let varitems = ul4._unpackvar(this.varname, item.value); + for (let i = 0; i < varitems.length; ++i) + { + let [lvalue, value] = varitems[i]; + lvalue._handle_eval_set(localcontext, value); + } + if (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext))) + result.add(this.item._handle_eval(localcontext)); + } + + return result; + } + }; + + ul4.SetCompAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["item", "varname", "container", "condition"]); + + ul4.DictAST = class DictAST extends ul4.CodeAST + { + constructor(template, pos) + { + super(template, pos); + this.items = []; + } + + __getattr__(attrname) + { + switch (attrname) + { + case "items": + return this.items; + default: + return super.__getattr__(attrname); + } + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let result = ul4._emptymap(); + for (let i = 0; i < this.items.length; ++i) + { + let item = this.items[i]; + item._handle_eval_dict(context, result); + } + return result; + } + }; + + ul4.DictAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["items"]); + + ul4.DictCompAST = class DictCompAST extends ul4.CodeAST + { + constructor(template, pos, key, value, varname, container, condition) + { + super(template, pos); + this.key = key; + this.value = value; + this.varname = varname; + this.container = container; + this.condition = condition; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let container = this.container._handle_eval(context); + + let localcontext = context.inheritvars(); + + let result = ul4._emptymap(); + + for (let iter = ul4._iter(container);;) + { + let item = iter.next(); + if (item.done) + break; + let varitems = ul4._unpackvar(this.varname, item.value); + for (let i = 0; i < varitems.length; ++i) + { + let [lvalue, value] = varitems[i]; + lvalue._handle_eval_set(localcontext, value); + } + if (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext))) + { + let key = this.key._handle_eval(localcontext); + let value = this.value._handle_eval(localcontext); + ul4._setmap(result, key, value); + } + } + + return result; + } + }; + + ul4.DictCompAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["key", "value", "varname", "container", "condition"]); + + ul4.GenExprAST = class GenExprAST extends ul4.CodeAST + { + constructor(template, pos, item, varname, container, condition) + { + super(template, pos); + this.item = item; + this.varname = varname; + this.container = container; + this.condition = condition; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let container = this.container._handle_eval(context); + let iter = ul4._iter(container); + + let localcontext = context.inheritvars(); + + let self = this; + + let result = { + next: function(){ + while (true) + { + let item = iter.next(); + if (item.done) + return item; + let varitems = ul4._unpackvar(self.varname, item.value); + for (let i = 0; i < varitems.length; ++i) + { + let [lvalue, value] = varitems[i]; + lvalue._handle_eval_set(localcontext, value); + } + if (self.condition === null || ul4._bool(self.condition._handle_eval(localcontext))) + { + let value = self.item._handle_eval(localcontext); + return {value: value, done: false}; + } + } + } + }; + + return result; + } + }; + + ul4.GenExprAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["item", "varname", "container", "condition"]); + + ul4.VarAST = class VarAST extends ul4.CodeAST + { + constructor(template, pos, name) + { + super(template, pos); + this.name = name; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + return this._get(context, this.name); + } + + _eval_set(context, value) + { + this._set(context, this.name, value); + } + + _eval_modify(context, operator, value) + { + this._modify(context, operator, this.name, value); + } + + _get(context, name) + { + let result = context.get(name); + if (typeof(result) === "undefined") + result = ul4.functions[name]; + return result; + } + + _set(context, name, value) + { + context.set(name, value); + } + + _modify(context, operator, name, value) + { + let newvalue = operator._ido(context.get(name), value); + context.set(name, newvalue); + } + }; + + ul4.VarAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["name"]); + + ul4.UnaryAST = class UnaryAST extends ul4.CodeAST + { + constructor(template, pos, obj) + { + super(template, pos); + this.obj = obj; + } + + _repr(out) + { + out.push("<"); + out.push(this.constructor.name); + out.push(" obj="); + this.obj._repr(out); + out.push(">"); + } + + _eval(context) + { + let obj = this.obj._handle_eval(context); + return this._do(obj); + } + }; + + ul4.UnaryAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["obj"]); + + // Negation + ul4.NegAST = class NegAST extends ul4.UnaryAST + { + _do(obj) + { + if (obj !== null && typeof(obj.__neg__) === "function") + return obj.__neg__(); + return -obj; + } + }; + + // Bitwise not + ul4.BitNotAST = class BitNotAST extends ul4.UnaryAST + { + _do(obj) + { + return -obj-1; + } + }; + + // Not + ul4.NotAST = class NotAST extends ul4.UnaryAST + { + _do(obj) + { + return !ul4._bool(obj); + } + }; + + // If expression + ul4.IfAST = class IfAST extends ul4.CodeAST + { + constructor(template, pos, objif, objcond, objelse) + { + super(template, pos); + this.objif = objif; + this.objcond = objcond; + this.objelse = objelse; + } + + _repr(out) + { + out.push("<"); + out.push(this.constructor.name); + out.push(+1); + out.push("objif="); + this.objif._repr(out); + out.push(0); + out.push("objcond="); + this.objcond._repr(out); + out.push(0); + out.push("objelse="); + this.objelse._repr(out); + out.push(-1); + out.push(">"); + } + + _eval(context) + { + let result; + let condvalue = this.objcond._handle_eval(context); + if (ul4._bool(condvalue)) + result = this.objif._handle_eval(context); + else + result = this.objelse._handle_eval(context); + return result; + } + }; + + ul4.IfAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["objif", "objcond", "objelse"]); + + ul4.ReturnAST = class ReturnAST extends ul4.UnaryAST + { + _eval(context) + { + let result = this.obj._handle_eval(context); + throw new ul4.ReturnException(result); + } + + _str(out) + { + out.push("return "); + this.obj._str(out); + } + }; + + ul4.PrintAST = class PrintAST extends ul4.UnaryAST + { + _eval(context) + { + let obj = this.obj._handle_eval(context); + let output = ul4._str(obj); + context.output(output); + } + + _str(out) + { + out.push("print "); + this.obj._str(out); + } + }; + + ul4.PrintXAST = class PrintXAST extends ul4.UnaryAST + { + _eval(context) + { + let obj = this.obj._handle_eval(context); + let output = ul4._xmlescape(obj); + context.output(output); + } + + _str(out) + { + out.push("printx "); + this.obj._str(out); + } + }; + + ul4.BinaryAST = class BinaryAST extends ul4.CodeAST + { + constructor(template, pos, obj1, obj2) + { + super(template, pos); + this.obj1 = obj1; + this.obj2 = obj2; + } + + _repr(out) + { + out.push("<"); + out.push(this.constructor.name); + out.push(" obj1="); + this.obj1._repr(out); + out.push(" obj2="); + this.obj2._repr(out); + out.push(">"); + } + + _eval(context) + { + let obj1 = this.obj1._handle_eval(context); + let obj2 = this.obj2._handle_eval(context); + return this._do(obj1, obj2); + } + }; + + ul4.BinaryAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["obj1", "obj2"]); + + // Item access and assignment: dict[key], list[index], string[index], color[index] + ul4.ItemAST = class ItemAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + let result = this._get(obj1, obj2); + return result; + } + + _eval_set(context, value) + { + let obj1 = this.obj1._handle_eval(context); + let obj2 = this.obj2._handle_eval(context); + this._set(obj1, obj2, value); + } + + _eval_modify(context, operator, value) + { + let obj1 = this.obj1._handle_eval(context); + let obj2 = this.obj2._handle_eval(context); + this._modify(operator, obj1, obj2, value); + } + + _get(container, key) + { + if (typeof(container) === "string" || ul4._islist(container)) + { + if (key instanceof ul4.slice) + { + let start = key.start, stop = key.stop; + if (typeof(start) === "undefined" || start === null) + start = 0; + if (typeof(stop) === "undefined" || stop === null) + stop = container.length; + return container.slice(start, stop); + } + else + { + let orgkey = key; + if (key < 0) + key += container.length; + if (key < 0 || key >= container.length) + throw new ul4.IndexError(container, orgkey); + return container[key]; + } + } + else if (container && typeof(container.__getitem__) === "function") // objects without ``_getitem__`` don't support item access + return container.__getitem__(key); + else if (ul4._ismap(container)) + return container.get(key); + else + throw new ul4.TypeError(ul4._type(container) + " object is not subscriptable"); + } + + _set(container, key, value) + { + if (ul4._islist(container)) + { + if (key instanceof ul4.slice) + { + let start = key.start, stop = key.stop; + if (start === null) + start = 0; + else if (start < 0) + start += container.length; + if (start < 0) + start = 0; + else if (start > container.length) + start = container.length; + if (stop === null) + stop = container.length; + else if (stop < 0) + stop += container.length; + if (stop < 0) + stop = 0; + else if (stop > container.length) + stop = container.length; + if (stop < start) + stop = start; + container.splice(start, stop-start); // Remove old element + for (let iter = ul4._iter(value);;) + { + let item = iter.next(); + if (item.done) + break; + container.splice(start++, 0, item.value); + } + } + else + { + let orgkey = key; + if (key < 0) + key += container.length; + if (key < 0 || key >= container.length) + throw new ul4.IndexError(container, orgkey); + container[key] = value; + } + } + else if (container && typeof(container.__setitem__) === "function") // test this before the generic object test + container.__setitem__(key, value); + else if (ul4._ismap(container)) + container.set(key, value); + else if (ul4._isobject(container)) + container[key] = value; + else + throw new ul4.NotSubscriptableError(container); + } + + _modify(operator, container, key, value) + { + this._set(container, key, operator._ido(this._get(container, key), value)); + } + }; + + // Identifty test operator ``is`` + ul4.IsAST = class IsAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return obj1 === obj2; + } + }; + + // Inverted identity test operator ``is not`` + ul4.IsNotAST = class IsNotAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return obj1 !== obj2; + } + }; + + // Comparison operator == + ul4.EQAST = class EQAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._eq(obj1, obj2); + } + }; + + // Comparison operator != + ul4.NEAST = class NEAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._ne(obj1, obj2); + } + }; + + // Comparison operator < + ul4.LTAST = class LTAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._lt(obj1, obj2); + } + }; + + // Comparison operator <= + ul4.LEAST = class LEAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._le(obj1, obj2); + } + }; + + // Comparison operator > + ul4.GTAST = class GTAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._gt(obj1, obj2); + } + }; + + // Comparison operator >= + ul4.GEAST = class GEAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._ge(obj1, obj2); + } + }; + + // Containment test: string in string, obj in list, key in dict, value in rgb + ul4.ContainsAST = class ContainsAST extends ul4.BinaryAST + { + _do(obj, container) + { + if (typeof(obj) === "string" && typeof(container) === "string") + { + return container.indexOf(obj) !== -1; + } + else if (ul4._islist(container)) + { + return container.indexOf(obj) !== -1; + } + else if (container && typeof(container.__contains__) === "function") // test this before the generic object test + return container.__contains__(obj); + else if (ul4._ismap(container) || ul4._isset(container)) + return container.has(obj); + else if (ul4._isobject(container)) + { + for (let key in container) + { + if (key === obj) + return true; + } + return false; + } + else if (ul4._iscolor(container)) + { + return container._r === obj || container._g === obj || container._b === obj || container._a === obj; + } + throw new ul4.TypeError(ul4._type(container) + " object is not iterable"); + } + }; + + // Inverted containment test + ul4.NotContainsAST = class NotContainsAST extends ul4.BinaryAST + { + _do(obj, container) + { + return !ul4.ContainsAST.prototype._do(obj, container); + } + }; + + // Addition: num + num, string + string + ul4.AddAST = class AddAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj1 && typeof(obj1.__add__) === "function") + return obj1.__add__(obj2); + else if (obj2 && typeof(obj2.__radd__) === "function") + return obj2.__radd__(obj1); + if (obj1 === null || obj2 === null) + throw new ul4.TypeError(ul4._type(this.obj1) + " + " + ul4._type(this.obj2) + " is not supported"); + if (ul4._islist(obj1) && ul4._islist(obj2)) + return [...obj1, ...obj2]; + else + return obj1 + obj2; + } + + _ido(obj1, obj2) + { + if (ul4._islist(obj1) && ul4._islist(obj2)) + { + ul4.ListProtocol.append(obj1, obj2); + return obj1; + } + else + return this._do(obj1, obj2); + } + }; + + // Substraction: num - num + ul4.SubAST = class SubAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj1 && typeof(obj1.__sub__) === "function") + return obj1.__sub__(obj2); + else if (obj2 && typeof(obj2.__rsub__) === "function") + return obj2.__rsub__(obj1); + else if (ul4._isdate(obj1) && ul4._isdate(obj2)) + return this._date_sub(obj1, obj2); + else if (ul4._isdatetime(obj1) && ul4._isdatetime(obj2)) + return this._datetime_sub(obj1, obj2); + if (obj1 === null || obj2 === null) + throw new ul4.TypeError(ul4._type(this.obj1) + " - " + ul4._type(this.obj2) + " is not supported"); + return obj1 - obj2; + } + + _date_sub(obj1, obj2) + { + return this._datetime_sub(obj1._date, obj2._date); + } + + _datetime_sub(obj1, obj2) + { + let swap = (obj2 > obj1); + + if (swap) + { + let t = obj1; + obj1 = obj2; + obj2 = t; + } + // From now on obj1 is > than obj2 + + let year1 = obj1.getFullYear(); + let yearday1 = ul4.DateTimeProtocol.yearday(obj1); + let year2 = obj2.getFullYear(); + let yearday2 = ul4.DateTimeProtocol.yearday(obj2); + + let diffdays = 0; + + while (year1 > year2) + { + diffdays += ul4.DateProtocol.yearday(ul4._date(year2, 12, 31)); + ++year2; + } + diffdays += yearday1 - yearday2; + + let hours1 = obj1.getHours(); + let minutes1 = obj1.getMinutes(); + let seconds1 = obj1.getSeconds(); + let hours2 = obj2.getHours(); + let minutes2 = obj2.getMinutes(); + let seconds2 = obj2.getSeconds(); + + let diffseconds = (seconds1 - seconds2) + 60 * ((minutes1 - minutes2) + 60 * (hours1 - hours2)); + + let diffmilliseconds = obj1.getMilliseconds() - obj2.getMilliseconds(); + + if (swap) + { + diffdays = -diffdays; + diffseconds = -diffseconds; + diffmilliseconds = -diffmilliseconds; + } + return new ul4.TimeDelta(diffdays, diffseconds, 1000*diffmilliseconds); + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + + // Multiplication: num * num, int * str, str * int, int * list, list * int + ul4.MulAST = class MulAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj1 && typeof(obj1.__mul__) === "function") + return obj1.__mul__(obj2); + else if (obj2 && typeof(obj2.__rmul__) === "function") + return obj2.__rmul__(obj1); + if (obj1 === null || obj2 === null) + throw new ul4.TypeError(ul4._type(obj1) + " * " + ul4._type(obj2) + " not supported"); + else if (ul4._isint(obj1) || ul4._isbool(obj1)) + { + if (typeof(obj2) === "string") + { + if (obj1 < 0) + throw new ul4.ValueError("repetition counter must be positive"); + return ul4._str_repeat(obj2, obj1); + } + else if (ul4._islist(obj2)) + { + if (obj1 < 0) + throw new ul4.ValueError("repetition counter must be positive"); + return ul4._list_repeat(obj2, obj1); + } + } + else if (ul4._isint(obj2) || ul4._isbool(obj2)) + { + if (typeof(obj1) === "string") + { + if (obj2 < 0) + throw new ul4.ValueError("repetition counter must be positive"); + return ul4._str_repeat(obj1, obj2); + } + else if (ul4._islist(obj1)) + { + if (obj2 < 0) + throw new ul4.ValueError("repetition counter must be positive"); + return ul4._list_repeat(obj1, obj2); + } + } + return obj1 * obj2; + } + + _ido(obj1, obj2) + { + if (ul4._islist(obj1) && ul4._isint(obj2)) + { + if (obj2 > 0) + { + let i = 0; + let targetsize = obj1.length * obj2; + while (obj1.length < targetsize) + obj1.push(obj1[i++]); + } + else + obj1.splice(0, obj1.length); + return obj1; + } + else + return this._do(obj1, obj2); + } + }; + + // Truncating division + ul4.FloorDivAST = class FloorDivAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj1 && typeof(obj1.__floordiv__) === "function") + return obj1.__floordiv__(obj2); + else if (obj2 && typeof(obj2.__rfloordiv__) === "function") + return obj2.__rfloordiv__(obj1); + if (obj1 === null || obj2 === null) + throw new ul4.TypeError(ul4._type(obj1) + " // " + ul4._type(obj2) + " not supported"); + else if (typeof(obj1) === "number" && typeof(obj2) === "number" && obj2 === 0) + throw new ul4.ZeroDivisionError(); + return Math.floor(obj1 / obj2); + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // "Real" division + ul4.TrueDivAST = class TrueDivAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj1 && typeof(obj1.__truediv__) === "function") + return obj1.__truediv__(obj2); + else if (obj2 && typeof(obj2.__rtruediv__) === "function") + return obj2.__rtruediv__(obj1); + if (obj1 === null || obj2 === null) + throw new ul4.TypeError(ul4._type(obj1) + " / " + ul4._type(obj2) + " not supported"); + else if (typeof(obj1) === "number" && typeof(obj2) === "number" && obj2 === 0) + throw new ul4.ZeroDivisionError(); + return obj1 / obj2; + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // Modulo + ul4.ModAST = class ModAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + return ul4._mod(obj1, obj2); + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // Bitwise left shift + ul4.ShiftLeftAST = class ShiftLeftAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj2 === false) + obj2 = 0; + else if (obj2 === true) + obj2 = 1; + if (obj2 < 0) + return ul4.ShiftRightAST.prototype._do(obj1, -obj2); + if (obj1 === false) + obj1 = 0; + else if (obj1 === true) + obj1 = 1; + while (obj2--) + obj1 *= 2; + return obj1; + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // Bitwise right shift + ul4.ShiftRightAST = class ShiftRightAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj2 === false) + obj2 = 0; + else if (obj2 === true) + obj2 = 1; + if (obj2 < 0) + return ul4.ShiftLeftAST.prototype._do(obj1, -obj2); + if (obj1 === false) + obj1 = 0; + else if (obj1 === true) + obj1 = 1; + while (obj2--) + obj1 /= 2; + return Math.floor(obj1); + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // Bitwise and + ul4.BitAndAST = class BitAndAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj2 === false) + obj2 = 0; + else if (obj2 === true) + obj2 = 1; + return obj1 & obj2; + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // Bitwise exclusive or + ul4.BitXOrAST = class BitXOrAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj2 === false) + obj2 = 0; + else if (obj2 === true) + obj2 = 1; + return obj1 ^ obj2; + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + // Bitwise or + ul4.BitOrAST = class BitOrAST extends ul4.BinaryAST + { + _do(obj1, obj2) + { + if (obj2 === false) + obj2 = 0; + else if (obj2 === true) + obj2 = 1; + return obj1 | obj2; + } + + _ido(obj1, obj2) + { + return this._do(obj1, obj2); + } + }; + + ul4.AndAST = class AndAST extends ul4.BinaryAST + { + _eval(context) + { + let obj1 = this.obj1._handle_eval(context); + if (!ul4._bool(obj1)) + return obj1; + let obj2 = this.obj2._handle_eval(context); + return obj2; + } + }; + + ul4.OrAST = class OrAST extends ul4.BinaryAST + { + _eval(context) + { + let obj1 = this.obj1._handle_eval(context); + if (ul4._bool(obj1)) + return obj1; + let obj2 = this.obj2._handle_eval(context); + return obj2; + } + }; + + ul4.AttrAST = class AttrAST extends ul4.CodeAST + { + constructor(template, pos, obj, attrname) + { + super(template, pos); + this.obj = obj; + this.attrname = attrname; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let obj = this.obj._handle_eval(context); + let result = this._get(obj, this.attrname); + return result; + } + + _eval_set(context, value) + { + let obj = this.obj._handle_eval(context); + this._set(obj, this.attrname, value); + } + + _eval_modify(context, operator, value) + { + let obj = this.obj._handle_eval(context); + this._modify(operator, obj, this.attrname, value); + } + + _get(object, attrname) + { + let proto = ul4.Protocol.get(object); + try + { + return proto.getattr(object, attrname); + } + catch (exc) + { + if (exc instanceof ul4.AttributeError && exc.obj === object) + return undefined; + else + throw exc; + } + } + + _set(object, attrname, value) + { + if (typeof(object) === "object" && typeof(object.__setattr__) === "function") + object.__setattr__(attrname, value); + else if (ul4._ismap(object)) + object.set(attrname, value); + else if (ul4._isobject(object)) + object[attrname] = value; + else + throw new ul4.TypeError(ul4._type(object) + " object has no writable attributes"); + } + + _modify(operator, object, attrname, value) + { + let oldvalue = this._get(object, attrname); + let newvalue = operator._ido(oldvalue, value); + this._set(object, attrname, newvalue); + } + }; + + ul4.AttrAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["obj", "attrname"]); + + ul4.CallAST = class CallAST extends ul4.CodeAST + { + constructor(template, pos, obj, args) + { + super(template, pos); + this.obj = obj; + this.args = args; + } + + _repr(out) + { + out.push(""); + } + + _makeargs(context) + { + let args = [], kwargs = {}; + for (let i = 0; i < this.args.length; ++i) + { + let arg = this.args[i]; + arg._handle_eval_call(context, args, kwargs); + } + return {args: args, kwargs: kwargs}; + } + + _handle_eval(context) + { + try + { + return this._eval(context); + } + catch (exc) + { + this._decorate_exception(exc); + throw exc; + } + } + + _eval(context) + { + let obj = this.obj._handle_eval(context); + let args = this._makeargs(context); + let result = ul4._call(context, obj, args.args, args.kwargs); + return result; + } + }; + + ul4.CallAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["obj", "args"]); + + ul4.RenderAST = class RenderAST extends ul4.CallAST + { + constructor(template, pos, obj, args) + { + super(template, pos, obj, args); + this.indent = null; + } + + _repr(out) + { + out.push("<"); + out.push(this._reprname); + out.push(""); + } + + _str(out) + { + out.push("render "); + out.push(this.tag.code.replace(/\r?\n/g, ' ')); + if (this.indent !== null) + { + out.push(" with indent "); + out.push(ul4._repr(this.indent.text)); + } + } + + _handle_eval(context) + { + let localcontext = context.withindent(this.indent !== null ? this.indent.text : null); + let obj = this.obj._handle_eval(localcontext); + let args = this._makeargs(localcontext); + this._handle_additional_arguments(localcontext, args); + + try + { + let result = ul4._callrender(localcontext, obj, args.args, args.kwargs); + return result; + } + catch (exc) + { + this._decorate_exception(exc); + throw exc; + } + } + + _handle_additional_arguments(context, args) + { + } + }; + + ul4.RenderAST.prototype._ul4onattrs = ul4.CallAST.prototype._ul4onattrs.concat(["indent"]); + ul4.RenderAST.prototype._reprname = "RenderAST"; + + ul4.RenderXAST = class RenderXAST extends ul4.RenderAST + { + _handle_eval(context) + { + context.escapes.push(ul4._xmlescape); + + let result = null; + try + { + result = super._handle_eval(context); + } + finally + { + context.escapes.splice(context.escapes.length-1, 1); + } + return result; + } + }; + + ul4.RenderBlockAST = class RenderBlockAST extends ul4.RenderAST + { + _handle_additional_arguments(context, args) + { + if (args.kwargs.hasOwnProperty("content")) + throw new ul4.ArgumentError("duplicate keyword argument content"); + let closure = new ul4.TemplateClosure(this.content, this.content.signature, context.vars); + args.kwargs.content = closure; + } + }; + + ul4.RenderBlockAST.prototype._ul4onattrs = ul4.RenderAST.prototype._ul4onattrs.concat(["content"]); + + ul4.RenderBlocksAST = class RenderBlocksAST extends ul4.RenderAST + { + _handle_additional_arguments(context, args) + { + let localcontext = context.inheritvars(); + ul4.BlockAST.prototype._eval.call(this, localcontext); + + for (let key in localcontext.vars) + { + if (localcontext.vars.hasOwnProperty(key)) + { + if (key in args.kwargs) + throw new ul4.ArgumentError("duplicate keyword argument " + key); + args.kwargs[key] = localcontext.get(key); + } + } + } + }; + + ul4.RenderBlocksAST.prototype._ul4onattrs = ul4.RenderAST.prototype._ul4onattrs.concat(["content"]); + + // Slice object + ul4.slice = class slice extends ul4.Proto + { + constructor(start, stop) + { + super(); + this.start = start; + this.stop = stop; + } + + of(string) + { + let start = this.start || 0; + let stop = this.stop === null ? string.length : this.stop; + return string.slice(start, stop); + } + + __repr__() + { + return "slice(" + ul4._repr(this.start) + ", " + ul4._repr(this.stop) + ", None)"; + } + + __getattr__(attrname) + { + switch (attrname) + { + case "start": + return this.start; + case "stop": + return this.stop; + default: + throw new ul4.AttributeError(this, attrname); + } + } + }; + + + // List/String slice + ul4.SliceAST = class SliceAST extends ul4.CodeAST + { + constructor(template, pos, index1, index2) + { + super(template, pos); + this.index1 = index1; + this.index2 = index2; + } + + _repr(out) + { + out.push(""); + } + + _eval(context) + { + let index1 = this.index1 !== null ? this.index1._handle_eval(context) : null; + let index2 = this.index2 !== null ? this.index2._handle_eval(context) : null; + return new ul4.slice(index1, index2); + } + }; + + ul4.SliceAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["index1", "index2"]); + + ul4.SetVarAST = class SetVarAST extends ul4.CodeAST + { + constructor(template, pos, lvalue, value) + { + super(template, pos); + this.lvalue = lvalue; + this.value = value; + } + + _repr(out) + { + out.push("<"); + out.push(this.constructor.name); + out.push(" lvalue="); + out.push(ul4._repr(this.lvalue)); + out.push(" value="); + this.value._repr(out); + out.push(">"); + } + + _eval(context) + { + let value = this.value._handle_eval(context); + let items = ul4._unpackvar(this.lvalue, value); + for (let i = 0; i < items.length; ++i) + { + let [lvalue, value] = items[i]; + lvalue._handle_eval_set(context, value); + } + } + }; + + ul4.SetVarAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["lvalue", "value"]); + + ul4.ModifyVarAST = class ModifyVarAST extends ul4.SetVarAST + { + _eval(context) + { + let value = this.value._handle_eval(context); + let items = ul4._unpackvar(this.lvalue, value); + for (let i = 0; i < items.length; ++i) + { + let [lvalue, value] = items[i]; + lvalue._handle_eval_modify(context, this._operator, value); + } + } + }; + + ul4.AddVarAST = class AddVarAST extends ul4.ModifyVarAST + { + }; + + ul4.AddVarAST.prototype._operator = ul4.AddAST.prototype; + + ul4.SubVarAST = class SubVarAST extends ul4.ModifyVarAST + { + }; + + ul4.SubVarAST.prototype._operator = ul4.SubAST.prototype; + + ul4.MulVarAST = class MulVarAST extends ul4.ModifyVarAST + { + }; + + ul4.MulVarAST.prototype._operator = ul4.MulAST.prototype; + + ul4.TrueDivVarAST = class TrueDivVarAST extends ul4.ModifyVarAST + { + }; + + ul4.TrueDivVarAST.prototype._operator = ul4.TrueDivAST.prototype; + + ul4.FloorDivVarAST = class FloorDivVarAST extends ul4.ModifyVarAST + { + }; + + ul4.FloorDivVarAST.prototype._operator = ul4.FloorDivAST.prototype; + + ul4.ModVarAST = class ModVarAST extends ul4.ModifyVarAST + { + }; + + ul4.ModVarAST.prototype._operator = ul4.ModAST.prototype; + + ul4.ShiftLeftVarAST = class ShiftLeftVarAST extends ul4.ModifyVarAST + { + }; + + ul4.ShiftLeftVarAST.prototype._operator = ul4.ShiftLeftAST.prototype; + + ul4.ShiftRightVarAST = class ShiftRightVarAST extends ul4.ModifyVarAST + { + }; + + ul4.ShiftRightVarAST.prototype._operator = ul4.ShiftRightAST.prototype; + + ul4.BitAndVarAST = class BitAndVarAST extends ul4.ModifyVarAST + { + }; + + ul4.BitAndVarAST.prototype._operator = ul4.BitAndAST.prototype; + + ul4.BitXOrVarAST = class BitXOrVarAST extends ul4.ModifyVarAST + { + }; + + ul4.BitXOrVarAST.prototype._operator = ul4.BitXOrAST.prototype; + + ul4.BitOrVarAST = class BitOrVarAST extends ul4.ModifyVarAST + { + }; + + ul4.BitOrVarAST.prototype._operator = ul4.BitOrAST.prototype; + + ul4.BlockAST = class BlockAST extends ul4.CodeAST + { + constructor(template, pos) + { + super(template, pos); + this.content = []; + } + + _eval(context) + { + for (let i = 0; i < this.content.length; ++i) + { + let item = this.content[i]; + item._handle_eval(context); + } + } + + _str(out) + { + if (this.content.length) + { + for (let i = 0; i < this.content.length; ++i) + { + let item = this.content[i]; + item._str(out); + out.push(0); + } + } + else + { + out.push("pass"); + out.push(0); + } + } + }; + + ul4.BlockAST.prototype._ul4onattrs = ul4.CodeAST.prototype._ul4onattrs.concat(["content"]); + + ul4.ForBlockAST = class ForBlockAST extends ul4.BlockAST + { + constructor(template, pos, varname, container) + { + super(template, pos); + this.varname = varname; + this.container = container; + } + + _repr(out) + { + out.push(""); + } + + _str_varname(out, varname) + { + if (ul4._islist(varname)) + { + out.push("("); + for (let i = 0; i < varname.length; ++i) + { + if (i) + out.push(", "); + this._str_varname(out, varname[i]); + } + if (varname.length == 1) + out.push(","); + out.push(")"); + } + else + varname._str(out); + } + + _eval(context) + { + let container = this.container._handle_eval(context); + + for (let iter = ul4._iter(container);;) + { + let value = iter.next(); + if (value.done) + break; + let varitems = ul4._unpackvar(this.varname, value.value); + for (let i = 0; i < varitems.length; ++i) + { + let [lvalue, value] = varitems[i]; + lvalue._handle_eval_set(context, value); + } + try + { + // We can't call _handle_eval() here, as this would in turn call this function again, leading to infinite recursion + // But we don't have to, as wrapping original exception in ``Error`` has already been done by the lower levels + super._eval(context); + } + catch (exc) + { + if (exc instanceof ul4.BreakException) + break; + else if (exc instanceof ul4.ContinueException) + ; + else + throw exc; + } + } + } + + _str(out) + { + out.push("for "); + this._str_varname(out, this.varname); + out.push(" in "); + this.container._str(out); + out.push(":"); + out.push(+1); + ul4.BlockAST.prototype._str.call(this, out); + out.push(-1); + } + }; + + ul4.ForBlockAST.prototype._ul4onattrs = ul4.BlockAST.prototype._ul4onattrs.concat(["varname", "container"]); + + ul4.WhileBlockAST = class WhileBlockAST extends ul4.BlockAST + { + constructor(template, pos, condition) + { + super(template, pos); + this.condition = condition; + } + + _repr(out) + { + out.push(""); + } + + _str(out) + { + out.push("while "); + this.condition._repr(out); + out.push(":"); + out.push(+1); + ul4.BlockAST.prototype._str.call(this, out); + out.push(-1); + } + + _eval(context) + { + while (true) + { + let cond = this.condition._handle_eval(context); + if (!ul4._bool(cond)) + break; + try + { + // We can't call _handle_eval() here, as this would in turn call this function again, leading to infinite recursion + // But we don't have to, as wrapping the original exception in ``Error`` has already been done by the lower levels + super._eval(context); + } + catch (exc) + { + if (exc instanceof ul4.BreakException) + break; + else if (exc instanceof ul4.ContinueException) + ; + else + throw exc; + } + } + } + }; + + ul4.WhileBlockAST.prototype._ul4onattrs = ul4.BlockAST.prototype._ul4onattrs.concat(["condition"]); + + ul4.BreakAST = class BreakAST extends ul4.CodeAST + { + _eval(context) + { + throw new ul4.BreakException(); + } + + _str(out) + { + out.push("break"); + out.push(0); + } + + _repr(out) + { + out.push(""); + } + }; + + ul4.ContinueAST = class ContinueAST extends ul4.CodeAST + { + _eval(context) + { + throw new ul4.ContinueException(); + } + + _str(out) + { + out.push("continue"); + out.push(0); + } + + _repr(out) + { + out.push(""); + } + }; + + ul4.CondBlockAST = class CondBlockAST extends ul4.BlockAST + { + _eval(context) + { + for (let i = 0; i < this.content.length; ++i) + { + let block = this.content[i]; + let execute = block._execute(context); + if (execute) + { + block._handle_eval(context); + break; + } + } + } + }; + + ul4.ConditionalBlockAST = class ConditionalBlockAST extends ul4.BlockAST + { + constructor(template, pos, condition) + { + super(template, pos); + this.condition = condition; + } + + _repr(out) + { + out.push("<"); + out.push(this.constructor.name); + out.push(" condition="); + this.condition._repr(out); + out.push(">"); + } + + _str(out) + { + out.push(this._strname); + out.push(" "); + this.condition._str(out); + out.push(":"); + out.push(+1); + ul4.BlockAST.prototype._str.call(this, out); + out.push(-1); + } + + _execute(context) + { + let cond = this.condition._handle_eval(context); + let result = ul4._bool(cond); + return result; + } + }; + + ul4.ConditionalBlockAST.prototype._ul4onattrs = ul4.BlockAST.prototype._ul4onattrs.concat(["condition"]); + + ul4.IfBlockAST = class IfBlockAST extends ul4.ConditionalBlockAST + { + }; + + ul4.IfBlockAST.prototype._strname = "if"; + + ul4.ElIfBlockAST = class ElIfBlockAST extends ul4.ConditionalBlockAST + { + }; + + ul4.ElIfBlockAST.prototype._strname = "else if"; + + ul4.ElseBlockAST = class ElseBlockAST extends ul4.BlockAST + { + _repr(out) + { + out.push(""); + } + + _str(out) + { + out.push("else:"); + out.push(+1); + ul4.BlockAST.prototype._str.call(this, out); + out.push(-1); + } + + _execute(context) + { + return true; + } + }; + + ul4.Template = class Template extends ul4.BlockAST + { + constructor(template, pos, source, name, whitespace, startdelim, enddelim, signature) + { + super(template, pos); + this._source = source; + this.name = name; + this.whitespace = whitespace; + this.startdelim = startdelim; + this.enddelim = enddelim; + this.docpos = null; + this.signature = signature; + this._asts = null; + this._ul4_callsignature = signature; + this._ul4_rendersignature = signature; + this.parenttemplate = null; + } + + __getattr__(attrname) + { + let self = this; + switch (attrname) + { + case "content": + return this.content; + case "source": + return this.source; + case "name": + return this.name; + case "whitespace": + return this.whitespace; + case "startdelim": + return this.startdelim; + case "enddelim": + return this.enddelim; + case "doc": + return this.doc(); + case "signature": + return this.signature; + case "parenttemplate": + return this.parenttemplate; + case "render": + let render = function render(context, vars){ self._renderbound(context, vars); }; + ul4.expose(render, this.signature, {needscontext: true, needsobject: true}); + return render; + case "renders": + let renders = function renders(context, vars){ return self._rendersbound(context, vars); }; + ul4.expose(renders, this.signature, {needscontext: true, needsobject: true}); + return renders; + default: + return super.__getattr__(attrname); + } + } + + ul4ondump(encoder) + { + let signature; + encoder.dump(ul4.version); + encoder.dump(this.name); + encoder.dump(this._source); + encoder.dump(this.whitespace); + encoder.dump(this.startdelim); + encoder.dump(this.enddelim); + encoder.dump(this.docpos); + encoder.dump(this.parenttemplate); + if (this.signature === null || this.signature instanceof ul4.SignatureAST) + signature = this.signature; + else + { + signature = []; + for (let i = 0; i < this.signature.args.length; ++i) + { + let arg = this.signature.args[i]; + if (typeof(arg.defaultValue) === "undefined") + signature.push(arg.name); + else + signature.push(arg.name+"=", arg.defaultValue); + } + if (this.signature.remargs !== null) + signature.push("*" + this.signature.remargs); + if (this.signature.remkwargs !== null) + signature.push("**" + this.signature.remkwargs); + } + encoder.dump(signature); + super.ul4ondump(encoder); + } + + ul4onload(decoder) + { + let version = decoder.load(); + let signature; + + if (version === null) + throw new ul4.ValueError("UL4ON doesn't support templates in 'source' format in Javascript implementation"); + + if (version !== ul4.version) + throw new ul4.ValueError("invalid version, expected " + ul4.version + ", got " + version); + + this.name = decoder.load(); + this._source = decoder.load(); + this.whitespace = decoder.load(); + this.startdelim = decoder.load(); + this.enddelim = decoder.load(); + this.docpos = decoder.load(); + this.parenttemplate = decoder.load(); + signature = decoder.load(); + if (ul4._islist(signature)) + signature = new ul4.Signature(...signature); + this.signature = signature; + this._ul4_callsignature = signature; + this._ul4_rendersignature = signature; + super.ul4onload(decoder); + } + + loads(string) + { + return ul4.loads(string); + } + + _eval(context) + { + let signature = null; + if (this.signature !== null) + signature = this.signature._handle_eval(context); + let closure = new ul4.TemplateClosure(this, signature, context.vars); + context.set(this.name, closure); + } + + _repr(out) + { + out.push("") + { + out.push(" enddelim="); + out.push(ul4._repr(this.enddelim)); + } + out.push(">"); + } + + _str(out) + { + out.push("def "); + out.push(this.name ? this.name : "unnamed"); + out.push(":"); + out.push(+1); + ul4.BlockAST.prototype._str.call(this, out); + out.push(-1); + } + + _renderbound(context, vars) + { + let localcontext = context.clone(); + localcontext.vars = vars; + try + { + ul4.BlockAST.prototype._eval.call(this, localcontext); + } + catch (exc) + { + if (!(exc instanceof ul4.ReturnException)) + throw exc; + } + } + + __render__(context, vars) + { + this._renderbound(context, vars); + } + + render(context, vars) + { + this._renderbound(context, vars); + } + + _rendersbound(context, vars) + { + let localcontext = context.replaceoutput(); + this._renderbound(localcontext, vars); + return localcontext.getoutput(); + } + + renders(vars) + { + vars = vars || {}; + let context = new ul4.Context(); + if (this.signature !== null) + vars = this.signature.bindObject(this.name, [], vars); + return this._rendersbound(context, vars); + } + + doc() + { + return this.docpos != null ? this.docpos.of(this._source) : null; + } + + _callbound(context, vars) + { + let localcontext = context.clone(); + localcontext.vars = vars; + try + { + ul4.BlockAST.prototype._eval.call(this, localcontext); + } + catch (exc) + { + if (exc instanceof ul4.ReturnException) + return exc.result; + else + throw exc; + } + return null; + } + + call(vars) + { + vars = vars || {}; + let context = new ul4.Context(); + if (this.signature !== null) + vars = this.signature.bindObject(this.name, [], vars); + return this._callbound(context, vars); + } + + __call__(context, vars) + { + return this._callbound(context, vars); + } + + ul4type() + { + return "template"; + } + }; + + ul4.Template.prototype._ul4_callneedsobject = true; + ul4.Template.prototype._ul4_callneedscontext = true; + ul4.Template.prototype._ul4_renderneedsobject = true; + ul4.Template.prototype._ul4_renderneedscontext = true; + + ul4.SignatureAST = class SignatureAST extends ul4.CodeAST + { + constructor(template, pos) + { + super(template, pos); + this.params = []; + } + + ul4ondump(encoder) + { + super.ul4ondump(encoder); + + let dump = []; + + for (let i = 0; i < this.params.length; ++i) + { + let param = this.params[i]; + if (param[1] === null) + dump.push(param[0]); + else + dump.push(param); + } + encoder.dump(dump); + } + + ul4onload(decoder) + { + super.ul4onload(decoder); + let dump = decoder.load(); + this.params = []; + for (let i = 0; i < dump.length; ++i) + { + let param = dump[i]; + if (typeof(param) === "string") + this.params.push([param, null]); + else + this.params.push(param); + } + } + + _eval(context) + { + let args = []; + for (let i = 0; i < this.params.length; ++i) + { + let param = this.params[i]; + if (param[1] === null) + args.push(param[0]); + else + { + args.push(param[0] + "="); + args.push(param[1]._handle_eval(context)); + } + } + return new ul4.Signature(...args); + } + + _repr(out) + { + out.push("<"); + out.push(this.constructor.name); + out.push(" params="); + this.params._repr(out); + out.push(">"); + } + }; + + ul4.TemplateClosure = class TemplateClosure extends ul4.Proto + { + constructor(template, signature, vars) + { + super(); + this.template = template; + this.signature = signature; + this.vars = vars; + this._ul4_callsignature = signature; + this._ul4_rendersignature = signature; + // Copy over the required attribute from the template + this.name = template.name; + this.tag = template.tag; + this.endtag = template.endtag; + this._source = template._source; + this.startdelim = template.startdelim; + this.enddelim = template.enddelim; + this.docpos = template.docpos; + this.content = template.content; + } + + __render__(context, vars) + { + this.template._renderbound(context, ul4._inherit(this.vars, vars)); + } + + render(context, vars) + { + this.template._renderbound(context, ul4._inherit(this.vars, vars)); + } + + __call__(context, vars) + { + return this.template._callbound(context, ul4._inherit(this.vars, vars)); + } + + _renderbound(context, vars) + { + this.template._renderbound(context, ul4._inherit(this.vars, vars)); + } + + _rendersbound(context, vars) + { + return this.template._rendersbound(context, ul4._inherit(this.vars, vars)); + } + + __getattr__(attrname) + { + let self = this; + switch (attrname) + { + case "render": + let render = function render(context, vars){ self._renderbound(context, vars); }; + ul4.expose(render, this.signature, {needscontext: true, needsobject: true}); + return render; + case "renders": + let renders = function renders(context, vars){ return self._rendersbound(context, vars); }; + ul4.expose(renders, this.signature, {needscontext: true, needsobject: true}); + return renders; + case "signature": + return this.signature; + default: + return this.template.__getattr__(attrname); + } + } + + ul4type() + { + return "template"; + } + }; + + ul4.TemplateClosure.prototype._ul4_callneedsobject = true; + ul4.TemplateClosure.prototype._ul4_callneedscontext = true; + ul4.TemplateClosure.prototype._ul4_renderneedsobject = true; + ul4.TemplateClosure.prototype._ul4_renderneedscontext = true; + + // Create a color object from the red, green, blue and alpha values ``r``, ``g``, ``b`` and ``b`` + ul4._rgb = function _rgb(r, g, b, a) + { + return new this.Color(255*r, 255*g, 255*b, 255*a); + }; + + // Convert ``obj`` to a string and escape the characters ``&``, ``<``, ``>``, ``'`` and ``"`` with their XML character/entity reference + ul4._xmlescape = function _xmlescape(obj) + { + obj = ul4._str(obj); + obj = obj.replace(/&/g, "&"); + obj = obj.replace(//g, ">"); + obj = obj.replace(/'/g, "'"); + obj = obj.replace(/"/g, """); + return obj; + }; + + // Convert ``obj`` to a string suitable for output into a CSV file + ul4._csv = function _csv(obj) + { + if (obj === null) + return ""; + else if (typeof(obj) !== "string") + obj = ul4._repr(obj); + if (obj.indexOf(",") !== -1 || obj.indexOf('"') !== -1 || obj.indexOf("\n") !== -1) + obj = '"' + obj.replace(/"/g, '""') + '"'; + return obj; + }; + + // Return a string containing one character with the codepoint ``i`` + ul4._chr = function _chr(i) + { + if (typeof(i) != "number") + throw new ul4.TypeError("chr() requires an int"); + return String.fromCharCode(i); + }; + + // Return the codepoint for the one and only character in the string ``c`` + ul4._ord = function _ord(c) + { + if (typeof(c) != "string" || c.length != 1) + throw new ul4.TypeError("ord() requires a string of length 1"); + return c.charCodeAt(0); + }; + + // Convert an integer to a hexadecimal string + ul4._hex = function _hex(number) + { + if (typeof(number) != "number") + throw new ul4.TypeError("hex() requires an int"); + if (number < 0) + return "-0x" + number.toString(16).substr(1); + else + return "0x" + number.toString(16); + }; + + // Convert an integer to a octal string + ul4._oct = function _oct(number) + { + if (typeof(number) != "number") + throw new ul4.TypeError("oct() requires an int"); + if (number < 0) + return "-0o" + number.toString(8).substr(1); + else + return "0o" + number.toString(8); + }; + + // Convert an integer to a binary string + ul4._bin = function _bin(number) + { + if (typeof(number) != "number") + throw new ul4.TypeError("bin() requires an int"); + if (number < 0) + return "-0b" + number.toString(2).substr(1); + else + return "0b" + number.toString(2); + }; + + // Return the minimum value + ul4._min = function _min(obj) + { + if (obj.length == 0) + throw new ul4.ArgumentError("min() requires at least 1 argument, 0 given"); + else if (obj.length == 1) + obj = obj[0]; + let iter = ul4._iter(obj); + let result; + let first = true; + while (true) + { + let item = iter.next(); + if (item.done) + { + if (first) + throw new ul4.ValueError("min() argument is an empty sequence!"); + return result; + } + if (first || (item.value < result)) + result = item.value; + first = false; + } + }; + + // Return the maximum value + ul4._max = function _max(obj) + { + if (obj.length == 0) + throw new ul4.ArgumentError("max() requires at least 1 argument, 0 given"); + else if (obj.length == 1) + obj = obj[0]; + let iter = ul4._iter(obj); + let result; + let first = true; + while (true) + { + let item = iter.next(); + if (item.done) + { + if (first) + throw new ul4.ValueError("max() argument is an empty sequence!"); + return result; + } + if (first || (item.value > result)) + result = item.value; + first = false; + } + }; + + // Return the of the values from the iterable starting with ``start`` (default ``0``) + ul4._sum = function _sum(iterable, start=0) + { + for (let iter = ul4._iter(iterable);;) + { + let item = iter.next(); + if (item.done) + break; + start += item.value; + } + return start; + }; + + // Return the first value produced by iterating through ``iterable`` (defaulting to ``defaultValue`` if the iterator is empty) + ul4._first = function _first(iterable, defaultValue=null) + { + let item = ul4._iter(iterable).next(); + return item.done ? defaultValue : item.value; + }; + + // Return the last value produced by iterating through ``iterable`` (defaulting to ``defaultValue`` if the iterator is empty) + ul4._last = function _last(iterable, defaultValue=null) + { + let value = defaultValue; + + for (let iter = ul4._iter(iterable);;) + { + let item = iter.next(); + if (item.done) + break; + value = item.value; + } + return value; + }; + + // Return a sorted version of ``iterable`` + ul4._sorted = function _sorted(context, iterable, key=null, reverse=false) + { + if (key === null) + { + // FIXME: stability + let cmp = reverse ? function cmp(a, b) + { + return -ul4._cmp("<=>", a, b); + } : function cmp(a, b) + { + return ul4._cmp("<=>", a, b); + }; + let result = ul4._list(iterable); + result.sort(cmp); + return result; + } + else + { + let sort = []; + + for (let i = 0, iter = ul4._iter(iterable);;++i) + { + let item = iter.next(); + if (item.done) + break; + let keyvalue = ul4._call(context, key, [item.value], {}); + // For a stable sorting we have to use the nagative index if + // reverse sorting is specified + sort.push([keyvalue, reverse ? -i : i, item.value]); + } + cmp = function cmp(s1, s2) + { + let res = ul4._cmp("<=>", s1[0], s2[0]); + if (res) + return reverse ? -res : res; + res = ul4._cmp("<=>", s1[1], s2[1]); + return reverse ? -res : res; + }; + + sort.sort(cmp); + + let result = []; + for (let i = 0; i < sort.length; ++i) + { + let item = sort[i]; + result.push(item[2]); + } + return result; + } + }; + + // Return a iterable object iterating from ``start`` up to (but not including) ``stop`` with a step size of ``step`` + ul4._range = function _range(args) + { + let start, stop, step; + if (args.length < 1) + throw new ul4.ArgumentError("required range() argument missing"); + else if (args.length > 3) + throw new ul4.ArgumentError("range() expects at most 3 positional arguments, " + args.length + " given"); + else if (args.length == 1) + { + start = 0; + stop = args[0]; + step = 1; + } + else if (args.length == 2) + { + start = args[0]; + stop = args[1]; + step = 1; + } + else if (args.length == 3) + { + start = args[0]; + stop = args[1]; + step = args[2]; + } + let lower, higher; + if (step === 0) + throw new ul4.ValueError("range() requires a step argument != 0"); + else if (step > 0) + { + lower = start; + higher = stop; + } + else + { + lower = stop; + higher = start; + } + let length = (lower < higher) ? Math.floor((higher - lower - 1)/Math.abs(step)) + 1 : 0; + + return { + index: 0, + next: function() + { + if (this.index >= length) + return {done: true}; + return {value: start + (this.index++) * step, done: false}; + } + }; + }; + + // Return a iterable object returning a slice from the argument + ul4._slice = function _slice(args) + { + let iterable, start, stop, step; + if (args.length < 2) + throw new ul4.ArgumentError("required slice() argument missing"); + else if (args.length > 4) + throw new ul4.ArgumentError("slice() expects at most 4 positional arguments, " + args.length + " given"); + else if (args.length == 2) + { + iterable = args[0]; + start = 0; + stop = args[1]; + step = 1; + } + else if (args.length == 3) + { + iterable = args[0]; + start = args[1] !== null ? args[1] : 0; + stop = args[2]; + step = 1; + } + else if (args.length == 4) + { + iterable = args[0]; + start = args[1] !== null ? args[1] : 0; + stop = args[2]; + step = args[3] !== null ? args[3] : 1; + } + if (start < 0) + throw new ul4.ValueError("slice() requires a start argument >= 0"); + if (stop < 0) + throw new ul4.ValueError("slice() requires a stop argument >= 0"); + if (step <= 0) + throw new ul4.ValueError("slice() requires a step argument > 0"); + + let next = start, count = 0; + let iter = ul4._iter(iterable); + return { + next: function() { + let result; + while (count < next) + { + result = iter.next(); + if (result.done) + return result; + ++count; + } + if (stop !== null && count >= stop) + return {done: true}; + result = iter.next(); + if (result.done) + return result; + ++count; + next += step; + if (stop !== null && next > stop) + next = stop; + return result; + } + }; + }; + + // ``%`` escape unsafe characters in the string ``string`` + ul4._urlquote = function _urlquote(string) + { + return encodeURIComponent(string); + }; + + // The inverse function of ``urlquote`` + ul4._urlunquote = function _urlunquote(string) + { + return decodeURIComponent(string); + }; + + // Return a reverse iterator over ``sequence`` + ul4._reversed = function _reversed(sequence) + { + if (typeof(sequence) != "string" && !ul4._islist(sequence)) // We don't have to materialize strings or lists + sequence = ul4._list(sequence); + return { + index: sequence.length-1, + next: function() { + return this.index >= 0 ? {value: sequence[this.index--], done: false} : {done: true}; + } + }; + }; + + // Returns a random number in the interval ``[0;1[`` + ul4._random = function _random() + { + return Math.random(); + }; + + // Return a randomly select item from ``range(start, stop, step)`` + ul4._randrange = function _randrange(args) + { + let start, stop, step; + if (args.length < 1) + throw new ul4.ArgumentError("required randrange() argument missing"); + else if (args.length > 3) + throw new ul4.ArgumentError("randrange() expects at most 3 positional arguments, " + args.length + " given"); + else if (args.length == 1) + { + start = 0; + stop = args[0]; + step = 1; + } + else if (args.length == 2) + { + start = args[0]; + stop = args[1]; + step = 1; + } + else if (args.length == 3) + { + start = args[0]; + stop = args[1]; + step = args[2]; + } + let width = stop-start; + + let value = Math.random(); + + let n; + if (step > 0) + n = Math.floor((width + step - 1) / step); + else if (step < 0) + n = Math.floor((width + step + 1) / step); + else + throw new ul4.ValueError("randrange() requires a step argument != 0"); + return start + step*Math.floor(value * n); + }; + + // Return a random item/char from the list/string ``sequence`` + ul4._randchoice = function _randchoice(sequence) + { + let iscolor = ul4._iscolor(sequence); + if (typeof(sequence) !== "string" && !ul4._islist(sequence) && !iscolor) + throw new ul4.TypeError("randchoice() requires a string or list"); + if (iscolor) + sequence = ul4._list(sequence); + return sequence[Math.floor(Math.random() * sequence.length)]; + }; + + // Round a number ``x`` to ``digits`` decimal places (may be negative) + ul4._round = function _round(x, digits=0) + { + if (digits) + { + let threshold = Math.pow(10, digits); + return Math.round(x*threshold)/threshold; + } + else + return Math.round(x); + }; + + // Return a hex-encode MD5 hash of the argument + // This uses the md5 function from https://github.com/blueimp/JavaScript-MD5 + if (iscommon) + { + ul4._md5 = function _md5(string) + { + let md5 = require('blueimp-md5'); + return md5(string); + }; + } + else + { + ul4._md5 = function _md5(string) + { + return md5(string); + }; } - ul4.version = "41"; - - // - // UL4ON - // - - ul4on._registry = {}; - - ul4on._havemap = (typeof(Map) === "function" && typeof(Map.prototype.forEach) === "function"); - - ul4on._havemapconstructor = false; - - if (ul4on._havemap) - { - try - { - if (new Map([[1, 2]]).size == 1) - ul4on._havemapconstructor = true; - } - catch (error) - { - } - } - - ul4on._haveset = (typeof(Set) === "function" && typeof(Set.prototype.forEach) === "function"); - - ul4on._havesetconstructor = false; - - if (ul4on._haveset) - { - try - { - if (new Set([1, 2]).size == 2) - ul4on._havesetconstructor = true; - } - catch (error) - { - } - } - - // Function used for making maps, when the Map constructor doesn't work - ul4on._makemap = function _makemap() - { - var map = new Map(); - - for (var i = 0; i < arguments.length; ++i) - { - var argument = arguments[i]; - map.set(argument[0], argument[1]); - } - return map; - }; - - // Function that creates en empty Map (if supported) or an empty object - ul4on._emptymap = function _emptymap() - { - return ul4on._havemap ? new Map() : {}; - }; - - // Function that adds a (key, value) item to an object (or map) - if (ul4on._havemap) - { - ul4on._setmap = function _setmap(map, key, value) - { - if (map.__proto__ === Map.prototype) - map.set(key, value); - else - map[key] = value; - }; - } - else - { - ul4on._setmap = function _setmap(map, key, value) - { - map[key] = value; - }; - } - - // Function used for making sets, when the Set constructor doesn't work (or we don't have sets) - if (ul4on._haveset) - { - ul4on._makeset = function _makeset() - { - var set = this._haveset ? new Set() : ul4._Set.create(); - - for (var i = 0; i < arguments.length; ++i) - set.add(arguments[i]); - return set; - }; - } - else - { - ul4on._makeset = function _makeset() - { - var set = ul4._Set.create(); - - for (var i = 0; i < arguments.length; ++i) - set.add(arguments[i]); - return set; - }; - } - - // Register the object ``obj`` under the name ``name`` with the UL4ON machinery - ul4on.register = function register(name, obj) - { - obj.ul4onname = name; - ul4on._registry[name] = function(){return obj.create();}; - }, - - // Return a string that contains the object ``obj`` in the UL4ON serialization format - ul4on.dumps = function dumps(obj, indent) - { - var encoder = ul4on.Encoder.create(indent); - encoder.dump(obj); - return encoder.finish(); - }, - - // Load an object from the string ``data``. - // ``data`` must contain the object in the UL4ON serialization format - // ``registry`` may be null or a dictionary mapping type names to objects with a create method - ul4on.loads = function loads(data, registry) - { - var decoder = ul4on.Decoder.create(data, registry); - return decoder.load(); - }, - - // Helper "class" for encoding - ul4on.Encoder = { - // Create a new Encoder object - create: function create(indent) - { - var encoder = ul4._clone(this); - encoder.indent = indent || null; - encoder.data = []; - encoder._level = 0; - encoder._strings2index = {}; - encoder._ids2index = {}; - encoder._backrefs = 0; - return encoder; - }, - - _line: function _line(line) - { - var i, oldindent; - - if (this.indent !== null) - { - for (i = 0; i < this._level; ++i) - this.data.push(this.indent); - } - else - { - if (this.data.length) - this.data.push(" "); - } - this.data.push(line); - - if (arguments.length > 1) - { - oldindent = this.indent; - this.indent = null; - for (i = 1; i < arguments.length; ++i) - this.dump(arguments[i]); - this.indent = oldindent; - } - - if (this.indent !== null) - this.data.push("\n"); - }, - - // Return the complete string written to the buffer - finish: function finish() - { - return this.data.join(""); - }, - - dump: function dump(obj) - { - if (obj === null) - this._line("n"); - else if (typeof(obj) == "boolean") - this._line(obj ? "bT" : "bF"); - else if (typeof(obj) == "number") - { - var type = (Math.round(obj) == obj) ? "i" : "f"; - this._line(type + obj); - } - else if (typeof(obj) == "string") - { - var index = this._strings2index[obj]; - if (typeof(index) !== "undefined") - { - this._line("^" + index); - } - else - { - this._strings2index[obj] = this._backrefs++; - this._line("S" + ul4._str_repr(obj)); - } - } - else if (ul4._iscolor(obj)) - this._line("c", obj.r(), obj.g(), obj.b(), obj.a()); - else if (ul4._isdate(obj)) - this._line("z", obj.getFullYear(), obj.getMonth()+1, obj.getDate(), obj.getHours(), obj.getMinutes(), obj.getSeconds(), obj.getMilliseconds() * 1000); - else if (ul4._istimedelta(obj)) - this._line("t", obj.days(), obj.seconds(), obj.microseconds()); - else if (ul4._ismonthdelta(obj)) - this._line("m", obj.months()); - else if (typeof(obj) === "object" && typeof(obj.isa) === "function" && obj.isa(ul4.slice)) - this._line("r", obj.start, obj.stop); - else if (obj.ul4onname && obj.ul4ondump) - { - if (obj.__id__) - { - var index = this._ids2index[obj.__id__]; - if (typeof(index) != "undefined") - { - this._line("^" + index); - return; - } - } - if (obj.__id__) - this._ids2index[obj.__id__] = this._backrefs++; - this._line("O", obj.ul4onname); - ++this._level; - obj.ul4ondump(this); - --this._level; - this._line(")"); - } - else if (ul4._islist(obj)) - { - this._line("l"); - ++this._level; - for (var i in obj) - this.dump(obj[i]); - --this._level; - this._line("]"); - } - else if (ul4._ismap(obj)) - { - this._line("e"); - ++this._level; - obj.forEach(function(value, key) { - this.dump(key); - this.dump(value); - }, this); - --this._level; - this._line("}"); - } - else if (ul4._isdict(obj)) - { - this._line("d"); - ++this._level; - for (var key in obj) - { - this.dump(key); - this.dump(obj[key]); - } - --this._level; - this._line("}"); - } - else if (ul4._isset(obj)) - { - this._line("y"); - ++this._level; - obj.forEach(function(value) { - this.dump(value); - }, this); - --this._level; - this._line("}"); - } - else - throw "can't handle object"; - } - }; - - // Helper "class" for decoding - ul4on.Decoder = { - // Creates a new decoder for reading from the string ``data`` - create: function create(data, registry) - { - var decoder = ul4._clone(this); - decoder.data = data; - decoder.pos = 0; - decoder.backrefs = []; - decoder.registry = typeof(registry) === "undefined" ? null : registry; - return decoder; - }, - - // Read a character from the buffer - readchar: function readchar() - { - if (this.pos >= this.data.length) - throw "UL4 decoder at EOF"; - return this.data.charAt(this.pos++); - }, - - // Read a character from the buffer (return null on eof) - readcharoreof: function readcharoreof() - { - if (this.pos >= this.data.length) - return null; - return this.data.charAt(this.pos++); - }, - - // Read next not-whitespace character from the buffer - readblackchar: function readblackchar() - { - var re_white = /\s/; - - for (;;) - { - if (this.pos >= this.data.length) - throw "UL4 decoder at EOF"; - var c = this.data.charAt(this.pos++); - if (!c.match(re_white)) - return c; - } - }, - - // Read ``size`` characters from the buffer - read: function read(size) - { - if (this.pos+size > this.length) - size = this.length-this.pos; - var result = this.data.substring(this.pos, this.pos+size); - this.pos += size; - return result; - }, - - // "unread" one character - backup: function backup() - { - --this.pos; - }, - - // Read a number from the buffer - readnumber: function readnumber() - { - var re_digits = /[-+0123456789.eE]/, value = ""; - for (;;) - { - var c = this.readcharoreof(); - if (c !== null && c.match(re_digits)) - value += c; - else - { - var result = parseFloat(value); - if (result == NaN) - throw "invalid number, got " + ul4._repr("value") + " at position " + this.pos; - return result; - } - } - }, - - _beginfakeloading: function _beginfakeloading() - { - var oldpos = this.backrefs.length; - this.backrefs.push(null); - return oldpos; - }, - - _endfakeloading: function _endfakeloading(oldpos, value) - { - this.backrefs[oldpos] = value; - }, - - _readescape: function _readescape(escapechar, length) - { - var chars = this.read(length); - if (chars.length != length) - throw "broken escape " + ul4._repr("\\" + escapechar + chars) + " at position " + this.pos; - var codepoint = parseInt(chars, 16); - if (isNaN(codepoint)) - throw "broken escape " + ul4._repr("\\" + escapechar + chars) + " at position " + this.pos; - return String.fromCharCode(codepoint); - }, - - // Load the next object from the buffer - load: function load() - { - var typecode = this.readblackchar(); - var result; - switch (typecode) - { - case "^": - return this.backrefs[this.readnumber()]; - case "n": - case "N": - if (typecode === "N") - this.backrefs.push(null); - return null; - case "b": - case "B": - result = this.readchar(); - if (result === "T") - result = true; - else if (result === "F") - result = false; - else - throw "wrong value for boolean, expected 'T' or 'F', got " + ul4._repr(result) + " at position " + this.pos; - if (typecode === "B") - this.backrefs.push(result); - return result; - case "i": - case "I": - case "f": - case "F": - result = this.readnumber(); - if (typecode === "I" || typecode === "F") - this.backrefs.push(result); - return result; - case "s": - case "S": - result = []; - var delimiter = this.readblackchar(); - for (;;) - { - var c = this.readchar(); - if (c == delimiter) - break; - if (c == "\\") - { - var c2 = this.readchar(); - if (c2 == "\\") - result.push("\\"); - else if (c2 == "n") - result.push("\n"); - else if (c2 == "r") - result.push("\r"); - else if (c2 == "t") - result.push("\t"); - else if (c2 == "f") - result.push("\u000c"); - else if (c2 == "b") - result.push("\u0008"); - else if (c2 == "a") - result.push("\u0007"); - else if (c2 == "'") - result.push("'"); - else if (c2 == '"') - result.push('"'); - else if (c2 == "x") - result.push(this._readescape("x", 2)); - else if (c2 == "u") - result.push(this._readescape("u", 4)); - else if (c2 == "U") - result.push(this._readescape("U", 8)); - else - result.push("\\" + c2); - } - else - result.push(c); - } - result = result.join(""); - if (typecode === "S") - this.backrefs.push(result); - return result; - case "c": - case "C": - result = ul4.Color.create(); - if (typecode === "C") - this.backrefs.push(result); - result._r = this.load(); - result._g = this.load(); - result._b = this.load(); - result._a = this.load(); - return result; - case "z": - case "Z": - result = new Date(); - result.setFullYear(this.load()); - result.setDate(1); - result.setMonth(this.load() - 1); - result.setDate(this.load()); - result.setHours(this.load()); - result.setMinutes(this.load()); - result.setSeconds(this.load()); - result.setMilliseconds(this.load()/1000); - if (typecode === "Z") - this.backrefs.push(result); - return result; - case "t": - case "T": - result = ul4.TimeDelta.create(); - result._days = this.load(); - result._seconds = this.load(); - result._microseconds = this.load(); - if (typecode === "T") - this.backrefs.push(result); - return result; - case "r": - case "R": - result = ul4.slice.create(); - if (typecode === "R") - this.backrefs.push(result); - result.start = this.load(); - result.stop = this.load(); - return result; - case "m": - case "M": - result = ul4.MonthDelta.create(); - if (typecode === "M") - this.backrefs.push(result); - result._months = this.load(); - return result; - case "l": - case "L": - result = []; - if (typecode === "L") - this.backrefs.push(result); - for (;;) - { - typecode = this.readblackchar(); - if (typecode === "]") - return result; - this.backup(); - result.push(this.load()); - } - return result; - case "d": - case "D": - case "e": - case "E": - if (!ul4on._havemap && (typecode == "e" || typecode == "E")) - throw "ordered dictionaries are not supported!"; - result = ul4on._emptymap(); - if (typecode === "D" || typecode === "E") - this.backrefs.push(result); - for (;;) - { - typecode = this.readblackchar(); - if (typecode === "}") - return result; - this.backup(); - var key = this.load(); - var value = this.load(); - ul4on._setmap(result, key, value); - } - return result; - case "y": - case "Y": - result = ul4on._makeset(); - if (typecode === "Y") - this.backrefs.push(result); - for (;;) - { - typecode = this.readblackchar(); - if (typecode === "}") - return result; - this.backup(); - result.add(this.load()); - } - return result; - case "o": - case "O": - var oldpos; - if (typecode === "O") - oldpos = this._beginfakeloading(); - var name = this.load(); - var proto; - if (this.registry !== null) - { - proto = this.registry[name]; - if (typeof(proto) === "undefined") - proto = ul4on._registry[name]; - } - else - proto = ul4on._registry[name]; - if (typeof(proto) === "undefined") - throw "can't load object of type " + ul4._repr(name); - result = proto(); - if (typecode === "O") - this._endfakeloading(oldpos, result); - result.ul4onload(this); - typecode = this.readblackchar(); - if (typecode !== ")") - throw "object terminator ')' for object of type '" + name + "' expected, got " + ul4._repr(typecode) + " at position " + this.pos; - return result; - default: - throw "unknown typecode " + ul4._repr(typecode) + " at position " + this.pos; - } - }, - - // Return an iterator for loading the content of a object - loadcontent: function load(loadcontent) - { - let self = this; - return { - next: function() - { - let typecode = self.readblackchar(); - self.backup(); - if (typecode == ")") - return {done: true}; - else - return {done: false, value: self.load()}; - } - }; - } - }; - - - // - // UL4 - // - - // REs for parsing JSON - ul4._rvalidchars = /^[\],:{}\s]*$/; - ul4._rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g; - ul4._rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; - ul4._rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g; - - /// Helper functions - - // Crockford style object creation - ul4._simpleclone = function _simpleclone(obj) - { - function F(){}; - F.prototype = obj; - var result = new F(); - return result; - }; - - // Crockford style object creation + prototype chain + object ids - ul4._clone = function _clone(obj) - { - var result = ul4._simpleclone(obj); - result.__prototype__ = obj; - result.__id__ = ul4.Proto._nextid++; - return result; - }; - - // Adds attributes from on object to another and returns it - ul4._extend = function _extend(obj, attrs) - { - for (var name in attrs) - obj[name] = attrs[name]; - return obj; - }; - - // Clone an object via ``_simpleclone`` and extend it - ul4._simpleinherit = function _simpleinherit(baseobj, attrs) - { - return ul4._extend(ul4._simpleclone(baseobj), attrs); - }; - - // Clone an object via ``_clone`` and extend it - ul4._inherit = function _inherit(baseobj, attrs) - { - return ul4._extend(ul4._clone(baseobj), attrs); - }; - - // Convert a map to an object - ul4._map2object = function _map2object(obj) - { - if (ul4._ismap(obj)) - { - var newobj = {}; - obj.forEach(function(value, key){ - if (typeof(key) !== "string") - throw ul4.TypeError.create("keys must be strings"); - newobj[key] = value; - }); - return newobj; - } - return obj; - }; - - // Clip a number to the range [0;max) - ul4._bound = function _bound(value, upper) - { - if (value < 0) - return 0; - else if (value > upper) - return upper; - else - return value; - }; - - // Create a pretty stacktrace from an exception - ul4._stacktrace = function _stacktrace(exc) - { - var output = ul4._type(exc); - var s = exc.toString(); - if (s) - output += ": " + s; - if (exc.cause) - output += "\n\n" + ul4._stacktrace(exc.cause); - return output; - }; - - // Call a function ``f`` with UL4 argument handling - ul4._internal_call = function _internal_call(context, f, name, functioncontext, signature, needscontext, needsobject, args, kwargs) - { - var finalargs; - if (needsobject) - { - if (signature === null) - { - if (args.length) - throw ul4.ArgumentError.create(ul4._repr(f) + " doesn't support positional arguments!"); - finalargs = [kwargs]; - } - else - finalargs = [signature.bindObject(name, args, kwargs)]; - } - else - { - if (signature === null) - throw ul4.ArgumentError.create(ul4._repr(f) + " doesn't support positional arguments!"); - finalargs = signature.bindArray(name, args, kwargs); - } - if (needscontext) - finalargs.unshift(context); - return f.apply(functioncontext, finalargs); - }; - - ul4._callfunction = function _callfunction(context, f, args, kwargs) - { - var name = f._ul4_name || f.name; - if (typeof(f._ul4_signature) === "undefined" || typeof(f._ul4_needsobject) === "undefined" || typeof(f._ul4_needscontext) === "undefined") - throw ul4.TypeError.create("call", "function " + ul4.repr(f) + " is not callable by UL4"); - return ul4._internal_call(context, f, name, ul4, f._ul4_signature, f._ul4_needscontext, f._ul4_needsobject, args, kwargs); - } - - ul4._callobject = function _callobject(context, obj, args, kwargs) - { - if (typeof(obj._ul4_callsignature) === "undefined" || typeof(obj._ul4_callneedsobject) === "undefined" || typeof(obj._ul4_callneedscontext) === "undefined") - throw ul4.TypeError.create("call", ul4.type(obj) + " object is not callable by UL4"); - return ul4._internal_call(context, obj.__call__, obj.name, obj, obj._ul4_callsignature, obj._ul4_callneedscontext, obj._ul4_callneedsobject, args, kwargs); - } - - ul4._callrender = function _callrender(context, obj, args, kwargs) - { - if (typeof(obj._ul4_rendersignature) === "undefined" || typeof(obj._ul4_renderneedsobject) === "undefined" || typeof(obj._ul4_renderneedscontext) === "undefined") - throw ul4.TypeError.create("render", ul4.type(obj) + " object is not renderable by UL4"); - return ul4._internal_call(context, obj.__render__, obj.name, obj, obj._ul4_rendersignature, obj._ul4_renderneedscontext, obj._ul4_renderneedsobject, args, kwargs); - } - - ul4._call = function _call(context, f, args, kwargs) - { - if (typeof(f) === "function") - return ul4._callfunction(context, f, args, kwargs); - else if (f && typeof(f.__call__) === "function") - return ul4._callobject(context, f, args, kwargs); - else - throw ul4.TypeError.create("call", ul4._type(f) + " is not callable"); - } - - ul4._unpackvar = function _unpackvar(lvalue, value) - { - if (!ul4._islist(lvalue)) - return [[lvalue, value]]; - else - { - var newvalue = []; - var iter = ul4._iter(value); - - for (var i = 0;;++i) - { - var item = iter.next(); - - if (item.done) - { - if (i === lvalue.length) - break; - else - throw ul4.ValueError.create("need " + lvalue.length + " value" + (lvalue.length === 1 ? "" : "s") + " to unpack, got " + i); - } - else - { - if (i < lvalue.length) - newvalue = newvalue.concat(ul4._unpackvar(lvalue[i], item.value)); - else - throw ul4.ValueError.create("too many values to unpack (expected " + lvalue.length + ")"); - } - } - return newvalue; - } - }; - - ul4._formatsource = function _formatsource(out) - { - var finalout = []; - var level = 0, needlf = false; - for (var i = 0; i < out.length; ++i) - { - if (typeof(out[i]) === "number") - { - level += out[i]; - needlf = true; - } - else - { - if (needlf) - { - finalout.push("\n"); - for (var j = 0; j < level; ++j) - finalout.push("\t"); - needlf = false; - } - finalout.push(out[i]); - } - } - if (needlf) - finalout.push("\n"); - return finalout.join(""); - }; - - // Compare ``obj1`` and ``obj2`` if they have the same value - ul4._eq = function _eq(obj1, obj2) - { - var numbertypes = ["boolean", "number"]; - - if (obj1 && typeof(obj1.__eq__) === "function") - return obj1.__eq__(obj2); - else if (obj2 && typeof(obj2.__eq__) === "function") - return obj2.__eq__(obj1); - else if (obj1 === null) - return obj2 === null; - else if (numbertypes.indexOf(typeof(obj1)) != -1) - { - if (numbertypes.indexOf(typeof(obj2)) != -1) - return obj1 == obj2 - else - return false; - } - else if (typeof(obj1) === "string") - { - if (typeof(obj2) === "string") - return obj1 == obj2; - else - return false; - } - else if (ul4._isdate(obj1)) - { - if (ul4._isdate(obj2)) - return obj1.getTime() == obj2.getTime(); - else - return false; - } - else if (ul4._islist(obj1)) - { - if (ul4._islist(obj2)) - { - // Shortcut, if it's the same object - if (obj1 === obj2) - return true; - if (obj1.length != obj2.length) - return false; - for (var i = 0; i < obj1.length; ++i) - { - if (!ul4._eq(obj1[i], obj2[i])) // This might lead to infinite recursion and a stackoverflow, but it does in all implementations - return false; - } - return true; - } - else - return false; - } - else if (ul4._isobject(obj1)) - { - if (ul4._isobject(obj2)) - { - // Shortcut, if it's the same object - if (obj1 === obj2) - return true; - // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value - for (var key in obj1) - { - if (obj2.hasOwnProperty(key)) - { - if (!ul4._eq(obj1[key], obj2[key])) - return false; - } - else - return false; - } - // Test that each attribute of ``obj2`` is alos in ``obj1`` (the value has been tested before) - for (var key in obj2) - { - if (!obj1.hasOwnProperty(key)) - return false; - } - return true; - } - else if (ul4._ismap(obj2)) - { - // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value - for (var key in obj1) - { - if (obj2.has(key)) - { - if (!ul4._eq(obj1[key], obj2.get(key))) - return false; - } - else - return false; - } - // Test that each attribute of ``obj2`` is alos in ``obj1`` (the value has been tested before) - var result = true; - obj2.forEach(function(value, key){ - if (!obj1.hasOwnProperty(key)) - result = false; - }); - return result; - } - else - return false; - } - else if (ul4._ismap(obj1)) - { - if (ul4._isobject(obj2)) - { - // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value - var result = true; - obj1.forEach(function(value, key){ - if (result) // Skip code, if result is already ``false`` - { - if (!obj2.hasOwnProperty(key)) - result = false; - else if (!ul4._eq(obj1.get(key), obj2[key])) - result = false; - } - }); - if (!result) - return false; - // Test that each attribute of ``obj2`` is alos in ``obj1`` (the value has been tested before) - for (var key in obj2) - { - if (!obj1.has(key)) - return false; - } - return true; - } - else if (ul4._ismap(obj2)) - { - // Shortcut, if it's the same object - if (obj1 === obj2) - return true; - if (obj1.size != obj2.size) - return false; - // Test that each attribute of ``obj1`` can also be found in ``obj2`` and has the same value - var result = true; - obj1.forEach(function(value, key){ - if (result) // Skip code, if result is already ``false`` - { - if (!obj2.has(key)) - result = false; - else if (!ul4._eq(obj1.get(key), obj2.get(key))) - result = false; - } - }); - return result; - } - else - return false; - } - else if (ul4._isset(obj1)) - { - // We don't have to test for ``ul4._Set`` as ``ul4._Set`` implements ``__eq__`` - if (ul4._isset(obj2)) - { - // Shortcut, if it's the same object - if (obj1 === obj2) - return true; - if (obj1.size != obj2.size) - return false; - var result = true; - obj1.forEach(function(value){ - if (result) // Skip code, if result is already ``false`` - { - if (!obj2.has(value)) - result = false; - } - }); - return result; - } - else - return false; - } - else - return obj1 === obj2; - }; - - // Compare ``obj1`` and ``obj2`` if they don't have the same value - ul4._ne = function _ne(obj1, obj2) - { - if (obj1 && typeof(obj1.__ne__) === "function") - return obj1.__ne__(obj2); - else if (obj2 && typeof(obj2.__ne__) === "function") - return obj2.__ne__(obj1); - else - return !ul4._eq(obj1, obj2); - } - - ul4._unorderable = function _unorderable(operator, obj1, obj2) - { - throw ul4.TypeError.create(operator, "unorderable types: " + ul4._type(obj1) + " " + operator + " " + ul4._type(obj2)); - }; - - // Return: - // -1 when ``obj1 < obj2``, - // 0 when ``obj1 == obj2``, - // 1 when ``obj1 > obj2``, - // null when ``obj1`` and ``obj2`` are comparable, but neither of the previous cases holds (only for sets) - // raise TypeError if objects are uncomparable - // This the purpose of ``_cmp`` is to support implementation of <, <=, > and >= - // and dicts/maps are not comparable with the operator ``_cmp`` does not support dicts/maps - - ul4._cmp = function _cmp(operator, obj1, obj2) - { - var numbertypes = ["boolean", "number"]; - - if (numbertypes.indexOf(typeof(obj1)) != -1) - { - if (numbertypes.indexOf(typeof(obj2)) != -1) - return (obj1 > obj2) - (obj1 < obj2); - } - else if (typeof(obj1) === "string") - { - if (typeof(obj2) === "string") - return (obj1 > obj2) - (obj1 < obj2); - } - else if (ul4._isdate(obj1)) - { - if (ul4._isdate(obj2)) - { - var v1 = obj1.getTime(), v2 = obj2.getTime(); - return (v1 > v2) - (v1 < v2); - } - } - else if (ul4._islist(obj1)) - { - if (ul4._islist(obj2)) - { - if (obj1 === obj2) - return 0; - for (var i = 0; i < obj1.length; ++i) - { - if (i >= obj2.length) - return 1; - var res = ul4._cmp(operator, obj1[i], obj2[i]); - if (res) - return res; - } - return obj2.length > obj1.length ? -1 : 0; - } - } - else if (ul4._isset(obj1) || ul4._isul4set(obj1)) - { - var in1only = false; - var in2only = false; - - if (ul4._isset(obj2)) - { - if (ul4._isset(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.has(value)) - in1only = true; - }); - obj2.forEach(function(value){ - if (!obj1.has(value)) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.items[value]) - in1only = true; - }); - for (var value in obj2.items) - { - if (!obj1.has(value)) - { - in2only = true; - break; - } - } - } - } - else if (ul4._isul4set(obj2)) - { - if (ul4._isset(obj2)) - { - for (var value in obj1.items) - { - if (!obj2.has(value)) - { - in1only = true; - break; - } - } - obj2.forEach(function(value){ - if (!obj1.items[value]) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - for (var value in obj1.items) - { - if (!obj2.items[value]) - { - in1only = true; - break; - } - } - for (var value in obj2.items) - { - if (!obj1.items[value]) - { - in2only = true; - break; - } - } - } - } - else - ul4._unorderable(operator, obj1, obj2); - - if (in1only) - { - if (in2only) - return null; - else - return 1; - } - else - { - if (in2only) - return -1; - else - return 0; - } - } - else - ul4._unorderable(operator, obj1, obj2); - } - - // Return whether ``obj1 < obj2`` - ul4._lt = function _lt(obj1, obj2) - { - var numbertypes = ["boolean", "number"]; - - if (obj1 && typeof(obj1.__lt__) === "function") - return obj1.__lt__(obj2); - else if (numbertypes.indexOf(typeof(obj1)) != -1) - { - if (numbertypes.indexOf(typeof(obj2)) != -1) - return obj1 < obj2; - } - else if (typeof(obj1) === "string") - { - if (typeof(obj2) === "string") - return obj1 < obj2; - } - else if (ul4._isdate(obj1)) - { - if (ul4._isdate(obj2)) - return obj1.getTime() < obj2.getTime(); - } - else if (ul4._islist(obj1)) - { - if (ul4._islist(obj2)) - { - if (obj1 === obj2) - return false; - for (var i = 0; i < obj1.length; ++i) - { - if (i >= obj2.length) - return false; - var eq = ul4._eq(obj1[i], obj2[i]); - if (!eq) - return ul4._lt(obj1[i], obj2[i]); - } - return obj1.length < obj2.length; - } - } - // FIXME: Set comparison - else if (ul4._isset(obj1)) - { - if (ul4._isset(obj2)) - { - if (ul4._isset(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.has(value)) - in1only = true; - }); - obj2.forEach(function(value){ - if (!obj1.has(value)) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.items[value]) - in1only = true; - }); - for (var value in obj2.items) - { - if (!obj1.has(value)) - { - in2only = true; - break; - } - } - } - } - else if (ul4._isul4set(obj2)) - { - if (ul4._isset(obj2)) - { - for (var value in obj1.items) - { - if (!obj2.has(value)) - { - in1only = true; - break; - } - } - obj2.forEach(function(value){ - if (!obj1.items[value]) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - for (var value in obj1.items) - { - if (!obj2.items[value]) - { - in1only = true; - break; - } - } - for (var value in obj2.items) - { - if (!obj1.items[value]) - { - in2only = true; - break; - } - } - } - } - else - ul4._unorderable(operator, obj1, obj2); - - if (in1only) - { - if (in2only) - return null; - else - return 1; - } - else - { - if (in2only) - return -1; - else - return 0; - } - } - ul4._unorderable("<", obj1, obj2); - }; - - // Return whether ``obj1 <= obj2`` - ul4._le = function _le(obj1, obj2) - { - var numbertypes = ["boolean", "number"]; - - if (obj1 && typeof(obj1.__le__) === "function") - return obj1.__le__(obj2); - if (numbertypes.indexOf(typeof(obj1)) != -1) - { - if (numbertypes.indexOf(typeof(obj2)) != -1) - return obj1 <= obj2; - } - else if (typeof(obj1) === "string") - { - if (typeof(obj2) === "string") - return obj1 <= obj2; - } - else if (ul4._isdate(obj1)) - { - if (ul4._isdate(obj2)) - return obj1.getTime() <= obj2.getTime(); - } - else if (ul4._islist(obj1)) - { - if (ul4._islist(obj2)) - { - if (obj1 === obj2) - return true; - for (var i = 0; i < obj1.length; ++i) - { - if (i >= obj2.length) - return false; - var eq = ul4._eq(obj1[i], obj2[i]); - if (!eq) - return ul4._lt(obj1[i], obj2[i]); - } - return obj1.length <= obj2.length; - } - } - // FIXME: Set comparison - else if (ul4._isset(obj1) || ul4._isul4set(obj1)) - { - var in1only = false; - var in2only = false; - - if (ul4._isset(obj2)) - { - if (ul4._isset(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.has(value)) - in1only = true; - }); - obj2.forEach(function(value){ - if (!obj1.has(value)) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.items[value]) - in1only = true; - }); - for (var value in obj2.items) - { - if (!obj1.has(value)) - { - in2only = true; - break; - } - } - } - } - else if (ul4._isul4set(obj2)) - { - if (ul4._isset(obj2)) - { - for (var value in obj1.items) - { - if (!obj2.has(value)) - { - in1only = true; - break; - } - } - obj2.forEach(function(value){ - if (!obj1.items[value]) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - for (var value in obj1.items) - { - if (!obj2.items[value]) - { - in1only = true; - break; - } - } - for (var value in obj2.items) - { - if (!obj1.items[value]) - { - in2only = true; - break; - } - } - } - } - else - ul4._unorderable(operator, obj1, obj2); - - if (in1only) - { - if (in2only) - return null; - else - return 1; - } - else - { - if (in2only) - return -1; - else - return 0; - } - } - ul4._unorderable("<=", obj1, obj2); - }; - - // Return whether ``obj1 > obj2`` - ul4._gt = function _gt(obj1, obj2) - { - var numbertypes = ["boolean", "number"]; - - if (obj1 && typeof(obj1.__gt__) === "function") - return obj1.__gt__(obj2); - if (numbertypes.indexOf(typeof(obj1)) != -1) - { - if (numbertypes.indexOf(typeof(obj2)) != -1) - return obj1 > obj2; - } - else if (typeof(obj1) === "string") - { - if (typeof(obj2) === "string") - return obj1 > obj2; - } - else if (ul4._isdate(obj1)) - { - if (ul4._isdate(obj2)) - return obj1.getTime() > obj2.getTime(); - } - else if (ul4._islist(obj1)) - { - if (ul4._islist(obj2)) - { - if (obj1 === obj2) - return false; - for (var i = 0; i < obj1.length; ++i) - { - if (i >= obj2.length) - return true; - var eq = ul4._eq(obj1[i], obj2[i]); - if (!eq) - return ul4._gt(obj1[i], obj2[i]); - } - return obj1.length > obj2.length; - } - } - // FIXME: Set comparison - else if (ul4._isset(obj1) || ul4._isul4set(obj1)) - { - var in1only = false; - var in2only = false; - - if (ul4._isset(obj2)) - { - if (ul4._isset(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.has(value)) - in1only = true; - }); - obj2.forEach(function(value){ - if (!obj1.has(value)) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.items[value]) - in1only = true; - }); - for (var value in obj2.items) - { - if (!obj1.has(value)) - { - in2only = true; - break; - } - } - } - } - else if (ul4._isul4set(obj2)) - { - if (ul4._isset(obj2)) - { - for (var value in obj1.items) - { - if (!obj2.has(value)) - { - in1only = true; - break; - } - } - obj2.forEach(function(value){ - if (!obj1.items[value]) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - for (var value in obj1.items) - { - if (!obj2.items[value]) - { - in1only = true; - break; - } - } - for (var value in obj2.items) - { - if (!obj1.items[value]) - { - in2only = true; - break; - } - } - } - } - else - ul4._unorderable(operator, obj1, obj2); - - if (in1only) - { - if (in2only) - return null; - else - return 1; - } - else - { - if (in2only) - return -1; - else - return 0; - } - } - ul4._unorderable(">", obj1, obj2); - }; - - // Return whether ``obj1 >= obj2`` - ul4._ge = function _ge(obj1, obj2) - { - var numbertypes = ["boolean", "number"]; - - if (obj1 && typeof(obj1.__ge__) === "function") - return obj1.__ge__(obj2); - else if (numbertypes.indexOf(typeof(obj1)) != -1) - { - if (numbertypes.indexOf(typeof(obj2)) != -1) - return obj1 >= obj2; - } - else if (typeof(obj1) === "string") - { - if (typeof(obj2) === "string") - return obj1 >= obj2; - } - else if (ul4._isdate(obj1)) - { - if (ul4._isdate(obj2)) - return obj1.getTime() >= obj2.getTime(); - } - else if (ul4._islist(obj1)) - { - if (ul4._islist(obj2)) - { - if (obj1 === obj2) - return true; - for (var i = 0; i < obj1.length; ++i) - { - if (i >= obj2.length) - return true; - var eq = ul4._eq(obj1[i], obj2[i]); - if (!eq) - return ul4._gt(obj1[i], obj2[i]); - } - return obj1.length >= obj2.length; - } - } - // FIXME: Set comparison - else if (ul4._isset(obj1) || ul4._isul4set(obj1)) - { - var in1only = false; - var in2only = false; - - if (ul4._isset(obj2)) - { - if (ul4._isset(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.has(value)) - in1only = true; - }); - obj2.forEach(function(value){ - if (!obj1.has(value)) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - obj1.forEach(function(value){ - if (!obj2.items[value]) - in1only = true; - }); - for (var value in obj2.items) - { - if (!obj1.has(value)) - { - in2only = true; - break; - } - } - } - } - else if (ul4._isul4set(obj2)) - { - if (ul4._isset(obj2)) - { - for (var value in obj1.items) - { - if (!obj2.has(value)) - { - in1only = true; - break; - } - } - obj2.forEach(function(value){ - if (!obj1.items[value]) - in2only = true; - }); - } - else if (ul4._isul4set(obj2)) - { - for (var value in obj1.items) - { - if (!obj2.items[value]) - { - in1only = true; - break; - } - } - for (var value in obj2.items) - { - if (!obj1.items[value]) - { - in2only = true; - break; - } - } - } - } - else - ul4._unorderable(operator, obj1, obj2); - - if (in1only) - { - if (in2only) - return null; - else - return 1; - } - else - { - if (in2only) - return -1; - else - return 0; - } - } - ul4._unorderable(">=", obj1, obj2); - }; - - // Return an iterator for ``obj`` - ul4._iter = function _iter(obj) - { - if (typeof(obj) === "string" || ul4._islist(obj)) - { - return { - index: 0, - next: function() - { - if (this.index < obj.length) - return {value: obj[this.index++], done: false}; - else - return {done: true}; - } - }; - } - else if (ul4._isiter(obj)) - return obj; - else if (obj !== null && typeof(obj.__iter__) === "function") - return obj.__iter__(); - else if (ul4._ismap(obj)) - { - var keys = []; - obj.forEach(function(value, key){ - keys.push(key); - }); - return { - index: 0, - next: function() - { - if (this.index >= keys.length) - return {done: true}; - return {value: keys[this.index++], done: false}; - } - }; - } - else if (ul4._isset(obj)) - { - var values = []; - obj.forEach(function(value, key){ - values.push(value); - }); - return { - index: 0, - next: function() - { - if (this.index >= values.length) - return {done: true}; - return {value: values[this.index++], done: false}; - } - }; - } - else if (ul4._isul4set(obj)) - { - return ul4._iter(obj.items); - } - else if (ul4._isobject(obj)) - { - var keys = []; - for (var key in obj) - keys.push(key); - return { - index: 0, - next: function() - { - if (this.index >= keys.length) - return {done: true}; - return {value: keys[this.index++], done: false}; - } - }; - } - throw ul4.TypeError.create("iter", ul4._type(obj) + " object is not iterable"); - }; - - ul4._str_repr = function _str_repr(str, ascii) - { - var result = ""; - var squote = false, dquote = false; - - for (var i = 0; i "; - else - return ""; - else if (ul4._isdate(obj)) - return ul4._date_repr(obj, ascii); - else if (typeof(obj) === "undefined") - return ""; - else if (typeof(obj) === "object" && typeof(obj.__repr__) === "function") - return obj.__repr__(); - else if (ul4._islist(obj)) - return ul4._list_repr(obj, ascii); - else if (ul4._ismap(obj)) - return ul4._map_repr(obj, ascii); - else if (ul4._isset(obj)) - return ul4._set_repr(obj, ascii); - else if (ul4._isobject(obj)) - return ul4._object_repr(obj, ascii); - return "?"; - }; - - // Return a string representation of ``obj``: If possible this should be an object literal supported by UL4, otherwise the output should be bracketed with ``<`` and ``>`` - ul4._repr = function _repr(obj) - { - return ul4._repr_internal(obj, false); - } - - ul4._ascii = function _ascii(obj) - { - return ul4._repr_internal(obj, true); - } - - ul4._date_str = function _date_str(obj) - { - var year = obj.getFullYear(); - var month = obj.getMonth()+1; - var day = obj.getDate(); - var hour = obj.getHours(); - var minute = obj.getMinutes(); - var second = obj.getSeconds(); - var ms = obj.getMilliseconds(); - - var result = year + "-" + ul4._lpad(month.toString(), "0", 2) + "-" + ul4._lpad(day.toString(), "0", 2) + " " + ul4._lpad(hour.toString(), "0", 2) + ":" + ul4._lpad(minute.toString(), "0", 2) + ":" + ul4._lpad(second.toString(), "0", 2); - if (ms) - result += "." + ul4._lpad(ms.toString(), "0", 3) + "000"; - return result; - }; - - ul4._str = function _str(obj) - { - if (typeof(obj) === "undefined") - return ""; - else if (obj === null) - return ""; - else if (obj === false) - return "False"; - else if (obj === true) - return "True"; - else if (typeof(obj) === "string") - return obj; - else if (typeof(obj) === "number") - return obj.toString(); - else if (ul4._isdate(obj)) - return ul4._date_str(obj); - else if (ul4._islist(obj)) - return ul4._list_repr(obj); - else if (ul4._isset(obj)) - return ul4._set_repr(obj); - else if (ul4._ismap(obj)) - return ul4._map_repr(obj); - else if (typeof(obj) === "object" && typeof(obj.__str__) === "function") - return obj.__str__(); - else if (typeof(obj) === "object" && typeof(obj.__repr__) === "function") - return obj.__repr__(); - else if (ul4._isobject(obj)) - return ul4._object_repr(obj); - return "?"; - }; - - // Convert ``obj`` to bool, according to its "truth value" - ul4._bool = function _bool(obj) - { - if (typeof(obj) === "undefined" || obj === null || obj === false || obj === 0 || obj === "") - return false; - else - { - if (typeof(obj) === "object", typeof(obj.__bool__) === "function") - return obj.__bool__(); - if (ul4._islist(obj)) - return obj.length !== 0; - else if (ul4._ismap(obj) || ul4._isset(obj)) - return obj.size != 0; - else if (ul4._isobject(obj)) - { - for (var key in obj) - { - if (!obj.hasOwnProperty(key)) - continue; - return true; - } - return false; - } - return true; - } - }; - - // Convert ``obj`` to an integer (if ``base`` is given ``obj`` must be a string and ``base`` is the base for the conversion (default is 10)) - ul4._int = function _int(obj, base) - { - var result; - if (base !== null) - { - if (typeof(obj) !== "string" || !ul4._isint(base)) - throw ul4.TypeError.create("int()", "int() requires a string and an integer"); - result = parseInt(obj, base); - if (result.toString() == "NaN") - throw ul4.TypeError.create("int()", "invalid literal for int()"); - return result; - } - else - { - if (typeof(obj) == "string") - { - result = parseInt(obj); - if (result.toString() == "NaN") - throw ul4.TypeError.create("int()", "invalid literal for int()"); - return result; - } - else if (typeof(obj) == "number") - return Math.floor(obj); - else if (obj === true) - return 1; - else if (obj === false) - return 0; - throw ul4.TypeError.create("int()", "int() argument must be a string or a number"); - } - }; - - // Convert ``obj`` to a float - ul4._float = function _float(obj) - { - if (typeof(obj) === "string") - return parseFloat(obj); - else if (typeof(obj) === "number") - return obj; - else if (obj === true) - return 1.0; - else if (obj === false) - return 0.0; - throw ul4.TypeError.create("float()", "float() argument must be a string or a number"); - }; - - // Convert ``obj`` to a list - ul4._list = function _list(obj) - { - var iter = ul4._iter(obj); - - var result = []; - for (;;) - { - var value = iter.next(); - if (value.done) - return result; - result.push(value.value); - } - }; - - // Convert ``obj`` to a set - ul4._set = function _set(obj) - { - var iter = ul4._iter(obj); - - var result = ul4on._haveset ? new Set() : ul4._Set.create(); - for (;;) - { - var value = iter.next(); - if (value.done) - return result; - result.add(value.value); - } - }; - - // Return the length of ``sequence`` - ul4._len = function _len(sequence) - { - if (typeof(sequence) == "string" || ul4._islist(sequence)) - return sequence.length; - else if (ul4._ismap(sequence) || ul4._isset(sequence)) - return sequence.size; - else if (ul4._isobject(sequence)) - { - var i = 0; - for (var key in sequence) - ++i; - return i; - } - throw ul4.TypeError.create("len", "object of type '" + ul4._type(sequence) + "' has no len()"); - }; - - ul4._type = function _type(obj) - { - if (obj === null) - return "none"; - else if (obj === false || obj === true) - return "bool"; - else if (typeof(obj) === "undefined") - return "undefined"; - else if (typeof(obj) === "string") - return "str"; - else if (typeof(obj) === "number") - return Math.round(obj) == obj ? "int" : "float"; - else if (ul4._islist(obj)) - return "list"; - else if (ul4._isset(obj)) - return "set"; - else if (ul4._isdate(obj)) - return "date"; - else if (typeof(obj.__type__) !== "undefined") - return obj.__type__; - else if (ul4._istimedelta(obj)) - return "timedelta"; - else if (ul4._isdict(obj)) - return "dict"; - else if (ul4._istemplate(obj)) - return "template"; - else if (ul4._isfunction(obj)) - return "function"; - return null; - }; - - - // Return whether any of the items in ``iterable`` are true - ul4._any = function _any(iterable) - { - if (typeof(iterable) == "string") - { - for (var i = 0; i < iterable.length; ++i) - { - if (iterable[i] !== '\x00') - return true; - } - return false; - } - else - { - for (var iter = ul4._iter(iterable);;) - { - var item = iter.next(); - if (item.done) - return false; - if (ul4._bool(item.value)) - return true; - } - } - }; - - // Return whether all of the items in ``iterable`` are true - ul4._all = function _all(iterable) - { - if (typeof(iterable) == "string") - { - for (var i = 0; i < iterable.length; ++i) - { - if (iterable[i] === '\x00') - return false; - } - return true; - } - else - { - for (var iter = ul4._iter(iterable);;) - { - var item = iter.next(); - if (item.done) - return true; - if (!ul4._bool(item.value)) - return false; - } - } - }; - - // Check if ``obj`` is undefined - ul4._isundefined = function _isundefined(obj) - { - return typeof(obj) === "undefined"; - }; - - - // Check if ``obj`` is *not* undefined - ul4._isdefined = function _isdefined(obj) - { - return typeof(obj) !== "undefined"; - }; - - // Check if ``obj`` is ``None`` - ul4._isnone = function _isnone(obj) - { - return obj === null; - }; - - // Check if ``obj`` is a boolean - ul4._isbool = function _isbool(obj) - { - return typeof(obj) == "boolean"; - }; - - // Check if ``obj`` is a int - ul4._isint = function _isint(obj) - { - return (typeof(obj) == "number") && Math.round(obj) == obj; - }; - - // Check if ``obj`` is a float - ul4._isfloat = function _isfloat(obj) - { - return (typeof(obj) == "number") && Math.round(obj) != obj; - }; - - // Check if ``obj`` is a string - ul4._isstr = function _isstr(obj) - { - return typeof(obj) == "string"; - }; - - // Check if ``obj`` is a date - ul4._isdate = function _isdate(obj) - { - return Object.prototype.toString.call(obj) == "[object Date]"; - }; - - // Check if ``obj`` is a color - ul4._iscolor = function _iscolor(obj) - { - return (obj !== null && typeof(obj) === "object" && typeof(obj.isa) === "function" && obj.isa(ul4.Color)); - }; - - // Check if ``obj`` is a timedelta object - ul4._istimedelta = function _istimedelta(obj) - { - return (obj !== null && typeof(obj) === "object" && typeof(obj.isa) === "function" && obj.isa(ul4.TimeDelta)); - }; - - // Check if ``obj`` is a monthdelta object - ul4._ismonthdelta = function _ismonthdelta(obj) - { - return obj !== null && typeof(obj) === "object" && typeof(obj.isa) === "function" && obj.isa(ul4.MonthDelta); - }; - - // Check if ``obj`` is a template - ul4._istemplate = function _istemplate(obj) - { - return Object.prototype.toString.call(obj) == "[object Object]" && (obj.__type__ === "ul4.Template" || obj.__type__ === "ul4.TemplateClosure"); - }; - - // Check if ``obj`` is a function - ul4._isfunction = function _isfunction(obj) - { - return typeof(obj) === "function" || (Object.prototype.toString.call(obj) == "[object Object]" && (obj.__type__ === "ul4.Template" || obj.__type__ === "ul4.TemplateClosure")); - }; - - // Check if ``obj`` is a list - ul4._islist = function _islist(obj) - { - return Object.prototype.toString.call(obj) == "[object Array]"; - }; - - // Check if ``obj`` is a set - ul4._isset = function _isset(obj) - { - return Object.prototype.toString.call(obj) == "[object Set]"; - }; - - // Check if ``obj`` is an exception (at least a UL4 exception) - ul4._isexception = function _isexception(obj) - { - return obj !== null && typeof(obj) === "object" && typeof(obj.isa) === "function" && obj.isa(ul4.Error); - }; - - ul4._isul4set = function _isul4set(obj) - { - return obj !== null && typeof(obj) === "object" && typeof(obj.isa) === "function" && obj.isa(ul4._Set); - }; - - // Check if ``obj`` is an iterator - ul4._isiter = function _isiter(obj) - { - return obj !== null && typeof(obj) === "object" && typeof(obj.next) === "function"; - }; - - // Check if ``obj`` is a JS object - ul4._isobject = function _isobject(obj) - { - return Object.prototype.toString.call(obj) == "[object Object]" && typeof(obj.__type__) === "undefined"; - }; - - // Check if ``obj`` is a map - ul4._ismap = function _ismap(obj) - { - if (ul4on._havemap) - return obj !== null && typeof(obj) === "object" && typeof(obj.__proto__) === "object" && obj.__proto__ === Map.prototype; - return false; - }; - - // Check if ``obj`` is a dict (i.e. a normal Javascript object or a ``Map``) - ul4._isdict = function _isdict(obj) - { - return ul4._isobject(obj) || ul4._ismap(obj); - }; - - - // Repeat string ``str`` ``rep`` times - ul4._str_repeat = function _str_repeat(str, rep) - { - var result = ""; - for (; rep>0; --rep) - result += str; - return result; - }; - - ul4._list_repeat = function _list_repeat(list, rep) - { - var result = []; - for (; rep>0; --rep) - for (var i = 0; i < list.length; ++i) - result.push(list[i]); - return result; - }; - - ul4._str_json = function _str_json(str) - { - var result = ""; - for (var i = 0; i < str.length; ++i) - { - var c = str[i]; - switch (c) - { - case "\r": - result += "\\r"; - break; - case "\n": - result += "\\n"; - break; - case "\t": - result += "\\t"; - break; - case "\\": - result += "\\\\"; - break; - case '"': - result += '\\"'; - break; - default: - var code = str.charCodeAt(i); - if (code >= 32 && code < 128) - result += c; - else - result += "\\u" + ul4._lpad(code.toString(16), "0", 4); - break; - } - } - return '"' + result + '"'; - }; - - // Encodes ``obj`` in the Javascript Object Notation (see http://json.org/; with support for dates, colors and templates) - ul4._asjson = function _asjson(obj) - { - if (obj === null) - return "null"; - else if (typeof(obj) === "undefined") - return "{}.undefined"; - else if (obj === false) - return "false"; - else if (obj === true) - return "true"; - else if (typeof(obj) === "string") - return ul4._str_json(obj); - else if (typeof(obj) === "number") - { - return "" + obj; - } - else if (ul4._islist(obj)) - { - var v = []; - v.push("["); - for (var i = 0; i < obj.length; ++i) - { - if (i != 0) - v.push(", "); - v.push(ul4._asjson(obj[i])); - } - v.push("]"); - return v.join(""); - } - else if (ul4._ismap(obj)) - { - var v = []; - v.push("{"); - var i = 0; - obj.forEach(function(value, key){ - if (i++) - v.push(", "); - v.push(ul4._asjson(key)); - v.push(": "); - v.push(ul4._asjson(value)); - }); - v.push("}"); - return v.join(""); - } - else if (ul4._isobject(obj)) - { - var v = []; - v.push("{"); - var i = 0; - for (var key in obj) - { - if (i++) - v.push(", "); - v.push(ul4._asjson(key)); - v.push(": "); - v.push(ul4._asjson(obj[key])); - } - v.push("}"); - return v.join(""); - } - else if (ul4._isdate(obj)) - { - return "new Date(" + obj.getFullYear() + ", " + obj.getMonth() + ", " + obj.getDate() + ", " + obj.getHours() + ", " + obj.getMinutes() + ", " + obj.getSeconds() + ", " + obj.getMilliseconds() + ")"; - } - else if (ul4._istimedelta(obj)) - { - return "ul4.TimeDelta.create(" + obj.days + ", " + obj.seconds + ", " + obj.microseconds + ")"; - } - else if (ul4._ismonthdelta(obj)) - { - return "ul4.MonthDelta.create(" + obj.months + ")"; - } - else if (ul4._iscolor(obj)) - { - return "ul4.Color.create(" + obj._r + ", " + obj._g + ", " + obj._b + ", " + obj._a + ")"; - } - else if (ul4._istemplate(obj)) - { - return "ul4.Template.loads(" + ul4._repr(obj.dumps()) + ")"; - } - throw ul4.TypeError.create("asjson()", "asjson() requires a serializable object"); - }; - - // Decodes the string ``string`` from the Javascript Object Notation (see http://json.org/) and returns the resulting object - ul4._fromjson = function _fromjson(string) - { - // The following is from jQuery's parseJSON function - string = ul4._strip(string, null); - if (root.JSON && root.JSON.parse) - return root.JSON.parse(string); - if (ul4._rvalidchars.test(string.replace(ul4._rvalidescape, "@").replace(ul4._rvalidtokens, "]").replace(ul4._rvalidbraces, ""))) - return (new Function("return " + string))(); - throw ul4.TypeError.create("fromjson()", "invalid JSON"); - }; - - // Encodes ``obj`` in the UL4 Object Notation format - ul4._asul4on = function _asul4on(obj) - { - return ul4on.dumps(obj); - }; - - // Decodes the string ``string`` from the UL4 Object Notation format and returns the resulting decoded object - ul4._fromul4on = function _fromul4on(string) - { - return ul4on.loads(string); - }; - - ul4._format_date = function _format_date(obj, fmt, lang) - { - var translations = { - de: { - ms: ["Jan", "Feb", "M\u00e4r", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"], - ml: ["Januar", "Februar", "M\u00e4rz", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], - ws: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], - wl: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - en: { - ms: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], - ml: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], - ws: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], - wl: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], - xf: "%m/%d/%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %I:%M:%S %p " - }, - fr: { - ms: ["janv.", "f\u00e9vr.", "mars", "avril", "mai", "juin", "juil.", "ao\u00fbt", "sept.", "oct.", "nov.", "d\u00e9c."], - ml: ["janvier", "f\u00e9vrier", "mars", "avril", "mai", "juin", "juillet", "ao\u00fbt", "septembre", "octobre", "novembre", "d\u00e9cembre"], - ws: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."], - wl: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], - xf: "%d/%m/%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - es: { - ms: ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"], - ml: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"], - ws: ["dom", "lun", "mar", "mi\u00e9", "jue", "vie", "s\u00e1b"], - wl: ["domingo", "lunes", "martes", "mi\u00e9rcoles", "jueves", "viernes", "s\u00e1bado"], - xf: "%d/%m/%y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - it: { - ms: ["gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic"], - ml: ["gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre"], - ws: ["dom", "lun", "mar", "mer", "gio", "ven", "sab"], - wl: ["domenica", "luned\u00ec", "marted\u00ec", "mercoled\u00ec", "gioved\u00ec", "venerd\u00ec", "sabato"], - xf: "%d/%m/%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - da: { - ms: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"], - ml: ["januar", "februar", "marts", "april", "maj", "juni", "juli", "august", "september", "oktober", "november", "december"], - ws: ["s\u00f8n", "man", "tir", "ons", "tor", "fre", "l\u00f8r"], - wl: ["s\u00f8ndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "l\u00f8rdag"], - xf: "%d-%m-%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - sv: { - ms: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"], - ml: ["januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december"], - ws: ["s\u00f6n", "m\u00e5n", "tis", "ons", "tor", "fre", "l\u00f6r"], - wl: ["s\u00f6ndag", "m\u00e5ndag", "tisdag", "onsdag", "torsdag", "fredag", "l\u00f6rdag"], - xf: "%Y-%m-%d", - Xf: "%H.%M.%S", - cf: "%a %d %b %Y %H.%M.%S" - }, - nl: { - ms: ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"], - ml: ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"], - ws: ["zo", "ma", "di", "wo", "do", "vr", "za"], - wl: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"], - xf: "%d-%m-%y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - pt: { - ms: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"], - ml: ["Janeiro", "Fevereiro", "Mar\u00e7o", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"], - ws: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "S\u00e1b"], - wl: ["Domingo", "Segunda", "Ter\u00e7a", "Quarta", "Quinta", "Sexta", "S\u00e1bado"], - xf: "%d-%m-%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - cs: { - ms: ["led", "\u00fano", "b\u0159e", "dub", "kv\u011b", "\u010den", "\u010dec", "srp", "z\u00e1\u0159", "\u0159\u00edj", "lis", "pro"], - ml: ["leden", "\u00fanor", "b\u0159ezen", "duben", "kv\u011bten", "\u010derven", "\u010dervenec", "srpen", "z\u00e1\u0159\u00ed", "\u0159\u00edjen", "listopad", "prosinec"], - ws: ["Ne", "Po", "\u00dat", "St", "\u010ct", "P\u00e1", "So"], - wl: ["Ned\u011ble", "Pond\u011bl\u00ed", "\u00dater\u00fd", "St\u0159eda", "\u010ctvrtek", "P\u00e1tek", "Sobota"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a\u00a0%d.\u00a0%B\u00a0%Y,\u00a0%H:%M:%S" - }, - sk: { - ms: ["jan", "feb", "mar", "apr", "m\u00e1j", "j\u00fan", "j\u00fal", "aug", "sep", "okt", "nov", "dec"], - ml: ["janu\u00e1r", "febru\u00e1r", "marec", "apr\u00edl", "m\u00e1j", "j\u00fan", "j\u00fal", "august", "september", "okt\u00f3ber", "november", "december"], - ws: ["Ne", "Po", "Ut", "St", "\u0160t", "Pi", "So"], - wl: ["Nede\u013ea", "Pondelok", "Utorok", "Streda", "\u0160tvrtok", "Piatok", "Sobota"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a\u00a0%d.\u00a0%B\u00a0%Y,\u00a0%H:%M:%S" - }, - pl: { - ms: ["sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "pa\u017a", "lis", "gru"], - ml: ["stycze\u0144", "luty", "marzec", "kwiecie\u0144", "maj", "czerwiec", "lipiec", "sierpie\u0144", "wrzesie\u0144", "pa\u017adziernik", "listopad", "grudzie\u0144"], - ws: ["nie", "pon", "wto", "\u015bro", "czw", "pi\u0105", "sob"], - wl: ["niedziela", "poniedzia\u0142ek", "wtorek", "\u015broda", "czwartek", "pi\u0105tek", "sobota"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a, %d %b %Y, %H:%M:%S" - }, - hr: { - ms: ["Sij", "Vel", "O\u017eu", "Tra", "Svi", "Lip", "Srp", "Kol", "Ruj", "Lis", "Stu", "Pro"], - ml: ["Sije\u010danj", "Velja\u010da", "O\u017eujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"], - ws: ["Ned", "Pon", "Uto", "Sri", "\u010cet", "Pet", "Sub"], - wl: ["Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "\u010cetvrtak", "Petak", "Subota"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - sr: { - ms: ["\u0458\u0430\u043d", "\u0444\u0435\u0431", "\u043c\u0430\u0440", "\u0430\u043f\u0440", "\u043c\u0430\u0458", "\u0458\u0443\u043d", "\u0458\u0443\u043b", "\u0430\u0432\u0433", "\u0441\u0435\u043f", "\u043e\u043a\u0442", "\u043d\u043e\u0432", "\u0434\u0435\u0446"], - ml: ["\u0458\u0430\u043d\u0443\u0430\u0440", "\u0444\u0435\u0431\u0440\u0443\u0430\u0440", "\u043c\u0430\u0440\u0442", "\u0430\u043f\u0440\u0438\u043b", "\u043c\u0430\u0458", "\u0458\u0443\u043d", "\u0458\u0443\u043b", "\u0430\u0432\u0433\u0443\u0441\u0442", "\u0441\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440", "\u043e\u043a\u0442\u043e\u0431\u0430\u0440", "\u043d\u043e\u0432\u0435\u043c\u0431\u0430\u0440", "\u0434\u0435\u0446\u0435\u043c\u0431\u0430\u0440"], - ws: ["\u043d\u0435\u0434", "\u043f\u043e\u043d", "\u0443\u0442\u043e", "\u0441\u0440\u0435", "\u0447\u0435\u0442", "\u043f\u0435\u0442", "\u0441\u0443\u0431"], - wl: ["\u043d\u0435\u0434\u0435\u0459\u0430", "\u043f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a", "\u0443\u0442\u043e\u0440\u0430\u043a", "\u0441\u0440\u0435\u0434\u0430", "\u0447\u0435\u0442\u0432\u0440\u0442\u0430\u043a", "\u043f\u0435\u0442\u0430\u043a", "\u0441\u0443\u0431\u043e\u0442\u0430"], - xf: "%d.%m.%Y.", - Xf: "%H:%M:%S", - cf: "%A, %d. %B %Y. %H:%M:%S" - }, - ro: { - ms: ["ian", "feb", "mar", "apr", "mai", "iun", "iul", "aug", "sep", "oct", "nov", "dec"], - ml: ["ianuarie", "februarie", "martie", "aprilie", "mai", "iunie", "iulie", "august", "septembrie", "octombrie", "noiembrie", "decembrie"], - ws: ["Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sb"], - wl: ["duminic\u0103", "luni", "mar\u0163i", "miercuri", "joi", "vineri", "s\u00e2mb\u0103t\u0103"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - hu: { - ms: ["jan", "febr", "m\u00e1rc", "\u00e1pr", "m\u00e1j", "j\u00fan", "j\u00fal", "aug", "szept", "okt", "nov", "dec"], - ml: ["janu\u00e1r", "febru\u00e1r", "m\u00e1rcius", "\u00e1prilis", "m\u00e1jus", "j\u00fanius", "j\u00falius", "augusztus", "szeptember", "okt\u00f3ber", "november", "december"], - ws: ["v", "h", "k", "sze", "cs", "p", "szo"], - wl: ["vas\u00e1rnap", "h\u00e9tf\u0151", "kedd", "szerda", "cs\u00fct\u00f6rt\u00f6k", "p\u00e9ntek", "szombat"], - xf: "%Y-%m-%d", - Xf: "%H.%M.%S", - cf: "%Y. %b. %d., %A, %H.%M.%S" - }, - tr: { - ms: ["Oca", "\u015eub", "Mar", "Nis", "May", "Haz", "Tem", "A\u011fu", "Eyl", "Eki", "Kas", "Ara"], - ml: ["Ocak", "\u015eubat", "Mart", "Nisan", "May\u0131s", "Haziran", "Temmuz", "A\u011fustos", "Eyl\u00fcl", "Ekim", "Kas\u0131m", "Aral\u0131k"], - ws: ["Paz", "Pzt", "Sal", "\u00c7r\u015f", "Pr\u015f", "Cum", "Cts"], - wl: ["Pazar", "Pazartesi", "Sal\u0131", "\u00c7ar\u015famba", "Per\u015fembe", "Cuma", "Cumartesi"], - xf: "%d-%m-%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - ru: { - ms: ["\u042f\u043d\u0432", "\u0424\u0435\u0432", "\u041c\u0430\u0440", "\u0410\u043f\u0440", "\u041c\u0430\u0439", "\u0418\u044e\u043d", "\u0418\u044e\u043b", "\u0410\u0432\u0433", "\u0421\u0435\u043d", "\u041e\u043a\u0442", "\u041d\u043e\u044f", "\u0414\u0435\u043a"], - ml: ["\u042f\u043d\u0432\u0430\u0440\u044c", "\u0424\u0435\u0432\u0440\u0430\u043b\u044c", "\u041c\u0430\u0440\u0442", "\u0410\u043f\u0440\u0435\u043b\u044c", "\u041c\u0430\u0439", "\u0418\u044e\u043d\u044c", "\u0418\u044e\u043b\u044c", "\u0410\u0432\u0433\u0443\u0441\u0442", "\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c", "\u041e\u043a\u0442\u044f\u0431\u0440\u044c", "\u041d\u043e\u044f\u0431\u0440\u044c", "\u0414\u0435\u043a\u0430\u0431\u0440\u044c"], - ws: ["\u0412\u0441\u043a", "\u041f\u043d\u0434", "\u0412\u0442\u0440", "\u0421\u0440\u0434", "\u0427\u0442\u0432", "\u041f\u0442\u043d", "\u0421\u0431\u0442"], - wl: ["\u0412\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435", "\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a", "\u0412\u0442\u043e\u0440\u043d\u0438\u043a", "\u0421\u0440\u0435\u0434\u0430", "\u0427\u0435\u0442\u0432\u0435\u0440\u0433", "\u041f\u044f\u0442\u043d\u0438\u0446\u0430", "\u0421\u0443\u0431\u0431\u043e\u0442\u0430"], - xf: "%d.%m.%Y", - Xf: "%H:%M:%S", - cf: "%a %d %b %Y %H:%M:%S" - }, - zh: { - ms: [" 1\u6708", " 2\u6708", " 3\u6708", " 4\u6708", " 5\u6708", " 6\u6708", " 7\u6708", " 8\u6708", " 9\u6708", "10\u6708", "11\u6708", "12\u6708"], - ml: ["\u4e00\u6708", "\u4e8c\u6708", "\u4e09\u6708", "\u56db\u6708", "\u4e94\u6708", "\u516d\u6708", "\u4e03\u6708", "\u516b\u6708", "\u4e5d\u6708", "\u5341\u6708", "\u5341\u4e00\u6708", "\u5341\u4e8c\u6708"], - ws: ["\u65e5", "\u4e00", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d"], - wl: ["\u661f\u671f\u65e5", "\u661f\u671f\u4e00", "\u661f\u671f\u4e8c", "\u661f\u671f\u4e09", "\u661f\u671f\u56db", "\u661f\u671f\u4e94", "\u661f\u671f\u516d"], - xf: "%Y\u5e74%b%d\u65e5", - Xf: "%H\u65f6%M\u5206%S\u79d2", - cf: "%Y\u5e74%b%d\u65e5 %A %H\u65f6%M\u5206%S\u79d2" - }, - ko: { - ms: [" 1\uc6d4", " 2\uc6d4", " 3\uc6d4", " 4\uc6d4", " 5\uc6d4", " 6\uc6d4", " 7\uc6d4", " 8\uc6d4", " 9\uc6d4", "10\uc6d4", "11\uc6d4", "12\uc6d4"], - ml: ["1\uc6d4", "2\uc6d4", "3\uc6d4", "4\uc6d4", "5\uc6d4", "6\uc6d4", "7\uc6d4", "8\uc6d4", "9\uc6d4", "10\uc6d4", "11\uc6d4", "12\uc6d4"], - ws: ["\uc77c", "\uc6d4", "\ud654", "\uc218", "\ubaa9", "\uae08", "\ud1a0"], - wl: ["\uc77c\uc694\uc77c", "\uc6d4\uc694\uc77c", "\ud654\uc694\uc77c", "\uc218\uc694\uc77c", "\ubaa9\uc694\uc77c", "\uae08\uc694\uc77c", "\ud1a0\uc694\uc77c"], - xf: "%Y\ub144 %B %d\uc77c", - Xf: "%H\uc2dc %M\ubd84 %S\ucd08", - cf: "%Y\ub144 %B %d\uc77c (%a) %p %I\uc2dc %M\ubd84 %S\ucd08" - }, - ja: { - ms: [" 1\u6708", " 2\u6708", " 3\u6708", " 4\u6708", " 5\u6708", " 6\u6708", " 7\u6708", " 8\u6708", " 9\u6708", "10\u6708", "11\u6708", "12\u6708"], - ml: ["1\u6708", "2\u6708", "3\u6708", "4\u6708", "5\u6708", "6\u6708", "7\u6708", "8\u6708", "9\u6708", "10\u6708", "11\u6708", "12\u6708"], - ws: ["\u65e5", "\u6708", "\u706b", "\u6c34", "\u6728", "\u91d1", "\u571f"], - wl: ["\u65e5\u66dc\u65e5", "\u6708\u66dc\u65e5", "\u706b\u66dc\u65e5", "\u6c34\u66dc\u65e5", "\u6728\u66dc\u65e5", "\u91d1\u66dc\u65e5", "\u571f\u66dc\u65e5"], - xf: "%Y\u5e74%B%d\u65e5", - Xf: "%H\u6642%M\u5206%S\u79d2", - cf: "%Y\u5e74%B%d\u65e5 %H\u6642%M\u5206%S\u79d2" - } - }; - - var translation = translations[lang]; - - var firstday; - - var result = []; - var inspec = false; - for (var i = 0; i < fmt.length; ++i) - { - var c = fmt[i]; - if (inspec) - { - switch (c) - { - case "a": - c = translation.ws[obj.getDay()]; - break; - case "A": - c = translation.wl[obj.getDay()]; - break; - case "b": - c = translation.ms[obj.getMonth()]; - break; - case "B": - c = translation.ml[obj.getMonth()]; - break; - case "c": - c = ul4._format(obj, translation.cf, lang); - break; - case "d": - c = ul4._lpad(obj.getDate(), "0", 2); - break; - case "f": - c = ul4._lpad(obj.getMilliseconds(), "0", 3) + "000"; - break; - case "H": - c = ul4._lpad(obj.getHours(), "0", 2); - break; - case "I": - c = ul4._lpad(((obj.getHours()-1) % 12)+1, "0", 2); - break; - case "j": - c = ul4._lpad(ul4._yearday(obj), "0", 3); - break; - case "m": - c = ul4._lpad(obj.getMonth()+1, "0", 2); - break; - case "M": - c = ul4._lpad(obj.getMinutes(), "0", 2); - break; - case "p": - c = obj.getHours() < 12 ? "AM" : "PM"; - break; - case "S": - c = ul4._lpad(obj.getSeconds(), "0", 2); - break; - case "U": - c = ul4._lpad(ul4._week(obj, 6), "0", 2); - break; - case "w": - c = obj.getDay(); - break; - case "W": - c = ul4._lpad(ul4._week(obj, 0), "0", 2); - break; - case "x": - c = ul4._format(obj, translation.xf, lang); - break; - case "X": - c = ul4._format(obj, translation.Xf, lang); - break; - case "y": - c = (obj.getFullYear() % 100).toString(); - break; - case "Y": - c = obj.getFullYear().toString(); - break; - case "z": - // UTC offset in the form +HHMM or -HHMM - c = ""; - break; - case "Z": - // Time zone name - c = ""; - break; - } - result.push(c); - inspec = false; - } - else - { - if (c == "%") - inspec = true; - else - result.push(c); - } - } - return result.join(""); - }; - - ul4._format_int = function _format_int(obj, fmt, lang) - { - var work = fmt; - - // Defaults - var fill = ' '; - var align = '>'; // '<', '>', '=' or '^' - var sign = '-'; // '+', '-' or ' ' - var alternate = false; - var minimumwidth = 0; - var type = 'd'; // 'b', 'c', 'd', 'o', 'x', 'X' or 'n' - - // Determine output type - if (/[bcdoxXn]$/.test(work)) - { - type = work.substring(work.length-1); - work = work.substring(0, work.length-1); - } - - // Extract minimum width - if (/\d+$/.test(work)) - { - var minimumwidthStr = /\d+$/.exec(work); - work = work.replace(/\d+$/, ""); - if (/^0/.test(minimumwidthStr)) - { - align = '='; - fill = '0'; - } - minimumwidth = parseInt(minimumwidthStr); - } - - // Alternate form? - if (/#$/.test(work)) - { - alternate = true; - work = work.substring(0, work.length-1); - } - - // Determine sign - if (/[+ -]$/.test(work)) - { - if (type == 'c') - throw ul4.ValueError.create("sign not allowed for integer format type 'c'"); - sign = work.substring(work.length-1); - work = work.substring(0, work.length-1); - } - - // Extract fill and align char - if (work.length >= 3) - throw ul4.ValueError.create("illegal integer format string " + ul4._repr(fmt)); - else if (work.length == 2) - { - if (/[<>=^]$/.test(work)) - { - align = work[1]; - fill = work[0]; - } - else - throw ul4.ValueError.create("illegal integer format string " + ul4._repr(fmt)); - } - else if (work.length == 1) - { - if (/^[<>=^]$/.test(work)) - align = work; - else - throw ul4.ValueError.create("illegal integer format string " + ul4._repr(fmt)); - } - - // Basic number formatting - var neg = obj < 0; - - if (neg) - obj = -obj; - - var output; - switch (type) - { - case 'b': - output = obj.toString(2); - break; - case 'c': - if (neg || obj > 65535) - throw ul4.ValueError.create("value out of bounds for c format"); - output = String.fromCharCode(obj); - break; - case 'd': - output = obj.toString(); - break; - case 'o': - output = obj.toString(8); - break; - case 'x': - output = obj.toString(16); - break; - case 'X': - output = obj.toString(16).toUpperCase(); - break; - case 'n': - // FIXME: locale formatting - output = obj.toString(); - break; - } - - // The rest of the formatting - if (align === '=') - { - if (neg || sign !== '-') - --minimumwidth; - if (alternate && (type === 'b' || type === 'o' || type === 'x' || type === 'X')) - minimumwidth -= 2; - - if (output.length < minimumwidth) - output = ul4._str_repeat(fill, minimumwidth-output.length) + output; - - if (alternate && (type === 'b' || type === 'o' || type === 'x' || type === 'X')) - output = "0" + type + output; - - if (neg) - output = "-" + output; - else if (sign != '-') - output = sign + output; - } - else - { - if (alternate && (type == 'b' || type == 'o' || type == 'x' || type == 'X')) - output = "0" + type + output; - if (neg) - output = "-" + output; - else if (sign != '-') - output = sign + output; - if (output.length < minimumwidth) - { - if (align == '<') - output = output + ul4._str_repeat(fill, minimumwidth-output.length); - else if (align == '>') - output = ul4._str_repeat(fill, minimumwidth-output.length) + output; - else // if (align == '^') - { - var pad = minimumwidth - output.length; - var padBefore = Math.floor(pad/2); - var padAfter = pad-padBefore; - output = ul4._str_repeat(fill, padBefore) + output + ul4._str_repeat(fill, padAfter); - } - } - } - return output; - }; - - // Format ``obj`` using the format string ``fmt`` in the language ``lang`` - ul4._format = function _format(obj, fmt, lang) - { - if (typeof(lang) === "undefined" || lang === null) - lang = "en"; - else - { - var translations = {de: null, en: null, fr: null, es: null, it: null, da: null, sv: null, nl: null, pt: null, cs: null, sk: null, pl: null, hr: null, sr: null, ro: null, hu: null, tr: null, ru: null, zh: null, ko: null, ja: null}; - lang = lang.toLowerCase(); - if (typeof(translations[lang]) === "undefined") - { - lang = lang.split(/_/)[0]; - if (typeof(translations[lang]) === "undefined") - lang = "en"; - } - } - if (ul4._isdate(obj)) - return ul4._format_date(obj, fmt, lang); - else if (ul4._isint(obj)) - return ul4._format_int(obj, fmt, lang); - else if (obj === true) - return ul4._format_int(1, fmt, lang); - else if (obj === false) - return ul4._format_int(0, fmt, lang); - }; - - ul4._lpad = function _lpad(string, pad, len) - { - if (typeof(string) === "number") - string = string.toString(); - while (string.length < len) - string = pad + string; - return string; - }; - - ul4._rpad = function _rpad(string, pad, len) - { - if (typeof(string) === "number") - string = string.toString(); - while (string.length < len) - string = string + pad; - return string; - }; - - ul4.Proto = { - __prototype__: null, - __id__: 0, - _nextid: 1, - isa: function isa(type) - { - if (this === type) - return true; - if (this.__prototype__ === null) - return false; - return this.__prototype__.isa(type); - }, - - isprotoof: function isprotoof(obj) - { - while (true) - { - if (obj === null || Object.prototype.toString.call(obj) !== "[object Object]" || typeof(obj.__prototype__) === "undefined") - return false; - if (obj === this) - return true; - obj = obj.__prototype__; - } - }, - - // equality comparison of objects defaults to identity comparison - __eq__: function __eq__(other) - { - return this === other; - }, - - // To overwrite equality comparison, you only have to overwrite ``__eq__``, - // ``__ne__`` will be synthesized from that - __ne__: function __ne__(other) - { - return !this.__eq__(other); - }, - - // For other comparison operators, each method has to be implemented: - // ``<`` calls ``__lt__``, ``<=`` calls ``__le__``, ``>`` calls ``__gt__`` and - // ``>=`` calls ``__ge__`` - - __bool__: function __bool__() - { - return true; - } - }; - - ul4.Signature = ul4._inherit( - ul4.Proto, - { - create: function create() - { - var signature = ul4._clone(this); - signature.args = []; - signature.argNames = {}; - signature.remargs = null; - signature.remkwargs = null; - - var nextDefault = false; - var lastArgname = null; - for (var i = 0; i < arguments.length; ++i) - { - var argName = arguments[i]; - if (nextDefault) - { - signature.args.push({name: lastArgname, defaultValue: argName}); - signature.argNames[lastArgname] = true; - nextDefault = false; - } - else - { - if (argName.substr(argName.length-1) === "=") - { - lastArgname = argName.substr(0, argName.length-1); - nextDefault = true; - } - else if (argName.substr(0, 2) === "**") - signature.remkwargs = argName.substr(2); - else if (argName.substr(0, 1) === "*") - signature.remargs = argName.substr(1); - else - { - signature.args.push({name: argName}); - signature.argNames[argName] = true; - } - } - } - return signature; - }, - - // Create the argument array for calling a function with this signature with the arguments available from ``args`` - bindArray: function bindArray(name, args, kwargs) - { - var finalargs = []; - var decname = name !== null ? name + "() " : ""; - - for (var i = 0; i < this.args.length; ++i) - { - var arg = this.args[i]; - if (i < args.length) - { - if (kwargs.hasOwnProperty(arg.name)) - throw ul4.ArgumentError.create(decname + "argument " + ul4._repr(arg.name) + " (position " + i + ") specified multiple times"); - finalargs.push(args[i]); - } - else - { - if (kwargs.hasOwnProperty(arg.name)) - finalargs.push(kwargs[arg.name]); - else - { - if (arg.hasOwnProperty("defaultValue")) - finalargs.push(arg.defaultValue); - else - throw ul4.ArgumentError.create("required " + decname + "argument " + ul4._repr(arg.name) + " (position " + i + ") missing"); - } - } - } - - // Do we accept additional positional arguments? - if (this.remargs === null) - { - // No, but we have them -> complain - if (args.length > this.args.length) - { - var prefix = name === null ? "expected" : name + "() expects"; - throw ul4.ArgumentError.create(prefix + " at most " + this.args.length + " positional argument" + (this.args.length != 1 ? "s" : "") + ", " + args.length + " given"); - } - } - else - { - // Put additional positional arguments in the call into the ``*`` argument (if there are none, this pushes an empty list) - finalargs.push(args.slice(this.args.length)); - } - - // Do we accept arbitrary keyword arguments? - if (this.remkwargs === null) - { - // No => complain about unknown ones - for (var key in kwargs) - { - if (!this.argNames[key]) - { - if (name === null) - throw ul4.ArgumentError.create("an argument named " + ul4._repr(key) + " isn't supported"); - else - throw ul4.ArgumentError.create(name + "() doesn't support an argument named " + ul4._repr(key)); - } - } - } - else - { - // Yes => Put the unknown ones into an object and add that to the arguments array - var remkwargs = {}; - for (var key in kwargs) - { - if (!this.argNames[key]) - remkwargs[key] = kwargs[key]; - } - finalargs.push(remkwargs); - } - - return finalargs; - }, - - // Create the argument object for calling a function with this signature with the arguments available from ``args`` - bindObject: function bindObject(name, args, kwargs) - { - args = this.bindArray(name, args, kwargs); - var argObject = {}; - var i; - for (i = 0; i < this.args.length; ++i) - argObject[this.args[i].name] = args[i]; - if (this.remargs !== null) - argObject[this.remargs] = args[i++]; - if (this.remkwargs !== null) - argObject[this.remkwargs] = args[i++]; - return argObject; - }, - - __repr__: function __repr__() - { - return ""; - }, - - __str__: function __str__() - { - return this.toString(); - }, - - toString: function toString() - { - var v = []; - for (var i = 0; i < this.args.length; ++i) - { - var arg = this.args[i]; - - if (arg.hasOwnProperty("defaultValue")) - v.push(arg.name + "=" + ul4._repr(arg.defaultValue)); - else - v.push(arg.name); - } - if (this.remargs !== null) - v.push("*" + this.remargs); - if (this.remkwargs !== null) - v.push("**" + this.remkwargs); - return "(" + v.join(", ") + ")"; - } - } - ); - - // Adds name and signature to a function/method and makes the method callable in templates - ul4.expose = function expose(signature, options, f) - { - if (typeof(f) === "undefined") - { - f = options; - options = {}; - } - if (options.name) - f._ul4_name = options.name; - if (ul4._islist(signature)) - signature = ul4.Signature.create.apply(ul4.Signature, signature); - f._ul4_signature = signature; - f._ul4_needsobject = options.needsobject || false; - f._ul4_needscontext = options.needscontext || false; - - return f; - }; - - ul4.Context = ul4._inherit( - ul4.Proto, - { - create: function create(vars) - { - if (vars === null || typeof(vars) === "undefined") - vars = {}; - var context = ul4._clone(this); - context.vars = vars; - context.indents = []; - context._output = []; - return context; - }, - - /* Return a clone of the ``Context``, but with a fresh empty ``vars`` objects that inherits from the previous one. - * This is used by the various comprehensions to avoid leaking loop variables. - */ - inheritvars: function inheritvars() - { - var context = ul4._clone(this); - context.vars = ul4._simpleclone(this.vars); - return context; - }, - - /* Return a clone of the ``Context`` with one additional indentation (this is used by ``RenderAST``) */ - withindent: function withindent(indent) - { - var context = ul4._clone(this); - if (indent !== null) - { - context.indents = this.indents.slice(); - context.indents.push(indent); - } - return context; - }, - - /* Return a clone of the ``Context`` with the output buffer replaced (this is used by ``renders`` to collect the output in a separate buffer) */ - replaceoutput: function replaceoutput() - { - var context = ul4._clone(this); - context._output = []; - return context; - }, - - clone: function clone(vars) - { - return ul4._clone(this); - }, - - output: function output(value) - { - this._output.push(value); - }, - - getoutput: function getoutput() - { - return this._output.join(""); - }, - - get: function get(name) - { - return this.vars[name]; - }, - - set: function set(name, value) - { - this.vars[name] = value; - } - } - ); - - /// Exceptions - - ul4.Exception = ul4._inherit( - ul4.Proto, - { - __type__: "ul4.Exception", - "cause": null, - - __getattr__: function __getattr__(attrname) - { - switch (attrname) - { - case "cause": - return this.cause; - default: - return undefined; - } - } - } - ); - - // Exceptions used internally by UL4 for flow control - ul4.InternalException = ul4._inherit(ul4.Exception, {}); - - // Control flow exceptions - ul4.ReturnException = ul4._inherit( - ul4.InternalException, - { - __type__: "ul4.ReturnException", - - create: function create(result) - { - var exception = ul4._clone(this); - exception.result = result; - return exception; - } - } - ); - - ul4.BreakException = ul4._inherit( - ul4.InternalException, - { - __type__: "ul4.BreakException" - } - ); - - ul4.ContinueException = ul4._inherit( - ul4.InternalException, - { - __type__: "ul4.ContinueException" - } - ); - - // Real exceptions raised by various parts of UL4 - ul4.SyntaxError = ul4._inherit( - ul4.Exception, - { - __type__: "ul4.SyntaxError" - } - ); - - ul4.LValueRequiredError = ul4._inherit( - ul4.SyntaxError, - { - __type__: "ul4.LValueRequiredError", - - toString: function toString() - { - return "lvalue required!"; - } - } - ); - - ul4.TypeError = ul4._inherit( - ul4.Exception, - { - __type__: "ul4.TypeError", - - create: function create(operation, message) - { - var exception = ul4._clone(this); - exception.operation = operation; - exception.message = message; - return exception; - }, - toString: function toString() - { - return this.message; - } - } - ); - - ul4.ValueError = ul4._inherit( - ul4.Exception, - { - __type__: "ul4.ValueError", - - create: function create(message) - { - var exception = ul4._clone(this); - exception.message = message; - return exception; - }, - toString: function toString() - { - return this.message; - } - } - ); - - ul4.ArgumentError = ul4._inherit( - ul4.Exception, - { - __type__: "ul4.ArgumentError", - - create: function create(message) - { - var exception = ul4._clone(this); - exception.message = message; - return exception; - }, - toString: function toString() - { - return this.message; - } - } - ); - - /// Exception that wraps other exceptions while they bubble up the stack - ul4.LocationError = ul4._inherit( - ul4.Exception, - { - __type__: "ul4.LocationError", - - create: function create(location, cause) - { - var exception = ul4._clone(this); - exception.location = location; - exception.cause = cause; - return exception; - }, - - _templateprefix: function(template) - { - var out = []; - if (template.parenttemplate !== null) - out.push("in local template "); - else - out.push("in template "); - var first = true; - while (template != null) - { - if (first) - first = false; - else - out.push(" in "); - out.push(template.name !== null ? ul4._repr(template.name) : "(unnamed)"); - template = template.parenttemplate; - } - return out.join(""); - }, - - _template: function _template() - { - if (ul4.Tag.isprotoof(this.location)) - return this.location.template; - else - return this.location.tag.template; - }, - - _outerpos: function _outerpos() - { - if (ul4.Tag.isprotoof(this.location)) - return this.location.pos; - else - { - var tag = this.location.tag; - if (tag === null) // A top level template as no tag - return this.location.pos; - else - return tag.pos; - } - }, - - _innerpos: function _innerpos() - { - return this.location.pos; - }, - - toString: function toString() - { - var template = this._template(); - var templateprefix = this._templateprefix(template); - var outerpos = this._outerpos(); - var innerpos = this._innerpos(); - - var prefix = template.source.substring(outerpos.start, innerpos.start); - var code = template.source.substring(innerpos.start, innerpos.stop); - var suffix = template.source.substring(innerpos.stop, outerpos.stop); - prefix = ul4._repr(prefix).slice(1, -1); - code = ul4._repr(code).slice(1, -1); - suffix = ul4._repr(suffix).slice(1, -1); - var text = prefix + code + suffix; - var underline = ul4._str_repeat("\u00a0", prefix.length) + ul4._str_repeat("~", code.length); - - // find line numbers - var lineno = 1, colno = 1; - for (var i = 0; i < innerpos.start; ++i) - { - if (template.source[i] === "\n") - { - ++lineno; - colno = 1; - } - else - ++colno; - } - - pos = "offset " + this.location.pos.start + ":" + this.location.pos.stop + "; line " + lineno + "; col " + colno; - - return templateprefix + ": " + pos + "\n" + text + "\n" + underline; - }, - - __getattr__: function __getattr__(attrname) - { - switch (attrname) - { - case "cause": - return this.cause; - case "location": - return this.location; - case "template": - return this._template; - case "outerpos": - return this._outerpos; - case "innerpos": - return this._innerpos; - default: - return undefined; - } - } - } - ); - - - /// Classes for the syntax tree - ul4.AST = ul4._inherit( - ul4.Proto, - { - create: function create(pos) - { - var ast = ul4._clone(this); - ast.pos = pos; - return ast; - }, - __str__: function __str__() - { - var out = []; - this._str(out); - return ul4._formatsource(out); - }, - __repr__: function __repr__() - { - var out = []; - this._repr(out); - return ul4._formatsource(out); - }, - _handle_eval: function _handle_eval(context) - { - try - { - return this._eval(context); - } - catch (exc) - { - if (!ul4.InternalException.isprotoof(exc) && !ul4.LocationError.isprotoof(exc)) - exc = ul4.LocationError.create(this, exc); - throw exc; - } - }, - _handle_eval_set: function _handle_eval_set(context, value) - { - try - { - return this._eval_set(context, value); - } - catch (exc) - { - if (!ul4.LocationError.isprotoof(exc)) - exc = ul4.LocationError.create(this, exc); - throw exc; - } - }, - _eval_set: function _eval_set(context, value) - { - throw ul4.LValueRequiredError; - }, - _handle_eval_modify: function _handle_eval_modify(context, operator, value) - { - try - { - return this._eval_modify(context, operator, value); - } - catch (exc) - { - if (!ul4.LocationError.isprotoof(exc)) - exc = ul4.LocationError.create(this, exc); - throw exc; - } - }, - _eval_modify: function _eval_modify(context, operator, value) - { - throw ul4.LValueRequiredError; - }, - _repr: function _repr(out) - { - }, - _str: function _str(out) - { - }, - ul4ondump: function ul4ondump(encoder) - { - for (var i = 0; i < this._ul4onattrs.length; ++i) - encoder.dump(this[this._ul4onattrs[i]]); - }, - ul4onload: function ul4onload(decoder) - { - for (var i = 0; i < this._ul4onattrs.length; ++i) - this[this._ul4onattrs[i]] = decoder.load(); - }, - __setitem__: function __setitem__(attrname, value) - { - throw ul4.TypeError.create("mutate", "object is immutable"); - }, - // used in ul4ondump/ul4ondump to automatically dump these attributes - _ul4onattrs: ["pos"] - } - ); - - ul4.TextAST = ul4._inherit( - ul4.AST, - { - create: function create(template, pos) - { - var text = ul4.AST.create.call(this, pos); - text.template = template; - return text; - }, - _ul4onattrs: ul4.AST._ul4onattrs.concat(["template"]), - _text: function _text() - { - return this.template.source.substring(this.pos.start, this.pos.stop); - }, - _eval: function _eval(context) - { - context.output(this._text()); - }, - _str: function _str(out) - { - out.push("text "); - out.push(ul4._repr(this._text())); - }, - _repr: function _repr(out) - { - out.push(""); - } - } - ); - - ul4.IndentAST = ul4._inherit( - ul4.TextAST, - { - create: function create(template, pos, text) - { - var indent = ul4.TextAST.create.call(this, template, pos); - indent._maketext(text); - return indent; - }, - _maketext: function _maketext(text) - { - if (typeof(this.template) !== "undefined") - { - if (text === null) - this.text = this.template.source.substring(this.pos.start, this.pos.stop); - else - this.text = text; - } - else - this.text = null; - }, - _text: function _text() - { - if (this.text === null) - return this.template.source.substring(this.pos.start, this.pos.stop); - else - return this.text; - }, - _eval: function _eval(context) - { - for (var i = 0; i < context.indents.length; ++i) - context.output(context.indents[i]); - context.output(this._text()); - }, - ul4ondump: function ul4ondump(encoder) - { - ul4.TextAST.ul4ondump.call(this, encoder); - - if (this.text === this.template.source.substring(this.pos.start, this.pos.stop)) - encoder.dump(null); - else - encoder.dump(this.text); - }, - ul4onload: function ul4onload(decoder) - { - ul4.TextAST.ul4onload.call(this, decoder); - // Recreate ``text`` attribute - this._maketext(decoder.load()); - }, - _str: function _str(out) - { - out.push("indent "); - out.push(ul4._repr(this._text())); - }, - _repr: function _repr(out) - { - out.push(""); - } - } - ); - - ul4.LineEndAST = ul4._inherit( - ul4.TextAST, - { - _str: function _str(out) - { - out.push("lineend "); - out.push(ul4._repr(this._text())); - }, - _repr: function _repr(out) - { - out.push(""); - } - } - ); - - ul4.Tag = ul4._inherit( - ul4.AST, - { - create: function create(template, tag, tagpos, codepos) - { - var tago = ul4.AST.create.call(this, tagpos); - tago.template = template; - tago.tag = tag; - tago.codepos = codepos; - tago._maketext(); - return tago; - }, - _maketext: function _maketext() - { - if (typeof(this.template) !== "undefined") - { - this.text = this.template.source.substring(this.pos.start, this.pos.stop); - this.code = this.template.source.substring(this.codepos.start, this.codepos.stop); - } - else - { - this.text = null; - this.code = null; - } - }, - ul4ondump: function ul4ondump(encoder) - { - ul4.AST.ul4ondump.call(this, encoder); - encoder.dump(this.template); - encoder.dump(this.tag); - encoder.dump(this.codepos); - }, - ul4onload: function ul4onload(decoder) - { - ul4.TextAST.ul4onload.call(this, decoder); - this.template = decoder.load(); - this.tag = decoder.load(); - this.codepos = decoder.load(); - // Recreate ``text`` attribute - this._maketext(); - } - } - ); - - ul4.CodeAST = ul4._inherit( - ul4.AST, - { - create: function create(tag, pos) - { - var code = ul4.AST.create.call(this, pos); - code.tag = tag; - return code; - }, - _ul4onattrs: ul4.AST._ul4onattrs.concat(["tag"]), - _str: function _str(out) - { - out.push(this.tag.source.substring(this.pos.start, this.pos.stop).replace(/\r?\n/g, ' ')); - } - } - ); - - ul4.ConstAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, value) - { - var constant = ul4.CodeAST.create.call(this, tag, pos); - constant.value = value; - return constant; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["value"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - return this.value; - } - } - ); - - ul4.ItemArgBase = ul4._inherit( - ul4.CodeAST, - { - _handle_eval_list: function _handle_eval_list(context, result) - { - try - { - return this._eval_list(context, result); - } - catch (exc) - { - if (!ul4.InternalException.isprotoof(exc) && !ul4.LocationError.isprotoof(exc)) - exc = ul4.LocationError.create(this, exc); - throw exc; - } - }, - _handle_eval_set: function _handle_eval_set(context, result) - { - try - { - return this._eval_set(context, result); - } - catch (exc) - { - if (!ul4.InternalException.isprotoof(exc) && !ul4.LocationError.isprotoof(exc)) - exc = ul4.LocationError.create(this, exc); - throw exc; - } - }, - _handle_eval_dict: function _handle_eval_dict(context, result) - { - try - { - return this._eval_dict(context, result); - } - catch (exc) - { - if (!ul4.InternalException.isprotoof(exc) && !ul4.LocationError.isprotoof(exc)) - exc = ul4.LocationError.create(this, exc); - throw exc; - } - }, - _handle_eval_call: function _handle_eval_call(context, args, kwargs) - { - try - { - return this._eval_call(context, args, kwargs); - } - catch (exc) - { - if (!ul4.InternalException.isprotoof(exc) && !ul4.LocationError.isprotoof(exc)) - exc = ul4.LocationError.create(this, exc); - throw exc; - } - } - } - ); - - ul4.SeqItemAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, value) - { - var seqitem = ul4.ItemArgBase.create.call(this, tag, pos); - seqitem.value = value; - return seqitem; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["value"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_list: function _eval_list(context, result) - { - var value = this.value._handle_eval(context); - result.push(value); - }, - _eval_set: function _eval_set(context, result) - { - var value = this.value._handle_eval(context); - result.add(value); - } - } - ); - - - ul4.UnpackSeqItemAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, value) - { - var unpackseqitem = ul4.ItemArgBase.create.call(this, tag, pos); - unpackseqitem.value = value; - return unpackseqitem; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["value"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_list: function _eval_list(context, result) - { - var value = this.value._handle_eval(context); - for (var iter = ul4._iter(value);;) - { - var item = iter.next(); - if (item.done) - break; - result.push(item.value); - } - }, - _eval_set: function _eval_set(context, result) - { - var value = this.value._handle_eval(context); - for (var iter = ul4._iter(value);;) - { - var item = iter.next(); - if (item.done) - break; - result.add(item.value); - } - } - } - ); - - ul4.DictItemAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, key, value) - { - var dictitem = ul4.ItemArgBase.create.call(this, tag, pos); - dictitem.key = key; - dictitem.value = value; - return dictitem; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["key", "value"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_dict: function _eval_dict(context, result) - { - var key = this.key._handle_eval(context); - var value = this.value._handle_eval(context); - ul4on._setmap(result, key, value); - } - } - ); - - ul4.UnpackDictItemAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, item) - { - var unpackdictitem = ul4.ItemArgBase.create.call(this, tag, pos); - unpackdictitem.item = item; - return unpackdictitem; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["item"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_dict: function _eval_dict(context, result) - { - var item = this.item._handle_eval(context); - if (ul4._islist(item)) - { - for (var i = 0; i < item.length; ++i) - { - if (!ul4._islist(item[i]) || item[i].length != 2) - throw ul4.ArgumentError.create("** requires a list of (key, value) pairs"); - var key = item[i][0], value = item[i][1]; - ul4on._setmap(result, key, value); - } - } - else if (ul4._ismap(item)) - { - item.forEach(function(value, key){ - ul4on._setmap(result, key, value); - }); - } - else if (ul4._isobject(item)) - { - for (var key in item) - ul4on._setmap(result, key, item[key]); - } - } - } - ); - - ul4.PosArgAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, value) - { - var arg = ul4.ItemArgBase.create.call(this, tag, pos); - arg.value = value; - return arg; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["value"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_call: function _eval_call(context, args, kwargs) - { - var value = this.value._handle_eval(context); - args.push(value); - } - } - ); - - ul4.KeywordArgAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, name, value) - { - var arg = ul4.ItemArgBase.create.call(this, tag, pos); - arg.name = name; - arg.value = value; - return arg; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["name", "value"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_call: function _eval_call(context, args, kwargs) - { - if (kwargs.hasOwnProperty(this.name)) - throw ul4.ArgumentError.create("duplicate keyword argument " + this.name); - var value = this.value._handle_eval(context); - kwargs[this.name] = value; - } - } - ); - - ul4.UnpackListArgAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, item) - { - var arg = ul4.ItemArgBase.create.call(this, tag, pos); - arg.item = item; - return arg; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["item"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_call: function _eval_call(context, args, kwargs) - { - var item = this.item._handle_eval(context); - args.push.apply(args, item); - } - } - ); - - ul4.UnpackDictArgAST = ul4._inherit( - ul4.ItemArgBase, - { - create: function create(tag, pos, item) - { - var arg = ul4.ItemArgBase.create.call(this, tag, pos); - arg.item = item; - return arg; - }, - _ul4onattrs: ul4.ItemArgBase._ul4onattrs.concat(["item"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval_call: function _eval_call(context, args, kwargs) - { - var item = this.item._handle_eval(context); - if (ul4._islist(item)) - { - for (var i = 0; i < item.length; ++i) - { - if (!ul4._islist(item[i]) || item[i].length != 2) - throw ul4.ArgumentError.create("** requires a list of (key, value) pairs"); - var key = item[i][0], value = item[i][1]; - if (kwargs.hasOwnProperty(key)) - throw ul4.ArgumentError.create("duplicate keyword argument " + key); - kwargs[key] = value; - } - } - else if (ul4._ismap(item)) - { - item.forEach(function(value, key){ - if (kwargs.hasOwnProperty(key)) - throw ul4.ArgumentError.create("duplicate keyword argument " + key); - kwargs[key] = value; - }); - } - else if (ul4._isobject(item)) - { - for (var key in item) - { - if (kwargs.hasOwnProperty(key)) - throw ul4.ArgumentError.create("duplicate keyword argument " + key); - kwargs[key] = item[key]; - } - } - } - } - ); - - ul4.ListAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos) - { - var list = ul4.CodeAST.create.call(this, tag, pos); - list.items = []; - return list; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["items"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - var result = []; - for (var i = 0; i < this.items.length; ++i) - this.items[i]._handle_eval_list(context, result); - return result; - } - } - ); - - ul4.ListCompAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, item, varname, container, condition) - { - var listcomp = ul4.CodeAST.create.call(this, tag, pos); - listcomp.item = item; - listcomp.varname = varname; - listcomp.container = container; - listcomp.condition = condition; - return listcomp; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["item", "varname", "container", "condition"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - var container = this.container._handle_eval(context); - - var localcontext = context.inheritvars(); - - var result = []; - for (var iter = ul4._iter(container);;) - { - var item = iter.next(); - if (item.done) - break; - var varitems = ul4._unpackvar(this.varname, item.value); - for (var i = 0; i < varitems.length; ++i) - varitems[i][0]._handle_eval_set(localcontext, varitems[i][1]); - if (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext))) - result.push(this.item._handle_eval(localcontext)); - } - return result; - } - } - ); - - ul4.DictAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos) - { - var dict = ul4.CodeAST.create.call(this, tag, pos); - dict.items = []; - return dict; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["items"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - var result = ul4on._emptymap(); - for (var i = 0; i < this.items.length; ++i) - this.items[i]._handle_eval_dict(context, result); - return result; - } - } - ); - - ul4.DictCompAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, key, value, varname, container, condition) - { - var listcomp = ul4.CodeAST.create.call(this, tag, pos); - listcomp.key = key; - listcomp.value = value; - listcomp.varname = varname; - listcomp.container = container; - listcomp.condition = condition; - return listcomp; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["key", "value", "varname", "container", "condition"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - var container = this.container._handle_eval(context); - - var localcontext = context.inheritvars(); - - var result = ul4on._emptymap(); - - for (var iter = ul4._iter(container);;) - { - var item = iter.next(); - if (item.done) - break; - var varitems = ul4._unpackvar(this.varname, item.value); - for (var i = 0; i < varitems.length; ++i) - varitems[i][0]._handle_eval_set(localcontext, varitems[i][1]); - if (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext))) - { - var key = this.key._handle_eval(localcontext); - var value = this.value._handle_eval(localcontext); - ul4on._setmap(result, key, value); - } - } - - return result; - } - } - ); - - ul4.SetAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos) - { - var set = ul4.CodeAST.create.call(this, tag, pos); - set.items = []; - return set; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["items"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - var result = ul4on._haveset ? new Set() : ul4._Set.create(); - - for (var i = 0; i < this.items.length; ++i) - this.items[i]._handle_eval_set(context, result); - - return result; - } - } - ); - - ul4.SetCompAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, item, varname, container, condition) - { - var setcomp = ul4.CodeAST.create.call(this, tag, pos); - setcomp.item = item; - setcomp.container = container; - setcomp.condition = condition; - return setcomp; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["item", "varname", "container", "condition"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - var container = this.container._handle_eval(context); - - var localcontext = context.inheritvars(); - - var result = ul4on._haveset ? new Set() : ul4._Set.create(); - for (var iter = ul4._iter(container);;) - { - var item = iter.next(); - if (item.done) - break; - var varitems = ul4._unpackvar(this.varname, item.value); - for (var i = 0; i < varitems.length; ++i) - varitems[i][0]._handle_eval_set(localcontext, varitems[i][1]); - if (this.condition === null || ul4._bool(this.condition._handle_eval(localcontext))) - result.add(this.item._handle_eval(localcontext)); - } - - return result; - } - } - ); - - ul4.GenExprAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, item, varname, container, condition) - { - var genexp = ul4.CodeAST.create.call(this, tag, pos); - genexp.item = item; - genexp.varname = varname; - genexp.container = container; - genexp.condition = condition; - return genexp; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["item", "varname", "container", "condition"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - var container = this.container._handle_eval(context); - var iter = ul4._iter(container); - - var localcontext = context.inheritvars(); - - var self = this; - - var result = { - next: function(){ - while (true) - { - var item = iter.next(); - if (item.done) - return item; - var varitems = ul4._unpackvar(self.varname, item.value); - for (var i = 0; i < varitems.length; ++i) - varitems[i][0]._handle_eval_set(localcontext, varitems[i][1]); - if (self.condition === null || ul4._bool(self.condition._handle_eval(localcontext))) - { - var value = self.item._handle_eval(localcontext); - return {value: value, done: false}; - } - } - } - }; - - return result; - } - } - ); - - ul4.VarAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, name) - { - var variable = ul4.CodeAST.create.call(this, tag, pos); - variable.name = name; - return variable; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["name"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - return this._get(context, this.name); - }, - _eval_set: function _eval_set(context, value) - { - this._set(context, this.name, value); - }, - _eval_modify: function _eval_modify(context, operator, value) - { - this._modify(context, operator, this.name, value); - }, - _get: function _get(context, name) - { - var result = context.get(name); - if (typeof(result) === "undefined") - result = ul4.functions[name]; - return result; - }, - _set: function _set(context, name, value) - { - context.set(name, value); - }, - _modify: function _modify(context, operator, name, value) - { - var newvalue = operator._ido(context.get(name), value) - context.set(name, newvalue); - } - } - ); - - ul4.UnaryAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, obj) - { - var unary = ul4.CodeAST.create.call(this, tag, pos); - unary.obj = obj; - return unary; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["obj"]), - _repr: function _repr(out) - { - out.push("<"); - out.push(this.typename); - out.push(" obj="); - this.obj._repr(out); - out.push(">"); - }, - _eval: function _eval(context) - { - var obj = this.obj._handle_eval(context); - return this._do(obj); - } - } - ); - - // Negation - ul4.NegAST = ul4._inherit( - ul4.UnaryAST, - { - _do: function _do(obj) - { - if (obj !== null && typeof(obj.__neg__) === "function") - return obj.__neg__(); - return -obj; - } - } - ); - - // Bitwise not - ul4.BitNotAST = ul4._inherit( - ul4.UnaryAST, - { - _do: function _do(obj) - { - return -obj-1; - } - } - ); - - // Not - ul4.NotAST = ul4._inherit( - ul4.UnaryAST, - { - _do: function _do(obj) - { - return !ul4._bool(obj); - } - } - ); - - // If expression - ul4.IfAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, objif, objcond, objelse) - { - var ifexpr = ul4.CodeAST.create.call(this, tag, pos); - ifexpr.objif = objif; - ifexpr.objcond = objcond; - ifexpr.objelse = objelse; - return ifexpr; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["objif", "objcond", "objelse"]), - _repr: function _repr(out) - { - out.push("<"); - out.push(this.typename); - out.push(+1); - out.push("objif="); - this.objif._repr(out); - out.push(0); - out.push("objcond="); - this.objcond._repr(out); - out.push(0); - out.push("objelse="); - this.objelse._repr(out); - out.push(-1); - out.push(">"); - }, - _eval: function _eval(context) - { - var result; - var condvalue = this.objcond._handle_eval(context); - if (ul4._bool(condvalue)) - result = this.objif._handle_eval(context); - else - result = this.objelse._handle_eval(context); - return result; - } - } - ); - - ul4.ReturnAST = ul4._inherit( - ul4.UnaryAST, - { - _eval: function _eval(context) - { - var result = this.obj._handle_eval(context); - throw ul4.ReturnException.create(result); - }, - _str: function _str(out) - { - out.push("return "); - this.obj._str(out); - } - } - ); - - ul4.PrintAST = ul4._inherit( - ul4.UnaryAST, - { - _eval: function _eval(context) - { - var obj = this.obj._handle_eval(context); - var output = ul4._str(obj); - context.output(output); - }, - _str: function _str(out) - { - out.push("print "); - this.obj._str(out); - } - } - ); - - ul4.PrintXAST = ul4._inherit( - ul4.UnaryAST, - { - _eval: function _eval(context) - { - var obj = this.obj._handle_eval(context); - var output = ul4._xmlescape(obj); - context.output(output); - }, - _str: function _str(out) - { - out.push("printx "); - this.obj._str(out); - } - } - ); - - ul4.BinaryAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, obj1, obj2) - { - var binary = ul4.CodeAST.create.call(this, tag, pos); - binary.obj1 = obj1; - binary.obj2 = obj2; - return binary; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["obj1", "obj2"]), - _repr: function _repr(out) - { - out.push("<"); - out.push(this.type); - out.push(" obj1="); - this.obj1._repr(out); - out.push(" obj2="); - this.obj2._repr(out); - out.push(">"); - }, - _eval: function _eval(context) - { - var obj1 = this.obj1._handle_eval(context); - var obj2 = this.obj2._handle_eval(context); - return this._do(obj1, obj2); - } - } - ); - - // Item access and assignment: dict[key], list[index], string[index], color[index] - ul4.ItemAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - var result = this._get(obj1, obj2); - return result; - }, - _eval_set: function _eval_set(context, value) - { - var obj1 = this.obj1._handle_eval(context); - var obj2 = this.obj2._handle_eval(context); - this._set(obj1, obj2, value); - }, - _eval_modify: function _eval_modify(context, operator, value) - { - var obj1 = this.obj1._handle_eval(context); - var obj2 = this.obj2._handle_eval(context); - this._modify(operator, obj1, obj2, value); - }, - _get: function _get(container, key) - { - if (typeof(container) === "string" || ul4._islist(container)) - { - if (typeof(key) === "object" && typeof(key.isa) === "function" && key.isa(ul4.slice)) - { - var start = key.start, stop = key.stop; - if (typeof(start) === "undefined" || start === null) - start = 0; - if (typeof(stop) === "undefined" || stop === null) - stop = container.length; - return container.slice(start, stop); - } - else - { - var orgkey = key; - if (key < 0) - key += container.length; - return container[key]; - } - } - else if (container && typeof(container.__getitem__) === "function") // test this before the generic object test - return container.__getitem__(key); - else if (ul4._ismap(container)) - return container.get(key); - else if (Object.prototype.toString.call(container) === "[object Object]") - return container[key]; - else - throw ul4.TypeError.create("[]", ul4._type(container) + " object is not subscriptable"); - }, - _set: function _set(container, key, value) - { - if (ul4._islist(container)) - { - if (typeof(key) === "object" && typeof(key.isa) === "function" && key.isa(ul4.slice)) - { - var start = key.start, stop = key.stop; - if (start === null) - start = 0; - else if (start < 0) - start += container.length; - if (start < 0) - start = 0; - else if (start > container.length) - start = container.length; - if (stop === null) - stop = container.length; - else if (stop < 0) - stop += container.length; - if (stop < 0) - stop = 0; - else if (stop > container.length) - stop = container.length; - if (stop < start) - stop = start; - container.splice(start, stop-start); // Remove old element - for (var iter = ul4._iter(value);;) - { - var item = iter.next(); - if (item.done) - break; - container.splice(start++, 0, item.value); - } - } - else - { - var orgkey = key; - if (key < 0) - key += container.length; - container[key] = value; - } - } - else if (container && typeof(container.__setitem__) === "function") // test this before the generic object test - container.__setitem__(key, value); - else if (ul4._ismap(container)) - container.set(key, value); - else if (Object.prototype.toString.call(container) === "[object Object]") - container[key] = value; - else - throw ul4.NotSubscriptableError.create(container); - }, - _modify: function _modify(operator, container, key, value) - { - this._set(container, key, operator._ido(this._get(container, key), value)); - } - } - ); - - // Identifty test operator ``is`` - ul4.IsAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return obj1 === obj2; - } - } - ); - - // Inverted tdentifty test operator ``is not`` - ul4.IsNotAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return obj1 !== obj2; - } - } - ); - - // Comparison operator == - ul4.EQAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return ul4._eq(obj1, obj2); - } - } - ); - - // Comparison operator != - ul4.NEAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return ul4._ne(obj1, obj2); - } - } - ); - - // Comparison operator < - ul4.LTAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return ul4._lt(obj1, obj2); - } - } - ); - - // Comparison operator <= - ul4.LEAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return ul4._le(obj1, obj2); - } - } - ); - - // Comparison operator > - ul4.GTAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return ul4._gt(obj1, obj2); - } - } - ); - - // Comparison operator >= - ul4.GEAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - return ul4._ge(obj1, obj2); - } - } - ); - - // Containment test: string in string, obj in list, key in dict, value in rgb - ul4.ContainsAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj, container) - { - if (typeof(obj) === "string" && typeof(container) === "string") - { - return container.indexOf(obj) !== -1; - } - else if (ul4._islist(container)) - { - return container.indexOf(obj) !== -1; - } - else if (container && typeof(container.__contains__) === "function") // test this before the generic object test - return container.__contains__(obj); - else if (ul4._ismap(container) || ul4._isset(container)) - return container.has(obj); - else if (ul4._isobject(container)) - { - for (var key in container) - { - if (key === obj) - return true; - } - return false; - } - else if (ul4._iscolor(container)) - { - return container._r === obj || container._g === obj || container._b === obj || container._a === obj; - } - throw ul4.TypeError.create("in", ul4._type(container) + " object is not iterable"); - } - } - ); - - // Inverted containment test - ul4.NotContainsAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj, container) - { - return !ul4.ContainsAST._do(obj, container); - } - } - ); - - // Addition: num + num, string + string - ul4.AddAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj1 && typeof(obj1.__add__) === "function") - return obj1.__add__(obj2); - else if (obj2 && typeof(obj2.__radd__) === "function") - return obj2.__radd__(obj1); - if (obj1 === null || obj2 === null) - throw ul4.TypeError.create("+", ul4._type(this.obj1) + " + " + ul4._type(this.obj2) + " is not supported"); - if (ul4._islist(obj1) && ul4._islist(obj2)) - { - var result = []; - ul4._append(result, obj1); - ul4._append(result, obj2); - return result; - } - else - return obj1 + obj2; - }, - _ido: function _ido(obj1, obj2) - { - if (ul4._islist(obj1) && ul4._islist(obj2)) - { - ul4._append(obj1, obj2); - return obj1; - } - else - return this._do(obj1, obj2); - } - } - ); - - // Substraction: num - num - ul4.SubAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj1 && typeof(obj1.__sub__) === "function") - return obj1.__sub__(obj2); - else if (obj2 && typeof(obj2.__rsub__) === "function") - return obj2.__rsub__(obj1); - else if (ul4._isdate(obj1) && ul4._isdate(obj2)) - return this._date_sub(obj1, obj2); - if (obj1 === null || obj2 === null) - throw ul4.TypeError.create("-", ul4._type(this.obj1) + " - " + ul4._type(this.obj2) + " is not supported"); - return obj1 - obj2; - }, - _date_sub: function _date_sub(obj1, obj2) - { - var swap = (obj2 > obj1); - - if (swap) - { - var t = obj1; - obj1 = obj2; - obj2 = t; - } - // From now on obj1 is > than obj2 - - var year1 = obj1.getFullYear(); - var yearday1 = ul4._yearday(obj1); - var year2 = obj2.getFullYear(); - var yearday2 = ul4._yearday(obj2); - - var diffdays = 0; - - while (year1 > year2) - { - diffdays += ul4._yearday(ul4._date(year2, 12, 31)); - ++year2; - } - diffdays += yearday1 - yearday2; - - var hours1 = obj1.getHours(); - var minutes1 = obj1.getMinutes(); - var seconds1 = obj1.getSeconds(); - var hours2 = obj2.getHours(); - var minutes2 = obj2.getMinutes(); - var seconds2 = obj2.getSeconds(); - - var diffseconds = (seconds1 - seconds2) + 60 * ((minutes1 - minutes2) + 60 * (hours1 - hours2)); - - var diffmilliseconds = obj1.getMilliseconds() - obj2.getMilliseconds(); - - if (swap) - { - diffdays = -diffdays; - diffseconds = -diffseconds; - diffmilliseconds = -diffmilliseconds; - } - return ul4.TimeDelta.create(diffdays, diffseconds, 1000*diffmilliseconds); - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Multiplication: num * num, int * str, str * int, int * list, list * int - ul4.MulAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj1 && typeof(obj1.__mul__) === "function") - return obj1.__mul__(obj2); - else if (obj2 && typeof(obj2.__rmul__) === "function") - return obj2.__rmul__(obj1); - if (obj1 === null || obj2 === null) - throw ul4.TypeError.create("*", ul4._type(obj1) + " * " + ul4._type(obj2) + " not supported"); - else if (ul4._isint(obj1) || ul4._isbool(obj1)) - { - if (typeof(obj2) === "string") - { - if (obj1 < 0) - throw ul4.ValueError.create("repetition counter must be positive"); - return ul4._str_repeat(obj2, obj1); - } - else if (ul4._islist(obj2)) - { - if (obj1 < 0) - throw ul4.ValueError.create("repetition counter must be positive"); - return ul4._list_repeat(obj2, obj1); - } - } - else if (ul4._isint(obj2) || ul4._isbool(obj2)) - { - if (typeof(obj1) === "string") - { - if (obj2 < 0) - throw ul4.ValueError.create("repetition counter must be positive"); - return ul4._str_repeat(obj1, obj2); - } - else if (ul4._islist(obj1)) - { - if (obj2 < 0) - throw ul4.ValueError.create("repetition counter must be positive"); - return ul4._list_repeat(obj1, obj2); - } - } - return obj1 * obj2; - }, - _ido: function _ido(obj1, obj2) - { - if (ul4._islist(obj1) && ul4._isint(obj2)) - { - if (obj2 > 0) - { - var i = 0; - var targetsize = obj1.length * obj2; - while (obj1.length < targetsize) - obj1.push(obj1[i++]) - } - else - obj1.splice(0, obj1.length); - return obj1; - } - else - return this._do(obj1, obj2); - } - } - ); - - // Truncating division - ul4.FloorDivAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj1 && typeof(obj1.__floordiv__) === "function") - return obj1.__floordiv__(obj2); - else if (obj2 && typeof(obj2.__rfloordiv__) === "function") - return obj2.__rfloordiv__(obj1); - if (obj1 === null || obj2 === null) - throw ul4.TypeError.create("//", ul4._type(obj1) + " // " + ul4._type(obj2) + " not supported"); - return Math.floor(obj1 / obj2); - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // "Real" division - ul4.TrueDivAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj1 && typeof(obj1.__truediv__) === "function") - return obj1.__truediv__(obj2); - else if (obj2 && typeof(obj2.__rtruediv__) === "function") - return obj2.__rtruediv__(obj1); - if (obj1 === null || obj2 === null) - throw ul4.TypeError.create("/", ul4._type(obj1) + " / " + ul4._type(obj2) + " not supported"); - return obj1 / obj2; - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Modulo - ul4.ModAST = ul4._inherit( - ul4.BinaryAST, - { - // (this is non-trivial, because it follows the Python semantic of ``-5 % 2`` being ``1``) - _do: function _do(obj1, obj2) - { - var div = Math.floor(obj1 / obj2); - var mod = obj1 - div * obj2; - - if (mod !== 0 && ((obj2 < 0 && mod > 0) || (obj2 > 0 && mod < 0))) - { - mod += obj2; - --div; - } - return obj1 - div * obj2; - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Bitwise left shift - ul4.ShiftLeftAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj2 === false) - obj2 = 0; - else if (obj2 === true) - obj2 = 1; - if (obj2 < 0) - return ul4.ShiftRightAST._do(obj1, -obj2); - if (obj1 === false) - obj1 = 0; - else if (obj1 === true) - obj1 = 1; - while (obj2--) - obj1 *= 2; - return obj1; - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Bitwise right shift - ul4.ShiftRightAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj2 === false) - obj2 = 0; - else if (obj2 === true) - obj2 = 1; - if (obj2 < 0) - return ul4.ShiftLeftAST._do(obj1, -obj2); - if (obj1 === false) - obj1 = 0; - else if (obj1 === true) - obj1 = 1; - while (obj2--) - obj1 /= 2; - return Math.floor(obj1); - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Bitwise and - ul4.BitAndAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj2 === false) - obj2 = 0; - else if (obj2 === true) - obj2 = 1; - return obj1 & obj2; - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Bitwise exclusive or - ul4.BitXOrAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj2 === false) - obj2 = 0; - else if (obj2 === true) - obj2 = 1; - return obj1 ^ obj2; - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - // Bitwise or - ul4.BitOrAST = ul4._inherit( - ul4.BinaryAST, - { - _do: function _do(obj1, obj2) - { - if (obj2 === false) - obj2 = 0; - else if (obj2 === true) - obj2 = 1; - return obj1 | obj2; - }, - _ido: function _ido(obj1, obj2) - { - return this._do(obj1, obj2); - } - } - ); - - ul4.AndAST = ul4._inherit( - ul4.BinaryAST, - { - _eval: function _eval(context) - { - var obj1 = this.obj1._handle_eval(context); - if (!ul4._bool(obj1)) - return obj1; - var obj2 = this.obj2._handle_eval(context); - return obj2; - } - } - ); - - ul4.OrAST = ul4._inherit( - ul4.BinaryAST, - { - _eval: function _eval(context) - { - var obj1 = this.obj1._handle_eval(context); - if (ul4._bool(obj1)) - return obj1; - var obj2 = this.obj2._handle_eval(context); - return obj2; - } - } - ); - - ul4.AttrAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, obj, attrname) - { - var attr = ul4.CodeAST.create.call(this, tag, pos); - attr.obj = obj; - attr.attrname = attrname; - return attr; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["obj", "attrname"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - var obj = this.obj._handle_eval(context); - var result = this._get(obj, this.attrname); - return result; - }, - _eval_set: function _eval_set(context, value) - { - var obj = this.obj._handle_eval(context); - this._set(obj, this.attrname, value); - }, - _eval_modify: function _eval_modify(context, operator, value) - { - var obj = this.obj._handle_eval(context); - this._modify(operator, obj, this.attrname, value); - }, - _get: function _get(object, attrname) - { - if (typeof(object) === "string") - { - switch (attrname) - { - case "count": - return ul4.expose(["sub", "start=", null, "end=", null], function count(sub, start, end){ return ul4._count(object, sub, start, end); }); - case "find": - return ul4.expose(["sub", "start=", null, "end=", null], function find(sub, start, end){ return ul4._find(object, sub, start, end); }); - case "rfind": - return ul4.expose(["sub", "start=", null, "end=", null], function rfind(sub, start, end){ return ul4._rfind(object, sub, start, end); }); - case "replace": - return ul4.expose(["old", "new", "count=", null], function replace(old, new_, count){ return ul4._replace(object, old, new_, count); }); - case "strip": - return ul4.expose(["chars=", null], function strip(chars){ return ul4._strip(object, chars); }); - case "lstrip": - return ul4.expose(["chars=", null], function lstrip(chars){ return ul4._lstrip(object, chars); }); - case "rstrip": - return ul4.expose(["chars=", null], function rstrip(chars){ return ul4._rstrip(object, chars); }); - case "split": - return ul4.expose(["sep=", null, "count=", null], function split(sep, count){ return ul4._split(object, sep, count); }); - case "rsplit": - return ul4.expose(["sep=", null, "count=", null], function rsplit(sep, count){ return ul4._rsplit(object, sep, count); }); - case "splitlines": - return ul4.expose(["keepends=", false], function splitlines(keepends){ return ul4._splitlines(object, keepends); }); - case "lower": - return ul4.expose([], function lower(){ return object.toLowerCase(); }); - case "upper": - return ul4.expose([], function upper(){ return object.toUpperCase(); }); - case "capitalize": - return ul4.expose([], function capitalize(){ return ul4._capitalize(object); }); - case "join": - return ul4.expose(["iterable"], function join(iterable){ return ul4._join(object, iterable); }); - case "startswith": - return ul4.expose(["prefix"], function startswith(prefix){ return ul4._startswith(object, prefix); }); - case "endswith": - return ul4.expose(["suffix"], function endswith(suffix){ return ul4._endswith(object, suffix); }); - default: - return undefined; - } - } - else if (ul4._islist(object)) - { - switch (attrname) - { - case "append": - return ul4.expose(["*items"], function append(items){ return ul4._append(object, items); }); - case "insert": - return ul4.expose(["pos", "*items"], function insert(pos, items){ return ul4._insert(object, pos, items); }); - case "pop": - return ul4.expose(["pos=", -1], function pop(pos){ return ul4._pop(object, pos); }); - case "count": - return ul4.expose(["sub", "start=", null, "end=", null], function count(sub, start, end){ return ul4._count(object, sub, start, end); }); - case "find": - return ul4.expose(["sub", "start=", null, "end=", null], function find(sub, start, end){ return ul4._find(object, sub, start, end); }); - case "rfind": - return ul4.expose(["sub", "start=", null, "end=", null], function rfind(sub, start, end){ return ul4._rfind(object, sub, start, end); }); - default: - return undefined; - } - } - else if (ul4._isdate(object)) - { - switch (attrname) - { - case "weekday": - return ul4.expose([], function weekday(){ return ul4._weekday(object); }); - case "week": - return ul4.expose(["firstweekday=", null], function week(firstweekday){ return ul4._week(object, firstweekday); }); - case "day": - return ul4.expose([], function day(){ return object.getDate(); }); - case "month": - return ul4.expose([], function month(){ return object.getMonth()+1; }); - case "year": - return ul4.expose([], function year(){ return object.getFullYear(); }); - case "hour": - return ul4.expose([], function hour(){ return object.getHours(); }); - case "minute": - return ul4.expose([], function minute(){ return object.getMinutes(); }); - case "second": - return ul4.expose([], function second(){ return object.getSeconds(); }); - case "microsecond": - return ul4.expose([], function microsecond(){ return object.getMilliseconds() * 1000; }); - case "mimeformat": - return ul4.expose([], function mimeformat(){ return ul4._mimeformat(object); }); - case "isoformat": - return ul4.expose([], function isoformat(){ return ul4._isoformat(object); }); - case "yearday": - return ul4.expose([], function yearday(){ return ul4._yearday(object); }); - default: - return undefined; - } - } - else if (ul4._ismap(object)) - { - switch (attrname) - { - case "get": - return ul4.expose(["key", "default=", null], function get(key, default_){ return ul4._get(object, key, default_); }); - case "items": - return ul4.expose([], function items(){ return ul4._items(object); }); - case "values": - return ul4.expose([], function values(){ return ul4._values(object); }); - case "update": - return ul4.expose(["*other", "**kwargs"], function update(other, kwargs){ return ul4._update(object, other, kwargs); }); - case "clear": - return ul4.expose([], function clear(){ return ul4._clear(object); }); - default: - return object.get(attrname); - } - } - else if (ul4._isset(object)) - { - switch (attrname) - { - case "add": - return ul4.expose(["*items"], function add(items){ for (var i = 0; i < items.length; ++i) { object.add(items[i]); } } ); - case "clear": - return ul4.expose([], function clear(){ return ul4._clear(object); }); - default: - return undefined; - } - } - else if (Object.prototype.toString.call(object) === "[object Object]") - { - switch (attrname) - { - case "get": - return ul4.expose(["key", "default=", null], function get(key, default_){ return ul4._get(object, key, default_); }); - case "items": - return ul4.expose([], function items(){ return ul4._items(object); }); - case "values": - return ul4.expose([], function values(){ return ul4._values(object); }); - case "update": - return ul4.expose(["*other", "**kwargs"], function update(other, kwargs){ return ul4._update(object, other, kwargs); }); - case "clear": - return ul4.expose([], function clear(){ return ul4._clear(object); }); - default: - var result; - if (object && typeof(object.__getattr__) === "function") // test this before the generic object test - result = object.__getattr__(attrname); - else - result = object[attrname]; - if (typeof(result) !== "function") - return result; - var realresult = function() { - return result.apply(object, arguments); - }; - realresult._ul4_name = result._ul4_name || result.name; - realresult._ul4_signature = result._ul4_signature; - realresult._ul4_needsobject = result._ul4_needsobject; - realresult._ul4_needscontext = result._ul4_needscontext; - return realresult; - } - } - throw ul4.TypeError.create("get", ul4._type(object) + " object has no readable attributes"); - }, - _set: function _set(object, attrname, value) - { - if (typeof(object) === "object" && typeof(object.__setattr__) === "function") - object.__setattr__(attrname, value); - else if (ul4._ismap(object)) - object.set(attrname, value) - else if (ul4._isobject(object)) - object[attrname] = value; - else - throw ul4.TypeError.create("set", ul4._type(object) + " object has no writable attributes"); - }, - _modify: function _modify(operator, object, attrname, value) - { - var oldvalue = this._get(object, attrname); - var newvalue = operator._ido(oldvalue, value); - this._set(object, attrname, newvalue); - } - } - ); - - ul4.CallAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, obj, args) - { - var call = ul4.CodeAST.create.call(this, tag, pos); - call.obj = obj; - call.args = args; - return call; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["obj", "args"]), - _repr: function _repr(out) - { - out.push(""); - }, - _makeargs: function _makeargs(context) - { - var args = [], kwargs = {}; - for (var i = 0; i < this.args.length; ++i) - this.args[i]._handle_eval_call(context, args, kwargs); - return {args: args, kwargs: kwargs}; - }, - _handle_eval: function _handle_eval(context) - { - try - { - return this._eval(context); - } - catch (exc) - { - exc = ul4.LocationError.create(this, exc); - throw exc; - } - }, - _eval: function _eval(context) - { - var obj = this.obj._handle_eval(context); - var args = this._makeargs(context); - var result = ul4._call(context, obj, args.args, args.kwargs); - return result; - } - } - ); - - ul4.RenderAST = ul4._inherit( - ul4.CallAST, - { - create: function create(tag, pos, obj, args) - { - var render = ul4.CallAST.create.call(this, tag, pos, obj, args); - render.indent = null; - return render; - }, - _ul4onattrs: ul4.CallAST._ul4onattrs.concat(["indent"]), - _repr: function _repr(out) - { - out.push(""); - }, - _str: function _str(out) - { - out.push("render "); - out.push(this.tag.source.substring(this.pos.start, this.pos.stop).replace(/\r?\n/g, ' ')); - if (this.indent !== null) - { - out.push(" with indent "); - out.push(ul4._repr(this.indent._text())); - } - }, - _handle_eval: function _handle_eval(context) - { - var localcontext = context.withindent(this.indent !== null ? this.indent._text() : null); - var obj = this.obj._handle_eval(localcontext); - var args = this._makeargs(localcontext); - - try - { - var result = ul4._callrender(localcontext, obj, args.args, args.kwargs); - return result; - } - catch (exc) - { - exc = ul4.LocationError.create(this, exc); - throw exc; - } - } - } - ); - - // Slice object - ul4.slice = ul4._inherit( - ul4.Proto, - { - create: function create(start, stop) - { - var slice = ul4._clone(this); - slice.start = start; - slice.stop = stop; - return slice; - }, - __repr__: function __repr__() - { - return "slice(" + ul4._repr(this.start) + ", " + ul4._repr(this.stop) + ")"; - } - } - ); - - - // List/String slice - ul4.SliceAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, index1, index2) - { - var slice = ul4.CodeAST.create.call(this, tag, pos); - slice.index1 = index1; - slice.index2 = index2; - return slice; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["index1", "index2"]), - _repr: function _repr(out) - { - out.push(""); - }, - _eval: function _eval(context) - { - var index1 = this.index1 !== null ? this.index1._handle_eval(context) : null; - var index2 = this.index2 !== null ? this.index2._handle_eval(context) : null; - return ul4.slice.create(index1, index2); - } - } - ); - - - ul4.SetVarAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos, lvalue, value) - { - var changevar = ul4.CodeAST.create.call(this, tag, pos); - changevar.lvalue = lvalue; - changevar.value = value; - return changevar; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["lvalue", "value"]), - _repr: function _repr(out) - { - out.push("<"); - out.push(this.typename); - out.push(" lvalue="); - out.push(ul4._repr(this.lvalue)); - out.push(" value="); - this.value._repr(out); - out.push(">"); - }, - _eval: function _eval(context) - { - var value = this.value._handle_eval(context); - var items = ul4._unpackvar(this.lvalue, value); - for (var i = 0; i < items.length; ++i) - { - var item = items[i]; - item[0]._handle_eval_set(context, item[1]); - } - } - } - ); - - ul4.ModifyVarAST = ul4._inherit( - ul4.SetVarAST, - { - _eval: function _eval(context) - { - var value = this.value._handle_eval(context); - var items = ul4._unpackvar(this.lvalue, value); - for (var i = 0; i < items.length; ++i) - { - var item = items[i]; - item[0]._handle_eval_modify(context, this._operator, item[1]); - } - } - } - ); - - ul4.AddVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.AddAST }); - - ul4.SubVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.SubAST }); - - ul4.MulVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.MulAST }); - - ul4.TrueDivVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.TrueDivAST }); - - ul4.FloorDivVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.FloorDivAST }); - - ul4.ModVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.ModAST }); - - ul4.ShiftLeftVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.ShiftLeftAST }); - - ul4.ShiftRightVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.ShiftRightAST }); - - ul4.BitAndVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.BitAndAST }); - - ul4.BitXOrVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.BitXOrAST }); - - ul4.BitOrVarAST = ul4._inherit(ul4.ModifyVarAST, { _operator: ul4.BitOrAST }); - - ul4.BlockAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos) - { - var block = ul4.CodeAST.create.call(this, tag, pos); - block.endtag = null; - block.content = []; - return block; - }, - _ul4onattrs: ul4.CodeAST._ul4onattrs.concat(["endtag", "content"]), - _eval: function _eval(context) - { - for (var i = 0; i < this.content.length; ++i) - this.content[i]._handle_eval(context); - }, - _str: function _str(out) - { - if (this.content.length) - { - for (var i = 0; i < this.content.length; ++i) - { - this.content[i]._str(out); - out.push(0); - } - } - else - { - out.push("pass"); - out.push(0); - } - } - } - ); - - ul4.ForBlockAST = ul4._inherit( - ul4.BlockAST, - { - create: function create(tag, pos, varname, container) - { - var for_ = ul4.BlockAST.create.call(this, tag, pos); - for_.varname = varname; - for_.container = container; - return for_; - }, - _ul4onattrs: ul4.BlockAST._ul4onattrs.concat(["varname", "container"]), - _repr: function _repr(out) - { - out.push(""); - }, - _str_varname: function _str_varname(out, varname) - { - if (ul4._islist(varname)) - { - out.push("("); - for (var i = 0; i < varname.length; ++i) - { - if (i) - out.push(", "); - this._str_varname(out, varname[i]); - } - if (varname.length == 1) - out.push(","); - out.push(")"); - } - else - varname._str(out); - }, - _eval: function _eval(context) - { - var container = this.container._handle_eval(context); - - for (var iter = ul4._iter(container);;) - { - var value = iter.next(); - if (value.done) - break; - var varitems = ul4._unpackvar(this.varname, value.value); - for (var i = 0; i < varitems.length; ++i) - varitems[i][0]._handle_eval_set(context, varitems[i][1]); - try - { - // We can't call _handle_eval() here, as this would in turn call this function again, leading to infinite recursion - // But we don't have to, as wrapping original exception in ``Error`` has already been done by the lower levels - ul4.BlockAST._eval.call(this, context); - } - catch (exc) - { - if (exc === ul4.BreakException) - break; - else if (exc === ul4.ContinueException) - ; - else - throw exc; - } - } - }, - _str: function _str(out) - { - out.push("for "); - this._str_varname(out, this.varname); - out.push(" in "); - this.container._str(out); - out.push(":"); - out.push(+1); - ul4.BlockAST._str.call(this, out); - out.push(-1); - } - } - ); - - ul4.WhileBlockAST = ul4._inherit( - ul4.BlockAST, - { - create: function create(tag, pos, condition) - { - var while_ = ul4.BlockAST.create.call(this, tag, pos); - while_.condition = condition; - return while_; - }, - _ul4onattrs: ul4.BlockAST._ul4onattrs.concat(["condition"]), - _repr: function _repr(out) - { - out.push(""); - }, - _str: function _str(out) - { - out.push("while "), - this.container._repr(out); - out.push(":"); - out.push(+1); - ul4.BlockAST._str.call(this, out); - out.push(-1); - }, - _eval: function _eval(context) - { - while (true) - { - var cond = this.condition._handle_eval(context); - if (!ul4._bool(cond)) - break; - try - { - // We can't call _handle_eval() here, as this would in turn call this function again, leading to infinite recursion - // But we don't have to, as wrapping original exception in ``Error`` has already been done by the lower levels - ul4.BlockAST._eval.call(this, context); - } - catch (exc) - { - if (exc === ul4.BreakException) - break; - else if (exc === ul4.ContinueException) - ; - else - throw exc; - } - } - }, - _str: function _str(out) - { - out.push("while "); - ul4.AST._str.call(this, out); - out.push(":"); - out.push(+1); - ul4.BlockAST._str.call(this, out); - out.push(-1); - } - } - ); - - ul4.BreakAST = ul4._inherit( - ul4.CodeAST, - { - _eval: function _eval(context) - { - throw ul4.BreakException; - }, - _str: function _str(out) - { - out.push("break"); - out.push(0); - }, - _repr: function _repr(out) - { - out.push(""); - } - } - ); - - ul4.ContinueAST = ul4._inherit( - ul4.CodeAST, - { - _eval: function _eval(context) - { - throw ul4.ContinueException; - }, - _str: function _str(out) - { - out.push("continue"); - out.push(0); - }, - _repr: function _repr(out) - { - out.push(""); - } - } - ); - - ul4.CondBlockAST = ul4._inherit( - ul4.BlockAST, - { - _eval: function _eval(context) - { - for (var i = 0; i < this.content.length; ++i) - { - var block = this.content[i]; - var execute = block._execute(context); - if (execute) - { - block._handle_eval(context); - break; - } - } - } - } - ); - - ul4.ConditionalBlockAST = ul4._inherit( - ul4.BlockAST, - { - create: function create(tag, pos, condition) - { - var block = ul4.BlockAST.create.call(this, tag, pos); - block.condition = condition; - return block; - }, - _ul4onattrs: ul4.BlockAST._ul4onattrs.concat(["condition"]), - _repr: function _repr(out) - { - out.push("<"); - out.push(this.typename); - out.push(" condition="); - this.condition._repr(out); - out.push(">"); - }, - _str: function _str(out) - { - out.push(this._strname); - out.push(" "); - this.condition._str(out); - out.push(":"); - out.push(+1); - ul4.BlockAST._str.call(this, out); - out.push(-1); - }, - _execute: function _execute(context) - { - var cond = this.condition._handle_eval(context); - var result = ul4._bool(cond); - return result; - } - } - ); - - ul4.IfBlockAST = ul4._inherit(ul4.ConditionalBlockAST, {_strname: "if"}); - - ul4.ElIfBlockAST = ul4._inherit(ul4.ConditionalBlockAST, {_strname: "else if"}); - - ul4.ElseBlockAST = ul4._inherit( - ul4.BlockAST, - { - _repr: function _repr(out) - { - out.push(""); - }, - _str: function _str(out) - { - out.push("else:"), - out.push(+1); - ul4.BlockAST._str.call(this, out); - out.push(-1); - }, - _execute: function _execute(context) - { - return true; - }, - _str: function _str(out) - { - out.push("else:"); - out.push(+1); - ul4.BlockAST._str.call(this, out); - out.push(-1); - } - } - ); - - ul4.Template = ul4._inherit( - ul4.BlockAST, - { - create: function create(tag, pos, source, name, whitespace, startdelim, enddelim, signature) - { - var template = ul4.BlockAST.create.call(this, tag, pos); - template.source = source; - template.name = name; - template.whitespace = whitespace; - template.startdelim = startdelim; - template.enddelim = enddelim; - template.docpos = null; - template.signature = signature; - template._jsfunction = null; - template._asts = null; - template._ul4_callsignature = signature; - template._ul4_rendersignature = signature; - template.parenttemplate = null; - return template; - }, - ul4ondump: function ul4ondump(encoder) - { - var signature; - encoder.dump(ul4.version); - encoder.dump(this.name); - encoder.dump(this.source); - encoder.dump(this.whitespace); - encoder.dump(this.startdelim); - encoder.dump(this.enddelim); - encoder.dump(this.docpos); - encoder.dump(this.parenttemplate); - if (this.signature === null || ul4.SignatureAST.isprotoof(this.signature)) - signature = this.signature; - else - { - signature = []; - for (var i = 0; i < this.signature.args.length; ++i) - { - var arg = this.signature.args[i]; - if (typeof(arg.defaultValue) === "undefined") - signature.push(arg.name); - else - signature.push(arg.name+"=", arg.defaultValue); - } - if (this.signature.remargs !== null) - signature.push("*" + this.signature.remargs); - if (this.signature.remkwargs !== null) - signature.push("**" + this.signature.remkwargs); - } - encoder.dump(signature); - ul4.BlockAST.ul4ondump.call(this, encoder); - }, - ul4onload: function ul4onload(decoder) - { - var version = decoder.load(); - var signature; - - if (version === null) - throw ul4.ValueError.create("UL4ON doesn't support templates in 'source' format in Javascript implementation"); - - if (version !== ul4.version) - throw ul4.ValueError.create("invalid version, expected " + ul4.version + ", got " + version); - this.name = decoder.load(); - this.source = decoder.load(); - this.whitespace = decoder.load(); - this.startdelim = decoder.load(); - this.enddelim = decoder.load(); - this.docpos = decoder.load(); - this.parenttemplate = decoder.load(); - signature = decoder.load(); - if (ul4._islist(signature)) - signature = ul4.Signature.create.apply(ul4.Signature, signature); - this.signature = signature; - this._ul4_callsignature = signature; - this._ul4_rendersignature = signature; - ul4.BlockAST.ul4onload.call(this, decoder); - }, - loads: function loads(string) - { - return ul4on.loads(string); - }, - _eval: function _eval(context) - { - var signature = null; - if (this.signature !== null) - signature = this.signature._handle_eval(context); - var closure = ul4.TemplateClosure.create(this, signature, context.vars); - context.set(this.name, closure); - }, - _repr: function _repr(out) - { - out.push("") - { - out.push(" enddelim="); - out.push(ul4._repr(this.enddelim)); - } - out.push(">"); - }, - _str: function _str(out) - { - out.push("def "); - out.push(this.name ? this.name : "unnamed"); - out.push(":"); - out.push(+1); - ul4.BlockAST._str.call(this, out); - out.push(-1); - }, - _ul4_callneedsobject: true, - _ul4_callneedscontext: true, - _ul4_renderneedsobject: true, - _ul4_renderneedscontext: true, - _renderbound: function _renderbound(context, vars) - { - var localcontext = context.clone(); - localcontext.vars = vars; - try - { - ul4.BlockAST._eval.call(this, localcontext); - } - catch (exc) - { - if (!ul4.ReturnException.isprotoof(exc)) - throw exc; - } - }, - __render__: function __render__(context, vars) - { - this._renderbound(context, vars); - }, - render: function render(context, vars) - { - this._renderbound(context, vars); - }, - _rendersbound: function _rendersbound(context, vars) - { - var localcontext = context.replaceoutput(); - this._renderbound(localcontext, vars); - return localcontext.getoutput(); - }, - renders: function renders(vars) - { - vars = vars || {}; - var context = ul4.Context.create(); - if (this.signature !== null) - vars = this.signature.bindObject(this.name, [], vars); - return this._rendersbound(context, vars); - }, - doc: function doc() - { - return this.docpos != null ? this.source.substring(this.docpos.start, this.docpos.stop) : null; - }, - __getattr__: function __getattr__(attrname) - { - var self = this; - switch (attrname) - { - case "tag": - return this.tag; - case "endtag": - return this.endtag; - case "content": - return this.content; - case "source": - return this.source; - case "name": - return this.name; - case "whitespace": - return this.whitespace; - case "startdelim": - return this.startdelim; - case "enddelim": - return this.enddelim; - case "doc": - return this.doc(); - case "signature": - return this.signature; - case "parenttemplate": - return this.parenttemplate; - case "render": - return ul4.expose(this.signature, {needscontext: true, needsobject: true}, function render(context, vars){ self._renderbound(context, vars); }); - case "renders": - return ul4.expose(this.signature, {needscontext: true, needsobject: true}, function renders(context, vars){ return self._rendersbound(context, vars); }); - default: - return undefined; - } - }, - _callbound: function _callbound(context, vars) - { - var localcontext = context.clone(); - localcontext.vars = vars; - try - { - ul4.BlockAST._eval.call(this, localcontext); - } - catch (exc) - { - if (ul4.ReturnException.isprotoof(exc)) - return exc.result; - else - throw exc; - } - return null; - }, - call: function call(vars) - { - vars = vars || {}; - var context = ul4.Context.create(); - if (this.signature !== null) - vars = this.signature.bindObject(this.name, [], vars); - return this._callbound(context, vars); - }, - __call__: function __call__(context, vars) - { - return this._callbound(context, vars); - }, - __type__: "ul4.Template" // used by ``istemplate()`` - } - ); - - ul4.SignatureAST = ul4._inherit( - ul4.CodeAST, - { - create: function create(tag, pos) - { - var signature = ul4.CodeAST.create.call(this, tag, pos); - signature.params = []; - return signature; - }, - ul4ondump: function ul4ondump(encoder) - { - ul4.CodeAST.ul4ondump.call(this, encoder); - - var dump = []; - - for (var i = 0; i < this.params.length; ++i) - { - var param = this.params[i]; - if (param[1] === null) - dump.push(param[0]); - else - dump.push(param); - } - encoder.dump(dump); - }, - ul4onload: function ul4onload(decoder) - { - ul4.AST.ul4onload.call(this, decoder); - var dump = decoder.load(); - this.params = []; - for (var i = 0; i < dump.length; ++i) - { - var param = dump[i]; - if (typeof(param) === "string") - this.params.push([param, null]); - else - this.params.push(param); - } - }, - _eval: function _eval(context) - { - var args = []; - for (var i = 0; i < this.params.length; ++i) - { - var param = this.params[i]; - if (param[1] === null) - args.push(param[0]); - else - { - args.push(param[0] + "="); - args.push(param[1]._handle_eval(context)); - } - } - return ul4.Signature.create.apply(ul4.Signature, args); - }, - _repr: function _repr(out) - { - out.push("<"); - out.push(this.typename); - out.push(" params="); - this.params._repr(out); - out.push(">"); - } - } - ); - - ul4.TemplateClosure = ul4._inherit( - ul4.Proto, - { - create: function create(template, signature, vars) - { - var closure = ul4._clone(this); - closure.template = template; - closure.signature = signature; - closure.vars = vars; - closure._ul4_callsignature = signature; - closure._ul4_rendersignature = signature; - // Copy over the required attribute from the template - closure.name = template.name; - closure.tag = template.tag; - closure.endtag = template.endtag; - closure.source = template.source; - closure.startdelim = template.startdelim; - closure.enddelim = template.enddelim; - closure.docpos = template.docpos; - closure.content = template.content; - return closure; - }, - _ul4_callneedsobject: true, - _ul4_callneedscontext: true, - _ul4_renderneedsobject: true, - _ul4_renderneedscontext: true, - __render__: function __render__(context, vars) - { - this.template._renderbound(context, ul4._simpleinherit(this.vars, vars)); - }, - render: function render(context, vars) - { - this.template._renderbound(context, ul4._simpleinherit(this.vars, vars)); - }, - __call__: function __call__(context, vars) - { - return this.template._callbound(context, ul4._simpleinherit(this.vars, vars)); - }, - _renderbound: function _renderbound(context, vars) - { - this.template._renderbound(context, ul4._simpleinherit(this.vars, vars)); - }, - _rendersbound: function _rendersbound(context, vars) - { - return this.template._rendersbound(context, ul4._simpleinherit(this.vars, vars)); - }, - __getattr__: function __getattr__(attrname) - { - var self = this; - switch (attrname) - { - case "render": - return ul4.expose(this.signature, {needscontext: true, needsobject: true}, function render(context, vars){ self._renderbound(context, vars); }); - case "renders": - return ul4.expose(this.signature, {needscontext: true, needsobject: true}, function renders(context, vars){ return self._rendersbound(context, vars); }); - case "signature": - return this.signature; - default: - return this.template.__getattr__(attrname); - } - }, - __type__: "ul4.TemplateClosure" // used by ``istemplate()`` - } - ); - - // Create a color object from the red, green, blue and alpha values ``r``, ``g``, ``b`` and ``b`` - ul4._rgb = function _rgb(r, g, b, a) - { - return this.Color.create(255*r, 255*g, 255*b, 255*a); - }; - - // Convert ``obj`` to a string and escape the characters ``&``, ``<``, ``>``, ``'`` and ``"`` with their XML character/entity reference - ul4._xmlescape = function _xmlescape(obj) - { - obj = ul4._str(obj); - obj = obj.replace(/&/g, "&"); - obj = obj.replace(//g, ">"); - obj = obj.replace(/'/g, "'"); - obj = obj.replace(/"/g, """); - return obj; - }; - - // Convert ``obj`` to a string suitable for output into a CSV file - ul4._csv = function _csv(obj) - { - if (obj === null) - return ""; - else if (typeof(obj) !== "string") - obj = ul4._repr(obj); - if (obj.indexOf(",") !== -1 || obj.indexOf('"') !== -1 || obj.indexOf("\n") !== -1) - obj = '"' + obj.replace(/"/g, '""') + '"'; - return obj; - }; - - // Return a string containing one character with the codepoint ``i`` - ul4._chr = function _chr(i) - { - if (typeof(i) != "number") - throw ul4.TypeError.create("chr()", "chr() requires an int"); - return String.fromCharCode(i); - }; - - // Return the codepoint for the one and only character in the string ``c`` - ul4._ord = function _ord(c) - { - if (typeof(c) != "string" || c.length != 1) - throw ul4.TypeError.create("ord()", "ord() requires a string of length 1"); - return c.charCodeAt(0); - }; - - // Convert an integer to a hexadecimal string - ul4._hex = function _hex(number) - { - if (typeof(number) != "number") - throw ul4.TypeError.create("hex()", "hex() requires an int"); - if (number < 0) - return "-0x" + number.toString(16).substr(1); - else - return "0x" + number.toString(16); - }; - - // Convert an integer to a octal string - ul4._oct = function _oct(number) - { - if (typeof(number) != "number") - throw ul4.TypeError.create("oct()", "oct() requires an int"); - if (number < 0) - return "-0o" + number.toString(8).substr(1); - else - return "0o" + number.toString(8); - }; - - // Convert an integer to a binary string - ul4._bin = function _bin(number) - { - if (typeof(number) != "number") - throw ul4.TypeError.create("bin()", "bin() requires an int"); - if (number < 0) - return "-0b" + number.toString(2).substr(1); - else - return "0b" + number.toString(2); - }; - - // Return the minimum value - ul4._min = function _min(obj) - { - if (obj.length == 0) - throw ul4.ArgumentError.create("min() requires at least 1 argument, 0 given"); - else if (obj.length == 1) - obj = obj[0]; - var iter = ul4._iter(obj); - var result; - var first = true; - while (true) - { - var item = iter.next(); - if (item.done) - { - if (first) - throw ul4.ValueError.create("min() argument is an empty sequence!"); - return result; - } - if (first || (item.value < result)) - result = item.value; - first = false; - } - }; - - // Return the maximum value - ul4._max = function _max(obj) - { - if (obj.length == 0) - throw ul4.ArgumentError.create("max() requires at least 1 argument, 0 given"); - else if (obj.length == 1) - obj = obj[0]; - var iter = ul4._iter(obj); - var result; - var first = true; - while (true) - { - var item = iter.next(); - if (item.done) - { - if (first) - throw ul4.ValueError.create("max() argument is an empty sequence!"); - return result; - } - if (first || (item.value > result)) - result = item.value; - first = false; - } - }; - - // Return the of the values from the iterable starting with ``start`` (default ``0``) - ul4._sum = function _sum(iterable, start) - { - if (typeof(start) === "undefined") - start = 0; - - for (var iter = ul4._iter(iterable);;) - { - var item = iter.next(); - if (item.done) - break; - start += item.value; - } - return start; - }; - - // Return the first value produced by iterating through ``iterable`` (defaulting to ``defaultValue`` if the iterator is empty) - ul4._first = function _first(iterable, defaultValue) - { - if (typeof(defaultValue) === "undefined") - defaultValue = null; - - var item = ul4._iter(iterable).next(); - return item.done ? defaultValue : item.value; - }; - - // Return the last value produced by iterating through ``iterable`` (defaulting to ``defaultValue`` if the iterator is empty) - ul4._last = function _last(iterable, defaultValue) - { - if (typeof(defaultValue) === "undefined") - defaultValue = null; - - var value = defaultValue; - - for (var iter = ul4._iter(iterable);;) - { - var item = iter.next(); - if (item.done) - break; - value = item.value; - } - return value; - }; - - // Return a sorted version of ``iterable`` - ul4._sorted = function _sorted(context, iterable, key, reverse) - { - var cmp; - if (key === null) - { - // FIXME: stability - if (reverse) - { - cmp = function cmp(a, b) - { - return -ul4._cmp("<=>", a, b); - } - } - else - { - cmp = function cmp(a, b) - { - return ul4._cmp("<=>", a, b); - } - } - var result = ul4._list(iterable); - result.sort(cmp); - return result; - } - else - { - var sort = []; - - for (var i = 0, iter = ul4._iter(iterable);;++i) - { - var item = iter.next(); - if (item.done) - break; - var keyvalue = ul4._call(context, key, [item.value], {}); - sort.push([keyvalue, i, item.value]); - } - cmp = function cmp(s1, s2) - { - var res = ul4._cmp("<=>", s1[0], s2[0]); - if (res) - return reverse ? -res : res; - res = ul4._cmp(s1[1], s2[1]); - return reverse ? -res : res; - } - - sort.sort(cmp); - - var result = []; - for (var i = 0; i < sort.length; ++i) - { - result.push(sort[i][2]); - } - return result; - } - }; - - // Return a iterable object iterating from ``start`` upto (but not including) ``stop`` with a step size of ``step`` - ul4._range = function _range(args) - { - var start, stop, step; - if (args.length < 1) - throw ul4.ArgumentError.create("required range() argument missing"); - else if (args.length > 3) - throw ul4.ArgumentError.create("range() expects at most 3 positional arguments, " + args.length + " given"); - else if (args.length == 1) - { - start = 0; - stop = args[0]; - step = 1; - } - else if (args.length == 2) - { - start = args[0]; - stop = args[1]; - step = 1; - } - else if (args.length == 3) - { - start = args[0]; - stop = args[1]; - step = args[2]; - } - var lower, higher; - if (step === 0) - throw ul4.ValueError.create("range() requires a step argument != 0"); - else if (step > 0) - { - lower = start; - heigher = stop; - } - else - { - lower = stop; - heigher = start; - } - var length = (lower < heigher) ? Math.floor((heigher - lower - 1)/Math.abs(step)) + 1 : 0; - - return { - index: 0, - next: function() - { - if (this.index >= length) - return {done: true}; - return {value: start + (this.index++) * step, done: false}; - } - }; - }; - - // Return a iterable object returning a slice from the argument - ul4._slice = function _slice(args) - { - var iterable, start, stop, step; - if (args.length < 2) - throw ul4.ArgumentError.create("required slice() argument missing"); - else if (args.length > 4) - throw ul4.ArgumentError.create("slice() expects at most 4 positional arguments, " + args.length + " given"); - else if (args.length == 2) - { - iterable = args[0]; - start = 0; - stop = args[1]; - step = 1; - } - else if (args.length == 3) - { - iterable = args[0]; - start = args[1] !== null ? args[1] : 0; - stop = args[2]; - step = 1; - } - else if (args.length == 4) - { - iterable = args[0]; - start = args[1] !== null ? args[1] : 0; - stop = args[2]; - step = args[3] !== null ? args[3] : 1; - } - if (start < 0) - throw ul4.ValueError.create("slice() requires a start argument >= 0"); - if (stop < 0) - throw ul4.ValueError.create("slice() requires a stop argument >= 0"); - if (step <= 0) - throw ul4.ValueError.create("slice() requires a step argument > 0"); - - var next = start, count = 0; - var iter = ul4._iter(iterable); - return { - next: function() { - var result; - while (count < next) - { - result = iter.next(); - if (result.done) - return result; - ++count; - } - if (stop !== null && count >= stop) - return {done: true}; - result = iter.next(); - if (result.done) - return result; - ++count; - next += step; - if (stop !== null && next > stop) - next = stop; - return result; - } - }; - }; - - // ``%`` escape unsafe characters in the string ``string`` - ul4._urlquote = function _urlquote(string) - { - return encodeURIComponent(string); - }; - - // The inverse function of ``urlquote`` - ul4._urlunquote = function _urlunquote(string) - { - return decodeURIComponent(string); - }; - - // Return a reverse iterator over ``sequence`` - ul4._reversed = function _reversed(sequence) - { - if (typeof(sequence) != "string" && !ul4._islist(sequence)) // We don't have to materialize strings or lists - sequence = ul4._list(sequence); - return { - index: sequence.length-1, - next: function() { - return this.index >= 0 ? {value: sequence[this.index--], done: false} : {done: true}; - } - }; - }; - - // Returns a random number in the interval ``[0;1[`` - ul4._random = function _random() - { - return Math.random(); - }; - - // Return a randomly select item from ``range(start, stop, step)`` - ul4._randrange = function _randrange(args) - { - var start, stop, step; - if (args.length < 1) - throw ul4.ArgumentError.create("required randrange() argument missing"); - else if (args.length > 3) - throw ul4.ArgumentError.create("randrange() expects at most 3 positional arguments, " + args.length + " given"); - else if (args.length == 1) - { - start = 0; - stop = args[0]; - step = 1; - } - else if (args.length == 2) - { - start = args[0]; - stop = args[1]; - step = 1; - } - else if (args.length == 3) - { - start = args[0]; - stop = args[1]; - step = args[2]; - } - var width = stop-start; - - var value = Math.random(); - - var n; - if (step > 0) - n = Math.floor((width + step - 1) / step); - else if (step < 0) - n = Math.floor((width + step + 1) / step); - else - throw ul4.ValueError.create("randrange() requires a step argument != 0"); - return start + step*Math.floor(value * n); - }; - - // Return a random item/char from the list/string ``sequence`` - ul4._randchoice = function _randchoice(sequence) - { - var iscolor = ul4._iscolor(sequence); - if (typeof(sequence) !== "string" && !ul4._islist(sequence) && !iscolor) - throw ul4.TypeError.create("randchoice() requires a string or list"); - if (iscolor) - sequence = ul4._list(sequence); - return sequence[Math.floor(Math.random() * sequence.length)]; - }; - - // Round a number ``x`` to ``digits`` decimal places (may be negative) - ul4._round = function _round(x, digits) - { - if (typeof(digits) === "undefined") - digits = 0; - if (digits) - { - var threshhold = Math.pow(10, digits); - return Math.round(x*threshhold)/threshhold; - } - else - return Math.round(x); - }; - - // Return a hex-encode MD5 hash of the argument - // This uses the m55 function from https://github.com/blueimp/JavaScript-MD5 - ul4._md5 = function _md5(string) - { - return md5(string); - }; - - // Return an iterator over ``[index, item]`` lists from the iterable object ``iterable``. ``index`` starts at ``start`` (defaulting to 0) - ul4._enumerate = function _enumerate(iterable, start) - { - if (typeof(start) === "undefined") - start = 0; - - return { - iter: ul4._iter(iterable), - index: start, - next: function() { - var item = this.iter.next(); - return item.done ? item : {value: [this.index++, item.value], done: false}; - } - }; - }; - - // Return an iterator over ``[isfirst, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, false otherwise) - ul4._isfirst = function _isfirst(iterable) - { - var iter = ul4._iter(iterable); - var isfirst = true; - return { - next: function() { - var item = iter.next(); - var result = item.done ? item : {value: [isfirst, item.value], done: false}; - isfirst = false; - return result; - } - }; - }; - - // Return an iterator over ``[islast, item]`` lists from the iterable object ``iterable`` (``islast`` is true for the last item, false otherwise) - ul4._islast = function _islast(iterable) - { - var iter = ul4._iter(iterable); - var lastitem = iter.next(); - return { - next: function() { - if (lastitem.done) - return lastitem; - var item = iter.next(); - var result = {value: [item.done, lastitem.value], done: false}; - lastitem = item; - return result; - } - }; - }; - - // Return an iterator over ``[isfirst, islast, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, ``islast`` is true for the last item. Both are false otherwise) - ul4._isfirstlast = function _isfirstlast(iterable) - { - var iter = ul4._iter(iterable); - var isfirst = true; - var lastitem = iter.next(); - return { - next: function() { - if (lastitem.done) - return lastitem; - var item = iter.next(); - var result = {value: [isfirst, item.done, lastitem.value], done: false}; - lastitem = item; - isfirst = false; - return result; - } - }; - }; - - // Return an iterator over ``[index, isfirst, islast, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, ``islast`` is true for the last item. Both are false otherwise) - ul4._enumfl = function _enumfl(iterable, start) - { - var iter = ul4._iter(iterable); - var i = start; - var isfirst = true; - var lastitem = iter.next(); - return { - next: function() { - if (lastitem.done) - return lastitem; - var item = iter.next(); - var result = {value: [i++, isfirst, item.done, lastitem.value], done: false}; - lastitem = item; - isfirst = false; - return result; - } - }; - }; - - // Return an iterator over lists, where the i'th list consists of all i'th items from the arguments (terminating when the shortest argument ends) - ul4._zip = function _zip(iterables) - { - var result; - if (iterables.length) - { - var iters = []; - for (var i = 0; i < iterables.length; ++i) - iters.push(ul4._iter(iterables[i])); - - return { - next: function() { - var items = []; - for (var i = 0; i < iters.length; ++i) - { - var item = iters[i].next(); - if (item.done) - return item; - items.push(item.value); - } - return {value: items, done: false}; - } - }; - } - else - { - return { - next: function() { - return {done: true}; - } - }; - } - }; - - // Return the absolute value for the number ``number`` - ul4._abs = function _abs(number) - { - if (number !== null && typeof(number.__abs__) === "function") - return number.__abs__(); - return Math.abs(number); - }; - - // Return a ``Date`` object from the arguments passed in - ul4._date = function _date(year, month, day, hour, minute, second, microsecond) - { - if (typeof(hour) === "undefined") - hour = 0; - - if (typeof(minute) === "undefined") - minute = 0; - - if (typeof(second) === "undefined") - second = 0; - - if (typeof(microsecond) === "undefined") - microsecond = 0; - - return new Date(year, month-1, day, hour, minute, second, microsecond/1000); - }; - - // Return a ``TimeDelta`` object from the arguments passed in - ul4._timedelta = function _timedelta(days, seconds, microseconds) - { - return this.TimeDelta.create(days, seconds, microseconds); - }; - - // Return a ``MonthDelta`` object from the arguments passed in - ul4._monthdelta = function _monthdelta(months) - { - return this.MonthDelta.create(months); - }; - - // Return a ``Color`` object from the hue, luminescence, saturation and alpha values ``h``, ``l``, ``s`` and ``a`` (i.e. using the HLS color model) - ul4._hls = function _hls(h, l, s, a) - { - var _v = function(m1, m2, hue) - { - hue = hue % 1.0; - if (hue < 1/6) - return m1 + (m2-m1)*hue*6.0; - else if (hue < 0.5) - return m2; - else if (hue < 2/3) - return m1 + (m2-m1)*(2/3-hue)*6.0; - return m1; - }; - - var m1, m2; - if (typeof(a) === "undefined") - a = 1; - if (s === 0.0) - return ul4._rgb(l, l, l, a); - if (l <= 0.5) - m2 = l * (1.0+s); - else - m2 = l+s-(l*s); - m1 = 2.0*l - m2; - return ul4._rgb(_v(m1, m2, h+1/3), _v(m1, m2, h), _v(m1, m2, h-1/3), a); - }; - - // Return a ``Color`` object from the hue, saturation, value and alpha values ``h``, ``s``, ``v`` and ``a`` (i.e. using the HSV color model) - ul4._hsv = function _hsv(h, s, v, a) - { - if (s === 0.0) - return ul4._rgb(v, v, v, a); - var i = Math.floor(h*6.0); - var f = (h*6.0) - i; - var p = v*(1.0 - s); - var q = v*(1.0 - s*f); - var t = v*(1.0 - s*(1.0-f)); - switch (i%6) - { - case 0: - return ul4._rgb(v, t, p, a); - case 1: - return ul4._rgb(q, v, p, a); - case 2: - return ul4._rgb(p, v, t, a); - case 3: - return ul4._rgb(p, q, v, a); - case 4: - return ul4._rgb(t, p, v, a); - case 5: - return ul4._rgb(v, p, q, a); - } - }; - - // Return the item with the key ``key`` from the dict ``container``. If ``container`` doesn't have this key, return ``defaultvalue`` - ul4._get = function _get(container, key, defaultvalue) - { - if (ul4._ismap(container)) - { - if (container.has(key)) - return container.get(key); - return defaultvalue; - } - else if (ul4._isobject(container)) - { - var result = container[key]; - if (typeof(result) === "undefined") - return defaultvalue; - return result; - } - throw ul4.TypeError.create("get()", "get() requires a dict"); - }; - - // Return a ``Date`` object for the current time - ul4.now = function now() - { - return new Date(); - }; - - // Return a ``Date`` object for the current time in UTC - ul4.utcnow = function utcnow() - { - var now = new Date(); - // FIXME: The timezone is wrong for the new ``Date`` object. - return new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(), now.getUTCMilliseconds()); - }; - - ul4.functions = { - repr: ul4.expose(["obj"], {name: "repr"}, ul4._repr), - ascii: ul4.expose(["obj"], {name: "ascii"}, ul4._ascii), - str: ul4.expose(["obj=", ""], {name: "str"}, ul4._str), - int: ul4.expose(["obj=", 0, "base=", null], {name: "int"}, ul4._int), - float: ul4.expose(["obj=", 0.0], {name: "float"}, ul4._float), - list: ul4.expose(["iterable=", []], {name: "list"}, ul4._list), - set: ul4.expose(["iterable=", []], {name: "set"}, ul4._set), - bool: ul4.expose(["obj=", false], {name: "bool"}, ul4._bool), - len: ul4.expose(["sequence"], {name: "len"}, ul4._len), - type: ul4.expose(["obj"], {name: "type"}, ul4._type), - format: ul4.expose(["obj", "fmt", "lang=", null], {name: "format"}, ul4._format), - any: ul4.expose(["iterable"], {name: "any"}, ul4._any), - all: ul4.expose(["iterable"], {name: "all"}, ul4._all), - zip: ul4.expose(["*iterables"], {name: "zip"}, ul4._zip), - isundefined: ul4.expose(["obj"], {name: "isundefined"}, ul4._isundefined), - isdefined: ul4.expose(["obj"], {name: "isdefined"}, ul4._isdefined), - isnone: ul4.expose(["obj"], {name: "isnone"}, ul4._isnone), - isbool: ul4.expose(["obj"], {name: "isbool"}, ul4._isbool), - isint: ul4.expose(["obj"], {name: "isint"}, ul4._isint), - isfloat: ul4.expose(["obj"], {name: "isfloat"}, ul4._isfloat), - isstr: ul4.expose(["obj"], {name: "isstr"}, ul4._isstr), - isdate: ul4.expose(["obj"], {name: "isdate"}, ul4._isdate), - iscolor: ul4.expose(["obj"], {name: "iscolor"}, ul4._iscolor), - istimedelta: ul4.expose(["obj"], {name: "istimedelta"}, ul4._istimedelta), - ismonthdelta: ul4.expose(["obj"], {name: "ismonthdelta"}, ul4._ismonthdelta), - istemplate: ul4.expose(["obj"], {name: "istemplate"}, ul4._istemplate), - isfunction: ul4.expose(["obj"], {name: "isfunction"}, ul4._isfunction), - islist: ul4.expose(["obj"], {name: "islist"}, ul4._islist), - isset: ul4.expose(["obj"], {name: "isset"}, ul4on._haveset ? ul4._isset : ul4._isul4set), - isdict: ul4.expose(["obj"], {name: "isdict"}, ul4._isdict), - isexception: ul4.expose(["obj"], {name: "isexception"}, ul4._isexception), - asjson: ul4.expose(["obj"], {name: "asjson"}, ul4._asjson), - fromjson: ul4.expose(["string"], {name: "fromjson"}, ul4._fromjson), - asul4on: ul4.expose(["obj"], {name: "asul4on"}, ul4._asul4on), - fromul4on: ul4.expose(["string"], {name: "fromul4on"}, ul4._fromul4on), - now: ul4.expose([], ul4.now), - utcnow: ul4.expose([], ul4.utcnow), - enumerate: ul4.expose(["iterable", "start=", 0], {name: "enumerate"}, ul4._enumerate), - isfirst: ul4.expose(["iterable"], {name: "isfirst"}, ul4._isfirst), - islast: ul4.expose(["iterable"], {name: "islast"}, ul4._islast), - isfirstlast: ul4.expose(["iterable"], {name: "isfirstlast"}, ul4._isfirstlast), - enumfl: ul4.expose(["iterable", "start=", 0], {name: "enumfl"}, ul4._enumfl), - abs: ul4.expose(["number"], {name: "abs"}, ul4._abs), - date: ul4.expose(["year", "month", "day", "hour=", 0, "minute=", 0, "second=", 0, "microsecond=", 0], {name: "date"}, ul4._date), - timedelta: ul4.expose(["days=", 0, "seconds=", 0, "microseconds=", 0], {name: "timedelta"}, ul4._timedelta), - monthdelta: ul4.expose(["months=", 0], {name: "monthdelta"}, ul4._monthdelta), - rgb: ul4.expose(["r", "g", "b", "a=", 1.0], {name: "rgb"}, ul4._rgb), - hls: ul4.expose(["h", "l", "s", "a=", 1.0], {name: "hls"}, ul4._hls), - hsv: ul4.expose(["h", "s", "v", "a=", 1.0], {name: "hsv"}, ul4._hsv), - xmlescape: ul4.expose(["obj"], {name: "xmlescape"}, ul4._xmlescape), - csv: ul4.expose(["obj"], {name: "csv"}, ul4._csv), - chr: ul4.expose(["i"], {name: "chr"}, ul4._chr), - ord: ul4.expose(["c"], {name: "ord"}, ul4._ord), - hex: ul4.expose(["number"], {name: "hex"}, ul4._hex), - oct: ul4.expose(["number"], {name: "oct"}, ul4._oct), - bin: ul4.expose(["number"], {name: "bin"}, ul4._bin), - min: ul4.expose(["*obj"], {name: "min"}, ul4._min), - max: ul4.expose(["*obj"], {name: "max"}, ul4._max), - sum: ul4.expose(["iterable", "start=", 0], {name: "sum"}, ul4._sum), - first: ul4.expose(["iterable", "default=", null], {name: "first"}, ul4._first), - last: ul4.expose(["iterable", "default=", null], {name: "last"}, ul4._last), - sorted: ul4.expose(["iterable", "key=", null, "reverse=", false], {name: "sorted", needscontext: true}, ul4._sorted), - range: ul4.expose(["*args"], {name: "range"}, ul4._range), - slice: ul4.expose(["*args"], {name: "slice"}, ul4._slice), - urlquote: ul4.expose(["string"], {name: "urlquote"}, ul4._urlquote), - urlunquote: ul4.expose(["string"], {name: "urlunquote"}, ul4._urlunquote), - reversed: ul4.expose(["sequence"], {name: "reversed"}, ul4._reversed), - random: ul4.expose([], {name: "random"}, ul4._random), - randrange: ul4.expose(["*args"], {name: "randrange"}, ul4._randrange), - randchoice: ul4.expose(["sequence"], {name: "randchoice"}, ul4._randchoice), - round: ul4.expose(["x", "digit=", 0], {name: "round"}, ul4._round), - md5: ul4.expose(["string"], {name: "md5"}, ul4._md5) - }; - - // Functions implementing UL4 methods - ul4._replace = function _replace(string, old, new_, count) - { - if (count === null) - count = string.length; - - var result = []; - while (string.length) - { - var pos = string.indexOf(old); - if (pos === -1 || !count--) - { - result.push(string); - break; - } - result.push(string.substr(0, pos)); - result.push(new_); - string = string.substr(pos + old.length); - } - return result.join(""); - }; - - ul4._strip = function _strip(string, chars) - { - if (chars === null) - chars = " \r\n\t"; - else if (typeof(chars) !== "string") - throw ul4.TypeError.create("strip()", "strip() requires two strings"); - - while (string && chars.indexOf(string[0]) >= 0) - string = string.substr(1); - while (string && chars.indexOf(string[string.length-1]) >= 0) - string = string.substr(0, string.length-1); - return string; - }; - - ul4._lstrip = function _lstrip(string, chars) - { - if (chars === null) - chars = " \r\n\t"; - else if (typeof(chars) !== "string") - throw ul4.TypeError.create("lstrip()", "lstrip() requires two strings"); - - while (string && chars.indexOf(string[0]) >= 0) - string = string.substr(1); - return string; - }; - - ul4._rstrip = function _rstrip(string, chars) - { - if (chars === null) - chars = " \r\n\t"; - else if (typeof(chars) !== "string") - throw ul4.TypeError.create("rstrip()", "rstrip() requires two strings"); - - while (string && chars.indexOf(string[string.length-1]) >= 0) - string = string.substr(0, string.length-1); - return string; - }; - - ul4._split = function _split(string, sep, count) - { - if (sep !== null && typeof(sep) !== "string") - throw ul4.TypeError.create("split()", "split() requires a string"); - - if (count === null) - { - var result = string.split(sep !== null ? sep : /[ \n\r\t]+/); - if (sep === null) - { - if (result.length && !result[0].length) - result.splice(0, 1); - if (result.length && !result[result.length-1].length) - result.splice(-1); - } - return result; - } - else - { - if (sep !== null) - { - var result = []; - while (string.length) - { - var pos = string.indexOf(sep); - if (pos === -1 || !count--) - { - result.push(string); - break; - } - result.push(string.substr(0, pos)); - string = string.substr(pos + sep.length); - } - return result; - } - else - { - var result = []; - while (string.length) - { - string = ul4._lstrip(string, null); - var part; - if (!count--) - part = string; // Take the rest of the string - else - part = string.split(/[ \n\r\t]+/, 1)[0]; - if (part.length) - result.push(part); - string = string.substr(part.length); - } - return result; - } - } - }; - - ul4._rsplit = function _rsplit(string, sep, count) - { - if (sep !== null && typeof(sep) !== "string") - throw ul4.TypeError.create("rsplit()", "rsplit() requires a string as second argument"); - - if (count === null) - { - var result = string.split(sep !== null ? sep : /[ \n\r\t]+/); - if (sep === null) - { - if (result.length && !result[0].length) - result.splice(0, 1); - if (result.length && !result[result.length-1].length) - result.splice(-1); - } - return result; - } - else - { - if (sep !== null) - { - var result = []; - while (string.length) - { - var pos = string.lastIndexOf(sep); - if (pos === -1 || !count--) - { - result.unshift(string); - break; - } - result.unshift(string.substr(pos+sep.length)); - string = string.substr(0, pos); - } - return result; - } - else - { - var result = []; - while (string.length) - { - string = ul4._rstrip(string, null, null); - var part; - if (!count--) - part = string; // Take the rest of the string - else - { - part = string.split(/[ \n\r\t]+/); - part = part[part.length-1]; - } - if (part.length) - result.unshift(part); - string = string.substr(0, string.length-part.length); - } - return result; - } - } - }; - - ul4._splitlines = function _splitlines(string, keepends) - { - var lookingAtLineEnd = function lookingAtLineEnd() - { - var c = string[pos]; - if (c === '\n' || c == '\u000B' || c == '\u000C' || c == '\u001C' || c == '\u001D' || c == '\u001E' || c == '\u0085' || c == '\u2028' || c == '\u2029') - return 1; - if (c === '\r') - { - if (pos == length-1) - return 1; - if (string[pos+1] === '\n') - return 2; - return 1; - } - return 0; - }; - - var result = [], length = string.length; - - for (var pos = 0, startpos = 0;;) - { - if (pos >= length) - { - if (startpos != pos) - result.push(string.substring(startpos)); - return result; - } - var lineendlen = lookingAtLineEnd(); - if (!lineendlen) - ++pos; - else - { - var endpos = pos + (keepends ? lineendlen : 0); - result.push(string.substring(startpos, endpos)); - pos += lineendlen; - startpos = pos; - } - } - }; - - ul4._count = function _count(obj, sub, start, end) - { - if (start < 0) - start += obj.length; - if (start === null) - start = 0; - - if (end < 0) - end += obj.length; - if (end === null) - end = obj.length; - - var isstr = ul4._isstr(obj); - - if (isstr && !sub.length) - { - if (end < 0 || start > obj.length || start > end) - return 0; - var result = end - start + 1; - if (result > obj.length + 1) - result = obj.length + 1; - return result; - } - - start = ul4._bound(start, obj.length); - end = ul4._bound(end, obj.length); - - var count = 0; - if (ul4._islist(obj)) - { - for (var i = start; i < end; ++i) - { - if (ul4._eq(obj[i], sub)) - ++count; - } - return count; - } - else // string - { - var lastIndex = start; - - for (;;) - { - lastIndex = obj.indexOf(sub, lastIndex); - if (lastIndex == -1) - break; - if (lastIndex + sub.length > end) - break; - ++count; - lastIndex += sub.length; - } - return count; - } - }; - - ul4._find = function _find(obj, sub, start, end) - { - if (start < 0) - start += obj.length; - if (start === null) - start = 0; - if (end < 0) - end += obj.length; - if (end === null) - end = obj.length; - start = ul4._bound(start, obj.length); - end = ul4._bound(end, obj.length); - - if (start !== 0 || end !== obj.length) - { - if (typeof(obj) == "string") - obj = obj.substring(start, end); - else - obj = obj.slice(start, end); - } - var result = obj.indexOf(sub); - if (result !== -1) - result += start; - return result; - }; - - ul4._rfind = function _rfind(obj, sub, start, end) - { - if (start < 0) - start += obj.length; - if (start === null) - start = 0; - if (end < 0) - end += obj.length; - if (end === null) - end = obj.length; - start = ul4._bound(start, obj.length); - end = ul4._bound(end, obj.length); - - if (start !== 0 || end !== obj.length) - { - if (typeof(obj) == "string") - obj = obj.substring(start, end); - else - obj = obj.slice(start, end); - } - var result = obj.lastIndexOf(sub); - if (result !== -1) - result += start; - return result; - }; - - ul4._capitalize = function _capitalize(obj) - { - if (typeof(obj) != "string") - throw ul4.TypeError.create("capitalize()", "capitalize() requires a string"); - - if (obj.length) - obj = obj[0].toUpperCase() + obj.slice(1).toLowerCase(); - return obj; - }; - - ul4._items = function _items(obj) - { - if (ul4._ismap(obj)) - { - var result = []; - obj.forEach(function(value, key){ - result.push([key, value]); - }); - return result; - } - else if (ul4._isobject(obj)) - { - var result = []; - for (var key in obj) - result.push([key, obj[key]]); - return result; - } - throw ul4.TypeError.create("items()", "items() requires a dict"); - }; - - ul4._values = function _values(obj) - { - if (ul4._ismap(obj)) - { - var result = []; - obj.forEach(function(value, key){ - result.push(value); - }); - return result; - } - else if (ul4._isobject(obj)) - { - var result = []; - for (var key in obj) - result.push(obj[key]); - return result; - } - throw ul4.TypeError.create("values()", "values() requires a dict"); - }; - - ul4._join = function _join(sep, iterable) - { - var resultlist = []; - for (var iter = ul4._iter(iterable);;) - { - var item = iter.next(); - if (item.done) - break; - resultlist.push(item.value); - } - return resultlist.join(sep); - }; - - ul4._startswith = function _startswith(string, prefix) - { - if (typeof(prefix) !== "string") - throw ul4.TypeError.create("startswith()", "startswith() argument must be string"); - - return string.substr(0, prefix.length) === prefix; - }; - - ul4._endswith = function _endswith(string, suffix) - { - if (typeof(suffix) !== "string") - throw ul4.TypeError.create("endswith()", "endswith() argument must be string"); - - return string.substr(string.length-suffix.length) === suffix; - }; - - ul4._isoformat = function _isoformat(obj) - { - if (!ul4._isdate(obj)) - throw ul4.TypeError.create("isoformat()", "isoformat() requires a date"); - - var result = obj.getFullYear() + "-" + ul4._lpad((obj.getMonth()+1).toString(), "0", 2) + "-" + ul4._lpad(obj.getDate().toString(), "0", 2); - var hour = obj.getHours(); - var minute = obj.getMinutes(); - var second = obj.getSeconds(); - var ms = obj.getMilliseconds(); - if (hour || minute || second || ms) - { - result += "T" + ul4._lpad(hour.toString(), "0", 2) + ":" + ul4._lpad(minute.toString(), "0", 2) + ":" + ul4._lpad(second.toString(), "0", 2); - if (ms) - result += "." + ul4._lpad(ms.toString(), "0", 3) + "000"; - } - return result; - }; - - ul4._mimeformat = function _mimeformat(obj) - { - var weekdayname = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; - var monthname = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; - - return weekdayname[ul4._weekday(obj)] + ", " + ul4._lpad(obj.getDate(), "0", 2) + " " + monthname[obj.getMonth()] + " " + obj.getFullYear() + " " + ul4._lpad(obj.getHours(), "0", 2) + ":" + ul4._lpad(obj.getMinutes(), "0", 2) + ":" + ul4._lpad(obj.getSeconds(), "0", 2) + " GMT"; - }; - - ul4._weekday = function _weekday(obj) - { - var d = obj.getDay(); - return d ? d-1 : 6; - }; - - ul4._week = function _week(obj, firstweekday) - { - if (firstweekday === null) - firstweekday = 0; - else - firstweekday %= 7; - - var yearday = ul4._yearday(obj)+6; - var jan1 = new Date(obj.getFullYear(), 0, 1); - var jan1weekday = jan1.getDay(); - if (--jan1weekday < 0) - jan1weekday = 6; - - while (jan1weekday != firstweekday) - { - --yearday; - if (++jan1weekday == 7) - jan1weekday = 0; - } - return Math.floor(yearday/7); - }; - - ul4._isleap = function _isleap(obj) - { - return new Date(obj.getFullYear(), 1, 29).getMonth() === 1; - }; - - ul4._yearday = function _yearday(obj) - { - var leap = ul4._isleap(obj) ? 1 : 0; - var day = obj.getDate(); - switch (obj.getMonth()) - { - case 0: - return day; - case 1: - return 31 + day; - case 2: - return 31 + 28 + leap + day; - case 3: - return 31 + 28 + leap + 31 + day; - case 4: - return 31 + 28 + leap + 31 + 30 + day; - case 5: - return 31 + 28 + leap + 31 + 30 + 31 + day; - case 6: - return 31 + 28 + leap + 31 + 30 + 31 + 30 + day; - case 7: - return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + day; - case 8: - return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + day; - case 9: - return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + day; - case 10: - return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + day; - case 11: - return 31 + 28 + leap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + day; - } - }; - - ul4._append = function _append(obj, items) - { - for (var i = 0; i < items.length; ++i) - obj.push(items[i]); - return null; - }; - - ul4._insert = function _insert(obj, pos, items) - { - if (pos < 0) - pos += obj.length; - - for (var i = 0; i < items.length; ++i) - obj.splice(pos++, 0, items[i]); - return null; - }; - - ul4._pop = function _pop(obj, pos) - { - if (pos < 0) - pos += obj.length; - - var result = obj[pos]; - obj.splice(pos, 1); - return result; - }; - - ul4._update = function _update(obj, others, kwargs) - { - if (!ul4._isdict(obj)) - throw ul4.TypeError.create("update()", "update() requires a dict"); - for (var i = 0; i < others.length; ++i) - { - var other = others[i]; - if (ul4._ismap(other)) - { - other.forEach(function(value, key){ - ul4on._setmap(obj, key, value); - }); - } - else if (ul4._isobject(other)) - { - for (var key in other) - ul4on._setmap(obj, key, other[key]); - } - else if (ul4._islist(other)) - { - for (var j = 0; j < other.length; ++j) - { - if (!ul4._islist(other[j]) || (other[j].length != 2)) - throw ul4.TypeError.create("update()", "update() requires a dict or a list of (key, value) pairs"); - ul4on._setmap(obj, other[j][0], other[j][1]); - } - } - else - throw ul4.TypeError.create("update()", "update() requires a dict or a list of (key, value) pairs"); - } - for (var key in kwargs) - ul4on._setmap(obj, key, kwargs[key]); - return null; - }; - - ul4._clear = function _clear(obj) - { - if (ul4._ismap(obj)) - obj.clear(); - else if (ul4._isset(obj)) - obj.clear(); - else if (ul4._isobject(obj)) - { - for (var key in obj) - delete obj[key]; - } - else - throw ul4.TypeError.create("clear()", "clear() requires a dict or set"); - return null; - }; - - ul4.Color = ul4._inherit( - ul4.Proto, - { - __type__: "ul4.Color", - - create: function create(r, g, b, a) - { - var c = ul4._clone(this); - c._r = typeof(r) !== "undefined" ? r : 0; - c._g = typeof(g) !== "undefined" ? g : 0; - c._b = typeof(b) !== "undefined" ? b : 0; - c._a = typeof(a) !== "undefined" ? a : 255; - return c; - }, - - __repr__: function __repr__() - { - var r = ul4._lpad(this._r.toString(16), "0", 2); - var g = ul4._lpad(this._g.toString(16), "0", 2); - var b = ul4._lpad(this._b.toString(16), "0", 2); - var a = ul4._lpad(this._a.toString(16), "0", 2); - if (this._a !== 0xff) - { - if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1] && a[0] === a[1]) - return "#" + r[0] + g[0] + b[0] + a[0]; - else - return "#" + r + g + b + a; - } - else - { - if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1]) - return "#" + r[0] + g[0] + b[0]; - else - return "#" + r + g + b; - } - }, - - __str__: function __str__() - { - if (this._a !== 0xff) - { - return "rgba(" + this._r + ", " + this._g + ", " + this._b + ", " + (this._a/255) + ")"; - } - else - { - var r = ul4._lpad(this._r.toString(16), "0", 2); - var g = ul4._lpad(this._g.toString(16), "0", 2); - var b = ul4._lpad(this._b.toString(16), "0", 2); - var a = ul4._lpad(this._a.toString(16), "0", 2); - if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1]) - return "#" + r[0] + g[0] + b[0]; - else - return "#" + r + g + b; - } - }, - - __iter__: function __iter__() - { - return { - obj: this, - index: 0, - next: function() { - if (this.index == 0) - { - ++this.index; - return {value: this.obj._r, done: false}; - } - else if (this.index == 1) - { - ++this.index; - return {value: this.obj._g, done: false}; - } - else if (this.index == 2) - { - ++this.index; - return {value: this.obj._b, done: false}; - } - else if (this.index == 3) - { - ++this.index; - return {value: this.obj._a, done: false}; - } - else - return {done: true}; - } - }; - }, - - __getattr__: function __getattr__(attrname) - { - var self = this; - switch (attrname) - { - case "r": - return ul4.expose([], function r(){ return self._r; }); - case "g": - return ul4.expose([], function g(){ return self._g; }); - case "b": - return ul4.expose([], function b(){ return self._b; }); - case "a": - return ul4.expose([], function a(){ return self._a; }); - case "lum": - return ul4.expose([], function lum(){ return self.lum(); }); - case "hls": - return ul4.expose([], function hls(){ return self.hls(); }); - case "hlsa": - return ul4.expose([], function hlsa(){ return self.hlsa(); }); - case "hsv": - return ul4.expose([], function hsv(){ return self.hsv(); }); - case "hsva": - return ul4.expose([], function hsva(){ return self.hsva(); }); - case "witha": - return ul4.expose(["a"], function witha(a){ return self.witha(a); }); - case "withlum": - return ul4.expose(["lum"], function withlum(lum){ return self.withlum(lum); }); - case "abslum": - return ul4.expose(["lum"], function abslum(lum){ return self.abslum(lum); }); - case "rellum": - return ul4.expose(["lum"], function rellum(lum){ return self.rellum(lum); }); - default: - return undefined; - } - }, - - __getitem__: function __getitem__(key) - { - var orgkey = key; - if (key < 0) - key += 4; - switch (key) - { - case 0: - return this._r; - case 1: - return this._g; - case 2: - return this._b; - case 3: - return this._a; - default: - return undefined; - } - }, - - __eq__: function __eq__(other) - { - if (ul4._iscolor(other)) - return this._r == other._r && this._g == other._g && this._b == other._b && this._a == other._a; - return false; - }, - - r: ul4.expose([], function r() { return this._r; }), - - g: ul4.expose([], function g() { return this._g; }), - - b: ul4.expose([], function b() { return this._b; }), - - a: ul4.expose([], function a() { return this._a; }), - - lum: ul4.expose([], function lum() {return this.hls()[1]; }), - - hls: ul4.expose([], - function hls() - { - var r = this._r/255.0; - var g = this._g/255.0; - var b = this._b/255.0; - var maxc = Math.max(r, g, b); - var minc = Math.min(r, g, b); - var h, l, s; - var rc, gc, bc; - - l = (minc+maxc)/2.0; - if (minc == maxc) - return [0.0, l, 0.0]; - if (l <= 0.5) - s = (maxc-minc) / (maxc+minc); - else - s = (maxc-minc) / (2.0-maxc-minc); - rc = (maxc-r) / (maxc-minc); - gc = (maxc-g) / (maxc-minc); - bc = (maxc-b) / (maxc-minc); - if (r == maxc) - h = bc-gc; - else if (g == maxc) - h = 2.0+rc-bc; - else - h = 4.0+gc-rc; - h = (h/6.0) % 1.0; - return [h, l, s]; - } - ), - - hlsa: ul4.expose([], - function hlsa() - { - var hls = this.hls(); - return hls.concat(this._a/255.0); - } - ), - - hsv: ul4.expose([], - function hsv() - { - var r = this._r/255.0; - var g = this._g/255.0; - var b = this._b/255.0; - var maxc = Math.max(r, g, b); - var minc = Math.min(r, g, b); - var v = maxc; - if (minc == maxc) - return [0.0, 0.0, v]; - var s = (maxc-minc) / maxc; - var rc = (maxc-r) / (maxc-minc); - var gc = (maxc-g) / (maxc-minc); - var bc = (maxc-b) / (maxc-minc); - var h; - if (r == maxc) - h = bc-gc; - else if (g == maxc) - h = 2.0+rc-bc; - else - h = 4.0+gc-rc; - h = (h/6.0) % 1.0; - return [h, s, v]; - } - ), - - hsva: ul4.expose([], - function hsva() - { - var hsv = this.hsv(); - return hsv.concat(this._a/255.0); - } - ), - - witha: ul4.expose(["a"], - function witha(a) - { - if (typeof(a) !== "number") - throw ul4.TypeError.create("witha()", "witha() requires a number"); - return ul4.Color.create(this._r, this._g, this._b, a); - } - ), - - withlum: ul4.expose(["lum"], - function withlum(lum) - { - if (typeof(lum) !== "number") - throw ul4.TypeError.create("witha()", "witha() requires a number"); - var hlsa = this.hlsa(); - return ul4._hls(hlsa[0], lum, hlsa[2], hlsa[3]); - } - ) - } - ); - - ul4.TimeDelta = ul4._inherit( - ul4.Proto, - { - __type__: "ul4.TimeDelta", - - create: function create(days, seconds, microseconds) - { - var td = ul4._clone(this); - if (typeof(days) === "undefined") - days = 0; - if (typeof(seconds) === "undefined") - seconds = 0; - if (typeof(microseconds) === "undefined") - microseconds = 0; - - var total_microseconds = Math.floor((days * 86400 + seconds)*1000000 + microseconds); - - microseconds = ul4.ModAST._do(total_microseconds, 1000000); - var total_seconds = Math.floor(total_microseconds / 1000000); - seconds = ul4.ModAST._do(total_seconds, 86400); - days = Math.floor(total_seconds / 86400); - if (seconds < 0) - { - seconds += 86400; - --days; - } - - td._microseconds = microseconds; - td._seconds = seconds; - td._days = days; - - return td; - }, - - __repr__: function __repr__() - { - if (!this._microseconds) - { - if (!this._seconds) - { - if (!this._days) - return "timedelta()"; - return "timedelta(" + this._days + ")"; - } - return "timedelta(" + this._days + ", " + this._seconds + ")"; - } - return "timedelta(" + this._days + ", " + this._seconds + ", " + this._microseconds + ")"; - }, - - __str__: function __str__() - { - var v = []; - if (this._days) - { - v.push(this._days + " day"); - if (this._days !== -1 && this._days !== 1) - v.push("s"); - v.push(", "); - } - var seconds = this._seconds % 60; - var minutes = Math.floor(this._seconds / 60); - var hours = Math.floor(minutes / 60); - minutes = minutes % 60; - - v.push("" + hours); - v.push(":"); - v.push(ul4._lpad(minutes.toString(), "0", 2)); - v.push(":"); - v.push(ul4._lpad(seconds.toString(), "0", 2)); - if (this._microseconds) - { - v.push("."); - v.push(ul4._lpad(this._microseconds.toString(), "0", 6)); - } - return v.join(""); - }, - - __bool__: function __bool__() - { - return this._days !== 0 || this._seconds !== 0 || this._microseconds !== 0; - }, - - __abs__: function __abs__() - { - return this._days < 0 ? ul4.TimeDelta.create(-this._days, -this._seconds, -this._microseconds) : this; - }, - - __eq__: function __eq__(other) - { - if (ul4._istimedelta(other)) - return (this._days === other._days) && (this._seconds === other._seconds) && (this._microseconds === other._microseconds); - return false; - }, - - __lt__: function __lt__(other) - { - if (ul4._istimedelta(other)) - { - if (this._days != other._days) - return this._days < other._days; - if (this._seconds != other._seconds) - return this._seconds < other._seconds; - return this._microseconds < other._microseconds; - } - ul4._unorderable("<", this, other); - }, - - __le__: function __le__(other) - { - if (ul4._istimedelta(other)) - { - if (this._days != other._days) - return this._days < other._days; - if (this._seconds != other._seconds) - return this._seconds < other._seconds; - return this._microseconds <= other._microseconds; - } - ul4._unorderable("<=", this, other); - }, - - __gt__: function __gt__(other) - { - if (ul4._istimedelta(other)) - { - if (this._days != other._days) - return this._days > other._days; - if (this._seconds != other._seconds) - return this._seconds > other._seconds; - return this._microseconds > other._microseconds; - } - ul4._unorderable(">", this, other); - }, - - __ge__: function __ge__(other) - { - if (ul4._istimedelta(other)) - { - if (this._days != other._days) - return this._days > other._days; - if (this._seconds != other._seconds) - return this._seconds > other._seconds; - return this._microseconds >= other._microseconds; - } - ul4._unorderable(">=", this, other); - }, - - __neg__: function __neg__() - { - return ul4.TimeDelta.create(-this._days, -this._seconds, -this._microseconds); - }, - - _add: function _add(date, days, seconds, microseconds) - { - var year = date.getFullYear(); - var month = date.getMonth(); - var day = date.getDate() + days; - var hour = date.getHours(); - var minute = date.getMinutes(); - var second = date.getSeconds() + seconds; - var millisecond = date.getMilliseconds() + microseconds/1000; - return new Date(year, month, day, hour, minute, second, millisecond); - }, - - __add__: function __add__(other) - { - if (ul4._istimedelta(other)) - return ul4.TimeDelta.create(this._days + other._days, this._seconds + other._seconds, this._microseconds + other._microseconds); - else if (ul4._isdate(other)) - return this._add(other, this._days, this._seconds, this._microseconds); - throw ul4.TypeError.create("+", ul4._type(this) + " + " + ul4._type(other) + " not supported"); - }, - - __radd__: function __radd__(other) - { - if (ul4._isdate(other)) - return this._add(other, this._days, this._seconds, this._microseconds); - throw ul4.TypeError.create("+", ul4._type(this) + " + " + ul4._type(other) + " not supported"); - }, - - __sub__: function __sub__(other) - { - if (ul4._istimedelta(other)) - return ul4.TimeDelta.create(this._days - other._days, this._seconds - other._seconds, this._microseconds - other._microseconds); - throw ul4.TypeError.create("-", ul4._type(this) + " - " + ul4._type(other) + " not supported"); - }, - - __rsub__: function __rsub__(other) - { - if (ul4._isdate(other)) - return this._add(other, -this._days, -this._seconds, -this._microseconds); - throw ul4.TypeError.create("-", ul4._type(this) + " - " + ul4._type(other) + " not supported"); - }, - - __mul__: function __mul__(other) - { - if (typeof(other) === "number") - { - return ul4.TimeDelta.create(this._days * other, this._seconds * other, this._microseconds * other); - } - throw ul4.TypeError.create("*", ul4._type(this) + " * " + ul4._type(other) + " not supported"); - }, - - __rmul__: function __rmul__(other) - { - if (typeof(other) === "number") - { - return ul4.TimeDelta.create(this._days * other, this._seconds * other, this._microseconds * other); - } - throw ul4.TypeError.create("*", ul4._type(this) + " * " + ul4._type(other) + " not supported"); - }, - - __truediv__: function __truediv__(other) - { - if (typeof(other) === "number") - { - return ul4.TimeDelta.create(this._days / other, this._seconds / other, this._microseconds / other); - } - else if (ul4._istimedelta(other)) - { - var myValue = this._days; - var otherValue = other._days; - var hasSeconds = this._seconds || other._seconds; - var hasMicroseconds = this._microseconds || other._microseconds; - if (hasSeconds || hasMicroseconds) - { - myValue = myValue*86400+this._seconds; - otherValue = otherValue*86400 + other._seconds; - if (hasMicroseconds) - { - myValue = myValue * 1000000 + this._microseconds; - otherValue = otherValue * 1000000 + other._microseconds; - } - } - return myValue/otherValue; - } - throw ul4.TypeError.create("/", ul4._type(this) + " / " + ul4._type(other) + " not supported"); - }, - - __getattr__: function __getattr__(attrname) - { - var self = this; - switch (attrname) - { - case "days": - return ul4.expose([], function days(){ return self._days; }); - case "seconds": - return ul4.expose([], function seconds(){ return self._seconds; }); - case "microseconds": - return ul4.expose([], function microseconds(){ return self._microseconds; }); - default: - return undefined; - } - }, - - days: function days() - { - return this._days; - }, - - seconds: function seconds() - { - return this._seconds; - }, - - microseconds: function microseconds() - { - return this._microseconds; - } - } - ); - - ul4.MonthDelta = ul4._inherit( - ul4.Proto, - { - __type__: "ul4.MonthDelta", - - create: function create(months) - { - var md = ul4._clone(this); - md._months = typeof(months) !== "undefined" ? months : 0; - return md; - }, - - __repr__: function __repr__() - { - if (!this._months) - return "monthdelta()"; - return "monthdelta(" + this._months + ")"; - }, - - __str__: function __str__() - { - if (this._months) - { - if (this._months !== -1 && this._months !== 1) - return this._months + " months"; - return this._months + " month"; - } - return "0 months"; - }, - - __bool__: function __bool__() - { - return this._months !== 0; - }, - - __abs__: function __abs__() - { - return this._months < 0 ? ul4.MonthDelta.create(-this._months) : this; - }, - - __eq__: function __eq__(other) - { - if (ul4._ismonthdelta(other)) - return this._months === other._months; - return false; - }, - - __lt__: function __lt__(other) - { - if (ul4._ismonthdelta(other)) - return this._months < other._months; - ul4._unorderable("<", this, other); - }, - - __le__: function __le__(other) - { - if (ul4._ismonthdelta(other)) - return this._months <= other._months; - ul4._unorderable("<=", this, other); - }, - - __gt__: function __gt__(other) - { - if (ul4._ismonthdelta(other)) - return this._months > other._months; - ul4._unorderable(">", this, other); - }, - - __ge__: function __ge__(other) - { - if (ul4._ismonthdelta(other)) - return this._months >= other._months; - ul4._unorderable(">=", this, other); - }, - - __neg__: function __neg__() - { - return ul4.MonthDelta.create(-this._months); - }, - - _add: function _add(date, months) - { - var year = date.getFullYear(); - var month = date.getMonth() + months; - var day = date.getDate(); - var hour = date.getHours(); - var minute = date.getMinutes(); - var second = date.getSeconds(); - var millisecond = date.getMilliseconds(); - - while (true) - { - // As the month might be out of bounds, we have to find out, what the real target month is - var targetmonth = new Date(year, month, 1, hour, minute, second, millisecond).getMonth(); - var result = new Date(year, month, day, hour, minute, second, millisecond); - if (result.getMonth() === targetmonth) - return result; - --day; - } - }, - - __add__: function __add__(other) - { - if (ul4._ismonthdelta(other)) - return ul4.MonthDelta.create(this._months + other._months); - else if (ul4._isdate(other)) - return this._add(other, this._months); - throw ul4._type(this) + " + " + ul4._type(other) + " not supported"; - }, - - __radd__: function __radd__(other) - { - if (ul4._isdate(other)) - return this._add(other, this._months); - throw ul4._type(this) + " + " + ul4._type(other) + " not supported"; - }, - - __sub__: function __sub__(other) - { - if (ul4._ismonthdelta(other)) - return ul4.MonthDelta.create(this._months - other._months); - throw ul4._type(this) + " - " + ul4._type(other) + " not supported"; - }, - - __rsub__: function __rsub__(other) - { - if (ul4._isdate(other)) - return this._add(other, -this._months); - throw ul4._type(this) + " - " + ul4._type(other) + " not supported"; - }, - - __mul__: function __mul__(other) - { - if (typeof(other) === "number") - return ul4.MonthDelta.create(this._months * Math.floor(other)); - throw ul4._type(this) + " * " + ul4._type(other) + " not supported"; - }, - - __rmul__: function __rmul__(other) - { - if (typeof(other) === "number") - return ul4.MonthDelta.create(this._months * Math.floor(other)); - throw ul4._type(this) + " * " + ul4._type(other) + " not supported"; - }, - - __floordiv__: function __floordiv__(other) - { - if (typeof(other) === "number") - return ul4.MonthDelta.create(Math.floor(this._months / other)); - else if (ul4._ismonthdelta(other)) - return Math.floor(this._months / other._months); - throw ul4._type(this) + " // " + ul4._type(other) + " not supported"; - }, - - __truediv__: function __truediv__(other) - { - if (ul4._ismonthdelta(other)) - return this._months / other._months; - throw ul4._type(this) + " / " + ul4._type(other) + " not supported"; - }, - - __getattr__: function __getattr__(attrname) - { - var self = this; - switch (attrname) - { - case "months": - return ul4.expose([], function months(){ return self._months; }); - default: - return undefined; - } - }, - - months: function months() - { - return this._months; - } - } - ); - - // When we don't have a real ``Set`` type, emulate one that supports strings - ul4._Set = ul4._inherit( - ul4.Proto, - { - __type__: "ul4._Set", - - create: function create() - { - var set = ul4._clone(this); - set.items = {}; - set.add.apply(set, arguments); - return set; - }, - - add: function add() - { - for (var i = 0; i < arguments.length; ++i) - { - this.items[arguments[i]] = true; - } - }, - - __getattr__: function __getattr__(attrname) - { - var self = this; - switch (attrname) - { - case "add": - return ul4.expose(["*items"], function add(items){ self.add.apply(self, items); }); - default: - return undefined; - } - }, - - __contains__: function __contains__(item) - { - return this.items[item] || false; - }, - - __bool__: function __bool__() - { - for (var item in this.items) - { - if (!this.items.hasOwnProperty(item)) - continue; - return true; - } - return false; - }, - - __repr__: function __repr__() - { - var v = []; - v.push("{"); - var i = 0; - for (var item in this.items) - { - if (!this.items.hasOwnProperty(item)) - continue; - if (i++) - v.push(", "); - v.push(ul4._repr(item)); - } - if (!i) - v.push("/"); - v.push("}"); - return v.join(""); - }, - - __eq__: function(other) - { - // We'll check that everything in ``this`` is in ``other`` - // and if both have the same number of items they are equal - if (ul4._isset(other)) - { - var count = 0; - for (var item in this.items) - { - if (!other.has(item)) - return false; - // count the number of items we have - ++count; - } - return other.size == count; - } - else if (ul4._isul4set(other)) - { - var count = 0; - for (var item in this.items) - { - if (!other[item]) - return false; - // count the number of items we have - ++count; - } - // Substract the number of items that ``other`` has - for (var item in other.items) - --count; - return count == 0; - } - else - return false; - }, - - __le__: function(other) - { - // check that ``this`` is a subset of ``other``, - // i.e. everything in ``this`` is also in ``other`` - if (ul4._isset(other)) - { - var count = 0; - for (var item in this.items) - { - if (!other.has(item)) - return false; - } - return true; - } - else if (ul4._isul4set(other)) - { - var count = 0; - for (var item in this.items) - { - if (!other.items[item]) - return false; - } - return true; - } - else - ul4._unorderable("<", this, other); - }, - - __ge__: function(other) - { - // check that ``this`` is a superset of ``other``, - // i.e. everything in ``other`` is also in ``this`` - if (ul4._isset(other)) - { - var result = true; - other.forEach(function(value) { - if (!this.items[value]) - result = false; - }); - return result; - } - else if (ul4._isul4set(other)) - { - var count = 0; - for (var item in other.items) - { - if (!this.items[item]) - return false; - } - return true; - } - else - ul4._unorderable("<=", this, other); - } - } - ); - - var classes = [ - "TextAST", - "IndentAST", - "LineEndAST", - "Tag", - "ConstAST", - "SeqItemAST", - "UnpackSeqItemAST", - "DictItemAST", - "UnpackDictItemAST", - "PosArgAST", - "KeywordArgAST", - "UnpackListArgAST", - "UnpackDictArgAST", - "ListAST", - "ListCompAST", - "DictAST", - "DictCompAST", - "SetAST", - "SetCompAST", - "GenExprAST", - "VarAST", - "NotAST", - "NegAST", - "BitNotAST", - "IfAST", - "ReturnAST", - "PrintAST", - "PrintXAST", - "ItemAST", - "IsAST", - "IsNotAST", - "EQAST", - "NEAST", - "LTAST", - "LEAST", - "GTAST", - "GEAST", - "NotContainsAST", - "ContainsAST", - "AddAST", - "SubAST", - "MulAST", - "FloorDivAST", - "TrueDivAST", - "ModAST", - "ShiftLeftAST", - "ShiftRightAST", - "BitAndAST", - "BitXOrAST", - "BitOrAST", - "AndAST", - "OrAST", - "SliceAST", - "AttrAST", - "CallAST", - "RenderAST", - "SetVarAST", - "AddVarAST", - "SubVarAST", - "MulVarAST", - "TrueDivVarAST", - "FloorDivVarAST", - "ModVarAST", - "ShiftLeftVarAST", - "ShiftRightVarAST", - "BitAndVarAST", - "BitXOrVarAST", - "BitOrVarAST", - "ForBlockAST", - "WhileBlockAST", - "BreakAST", - "ContinueAST", - "CondBlockAST", - "IfBlockAST", - "ElIfBlockAST", - "ElseBlockAST", - "SignatureAST", - "Template" - ]; - - for (var i = 0; i < classes.length; ++i) - { - var name = classes[i]; - var ul4onname = name; - if (ul4onname.substr(ul4onname.length-3) === "AST") - ul4onname = ul4onname.substr(0, ul4onname.length-3); - ul4onname = ul4onname.toLowerCase(); - var object = ul4[name]; - object.typename = name; - object.type = ul4onname; - ul4on.register("de.livinglogic.ul4." + ul4onname, object); - } - - })(); \ No newline at end of file + // Return an iterator over ``[index, item]`` lists from the iterable object ``iterable``. ``index`` starts at ``start`` (defaulting to 0) + ul4._enumerate = function _enumerate(iterable, start=0) + { + return { + iter: ul4._iter(iterable), + index: start, + next: function() { + let item = this.iter.next(); + return item.done ? item : {value: [this.index++, item.value], done: false}; + } + }; + }; + + // Return an iterator over ``[isfirst, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, false otherwise) + ul4._isfirst = function _isfirst(iterable) + { + let iter = ul4._iter(iterable); + let isfirst = true; + return { + next: function() { + let item = iter.next(); + let result = item.done ? item : {value: [isfirst, item.value], done: false}; + isfirst = false; + return result; + } + }; + }; + + // Return an iterator over ``[islast, item]`` lists from the iterable object ``iterable`` (``islast`` is true for the last item, false otherwise) + ul4._islast = function _islast(iterable) + { + let iter = ul4._iter(iterable); + let lastitem = iter.next(); + return { + next: function() { + if (lastitem.done) + return lastitem; + let item = iter.next(); + let result = {value: [item.done, lastitem.value], done: false}; + lastitem = item; + return result; + } + }; + }; + + // Return an iterator over ``[isfirst, islast, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, ``islast`` is true for the last item. Both are false otherwise) + ul4._isfirstlast = function _isfirstlast(iterable) + { + let iter = ul4._iter(iterable); + let isfirst = true; + let lastitem = iter.next(); + return { + next: function() { + if (lastitem.done) + return lastitem; + let item = iter.next(); + let result = {value: [isfirst, item.done, lastitem.value], done: false}; + lastitem = item; + isfirst = false; + return result; + } + }; + }; + + // Return an iterator over ``[index, isfirst, islast, item]`` lists from the iterable object ``iterable`` (``isfirst`` is true for the first item, ``islast`` is true for the last item. Both are false otherwise) + ul4._enumfl = function _enumfl(iterable, start=0) + { + let iter = ul4._iter(iterable); + let i = start; + let isfirst = true; + let lastitem = iter.next(); + return { + next: function() { + if (lastitem.done) + return lastitem; + let item = iter.next(); + let result = {value: [i++, isfirst, item.done, lastitem.value], done: false}; + lastitem = item; + isfirst = false; + return result; + } + }; + }; + + // Return an iterator over lists, where the i'th list consists of all i'th items from the arguments (terminating when the shortest argument ends) + ul4._zip = function _zip(iterables) + { + let result; + if (iterables.length) + { + let iters = []; + for (let i = 0; i < iterables.length; ++i) + iters.push(ul4._iter(iterables[i])); + + return { + next: function() { + let items = []; + for (let i = 0; i < iters.length; ++i) + { + let item = iters[i].next(); + if (item.done) + return item; + items.push(item.value); + } + return {value: items, done: false}; + } + }; + } + else + { + return { + next: function() { + return {done: true}; + } + }; + } + }; + + // Return the absolute value for the number ``number`` + ul4._abs = function _abs(number) + { + if (number !== null && typeof(number.__abs__) === "function") + return number.__abs__(); + return Math.abs(number); + }; + + // Return a ``Date`` object from the arguments passed in + ul4._date = function _date(year, month, day) + { + return new ul4.Date(year, month, day); + }; + + ul4._datetime = function _datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0) + { + return new Date(year, month-1, day, hour, minute, second, microsecond/1000); + }; + + // Return a ``TimeDelta`` object from the arguments passed in + ul4._timedelta = function _timedelta(days=0, seconds=0, microseconds=0) + { + return new this.TimeDelta(days, seconds, microseconds); + }; + + // Return a ``MonthDelta`` object from the arguments passed in + ul4._monthdelta = function _monthdelta(months=0) + { + return new this.MonthDelta(months); + }; + + // Return a ``Color`` object from the hue, luminescence, saturation and alpha values ``h``, ``l``, ``s`` and ``a`` (i.e. using the HLS color model) + ul4._hls = function _hls(h, l, s, a) + { + let _v = function(m1, m2, hue) + { + hue = hue % 1.0; + if (hue < 1/6) + return m1 + (m2-m1)*hue*6.0; + else if (hue < 0.5) + return m2; + else if (hue < 2/3) + return m1 + (m2-m1)*(2/3-hue)*6.0; + return m1; + }; + + let m1, m2; + if (typeof(a) === "undefined") + a = 1; + if (s === 0.0) + return ul4._rgb(l, l, l, a); + if (l <= 0.5) + m2 = l * (1.0+s); + else + m2 = l+s-(l*s); + m1 = 2.0*l - m2; + return ul4._rgb(_v(m1, m2, h+1/3), _v(m1, m2, h), _v(m1, m2, h-1/3), a); + }; + + // Return a ``Color`` object from the hue, saturation, value and alpha values ``h``, ``s``, ``v`` and ``a`` (i.e. using the HSV color model) + ul4._hsv = function _hsv(h, s, v, a) + { + if (s === 0.0) + return ul4._rgb(v, v, v, a); + let i = Math.floor(h*6.0); + let f = (h*6.0) - i; + let p = v*(1.0 - s); + let q = v*(1.0 - s*f); + let t = v*(1.0 - s*(1.0-f)); + switch (i%6) + { + case 0: + return ul4._rgb(v, t, p, a); + case 1: + return ul4._rgb(q, v, p, a); + case 2: + return ul4._rgb(p, v, t, a); + case 3: + return ul4._rgb(p, q, v, a); + case 4: + return ul4._rgb(t, p, v, a); + case 5: + return ul4._rgb(v, p, q, a); + } + }; + + // Return the item with the key ``key`` from the dict ``container``. If ``container`` doesn't have this key, return ``defaultvalue`` + ul4._get = function _get(container, key, defaultvalue) + { + if (ul4._ismap(container)) + { + if (container.has(key)) + return container.get(key); + return defaultvalue; + } + else if (ul4._isobject(container)) + { + let result = container[key]; + if (typeof(result) === "undefined") + return defaultvalue; + return result; + } + throw new ul4.TypeError("get() requires a dict"); + }; + + // Return a ``Date`` object for the current time + ul4.now = function now() + { + return new Date(); + }; + + // Return a ``Date`` object for the current time in UTC + ul4.utcnow = function utcnow() + { + let now = new Date(); + // FIXME: The timezone is wrong for the new ``Date`` object. + return new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(), now.getUTCMilliseconds()); + }; + + // Return an ``ul4.Date`` object for today + ul4.today = function today() + { + let now = new Date(); + return new ul4.Date(now.getFullYear(), now.getMonth()+1, now.getDate()); + }; + + ul4.functions = { + repr: ul4._repr, + ascii: ul4._ascii, + str: ul4._str, + int: ul4._int, + float: ul4._float, + list: ul4._list, + set: ul4._set, + bool: ul4._bool, + len: ul4._len, + type: ul4._type, + format: ul4._format, + any: ul4._any, + all: ul4._all, + zip: ul4._zip, + getattr: ul4._getattr, + hasattr: ul4._hasattr, + dir: ul4._dir, + isundefined: ul4._isundefined, + isdefined: ul4._isdefined, + isnone: ul4._isnone, + isbool: ul4._isbool, + isint: ul4._isint, + isfloat: ul4._isfloat, + isstr: ul4._isstr, + isdate: ul4._isdate, + isdatetime: ul4._isdatetime, + iscolor: ul4._iscolor, + istimedelta: ul4._istimedelta, + ismonthdelta: ul4._ismonthdelta, + istemplate: ul4._istemplate, + isfunction: ul4._isfunction, + islist: ul4._islist, + isset: ul4._isanyset, + isdict: ul4._isdict, + isexception: ul4._isexception, + asjson: ul4._asjson, + fromjson: ul4._fromjson, + asul4on: ul4._asul4on, + fromul4on: ul4._fromul4on, + now: ul4.now, + utcnow: ul4.utcnow, + today: ul4.today, + enumerate: ul4._enumerate, + isfirst: ul4._isfirst, + islast: ul4._islast, + isfirstlast: ul4._isfirstlast, + enumfl: ul4._enumfl, + abs: ul4._abs, + date: ul4._date, + datetime: ul4._datetime, + timedelta: ul4._timedelta, + monthdelta: ul4._monthdelta, + rgb: ul4._rgb, + hls: ul4._hls, + hsv: ul4._hsv, + xmlescape: ul4._xmlescape, + csv: ul4._csv, + chr: ul4._chr, + ord: ul4._ord, + hex: ul4._hex, + oct: ul4._oct, + bin: ul4._bin, + min: ul4._min, + max: ul4._max, + sum: ul4._sum, + first: ul4._first, + last: ul4._last, + sorted: ul4._sorted, + range: ul4._range, + slice: ul4._slice, + urlquote: ul4._urlquote, + urlunquote: ul4._urlunquote, + reversed: ul4._reversed, + random: ul4._random, + randrange: ul4._randrange, + randchoice: ul4._randchoice, + round: ul4._round, + md5: ul4._md5 + }; + + ul4.expose(ul4._repr, ["obj"], {name: "repr"}); + ul4.expose(ul4._ascii, ["obj"], {name: "ascii"}); + ul4.expose(ul4._str, ["obj=", ""], {name: "str"}); + ul4.expose(ul4._int, ["obj=", 0, "base=", null], {name: "int"}); + ul4.expose(ul4._float, ["obj=", 0.0], {name: "float"}); + ul4.expose(ul4._list, ["iterable=", []], {name: "list"}); + ul4.expose(ul4._set, ["iterable=", []], {name: "set"}); + ul4.expose(ul4._bool, ["obj=", false], {name: "bool"}); + ul4.expose(ul4._len, ["sequence"], {name: "len"}); + ul4.expose(ul4._type, ["obj"], {name: "type"}); + ul4.expose(ul4._format, ["obj", "fmt", "lang=", null], {name: "format"}); + ul4.expose(ul4._any, ["iterable"], {name: "any"}); + ul4.expose(ul4._all, ["iterable"], {name: "all"}); + ul4.expose(ul4._zip, ["*iterables"], {name: "zip"}); + ul4.expose(ul4._getattr, ["obj", "attrname", "default=", null], {name: "getattr"}); + ul4.expose(ul4._hasattr, ["obj", "attrname"], {name: "hasattr"}); + ul4.expose(ul4._dir, ["obj"], {name: "dir"}); + ul4.expose(ul4._isundefined, ["obj"], {name: "isundefined"}); + ul4.expose(ul4._isdefined, ["obj"], {name: "isdefined"}); + ul4.expose(ul4._isnone, ["obj"], {name: "isnone"}); + ul4.expose(ul4._isbool, ["obj"], {name: "isbool"}); + ul4.expose(ul4._isint, ["obj"], {name: "isint"}); + ul4.expose(ul4._isfloat, ["obj"], {name: "isfloat"}); + ul4.expose(ul4._isstr, ["obj"], {name: "isstr"}); + ul4.expose(ul4._isdate, ["obj"], {name: "isdate"}); + ul4.expose(ul4._isdatetime, ["obj"], {name: "isdatetime"}); + ul4.expose(ul4._iscolor, ["obj"], {name: "iscolor"}); + ul4.expose(ul4._istimedelta, ["obj"], {name: "istimedelta"}); + ul4.expose(ul4._ismonthdelta, ["obj"], {name: "ismonthdelta"}); + ul4.expose(ul4._istemplate, ["obj"], {name: "istemplate"}); + ul4.expose(ul4._isfunction, ["obj"], {name: "isfunction"}); + ul4.expose(ul4._islist, ["obj"], {name: "islist"}); + ul4.expose(ul4._isanyset, ["obj"], {name: "isset"}); + ul4.expose(ul4._isdict, ["obj"], {name: "isdict"}); + ul4.expose(ul4._isexception, ["obj"], {name: "isexception"}); + ul4.expose(ul4._asjson, ["obj"], {name: "asjson"}); + ul4.expose(ul4._fromjson, ["string"], {name: "fromjson"}); + ul4.expose(ul4._asul4on, ["obj"], {name: "asul4on"}); + ul4.expose(ul4._fromul4on, ["string"], {name: "fromul4on"}); + ul4.expose(ul4.now, []); + ul4.expose(ul4.utcnow, []); + ul4.expose(ul4.today, []); + ul4.expose(ul4._enumerate, ["iterable", "start=", 0], {name: "enumerate"}); + ul4.expose(ul4._isfirst, ["iterable"], {name: "isfirst"}); + ul4.expose(ul4._islast, ["iterable"], {name: "islast"}); + ul4.expose(ul4._isfirstlast, ["iterable"], {name: "isfirstlast"}); + ul4.expose(ul4._enumfl, ["iterable", "start=", 0], {name: "enumfl"}); + ul4.expose(ul4._abs, ["number"], {name: "abs"}); + ul4.expose(ul4._date, ["year", "month", "day"], {name: "date"}); + ul4.expose(ul4._datetime, ["year", "month", "day", "hour=", 0, "minute=", 0, "second=", 0, "microsecond=", 0], {name: "datetime"}); + ul4.expose(ul4._timedelta, ["days=", 0, "seconds=", 0, "microseconds=", 0], {name: "timedelta"}); + ul4.expose(ul4._monthdelta, ["months=", 0], {name: "monthdelta"}); + ul4.expose(ul4._rgb, ["r", "g", "b", "a=", 1.0], {name: "rgb"}); + ul4.expose(ul4._hls, ["h", "l", "s", "a=", 1.0], {name: "hls"}); + ul4.expose(ul4._hsv, ["h", "s", "v", "a=", 1.0], {name: "hsv"}); + ul4.expose(ul4._xmlescape, ["obj"], {name: "xmlescape"}); + ul4.expose(ul4._csv, ["obj"], {name: "csv"}); + ul4.expose(ul4._chr, ["i"], {name: "chr"}); + ul4.expose(ul4._ord, ["c"], {name: "ord"}); + ul4.expose(ul4._hex, ["number"], {name: "hex"}); + ul4.expose(ul4._oct, ["number"], {name: "oct"}); + ul4.expose(ul4._bin, ["number"], {name: "bin"}); + ul4.expose(ul4._min, ["*obj"], {name: "min"}); + ul4.expose(ul4._max, ["*obj"], {name: "max"}); + ul4.expose(ul4._sum, ["iterable", "start=", 0], {name: "sum"}); + ul4.expose(ul4._first, ["iterable", "default=", null], {name: "first"}); + ul4.expose(ul4._last, ["iterable", "default=", null], {name: "last"}); + ul4.expose(ul4._sorted, ["iterable", "key=", null, "reverse=", false], {name: "sorted", needscontext: true}); + ul4.expose(ul4._range, ["*args"], {name: "range"}); + ul4.expose(ul4._slice, ["*args"], {name: "slice"}); + ul4.expose(ul4._urlquote, ["string"], {name: "urlquote"}); + ul4.expose(ul4._urlunquote, ["string"], {name: "urlunquote"}); + ul4.expose(ul4._reversed, ["sequence"], {name: "reversed"}); + ul4.expose(ul4._random, [], {name: "random"}); + ul4.expose(ul4._randrange, ["*args"], {name: "randrange"}); + ul4.expose(ul4._randchoice, ["sequence"], {name: "randchoice"}); + ul4.expose(ul4._round, ["x", "digit=", 0], {name: "round"}); + ul4.expose(ul4._md5, ["string"], {name: "md5"}); + + // Functions implementing UL4 methods + ul4._count = function _count(obj, sub, start=null, end=null) + { + if (start < 0) + start += obj.length; + if (start === null) + start = 0; + + if (end < 0) + end += obj.length; + if (end === null) + end = obj.length; + + let isstr = ul4._isstr(obj); + + if (isstr && !sub.length) + { + if (end < 0 || start > obj.length || start > end) + return 0; + let result = end - start + 1; + if (result > obj.length + 1) + result = obj.length + 1; + return result; + } + + start = ul4._bound(start, obj.length); + end = ul4._bound(end, obj.length); + + let count = 0; + if (ul4._islist(obj)) + { + for (let i = start; i < end; ++i) + { + if (ul4._eq(obj[i], sub)) + ++count; + } + return count; + } + else // string + { + let lastIndex = start; + + for (;;) + { + lastIndex = obj.indexOf(sub, lastIndex); + if (lastIndex == -1) + break; + if (lastIndex + sub.length > end) + break; + ++count; + lastIndex += sub.length; + } + return count; + } + }; + + ul4._find = function _find(obj, sub, start=null, end=null) + { + if (start < 0) + start += obj.length; + if (start === null) + start = 0; + if (end < 0) + end += obj.length; + if (end === null) + end = obj.length; + start = ul4._bound(start, obj.length); + end = ul4._bound(end, obj.length); + + if (start !== 0 || end !== obj.length) + { + if (typeof(obj) == "string") + obj = obj.substring(start, end); + else + obj = obj.slice(start, end); + } + let result = obj.indexOf(sub); + if (result !== -1) + result += start; + return result; + }; + + ul4._rfind = function _rfind(obj, sub, start=null, end=null) + { + if (start < 0) + start += obj.length; + if (start === null) + start = 0; + if (end < 0) + end += obj.length; + if (end === null) + end = obj.length; + start = ul4._bound(start, obj.length); + end = ul4._bound(end, obj.length); + + if (start !== 0 || end !== obj.length) + { + if (typeof(obj) == "string") + obj = obj.substring(start, end); + else + obj = obj.slice(start, end); + } + let result = obj.lastIndexOf(sub); + if (result !== -1) + result += start; + return result; + }; + + ul4._week4format = function _week(obj, firstweekday=null) + { + if (firstweekday === null) + firstweekday = 0; + else + firstweekday %= 7; + + let yearday = ul4.DateTimeProtocol.yearday(obj)+6; + let jan1 = new Date(obj.getFullYear(), 0, 1); + let jan1weekday = jan1.getDay(); + if (--jan1weekday < 0) + jan1weekday = 6; + + while (jan1weekday != firstweekday) + { + --yearday; + if (++jan1weekday == 7) + jan1weekday = 0; + } + return Math.floor(yearday/7); + }; + + ul4._isleap = function _isleap(obj) + { + return new Date(obj.getFullYear(), 1, 29).getMonth() === 1; + }; + + ul4._update = function _update(obj, others, kwargs) + { + if (!ul4._isdict(obj)) + throw new ul4.TypeError("update() requires a dict"); + for (let i = 0; i < others.length; ++i) + { + let other = others[i]; + if (ul4._ismap(other)) + { + other.forEach(function(value, key) { + ul4._setmap(obj, key, value); + }); + } + else if (ul4._isobject(other)) + { + for (let key in other) + ul4._setmap(obj, key, other[key]); + } + else if (ul4._islist(other)) + { + for (let i = 0; i < other.length; ++i) + { + let item = other[i]; + if (!ul4._islist(item) || (item.length != 2)) + throw new ul4.TypeError("update() requires a dict or a list of (key, value) pairs"); + ul4._setmap(obj, item[0], item[1]); + } + } + else + throw new ul4.TypeError("update() requires a dict or a list of (key, value) pairs"); + } + kwargs.forEach(function(value, key) { + ul4._setmap(obj, key, value); + }); + return null; + }; + + ul4.Color = class Color extends ul4.Proto + { + constructor(r=0, g=0, b=0, a=255) + { + super(); + this._r = r; + this._g = g; + this._b = b; + this._a = a; + } + + __repr__() + { + let r = ul4._lpad(this._r.toString(16), "0", 2); + let g = ul4._lpad(this._g.toString(16), "0", 2); + let b = ul4._lpad(this._b.toString(16), "0", 2); + let a = ul4._lpad(this._a.toString(16), "0", 2); + if (this._a !== 0xff) + { + if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1] && a[0] === a[1]) + return "#" + r[0] + g[0] + b[0] + a[0]; + else + return "#" + r + g + b + a; + } + else + { + if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1]) + return "#" + r[0] + g[0] + b[0]; + else + return "#" + r + g + b; + } + } + + __str__() + { + if (this._a !== 0xff) + { + return "rgba(" + this._r + ", " + this._g + ", " + this._b + ", " + (this._a/255) + ")"; + } + else + { + let r = ul4._lpad(this._r.toString(16), "0", 2); + let g = ul4._lpad(this._g.toString(16), "0", 2); + let b = ul4._lpad(this._b.toString(16), "0", 2); + if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1]) + return "#" + r[0] + g[0] + b[0]; + else + return "#" + r + g + b; + } + } + + __iter__() + { + return { + obj: this, + index: 0, + next: function() { + if (this.index == 0) + { + ++this.index; + return {value: this.obj._r, done: false}; + } + else if (this.index == 1) + { + ++this.index; + return {value: this.obj._g, done: false}; + } + else if (this.index == 2) + { + ++this.index; + return {value: this.obj._b, done: false}; + } + else if (this.index == 3) + { + ++this.index; + return {value: this.obj._a, done: false}; + } + else + return {done: true}; + } + }; + } + + __getattr__(attrname) + { + let self = this; + switch (attrname) + { + case "r": + let r = function r(){ return self._r; }; + ul4.expose(r, []); + return r; + case "g": + let g = function g(){ return self._g; }; + ul4.expose(g, []); + return g; + case "b": + let b = function b(){ return self._b; }; + ul4.expose(b, []); + return b; + case "a": + let a = function a(){ return self._a; }; + ul4.expose(a, []); + return a; + case "lum": + let lum = function lum(){ return self.lum(); }; + ul4.expose(lum, []); + return lum; + case "hls": + let hls = function hls(){ return self.hls(); }; + ul4.expose(hls, []); + return hls; + case "hlsa": + let hlsa = function hlsa(){ return self.hlsa(); }; + ul4.expose(hlsa, []); + return hlsa; + case "hsv": + let hsv = function hsv(){ return self.hsv(); }; + ul4.expose(hsv, []); + return hsv; + case "hsva": + let hsva = function hsva(){ return self.hsva(); }; + ul4.expose(hsva, []); + return hsva; + case "witha": + let witha = function witha(a){ return self.witha(a); }; + ul4.expose(witha, ["a"]); + return witha; + case "withlum": + let withlum = function withlum(lum){ return self.withlum(lum); }; + ul4.expose(withlum, ["lum"]); + return withlum; + case "abslum": + let abslum = function abslum(lum){ return self.abslum(lum); }; + ul4.expose(abslum, ["lum"]); + return abslum; + case "rellum": + let rellum = function rellum(lum){ return self.rellum(lum); }; + ul4.expose(rellum, ["lum"]); + return rellum; + default: + throw new ul4.AttributeError(this, attrname); + } + } + + __getitem__(key) + { + let orgkey = key; + if (key < 0) + key += 4; + switch (key) + { + case 0: + return this._r; + case 1: + return this._g; + case 2: + return this._b; + case 3: + return this._a; + default: + throw new ul4.IndexError(this, orgkey); + } + } + + __eq__(other) + { + if (other instanceof ul4.Color) + return this._r == other._r && this._g == other._g && this._b == other._b && this._a == other._a; + return false; + } + + r() + { + return this._r; + } + + g() + { + return this._g; + } + + b() + { + return this._b; + } + + a() + { + return this._a; + } + + lum() + { + return this.hls()[1]; + } + + hls() + { + let r = this._r/255.0; + let g = this._g/255.0; + let b = this._b/255.0; + let maxc = Math.max(r, g, b); + let minc = Math.min(r, g, b); + let h, l, s; + let rc, gc, bc; + + l = (minc+maxc)/2.0; + if (minc == maxc) + return [0.0, l, 0.0]; + if (l <= 0.5) + s = (maxc-minc) / (maxc+minc); + else + s = (maxc-minc) / (2.0-maxc-minc); + rc = (maxc-r) / (maxc-minc); + gc = (maxc-g) / (maxc-minc); + bc = (maxc-b) / (maxc-minc); + if (r == maxc) + h = bc-gc; + else if (g == maxc) + h = 2.0+rc-bc; + else + h = 4.0+gc-rc; + h = (h/6.0) % 1.0; + return [h, l, s]; + } + + hlsa() + { + let hls = this.hls(); + return hls.concat(this._a/255.0); + } + + hsv() + { + let r = this._r/255.0; + let g = this._g/255.0; + let b = this._b/255.0; + let maxc = Math.max(r, g, b); + let minc = Math.min(r, g, b); + let v = maxc; + if (minc == maxc) + return [0.0, 0.0, v]; + let s = (maxc-minc) / maxc; + let rc = (maxc-r) / (maxc-minc); + let gc = (maxc-g) / (maxc-minc); + let bc = (maxc-b) / (maxc-minc); + let h; + if (r == maxc) + h = bc-gc; + else if (g == maxc) + h = 2.0+rc-bc; + else + h = 4.0+gc-rc; + h = (h/6.0) % 1.0; + return [h, s, v]; + } + + hsva() + { + let hsv = this.hsv(); + return hsv.concat(this._a/255.0); + } + + witha(a) + { + if (typeof(a) !== "number") + throw new ul4.TypeError("witha() requires a number"); + return new ul4.Color(this._r, this._g, this._b, a); + } + + withlum(lum) + { + if (typeof(lum) !== "number") + throw new ul4.TypeError("witha() requires a number"); + let hlsa = this.hlsa(); + return ul4._hls(hlsa[0], lum, hlsa[2], hlsa[3]); + } + + ul4type() + { + return "color"; + } + }; + + ul4.expose(ul4.Color.prototype.r, []); + ul4.expose(ul4.Color.prototype.g, []); + ul4.expose(ul4.Color.prototype.b, []); + ul4.expose(ul4.Color.prototype.a, []); + ul4.expose(ul4.Color.prototype.lum, []); + ul4.expose(ul4.Color.prototype.hls, []); + ul4.expose(ul4.Color.prototype.hlsa, []); + ul4.expose(ul4.Color.prototype.hsv, []); + ul4.expose(ul4.Color.prototype.hsva, []); + ul4.expose(ul4.Color.prototype.witha, ["a"]); + ul4.expose(ul4.Color.prototype.withlum, ["lum"]); + + const _js_Date = Date; + + ul4.Date = class Date extends ul4.Proto + { + constructor(year, month, day) + { + super(); + this._date = new _js_Date(year, month-1, day); + } + + __repr__() + { + return '@(' + this.__str__() + ")"; + } + + __str__() + { + return ul4._lpad(this._date.getFullYear(), "0", 4) + "-" + ul4._lpad(this._date.getMonth()+1, "0", 2) + "-" + ul4._lpad(this._date.getDate(), "0", 2); + } + + __eq__(other) + { + if (other instanceof ul4.Date) + return this._date.getTime() === other._date.getTime(); + return false; + } + + __lt__(other) + { + if (other instanceof ul4.Date) + return this._date < other._date; + ul4._unorderable("<", this, other); + } + + __le__(other) + { + if (other instanceof ul4.Date) + return this._date <= other._date; + ul4._unorderable("<=", this, other); + } + + __gt__(other) + { + if (other instanceof ul4.Date) + return this._date > other._date; + ul4._unorderable(">", this, other); + } + + __ge__(other) + { + if (other instanceof ul4.Date) + return this._date >= other._date; + ul4._unorderable(">=", this, other); + } + + year() + { + return this._date.getFullYear(); + } + + month() + { + return this._date.getMonth()+1; + } + + day() + { + return this._date.getDate(); + } + + ul4type() + { + return "date"; + } + }; + + + ul4.TimeDelta = class TimeDelta extends ul4.Proto + { + constructor(days=0, seconds=0, microseconds=0) + { + super(); + let total_microseconds = Math.floor((days * 86400 + seconds)*1000000 + microseconds); + + microseconds = ul4.ModAST.prototype._do(total_microseconds, 1000000); + let total_seconds = Math.floor(total_microseconds / 1000000); + seconds = ul4.ModAST.prototype._do(total_seconds, 86400); + days = Math.floor(total_seconds / 86400); + if (seconds < 0) + { + seconds += 86400; + --days; + } + + this._microseconds = microseconds; + this._seconds = seconds; + this._days = days; + } + + __repr__() + { + let v = [], first = true; + v.push("timedelta("); + if (this._days) + { + v.push("days=" + this._days); + first = false; + } + if (this._seconds) + { + if (!first) + v.push(", "); + v.push("seconds=" + this._seconds); + first = false; + } + if (this._microseconds) + { + if (!first) + v.push(", "); + v.push("microseconds=" + this._microseconds); + } + v.push(")"); + return v.join(""); + } + + __str__() + { + let v = []; + if (this._days) + { + v.push(this._days + " day"); + if (this._days !== -1 && this._days !== 1) + v.push("s"); + v.push(", "); + } + let seconds = this._seconds % 60; + let minutes = Math.floor(this._seconds / 60); + let hours = Math.floor(minutes / 60); + minutes = minutes % 60; + + v.push("" + hours); + v.push(":"); + v.push(ul4._lpad(minutes.toString(), "0", 2)); + v.push(":"); + v.push(ul4._lpad(seconds.toString(), "0", 2)); + if (this._microseconds) + { + v.push("."); + v.push(ul4._lpad(this._microseconds.toString(), "0", 6)); + } + return v.join(""); + } + + __bool__() + { + return this._days !== 0 || this._seconds !== 0 || this._microseconds !== 0; + } + + __abs__() + { + return this._days < 0 ? new ul4.TimeDelta(-this._days, -this._seconds, -this._microseconds) : this; + } + + __eq__(other) + { + if (other instanceof ul4.TimeDelta) + return (this._days === other._days) && (this._seconds === other._seconds) && (this._microseconds === other._microseconds); + return false; + } + + __lt__(other) + { + if (other instanceof ul4.TimeDelta) + { + if (this._days != other._days) + return this._days < other._days; + if (this._seconds != other._seconds) + return this._seconds < other._seconds; + return this._microseconds < other._microseconds; + } + ul4._unorderable("<", this, other); + } + + __le__(other) + { + if (other instanceof ul4.TimeDelta) + { + if (this._days != other._days) + return this._days < other._days; + if (this._seconds != other._seconds) + return this._seconds < other._seconds; + return this._microseconds <= other._microseconds; + } + ul4._unorderable("<=", this, other); + } + + __gt__(other) + { + if (other instanceof ul4.TimeDelta) + { + if (this._days != other._days) + return this._days > other._days; + if (this._seconds != other._seconds) + return this._seconds > other._seconds; + return this._microseconds > other._microseconds; + } + ul4._unorderable(">", this, other); + } + + __ge__(other) + { + if (other instanceof ul4.TimeDelta) + { + if (this._days != other._days) + return this._days > other._days; + if (this._seconds != other._seconds) + return this._seconds > other._seconds; + return this._microseconds >= other._microseconds; + } + ul4._unorderable(">=", this, other); + } + + __neg__() + { + return new ul4.TimeDelta(-this._days, -this._seconds, -this._microseconds); + } + + adddate(date, days) + { + let year = date._date.getFullYear(); + let month = date._date.getMonth(); + let day = date._date.getDate() + days; + return new ul4.Date(year, month, day); + } + + _adddatetime(date, days, seconds, microseconds) + { + let year = date.getFullYear(); + let month = date.getMonth(); + let day = date.getDate() + days; + let hour = date.getHours(); + let minute = date.getMinutes(); + let second = date.getSeconds() + seconds; + let millisecond = date.getMilliseconds() + microseconds/1000; + return new Date(year, month, day, hour, minute, second, millisecond); + } + + __add__(other) + { + if (other instanceof ul4.TimeDelta) + return new ul4.TimeDelta(this._days + other._days, this._seconds + other._seconds, this._microseconds + other._microseconds); + else if (ul4._isdate(other)) + return this._adddate(other, this._days); + else if (ul4._isdatetime(other)) + return this._adddatetime(other, this._days, this._seconds, this._microseconds); + throw new ul4.TypeError(ul4._type(this) + " + " + ul4._type(other) + " not supported"); + } + + __radd__(other) + { + if (ul4._isdate(other)) + return this._adddate(other, this._days); + else if (ul4._isdatetime(other)) + return this._adddatetime(other, this._days, this._seconds, this._microseconds); + throw new ul4.TypeError(ul4._type(this) + " + " + ul4._type(other) + " not supported"); + } + + __sub__(other) + { + if (other instanceof ul4.TimeDelta) + return new ul4.TimeDelta(this._days - other._days, this._seconds - other._seconds, this._microseconds - other._microseconds); + throw new ul4.TypeError(ul4._type(this) + " - " + ul4._type(other) + " not supported"); + } + + __rsub__(other) + { + if (ul4._isdate(other)) + return this._adddate(other, -this._days); + else if (ul4._isdatetime(other)) + return this._adddatetime(other, -this._days, -this._seconds, -this._microseconds); + throw new ul4.TypeError(ul4._type(this) + " - " + ul4._type(other) + " not supported"); + } + + __mul__(other) + { + if (typeof(other) === "number") + return new ul4.TimeDelta(this._days * other, this._seconds * other, this._microseconds * other); + throw new ul4.TypeError(ul4._type(this) + " * " + ul4._type(other) + " not supported"); + } + + __rmul__(other) + { + if (typeof(other) === "number") + return new ul4.TimeDelta(this._days * other, this._seconds * other, this._microseconds * other); + throw new ul4.TypeError(ul4._type(this) + " * " + ul4._type(other) + " not supported"); + } + + __truediv__(other) + { + if (typeof(other) === "number") + { + return new ul4.TimeDelta(this._days / other, this._seconds / other, this._microseconds / other); + } + else if (other instanceof ul4.TimeDelta) + { + let myValue = this._days; + let otherValue = other._days; + let hasSeconds = this._seconds || other._seconds; + let hasMicroseconds = this._microseconds || other._microseconds; + if (hasSeconds || hasMicroseconds) + { + myValue = myValue*86400+this._seconds; + otherValue = otherValue*86400 + other._seconds; + if (hasMicroseconds) + { + myValue = myValue * 1000000 + this._microseconds; + otherValue = otherValue * 1000000 + other._microseconds; + } + } + return myValue/otherValue; + } + throw new ul4.TypeError(ul4._type(this) + " / " + ul4._type(other) + " not supported"); + } + + __getattr__(attrname) + { + let self = this; + switch (attrname) + { + case "days": + let days = function days(){ return self._days; }; + ul4.expose(days, []); + return days; + case "seconds": + let seconds = function seconds(){ return self._seconds; }; + ul4.expose(seconds, []); + return seconds; + case "microseconds": + let microseconds = function microseconds(){ return self._microseconds; }; + ul4.expose(microseconds, []); + return microseconds; + default: + throw new ul4.AttributeError(this, attrname); + } + } + + days() + { + return this._days; + } + + seconds() + { + return this._seconds; + } + + microseconds() + { + return this._microseconds; + } + + ul4type() + { + return "timedelta"; + } + }; + + + ul4.MonthDelta = class MonthDelta extends ul4.Proto + { + constructor(months=0) + { + super(); + this._months = months; + } + + __repr__() + { + if (!this._months) + return "monthdelta()"; + return "monthdelta(" + this._months + ")"; + } + + __str__() + { + if (this._months) + { + if (this._months !== -1 && this._months !== 1) + return this._months + " months"; + return this._months + " month"; + } + return "0 months"; + } + + toString() + { + return this.__str__(); + } + + __bool__() + { + return this._months !== 0; + } + + __abs__() + { + return this._months < 0 ? new ul4.MonthDelta(-this._months) : this; + } + + __eq__(other) + { + if (other instanceof MonthDelta) + return this._months === other._months; + return false; + } + + __lt__(other) + { + if (other instanceof ul4.MonthDelta) + return this._months < other._months; + ul4._unorderable("<", this, other); + } + + __le__(other) + { + if (other instanceof ul4.MonthDelta) + return this._months <= other._months; + ul4._unorderable("<=", this, other); + } + + __gt__(other) + { + if (other instanceof ul4.MonthDelta) + return this._months > other._months; + ul4._unorderable(">", this, other); + } + + __ge__(other) + { + if (other instanceof ul4.MonthDelta) + return this._months >= other._months; + ul4._unorderable(">=", this, other); + } + + __neg__() + { + return new ul4.MonthDelta(-this._months); + } + + _adddate(date, months) + { + let result = this._adddatetime(date._date, months); + return new ul4.Date(result.getFullYear(), result.getMonth()+1, result.getDate()); + } + + _adddatetime(date, months) + { + let year = date.getFullYear(); + let month = date.getMonth() + months; + let day = date.getDate(); + let hour = date.getHours(); + let minute = date.getMinutes(); + let second = date.getSeconds(); + let millisecond = date.getMilliseconds(); + + while (true) + { + // As the month might be out of bounds, we have to find out, what the real target month is + let targetmonth = new Date(year, month, 1, hour, minute, second, millisecond).getMonth(); + let result = new Date(year, month, day, hour, minute, second, millisecond); + if (result.getMonth() === targetmonth) + return result; + --day; + } + } + + __add__(other) + { + if (ul4._ismonthdelta(other)) + return new ul4.MonthDelta(this._months + other._months); + else if (ul4._isdate(other)) + return this._adddate(other, this._months); + else if (ul4._isdatetime(other)) + return this._adddatetime(other, this._months); + throw new ul4.ArgumentError(ul4._type(this) + " + " + ul4._type(other) + " not supported"); + } + + __radd__(other) + { + if (ul4._isdate(other)) + return this._adddate(other, this._months); + else if (ul4._isdatetime(other)) + return this._adddatetime(other, this._months); + throw new ul4.ArgumentError(ul4._type(this) + " + " + ul4._type(other) + " not supported"); + } + + __sub__(other) + { + if (ul4._ismonthdelta(other)) + return new ul4.MonthDelta(this._months - other._months); + throw new ul4.ArgumentError(ul4._type(this) + " - " + ul4._type(other) + " not supported"); + } + + __rsub__(other) + { + if (ul4._isdate(other)) + return this._adddate(other, -this._months); + else if (ul4._isdatetime(other)) + return this._adddatetime(other, -this._months); + throw new ul4.ArgumentError(ul4._type(this) + " - " + ul4._type(other) + " not supported"); + } + + __mul__(other) + { + if (typeof(other) === "number") + return new ul4.MonthDelta(this._months * Math.floor(other)); + throw new ul4.ArgumentError(ul4._type(this) + " * " + ul4._type(other) + " not supported"); + } + + __rmul__(other) + { + if (typeof(other) === "number") + return new ul4.MonthDelta(this._months * Math.floor(other)); + throw new ul4.ArgumentError(ul4._type(this) + " * " + ul4._type(other) + " not supported"); + } + + __floordiv__(other) + { + if (typeof(other) === "number") + return new ul4.MonthDelta(Math.floor(this._months / other)); + else if (ul4._ismonthdelta(other)) + return Math.floor(this._months / other._months); + throw new ul4.ArgumentError(ul4._type(this) + " // " + ul4._type(other) + " not supported"); + } + + __truediv__(other) + { + if (ul4._ismonthdelta(other)) + return this._months / other._months; + throw new ul4.ArgumentError(ul4._type(this) + " / " + ul4._type(other) + " not supported"); + } + + __getattr__(attrname) + { + let self = this; + switch (attrname) + { + case "months": + let months = function months(){ return self._months; }; + ul4.expose(months, []); + return months; + default: + throw new ul4.AttributeError(this, attrname); + } + } + + months() + { + return this._months; + } + + ul4type() + { + return "monthdelta"; + } + }; + + const classes = [ + ul4.TextAST, + ul4.IndentAST, + ul4.LineEndAST, + ul4.ConstAST, + ul4.SeqItemAST, + ul4.UnpackSeqItemAST, + ul4.DictItemAST, + ul4.UnpackDictItemAST, + ul4.PosArgAST, + ul4.KeywordArgAST, + ul4.UnpackListArgAST, + ul4.UnpackDictArgAST, + ul4.ListAST, + ul4.ListCompAST, + ul4.DictAST, + ul4.DictCompAST, + ul4.SetAST, + ul4.SetCompAST, + ul4.GenExprAST, + ul4.VarAST, + ul4.NotAST, + ul4.NegAST, + ul4.BitNotAST, + ul4.IfAST, + ul4.ReturnAST, + ul4.PrintAST, + ul4.PrintXAST, + ul4.ItemAST, + ul4.IsAST, + ul4.IsNotAST, + ul4.EQAST, + ul4.NEAST, + ul4.LTAST, + ul4.LEAST, + ul4.GTAST, + ul4.GEAST, + ul4.NotContainsAST, + ul4.ContainsAST, + ul4.AddAST, + ul4.SubAST, + ul4.MulAST, + ul4.FloorDivAST, + ul4.TrueDivAST, + ul4.ModAST, + ul4.ShiftLeftAST, + ul4.ShiftRightAST, + ul4.BitAndAST, + ul4.BitXOrAST, + ul4.BitOrAST, + ul4.AndAST, + ul4.OrAST, + ul4.SliceAST, + ul4.AttrAST, + ul4.CallAST, + ul4.RenderAST, + ul4.RenderXAST, + ul4.RenderBlockAST, + ul4.RenderBlocksAST, + ul4.SetVarAST, + ul4.AddVarAST, + ul4.SubVarAST, + ul4.MulVarAST, + ul4.TrueDivVarAST, + ul4.FloorDivVarAST, + ul4.ModVarAST, + ul4.ShiftLeftVarAST, + ul4.ShiftRightVarAST, + ul4.BitAndVarAST, + ul4.BitXOrVarAST, + ul4.BitOrVarAST, + ul4.ForBlockAST, + ul4.WhileBlockAST, + ul4.BreakAST, + ul4.ContinueAST, + ul4.CondBlockAST, + ul4.IfBlockAST, + ul4.ElIfBlockAST, + ul4.ElseBlockAST, + ul4.SignatureAST, + ul4.Template + ]; + + for (let i = 0; i < classes.length; ++i) + { + let constructor = classes[i]; + let ul4onname = constructor.name; + if (ul4onname.substr(ul4onname.length-3) === "AST") + ul4onname = ul4onname.substr(0, ul4onname.length-3); + ul4onname = ul4onname.toLowerCase(); + constructor.prototype.type = ul4onname; + ul4.register("de.livinglogic.ul4." + ul4onname, constructor); + } \ No newline at end of file diff --git a/test/node_test.js b/test/node_test.js deleted file mode 100644 index 85d9733..0000000 --- a/test/node_test.js +++ /dev/null @@ -1,62 +0,0 @@ -let livingSDK; -let config; -let defaultSettings = { -} -if (typeof module === 'object' && module.exports){ - livingSDK = require('../src/livingSDK'); - config = require('./config'); -} else { - config = this.configs; - livingSDK = this.livingSDK; -} -describe ('login', () => { - it ('login', () => { - let lsdk = new livingSDK(defaultSettings, config.username, config.password); - return lsdk.login().then((res) => console.log(res)); - }); - it ('login and get function', () => { - let lsdk = new livingSDK(defaultSettings, config.username, config.password); - lsdk.session = (function() {return new Promise ((resolve, reject) => {resolve(123)})})(); - return lsdk.get(config.appId).then((LAAPI) => { - return LAAPI - }); - }); - it ('insert a entry', () => { - let lsdk = new livingSDK(defaultSettings, config.username, config.password); - return lsdk.get(config.appId).then((LAAPI) => { - let app = LAAPI.get('datasources').get('default').app; - return app.insert({ - mitarbeiter: 'Einstein', - interessensgebiete: ['kaffee'] - }); - }) - }); - it ('update first entry', () => { - let lsdk = new livingSDK(defaultSettings, config.username, config.password); - return lsdk.get(config.appId).then((LAAPI) => { - let app = LAAPI.get('datasources').get('default').app; - let records = app.records.values(); - let last; - for (let d of records) { - last = d; - break; - } - return last.update({ - mitarbeiter: 'Time: ' + Date.now(), - interessensgebiete: ['kaffee'] - }) - }) - }); - it ('delete a entry', () => { - let lsdk = new livingSDK(defaultSettings, config.username, config.password); - return lsdk.get(config.appId).then((LAAPI) => { - let app = LAAPI.get('datasources').get('default').app; - let records = app.records.values(); - let last; - for (let d of records) { - last = d; - } - return last.delete(); - }) - }) -}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..95254bd --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,16 @@ +{ + "include": [ + "./src/**/*.ts" + ], + "compilerOptions": { + "rootDir": "./src", + "target": "es2015", + "module": "es2015", + "declaration": true, + "outDir": "./dist/es2015", + "removeComments": true, + "moduleResolution": "node", + "esModuleInterop": true, + "sourceMap": true + } + } \ No newline at end of file