# Technical Documentation: jashkenas/underscore

> ℹ️ **Provenance:** In-Tree Documentation (11 Chapters) · [CodeWiki Reference](https://codewiki.google/github.com/jashkenas/underscore) · Recency: Active (< 180 days)

## File: README.md

__
                      /\ \                                                         __
     __  __    ___    \_\ \     __   _ __   ____    ___    ___   _ __    __       /\_\    ____
    /\ \/\ \ /' _ `\  /'_  \  /'__`\/\  __\/ ,__\  / ___\ / __`\/\  __\/'__`\     \/\ \  /',__\
    \ \ \_\ \/\ \/\ \/\ \ \ \/\  __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\  __/  __  \ \ \/\__, `\
     \ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/
      \/___/  \/_/\/_/\/__,_ /\/____/ \/_/ \/___/  \/____/\/___/  \/_/ \/____/\/_//\ \_\ \/___/
                                                                                  \ \____/
                                                                                   \/___/

Underscore.js is a utility-belt library for JavaScript that provides
support for the usual functional suspects (each, map, reduce, filter...)
without extending any core JavaScript objects.

For Docs, License, Tests, and pre-packed downloads, see:
https://underscorejs.org

For support and questions, please consult
our [security policy](SECURITY.md),
[the gitter channel](https://gitter.im/jashkenas/underscore)
or [stackoverflow](https://stackoverflow.com/search?q=underscore.js)

Underscore is an open-sourced component of DocumentCloud:
https://github.com/documentcloud

Many thanks to our contributors:
https://github.com/jashkenas/underscore/contributors

You can support the project by donating on
[Patreon](https://patreon.com/juliangonggrijp).
Enterprise coverage is available as part of the
[Tidelift Subscription](https://tidelift.com/subscription/pkg/npm-underscore?utm_source=npm-underscore&utm_medium=referral&utm_campaign=enterprise).

This project adheres to a [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.

---

## File: bower.json

{
  "name": "underscore",
  "main": "underscore-umd.js",
  "keywords": ["util", "functional", "server", "client", "browser"],
  "ignore" : ["docs", "test", "*.yml", "CNAME", "index.html", "favicon.ico", "CONTRIBUTING.md", ".*", "package.json", "karma.*"]
}

---

## File: CODE_OF_CONDUCT.md

# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
  address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at jashkenas@gmail.com. The project team
will review and investigate all complaints, and will respond in a way that it deems
appropriate to the circumstances. The project team is obligated to maintain
confidentiality with regard to the reporter of an incident.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Moderation

Edits of another user's comment must be clearly marked with "**edit**", the
moderator's username, and a timestamp for each occurrence. The only acceptable
reasons for editing another user's comment are:

1. to edit out violations of Our Pledge. These edits must include a rationale.
2. to direct future readers to a relevant point later in the conversation
   (usually the resolution). These edits must be append-only.

Deletion of another user's comment is only acceptable when the comment includes
no original value, such as "+1", ":+1:", or "me too".

## Self-Moderation

Edits of your own comment after someone has responded must be append-only and
clearly marked with "**edit**". Typographical and formatting fixes to your own
comment which do not affect its meaning are exempt from this requirement.
Deletion of your own comment is only acceptable before any later comments have
been posted.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [https://contributor-covenant.org/version/1/4][version]

[homepage]: https://contributor-covenant.org
[version]: https://contributor-covenant.org/version/1/4/

---

## File: CONTRIBUTING.md

## How to contribute to Underscore.js

* This project adheres to a [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.

* Please do not open an issue to report a security issue. Consult the [security policy](SECURITY.md) on what to do instead.

* Before you open an issue or send a pull request, [search](https://github.com/jashkenas/underscore/issues) for previous discussions about the same feature or issue. Add to the earlier ticket if you find one.

* If you're proposing a new feature, make sure it isn't already implemented in [Underscore-Contrib](https://github.com/documentcloud/underscore-contrib).

* When contributing code, make sure that you edit the source code in the `modules/` directory. Also, run `npm install` before committing any changes to ensure that our commit hooks can do their work.

* Before sending a pull request for a feature, be sure to have [tests](https://underscorejs.org/test/).

* Use the same coding style as the rest of the [codebase](https://github.com/jashkenas/underscore/blob/master/modules/index.js).

* In your pull request, do not add documentation or re-build the minified `underscore-umd-min.js` file. We'll do those things before cutting a new release.

### "Help, cloning fails with `fatal: fsck error in packed object`"
This error is caused by zero-padded file modes in the commit history. As fixing this is highly destructive, we suggest ignoring these warnings. The simplest way is to instruct git to do so when cloning. For example, to clone from `jashkenas/underscore`, run the following command: `git clone --config transfer.fsckobjects=false git@github.com:jashkenas/underscore.git`. If cloning from a different user or organization, replace `jashkenas` with their name in the previous command.

### AI policy

We are very critical of generative AI. Please see the [LLVM AI Tool Use
Policy](https://llvm.org/docs/AIToolPolicy.html) for a detailed account of how
we feel about value and effort and Codeberg's [Protecting our FLOSS commons from
LLMs](https://blog.codeberg.org/protecting-our-floss-commons-from-llms.html) for
a comprehensive overview of negative aspects of generative AI.

That being said, we *reluctantly* allow the use of generative AI in
contributions, for two reasons. Firstly, because some people have demonstrated
that these tools have a real value to them and that they can use them
responsibly. Secondly, because we believe that use of generative AI is not
necessarily recognizable as such when done responsibly, which means that we
would not be able to enforce a complete ban on this practice, anyway. If you
want to use generative AI assistance, please observe the following rules.

* **Never** allow your tools to publish anything on your behalf, including code,
  documentation, issues, pull requests, reviews and comments.

* In general, consider generative AI part of your private workflow. Just like
  with code completion or a spell checker, the fact that you are using
  generative AI is no reason to burden other people with additional work.

* All changes must be humanly motivated. If your tool finds a quirky corner case
  in an automated scan, this by itself is not enough reason for an issue ticket
  or a pull request, even if the finding is correct.

* It is *your* job to fully review, understand, correct and polish anything that
  was generated by your tools. The end result of your work, which you share with
  the community, should meet your own highest standards.

* If you fail to follow the rules in this section, your issue or pull request
  may be closed without a review and without further notice.

* If you are contributing to learn, we strongly recommend that you skip AI
assistance entirely.

---

## File: package.json

{
  "name": "underscore",
  "description": "JavaScript's functional programming helper library.",
  "version": "1.13.8",
  "author": "Jeremy Ashkenas <jeremy@documentcloud.org>",
  "license": "MIT",
  "homepage": "https://underscorejs.org",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/jashkenas/underscore.git"
  },
  "keywords": [
    "util",
    "functional",
    "server",
    "client",
    "browser"
  ],
  "main": "underscore-umd.js",
  "module": "modules/index-all.js",
  "type": "commonjs",
  "exports": {
    ".": {
      "import": {
        "module": "./modules/index-all.js",
        "browser": {
          "production": "./underscore-esm-min.js",
          "default": "./underscore-esm.js"
        },
        "node": "./underscore-node.mjs",
        "default": "./underscore-esm.js"
      },
      "require": {
        "module": "./modules/index-all.js",
        "browser": {
          "production": "./underscore-umd-min.js",
          "default": "./underscore-umd.js"
        },
        "node": "./underscore-node.cjs",
        "default": "./underscore-umd.js"
      },
      "default": "./underscore-umd.js"
    },
    "./underscore*": "./underscore*",
    "./modules/*": {
      "require": "./cjs/*",
      "default": "./modules/*"
    },
    "./amd/*": "./amd/*",
    "./cjs/*": "./cjs/*",
    "./package.json": "./package.json"
  },
  "devDependencies": {
    "coveralls": "^3.1.1",
    "cpy-cli": "^3.1.1",
    "docco": "^0.8.0",
    "eslint": "^6.8.0",
    "eslint-plugin-import": "^2.20.1",
    "glob": "^7.1.6",
    "gzip-size-cli": "^1.0.0",
    "husky": "^4.2.3",
    "karma": "^4.4.1",
    "karma-qunit": "^4.1.2",
    "karma-sauce-launcher": "^4.3.6",
    "nyc": "^15.1.0",
    "patch-package": "^6.4.7",
    "pretty-bytes-cli": "^1.0.0",
    "qunit": "2.10.1",
    "rollup": "^2.40.0",
    "terser": "^4.6.13"
  },
  "overrides": {
    "colors@>1.4.0": "1.4.0"
  },
  "scripts": {
    "test": "npm run lint && npm run prepare-tests && npm run test-node",
    "coverage": "npm run prepare-tests && nyc npm run test-node && nyc report",
    "coveralls": "nyc npm run test-node && nyc report --reporter=text-lcov | coveralls",
    "lint": "eslint modules/*.js test/*.js",
    "test-node": "qunit test/",
    "test-browser": "npm i karma-phantomjs-launcher && karma start",
    "bundle": "rollup -c && eslint underscore-umd.js && rollup -c rollup.config2.js",
    "bundle-treeshake": "cd test-treeshake && rollup --config",
    "prepare-tests": "npm run bundle && npm run bundle-treeshake",
    "minify-umd": "terser underscore-umd.js -c \"evaluate=false\" --comments \"/    .*/\" -m",
    "minify-esm": "terser underscore-esm.js -c \"evaluate=false\" --comments \"/    .*/\" -m",
    "module-package-json": "node -e 'console.log(`{\"type\":\"module\",\"version\":\"${process.env.npm_package_version}\"}`)' > modules/package.json",
    "build-umd": "npm run minify-umd -- --source-map content=underscore-umd.js.map --source-map-url \" \" -o underscore-umd-min.js",
    "build-esm": "npm run module-package-json && npm run minify-esm -- --source-map content=underscore-esm.js.map --source-map-url \" \" -o underscore-esm-min.js",
    "alias-bundle": "cpy --rename=underscore.js underscore-umd.js . && cpy --rename=underscore-min.js underscore-umd-min.js . && cpy --rename=underscore-min.js.map underscore-umd-min.js.map .",
    "build": "npm run bundle && npm run build-umd && npm run build-esm && npm run alias-bundle",
    "doc": "patch-package && docco underscore-esm.js && docco modules/*.js -c docco.css -t docs/linked-esm.jst",
    "weight": "npm run bundle && npm run minify-umd | gzip-size | pretty-bytes",
    "prepublishOnly": "npm run build && npm run doc"
  },
  "files": [
    "underscore-esm.js",
    "underscore-esm.js.map",
    "underscore-esm-min.js",
    "underscore-esm-min.js.map",
    "underscore-umd.js",
    "underscore-umd.js.map",
    "underscore-umd-min.js",
    "underscore-umd-min.js.map",
    "underscore.js",
    "underscore-min.js",
    "underscore-min.js.map",
    "underscore-node-f.cjs",
    "underscore-node-f.cjs.map",
    "underscore-node.cjs",
    "underscore-node.cjs.map",
    "underscore-node.mjs",
    "underscore-node.mjs.map",
    "modules/",
    "amd/",
    "cjs/"
  ],
  "husky": {
    "hooks": {
      "pre-commit": "npm run bundle && git add underscore-umd.js underscore-umd.js.map underscore-esm.js underscore-esm.js.map underscore-node-f.cjs underscore-node-f.cjs.map underscore-node.cjs underscore-node.cjs.map underscore-node.mjs underscore-node.mjs.map",
      "post-commit": "git reset underscore-umd.js underscore-umd.js.map underscore-esm.js underscore-esm.js.map underscore-node-f.cjs underscore-node-f.cjs.map underscore-node.cjs underscore-node.cjs.map underscore-node.mjs underscore-node.mjs.map"
    }
  }
}

---

## File: SECURITY.md

# Security Policy

## Supported Versions

We currently support the following versions of Underscore with security updates:

- the latest commit on the `master` branch (published as "edge" on the
  [project website][website]);
- the 1.x release tagged as [latest][npm-latest] on npm;
- any release tagged as [preview][npm-preview] on npm, if present.

[website]: https://underscorejs.org
[npm-latest]: https://www.npmjs.com/package/underscore/v/latest
[npm-preview]: https://www.npmjs.com/package/underscore/v/preview

## Reporting a Vulnerability

Please report security issues by sending an email to
dev@juliangonggrijp.com and jashkenas@gmail.com.

Do __not__ submit an issue ticket or pull request or otherwise publicly
disclose the issue.

After receiving your email, we will respond as soon as possible and indicate
what we plan to do.

### A note on `_.template`

[`template`][template] allows the user to inject arbitrary JavaScript
code in the template string. This is allowed by design. In fact, it is
the main feature of `template`. Without this feature, templates would
not be able to have conditional or repeated sections.

Because of this feature, it is the responsibility of the user not to
pass any untrusted input to `template`. The contract is similar to
that of the `Function` constructor or even `eval`: this function is so
powerful that it can be dangerous, so users must only pass trusted input. This is made explicit in [the documentation][template].

If this does not sound exactly like what you were considering to
report, or in case of doubt, please do send us a report. Of course, we
would rather be safe than sorry. You would not be the first to find a
[vulnerability in `template`][cve-2021-23358].

[template]: https://underscorejs.org/#template
[cve-2021-23358]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-23358

## Disclosure policy

After confirming a vulnerability, we will generally release a security update
as soon as possible, including the minimum amount of information required for
software maintainers and system administrators to assess the urgency of the
update for their particular situation.

We postpone the publication of any further details such as code comments,
tests, commit history and diffs, in order to enable a substantial share of the
users to install the security fix before this time.

Upon publication of full details, we will credit the reporter if the reporter wishes to be publicly identified.

---

## File: .travis.yml

language: node_js
sudo: false
jobs:
  include:
    - node_js: 8
      env:
        - DOWNGRADE=true
        - EXTRA=false
    - node_js: 12
      env:
        - DOWNGRADE=false
        - EXTRA=false
    - node_js: 16
      env:
        - DOWNGRADE=false
        - EXTRA=true
before_install:
  - "[ $EXTRA = false ] || npm install karma-cli"
before_script:
  - "[ $EXTRA = false ] || npm install karma-sauce-launcher"
  - "[ $DOWNGRADE = false ] || npm install rollup@1"
script:
  - "[ $EXTRA = false ] || npm run lint"
  - npm run prepare-tests
  - "[ $EXTRA = false ] || npm run build-umd"
  - "[ $EXTRA = false ] || npm run build-esm"
  - "[ $EXTRA = false ] || npm run doc"
  - "[ $EXTRA = true ] || npm run test-node"
  - "[ $EXTRA = false ] || npm run coveralls"
  - "[ $EXTRA = false ] || npm run test-browser"
  - "[ $EXTRA = false ] || karma start karma.conf-sauce.js"
notifications:
  email: false
env:
  global:
  - NPM_CONFIG_PROGRESS="false"
  - secure: bDZSBQfqr21hCayjcZ20IxrV6+XGhxQPFIfwWqEKLrF93Gu8LLVjZRxXE/mE8I8N4Z5WtDNb4ZHrm/TTzmcPa5MuHgIxEdknQCncobH8oimwc83SHwEPk6okeNKl39VlCjvvnmoe/V/KpnknuYn3Rqghtl/Uv9KLpCwskwjTtcw=
  - secure: SRECgXuwcZTcD3GVxTS2bYNgRyye4vq6BLrV2PH9FyNenowsKQR2EwlC/dppc1Q8NWMgv79J/R96q9JOFh+mEH9L5dlBb2yhnGH8amVeM/ChAJHT/F8YktKM453uVpz5fR00QcCQDDUOx6Pvx374ID0OKNpWKAkQBWA9mPTsLnE=

---

## File: modules/package.json

{"type":"module","version":"1.13.8"}

---

## File: .github/FUNDING.yml

tidelift: "npm/underscore"
patreon: juliangonggrijp
github: [jgonggrijp]

---

## File: .github/config/codeql.yml

paths:
  - 'modules/**'
  - 'test/**'
  - 'test-treeshake/**'
  - 'rollup*.js'
  - 'index.html'

---

## File: .github/workflows/codeql-analysis.yml

# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
  push:
    branches: [ master ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ master ]
    paths:
      - 'modules/**'
      - 'test/**'
      - 'test-treeshake/**'
      - 'rollup*.js'
      - 'index.html'
  schedule:
    - cron: '16 8 * * 3'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'javascript' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
        # Learn more about CodeQL language support at
        # https://codeql.github.com/docs/codeql-overview/supported-languages-and-frameworks/

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v3
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.
        # queries: ./path/to/local/query, your-org/your-repo/queries@main
        config-file: ./.github/config/codeql.yml

    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v3

    # ℹ️ Command-line programs to run using the OS shell.
    # 📚 https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions

    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
    #    and modify them (or add more) to build your code if your project
    #    uses a compiled language

    #- run: |
    #   make bootstrap
    #   make release

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v3

--- METRICS ---
- Files Extracted: 11
- Estimated Token Budget: ~5566 tokens
- Recency Window: Active (< 180 days)
- Canonical Reference: https://codewiki.google/github.com/jashkenas/underscore
