ganeshpl-mithril_rails 1.0.1

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.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +32 -0
  4. data/app/assets/javascripts/MSXTransformer.js +15920 -0
  5. data/app/assets/javascripts/mithril.js +1160 -0
  6. data/app/assets/javascripts/mithril_ujs.js +93 -0
  7. data/app/helpers/mithril_helper.rb +14 -0
  8. data/lib/mithril_rails.rb +2 -0
  9. data/lib/mithril_rails/msx.rb +31 -0
  10. data/lib/mithril_rails/msx/template.rb +17 -0
  11. data/lib/mithril_rails/rails.rb +2 -0
  12. data/lib/mithril_rails/rails/engine.rb +9 -0
  13. data/lib/mithril_rails/rails/railtie.rb +10 -0
  14. data/lib/mithril_rails/version.rb +3 -0
  15. data/test/dummy/README.rdoc +28 -0
  16. data/test/dummy/Rakefile +6 -0
  17. data/test/dummy/app/assets/javascripts/application.js +13 -0
  18. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  19. data/test/dummy/app/controllers/application_controller.rb +5 -0
  20. data/test/dummy/app/helpers/application_helper.rb +2 -0
  21. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  22. data/test/dummy/bin/bundle +3 -0
  23. data/test/dummy/bin/rails +4 -0
  24. data/test/dummy/bin/rake +4 -0
  25. data/test/dummy/config.ru +4 -0
  26. data/test/dummy/config/application.rb +23 -0
  27. data/test/dummy/config/boot.rb +5 -0
  28. data/test/dummy/config/database.yml +25 -0
  29. data/test/dummy/config/environment.rb +5 -0
  30. data/test/dummy/config/environments/development.rb +37 -0
  31. data/test/dummy/config/environments/production.rb +83 -0
  32. data/test/dummy/config/environments/test.rb +39 -0
  33. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  34. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  35. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  36. data/test/dummy/config/initializers/inflections.rb +16 -0
  37. data/test/dummy/config/initializers/mime_types.rb +4 -0
  38. data/test/dummy/config/initializers/session_store.rb +3 -0
  39. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  40. data/test/dummy/config/locales/en.yml +23 -0
  41. data/test/dummy/config/routes.rb +56 -0
  42. data/test/dummy/config/secrets.yml +22 -0
  43. data/test/dummy/public/404.html +67 -0
  44. data/test/dummy/public/422.html +67 -0
  45. data/test/dummy/public/500.html +66 -0
  46. data/test/dummy/public/favicon.ico +0 -0
  47. data/test/mithril_rails_test.rb +7 -0
  48. data/test/test_helper.rb +15 -0
  49. metadata +183 -0
@@ -0,0 +1,1160 @@
1
+ new function() {
2
+
3
+ function Vnode(tag, key, attrs0, children, text, dom) {
4
+ return {tag: tag, key: key, attrs: attrs0, children: children, text: text, dom: dom, domSize: undefined, state: {}, events: undefined, instance: undefined, skip: false}
5
+ }
6
+ Vnode.normalize = function(node) {
7
+ if (Array.isArray(node)) return Vnode("[", undefined, undefined, Vnode.normalizeChildren(node), undefined, undefined)
8
+ if (node != null && typeof node !== "object") return Vnode("#", undefined, undefined, node === false ? "" : node, undefined, undefined)
9
+ return node
10
+ }
11
+ Vnode.normalizeChildren = function normalizeChildren(children) {
12
+ for (var i = 0; i < children.length; i++) {
13
+ children[i] = Vnode.normalize(children[i])
14
+ }
15
+ return children
16
+ }
17
+ var selectorParser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g
18
+ var selectorCache = {}
19
+ function hyperscript(selector) {
20
+ if (selector == null || typeof selector !== "string" && typeof selector.view !== "function") {
21
+ throw Error("The selector must be either a string or a component.");
22
+ }
23
+ if (typeof selector === "string" && selectorCache[selector] === undefined) {
24
+ var match, tag, classes = [], attributes = {}
25
+ while (match = selectorParser.exec(selector)) {
26
+ var type = match[1], value = match[2]
27
+ if (type === "" && value !== "") tag = value
28
+ else if (type === "#") attributes.id = value
29
+ else if (type === ".") classes.push(value)
30
+ else if (match[3][0] === "[") {
31
+ var attrValue = match[6]
32
+ if (attrValue) attrValue = attrValue.replace(/\\(["'])/g, "$1").replace(/\\\\/g, "\\")
33
+ if (match[4] === "class") classes.push(attrValue)
34
+ else attributes[match[4]] = attrValue || true
35
+ }
36
+ }
37
+ if (classes.length > 0) attributes.className = classes.join(" ")
38
+ selectorCache[selector] = function(attrs, children) {
39
+ var hasAttrs = false, childList, text
40
+ var className = attrs.className || attrs.class
41
+ for (var key in attributes) attrs[key] = attributes[key]
42
+ if (className !== undefined) {
43
+ if (attrs.class !== undefined) {
44
+ attrs.class = undefined
45
+ attrs.className = className
46
+ }
47
+ if (attributes.className !== undefined) attrs.className = attributes.className + " " + className
48
+ }
49
+ for (var key in attrs) {
50
+ if (key !== "key") {
51
+ hasAttrs = true
52
+ break
53
+ }
54
+ }
55
+ if (Array.isArray(children) && children.length == 1 && children[0] != null && children[0].tag === "#") text = children[0].children
56
+ else childList = children
57
+ return Vnode(tag || "div", attrs.key, hasAttrs ? attrs : undefined, childList, text, undefined)
58
+ }
59
+ }
60
+ var attrs, children, childrenIndex
61
+ if (arguments[1] == null || typeof arguments[1] === "object" && arguments[1].tag === undefined && !Array.isArray(arguments[1])) {
62
+ attrs = arguments[1]
63
+ childrenIndex = 2
64
+ }
65
+ else childrenIndex = 1
66
+ if (arguments.length === childrenIndex + 1) {
67
+ children = Array.isArray(arguments[childrenIndex]) ? arguments[childrenIndex] : [arguments[childrenIndex]]
68
+ }
69
+ else {
70
+ children = []
71
+ for (var i = childrenIndex; i < arguments.length; i++) children.push(arguments[i])
72
+ }
73
+ if (typeof selector === "string") return selectorCache[selector](attrs || {}, Vnode.normalizeChildren(children))
74
+ return Vnode(selector, attrs && attrs.key, attrs || {}, Vnode.normalizeChildren(children), undefined, undefined)
75
+ }
76
+ hyperscript.trust = function(html) {
77
+ if (html == null) html = ""
78
+ return Vnode("<", undefined, undefined, html, undefined, undefined)
79
+ }
80
+ hyperscript.fragment = function(attrs1, children) {
81
+ return Vnode("[", attrs1.key, attrs1, Vnode.normalizeChildren(children), undefined, undefined)
82
+ }
83
+ var m = hyperscript
84
+ /** @constructor */
85
+ var PromisePolyfill = function(executor) {
86
+ if (!(this instanceof PromisePolyfill)) throw new Error("Promise must be called with `new`")
87
+ if (typeof executor !== "function") throw new TypeError("executor must be a function")
88
+ var self = this, resolvers = [], rejectors = [], resolveCurrent = handler(resolvers, true), rejectCurrent = handler(rejectors, false)
89
+ var instance = self._instance = {resolvers: resolvers, rejectors: rejectors}
90
+ var callAsync = typeof setImmediate === "function" ? setImmediate : setTimeout
91
+ function handler(list, shouldAbsorb) {
92
+ return function execute(value) {
93
+ var then
94
+ try {
95
+ if (shouldAbsorb && value != null && (typeof value === "object" || typeof value === "function") && typeof (then = value.then) === "function") {
96
+ if (value === self) throw new TypeError("Promise can't be resolved w/ itself")
97
+ executeOnce(then.bind(value))
98
+ }
99
+ else {
100
+ callAsync(function() {
101
+ if (!shouldAbsorb && list.length === 0) console.error("Possible unhandled promise rejection:", value)
102
+ for (var i = 0; i < list.length; i++) list[i](value)
103
+ resolvers.length = 0, rejectors.length = 0
104
+ instance.state = shouldAbsorb
105
+ instance.retry = function() {execute(value)}
106
+ })
107
+ }
108
+ }
109
+ catch (e) {
110
+ rejectCurrent(e)
111
+ }
112
+ }
113
+ }
114
+ function executeOnce(then) {
115
+ var runs = 0
116
+ function run(fn) {
117
+ return function(value) {
118
+ if (runs++ > 0) return
119
+ fn(value)
120
+ }
121
+ }
122
+ var onerror = run(rejectCurrent)
123
+ try {then(run(resolveCurrent), onerror)} catch (e) {onerror(e)}
124
+ }
125
+ executeOnce(executor)
126
+ }
127
+ PromisePolyfill.prototype.then = function(onFulfilled, onRejection) {
128
+ var self = this, instance = self._instance
129
+ function handle(callback, list, next, state) {
130
+ list.push(function(value) {
131
+ if (typeof callback !== "function") next(value)
132
+ else try {resolveNext(callback(value))} catch (e) {if (rejectNext) rejectNext(e)}
133
+ })
134
+ if (typeof instance.retry === "function" && state === instance.state) instance.retry()
135
+ }
136
+ var resolveNext, rejectNext
137
+ var promise = new PromisePolyfill(function(resolve, reject) {resolveNext = resolve, rejectNext = reject})
138
+ handle(onFulfilled, instance.resolvers, resolveNext, true), handle(onRejection, instance.rejectors, rejectNext, false)
139
+ return promise
140
+ }
141
+ PromisePolyfill.prototype.catch = function(onRejection) {
142
+ return this.then(null, onRejection)
143
+ }
144
+ PromisePolyfill.resolve = function(value) {
145
+ if (value instanceof PromisePolyfill) return value
146
+ return new PromisePolyfill(function(resolve) {resolve(value)})
147
+ }
148
+ PromisePolyfill.reject = function(value) {
149
+ return new PromisePolyfill(function(resolve, reject) {reject(value)})
150
+ }
151
+ PromisePolyfill.all = function(list) {
152
+ return new PromisePolyfill(function(resolve, reject) {
153
+ var total = list.length, count = 0, values = []
154
+ if (list.length === 0) resolve([])
155
+ else for (var i = 0; i < list.length; i++) {
156
+ (function(i) {
157
+ function consume(value) {
158
+ count++
159
+ values[i] = value
160
+ if (count === total) resolve(values)
161
+ }
162
+ if (list[i] != null && (typeof list[i] === "object" || typeof list[i] === "function") && typeof list[i].then === "function") {
163
+ list[i].then(consume, reject)
164
+ }
165
+ else consume(list[i])
166
+ })(i)
167
+ }
168
+ })
169
+ }
170
+ PromisePolyfill.race = function(list) {
171
+ return new PromisePolyfill(function(resolve, reject) {
172
+ for (var i = 0; i < list.length; i++) {
173
+ list[i].then(resolve, reject)
174
+ }
175
+ })
176
+ }
177
+ if (typeof window !== "undefined") {
178
+ if (typeof window.Promise === "undefined") window.Promise = PromisePolyfill
179
+ var PromisePolyfill = window.Promise
180
+ } else if (typeof global !== "undefined") {
181
+ if (typeof global.Promise === "undefined") global.Promise = PromisePolyfill
182
+ var PromisePolyfill = global.Promise
183
+ } else {
184
+ }
185
+ var buildQueryString = function(object) {
186
+ if (Object.prototype.toString.call(object) !== "[object Object]") return ""
187
+ var args = []
188
+ for (var key0 in object) {
189
+ destructure(key0, object[key0])
190
+ }
191
+ return args.join("&")
192
+ function destructure(key0, value) {
193
+ if (Array.isArray(value)) {
194
+ for (var i = 0; i < value.length; i++) {
195
+ destructure(key0 + "[" + i + "]", value[i])
196
+ }
197
+ }
198
+ else if (Object.prototype.toString.call(value) === "[object Object]") {
199
+ for (var i in value) {
200
+ destructure(key0 + "[" + i + "]", value[i])
201
+ }
202
+ }
203
+ else args.push(encodeURIComponent(key0) + (value != null && value !== "" ? "=" + encodeURIComponent(value) : ""))
204
+ }
205
+ }
206
+ var _8 = function($window, Promise) {
207
+ var callbackCount = 0
208
+ var oncompletion
209
+ function setCompletionCallback(callback) {oncompletion = callback}
210
+ function finalizer() {
211
+ var count = 0
212
+ function complete() {if (--count === 0 && typeof oncompletion === "function") oncompletion()}
213
+ return function finalize(promise0) {
214
+ var then0 = promise0.then
215
+ promise0.then = function() {
216
+ count++
217
+ var next = then0.apply(promise0, arguments)
218
+ next.then(complete, function(e) {
219
+ complete()
220
+ if (count === 0) throw e
221
+ })
222
+ return finalize(next)
223
+ }
224
+ return promise0
225
+ }
226
+ }
227
+ function normalize(args, extra) {
228
+ if (typeof args === "string") {
229
+ var url = args
230
+ args = extra || {}
231
+ if (args.url == null) args.url = url
232
+ }
233
+ return args
234
+ }
235
+ function request(args, extra) {
236
+ var finalize = finalizer()
237
+ args = normalize(args, extra)
238
+ var promise0 = new Promise(function(resolve, reject) {
239
+ if (args.method == null) args.method = "GET"
240
+ args.method = args.method.toUpperCase()
241
+ var useBody = typeof args.useBody === "boolean" ? args.useBody : args.method !== "GET" && args.method !== "TRACE"
242
+ if (typeof args.serialize !== "function") args.serialize = typeof FormData !== "undefined" && args.data instanceof FormData ? function(value) {return value} : JSON.stringify
243
+ if (typeof args.deserialize !== "function") args.deserialize = deserialize
244
+ if (typeof args.extract !== "function") args.extract = extract
245
+ args.url = interpolate(args.url, args.data)
246
+ if (useBody) args.data = args.serialize(args.data)
247
+ else args.url = assemble(args.url, args.data)
248
+ var xhr = new $window.XMLHttpRequest()
249
+ xhr.open(args.method, args.url, typeof args.async === "boolean" ? args.async : true, typeof args.user === "string" ? args.user : undefined, typeof args.password === "string" ? args.password : undefined)
250
+ if (args.serialize === JSON.stringify && useBody) {
251
+ xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8")
252
+ }
253
+ if (args.deserialize === deserialize) {
254
+ xhr.setRequestHeader("Accept", "application/json, text/*")
255
+ }
256
+ if (args.withCredentials) xhr.withCredentials = args.withCredentials
257
+ for (var key in args.headers) if ({}.hasOwnProperty.call(args.headers, key)) {
258
+ xhr.setRequestHeader(key, args.headers[key])
259
+ }
260
+ if (typeof args.config === "function") xhr = args.config(xhr, args) || xhr
261
+ xhr.onreadystatechange = function() {
262
+ // Don't throw errors on xhr.abort(). XMLHttpRequests ends up in a state of
263
+ // xhr.status == 0 and xhr.readyState == 4 if aborted after open, but before completion.
264
+ if (xhr.status && xhr.readyState === 4) {
265
+ try {
266
+ var response = (args.extract !== extract) ? args.extract(xhr, args) : args.deserialize(args.extract(xhr, args))
267
+ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
268
+ resolve(cast(args.type, response))
269
+ }
270
+ else {
271
+ var error = new Error(xhr.responseText)
272
+ for (var key in response) error[key] = response[key]
273
+ reject(error)
274
+ }
275
+ }
276
+ catch (e) {
277
+ reject(e)
278
+ }
279
+ }
280
+ }
281
+ if (useBody && (args.data != null)) xhr.send(args.data)
282
+ else xhr.send()
283
+ })
284
+ return args.background === true ? promise0 : finalize(promise0)
285
+ }
286
+ function jsonp(args, extra) {
287
+ var finalize = finalizer()
288
+ args = normalize(args, extra)
289
+ var promise0 = new Promise(function(resolve, reject) {
290
+ var callbackName = args.callbackName || "_mithril_" + Math.round(Math.random() * 1e16) + "_" + callbackCount++
291
+ var script = $window.document.createElement("script")
292
+ $window[callbackName] = function(data) {
293
+ script.parentNode.removeChild(script)
294
+ resolve(cast(args.type, data))
295
+ delete $window[callbackName]
296
+ }
297
+ script.onerror = function() {
298
+ script.parentNode.removeChild(script)
299
+ reject(new Error("JSONP request failed"))
300
+ delete $window[callbackName]
301
+ }
302
+ if (args.data == null) args.data = {}
303
+ args.url = interpolate(args.url, args.data)
304
+ args.data[args.callbackKey || "callback"] = callbackName
305
+ script.src = assemble(args.url, args.data)
306
+ $window.document.documentElement.appendChild(script)
307
+ })
308
+ return args.background === true? promise0 : finalize(promise0)
309
+ }
310
+ function interpolate(url, data) {
311
+ if (data == null) return url
312
+ var tokens = url.match(/:[^\/]+/gi) || []
313
+ for (var i = 0; i < tokens.length; i++) {
314
+ var key = tokens[i].slice(1)
315
+ if (data[key] != null) {
316
+ url = url.replace(tokens[i], data[key])
317
+ }
318
+ }
319
+ return url
320
+ }
321
+ function assemble(url, data) {
322
+ var querystring = buildQueryString(data)
323
+ if (querystring !== "") {
324
+ var prefix = url.indexOf("?") < 0 ? "?" : "&"
325
+ url += prefix + querystring
326
+ }
327
+ return url
328
+ }
329
+ function deserialize(data) {
330
+ try {return data !== "" ? JSON.parse(data) : null}
331
+ catch (e) {throw new Error(data)}
332
+ }
333
+ function extract(xhr) {return xhr.responseText}
334
+ function cast(type0, data) {
335
+ if (typeof type0 === "function") {
336
+ if (Array.isArray(data)) {
337
+ for (var i = 0; i < data.length; i++) {
338
+ data[i] = new type0(data[i])
339
+ }
340
+ }
341
+ else return new type0(data)
342
+ }
343
+ return data
344
+ }
345
+ return {request: request, jsonp: jsonp, setCompletionCallback: setCompletionCallback}
346
+ }
347
+ var requestService = _8(window, PromisePolyfill)
348
+ var coreRenderer = function($window) {
349
+ var $doc = $window.document
350
+ var $emptyFragment = $doc.createDocumentFragment()
351
+ var onevent
352
+ function setEventCallback(callback) {return onevent = callback}
353
+ //create
354
+ function createNodes(parent, vnodes, start, end, hooks, nextSibling, ns) {
355
+ for (var i = start; i < end; i++) {
356
+ var vnode = vnodes[i]
357
+ if (vnode != null) {
358
+ insertNode(parent, createNode(vnode, hooks, ns), nextSibling)
359
+ }
360
+ }
361
+ }
362
+ function createNode(vnode, hooks, ns) {
363
+ var tag = vnode.tag
364
+ if (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks)
365
+ if (typeof tag === "string") {
366
+ switch (tag) {
367
+ case "#": return createText(vnode)
368
+ case "<": return createHTML(vnode)
369
+ case "[": return createFragment(vnode, hooks, ns)
370
+ default: return createElement(vnode, hooks, ns)
371
+ }
372
+ }
373
+ else return createComponent(vnode, hooks, ns)
374
+ }
375
+ function createText(vnode) {
376
+ return vnode.dom = $doc.createTextNode(vnode.children)
377
+ }
378
+ function createHTML(vnode) {
379
+ var match1 = vnode.children.match(/^\s*?<(\w+)/im) || []
380
+ var parent = {caption: "table", thead: "table", tbody: "table", tfoot: "table", tr: "tbody", th: "tr", td: "tr", colgroup: "table", col: "colgroup"}[match1[1]] || "div"
381
+ var temp = $doc.createElement(parent)
382
+ temp.innerHTML = vnode.children
383
+ vnode.dom = temp.firstChild
384
+ vnode.domSize = temp.childNodes.length
385
+ var fragment = $doc.createDocumentFragment()
386
+ var child
387
+ while (child = temp.firstChild) {
388
+ fragment.appendChild(child)
389
+ }
390
+ return fragment
391
+ }
392
+ function createFragment(vnode, hooks, ns) {
393
+ var fragment = $doc.createDocumentFragment()
394
+ if (vnode.children != null) {
395
+ var children = vnode.children
396
+ createNodes(fragment, children, 0, children.length, hooks, null, ns)
397
+ }
398
+ vnode.dom = fragment.firstChild
399
+ vnode.domSize = fragment.childNodes.length
400
+ return fragment
401
+ }
402
+ function createElement(vnode, hooks, ns) {
403
+ var tag = vnode.tag
404
+ switch (vnode.tag) {
405
+ case "svg": ns = "http://www.w3.org/2000/svg"; break
406
+ case "math": ns = "http://www.w3.org/1998/Math/MathML"; break
407
+ }
408
+ var attrs2 = vnode.attrs
409
+ var is = attrs2 && attrs2.is
410
+ var element = ns ?
411
+ is ? $doc.createElementNS(ns, tag, {is: is}) : $doc.createElementNS(ns, tag) :
412
+ is ? $doc.createElement(tag, {is: is}) : $doc.createElement(tag)
413
+ vnode.dom = element
414
+ if (attrs2 != null) {
415
+ setAttrs(vnode, attrs2, ns)
416
+ }
417
+ if (vnode.attrs != null && vnode.attrs.contenteditable != null) {
418
+ setContentEditable(vnode)
419
+ }
420
+ else {
421
+ if (vnode.text != null) {
422
+ if (vnode.text !== "") element.textContent = vnode.text
423
+ else vnode.children = [Vnode("#", undefined, undefined, vnode.text, undefined, undefined)]
424
+ }
425
+ if (vnode.children != null) {
426
+ var children = vnode.children
427
+ createNodes(element, children, 0, children.length, hooks, null, ns)
428
+ setLateAttrs(vnode)
429
+ }
430
+ }
431
+ return element
432
+ }
433
+ function createComponent(vnode, hooks, ns) {
434
+ vnode.state = Object.create(vnode.tag)
435
+ var view = vnode.tag.view
436
+ if (view.reentrantLock != null) return $emptyFragment
437
+ view.reentrantLock = true
438
+ initLifecycle(vnode.tag, vnode, hooks)
439
+ vnode.instance = Vnode.normalize(view.call(vnode.state, vnode))
440
+ view.reentrantLock = null
441
+ if (vnode.instance != null) {
442
+ if (vnode.instance === vnode) throw Error("A view cannot return the vnode it received as arguments")
443
+ var element = createNode(vnode.instance, hooks, ns)
444
+ vnode.dom = vnode.instance.dom
445
+ vnode.domSize = vnode.dom != null ? vnode.instance.domSize : 0
446
+ return element
447
+ }
448
+ else {
449
+ vnode.domSize = 0
450
+ return $emptyFragment
451
+ }
452
+ }
453
+ //update
454
+ function updateNodes(parent, old, vnodes, hooks, nextSibling, ns) {
455
+ if (old === vnodes || old == null && vnodes == null) return
456
+ else if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, undefined)
457
+ else if (vnodes == null) removeNodes(old, 0, old.length, vnodes)
458
+ else {
459
+ if (old.length === vnodes.length) {
460
+ var isUnkeyed = false
461
+ for (var i = 0; i < vnodes.length; i++) {
462
+ if (vnodes[i] != null && old[i] != null) {
463
+ isUnkeyed = vnodes[i].key == null && old[i].key == null
464
+ break
465
+ }
466
+ }
467
+ if (isUnkeyed) {
468
+ for (var i = 0; i < old.length; i++) {
469
+ if (old[i] === vnodes[i]) continue
470
+ else if (old[i] == null && vnodes[i] != null) insertNode(parent, createNode(vnodes[i], hooks, ns), getNextSibling(old, i + 1, nextSibling))
471
+ else if (vnodes[i] == null) removeNodes(old, i, i + 1, vnodes)
472
+ else updateNode(parent, old[i], vnodes[i], hooks, getNextSibling(old, i + 1, nextSibling), false, ns)
473
+ }
474
+ return
475
+ }
476
+ }
477
+ var recycling = isRecyclable(old, vnodes)
478
+ if (recycling) old = old.concat(old.pool)
479
+ var oldStart = 0, start = 0, oldEnd = old.length - 1, end = vnodes.length - 1, map
480
+ while (oldEnd >= oldStart && end >= start) {
481
+ var o = old[oldStart], v = vnodes[start]
482
+ if (o === v && !recycling) oldStart++, start++
483
+ else if (o == null) oldStart++
484
+ else if (v == null) start++
485
+ else if (o.key === v.key) {
486
+ oldStart++, start++
487
+ updateNode(parent, o, v, hooks, getNextSibling(old, oldStart, nextSibling), recycling, ns)
488
+ if (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling)
489
+ }
490
+ else {
491
+ var o = old[oldEnd]
492
+ if (o === v && !recycling) oldEnd--, start++
493
+ else if (o == null) oldEnd--
494
+ else if (v == null) start++
495
+ else if (o.key === v.key) {
496
+ updateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling, ns)
497
+ if (recycling || start < end) insertNode(parent, toFragment(o), getNextSibling(old, oldStart, nextSibling))
498
+ oldEnd--, start++
499
+ }
500
+ else break
501
+ }
502
+ }
503
+ while (oldEnd >= oldStart && end >= start) {
504
+ var o = old[oldEnd], v = vnodes[end]
505
+ if (o === v && !recycling) oldEnd--, end--
506
+ else if (o == null) oldEnd--
507
+ else if (v == null) end--
508
+ else if (o.key === v.key) {
509
+ updateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling, ns)
510
+ if (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling)
511
+ if (o.dom != null) nextSibling = o.dom
512
+ oldEnd--, end--
513
+ }
514
+ else {
515
+ if (!map) map = getKeyMap(old, oldEnd)
516
+ if (v != null) {
517
+ var oldIndex = map[v.key]
518
+ if (oldIndex != null) {
519
+ var movable = old[oldIndex]
520
+ updateNode(parent, movable, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling, ns)
521
+ insertNode(parent, toFragment(movable), nextSibling)
522
+ old[oldIndex].skip = true
523
+ if (movable.dom != null) nextSibling = movable.dom
524
+ }
525
+ else {
526
+ var dom = createNode(v, hooks, undefined)
527
+ insertNode(parent, dom, nextSibling)
528
+ nextSibling = dom
529
+ }
530
+ }
531
+ end--
532
+ }
533
+ if (end < start) break
534
+ }
535
+ createNodes(parent, vnodes, start, end + 1, hooks, nextSibling, ns)
536
+ removeNodes(old, oldStart, oldEnd + 1, vnodes)
537
+ }
538
+ }
539
+ function updateNode(parent, old, vnode, hooks, nextSibling, recycling, ns) {
540
+ var oldTag = old.tag, tag = vnode.tag
541
+ if (oldTag === tag) {
542
+ vnode.state = old.state
543
+ vnode.events = old.events
544
+ if (shouldUpdate(vnode, old)) return
545
+ if (vnode.attrs != null) {
546
+ updateLifecycle(vnode.attrs, vnode, hooks, recycling)
547
+ }
548
+ if (typeof oldTag === "string") {
549
+ switch (oldTag) {
550
+ case "#": updateText(old, vnode); break
551
+ case "<": updateHTML(parent, old, vnode, nextSibling); break
552
+ case "[": updateFragment(parent, old, vnode, hooks, nextSibling, ns); break
553
+ default: updateElement(old, vnode, hooks, ns)
554
+ }
555
+ }
556
+ else updateComponent(parent, old, vnode, hooks, nextSibling, recycling, ns)
557
+ }
558
+ else {
559
+ removeNode(old, null)
560
+ insertNode(parent, createNode(vnode, hooks, ns), nextSibling)
561
+ }
562
+ }
563
+ function updateText(old, vnode) {
564
+ if (old.children.toString() !== vnode.children.toString()) {
565
+ old.dom.nodeValue = vnode.children
566
+ }
567
+ vnode.dom = old.dom
568
+ }
569
+ function updateHTML(parent, old, vnode, nextSibling) {
570
+ if (old.children !== vnode.children) {
571
+ toFragment(old)
572
+ insertNode(parent, createHTML(vnode), nextSibling)
573
+ }
574
+ else vnode.dom = old.dom, vnode.domSize = old.domSize
575
+ }
576
+ function updateFragment(parent, old, vnode, hooks, nextSibling, ns) {
577
+ updateNodes(parent, old.children, vnode.children, hooks, nextSibling, ns)
578
+ var domSize = 0, children = vnode.children
579
+ vnode.dom = null
580
+ if (children != null) {
581
+ for (var i = 0; i < children.length; i++) {
582
+ var child = children[i]
583
+ if (child != null && child.dom != null) {
584
+ if (vnode.dom == null) vnode.dom = child.dom
585
+ domSize += child.domSize || 1
586
+ }
587
+ }
588
+ if (domSize !== 1) vnode.domSize = domSize
589
+ }
590
+ }
591
+ function updateElement(old, vnode, hooks, ns) {
592
+ var element = vnode.dom = old.dom
593
+ switch (vnode.tag) {
594
+ case "svg": ns = "http://www.w3.org/2000/svg"; break
595
+ case "math": ns = "http://www.w3.org/1998/Math/MathML"; break
596
+ }
597
+ if (vnode.tag === "textarea") {
598
+ if (vnode.attrs == null) vnode.attrs = {}
599
+ if (vnode.text != null) {
600
+ vnode.attrs.value = vnode.text //FIXME handle0 multiple children
601
+ vnode.text = undefined
602
+ }
603
+ }
604
+ updateAttrs(vnode, old.attrs, vnode.attrs, ns)
605
+ if (vnode.attrs != null && vnode.attrs.contenteditable != null) {
606
+ setContentEditable(vnode)
607
+ }
608
+ else if (old.text != null && vnode.text != null && vnode.text !== "") {
609
+ if (old.text.toString() !== vnode.text.toString()) old.dom.firstChild.nodeValue = vnode.text
610
+ }
611
+ else {
612
+ if (old.text != null) old.children = [Vnode("#", undefined, undefined, old.text, undefined, old.dom.firstChild)]
613
+ if (vnode.text != null) vnode.children = [Vnode("#", undefined, undefined, vnode.text, undefined, undefined)]
614
+ updateNodes(element, old.children, vnode.children, hooks, null, ns)
615
+ }
616
+ }
617
+ function updateComponent(parent, old, vnode, hooks, nextSibling, recycling, ns) {
618
+ vnode.instance = Vnode.normalize(vnode.tag.view.call(vnode.state, vnode))
619
+ updateLifecycle(vnode.tag, vnode, hooks, recycling)
620
+ if (vnode.instance != null) {
621
+ if (old.instance == null) insertNode(parent, createNode(vnode.instance, hooks, ns), nextSibling)
622
+ else updateNode(parent, old.instance, vnode.instance, hooks, nextSibling, recycling, ns)
623
+ vnode.dom = vnode.instance.dom
624
+ vnode.domSize = vnode.instance.domSize
625
+ }
626
+ else if (old.instance != null) {
627
+ removeNode(old.instance, null)
628
+ vnode.dom = undefined
629
+ vnode.domSize = 0
630
+ }
631
+ else {
632
+ vnode.dom = old.dom
633
+ vnode.domSize = old.domSize
634
+ }
635
+ }
636
+ function isRecyclable(old, vnodes) {
637
+ if (old.pool != null && Math.abs(old.pool.length - vnodes.length) <= Math.abs(old.length - vnodes.length)) {
638
+ var oldChildrenLength = old[0] && old[0].children && old[0].children.length || 0
639
+ var poolChildrenLength = old.pool[0] && old.pool[0].children && old.pool[0].children.length || 0
640
+ var vnodesChildrenLength = vnodes[0] && vnodes[0].children && vnodes[0].children.length || 0
641
+ if (Math.abs(poolChildrenLength - vnodesChildrenLength) <= Math.abs(oldChildrenLength - vnodesChildrenLength)) {
642
+ return true
643
+ }
644
+ }
645
+ return false
646
+ }
647
+ function getKeyMap(vnodes, end) {
648
+ var map = {}, i = 0
649
+ for (var i = 0; i < end; i++) {
650
+ var vnode = vnodes[i]
651
+ if (vnode != null) {
652
+ var key2 = vnode.key
653
+ if (key2 != null) map[key2] = i
654
+ }
655
+ }
656
+ return map
657
+ }
658
+ function toFragment(vnode) {
659
+ var count0 = vnode.domSize
660
+ if (count0 != null || vnode.dom == null) {
661
+ var fragment = $doc.createDocumentFragment()
662
+ if (count0 > 0) {
663
+ var dom = vnode.dom
664
+ while (--count0) fragment.appendChild(dom.nextSibling)
665
+ fragment.insertBefore(dom, fragment.firstChild)
666
+ }
667
+ return fragment
668
+ }
669
+ else return vnode.dom
670
+ }
671
+ function getNextSibling(vnodes, i, nextSibling) {
672
+ for (; i < vnodes.length; i++) {
673
+ if (vnodes[i] != null && vnodes[i].dom != null) return vnodes[i].dom
674
+ }
675
+ return nextSibling
676
+ }
677
+ function insertNode(parent, dom, nextSibling) {
678
+ if (nextSibling && nextSibling.parentNode) parent.insertBefore(dom, nextSibling)
679
+ else parent.appendChild(dom)
680
+ }
681
+ function setContentEditable(vnode) {
682
+ var children = vnode.children
683
+ if (children != null && children.length === 1 && children[0].tag === "<") {
684
+ var content = children[0].children
685
+ if (vnode.dom.innerHTML !== content) vnode.dom.innerHTML = content
686
+ }
687
+ else if (vnode.text != null || children != null && children.length !== 0) throw new Error("Child node of a contenteditable must be trusted")
688
+ }
689
+ //remove
690
+ function removeNodes(vnodes, start, end, context) {
691
+ for (var i = start; i < end; i++) {
692
+ var vnode = vnodes[i]
693
+ if (vnode != null) {
694
+ if (vnode.skip) vnode.skip = false
695
+ else removeNode(vnode, context)
696
+ }
697
+ }
698
+ }
699
+ function removeNode(vnode, context) {
700
+ var expected = 1, called = 0
701
+ if (vnode.attrs && vnode.attrs.onbeforeremove) {
702
+ var result = vnode.attrs.onbeforeremove.call(vnode.state, vnode)
703
+ if (result != null && typeof result.then === "function") {
704
+ expected++
705
+ result.then(continuation, continuation)
706
+ }
707
+ }
708
+ if (typeof vnode.tag !== "string" && vnode.tag.onbeforeremove) {
709
+ var result = vnode.tag.onbeforeremove.call(vnode.state, vnode)
710
+ if (result != null && typeof result.then === "function") {
711
+ expected++
712
+ result.then(continuation, continuation)
713
+ }
714
+ }
715
+ continuation()
716
+ function continuation() {
717
+ if (++called === expected) {
718
+ onremove(vnode)
719
+ if (vnode.dom) {
720
+ var count0 = vnode.domSize || 1
721
+ if (count0 > 1) {
722
+ var dom = vnode.dom
723
+ while (--count0) {
724
+ removeNodeFromDOM(dom.nextSibling)
725
+ }
726
+ }
727
+ removeNodeFromDOM(vnode.dom)
728
+ if (context != null && vnode.domSize == null && !hasIntegrationMethods(vnode.attrs) && typeof vnode.tag === "string") { //TODO test custom elements
729
+ if (!context.pool) context.pool = [vnode]
730
+ else context.pool.push(vnode)
731
+ }
732
+ }
733
+ }
734
+ }
735
+ }
736
+ function removeNodeFromDOM(node) {
737
+ var parent = node.parentNode
738
+ if (parent != null) parent.removeChild(node)
739
+ }
740
+ function onremove(vnode) {
741
+ if (vnode.attrs && vnode.attrs.onremove) vnode.attrs.onremove.call(vnode.state, vnode)
742
+ if (typeof vnode.tag !== "string" && vnode.tag.onremove) vnode.tag.onremove.call(vnode.state, vnode)
743
+ if (vnode.instance != null) onremove(vnode.instance)
744
+ else {
745
+ var children = vnode.children
746
+ if (Array.isArray(children)) {
747
+ for (var i = 0; i < children.length; i++) {
748
+ var child = children[i]
749
+ if (child != null) onremove(child)
750
+ }
751
+ }
752
+ }
753
+ }
754
+ //attrs2
755
+ function setAttrs(vnode, attrs2, ns) {
756
+ for (var key2 in attrs2) {
757
+ setAttr(vnode, key2, null, attrs2[key2], ns)
758
+ }
759
+ }
760
+ function setAttr(vnode, key2, old, value, ns) {
761
+ var element = vnode.dom
762
+ if (key2 === "key" || key2 === "is" || (old === value && !isFormAttribute(vnode, key2)) && typeof value !== "object" || typeof value === "undefined" || isLifecycleMethod(key2)) return
763
+ var nsLastIndex = key2.indexOf(":")
764
+ if (nsLastIndex > -1 && key2.substr(0, nsLastIndex) === "xlink") {
765
+ element.setAttributeNS("http://www.w3.org/1999/xlink", key2.slice(nsLastIndex + 1), value)
766
+ }
767
+ else if (key2[0] === "o" && key2[1] === "n" && typeof value === "function") updateEvent(vnode, key2, value)
768
+ else if (key2 === "style") updateStyle(element, old, value)
769
+ else if (key2 in element && !isAttribute(key2) && ns === undefined && !isCustomElement(vnode)) {
770
+ //setting input[value] to same value by typing on focused element moves cursor to end in Chrome
771
+ if (vnode.tag === "input" && key2 === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return
772
+ //setting select[value] to same value while having select open blinks select dropdown in Chrome
773
+ if (vnode.tag === "select" && key2 === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return
774
+ //setting option[value] to same value while having select open blinks select dropdown in Chrome
775
+ if (vnode.tag === "option" && key2 === "value" && vnode.dom.value === value) return
776
+ element[key2] = value
777
+ }
778
+ else {
779
+ if (typeof value === "boolean") {
780
+ if (value) element.setAttribute(key2, "")
781
+ else element.removeAttribute(key2)
782
+ }
783
+ else element.setAttribute(key2 === "className" ? "class" : key2, value)
784
+ }
785
+ }
786
+ function setLateAttrs(vnode) {
787
+ var attrs2 = vnode.attrs
788
+ if (vnode.tag === "select" && attrs2 != null) {
789
+ if ("value" in attrs2) setAttr(vnode, "value", null, attrs2.value, undefined)
790
+ if ("selectedIndex" in attrs2) setAttr(vnode, "selectedIndex", null, attrs2.selectedIndex, undefined)
791
+ }
792
+ }
793
+ function updateAttrs(vnode, old, attrs2, ns) {
794
+ if (attrs2 != null) {
795
+ for (var key2 in attrs2) {
796
+ setAttr(vnode, key2, old && old[key2], attrs2[key2], ns)
797
+ }
798
+ }
799
+ if (old != null) {
800
+ for (var key2 in old) {
801
+ if (attrs2 == null || !(key2 in attrs2)) {
802
+ if (key2 === "className") key2 = "class"
803
+ if (key2[0] === "o" && key2[1] === "n" && !isLifecycleMethod(key2)) updateEvent(vnode, key2, undefined)
804
+ else if (key2 !== "key") vnode.dom.removeAttribute(key2)
805
+ }
806
+ }
807
+ }
808
+ }
809
+ function isFormAttribute(vnode, attr) {
810
+ return attr === "value" || attr === "checked" || attr === "selectedIndex" || attr === "selected" && vnode.dom === $doc.activeElement
811
+ }
812
+ function isLifecycleMethod(attr) {
813
+ return attr === "oninit" || attr === "oncreate" || attr === "onupdate" || attr === "onremove" || attr === "onbeforeremove" || attr === "onbeforeupdate"
814
+ }
815
+ function isAttribute(attr) {
816
+ return attr === "href" || attr === "list" || attr === "form" || attr === "width" || attr === "height"// || attr === "type"
817
+ }
818
+ function isCustomElement(vnode){
819
+ return vnode.attrs.is || vnode.tag.indexOf("-") > -1
820
+ }
821
+ function hasIntegrationMethods(source) {
822
+ return source != null && (source.oncreate || source.onupdate || source.onbeforeremove || source.onremove)
823
+ }
824
+ //style
825
+ function updateStyle(element, old, style) {
826
+ if (old === style) element.style.cssText = "", old = null
827
+ if (style == null) element.style.cssText = ""
828
+ else if (typeof style === "string") element.style.cssText = style
829
+ else {
830
+ if (typeof old === "string") element.style.cssText = ""
831
+ for (var key2 in style) {
832
+ element.style[key2] = style[key2]
833
+ }
834
+ if (old != null && typeof old !== "string") {
835
+ for (var key2 in old) {
836
+ if (!(key2 in style)) element.style[key2] = ""
837
+ }
838
+ }
839
+ }
840
+ }
841
+ //event
842
+ function updateEvent(vnode, key2, value) {
843
+ var element = vnode.dom
844
+ var callback = typeof onevent !== "function" ? value : function(e) {
845
+ var result = value.call(element, e)
846
+ onevent.call(element, e)
847
+ return result
848
+ }
849
+ if (key2 in element) element[key2] = typeof value === "function" ? callback : null
850
+ else {
851
+ var eventName = key2.slice(2)
852
+ if (vnode.events === undefined) vnode.events = {}
853
+ if (vnode.events[key2] === callback) return
854
+ if (vnode.events[key2] != null) element.removeEventListener(eventName, vnode.events[key2], false)
855
+ if (typeof value === "function") {
856
+ vnode.events[key2] = callback
857
+ element.addEventListener(eventName, vnode.events[key2], false)
858
+ }
859
+ }
860
+ }
861
+ //lifecycle
862
+ function initLifecycle(source, vnode, hooks) {
863
+ if (typeof source.oninit === "function") source.oninit.call(vnode.state, vnode)
864
+ if (typeof source.oncreate === "function") hooks.push(source.oncreate.bind(vnode.state, vnode))
865
+ }
866
+ function updateLifecycle(source, vnode, hooks, recycling) {
867
+ if (recycling) initLifecycle(source, vnode, hooks)
868
+ else if (typeof source.onupdate === "function") hooks.push(source.onupdate.bind(vnode.state, vnode))
869
+ }
870
+ function shouldUpdate(vnode, old) {
871
+ var forceVnodeUpdate, forceComponentUpdate
872
+ if (vnode.attrs != null && typeof vnode.attrs.onbeforeupdate === "function") forceVnodeUpdate = vnode.attrs.onbeforeupdate.call(vnode.state, vnode, old)
873
+ if (typeof vnode.tag !== "string" && typeof vnode.tag.onbeforeupdate === "function") forceComponentUpdate = vnode.tag.onbeforeupdate.call(vnode.state, vnode, old)
874
+ if (!(forceVnodeUpdate === undefined && forceComponentUpdate === undefined) && !forceVnodeUpdate && !forceComponentUpdate) {
875
+ vnode.dom = old.dom
876
+ vnode.domSize = old.domSize
877
+ vnode.instance = old.instance
878
+ return true
879
+ }
880
+ return false
881
+ }
882
+ function render(dom, vnodes) {
883
+ if (!dom) throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.")
884
+ var hooks = []
885
+ var active = $doc.activeElement
886
+ // First time0 rendering into a node clears it out
887
+ if (dom.vnodes == null) dom.textContent = ""
888
+ if (!Array.isArray(vnodes)) vnodes = [vnodes]
889
+ updateNodes(dom, dom.vnodes, Vnode.normalizeChildren(vnodes), hooks, null, undefined)
890
+ dom.vnodes = vnodes
891
+ for (var i = 0; i < hooks.length; i++) hooks[i]()
892
+ if ($doc.activeElement !== active) active.focus()
893
+ }
894
+ return {render: render, setEventCallback: setEventCallback}
895
+ }
896
+ function throttle(callback) {
897
+ //60fps translates to 16.6ms, round it down since setTimeout requires int
898
+ var time = 16
899
+ var last = 0, pending = null
900
+ var timeout = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout
901
+ return function() {
902
+ var now = Date.now()
903
+ if (last === 0 || now - last >= time) {
904
+ last = now
905
+ callback()
906
+ }
907
+ else if (pending === null) {
908
+ pending = timeout(function() {
909
+ pending = null
910
+ callback()
911
+ last = Date.now()
912
+ }, time - (now - last))
913
+ }
914
+ }
915
+ }
916
+ var _11 = function($window) {
917
+ var renderService = coreRenderer($window)
918
+ renderService.setEventCallback(function(e) {
919
+ if (e.redraw !== false) redraw()
920
+ })
921
+
922
+ var callbacks = []
923
+ function subscribe(key1, callback) {
924
+ unsubscribe(key1)
925
+ callbacks.push(key1, throttle(callback))
926
+ }
927
+ function unsubscribe(key1) {
928
+ var index = callbacks.indexOf(key1)
929
+ if (index > -1) callbacks.splice(index, 2)
930
+ }
931
+ function redraw() {
932
+ for (var i = 1; i < callbacks.length; i += 2) {
933
+ callbacks[i]()
934
+ }
935
+ }
936
+ return {subscribe: subscribe, unsubscribe: unsubscribe, redraw: redraw, render: renderService.render}
937
+ }
938
+ var redrawService = _11(window)
939
+ requestService.setCompletionCallback(redrawService.redraw)
940
+ var _16 = function(redrawService0) {
941
+ return function(root, component) {
942
+ if (component === null) {
943
+ redrawService0.render(root, [])
944
+ redrawService0.unsubscribe(root)
945
+ return
946
+ }
947
+
948
+ if (component.view == null) throw new Error("m.mount(element, component) expects a component, not a vnode")
949
+
950
+ var run0 = function() {
951
+ redrawService0.render(root, Vnode(component))
952
+ }
953
+ redrawService0.subscribe(root, run0)
954
+ redrawService0.redraw()
955
+ }
956
+ }
957
+ m.mount = _16(redrawService)
958
+ var Promise = PromisePolyfill
959
+ var parseQueryString = function(string) {
960
+ if (string === "" || string == null) return {}
961
+ if (string.charAt(0) === "?") string = string.slice(1)
962
+ var entries = string.split("&"), data0 = {}, counters = {}
963
+ for (var i = 0; i < entries.length; i++) {
964
+ var entry = entries[i].split("=")
965
+ var key5 = decodeURIComponent(entry[0])
966
+ var value = entry.length === 2 ? decodeURIComponent(entry[1]) : ""
967
+ if (value === "true") value = true
968
+ else if (value === "false") value = false
969
+ var levels = key5.split(/\]\[?|\[/)
970
+ var cursor = data0
971
+ if (key5.indexOf("[") > -1) levels.pop()
972
+ for (var j = 0; j < levels.length; j++) {
973
+ var level = levels[j], nextLevel = levels[j + 1]
974
+ var isNumber = nextLevel == "" || !isNaN(parseInt(nextLevel, 10))
975
+ var isValue = j === levels.length - 1
976
+ if (level === "") {
977
+ var key5 = levels.slice(0, j).join()
978
+ if (counters[key5] == null) counters[key5] = 0
979
+ level = counters[key5]++
980
+ }
981
+ if (cursor[level] == null) {
982
+ cursor[level] = isValue ? value : isNumber ? [] : {}
983
+ }
984
+ cursor = cursor[level]
985
+ }
986
+ }
987
+ return data0
988
+ }
989
+ var coreRouter = function($window) {
990
+ var supportsPushState = typeof $window.history.pushState === "function"
991
+ var callAsync0 = typeof setImmediate === "function" ? setImmediate : setTimeout
992
+ function normalize1(fragment0) {
993
+ var data = $window.location[fragment0].replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponent)
994
+ if (fragment0 === "pathname" && data[0] !== "/") data = "/" + data
995
+ return data
996
+ }
997
+ var asyncId
998
+ function debounceAsync(callback0) {
999
+ return function() {
1000
+ if (asyncId != null) return
1001
+ asyncId = callAsync0(function() {
1002
+ asyncId = null
1003
+ callback0()
1004
+ })
1005
+ }
1006
+ }
1007
+ function parsePath(path, queryData, hashData) {
1008
+ var queryIndex = path.indexOf("?")
1009
+ var hashIndex = path.indexOf("#")
1010
+ var pathEnd = queryIndex > -1 ? queryIndex : hashIndex > -1 ? hashIndex : path.length
1011
+ if (queryIndex > -1) {
1012
+ var queryEnd = hashIndex > -1 ? hashIndex : path.length
1013
+ var queryParams = parseQueryString(path.slice(queryIndex + 1, queryEnd))
1014
+ for (var key4 in queryParams) queryData[key4] = queryParams[key4]
1015
+ }
1016
+ if (hashIndex > -1) {
1017
+ var hashParams = parseQueryString(path.slice(hashIndex + 1))
1018
+ for (var key4 in hashParams) hashData[key4] = hashParams[key4]
1019
+ }
1020
+ return path.slice(0, pathEnd)
1021
+ }
1022
+ var router = {prefix: "#!"}
1023
+ router.getPath = function() {
1024
+ var type2 = router.prefix.charAt(0)
1025
+ switch (type2) {
1026
+ case "#": return normalize1("hash").slice(router.prefix.length)
1027
+ case "?": return normalize1("search").slice(router.prefix.length) + normalize1("hash")
1028
+ default: return normalize1("pathname").slice(router.prefix.length) + normalize1("search") + normalize1("hash")
1029
+ }
1030
+ }
1031
+ router.setPath = function(path, data, options) {
1032
+ var queryData = {}, hashData = {}
1033
+ path = parsePath(path, queryData, hashData)
1034
+ if (data != null) {
1035
+ for (var key4 in data) queryData[key4] = data[key4]
1036
+ path = path.replace(/:([^\/]+)/g, function(match2, token) {
1037
+ delete queryData[token]
1038
+ return data[token]
1039
+ })
1040
+ }
1041
+ var query = buildQueryString(queryData)
1042
+ if (query) path += "?" + query
1043
+ var hash = buildQueryString(hashData)
1044
+ if (hash) path += "#" + hash
1045
+ if (supportsPushState) {
1046
+ var state = options ? options.state : null
1047
+ var title = options ? options.title : null
1048
+ $window.onpopstate()
1049
+ if (options && options.replace) $window.history.replaceState(state, title, router.prefix + path)
1050
+ else $window.history.pushState(state, title, router.prefix + path)
1051
+ }
1052
+ else $window.location.href = router.prefix + path
1053
+ }
1054
+ router.defineRoutes = function(routes, resolve, reject) {
1055
+ function resolveRoute() {
1056
+ var path = router.getPath()
1057
+ var params = {}
1058
+ var pathname = parsePath(path, params, params)
1059
+
1060
+ var state = $window.history.state
1061
+ if (state != null) {
1062
+ for (var k in state) params[k] = state[k]
1063
+ }
1064
+ for (var route0 in routes) {
1065
+ var matcher = new RegExp("^" + route0.replace(/:[^\/]+?\.{3}/g, "(.*?)").replace(/:[^\/]+/g, "([^\\/]+)") + "\/?$")
1066
+ if (matcher.test(pathname)) {
1067
+ pathname.replace(matcher, function() {
1068
+ var keys = route0.match(/:[^\/]+/g) || []
1069
+ var values = [].slice.call(arguments, 1, -2)
1070
+ for (var i = 0; i < keys.length; i++) {
1071
+ params[keys[i].replace(/:|\./g, "")] = decodeURIComponent(values[i])
1072
+ }
1073
+ resolve(routes[route0], params, path, route0)
1074
+ })
1075
+ return
1076
+ }
1077
+ }
1078
+ reject(path, params)
1079
+ }
1080
+
1081
+ if (supportsPushState) $window.onpopstate = debounceAsync(resolveRoute)
1082
+ else if (router.prefix.charAt(0) === "#") $window.onhashchange = resolveRoute
1083
+ resolveRoute()
1084
+ }
1085
+
1086
+ return router
1087
+ }
1088
+ var _20 = function($window, redrawService0) {
1089
+ var routeService = coreRouter($window)
1090
+ var identity = function(v) {return v}
1091
+ var render1, component, attrs3, currentPath, lastUpdate
1092
+ var route = function(root, defaultRoute, routes) {
1093
+ if (root == null) throw new Error("Ensure the DOM element that was passed to `m.route` is not undefined")
1094
+ var run1 = function() {
1095
+ if (render1 != null) redrawService0.render(root, render1(Vnode(component, attrs3.key, attrs3)))
1096
+ }
1097
+ var bail = function() {
1098
+ routeService.setPath(defaultRoute, null, {replace: true})
1099
+ }
1100
+ routeService.defineRoutes(routes, function(payload, params, path) {
1101
+ var update = lastUpdate = function(routeResolver, comp) {
1102
+ if (update !== lastUpdate) return
1103
+ component = comp != null && typeof comp.view === "function" ? comp : "div", attrs3 = params, currentPath = path, lastUpdate = null
1104
+ render1 = (routeResolver.render || identity).bind(routeResolver)
1105
+ run1()
1106
+ }
1107
+ if (payload.view) update({}, payload)
1108
+ else {
1109
+ if (payload.onmatch) {
1110
+ Promise.resolve(payload.onmatch(params, path)).then(function(resolved) {
1111
+ update(payload, resolved)
1112
+ }, bail)
1113
+ }
1114
+ else update(payload, "div")
1115
+ }
1116
+ }, bail)
1117
+ redrawService0.subscribe(root, run1)
1118
+ }
1119
+ route.set = function(path, data, options) {
1120
+ if (lastUpdate != null) options = {replace: true}
1121
+ lastUpdate = null
1122
+ routeService.setPath(path, data, options)
1123
+ }
1124
+ route.get = function() {return currentPath}
1125
+ route.prefix = function(prefix0) {routeService.prefix = prefix0}
1126
+ route.link = function(vnode1) {
1127
+ vnode1.dom.setAttribute("href", routeService.prefix + vnode1.attrs.href)
1128
+ vnode1.dom.onclick = function(e) {
1129
+ if (e.ctrlKey || e.metaKey || e.shiftKey || e.which === 2) return
1130
+ e.preventDefault()
1131
+ e.redraw = false
1132
+ var href = this.getAttribute("href")
1133
+ if (href.indexOf(routeService.prefix) === 0) href = href.slice(routeService.prefix.length)
1134
+ route.set(href, undefined, undefined)
1135
+ }
1136
+ }
1137
+ route.param = function(key3) {
1138
+ if(typeof attrs3 !== "undefined" && typeof key3 !== "undefined") return attrs3[key3]
1139
+ return attrs3
1140
+ }
1141
+ return route
1142
+ }
1143
+ m.route = _20(window, redrawService)
1144
+ m.withAttr = function(attrName, callback1, context) {
1145
+ return function(e) {
1146
+ callback1.call(context || this, attrName in e.currentTarget ? e.currentTarget[attrName] : e.currentTarget.getAttribute(attrName))
1147
+ }
1148
+ }
1149
+ var _28 = coreRenderer(window)
1150
+ m.render = _28.render
1151
+ m.redraw = redrawService.redraw
1152
+ m.request = requestService.request
1153
+ m.jsonp = requestService.jsonp
1154
+ m.parseQueryString = parseQueryString
1155
+ m.buildQueryString = buildQueryString
1156
+ m.version = "1.0.0"
1157
+ m.vnode = Vnode
1158
+ if (typeof module !== "undefined") module["exports"] = m
1159
+ else window.m = m
1160
+ }