@naanlang/naan 1.3.1 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,7 +36,7 @@
36
36
  *
37
37
  */
38
38
 
39
- var CurrentCacheName = "Naanlang-1.3.1+1";
39
+ var CurrentCacheName = "Naanlang-1.3.2+1";
40
40
 
41
41
 
42
42
  //
@@ -92,18 +92,18 @@ var terminated; // flag that this service worker
92
92
  var pubVersion = event.data.hereIsMyVersion;
93
93
  var sourceId = event.source.id; // client id of sender of message
94
94
  msgPorts[sourceId] = msgport;
95
- console.log("[1.3.1+1] received new msgport for", sourceId, pubID, "-", pubVersion);
96
- if (pubVersion != "1.3.1+1") {
95
+ console.log("[1.3.2+1] received new msgport for", sourceId, pubID, "-", pubVersion);
96
+ if (pubVersion != "1.3.2+1") {
97
97
  if (upgradeMsgPorts) { // if not activated
98
- console.log("[1.3.1+1] update pending for", sourceId);
98
+ console.log("[1.3.2+1] update pending for", sourceId);
99
99
  upgradeMsgPorts[sourceId] = msgport;
100
100
  }
101
101
  else {
102
102
  msgport.postMessage({ // notify new version available
103
103
  id: "upgrade",
104
- version: "1.3.1+1"
104
+ version: "1.3.2+1"
105
105
  });
106
- console.log("[1.3.1+1] update sent for:", sourceId);
106
+ console.log("[1.3.2+1] update sent for:", sourceId);
107
107
  }
108
108
  }
109
109
  Reaper(); // clean up obsolete info
@@ -134,10 +134,10 @@ var terminated; // flag that this service worker
134
134
  msgport.onmessage = function(msg) {
135
135
  msg = msg.data;
136
136
  if (msg.id == "skipWaiting") { // try to activate this SW now
137
- console.log("[1.3.1+1] attempting skipWaiting");
137
+ console.log("[1.3.2+1] attempting skipWaiting");
138
138
  self.skipWaiting();
139
139
  } else if (msg.id == "terminate") { // termiante this SW now
140
- console.log("[1.3.1+1] terminated");
140
+ console.log("[1.3.2+1] terminated");
141
141
  terminate();
142
142
  } else if (msg.id == "abortURL") { // abort an I/O transaction
143
143
  var href = new URL(msg.url).href;
@@ -150,7 +150,7 @@ var terminated; // flag that this service worker
150
150
  } else if (msg.id == "response") // response from fetch request
151
151
  processResponse(msg);
152
152
  else if (msg.id == "text") // just log some text
153
- console.log("[1.3.1+1] msg received:", msg.text);
153
+ console.log("[1.3.2+1] msg received:", msg.text);
154
154
  };
155
155
 
156
156
  // send text to IDE log
@@ -161,7 +161,7 @@ var terminated; // flag that this service worker
161
161
  // don't clutter the log
162
162
  msgport.postMessage({
163
163
  id: "text",
164
- text: "port received by 1.3.1+1",
164
+ text: "port received by 1.3.2+1",
165
165
  });
166
166
  */
167
167
  if (--pending === 0)
@@ -178,7 +178,7 @@ var terminated; // flag that this service worker
178
178
  includeUncontrolled: true
179
179
  }).then(function(clientList) {
180
180
  clientList.every(function(client) {
181
- console.log("[1.3.1+1] requesting new msgport for", client.id);
181
+ console.log("[1.3.2+1] requesting new msgport for", client.id);
182
182
  ++pending;
183
183
  client.postMessage({ // tell client(s) we need this fetch source
184
184
  msg: "Naan_need_fetch_port",
@@ -224,12 +224,12 @@ function Reaper() {
224
224
  clients[clientList[clidex].id] = clientList[clidex];
225
225
  for (var sourceId in msgPorts)
226
226
  if (!clients[sourceId]) {
227
- console.log("[1.3.1+1] source gone:", sourceId);
227
+ console.log("[1.3.2+1] source gone:", sourceId);
228
228
  delete msgPorts[sourceId]; // no longer a source
229
229
  }
230
230
  for (var clientId in fetchPorts)
231
231
  if (!clients[clientId]) {
232
- console.log("[1.3.1+1] client gone:", clientId);
232
+ console.log("[1.3.2+1] client gone:", clientId);
233
233
  delete fetchPorts[clientId]; // no longer a client
234
234
  }
235
235
  for (var fqdex = 0; fqdex < fetchQueue.length; ++fqdex) {
@@ -263,16 +263,16 @@ function ClearCaches() {
263
263
  return (Promise.all(
264
264
  cacheNames.map(function(cacheName) {
265
265
  if (cacheName != CurrentCacheName) {
266
- console.log('[1.3.1+1] deleting old cache:', cacheName);
266
+ console.log('[1.3.2+1] deleting old cache:', cacheName);
267
267
  return (caches.delete(cacheName));
268
268
  }
269
269
  })
270
270
  ));
271
271
  }).then(function() { // claim all clients
272
- console.log('[1.3.1+1] claiming clients');
272
+ console.log('[1.3.2+1] claiming clients');
273
273
  return (self.clients.claim());
274
274
  }).then(function() {
275
- console.log('[1.3.1+1] clients claimed');
275
+ console.log('[1.3.2+1] clients claimed');
276
276
  return (Promise.resolve(true));
277
277
  });
278
278
  return (promise);
@@ -315,7 +315,7 @@ function GetClientResponse(event, urlpath) {
315
315
  msgport.postMessage({
316
316
  id: "fetch",
317
317
  seq: seqno,
318
- version: "1.3.1+1",
318
+ version: "1.3.2+1",
319
319
  request: {
320
320
  method: event.request.method,
321
321
  url: event.request.url
@@ -363,7 +363,7 @@ function GetClientResponse(event, urlpath) {
363
363
  */
364
364
 
365
365
  self.addEventListener('install', function(event) {
366
- console.log("[1.3.1+1] install");
366
+ console.log("[1.3.2+1] install");
367
367
  self.skipWaiting();
368
368
  });
369
369
 
@@ -376,20 +376,20 @@ self.addEventListener('install', function(event) {
376
376
  */
377
377
 
378
378
  self.addEventListener('activate', function(event) {
379
- console.log("[1.3.1+1] activate");
379
+ console.log("[1.3.2+1] activate");
380
380
  self.clients.matchAll({ // for debugging, list controlled clients
381
381
  includeUncontrolled: true
382
382
  }).then(function(clientList) {
383
383
  var urls = clientList.map(function(client) {
384
384
  return (client.url);
385
385
  });
386
- console.log('[1.3.1+1] matching clients:', urls.join(', '));
386
+ console.log('[1.3.2+1] matching clients:', urls.join(', '));
387
387
  });
388
388
  var promise = ClearCaches().then(function() {
389
389
  for (var sourceId in upgradeMsgPorts) {
390
390
  upgradeMsgPorts[sourceId].postMessage({ // notify new version available
391
391
  id: "upgrade",
392
- version: "1.3.1+1"
392
+ version: "1.3.2+1"
393
393
  });
394
394
  }
395
395
  upgradeMsgPorts = false;
@@ -421,7 +421,7 @@ self.addEventListener('fetch', function(event) {
421
421
  var promise;
422
422
  var url = new URL(request.url);
423
423
  var nocache = request.method != "GET"
424
- || url.search.length !== 0 && url.searchParams.get("naanver") !== "ecae8a62f4a0ae0408f1cbd16082d4ea"
424
+ || url.search.length !== 0 && url.searchParams.get("naanver") !== "7ea12b22a1787cca6650606cb36818d6"
425
425
  || request.headers.get('range');
426
426
  if (url.pathname.startsWith("/run/")) {
427
427
  nocache = true;
@@ -455,7 +455,7 @@ self.addEventListener('fetch', function(event) {
455
455
  statusText: "Request Cancelled"
456
456
  }));
457
457
  }
458
- console.log("[1.3.1+1] fetch failed", request.url, e);
458
+ console.log("[1.3.2+1] fetch failed", request.url, e);
459
459
  return (new Response(undefined, {
460
460
  status: 404,
461
461
  statusText: "Fetch Failed"
@@ -154,7 +154,7 @@ closure TermHost(track, api, name, options, local target, nlregex, xtarg)
154
154
  // An error occurred on the WebSocket connection.
155
155
  target.ws.onerror = function onerror(e) {
156
156
  pending.signal(list(Error("websocket failed", e)))
157
- debuglog("ws error:", e)
157
+ debuglog("ws error")
158
158
  }
159
159
 
160
160
  // onclose
@@ -371,10 +371,13 @@ closure TrackedScope(track, scope, fs, rootpath, local trope) {
371
371
  "jpg": "image/jpeg",
372
372
  "js": "text/javascript",
373
373
  "json": "application/json",
374
+ "mov": "video/mp4",
374
375
  "mp3": "audio/mpeg",
375
376
  "mp4": "video/mp4",
376
377
  "nlg": "text/plain",
377
378
  "npk": "application/json",
379
+ "ogg": "video/ogg",
380
+ "png": "image/png",
378
381
  "svg": "image/svg+xml",
379
382
  "text": "text/plain",
380
383
  "txt": "text/plain",
@@ -83,6 +83,7 @@ function ContentTypeFromFileExt(filepath, local mimeType, encoding) {
83
83
  "nlg": "text/plain",
84
84
  "npk": "application/json",
85
85
  "ogg": "video/ogg",
86
+ "png": "image/png",
86
87
  "svg": "image/svg+xml",
87
88
  "text": "text/plain",
88
89
  "txt": "text/plain",
@@ -192,20 +193,15 @@ function JsonStringify(data) {
192
193
 
193
194
  jsScripts = { }; // script values become false on reload
194
195
 
195
- closure JsLoadScript(libpath, globalID, local savens, fpath, hostpath, pending, scriptTag) {
196
- global(jsScripts, js, JSpath)
196
+ closure JsLoadScript(libpath, globalID, local savens, hostpath, pending, scriptTag) {
197
+ global(jsScripts, JSpath, js)
197
198
  if jsScripts[libpath]
198
199
  return // already loaded
199
200
  savens = nsactive()
200
- if libpath.startsWith("/")
201
- fpath = libpath
202
- else
203
- fpath = "/".concat(libpath)
204
- hostpath = js.w.location.origin.concat(JSpath.dirname(js.w.location.pathname))
201
+ hostpath = js.w.location.origin.concat(JSpath.join(JSpath.dirname(js.w.location.pathname), libpath))
205
202
  if js.s.importScripts && tostring(js.s.importScripts) == "[Function importScripts]" {
206
- fpath = hostpath.concat(fpath)
207
203
  try {
208
- js.s.importScripts(fpath) // load in worker context
204
+ js.s.importScripts(hostpath) // load in worker context
209
205
  jsScripts[libpath] = js.s[globalID]
210
206
  } catch {
211
207
  debuglog("JsLoadScript:", libpath, "failed", exception)
@@ -214,7 +210,7 @@ closure JsLoadScript(libpath, globalID, local savens, fpath, hostpath, pending,
214
210
  } else if js.w { // load in browser context
215
211
  pending = new(nonce)
216
212
  scriptTag = js.w.document.createElement("script")
217
- scriptTag.src = hostpath.concat(fpath, requireQuery())
213
+ scriptTag.src = hostpath.concat(requireQuery())
218
214
  scriptTag.onload = function (event) {
219
215
  jsScripts[libpath] = js.w[globalID]
220
216
  pending.signal(js.w[globalID])
@@ -31,7 +31,8 @@
31
31
  * key: <data>
32
32
  * passphrase: <data> // optional
33
33
  * }
34
- * allowSelfSigned: <boolean> // allow a self-signed certificate at the servera
34
+ * allowSelfSigned: <boolean> // allow a self-signed certificate at the server
35
+ * streamHook: <proc> // called for incoming chunks of text/event-stream
35
36
  * debug: <boolean> // log errors and status results
36
37
  * }
37
38
  *
@@ -100,11 +101,26 @@ closure httpsApiReqOnce(url, options,
100
101
  pending = new(nonce)
101
102
  chunks = []
102
103
  request = nodeHttps.request(url, reqOptions, closure (response) {
104
+ // test if response is a SSE stream
105
+ function stream() { response.headers["content-type"].startsWith("text/event-stream") }
106
+
103
107
  response.on("data", function (chunk) {
104
- chunks.push(chunk)
108
+ if options.streamHook && stream()
109
+ call(options.streamHook, chunk) // got some data
110
+ else
111
+ chunks.push(chunk)
105
112
  })
106
- response.on("end", function (local content, error, headers) {
107
- content = js.g.Buffer.concat(chunks)
113
+ response.on("end", function (local state, content, error, headers) {
114
+ state = {
115
+ headers: response.headers
116
+ status: response.statusCode
117
+ contentType: response.headers["content-type"]
118
+ complete: response.complete
119
+ }
120
+ if options.streamHook && stream()
121
+ call(options.streamHook, false, state) // no more data
122
+ else
123
+ content = js.g.Buffer.concat(chunks)
108
124
  if response.statusCode < 200 || response.statusCode >= 299 { // 299 is "cancelled"
109
125
  if options.debug
110
126
  debuglog("HttpsApiRequest status:", url, response.statusCode, "message:", content)
@@ -120,7 +136,7 @@ closure httpsApiReqOnce(url, options,
120
136
  error = Error("HttpsApiRequest decode:", url, error)
121
137
  else
122
138
  content = new(content)
123
- if array(content) { // deencapsulate to get API result
139
+ if array(content) { // naan: decapsulate to get API result
124
140
  content = totuple(content)
125
141
  error = content.0
126
142
  content = content.1
@@ -129,11 +145,7 @@ closure httpsApiReqOnce(url, options,
129
145
  }
130
146
  else
131
147
  error = Error("HttpsApiRequest terminated prematurely:", url, response.statusCode)
132
- pending.signal(list(error, content, {
133
- headers: response.headers
134
- status: response.statusCode
135
- contentType: response.headers["content-type"]
136
- }))
148
+ pending.signal(list(error, content, state))
137
149
  })
138
150
  })
139
151
  request.on("error", function hre(error) {
@@ -149,6 +161,66 @@ closure httpsApiReqOnce(url, options,
149
161
  };
150
162
 
151
163
 
164
+ /*
165
+ * sseParserFactory
166
+ *
167
+ * Returns an Server-Sent Events parser that calls the specified message procedure each time an event
168
+ * is recognized. Call the returned parser object's write method to add data for parsing.
169
+ *
170
+ */
171
+
172
+ closure sseParserFactory(message, local parser) {
173
+ global()
174
+ parser = new(object, this)
175
+ parser.buffer = ""
176
+ parser.eomrx = RegExp("(?:\\r(?!\\n)|\\r\\n|\\n){2}")
177
+ parser.eolrx = RegExp("(?:\\r(?!\\n)|\\r\\n|\\n){1}")
178
+ parser.divrx = RegExp("([^:]*)[:] ?(.*)")
179
+
180
+ // write
181
+ //
182
+ // Add a string to the parser input, calling message for any completed messages.
183
+ //
184
+ parser.write = function write(text,
185
+ local messages, msg, output, line, found, field, value) {
186
+ parser.buffer = parser.buffer.concat(text)
187
+ messages = parser.buffer.split(parser.eomrx)
188
+ loop {
189
+ msg = messages.shift()
190
+ if messages.length == 0 {
191
+ parser.buffer = msg
192
+ break
193
+ }
194
+ output = { }
195
+ for line in msg.split(parser.eolrx) {
196
+ found = line.match(parser.divrx)
197
+ if found {
198
+ field = found.1
199
+ value = found.2
200
+ } else {
201
+ field = line
202
+ value = ""
203
+ }
204
+ if field == "data" {
205
+ if output.data
206
+ output.data = output.data.concat("\n", value)
207
+ else
208
+ output.data = value
209
+ }
210
+ else if field == "event"
211
+ output.type = value
212
+ else if field == "id"
213
+ output.lastEventID = value
214
+ }
215
+ call(message, output)
216
+ }
217
+ }
218
+
219
+ // finis
220
+ parser
221
+ };
222
+
223
+
152
224
  /*
153
225
  * HttpsApiRequest
154
226
  *
@@ -157,11 +229,24 @@ closure httpsApiReqOnce(url, options,
157
229
  * Options:
158
230
  * {
159
231
  * retrier: function(error) { error.status == 502 } // retry 502 errors
232
+ * sseHook: function(msg) { } // process SSE messages
160
233
  * }
161
234
  *
162
235
  */
163
236
 
164
- closure HttpsApiRequest(url, options, local result) {
237
+ closure HttpsApiRequest(url, options, local parser, decoder, result) {
238
+ if options.sseHook {
239
+ parser = sseParserFactory(options.sseHook)
240
+ decoder = xnew(stringDecoder.StringDecoder, "utf8")
241
+ options = merge(options, {
242
+ streamHook: function(chunk) {
243
+ if chunk
244
+ parser.write(decoder.write(chunk)) // data arrived
245
+ else
246
+ parser.write(decoder.end()) // end of data
247
+ }
248
+ })
249
+ }
165
250
  loop {
166
251
  result = httpsApiReqOnce(url, options)
167
252
  if result.0 && result.0.status { // check for retries
@@ -182,7 +267,7 @@ closure HttpsApiRequest(url, options, local result) {
182
267
  */
183
268
 
184
269
  function https_nodeInit(local manifest) {
185
- manifest = `(httpsApiReqOnce, HttpsApiRequest, https_nodeInit)
270
+ manifest = `(httpsApiReqOnce, sseParserFactory, HttpsApiRequest, https_nodeInit)
186
271
 
187
272
  Naan.module.build(module.id, "https_request", function(modobj, compobj) {
188
273
  require("./node.nlg")
@@ -133,6 +133,7 @@ function nodrInit(local manifest) {
133
133
  nodeHttps = js.r("https")
134
134
  nodeUrl= js.r("url")
135
135
  threads = js.r("worker_threads")
136
+ stringDecoder = js.r("string_decoder")
136
137
  }()
137
138
  module.reload = nodrReload
138
139
  module.exports.NaanlangDir = NaanlangDir
@@ -142,8 +142,8 @@
142
142
 
143
143
  closure Builder(rules, operation, fs, srcpath, destpath, track, local build, group, newgroup) {
144
144
  build = new(object, this)
145
- build.srcpath = srcpath
146
- build.destpath = destpath
145
+ build.srcpath = JSpath.normalize(srcpath)
146
+ build.destpath = JSpath.normalize(destpath)
147
147
  build.intpath = JSpath.join(destpath, "tmp")
148
148
  build.tasks = { // all tasks counter
149
149
  copy: 0,
@@ -694,13 +694,13 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
694
694
  if !file.info.hidden
695
695
  addgroup.sources.push(file.name) // add non-hidden files found in specified directory
696
696
  if addgroup.input
697
- addgroup.input = JSpath.join(addgroup.input, source, listing.data.pathsep)
697
+ addgroup.input = JSpath.join(addgroup.input, source, "/")
698
698
  else
699
- addgroup.input = source.concat(listing.data.pathsep)
699
+ addgroup.input = JSpath.join("/")
700
700
  if group.destfile
701
- addgroup.output = JSpath.join(addgroup.output, listing.data.pathsep)
701
+ addgroup.output = JSpath.join(addgroup.output, "/")
702
702
  else
703
- addgroup.output = JSpath.join(addgroup.output, source, listing.data.pathsep)
703
+ addgroup.output = JSpath.join(addgroup.output, source, "/")
704
704
  addgroup.groupno = build.nextgno++ // needed for concat/zip
705
705
  groups.push(addgroup)
706
706
  }
@@ -1067,6 +1067,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
1067
1067
  //
1068
1068
  function writeCatenate(writepath,
1069
1069
  local template, entry, content, catsub, dozip, docat, fsoptions, zipmap, error, result) {
1070
+ debuglog("writeCatenate", writepath)
1070
1071
  template = build.templates[writepath] // optional in some cases ### should warn in others
1071
1072
  catsub = { }
1072
1073
  for entry in catenates[writepath] { // error check and substitution build
@@ -1145,6 +1146,11 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
1145
1146
  build.make = closure make(options, local sink, xchan, entry, outext, error) {
1146
1147
  sink = new(textstream, "", `string) // log all output
1147
1148
  xchan = textstreams(list(sink, sink))
1149
+ `(error) = fs.mkdir(build.destpath) // make sure our directory exists
1150
+ if error {
1151
+ error = Error("cannot make build products folder", error)
1152
+ return (list(error))
1153
+ }
1148
1154
  try {
1149
1155
  resetlist()
1150
1156
  analyze(options.debugMake)
@@ -1201,7 +1207,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
1201
1207
  workerID: "Run-${build.buildnum}"
1202
1208
  startup: {
1203
1209
  initcmds: maintext
1204
- dirpath: fs.path.resolve(fs.path.sep, fs.rootpath, build.destpath)
1210
+ dirpath: fs.path.resolve("/", fs.rootpath, build.destpath)
1205
1211
  }
1206
1212
  })
1207
1213
  if error
@@ -296,7 +296,7 @@ closure projConnector(projman, projtype, local connector, watch) {
296
296
  *
297
297
  * Nide.proj/
298
298
  * nide_cliser.cfg - JSON definition of the project (see below)
299
- * NaanIDE_version.txt - [default] substitution file defining 1.3.1+1 etc.
299
+ * NaanIDE_version.txt - [default] substitution file defining 1.3.2+1 etc.
300
300
  * NaanIDE_version_builds.txt - [default] contains current build number as decimal string
301
301
  * build/ - [optional] default build output location
302
302
  * NaanIDE.lic - [optional] defines Zulch Laboratories, Inc. and other license info
@@ -574,8 +574,12 @@ closure projConfig(projman, where, projID, local procon, fs, configpath) {
574
574
  if error
575
575
  return (list(error))
576
576
  rules = procon.configDict."build-rules"[stage]
577
- if rules.inherit
578
- rules = js.o.assign(procon.configDict."build-rules"[rules.inherit], rules)
577
+ if rules.inherit {
578
+ data = procon.configDict."build-rules"[rules.inherit]
579
+ if !data
580
+ return (list(Error("build inherit rules '${rules.inherit}' do not exist")))
581
+ rules = merge(data, rules)
582
+ }
579
583
  else if !rules
580
584
  rules = procon.configDict.build // fallback to old config structure
581
585
  rules = new(rules)
@@ -536,7 +536,7 @@ exports.NaanControllerWeb = function() {
536
536
  statedoc.curversion = kStateCurrentVersion;
537
537
  statedoc.firstver = kStateFirstVersion;
538
538
  statedoc.licensee = "MIT-License";
539
- statedoc.verstring = "1.3.1+1";
539
+ statedoc.verstring = "1.3.2+1";
540
540
  statedoc.date = new Date().toISOString();
541
541
  statedoc.prefs = prefs;
542
542
  statedoc.naan = naanlib.saveState(false); // true to optimize, which is a bit slower
@@ -554,7 +554,7 @@ exports.NaanControllerWeb = function() {
554
554
  || statedoc.firstver > kStateCurrentVersion
555
555
  || statedoc.curversion < kStateFirstVersion
556
556
  || statedoc.licensee != "MIT-License"
557
- || statedoc.verstring != "1.3.1+1")
557
+ || statedoc.verstring != "1.3.2+1")
558
558
  {
559
559
  localStorage.removeItem("NaanState_Hosted");
560
560
  return (false);
@@ -613,7 +613,7 @@ exports.NaanControllerWeb = function() {
613
613
  op: "VsiteOpen",
614
614
  name: vsiteName,
615
615
  naancont: contSelf,
616
- title: vsiteName + " 1.3.1+1"
616
+ title: vsiteName + " 1.3.2+1"
617
617
  });
618
618
  }
619
619
  } catch (e) {
@@ -627,7 +627,7 @@ exports.NaanControllerWeb = function() {
627
627
  op: "VsiteClose",
628
628
  name: vsiteName,
629
629
  naancont: contSelf,
630
- title: vsiteName + " 1.3.1+1"
630
+ title: vsiteName + " 1.3.2+1"
631
631
  });
632
632
  termTextOut("\x1b[90m\x1b[3m".concat("\nwindow closed", "\x1b[0m\n"));
633
633
  }
@@ -642,8 +642,8 @@ exports.NaanControllerWeb = function() {
642
642
  naanlib.banner();
643
643
  var hostpath = window.location.origin.concat(naanlib.js.r("path").dirname(window.location.pathname));
644
644
  naanlib.start({
645
- cmd: 'App.version = "1.3.1+1";;\r\n'
646
- + 'App.cache = "1f0eccb08fd1a57ede0bd91dc0e934cc";;\r\n'
645
+ cmd: 'App.version = "1.3.2+1";;\r\n'
646
+ + 'App.cache = "a8f6e5b80d3b14e762d56efbef3ae771";;\r\n'
647
647
  + 'Naan.module.requireQuery({ naanver: App.cache });;\r\n'
648
648
  + 'Naan.module.webparse("naan_init.nlg", "' + hostpath + '", { naanver: App.cache });;\r\n'
649
649
  });