1 |
|
2 |
|
3 |
|
4 | !function(exports, Object) {
|
5 |
|
6 | "use strict";
|
7 | var getFns = Object.create(null)
|
8 | , setFns = Object.create(null)
|
9 | , filterFns = Object.create(null)
|
10 | , KEYS = Object.keys
|
11 | , FILTER_ERR = "Invalid filter: "
|
12 | , escRe = /['\n\r\u2028\u2029]|\\(?!x2e)/g
|
13 | , pathRe = /(^$|[\s\S]+?)(?:(?:\[((?:\[[^\]]+\]|[^\]])*)\]|\{([^}]*)})(?:([*^])(.*))?)?(?:\.(?=([^.]))|(?:;(.+))?$)/g
|
14 | , pathArgs = "i,j,I,J,K,m,p,f,r,e,t"
|
15 | , pattRe = /(\w+)(?::((?:(['"\/])(?:\\\3|.)*?\3[gim]*|[^;])*))?/g
|
16 | , reEscRe = /[.+^=:${}()|\/\\]/g
|
17 | , keyRe = /\[(.*?)\]/g
|
18 | , globRe = /\[.+?\]|[?*]/
|
19 | , globReplace = /\?|(?=\*)/g
|
20 | , globGroup = /\[!(?=.*\])/g
|
21 | , primitiveRe = /^(-?(\d*\.)?\d+|true|false|null)$/
|
22 | , valRe = /("|')(?:\\\1|.)*?\1|(\w*)\{((?:("|')(?:\\\4|.)*?\4|\w*\{(?:("|')(?:\\\5|.)*?\5|[^}])*?\}|.)*?)\}|([@$]?)([^,]+)/g
|
23 | , filterRe = /(!?)(\$?)((?:[-+:.\/\w]|\[[^\]]+\]|\{[^}]+}|\\x2e)+)(\[]|\{}|)(?:(!(?=\1)==?|(?=\1)[<>=]=?)((?:("|')(?:\\\7|.)*?\7|\w*\{(?:("|')(?:\\\8|.)*?\8|\{(?:("|')(?:\\\9|.)*?\9|[^}])*?\}|[^{"'])*?\}|[^|&()])*))?(?=[;)|&]|$)|(([;&|])\11*|([()])|.)/g
|
24 | , onlyFilterRe = RegExp("^(?:([@*])|" + filterRe.source.slice(0, -10) + "))+$")
|
25 | , cleanRe = /(\(o=d\)&&(?!.*o=o).*)\(o=d\)&&/g
|
26 | , fns = {
|
27 | "==": "a==d",
|
28 | "===": "a===d",
|
29 | ">": "a<d",
|
30 | ">=": "a<=d",
|
31 | "<": "a>d",
|
32 | "<=": "a>=d",
|
33 | "~": "typeof d==='string'&&a.test(d)"
|
34 | }
|
35 | , fnMap = {
|
36 | w: "Day()||7",
|
37 | Y: "FullYear()%100",
|
38 | M: "Month()+1",
|
39 | D: "Date()",
|
40 | h: "Hours()",
|
41 | H: "Hours()%12||12",
|
42 | m: "Minutes()",
|
43 | s: "Seconds()",
|
44 | S: "Milliseconds()"
|
45 | }
|
46 | , hasOwn = fns.hasOwnProperty
|
47 | , tmpDate = new Date()
|
48 | , isArray = Array.isArray
|
49 |
|
50 | exports.clone = clone
|
51 | exports.matcher = matcher
|
52 | exports.get = function(obj, pointer, fallback) { return pathFn(pointer)(obj, fallback) }
|
53 | exports.isObject = isObject
|
54 | exports.mergePatch = mergePatch
|
55 | exports.set = function(obj, pointer, value) { return pathFn(pointer, true)(obj, value) }
|
56 | exports.setForm = setForm
|
57 | exports.tr = tr
|
58 |
|
59 | exports.get.str = pathStr
|
60 | matcher.re = filterRe
|
61 | matcher.str = filterStr
|
62 | matcher.valRe = valRe
|
63 |
|
64 | exports.ext = {
|
65 | toNum: function(str, dec) {
|
66 | var out = typeof str === "string" ? parseFloat(
|
67 | str.replace(dec || ".", "\ufdff").replace(/[^-e\d\ufdff]/g, "").replace("\ufdff", ".")
|
68 | ) : NaN
|
69 | return out === out ? out : null
|
70 | },
|
71 | toDate: Date.parse
|
72 | }
|
73 |
|
74 | function quote(str) {
|
75 | return "'" + (str || "").replace(escRe, escFn) + "'"
|
76 | }
|
77 |
|
78 | |
79 |
|
80 |
|
81 |
|
82 |
|
83 | function mergePatch(target, patch, changed, previous, pointer) {
|
84 | var undef, key, oldVal, val, len, nextPointer
|
85 | if (isObject(patch)) {
|
86 | if (!pointer) {
|
87 | pointer = ""
|
88 | }
|
89 | if (!isObject(target)) {
|
90 | target = {}
|
91 | }
|
92 | for (key in patch) if (
|
93 | undef !== (oldVal = target[key], val = patch[key]) &&
|
94 | hasOwn.call(patch, key) &&
|
95 | (
|
96 | undef == val ?
|
97 | undef !== oldVal && delete target[key] :
|
98 | target[key] !== val
|
99 | )
|
100 | ) {
|
101 | nextPointer = pointer + "/" + key.replace(/~/g, "~0").replace(/\//g, "~1")
|
102 | len = changed && isObject(target[key]) && changed.length
|
103 | if (undef != val) {
|
104 | target[key] = mergePatch(target[key], val, changed, previous, nextPointer)
|
105 | }
|
106 | if (len === false || changed && len != changed.length) {
|
107 | changed.push(nextPointer)
|
108 | if (previous && !isObject(oldVal)) {
|
109 | previous[nextPointer] = oldVal
|
110 | }
|
111 | }
|
112 | }
|
113 | } else {
|
114 | if (changed && isObject(target)) {
|
115 | val = {}
|
116 | for (key in target) if (hasOwn.call(target, key)) {
|
117 | val[key] = null
|
118 | }
|
119 | mergePatch(target, val, changed, previous, pointer)
|
120 | }
|
121 | target = patch
|
122 | }
|
123 | return target
|
124 | }
|
125 |
|
126 | function escFn(str) {
|
127 | return escape(str).replace(/%u/g, "\\u").replace(/%/g, "\\x")
|
128 | }
|
129 |
|
130 | function pathStr(str, set) {
|
131 | return (
|
132 | str.charAt(0) === "/" ?
|
133 | str.slice(1).replace(/\./g, "\\x2e").replace(/\//g, ".").replace(/~1/g, "/").replace(/~0/g, "~") :
|
134 | str
|
135 | )
|
136 | .replace(pathRe, set === true ? pathSet : pathGet)
|
137 | }
|
138 |
|
139 | function pathGet(str, path, arr, obj, arrExt, arrSup, dot, ext) {
|
140 | var v = dot ? "(o=" : "(c="
|
141 | , sub = arr || obj
|
142 | if (sub && !(sub = onlyFilterRe.exec(sub))) throw Error(FILTER_ERR + str)
|
143 | v = (
|
144 | sub || arrExt ?
|
145 | pathGet(0, path, 0, 0, 0, 0, 1) + (arr || arr === "" ? "i" : "j") + "(o)&&" + v + (
|
146 | arrExt ? "f(o," + (sub ? "m(" + quote(sub[0]) + ")" : "1") + (
|
147 | arrSup ? (arrExt === "*" ? ",p(" : ",r(") + quote(arrSup) + "))" : ")"
|
148 | ) :
|
149 | sub[1] ? (arr ? "o" : "K(o)") + (sub[0] === "*" ? "" : ".length") :
|
150 | +arr == arr ? "o[" + (arr < 0 ? "o.length" + arr : arr) + "]" :
|
151 | sub[0].charAt(0) === "@" ? "o[p(" + quote(sub[0].slice(1)) + ")(d)]" :
|
152 | (arr ? "I" : "J") + "(o,m(" + quote(sub[0]) + "))"
|
153 | ) + ")" :
|
154 | v + "o[" + quote(path) + "])" + (
|
155 | arr === "" ? "&&i(c)&&c" :
|
156 | obj === "" ? "&&j(c)&&c" :
|
157 | ""
|
158 | )
|
159 | ) + (dot ? "&&" : "")
|
160 | if (ext) for (; sub = pattRe.exec(ext); ) {
|
161 | v = "(c=e." + sub[1] + "(" + v + (sub[2] ? "," + sub[2] : "") + "))"
|
162 | }
|
163 | return v
|
164 | }
|
165 |
|
166 | function pathSet(str, path, arr, obj, arrExt, arrSup, dot) {
|
167 | var op = "o[" + quote(path) + "]"
|
168 | , out = ""
|
169 | , sub = arr || obj
|
170 | if (sub || arrExt) {
|
171 | out = "(o=" + (arr || arr === "" ? "i(" : "j(") + op + ")?" + op + ":(" + op + (arr || arr === "" ? "=[]" : "={}") +"))&&"
|
172 | if (arr === "-") {
|
173 | op = "o[o.length]"
|
174 | } else if (+arr == arr) {
|
175 | op = "o[" + (arr < 0 ? "o.length" + arr : arr) + "]"
|
176 | } else if (sub.charAt(0) === "@") {
|
177 | op = "o[p(" + quote(sub.slice(1)) + ")(d)]"
|
178 | } else if (!arrExt) {
|
179 | if (!onlyFilterRe.test(arr)) throw Error(FILTER_ERR + str)
|
180 | op = "o[t]"
|
181 | out += "(t=" + (arr ? "I" : "J") + "(o,m(" + quote(sub) + "),1))!=null&&"
|
182 | }
|
183 | }
|
184 | return out + (
|
185 | arrExt ?
|
186 | "(c=f(o," + (sub ? "m(" + quote(sub) + ")" : 1) + (arrSup ? ",p(" + quote(arrSup) + ",true),v))" : ",0,v))") :
|
187 | dot ?
|
188 | "(o=typeof " + op + "==='object'&&" + op + "||(" + op + "={}))&&" :
|
189 | "((c=" + op + "),(" + op + "=v),c)"
|
190 | )
|
191 | }
|
192 |
|
193 | function pathFn(str, set) {
|
194 | var map = set === true ? setFns : getFns
|
195 | return map[str] || (map[str] = Function(
|
196 | pathArgs,
|
197 | "return function(d,v,b){var c,o;return (o=d)&&" +
|
198 | pathStr(str, set) +
|
199 | (set ? ",c}": "!==void 0?c:v}")
|
200 | )(isArray, isObject, inArray, inObject, KEYS, matcher, pathFn, filterObj, tr, exports.ext))
|
201 | }
|
202 |
|
203 | function clone(obj) {
|
204 | var temp, key
|
205 | if (obj && typeof obj == "object") {
|
206 |
|
207 | temp = obj instanceof Date ? new Date(+obj) :
|
208 | obj instanceof RegExp ? RegExp(obj.source, (""+obj).split("/").pop()) :
|
209 | obj.constructor()
|
210 | for (key in obj) if (hasOwn.call(obj, key)) {
|
211 | temp[key] = clone(obj[key])
|
212 | }
|
213 | obj = temp
|
214 | }
|
215 | return obj
|
216 | }
|
217 |
|
218 | function matcher(str, prefix, opts, getter, tmp) {
|
219 | var optimized
|
220 | , arr = []
|
221 | , key = (prefix || "") + (fns[str] || filterStr(str, opts, arr, getter))
|
222 | , fn = filterFns[key]
|
223 | if (!fn) {
|
224 | for (optimized = key; optimized != (optimized = optimized.replace(cleanRe, "$1")); );
|
225 | fn = filterFns[key] = Function(
|
226 | fns[str] ? "a" : "a," + pathArgs,
|
227 | "return function(d,b){var o;return " + optimized + "}"
|
228 | )
|
229 | fn.source = optimized
|
230 | }
|
231 | return fns[str] ? fn : fn(
|
232 | arr, isArray, isObject, inArray, inObject, KEYS, matcher, pathFn, filterObj, tr, exports.ext, tmp
|
233 | )
|
234 | }
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 | matcher.date = function(str) {
|
246 | return matcher(str, "(t.setTime(typeof d==='string'?Date.parse(d):+d)>=0)&&", null, dateGetter, tmpDate)
|
247 | }
|
248 |
|
249 | function dateGetter(name) {
|
250 | return "(t.get" + fnMap[name] + ")"
|
251 | }
|
252 |
|
253 | function filterStr(qs, opts, arr, getter) {
|
254 | return qs.replace(filterRe, worker).replace(/^[1&]&+|&+1?$/g, "") || "1"
|
255 |
|
256 | function worker(all, not, isOption, attr, isArray, op, val, q1, q2, q3, ext, ok2, ok1) {
|
257 | if (ext) {
|
258 | if (!ok2 && !ok1) {
|
259 | throw Error(FILTER_ERR + qs)
|
260 | }
|
261 | return ok1 ? ok1 : ok2 == ";" ? "&&" : ok2 + ok2
|
262 | }
|
263 | if (isOption) {
|
264 | if (opts) opts[attr] = val
|
265 | return "1"
|
266 | }
|
267 |
|
268 | var idd, m, v, isRe
|
269 | , a = []
|
270 | , pre = "(o=d)&&"
|
271 |
|
272 | attr = (getter || pathStr)(attr)
|
273 |
|
274 | if (m = attr.match(/\(c=(.*?)\)$/)) {
|
275 | if (m[1] == "K(o)") {
|
276 | pre += attr + "&&"
|
277 | attr = "c"
|
278 | } else {
|
279 | if (m.index) pre += attr.slice(0, m.index)
|
280 | attr = m[1]
|
281 | }
|
282 | }
|
283 |
|
284 | if (op == "!=" || op == "!==") {
|
285 | not = "!"
|
286 | op = op.slice(1)
|
287 | }
|
288 | if (isArray) {
|
289 | pre += not + (isArray === "[]" ? "i(" : "j(") + attr + ")"
|
290 | }
|
291 |
|
292 | if (!op) {
|
293 | return isArray === "" ? pre + not + attr : pre
|
294 | }
|
295 |
|
296 | if (op == "=" || op == "==") op += "="
|
297 | if (val === "") val="''"
|
298 | for (; m = valRe.exec(val); ) {
|
299 |
|
300 |
|
301 | isRe = 0
|
302 | v = m[6] == "$" ? "b['"+ m[7] +"']" : arrIdx(arr,
|
303 | m[1] || m[3] ? m[0].slice(m[3] ? m[2].length + 1 : 1, -1) :
|
304 | m[6] ? m[7] :
|
305 | primitiveRe.test(m[0]) ? exports.parse(m[0]) :
|
306 | (isRe = globRe.test(m[0])) ? RegExp(
|
307 | "^" + m[0]
|
308 | .replace(reEscRe, "\\$&")
|
309 | .replace(globReplace, ".")
|
310 | .replace(globGroup, "[^") + "$",
|
311 | op === "==" ? "i" : ""
|
312 | ) :
|
313 | m[0]
|
314 | )
|
315 | idd = (
|
316 | m[2] ? "m." + m[2].toLowerCase() :
|
317 | m[3] ? "m" :
|
318 | isArray || attr === "c" ? arrIdx(arr, matcher(isRe ? "~" : op)) :
|
319 | ""
|
320 | ) + "(" + v
|
321 | a.push(
|
322 | isArray || attr === "c" ? (isArray == "{}" ? "J(" : "I(") + attr + "," + idd + "))" :
|
323 | m[2] || m[3] ? idd + ")(" + attr + ")" :
|
324 | isRe ? "typeof " + attr + "==='string'&&" + v + ".test(" + attr + ")" :
|
325 | m[6] ? attr + "!==void 0&&" + attr + op + (
|
326 | m[6] == "$" ? "b['"+ m[7] +"']" : "p(" + v + ")(o)"
|
327 | ) :
|
328 | attr + op + v
|
329 | )
|
330 | }
|
331 |
|
332 | return pre + (
|
333 | isArray ? (not ? "||" : "&&") : ""
|
334 | ) + not + "(" + a.join("||") + ")"
|
335 | }
|
336 | }
|
337 |
|
338 | function arrIdx(arr, val) {
|
339 | for (
|
340 | var i = arr.length;
|
341 | 0 <= --i && !(
|
342 | arr[i] === val ||
|
343 | val && val.source && val.source === arr[i].source
|
344 | );
|
345 | );
|
346 | return "a[" + (-1 < i ? i : arr.push(val) - 1) + "]"
|
347 | }
|
348 |
|
349 | function setForm(map, key_, val) {
|
350 | for (var match, key = key_, step = map; match = keyRe.exec(key_); ) {
|
351 | if (step === map) key = key.slice(0, match.index)
|
352 | match = match[1]
|
353 | step = step[key] || (
|
354 | step[key] = match && +match != match ? {} : []
|
355 | )
|
356 | key = match
|
357 | }
|
358 | if (isArray(step)) {
|
359 | step.push(val)
|
360 | } else if (isArray(step[key])) {
|
361 | step[key].push(val)
|
362 | } else {
|
363 | step[key] = step[key] != null ? [step[key], val] : val
|
364 | }
|
365 | }
|
366 |
|
367 | function tr(attrs, aclFn) {
|
368 | var attr, tmp
|
369 | , arr = []
|
370 | , map = {}
|
371 | , i = 0
|
372 | for (; attr = valRe.exec(attrs); ) {
|
373 | tmp = attr[0].split(":")
|
374 | exports.set(map, tmp[0], i)
|
375 | arr[i++] = pathFn(tmp[1] ? attr[0].slice(tmp[0].length+1) : tmp[0])
|
376 | }
|
377 | return Function(
|
378 | "g,a",
|
379 | "return function(o,a){return " +
|
380 | exports.stringify(map).replace(/:(\d+)/g,":g[$1](o)") + "}"
|
381 | )(arr, aclFn)
|
382 | }
|
383 |
|
384 | function isObject(obj) {
|
385 | return !!obj && obj.constructor === Object
|
386 | }
|
387 |
|
388 | function inArray(a, fn, idx) {
|
389 | for (var i = -1, len = a.length; ++i < len; ) {
|
390 | if (fn(a[i])) return idx == null ? a[i] : i
|
391 | }
|
392 | return idx != null && len
|
393 | }
|
394 |
|
395 | function inObject(o, fn, idx) {
|
396 | for (var key in o) {
|
397 | if (fn(o[key])) return idx == null ? o[key] : key
|
398 | }
|
399 | return null
|
400 | }
|
401 |
|
402 | function filterObj(a, match, get, val) {
|
403 | var out = []
|
404 | , i = -1
|
405 | , len = a.length
|
406 | if (isObject(a)) {
|
407 | for (i in a) if (hasOwn.call(a, i) && (match === 1 || match(a[i]))) {
|
408 | out.push(get ? get(a[i], val) : a[i])
|
409 | if (get === 0) a[i] = val
|
410 | }
|
411 | } else {
|
412 | for (; ++i < len; ) if (match === 1 || match(a[i])) {
|
413 | out.push(get ? get(a[i], val) : a[i])
|
414 | if (get === 0) a[i] = val
|
415 | }
|
416 | }
|
417 | return out
|
418 | }
|
419 | // `this` refers to the `window` in browser and to the `exports` in Node.js.
|
420 | }(JSON, Object) // jshint ignore:line
|
421 |
|
422 |
|