{
  "!name": "underscore",
  "_": {
    "!doc": "Save the previous value of the `_` variable.",
    "!type": "fn(obj: ?) -> +_",
    "VERSION": {
      "!type": "string",
      "!url": "http://underscorejs.org/#VERSION"
    },
    "after": {
      "!doc": "Returns a function that will only be executed after being called N times.",
      "!url": "http://underscorejs.org/#after",
      "!type": "fn(times: number, func: fn()) -> !1"
    },
    "all": "_.every",
    "any": "_.some",
    "bind": {
      "!doc": "Create a function bound to a given object (assigning `this`, and arguments, optionally).",
      "!type": "fn(func: ?, context?: ?, args?: ?) -> !0",
      "!url": "http://underscorejs.org/#bind"
    },
    "bindAll": {
      "!doc": "Bind all of an object's methods to that object.",
      "!type": "fn(obj: ?, names?: [string])",
      "!url": "http://underscorejs.org/#bindAll"
    },
    "chain": {
      "!doc": "Add a \"chain\" function, which will delegate to the wrapper.",
      "!type": "fn(obj: ?)",
      "!url": "http://underscorejs.org/#chain"
    },
    "clone": {
      "!doc": "Create a (shallow-cloned) duplicate of an object.",
      "!type": "fn(obj: ?) -> !0",
      "!url": "http://underscorejs.org/#clone"
    },
    "collect": "_.map",
    "compact": {
      "!doc": "Trim out all falsy values from an array.",
      "!type": "fn(array: [?]) -> [?]",
      "!url": "http://underscorejs.org/#compact"
    },
    "compose": {
      "!doc": "Returns a function that is the composition of a list of functions, each consuming the return value of the function that follows.",
      "!type": "fn(a: fn(), b: fn()) -> fn() -> !1.!ret",
      "!url": "http://underscorejs.org/#compose"
    },
    "contains": {
      "!doc": "Determine if the array or object contains a given value (using `===`).",
      "!type": "fn(list: [?], target: ?) -> bool",
      "!url": "http://underscorejs.org/#contains"
    },
    "countBy": {
      "!doc": "Counts instances of an object that group by a certain criterion.",
      "!type": "fn(obj: ?, iterator: fn(elt: ?, i: number) -> ?, context?: ?) -> ?",
      "!url": "http://underscorejs.org/#countBy"
    },
    "debounce": {
      "!doc": "Returns a function, that, as long as it continues to be invoked, will not be triggered.",
      "!type": "fn(func: fn(), wait: number, immediate?: bool) -> !0",
      "!url": "http://underscorejs.org/#debounce"
    },
    "defaults": {
      "!doc": "Fill in a given object with default properties.",
      "!type": "fn(obj: ?, defaults: ?) -> !0",
      "!effects": ["copy !1 !0"],
      "!url": "http://underscorejs.org/#defaults"
    },
    "defer": {
      "!doc": "Defers a function, scheduling it to run after the current call stack has cleared.",
      "!type": "fn(func: fn(), args?: ?) -> number",
      "!url": "http://underscorejs.org/#defer"
    },
    "delay": {
      "!doc": "Delays a function for the given number of milliseconds, and then calls it with the arguments supplied.",
      "!type": "fn(func: fn(), wait: number, args?: ?) -> number",
      "!url": "http://underscorejs.org/#delay"
    },
    "detect": "_.find",
    "difference": {
      "!doc": "Take the difference between one array and a number of other arrays.",
      "!type": "fn(array: [?], others?: [?]) -> !0",
      "!url": "http://underscorejs.org/#difference"
    },
    "drop": "_.rest",
    "each": {
      "!doc": "Iterates over a list of elements, yielding each in turn to an iterator function.",
      "!type": "fn(obj: [?], iterator: fn(value: ?, index: number), context?: ?)",
      "!effects": ["call !1 this=!2 !0.<i> number"],
      "!url": "http://underscorejs.org/#each"
    },
    "escape": {
      "!doc": "Escapes a string for insertion into HTML.",
      "!type": "fn(string) -> string",
      "!url": "http://underscorejs.org/#escape"
    },
    "every": {
      "!doc": "Determine whether all of the elements match a truth test.",
      "!type": "fn(list: [?], iterator: fn(elt: ?, i: number) -> bool, context?: ?) -> bool",
      "!effects": ["call !1 this=!2 !0.<i> number"],
      "!url": "http://underscorejs.org/#every"
    },
    "extend": {
      "!doc": "Extend a given object with all the properties in passed-in object(s).",
      "!type": "fn(destination: ?, source1: ?, source2?: ?) -> !0",
      "!effects": ["copy !1 !0", "copy !2 !0"],
      "!url": "http://underscorejs.org/#extend"
    },
    "filter": {
      "!doc": "Looks through each value in the list, returning an array of all the values that pass a truth test.",
      "!type": "fn(list: [?], test: fn(value: ?, index: number) -> bool, context?: ?) -> !0",
      "!effects": ["call !1 this=!2 !0.<i> number"],
      "!url": "http://underscorejs.org/#filter"
    },
    "find": {
      "!doc": "Return the first value which passes a truth test.",
      "!type": "fn(list: [?], test: fn(?) -> bool, context?: ?) -> !0.<i>",
      "!effects": ["call !1 !0.<i>"],
      "!url": "http://underscorejs.org/#find"
    },
    "findWhere": {
      "!doc": "Looks through the list and returns the first value that matches all of the key-value pairs listed in properties.",
      "!type": "fn(list: [?], attrs: ?) -> !0.<i>",
      "!url": "http://underscorejs.org/#findWhere"
    },
    "first": {
      "!doc": "Get the first element of an array. Passing n will return the first N values in the array.",
      "!type": "fn(list: [?], n?: number) -> !0.<i>",
      "!url": "http://underscorejs.org/#first"
    },
    "flatten": {
      "!doc": "Return a completely flattened version of an array.",
      "!type": "fn(array: [?], shallow?: bool) -> [?]",
      "!url": "http://underscorejs.org/#flatten"
    },
    "foldl": "_.reduce",
    "foldr": "_.reduceRight",
    "forEach": "_.each",
    "functions": {
      "!doc": "Return a sorted list of the function names available on the object.",
      "!type": "fn(obj: _) -> [string]",
      "!url": "http://underscorejs.org/#functions"
    },
    "groupBy": {
      "!doc": "Groups the object's values by a criterion.",
      "!type": "fn(obj: [?], iterator: fn(elt: ?, i: number) -> ?, context?: ?) -> ?",
      "!url": "http://underscorejs.org/#groupBy"
    },
    "has": {
      "!doc": "Shortcut function for checking if an object has a given property directly on itself (in other words, not on a prototype).",
      "!type": "fn(obj: ?, key: string) -> bool",
      "!url": "http://underscorejs.org/#has"
    },
    "head": "_.first",
    "identity": {
      "!doc": "Returns the same value that is used as the argument.",
      "!type": "fn(value: ?) -> !0",
      "!url": "http://underscorejs.org/#identity"
    },
    "include": "_.contains",
    "indexOf": {
      "!doc": "Returns the index at which value can be found in the array, or -1 if value is not present in the array.",
      "!type": "fn(list: [?], item: ?, isSorted?: bool) -> number",
      "!url": "http://underscorejs.org/#indexOf"
    },
    "initial": {
      "!doc": "Returns everything but the last entry of the array.",
      "!type": "fn(array: [?], n?: number) -> !0",
      "!url": "http://underscorejs.org/#initial"
    },
    "inject": "_.reduce",
    "intersection": {
      "!doc": "Produce an array that contains every item shared between all the passed-in arrays.",
      "!type": "fn(array: [?], others?: [?]) -> !0",
      "!url": "http://underscorejs.org/#intersection"
    },
    "invert": {
      "!doc": "Invert the keys and values of an object.",
      "!type": "fn(obj: ?) -> ?",
      "!url": "http://underscorejs.org/#invert"
    },
    "invoke": {
      "!doc": "Invoke a method (with arguments) on every item in a collection.",
      "!type": "fn(obj: ?, method: string, args?: ?) -> [?]",
      "!url": "http://underscorejs.org/#invoke"
    },
    "isArguments": {
      "!doc": "Returns true if object is an Arguments object.",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isArguments"
    },
    "isArray": {
      "!doc": "Is a given value an array? Delegates to ECMA5's native Array.isArray",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isArray"
    },
    "isBoolean": {
      "!doc": "Is a given value a boolean?",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isBoolean"
    },
    "isDate": {
      "!doc": "Returns true if object is a Date object.",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isDate"
    },
    "isElement": {
      "!doc": "Is a given value a DOM element?",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isElement"
    },
    "isEmpty": {
      "!doc": "Is a given array, string, or object empty? An \"empty\" object has no enumerable own-properties.",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isEmpty"
    },
    "isEqual": {
      "!doc": "Perform a deep comparison to check if two objects are equal.",
      "!type": "fn(a: ?, b: ?) -> bool",
      "!url": "http://underscorejs.org/#isEqual"
    },
    "isFinite": {
      "!doc": "Is a given object a finite number?",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isFinite"
    },
    "isFunction": {
      "!doc": "Returns true if object is a Function.",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isFunction"
    },
    "isNaN": {
      "!doc": "Is the given value `NaN`? (NaN is the only number which does not equal itself).",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isNaN"
    },
    "isNull": {
      "!doc": "Is a given value equal to null?",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isNull"
    },
    "isNumber": {
      "!doc": "Returns true if object is a Number (including NaN).",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isNumber"
    },
    "isObject": {
      "!doc": "Is a given variable an object?",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isObject"
    },
    "isRegExp": {
      "!doc": "Returns true if object is a regular expression.",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isRegExp"
    },
    "isString": {
      "!doc": "Returns true if object is a String.",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isString"
    },
    "isUndefined": {
      "!doc": "Is a given variable undefined?",
      "!type": "fn(obj: ?) -> bool",
      "!url": "http://underscorejs.org/#isUndefined"
    },
    "keys": {
      "!doc": "Retrieve the names of an object's properties. Delegates to ECMAScript 5's native `Object.keys`",
      "!type": "fn(obj: ?) -> [string]",
      "!url": "http://underscorejs.org/#keys"
    },
    "last": {
      "!doc": "Get the last element of an array.",
      "!type": "fn(array: [?], n?: number) -> !0.<i>",
      "!url": "http://underscorejs.org/#last"
    },
    "lastIndexOf": {
      "!doc": "Returns the index of the last occurrence of value in the array, or -1 if value is not present.",
      "!type": "fn(array: [?], item: ?, from?: number) -> number",
      "!url": "http://underscorejs.org/#lastIndexOf"
    },
    "map": {
      "!doc": "Produces a new array of values by mapping each value in list through a transformation function (iterator).",
      "!type": "fn(obj: [?], iterator: fn(elt: ?, i: number) -> ?, context?: ?) -> [!1.!ret]",
      "!effects": ["call !1 !this=!2 !0.<i> number"],
      "!url": "http://underscorejs.org/#map"
    },
    "max": {
      "!doc": "Returns the maximum value in list.",
      "!type": "fn(list: [?], iterator?: fn(elt: ?, i: number) -> number, context?: ?) -> number",
      "!url": "http://underscorejs.org/#max"
    },
    "memoize": {
      "!doc": "Memoize an expensive function by storing its results.",
      "!type": "fn(func: fn(), hasher?: fn(args: ?) -> ?) -> !0",
      "!url": "http://underscorejs.org/#memoize"
    },
    "methods": "_.functions",
    "min": {
      "!doc": "Returns the minimum value in list.",
      "!type": "fn(list: [?], iterator?: fn(elt: ?, i: number) -> number, context?: ?) -> number",
      "!url": "http://underscorejs.org/#min"
    },
    "mixin": {
      "!doc": "Add your own custom functions to the Underscore object.",
      "!type": "fn(obj: _)",
      "!url": "http://underscorejs.org/#mixin"
    },
    "noConflict": {
      "!doc": "Run Underscore.js in *noConflict* mode, returning the `_` variable to its previous owner. Returns a reference to the Underscore object.",
      "!type": "fn() -> _",
      "!url": "http://underscorejs.org/#noConflict"
    },
    "object": {
      "!doc": "Converts lists into objects.",
      "!type": "fn(list: [?], values?: [?]) -> ?",
      "!url": "http://underscorejs.org/#object"
    },
    "omit": {
      "!doc": "Return a copy of the object without the blacklisted properties.",
      "!type": "fn(obj: ?, keys?: string) -> !0",
      "!url": "http://underscorejs.org/#omit"
    },
    "once": {
      "!doc": "Returns a function that will be executed at most one time, no matter how often you call it.",
      "!type": "fn(func: fn() -> ?) -> !0",
      "!url": "http://underscorejs.org/#once"
    },
    "pairs": {
      "!doc": "Convert an object into a list of `[key, value]` pairs.",
      "!type": "fn(obj: ?) -> [[?]]",
      "!url": "http://underscorejs.org/#pairs"
    },
    "partial": {
      "!doc": "Partially apply a function by creating a version that has had some of its arguments pre-filled, without changing its dynamic `this` context.",
      "!type": "fn(func: ?, args?: ?) -> fn()",
      "!url": "http://underscorejs.org/#partial"
    },
    "pick": {
      "!doc": "Return a copy of the object only containing the whitelisted properties.",
      "!type": "fn(obj: ?, keys?: string) -> !0",
      "!url": "http://underscorejs.org/#pick"
    },
    "pluck": {
      "!doc": "Convenience version of a common use case of `map`: fetching a property.",
      "!type": "fn(obj: [?], key: string) -> [?]",
      "!url": "http://underscorejs.org/#pluck"
    },
    "prototype": {
      "chain": {
        "!doc": "Start chaining a wrapped Underscore object.",
        "!type": "fn() -> !this"
      },
      "value": {
        "!doc": "Extracts the result from a wrapped and chained object.",
        "!type": "fn() -> ?"
      },
      "pop": "fn() -> ?",
      "push": "fn(newelt: ?) -> number",
      "reverse": "fn()",
      "shift": "fn() -> ?",
      "sort": "fn() -> !this",
      "splice": "fn(pos: number, amount: number)",
      "unshift": "fn(elt: ?) -> number",
      "concat": "fn(other: ?) -> !this",
      "join": "fn(separator?: string) -> string",
      "slice": "fn(from: number, to?: number) -> !this"
    },
    "random": {
      "!doc": "Return a random integer between min and max (inclusive).",
      "!type": "fn(min: number, max: number) -> number",
      "!url": "http://underscorejs.org/#random"
    },
    "range": {
      "!doc": "A function to create flexibly-numbered lists of integers.",
      "!type": "fn(start?: number, stop: number, step?: number) -> [number]",
      "!url": "http://underscorejs.org/#range"
    },
    "reduce": {
      "!doc": "reduce boils down a list of values into a single value.",
      "!type": "fn(list: [?], iterator: fn(sum: ?, elt: ?, i: number) -> ?, init?: ?, context?: ?) -> !1.!ret",
      "!effects": ["call !1 this=!3 !2 !0.<i> number"],
      "!url": "http://underscorejs.org/#reduce"
    },
    "reduceRight": {
      "!doc": "The right-associative version of reduce, also known as `foldr`.",
      "!type": "fn(list: [?], iterator: fn(sum: ?, elt: ?, i: number) -> ?, init?: ?, context?: ?) -> !1.!ret",
      "!effects": ["call !1 this=!3 !2 !0.<i> number"],
      "!url": "http://underscorejs.org/#reduceRight"
    },
    "reject": {
      "!doc": "Returns the values in list without the elements that the truth test (iterator) passes. The opposite of filter.",
      "!type": "fn(list: [?], iterator: fn(elt: ?, i: number) -> bool, context?: ?) -> !0",
      "!effects": ["call !1 this=!3 !0.<i> number"],
      "!url": "http://underscorejs.org/#reject"
    },
    "rest": {
      "!doc": "Returns the rest of the elements in an array.",
      "!type": "fn(array: [?], n?: number) -> !0",
      "!url": "http://underscorejs.org/#rest"
    },
    "result": {
      "!doc": "If the value of the named `property` is a function then invoke it with the `object` as context; otherwise, return it.",
      "!type": "fn(object: ?, property: string) -> !0.<i>",
      "!url": "http://underscorejs.org/#result"
    },
    "select": "_.filter",
    "shuffle": {
      "!doc": "Shuffle an array.",
      "!type": "fn(list: [?]) -> !0",
      "!url": "http://underscorejs.org/#shuffle"
    },
    "size": {
      "!doc": "Return the number of elements in an object.",
      "!type": "fn(obj: ?) -> number",
      "!url": "http://underscorejs.org/#size"
    },
    "some": {
      "!doc": "Returns true if any of the values in the list pass the iterator truth test.",
      "!type": "fn(list: [?], iterator: fn(elt: ?, i: number) -> bool, context?: ?) -> bool",
      "!effects": ["call !1 this=!2 !0.<i> number"],
      "!url": "http://underscorejs.org/#some"
    },
    "sortBy": {
      "!doc": "Sort the object's values by a criterion produced by an iterator.",
      "!type": "fn(list: [?], iterator: fn(elt: ?, i: number) -> number, context?: ?) -> !0",
      "!url": "http://underscorejs.org/#sortBy"
    },
    "sortedIndex": {
      "!doc": "Use a comparator function to figure out the smallest index at which an object should be inserted so as to maintain order.",
      "!type": "fn(array: [?], obj: ?, iterator: fn(elt: ?, i: number), context?: ?) -> number",
      "!url": "http://underscorejs.org/#sortedIndex"
    },
    "tail": "_.rest",
    "take": "_.first",
    "tap": {
      "!doc": "Invokes interceptor with the obj, and then returns obj.",
      "!type": "fn(obj: ?, interceptor: fn()) -> !0",
      "!effects": ["call !1 !0"],
      "!url": "http://underscorejs.org/#tap"
    },
    "template": {
      "!doc": "Compiles JavaScript templates into functions that can be evaluated for rendering. ",
      "!type": "fn(text: string, data?: ?, settings?: _.templateSettings) -> fn(data: ?) -> string",
      "!url": "http://underscorejs.org/#template"
    },
    "templateSettings": {
      "!doc": "By default, Underscore uses ERB-style template delimiters, change the following template settings to use alternative delimiters.",
      "escape": "+RegExp",
      "evaluate": "+RegExp",
      "interpolate": "+RegExp",
      "!url": "http://underscorejs.org/#templateSettings"
    },
    "throttle": {
      "!doc": "Returns a function, that, when invoked, will only be triggered at most once during a given window of time.",
      "!type": "fn(func: fn(), wait: number, options?: ?) -> !0",
      "!url": "http://underscorejs.org/#throttle"
    },
    "times": {
      "!doc": "Run a function n times.",
      "!type": "fn(n: number, iterator: fn(), context?: ?) -> [!1.!ret]",
      "!url": "http://underscorejs.org/#times"
    },
    "toArray": {
      "!doc": "Safely create a real, live array from anything iterable.",
      "!type": "fn(obj: ?) -> [?]",
      "!url": "http://underscorejs.org/#toArray"
    },
    "unescape": {
      "!doc": "The opposite of escape.",
      "!type": "fn(string) -> string",
      "!url": "http://underscorejs.org/#unescape"
    },
    "union": {
      "!doc": "Produce an array that contains the union: each distinct element from all of the passed-in arrays.",
      "!type": "fn(array: [?], array2: [?]) -> ?0",
      "!url": "http://underscorejs.org/#union"
    },
    "uniq": {
      "!doc": "Produce a duplicate-free version of the array.",
      "!type": "fn(array: [?], isSorted?: bool, iterator?: fn(elt: ?, i: number), context?: ?) -> [?]",
      "!url": "http://underscorejs.org/#uniq"
    },
    "unique": "_.uniq",
    "uniqueId": {
      "!doc": "Generate a unique integer id (unique within the entire client session). Useful for temporary DOM ids.",
      "!type": "fn(prefix: string) -> string",
      "!url": "http://underscorejs.org/#uniqueId"
    },
    "values": {
      "!doc": "Retrieve the values of an object's properties.",
      "!type": "fn(obj: ?) -> [!0.<i>]",
      "!url": "http://underscorejs.org/#values"
    },
    "where": {
      "!doc": "Looks through each value in the list, returning an array of all the values that contain all of the key-value pairs listed in properties.",
      "!type": "fn(list: [?], attrs: ?) -> !0",
      "!url": "http://underscorejs.org/#where"
    },
    "without": {
      "!doc": "Return a version of the array that does not contain the specified value(s).",
      "!type": "fn(array: [?], values: [?]) -> !0",
      "!url": "http://underscorejs.org/#without"
    },
    "wrap": {
      "!doc": "Returns the first function passed as an argument to the second, allowing you to adjust arguments, run code before and after, and conditionally execute the original function.",
      "!type": "fn(func: fn(), wrapper: fn(?)) -> !0",
      "!effects": ["call !1 !0"],
      "!url": "http://underscorejs.org/#wrap"
    },
    "zip": {
      "!doc": "Zip together multiple lists into a single array -- elements that share an index go together.",
      "!type": "fn(array1: [?], array2: [?]) -> [?]",
      "!url": "http://underscorejs.org/#zip"
    }
  }
}
