stylus-source 0.31.0 → 0.32.0

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 (143) hide show
  1. checksums.yaml +7 -0
  2. data/VERSION +1 -1
  3. data/vendor/lib/nodes/unit.js +1 -1
  4. data/vendor/lib/parser.js +0 -1
  5. data/vendor/lib/renderer.js +2 -0
  6. data/vendor/lib/visitor/compiler.js +6 -0
  7. data/vendor/node_modules/cssom/README.mdown +34 -0
  8. data/vendor/node_modules/cssom/package.json +2 -1
  9. data/vendor/node_modules/debug/History.md +15 -0
  10. data/vendor/node_modules/debug/Readme.md +3 -18
  11. data/vendor/node_modules/debug/component.json +9 -0
  12. data/vendor/node_modules/debug/debug.js +10 -2
  13. data/vendor/node_modules/debug/index.js +5 -2
  14. data/vendor/node_modules/debug/lib/debug.js +5 -6
  15. data/vendor/node_modules/debug/package.json +11 -6
  16. data/vendor/node_modules/mkdirp/package.json +6 -9
  17. data/vendor/node_modules/mkdirp/{README.markdown → readme.markdown} +26 -24
  18. data/vendor/node_modules/mocha/History.md +140 -58
  19. data/vendor/node_modules/mocha/LICENSE +2 -2
  20. data/vendor/node_modules/mocha/Makefile +20 -5
  21. data/vendor/node_modules/mocha/Readme.md +110 -22
  22. data/vendor/node_modules/mocha/_mocha.js +574 -182
  23. data/vendor/node_modules/mocha/bin/_mocha +39 -22
  24. data/vendor/node_modules/mocha/bin/mocha +6 -2
  25. data/vendor/node_modules/mocha/component.json +16 -0
  26. data/vendor/node_modules/mocha/lib/browser/debug.js +1 -2
  27. data/vendor/node_modules/mocha/lib/browser/diff.js +287 -0
  28. data/vendor/node_modules/mocha/lib/browser/tty.js +7 -2
  29. data/vendor/node_modules/mocha/lib/hook.js +0 -1
  30. data/vendor/node_modules/mocha/lib/interfaces/bdd.js +3 -3
  31. data/vendor/node_modules/mocha/lib/interfaces/exports.js +5 -5
  32. data/vendor/node_modules/mocha/lib/interfaces/qunit.js +38 -9
  33. data/vendor/node_modules/mocha/lib/interfaces/tdd.js +15 -2
  34. data/vendor/node_modules/mocha/lib/mocha.js +20 -4
  35. data/vendor/node_modules/mocha/lib/reporters/base.js +57 -37
  36. data/vendor/node_modules/mocha/lib/reporters/html.js +2 -4
  37. data/vendor/node_modules/mocha/lib/reporters/json-stream.js +4 -14
  38. data/vendor/node_modules/mocha/lib/reporters/json.js +9 -19
  39. data/vendor/node_modules/mocha/lib/reporters/markdown.js +0 -1
  40. data/vendor/node_modules/mocha/lib/reporters/min.js +2 -2
  41. data/vendor/node_modules/mocha/lib/reporters/nyan.js +33 -39
  42. data/vendor/node_modules/mocha/lib/reporters/tap.js +12 -2
  43. data/vendor/node_modules/mocha/lib/reporters/templates/coverage.jade +3 -3
  44. data/vendor/node_modules/mocha/lib/reporters/templates/menu.jade +1 -1
  45. data/vendor/node_modules/mocha/lib/reporters/xunit.js +4 -4
  46. data/vendor/node_modules/mocha/lib/runnable.js +7 -9
  47. data/vendor/node_modules/mocha/lib/runner.js +24 -9
  48. data/vendor/node_modules/mocha/lib/template.html +2 -1
  49. data/vendor/node_modules/mocha/lib/utils.js +3 -3
  50. data/vendor/node_modules/mocha/mocha.css +37 -13
  51. data/vendor/node_modules/mocha/mocha.js +661 -253
  52. data/vendor/node_modules/mocha/node_modules/commander/package.json +5 -1
  53. data/vendor/node_modules/mocha/node_modules/diff/package.json +5 -1
  54. data/vendor/node_modules/mocha/node_modules/glob/LICENSE +27 -0
  55. data/vendor/node_modules/mocha/node_modules/glob/README.md +250 -0
  56. data/vendor/node_modules/mocha/node_modules/glob/examples/g.js +9 -0
  57. data/vendor/node_modules/mocha/node_modules/glob/examples/usr-local.js +9 -0
  58. data/vendor/node_modules/mocha/node_modules/glob/glob.js +675 -0
  59. data/vendor/node_modules/mocha/node_modules/glob/node_modules/graceful-fs/LICENSE +27 -0
  60. data/vendor/node_modules/mocha/node_modules/glob/node_modules/graceful-fs/README.md +33 -0
  61. data/vendor/node_modules/mocha/node_modules/glob/node_modules/graceful-fs/graceful-fs.js +442 -0
  62. data/vendor/node_modules/mocha/node_modules/glob/node_modules/graceful-fs/package.json +49 -0
  63. data/vendor/node_modules/mocha/node_modules/glob/node_modules/graceful-fs/test/open.js +46 -0
  64. data/vendor/node_modules/mocha/node_modules/glob/node_modules/graceful-fs/test/ulimit.js +158 -0
  65. data/vendor/node_modules/mocha/node_modules/glob/node_modules/inherits/README.md +51 -0
  66. data/vendor/node_modules/mocha/node_modules/glob/node_modules/inherits/inherits.js +29 -0
  67. data/vendor/node_modules/mocha/node_modules/glob/node_modules/inherits/package.json +26 -0
  68. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/LICENSE +23 -0
  69. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/README.md +218 -0
  70. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/minimatch.js +1079 -0
  71. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/AUTHORS +8 -0
  72. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE +23 -0
  73. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md +97 -0
  74. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js +257 -0
  75. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json +59 -0
  76. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/s.js +25 -0
  77. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js +329 -0
  78. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js +52 -0
  79. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js +50 -0
  80. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE +27 -0
  81. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md +53 -0
  82. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js +283 -0
  83. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json +38 -0
  84. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js +39 -0
  85. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js +24 -0
  86. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/package.json +36 -0
  87. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/basic.js +399 -0
  88. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/brace-expand.js +33 -0
  89. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/caching.js +14 -0
  90. data/vendor/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/defaults.js +274 -0
  91. data/vendor/node_modules/mocha/node_modules/glob/package.json +40 -0
  92. data/vendor/node_modules/mocha/node_modules/glob/test/00-setup.js +176 -0
  93. data/vendor/node_modules/mocha/node_modules/glob/test/bash-comparison.js +63 -0
  94. data/vendor/node_modules/mocha/node_modules/glob/test/bash-results.json +350 -0
  95. data/vendor/node_modules/mocha/node_modules/glob/test/cwd-test.js +55 -0
  96. data/vendor/node_modules/mocha/node_modules/glob/test/globstar-match.js +19 -0
  97. data/vendor/node_modules/mocha/node_modules/glob/test/mark.js +74 -0
  98. data/vendor/node_modules/mocha/node_modules/glob/test/nocase-nomagic.js +113 -0
  99. data/vendor/node_modules/mocha/node_modules/glob/test/pause-resume.js +73 -0
  100. data/vendor/node_modules/mocha/node_modules/glob/test/root-nomount.js +39 -0
  101. data/vendor/node_modules/mocha/node_modules/glob/test/root.js +46 -0
  102. data/vendor/node_modules/mocha/node_modules/glob/test/stat.js +32 -0
  103. data/vendor/node_modules/mocha/node_modules/glob/test/zz-cleanup.js +11 -0
  104. data/vendor/node_modules/mocha/node_modules/growl/History.md +5 -0
  105. data/vendor/node_modules/mocha/node_modules/growl/lib/growl.js +2 -0
  106. data/vendor/node_modules/mocha/node_modules/growl/package.json +7 -3
  107. data/vendor/node_modules/mocha/node_modules/jade/node_modules/mkdirp/package.json +5 -1
  108. data/vendor/node_modules/mocha/node_modules/jade/package.json +5 -1
  109. data/vendor/node_modules/mocha/node_modules/ms/package.json +5 -1
  110. data/vendor/node_modules/mocha/package.json +13 -7
  111. data/vendor/node_modules/mocha/test.js +10 -21
  112. data/vendor/node_modules/should/History.md +5 -0
  113. data/vendor/node_modules/should/Readme.md +172 -172
  114. data/vendor/node_modules/should/lib/eql.js +2 -0
  115. data/vendor/node_modules/should/lib/should.js +4 -3
  116. data/vendor/node_modules/should/package.json +8 -4
  117. data/vendor/node_modules/should/test/should.test.js +27 -0
  118. data/vendor/package.json +1 -1
  119. metadata +61 -35
  120. data/vendor/node_modules/debug/Makefile +0 -4
  121. data/vendor/node_modules/debug/debug.component.js +0 -120
  122. data/vendor/node_modules/debug/head.js +0 -1
  123. data/vendor/node_modules/debug/tail.js +0 -4
  124. data/vendor/node_modules/mocha/node_modules/mkdirp/LICENSE +0 -21
  125. data/vendor/node_modules/mocha/node_modules/mkdirp/README.markdown +0 -61
  126. data/vendor/node_modules/mocha/node_modules/mkdirp/examples/pow.js +0 -6
  127. data/vendor/node_modules/mocha/node_modules/mkdirp/examples/pow.js.orig +0 -6
  128. data/vendor/node_modules/mocha/node_modules/mkdirp/examples/pow.js.rej +0 -19
  129. data/vendor/node_modules/mocha/node_modules/mkdirp/index.js +0 -94
  130. data/vendor/node_modules/mocha/node_modules/mkdirp/package.json +0 -33
  131. data/vendor/node_modules/mocha/node_modules/mkdirp/test/chmod.js +0 -38
  132. data/vendor/node_modules/mocha/node_modules/mkdirp/test/clobber.js +0 -37
  133. data/vendor/node_modules/mocha/node_modules/mkdirp/test/mkdirp.js +0 -28
  134. data/vendor/node_modules/mocha/node_modules/mkdirp/test/perm.js +0 -32
  135. data/vendor/node_modules/mocha/node_modules/mkdirp/test/perm_sync.js +0 -39
  136. data/vendor/node_modules/mocha/node_modules/mkdirp/test/race.js +0 -41
  137. data/vendor/node_modules/mocha/node_modules/mkdirp/test/rel.js +0 -32
  138. data/vendor/node_modules/mocha/node_modules/mkdirp/test/return.js +0 -25
  139. data/vendor/node_modules/mocha/node_modules/mkdirp/test/return_sync.js +0 -24
  140. data/vendor/node_modules/mocha/node_modules/mkdirp/test/root.js +0 -18
  141. data/vendor/node_modules/mocha/node_modules/mkdirp/test/sync.js +0 -32
  142. data/vendor/node_modules/mocha/node_modules/mkdirp/test/umask.js +0 -28
  143. data/vendor/node_modules/mocha/node_modules/mkdirp/test/umask_sync.js +0 -32
@@ -0,0 +1,1079 @@
1
+ ;(function (require, exports, module, platform) {
2
+
3
+ if (module) module.exports = minimatch
4
+ else exports.minimatch = minimatch
5
+
6
+ if (!require) {
7
+ require = function (id) {
8
+ switch (id) {
9
+ case "sigmund": return function sigmund (obj) {
10
+ return JSON.stringify(obj)
11
+ }
12
+ case "path": return { basename: function (f) {
13
+ f = f.split(/[\/\\]/)
14
+ var e = f.pop()
15
+ if (!e) e = f.pop()
16
+ return e
17
+ }}
18
+ case "lru-cache": return function LRUCache () {
19
+ // not quite an LRU, but still space-limited.
20
+ var cache = {}
21
+ var cnt = 0
22
+ this.set = function (k, v) {
23
+ cnt ++
24
+ if (cnt >= 100) cache = {}
25
+ cache[k] = v
26
+ }
27
+ this.get = function (k) { return cache[k] }
28
+ }
29
+ }
30
+ }
31
+ }
32
+
33
+ minimatch.Minimatch = Minimatch
34
+
35
+ var LRU = require("lru-cache")
36
+ , cache = minimatch.cache = new LRU({max: 100})
37
+ , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
38
+ , sigmund = require("sigmund")
39
+
40
+ var path = require("path")
41
+ // any single thing other than /
42
+ // don't need to escape / when using new RegExp()
43
+ , qmark = "[^/]"
44
+
45
+ // * => any number of characters
46
+ , star = qmark + "*?"
47
+
48
+ // ** when dots are allowed. Anything goes, except .. and .
49
+ // not (^ or / followed by one or two dots followed by $ or /),
50
+ // followed by anything, any number of times.
51
+ , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
52
+
53
+ // not a ^ or / followed by a dot,
54
+ // followed by anything, any number of times.
55
+ , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
56
+
57
+ // characters that need to be escaped in RegExp.
58
+ , reSpecials = charSet("().*{}+?[]^$\\!")
59
+
60
+ // "abc" -> { a:true, b:true, c:true }
61
+ function charSet (s) {
62
+ return s.split("").reduce(function (set, c) {
63
+ set[c] = true
64
+ return set
65
+ }, {})
66
+ }
67
+
68
+ // normalizes slashes.
69
+ var slashSplit = /\/+/
70
+
71
+ minimatch.monkeyPatch = monkeyPatch
72
+ function monkeyPatch () {
73
+ var desc = Object.getOwnPropertyDescriptor(String.prototype, "match")
74
+ var orig = desc.value
75
+ desc.value = function (p) {
76
+ if (p instanceof Minimatch) return p.match(this)
77
+ return orig.call(this, p)
78
+ }
79
+ Object.defineProperty(String.prototype, desc)
80
+ }
81
+
82
+ minimatch.filter = filter
83
+ function filter (pattern, options) {
84
+ options = options || {}
85
+ return function (p, i, list) {
86
+ return minimatch(p, pattern, options)
87
+ }
88
+ }
89
+
90
+ function ext (a, b) {
91
+ a = a || {}
92
+ b = b || {}
93
+ var t = {}
94
+ Object.keys(b).forEach(function (k) {
95
+ t[k] = b[k]
96
+ })
97
+ Object.keys(a).forEach(function (k) {
98
+ t[k] = a[k]
99
+ })
100
+ return t
101
+ }
102
+
103
+ minimatch.defaults = function (def) {
104
+ if (!def || !Object.keys(def).length) return minimatch
105
+
106
+ var orig = minimatch
107
+
108
+ var m = function minimatch (p, pattern, options) {
109
+ return orig.minimatch(p, pattern, ext(def, options))
110
+ }
111
+
112
+ m.Minimatch = function Minimatch (pattern, options) {
113
+ return new orig.Minimatch(pattern, ext(def, options))
114
+ }
115
+
116
+ return m
117
+ }
118
+
119
+ Minimatch.defaults = function (def) {
120
+ if (!def || !Object.keys(def).length) return Minimatch
121
+ return minimatch.defaults(def).Minimatch
122
+ }
123
+
124
+
125
+ function minimatch (p, pattern, options) {
126
+ if (typeof pattern !== "string") {
127
+ throw new TypeError("glob pattern string required")
128
+ }
129
+
130
+ if (!options) options = {}
131
+
132
+ // shortcut: comments match nothing.
133
+ if (!options.nocomment && pattern.charAt(0) === "#") {
134
+ return false
135
+ }
136
+
137
+ // "" only matches ""
138
+ if (pattern.trim() === "") return p === ""
139
+
140
+ return new Minimatch(pattern, options).match(p)
141
+ }
142
+
143
+ function Minimatch (pattern, options) {
144
+ if (!(this instanceof Minimatch)) {
145
+ return new Minimatch(pattern, options, cache)
146
+ }
147
+
148
+ if (typeof pattern !== "string") {
149
+ throw new TypeError("glob pattern string required")
150
+ }
151
+
152
+ if (!options) options = {}
153
+ pattern = pattern.trim()
154
+
155
+ // windows: need to use /, not \
156
+ // On other platforms, \ is a valid (albeit bad) filename char.
157
+ if (platform === "win32") {
158
+ pattern = pattern.split("\\").join("/")
159
+ }
160
+
161
+ // lru storage.
162
+ // these things aren't particularly big, but walking down the string
163
+ // and turning it into a regexp can get pretty costly.
164
+ var cacheKey = pattern + "\n" + sigmund(options)
165
+ var cached = minimatch.cache.get(cacheKey)
166
+ if (cached) return cached
167
+ minimatch.cache.set(cacheKey, this)
168
+
169
+ this.options = options
170
+ this.set = []
171
+ this.pattern = pattern
172
+ this.regexp = null
173
+ this.negate = false
174
+ this.comment = false
175
+ this.empty = false
176
+
177
+ // make the set of regexps etc.
178
+ this.make()
179
+ }
180
+
181
+ Minimatch.prototype.make = make
182
+ function make () {
183
+ // don't do it more than once.
184
+ if (this._made) return
185
+
186
+ var pattern = this.pattern
187
+ var options = this.options
188
+
189
+ // empty patterns and comments match nothing.
190
+ if (!options.nocomment && pattern.charAt(0) === "#") {
191
+ this.comment = true
192
+ return
193
+ }
194
+ if (!pattern) {
195
+ this.empty = true
196
+ return
197
+ }
198
+
199
+ // step 1: figure out negation, etc.
200
+ this.parseNegate()
201
+
202
+ // step 2: expand braces
203
+ var set = this.globSet = this.braceExpand()
204
+
205
+ if (options.debug) console.error(this.pattern, set)
206
+
207
+ // step 3: now we have a set, so turn each one into a series of path-portion
208
+ // matching patterns.
209
+ // These will be regexps, except in the case of "**", which is
210
+ // set to the GLOBSTAR object for globstar behavior,
211
+ // and will not contain any / characters
212
+ set = this.globParts = set.map(function (s) {
213
+ return s.split(slashSplit)
214
+ })
215
+
216
+ if (options.debug) console.error(this.pattern, set)
217
+
218
+ // glob --> regexps
219
+ set = set.map(function (s, si, set) {
220
+ return s.map(this.parse, this)
221
+ }, this)
222
+
223
+ if (options.debug) console.error(this.pattern, set)
224
+
225
+ // filter out everything that didn't compile properly.
226
+ set = set.filter(function (s) {
227
+ return -1 === s.indexOf(false)
228
+ })
229
+
230
+ if (options.debug) console.error(this.pattern, set)
231
+
232
+ this.set = set
233
+ }
234
+
235
+ Minimatch.prototype.parseNegate = parseNegate
236
+ function parseNegate () {
237
+ var pattern = this.pattern
238
+ , negate = false
239
+ , options = this.options
240
+ , negateOffset = 0
241
+
242
+ if (options.nonegate) return
243
+
244
+ for ( var i = 0, l = pattern.length
245
+ ; i < l && pattern.charAt(i) === "!"
246
+ ; i ++) {
247
+ negate = !negate
248
+ negateOffset ++
249
+ }
250
+
251
+ if (negateOffset) this.pattern = pattern.substr(negateOffset)
252
+ this.negate = negate
253
+ }
254
+
255
+ // Brace expansion:
256
+ // a{b,c}d -> abd acd
257
+ // a{b,}c -> abc ac
258
+ // a{0..3}d -> a0d a1d a2d a3d
259
+ // a{b,c{d,e}f}g -> abg acdfg acefg
260
+ // a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
261
+ //
262
+ // Invalid sets are not expanded.
263
+ // a{2..}b -> a{2..}b
264
+ // a{b}c -> a{b}c
265
+ minimatch.braceExpand = function (pattern, options) {
266
+ return new Minimatch(pattern, options).braceExpand()
267
+ }
268
+
269
+ Minimatch.prototype.braceExpand = braceExpand
270
+ function braceExpand (pattern, options) {
271
+ options = options || this.options
272
+ pattern = typeof pattern === "undefined"
273
+ ? this.pattern : pattern
274
+
275
+ if (typeof pattern === "undefined") {
276
+ throw new Error("undefined pattern")
277
+ }
278
+
279
+ if (options.nobrace ||
280
+ !pattern.match(/\{.*\}/)) {
281
+ // shortcut. no need to expand.
282
+ return [pattern]
283
+ }
284
+
285
+ var escaping = false
286
+
287
+ // examples and comments refer to this crazy pattern:
288
+ // a{b,c{d,e},{f,g}h}x{y,z}
289
+ // expected:
290
+ // abxy
291
+ // abxz
292
+ // acdxy
293
+ // acdxz
294
+ // acexy
295
+ // acexz
296
+ // afhxy
297
+ // afhxz
298
+ // aghxy
299
+ // aghxz
300
+
301
+ // everything before the first \{ is just a prefix.
302
+ // So, we pluck that off, and work with the rest,
303
+ // and then prepend it to everything we find.
304
+ if (pattern.charAt(0) !== "{") {
305
+ // console.error(pattern)
306
+ var prefix = null
307
+ for (var i = 0, l = pattern.length; i < l; i ++) {
308
+ var c = pattern.charAt(i)
309
+ // console.error(i, c)
310
+ if (c === "\\") {
311
+ escaping = !escaping
312
+ } else if (c === "{" && !escaping) {
313
+ prefix = pattern.substr(0, i)
314
+ break
315
+ }
316
+ }
317
+
318
+ // actually no sets, all { were escaped.
319
+ if (prefix === null) {
320
+ // console.error("no sets")
321
+ return [pattern]
322
+ }
323
+
324
+ var tail = braceExpand(pattern.substr(i), options)
325
+ return tail.map(function (t) {
326
+ return prefix + t
327
+ })
328
+ }
329
+
330
+ // now we have something like:
331
+ // {b,c{d,e},{f,g}h}x{y,z}
332
+ // walk through the set, expanding each part, until
333
+ // the set ends. then, we'll expand the suffix.
334
+ // If the set only has a single member, then'll put the {} back
335
+
336
+ // first, handle numeric sets, since they're easier
337
+ var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
338
+ if (numset) {
339
+ // console.error("numset", numset[1], numset[2])
340
+ var suf = braceExpand(pattern.substr(numset[0].length), options)
341
+ , start = +numset[1]
342
+ , end = +numset[2]
343
+ , inc = start > end ? -1 : 1
344
+ , set = []
345
+ for (var i = start; i != (end + inc); i += inc) {
346
+ // append all the suffixes
347
+ for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
348
+ set.push(i + suf[ii])
349
+ }
350
+ }
351
+ return set
352
+ }
353
+
354
+ // ok, walk through the set
355
+ // We hope, somewhat optimistically, that there
356
+ // will be a } at the end.
357
+ // If the closing brace isn't found, then the pattern is
358
+ // interpreted as braceExpand("\\" + pattern) so that
359
+ // the leading \{ will be interpreted literally.
360
+ var i = 1 // skip the \{
361
+ , depth = 1
362
+ , set = []
363
+ , member = ""
364
+ , sawEnd = false
365
+ , escaping = false
366
+
367
+ function addMember () {
368
+ set.push(member)
369
+ member = ""
370
+ }
371
+
372
+ // console.error("Entering for")
373
+ FOR: for (i = 1, l = pattern.length; i < l; i ++) {
374
+ var c = pattern.charAt(i)
375
+ // console.error("", i, c)
376
+
377
+ if (escaping) {
378
+ escaping = false
379
+ member += "\\" + c
380
+ } else {
381
+ switch (c) {
382
+ case "\\":
383
+ escaping = true
384
+ continue
385
+
386
+ case "{":
387
+ depth ++
388
+ member += "{"
389
+ continue
390
+
391
+ case "}":
392
+ depth --
393
+ // if this closes the actual set, then we're done
394
+ if (depth === 0) {
395
+ addMember()
396
+ // pluck off the close-brace
397
+ i ++
398
+ break FOR
399
+ } else {
400
+ member += c
401
+ continue
402
+ }
403
+
404
+ case ",":
405
+ if (depth === 1) {
406
+ addMember()
407
+ } else {
408
+ member += c
409
+ }
410
+ continue
411
+
412
+ default:
413
+ member += c
414
+ continue
415
+ } // switch
416
+ } // else
417
+ } // for
418
+
419
+ // now we've either finished the set, and the suffix is
420
+ // pattern.substr(i), or we have *not* closed the set,
421
+ // and need to escape the leading brace
422
+ if (depth !== 0) {
423
+ // console.error("didn't close", pattern)
424
+ return braceExpand("\\" + pattern, options)
425
+ }
426
+
427
+ // x{y,z} -> ["xy", "xz"]
428
+ // console.error("set", set)
429
+ // console.error("suffix", pattern.substr(i))
430
+ var suf = braceExpand(pattern.substr(i), options)
431
+ // ["b", "c{d,e}","{f,g}h"] ->
432
+ // [["b"], ["cd", "ce"], ["fh", "gh"]]
433
+ var addBraces = set.length === 1
434
+ // console.error("set pre-expanded", set)
435
+ set = set.map(function (p) {
436
+ return braceExpand(p, options)
437
+ })
438
+ // console.error("set expanded", set)
439
+
440
+
441
+ // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
442
+ // ["b", "cd", "ce", "fh", "gh"]
443
+ set = set.reduce(function (l, r) {
444
+ return l.concat(r)
445
+ })
446
+
447
+ if (addBraces) {
448
+ set = set.map(function (s) {
449
+ return "{" + s + "}"
450
+ })
451
+ }
452
+
453
+ // now attach the suffixes.
454
+ var ret = []
455
+ for (var i = 0, l = set.length; i < l; i ++) {
456
+ for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
457
+ ret.push(set[i] + suf[ii])
458
+ }
459
+ }
460
+ return ret
461
+ }
462
+
463
+ // parse a component of the expanded set.
464
+ // At this point, no pattern may contain "/" in it
465
+ // so we're going to return a 2d array, where each entry is the full
466
+ // pattern, split on '/', and then turned into a regular expression.
467
+ // A regexp is made at the end which joins each array with an
468
+ // escaped /, and another full one which joins each regexp with |.
469
+ //
470
+ // Following the lead of Bash 4.1, note that "**" only has special meaning
471
+ // when it is the *only* thing in a path portion. Otherwise, any series
472
+ // of * is equivalent to a single *. Globstar behavior is enabled by
473
+ // default, and can be disabled by setting options.noglobstar.
474
+ Minimatch.prototype.parse = parse
475
+ var SUBPARSE = {}
476
+ function parse (pattern, isSub) {
477
+ var options = this.options
478
+
479
+ // shortcuts
480
+ if (!options.noglobstar && pattern === "**") return GLOBSTAR
481
+ if (pattern === "") return ""
482
+
483
+ var re = ""
484
+ , hasMagic = !!options.nocase
485
+ , escaping = false
486
+ // ? => one single character
487
+ , patternListStack = []
488
+ , plType
489
+ , stateChar
490
+ , inClass = false
491
+ , reClassStart = -1
492
+ , classStart = -1
493
+ // . and .. never match anything that doesn't start with .,
494
+ // even when options.dot is set.
495
+ , patternStart = pattern.charAt(0) === "." ? "" // anything
496
+ // not (start or / followed by . or .. followed by / or end)
497
+ : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
498
+ : "(?!\\.)"
499
+
500
+ function clearStateChar () {
501
+ if (stateChar) {
502
+ // we had some state-tracking character
503
+ // that wasn't consumed by this pass.
504
+ switch (stateChar) {
505
+ case "*":
506
+ re += star
507
+ hasMagic = true
508
+ break
509
+ case "?":
510
+ re += qmark
511
+ hasMagic = true
512
+ break
513
+ default:
514
+ re += "\\"+stateChar
515
+ break
516
+ }
517
+ stateChar = false
518
+ }
519
+ }
520
+
521
+ for ( var i = 0, len = pattern.length, c
522
+ ; (i < len) && (c = pattern.charAt(i))
523
+ ; i ++ ) {
524
+
525
+ if (options.debug) {
526
+ console.error("%s\t%s %s %j", pattern, i, re, c)
527
+ }
528
+
529
+ // skip over any that are escaped.
530
+ if (escaping && reSpecials[c]) {
531
+ re += "\\" + c
532
+ escaping = false
533
+ continue
534
+ }
535
+
536
+ SWITCH: switch (c) {
537
+ case "/":
538
+ // completely not allowed, even escaped.
539
+ // Should already be path-split by now.
540
+ return false
541
+
542
+ case "\\":
543
+ clearStateChar()
544
+ escaping = true
545
+ continue
546
+
547
+ // the various stateChar values
548
+ // for the "extglob" stuff.
549
+ case "?":
550
+ case "*":
551
+ case "+":
552
+ case "@":
553
+ case "!":
554
+ if (options.debug) {
555
+ console.error("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
556
+ }
557
+
558
+ // all of those are literals inside a class, except that
559
+ // the glob [!a] means [^a] in regexp
560
+ if (inClass) {
561
+ if (c === "!" && i === classStart + 1) c = "^"
562
+ re += c
563
+ continue
564
+ }
565
+
566
+ // if we already have a stateChar, then it means
567
+ // that there was something like ** or +? in there.
568
+ // Handle the stateChar, then proceed with this one.
569
+ clearStateChar()
570
+ stateChar = c
571
+ // if extglob is disabled, then +(asdf|foo) isn't a thing.
572
+ // just clear the statechar *now*, rather than even diving into
573
+ // the patternList stuff.
574
+ if (options.noext) clearStateChar()
575
+ continue
576
+
577
+ case "(":
578
+ if (inClass) {
579
+ re += "("
580
+ continue
581
+ }
582
+
583
+ if (!stateChar) {
584
+ re += "\\("
585
+ continue
586
+ }
587
+
588
+ plType = stateChar
589
+ patternListStack.push({ type: plType
590
+ , start: i - 1
591
+ , reStart: re.length })
592
+ // negation is (?:(?!js)[^/]*)
593
+ re += stateChar === "!" ? "(?:(?!" : "(?:"
594
+ stateChar = false
595
+ continue
596
+
597
+ case ")":
598
+ if (inClass || !patternListStack.length) {
599
+ re += "\\)"
600
+ continue
601
+ }
602
+
603
+ hasMagic = true
604
+ re += ")"
605
+ plType = patternListStack.pop().type
606
+ // negation is (?:(?!js)[^/]*)
607
+ // The others are (?:<pattern>)<type>
608
+ switch (plType) {
609
+ case "!":
610
+ re += "[^/]*?)"
611
+ break
612
+ case "?":
613
+ case "+":
614
+ case "*": re += plType
615
+ case "@": break // the default anyway
616
+ }
617
+ continue
618
+
619
+ case "|":
620
+ if (inClass || !patternListStack.length || escaping) {
621
+ re += "\\|"
622
+ escaping = false
623
+ continue
624
+ }
625
+
626
+ re += "|"
627
+ continue
628
+
629
+ // these are mostly the same in regexp and glob
630
+ case "[":
631
+ // swallow any state-tracking char before the [
632
+ clearStateChar()
633
+
634
+ if (inClass) {
635
+ re += "\\" + c
636
+ continue
637
+ }
638
+
639
+ inClass = true
640
+ classStart = i
641
+ reClassStart = re.length
642
+ re += c
643
+ continue
644
+
645
+ case "]":
646
+ // a right bracket shall lose its special
647
+ // meaning and represent itself in
648
+ // a bracket expression if it occurs
649
+ // first in the list. -- POSIX.2 2.8.3.2
650
+ if (i === classStart + 1 || !inClass) {
651
+ re += "\\" + c
652
+ escaping = false
653
+ continue
654
+ }
655
+
656
+ // finish up the class.
657
+ hasMagic = true
658
+ inClass = false
659
+ re += c
660
+ continue
661
+
662
+ default:
663
+ // swallow any state char that wasn't consumed
664
+ clearStateChar()
665
+
666
+ if (escaping) {
667
+ // no need
668
+ escaping = false
669
+ } else if (reSpecials[c]
670
+ && !(c === "^" && inClass)) {
671
+ re += "\\"
672
+ }
673
+
674
+ re += c
675
+
676
+ } // switch
677
+ } // for
678
+
679
+
680
+ // handle the case where we left a class open.
681
+ // "[abc" is valid, equivalent to "\[abc"
682
+ if (inClass) {
683
+ // split where the last [ was, and escape it
684
+ // this is a huge pita. We now have to re-walk
685
+ // the contents of the would-be class to re-translate
686
+ // any characters that were passed through as-is
687
+ var cs = pattern.substr(classStart + 1)
688
+ , sp = this.parse(cs, SUBPARSE)
689
+ re = re.substr(0, reClassStart) + "\\[" + sp[0]
690
+ hasMagic = hasMagic || sp[1]
691
+ }
692
+
693
+ // handle the case where we had a +( thing at the *end*
694
+ // of the pattern.
695
+ // each pattern list stack adds 3 chars, and we need to go through
696
+ // and escape any | chars that were passed through as-is for the regexp.
697
+ // Go through and escape them, taking care not to double-escape any
698
+ // | chars that were already escaped.
699
+ var pl
700
+ while (pl = patternListStack.pop()) {
701
+ var tail = re.slice(pl.reStart + 3)
702
+ // maybe some even number of \, then maybe 1 \, followed by a |
703
+ tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
704
+ if (!$2) {
705
+ // the | isn't already escaped, so escape it.
706
+ $2 = "\\"
707
+ }
708
+
709
+ // need to escape all those slashes *again*, without escaping the
710
+ // one that we need for escaping the | character. As it works out,
711
+ // escaping an even number of slashes can be done by simply repeating
712
+ // it exactly after itself. That's why this trick works.
713
+ //
714
+ // I am sorry that you have to see this.
715
+ return $1 + $1 + $2 + "|"
716
+ })
717
+
718
+ // console.error("tail=%j\n %s", tail, tail)
719
+ var t = pl.type === "*" ? star
720
+ : pl.type === "?" ? qmark
721
+ : "\\" + pl.type
722
+
723
+ hasMagic = true
724
+ re = re.slice(0, pl.reStart)
725
+ + t + "\\("
726
+ + tail
727
+ }
728
+
729
+ // handle trailing things that only matter at the very end.
730
+ clearStateChar()
731
+ if (escaping) {
732
+ // trailing \\
733
+ re += "\\\\"
734
+ }
735
+
736
+ // only need to apply the nodot start if the re starts with
737
+ // something that could conceivably capture a dot
738
+ var addPatternStart = false
739
+ switch (re.charAt(0)) {
740
+ case ".":
741
+ case "[":
742
+ case "(": addPatternStart = true
743
+ }
744
+
745
+ // if the re is not "" at this point, then we need to make sure
746
+ // it doesn't match against an empty path part.
747
+ // Otherwise a/* will match a/, which it should not.
748
+ if (re !== "" && hasMagic) re = "(?=.)" + re
749
+
750
+ if (addPatternStart) re = patternStart + re
751
+
752
+ // parsing just a piece of a larger pattern.
753
+ if (isSub === SUBPARSE) {
754
+ return [ re, hasMagic ]
755
+ }
756
+
757
+ // skip the regexp for non-magical patterns
758
+ // unescape anything in it, though, so that it'll be
759
+ // an exact match against a file etc.
760
+ if (!hasMagic) {
761
+ return globUnescape(pattern)
762
+ }
763
+
764
+ var flags = options.nocase ? "i" : ""
765
+ , regExp = new RegExp("^" + re + "$", flags)
766
+
767
+ regExp._glob = pattern
768
+ regExp._src = re
769
+
770
+ return regExp
771
+ }
772
+
773
+ minimatch.makeRe = function (pattern, options) {
774
+ return new Minimatch(pattern, options || {}).makeRe()
775
+ }
776
+
777
+ Minimatch.prototype.makeRe = makeRe
778
+ function makeRe () {
779
+ if (this.regexp || this.regexp === false) return this.regexp
780
+
781
+ // at this point, this.set is a 2d array of partial
782
+ // pattern strings, or "**".
783
+ //
784
+ // It's better to use .match(). This function shouldn't
785
+ // be used, really, but it's pretty convenient sometimes,
786
+ // when you just want to work with a regex.
787
+ var set = this.set
788
+
789
+ if (!set.length) return this.regexp = false
790
+ var options = this.options
791
+
792
+ var twoStar = options.noglobstar ? star
793
+ : options.dot ? twoStarDot
794
+ : twoStarNoDot
795
+ , flags = options.nocase ? "i" : ""
796
+
797
+ var re = set.map(function (pattern) {
798
+ return pattern.map(function (p) {
799
+ return (p === GLOBSTAR) ? twoStar
800
+ : (typeof p === "string") ? regExpEscape(p)
801
+ : p._src
802
+ }).join("\\\/")
803
+ }).join("|")
804
+
805
+ // must match entire pattern
806
+ // ending in a * or ** will make it less strict.
807
+ re = "^(?:" + re + ")$"
808
+
809
+ // can match anything, as long as it's not this.
810
+ if (this.negate) re = "^(?!" + re + ").*$"
811
+
812
+ try {
813
+ return this.regexp = new RegExp(re, flags)
814
+ } catch (ex) {
815
+ return this.regexp = false
816
+ }
817
+ }
818
+
819
+ minimatch.match = function (list, pattern, options) {
820
+ var mm = new Minimatch(pattern, options)
821
+ list = list.filter(function (f) {
822
+ return mm.match(f)
823
+ })
824
+ if (options.nonull && !list.length) {
825
+ list.push(pattern)
826
+ }
827
+ return list
828
+ }
829
+
830
+ Minimatch.prototype.match = match
831
+ function match (f, partial) {
832
+ // console.error("match", f, this.pattern)
833
+ // short-circuit in the case of busted things.
834
+ // comments, etc.
835
+ if (this.comment) return false
836
+ if (this.empty) return f === ""
837
+
838
+ if (f === "/" && partial) return true
839
+
840
+ var options = this.options
841
+
842
+ // windows: need to use /, not \
843
+ // On other platforms, \ is a valid (albeit bad) filename char.
844
+ if (platform === "win32") {
845
+ f = f.split("\\").join("/")
846
+ }
847
+
848
+ // treat the test path as a set of pathparts.
849
+ f = f.split(slashSplit)
850
+ if (options.debug) {
851
+ console.error(this.pattern, "split", f)
852
+ }
853
+
854
+ // just ONE of the pattern sets in this.set needs to match
855
+ // in order for it to be valid. If negating, then just one
856
+ // match means that we have failed.
857
+ // Either way, return on the first hit.
858
+
859
+ var set = this.set
860
+ // console.error(this.pattern, "set", set)
861
+
862
+ for (var i = 0, l = set.length; i < l; i ++) {
863
+ var pattern = set[i]
864
+ var hit = this.matchOne(f, pattern, partial)
865
+ if (hit) {
866
+ if (options.flipNegate) return true
867
+ return !this.negate
868
+ }
869
+ }
870
+
871
+ // didn't get any hits. this is success if it's a negative
872
+ // pattern, failure otherwise.
873
+ if (options.flipNegate) return false
874
+ return this.negate
875
+ }
876
+
877
+ // set partial to true to test if, for example,
878
+ // "/a/b" matches the start of "/*/b/*/d"
879
+ // Partial means, if you run out of file before you run
880
+ // out of pattern, then that's fine, as long as all
881
+ // the parts match.
882
+ Minimatch.prototype.matchOne = function (file, pattern, partial) {
883
+ var options = this.options
884
+
885
+ if (options.debug) {
886
+ console.error("matchOne",
887
+ { "this": this
888
+ , file: file
889
+ , pattern: pattern })
890
+ }
891
+
892
+ if (options.matchBase && pattern.length === 1) {
893
+ file = path.basename(file.join("/")).split("/")
894
+ }
895
+
896
+ if (options.debug) {
897
+ console.error("matchOne", file.length, pattern.length)
898
+ }
899
+
900
+ for ( var fi = 0
901
+ , pi = 0
902
+ , fl = file.length
903
+ , pl = pattern.length
904
+ ; (fi < fl) && (pi < pl)
905
+ ; fi ++, pi ++ ) {
906
+
907
+ if (options.debug) {
908
+ console.error("matchOne loop")
909
+ }
910
+ var p = pattern[pi]
911
+ , f = file[fi]
912
+
913
+ if (options.debug) {
914
+ console.error(pattern, p, f)
915
+ }
916
+
917
+ // should be impossible.
918
+ // some invalid regexp stuff in the set.
919
+ if (p === false) return false
920
+
921
+ if (p === GLOBSTAR) {
922
+ if (options.debug)
923
+ console.error('GLOBSTAR', [pattern, p, f])
924
+
925
+ // "**"
926
+ // a/**/b/**/c would match the following:
927
+ // a/b/x/y/z/c
928
+ // a/x/y/z/b/c
929
+ // a/b/x/b/x/c
930
+ // a/b/c
931
+ // To do this, take the rest of the pattern after
932
+ // the **, and see if it would match the file remainder.
933
+ // If so, return success.
934
+ // If not, the ** "swallows" a segment, and try again.
935
+ // This is recursively awful.
936
+ //
937
+ // a/**/b/**/c matching a/b/x/y/z/c
938
+ // - a matches a
939
+ // - doublestar
940
+ // - matchOne(b/x/y/z/c, b/**/c)
941
+ // - b matches b
942
+ // - doublestar
943
+ // - matchOne(x/y/z/c, c) -> no
944
+ // - matchOne(y/z/c, c) -> no
945
+ // - matchOne(z/c, c) -> no
946
+ // - matchOne(c, c) yes, hit
947
+ var fr = fi
948
+ , pr = pi + 1
949
+ if (pr === pl) {
950
+ if (options.debug)
951
+ console.error('** at the end')
952
+ // a ** at the end will just swallow the rest.
953
+ // We have found a match.
954
+ // however, it will not swallow /.x, unless
955
+ // options.dot is set.
956
+ // . and .. are *never* matched by **, for explosively
957
+ // exponential reasons.
958
+ for ( ; fi < fl; fi ++) {
959
+ if (file[fi] === "." || file[fi] === ".." ||
960
+ (!options.dot && file[fi].charAt(0) === ".")) return false
961
+ }
962
+ return true
963
+ }
964
+
965
+ // ok, let's see if we can swallow whatever we can.
966
+ WHILE: while (fr < fl) {
967
+ var swallowee = file[fr]
968
+
969
+ if (options.debug) {
970
+ console.error('\nglobstar while',
971
+ file, fr, pattern, pr, swallowee)
972
+ }
973
+
974
+ // XXX remove this slice. Just pass the start index.
975
+ if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
976
+ if (options.debug)
977
+ console.error('globstar found match!', fr, fl, swallowee)
978
+ // found a match.
979
+ return true
980
+ } else {
981
+ // can't swallow "." or ".." ever.
982
+ // can only swallow ".foo" when explicitly asked.
983
+ if (swallowee === "." || swallowee === ".." ||
984
+ (!options.dot && swallowee.charAt(0) === ".")) {
985
+ if (options.debug)
986
+ console.error("dot detected!", file, fr, pattern, pr)
987
+ break WHILE
988
+ }
989
+
990
+ // ** swallows a segment, and continue.
991
+ if (options.debug)
992
+ console.error('globstar swallow a segment, and continue')
993
+ fr ++
994
+ }
995
+ }
996
+ // no match was found.
997
+ // However, in partial mode, we can't say this is necessarily over.
998
+ // If there's more *pattern* left, then
999
+ if (partial) {
1000
+ // ran out of file
1001
+ // console.error("\n>>> no match, partial?", file, fr, pattern, pr)
1002
+ if (fr === fl) return true
1003
+ }
1004
+ return false
1005
+ }
1006
+
1007
+ // something other than **
1008
+ // non-magic patterns just have to match exactly
1009
+ // patterns with magic have been turned into regexps.
1010
+ var hit
1011
+ if (typeof p === "string") {
1012
+ if (options.nocase) {
1013
+ hit = f.toLowerCase() === p.toLowerCase()
1014
+ } else {
1015
+ hit = f === p
1016
+ }
1017
+ if (options.debug) {
1018
+ console.error("string match", p, f, hit)
1019
+ }
1020
+ } else {
1021
+ hit = f.match(p)
1022
+ if (options.debug) {
1023
+ console.error("pattern match", p, f, hit)
1024
+ }
1025
+ }
1026
+
1027
+ if (!hit) return false
1028
+ }
1029
+
1030
+ // Note: ending in / means that we'll get a final ""
1031
+ // at the end of the pattern. This can only match a
1032
+ // corresponding "" at the end of the file.
1033
+ // If the file ends in /, then it can only match a
1034
+ // a pattern that ends in /, unless the pattern just
1035
+ // doesn't have any more for it. But, a/b/ should *not*
1036
+ // match "a/b/*", even though "" matches against the
1037
+ // [^/]*? pattern, except in partial mode, where it might
1038
+ // simply not be reached yet.
1039
+ // However, a/b/ should still satisfy a/*
1040
+
1041
+ // now either we fell off the end of the pattern, or we're done.
1042
+ if (fi === fl && pi === pl) {
1043
+ // ran out of pattern and filename at the same time.
1044
+ // an exact hit!
1045
+ return true
1046
+ } else if (fi === fl) {
1047
+ // ran out of file, but still had pattern left.
1048
+ // this is ok if we're doing the match as part of
1049
+ // a glob fs traversal.
1050
+ return partial
1051
+ } else if (pi === pl) {
1052
+ // ran out of pattern, still have file left.
1053
+ // this is only acceptable if we're on the very last
1054
+ // empty segment of a file with a trailing slash.
1055
+ // a/* should match a/b/
1056
+ var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
1057
+ return emptyFileEnd
1058
+ }
1059
+
1060
+ // should be unreachable.
1061
+ throw new Error("wtf?")
1062
+ }
1063
+
1064
+
1065
+ // replace stuff like \* with *
1066
+ function globUnescape (s) {
1067
+ return s.replace(/\\(.)/g, "$1")
1068
+ }
1069
+
1070
+
1071
+ function regExpEscape (s) {
1072
+ return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
1073
+ }
1074
+
1075
+ })( typeof require === "function" ? require : null,
1076
+ this,
1077
+ typeof module === "object" ? module : null,
1078
+ typeof process === "object" ? process.platform : "win32"
1079
+ )