| // Generated by LiveScript 1.6.0 | 
| (function(){ | 
|   var identifierRegex, tokenRegex; | 
|   identifierRegex = /[\$\w]+/; | 
|   function peek(tokens){ | 
|     var token; | 
|     token = tokens[0]; | 
|     if (token == null) { | 
|       throw new Error('Unexpected end of input.'); | 
|     } | 
|     return token; | 
|   } | 
|   function consumeIdent(tokens){ | 
|     var token; | 
|     token = peek(tokens); | 
|     if (!identifierRegex.test(token)) { | 
|       throw new Error("Expected text, got '" + token + "' instead."); | 
|     } | 
|     return tokens.shift(); | 
|   } | 
|   function consumeOp(tokens, op){ | 
|     var token; | 
|     token = peek(tokens); | 
|     if (token !== op) { | 
|       throw new Error("Expected '" + op + "', got '" + token + "' instead."); | 
|     } | 
|     return tokens.shift(); | 
|   } | 
|   function maybeConsumeOp(tokens, op){ | 
|     var token; | 
|     token = tokens[0]; | 
|     if (token === op) { | 
|       return tokens.shift(); | 
|     } else { | 
|       return null; | 
|     } | 
|   } | 
|   function consumeArray(tokens){ | 
|     var types; | 
|     consumeOp(tokens, '['); | 
|     if (peek(tokens) === ']') { | 
|       throw new Error("Must specify type of Array - eg. [Type], got [] instead."); | 
|     } | 
|     types = consumeTypes(tokens); | 
|     consumeOp(tokens, ']'); | 
|     return { | 
|       structure: 'array', | 
|       of: types | 
|     }; | 
|   } | 
|   function consumeTuple(tokens){ | 
|     var components; | 
|     components = []; | 
|     consumeOp(tokens, '('); | 
|     if (peek(tokens) === ')') { | 
|       throw new Error("Tuple must be of at least length 1 - eg. (Type), got () instead."); | 
|     } | 
|     for (;;) { | 
|       components.push(consumeTypes(tokens)); | 
|       maybeConsumeOp(tokens, ','); | 
|       if (')' === peek(tokens)) { | 
|         break; | 
|       } | 
|     } | 
|     consumeOp(tokens, ')'); | 
|     return { | 
|       structure: 'tuple', | 
|       of: components | 
|     }; | 
|   } | 
|   function consumeFields(tokens){ | 
|     var fields, subset, ref$, key, types; | 
|     fields = {}; | 
|     consumeOp(tokens, '{'); | 
|     subset = false; | 
|     for (;;) { | 
|       if (maybeConsumeOp(tokens, '...')) { | 
|         subset = true; | 
|         break; | 
|       } | 
|       ref$ = consumeField(tokens), key = ref$[0], types = ref$[1]; | 
|       fields[key] = types; | 
|       maybeConsumeOp(tokens, ','); | 
|       if ('}' === peek(tokens)) { | 
|         break; | 
|       } | 
|     } | 
|     consumeOp(tokens, '}'); | 
|     return { | 
|       structure: 'fields', | 
|       of: fields, | 
|       subset: subset | 
|     }; | 
|   } | 
|   function consumeField(tokens){ | 
|     var key, types; | 
|     key = consumeIdent(tokens); | 
|     consumeOp(tokens, ':'); | 
|     types = consumeTypes(tokens); | 
|     return [key, types]; | 
|   } | 
|   function maybeConsumeStructure(tokens){ | 
|     switch (tokens[0]) { | 
|     case '[': | 
|       return consumeArray(tokens); | 
|     case '(': | 
|       return consumeTuple(tokens); | 
|     case '{': | 
|       return consumeFields(tokens); | 
|     } | 
|   } | 
|   function consumeType(tokens){ | 
|     var token, wildcard, type, structure; | 
|     token = peek(tokens); | 
|     wildcard = token === '*'; | 
|     if (wildcard || identifierRegex.test(token)) { | 
|       type = wildcard | 
|         ? consumeOp(tokens, '*') | 
|         : consumeIdent(tokens); | 
|       structure = maybeConsumeStructure(tokens); | 
|       if (structure) { | 
|         return structure.type = type, structure; | 
|       } else { | 
|         return { | 
|           type: type | 
|         }; | 
|       } | 
|     } else { | 
|       structure = maybeConsumeStructure(tokens); | 
|       if (!structure) { | 
|         throw new Error("Unexpected character: " + token); | 
|       } | 
|       return structure; | 
|     } | 
|   } | 
|   function consumeTypes(tokens){ | 
|     var lookahead, types, typesSoFar, typeObj, type, structure; | 
|     if ('::' === peek(tokens)) { | 
|       throw new Error("No comment before comment separator '::' found."); | 
|     } | 
|     lookahead = tokens[1]; | 
|     if (lookahead != null && lookahead === '::') { | 
|       tokens.shift(); | 
|       tokens.shift(); | 
|     } | 
|     types = []; | 
|     typesSoFar = {}; | 
|     if ('Maybe' === peek(tokens)) { | 
|       tokens.shift(); | 
|       types = [ | 
|         { | 
|           type: 'Undefined' | 
|         }, { | 
|           type: 'Null' | 
|         } | 
|       ]; | 
|       typesSoFar = { | 
|         Undefined: true, | 
|         Null: true | 
|       }; | 
|     } | 
|     for (;;) { | 
|       typeObj = consumeType(tokens), type = typeObj.type, structure = typeObj.structure; | 
|       if (!typesSoFar[type]) { | 
|         types.push(typeObj); | 
|       } | 
|       if (structure == null) { | 
|         typesSoFar[type] = true; | 
|       } | 
|       if (!maybeConsumeOp(tokens, '|')) { | 
|         break; | 
|       } | 
|     } | 
|     return types; | 
|   } | 
|   tokenRegex = RegExp('\\.\\.\\.|::|->|' + identifierRegex.source + '|\\S', 'g'); | 
|   module.exports = function(input){ | 
|     var tokens, e; | 
|     if (!input.length) { | 
|       throw new Error('No type specified.'); | 
|     } | 
|     tokens = input.match(tokenRegex) || []; | 
|     if (in$('->', tokens)) { | 
|       throw new Error("Function types are not supported.\ To validate that something is a function, you may use 'Function'."); | 
|     } | 
|     try { | 
|       return consumeTypes(tokens); | 
|     } catch (e$) { | 
|       e = e$; | 
|       throw new Error(e.message + " - Remaining tokens: " + JSON.stringify(tokens) + " - Initial input: '" + input + "'"); | 
|     } | 
|   }; | 
|   function in$(x, xs){ | 
|     var i = -1, l = xs.length >>> 0; | 
|     while (++i < l) if (x === xs[i]) return true; | 
|     return false; | 
|   } | 
| }).call(this); |