UNPKG

42.8 kBJavaScriptView Raw
1!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.geojsonhint=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
2var jsonlint = _dereq_('jsonlint-lines');
3
4function hint(str) {
5
6 var errors = [], gj;
7
8 function root(_) {
9 if (!_.type) {
10 errors.push({
11 message: 'The type property is required and was not found',
12 line: _.__line__
13 });
14 } else if (!types[_.type]) {
15 errors.push({
16 message: 'The type ' + _.type + ' is unknown',
17 line: _.__line__
18 });
19 } else if (_) {
20 types[_.type](_);
21 }
22 }
23
24 function everyIs(_, type) {
25 // make a single exception because typeof null === 'object'
26 return _.every(function(x) { return (x !== null) && (typeof x === type); });
27 }
28
29 function requiredProperty(_, name, type) {
30 if (typeof _[name] == 'undefined') {
31 return errors.push({
32 message: '"' + name + '" property required',
33 line: _.__line__
34 });
35 } else if (type === 'array') {
36 if (!Array.isArray(_[name])) {
37 return errors.push({
38 message: '"' + name +
39 '" property should be an array, but is an ' +
40 (typeof _[name]) + ' instead',
41 line: _.__line__
42 });
43 }
44 } else if (type && typeof _[name] !== type) {
45 return errors.push({
46 message: '"' + name +
47 '" property should be ' + (type) +
48 ', but is an ' + (typeof _[name]) + ' instead',
49 line: _.__line__
50 });
51 }
52 }
53
54 // http://geojson.org/geojson-spec.html#feature-collection-objects
55 function FeatureCollection(_) {
56 crs(_);
57 bbox(_);
58 if (!requiredProperty(_, 'features', 'array')) {
59 if (!everyIs(_.features, 'object')) {
60 return errors.push({
61 message: 'Every feature must be an object',
62 line: _.__line__
63 });
64 }
65 _.features.forEach(Feature);
66 }
67 }
68
69 // http://geojson.org/geojson-spec.html#positions
70 function position(_, line) {
71 if (!Array.isArray(_)) {
72 return errors.push({
73 message: 'position should be an array, is a ' + (typeof _) +
74 ' instead',
75 line: _.__line__ || line
76 });
77 } else {
78 if (_.length < 2) {
79 return errors.push({
80 message: 'position must have 2 or more elements',
81 line: _.__line__ || line
82 });
83 }
84 if (!everyIs(_, 'number')) {
85 return errors.push({
86 message: 'each element in a position must be a number',
87 line: _.__line__ || line
88 });
89 }
90 }
91 }
92
93 function positionArray(coords, type, depth, line) {
94 if (line === undefined && coords.__line__ !== undefined) {
95 line = coords.__line__;
96 }
97 if (depth === 0) {
98 return position(coords, line);
99 } else {
100 if (depth === 1 && type) {
101 if (type === 'LinearRing') {
102 if (!Array.isArray(coords[coords.length - 1])) {
103 return errors.push({
104 message: 'a number was found where a coordinate array should have been found: this needs to be nested more deeply',
105 line: line
106 });
107 }
108 if (coords.length < 4) {
109 errors.push({
110 message: 'a LinearRing of coordinates needs to have four or more positions',
111 line: line
112 });
113 }
114 if (coords.length &&
115 (coords[coords.length - 1].length !== coords[0].length ||
116 !coords[coords.length - 1].every(function(position, index) {
117 return coords[0][index] === position;
118 }))) {
119 errors.push({
120 message: 'the first and last positions in a LinearRing of coordinates must be the same',
121 line: line
122 });
123 }
124 } else if (type === 'Line' && coords.length < 2) {
125 errors.push({
126 message: 'a line needs to have two or more coordinates to be valid',
127 line: line
128 });
129 }
130 }
131 if (!Array.isArray(coords)) {
132 return errors.push({
133 message: 'coordinates must be list of positions',
134 line: line
135 });
136 }
137 coords.forEach(function(c) {
138 positionArray(c, type, depth - 1, c.__line__ || line);
139 });
140 }
141 }
142
143 function crs(_) {
144 if (!_.crs) return;
145 if (typeof _.crs === 'object') {
146 var strErr = requiredProperty(_.crs, 'type', 'string'),
147 propErr = requiredProperty(_.crs, 'properties', 'object');
148 if (!strErr && !propErr) {
149 // http://geojson.org/geojson-spec.html#named-crs
150 if (_.crs.type == 'name') {
151 requiredProperty(_.crs.properties, 'name', 'string');
152 } else if (_.crs.type == 'link') {
153 requiredProperty(_.crs.properties, 'href', 'string');
154 }
155 }
156 } else {
157 errors.push({
158 message: 'the value of the crs property must be an object, not a ' + (typeof _.crs),
159 line: _.__line__
160 });
161 }
162 }
163
164 function bbox(_) {
165 if (!_.bbox) return;
166 if (Array.isArray(_.bbox)) {
167 if (!everyIs(_.bbox, 'number')) {
168 return errors.push({
169 message: 'each element in a bbox property must be a number',
170 line: _.bbox.__line__
171 });
172 }
173 } else {
174 errors.push({
175 message: 'bbox property must be an array of numbers, but is a ' + (typeof _.bbox),
176 line: _.__line__
177 });
178 }
179 }
180
181 // http://geojson.org/geojson-spec.html#point
182 function Point(_) {
183 crs(_);
184 bbox(_);
185 if (!requiredProperty(_, 'coordinates', 'array')) {
186 position(_.coordinates);
187 }
188 }
189
190 // http://geojson.org/geojson-spec.html#polygon
191 function Polygon(_) {
192 crs(_);
193 bbox(_);
194 if (!requiredProperty(_, 'coordinates', 'array')) {
195 positionArray(_.coordinates, 'LinearRing', 2);
196 }
197 }
198
199 // http://geojson.org/geojson-spec.html#multipolygon
200 function MultiPolygon(_) {
201 crs(_);
202 bbox(_);
203 if (!requiredProperty(_, 'coordinates', 'array')) {
204 positionArray(_.coordinates, 'LinearRing', 3);
205 }
206 }
207
208 // http://geojson.org/geojson-spec.html#linestring
209 function LineString(_) {
210 crs(_);
211 bbox(_);
212 if (!requiredProperty(_, 'coordinates', 'array')) {
213 positionArray(_.coordinates, 'Line', 1);
214 }
215 }
216
217 // http://geojson.org/geojson-spec.html#multilinestring
218 function MultiLineString(_) {
219 crs(_);
220 bbox(_);
221 if (!requiredProperty(_, 'coordinates', 'array')) {
222 positionArray(_.coordinates, 'Line', 2);
223 }
224 }
225
226 // http://geojson.org/geojson-spec.html#multipoint
227 function MultiPoint(_) {
228 crs(_);
229 bbox(_);
230 if (!requiredProperty(_, 'coordinates', 'array')) {
231 positionArray(_.coordinates, '', 1);
232 }
233 }
234
235 function GeometryCollection(_) {
236 crs(_);
237 bbox(_);
238 if (!requiredProperty(_, 'geometries', 'array')) {
239 _.geometries.forEach(function(geometry) {
240 if (geometry) root(geometry);
241 });
242 }
243 }
244
245 function Feature(_) {
246 crs(_);
247 bbox(_);
248 // https://github.com/geojson/draft-geojson/blob/master/middle.mkd#feature-object
249 if (_.id !== undefined &&
250 typeof _.id !== 'string' &&
251 typeof _.id !== 'number') {
252 errors.push({
253 message: 'Feature "id" property must have a string or number value',
254 line: _.__line__
255 });
256 }
257 if (_.type !== 'Feature') {
258 errors.push({
259 message: 'GeoJSON features must have a type=feature property',
260 line: _.__line__
261 });
262 }
263 requiredProperty(_, 'properties', 'object');
264 if (!requiredProperty(_, 'geometry', 'object')) {
265 // http://geojson.org/geojson-spec.html#feature-objects
266 // tolerate null geometry
267 if (_.geometry) root(_.geometry);
268 }
269 }
270
271 var types = {
272 Point: Point,
273 Feature: Feature,
274 MultiPoint: MultiPoint,
275 LineString: LineString,
276 MultiLineString: MultiLineString,
277 FeatureCollection: FeatureCollection,
278 GeometryCollection: GeometryCollection,
279 Polygon: Polygon,
280 MultiPolygon: MultiPolygon
281 };
282
283 if (typeof str !== 'string') {
284 return [{
285 message: 'Expected string input',
286 line: 0
287 }];
288 }
289
290 try {
291 gj = jsonlint.parse(str);
292 } catch(e) {
293 var match = e.message.match(/line (\d+)/),
294 lineNumber = 0;
295 if (match) lineNumber = parseInt(match[1], 10);
296 return [{
297 line: lineNumber - 1,
298 message: e.message,
299 error: e
300 }];
301 }
302
303 if (typeof gj !== 'object' ||
304 gj === null ||
305 gj === undefined) {
306 errors.push({
307 message: 'The root of a GeoJSON object must be an object.',
308 line: 0
309 });
310 return errors;
311 }
312
313 root(gj);
314
315 return errors;
316}
317
318module.exports.hint = hint;
319
320},{"jsonlint-lines":2}],2:[function(_dereq_,module,exports){
321(function (process){
322/* parser generated by jison 0.4.6 */
323/*
324 Returns a Parser object of the following structure:
325
326 Parser: {
327 yy: {}
328 }
329
330 Parser.prototype: {
331 yy: {},
332 trace: function(),
333 symbols_: {associative list: name ==> number},
334 terminals_: {associative list: number ==> name},
335 productions_: [...],
336 performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
337 table: [...],
338 defaultActions: {...},
339 parseError: function(str, hash),
340 parse: function(input),
341
342 lexer: {
343 EOF: 1,
344 parseError: function(str, hash),
345 setInput: function(input),
346 input: function(),
347 unput: function(str),
348 more: function(),
349 less: function(n),
350 pastInput: function(),
351 upcomingInput: function(),
352 showPosition: function(),
353 test_match: function(regex_match_array, rule_index),
354 next: function(),
355 lex: function(),
356 begin: function(condition),
357 popState: function(),
358 _currentRules: function(),
359 topState: function(),
360 pushState: function(condition),
361
362 options: {
363 ranges: boolean (optional: true ==> token location info will include a .range[] member)
364 flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
365 backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
366 },
367
368 performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
369 rules: [...],
370 conditions: {associative list: name ==> set},
371 }
372 }
373
374
375 token location info (@$, _$, etc.): {
376 first_line: n,
377 last_line: n,
378 first_column: n,
379 last_column: n,
380 range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)
381 }
382
383
384 the parseError function receives a 'hash' object with these members for lexer and parser errors: {
385 text: (matched text)
386 token: (the produced terminal token, if any)
387 line: (yylineno)
388 }
389 while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
390 loc: (yylloc)
391 expected: (string describing the set of expected tokens)
392 recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
393 }
394*/
395var jsonlint = (function(){
396var parser = {trace: function trace() { },
397yy: {},
398symbols_: {"error":2,"JSONString":3,"STRING":4,"JSONNumber":5,"NUMBER":6,"JSONNullLiteral":7,"NULL":8,"JSONBooleanLiteral":9,"TRUE":10,"FALSE":11,"JSONText":12,"JSONValue":13,"EOF":14,"JSONObject":15,"JSONArray":16,"{":17,"}":18,"JSONMemberList":19,"JSONMember":20,":":21,",":22,"[":23,"]":24,"JSONElementList":25,"$accept":0,"$end":1},
399terminals_: {2:"error",4:"STRING",6:"NUMBER",8:"NULL",10:"TRUE",11:"FALSE",14:"EOF",17:"{",18:"}",21:":",22:",",23:"[",24:"]"},
400productions_: [0,[3,1],[5,1],[7,1],[9,1],[9,1],[12,2],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[15,2],[15,3],[20,3],[19,1],[19,3],[16,2],[16,3],[25,1],[25,3]],
401performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
402/* this == yyval */
403
404var $0 = $$.length - 1;
405switch (yystate) {
406case 1: // replace escaped characters with actual character
407 this.$ = yytext.replace(/\\(\\|")/g, "$"+"1")
408 .replace(/\\n/g,'\n')
409 .replace(/\\r/g,'\r')
410 .replace(/\\t/g,'\t')
411 .replace(/\\v/g,'\v')
412 .replace(/\\f/g,'\f')
413 .replace(/\\b/g,'\b');
414
415break;
416case 2:this.$ = Number(yytext);
417break;
418case 3:this.$ = null;
419break;
420case 4:this.$ = true;
421break;
422case 5:this.$ = false;
423break;
424case 6:return this.$ = $$[$0-1];
425break;
426case 13:this.$ = {}; Object.defineProperty(this.$, '__line__', {
427 value: this._$.first_line,
428 enumerable: false
429 })
430break;
431case 14:this.$ = $$[$0-1]; Object.defineProperty(this.$, '__line__', {
432 value: this._$.first_line,
433 enumerable: false
434 })
435break;
436case 15:this.$ = [$$[$0-2], $$[$0]];
437break;
438case 16:this.$ = {}; this.$[$$[$0][0]] = $$[$0][1];
439break;
440case 17:this.$ = $$[$0-2]; $$[$0-2][$$[$0][0]] = $$[$0][1];
441break;
442case 18:this.$ = []; Object.defineProperty(this.$, '__line__', {
443 value: this._$.first_line,
444 enumerable: false
445 })
446break;
447case 19:this.$ = $$[$0-1]; Object.defineProperty(this.$, '__line__', {
448 value: this._$.first_line,
449 enumerable: false
450 })
451break;
452case 20:this.$ = [$$[$0]];
453break;
454case 21:this.$ = $$[$0-2]; $$[$0-2].push($$[$0]);
455break;
456}
457},
458table: [{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],12:1,13:2,15:7,16:8,17:[1,14],23:[1,15]},{1:[3]},{14:[1,16]},{14:[2,7],18:[2,7],22:[2,7],24:[2,7]},{14:[2,8],18:[2,8],22:[2,8],24:[2,8]},{14:[2,9],18:[2,9],22:[2,9],24:[2,9]},{14:[2,10],18:[2,10],22:[2,10],24:[2,10]},{14:[2,11],18:[2,11],22:[2,11],24:[2,11]},{14:[2,12],18:[2,12],22:[2,12],24:[2,12]},{14:[2,3],18:[2,3],22:[2,3],24:[2,3]},{14:[2,4],18:[2,4],22:[2,4],24:[2,4]},{14:[2,5],18:[2,5],22:[2,5],24:[2,5]},{14:[2,1],18:[2,1],21:[2,1],22:[2,1],24:[2,1]},{14:[2,2],18:[2,2],22:[2,2],24:[2,2]},{3:20,4:[1,12],18:[1,17],19:18,20:19},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:23,15:7,16:8,17:[1,14],23:[1,15],24:[1,21],25:22},{1:[2,6]},{14:[2,13],18:[2,13],22:[2,13],24:[2,13]},{18:[1,24],22:[1,25]},{18:[2,16],22:[2,16]},{21:[1,26]},{14:[2,18],18:[2,18],22:[2,18],24:[2,18]},{22:[1,28],24:[1,27]},{22:[2,20],24:[2,20]},{14:[2,14],18:[2,14],22:[2,14],24:[2,14]},{3:20,4:[1,12],20:29},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:30,15:7,16:8,17:[1,14],23:[1,15]},{14:[2,19],18:[2,19],22:[2,19],24:[2,19]},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:31,15:7,16:8,17:[1,14],23:[1,15]},{18:[2,17],22:[2,17]},{18:[2,15],22:[2,15]},{22:[2,21],24:[2,21]}],
459defaultActions: {16:[2,6]},
460parseError: function parseError(str, hash) {
461 if (hash.recoverable) {
462 this.trace(str);
463 } else {
464 throw new Error(str);
465 }
466},
467parse: function parse(input) {
468 var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
469 this.lexer.setInput(input);
470 this.lexer.yy = this.yy;
471 this.yy.lexer = this.lexer;
472 this.yy.parser = this;
473 if (typeof this.lexer.yylloc == 'undefined') {
474 this.lexer.yylloc = {};
475 }
476 var yyloc = this.lexer.yylloc;
477 lstack.push(yyloc);
478 var ranges = this.lexer.options && this.lexer.options.ranges;
479 if (typeof this.yy.parseError === 'function') {
480 this.parseError = this.yy.parseError;
481 } else {
482 this.parseError = Object.getPrototypeOf(this).parseError;
483 }
484 function popStack(n) {
485 stack.length = stack.length - 2 * n;
486 vstack.length = vstack.length - n;
487 lstack.length = lstack.length - n;
488 }
489 function lex() {
490 var token;
491 token = self.lexer.lex() || EOF;
492 if (typeof token !== 'number') {
493 token = self.symbols_[token] || token;
494 }
495 return token;
496 }
497 var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
498 while (true) {
499 state = stack[stack.length - 1];
500 if (this.defaultActions[state]) {
501 action = this.defaultActions[state];
502 } else {
503 if (symbol === null || typeof symbol == 'undefined') {
504 symbol = lex();
505 }
506 action = table[state] && table[state][symbol];
507 }
508 if (typeof action === 'undefined' || !action.length || !action[0]) {
509 var errStr = '';
510 expected = [];
511 for (p in table[state]) {
512 if (this.terminals_[p] && p > TERROR) {
513 expected.push('\'' + this.terminals_[p] + '\'');
514 }
515 }
516 if (this.lexer.showPosition) {
517 errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + this.lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
518 } else {
519 errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
520 }
521 this.parseError(errStr, {
522 text: this.lexer.match,
523 token: this.terminals_[symbol] || symbol,
524 line: this.lexer.yylineno,
525 loc: yyloc,
526 expected: expected
527 });
528 }
529 if (action[0] instanceof Array && action.length > 1) {
530 throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
531 }
532 switch (action[0]) {
533 case 1:
534 stack.push(symbol);
535 vstack.push(this.lexer.yytext);
536 lstack.push(this.lexer.yylloc);
537 stack.push(action[1]);
538 symbol = null;
539 if (!preErrorSymbol) {
540 yyleng = this.lexer.yyleng;
541 yytext = this.lexer.yytext;
542 yylineno = this.lexer.yylineno;
543 yyloc = this.lexer.yylloc;
544 if (recovering > 0) {
545 recovering--;
546 }
547 } else {
548 symbol = preErrorSymbol;
549 preErrorSymbol = null;
550 }
551 break;
552 case 2:
553 len = this.productions_[action[1]][1];
554 yyval.$ = vstack[vstack.length - len];
555 yyval._$ = {
556 first_line: lstack[lstack.length - (len || 1)].first_line,
557 last_line: lstack[lstack.length - 1].last_line,
558 first_column: lstack[lstack.length - (len || 1)].first_column,
559 last_column: lstack[lstack.length - 1].last_column
560 };
561 if (ranges) {
562 yyval._$.range = [
563 lstack[lstack.length - (len || 1)].range[0],
564 lstack[lstack.length - 1].range[1]
565 ];
566 }
567 r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
568 if (typeof r !== 'undefined') {
569 return r;
570 }
571 if (len) {
572 stack = stack.slice(0, -1 * len * 2);
573 vstack = vstack.slice(0, -1 * len);
574 lstack = lstack.slice(0, -1 * len);
575 }
576 stack.push(this.productions_[action[1]][0]);
577 vstack.push(yyval.$);
578 lstack.push(yyval._$);
579 newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
580 stack.push(newState);
581 break;
582 case 3:
583 return true;
584 }
585 }
586 return true;
587}};
588/* generated by jison-lex 0.2.1 */
589var lexer = (function(){
590var lexer = {
591
592EOF:1,
593
594parseError:function parseError(str, hash) {
595 if (this.yy.parser) {
596 this.yy.parser.parseError(str, hash);
597 } else {
598 throw new Error(str);
599 }
600 },
601
602// resets the lexer, sets new input
603setInput:function (input) {
604 this._input = input;
605 this._more = this._backtrack = this.done = false;
606 this.yylineno = this.yyleng = 0;
607 this.yytext = this.matched = this.match = '';
608 this.conditionStack = ['INITIAL'];
609 this.yylloc = {
610 first_line: 1,
611 first_column: 0,
612 last_line: 1,
613 last_column: 0
614 };
615 if (this.options.ranges) {
616 this.yylloc.range = [0,0];
617 }
618 this.offset = 0;
619 return this;
620 },
621
622// consumes and returns one char from the input
623input:function () {
624 var ch = this._input[0];
625 this.yytext += ch;
626 this.yyleng++;
627 this.offset++;
628 this.match += ch;
629 this.matched += ch;
630 var lines = ch.match(/(?:\r\n?|\n).*/g);
631 if (lines) {
632 this.yylineno++;
633 this.yylloc.last_line++;
634 } else {
635 this.yylloc.last_column++;
636 }
637 if (this.options.ranges) {
638 this.yylloc.range[1]++;
639 }
640
641 this._input = this._input.slice(1);
642 return ch;
643 },
644
645// unshifts one char (or a string) into the input
646unput:function (ch) {
647 var len = ch.length;
648 var lines = ch.split(/(?:\r\n?|\n)/g);
649
650 this._input = ch + this._input;
651 this.yytext = this.yytext.substr(0, this.yytext.length - len - 1);
652 //this.yyleng -= len;
653 this.offset -= len;
654 var oldLines = this.match.split(/(?:\r\n?|\n)/g);
655 this.match = this.match.substr(0, this.match.length - 1);
656 this.matched = this.matched.substr(0, this.matched.length - 1);
657
658 if (lines.length - 1) {
659 this.yylineno -= lines.length - 1;
660 }
661 var r = this.yylloc.range;
662
663 this.yylloc = {
664 first_line: this.yylloc.first_line,
665 last_line: this.yylineno + 1,
666 first_column: this.yylloc.first_column,
667 last_column: lines ?
668 (lines.length === oldLines.length ? this.yylloc.first_column : 0)
669 + oldLines[oldLines.length - lines.length].length - lines[0].length :
670 this.yylloc.first_column - len
671 };
672
673 if (this.options.ranges) {
674 this.yylloc.range = [r[0], r[0] + this.yyleng - len];
675 }
676 this.yyleng = this.yytext.length;
677 return this;
678 },
679
680// When called from action, caches matched text and appends it on next action
681more:function () {
682 this._more = true;
683 return this;
684 },
685
686// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
687reject:function () {
688 if (this.options.backtrack_lexer) {
689 this._backtrack = true;
690 } else {
691 return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
692 text: "",
693 token: null,
694 line: this.yylineno
695 });
696
697 }
698 return this;
699 },
700
701// retain first n characters of the match
702less:function (n) {
703 this.unput(this.match.slice(n));
704 },
705
706// displays already matched input, i.e. for error messages
707pastInput:function () {
708 var past = this.matched.substr(0, this.matched.length - this.match.length);
709 return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
710 },
711
712// displays upcoming input, i.e. for error messages
713upcomingInput:function () {
714 var next = this.match;
715 if (next.length < 20) {
716 next += this._input.substr(0, 20-next.length);
717 }
718 return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
719 },
720
721// displays the character position where the lexing error occurred, i.e. for error messages
722showPosition:function () {
723 var pre = this.pastInput();
724 var c = new Array(pre.length + 1).join("-");
725 return pre + this.upcomingInput() + "\n" + c + "^";
726 },
727
728// test the lexed token: return FALSE when not a match, otherwise return token
729test_match:function (match, indexed_rule) {
730 var token,
731 lines,
732 backup;
733
734 if (this.options.backtrack_lexer) {
735 // save context
736 backup = {
737 yylineno: this.yylineno,
738 yylloc: {
739 first_line: this.yylloc.first_line,
740 last_line: this.last_line,
741 first_column: this.yylloc.first_column,
742 last_column: this.yylloc.last_column
743 },
744 yytext: this.yytext,
745 match: this.match,
746 matches: this.matches,
747 matched: this.matched,
748 yyleng: this.yyleng,
749 offset: this.offset,
750 _more: this._more,
751 _input: this._input,
752 yy: this.yy,
753 conditionStack: this.conditionStack.slice(0),
754 done: this.done
755 };
756 if (this.options.ranges) {
757 backup.yylloc.range = this.yylloc.range.slice(0);
758 }
759 }
760
761 lines = match[0].match(/(?:\r\n?|\n).*/g);
762 if (lines) {
763 this.yylineno += lines.length;
764 }
765 this.yylloc = {
766 first_line: this.yylloc.last_line,
767 last_line: this.yylineno + 1,
768 first_column: this.yylloc.last_column,
769 last_column: lines ?
770 lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
771 this.yylloc.last_column + match[0].length
772 };
773 this.yytext += match[0];
774 this.match += match[0];
775 this.matches = match;
776 this.yyleng = this.yytext.length;
777 if (this.options.ranges) {
778 this.yylloc.range = [this.offset, this.offset += this.yyleng];
779 }
780 this._more = false;
781 this._backtrack = false;
782 this._input = this._input.slice(match[0].length);
783 this.matched += match[0];
784 token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
785 if (this.done && this._input) {
786 this.done = false;
787 }
788 if (token) {
789 return token;
790 } else if (this._backtrack) {
791 // recover context
792 for (var k in backup) {
793 this[k] = backup[k];
794 }
795 return false; // rule action called reject() implying the next rule should be tested instead.
796 }
797 return false;
798 },
799
800// return next match in input
801next:function () {
802 if (this.done) {
803 return this.EOF;
804 }
805 if (!this._input) {
806 this.done = true;
807 }
808
809 var token,
810 match,
811 tempMatch,
812 index;
813 if (!this._more) {
814 this.yytext = '';
815 this.match = '';
816 }
817 var rules = this._currentRules();
818 for (var i = 0; i < rules.length; i++) {
819 tempMatch = this._input.match(this.rules[rules[i]]);
820 if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
821 match = tempMatch;
822 index = i;
823 if (this.options.backtrack_lexer) {
824 token = this.test_match(tempMatch, rules[i]);
825 if (token !== false) {
826 return token;
827 } else if (this._backtrack) {
828 match = false;
829 continue; // rule action called reject() implying a rule MISmatch.
830 } else {
831 // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
832 return false;
833 }
834 } else if (!this.options.flex) {
835 break;
836 }
837 }
838 }
839 if (match) {
840 token = this.test_match(match, rules[index]);
841 if (token !== false) {
842 return token;
843 }
844 // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
845 return false;
846 }
847 if (this._input === "") {
848 return this.EOF;
849 } else {
850 return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
851 text: "",
852 token: null,
853 line: this.yylineno
854 });
855 }
856 },
857
858// return next match that has a token
859lex:function lex() {
860 var r = this.next();
861 if (r) {
862 return r;
863 } else {
864 return this.lex();
865 }
866 },
867
868// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
869begin:function begin(condition) {
870 this.conditionStack.push(condition);
871 },
872
873// pop the previously active lexer condition state off the condition stack
874popState:function popState() {
875 var n = this.conditionStack.length - 1;
876 if (n > 0) {
877 return this.conditionStack.pop();
878 } else {
879 return this.conditionStack[0];
880 }
881 },
882
883// produce the lexer rule set which is active for the currently active lexer condition state
884_currentRules:function _currentRules() {
885 if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
886 return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
887 } else {
888 return this.conditions["INITIAL"].rules;
889 }
890 },
891
892// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
893topState:function topState(n) {
894 n = this.conditionStack.length - 1 - Math.abs(n || 0);
895 if (n >= 0) {
896 return this.conditionStack[n];
897 } else {
898 return "INITIAL";
899 }
900 },
901
902// alias for begin(condition)
903pushState:function pushState(condition) {
904 this.begin(condition);
905 },
906
907// return the number of states currently on the stack
908stateStackSize:function stateStackSize() {
909 return this.conditionStack.length;
910 },
911options: {},
912performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
913
914var YYSTATE=YY_START;
915switch($avoiding_name_collisions) {
916case 0:/* skip whitespace */
917break;
918case 1:return 6
919break;
920case 2:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 4
921break;
922case 3:return 17
923break;
924case 4:return 18
925break;
926case 5:return 23
927break;
928case 6:return 24
929break;
930case 7:return 22
931break;
932case 8:return 21
933break;
934case 9:return 10
935break;
936case 10:return 11
937break;
938case 11:return 8
939break;
940case 12:return 14
941break;
942case 13:return 'INVALID'
943break;
944}
945},
946rules: [/^(?:\s+)/,/^(?:(-?([0-9]|[1-9][0-9]+))(\.[0-9]+)?([eE][-+]?[0-9]+)?\b)/,/^(?:"(?:\\[\\"bfnrt/]|\\u[a-fA-F0-9]{4}|[^\\\0-\x09\x0a-\x1f"])*")/,/^(?:\{)/,/^(?:\})/,/^(?:\[)/,/^(?:\])/,/^(?:,)/,/^(?::)/,/^(?:true\b)/,/^(?:false\b)/,/^(?:null\b)/,/^(?:$)/,/^(?:.)/],
947conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13],"inclusive":true}}
948};
949return lexer;
950})();
951parser.lexer = lexer;
952function Parser () {
953 this.yy = {};
954}
955Parser.prototype = parser;parser.Parser = Parser;
956return new Parser;
957})();
958
959
960if (typeof _dereq_ !== 'undefined' && typeof exports !== 'undefined') {
961exports.parser = jsonlint;
962exports.Parser = jsonlint.Parser;
963exports.parse = function () { return jsonlint.parse.apply(jsonlint, arguments); };
964exports.main = function commonjsMain(args) {
965 if (!args[1]) {
966 console.log('Usage: '+args[0]+' FILE');
967 process.exit(1);
968 }
969 var source = _dereq_('fs').readFileSync(_dereq_('path').normalize(args[1]), "utf8");
970 return exports.parser.parse(source);
971};
972if (typeof module !== 'undefined' && _dereq_.main === module) {
973 exports.main(process.argv.slice(1));
974}
975}
976}).call(this,_dereq_("UPikzY"))
977},{"UPikzY":5,"fs":3,"path":4}],3:[function(_dereq_,module,exports){
978
979},{}],4:[function(_dereq_,module,exports){
980(function (process){
981// Copyright Joyent, Inc. and other Node contributors.
982//
983// Permission is hereby granted, free of charge, to any person obtaining a
984// copy of this software and associated documentation files (the
985// "Software"), to deal in the Software without restriction, including
986// without limitation the rights to use, copy, modify, merge, publish,
987// distribute, sublicense, and/or sell copies of the Software, and to permit
988// persons to whom the Software is furnished to do so, subject to the
989// following conditions:
990//
991// The above copyright notice and this permission notice shall be included
992// in all copies or substantial portions of the Software.
993//
994// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
995// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
996// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
997// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
998// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
999// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
1000// USE OR OTHER DEALINGS IN THE SOFTWARE.
1001
1002// resolves . and .. elements in a path array with directory names there
1003// must be no slashes, empty elements, or device names (c:\) in the array
1004// (so also no leading and trailing slashes - it does not distinguish
1005// relative and absolute paths)
1006function normalizeArray(parts, allowAboveRoot) {
1007 // if the path tries to go above the root, `up` ends up > 0
1008 var up = 0;
1009 for (var i = parts.length - 1; i >= 0; i--) {
1010 var last = parts[i];
1011 if (last === '.') {
1012 parts.splice(i, 1);
1013 } else if (last === '..') {
1014 parts.splice(i, 1);
1015 up++;
1016 } else if (up) {
1017 parts.splice(i, 1);
1018 up--;
1019 }
1020 }
1021
1022 // if the path is allowed to go above the root, restore leading ..s
1023 if (allowAboveRoot) {
1024 for (; up--; up) {
1025 parts.unshift('..');
1026 }
1027 }
1028
1029 return parts;
1030}
1031
1032// Split a filename into [root, dir, basename, ext], unix version
1033// 'root' is just a slash, or nothing.
1034var splitPathRe =
1035 /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
1036var splitPath = function(filename) {
1037 return splitPathRe.exec(filename).slice(1);
1038};
1039
1040// path.resolve([from ...], to)
1041// posix version
1042exports.resolve = function() {
1043 var resolvedPath = '',
1044 resolvedAbsolute = false;
1045
1046 for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
1047 var path = (i >= 0) ? arguments[i] : process.cwd();
1048
1049 // Skip empty and invalid entries
1050 if (typeof path !== 'string') {
1051 throw new TypeError('Arguments to path.resolve must be strings');
1052 } else if (!path) {
1053 continue;
1054 }
1055
1056 resolvedPath = path + '/' + resolvedPath;
1057 resolvedAbsolute = path.charAt(0) === '/';
1058 }
1059
1060 // At this point the path should be resolved to a full absolute path, but
1061 // handle relative paths to be safe (might happen when process.cwd() fails)
1062
1063 // Normalize the path
1064 resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
1065 return !!p;
1066 }), !resolvedAbsolute).join('/');
1067
1068 return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
1069};
1070
1071// path.normalize(path)
1072// posix version
1073exports.normalize = function(path) {
1074 var isAbsolute = exports.isAbsolute(path),
1075 trailingSlash = substr(path, -1) === '/';
1076
1077 // Normalize the path
1078 path = normalizeArray(filter(path.split('/'), function(p) {
1079 return !!p;
1080 }), !isAbsolute).join('/');
1081
1082 if (!path && !isAbsolute) {
1083 path = '.';
1084 }
1085 if (path && trailingSlash) {
1086 path += '/';
1087 }
1088
1089 return (isAbsolute ? '/' : '') + path;
1090};
1091
1092// posix version
1093exports.isAbsolute = function(path) {
1094 return path.charAt(0) === '/';
1095};
1096
1097// posix version
1098exports.join = function() {
1099 var paths = Array.prototype.slice.call(arguments, 0);
1100 return exports.normalize(filter(paths, function(p, index) {
1101 if (typeof p !== 'string') {
1102 throw new TypeError('Arguments to path.join must be strings');
1103 }
1104 return p;
1105 }).join('/'));
1106};
1107
1108
1109// path.relative(from, to)
1110// posix version
1111exports.relative = function(from, to) {
1112 from = exports.resolve(from).substr(1);
1113 to = exports.resolve(to).substr(1);
1114
1115 function trim(arr) {
1116 var start = 0;
1117 for (; start < arr.length; start++) {
1118 if (arr[start] !== '') break;
1119 }
1120
1121 var end = arr.length - 1;
1122 for (; end >= 0; end--) {
1123 if (arr[end] !== '') break;
1124 }
1125
1126 if (start > end) return [];
1127 return arr.slice(start, end - start + 1);
1128 }
1129
1130 var fromParts = trim(from.split('/'));
1131 var toParts = trim(to.split('/'));
1132
1133 var length = Math.min(fromParts.length, toParts.length);
1134 var samePartsLength = length;
1135 for (var i = 0; i < length; i++) {
1136 if (fromParts[i] !== toParts[i]) {
1137 samePartsLength = i;
1138 break;
1139 }
1140 }
1141
1142 var outputParts = [];
1143 for (var i = samePartsLength; i < fromParts.length; i++) {
1144 outputParts.push('..');
1145 }
1146
1147 outputParts = outputParts.concat(toParts.slice(samePartsLength));
1148
1149 return outputParts.join('/');
1150};
1151
1152exports.sep = '/';
1153exports.delimiter = ':';
1154
1155exports.dirname = function(path) {
1156 var result = splitPath(path),
1157 root = result[0],
1158 dir = result[1];
1159
1160 if (!root && !dir) {
1161 // No dirname whatsoever
1162 return '.';
1163 }
1164
1165 if (dir) {
1166 // It has a dirname, strip trailing slash
1167 dir = dir.substr(0, dir.length - 1);
1168 }
1169
1170 return root + dir;
1171};
1172
1173
1174exports.basename = function(path, ext) {
1175 var f = splitPath(path)[2];
1176 // TODO: make this comparison case-insensitive on windows?
1177 if (ext && f.substr(-1 * ext.length) === ext) {
1178 f = f.substr(0, f.length - ext.length);
1179 }
1180 return f;
1181};
1182
1183
1184exports.extname = function(path) {
1185 return splitPath(path)[3];
1186};
1187
1188function filter (xs, f) {
1189 if (xs.filter) return xs.filter(f);
1190 var res = [];
1191 for (var i = 0; i < xs.length; i++) {
1192 if (f(xs[i], i, xs)) res.push(xs[i]);
1193 }
1194 return res;
1195}
1196
1197// String.prototype.substr - negative index don't work in IE8
1198var substr = 'ab'.substr(-1) === 'b'
1199 ? function (str, start, len) { return str.substr(start, len) }
1200 : function (str, start, len) {
1201 if (start < 0) start = str.length + start;
1202 return str.substr(start, len);
1203 }
1204;
1205
1206}).call(this,_dereq_("UPikzY"))
1207},{"UPikzY":5}],5:[function(_dereq_,module,exports){
1208// shim for using process in browser
1209
1210var process = module.exports = {};
1211
1212process.nextTick = (function () {
1213 var canSetImmediate = typeof window !== 'undefined'
1214 && window.setImmediate;
1215 var canPost = typeof window !== 'undefined'
1216 && window.postMessage && window.addEventListener
1217 ;
1218
1219 if (canSetImmediate) {
1220 return function (f) { return window.setImmediate(f) };
1221 }
1222
1223 if (canPost) {
1224 var queue = [];
1225 window.addEventListener('message', function (ev) {
1226 var source = ev.source;
1227 if ((source === window || source === null) && ev.data === 'process-tick') {
1228 ev.stopPropagation();
1229 if (queue.length > 0) {
1230 var fn = queue.shift();
1231 fn();
1232 }
1233 }
1234 }, true);
1235
1236 return function nextTick(fn) {
1237 queue.push(fn);
1238 window.postMessage('process-tick', '*');
1239 };
1240 }
1241
1242 return function nextTick(fn) {
1243 setTimeout(fn, 0);
1244 };
1245})();
1246
1247process.title = 'browser';
1248process.browser = true;
1249process.env = {};
1250process.argv = [];
1251
1252function noop() {}
1253
1254process.on = noop;
1255process.addListener = noop;
1256process.once = noop;
1257process.off = noop;
1258process.removeListener = noop;
1259process.removeAllListeners = noop;
1260process.emit = noop;
1261
1262process.binding = function (name) {
1263 throw new Error('process.binding is not supported');
1264}
1265
1266// TODO(shtylman)
1267process.cwd = function () { return '/' };
1268process.chdir = function (dir) {
1269 throw new Error('process.chdir is not supported');
1270};
1271
1272},{}]},{},[1])
1273(1)
1274});
\No newline at end of file