[
  {
    "path": ".claude/settings.local.json",
    "content": "{\n  \"permissions\": {\n    \"allow\": [\n      \"Bash(grep:*)\",\n      \"Bash(find:*)\",\n      \"Bash(git checkout:*)\",\n      \"Bash(go test:*)\",\n      \"Bash(go build:*)\",\n      \"Bash(make:*)\"\n    ]\n  }\n}\n"
  },
  {
    "path": ".dockerignore",
    "content": ".github\nbin/\n./pgweb\n"
  },
  {
    "path": ".gitattributes",
    "content": "bindata.go -diff\n"
  },
  {
    "path": ".github/workflows/checks.yml",
    "content": "name: checks\n\non:\n  push:\n    branches:\n      - main\n    paths-ignore:\n      - '**.md'\n  pull_request:\n    types:\n      - opened\n      - synchronize\n    paths-ignore:\n      - '**.md'\n\n\nenv:\n  GO_VERSION: \"1.25\"\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.ref }}\n  cancel-in-progress: true\n\njobs:\n  tests:\n    name: tests\n    runs-on: ubuntu-latest\n    timeout-minutes: 40\n    strategy:\n      matrix:\n        pg_version: [9.6, 10, 11, 12, 13, 14, 15, 16, 17, 18]\n\n    services:\n      postgres:\n        image: postgres:${{ matrix.pg_version }}\n        env:\n          POSTGRES_USER: postgres\n          POSTGRES_PASSWORD: postgres\n          POSTGRES_DB: booktown\n        ports:\n          - 5432:5432\n        options: >-\n            --health-cmd pg_isready\n            --health-interval 10s\n            --health-timeout 5s\n            --health-retries 5\n    steps:\n      - name: Install latest Postgres client\n        run: |\n          sudo rm -f /etc/apt/sources.list.d/pgdg.list\n          curl --silent https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add\n          echo \"deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main\" | sudo tee /etc/apt/sources.list.d/pgdg.list\n          sudo apt-get update && sudo apt-get install -y postgresql-client-18\n\n      - uses: actions/checkout@v3\n        with:\n          fetch-depth: 0\n      - uses: actions/setup-go@v3\n        with:\n          go-version: ${{ env.GO_VERSION }}\n      - run: go mod download\n      - run: make test\n        env:\n          MallocNanoZone: 0 # https://github.com/golang/go/issues/49138\n          PGHOST: localhost\n          PGUSER: postgres\n          PGPASSWORD: postgres\n          PGDATABASE: booktown\n\n  tests-windows:\n    runs-on: windows-latest\n    timeout-minutes: 30\n\n    steps:\n      - uses: actions/checkout@v3\n        with:\n          fetch-depth: 0\n      - uses: actions/setup-go@v3\n        with:\n          go-version: ${{ env.GO_VERSION }}\n      - run: go mod download\n      - run: make test\n\n  lint:\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n\n    steps:\n      - uses: actions/setup-go@v3\n        with:\n          go-version: ${{ env.GO_VERSION }}\n\n      - uses: actions/checkout@v3\n        with:\n          fetch-depth: 0\n\n      - name: golangci-lint\n        uses: golangci/golangci-lint-action@v8\n        with:\n          version: v2.7.2\n\n  fmt:\n    name: fmt\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n        with:\n          fetch-depth: 0\n      - uses: actions/setup-go@v3\n        with:\n          go-version: ${{ env.GO_VERSION }}\n      - run: go mod download\n      - run: script/check_formatting.sh\n"
  },
  {
    "path": ".github/workflows/deploy.yml",
    "content": "name: demo deploy\n\non:\n  push:\n    branches:\n      - main\n\nenv:\n  FLY_API_TOKEN: ${{ secrets.FLY_TOKEN }}\n\njobs:\n  deploy:\n    name: Deploy to Fly\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n\n    steps:\n      - uses: actions/checkout@v3\n      - uses: superfly/flyctl-actions/setup-flyctl@master\n      - run: flyctl deploy --remote-only\n"
  },
  {
    "path": ".github/workflows/docker.yml",
    "content": "name: docker\n\non:\n  push:\n    branches:\n      - main\n\nenv:\n  GO_VERSION: \"1.25\"\n  CGO_ENABLED: 0\n  IMAGE_REPOSITORY: sosedoff/pgweb\n\njobs:\n  docker-build:\n    name: docker images\n    runs-on: ubuntu-latest\n    timeout-minutes: 30\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v2\n\n      - name: Configure docker build context\n        uses: docker/setup-buildx-action@v2\n\n      - name: Build docker images\n        uses: docker/build-push-action@v2\n        with:\n          context: .\n          push: false\n          tags: pgweb:latest\n          platforms: linux/amd64,linux/arm64,linux/arm/v7\n          build-args: |\n            \"CGO_ENABLED=${{ env.CGO_ENABLED }}\"\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: release\n\non:\n  push:\n    tags:\n      - \"v*\"\n\nenv:\n  GO_VERSION: \"1.25\"\n  CGO_ENABLED: 0\n  DOCKER_REPOSITORY: sosedoff/pgweb\n  GHCR_REPOSITORY: sosedoff/pgweb\n\njobs:\n  docker-release:\n    name: Publish Docker images\n    runs-on: ubuntu-latest\n    timeout-minutes: 30\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v2\n\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v2\n\n      - name: Configure docker build context\n        uses: docker/setup-buildx-action@v2\n\n      - name: Set reference tags\n        id: refs\n        run: |\n          echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/}\n          echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/}\n          echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/v}\n\n      - name: Login to Docker Hub\n        uses: docker/login-action@v2\n        with:\n          username: ${{ secrets.DOCKER_USERNAME }}\n          password: ${{ secrets.DOCKER_PASSWORD }}\n\n      - name: Login to Github Container Registry\n        uses: docker/login-action@v2\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GH_TOKEN }}\n\n      - name: Build and push docker images\n        uses: docker/build-push-action@v2\n        with:\n          context: .\n          push: true\n          tags: |\n            ${{ env.DOCKER_REPOSITORY }}:${{ steps.refs.outputs.SOURCE_TAG }}\n            ${{ env.DOCKER_REPOSITORY }}:latest\n            ghcr.io/${{ env.GHCR_REPOSITORY }}:${{ steps.refs.outputs.SOURCE_TAG }}\n            ghcr.io/${{ env.GHCR_REPOSITORY }}:latest\n          platforms: linux/amd64,linux/arm64,linux/arm/v7\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\n.idea\n.env\n.envrc\npgweb\nbin\ntmp/\ncover.out\n"
  },
  {
    "path": ".golangci.yml",
    "content": "version: \"2\"\nlinters:\n  disable:\n    - errcheck\n  settings:\n    staticcheck:\n      checks: [\"all\", \"-ST1000\", \"-ST1003\", \"-ST1016\", \"-ST1020\", \"-ST1021\", \"-ST1022\", \"-ST1005\", \"-QF1004\"]\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## Changelog\n\nCurrent [release](https://github.com/sosedoff/pgweb/releases) is `0.17.0`.\n\n## Next\n\n- `NEW` Add PGWEB_BOOKMARKS_DIR environment variable to configure bookmarks directory\n\n## 0.17.0 - 2025-11-22\n\n- `NEW` Update Dockerfile to use Golang 1.24 image, GH-821\n- `NEW` Bump go crypto package to 0.44.x, GH-820, GH-823\n- `NEW` Add PostgreSQL 18 support to Github Actions, GH-816\n- `NEW` Connect backend refactor, GH-801\n- `NEW` Add server settings view, GH-768\n- `NEW` Add exec time of empty queries, GH-763\n- `FIX` Minor typos, GH-764, GH-786\n- `FIX` Shorten git revision printed in the --version output, GH-770\n\n## 0.16.2 - 2024-11-02\n\n- `FIX` Build a new Docker image with PostgreSQL 17 support\n- `FIX` Run CI against PostgreSQL 17, GH-758\n- `FIX` Rename master to main branch, GH-750\n\n## 0.16.1 - 2024-09-07\n\n- `FIX` Remove linux/arm/v5 from docker release action, GH-742\n\n## 0.16.0 - 2024-06-04\n\n- `NEW` Allow database stats downloads, GH-738\n- `NEW` Add analyze table action, GH-737\n- `NEW` Bump postgres version used in docker compose to 15, GH-729\n- `NEW` Build on Go 1.22, GH-726\n- `FIX` SSH tunnel cleanup and parse fixup, GH-731\n- `FIX` Drop linux/arm/v5 from docker build, GH-728\n- `FIX` Propagate CGO_ENABLED environment variable to docker build, GH-724\n\n## 0.15.0 - 2024-03-14\n\n- `NEW` Add support for a bookmarks-only mode, GH-716\n- `FIX` Fix missing indexes by quoting schema/table name to ::regclass, GH-711\n- `FIX` Continue on parseJSON error, GH-708\n\n## 0.14.3 - 2024-01-28\n\n- `NEW` Allow retrying a connection on startup, GH-695\n- `NEW` Allow setting readonly mode in bookmarks, GH-707\n- `FIX` Add UPDATE to list of restricted keywords in read-only mode, GH-697\n\n## 0.14.2 - 2023-10-29\n\n- `NEW` Execute tests using PostgreSQL 16, GH-691\n- `FIX` Unclosed database sessions and tunnels, GH-688\n- `FIX` Use pg_table_size for table stats query, GH-685\n- `FIX` Use `HasSuffix` to correctly determine URL prefix, GH-684\n\n## 0.14.1 - 2023-06-17\n\n- `NEW` Add process start time metric, GH-675\n- `NEW` Configure pgweb user for docker container, GH-674\n- `NEW` Updated dockerfile, GH-645\n- `FIX` Fix typo in the healthy metric, GH-657\n- `NEW` Use entrypoint instead of cmd in in dockerfile, GH-654\n\n## 0.14.0 - 2023-02-21\n\n- `FIX` History page query loading fixup, GH-632\n- `NEW` Display cell content via context menu, GH-634\n- `NEW` Handle support/permissions errors in info call, GH-635\n- `NEW` Show error message when API calls fail, GH-636\n- `NEW` Add bookmark options to load username/password from env vars, GH-638\n- `NEW` Add context menu to display database tables stats, GH-639\n- `NEW` Added Local Queries feature, GH-641\n- `FIX` Ensure that objects are sorted by schema and name, GH-648\n- `FIX` Fetch local queries on db connect, GH-650\n\n## 0.13.1 - 2022-12-27\n\n- Fix connect flow when `~/.pgweb/bookmarks` directory is not available, GH-631\n\n## 0.13.0 - 2022-12-25\n\n- Add support for .pgpass file, GH-617\n- Request logging additions (request id, forwarded user), GH-618\n- Establish connections using bookmark ID only, GH-619\n- Display empty schemas on the sidebar, GH-621\n- Configure timeout and retries when testing connection status, GH-623\n- Setup basic prom metrics endpoint, GH-624\n- Add default connect_timeout option to connection string, GH-626\n- Add duration_ms to log entries, GH-628\n- Add query execution stats to api endpoint, GH-629\n\n## 0.12.0 - 2022-12-13\n\n- Deprecate usage of Gox for binary builds, GH-571\n- Add netcat install in dockerfile to provide a way to healthcheck, GH-572\n- Install latest postgres client in docker image, GH-577\n- Add support for `PGWEB_` prefix environment variables, GH-585\n- Fix export URL generation, refactor export code, GH-588\n- Add logrus-based request logger, GH-589\n- Configure logger for connect backend, GH-591\n- Set LDFLAGS for make build/release commands, GH-592\n- Add internal sessions manager, GH-593\n- Include index size on the index list view, GH-595\n- Fix flaky backend connection test, GH-596\n- Add ability to view and copy views/materialized views definitions, GH-594\n- Enable dev assets mode with PGWEB_ASSETS_DEVMODE env var, GH-597\n- Make query input box resizable, GH-599\n- Deprecate Heroku demo deployments and switch to Fly, GH-600\n- Handle returning values in update/delete queries, GH-601\n- Fix panic with invalid time marshaling, GH-602\n- Configure logging level and format, GH-605\n- Use go embed to load queries from static files, GH-607\n- Switch go build target to 1.19, GH-603\n- Add support for user functions, GH-608\n- Implement global query timeout option, GH-609\n- Switch windows tests from Appveyor to Github Actions, GH-611\n- Fix activity endpoint panic when server version is not detected, GH-612\n\n## 0.11.12 - 2022-07-05\n\n- Update base docker image (alpine), update deps, GH-558\n- Refactor docker images building, include ARM, GH-568\n\n## 0.11.11 - 2022-03-29\n\n- Auto-detect the query from the query source based on user selection, GH-547\n- Added binary codec base58 as well as improving the help for --binary-codec flag, GH-548\n- Change binary codec back to none, GH-555\n\n## 0.11.10 - 2022-01-20\n\n- Removes alert on column copy value, GH-536\n- Migrate test suite to Github Action, GH-540\n- Serialize binary bytea cols into hex/base64, GH-537\n- Include build time into version string, GH-541\n- Explain analyze dropdown button, GH-532\n- Switch to go 1.17, GH-543\n- Use HTTP 302 status code for successful backend redirect, GH-544\n- Add connect backend tests, GH-546\n\n## 0.11.9 - 2021-11-08\n\n- Releases are built on Go 1.17\n- Build time correction, GH-521\n- Fix broken assets URL path prefix, GH-525\n- Update docker build image to alpine:3.14, GH-522\n- Upgrade gin dependency to v1.7.4, GH-527\n- Add FreeBSD startup script, GH-520\n\n## 0.11.8 - 2021-07-07\n\n- Releases are built with Go 1.16\n- Add ARM64 v7 build target, GH-497\n- Switch to Go modules for dependency management, GH-509\n- Switch to Go embed for static assets management, GH-510\n- Add Darwin/ARM64 build target (Apple Silicon), GH-513\n\n## 0.11.7 - 2020-10-18\n\n- Releases are built with Go 1.15\n- Show results row context menu on custom query results, GH-457\n- Do not terminate if local authentication failed on start, GH-463\n- Do not show other databases if session is locked, GH-470\n- Strip debug information from binary to reduce size, GH-489\n- Disable autocomplete on database search field, GH-492\n- Improve windows connection error matching during start, GH-493\n\n## 0.11.6 - 2020-02-19\n\n- Add CLI options for SSL key, cert and root certs, GH-452\n- Remove double click action on cell, GH-455\n\n## 0.11.5 - 2019-12-16\n\n- Add basic SQL keyword autocompletion, GH-443\n- SSH Private Key handling update (encrypted keys are supported now), GH-445\n- Include Go version into `pgweb --version` output, GH-447\n- Fix long table name bug in the sidebar, GH-448\n- Add SQL objects (table,views,etc) autocompletion, GH-449\n- Include Go version into info API endpoint, GH-450\n\n## 0.11.4 - 2019-10-05\n\n- Fix SQL export filename, GH-438\n- Update Docker image to alpine:3.10, GH-439\n- Drop unsupported pg_dump options from connection string, GH-441\n- Misc code cleanup and formatting, GH-442\n\n## 0.11.3 - 2019-07-24\n\n- Misc: add script to update homebrew formula version, GH-423\n- Destructive keyword restriction in read-only mode, GH-421\n- Make database object searchable in sidebar, GH-434\n- Update lib/pg to 1.1.1, GH-435\n\n## 0.11.2 - 2019-02-15\n\n- Fix table row estimation query for camelcase schemas, GH-414\n\n## 0.11.1 - 2019-01-28\n\n- Typo fixes\n- Add Base64 javascript encoder/decoder to replace deprecated window.atob call, GH-405\n- Fix startup error when DATABASE_URL is set, GH-406\n- Fix user auto detection when USER env var is not set, GH-408\n- Switch bindata dependency to use maintained fork: github.com/go-bindata/go-bindata, GH-409\n\n## 0.11.0 - 2018-12-24\n\n- Tweak sidebar database object counters styles, GH-400\n- Do not exit with error if local server is not running, GH-399\n- Fix SSH host verification check, GH-398\n- Scope activity list to current database only, GH-397\n- Show current release version and check for updates, GH-396\n- Force switch back to default connection settings view, GH-395\n- Fix row count estimation bug, GH-394\n- Print out failed query SQL and args with --debug flag, GH-393\n\n## 0.10.0 - 2018-11-28\n\n- Fixes relation not found errors when dealing with table names that have uppercase characters, GH-356\n- Dockerfile updates, GH-357\n- Check if pg_dump is available before running database export, GH-358\n- Improvements to CockroachDB integration, GH-365\n- Add EstimatedTableRowsCount to avoid count in large tables, GH-366\n- Automatically set table filter option to 'equals' if its not set, GH-370\n- Dependencies update and switch to dep, GH-375\n- Add column context menu item to get numeric stats, GH-377\n- Fix issues with connection string builder, GH-378\n- Include rows count to numeric stats view on table column, GH-379\n- Make localhost to be a default db host, GH-380\n- Clear out connection settings/bookmark on login screen when running in session/connect mode\n- Add table row context menu with actions, GH-381\n- Allow settings url prefix with URL_PREFIX env var, GH-387\n- Fix JSON marshal panic when dealing with NaN values, GH-388\n- Fix startup behavior when user did not provide a database name, GH-389\n\n## 0.9.12 - 2018-04-23\n\n- Add link to view database connection string format on login page\n- Include constraint name under \"constraints\" tab, GH-343\n- Misc CI and config changes\n\n## 0.9.11 - 2017-12-07\n\n- Fix ssl mode for the connection url in the bookmarks, GH-320\n- Add support for CORS, GH-321\n- Fix custom query results counter for empty queries, GH-322\n- Reorganize the table context menu, GH-323\n- Disable database connection string text field autocomplete, GH-327\n- Add db prefix to the table export files, GH-329\n- Add database view context menu with export actions, GH-330\n\n## 0.9.10 - 2017-11-03\n\n- Make idle connection timeout configurable, [GH-282]\n- Fix panics when sshinfo is not set on bookmarks, [GH-296]\n- Dot now allow using startup bookmark in multi-session mode, [GH-300]\n- Add ability to copy table name from the sidebar, [GH-301]\n\n## 0.9.9 - 2017-09-28\n\n- Automatically format JSON data exports, GH-255\n- Update Docker image to alpine:3.6, GH-256\n- Print out PostgreSQL server version on start in a single-session mode, GH-264\n- Record last query timestamp for the client connection, GH-265\n- Add context menu for table headers in browse mode (copy name, see unique values), GH-268\n- Add ability to export current database dump, GH-270\n- Automatically open pgweb in browser on start if its already running, GH-272\n- Connect to the database with credentials provided by a third-party backend, GH-266\n- Automatically close idle sessions (no activity in 1 hour), GH-275\n- Allow connecting via SSH with a custom private key and other fixes, GH-277\n- Add options to disable SSH connections, GH-279\n\n## 0.9.8 - 2017-08-04\n\n- Fixed error checking in the API, GH-234\n- Fixed activity tab to support PG 9.x versions, GH-237\n- Remember sort column and order for pagination, GH-240\n- Use `sslmode=disable` for bookmarks without sslmode option, GH-244\n- Javascript fixes for IE9-11, GH-245\n- Require confirmation for the disconnect, GH-246\n- Clean the results table on manual disconnect\n\n## 0.9.7 - 2017-04-04\n\n- Fixed issue with locked session and empty db url, GH-206\n- Fixed path rewrite on DB change, GH-212\n- Upgraded dependencies, GH-217\n- Added ability to specify bookmarks path, GH-218\n- Added counter for the number of rows from a custom SQL query, GH-224\n- Added new behavior for removing table rows view on custom SQL query page, GH-225\n\n## 0.9.6 - 2016-11-18\n\n- Fixed bug in query base64-encoding, GH-186\n- Fixed rows pagination visibility bug, GH-190\n- Fixed issue with query order escaping, GH-191\n- Fixed invalid query selection for explain command, GH-198\n- Fixed issue with empty sidebar, now it shows empty state, GH-202\n- Added new flag --readonly to enable read only transaction mode, GH-193\n- Added ability to kill any running query, GH-194\n- Added session database connection locking, GH-195\n- Added ability to switch between databases, GH-196\n- Added feature to keep last selected tab when switching between tables, GH-197\n- Added new flag --bookmark (-b) to specify server connection from bookmark, GH-201\n\n## 0.9.5 - 2016-10-01\n\n- Only view schema with USAGE privileges, GH-167\n- Fixed broken export to CSV/JSON/XML if hashmark in URL, GH-175\n- Added example service configuration for systemd, GH-177\n- Allow setting auth user and pass using variables\n\n## 0.9.4 - 2016-07-29\n\n- Fixes CSV/JSON/XML export buttons when pgweb is running with url prefix, GH-170\n\n## 0.9.3 - 2016-06-30\n\n- Uses Go 1.6 for development, GH-155\n- Fixes timestamp formatting in CSV export, GH-163\n- Included PostgreSQL 9.6 for integration testing\n- Switches docker image to Alpine to reduce image size\n- Adds support for ARMv5\n\n## 0.9.2 - 2016-03-01\n\n- Fixes bug with unsafe base64 encoded sql queries\n- Fixes issue with session id not being included in multi-session mode\n- Fixes visual issue with long table names in sidebar\n- Fixes visual issue with a scrollbar in table information widget\n- Fixes issue with database connection form being reset by clicking on 'cancel' button\n- Adds ability to close connection\n- Adds display message for number of affected rows for update/delete queries, GH-133\n- Adds web server url prefix as a CLI option, GH-135\n\n## 0.9.1 - 2016-01-25\n\n- Fixes bug with tables context menu\n- Fixes JS bug when query returns no rows\n- Fixes bug with switching between different connection modes\n- Adds AJAX timeout to 5s\n- Adds sidebar reload action on any CREATE/DROP action\n\n## 0.9.0 - 2016-01-19\n\n- Add support for multiple schemas. GH-112\n- Add support for native ssh tunnes. GH-114\n- Add materialized views to list of schema objects\n- Adds a few design tweaks and cleanups\n- Fixes bug with nil result set when fetching rows\n\n## 0.8.0 - 2016-01-11\n\n- Fixes bug with bigint conversions in javascript. Now bigints are encoded as strings. GH-109\n- Adds pagination and simple column filtering to table rows browser. GH-110\n- Adds ability to use pgweb with multiple database sessions. GH-111\n- Adds a few design tweaks and cleanups\n\n## 0.7.0 - 2016-01-05\n\n- Adds sequences to the sidebar panel - GH-100\n- Adds table constrains view - GH-104\n- Adds ability to export table and query rows as JSON/XML - GH-107\n- Updates to UI theme and SQL editor\n\n## 0.6.3 - 2015-08-16\n\n- Adds PostgreSQL password escaping in web ui, GH-96\n- Adds base64 query encoding for CSV export, GH-95\n- Adds automatic saving of last executed query to localStorage\n- Adds request middleware to log incoming form params in debug mode\n\n## 0.6.2 - 2015-07-15\n\n- Adds ability to specify connection strings prefixed by `postgresql://`, [GH-92]\n- Updates configuration for Heroku, [GH-89], [GH-90]\n- Updates postgresql library dependency to latest, [GH-91]\n- Fixes password field to not display plaintext passwords, [GH-87]\n\n## 0.6.1 - 2015-06-18\n\n- This release is repackage-release targeted to fix binary downloads\n\n## 0.6.0 - 2015-05-31\n\n- Adds ability to execute only selected SQL query in run command view, [GH-85]\n- Adds ability to delete/truncate table via context many on sidebar view\n- Adds ability to export table contents to CSV via context menu on sidebar view\n- Changes sidebar color scheme to a lighter and better looking one\n\n## 0.5.3 - 2015-05-06\n\n- Changes default server port from 8080 to 8081 to avoil conflict with RethinkDB\n- Changes styles for table rows and connection settings window\n- Adds highlighting styles for columns with sort order\n- Adds git sha into program version output\n- Add new endpoint /api/info to get build details\n\n## 0.5.2 - 2015-04-13\n\n- Adds a new endpoint /activity that returns active queries\n- Adds tab to view active queries\n- Adds column sorting when browsing table contents\n- Fixes SQL query view when switching to table structure view\n\n## 0.5.1 - 2015-02-23\n\n- Upgrades Gin framework dependency to 0.5.0\n- Fixes server crash if another pgweb server is running\n\n## 0.5.0 - 2015-01-13\n\n- Adds Go 1.4 support\n- Adds connection string printing in debug mode\n- Adds initial bookmarks support\n- Adds /api prefix for all API calls\n- Adds makefile usage task\n- Adds windows CI to verify build process\n- Adds example sql database to codebase\n- Adds timestamped filenames when exporting results to CSV [GH-75]\n- Adds connection checking on each request to prevent api panics\n- Adds timestamps to query history records\n- Adds current database name to the sidebar\n- Adds button to refresh tables list to the sidebar\n- Updates all application dependencies\n- Changes /api/info endpoint to /api/connection\n- Fixes issues with connection string/options parsing\n- Fixes capitalized column names in table view\n- Fixes connection string validation in /api/connect endpoint\n\n## 0.4.1 - 2014-12-01\n\n- Adds pgweb version on start [GH-65]\n- Adds user detection from OS environment\n- Adds simple memory profiles with --debug option\n- Adds the session user and search path in connection info [GH-67]\n- Adds table list reloading after CREATE/DROP TABLE queries [GH-69]\n- Adds font awesome icons for the sidebar\n- Removes query recording for internal queries [GH-67]\n- Fixes default sslmode. Its not longer set to \"disable\"\n- Fixes cells cropping on table indexes view\n- Fixes connection URL generation using web interface\n- Fixes SQL statements for table row count [GH-67]\n- Fixes /tables JSON response if database does not have any tables\n\n## 0.4.0 - 2014-11-11\n\n- Adds query escaping when exporting results to CSV [GH-38]\n- Adds keyboard shortcut (ctrl+e, command+e on mac) for query explain action\n- Adds HTTP basic authentication with --auth-user and --auth-pass flags\n- Adds -skip-open/-s flag to disable automatic browser launch\n- Adds --bind option to specify server listen hostname/ip\n- Adds ssl mode parameters to url if ssl flag is set and not defined in the url\n- Adds dependency management with Godep\n- Adds Docker support\n- Adds Heroku support\n- Adds ability to connect to databases with no tables\n- Adds precompiled assets into repository to simplify development\n- Adds a connection details view\n- Adds a new interface to specify connection settings or make a new connection\n- Adds page favicon\n- Adds ability to present cell data as text area by double clicking on it\n- Fixes styles for query explain results\n- Fixes sidebar navigation scrolling styles [GH-12]\n- Fixes sidebar table name styles to support long names\n\n## 0.3.1 - 2014-10-28\n\n- Adds proper exit code when printing version via -v/--version flag\n- Adds --version and --debug long flag names\n- Adds double quotes for table name when fetching table contents\n- Adds support for DATABASE_URL environment variable if no --url is set\n- Adds proper usage of jQuery .prop method\n- Adds --pass flag to specify connection password\n- Fixes --ssl flag usage, previous value was hardcoded\n\n## 0.3.0 - 2014-10-26\n\n- Renamed `make deps` to `make setup` and fix issues with bootstrapping\n- Removed hardcoded url for CSV export, it now detects application host:port\n- Improved query history view table styles\n- Moved table information view to the sidebar\n- Added --listen flag to specify web server port, still defaults to 8080\n\n## 0.2.0 - 2014-10-23\n\n- Design tweaks\n- Automatically opens browser on OSX systems\n- Adds query explain functionality\n- Adds export to CSV\n\n## 0.1.0 - 2014-10-14\n\n- Initial release\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "- Fork repository\n- Create a new git branch\n- Make changes\n- Run tests: `make test`\n- Run tests against all supported PostreSQL versions: `make test-all` (optional)\n- If you change frontend code (js/css) make sure to rebuild assets: `make assets`\n- Open a new pull request"
  },
  {
    "path": "Dockerfile",
    "content": "# ------------------------------------------------------------------------------\n# Builder Stage\n# ------------------------------------------------------------------------------\nFROM golang:1.25-trixie AS build\n\n# Set default build argument for CGO_ENABLED\nARG CGO_ENABLED=0\nENV CGO_ENABLED=${CGO_ENABLED}\n\nWORKDIR /build\n\nRUN git config --global --add safe.directory /build\nCOPY go.mod go.sum ./\nRUN go mod download\nCOPY Makefile main.go ./\nCOPY static/ static/\nCOPY pkg/ pkg/\nCOPY .git/ .\nRUN make build\n\n# ------------------------------------------------------------------------------\n# Fetch signing key\n# ------------------------------------------------------------------------------\nFROM debian:trixie-slim AS keyring\nADD https://www.postgresql.org/media/keys/ACCC4CF8.asc keyring.asc\nRUN apt-get update && \\\n    apt-get install -qq --no-install-recommends gpg\nRUN gpg -o keyring.pgp --dearmor keyring.asc\n\n# ------------------------------------------------------------------------------\n# Release Stage\n# ------------------------------------------------------------------------------\nFROM debian:trixie-slim\n\nARG keyring=/usr/share/keyrings/postgresql-archive-keyring.pgp\nCOPY --from=keyring /keyring.pgp $keyring\nRUN . /etc/os-release && \\\n    echo \"deb [signed-by=${keyring}] http://apt.postgresql.org/pub/repos/apt/ ${VERSION_CODENAME}-pgdg main\" > /etc/apt/sources.list.d/pgdg.list && \\\n    apt-get update && \\\n    apt-get install -qq --no-install-recommends ca-certificates openssl netcat-openbsd curl postgresql-client\n\nCOPY --from=build /build/pgweb /usr/bin/pgweb\n\nRUN useradd --uid 1000 --no-create-home --shell /bin/false pgweb\nUSER pgweb\n\nEXPOSE 8081\nENTRYPOINT [\"/usr/bin/pgweb\", \"--bind=0.0.0.0\", \"--listen=8081\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014-2024 Dan Sosedoff <dan.sosedoff@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": "PKG = github.com/sosedoff/pgweb\nGIT_COMMIT ?= $(shell git rev-parse --short=8 HEAD)\nBUILD_TIME ?= $(shell date -u +\"%Y-%m-%dT%H:%M:%SZ\" | tr -d '\\n')\nGO_VERSION ?= $(shell go version | awk {'print $$3'})\n\nDOCKER_RELEASE_TAG = \"sosedoff/pgweb:$(shell git describe --abbrev=0 --tags | sed 's/v//')\"\nDOCKER_LATEST_TAG = \"sosedoff/pgweb:latest\"\n\nLDFLAGS = -s -w\nLDFLAGS += -X $(PKG)/pkg/command.GitCommit=$(GIT_COMMIT)\nLDFLAGS += -X $(PKG)/pkg/command.BuildTime=$(BUILD_TIME)\nLDFLAGS += -X $(PKG)/pkg/command.GoVersion=$(GO_VERSION)\n\nusage:\n\t@echo \"\"\n\t@echo \"Task                 : Description\"\n\t@echo \"-----------------    : -------------------\"\n\t@echo \"make dev             : Generate development build\"\n\t@echo \"make build           : Generate production build for current OS\"\n\t@echo \"make release         : Generate binaries for all supported OSes\"\n\t@echo \"make test            : Execute test suite\"\n\t@echo \"make test-all        : Execute test suite on multiple PG versions\"\n\t@echo \"make lint            : Execute code linter\"\n\t@echo \"make clean           : Remove all build files and reset assets\"\n\t@echo \"make docker          : Build docker image\"\n\t@echo \"make docker-release  : Build and tag docker image\"\n\t@echo \"make docker-push     : Push docker images to registry\"\n\t@echo \"\"\n\ntest:\n\tgo test -v -race -cover ./pkg/...\n\ntest-all:\n\t@./script/test_all.sh\n\t@./script/test_cockroach.sh\n\nlint:\n\tgolangci-lint run\n\ndev:\n\tgo build\n\t@echo \"You can now execute ./pgweb\"\n\nbuild:\n\tgo build -ldflags '${LDFLAGS}'\n\t@echo \"You can now execute ./pgweb\"\n\ninstall:\n\tgo install -ldflags '${LDFLAGS}'\n\t@echo \"You can now execute pgweb\"\n\nrelease: clean\n\t@echo \"Building binaries...\"\n\t@LDFLAGS='${LDFLAGS}' ./script/build_all.sh\n\nclean:\n\t@echo \"Removing all artifacts\"\n\t@rm -rf ./pgweb ./bin/*\n\ndocker:\n\tdocker build --no-cache -t pgweb .\n\ndocker-run:\n\tdocker run --rm -p 8081:8081 -it pgweb\n\ndocker-release:\n\tdocker build --no-cache -t $(DOCKER_RELEASE_TAG) .\n\tdocker tag $(DOCKER_RELEASE_TAG) $(DOCKER_LATEST_TAG)\n\tdocker images $(DOCKER_RELEASE_TAG)\n\ndocker-push:\n\tdocker push $(DOCKER_RELEASE_TAG)\n\tdocker push $(DOCKER_LATEST_TAG)\n"
  },
  {
    "path": "Procfile",
    "content": "web: pgweb --url=$DATABASE_URL --listen=$PORT --bind=0.0.0.0 --auth-user=$AUTH_USER --auth-pass=$AUTH_PASS\n"
  },
  {
    "path": "README.md",
    "content": "# pgweb\n\nSimple web-based and cross platform PostgreSQL database explorer.\n\n[![Release](https://img.shields.io/github/release/sosedoff/pgweb.svg?label=Release)](https://github.com/sosedoff/pgweb/releases)\n[![Linux Build](https://github.com/sosedoff/pgweb/actions/workflows/checks.yml/badge.svg)](https://github.com/sosedoff/pgweb/actions?query=branch%3Amain)\n[![Go Report Card](https://goreportcard.com/badge/github.com/sosedoff/pgweb)](https://goreportcard.com/report/github.com/sosedoff/pgweb)\n[![GoDoc](https://godoc.org/github.com/sosedoff/pgweb?status.svg)](https://godoc.org/github.com/sosedoff/pgweb)\n[![Docker Pulls](https://img.shields.io/docker/pulls/sosedoff/pgweb.svg)](https://hub.docker.com/r/sosedoff/pgweb/)\n\n## Overview\n\nPgweb is a web-based database explorer for PostgreSQL, written in Go, and works\non Mac, Linux and Windows machines. Distributed as a simple binary with zero dependencies.\nVery easy to use and packs just the right amount of features.\n\n[See application screenshots](SCREENS.md)\n\n## Features\n\n- Cross-platform: Mac/Linux/Windows (64bit).\n- Simple installation (distributed as a single binary).\n- Zero dependencies.\n- Works with PostgreSQL 9.1+.\n- Supports native SSH tunnels.\n- Multiple database sessions.\n- Execute and analyze custom SQL queries.\n- Table and query data export to CSV/JSON/XML.\n- Query history.\n- Server bookmarks.\n\nVisit [WIKI](https://github.com/sosedoff/pgweb/wiki) for more details.\n\n## Demo\n\nVisit https://pgweb-demo.fly.dev/ to see Pgweb in action.\n\n## Installation\n\n- [Precompiled binaries](https://github.com/sosedoff/pgweb/releases) for supported operating systems are available.\n- [More installation options](https://github.com/sosedoff/pgweb/wiki/Installation)\n\n## Usage\n\nStart server:\n\n```\npgweb\n```\n\nYou can also provide connection flags:\n\n```\npgweb --host localhost --user myuser --db mydb\n```\n\nConnection URL scheme is also supported:\n\n```\npgweb --url postgres://user:password@host:port/database?sslmode=[mode]\npgweb --url \"postgres:///database?host=/absolute/path/to/unix/socket/dir\"\n```\n\n### Multiple database sessions\n\nTo enable multiple database sessions in pgweb, start the server with:\n\n```\npgweb --sessions\n```\n\nOr set environment variable:\n\n```\nPGWEB_SESSIONS=1 pgweb\n```\n\n## Testing\n\nBefore running tests, make sure you have PostgreSQL server running on `localhost:5432`\ninterface. Also, you must have `postgres` user that could create new databases\nin your local environment. Pgweb server should not be running at the same time.\n\nExecute test suite:\n\n```\nmake test\n```\n\nIf you're using Docker locally, you might also run pgweb test suite against\nall supported PostgreSQL version with a single command:\n\n```\nmake test-all\n```\n\n## Contribute\n\n- Fork this repository\n- Create a new feature branch for a new functionality or bugfix\n- Commit your changes\n- Execute test suite\n- Push your code and open a new pull request\n- Use [issues](https://github.com/sosedoff/pgweb/issues) for any questions\n- Check [wiki](https://github.com/sosedoff/pgweb/wiki) for extra documentation\n\n## License\n\nThe MIT License (MIT). See [LICENSE](LICENSE) file for more details.\n"
  },
  {
    "path": "SCREENS.md",
    "content": "# Screenshots\n\n### Connect\n<img src=\"screenshots/connect.png\" />\n\n### Browse table rows\n<img src=\"screenshots/browse.png\" />\n\n### Write SQL queries\n<img src=\"screenshots/query.png\" />"
  },
  {
    "path": "config/examples/connect_backend_go/README.md",
    "content": "# connect-backend-go\n\nExample Golang backend for Pgweb Connect feature\n\n## Usage\n\nRun the backend:\n\n```bash\ngo run main.go\n```\n\nConfigure pgweb:\n\n```bash\npgweb --sessions --connect-backend=http://localhost:4567 --connect-token=test\n```\n"
  },
  {
    "path": "config/examples/connect_backend_go/main.go",
    "content": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n)\n\ntype BackendRequest struct {\n\tResource string            `json:\"resource\"`\n\tToken    string            `json:\"token\"`\n\tHeaders  map[string]string `json:\"headers\"`\n}\n\ntype BackendResponse struct {\n\tDatabaseURL string `json:\"database_url\"`\n}\n\nfunc main() {\n\tresources := map[string]string{\n\t\t\"id1\": \"postgres://localhost:5432/db1?sslmode=disable\",\n\t\t\"id2\": \"postgres://localhost:5432/db2?sslmode=disable\",\n\t\t\"id3\": \"postgres://localhost:5432/db3?sslmode=disable\",\n\t}\n\n\thttp.HandleFunc(\"/\", func(rw http.ResponseWriter, req *http.Request) {\n\t\tbackendReq := BackendRequest{}\n\n\t\tif err := json.NewDecoder(req.Body).Decode(&backendReq); err != nil {\n\t\t\trw.WriteHeader(400)\n\t\t\tfmt.Fprintf(rw, \"error while parsing request: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tres, ok := resources[backendReq.Resource]\n\t\tif !ok {\n\t\t\trw.WriteHeader(404)\n\t\t\treturn\n\t\t}\n\n\t\tresp := BackendResponse{\n\t\t\tDatabaseURL: res,\n\t\t}\n\n\t\tjson.NewEncoder(rw).Encode(resp)\n\t})\n\n\tif err := http.ListenAndServe(\":4567\", nil); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n"
  },
  {
    "path": "config/examples/connect_backend_ruby/Gemfile",
    "content": "source \"https://rubygems.org\"\n\ngem \"sinatra\"\ngem \"json\"\ngem \"puma\"\ngem \"rackup\"\n"
  },
  {
    "path": "config/examples/connect_backend_ruby/README.md",
    "content": "# connect-backend-ruby\n\nExample Ruby backend for Pgweb Connect feature\n\n## Usage\n\nInstall and run the backend:\n\n```bash\nbundle install\nruby main.rb\n```\n\nConfigure pgweb:\n\n```bash\npgweb --sessions --connect-backend=http://localhost:4567 --connect-token=test\n```\n"
  },
  {
    "path": "config/examples/connect_backend_ruby/config.ru",
    "content": "require \"bundler/setup\"\nrequire \"./main\"\n\nrun Sinatra::Application\n"
  },
  {
    "path": "config/examples/connect_backend_ruby/main.rb",
    "content": "require \"bundler/setup\"\nrequire \"sinatra\"\n\n# Authentication token\n$token = \"test\"\n\n# List of all available resources\n$resources = {\n  \"id1\" => \"postgres://localhost:5432/db1?sslmode=disable\",\n  \"id2\" => \"postgres://localhost:5432/db2?sslmode=disable\",\n  \"id3\" => \"postgres://localhost:5432/db3?sslmode=disable\"\n}\n\nhelpers do\n  def error(code, message)\n    halt(code, JSON.dump(error: message))\n  end\nend\n\nbefore do\n  content_type :json\nend\n\npost \"/\" do\n  req = JSON.load(request.body) || {}\n\n  unless req[\"resource\"]\n    halt 404, \"Resource ID required\"\n  end\n\n  # Check the resource\n  resource = $resources[req[\"resource\"]]\n  if !resource\n    halt 404, \"Invalid resource ID\"\n  end\n\n  # Return connection credentials\n  JSON.dump(\n    database_url: resource\n  )\nend\n"
  },
  {
    "path": "config/pgweb.freebsd_rc",
    "content": "#!/bin/sh\n#\n# $FreeBSD: $\n#\n# PROVIDE: pgweb\n# REQUIRE: NETWORKING\n# KEYWORD:\n#\n# Add the following lines to /etc/rc.conf to enable pgweb:\n# pgweb_enable=\"YES\"\n#\n# pgweb_enable (bool):              Set to YES to enable pgweb\n#                                       Default: NO\n# pgweb_bind (str):               HTTP server host\n#                                       Default: localhost\n# pgweb_listen (str):   HTTP server listen port\n#                                       Default: 8081\n# pgweb_user (str):         pgweb daemon user\n#                                       Default: www\n# pgweb_group (str):                pgweb daemon group\n#                                       Default: www\n\n. /etc/rc.subr\n\nname=\"pgweb\"\nrcvar=\"pgweb_enable\"\nload_rc_config $name\n\n: ${pgweb_user:=\"www\"}\n: ${pgweb_group:=\"www\"}\n: ${pgweb_enable:=\"NO\"}\n: ${pgweb_bind:=\"localhost\"}\n: ${pgweb_flags=\"\"}\n: ${pgweb_facility:=\"daemon\"}\n: ${pgweb_priority:=\"debug\"}\n: ${pgweb_listen:=\"8081\"}\n\nprocname=\"/usr/local/bin/${name}\"\npidfile=\"/var/run/${name}.pid\"\nstart_precmd=\"${name}_precmd\"\ncommand=/usr/sbin/daemon\ncommand_args=\"-S -l ${pgweb_facility} -s ${pgweb_priority} -T ${name} -t ${name} -p ${pidfile} \\\n        ${procname} --bind=${pgweb_bind} --listen=${pgweb_listen} ${pgweb_flags}\"\n\npgweb_precmd()\n{\n        install -o ${pgweb_user} /dev/null ${pidfile}\n}\n\nrun_rc_command \"$1\"\n"
  },
  {
    "path": "config/pgweb.service",
    "content": "[Unit]\nDescription=pgweb - Cross-platform client for PostgreSQL databases\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/usr/bin/pgweb --bind=0.0.0.0 --listen=8081\nRestart=on-abort\n\n[Install]\nWantedBy=multi-user.target\n"
  },
  {
    "path": "config/pgweb_initd.conf",
    "content": "#!/bin/sh\n### BEGIN INIT INFO\n# Provides:          pgweb\n# Required-Start:    $remote_fs $syslog\n# Required-Stop:     $remote_fs $syslog\n# Default-Start:     2 3 4 5\n# Default-Stop:      0 1 6\n# Short-Description: Start daemon at boot time\n# Description:       Enable service provided by daemon.\n### END INIT INFO\n\n# Installation instructions (originally written for Debian)\n#\n# Save this script into /etc/init.d/pgweb file, make it executable,\n# and install it into the boot sequence:\n#\n#    chmod 755 /etc/init.d/pgweb\n#    update-rc.d pgweb defaults\n# \n# This script assumes that pgweb binary is located at /home/pgweb/, and that\n# there's a bookmark 'server' in /home/pgweb/.pgweb/bookmarks/.\n#\n\nNAME=\"pgweb\"\nPIDFILE=\"/var/run/$NAME.pid\"\n\nUSER=\"pgweb\"  # Linux system user\nSU=\"su $USER -s /bin/bash\"\n\nTIMEOUT=5  # Time in seconds to wait postgresql to show up\n\ncase \"$1\" in\n  start)\n    if [ -f $PIDFILE ]; then\n        echo \"Already running... cat $PIDFILE\"\n        exit 0\n    fi\n    \n    # Wait postgresql to show up\n    while ! test -f /var/run/postgresql/*main.pid\n    do\n        sleep 1\n        TIMEOUT=`expr $TIMEOUT - 1`\n        if test $TIMEOUT -eq 0; then\n            exit 1\n        fi\n    done\n    \n    # Ready to start pgweb\n    PID=`$SU -c '/home/pgweb/pgweb -s -b server >/dev/null & echo $!'`  # Note! Logs are lost.\n    if [ -z $PID ]; then\n        exit 1\n    else\n        echo $PID > $PIDFILE\n    fi\n    ;;\n  stop)\n    PID=`cat $PIDFILE`\n    kill $PID && rm $PIDFILE\n    ;;\n  *)\n    echo \"Usage: /etc/init.d/$NAME {start|stop}\"\n    exit 1\n    ;;\nesac\n\nexit 0"
  },
  {
    "path": "config/pgweb_upstart.conf",
    "content": "description \"PgWeb as a Service for Ubuntu 14.04 With Upstart\"\n\nstart on runlevel [2345]\nstop on runlevel [!2345]\n\nrespawn\nsetuid youruser\nsetgid www-data\n\nexec /usr/bin/pgweb --bind=0.0.0.0 --listen=8081\n"
  },
  {
    "path": "data/bookmark.toml",
    "content": "host = \"localhost\"\nport = 5432\nuser = \"postgres\"\ndatabase = \"mydatabase\"\nssl = \"disable\"\n"
  },
  {
    "path": "data/bookmark_invalid_ssl.toml",
    "content": "host = \"localhost\"\nport = 5432\nuser = \"postgres\"\ndatabase = \"mydatabase\"\nssl = \"disabled\"\n"
  },
  {
    "path": "data/bookmark_url.toml",
    "content": "url = \"postgres://username:password@host:port/database?sslmode=disable\"\n"
  },
  {
    "path": "data/bookmark_with_ssh.toml",
    "content": "host = \"localhost\"\nport = 5432\nuser = \"postgres\"\ndatabase = \"mydatabase\"\nssl = \"disable\"\n\n[SSH]\nhost = \"ssh-host\"\nuser = \"ssh-user\"\npassword = \"ssh-password\"\nkey = \"/path/to/key-file\"\nkeypassword = \"key-file-password\"\n"
  },
  {
    "path": "data/booktown.sql",
    "content": "--\n-- Selected TOC Entries:\n--\n--\n-- TOC Entry ID 1 (OID 0)\n--\n-- Name: booktown Type: DATABASE Owner: postgres\n--\n\nDROP DATABASE IF EXISTS \"booktown\";\nCREATE DATABASE \"booktown\";\n\n-- \\connect booktown postgres\n--\n-- TOC Entry ID 2 (OID 2991542)\n--\n-- Name: DATABASE \"booktown\" Type: COMMENT Owner: \n--\n\nCREATE TABLE \"dummies\" (\n  \"id\" integer NOT NULL,\n  \"isDummy\" boolean\n);\n\nINSERT INTO \"dummies\" VALUES (1, true);\nINSERT INTO \"dummies\" VALUES (2, true);\n\n\nCOMMENT ON DATABASE \"booktown\" IS 'The Book Town Database.';\n\n--\n-- TOC Entry ID 33 (OID 3629264)\n--\n-- Name: books Type: TABLE Owner: manager\n--\n\nCREATE TABLE \"books\" (\n\t\"id\" integer NOT NULL,\n\t\"title\" text NOT NULL,\n\t\"author_id\" integer,\n\t\"subject_id\" integer,\n\tConstraint \"books_id_pkey\" Primary Key (\"id\")\n);\n\n--\n-- TOC Entry ID 47 (OID 2991733)\n--\n-- Name: \"plpgsql_call_handler\" () Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"plpgsql_call_handler\" () RETURNS opaque AS '/usr/local/pgsql/lib/plpgsql.so', 'plpgsql_call_handler' LANGUAGE 'C';\n\n--\n-- TOC Entry ID 48 (OID 2991734)\n--\n-- Name: plpgsql Type: PROCEDURAL LANGUAGE Owner: \n--\n\nCREATE TRUSTED PROCEDURAL LANGUAGE 'plpgsql' HANDLER \"plpgsql_call_handler\" LANCOMPILER 'PL/pgSQL';\n\n--\n-- TOC Entry ID 51 (OID 2991735)\n--\n-- Name: \"audit_bk\" (integer) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"audit_bk\" (integer) RETURNS integer AS '\n\tDECLARE\n\t key ALIAS FOR $1;\n\ttable_data inventory%ROWTYPE;\n  BEGIN\n\tINSERT INTO inventory_audit SELECT table_data WHERE sort_key=key;\n\t\n\tIF NOT FOUND THEN\n\t  RAISE EXCEPTION ''View'' || key || '' not found '';\n\tEND IF;\n\t\n\treturn 1;\nend;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 52 (OID 2991736)\n--\n-- Name: \"audit\" (integer) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"audit\" (integer) RETURNS integer AS '\n\tDECLARE\n\t key ALIAS FOR $1;\n\ttable_data inventory%ROWTYPE;\n  BEGIN\n\tINSERT INTO inventory_audit SELECT table_data WHERE sort_key=key;\n\t\n\tIF NOT FOUND THEN\n\t  RAISE EXCEPTION ''View'' || key || '' not found '';\n\tEND IF;\n\t\n\treturn 1;\nend;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 53 (OID 2991737)\n--\n-- Name: \"auditbk\" () Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"auditbk\" () RETURNS integer AS '\n\tDECLARE\n\t key ALIAS FOR $1;\n\ttable_data inventory%ROWTYPE;\n  BEGIN\n\tINSERT INTO inventory_audit SELECT table_data WHERE sort_key=key;\n\t\n\tIF NOT FOUND THEN\n\t  RAISE EXCEPTION ''View'' || key || '' not found '';\n\tEND IF;\n\t\n\treturn 1;\nend;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 54 (OID 2991738)\n--\n-- Name: \"audit_bk1\" () Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"audit_bk1\" () RETURNS opaque AS '\n\tDECLARE\n\t key ALIAS FOR $1;\n\ttable_data inventory%ROWTYPE;\n  BEGIN\n\tINSERT INTO inventory_audit SELECT table_data WHERE sort_key=key;\n\t\n\tIF NOT FOUND THEN\n\t  RAISE EXCEPTION ''View'' || key || '' not found '';\n\tEND IF;\n\t\n\treturn 1;\nend;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 73 (OID 2991835)\n--\n-- Name: \"test_check_a_id\" () Type: FUNCTION Owner: example\n--\n\nCREATE FUNCTION \"test_check_a_id\" () RETURNS opaque AS '\n    BEGIN\n     -- checks to make sure the author id\n     -- inserted is not left blank or less than 100\n\n        IF NEW.a_id ISNULL THEN\n           RAISE EXCEPTION\n           ''The author id cannot be left blank!'';\n        ELSE\n           IF NEW.a_id < 100 THEN\n              RAISE EXCEPTION\n              ''Please insert a valid author id.'';\n           ELSE\n           RETURN NEW;\n           END IF;\n        END IF;\n    END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 66 (OID 2992619)\n--\n-- Name: \"audit_test\" () Type: FUNCTION Owner: example\n--\n\nCREATE FUNCTION \"audit_test\" () RETURNS opaque AS '\n    BEGIN   \n       \n      IF TG_OP = ''INSERT'' OR TG_OP = ''UPDATE'' THEN\n\n         NEW.user_aud := current_user;\n         NEW.mod_time := ''NOW'';\n\n        INSERT INTO inventory_audit SELECT * FROM inventory WHERE prod_id=NEW.prod_id;\n              \n      RETURN NEW; \n\n      ELSE if TG_OP = ''DELETE'' THEN\n        INSERT INTO inventory_audit SELECT *, current_user, ''NOW'' FROM inventory WHERE prod_id=OLD.prod_id;\n\n      RETURN OLD;\n      END IF;\n     END IF;\n    END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 67 (OID 3000878)\n--\n-- Name: \"first\" () Type: FUNCTION Owner: example\n--\n\nCREATE FUNCTION \"first\" () RETURNS integer AS ' \n       DecLarE\n        oNe IntEgER := 1;\n       bEGiN\n        ReTUrn oNE;       \n       eNd;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 68 (OID 3000881)\n--\n-- Name: \"test\" (integer) Type: FUNCTION Owner: example\n--\n\nCREATE FUNCTION \"test\" (integer) RETURNS integer AS '\n  \n DECLARE \n   -- defines the variable as ALIAS\n  variable ALIAS FOR $1;\n BEGIN\n  -- displays the variable after multiplying it by two \n  return variable * 2.0;\n END; \n ' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 69 (OID 3000991)\n--\n-- Name: \"you_me\" (integer) Type: FUNCTION Owner: example\n--\n\nCREATE FUNCTION \"you_me\" (integer) RETURNS integer AS '\n  DECLARE\n   RENAME $1 TO user_no;\n    --you INTEGER := 5;\n  BEGIN\n    return user_no;\n  END;' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 62 (OID 3001136)\n--\n-- Name: \"count_by_two\" (integer) Type: FUNCTION Owner: example\n--\n\nCREATE FUNCTION \"count_by_two\" (integer) RETURNS integer AS '\n     DECLARE\n          userNum ALIAS FOR $1;\n          i integer;\n     BEGIN\n          i := 1;\n          WHILE userNum[1] < 20 LOOP\n                i = i+1; \n                return userNum;              \n          END LOOP;\n          \n     END;\n   ' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 63 (OID 3001139)\n--\n-- Name: \"me\" () Type: FUNCTION Owner: example\n--\n\nCREATE FUNCTION \"me\" () RETURNS text AS '\n  DECLARE\n     you text := ''testing'';\n     RENAME you to me;\n  BEGIN\n     return me;\n  END;' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 64 (OID 3001149)\n--\n-- Name: \"display_cust\" (integer) Type: FUNCTION Owner: example\n--\n\nCREATE FUNCTION \"display_cust\" (integer) RETURNS text AS '\n DECLARE\n   -- declares an alias name for input\n   cust_num ALIAS FOR $1;\n\n   -- declares a row type\n   cust_info customer%ROWTYPE;\n BEGIN\n   -- puts information into the newly declared rowtype\n   SELECT into cust_info * \n     FROM customer \n    WHERE cust_id=cust_num;    \n\n   -- displays the customer lastname\n   -- extracted from the rowtype   \n   return cust_info.lastname;\n END;\n ' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 65 (OID 3001151)\n--\n-- Name: \"mixed\" () Type: FUNCTION Owner: example\n--\n\nCREATE FUNCTION \"mixed\" () RETURNS integer AS '\n       DecLarE\n          --assigns 1 to the oNe variable\n          oNe IntEgER \n          := 1;\n\n       bEGiN\n\n          --displays the value of oNe\n          ReTUrn oNe;       \n       eNd;\n       ' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 12 (OID 3117548)\n--\n-- Name: publishers Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"publishers\" (\n\t\"id\" integer NOT NULL,\n\t\"name\" text,\n\t\"address\" text,\n\tConstraint \"publishers_pkey\" Primary Key (\"id\")\n);\n\n--\n-- TOC Entry ID 55 (OID 3117729)\n--\n-- Name: \"compound_word\" (text,text) Type: FUNCTION Owner: example\n--\n\nCREATE FUNCTION \"compound_word\" (text,text) RETURNS text AS '\n     DECLARE\n       -- defines an alias name for the two input values\n       word1 ALIAS FOR $1;\n       word2 ALIAS FOR $2;\n     BEGIN\n       -- displays the resulting joined words\n       RETURN word1 || word2;\n     END;\n  ' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 56 (OID 3117787)\n--\n-- Name: \"givename\" () Type: FUNCTION Owner: example\n--\n\nCREATE FUNCTION \"givename\" () RETURNS opaque AS '\n DECLARE\n   tablename text;\n BEGIN\n   \n   tablename = TG_RELNAME; \n   INSERT INTO INVENTORY values (123, tablename);\n   return old;\n END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 14 (OID 3389594)\n--\n-- Name: authors Type: TABLE Owner: manager\n--\n\nCREATE TABLE \"authors\" (\n\t\"id\" integer NOT NULL,\n\t\"last_name\" text,\n\t\"first_name\" text,\n\tConstraint \"authors_pkey\" Primary Key (\"id\")\n);\n\n--\n-- TOC Entry ID 15 (OID 3389632)\n--\n-- Name: states Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"states\" (\n\t\"id\" integer NOT NULL,\n\t\"name\" text,\n\t\"abbreviation\" character(2),\n\tConstraint \"state_pkey\" Primary Key (\"id\")\n);\n\n--\n-- TOC Entry ID 16 (OID 3389702)\n--\n-- Name: my_list Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"my_list\" (\n\t\"todos\" text\n);\n\n--\n-- TOC Entry ID 17 (OID 3390348)\n--\n-- Name: stock Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"stock\" (\n\t\"isbn\" text NOT NULL,\n\t\"cost\" numeric(5,2),\n\t\"retail\" numeric(5,2),\n\t\"stock\" integer,\n\tConstraint \"stock_pkey\" Primary Key (\"isbn\")\n);\n\n--\n-- TOC Entry ID 4 (OID 3390416)\n--\n-- Name: subject_ids Type: SEQUENCE Owner: postgres\n--\n\nCREATE SEQUENCE \"subject_ids\" start 0 increment 1 maxvalue 2147483647 minvalue 0  cache 1 ;\n\n--\n-- TOC Entry ID 19 (OID 3390653)\n--\n-- Name: numeric_values Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"numeric_values\" (\n\t\"num\" numeric(30,6)\n);\n\n--\n-- TOC Entry ID 20 (OID 3390866)\n--\n-- Name: daily_inventory Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"daily_inventory\" (\n\t\"isbn\" text,\n\t\"is_stocked\" boolean\n);\n\n--\n-- TOC Entry ID 21 (OID 3391084)\n--\n-- Name: money_example Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"money_example\" (\n\t\"money_cash\" money,\n\t\"numeric_cash\" numeric(6,2)\n);\n\n--\n-- TOC Entry ID 22 (OID 3391184)\n--\n-- Name: shipments Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"shipments\" (\n\t\"id\" integer DEFAULT nextval('\"shipments_ship_id_seq\"'::text) NOT NULL,\n\t\"customer_id\" integer,\n\t\"isbn\" text,\n\t\"ship_date\" timestamp with time zone\n);\n\n--\n-- TOC Entry ID 24 (OID 3391454)\n--\n-- Name: customers Type: TABLE Owner: manager\n--\n\nCREATE TABLE \"customers\" (\n\t\"id\" integer NOT NULL,\n\t\"last_name\" text,\n\t\"first_name\" text,\n\tConstraint \"customers_pkey\" Primary Key (\"id\")\n);\n\n--\n-- TOC Entry ID 6 (OID 3574018)\n--\n-- Name: book_ids Type: SEQUENCE Owner: postgres\n--\n\nCREATE SEQUENCE \"book_ids\" start 0 increment 1 maxvalue 2147483647 minvalue 0  cache 1 ;\n\n--\n-- TOC Entry ID 26 (OID 3574043)\n--\n-- Name: book_queue Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"book_queue\" (\n\t\"title\" text NOT NULL,\n\t\"author_id\" integer,\n\t\"subject_id\" integer,\n\t\"approved\" boolean\n);\n\n--\n-- TOC Entry ID 78 (OID 3574403)\n--\n-- Name: \"title\" (integer) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"title\" (integer) RETURNS text AS 'SELECT title from books where id = $1' LANGUAGE 'sql';\n\n--\n-- TOC Entry ID 27 (OID 3574983)\n--\n-- Name: stock_backup Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"stock_backup\" (\n\t\"isbn\" text,\n\t\"cost\" numeric(5,2),\n\t\"retail\" numeric(5,2),\n\t\"stock\" integer\n);\n\n--\n-- TOC Entry ID 89 (OID 3625934)\n--\n-- Name: \"double_price\" (double precision) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"double_price\" (double precision) RETURNS double precision AS '\n  DECLARE\n  BEGIN\n    return $1 * 2;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 90 (OID 3625935)\n--\n-- Name: \"triple_price\" (double precision) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"triple_price\" (double precision) RETURNS double precision AS '\n  DECLARE\n     -- Declare input_price as an alias for the\n     -- argument variable normally referenced with\n     -- the $1 identifier.\n    input_price ALIAS FOR $1;\n \n  BEGIN\n     -- Return the input price multiplied by three.\n    RETURN input_price * 3;\n  END;\n ' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 87 (OID 3625944)\n--\n-- Name: \"stock_amount\" (integer,integer) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"stock_amount\" (integer,integer) RETURNS integer AS '\n  DECLARE\n     -- Declare aliases for function arguments.\n    b_id ALIAS FOR $1;\n    b_edition ALIAS FOR $2;\n     -- Declare variable to store the ISBN number.\n    b_isbn TEXT;\n     -- Declare variable to store the stock amount.\n    stock_amount INTEGER;\n  BEGIN\n     -- This SELECT INTO statement retrieves the ISBN\n     -- number of the row in the editions table that had\n     -- both the book ID number and edition number that\n     -- were provided as function arguments.\n    SELECT INTO b_isbn isbn FROM editions WHERE\n      book_id = b_id AND edition = b_edition;\n \n     -- Check to see if the ISBN number retrieved\n     -- is NULL.  This will happen if there is not an\n     -- existing book with both the ID number and edition\n     -- number specified in the function arguments.\n     -- If the ISBN is null, the function returns a\n     -- value of -1 and ends.\n    IF b_isbn IS NULL THEN\n      RETURN -1;\n    END IF;\n \n     -- Retrieve the amount of books available from the\n     -- stock table and record the number in the\n     -- stock_amount variable.\n    SELECT INTO stock_amount stock FROM stock WHERE isbn = b_isbn;\n \n     -- Return the amount of books available.\n    RETURN stock_amount;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 86 (OID 3625946)\n--\n-- Name: \"in_stock\" (integer,integer) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"in_stock\" (integer,integer) RETURNS boolean AS '\n  DECLARE\n    b_id ALIAS FOR $1;\n    b_edition ALIAS FOR $2;\n    b_isbn TEXT;\n    stock_amount INTEGER;\n  BEGIN\n     -- This SELECT INTO statement retrieves the ISBN\n     -- number of the row in the editions table that had\n     -- both the book ID number and edition number that\n     -- were provided as function arguments.\n    SELECT INTO b_isbn isbn FROM editions WHERE\n      book_id = b_id AND edition = b_edition;\n \n     -- Check to see if the ISBN number retrieved\n     -- is NULL.  This will happen if there is not an\n     -- existing book with both the ID number and edition\n     -- number specified in the function arguments.\n     -- If the ISBN is null, the function returns a\n     -- FALSE value and ends.\n    IF b_isbn IS NULL THEN\n      RETURN FALSE;\n    END IF;\n \n     -- Retrieve the amount of books available from the\n     -- stock table and record the number in the\n     -- stock_amount variable.\n    SELECT INTO stock_amount stock FROM stock WHERE isbn = b_isbn;\n \n     -- Use an IF/THEN/ELSE check to see if the amount\n     -- of books available is less than, or equal to 0.\n     -- If so, return FALSE.  If not, return TRUE.\n    IF stock_amount <= 0 THEN\n      RETURN FALSE;\n    ELSE\n      RETURN TRUE;\n    END IF;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 82 (OID 3626013)\n--\n-- Name: \"extract_all_titles\" () Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"extract_all_titles\" () RETURNS text AS '\n  DECLARE\n    sub_id INTEGER;\n    text_output TEXT = '' '';\n    sub_title TEXT;\n    row_data books%ROWTYPE;\n  BEGIN\n    FOR i IN 0..15 LOOP\n      SELECT INTO sub_title subject FROM subjects WHERE id = i;\n      text_output = text_output || ''\n'' || sub_title || '':\n'';\n\n      FOR row_data IN SELECT * FROM books\n        WHERE subject_id = i  LOOP\n\n        IF NOT FOUND THEN\n          text_output := text_output || ''None.\n'';\n        ELSE\n          text_output := text_output || row_data.title || ''\n'';\n        END IF;\n\n      END LOOP;\n    END LOOP;\n    RETURN text_output;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 79 (OID 3626052)\n--\n-- Name: \"books_by_subject\" (text) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"books_by_subject\" (text) RETURNS text AS '\n  DECLARE\n    sub_title ALIAS FOR $1;\n    sub_id INTEGER;\n    found_text TEXT :='''';\n  BEGIN\n      SELECT INTO sub_id id FROM subjects WHERE subject = sub_title;\n      RAISE NOTICE ''sub_id = %'',sub_id;\n      IF sub_title = ''all'' THEN\n        found_text := extract_all_titles();\n        RETURN found_text;\n      ELSE IF sub_id  >= 0 THEN\n          found_text := extract_title(sub_id);\n          RETURN  ''\n'' || sub_title || '':\n'' || found_text;\n        END IF;\n    END IF;\n    RETURN ''Subject not found.'';\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 81 (OID 3626590)\n--\n-- Name: \"add_two_loop\" (integer,integer) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"add_two_loop\" (integer,integer) RETURNS integer AS '\n  DECLARE\n \n     -- Declare aliases for function arguments.\n \n    low_number ALIAS FOR $1;\n    high_number ALIAS FOR $2;\n \n     -- Declare a variable to hold the result.\n \n    result INTEGER = 0;\n \n  BEGIN\n \n    WHILE result != high_number LOOP\n      result := result + 1;\n    END LOOP;\n \n    RETURN result;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 92 (OID 3627916)\n--\n-- Name: \"extract_all_titles2\" () Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"extract_all_titles2\" () RETURNS text AS '\n  DECLARE\n    sub_id INTEGER;\n    text_output TEXT = '' '';\n    sub_title TEXT;\n    row_data books%ROWTYPE;\n  BEGIN\n    FOR i IN 0..15 LOOP\n      SELECT INTO sub_title subject FROM subjects WHERE id = i;\n      text_output = text_output || ''\n'' || sub_title || '':\n'';\n\n      FOR row_data IN SELECT * FROM books\n        WHERE subject_id = i  LOOP\n\n        text_output := text_output || row_data.title || ''\n'';\n\n      END LOOP;\n    END LOOP;\n    RETURN text_output;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 94 (OID 3627974)\n--\n-- Name: \"extract_title\" (integer) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"extract_title\" (integer) RETURNS text AS '\n  DECLARE\n    sub_id ALIAS FOR $1;\n    text_output TEXT :=''\n'';\n    row_data RECORD;\n  BEGIN\n    FOR row_data IN SELECT * FROM books\n    WHERE subject_id = sub_id ORDER BY title  LOOP\n      text_output := text_output || row_data.title || ''\n'';\n    END LOOP;\n    RETURN text_output;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 95 (OID 3628021)\n--\n-- Name: \"raise_test\" () Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"raise_test\" () RETURNS integer AS '\n  DECLARE\n \n     -- Declare an integer variable for testing.\n \n    an_integer INTEGER = 1;\n \n  BEGIN\n \n     -- Raise a debug level message.\n \n    RAISE DEBUG ''The raise_test() function began.'';\n \n    an_integer = an_integer + 1;\n \n     -- Raise a notice stating that the an_integer\n     -- variable was changed, then raise another notice\n     -- stating its new value.\n \n    RAISE NOTICE ''Variable an_integer was changed.'';\n    RAISE NOTICE ''Variable an_integer value is now %.'',an_integer;\n \n     -- Raise an exception.\n \n    RAISE EXCEPTION ''Variable % changed.  Aborting transaction.'',an_integer;\n \n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 93 (OID 3628069)\n--\n-- Name: \"add_shipment\" (integer,text) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"add_shipment\" (integer,text) RETURNS timestamp with time zone AS '\n  DECLARE\n    customer_id ALIAS FOR $1;\n    isbn ALIAS FOR $2;\n    shipment_id INTEGER;\n    right_now timestamp;\n  BEGIN\n    right_now := ''now'';\n    SELECT INTO shipment_id id FROM shipments ORDER BY id DESC;\n    shipment_id := shipment_id + 1;\n    INSERT INTO shipments VALUES ( shipment_id, customer_id, isbn, right_now );\n    RETURN right_now;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 102 (OID 3628076)\n--\n-- Name: \"ship_item\" (text,text,text) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"ship_item\" (text,text,text) RETURNS integer AS '\n  DECLARE\n    l_name ALIAS FOR $1;\n    f_name ALIAS FOR $2;\n    book_isbn ALIAS FOR $3;\n    book_id INTEGER;\n    customer_id INTEGER;\n \n  BEGIN\n \n    SELECT INTO customer_id get_customer_id(l_name,f_name);\n \n    IF customer_id = -1 THEN\n      RETURN -1;\n    END IF;\n \n    SELECT INTO book_id book_id FROM editions WHERE isbn = book_isbn;\n \n    IF NOT FOUND THEN\n      RETURN -1;\n    END IF;\n \n    PERFORM add_shipment(customer_id,book_isbn);\n \n    RETURN 1;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 103 (OID 3628114)\n--\n-- Name: \"check_book_addition\" () Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"check_book_addition\" () RETURNS opaque AS '\n  DECLARE \n    id_number INTEGER;\n    book_isbn TEXT;\n  BEGIN\n\n    SELECT INTO id_number id FROM customers WHERE id = NEW.customer_id; \n\n    IF NOT FOUND THEN\n      RAISE EXCEPTION ''Invalid customer ID number.'';  \n    END IF;\n\n    SELECT INTO book_isbn isbn FROM editions WHERE isbn = NEW.isbn; \n\n    IF NOT FOUND THEN\n      RAISE EXCEPTION ''Invalid ISBN.''; \n    END IF; \n\n    UPDATE stock SET stock = stock -1 WHERE isbn = NEW.isbn; \n\n    RETURN NEW; \n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 28 (OID 3628246)\n--\n-- Name: stock_view Type: VIEW Owner: postgres\n--\n\nCREATE VIEW \"stock_view\" as SELECT stock.isbn, stock.retail, stock.stock FROM stock;\n\nCREATE MATERIALIZED VIEW \"m_stock_view\" as SELECT stock.isbn, stock.retail, stock.stock FROM stock;\n\n--\n-- TOC Entry ID 30 (OID 3628247)\n--\n-- Name: favorite_books Type: TABLE Owner: manager\n--\n\nCREATE TABLE \"favorite_books\" (\n\t\"employee_id\" integer,\n\t\"books\" text[]\n);\n\n--\n-- TOC Entry ID 8 (OID 3628626)\n--\n-- Name: shipments_ship_id_seq Type: SEQUENCE Owner: manager\n--\n\nCREATE SEQUENCE \"shipments_ship_id_seq\" start 0 increment 1 maxvalue 2147483647 minvalue 0  cache 1 ;\n\n--\n-- TOC Entry ID 74 (OID 3628648)\n--\n-- Name: \"check_shipment_addition\" () Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"check_shipment_addition\" () RETURNS opaque AS '\n  DECLARE\n     -- Declare a variable to hold the customer ID.\n    id_number INTEGER;\n \n     -- Declare a variable to hold the ISBN.\n    book_isbn TEXT;\n  BEGIN\n \n     -- If there is an ID number that matches the customer ID in\n     -- the new table, retrieve it from the customers table.\n    SELECT INTO id_number id FROM customers WHERE id = NEW.customer_id;\n \n     -- If there was no matching ID number, raise an exception.\n    IF NOT FOUND THEN\n      RAISE EXCEPTION ''Invalid customer ID number.'';\n    END IF;\n \n     -- If there is an ISBN that matches the ISBN specified in the\n     -- new table, retrieve it from the editions table.\n    SELECT INTO book_isbn isbn FROM editions WHERE isbn = NEW.isbn;\n \n     -- If there is no matching ISBN, raise an exception.\n    IF NOT FOUND THEN\n      RAISE EXCEPTION ''Invalid ISBN.'';\n    END IF;\n \n    -- If the previous checks succeeded, update the stock amount\n    -- for INSERT commands.\n    IF TG_OP = ''INSERT'' THEN\n       UPDATE stock SET stock = stock -1 WHERE isbn = NEW.isbn;\n    END IF;\n \n    RETURN NEW;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 31 (OID 3628899)\n--\n-- Name: employees Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"employees\" (\n\t\"id\" integer NOT NULL,\n\t\"last_name\" text NOT NULL,\n\t\"first_name\" text,\n\tCONSTRAINT \"employees_id\" CHECK ((id > 100)),\n\tConstraint \"employees_pkey\" Primary Key (\"id\")\n);\n\n--\n-- TOC Entry ID 32 (OID 3629174)\n--\n-- Name: editions Type: TABLE Owner: manager\n--\n\nCREATE TABLE \"editions\" (\n\t\"isbn\" text NOT NULL,\n\t\"book_id\" integer,\n\t\"edition\" integer,\n\t\"publisher_id\" integer,\n\t\"publication\" date,\n\t\"type\" character(1),\n\tCONSTRAINT \"integrity\" CHECK (((book_id NOTNULL) AND (edition NOTNULL))),\n\tConstraint \"pkey\" Primary Key (\"isbn\")\n);\n\n--\n-- TOC Entry ID 10 (OID 3629402)\n--\n-- Name: author_ids Type: SEQUENCE Owner: manager\n--\n\nCREATE SEQUENCE \"author_ids\" start 0 increment 1 maxvalue 2147483647 minvalue 0  cache 1 ;\n\n--\n-- TOC Entry ID 35 (OID 3629424)\n--\n-- Name: distinguished_authors Type: TABLE Owner: manager\n--\n\nCREATE TABLE \"distinguished_authors\" (\n\t\"award\" text\n)\nINHERITS (\"authors\");\n\n--\n-- TOC Entry ID 107 (OID 3726476)\n--\n-- Name: \"isbn_to_title\" (text) Type: FUNCTION Owner: manager\n--\n\nCREATE FUNCTION \"isbn_to_title\" (text) RETURNS text AS 'SELECT title FROM books\n                                 JOIN editions AS e (isbn, id)\n                                 USING (id)\n                                 WHERE isbn = $1' LANGUAGE 'sql';\n\n--\n-- TOC Entry ID 36 (OID 3727889)\n--\n-- Name: favorite_authors Type: TABLE Owner: manager\n--\n\nCREATE TABLE \"favorite_authors\" (\n\t\"employee_id\" integer,\n\t\"authors_and_titles\" text[]\n);\n\n--\n-- TOC Entry ID 99 (OID 3728728)\n--\n-- Name: \"get_customer_name\" (integer) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"get_customer_name\" (integer) RETURNS text AS '\n  DECLARE\n  \n    -- Declare aliases for user input.\n    customer_id ALIAS FOR $1;\n    \n    -- Declare variables to hold the customer name.\n    customer_fname TEXT;\n    customer_lname TEXT;\n  \n  BEGIN\n  \n    -- Retrieve the customer first and last name for the customer whose\n    -- ID matches the value supplied as a function argument.\n    SELECT INTO customer_fname, customer_lname \n                first_name, last_name FROM customers\n      WHERE id = customer_id;\n    \n    -- Return the name.\n    RETURN customer_fname || '' '' || customer_lname;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 100 (OID 3728729)\n--\n-- Name: \"get_customer_id\" (text,text) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"get_customer_id\" (text,text) RETURNS integer AS '\n  DECLARE\n \n    -- Declare aliases for user input.\n    l_name ALIAS FOR $1;\n    f_name ALIAS FOR $2;\n \n    -- Declare a variable to hold the customer ID number.\n    customer_id INTEGER;\n \n  BEGIN\n \n    -- Retrieve the customer ID number of the customer whose first and last\n    --  name match the values supplied as function arguments.\n    SELECT INTO customer_id id FROM customers\n      WHERE last_name = l_name AND first_name = f_name;\n \n    -- Return the ID number.\n    RETURN customer_id;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 101 (OID 3728730)\n--\n-- Name: \"get_author\" (text) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"get_author\" (text) RETURNS text AS '\n  DECLARE\n \n      -- Declare an alias for the function argument,\n      -- which should be the first name of an author.\n     f_name ALIAS FOR $1;\n \n       -- Declare a variable with the same type as\n       -- the last_name field of the authors table.\n     l_name authors.last_name%TYPE;\n \n  BEGIN\n \n      -- Retrieve the last name of an author from the\n      -- authors table whose first name matches the\n      -- argument received by the function, and\n      -- insert it into the l_name variable.\n     SELECT INTO l_name last_name FROM authors WHERE first_name = f_name;\n \n       -- Return the first name and last name, separated\n       -- by a space.\n     return f_name || '' '' || l_name;\n \n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 97 (OID 3728759)\n--\n-- Name: \"get_author\" (integer) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"get_author\" (integer) RETURNS text AS '\n  DECLARE\n \n    -- Declare an alias for the function argument,\n    -- which should be the id of the author.\n    author_id ALIAS FOR $1;\n \n    -- Declare a variable that uses the structure of\n    -- the authors table.\n    found_author authors%ROWTYPE;\n \n  BEGIN\n \n    -- Retrieve a row of author information for\n    -- the author whose id number matches\n    -- the argument received by the function.\n    SELECT INTO found_author * FROM authors WHERE id = author_id;\n \n    -- Return the first\n    RETURN found_author.first_name || '' '' || found_author.last_name;\n \n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 70 (OID 3743412)\n--\n-- Name: \"html_linebreaks\" (text) Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"html_linebreaks\" (text) RETURNS text AS '\n  DECLARE\n    formatted_string text := '''';\n  BEGIN\n    FOR i IN 0 .. length($1) LOOP\n      IF substr($1, i, 1) = ''\n'' THEN\n        formatted_string := formatted_string || ''<br>'';\n      ELSE\n        formatted_string := formatted_string || substr($1, i, 1);\n      END IF;\n    END LOOP;\n    RETURN formatted_string;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 37 (OID 3751599)\n--\n-- Name: text_sorting Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"text_sorting\" (\n\t\"letter\" character(1)\n);\n\n--\n-- TOC Entry ID 38 (OID 3751882)\n--\n-- Name: subjects Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"subjects\" (\n\t\"id\" integer NOT NULL,\n\t\"subject\" text,\n\t\"location\" text,\n\tConstraint \"subjects_pkey\" Primary Key (\"id\")\n);\n\n--\n-- TOC Entry ID 108 (OID 3751924)\n--\n-- Name: sum(text) Type: AGGREGATE Owner: postgres\n--\n\nCREATE AGGREGATE sum ( BASETYPE = text, SFUNC = textcat, STYPE = text, INITCOND = '' );\n\n--\n-- TOC Entry ID 39 (OID 3751975)\n--\n-- Name: alternate_stock Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"alternate_stock\" (\n\t\"isbn\" text,\n\t\"cost\" numeric(5,2),\n\t\"retail\" numeric(5,2),\n\t\"stock\" integer\n);\n\n--\n-- TOC Entry ID 40 (OID 3752020)\n--\n-- Name: book_backup Type: TABLE Owner: postgres\n--\n\nCREATE TABLE \"book_backup\" (\n\t\"id\" integer,\n\t\"title\" text,\n\t\"author_id\" integer,\n\t\"subject_id\" integer\n);\n\n--\n-- TOC Entry ID 80 (OID 3752102)\n--\n-- Name: \"sync_authors_and_books\" () Type: FUNCTION Owner: postgres\n--\n\nCREATE FUNCTION \"sync_authors_and_books\" () RETURNS opaque AS '\n  BEGIN\n    IF TG_OP = ''UPDATE'' THEN\n      UPDATE books SET author_id = new.id WHERE author_id = old.id; \n    END IF;\n    RETURN new;\n  END;\n' LANGUAGE 'plpgsql';\n\n--\n-- TOC Entry ID 41 (OID 4063343)\n--\n-- Name: schedules Type: TABLE Owner: postgres\n--\n \nCREATE TABLE \"schedules\" (\n        \"employee_id\" integer NOT NULL,\n        \"schedule\" text,\n        Constraint \"schedules_pkey\" Primary Key (\"employee_id\")\n);\n\n--\n-- TOC Entry ID 42 (OID 4063653)\n--\n-- Name: recent_shipments Type: VIEW Owner: postgres\n--\n\nCREATE VIEW \"recent_shipments\" as SELECT count(*) AS num_shipped, max(shipments.ship_date) AS max, b.title FROM ((shipments JOIN editions USING (isbn)) NATURAL JOIN books b(book_id)) GROUP BY b.title ORDER BY count(*) DESC;\n\n--\n-- Data for TOC Entry ID 112 (OID 3117548)\n--\n-- Name: publishers Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"publishers\"  FROM stdin;\n150\tKids Can Press\tKids Can Press, 29 Birch Ave. Toronto,�ON��M4V 1E2\n91\tHenry Holt & Company, Inc.\tHenry Holt & Company, Inc. 115 West 18th Street New York, NY 10011\n113\tO'Reilly & Associates\tO'Reilly & Associates, Inc. 101 Morris St, Sebastopol, CA 95472\n62\tWatson-Guptill Publications\t1515 Boradway, New York, NY 10036\n105\tNoonday Press\tFarrar Straus & Giroux Inc, 19 Union Square W, New York, NY 10003\n99\tAce Books\tThe Berkley Publishing Group, Penguin Putnam Inc, 375 Hudson St, New York, NY 10014\n101\tRoc\tPenguin Putnam Inc, 375 Hudson St, New York, NY 10014\n163\tMojo Press\tMojo Press, PO Box 1215, Dripping Springs, TX 78720\n171\tBooks of Wonder\tBooks of Wonder, 16 W. 18th St. New York, NY, 10011\n102\tPenguin\tPenguin Putnam Inc, 375 Hudson St, New York, NY 10014\n75\tDoubleday\tRandom House, Inc, 1540 Broadway, New York, NY 10036\n65\tHarperCollins\tHarperCollins Publishers, 10 E 53rd St, New York, NY 10022\n59\tRandom House\tRandom House, Inc, 1540 Broadway, New York, NY 10036\n\\.\n--\n-- Data for TOC Entry ID 113 (OID 3389594)\n--\n-- Name: authors Type: TABLE DATA Owner: manager\n--\n\n\nCOPY \"authors\"  FROM stdin;\n1111\tDenham\tAriel\n1212\tWorsley\tJohn\n15990\tBourgeois\tPaulette\n25041\tBianco\tMargery Williams\n16\tAlcott\tLouisa May\n4156\tKing\tStephen\n1866\tHerbert\tFrank\n1644\tHogarth\tBurne\n2031\tBrown\tMargaret Wise\n115\tPoe\tEdgar Allen\n7805\tLutz\tMark\n7806\tChristiansen\tTom\n1533\tBrautigan\tRichard\n1717\tBrite\tPoppy Z.\n2112\tGorey\tEdward\n2001\tClarke\tArthur C.\n1213\tBrookins\tAndrew\n\\.\n--\n-- Data for TOC Entry ID 114 (OID 3389632)\n--\n-- Name: states Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"states\"  FROM stdin;\n42\tWashington\tWA\n51\tOregon\tOR\n\\.\n--\n-- Data for TOC Entry ID 115 (OID 3389702)\n--\n-- Name: my_list Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"my_list\"  FROM stdin;\nPick up laundry.\nSend out bills.\nWrap up Grand Unifying Theory for publication.\n\\.\n--\n-- Data for TOC Entry ID 116 (OID 3390348)\n--\n-- Name: stock Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"stock\"  FROM stdin;\n0385121679\t29.00\t36.95\t65\n039480001X\t30.00\t32.95\t31\n0394900014\t23.00\t23.95\t0\n044100590X\t36.00\t45.95\t89\n0441172717\t17.00\t21.95\t77\n0451160916\t24.00\t28.95\t22\n0451198492\t36.00\t46.95\t0\n0451457994\t17.00\t22.95\t0\n0590445065\t23.00\t23.95\t10\n0679803335\t20.00\t24.95\t18\n0694003611\t25.00\t28.95\t50\n0760720002\t18.00\t23.95\t28\n0823015505\t26.00\t28.95\t16\n0929605942\t19.00\t21.95\t25\n1885418035\t23.00\t24.95\t77\n0394800753\t16.00\t16.95\t4\n\\.\n--\n-- Data for TOC Entry ID 117 (OID 3390653)\n--\n-- Name: numeric_values Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"numeric_values\"  FROM stdin;\n68719476736.000000\n68719476737.000000\n6871947673778.000000\n999999999999999999999999.999900\n999999999999999999999999.999999\n-999999999999999999999999.999999\n-100000000000000000000000.999999\n1.999999\n2.000000\n2.000000\n999999999999999999999999.999999\n999999999999999999999999.000000\n\\.\n--\n-- Data for TOC Entry ID 118 (OID 3390866)\n--\n-- Name: daily_inventory Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"daily_inventory\"  FROM stdin;\n039480001X\tt\n044100590X\tt\n0451198492\tf\n0394900014\tf\n0441172717\tt\n0451160916\tf\n0385121679\t\\N\n\\.\n--\n-- Data for TOC Entry ID 119 (OID 3391084)\n--\n-- Name: money_example Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"money_example\"  FROM stdin;\n$12.24\t12.24\n\\.\n--\n-- Data for TOC Entry ID 120 (OID 3391184)\n--\n-- Name: shipments Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"shipments\"  FROM stdin;\n375\t142\t039480001X\t2001-08-06 09:29:21-07\n323\t671\t0451160916\t2001-08-14 10:36:41-07\n998\t1045\t0590445065\t2001-08-12 12:09:47-07\n749\t172\t0694003611\t2001-08-11 10:52:34-07\n662\t655\t0679803335\t2001-08-09 07:30:07-07\n806\t1125\t0760720002\t2001-08-05 09:34:04-07\n102\t146\t0394900014\t2001-08-11 13:34:08-07\n813\t112\t0385121679\t2001-08-08 09:53:46-07\n652\t724\t1885418035\t2001-08-14 13:41:39-07\n599\t430\t0929605942\t2001-08-10 08:29:42-07\n969\t488\t0441172717\t2001-08-14 08:42:58-07\n433\t898\t044100590X\t2001-08-12 08:46:35-07\n660\t409\t0451457994\t2001-08-07 11:56:42-07\n310\t738\t0451198492\t2001-08-15 14:02:01-07\n510\t860\t0823015505\t2001-08-14 07:33:47-07\n997\t185\t039480001X\t2001-08-10 13:47:52-07\n999\t221\t0451160916\t2001-08-14 13:45:51-07\n56\t880\t0590445065\t2001-08-14 13:49:00-07\n72\t574\t0694003611\t2001-08-06 07:49:44-07\n146\t270\t039480001X\t2001-08-13 09:42:10-07\n981\t652\t0451160916\t2001-08-08 08:36:44-07\n95\t480\t0590445065\t2001-08-10 07:29:52-07\n593\t476\t0694003611\t2001-08-15 11:57:40-07\n977\t853\t0679803335\t2001-08-09 09:30:46-07\n117\t185\t0760720002\t2001-08-07 13:00:48-07\n406\t1123\t0394900014\t2001-08-13 09:47:04-07\n340\t1149\t0385121679\t2001-08-12 13:39:22-07\n871\t388\t1885418035\t2001-08-07 11:31:57-07\n1000\t221\t039480001X\t2001-09-14 16:46:32-07\n1001\t107\t039480001X\t2001-09-14 17:42:22-07\n754\t107\t0394800753\t2001-08-11 09:55:05-07\n458\t107\t0394800753\t2001-08-07 10:58:36-07\n189\t107\t0394800753\t2001-08-06 11:46:36-07\n720\t107\t0394800753\t2001-08-08 10:46:13-07\n1002\t107\t0394800753\t2001-09-22 11:23:28-07\n2\t107\t0394800753\t2001-09-22 20:58:56-07\n\\.\n--\n-- Data for TOC Entry ID 121 (OID 3391454)\n--\n-- Name: customers Type: TABLE DATA Owner: manager\n--\n\n\nCOPY \"customers\"  FROM stdin;\n107\tJackson\tAnnie\n112\tGould\tEd\n142\tAllen\tChad\n146\tWilliams\tJames\n172\tBrown\tRichard\n185\tMorrill\tEric\n221\tKing\tJenny\n270\tBollman\tJulie\n388\tMorrill\tRoyce\n409\tHolloway\tChristine\n430\tBlack\tJean\n476\tClark\tJames\n480\tThomas\tRich\n488\tYoung\tTrevor\n574\tBennett\tLaura\n652\tAnderson\tJonathan\n655\tOlson\tDave\n671\tBrown\tChuck\n723\tEisele\tDon\n724\tHolloway\tAdam\n738\tGould\tShirley\n830\tRobertson\tRoyce\n853\tBlack\tWendy\n860\tOwens\tTim\n880\tRobinson\tTammy\n898\tGerdes\tKate\n964\tGould\tRamon\n1045\tOwens\tJean\n1125\tBollman\tOwen\n1149\tBecker\tOwen\n1123\tCorner\tKathy\n\\.\n--\n-- Data for TOC Entry ID 122 (OID 3574043)\n--\n-- Name: book_queue Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"book_queue\"  FROM stdin;\nLearning Python\t7805\t4\tt\nPerl Cookbook\t7806\t4\tt\n\\.\n--\n-- Data for TOC Entry ID 123 (OID 3574983)\n--\n-- Name: stock_backup Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"stock_backup\"  FROM stdin;\n0385121679\t29.00\t36.95\t65\n039480001X\t30.00\t32.95\t31\n0394800753\t16.00\t16.95\t0\n0394900014\t23.00\t23.95\t0\n044100590X\t36.00\t45.95\t89\n0441172717\t17.00\t21.95\t77\n0451160916\t24.00\t28.95\t22\n0451198492\t36.00\t46.95\t0\n0451457994\t17.00\t22.95\t0\n0590445065\t23.00\t23.95\t10\n0679803335\t20.00\t24.95\t18\n0694003611\t25.00\t28.95\t50\n0760720002\t18.00\t23.95\t28\n0823015505\t26.00\t28.95\t16\n0929605942\t19.00\t21.95\t25\n1885418035\t23.00\t24.95\t77\n\\.\n--\n-- Data for TOC Entry ID 124 (OID 3628247)\n--\n-- Name: favorite_books Type: TABLE DATA Owner: manager\n--\n\n\nCOPY \"favorite_books\"  FROM stdin;\n102\t{\"The Hitchhiker's Guide to the Galaxy\",\"The Restauraunt at the End of the Universe\"}\n103\t{\"There and Back Again: A Hobbit's Holiday\",\"Kittens Squared\"}\n\\.\n--\n-- Data for TOC Entry ID 125 (OID 3628899)\n--\n-- Name: employees Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"employees\"  FROM stdin;\n101\tAppel\tVincent\n102\tHolloway\tMichael\n105\tConnoly\tSarah\n104\tNoble\tBen\n103\tJoble\tDavid\n106\tHall\tTimothy\n1008\tWilliams\t\\N\n\\.\n--\n-- Data for TOC Entry ID 126 (OID 3629174)\n--\n-- Name: editions Type: TABLE DATA Owner: manager\n--\n\n\nCOPY \"editions\"  FROM stdin;\n039480001X\t1608\t1\t59\t1957-03-01\th\n0451160916\t7808\t1\t75\t1981-08-01\tp\n0394800753\t1590\t1\t59\t1949-03-01\tp\n0590445065\t25908\t1\t150\t1987-03-01\tp\n0694003611\t1501\t1\t65\t1947-03-04\tp\n0679803335\t1234\t1\t102\t1922-01-01\tp\n0760720002\t190\t1\t91\t1868-01-01\tp\n0394900014\t1608\t1\t59\t1957-01-01\tp\n0385121679\t7808\t2\t75\t1993-10-01\th\n1885418035\t156\t1\t163\t1995-03-28\tp\n0929605942\t156\t2\t171\t1998-12-01\tp\n0441172717\t4513\t2\t99\t1998-09-01\tp\n044100590X\t4513\t3\t99\t1999-10-01\th\n0451457994\t4267\t3\t101\t2000-09-12\tp\n0451198492\t4267\t3\t101\t1999-10-01\th\n0823015505\t2038\t1\t62\t1958-01-01\tp\n0596000855\t41473\t2\t113\t2001-03-01\tp\n\\.\n--\n-- Data for TOC Entry ID 127 (OID 3629264)\n--\n-- Name: books Type: TABLE DATA Owner: manager\n--\n\n\nCOPY \"books\"  FROM stdin;\n7808\tThe Shining\t4156\t9\n4513\tDune\t1866\t15\n4267\t2001: A Space Odyssey\t2001\t15\n1608\tThe Cat in the Hat\t1809\t2\n1590\tBartholomew and the Oobleck\t1809\t2\n25908\tFranklin in the Dark\t15990\t2\n1501\tGoodnight Moon\t2031\t2\n190\tLittle Women\t16\t6\n1234\tThe Velveteen Rabbit\t25041\t3\n2038\tDynamic Anatomy\t1644\t0\n156\tThe Tell-Tale Heart\t115\t9\n41473\tProgramming Python\t7805\t4\n41477\tLearning Python\t7805\t4\n41478\tPerl Cookbook\t7806\t4\n41472\tPractical PostgreSQL\t1212\t4\n\\.\n--\n-- Data for TOC Entry ID 128 (OID 3629424)\n--\n-- Name: distinguished_authors Type: TABLE DATA Owner: manager\n--\n\n\nCOPY \"distinguished_authors\"  FROM stdin;\n25043\tSimon\tNeil\tPulitzer Prize\n1809\tGeisel\tTheodor Seuss\tPulitzer Prize\n\\.\n--\n-- Data for TOC Entry ID 129 (OID 3727889)\n--\n-- Name: favorite_authors Type: TABLE DATA Owner: manager\n--\n\n\nCOPY \"favorite_authors\"  FROM stdin;\n102\t{{\"J.R.R. Tolkien\",\"The Silmarillion\"},{\"Charles Dickens\",\"Great Expectations\"},{\"Ariel Denham\",\"Attic Lives\"}}\n\\.\n--\n-- Data for TOC Entry ID 130 (OID 3751599)\n--\n-- Name: text_sorting Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"text_sorting\"  FROM stdin;\n0\n1\n2\n3\nA\nB\nC\nD\na\nb\nc\nd\n\\.\n--\n-- Data for TOC Entry ID 131 (OID 3751882)\n--\n-- Name: subjects Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"subjects\"  FROM stdin;\n0\tArts\tCreativity St\n1\tBusiness\tProductivity Ave\n2\tChildren's Books\tKids Ct\n3\tClassics\tAcademic Rd\n4\tComputers\tProductivity Ave\n5\tCooking\tCreativity St\n6\tDrama\tMain St\n7\tEntertainment\tMain St\n8\tHistory\tAcademic Rd\n9\tHorror\tBlack Raven Dr\n10\tMystery\tBlack Raven Dr\n11\tPoetry\tSunset Dr\n12\tReligion\t\\N\n13\tRomance\tMain St\n14\tScience\tProductivity Ave\n15\tScience Fiction\tMain St\n\\.\n--\n-- Data for TOC Entry ID 132 (OID 3751975)\n--\n-- Name: alternate_stock Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"alternate_stock\"  FROM stdin;\n0385121679\t29.00\t36.95\t65\n039480001X\t30.00\t32.95\t31\n0394900014\t23.00\t23.95\t0\n044100590X\t36.00\t45.95\t89\n0441172717\t17.00\t21.95\t77\n0451160916\t24.00\t28.95\t22\n0451198492\t36.00\t46.95\t0\n0451457994\t17.00\t22.95\t0\n0590445065\t23.00\t23.95\t10\n0679803335\t20.00\t24.95\t18\n0694003611\t25.00\t28.95\t50\n0760720002\t18.00\t23.95\t28\n0823015505\t26.00\t28.95\t16\n0929605942\t19.00\t21.95\t25\n1885418035\t23.00\t24.95\t77\n0394800753\t16.00\t16.95\t4\n\\.\n--\n-- Data for TOC Entry ID 133 (OID 3752020)\n--\n-- Name: book_backup Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"book_backup\"  FROM stdin;\n7808\tThe Shining\t4156\t9\n4513\tDune\t1866\t15\n4267\t2001: A Space Odyssey\t2001\t15\n1608\tThe Cat in the Hat\t1809\t2\n1590\tBartholomew and the Oobleck\t1809\t2\n25908\tFranklin in the Dark\t15990\t2\n1501\tGoodnight Moon\t2031\t2\n190\tLittle Women\t16\t6\n1234\tThe Velveteen Rabbit\t25041\t3\n2038\tDynamic Anatomy\t1644\t0\n156\tThe Tell-Tale Heart\t115\t9\n41472\tPractical PostgreSQL\t1212\t4\n41473\tProgramming Python\t7805\t4\n41477\tLearning Python\t7805\t4\n41478\tPerl Cookbook\t7806\t4\n7808\tThe Shining\t4156\t9\n4513\tDune\t1866\t15\n4267\t2001: A Space Odyssey\t2001\t15\n1608\tThe Cat in the Hat\t1809\t2\n1590\tBartholomew and the Oobleck\t1809\t2\n25908\tFranklin in the Dark\t15990\t2\n1501\tGoodnight Moon\t2031\t2\n190\tLittle Women\t16\t6\n1234\tThe Velveteen Rabbit\t25041\t3\n2038\tDynamic Anatomy\t1644\t0\n156\tThe Tell-Tale Heart\t115\t9\n41473\tProgramming Python\t7805\t4\n41477\tLearning Python\t7805\t4\n41478\tPerl Cookbook\t7806\t4\n41472\tPractical PostgreSQL\t1212\t4\n\\.\n--\n-- Data for TOC Entry ID 134 (OID 4063343)\n--\n-- Name: schedules Type: TABLE DATA Owner: postgres\n--\n\n\nCOPY \"schedules\"  FROM stdin;\n102\tMon - Fri, 9am - 5pm\n\\.\n--\n-- TOC Entry ID 45 (OID 3117548)\n--\n-- Name: \"unique_publisher_idx\" Type: INDEX Owner: postgres\n--\n\nCREATE UNIQUE INDEX \"unique_publisher_idx\" on \"publishers\" using btree ( \"name\" \"text_ops\" );\n\n--\n-- TOC Entry ID 43 (OID 3391184)\n--\n-- Name: \"shipments_ship_id_key\" Type: INDEX Owner: postgres\n--\n\nCREATE UNIQUE INDEX \"shipments_ship_id_key\" on \"shipments\" using btree ( \"id\" \"int4_ops\" );\n\n--\n-- TOC Entry ID 44 (OID 3629264)\n--\n-- Name: \"books_title_idx\" Type: INDEX Owner: manager\n--\n\nCREATE  INDEX \"books_title_idx\" on \"books\" using btree ( \"title\" \"text_ops\" );\n\n--\n-- TOC Entry ID 46 (OID 3751599)\n--\n-- Name: \"text_idx\" Type: INDEX Owner: postgres\n--\n\nCREATE  INDEX \"text_idx\" on \"text_sorting\" using btree ( \"letter\" \"bpchar_ops\" );\n\n--\n-- TOC Entry ID 136 (OID 3628649)\n--\n-- Name: check_shipment Type: TRIGGER Owner: postgres\n--\n\nCREATE TRIGGER \"check_shipment\" BEFORE INSERT OR UPDATE ON \"shipments\"  FOR EACH ROW EXECUTE PROCEDURE \"check_shipment_addition\" ();\n\n--\n-- TOC Entry ID 135 (OID 3752103)\n--\n-- Name: sync_authors_books Type: TRIGGER Owner: manager\n--\n\nCREATE TRIGGER \"sync_authors_books\" BEFORE UPDATE ON \"authors\"  FOR EACH ROW EXECUTE PROCEDURE \"sync_authors_and_books\" ();\n\n--\n-- TOC Entry ID 139 (OID 4063374)\n--\n-- Name: \"RI_ConstraintTrigger_4063373\" Type: TRIGGER Owner: postgres\n--\n\nCREATE CONSTRAINT TRIGGER \"valid_employee\" AFTER INSERT OR UPDATE ON \"schedules\"  FROM \"employees\" NOT DEFERRABLE INITIALLY IMMEDIATE FOR EACH ROW EXECUTE PROCEDURE \"RI_FKey_check_ins\" ('valid_employee', 'schedules', 'employees', 'FULL', 'employee_id', 'id');\n\n--\n-- TOC Entry ID 137 (OID 4063376)\n--\n-- Name: \"RI_ConstraintTrigger_4063375\" Type: TRIGGER Owner: postgres\n--\n\nCREATE CONSTRAINT TRIGGER \"valid_employee\" AFTER DELETE ON \"employees\"  FROM \"schedules\" NOT DEFERRABLE INITIALLY IMMEDIATE FOR EACH ROW EXECUTE PROCEDURE \"RI_FKey_noaction_del\" ('valid_employee', 'schedules', 'employees', 'FULL', 'employee_id', 'id');\n\n--\n-- TOC Entry ID 138 (OID 4063378)\n--\n-- Name: \"RI_ConstraintTrigger_4063377\" Type: TRIGGER Owner: postgres\n--\n\nCREATE CONSTRAINT TRIGGER \"valid_employee\" AFTER UPDATE ON \"employees\"  FROM \"schedules\" NOT DEFERRABLE INITIALLY IMMEDIATE FOR EACH ROW EXECUTE PROCEDURE \"RI_FKey_noaction_upd\" ('valid_employee', 'schedules', 'employees', 'FULL', 'employee_id', 'id');\n\n--\n-- TOC Entry ID 140 (OID 3752079)\n--\n-- Name: sync_stock_with_editions Type: RULE Owner: manager\n--\n\nCREATE RULE sync_stock_with_editions AS ON UPDATE TO editions DO UPDATE stock SET isbn = new.isbn WHERE (stock.isbn = old.isbn);\n--\n-- TOC Entry ID 5 (OID 3390416)\n--\n-- Name: subject_ids Type: SEQUENCE SET Owner: \n--\n\nSELECT setval ('\"subject_ids\"', 15, 't');\n\n--\n-- TOC Entry ID 7 (OID 3574018)\n--\n-- Name: book_ids Type: SEQUENCE SET Owner: \n--\n\nSELECT setval ('\"book_ids\"', 41478, 't');\n\n--\n-- TOC Entry ID 9 (OID 3628626)\n--\n-- Name: shipments_ship_id_seq Type: SEQUENCE SET Owner: \n--\n\nSELECT setval ('\"shipments_ship_id_seq\"', 1011, 't');\n\n--\n-- TOC Entry ID 11 (OID 3629402)\n--\n-- Name: author_ids Type: SEQUENCE SET Owner: \n--\n\nSELECT setval ('\"author_ids\"', 25044, 't');\n\n"
  },
  {
    "path": "data/invalid.toml",
    "content": "invalid encoding"
  },
  {
    "path": "data/lc_example1.sql",
    "content": "-- pgweb: host=\"localhost\"\nselect 'foo'\n"
  },
  {
    "path": "data/lc_example2.sql",
    "content": "-- pgweb: host=\"localhost\"\n-- some comment\n-- pgweb: user=\"foo\"\n\nselect 'foo'\n"
  },
  {
    "path": "data/lc_invalid_meta.sql",
    "content": "-- pgweb: host=\"localhost\" mode=\"foo\"\nselect 'foo'\n"
  },
  {
    "path": "data/lc_no_meta.sql",
    "content": "select 'foo'\n"
  },
  {
    "path": "data/passfile",
    "content": "localhost:5432:dbname:username:password\n127.0.0.1:5432:*:*:password2\n"
  },
  {
    "path": "data/roach.sql",
    "content": "DROP DATABASE IF EXISTS \"roach\";\nCREATE DATABASE \"roach\";\nUSE \"roach\";\n\nCREATE TABLE product_information (\n  product_id           INT PRIMARY KEY NOT NULL,\n  product_name         STRING(50) UNIQUE NOT NULL,\n  product_description  STRING(2000),\n  category_id          STRING(1) NOT NULL CHECK (category_id IN ('A','B','C')),\n  weight_class         INT,\n  warranty_period      INT CONSTRAINT valid_warranty CHECK (warranty_period BETWEEN 0 AND 24),\n  supplier_id          INT,\n  product_status       STRING(20),\n  list_price           DECIMAL(8,2),\n  min_price            DECIMAL(8,2),\n  catalog_url          STRING(50) UNIQUE,\n  date_added           DATE DEFAULT CURRENT_DATE(),\n  misc                 JSONB,     \n  CONSTRAINT price_check CHECK (list_price >= min_price),\n  INDEX date_added_idx (date_added),\n  INDEX supp_id_prod_status_idx (supplier_id, product_status),\n  INVERTED INDEX details (misc)\n);\n\nINSERT INTO product_information VALUES\n  (1, 'Product A', 'Text', 'A', NULL, 1),\n  (2, 'Product B', 'Text', 'B', NULL, 2),\n  (3, 'Product C', 'Text', 'C', NULL, 3);\n\nCREATE TABLE customers (\n  id INT PRIMARY KEY,\n  name STRING\n);\n\nCREATE TABLE orders (\n  id INT PRIMARY KEY,\n  customer_id INT REFERENCES customers(id) ON DELETE CASCADE\n);\n\nINSERT INTO customers VALUES (1, 'Lauren');\nINSERT INTO orders VALUES (1,1);\nDELETE FROM customers WHERE id = 1;\nSELECT * FROM orders;"
  },
  {
    "path": "docker-compose-pg.yml",
    "content": "---\nx-base: &base\n  environment: &env\n    POSTGRES_DB: pgweb\n    POSTGRES_PASSWORD: pgweb\n    POSTGRES_USER: pgweb\n  healthcheck:\n    test: pg_isready -U pgweb -h 127.0.0.1\n    interval: 5s\n\nservices:\n  postgres18:\n    <<: *base\n    image: postgres:18\n    ports:\n      - 5433:5432\n  postgres17:\n    <<: *base\n    image: postgres:17\n    ports:\n      - 5433:5432\n  postgres16:\n    <<: *base\n    image: postgres:16\n    ports:\n      - 5433:5432\n  postgres15:\n    <<: *base\n    image: postgres:15\n    ports:\n      - 5433:5432\n  postgres14:\n    <<: *base\n    image: postgres:14\n    ports:\n      - 5434:5432\n  postgres13:\n    <<: *base\n    image: postgres:13\n    ports:\n      - 5435:5432\n  postgres12:\n    <<: *base\n    image: postgres:12\n    ports:\n      - 5436:5432\n  postgres11:\n    <<: *base\n    image: postgres:11\n    ports:\n      - 5437:5432\n  postgres10:\n    <<: *base\n    image: postgres:10\n    ports:\n      - 5438:5432\n  postgres9.6:\n    <<: *base\n    image: postgres:9.6\n    ports:\n      - 5439:5432\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "---\nservices:\n  postgres:\n    container_name: pgweb-postgres\n    image: postgres:15\n    ports:\n      - 5433:5432\n    volumes:\n      - data:/var/lib/postgresql/data\n    environment:\n      POSTGRES_DB: pgweb\n      POSTGRES_PASSWORD: pgweb\n      POSTGRES_USER: pgweb\n    healthcheck:\n      test: pg_isready -U pgweb -h 127.0.0.1\n      interval: 5s\n    networks:\n      - pgweb\n\n  pgweb:\n    container_name: pgweb\n    image: sosedoff/pgweb:latest\n    build: .\n    environment:\n      PGWEB_DATABASE_URL: postgres://pgweb:pgweb@pgweb-postgres:5432/pgweb?sslmode=disable\n    ports:\n      - 8081:8081\n    networks:\n      - pgweb\n    depends_on:\n      postgres:\n        condition: service_healthy\n    healthcheck:\n      test: [\"CMD\", \"nc\", \"-vz\", \"127.0.0.1\", \"8081\"]\n      interval: 5s\n\nvolumes:\n  data:\n    name: pgweb_postgres\n\nnetworks:\n  pgweb:\n    name: pgweb\n"
  },
  {
    "path": "fly.toml",
    "content": "app = \"pgweb-demo\"\nkill_signal = \"SIGINT\"\nkill_timeout = 5\n\n[processes]\n  web = \"pgweb --sessions --bind=0.0.0.0 --metrics --idle-timeout=30\"\n\n[[services]]\n  http_checks = []\n  internal_port = 8081\n  processes = [\"web\"]\n  protocol = \"tcp\"\n  script_checks = []\n\n  [services.concurrency]\n    hard_limit = 25\n    soft_limit = 20\n    type = \"connections\"\n\n  [[services.ports]]\n    force_https = true\n    handlers = [\"http\"]\n    port = 80\n\n  [[services.ports]]\n    handlers = [\"tls\", \"http\"]\n    port = 443\n\n  [[services.tcp_checks]]\n    grace_period = \"1s\"\n    interval = \"15s\"\n    restart_limit = 0\n    timeout = \"2s\"\n\n[metrics]\n  port = 8081\n  path = \"/metrics\"\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/sosedoff/pgweb\n\ngo 1.25\n\ntoolchain go1.25.4\n\nrequire (\n\tgithub.com/BurntSushi/toml v1.1.0\n\tgithub.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5\n\tgithub.com/gin-gonic/gin v1.11.0\n\tgithub.com/jackc/pgpassfile v1.0.0\n\tgithub.com/jessevdk/go-flags v1.5.0\n\tgithub.com/jmoiron/sqlx v1.3.5\n\tgithub.com/lib/pq v1.10.5\n\tgithub.com/mitchellh/go-homedir v1.1.0\n\tgithub.com/mr-tron/base58 v1.2.0\n\tgithub.com/prometheus/client_golang v1.19.1\n\tgithub.com/sirupsen/logrus v1.9.1\n\tgithub.com/stretchr/testify v1.11.1\n\tgithub.com/tuvistavie/securerandom v0.0.0-20140719024926-15512123a948\n\tgolang.org/x/crypto v0.46.0\n)\n\nrequire (\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/bytedance/gopkg v0.1.3 // indirect\n\tgithub.com/bytedance/sonic v1.14.2 // indirect\n\tgithub.com/bytedance/sonic/loader v0.4.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.2.0 // indirect\n\tgithub.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect\n\tgithub.com/cloudwego/base64x v0.1.6 // indirect\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a // indirect\n\tgithub.com/gabriel-vasile/mimetype v1.4.12 // indirect\n\tgithub.com/gin-contrib/sse v1.1.0 // indirect\n\tgithub.com/go-playground/locales v0.14.1 // indirect\n\tgithub.com/go-playground/universal-translator v0.18.1 // indirect\n\tgithub.com/go-playground/validator/v10 v10.30.1 // indirect\n\tgithub.com/goccy/go-json v0.10.5 // indirect\n\tgithub.com/goccy/go-yaml v1.19.1 // indirect\n\tgithub.com/golang/protobuf v1.5.3 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/klauspost/cpuid/v2 v2.3.0 // indirect\n\tgithub.com/kr/pretty v0.3.1 // indirect\n\tgithub.com/leodido/go-urn v1.4.0 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.2 // indirect\n\tgithub.com/pelletier/go-toml/v2 v2.2.4 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/prometheus/client_model v0.5.0 // indirect\n\tgithub.com/prometheus/common v0.48.0 // indirect\n\tgithub.com/prometheus/procfs v0.12.0 // indirect\n\tgithub.com/quic-go/qpack v0.6.0 // indirect\n\tgithub.com/quic-go/quic-go v0.58.0 // indirect\n\tgithub.com/twitchyliquid64/golang-asm v0.15.1 // indirect\n\tgithub.com/ugorji/go/codec v1.3.1 // indirect\n\tgo.uber.org/mock v0.6.0 // indirect\n\tgolang.org/x/arch v0.23.0 // indirect\n\tgolang.org/x/mod v0.31.0 // indirect\n\tgolang.org/x/net v0.48.0 // indirect\n\tgolang.org/x/sync v0.19.0 // indirect\n\tgolang.org/x/sys v0.39.0 // indirect\n\tgolang.org/x/text v0.32.0 // indirect\n\tgolang.org/x/tools v0.40.0 // indirect\n\tgoogle.golang.org/protobuf v1.36.11 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=\ngithub.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=\ngithub.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5 h1:VauE2GcJNZFun2Och6tIT2zJZK1v6jxALQDA9BIji/E=\ngithub.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5/go.mod h1:gxOHeajFfvGQh/fxlC8oOKBe23xnnJTif00IFFbiT+o=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=\ngithub.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=\ngithub.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=\ngithub.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=\ngithub.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=\ngithub.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE=\ngithub.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980=\ngithub.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o=\ngithub.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=\ngithub.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=\ngithub.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=\ngithub.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=\ngithub.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=\ngithub.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=\ngithub.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a h1:saTgr5tMLFnmy/yg3qDTft4rE5DY2uJ/cCxCe3q0XTU=\ngithub.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a/go.mod h1:Bw9BbhOJVNR+t0jCqx2GC6zv0TGBsShs56Y3gfSCvl0=\ngithub.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=\ngithub.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=\ngithub.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=\ngithub.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=\ngithub.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=\ngithub.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=\ngithub.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=\ngithub.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=\ngithub.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=\ngithub.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=\ngithub.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=\ngithub.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=\ngithub.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=\ngithub.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=\ngithub.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=\ngithub.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=\ngithub.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=\ngithub.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=\ngithub.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=\ngithub.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=\ngithub.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=\ngithub.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=\ngithub.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=\ngithub.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=\ngithub.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=\ngithub.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=\ngithub.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=\ngithub.com/goccy/go-yaml v1.19.1 h1:3rG3+v8pkhRqoQ/88NYNMHYVGYztCOCIZ7UQhu7H+NE=\ngithub.com/goccy/go-yaml v1.19.1/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=\ngithub.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=\ngithub.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=\ngithub.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=\ngithub.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=\ngithub.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=\ngithub.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=\ngithub.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=\ngithub.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=\ngithub.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=\ngithub.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=\ngithub.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=\ngithub.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=\ngithub.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=\ngithub.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=\ngithub.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ=\ngithub.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=\ngithub.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=\ngithub.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=\ngithub.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=\ngithub.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=\ngithub.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=\ngithub.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=\ngithub.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=\ngithub.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=\ngithub.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=\ngithub.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=\ngithub.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=\ngithub.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=\ngithub.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=\ngithub.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=\ngithub.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=\ngithub.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=\ngithub.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=\ngithub.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=\ngithub.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI=\ngithub.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y=\ngithub.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=\ngithub.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=\ngithub.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=\ngithub.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=\ngithub.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=\ngithub.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=\ngithub.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=\ngithub.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=\ngithub.com/quic-go/quic-go v0.58.0 h1:ggY2pvZaVdB9EyojxL1p+5mptkuHyX5MOSv4dgWF4Ug=\ngithub.com/quic-go/quic-go v0.58.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=\ngithub.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=\ngithub.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=\ngithub.com/sirupsen/logrus v1.9.1 h1:Ou41VVR3nMWWmTiEUnj0OlsgOSCUFgsPAOl6jRIcVtQ=\ngithub.com/sirupsen/logrus v1.9.1/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=\ngithub.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/tuvistavie/securerandom v0.0.0-20140719024926-15512123a948 h1:yL0l/u242MzDP6D0B5vGC+wxm5WRY+alQZy+dJk3bFI=\ngithub.com/tuvistavie/securerandom v0.0.0-20140719024926-15512123a948/go.mod h1:a06d/M1pxWi51qiSrfGMHaEydtuXT06nha8N2aNQuXk=\ngithub.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=\ngithub.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=\ngithub.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=\ngithub.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=\ngithub.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=\ngithub.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=\ngo.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=\ngo.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=\ngolang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=\ngolang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=\ngolang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=\ngolang.org/x/arch v0.23.0 h1:lKF64A2jF6Zd8L0knGltUnegD62JMFBiCPBmQpToHhg=\ngolang.org/x/arch v0.23.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=\ngolang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=\ngolang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=\ngolang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=\ngolang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=\ngolang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=\ngolang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=\ngolang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=\ngolang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=\ngolang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=\ngolang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=\ngolang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=\ngolang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=\ngolang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=\ngolang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=\ngolang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=\ngolang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=\ngolang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=\ngoogle.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngoogle.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nrsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport (\n\t\"github.com/sosedoff/pgweb/pkg/cli\"\n)\n\nfunc main() {\n\tcli.Run()\n}\n"
  },
  {
    "path": "pkg/api/api.go",
    "content": "package api\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"net/http\"\n\tneturl \"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/tuvistavie/securerandom\"\n\n\t\"github.com/sosedoff/pgweb/pkg/bookmarks\"\n\t\"github.com/sosedoff/pgweb/pkg/client\"\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n\t\"github.com/sosedoff/pgweb/pkg/connect\"\n\t\"github.com/sosedoff/pgweb/pkg/connection\"\n\t\"github.com/sosedoff/pgweb/pkg/metrics\"\n\t\"github.com/sosedoff/pgweb/pkg/queries\"\n\t\"github.com/sosedoff/pgweb/pkg/shared\"\n\t\"github.com/sosedoff/pgweb/static\"\n)\n\nvar (\n\t// DbClient represents the active database connection in a single-session mode\n\tDbClient *client.Client\n\n\t// DbSessions represents the mapping for client connections\n\tDbSessions *SessionManager\n\n\t// QueryStore reads the SQL queries stores in the home directory\n\tQueryStore *queries.Store\n)\n\n// DB returns a database connection from the client context\nfunc DB(c *gin.Context) *client.Client {\n\tif command.Opts.Sessions {\n\t\treturn DbSessions.Get(getSessionId(c.Request))\n\t}\n\treturn DbClient\n}\n\n// setClient sets the database client connection for the sessions\nfunc setClient(c *gin.Context, newClient *client.Client) error {\n\tcurrentClient := DB(c)\n\tif currentClient != nil {\n\t\tcurrentClient.Close()\n\t}\n\n\tif !command.Opts.Sessions {\n\t\tDbClient = newClient\n\t\treturn nil\n\t}\n\n\tsid := getSessionId(c.Request)\n\tif sid == \"\" {\n\t\treturn errSessionRequired\n\t}\n\n\tDbSessions.Add(sid, newClient)\n\treturn nil\n}\n\n// GetHome renders the home page\nfunc GetHome(prefix string) http.Handler {\n\tif prefix != \"\" {\n\t\tprefix = \"/\" + prefix\n\t}\n\treturn http.StripPrefix(prefix, static.GetHandler())\n}\n\nfunc GetAssets(prefix string) http.Handler {\n\tif prefix != \"\" {\n\t\tprefix = \"/\" + prefix + \"static/\"\n\t} else {\n\t\tprefix = \"/static/\"\n\t}\n\treturn http.StripPrefix(prefix, static.GetHandler())\n}\n\n// GetSessions renders the number of active sessions\nfunc GetSessions(c *gin.Context) {\n\t// In debug mode endpoint will return a lot of sensitive information\n\t// like full database connection string and all query history.\n\tif command.Opts.Debug {\n\t\tsuccessResponse(c, DbSessions.Sessions())\n\t\treturn\n\t}\n\tsuccessResponse(c, gin.H{\"sessions\": DbSessions.Len()})\n}\n\n// ConnectWithBackend creates a new connection based on backend resource\nfunc ConnectWithBackend(c *gin.Context) {\n\tbackend := connect.NewBackend(command.Opts.ConnectBackend, command.Opts.ConnectToken)\n\tbackend.SetLogger(logger)\n\n\tif command.Opts.ConnectHeaders != \"\" {\n\t\tbackend.SetPassHeaders(strings.Split(command.Opts.ConnectHeaders, \",\"))\n\t}\n\n\tctx, cancel := context.WithTimeout(context.Background(), time.Second*10)\n\tdefer cancel()\n\n\t// Fetch connection credentials\n\tcred, err := backend.FetchCredential(ctx, c.Param(\"resource\"), c.Request.Header)\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\t// Make the new session\n\tsid, err := securerandom.Uuid()\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\tc.Request.Header.Add(\"x-session-id\", sid)\n\n\t// Connect to the database\n\tcl, err := client.NewFromUrl(cred.DatabaseURL, nil)\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\tcl.External = true\n\n\t// Finalize session seetup\n\t_, err = cl.Info()\n\tif err == nil {\n\t\terr = setClient(c, cl)\n\t}\n\tif err != nil {\n\t\tcl.Close()\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tredirectURI := fmt.Sprintf(\"/%s?session=%s\", command.Opts.Prefix, sid)\n\tc.Redirect(302, redirectURI)\n}\n\n// Connect creates a new client connection\nfunc Connect(c *gin.Context) {\n\tif command.Opts.LockSession {\n\t\tbadRequest(c, errSessionLocked)\n\t\treturn\n\t}\n\n\tvar (\n\t\tcl  *client.Client\n\t\terr error\n\t)\n\n\tif bookmarkID := c.Request.FormValue(\"bookmark_id\"); bookmarkID != \"\" {\n\t\tcl, err = ConnectWithBookmark(bookmarkID)\n\t} else if command.Opts.BookmarksOnly {\n\t\terr = errNotPermitted\n\t} else {\n\t\tcl, err = ConnectWithURL(c)\n\t}\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\terr = cl.Test()\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tinfo, err := cl.Info()\n\tif err == nil {\n\t\terr = setClient(c, cl)\n\t}\n\tif err != nil {\n\t\tcl.Close()\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tsuccessResponse(c, info.Format()[0])\n}\n\nfunc ConnectWithURL(c *gin.Context) (*client.Client, error) {\n\turl := c.Request.FormValue(\"url\")\n\tif url == \"\" {\n\t\treturn nil, errURLRequired\n\t}\n\n\turl, err := connection.FormatURL(command.Options{\n\t\tURL:      url,\n\t\tPassfile: command.Opts.Passfile,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar sshInfo *shared.SSHInfo\n\tif c.Request.FormValue(\"ssh\") != \"\" {\n\t\tsshInfo = parseSshInfo(c)\n\t}\n\n\treturn client.NewFromUrl(url, sshInfo)\n}\n\nfunc ConnectWithBookmark(id string) (*client.Client, error) {\n\tmanager := bookmarks.NewManager(command.Opts.BookmarksDir)\n\n\tbookmark, err := manager.Get(id)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn client.NewFromBookmark(bookmark)\n}\n\n// SwitchDb perform database switch for the client connection\nfunc SwitchDb(c *gin.Context) {\n\tif command.Opts.LockSession {\n\t\tbadRequest(c, errSessionLocked)\n\t\treturn\n\t}\n\n\tname := c.Request.URL.Query().Get(\"db\")\n\tif name == \"\" {\n\t\tname = c.Request.FormValue(\"db\")\n\t}\n\tif name == \"\" {\n\t\tbadRequest(c, errDatabaseNameRequired)\n\t\treturn\n\t}\n\n\tconn := DB(c)\n\tif conn == nil {\n\t\tbadRequest(c, errNotConnected)\n\t\treturn\n\t}\n\n\t// Do not allow switching databases for connections from third-party backends\n\tif conn.External {\n\t\tbadRequest(c, errSessionLocked)\n\t\treturn\n\t}\n\n\tcurrentURL, err := neturl.Parse(conn.ConnectionString)\n\tif err != nil {\n\t\tbadRequest(c, errInvalidConnString)\n\t\treturn\n\t}\n\tcurrentURL.Path = name\n\n\tcl, err := client.NewFromUrl(currentURL.String(), nil)\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\terr = cl.Test()\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tinfo, err := cl.Info()\n\tif err == nil {\n\t\terr = setClient(c, cl)\n\t}\n\tif err != nil {\n\t\tcl.Close()\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tconn.Close()\n\n\tsuccessResponse(c, info.Format()[0])\n}\n\n// Disconnect closes the current database connection\nfunc Disconnect(c *gin.Context) {\n\tif command.Opts.LockSession {\n\t\tbadRequest(c, errSessionLocked)\n\t\treturn\n\t}\n\n\tif command.Opts.Sessions {\n\t\tresult := DbSessions.Remove(getSessionId(c.Request))\n\t\tsuccessResponse(c, gin.H{\"success\": result})\n\t\treturn\n\t}\n\n\tconn := DB(c)\n\tif conn == nil {\n\t\tbadRequest(c, errNotConnected)\n\t\treturn\n\t}\n\n\terr := conn.Close()\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tDbClient = nil\n\tsuccessResponse(c, gin.H{\"success\": true})\n}\n\n// RunQuery executes the query\nfunc RunQuery(c *gin.Context) {\n\tquery := cleanQuery(c.Request.FormValue(\"query\"))\n\n\tif query == \"\" {\n\t\tbadRequest(c, errQueryRequired)\n\t\treturn\n\t}\n\n\tHandleQuery(query, c)\n}\n\n// ExplainQuery renders query explain plan\nfunc ExplainQuery(c *gin.Context) {\n\tquery := cleanQuery(c.Request.FormValue(\"query\"))\n\n\tif query == \"\" {\n\t\tbadRequest(c, errQueryRequired)\n\t\treturn\n\t}\n\n\tHandleQuery(fmt.Sprintf(\"EXPLAIN %s\", query), c)\n}\n\n// AnalyzeQuery renders query explain plan and analyze profile\nfunc AnalyzeQuery(c *gin.Context) {\n\tquery := cleanQuery(c.Request.FormValue(\"query\"))\n\n\tif query == \"\" {\n\t\tbadRequest(c, errQueryRequired)\n\t\treturn\n\t}\n\n\tHandleQuery(fmt.Sprintf(\"EXPLAIN ANALYZE %s\", query), c)\n}\n\n// GetDatabases renders a list of all databases on the server\nfunc GetDatabases(c *gin.Context) {\n\tif command.Opts.LockSession {\n\t\tserveResult(c, []string{}, nil)\n\t\treturn\n\t}\n\tconn := DB(c)\n\tif conn.External {\n\t\terrorResponse(c, 403, errNotPermitted)\n\t\treturn\n\t}\n\n\tnames, err := DB(c).Databases()\n\tserveResult(c, names, err)\n}\n\n// GetObjects renders a list of database objects\nfunc GetObjects(c *gin.Context) {\n\tresult, err := DB(c).Objects()\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\tsuccessResponse(c, client.ObjectsFromResult(result))\n}\n\n// GetSchemas renders list of available schemas\nfunc GetSchemas(c *gin.Context) {\n\tres, err := DB(c).Schemas()\n\tserveResult(c, res, err)\n}\n\n// GetTable renders table information\nfunc GetTable(c *gin.Context) {\n\tvar (\n\t\tres *client.Result\n\t\terr error\n\t)\n\n\tdb := DB(c)\n\ttableName := c.Params.ByName(\"table\")\n\n\tswitch c.Request.FormValue(\"type\") {\n\tcase client.ObjTypeMaterializedView:\n\t\tres, err = db.MaterializedView(tableName)\n\tcase client.ObjTypeFunction:\n\t\tres, err = db.Function(tableName)\n\tdefault:\n\t\tres, err = db.Table(tableName)\n\t}\n\n\tserveResult(c, res, err)\n}\n\n// GetTableRows renders table rows\nfunc GetTableRows(c *gin.Context) {\n\toffset, err := parseIntFormValue(c, \"offset\", 0)\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tlimit, err := parseIntFormValue(c, \"limit\", 100)\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\topts := client.RowsOptions{\n\t\tLimit:      limit,\n\t\tOffset:     offset,\n\t\tSortColumn: c.Request.FormValue(\"sort_column\"),\n\t\tSortOrder:  c.Request.FormValue(\"sort_order\"),\n\t\tWhere:      c.Request.FormValue(\"where\"),\n\t}\n\n\tres, err := DB(c).TableRows(c.Params.ByName(\"table\"), opts)\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tcountRes, err := DB(c).TableRowsCount(c.Params.ByName(\"table\"), opts)\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tnumFetch := int64(opts.Limit)\n\tnumOffset := int64(opts.Offset)\n\tnumRows := countRes.Rows[0][0].(int64)\n\tnumPages := numRows / numFetch\n\n\tif numPages*numFetch < numRows {\n\t\tnumPages++\n\t}\n\n\tres.Pagination = &client.Pagination{\n\t\tRows:    numRows,\n\t\tPage:    (numOffset / numFetch) + 1,\n\t\tPages:   numPages,\n\t\tPerPage: numFetch,\n\t}\n\n\tserveResult(c, res, err)\n}\n\n// GetTableInfo renders a selected table information\nfunc GetTableInfo(c *gin.Context) {\n\tres, err := DB(c).TableInfo(c.Params.ByName(\"table\"))\n\tif err == nil {\n\t\tsuccessResponse(c, res.Format()[0])\n\t} else {\n\t\tbadRequest(c, err)\n\t}\n}\n\n// GetHistory renders a list of recent queries\nfunc GetHistory(c *gin.Context) {\n\tsuccessResponse(c, DB(c).History)\n}\n\n// GetConnectionInfo renders information about current connection\nfunc GetConnectionInfo(c *gin.Context) {\n\tconn := DB(c)\n\n\tif err := conn.TestWithTimeout(5 * time.Second); err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tres, err := conn.Info()\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tinfo := res.Format()[0]\n\tinfo[\"session_lock\"] = command.Opts.LockSession\n\n\tsuccessResponse(c, info)\n}\n\n// GetServerSettings renders a list of all server settings\nfunc GetServerSettings(c *gin.Context) {\n\tres, err := DB(c).ServerSettings()\n\tserveResult(c, res, err)\n}\n\n// GetActivity renders a list of running queries\nfunc GetActivity(c *gin.Context) {\n\tres, err := DB(c).Activity()\n\tserveResult(c, res, err)\n}\n\n// GetTableIndexes renders a list of database table indexes\nfunc GetTableIndexes(c *gin.Context) {\n\tres, err := DB(c).TableIndexes(c.Params.ByName(\"table\"))\n\tserveResult(c, res, err)\n}\n\n// GetTableConstraints renders a list of database constraints\nfunc GetTableConstraints(c *gin.Context) {\n\tres, err := DB(c).TableConstraints(c.Params.ByName(\"table\"))\n\tserveResult(c, res, err)\n}\n\n// GetTablesStats renders data sizes and estimated rows for all tables in the database\nfunc GetTablesStats(c *gin.Context) {\n\tdb := DB(c)\n\n\tconnCtx, err := db.GetConnContext()\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tres, err := db.TablesStats()\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tformat := getQueryParam(c, \"format\")\n\tif format == \"\" {\n\t\tformat = \"json\"\n\t}\n\n\t// Save as attachment if exporting parameter is set\n\tif getQueryParam(c, \"export\") == \"true\" {\n\t\tts := time.Now().Format(time.DateOnly)\n\n\t\tfilename := fmt.Sprintf(\"pgweb-dbstats-%s-%s.%s\", connCtx.Database, ts, format)\n\t\tc.Writer.Header().Set(\"Content-disposition\", \"attachment;filename=\"+filename)\n\t}\n\n\tswitch format {\n\tcase \"json\":\n\t\tc.JSON(http.StatusOK, res)\n\tcase \"csv\":\n\t\tc.Data(http.StatusOK, \"text/csv\", res.CSV())\n\tcase \"xml\":\n\t\tc.XML(200, res)\n\tdefault:\n\t\tbadRequest(c, \"invalid format\")\n\t}\n}\n\n// HandleQuery runs the database query\nfunc HandleQuery(query string, c *gin.Context) {\n\tmetrics.IncrementQueriesCount()\n\n\trawQuery, err := base64.StdEncoding.DecodeString(desanitize64(query))\n\tif err == nil {\n\t\tquery = string(rawQuery)\n\t}\n\n\tresult, err := DB(c).Query(query)\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tformat := getQueryParam(c, \"format\")\n\tfilename := getQueryParam(c, \"filename\")\n\n\tif filename == \"\" {\n\t\tfilename = fmt.Sprintf(\"pgweb-%v.%v\", time.Now().Unix(), format)\n\t}\n\n\tif format != \"\" {\n\t\tc.Writer.Header().Set(\"Content-disposition\", \"attachment;filename=\"+filename)\n\t}\n\n\tswitch format {\n\tcase \"csv\":\n\t\tc.Data(200, \"text/csv\", result.CSV())\n\tcase \"json\":\n\t\tc.Data(200, \"application/json\", result.JSON())\n\tcase \"xml\":\n\t\tc.XML(200, result)\n\tdefault:\n\t\tc.JSON(200, result)\n\t}\n}\n\n// GetBookmarks renders the list of available bookmarks\nfunc GetBookmarks(c *gin.Context) {\n\tmanager := bookmarks.NewManager(command.Opts.BookmarksDir)\n\tids, err := manager.ListIDs()\n\tserveResult(c, ids, err)\n}\n\n// GetInfo renders the pgweb system information\nfunc GetInfo(c *gin.Context) {\n\tsuccessResponse(c, gin.H{\n\t\t\"app\": command.Info,\n\t\t\"features\": gin.H{\n\t\t\t\"session_lock\":   command.Opts.LockSession,\n\t\t\t\"query_timeout\":  command.Opts.QueryTimeout,\n\t\t\t\"local_queries\":  QueryStore != nil,\n\t\t\t\"bookmarks_only\": command.Opts.BookmarksOnly,\n\t\t},\n\t})\n}\n\n// DataExport performs database table export\nfunc DataExport(c *gin.Context) {\n\tdb := DB(c)\n\n\tinfo, err := db.Info()\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tdump := client.Dump{\n\t\tTable: strings.TrimSpace(c.Request.FormValue(\"table\")),\n\t}\n\n\t// Perform validation of pg_dump command availability and compatibility.\n\t// Must be done before the actual command is executed to display errors.\n\tif err := dump.Validate(db.ServerVersion()); err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tformattedInfo := info.Format()[0]\n\tfilename := formattedInfo[\"current_database\"].(string)\n\tif dump.Table != \"\" {\n\t\tfilename = filename + \"_\" + dump.Table\n\t}\n\n\tfilename = sanitizeFilename(filename)\n\tfilename = fmt.Sprintf(\"%s_%s\", filename, time.Now().Format(\"20060102_150405\"))\n\n\tc.Header(\n\t\t\"Content-Disposition\",\n\t\tfmt.Sprintf(`attachment; filename=\"%s.sql.gz\"`, filename),\n\t)\n\n\terr = dump.Export(c.Request.Context(), db.ConnectionString, c.Writer)\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"pg_dump command failed\")\n\t\tbadRequest(c, err)\n\t}\n}\n\n// GetFunction renders function information\nfunc GetFunction(c *gin.Context) {\n\tres, err := DB(c).Function(c.Param(\"id\"))\n\tserveResult(c, res, err)\n}\n\nfunc GetLocalQueries(c *gin.Context) {\n\tconnCtx, err := DB(c).GetConnContext()\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tstoreQueries, err := QueryStore.ReadAll()\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tqueries := []localQuery{}\n\tfor _, q := range storeQueries {\n\t\tif !q.IsPermitted(connCtx.Host, connCtx.User, connCtx.Database, connCtx.Mode) {\n\t\t\tcontinue\n\t\t}\n\n\t\tqueries = append(queries, localQuery{\n\t\t\tID:          q.ID,\n\t\t\tTitle:       q.Meta.Title,\n\t\t\tDescription: q.Meta.Description,\n\t\t\tQuery:       cleanQuery(q.Data),\n\t\t})\n\t}\n\n\tsuccessResponse(c, queries)\n}\n\nfunc RunLocalQuery(c *gin.Context) {\n\tquery, err := QueryStore.Read(c.Param(\"id\"))\n\tif err != nil {\n\t\tif err == queries.ErrQueryFileNotExist {\n\t\t\tquery = nil\n\t\t} else {\n\t\t\tbadRequest(c, err)\n\t\t\treturn\n\t\t}\n\t}\n\tif query == nil {\n\t\terrorResponse(c, 404, \"query not found\")\n\t\treturn\n\t}\n\n\tconnCtx, err := DB(c).GetConnContext()\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tif !query.IsPermitted(connCtx.Host, connCtx.User, connCtx.Database, connCtx.Mode) {\n\t\terrorResponse(c, 404, \"query not found\")\n\t\treturn\n\t}\n\n\tif c.Request.Method == http.MethodGet {\n\t\tsuccessResponse(c, localQuery{\n\t\t\tID:          query.ID,\n\t\t\tTitle:       query.Meta.Title,\n\t\t\tDescription: query.Meta.Description,\n\t\t\tQuery:       query.Data,\n\t\t})\n\t\treturn\n\t}\n\n\tstatement := cleanQuery(query.Data)\n\tif statement == \"\" {\n\t\tbadRequest(c, errQueryRequired)\n\t\treturn\n\t}\n\n\tHandleQuery(statement, c)\n}\n"
  },
  {
    "path": "pkg/api/api_test.go",
    "content": "package api\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc Test_assetContentType(t *testing.T) {\n\tsamples := map[string]string{\n\t\t\"foo.html\": \"text/html; charset=utf-8\",\n\t\t\"foo.css\":  \"text/css; charset=utf-8\",\n\t\t\"foo.js\":   \"application/javascript\",\n\t\t\"foo.icon\": \"image-x-icon\",\n\t\t\"foo.png\":  \"image/png\",\n\t\t\"foo.jpg\":  \"image/jpeg\",\n\t\t\"foo.gif\":  \"image/gif\",\n\t\t\"foo.eot\":  \"application/vnd.ms-fontobject\",\n\t\t\"foo.svg\":  \"image/svg+xml\",\n\t\t\"foo.foo\":  \"text/plain; charset=utf-8\",\n\t\t\"foo\":      \"text/plain; charset=utf-8\",\n\t}\n\n\talternatives := map[string]string{\n\t\t\"foo.js\": \"text/javascript; charset=utf-8\",\n\t}\n\n\tfor name, expected := range samples {\n\t\tif alternatives[name] == \"\" {\n\t\t\tassert.Equal(t, expected, assetContentType(name))\n\t\t\tcontinue\n\t\t}\n\n\t\tactual := assetContentType(name)\n\n\t\tif actual != expected && actual != alternatives[name] {\n\t\t\tt.Errorf(\"expected %v but got %v (alternative value failed)\", expected, actual)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "pkg/api/errors.go",
    "content": "package api\n\nimport (\n\t\"errors\"\n)\n\nvar (\n\terrNotConnected         = errors.New(\"Not connected\")\n\terrNotPermitted         = errors.New(\"Not permitted\")\n\terrInvalidConnString    = errors.New(\"Invalid connection string\")\n\terrSessionRequired      = errors.New(\"Session ID is required\")\n\terrSessionLocked        = errors.New(\"Session is locked\")\n\terrURLRequired          = errors.New(\"URL parameter is required\")\n\terrQueryRequired        = errors.New(\"Query parameter is required\")\n\terrDatabaseNameRequired = errors.New(\"Database name is required\")\n)\n"
  },
  {
    "path": "pkg/api/helpers.go",
    "content": "package api\n\nimport (\n\t\"fmt\"\n\t\"mime\"\n\t\"net/http\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/gin-gonic/gin\"\n\n\t\"github.com/sosedoff/pgweb/pkg/shared\"\n)\n\nvar (\n\t// Mime types definitions\n\textraMimeTypes = map[string]string{\n\t\t\".icon\": \"image-x-icon\",\n\t\t\".ttf\":  \"application/x-font-ttf\",\n\t\t\".woff\": \"application/x-font-woff\",\n\t\t\".eot\":  \"application/vnd.ms-fontobject\",\n\t\t\".svg\":  \"image/svg+xml\",\n\t\t\".html\": \"text/html; charset-utf-8\",\n\t}\n\n\t// Paths that dont require database connection\n\tallowedPaths = map[string]bool{\n\t\t\"/api/sessions\":  true,\n\t\t\"/api/info\":      true,\n\t\t\"/api/connect\":   true,\n\t\t\"/api/bookmarks\": true,\n\t\t\"/api/history\":   true,\n\t}\n\n\t// List of characters replaced by javascript code to make queries url-safe.\n\tbase64subs = map[string]string{\n\t\t\"-\": \"+\",\n\t\t\"_\": \"/\",\n\t\t\".\": \"=\",\n\t}\n\n\t// Regular expression to remove unwanted characters in filenames\n\tregexCleanFilename = regexp.MustCompile(`[^\\w]+`)\n)\n\ntype Error struct {\n\tMessage string `json:\"error\"`\n}\n\nfunc NewError(err error) Error {\n\treturn Error{err.Error()}\n}\n\n// Returns a clean query without any comment statements\nfunc cleanQuery(query string) string {\n\tlines := []string{}\n\n\tfor _, line := range strings.Split(query, \"\\n\") {\n\t\tline = strings.TrimSpace(line)\n\t\tif strings.HasPrefix(line, \"--\") {\n\t\t\tcontinue\n\t\t}\n\t\tlines = append(lines, line)\n\t}\n\n\treturn strings.TrimSpace(strings.Join(lines, \"\\n\"))\n}\n\nfunc desanitize64(query string) string {\n\t// Before feeding the string into decoded, we must \"reconstruct\" the base64 data.\n\t// Javascript replaces a few characters to be url-safe.\n\tfor olds, news := range base64subs {\n\t\tquery = strings.Replace(query, olds, news, -1)\n\t}\n\n\treturn query\n}\n\nfunc sanitizeFilename(str string) string {\n\tstr = strings.ReplaceAll(str, \".\", \"_\")\n\treturn regexCleanFilename.ReplaceAllString(str, \"\")\n}\n\nfunc getSessionId(req *http.Request) string {\n\tid := req.Header.Get(\"x-session-id\")\n\tif id == \"\" {\n\t\tid = req.URL.Query().Get(\"_session_id\")\n\t}\n\treturn id\n}\n\nfunc getQueryParam(c *gin.Context, name string) string {\n\tresult := \"\"\n\tq := c.Request.URL.Query()\n\n\tif len(q[name]) > 0 {\n\t\tresult = q[name][0]\n\t}\n\n\treturn result\n}\n\nfunc parseIntFormValue(c *gin.Context, name string, defValue int) (int, error) {\n\tval := c.Request.FormValue(name)\n\n\tif val == \"\" {\n\t\treturn defValue, nil\n\t}\n\n\tnum, err := strconv.Atoi(val)\n\tif err != nil {\n\t\treturn defValue, fmt.Errorf(\"%s must be a number\", name)\n\t}\n\n\tif num < 1 && defValue != 0 {\n\t\treturn defValue, fmt.Errorf(\"%s must be greater than 0\", name)\n\t}\n\n\treturn num, nil\n}\n\nfunc parseSshInfo(c *gin.Context) *shared.SSHInfo {\n\tinfo := shared.SSHInfo{\n\t\tHost:        c.Request.FormValue(\"ssh_host\"),\n\t\tPort:        c.Request.FormValue(\"ssh_port\"),\n\t\tUser:        c.Request.FormValue(\"ssh_user\"),\n\t\tPassword:    c.Request.FormValue(\"ssh_password\"),\n\t\tKey:         c.Request.FormValue(\"ssh_key\"),\n\t\tKeyPassword: c.Request.FormValue(\"ssh_key_password\"),\n\t}\n\n\tif info.Port == \"\" {\n\t\tinfo.Port = \"22\"\n\t}\n\n\treturn &info\n}\n\nfunc assetContentType(name string) string {\n\text := filepath.Ext(name)\n\tresult := mime.TypeByExtension(ext)\n\n\tif result == \"\" {\n\t\tresult = extraMimeTypes[ext]\n\t}\n\n\tif result == \"\" {\n\t\tresult = \"text/plain; charset=utf-8\"\n\t}\n\n\treturn result\n}\n\n// Send a query result to client\nfunc serveResult(c *gin.Context, result interface{}, err interface{}) {\n\tif err != nil {\n\t\tbadRequest(c, err)\n\t\treturn\n\t}\n\n\tsuccessResponse(c, result)\n}\n\n// Send successful response back to client\nfunc successResponse(c *gin.Context, data interface{}) {\n\tc.JSON(200, data)\n}\n\n// Send an error response back to client\nfunc errorResponse(c *gin.Context, status int, err interface{}) {\n\tvar message interface{}\n\n\tswitch v := err.(type) {\n\tcase error:\n\t\tmessage = v.Error()\n\tcase string:\n\t\tmessage = v\n\tdefault:\n\t\tmessage = v\n\t}\n\n\tc.AbortWithStatusJSON(status, gin.H{\"status\": status, \"error\": message})\n}\n\n// Send a bad request (http 400) back to client\nfunc badRequest(c *gin.Context, err interface{}) {\n\terrorResponse(c, 400, err)\n}\n"
  },
  {
    "path": "pkg/api/helpers_test.go",
    "content": "package api\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"testing\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc Test_desanitize64(t *testing.T) {\n\texamples := map[string]string{\n\t\t\"test\":        \"test\",\n\t\t\"test+test+\":  \"test-test-\",\n\t\t\"test/test/\":  \"test_test_\",\n\t\t\"test=test==\": \"test.test..\",\n\t}\n\n\tfor expected, example := range examples {\n\t\tassert.Equal(t, expected, desanitize64(example))\n\t}\n}\n\nfunc Test_cleanQuery(t *testing.T) {\n\tassert.Equal(t, \"a\\nb\\nc\", cleanQuery(\"a\\nb\\nc\"))\n\tassert.Equal(t, \"\", cleanQuery(\"--something\"))\n\tassert.Equal(t, \"test\", cleanQuery(\"--test\\ntest\\n   -- test\\n\"))\n}\n\nfunc Test_sanitizeFilename(t *testing.T) {\n\texamples := map[string]string{\n\t\t\"foo\":              \"foo\",\n\t\t\"fooBar\":           \"fooBar\",\n\t\t\"foo.bar\":          \"foo_bar\",\n\t\t`\"foo\".\"bar\"`:      \"foo_bar\",\n\t\t\"!@#$foo.&&*(&bar\": \"foo_bar\",\n\t}\n\n\tfor given, expected := range examples {\n\t\tt.Run(given, func(t *testing.T) {\n\t\t\tassert.Equal(t, expected, sanitizeFilename(given))\n\t\t})\n\t}\n}\n\nfunc Test_getSessionId(t *testing.T) {\n\treq := &http.Request{Header: http.Header{}}\n\treq.Header.Add(\"x-session-id\", \"token\")\n\tassert.Equal(t, \"token\", getSessionId(req))\n\n\treq = &http.Request{}\n\treq.URL, _ = url.Parse(\"http://foobar/?_session_id=token\")\n\tassert.Equal(t, \"token\", getSessionId(req))\n}\n\nfunc Test_serveResult(t *testing.T) {\n\tserver := gin.Default()\n\tserver.GET(\"/good\", func(c *gin.Context) {\n\t\tserveResult(c, gin.H{\"foo\": \"bar\"}, nil)\n\t})\n\tserver.GET(\"/bad\", func(c *gin.Context) {\n\t\tserveResult(c, nil, errors.New(\"message\"))\n\t})\n\tserver.GET(\"/nodata\", func(c *gin.Context) {\n\t\tserveResult(c, nil, nil)\n\t})\n\n\tw := httptest.NewRecorder()\n\treq, _ := http.NewRequest(\"GET\", \"/good\", nil)\n\tserver.ServeHTTP(w, req)\n\tassert.Equal(t, 200, w.Code)\n\tassert.Equal(t, `{\"foo\":\"bar\"}`, w.Body.String())\n\n\tw = httptest.NewRecorder()\n\treq, _ = http.NewRequest(\"GET\", \"/bad\", nil)\n\tserver.ServeHTTP(w, req)\n\tassert.Equal(t, 400, w.Code)\n\tassert.Equal(t, `{\"error\":\"message\",\"status\":400}`, w.Body.String())\n\n\tw = httptest.NewRecorder()\n\treq, _ = http.NewRequest(\"GET\", \"/nodata\", nil)\n\tserver.ServeHTTP(w, req)\n\tassert.Equal(t, 200, w.Code)\n\tassert.Equal(t, `null`, w.Body.String())\n}\n"
  },
  {
    "path": "pkg/api/logger.go",
    "content": "package api\n\nimport (\n\t\"net/http\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/sirupsen/logrus\"\n\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n)\n\nvar (\n\tlogger *logrus.Logger\n\n\treConnectToken = regexp.MustCompile(\"/connect/(.*)\")\n)\n\nfunc init() {\n\tif logger == nil {\n\t\tlogger = logrus.New()\n\t}\n}\n\n// TODO: Move this into server struct when it's ready\nfunc SetLogger(l *logrus.Logger) {\n\tlogger = l\n}\n\nfunc RequestLogger(logger *logrus.Logger) gin.HandlerFunc {\n\tdebug := logger.Level > logrus.InfoLevel\n\tlogForwardedUser := command.Opts.LogForwardedUser\n\n\treturn func(c *gin.Context) {\n\t\tstart := time.Now()\n\t\tpath := c.Request.URL.Path\n\n\t\t// Process request\n\t\tc.Next()\n\n\t\tif !debug {\n\t\t\t// Skip static assets logging\n\t\t\tif strings.Contains(path, \"/static/\") {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tpath = sanitizeLogPath(path)\n\t\t}\n\n\t\tstatus := c.Writer.Status()\n\t\tend := time.Now()\n\t\tlatency := end.Sub(start)\n\n\t\tfields := logrus.Fields{\n\t\t\t\"status\":      status,\n\t\t\t\"method\":      c.Request.Method,\n\t\t\t\"remote_addr\": c.ClientIP(),\n\t\t\t\"duration\":    latency.String(),\n\t\t\t\"duration_ms\": latency.Milliseconds(),\n\t\t\t\"path\":        path,\n\t\t}\n\n\t\tif reqID := getRequestID(c); reqID != \"\" {\n\t\t\tfields[\"id\"] = reqID\n\t\t}\n\n\t\tif logForwardedUser {\n\t\t\tif forwardedUser := c.GetHeader(\"X-Forwarded-User\"); forwardedUser != \"\" {\n\t\t\t\tfields[\"forwarded_user\"] = forwardedUser\n\t\t\t}\n\t\t\tif forwardedEmail := c.GetHeader(\"X-Forwarded-Email\"); forwardedEmail != \"\" {\n\t\t\t\tfields[\"forwarded_email\"] = forwardedEmail\n\t\t\t}\n\t\t}\n\n\t\tif err := c.Errors.Last(); err != nil {\n\t\t\tfields[\"error\"] = err.Error()\n\t\t}\n\n\t\t// Additional fields for debugging\n\t\tif debug {\n\t\t\tfields[\"raw_query\"] = c.Request.URL.RawQuery\n\n\t\t\tif c.Request.Method != http.MethodGet {\n\t\t\t\tfields[\"raw_form\"] = c.Request.Form\n\t\t\t}\n\t\t}\n\n\t\tentry := logger.WithFields(fields)\n\t\tmsg := \"http_request\"\n\n\t\tswitch {\n\t\tcase status >= http.StatusBadRequest && status < http.StatusInternalServerError:\n\t\t\tentry.Warn(msg)\n\t\tcase status >= http.StatusInternalServerError:\n\t\t\tentry.Error(msg)\n\t\tdefault:\n\t\t\tentry.Info(msg)\n\t\t}\n\t}\n}\n\nfunc sanitizeLogPath(str string) string {\n\treturn reConnectToken.ReplaceAllString(str, \"/connect/REDACTED\")\n}\n\nfunc getRequestID(c *gin.Context) string {\n\tid := c.GetHeader(\"x-request-id\")\n\tif id == \"\" {\n\t\tid = c.GetHeader(\"x-amzn-trace-id\")\n\t}\n\treturn id\n}\n"
  },
  {
    "path": "pkg/api/logger_test.go",
    "content": "package api\n\nimport (\n\t\"net/http\"\n\t\"testing\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc Test_getRequestID(t *testing.T) {\n\texamples := []struct {\n\t\theaders map[string]string\n\t\tresult  string\n\t}{\n\t\t{map[string]string{}, \"\"},\n\t\t{map[string]string{\"X-Request-ID\": \"foo\"}, \"foo\"},\n\t\t{map[string]string{\"x-request-id\": \"foo\"}, \"foo\"},\n\t\t{map[string]string{\"x-request-id\": \"foo\"}, \"foo\"},\n\t\t{map[string]string{\"x-request-id\": \"foo\", \"x-amzn-trace-id\": \"amz\"}, \"foo\"},\n\t}\n\n\tfor _, ex := range examples {\n\t\treq := &http.Request{Header: http.Header{}}\n\t\tfor k, v := range ex.headers {\n\t\t\treq.Header.Set(k, v)\n\t\t}\n\n\t\tassert.Equal(t, ex.result, getRequestID(&gin.Context{Request: req}))\n\t}\n}\n"
  },
  {
    "path": "pkg/api/middleware.go",
    "content": "package api\n\nimport (\n\t\"strings\"\n\n\t\"github.com/gin-gonic/gin\"\n\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n)\n\n// Middleware to check database connection status before running queries\nfunc dbCheckMiddleware() gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tpath := strings.Replace(c.Request.URL.Path, command.Opts.Prefix, \"\", -1)\n\n\t\t// Allow whitelisted paths\n\t\tif allowedPaths[path] {\n\t\t\tc.Next()\n\t\t\treturn\n\t\t}\n\n\t\t// Check if session exists in single-session mode\n\t\tif !command.Opts.Sessions {\n\t\t\tif DbClient == nil {\n\t\t\t\tbadRequest(c, errNotConnected)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tc.Next()\n\t\t\treturn\n\t\t}\n\n\t\t// Determine session ID from the client request\n\t\tsid := getSessionId(c.Request)\n\t\tif sid == \"\" {\n\t\t\tbadRequest(c, errSessionRequired)\n\t\t\treturn\n\t\t}\n\n\t\t// Determine the database connection handle for the session\n\t\tconn := DbSessions.Get(sid)\n\t\tif conn == nil {\n\t\t\tbadRequest(c, errNotConnected)\n\t\t\treturn\n\t\t}\n\n\t\tc.Next()\n\t}\n}\n\n// Middleware to inject CORS headers\nfunc corsMiddleware() gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tc.Header(\"Access-Control-Allow-Methods\", \"GET, POST, OPTIONS\")\n\t\tc.Header(\"Access-Control-Expose-Headers\", \"*\")\n\t\tc.Header(\"Access-Control-Allow-Origin\", command.Opts.CorsOrigin)\n\t}\n}\n\nfunc requireLocalQueries() gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tif QueryStore == nil {\n\t\t\tbadRequest(c, \"local queries are disabled\")\n\t\t\treturn\n\t\t}\n\n\t\tc.Next()\n\t}\n}\n"
  },
  {
    "path": "pkg/api/routes.go",
    "content": "package api\n\nimport (\n\t\"github.com/gin-gonic/gin\"\n\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n\t\"github.com/sosedoff/pgweb/pkg/metrics\"\n)\n\nfunc SetupMiddlewares(group *gin.RouterGroup) {\n\tif command.Opts.Cors {\n\t\tgroup.Use(corsMiddleware())\n\t}\n\n\tgroup.Use(dbCheckMiddleware())\n}\n\nfunc SetupRoutes(router *gin.Engine) {\n\troot := router.Group(command.Opts.Prefix)\n\n\troot.GET(\"/\", gin.WrapH(GetHome(command.Opts.Prefix)))\n\troot.GET(\"/static/*path\", gin.WrapH(GetAssets(command.Opts.Prefix)))\n\troot.GET(\"/connect/:resource\", ConnectWithBackend)\n\n\tapi := root.Group(\"/api\")\n\tSetupMiddlewares(api)\n\n\tif command.Opts.Sessions {\n\t\tapi.GET(\"/sessions\", GetSessions)\n\t}\n\n\tapi.GET(\"/info\", GetInfo)\n\tapi.POST(\"/connect\", Connect)\n\tapi.POST(\"/disconnect\", Disconnect)\n\tapi.POST(\"/switchdb\", SwitchDb)\n\tapi.GET(\"/databases\", GetDatabases)\n\tapi.GET(\"/connection\", GetConnectionInfo)\n\tapi.GET(\"/server_settings\", GetServerSettings)\n\tapi.GET(\"/activity\", GetActivity)\n\tapi.GET(\"/schemas\", GetSchemas)\n\tapi.GET(\"/objects\", GetObjects)\n\tapi.GET(\"/tables/:table\", GetTable)\n\tapi.GET(\"/tables/:table/rows\", GetTableRows)\n\tapi.GET(\"/tables/:table/info\", GetTableInfo)\n\tapi.GET(\"/tables/:table/indexes\", GetTableIndexes)\n\tapi.GET(\"/tables/:table/constraints\", GetTableConstraints)\n\tapi.GET(\"/tables_stats\", GetTablesStats)\n\tapi.GET(\"/functions/:id\", GetFunction)\n\tapi.GET(\"/query\", RunQuery)\n\tapi.POST(\"/query\", RunQuery)\n\tapi.GET(\"/explain\", ExplainQuery)\n\tapi.POST(\"/explain\", ExplainQuery)\n\tapi.GET(\"/analyze\", AnalyzeQuery)\n\tapi.POST(\"/analyze\", AnalyzeQuery)\n\tapi.GET(\"/history\", GetHistory)\n\tapi.GET(\"/bookmarks\", GetBookmarks)\n\tapi.GET(\"/export\", DataExport)\n\tapi.GET(\"/local_queries\", requireLocalQueries(), GetLocalQueries)\n\tapi.GET(\"/local_queries/:id\", requireLocalQueries(), RunLocalQuery)\n\tapi.POST(\"/local_queries/:id\", requireLocalQueries(), RunLocalQuery)\n}\n\nfunc SetupMetrics(engine *gin.Engine) {\n\tif command.Opts.MetricsEnabled && command.Opts.MetricsAddr == \"\" {\n\t\t// NOTE: We're not supporting the MetricsPath CLI option here to avoid the route conflicts.\n\t\tengine.GET(\"/metrics\", gin.WrapH(metrics.NewHandler()))\n\t}\n}\n"
  },
  {
    "path": "pkg/api/session_manager.go",
    "content": "package api\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/sirupsen/logrus\"\n\n\t\"github.com/sosedoff/pgweb/pkg/client\"\n\t\"github.com/sosedoff/pgweb/pkg/metrics\"\n)\n\ntype SessionManager struct {\n\tlogger      *logrus.Logger\n\tsessions    map[string]*client.Client\n\tmu          sync.Mutex\n\tidleTimeout time.Duration\n}\n\nfunc NewSessionManager(logger *logrus.Logger) *SessionManager {\n\treturn &SessionManager{\n\t\tlogger:   logger,\n\t\tsessions: map[string]*client.Client{},\n\t\tmu:       sync.Mutex{},\n\t}\n}\n\nfunc (m *SessionManager) SetIdleTimeout(timeout time.Duration) {\n\tm.idleTimeout = timeout\n}\n\nfunc (m *SessionManager) IDs() []string {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\n\tids := []string{}\n\tfor k := range m.sessions {\n\t\tids = append(ids, k)\n\t}\n\n\treturn ids\n}\n\nfunc (m *SessionManager) Sessions() map[string]*client.Client {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\n\tsessions := make(map[string]*client.Client, len(m.sessions))\n\tfor k, v := range m.sessions {\n\t\tsessions[k] = v\n\t}\n\n\treturn sessions\n}\n\nfunc (m *SessionManager) Get(id string) *client.Client {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\n\treturn m.sessions[id]\n}\n\nfunc (m *SessionManager) Add(id string, conn *client.Client) {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\n\tm.sessions[id] = conn\n\tmetrics.SetSessionsCount(len(m.sessions))\n}\n\nfunc (m *SessionManager) Remove(id string) bool {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\n\tconn, ok := m.sessions[id]\n\tif ok {\n\t\tconn.Close()\n\t\tdelete(m.sessions, id)\n\t}\n\n\tmetrics.SetSessionsCount(len(m.sessions))\n\treturn ok\n}\n\nfunc (m *SessionManager) Len() int {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\n\treturn len(m.sessions)\n}\n\nfunc (m *SessionManager) Cleanup() int {\n\tif m.idleTimeout == 0 {\n\t\treturn 0\n\t}\n\n\tremoved := 0\n\n\tm.logger.Debug(\"starting idle sessions cleanup\")\n\tdefer func() {\n\t\tm.logger.Debug(\"removed idle sessions:\", removed)\n\t}()\n\n\tfor _, id := range m.staleSessions() {\n\t\tm.logger.WithField(\"id\", id).Debug(\"closing stale session\")\n\t\tif m.Remove(id) {\n\t\t\tremoved++\n\t\t}\n\t}\n\n\treturn removed\n}\n\nfunc (m *SessionManager) RunPeriodicCleanup() {\n\tm.logger.WithField(\"timeout\", m.idleTimeout).Info(\"session manager cleanup enabled\")\n\n\tfor range time.Tick(time.Minute) {\n\t\tm.Cleanup()\n\t}\n}\n\nfunc (m *SessionManager) staleSessions() []string {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\n\tnow := time.Now()\n\tids := []string{}\n\n\tfor id, conn := range m.sessions {\n\t\tif now.Sub(conn.LastQueryTime()) > m.idleTimeout {\n\t\t\tids = append(ids, id)\n\t\t}\n\t}\n\n\treturn ids\n}\n"
  },
  {
    "path": "pkg/api/session_manager_test.go",
    "content": "package api\n\nimport (\n\t\"sort\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/sirupsen/logrus\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/sosedoff/pgweb/pkg/client\"\n)\n\nfunc TestSessionManager(t *testing.T) {\n\tt.Run(\"return ids\", func(t *testing.T) {\n\t\tmanager := NewSessionManager(nil)\n\t\tassert.Equal(t, []string{}, manager.IDs())\n\n\t\tmanager.sessions[\"foo\"] = &client.Client{}\n\t\tmanager.sessions[\"bar\"] = &client.Client{}\n\n\t\tids := manager.IDs()\n\t\tsort.Strings(ids)\n\t\tassert.Equal(t, []string{\"bar\", \"foo\"}, ids)\n\t})\n\n\tt.Run(\"get session\", func(t *testing.T) {\n\t\tmanager := NewSessionManager(nil)\n\t\tassert.Nil(t, manager.Get(\"foo\"))\n\n\t\tmanager.sessions[\"foo\"] = &client.Client{}\n\t\tassert.NotNil(t, manager.Get(\"foo\"))\n\t})\n\n\tt.Run(\"set session\", func(t *testing.T) {\n\t\tmanager := NewSessionManager(nil)\n\t\tassert.Nil(t, manager.Get(\"foo\"))\n\n\t\tmanager.Add(\"foo\", &client.Client{})\n\t\tassert.NotNil(t, manager.Get(\"foo\"))\n\t})\n\n\tt.Run(\"remove session\", func(t *testing.T) {\n\t\tmanager := NewSessionManager(nil)\n\t\tassert.Nil(t, manager.Get(\"foo\"))\n\n\t\tmanager.Add(\"foo\", &client.Client{})\n\t\tassert.NotNil(t, manager.Get(\"foo\"))\n\t\tassert.True(t, manager.Remove(\"foo\"))\n\t\tassert.False(t, manager.Remove(\"foo\"))\n\t\tassert.Nil(t, manager.Get(\"foo\"))\n\t})\n\n\tt.Run(\"return len\", func(t *testing.T) {\n\t\tmanager := NewSessionManager(nil)\n\t\tmanager.sessions[\"foo\"] = &client.Client{}\n\t\tmanager.sessions[\"bar\"] = &client.Client{}\n\n\t\tassert.Equal(t, 2, manager.Len())\n\t})\n\n\tt.Run(\"clean up stale sessions\", func(t *testing.T) {\n\t\tmanager := NewSessionManager(logrus.New())\n\t\tconn := &client.Client{}\n\t\tmanager.Add(\"foo\", conn)\n\n\t\tassert.Equal(t, 1, manager.Len())\n\t\tassert.Equal(t, 0, manager.Cleanup())\n\t\tassert.Equal(t, 1, manager.Len())\n\n\t\tres, err := conn.Query(\"select 1\")\n\t\tassert.Nil(t, res)\n\t\tassert.Nil(t, err)\n\n\t\tmanager.SetIdleTimeout(time.Minute)\n\t\tassert.Equal(t, 1, manager.Cleanup())\n\t\tassert.Equal(t, 0, manager.Len())\n\t\tassert.True(t, conn.IsClosed())\n\t})\n}\n"
  },
  {
    "path": "pkg/api/types.go",
    "content": "package api\n\ntype localQuery struct {\n\tID          string `json:\"id\"`\n\tTitle       string `json:\"title,omitempty\"`\n\tDescription string `json:\"description,omitempty\"`\n\tQuery       string `json:\"query\"`\n}\n"
  },
  {
    "path": "pkg/bookmarks/bookmarks.go",
    "content": "package bookmarks\n\nimport (\n\t\"os\"\n\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n\t\"github.com/sosedoff/pgweb/pkg/shared\"\n)\n\n// Bookmark contains information about bookmarked database connection\ntype Bookmark struct {\n\tID          string          // ID generated from the filename\n\tURL         string          // Postgres connection URL\n\tHost        string          // Server hostname\n\tPort        int             // Server port\n\tUser        string          // Database user\n\tUserVar     string          // Database user environment variable\n\tPassword    string          // User password\n\tPasswordVar string          // User password environment variable\n\tDatabase    string          // Database name\n\tSSLMode     string          // Connection SSL mode\n\tSSH         *shared.SSHInfo // SSH tunnel config\n\tReadOnly    bool            // Enable read-only transaction mode\n}\n\n// SSHInfoIsEmpty returns true if ssh configuration is not provided\nfunc (b Bookmark) SSHInfoIsEmpty() bool {\n\treturn b.SSH == nil || (b.SSH.User == \"\" && b.SSH.Host == \"\" && b.SSH.Port == \"\")\n}\n\n// ConvertToOptions returns an options struct from connection details\nfunc (b Bookmark) ConvertToOptions() command.Options {\n\tuser := b.User\n\tif b.User == \"\" {\n\t\tuser = os.Getenv(b.UserVar)\n\t}\n\n\tpass := b.Password\n\tif b.Password == \"\" {\n\t\tpass = os.Getenv(b.PasswordVar)\n\t}\n\n\treturn command.Options{\n\t\tURL:      b.URL,\n\t\tHost:     b.Host,\n\t\tPort:     b.Port,\n\t\tUser:     user,\n\t\tPass:     pass,\n\t\tDbName:   b.Database,\n\t\tSSLMode:  b.SSLMode,\n\t\tReadOnly: b.ReadOnly,\n\t}\n}\n"
  },
  {
    "path": "pkg/bookmarks/bookmarks_test.go",
    "content": "package bookmarks\n\nimport (\n\t\"testing\"\n\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n\t\"github.com/sosedoff/pgweb/pkg/shared\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestBookmarkSSHInfoIsEmpty(t *testing.T) {\n\tt.Run(\"empty\", func(t *testing.T) {\n\t\tinfo := &shared.SSHInfo{\n\t\t\tHost: \"\",\n\t\t\tPort: \"\",\n\t\t\tUser: \"\",\n\t\t}\n\n\t\tb := Bookmark{SSH: nil}\n\t\tassert.True(t, b.SSHInfoIsEmpty())\n\n\t\tb = Bookmark{SSH: info}\n\t\tassert.True(t, b.SSHInfoIsEmpty())\n\t})\n\n\tt.Run(\"only host set\", func(t *testing.T) {\n\t\tb := Bookmark{SSH: &shared.SSHInfo{Host: \"localhost\"}}\n\t\tassert.False(t, b.SSHInfoIsEmpty())\n\t})\n\n\tt.Run(\"only port set\", func(t *testing.T) {\n\t\tb := Bookmark{SSH: &shared.SSHInfo{Port: \"8080\"}}\n\t\tassert.False(t, b.SSHInfoIsEmpty())\n\t})\n\n\tt.Run(\"only user set\", func(t *testing.T) {\n\t\tb := Bookmark{SSH: &shared.SSHInfo{User: \"postgres\"}}\n\t\tassert.False(t, b.SSHInfoIsEmpty())\n\t})\n\n\tt.Run(\"populated\", func(t *testing.T) {\n\t\tinfo := &shared.SSHInfo{\n\t\t\tHost: \"localhost\",\n\t\t\tPort: \"8080\",\n\t\t\tUser: \"postgres\",\n\t\t}\n\n\t\tb := Bookmark{SSH: info}\n\t\tassert.False(t, b.SSHInfoIsEmpty())\n\t})\n}\n\nfunc TestBookmarkWithVarsConvertToOptions(t *testing.T) {\n\tt.Run(\"literals set\", func(t *testing.T) {\n\t\tb := Bookmark{\n\t\t\tUser:        \"user\",\n\t\t\tUserVar:     \"\",\n\t\t\tPassword:    \"password\",\n\t\t\tPasswordVar: \"\",\n\t\t}\n\n\t\texpOpt := command.Options{\n\t\t\tUser: \"user\",\n\t\t\tPass: \"password\",\n\t\t}\n\n\t\topt := b.ConvertToOptions()\n\t\tassert.Equal(t, expOpt, opt)\n\t})\n\n\tt.Run(\"all set\", func(t *testing.T) {\n\t\tb := Bookmark{\n\t\t\tUser:        \"user\",\n\t\t\tUserVar:     \"DB_USER\",\n\t\t\tPassword:    \"password\",\n\t\t\tPasswordVar: \"DB_PASSWORD\",\n\t\t}\n\n\t\texpOpt := command.Options{\n\t\t\tUser: \"user\",\n\t\t\tPass: \"password\",\n\t\t}\n\n\t\tt.Setenv(\"DB_USER\", \"user123\")\n\t\tt.Setenv(\"DB_PASSWORD\", \"password123\")\n\n\t\topt := b.ConvertToOptions()\n\t\tassert.Equal(t, expOpt, opt)\n\t})\n\n\tt.Run(\"env vars set\", func(t *testing.T) {\n\t\tb := Bookmark{\n\t\t\tUser:        \"\",\n\t\t\tUserVar:     \"DB_USER\",\n\t\t\tPassword:    \"\",\n\t\t\tPasswordVar: \"DB_PASSWORD\",\n\t\t}\n\n\t\texpOpt := command.Options{\n\t\t\tUser: \"user123\",\n\t\t\tPass: \"password123\",\n\t\t}\n\n\t\tt.Setenv(\"DB_USER\", \"user123\")\n\t\tt.Setenv(\"DB_PASSWORD\", \"password123\")\n\n\t\topt := b.ConvertToOptions()\n\t\tassert.Equal(t, expOpt, opt)\n\t})\n}\n\nfunc TestBookmarkConvertToOptions(t *testing.T) {\n\tb := Bookmark{\n\t\tURL:      \"postgres://username:password@host:port/database?sslmode=disable\",\n\t\tHost:     \"localhost\",\n\t\tPort:     5432,\n\t\tUser:     \"postgres\",\n\t\tPassword: \"password\",\n\t\tDatabase: \"mydatabase\",\n\t\tSSLMode:  \"disable\",\n\t\tReadOnly: true,\n\t}\n\n\texpOpt := command.Options{\n\t\tURL:      \"postgres://username:password@host:port/database?sslmode=disable\",\n\t\tHost:     \"localhost\",\n\t\tPort:     5432,\n\t\tUser:     \"postgres\",\n\t\tPass:     \"password\",\n\t\tDbName:   \"mydatabase\",\n\t\tSSLMode:  \"disable\",\n\t\tReadOnly: true,\n\t}\n\n\topt := b.ConvertToOptions()\n\tassert.Equal(t, expOpt, opt)\n}\n"
  },
  {
    "path": "pkg/bookmarks/manager.go",
    "content": "package bookmarks\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/BurntSushi/toml\"\n)\n\ntype Manager struct {\n\tdir string\n}\n\nfunc NewManager(dir string) Manager {\n\treturn Manager{\n\t\tdir: dir,\n\t}\n}\n\nfunc (m Manager) Get(id string) (*Bookmark, error) {\n\tbookmarks, err := m.list()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, b := range bookmarks {\n\t\tif b.ID == id {\n\t\t\treturn &b, nil\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"bookmark %v not found\", id)\n}\n\nfunc (m Manager) List() ([]Bookmark, error) {\n\treturn m.list()\n}\n\nfunc (m Manager) ListIDs() ([]string, error) {\n\tbookmarks, err := m.list()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tids := make([]string, len(bookmarks))\n\tfor i, bookmark := range bookmarks {\n\t\tids[i] = bookmark.ID\n\t}\n\n\treturn ids, nil\n}\n\nfunc (m Manager) list() ([]Bookmark, error) {\n\tresult := []Bookmark{}\n\n\tif m.dir == \"\" {\n\t\treturn result, nil\n\t}\n\n\tinfo, err := os.Stat(m.dir)\n\tif err != nil {\n\t\t// Do not fail if base dir does not exists: it's not created by default\n\t\tif errors.Is(err, os.ErrNotExist) {\n\t\t\tfmt.Fprintf(os.Stderr, \"[WARN] bookmarks dir %s does not exist\\n\", m.dir)\n\t\t\treturn result, nil\n\t\t}\n\t\treturn nil, err\n\t}\n\tif !info.IsDir() {\n\t\treturn nil, fmt.Errorf(\"path %s is not a directory\", m.dir)\n\t}\n\n\tdirEntries, err := os.ReadDir(m.dir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, entry := range dirEntries {\n\t\tname := entry.Name()\n\t\tif filepath.Ext(name) != \".toml\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tbookmark, err := readBookmark(filepath.Join(m.dir, name))\n\t\tif err != nil {\n\t\t\t// Do not fail if one of the bookmarks is invalid\n\t\t\tfmt.Fprintf(os.Stderr, \"[WARN] bookmark file %s is invalid: %s\\n\", name, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tresult = append(result, bookmark)\n\t}\n\n\treturn result, nil\n}\n\nfunc readBookmark(path string) (Bookmark, error) {\n\tbookmark := Bookmark{\n\t\tID: fileBasename(path),\n\t}\n\n\t_, err := os.Stat(path)\n\tif err != nil {\n\t\tif errors.Is(err, os.ErrNotExist) {\n\t\t\terr = fmt.Errorf(\"bookmark file %s does not exist\", path)\n\t\t}\n\t\treturn bookmark, err\n\t}\n\n\tbuff, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn bookmark, err\n\t}\n\n\t_, err = toml.Decode(string(buff), &bookmark)\n\n\tif bookmark.Port == 0 {\n\t\tbookmark.Port = 5432\n\t}\n\n\t// List of all supported postgres modes\n\tmodes := []string{\"disable\", \"allow\", \"prefer\", \"require\", \"verify-ca\", \"verify-full\"}\n\tvalid := false\n\n\tfor _, mode := range modes {\n\t\tif bookmark.SSLMode == mode {\n\t\t\tvalid = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Fall back to a default mode if mode is not set or invalid\n\t// Typical typo: ssl mode set to \"disabled\"\n\tif bookmark.SSLMode == \"\" || !valid {\n\t\tbookmark.SSLMode = \"disable\"\n\t}\n\n\t// Set default SSH port if it's not provided by user\n\tif bookmark.SSH != nil && bookmark.SSH.Port == \"\" {\n\t\tbookmark.SSH.Port = \"22\"\n\t}\n\n\treturn bookmark, err\n}\n\nfunc fileBasename(path string) string {\n\tfilename := filepath.Base(path)\n\treturn strings.Replace(filename, filepath.Ext(path), \"\", 1)\n}\n"
  },
  {
    "path": "pkg/bookmarks/manager_test.go",
    "content": "package bookmarks\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestManagerList(t *testing.T) {\n\texamples := []struct {\n\t\tdir string\n\t\tnum int\n\t\terr string\n\t}{\n\t\t{\"../../data\", 4, \"\"},\n\t\t{\"../../data/bookmark.toml\", 0, \"is not a directory\"},\n\t\t{\"../../data2\", 0, \"\"},\n\t\t{\"\", 0, \"\"},\n\t}\n\n\tfor _, ex := range examples {\n\t\tt.Run(ex.dir, func(t *testing.T) {\n\t\t\tbookmarks, err := NewManager(ex.dir).List()\n\t\t\tif ex.err != \"\" {\n\t\t\t\tassert.Contains(t, err.Error(), ex.err)\n\t\t\t}\n\t\t\tassert.Len(t, bookmarks, ex.num)\n\t\t})\n\t}\n}\n\nfunc TestManagerListIDs(t *testing.T) {\n\tids, err := NewManager(\"../../data\").ListIDs()\n\tassert.NoError(t, err)\n\tassert.Equal(t, []string{\n\t\t\"bookmark\",\n\t\t\"bookmark_invalid_ssl\",\n\t\t\"bookmark_url\",\n\t\t\"bookmark_with_ssh\",\n\t}, ids)\n}\n\nfunc TestManagerGet(t *testing.T) {\n\tmanager := NewManager(\"../../data\")\n\n\tb, err := manager.Get(\"bookmark\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"bookmark\", b.ID)\n\n\tb, err = manager.Get(\"foo\")\n\tassert.Equal(t, \"bookmark foo not found\", err.Error())\n\tassert.Nil(t, b)\n}\n\nfunc Test_fileBasename(t *testing.T) {\n\tassert.Equal(t, \"filename\", fileBasename(\"filename.toml\"))\n\tassert.Equal(t, \"filename\", fileBasename(\"path/filename.toml\"))\n\tassert.Equal(t, \"filename\", fileBasename(\"~/long/path/filename.toml\"))\n\tassert.Equal(t, \"filename\", fileBasename(\"filename\"))\n}\n\nfunc Test_readBookmark(t *testing.T) {\n\tt.Run(\"good\", func(t *testing.T) {\n\t\tb, err := readBookmark(\"../../data/bookmark.toml\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"bookmark\", b.ID)\n\t\tassert.Equal(t, \"localhost\", b.Host)\n\t\tassert.Equal(t, 5432, b.Port)\n\t\tassert.Equal(t, \"postgres\", b.User)\n\t\tassert.Equal(t, \"mydatabase\", b.Database)\n\t\tassert.Equal(t, \"disable\", b.SSLMode)\n\t\tassert.Equal(t, \"\", b.Password)\n\t\tassert.Equal(t, \"\", b.URL)\n\t})\n\n\tt.Run(\"with url\", func(t *testing.T) {\n\t\tb, err := readBookmark(\"../../data/bookmark_url.toml\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://username:password@host:port/database?sslmode=disable\", b.URL)\n\t\tassert.Equal(t, \"\", b.Host)\n\t\tassert.Equal(t, 5432, b.Port)\n\t\tassert.Equal(t, \"\", b.User)\n\t\tassert.Equal(t, \"\", b.Database)\n\t\tassert.Equal(t, \"disable\", b.SSLMode)\n\t\tassert.Equal(t, \"\", b.Password)\n\t})\n\n\tt.Run(\"with ssh options\", func(t *testing.T) {\n\t\tb, err := readBookmark(\"../../data/bookmark_with_ssh.toml\")\n\t\tassert.NoError(t, err)\n\t\tassert.NotNil(t, b.SSH)\n\n\t\tsshc := b.SSH\n\t\tassert.Equal(t, \"ssh-host\", sshc.Host)\n\t\tassert.Equal(t, \"ssh-user\", sshc.User)\n\t\tassert.Equal(t, \"ssh-password\", sshc.Password)\n\t\tassert.Equal(t, \"/path/to/key-file\", sshc.Key)\n\t\tassert.Equal(t, \"key-file-password\", sshc.KeyPassword)\n\t})\n\n\tt.Run(\"invalid ssl\", func(t *testing.T) {\n\t\tb, err := readBookmark(\"../../data/bookmark_invalid_ssl.toml\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"disable\", b.SSLMode)\n\t})\n\n\tt.Run(\"invalid file\", func(t *testing.T) {\n\t\t_, err := readBookmark(\"foobar\")\n\t\tassert.Equal(t, \"bookmark file foobar does not exist\", err.Error())\n\t})\n\n\tt.Run(\"invalid syntax\", func(t *testing.T) {\n\t\t_, err := readBookmark(\"../../data/invalid.toml\")\n\t\tassert.Equal(t, \"toml: line 1: expected '.' or '=', but got 'e' instead\", err.Error())\n\t})\n}\n"
  },
  {
    "path": "pkg/cli/cli.go",
    "content": "package cli\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"os/signal\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/jessevdk/go-flags\"\n\t\"github.com/sirupsen/logrus\"\n\n\t\"github.com/sosedoff/pgweb/pkg/api\"\n\t\"github.com/sosedoff/pgweb/pkg/bookmarks\"\n\t\"github.com/sosedoff/pgweb/pkg/client\"\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n\t\"github.com/sosedoff/pgweb/pkg/connection\"\n\t\"github.com/sosedoff/pgweb/pkg/metrics\"\n\t\"github.com/sosedoff/pgweb/pkg/queries\"\n\t\"github.com/sosedoff/pgweb/pkg/util\"\n)\n\nvar (\n\tlogger  *logrus.Logger\n\toptions command.Options\n\n\treadonlyWarning = `\n--------------------------------------------------------------------------------\nSECURITY WARNING: You are running Pgweb in read-only mode.\nThis mode is designed for environments where users could potentially delete or change data.\nFor proper read-only access please follow PostgreSQL role management documentation.\n--------------------------------------------------------------------------------`\n)\n\nfunc init() {\n\tlogger = logrus.New()\n}\n\nfunc exitWithMessage(message string) {\n\tfmt.Println(\"Error:\", message)\n\tos.Exit(1)\n}\n\nfunc initClientUsingBookmark(baseDir, bookmarkName string) (*client.Client, error) {\n\tmanager := bookmarks.NewManager(baseDir)\n\tbookmark, err := manager.Get(bookmarkName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn client.NewFromBookmark(bookmark)\n}\n\nfunc initClient() {\n\tif connection.IsBlank(command.Opts) && options.Bookmark == \"\" {\n\t\treturn\n\t}\n\n\tvar cl *client.Client\n\tvar err error\n\n\tif options.Bookmark != \"\" {\n\t\tcl, err = initClientUsingBookmark(options.BookmarksDir, options.Bookmark)\n\t} else {\n\t\tcl, err = client.New()\n\t}\n\tif err != nil {\n\t\texitWithMessage(err.Error())\n\t}\n\n\tif command.Opts.Debug {\n\t\tfmt.Println(\"Opening database connection using string:\", cl.ConnectionString)\n\t}\n\n\tretryCount := command.Opts.RetryCount\n\tretryDelay := time.Second * time.Duration(command.Opts.RetryDelay)\n\n\tfmt.Println(\"Connecting to server...\")\n\tabort, err := testClient(cl, int(retryCount), retryDelay)\n\tif err != nil {\n\t\tif abort {\n\t\t\texitWithMessage(err.Error())\n\t\t} else {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif !command.Opts.Sessions {\n\t\tfmt.Printf(\"Connected to %s\\n\", cl.ServerVersionInfo())\n\t}\n\n\tfmt.Println(\"Checking database objects...\")\n\t_, err = cl.Objects()\n\tif err != nil {\n\t\texitWithMessage(err.Error())\n\t}\n\n\tapi.DbClient = cl\n}\n\nfunc initOptions() {\n\topts, err := command.ParseOptions(os.Args)\n\tif err != nil {\n\t\tswitch errVal := err.(type) {\n\t\tcase *flags.Error:\n\t\t\tif errVal.Type == flags.ErrHelp {\n\t\t\t\tfmt.Println(\"Available environment variables:\")\n\t\t\t\tfmt.Println(command.AvailableEnvVars())\n\t\t\t}\n\t\t\t// no need to print error, flags package already does that\n\t\tdefault:\n\t\t\tfmt.Println(err.Error())\n\t\t}\n\t\tos.Exit(1)\n\t}\n\tcommand.Opts = opts\n\toptions = opts\n\n\tif options.Version {\n\t\tprintVersion()\n\t\tos.Exit(0)\n\t}\n\n\tif err := configureLogger(opts); err != nil {\n\t\texitWithMessage(err.Error())\n\t\treturn\n\t}\n\n\tif options.ReadOnly {\n\t\tfmt.Println(readonlyWarning)\n\t}\n\n\tif options.BinaryCodec != \"\" {\n\t\tif err := client.SetBinaryCodec(options.BinaryCodec); err != nil {\n\t\t\texitWithMessage(err.Error())\n\t\t}\n\t}\n\n\tconfigureLocalQueryStore()\n\tprintVersion()\n}\n\nfunc configureLocalQueryStore() {\n\tif options.Sessions || options.QueriesDir == \"\" {\n\t\treturn\n\t}\n\n\tstat, err := os.Stat(options.QueriesDir)\n\tif err != nil {\n\t\tif errors.Is(err, os.ErrNotExist) {\n\t\t\tlogger.Debugf(\"local queries directory %q does not exist, disabling feature\", options.QueriesDir)\n\t\t} else {\n\t\t\tlogger.Debugf(\"local queries feature disabled due to error: %v\", err)\n\t\t}\n\t\treturn\n\t}\n\n\tif !stat.IsDir() {\n\t\tlogger.Debugf(\"local queries path %q is not a directory\", options.QueriesDir)\n\t\treturn\n\t}\n\n\tapi.QueryStore = queries.NewStore(options.QueriesDir)\n}\n\nfunc configureLogger(opts command.Options) error {\n\tif options.Debug {\n\t\tlogger.SetLevel(logrus.DebugLevel)\n\t} else {\n\t\tlvl, err := logrus.ParseLevel(opts.LogLevel)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tlogger.SetLevel(lvl)\n\t}\n\n\tswitch options.LogFormat {\n\tcase \"text\":\n\t\tlogger.SetFormatter(&logrus.TextFormatter{})\n\tcase \"json\":\n\t\tlogger.SetFormatter(&logrus.JSONFormatter{})\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid logger format: %v\", options.LogFormat)\n\t}\n\n\treturn nil\n}\n\nfunc printVersion() {\n\tfmt.Println(command.VersionString())\n}\n\nfunc startServer() {\n\trouter := gin.New()\n\trouter.Use(api.RequestLogger(logger))\n\trouter.Use(gin.Recovery())\n\n\t// Enable HTTP basic authentication only if both user and password are set\n\tif options.AuthUser != \"\" && options.AuthPass != \"\" {\n\t\tauth := map[string]string{options.AuthUser: options.AuthPass}\n\t\trouter.Use(gin.BasicAuth(auth))\n\t}\n\n\tapi.SetLogger(logger)\n\tapi.SetupRoutes(router)\n\tapi.SetupMetrics(router)\n\n\tfmt.Println(\"Starting server...\")\n\tgo func() {\n\t\tmetrics.SetHealthy(true)\n\n\t\terr := router.Run(fmt.Sprintf(\"%v:%v\", options.HTTPHost, options.HTTPPort))\n\t\tif err != nil {\n\t\t\tfmt.Println(\"Can't start server:\", err)\n\t\t\tif strings.Contains(err.Error(), \"address already in use\") {\n\t\t\t\topenPage()\n\t\t\t}\n\t\t\tos.Exit(1)\n\t\t}\n\t}()\n}\n\nfunc startMetricsServer() {\n\tserverAddr := fmt.Sprintf(\"%v:%v\", command.Opts.HTTPHost, command.Opts.HTTPPort)\n\tif options.MetricsAddr == serverAddr {\n\t\treturn\n\t}\n\n\terr := metrics.StartServer(logger, options.MetricsPath, options.MetricsAddr)\n\tif err != nil {\n\t\tlogger.WithError(err).Fatal(\"unable to start prometheus metrics server\")\n\t}\n}\n\nfunc handleSignals() {\n\tc := make(chan os.Signal, 1)\n\tsignal.Notify(c, os.Interrupt, syscall.SIGTERM)\n\t<-c\n}\n\nfunc openPage() {\n\turl := fmt.Sprintf(\"http://%v:%v/%s\", options.HTTPHost, options.HTTPPort, options.Prefix)\n\tfmt.Println(\"To view database open\", url, \"in browser\")\n\n\tif options.SkipOpen {\n\t\treturn\n\t}\n\n\t_, err := exec.Command(\"which\", \"open\").Output()\n\tif err != nil {\n\t\treturn\n\t}\n\n\t_, err = exec.Command(\"open\", url).Output()\n\tif err != nil {\n\t\tfmt.Println(\"Unable to auto-open pgweb URL:\", err)\n\t}\n}\n\n// testClient attempts to establish a database connection until it succeeds or\n// give up after certain number of retries. Retries only available when database\n// name or a connection string is provided.\nfunc testClient(cl *client.Client, retryCount int, retryDelay time.Duration) (abort bool, err error) {\n\tusingDefaultDB := command.Opts.DbName == \"\" && command.Opts.URL == \"\"\n\n\tfor {\n\t\terr = cl.Test()\n\t\tif err == nil {\n\t\t\treturn false, nil\n\t\t}\n\n\t\t// Continue normal start up if can't connect locally without database details.\n\t\tif usingDefaultDB {\n\t\t\tif errors.Is(err, client.ErrConnectionRefused) ||\n\t\t\t\terrors.Is(err, client.ErrAuthFailed) ||\n\t\t\t\terrors.Is(err, client.ErrDatabaseNotExist) {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\n\t\t// Only retry if can't establish connection to the server.\n\t\tif errors.Is(err, client.ErrConnectionRefused) && retryCount > 0 {\n\t\t\tfmt.Printf(\"Connection error: %v, retrying in %v (%d remaining)\\n\", err, retryDelay, retryCount)\n\t\t\tretryCount--\n\t\t\t<-time.After(retryDelay)\n\t\t\tcontinue\n\t\t}\n\n\t\treturn true, err\n\t}\n}\n\nfunc Run() {\n\tinitOptions()\n\tinitClient()\n\n\tif api.DbClient != nil {\n\t\tdefer api.DbClient.Close()\n\t}\n\n\tif !options.Debug {\n\t\tgin.SetMode(\"release\")\n\t}\n\n\t// Print memory usage every 30 seconds with debug flag\n\tif options.Debug {\n\t\tutil.StartProfiler()\n\t}\n\n\t// Start session cleanup worker\n\tif options.Sessions {\n\t\tapi.DbSessions = api.NewSessionManager(logger)\n\n\t\tif !command.Opts.DisableConnectionIdleTimeout {\n\t\t\tapi.DbSessions.SetIdleTimeout(time.Minute * time.Duration(command.Opts.ConnectionIdleTimeout))\n\t\t\tgo api.DbSessions.RunPeriodicCleanup()\n\t\t}\n\t}\n\n\t// Start a separate metrics http server. If metrics addr is not provided, we\n\t// add the metrics endpoint in the existing application server (see api.go).\n\tif options.MetricsEnabled && options.MetricsAddr != \"\" {\n\t\tgo startMetricsServer()\n\t}\n\n\tstartServer()\n\topenPage()\n\thandleSignals()\n}\n"
  },
  {
    "path": "pkg/client/client.go",
    "content": "package client\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\tneturl \"net/url\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/jmoiron/sqlx\"\n\t_ \"github.com/lib/pq\"\n\n\t\"github.com/sosedoff/pgweb/pkg/bookmarks\"\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n\t\"github.com/sosedoff/pgweb/pkg/connection\"\n\t\"github.com/sosedoff/pgweb/pkg/history\"\n\t\"github.com/sosedoff/pgweb/pkg/shared\"\n\t\"github.com/sosedoff/pgweb/pkg/statements\"\n)\n\nvar (\n\tregexErrAuthFailed        = regexp.MustCompile(`(authentication failed|role \"(.*)\" does not exist)`)\n\tregexErrConnectionRefused = regexp.MustCompile(`(connection|actively) refused`)\n\tregexErrDatabaseNotExist  = regexp.MustCompile(`database \"(.*)\" does not exist`)\n)\n\nvar (\n\tErrAuthFailed        = errors.New(\"authentication failed\")\n\tErrConnectionRefused = errors.New(\"connection refused\")\n\tErrDatabaseNotExist  = errors.New(\"database does not exist\")\n)\n\ntype Client struct {\n\tdb               *sqlx.DB\n\ttunnel           *Tunnel\n\tserverVersion    string\n\tserverType       string\n\tlastQueryTime    time.Time\n\tqueryTimeout     time.Duration\n\treadonly         bool\n\tclosed           bool\n\tExternal         bool             `json:\"external\"`\n\tHistory          []history.Record `json:\"history\"`\n\tConnectionString string           `json:\"connection_string\"`\n}\n\nfunc getSchemaAndTable(str string) (string, string) {\n\tchunks := strings.Split(str, \".\")\n\tif len(chunks) == 1 {\n\t\treturn \"public\", chunks[0]\n\t}\n\treturn chunks[0], chunks[1]\n}\n\nfunc New() (*Client, error) {\n\tstr, err := connection.BuildStringFromOptions(command.Opts)\n\n\tif command.Opts.Debug && str != \"\" {\n\t\tfmt.Println(\"Creating a new client for:\", str)\n\t}\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdb, err := sqlx.Open(\"postgres\", str)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tclient := Client{\n\t\tdb:               db,\n\t\tConnectionString: str,\n\t\tHistory:          history.New(),\n\t}\n\n\tclient.init()\n\treturn &client, nil\n}\n\nfunc NewFromUrl(url string, sshInfo *shared.SSHInfo) (*Client, error) {\n\tvar (\n\t\ttunnel *Tunnel\n\t\terr    error\n\t)\n\n\tif sshInfo != nil {\n\t\tif command.Opts.DisableSSH {\n\t\t\treturn nil, fmt.Errorf(\"ssh connections are disabled\")\n\t\t}\n\t\tif command.Opts.Debug {\n\t\t\tfmt.Println(\"Opening SSH tunnel for:\", sshInfo)\n\t\t}\n\n\t\ttunnel, err = NewTunnel(sshInfo, url)\n\t\tif err != nil {\n\t\t\ttunnel.Close()\n\t\t\treturn nil, err\n\t\t}\n\n\t\terr = tunnel.Configure()\n\t\tif err != nil {\n\t\t\ttunnel.Close()\n\t\t\treturn nil, err\n\t\t}\n\n\t\tgo tunnel.Start()\n\n\t\turi, err := neturl.Parse(url)\n\t\tif err != nil {\n\t\t\ttunnel.Close()\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// Override remote postgres port with local proxy port\n\t\turl = strings.Replace(url, uri.Host, fmt.Sprintf(\"127.0.0.1:%v\", tunnel.Port), 1)\n\t}\n\n\tif command.Opts.Debug {\n\t\tfmt.Println(\"Creating a new client for:\", url)\n\t}\n\n\turi, err := neturl.Parse(url)\n\tif err == nil && uri.Path == \"\" {\n\t\treturn nil, fmt.Errorf(\"Database name is not provided\")\n\t}\n\n\tdb, err := sqlx.Open(\"postgres\", url)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tclient := Client{\n\t\tdb:               db,\n\t\ttunnel:           tunnel,\n\t\tserverType:       postgresType,\n\t\tConnectionString: url,\n\t\tHistory:          history.New(),\n\t}\n\n\tclient.init()\n\treturn &client, nil\n}\n\nfunc NewFromBookmark(bookmark *bookmarks.Bookmark) (*Client, error) {\n\tvar (\n\t\tconnStr string\n\t\terr     error\n\t)\n\n\toptions := bookmark.ConvertToOptions()\n\tif options.URL != \"\" {\n\t\tconnStr = options.URL\n\t} else {\n\t\tconnStr, err = connection.BuildStringFromOptions(options)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tvar sshInfo *shared.SSHInfo\n\tif !bookmark.SSHInfoIsEmpty() {\n\t\tsshInfo = bookmark.SSH\n\t}\n\n\tclient, err := NewFromUrl(connStr, sshInfo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif bookmark.ReadOnly {\n\t\tclient.readonly = true\n\t}\n\n\treturn client, nil\n}\n\nfunc (client *Client) init() {\n\tif command.Opts.QueryTimeout > 0 {\n\t\tclient.queryTimeout = time.Second * time.Duration(command.Opts.QueryTimeout)\n\t}\n\n\tclient.setServerVersion()\n}\n\nfunc (client *Client) setServerVersion() {\n\tres, err := client.query(\"SELECT version()\")\n\tif err != nil || len(res.Rows) < 1 {\n\t\treturn\n\t}\n\n\tversion := res.Rows[0][0].(string)\n\tmatch, serverType, serverVersion := detectServerTypeAndVersion(version)\n\tif match {\n\t\tclient.serverType = serverType\n\t\tclient.serverVersion = serverVersion\n\t}\n}\n\nfunc (client *Client) Test() error {\n\t// NOTE: This is a different timeout defined in CLI OpenTimeout\n\tctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\n\tdefer cancel()\n\n\terr := client.db.PingContext(ctx)\n\tif err == nil {\n\t\treturn nil\n\t}\n\n\terrMsg := err.Error()\n\n\tif regexErrConnectionRefused.MatchString(errMsg) {\n\t\treturn ErrConnectionRefused\n\t}\n\tif regexErrAuthFailed.MatchString(errMsg) {\n\t\treturn ErrAuthFailed\n\t}\n\tif regexErrDatabaseNotExist.MatchString(errMsg) {\n\t\treturn ErrDatabaseNotExist\n\t}\n\n\treturn err\n}\n\nfunc (client *Client) TestWithTimeout(timeout time.Duration) (result error) {\n\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\tdefer cancel()\n\n\t// Check connection status right away without waiting for the ticker to kick in.\n\t// We're expecting to get \"connection refused\" here for the most part.\n\tif err := client.db.PingContext(ctx); err == nil {\n\t\treturn nil\n\t}\n\n\tticker := time.NewTicker(250 * time.Millisecond)\n\tdefer ticker.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase <-ticker.C:\n\t\t\tresult = client.db.PingContext(ctx)\n\t\t\tif result == nil {\n\t\t\t\treturn\n\t\t\t}\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (client *Client) Info() (*Result, error) {\n\tresult, err := client.query(statements.Info)\n\tif err != nil {\n\t\tmsg := err.Error()\n\t\tif strings.Contains(msg, \"inet_\") && (strings.Contains(msg, \"not supported\") || strings.Contains(msg, \"permission denied\")) {\n\t\t\t// Fetch client information without inet_ function calls\n\t\t\tresult, err = client.query(statements.InfoSimple)\n\t\t}\n\t}\n\treturn result, err\n}\n\nfunc (client *Client) Databases() ([]string, error) {\n\treturn client.fetchRows(statements.Databases)\n}\n\nfunc (client *Client) Schemas() ([]string, error) {\n\treturn client.fetchRows(statements.Schemas)\n}\n\nfunc (client *Client) Objects() (*Result, error) {\n\treturn client.query(statements.Objects)\n}\n\nfunc (client *Client) Table(table string) (*Result, error) {\n\tschema, table := getSchemaAndTable(table)\n\treturn client.query(statements.TableSchema, schema, table)\n}\n\nfunc (client *Client) MaterializedView(name string) (*Result, error) {\n\treturn client.query(statements.MaterializedView, name)\n}\n\nfunc (client *Client) Function(id string) (*Result, error) {\n\treturn client.query(statements.Function, id)\n}\n\nfunc (client *Client) TableRows(table string, opts RowsOptions) (*Result, error) {\n\tschema, table := getSchemaAndTable(table)\n\tsql := fmt.Sprintf(`SELECT * FROM \"%s\".\"%s\"`, schema, table)\n\n\tif opts.Where != \"\" {\n\t\tsql += fmt.Sprintf(\" WHERE %s\", opts.Where)\n\t}\n\n\tif opts.SortColumn != \"\" {\n\t\tif opts.SortOrder == \"\" {\n\t\t\topts.SortOrder = \"ASC\"\n\t\t}\n\n\t\tsql += fmt.Sprintf(` ORDER BY \"%s\" %s`, opts.SortColumn, opts.SortOrder)\n\t}\n\n\tif opts.Limit > 0 {\n\t\tsql += fmt.Sprintf(\" LIMIT %d\", opts.Limit)\n\t}\n\n\tif opts.Offset > 0 {\n\t\tsql += fmt.Sprintf(\" OFFSET %d\", opts.Offset)\n\t}\n\n\treturn client.query(sql)\n}\n\nfunc (client *Client) EstimatedTableRowsCount(table string, opts RowsOptions) (*Result, error) {\n\tschema, table := getSchemaAndTable(table)\n\tresult, err := client.query(statements.EstimatedTableRowCount, schema, table)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// float64 to int64 conversion\n\testimatedRowsCount := result.Rows[0][0].(float64)\n\tresult.Rows[0] = Row{int64(estimatedRowsCount)}\n\n\treturn result, nil\n}\n\nfunc (client *Client) TableRowsCount(table string, opts RowsOptions) (*Result, error) {\n\t// Return postgres estimated rows count on empty filter\n\tif opts.Where == \"\" && client.serverType == postgresType {\n\t\tres, err := client.EstimatedTableRowsCount(table, opts)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tn := res.Rows[0][0].(int64)\n\t\tif n >= 100000 {\n\t\t\treturn res, nil\n\t\t}\n\t}\n\n\tschema, tableName := getSchemaAndTable(table)\n\tsql := fmt.Sprintf(`SELECT COUNT(1) FROM \"%s\".\"%s\"`, schema, tableName)\n\n\tif opts.Where != \"\" {\n\t\tsql += fmt.Sprintf(\" WHERE %s\", opts.Where)\n\t}\n\n\treturn client.query(sql)\n}\n\nfunc (client *Client) TableInfo(table string) (*Result, error) {\n\tif client.serverType == cockroachType {\n\t\treturn client.query(statements.TableInfoCockroach)\n\t}\n\tschema, table := getSchemaAndTable(table)\n\treturn client.query(statements.TableInfo, fmt.Sprintf(`\"%s\".\"%s\"`, schema, table))\n}\n\nfunc (client *Client) TableIndexes(table string) (*Result, error) {\n\tschema, table := getSchemaAndTable(table)\n\tres, err := client.query(statements.TableIndexes, schema, table)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn res, err\n}\n\nfunc (client *Client) TableConstraints(table string) (*Result, error) {\n\tschema, table := getSchemaAndTable(table)\n\tres, err := client.query(statements.TableConstraints, schema, table)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn res, err\n}\n\nfunc (client *Client) TablesStats() (*Result, error) {\n\treturn client.query(statements.TablesStats)\n}\n\nfunc (client *Client) ServerSettings() (*Result, error) {\n\treturn client.query(statements.Settings)\n}\n\n// Returns all active queriers on the server\nfunc (client *Client) Activity() (*Result, error) {\n\tif client.serverType == cockroachType {\n\t\treturn client.query(\"SHOW QUERIES\")\n\t}\n\n\tversion := getMajorMinorVersionString(client.serverVersion)\n\tquery := statements.Activity[version]\n\tif query == \"\" {\n\t\tquery = statements.Activity[\"default\"]\n\t}\n\n\treturn client.query(query)\n}\n\nfunc (client *Client) Query(query string) (*Result, error) {\n\tres, err := client.query(query)\n\n\t// Save history records only if query did not fail\n\tif err == nil && !client.hasHistoryRecord(query) {\n\t\tclient.History = append(client.History, history.NewRecord(query))\n\t}\n\n\treturn res, err\n}\n\nfunc (client *Client) SetReadOnlyMode() error {\n\tvar value string\n\tif err := client.db.Get(&value, \"SHOW default_transaction_read_only;\"); err != nil {\n\t\treturn err\n\t}\n\n\tif value == \"off\" {\n\t\t_, err := client.db.Exec(\"SET default_transaction_read_only=on;\")\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (client *Client) ServerVersionInfo() string {\n\treturn fmt.Sprintf(\"%s %s\", client.serverType, client.serverVersion)\n}\n\nfunc (client *Client) ServerVersion() string {\n\treturn client.serverVersion\n}\n\nfunc (client *Client) context() (context.Context, context.CancelFunc) {\n\tif client.queryTimeout > 0 {\n\t\treturn context.WithTimeout(context.Background(), client.queryTimeout)\n\t}\n\treturn context.Background(), func() {}\n}\n\nfunc (client *Client) exec(query string, args ...interface{}) (*Result, error) {\n\tctx, cancel := client.context()\n\tdefer cancel()\n\n\tqueryStart := time.Now()\n\tres, err := client.db.ExecContext(ctx, query, args...)\n\tqueryFinish := time.Now()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\taffected, err := res.RowsAffected()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresult := Result{\n\t\tColumns: []string{\"Rows Affected\"},\n\t\tRows: []Row{\n\t\t\t{affected},\n\t\t},\n\t\tStats: &ResultStats{\n\t\t\tColumnsCount:    1,\n\t\t\tRowsCount:       1,\n\t\t\tQueryStartTime:  queryStart.UTC(),\n\t\t\tQueryFinishTime: queryFinish.UTC(),\n\t\t\tQueryDuration:   queryFinish.Sub(queryStart).Milliseconds(),\n\t\t},\n\t}\n\n\treturn &result, nil\n}\n\nfunc (client *Client) query(query string, args ...interface{}) (*Result, error) {\n\tif client.db == nil {\n\t\treturn nil, nil\n\t}\n\n\t// Update the last usage time\n\tdefer func() {\n\t\tclient.lastQueryTime = time.Now().UTC()\n\t}()\n\n\t// We're going to force-set transaction mode on every query.\n\t// This is needed so that default mode could not be changed by user.\n\tif command.Opts.ReadOnly || client.readonly {\n\t\tif err := client.SetReadOnlyMode(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif containsRestrictedKeywords(query) {\n\t\t\treturn nil, errors.New(\"query contains keywords not allowed in read-only mode\")\n\t\t}\n\t}\n\n\taction := strings.ToLower(strings.Split(query, \" \")[0])\n\thasReturnValues := strings.Contains(strings.ToLower(query), \" returning \")\n\n\tif (action == \"update\" || action == \"delete\") && !hasReturnValues {\n\t\treturn client.exec(query, args...)\n\t}\n\n\tctx, cancel := client.context()\n\tdefer cancel()\n\n\tqueryStart := time.Now()\n\trows, err := client.db.QueryxContext(ctx, query, args...)\n\tqueryFinish := time.Now()\n\tif err != nil {\n\t\tif command.Opts.Debug {\n\t\t\tlog.Println(\"Failed query:\", query, \"\\nArgs:\", args)\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer rows.Close()\n\n\tcols, err := rows.Columns()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Make sure to never return null columns\n\tif cols == nil {\n\t\tcols = []string{}\n\t}\n\n\tresult := Result{\n\t\tColumns: cols,\n\t\tRows:    []Row{},\n\t}\n\n\tfor rows.Next() {\n\t\tobj, err := rows.SliceScan()\n\n\t\tfor i, item := range obj {\n\t\t\tif item == nil {\n\t\t\t\tobj[i] = nil\n\t\t\t} else {\n\t\t\t\tt := reflect.TypeOf(item).Kind().String()\n\n\t\t\t\tif t == \"slice\" {\n\t\t\t\t\tobj[i] = string(item.([]byte))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif err == nil {\n\t\t\tresult.Rows = append(result.Rows, obj)\n\t\t}\n\t}\n\n\tresult.Stats = &ResultStats{\n\t\tColumnsCount:    len(cols),\n\t\tRowsCount:       len(result.Rows),\n\t\tQueryStartTime:  queryStart.UTC(),\n\t\tQueryFinishTime: queryFinish.UTC(),\n\t\tQueryDuration:   queryFinish.Sub(queryStart).Milliseconds(),\n\t}\n\n\tresult.PostProcess()\n\n\treturn &result, nil\n}\n\n// Close database connection\nfunc (client *Client) Close() error {\n\tif client.closed {\n\t\treturn nil\n\t}\n\tdefer func() {\n\t\tclient.closed = true\n\t\tclient.tunnel = nil\n\t}()\n\n\tif client.tunnel != nil {\n\t\tclient.tunnel.Close()\n\t}\n\n\tif client.db != nil {\n\t\treturn client.db.Close()\n\t}\n\n\treturn nil\n}\n\nfunc (c *Client) IsClosed() bool {\n\treturn c.closed\n}\n\nfunc (c *Client) LastQueryTime() time.Time {\n\treturn c.lastQueryTime\n}\n\nfunc (client *Client) IsIdle() bool {\n\tmins := int(time.Since(client.lastQueryTime).Minutes())\n\n\tif command.Opts.ConnectionIdleTimeout > 0 {\n\t\treturn mins >= command.Opts.ConnectionIdleTimeout\n\t}\n\n\treturn false\n}\n\n// Fetch all rows as strings for a single column\nfunc (client *Client) fetchRows(q string) ([]string, error) {\n\tres, err := client.query(q)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Init empty slice so json.Marshal will encode it to \"[]\" instead of \"null\"\n\tresults := make([]string, 0)\n\n\tfor _, row := range res.Rows {\n\t\tresults = append(results, row[0].(string))\n\t}\n\n\treturn results, nil\n}\n\nfunc (client *Client) hasHistoryRecord(query string) bool {\n\tresult := false\n\n\tfor _, record := range client.History {\n\t\tif record.Query == query {\n\t\t\tresult = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn result\n}\n\ntype ConnContext struct {\n\tHost     string\n\tUser     string\n\tDatabase string\n\tMode     string\n}\n\nfunc (c ConnContext) String() string {\n\treturn fmt.Sprintf(\n\t\t\"host=%q user=%q database=%q mode=%q\",\n\t\tc.Host, c.User, c.Database, c.Mode,\n\t)\n}\n\n// ConnContext returns information about current database connection\nfunc (client *Client) GetConnContext() (*ConnContext, error) {\n\turl, err := neturl.Parse(client.ConnectionString)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tctx, cancel := context.WithTimeout(context.Background(), time.Second*10)\n\tdefer cancel()\n\n\tconnCtx := ConnContext{\n\t\tHost: url.Hostname(),\n\t\tMode: \"default\",\n\t}\n\n\tif command.Opts.ReadOnly {\n\t\tconnCtx.Mode = \"readonly\"\n\t}\n\n\trow := client.db.QueryRowContext(ctx, \"SELECT current_user, current_database()\")\n\tif err := row.Scan(&connCtx.User, &connCtx.Database); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &connCtx, nil\n}\n"
  },
  {
    "path": "pkg/client/client_test.go",
    "content": "package client\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"os/exec\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n)\n\nvar (\n\ttestClient     *Client\n\ttestCommands   map[string]string\n\tserverHost     string\n\tserverPort     string\n\tserverUser     string\n\tserverPassword string\n\tserverDatabase string\n)\n\nfunc mapKeys(data map[string]*Objects) []string {\n\tresult := []string{}\n\tfor k := range data {\n\t\tresult = append(result, k)\n\t}\n\treturn result\n}\n\nfunc objectNames(data []Object) []string {\n\tnames := make([]string, len(data))\n\tfor i, obj := range data {\n\t\tnames[i] = obj.Name\n\t}\n\n\tsort.Strings(names)\n\treturn names\n}\n\n// assertMatches is a helper method to check if src slice contains any elements of expected slice\nfunc assertMatches(t *testing.T, expected, src []string) {\n\tassert.NotEqual(t, 0, len(expected))\n\tassert.NotEqual(t, 0, len(src))\n\n\tfor _, val := range expected {\n\t\tassert.Contains(t, src, val)\n\t}\n}\n\nfunc pgVersion() (int, int) {\n\tvar major, minor int\n\tif _, err := fmt.Sscanf(os.Getenv(\"PGVERSION\"), \"%d.%d\", &major, &minor); err != nil {\n\t\tlog.Println(\"[warn] unable to read value of PGVERSION env var\")\n\t}\n\treturn major, minor\n}\n\nfunc getVar(name, def string) string {\n\tval := os.Getenv(name)\n\tif val == \"\" {\n\t\treturn def\n\t}\n\treturn val\n}\n\nfunc initVars() {\n\t// We need to load default options to make sure all stuff works\n\tif err := command.SetDefaultOptions(); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tserverHost = getVar(\"PGHOST\", \"localhost\")\n\tserverPort = getVar(\"PGPORT\", \"5432\")\n\tserverUser = getVar(\"PGUSER\", \"postgres\")\n\tserverPassword = getVar(\"PGPASSWORD\", \"postgres\")\n\tserverDatabase = getVar(\"PGDATABASE\", \"booktown\")\n}\n\nfunc setupCommands() {\n\ttestCommands = map[string]string{\n\t\t\"createdb\": \"createdb\",\n\t\t\"psql\":     \"psql\",\n\t\t\"dropdb\":   \"dropdb\",\n\t}\n\n\tif onWindows() {\n\t\tfor k, v := range testCommands {\n\t\t\ttestCommands[k] = v + \".exe\"\n\t\t}\n\t}\n}\n\nfunc onWindows() bool {\n\treturn runtime.GOOS == \"windows\"\n}\n\nfunc setup() {\n\t// No pretty JSON for tests\n\tcommand.Opts.DisablePrettyJSON = true\n\n\tout, err := exec.Command(\n\t\ttestCommands[\"createdb\"],\n\t\t\"-U\", serverUser,\n\t\t\"-h\", serverHost,\n\t\t\"-p\", serverPort,\n\t\tserverDatabase,\n\t).CombinedOutput()\n\n\tif err != nil {\n\t\tfmt.Println(\"Database creation failed:\", string(out))\n\t\tfmt.Println(\"Error:\", err)\n\t\tos.Exit(1)\n\t}\n\n\tout, err = exec.Command(\n\t\ttestCommands[\"psql\"],\n\t\t\"-U\", serverUser,\n\t\t\"-h\", serverHost,\n\t\t\"-p\", serverPort,\n\t\t\"-f\", \"../../data/booktown.sql\",\n\t\tserverDatabase,\n\t).CombinedOutput()\n\n\tif err != nil {\n\t\tfmt.Println(\"Database import failed:\", string(out))\n\t\tfmt.Println(\"Error:\", err)\n\t\tos.Exit(1)\n\t}\n}\n\nfunc setupClient() {\n\turl := fmt.Sprintf(\"postgres://%s@%s:%s/%s?sslmode=disable\", serverUser, serverHost, serverPort, serverDatabase)\n\ttestClient, _ = NewFromUrl(url, nil)\n}\n\nfunc teardownClient() {\n\tif testClient != nil {\n\t\ttestClient.Close()\n\t}\n}\n\nfunc teardown(t *testing.T, allowFail bool) {\n\toutput, err := exec.Command(\n\t\ttestCommands[\"dropdb\"],\n\t\t\"-U\", serverUser,\n\t\t\"-h\", serverHost,\n\t\t\"-p\", serverPort,\n\t\tserverDatabase,\n\t).CombinedOutput()\n\n\tif err != nil && strings.Contains(err.Error(), \"does not exist\") {\n\t\tt.Log(\"Teardown error:\", err)\n\t\tt.Logf(\"%s\\n\", output)\n\n\t\tif !allowFail {\n\t\t\tassert.NoError(t, err)\n\t\t}\n\t}\n}\n\nfunc testNewClientFromURL(t *testing.T) {\n\tt.Run(\"postgres prefix\", func(t *testing.T) {\n\t\turl := fmt.Sprintf(\"postgres://%s@%s:%s/%s?sslmode=disable\", serverUser, serverHost, serverPort, serverDatabase)\n\t\tclient, err := NewFromUrl(url, nil)\n\n\t\tassert.Equal(t, nil, err)\n\t\tassert.Equal(t, url, client.ConnectionString)\n\t\tassert.NoError(t, client.Close())\n\t})\n\n\tt.Run(\"postgresql prefix\", func(t *testing.T) {\n\t\turl := fmt.Sprintf(\"postgresql://%s@%s:%s/%s?sslmode=disable\", serverUser, serverHost, serverPort, serverDatabase)\n\t\tclient, err := NewFromUrl(url, nil)\n\n\t\tassert.Equal(t, nil, err)\n\t\tassert.Equal(t, url, client.ConnectionString)\n\t\tassert.NoError(t, client.Close())\n\t})\n}\n\nfunc testClientIdleTime(t *testing.T) {\n\texamples := map[time.Time]bool{\n\t\ttime.Now():                         false, // Current time\n\t\ttime.Now().Add(time.Minute * -30):  false, // 30 minutes ago\n\t\ttime.Now().Add(time.Minute * -240): true,  // 240 minutes ago\n\t\ttime.Now().Add(time.Minute * 30):   false, // 30 minutes in future\n\t\ttime.Now().Add(time.Minute * 128):  false, // 128 minutes in future\n\t}\n\n\tfor ts, expected := range examples {\n\t\ttestClient.lastQueryTime = ts\n\t\tassert.Equal(t, expected, testClient.IsIdle())\n\t}\n}\n\nfunc testTest(t *testing.T) {\n\texamples := []struct {\n\t\tname  string\n\t\tinput string\n\t\terr   error\n\t}{\n\t\t{\n\t\t\tname:  \"success\",\n\t\t\tinput: fmt.Sprintf(\"postgres://%s@%s:%s/%s?sslmode=disable\", serverUser, serverHost, serverPort, serverDatabase),\n\t\t\terr:   nil,\n\t\t},\n\t\t{\n\t\t\tname:  \"connection refused\",\n\t\t\tinput: \"postgresql://localhost:5433/dbname\",\n\t\t\terr:   ErrConnectionRefused,\n\t\t},\n\t\t{\n\t\t\tname:  \"invalid user\",\n\t\t\tinput: fmt.Sprintf(\"postgres://%s:%s@%s:%s/%s?sslmode=disable\", \"foo\", serverPassword, serverHost, serverPort, serverDatabase),\n\t\t\terr:   ErrAuthFailed,\n\t\t},\n\t\t{\n\t\t\tname:  \"invalid password\",\n\t\t\tinput: fmt.Sprintf(\"postgres://%s:%s@%s:%s/%s?sslmode=disable\", serverUser, \"foo\", serverHost, serverPort, serverDatabase),\n\t\t\terr:   ErrAuthFailed,\n\t\t},\n\t\t{\n\t\t\tname:  \"invalid database\",\n\t\t\tinput: fmt.Sprintf(\"postgres://%s@%s:%s/%s?sslmode=disable\", serverUser, serverHost, serverPort, \"foo\"),\n\t\t\terr:   ErrDatabaseNotExist,\n\t\t},\n\t}\n\n\tfor _, ex := range examples {\n\t\tt.Run(ex.name, func(t *testing.T) {\n\t\t\tconn, err := NewFromUrl(ex.input, nil)\n\t\t\trequire.NoError(t, err)\n\n\t\t\trequire.Equal(t, ex.err, conn.Test())\n\t\t})\n\t}\n}\n\nfunc testInfo(t *testing.T) {\n\tt.Run(\"normal\", func(t *testing.T) {\n\t\texpected := []string{\n\t\t\t\"session_user\",\n\t\t\t\"current_user\",\n\t\t\t\"current_database\",\n\t\t\t\"current_schemas\",\n\t\t\t\"inet_client_addr\",\n\t\t\t\"inet_client_port\",\n\t\t\t\"inet_server_addr\",\n\t\t\t\"inet_server_port\",\n\t\t\t\"version\",\n\t\t}\n\n\t\tres, err := testClient.Info()\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, expected, res.Columns)\n\t})\n\n\tt.Run(\"with restrictions\", func(t *testing.T) {\n\t\texpected := []string{\n\t\t\t\"session_user\",\n\t\t\t\"current_user\",\n\t\t\t\"current_database\",\n\t\t\t\"current_schemas\",\n\t\t\t\"version\",\n\t\t}\n\n\t\t// Prepare a new user and database\n\t\ttestClient.db.MustExec(\"DROP DATABASE IF EXISTS testdb\")\n\t\ttestClient.db.Exec(\"DROP OWNED BY IF EXISTS testuser\") //nolint:all\n\t\ttestClient.db.MustExec(\"DROP ROLE IF EXISTS testuser\")\n\t\ttestClient.db.MustExec(\"CREATE ROLE testuser WITH PASSWORD 'secret' LOGIN NOSUPERUSER NOINHERIT\")\n\t\ttestClient.db.MustExec(\"CREATE DATABASE testdb OWNER testuser\")\n\n\t\t// Disable access to inet_ calls for new user\n\t\turl := fmt.Sprintf(\"postgres://%s:@%s:%s/testdb?sslmode=disable\", serverUser, serverHost, serverPort)\n\t\tclient, err := NewFromUrl(url, nil)\n\t\tassert.NoError(t, err)\n\t\tclient.db.MustExec(\"REVOKE EXECUTE ON FUNCTION inet_client_addr() FROM PUBLIC\")\n\t\tassert.NoError(t, client.Close())\n\n\t\t// Connect using new user\n\t\turl = fmt.Sprintf(\"postgres://testuser:secret@%s:%s/testdb?sslmode=disable\", serverHost, serverPort)\n\t\tclient, err = NewFromUrl(url, nil)\n\t\tassert.NoError(t, err)\n\t\tdefer client.Close()\n\n\t\tres, err := client.Info()\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, expected, res.Columns)\n\t})\n}\n\nfunc testActivity(t *testing.T) {\n\texpected := []string{\"datid\", \"pid\", \"query\", \"query_start\", \"state\", \"client_addr\"}\n\n\tres, err := testClient.Activity()\n\tassert.NoError(t, err)\n\tassertMatches(t, expected, res.Columns)\n}\n\nfunc testDatabases(t *testing.T) {\n\tres, err := testClient.Databases()\n\tassert.NoError(t, err)\n\tassertMatches(t, []string{\"booktown\", \"postgres\"}, res)\n}\n\nfunc testSchemas(t *testing.T) {\n\tres, err := testClient.Schemas()\n\tassert.NoError(t, err)\n\tassert.Equal(t, []string{\"public\"}, res)\n}\n\nfunc testObjects(t *testing.T) {\n\tres, err := testClient.Objects()\n\tobjects := ObjectsFromResult(res)\n\n\ttables := []string{\n\t\t\"alternate_stock\",\n\t\t\"authors\",\n\t\t\"book_backup\",\n\t\t\"book_queue\",\n\t\t\"books\",\n\t\t\"customers\",\n\t\t\"daily_inventory\",\n\t\t\"distinguished_authors\",\n\t\t\"dummies\",\n\t\t\"editions\",\n\t\t\"employees\",\n\t\t\"favorite_authors\",\n\t\t\"favorite_books\",\n\t\t\"money_example\",\n\t\t\"my_list\",\n\t\t\"numeric_values\",\n\t\t\"publishers\",\n\t\t\"schedules\",\n\t\t\"shipments\",\n\t\t\"states\",\n\t\t\"stock\",\n\t\t\"stock_backup\",\n\t\t\"subjects\",\n\t\t\"text_sorting\",\n\t}\n\n\tfunctions := []string{\n\t\t\"add_shipment\",\n\t\t\"add_two_loop\",\n\t\t\"books_by_subject\",\n\t\t\"compound_word\",\n\t\t\"count_by_two\",\n\t\t\"double_price\",\n\t\t\"extract_all_titles\",\n\t\t\"extract_all_titles2\",\n\t\t\"extract_title\",\n\t\t\"first\",\n\t\t\"get_author\",\n\t\t\"get_author\",\n\t\t\"get_customer_id\",\n\t\t\"get_customer_name\",\n\t\t\"html_linebreaks\",\n\t\t\"in_stock\",\n\t\t\"isbn_to_title\",\n\t\t\"mixed\",\n\t\t\"raise_test\",\n\t\t\"ship_item\",\n\t\t\"stock_amount\",\n\t\t\"test\",\n\t\t\"title\",\n\t\t\"triple_price\",\n\t}\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, []string{\"oid\", \"schema\", \"name\", \"type\", \"owner\", \"comment\"}, res.Columns)\n\tassert.Equal(t, []string{\"public\"}, mapKeys(objects))\n\tassert.Equal(t, tables, objectNames(objects[\"public\"].Tables))\n\tassertMatches(t, functions, objectNames(objects[\"public\"].Functions))\n\tassert.Equal(t, []string{\"recent_shipments\", \"stock_view\"}, objectNames(objects[\"public\"].Views))\n\tassert.Equal(t, []string{\"author_ids\", \"book_ids\", \"shipments_ship_id_seq\", \"subject_ids\"}, objectNames(objects[\"public\"].Sequences))\n\n\tmajor, minor := pgVersion()\n\tif minor == 0 || minor >= 3 {\n\t\tassert.Equal(t, []string{\"m_stock_view\"}, objectNames(objects[\"public\"].MaterializedViews))\n\t} else {\n\t\tt.Logf(\"Skipping materialized view on %d.%d\\n\", major, minor)\n\t}\n}\n\nfunc testTable(t *testing.T) {\n\tcolumns := []string{\n\t\t\"column_name\",\n\t\t\"data_type\",\n\t\t\"is_nullable\",\n\t\t\"character_maximum_length\",\n\t\t\"character_set_catalog\",\n\t\t\"column_default\",\n\t\t\"comment\",\n\t}\n\n\tres, err := testClient.Table(\"books\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, columns, res.Columns)\n\tassert.Equal(t, 4, len(res.Rows))\n}\n\nfunc testTableRows(t *testing.T) {\n\tres, err := testClient.TableRows(\"books\", RowsOptions{})\n\tassert.NoError(t, err)\n\tassert.Equal(t, 4, len(res.Columns))\n\tassert.Equal(t, 15, len(res.Rows))\n}\n\nfunc testTableInfo(t *testing.T) {\n\tres, err := testClient.TableInfo(\"books\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, 4, len(res.Columns))\n\tassert.Equal(t, 1, len(res.Rows))\n}\n\nfunc testEstimatedTableRowsCount(t *testing.T) {\n\tres, err := testClient.EstimatedTableRowsCount(\"books\", RowsOptions{})\n\tassert.NoError(t, err)\n\tassert.Equal(t, []string{\"reltuples\"}, res.Columns)\n\tassert.Equal(t, []Row{{int64(15)}}, res.Rows)\n}\n\nfunc testTableRowsCount(t *testing.T) {\n\tres, err := testClient.TableRowsCount(\"books\", RowsOptions{})\n\tassert.NoError(t, err)\n\tassert.Equal(t, []string{\"count\"}, res.Columns)\n\tassert.Equal(t, []Row{{int64(15)}}, res.Rows)\n}\n\nfunc testTableRowsCountWithLargeTable(t *testing.T) {\n\ttestClient.db.MustExec(`CREATE TABLE large_table AS SELECT s FROM generate_series(1,1000000) s;`)\n\ttestClient.db.MustExec(`VACUUM large_table;`)\n\n\tres, err := testClient.TableRowsCount(\"large_table\", RowsOptions{})\n\tassert.Equal(t, nil, err)\n\tassert.Equal(t, []string{\"reltuples\"}, res.Columns)\n\tassert.Equal(t, []Row{{int64(1000000)}}, res.Rows)\n}\n\nfunc testTableIndexes(t *testing.T) {\n\tres, err := testClient.TableIndexes(\"books\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, []string{\"index_name\", \"index_size\", \"index_definition\"}, res.Columns)\n\tassert.Equal(t, 2, len(res.Rows))\n}\n\nfunc testTableConstraints(t *testing.T) {\n\tres, err := testClient.TableConstraints(\"editions\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, []string{\"name\", \"definition\"}, res.Columns)\n\tassert.Equal(t, Row{\"pkey\", \"PRIMARY KEY (isbn)\"}, res.Rows[0])\n\tassert.Equal(t, Row{\"integrity\", \"CHECK (book_id IS NOT NULL AND edition IS NOT NULL)\"}, res.Rows[1])\n}\n\nfunc testTableNameWithCamelCase(t *testing.T) {\n\ttestClient.db.MustExec(`CREATE TABLE \"exampleTable\" (id int, name varchar);`)\n\ttestClient.db.MustExec(`INSERT INTO \"exampleTable\" (id, name) VALUES (1, 'foo'), (2, 'bar');`)\n\n\t_, err := testClient.Table(\"exampleTable\")\n\tassert.NoError(t, err)\n\n\t_, err = testClient.TableInfo(\"exampleTable\")\n\tassert.NoError(t, err)\n\n\t_, err = testClient.TableConstraints(\"exampleTable\")\n\tassert.NoError(t, err)\n\n\t_, err = testClient.TableIndexes(\"exampleTable\")\n\tassert.NoError(t, err)\n\n\t_, err = testClient.TableRowsCount(\"exampleTable\", RowsOptions{})\n\tassert.NoError(t, err)\n\n\t_, err = testClient.EstimatedTableRowsCount(\"exampleTable\", RowsOptions{})\n\tassert.NoError(t, err)\n}\n\nfunc testQuery(t *testing.T) {\n\tt.Run(\"basic query\", func(t *testing.T) {\n\t\tres, err := testClient.Query(\"SELECT * FROM books\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, 4, len(res.Columns))\n\t\tassert.Equal(t, 15, len(res.Rows))\n\t})\n\n\tt.Run(\"error\", func(t *testing.T) {\n\t\tres, err := testClient.Query(\"SELCT * FROM books\")\n\t\tassert.NotNil(t, err)\n\t\tassert.Equal(t, \"pq: syntax error at or near \\\"SELCT\\\"\", err.Error())\n\t\tassert.Nil(t, res)\n\t})\n\n\tt.Run(\"invalid table\", func(t *testing.T) {\n\t\tres, err := testClient.Query(\"SELECT * FROM books2\")\n\t\tassert.NotNil(t, err)\n\t\tassert.Equal(t, \"pq: relation \\\"books2\\\" does not exist\", err.Error())\n\t\tassert.Nil(t, res)\n\t})\n\n\tt.Run(\"timeout\", func(t *testing.T) {\n\t\ttestClient.queryTimeout = time.Millisecond * 100\n\t\tdefer func() {\n\t\t\ttestClient.queryTimeout = 0\n\t\t}()\n\n\t\tres, err := testClient.query(\"SELECT pg_sleep(1);\")\n\t\tassert.Equal(t, \"pq: canceling statement due to user request\", err.Error())\n\t\tassert.Nil(t, res)\n\t})\n}\n\nfunc testUpdateQuery(t *testing.T) {\n\tt.Run(\"updating data\", func(t *testing.T) {\n\t\t// Add new row\n\t\ttestClient.db.MustExec(\"INSERT INTO books (id, title) VALUES (8888, 'Test Book'), (8889, 'Test Book 2')\")\n\n\t\t// Update without return values\n\t\tres, err := testClient.Query(\"UPDATE books SET title = 'Foo' WHERE id >= 8888 AND id <= 8889\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"Rows Affected\", res.Columns[0])\n\t\tassert.Equal(t, int64(2), res.Rows[0][0])\n\n\t\t// Update with return values\n\t\tres, err = testClient.Query(\"UPDATE books SET title = 'Foo2' WHERE id >= 8888 AND id <= 8889 RETURNING id, title\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, []string{\"id\", \"title\"}, res.Columns)\n\t\tassert.Equal(t, Row{int64(8888), \"Foo2\"}, res.Rows[0])\n\t\tassert.Equal(t, Row{int64(8889), \"Foo2\"}, res.Rows[1])\n\t})\n\n\tt.Run(\"deleting data\", func(t *testing.T) {\n\t\t// Add new row\n\t\ttestClient.db.MustExec(\"INSERT INTO books (id, title) VALUES (9999, 'Test Book')\")\n\n\t\t// Delete the existing row\n\t\tres, err := testClient.Query(\"DELETE FROM books WHERE id = 9999\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"Rows Affected\", res.Columns[0])\n\t\tassert.Equal(t, int64(1), res.Rows[0][0])\n\n\t\t// Deleting already deleted row\n\t\tres, err = testClient.Query(\"DELETE FROM books WHERE id = 9999\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, int64(0), res.Rows[0][0])\n\n\t\t// Delete with returning value\n\t\ttestClient.db.MustExec(\"INSERT INTO books (id, title) VALUES (9999, 'Test Book')\")\n\n\t\tres, err = testClient.Query(\"DELETE FROM books WHERE id = 9999 RETURNING id\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, int64(9999), res.Rows[0][0])\n\t})\n}\n\nfunc testTableRowsOrderEscape(t *testing.T) {\n\trows, err := testClient.TableRows(\"dummies\", RowsOptions{SortColumn: \"isDummy\"})\n\tassert.NoError(t, err)\n\tassert.Equal(t, 2, len(rows.Rows))\n\n\trows, err = testClient.TableRows(\"dummies\", RowsOptions{SortColumn: \"isdummy\"})\n\tassert.NotNil(t, err)\n\tassert.Equal(t, `pq: column \"isdummy\" does not exist`, err.Error())\n\tassert.Nil(t, rows)\n}\n\nfunc testFunctions(t *testing.T) {\n\tfuncName := \"get_customer_name\"\n\tfuncID := \"\"\n\n\tres, err := testClient.Objects()\n\tassert.NoError(t, err)\n\n\tfor _, row := range res.Rows {\n\t\tif row[2] == funcName {\n\t\t\tfuncID = row[0].(string)\n\t\t\tbreak\n\t\t}\n\t}\n\n\tres, err = testClient.Function(\"12345\")\n\tassert.NoError(t, err)\n\tassertMatches(t, []string{\"oid\", \"proname\", \"functiondef\"}, res.Columns)\n\tassert.Equal(t, 0, len(res.Rows))\n\n\tres, err = testClient.Function(funcID)\n\tassert.NoError(t, err)\n\tassertMatches(t, []string{\"oid\", \"proname\", \"functiondef\"}, res.Columns)\n\tassert.Equal(t, 1, len(res.Rows))\n\tassert.Equal(t, funcName, res.Rows[0][1])\n\tassert.Contains(t, res.Rows[0][len(res.Columns)-1], \"SELECT INTO customer_fname, customer_lname\")\n}\n\nfunc testResult(t *testing.T) {\n\tt.Run(\"json\", func(t *testing.T) {\n\t\tresult, err := testClient.Query(\"SELECT * FROM books LIMIT 1\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, `[{\"author_id\":4156,\"id\":7808,\"subject_id\":9,\"title\":\"The Shining\"}]`, string(result.JSON()))\n\n\t\tresult, err = testClient.Query(\"SELECT 'NaN'::float AS value;\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, `[{\"value\":null}]`, string(result.JSON()))\n\t})\n\n\tt.Run(\"csv\", func(t *testing.T) {\n\t\texpected := \"id,title,author_id,subject_id\\n156,The Tell-Tale Heart,115,9\\n\"\n\n\t\tres, err := testClient.Query(\"SELECT * FROM books ORDER BY id ASC LIMIT 1\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, expected, string(res.CSV()))\n\t})\n}\n\nfunc testHistory(t *testing.T) {\n\tt.Run(\"success\", func(t *testing.T) {\n\t\t_, err := testClient.Query(\"SELECT * FROM books WHERE id = 12345\")\n\t\tquery := testClient.History[len(testClient.History)-1].Query\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"SELECT * FROM books WHERE id = 12345\", query)\n\t})\n\n\tt.Run(\"failed query\", func(t *testing.T) {\n\t\t_, err := testClient.Query(\"SELECT * FROM books123\")\n\t\tquery := testClient.History[len(testClient.History)-1].Query\n\t\tassert.NotNil(t, err)\n\t\tassert.NotEqual(t, \"SELECT * FROM books123\", query)\n\t})\n\n\tt.Run(\"unique queries\", func(t *testing.T) {\n\t\turl := fmt.Sprintf(\"postgres://%s@%s:%s/%s?sslmode=disable\", serverUser, serverHost, serverPort, serverDatabase)\n\n\t\tclient, _ := NewFromUrl(url, nil)\n\t\tdefer client.Close()\n\n\t\tfor i := 0; i < 3; i++ {\n\t\t\t_, err := client.Query(\"SELECT * FROM books WHERE id = 1\")\n\t\t\tassert.NoError(t, err)\n\t\t}\n\n\t\tassert.Equal(t, 1, len(client.History))\n\t\tassert.Equal(t, \"SELECT * FROM books WHERE id = 1\", client.History[0].Query)\n\t})\n}\n\nfunc testReadOnlyMode(t *testing.T) {\n\tcommand.Opts.ReadOnly = true\n\tdefer func() {\n\t\tcommand.Opts.ReadOnly = false\n\t}()\n\n\turl := fmt.Sprintf(\"postgres://%s@%s:%s/%s?sslmode=disable\", serverUser, serverHost, serverPort, serverDatabase)\n\tclient, _ := NewFromUrl(url, nil)\n\tdefer client.Close()\n\n\terr := client.SetReadOnlyMode()\n\tassert.NoError(t, err)\n\n\t_, err = client.Query(\"\\nCREATE TABLE foobar(id integer);\\n\")\n\tassert.NotNil(t, err)\n\tassert.Error(t, err, \"query contains keywords not allowed in read-only mode\")\n\n\t// Turn off guard\n\t_, err = client.db.Exec(\"SET default_transaction_read_only=off;\")\n\tassert.NoError(t, err)\n\n\t_, err = client.Query(\"\\nCREATE TABLE foobar(id integer);\\n\")\n\tassert.NotNil(t, err)\n\tassert.Contains(t, err.Error(), \"query contains keywords not allowed in read-only mode\")\n\n\t_, err = client.Query(\"-- CREATE TABLE foobar(id integer);\\nSELECT 'foo';\")\n\tassert.NoError(t, err)\n\n\t_, err = client.Query(\"/* CREATE TABLE foobar(id integer); */ SELECT 'foo';\")\n\tassert.NoError(t, err)\n\n\tt.Run(\"with local readonly flag\", func(t *testing.T) {\n\t\tcommand.Opts.ReadOnly = false\n\t\tclient.readonly = true\n\n\t\t_, err := client.Query(\"INSERT INTO foobar(id) VALUES(1)\")\n\t\tassert.Error(t, err, \"query contains keywords not allowed in read-only mode\")\n\t})\n}\n\nfunc testTablesStats(t *testing.T) {\n\tcolumns := []string{\n\t\t\"schema_name\",\n\t\t\"table_name\",\n\t\t\"total_size\",\n\t\t\"data_size\",\n\t\t\"index_size\",\n\t\t\"estimated_rows_count\",\n\t\t\"estimated_rows\",\n\t\t\"index_to_data_ratio\",\n\t\t\"indexes_count\",\n\t\t\"columns_count\",\n\t}\n\n\tresult, err := testClient.TablesStats()\n\tassert.NoError(t, err)\n\tassert.Equal(t, columns, result.Columns)\n}\n\nfunc testConnContext(t *testing.T) {\n\tresult, err := testClient.GetConnContext()\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"localhost\", result.Host)\n\tassert.Equal(t, \"postgres\", result.User)\n\tassert.Equal(t, \"booktown\", result.Database)\n\tassert.Equal(t, \"default\", result.Mode)\n}\n\nfunc testServerSettings(t *testing.T) {\n\texpectedColumns := []string{\n\t\t\"name\",\n\t\t\"setting\",\n\t\t\"unit\",\n\t\t\"category\",\n\t\t\"short_desc\",\n\t\t\"extra_desc\",\n\t\t\"context\",\n\t\t\"vartype\",\n\t\t\"source\",\n\t\t\"min_val\",\n\t\t\"max_val\",\n\t\t\"enumvals\",\n\t\t\"boot_val\",\n\t\t\"reset_val\",\n\t\t\"sourcefile\",\n\t\t\"sourceline\",\n\t\t\"pending_restart\",\n\t}\n\n\tresult, err := testClient.ServerSettings()\n\tassert.NoError(t, err)\n\tassert.Equal(t, expectedColumns, result.Columns)\n}\n\nfunc TestAll(t *testing.T) {\n\tif onWindows() {\n\t\tt.Log(\"Unit testing on Windows platform is not supported.\")\n\t\treturn\n\t}\n\n\tinitVars()\n\tsetupCommands()\n\tteardown(t, false)\n\tsetup()\n\tsetupClient()\n\n\ttestNewClientFromURL(t)\n\ttestClientIdleTime(t)\n\ttestTest(t)\n\ttestInfo(t)\n\ttestActivity(t)\n\ttestDatabases(t)\n\ttestSchemas(t)\n\ttestObjects(t)\n\ttestTable(t)\n\ttestTableRows(t)\n\ttestTableInfo(t)\n\ttestEstimatedTableRowsCount(t)\n\ttestTableRowsCount(t)\n\ttestTableRowsCountWithLargeTable(t)\n\ttestTableIndexes(t)\n\ttestTableConstraints(t)\n\ttestTableNameWithCamelCase(t)\n\ttestQuery(t)\n\ttestUpdateQuery(t)\n\ttestTableRowsOrderEscape(t)\n\ttestFunctions(t)\n\ttestResult(t)\n\ttestHistory(t)\n\ttestReadOnlyMode(t)\n\ttestDumpExport(t)\n\ttestTablesStats(t)\n\ttestConnContext(t)\n\ttestServerSettings(t)\n\n\tteardownClient()\n\tteardown(t, true)\n}\n"
  },
  {
    "path": "pkg/client/codec.go",
    "content": "package client\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\n\t\"github.com/mr-tron/base58\"\n)\n\nconst (\n\tCodecNone   = \"none\"\n\tCodecHex    = \"hex\"\n\tCodecBase58 = \"base58\"\n\tCodecBase64 = \"base64\"\n)\n\nvar (\n\t// BinaryCodec sets the serialization format of binary data\n\tBinaryCodec = CodecBase64\n)\n\nfunc SetBinaryCodec(codec string) error {\n\tswitch codec {\n\tcase CodecNone, CodecHex, CodecBase58, CodecBase64:\n\t\tBinaryCodec = codec\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid binary codec: %v\", codec)\n\t}\n\n\treturn nil\n}\n\nfunc encodeBinaryData(data []byte, codec string) string {\n\tswitch codec {\n\tcase CodecHex:\n\t\treturn hex.EncodeToString(data)\n\tcase CodecBase58:\n\t\treturn base58.Encode(data)\n\tcase CodecBase64:\n\t\treturn base64.StdEncoding.EncodeToString(data)\n\tdefault:\n\t\treturn string(data)\n\t}\n}\n"
  },
  {
    "path": "pkg/client/codec_test.go",
    "content": "package client\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestSetBinaryCodec(t *testing.T) {\n\texamples := []struct {\n\t\tinput string\n\t\terr   error\n\t}{\n\t\t{input: CodecNone, err: nil},\n\t\t{input: CodecBase58, err: nil},\n\t\t{input: CodecBase64, err: nil},\n\t\t{input: CodecHex, err: nil},\n\t\t{input: \"foobar\", err: errors.New(\"invalid binary codec: foobar\")},\n\t}\n\n\tfor _, ex := range examples {\n\t\tt.Run(ex.input, func(t *testing.T) {\n\t\t\tval := BinaryCodec\n\t\t\tdefer func() {\n\t\t\t\tBinaryCodec = val\n\t\t\t}()\n\n\t\t\tassert.Equal(t, ex.err, SetBinaryCodec(ex.input))\n\t\t})\n\t}\n}\n\nfunc Test_encodeBinaryData(t *testing.T) {\n\texamples := []struct {\n\t\tinput    string\n\t\texpected string\n\t\tencoding string\n\t}{\n\t\t{input: \"hello world\", expected: \"hello world\", encoding: CodecNone},\n\t\t{input: \"hello world\", expected: \"StV1DL6CwTryKyV\", encoding: CodecBase58},\n\t\t{input: \"hello world\", expected: \"aGVsbG8gd29ybGQ=\", encoding: CodecBase64},\n\t\t{input: \"hello world\", expected: \"68656c6c6f20776f726c64\", encoding: CodecHex},\n\t}\n\n\tfor _, ex := range examples {\n\t\tt.Run(ex.input, func(t *testing.T) {\n\t\t\tassert.Equal(t, ex.expected, encodeBinaryData([]byte(ex.input), ex.encoding))\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/client/dump.go",
    "content": "package client\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/url\"\n\t\"os/exec\"\n\t\"strings\"\n)\n\nvar (\n\tunsupportedDumpOptions = []string{\n\t\t\"search_path\",\n\t}\n)\n\n// Dump represents a database dump\ntype Dump struct {\n\tTable string\n}\n\n// Validate checks availability and version of pg_dump CLI\nfunc (d *Dump) Validate(serverVersion string) error {\n\tout := bytes.NewBuffer(nil)\n\n\tcmd := exec.Command(\"pg_dump\", \"--version\")\n\tcmd.Stdout = out\n\tcmd.Stderr = out\n\n\tif err := cmd.Run(); err != nil {\n\t\treturn fmt.Errorf(\"pg_dump command failed: %s\", out.Bytes())\n\t}\n\n\tdetected, dumpVersion := detectDumpVersion(out.String())\n\tif detected && serverVersion != \"\" {\n\t\tsatisfied := checkVersionRequirement(dumpVersion, serverVersion)\n\t\tif !satisfied {\n\t\t\treturn fmt.Errorf(\"pg_dump version %v not compatible with server version %v\", dumpVersion, serverVersion)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Export streams the database dump to the specified writer\nfunc (d *Dump) Export(ctx context.Context, connstr string, writer io.Writer) error {\n\tif str, err := removeUnsupportedOptions(connstr); err != nil {\n\t\treturn err\n\t} else {\n\t\tconnstr = str\n\t}\n\n\topts := []string{\n\t\t\"--no-owner\",      // skip restoration of object ownership in plain-text format\n\t\t\"--clean\",         // clean (drop) database objects before recreating\n\t\t\"--compress\", \"6\", // compression level for compressed formats\n\t}\n\n\tif d.Table != \"\" {\n\t\topts = append(opts, []string{\"--table\", d.Table}...)\n\t}\n\n\topts = append(opts, connstr)\n\terrOutput := bytes.NewBuffer(nil)\n\n\tcmd := exec.CommandContext(ctx, \"pg_dump\", opts...)\n\tcmd.Stdout = writer\n\tcmd.Stderr = errOutput\n\n\tif err := cmd.Run(); err != nil {\n\t\treturn fmt.Errorf(\"error: %s. output: %s\", err.Error(), errOutput.Bytes())\n\t}\n\treturn nil\n}\n\n// removeUnsupportedOptions removes any options unsupported for making a db dump\nfunc removeUnsupportedOptions(input string) (string, error) {\n\turi, err := url.Parse(input)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tq := uri.Query()\n\tfor _, opt := range unsupportedDumpOptions {\n\t\tq.Del(opt)\n\t\tq.Del(strings.ToUpper(opt))\n\t}\n\turi.RawQuery = q.Encode()\n\n\treturn uri.String(), nil\n}\n"
  },
  {
    "path": "pkg/client/dump_test.go",
    "content": "package client\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc testDumpExport(t *testing.T) {\n\turl := fmt.Sprintf(\"postgres://%s@%s:%s/%s?sslmode=disable\", serverUser, serverHost, serverPort, serverDatabase)\n\n\tsavePath := \"/tmp/dump.sql.gz\"\n\tos.Remove(savePath)\n\n\tsaveFile, err := os.Create(savePath)\n\tif err != nil {\n\t\tt.Fatal(err.Error())\n\t}\n\n\tdefer func() {\n\t\tsaveFile.Close()\n\t\tos.Remove(savePath)\n\t}()\n\n\tdump := Dump{}\n\n\t// Test for pg_dump presence\n\tassert.NoError(t, dump.Validate(\"10.0\"))\n\tassert.NoError(t, dump.Validate(\"\"))\n\tassert.Contains(t, dump.Validate(\"20\").Error(), \"not compatible with server version 20\")\n\n\t// Test full db dump\n\terr = dump.Export(context.Background(), url, saveFile)\n\tassert.NoError(t, err)\n\n\t// Test nonexistent database\n\tinvalidURL := fmt.Sprintf(\"postgres://%s@%s:%s/%s?sslmode=disable\", serverUser, serverHost, serverPort, \"foobar\")\n\terr = dump.Export(context.Background(), invalidURL, saveFile)\n\tassert.Contains(t, err.Error(), `database \"foobar\" does not exist`)\n\n\t// Test dump of non existent db\n\tdump = Dump{Table: \"foobar\"}\n\terr = dump.Export(context.Background(), url, saveFile)\n\tassert.NotNil(t, err)\n\tassert.Contains(t, err.Error(), \"no matching tables were found\")\n\n\t// Should drop \"search_path\" param from URI\n\tdump = Dump{}\n\tsearchPathURL := fmt.Sprintf(\"postgres://%s@%s:%s/%s?sslmode=disable&search_path=private\", serverUser, serverHost, serverPort, serverDatabase)\n\terr = dump.Export(context.Background(), searchPathURL, saveFile)\n\tassert.NoError(t, err)\n}\n"
  },
  {
    "path": "pkg/client/result.go",
    "content": "package client\n\nimport (\n\t\"bytes\"\n\t\"encoding/csv\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"math\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n)\n\nconst (\n\tObjTypeTable            = \"table\"\n\tObjTypeView             = \"view\"\n\tObjTypeMaterializedView = \"materialized_view\"\n\tObjTypeSequence         = \"sequence\"\n\tObjTypeFunction         = \"function\"\n)\n\ntype (\n\t// Row represents a single row of data\n\tRow []interface{}\n\n\t// RowsOptions contains a list of parameters for table browsing requests\n\tRowsOptions struct {\n\t\tWhere      string // Custom filter\n\t\tOffset     int    // Number of rows to skip\n\t\tLimit      int    // Number of rows to fetch\n\t\tSortColumn string // Column to sort by\n\t\tSortOrder  string // Sort direction (ASC, DESC)\n\t}\n\n\tPagination struct {\n\t\tRows    int64 `json:\"rows_count\"`\n\t\tPage    int64 `json:\"page\"`\n\t\tPages   int64 `json:\"pages_count\"`\n\t\tPerPage int64 `json:\"per_page\"`\n\t}\n\n\tResult struct {\n\t\tPagination *Pagination  `json:\"pagination,omitempty\"`\n\t\tColumns    []string     `json:\"columns\"`\n\t\tRows       []Row        `json:\"rows\"`\n\t\tStats      *ResultStats `json:\"stats,omitempty\"`\n\t}\n\n\tResultStats struct {\n\t\tColumnsCount    int       `json:\"columns_count\"`\n\t\tRowsCount       int       `json:\"rows_count\"`\n\t\tRowsAffected    int64     `json:\"rows_affected\"`\n\t\tQueryStartTime  time.Time `json:\"query_start_time\"`\n\t\tQueryFinishTime time.Time `json:\"query_finish_time\"`\n\t\tQueryDuration   int64     `json:\"query_duration_ms\"`\n\t}\n\n\tObject struct {\n\t\tOID  string `json:\"oid\"`\n\t\tName string `json:\"name\"`\n\t}\n\n\tObjects struct {\n\t\tTables            []Object `json:\"table\"`\n\t\tViews             []Object `json:\"view\"`\n\t\tMaterializedViews []Object `json:\"materialized_view\"`\n\t\tFunctions         []Object `json:\"function\"`\n\t\tSequences         []Object `json:\"sequence\"`\n\t}\n)\n\n// Due to big int number limitations in javascript, numbers should be encoded\n// as strings so they could be properly loaded on the frontend.\nfunc (res *Result) PostProcess() {\n\tfor i, row := range res.Rows {\n\t\tfor j, col := range row {\n\t\t\tif col == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tswitch val := col.(type) {\n\t\t\tcase int64:\n\t\t\t\tif val < -9007199254740991 || val > 9007199254740991 {\n\t\t\t\t\tres.Rows[i][j] = strconv.FormatInt(col.(int64), 10)\n\t\t\t\t}\n\t\t\tcase float64:\n\t\t\t\t// json.Marshal panics when dealing with NaN/Inf values\n\t\t\t\t// issue: https://github.com/golang/go/issues/25721\n\t\t\t\tif math.IsNaN(val) {\n\t\t\t\t\tres.Rows[i][j] = nil\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif val < -999999999999999 || val > 999999999999999 {\n\t\t\t\t\tres.Rows[i][j] = strconv.FormatFloat(val, 'e', -1, 64)\n\t\t\t\t}\n\t\t\tcase string:\n\t\t\t\tif hasBinary(val, 8) && BinaryCodec != CodecNone {\n\t\t\t\t\tres.Rows[i][j] = encodeBinaryData([]byte(val), BinaryCodec)\n\t\t\t\t}\n\t\t\tcase time.Time:\n\t\t\t\t// RFC 3339 is clear that years are 4 digits exactly.\n\t\t\t\t// See golang.org/issue/4556#c15 for more discussion.\n\t\t\t\tif val.Year() < 0 || val.Year() >= 10000 {\n\t\t\t\t\tres.Rows[i][j] = \"ERR: INVALID_DATE\"\n\t\t\t\t} else {\n\t\t\t\t\tres.Rows[i][j] = val\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (res *Result) Format() []map[string]interface{} {\n\titems := make([]map[string]interface{}, len(res.Rows))\n\n\tfor rowIdx, row := range res.Rows {\n\t\titem := make(map[string]interface{})\n\t\tfor i, c := range res.Columns {\n\t\t\titem[c] = row[i]\n\t\t}\n\n\t\titems[rowIdx] = item\n\t}\n\n\treturn items\n}\n\nfunc (res *Result) CSV() []byte {\n\tbuff := &bytes.Buffer{}\n\twriter := csv.NewWriter(buff)\n\n\tif err := writer.Write(res.Columns); err != nil {\n\t\tlog.Printf(\"result csv write error: %v\\n\", err)\n\t}\n\n\tfor _, row := range res.Rows {\n\t\trecord := make([]string, len(res.Columns))\n\n\t\tfor i, item := range row {\n\t\t\tswitch v := item.(type) {\n\t\t\tcase time.Time:\n\t\t\t\trecord[i] = v.Format(\"2006-01-02 15:04:05\")\n\t\t\tcase nil:\n\t\t\t\trecord[i] = \"\"\n\t\t\tdefault:\n\t\t\t\trecord[i] = fmt.Sprintf(\"%v\", item)\n\t\t\t}\n\t\t}\n\n\t\terr := writer.Write(record)\n\t\tif err != nil {\n\t\t\tfmt.Println(err)\n\t\t\tbreak\n\t\t}\n\t}\n\n\twriter.Flush()\n\treturn buff.Bytes()\n}\n\nfunc (res *Result) JSON() []byte {\n\tvar data []byte\n\n\tif command.Opts.DisablePrettyJSON {\n\t\tdata, _ = json.Marshal(res.Format())\n\t} else {\n\t\tdata, _ = json.MarshalIndent(res.Format(), \"\", \" \")\n\t}\n\n\treturn data\n}\n\nfunc ObjectsFromResult(res *Result) map[string]*Objects {\n\tobjects := map[string]*Objects{}\n\n\tfor _, row := range res.Rows {\n\t\toid := row[0].(string)\n\t\tschema := row[1].(string)\n\t\tname := row[2].(string)\n\t\tobjectType := row[3].(string)\n\n\t\tif objects[schema] == nil {\n\t\t\tobjects[schema] = &Objects{\n\t\t\t\tTables:            []Object{},\n\t\t\t\tViews:             []Object{},\n\t\t\t\tMaterializedViews: []Object{},\n\t\t\t\tFunctions:         []Object{},\n\t\t\t\tSequences:         []Object{},\n\t\t\t}\n\t\t}\n\n\t\tobj := Object{OID: oid, Name: name}\n\n\t\tswitch objectType {\n\t\tcase ObjTypeTable:\n\t\t\tobjects[schema].Tables = append(objects[schema].Tables, obj)\n\t\tcase ObjTypeView:\n\t\t\tobjects[schema].Views = append(objects[schema].Views, obj)\n\t\tcase ObjTypeMaterializedView:\n\t\t\tobjects[schema].MaterializedViews = append(objects[schema].MaterializedViews, obj)\n\t\tcase ObjTypeFunction:\n\t\t\tobjects[schema].Functions = append(objects[schema].Functions, obj)\n\t\tcase ObjTypeSequence:\n\t\t\tobjects[schema].Sequences = append(objects[schema].Sequences, obj)\n\t\t}\n\t}\n\n\treturn objects\n}\n"
  },
  {
    "path": "pkg/client/result_test.go",
    "content": "package client\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestPostProcess(t *testing.T) {\n\tt.Run(\"large numbers\", func(t *testing.T) {\n\t\tresult := Result{\n\t\t\tColumns: []string{\"value\"},\n\t\t\tRows: []Row{\n\t\t\t\t{int(1234)},\n\t\t\t\t{int64(9223372036854775807)},\n\t\t\t\t{int64(-9223372036854775808)},\n\t\t\t\t{float64(9223372036854775808.9223372036854775808)},\n\t\t\t\t{float64(999999999999999.9)},\n\t\t\t},\n\t\t}\n\n\t\tresult.PostProcess()\n\n\t\tassert.Equal(t, 1234, result.Rows[0][0])\n\t\tassert.Equal(t, \"9223372036854775807\", result.Rows[1][0])\n\t\tassert.Equal(t, \"-9223372036854775808\", result.Rows[2][0])\n\t\tassert.Equal(t, \"9.223372036854776e+18\", result.Rows[3][0])\n\t\tassert.Equal(t, \"9.999999999999999e+14\", result.Rows[4][0])\n\t})\n\n\tt.Run(\"binary encoding\", func(t *testing.T) {\n\t\tresult := Result{\n\t\t\tColumns: []string{\"data\"},\n\t\t\tRows: []Row{\n\t\t\t\t{\"text value\"},\n\t\t\t\t{\"text with symbols !@#$%\"},\n\t\t\t\t{string([]byte{10, 11, 12, 13})},\n\t\t\t},\n\t\t}\n\n\t\tresult.PostProcess()\n\n\t\tassert.Equal(t, \"text value\", result.Rows[0][0])\n\t\tassert.Equal(t, \"text with symbols !@#$%\", result.Rows[1][0])\n\t\tassert.Equal(t, \"CgsMDQ==\", result.Rows[2][0])\n\t})\n}\n\nfunc TestCSV(t *testing.T) {\n\tresult := Result{\n\t\tColumns: []string{\"id\", \"name\", \"email\", \"extra\"},\n\t\tRows: []Row{\n\t\t\t{1, \"John\", \"john@example.com\", \"data\"},\n\t\t\t{2, \"Bob\", \"bob@example.com\", nil},\n\t\t},\n\t}\n\n\texpected := strings.Join([]string{\n\t\t\"id,name,email,extra\",\n\t\t\"1,John,john@example.com,data\",\n\t\t\"2,Bob,bob@example.com,\",\n\t}, \"\\n\") + \"\\n\"\n\n\tassert.Equal(t, expected, string(result.CSV()))\n}\n\nfunc TestJSON(t *testing.T) {\n\tresult := Result{\n\t\tColumns: []string{\"id\", \"name\", \"email\"},\n\t\tRows: []Row{\n\t\t\t{1, \"John\", \"john@example.com\"},\n\t\t\t{2, \"Bob\", \"bob@example.com\"},\n\t\t},\n\t}\n\n\tobj := []struct {\n\t\tId    int\n\t\tName  string\n\t\tEmail string\n\t}{}\n\n\texpected := []struct {\n\t\tId    int\n\t\tName  string\n\t\tEmail string\n\t}{\n\t\t{1, \"John\", \"john@example.com\"},\n\t\t{2, \"Bob\", \"bob@example.com\"},\n\t}\n\n\tassert.NoError(t, json.Unmarshal(result.JSON(), &obj))\n\tassert.Equal(t, 2, len(obj))\n\tassert.Equal(t, expected, obj)\n\n\tt.Run(\"invalid time\", func(t *testing.T) {\n\t\tloc, err := time.LoadLocation(\"UTC\")\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tcommand.Opts.DisablePrettyJSON = true\n\t\tdefer func() {\n\t\t\tcommand.Opts.DisablePrettyJSON = false\n\t\t}()\n\n\t\tresult := Result{\n\t\t\tColumns: []string{\"value\"},\n\t\t\tRows: []Row{\n\t\t\t\t{time.Unix(1640995200, 0).In(loc)},\n\t\t\t\t{time.Unix(222539616000, 0).In(loc)},\n\t\t\t\t{time.Unix(254096611200, 0).In(loc)},\n\t\t\t},\n\t\t}\n\n\t\tresult.PostProcess()\n\t\tassert.Equal(t, `[{\"value\":\"2022-01-01T00:00:00Z\"},{\"value\":\"9022-01-01T00:00:00Z\"},{\"value\":\"ERR: INVALID_DATE\"}]`, string(result.JSON()))\n\t})\n}\n\nfunc TestResultFormat(t *testing.T) {\n\tresult := Result{\n\t\tColumns: []string{\"col1\", \"col2\", \"col3\", \"col4\"},\n\t\tRows: []Row{\n\t\t\t{\"1\", \"2\", \"3\", nil},\n\t\t\t{\"4\", \"5\", \"6\", nil},\n\t\t},\n\t}\n\n\texpected := []map[string]interface{}{\n\t\t{\"col1\": \"1\", \"col2\": \"2\", \"col3\": \"3\", \"col4\": nil},\n\t\t{\"col1\": \"4\", \"col2\": \"5\", \"col3\": \"6\", \"col4\": nil},\n\t}\n\n\tassert.Equal(t, expected, result.Format())\n}\n"
  },
  {
    "path": "pkg/client/tunnel.go",
    "content": "package client\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"net\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/ScaleFT/sshkeys\"\n\t\"golang.org/x/crypto/ssh\"\n\n\t\"github.com/sosedoff/pgweb/pkg/connection\"\n\t\"github.com/sosedoff/pgweb/pkg/shared\"\n)\n\nconst (\n\tportStart = 29168\n\tportLimit = 500\n)\n\n// Tunnel represents the connection between local and remote server\ntype Tunnel struct {\n\tTargetHost string\n\tTargetPort string\n\tPort       int\n\tSSHInfo    *shared.SSHInfo\n\tConfig     *ssh.ClientConfig\n\tClient     *ssh.Client\n\tListener   *net.TCPListener\n}\n\nfunc defaultKeyPath() string {\n\treturn filepath.Join(os.Getenv(\"HOME\"), \".ssh/id_rsa\")\n}\n\nfunc expandKeyPath(path string) string {\n\thome := os.Getenv(\"HOME\")\n\tif home == \"\" {\n\t\treturn path\n\t}\n\treturn strings.Replace(path, \"~\", home, 1)\n}\n\nfunc fileExists(path string) bool {\n\t_, err := os.Stat(path)\n\treturn err == nil\n}\n\nfunc parsePrivateKey(keyPath string, keyPass string) (ssh.Signer, error) {\n\tbuff, err := os.ReadFile(keyPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsigner, err := ssh.ParsePrivateKey(buff)\n\tif _, ok := err.(*ssh.PassphraseMissingError); ok {\n\t\tif keyPass == \"\" {\n\t\t\treturn nil, errors.New(\"ssh key password is not provided\")\n\t\t}\n\t\treturn sshkeys.ParseEncryptedPrivateKey(buff, []byte(keyPass))\n\t}\n\n\treturn signer, err\n}\n\nfunc makeConfig(info *shared.SSHInfo) (*ssh.ClientConfig, error) {\n\tmethods := []ssh.AuthMethod{}\n\n\t// Try to use user-provided key, fallback to system default key\n\tkeyPath := info.Key\n\tif keyPath == \"\" {\n\t\tkeyPath = defaultKeyPath()\n\t} else {\n\t\tkeyPath = expandKeyPath(keyPath)\n\t}\n\n\tif !fileExists(keyPath) {\n\t\treturn nil, fmt.Errorf(\"ssh public key not found at path %q\", keyPath)\n\t}\n\n\t// Append public key authentication method\n\tkey, err := parsePrivateKey(keyPath, info.KeyPassword)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmethods = append(methods, ssh.PublicKeys(key))\n\n\t// Append password authentication method\n\tif info.Password != \"\" {\n\t\tmethods = append(methods, ssh.Password(info.Password))\n\t}\n\n\tcfg := &ssh.ClientConfig{\n\t\tUser:    info.User,\n\t\tAuth:    methods,\n\t\tTimeout: time.Second * 10,\n\t\tHostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {\n\t\t\treturn nil\n\t\t},\n\t}\n\n\treturn cfg, nil\n}\n\nfunc (tunnel *Tunnel) sshEndpoint() string {\n\treturn fmt.Sprintf(\"%s:%v\", tunnel.SSHInfo.Host, tunnel.SSHInfo.Port)\n}\n\nfunc (tunnel *Tunnel) targetEndpoint() string {\n\treturn fmt.Sprintf(\"%v:%v\", tunnel.TargetHost, tunnel.TargetPort)\n}\n\nfunc (tunnel *Tunnel) copy(wg *sync.WaitGroup, writer, reader net.Conn) {\n\tdefer wg.Done()\n\tif _, err := io.Copy(writer, reader); err != nil {\n\t\tlog.Println(\"Tunnel copy error:\", err)\n\t}\n}\n\nfunc (tunnel *Tunnel) handleConnection(local net.Conn) {\n\tremote, err := tunnel.Client.Dial(\"tcp\", tunnel.targetEndpoint())\n\tif err != nil {\n\t\treturn\n\t}\n\n\twg := &sync.WaitGroup{}\n\twg.Add(2)\n\n\tgo tunnel.copy(wg, local, remote)\n\tgo tunnel.copy(wg, remote, local)\n\n\twg.Wait()\n\tlocal.Close()\n}\n\n// Close closes the tunnel connection\nfunc (tunnel *Tunnel) Close() {\n\tif tunnel.Client != nil {\n\t\ttunnel.Client.Close()\n\t}\n\n\tif tunnel.Listener != nil {\n\t\ttunnel.Listener.Close()\n\t}\n}\n\n// Configure establishes the tunnel between localhost and remote machine\nfunc (tunnel *Tunnel) Configure() error {\n\tconfig, err := makeConfig(tunnel.SSHInfo)\n\tif err != nil {\n\t\treturn err\n\t}\n\ttunnel.Config = config\n\n\tclient, err := ssh.Dial(\"tcp\", tunnel.sshEndpoint(), config)\n\tif err != nil {\n\t\treturn err\n\t}\n\ttunnel.Client = client\n\n\tlistener, err := net.Listen(\"tcp\", fmt.Sprintf(\"127.0.0.1:%v\", tunnel.Port))\n\tif err != nil {\n\t\treturn err\n\t}\n\ttunnel.Listener = listener.(*net.TCPListener)\n\n\treturn nil\n}\n\n// Start starts the connection handler loop\nfunc (tunnel *Tunnel) Start() {\n\tdefer tunnel.Close()\n\n\tfor {\n\t\tconn, err := tunnel.Listener.Accept()\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\n\t\tgo tunnel.handleConnection(conn)\n\t}\n}\n\n// NewTunnel instantiates a new tunnel struct from given ssh info\nfunc NewTunnel(sshInfo *shared.SSHInfo, dbUrl string) (*Tunnel, error) {\n\turi, err := url.Parse(dbUrl)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlistenPort, err := connection.FindAvailablePort(portStart, portLimit)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tchunks := strings.Split(uri.Host, \":\")\n\thost := chunks[0]\n\tport := \"5432\"\n\n\tif len(chunks) == 2 {\n\t\tport = chunks[1]\n\t}\n\n\ttunnel := &Tunnel{\n\t\tPort:       listenPort,\n\t\tSSHInfo:    sshInfo,\n\t\tTargetHost: host,\n\t\tTargetPort: port,\n\t}\n\n\treturn tunnel, nil\n}\n"
  },
  {
    "path": "pkg/client/util.go",
    "content": "package client\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n)\n\nvar (\n\t// List of keywords that are not allowed in read-only mode\n\treRestrictedKeywords = regexp.MustCompile(`(?mi)\\s?(CREATE|INSERT|UPDATE|DROP|DELETE|TRUNCATE|GRANT|OPEN|IMPORT|COPY)\\s`)\n\n\t// Comment regular expressions\n\treSlashComment = regexp.MustCompile(`(?m)/\\*.+\\*/`)\n\treDashComment  = regexp.MustCompile(`(?m)--.+`)\n\n\t// Postgres version signature\n\tpostgresSignature     = regexp.MustCompile(`(?i)postgresql ([\\d\\.]+)\\s?`)\n\tpostgresDumpSignature = regexp.MustCompile(`\\s([\\d\\.]+)\\s?`)\n\tpostgresType          = \"PostgreSQL\"\n\n\t// Cockroach version signature\n\tcockroachSignature = regexp.MustCompile(`(?i)cockroachdb ccl v([\\d\\.]+)\\s?`)\n\tcockroachType      = \"CockroachDB\"\n)\n\n// Get major and minor version components\n// Example: 10.2.3.1 -> 10.2\nfunc getMajorMinorVersion(str string) (major int, minor int) {\n\tchunks := strings.Split(str, \".\")\n\tfmt.Sscanf(chunks[0], \"%d\", &major) //nolint\n\tif len(chunks) > 1 {\n\t\tfmt.Sscanf(chunks[1], \"%d\", &minor) //nolint\n\t}\n\treturn\n}\n\n// Get short version from the string\n// Example: 10.2.3.1 -> 10.2\nfunc getMajorMinorVersionString(str string) string {\n\tmajor, minor := getMajorMinorVersion(str)\n\treturn fmt.Sprintf(\"%d.%d\", major, minor)\n}\n\nfunc detectServerTypeAndVersion(version string) (bool, string, string) {\n\tversion = strings.TrimSpace(version)\n\n\t// Detect postgresql\n\tmatches := postgresSignature.FindAllStringSubmatch(version, 1)\n\tif len(matches) > 0 {\n\t\treturn true, postgresType, matches[0][1]\n\t}\n\n\t// Detect cockroachdb\n\tmatches = cockroachSignature.FindAllStringSubmatch(version, 1)\n\tif len(matches) > 0 {\n\t\treturn true, cockroachType, matches[0][1]\n\t}\n\n\treturn false, \"\", \"\"\n}\n\n// detectDumpVersion parses out version from `pg_dump -V` command.\nfunc detectDumpVersion(version string) (bool, string) {\n\tmatches := postgresDumpSignature.FindAllStringSubmatch(version, 1)\n\tif len(matches) > 0 {\n\t\treturn true, matches[0][1]\n\t}\n\treturn false, \"\"\n}\n\nfunc checkVersionRequirement(client, server string) bool {\n\tclientMajor, clientMinor := getMajorMinorVersion(client)\n\tserverMajor, serverMinor := getMajorMinorVersion(server)\n\n\tif serverMajor < 10 {\n\t\treturn clientMajor >= serverMajor && clientMinor >= serverMinor\n\t}\n\n\treturn clientMajor >= serverMajor\n}\n\n// containsRestrictedKeywords returns true if given keyword is not allowed in read-only mode\nfunc containsRestrictedKeywords(str string) bool {\n\tstr = reSlashComment.ReplaceAllString(str, \"\")\n\tstr = reDashComment.ReplaceAllString(str, \"\")\n\n\treturn reRestrictedKeywords.MatchString(str)\n}\n\nfunc hasBinary(data string, checkLen int) bool {\n\tfor idx, chr := range data {\n\t\tif int(chr) < 32 || int(chr) > 126 {\n\t\t\treturn true\n\t\t}\n\t\tif idx >= checkLen {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "pkg/client/util_test.go",
    "content": "package client\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestDetectServerType(t *testing.T) {\n\texamples := []struct {\n\t\tinput      string\n\t\tmatch      bool\n\t\tserverType string\n\t\tversion    string\n\t}{\n\t\t{input: \"\",\n\t\t\tmatch:      false,\n\t\t\tserverType: \"\",\n\t\t\tversion:    \"\",\n\t\t},\n\t\t{\n\t\t\tinput:      \" postgresql 15 \",\n\t\t\tmatch:      true,\n\t\t\tserverType: postgresType,\n\t\t\tversion:    \"15\",\n\t\t},\n\t\t{\n\t\t\tinput:      \"PostgreSQL 14.5 (Homebrew) on aarch64-apple-darwin21.6.0\",\n\t\t\tmatch:      true,\n\t\t\tserverType: postgresType,\n\t\t\tversion:    \"14.5\",\n\t\t},\n\t\t{\n\t\t\tinput:      \"PostgreSQL 11.16, compiled by Visual C++ build 1800, 64-bit\",\n\t\t\tmatch:      true,\n\t\t\tserverType: postgresType,\n\t\t\tversion:    \"11.16\",\n\t\t},\n\t}\n\n\tfor _, ex := range examples {\n\t\tt.Run(\"input:\"+ex.input, func(t *testing.T) {\n\t\t\tmatch, stype, version := detectServerTypeAndVersion(ex.input)\n\n\t\t\tassert.Equal(t, ex.match, match)\n\t\t\tassert.Equal(t, ex.serverType, stype)\n\t\t\tassert.Equal(t, ex.version, version)\n\t\t})\n\t}\n}\n\nfunc TestDetectDumpVersion(t *testing.T) {\n\texamples := []struct {\n\t\tinput   string\n\t\tmatch   bool\n\t\tversion string\n\t}{\n\t\t{\"\", false, \"\"},\n\t\t{\"pg_dump (PostgreSQL) 9.6\", true, \"9.6\"},\n\t\t{\"pg_dump 10\", true, \"10\"},\n\t\t{\"pg_dump (PostgreSQL) 14.5 (Homebrew)\", true, \"14.5\"},\n\t}\n\n\tfor _, ex := range examples {\n\t\tt.Run(\"input:\"+ex.input, func(t *testing.T) {\n\t\t\tmatch, version := detectDumpVersion(ex.input)\n\n\t\t\tassert.Equal(t, ex.match, match)\n\t\t\tassert.Equal(t, ex.version, version)\n\t\t})\n\t}\n}\n\nfunc TestGetMajorMinorVersion(t *testing.T) {\n\texamples := []struct {\n\t\tinput string\n\t\tmajor int\n\t\tminor int\n\t}{\n\t\t{\"\", 0, 0},\n\t\t{\"   \", 0, 0},\n\t\t{\"0\", 0, 0},\n\t\t{\"9.6\", 9, 6},\n\t\t{\"9.6.1.1\", 9, 6},\n\t\t{\"10\", 10, 0},\n\t\t{\"10.1 \", 10, 1},\n\t}\n\n\tfor _, ex := range examples {\n\t\tt.Run(ex.input, func(t *testing.T) {\n\t\t\tmajor, minor := getMajorMinorVersion(ex.input)\n\t\t\tassert.Equal(t, ex.major, major)\n\t\t\tassert.Equal(t, ex.minor, minor)\n\t\t})\n\t}\n}\n\nfunc TestCheckVersionRequirement(t *testing.T) {\n\texamples := []struct {\n\t\tclient string\n\t\tserver string\n\t\tresult bool\n\t}{\n\t\t{\"\", \"\", true},\n\t\t{\"0\", \"0\", true},\n\t\t{\"9.6\", \"9.7\", false},\n\t\t{\"9.6.10\", \"9.6.25\", true},\n\t\t{\"10.0\", \"10.1\", true},\n\t\t{\"10.5\", \"10.1\", true},\n\t\t{\"14.5\", \"15.1\", false},\n\t}\n\n\tfor _, ex := range examples {\n\t\tassert.Equal(t, ex.result, checkVersionRequirement(ex.client, ex.server))\n\t}\n}\n"
  },
  {
    "path": "pkg/command/options.go",
    "content": "package command\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/user\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/jackc/pgpassfile\"\n\t\"github.com/jessevdk/go-flags\"\n\t\"github.com/mitchellh/go-homedir\"\n\t\"github.com/sirupsen/logrus\"\n)\n\nconst (\n\t// Prefix to use for all pgweb env vars, ie PGWEB_HOST, PGWEB_PORT, etc\n\tenvVarPrefix = \"PGWEB_\"\n)\n\ntype Options struct {\n\tVersion                      bool   `short:\"v\" long:\"version\" description:\"Print version\"`\n\tDebug                        bool   `short:\"d\" long:\"debug\" description:\"Enable debugging mode\"`\n\tLogLevel                     string `long:\"log-level\" description:\"Logging level\" default:\"info\"`\n\tLogFormat                    string `long:\"log-format\" description:\"Logging output format\" default:\"text\"`\n\tLogForwardedUser             bool   `long:\"log-forwarded-user\" description:\"Log user information available in X-Forwarded-User/Email headers\"`\n\tURL                          string `long:\"url\" description:\"Database connection string\"`\n\tHost                         string `long:\"host\" description:\"Server hostname or IP\" default:\"localhost\"`\n\tPort                         int    `long:\"port\" description:\"Server port\" default:\"5432\"`\n\tUser                         string `long:\"user\" description:\"Database user\"`\n\tPass                         string `long:\"pass\" description:\"Password for user\"`\n\tPassfile                     string `long:\"passfile\" description:\"Local passwords file location\"`\n\tDbName                       string `long:\"db\" description:\"Database name\"`\n\tSSLMode                      string `long:\"ssl\" description:\"SSL mode\"`\n\tSSLRootCert                  string `long:\"ssl-rootcert\" description:\"SSL certificate authority file\"`\n\tSSLCert                      string `long:\"ssl-cert\" description:\"SSL client certificate file\"`\n\tSSLKey                       string `long:\"ssl-key\" description:\"SSL client certificate key file\"`\n\tOpenTimeout                  int    `long:\"open-timeout\" description:\"Maximum wait time for connection, in seconds\" default:\"30\"`\n\tRetryDelay                   uint   `long:\"open-retry-delay\" description:\"Number of seconds to wait before retrying the connection\" default:\"3\"`\n\tRetryCount                   uint   `long:\"open-retry\" description:\"Number of times to retry establishing connection\" default:\"0\"`\n\tHTTPHost                     string `long:\"bind\" description:\"HTTP server host\" default:\"localhost\"`\n\tHTTPPort                     uint   `long:\"listen\" description:\"HTTP server listen port\" default:\"8081\"`\n\tAuthUser                     string `long:\"auth-user\" description:\"HTTP basic auth user\"`\n\tAuthPass                     string `long:\"auth-pass\" description:\"HTTP basic auth password\"`\n\tSkipOpen                     bool   `short:\"s\" long:\"skip-open\" description:\"Skip browser open on start\"`\n\tSessions                     bool   `long:\"sessions\" description:\"Enable multiple database sessions\"`\n\tPrefix                       string `long:\"prefix\" description:\"Add a url prefix\"`\n\tReadOnly                     bool   `long:\"readonly\" description:\"Run database connection in readonly mode\"`\n\tLockSession                  bool   `long:\"lock-session\" description:\"Lock session to a single database connection\"`\n\tBookmark                     string `short:\"b\" long:\"bookmark\" description:\"Bookmark to use for connection. Bookmark files are stored under $HOME/.pgweb/bookmarks/*.toml\" default:\"\"`\n\tBookmarksDir                 string `long:\"bookmarks-dir\" description:\"Overrides default directory for bookmark files to search\" default:\"\"`\n\tBookmarksOnly                bool   `long:\"bookmarks-only\" description:\"Allow only connections from bookmarks\"`\n\tQueriesDir                   string `long:\"queries-dir\" description:\"Overrides default directory for local queries\"`\n\tDisablePrettyJSON            bool   `long:\"no-pretty-json\" description:\"Disable JSON formatting feature for result export\"`\n\tDisableSSH                   bool   `long:\"no-ssh\" description:\"Disable database connections via SSH\"`\n\tConnectBackend               string `long:\"connect-backend\" description:\"Enable database authentication through a third party backend\"`\n\tConnectToken                 string `long:\"connect-token\" description:\"Authentication token for the third-party connect backend\"`\n\tConnectHeaders               string `long:\"connect-headers\" description:\"List of headers to pass to the connect backend\"`\n\tDisableConnectionIdleTimeout bool   `long:\"no-idle-timeout\" description:\"Disable connection idle timeout\"`\n\tConnectionIdleTimeout        int    `long:\"idle-timeout\" description:\"Set connection idle timeout in minutes\" default:\"180\"`\n\tQueryTimeout                 uint   `long:\"query-timeout\" description:\"Set global query execution timeout in seconds\" default:\"300\"`\n\tCors                         bool   `long:\"cors\" description:\"Enable Cross-Origin Resource Sharing (CORS)\"`\n\tCorsOrigin                   string `long:\"cors-origin\" description:\"Allowed CORS origins\" default:\"*\"`\n\tBinaryCodec                  string `long:\"binary-codec\" description:\"Codec for binary data serialization, one of 'none', 'hex', 'base58', 'base64'\" default:\"none\"`\n\tMetricsEnabled               bool   `long:\"metrics\" description:\"Enable Prometheus metrics endpoint\"`\n\tMetricsPath                  string `long:\"metrics-path\" description:\"Path prefix for Prometheus metrics endpoint\" default:\"/metrics\"`\n\tMetricsAddr                  string `long:\"metrics-addr\" description:\"Listen host and port for Prometheus metrics server\"`\n}\n\nvar Opts Options\n\n// ParseOptions returns a new options struct from the input arguments\nfunc ParseOptions(args []string) (Options, error) {\n\tvar opts = Options{}\n\n\t_, err := flags.ParseArgs(&opts, args)\n\tif err != nil {\n\t\treturn opts, err\n\t}\n\n\t_, err = logrus.ParseLevel(opts.LogLevel)\n\tif err != nil {\n\t\treturn opts, err\n\t}\n\n\tif opts.URL == \"\" {\n\t\topts.URL = getPrefixedEnvVar(\"DATABASE_URL\")\n\t}\n\n\tif opts.Prefix == \"\" {\n\t\topts.Prefix = getPrefixedEnvVar(\"URL_PREFIX\")\n\t}\n\n\tif opts.Passfile == \"\" {\n\t\tpassfile := os.Getenv(\"PGPASSFILE\")\n\t\tif passfile == \"\" {\n\t\t\tpassfile = filepath.Join(os.Getenv(\"HOME\"), \".pgpass\")\n\t\t}\n\n\t\t_, err := os.Stat(passfile)\n\t\tif err == nil {\n\t\t\t_, err = pgpassfile.ReadPassfile(passfile)\n\t\t\tif err == nil {\n\t\t\t\topts.Passfile = passfile\n\t\t\t} else {\n\t\t\t\tfmt.Printf(\"[WARN] Pgpass file unreadable: %s\\n\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Handle edge case where pgweb is started with a default host `localhost` and no user.\n\t// When user is not set the `lib/pq` connection will fail and cause pgweb's termination.\n\tif (opts.Host == \"localhost\" || opts.Host == \"127.0.0.1\") && opts.User == \"\" {\n\t\tif username := getCurrentUser(); username != \"\" {\n\t\t\topts.User = username\n\t\t} else {\n\t\t\topts.Host = \"\"\n\t\t}\n\t}\n\n\tif getPrefixedEnvVar(\"BOOKMARKS_ONLY\") != \"\" {\n\t\topts.BookmarksOnly = true\n\t}\n\n\tif getPrefixedEnvVar(\"SESSIONS\") != \"\" {\n\t\topts.Sessions = true\n\t}\n\n\tif getPrefixedEnvVar(\"LOCK_SESSION\") != \"\" {\n\t\topts.LockSession = true\n\t\topts.Sessions = false\n\t}\n\n\tif opts.Sessions || opts.ConnectBackend != \"\" {\n\t\topts.Bookmark = \"\"\n\t\topts.URL = \"\"\n\t\topts.Host = \"\"\n\t\topts.User = \"\"\n\t\topts.Pass = \"\"\n\t\topts.DbName = \"\"\n\t\topts.SSLMode = \"\"\n\t}\n\n\tif opts.Prefix != \"\" && !strings.HasSuffix(opts.Prefix, \"/\") {\n\t\topts.Prefix = opts.Prefix + \"/\"\n\t}\n\n\tif opts.AuthUser == \"\" {\n\t\topts.AuthUser = getPrefixedEnvVar(\"AUTH_USER\")\n\t}\n\n\tif opts.AuthPass == \"\" {\n\t\topts.AuthPass = getPrefixedEnvVar(\"AUTH_PASS\")\n\t}\n\n\tif opts.ConnectBackend != \"\" {\n\t\tif !opts.Sessions {\n\t\t\treturn opts, errors.New(\"--sessions flag must be set\")\n\t\t}\n\t\tif opts.ConnectToken == \"\" {\n\t\t\treturn opts, errors.New(\"--connect-token flag must be set\")\n\t\t}\n\t} else {\n\t\tif opts.ConnectToken != \"\" || opts.ConnectHeaders != \"\" {\n\t\t\treturn opts, errors.New(\"--connect-backend flag must be set\")\n\t\t}\n\t}\n\n\tif opts.BookmarksOnly {\n\t\tif opts.URL != \"\" {\n\t\t\treturn opts, errors.New(\"--url not supported in bookmarks-only mode\")\n\t\t}\n\t\tif opts.Host != \"\" && opts.Host != \"localhost\" {\n\t\t\treturn opts, errors.New(\"--host not supported in bookmarks-only mode\")\n\t\t}\n\t\tif opts.ConnectBackend != \"\" {\n\t\t\treturn opts, errors.New(\"--connect-backend not supported in bookmarks-only mode\")\n\t\t}\n\t}\n\n\tif opts.BookmarksDir == \"\" {\n\t\topts.BookmarksDir = getPrefixedEnvVar(\"BOOKMARKS_DIR\")\n\t}\n\n\thomePath, err := homedir.Dir()\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"[WARN] can't detect home dir: %v\", err)\n\t\thomePath = os.Getenv(\"HOME\")\n\t}\n\n\tif homePath != \"\" {\n\t\tif opts.BookmarksDir == \"\" {\n\t\t\topts.BookmarksDir = filepath.Join(homePath, \".pgweb/bookmarks\")\n\t\t}\n\n\t\tif opts.QueriesDir == \"\" {\n\t\t\topts.QueriesDir = filepath.Join(homePath, \".pgweb/queries\")\n\t\t}\n\t}\n\n\treturn opts, nil\n}\n\n// SetDefaultOptions parses and assigns the options\nfunc SetDefaultOptions() error {\n\topts, err := ParseOptions([]string{})\n\tif err != nil {\n\t\treturn err\n\t}\n\tOpts = opts\n\treturn nil\n}\n\n// getCurrentUser returns a current user name\nfunc getCurrentUser() string {\n\tu, _ := user.Current()\n\tif u != nil {\n\t\treturn u.Username\n\t}\n\treturn os.Getenv(\"USER\")\n}\n\n// getPrefixedEnvVar returns env var with prefix, or falls back to unprefixed one\nfunc getPrefixedEnvVar(name string) string {\n\tval := os.Getenv(envVarPrefix + name)\n\tif val == \"\" {\n\t\tval = os.Getenv(name)\n\t\tif val != \"\" {\n\t\t\tfmt.Printf(\"[DEPRECATION] Usage of %s env var is deprecated, please use PGWEB_%s variable instead\\n\", name, name)\n\t\t}\n\t}\n\treturn val\n}\n\n// AvailableEnvVars returns list of supported env vars.\n//\n// TODO: These should probably be embedded into flag parsing logic so we dont have\n// to maintain the list manually.\nfunc AvailableEnvVars() string {\n\treturn strings.Join([]string{\n\t\t\"  \" + envVarPrefix + \"DATABASE_URL  Database connection string\",\n\t\t\"  \" + envVarPrefix + \"URL_PREFIX    HTTP server path prefix\",\n\t\t\"  \" + envVarPrefix + \"SESSIONS      Enable multiple database sessions\",\n\t\t\"  \" + envVarPrefix + \"LOCK_SESSION  Lock session to a single database connection\",\n\t\t\"  \" + envVarPrefix + \"AUTH_USER     HTTP basic auth username\",\n\t\t\"  \" + envVarPrefix + \"AUTH_PASS     HTTP basic auth password\",\n\t\t\"  \" + envVarPrefix + \"BOOKMARKS_DIR Overrides default directory for bookmark files\",\n\t}, \"\\n\")\n}\n"
  },
  {
    "path": "pkg/command/options_test.go",
    "content": "package command\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/mitchellh/go-homedir\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestParseOptions(t *testing.T) {\n\tvar hdir string\n\tif d, err := homedir.Dir(); err == nil {\n\t\thdir = d\n\t}\n\n\tt.Run(\"defaults\", func(t *testing.T) {\n\t\topts, err := ParseOptions([]string{})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, false, opts.Sessions)\n\t\tassert.Equal(t, \"\", opts.Prefix)\n\t\tassert.Equal(t, \"\", opts.ConnectToken)\n\t\tassert.Equal(t, \"\", opts.ConnectHeaders)\n\t\tassert.Equal(t, false, opts.DisableSSH)\n\t\tassert.Equal(t, false, opts.DisablePrettyJSON)\n\t\tassert.Equal(t, false, opts.DisableConnectionIdleTimeout)\n\t\tassert.Equal(t, 180, opts.ConnectionIdleTimeout)\n\t\tassert.Equal(t, false, opts.Cors)\n\t\tassert.Equal(t, \"*\", opts.CorsOrigin)\n\t\tassert.Equal(t, \"\", opts.Passfile)\n\t\tassert.Equal(t, filepath.Join(hdir, \".pgweb/bookmarks\"), opts.BookmarksDir)\n\t})\n\n\tt.Run(\"sessions\", func(t *testing.T) {\n\t\topts, err := ParseOptions([]string{\"--sessions\", \"1\"})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, true, opts.Sessions)\n\t})\n\n\tt.Run(\"url prefix\", func(t *testing.T) {\n\t\topts, err := ParseOptions([]string{\"--prefix\", \"pgweb\"})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"pgweb/\", opts.Prefix)\n\n\t\topts, err = ParseOptions([]string{\"--prefix\", \"pgweb/\"})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"pgweb/\", opts.Prefix)\n\t})\n\n\tt.Run(\"connect backend\", func(t *testing.T) {\n\t\t_, err := ParseOptions([]string{\"--connect-backend\", \"test\"})\n\t\tassert.EqualError(t, err, \"--sessions flag must be set\")\n\n\t\t_, err = ParseOptions([]string{\"--connect-backend\", \"test\", \"--sessions\"})\n\t\tassert.EqualError(t, err, \"--connect-token flag must be set\")\n\n\t\t_, err = ParseOptions([]string{\"--connect-backend\", \"test\", \"--sessions\", \"--connect-token\", \"token\"})\n\t\tassert.NoError(t, err)\n\t})\n\n\tt.Run(\"passfile\", func(t *testing.T) {\n\t\tdefer os.Unsetenv(\"PGPASSFILE\")\n\n\t\t// File does not exist\n\t\tos.Setenv(\"PGPASSFILE\", \"/tmp/foo\")\n\t\topts, err := ParseOptions([]string{})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"\", opts.Passfile)\n\n\t\t// File exists and valid\n\t\tos.Setenv(\"PGPASSFILE\", \"../../data/passfile\")\n\t\topts, err = ParseOptions([]string{})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"../../data/passfile\", opts.Passfile)\n\n\t\t// Set via flag\n\t\tos.Unsetenv(\"PGPASSFILE\")\n\t\topts, err = ParseOptions([]string{\"--passfile\", \"../../data/passfile\"})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"../../data/passfile\", opts.Passfile)\n\t})\n\n\tt.Run(\"bookmarks dir from env var\", func(t *testing.T) {\n\t\tos.Setenv(\"PGWEB_BOOKMARKS_DIR\", \"/tmp/my-bookmarks\")\n\t\tdefer os.Unsetenv(\"PGWEB_BOOKMARKS_DIR\")\n\n\t\topts, err := ParseOptions([]string{})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"/tmp/my-bookmarks\", opts.BookmarksDir)\n\t})\n\n\tt.Run(\"bookmarks dir flag takes precedence over env var\", func(t *testing.T) {\n\t\tos.Setenv(\"PGWEB_BOOKMARKS_DIR\", \"/tmp/my-bookmarks\")\n\t\tdefer os.Unsetenv(\"PGWEB_BOOKMARKS_DIR\")\n\n\t\tflagDir := t.TempDir()\n\n\t\topts, err := ParseOptions([]string{\"--bookmarks-dir\", flagDir})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, flagDir, opts.BookmarksDir)\n\t})\n\n\tt.Run(\"bookmarks only mode\", func(t *testing.T) {\n\t\t_, err := ParseOptions([]string{\"--bookmarks-only\"})\n\t\tassert.NoError(t, err)\n\n\t\t_, err = ParseOptions([]string{\"--bookmarks-only\", \"--url\", \"test\"})\n\t\tassert.EqualError(t, err, \"--url not supported in bookmarks-only mode\")\n\n\t\t_, err = ParseOptions([]string{\"--bookmarks-only\", \"--host\", \"test\", \"--port\", \"5432\"})\n\t\tassert.EqualError(t, err, \"--host not supported in bookmarks-only mode\")\n\n\t\t_, err = ParseOptions([]string{\"--bookmarks-only\", \"--connect-backend\", \"test\", \"--sessions\", \"--connect-token\", \"token\", \"--url\", \"127.0.0.2\"})\n\t\tassert.EqualError(t, err, \"--connect-backend not supported in bookmarks-only mode\")\n\t})\n}\n"
  },
  {
    "path": "pkg/command/version.go",
    "content": "package command\n\nimport (\n\t\"fmt\"\n\t\"runtime\"\n\t\"strings\"\n)\n\nconst (\n\t// Version is the current Pgweb application version\n\tVersion = \"0.17.0\"\n)\n\nvar (\n\t// GitCommit contains the Git commit SHA for the binary\n\tGitCommit string\n\n\t// BuildTime contains the binary build time\n\tBuildTime string\n\n\t// BuildArch contains the OS architecture of the binary\n\tBuildArch string = fmt.Sprintf(\"%s/%s\", runtime.GOOS, runtime.GOARCH)\n\n\t// GoVersion contains the build time Go version\n\tGoVersion string\n\n\t// Info contains all version information\n\tInfo VersionInfo\n)\n\ntype VersionInfo struct {\n\tVersion   string `json:\"version\"`\n\tGitCommit string `json:\"git_sha\"`\n\tBuildTime string `json:\"build_time\"`\n\tBuildArch string `json:\"build_arch\"`\n\tGoVersion string `json:\"go_version\"`\n}\n\nfunc init() {\n\tInfo.Version = Version\n\tInfo.GitCommit = GitCommit\n\tInfo.BuildTime = BuildTime\n\tInfo.BuildArch = BuildArch\n\tInfo.GoVersion = GoVersion\n}\n\nfunc VersionString() string {\n\tchunks := []string{fmt.Sprintf(\"Pgweb v%s\", Version)}\n\n\tif GitCommit != \"\" {\n\t\tchunks = append(chunks, fmt.Sprintf(\"(git: %s)\", GitCommit))\n\t}\n\tif GoVersion != \"\" {\n\t\tchunks = append(chunks, fmt.Sprintf(\"(go: %s)\", GoVersion))\n\t}\n\tif BuildTime != \"\" {\n\t\tchunks = append(chunks, fmt.Sprintf(\"(build time: %s)\", BuildTime))\n\t}\n\tif BuildArch != \"\" {\n\t\tchunks = append(chunks, fmt.Sprintf(\"(arch: %s)\", BuildArch))\n\t}\n\n\treturn strings.Join(chunks, \" \")\n}\n"
  },
  {
    "path": "pkg/connect/backend.go",
    "content": "package connect\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/sirupsen/logrus\"\n)\n\ntype Backend struct {\n\tEndpoint    string\n\tToken       string\n\tPassHeaders []string\n\n\tlogger *logrus.Logger\n}\n\nfunc NewBackend(endpoint string, token string) Backend {\n\treturn Backend{\n\t\tEndpoint: endpoint,\n\t\tToken:    token,\n\t\tlogger:   logrus.StandardLogger(),\n\t}\n}\n\nfunc (be *Backend) SetLogger(logger *logrus.Logger) {\n\tbe.logger = logger\n}\n\nfunc (be *Backend) SetPassHeaders(headers []string) {\n\tbe.PassHeaders = headers\n}\n\nfunc (be *Backend) FetchCredential(ctx context.Context, resource string, headers http.Header) (*Credential, error) {\n\tbe.logger.WithField(\"resource\", resource).Debug(\"fetching database credential\")\n\n\trequest := Request{\n\t\tResource: resource,\n\t\tToken:    be.Token,\n\t\tHeaders:  map[string]string{},\n\t}\n\n\t// Pass allow-listed client headers to the backend request\n\tfor _, name := range be.PassHeaders {\n\t\trequest.Headers[strings.ToLower(name)] = headers.Get(name)\n\t}\n\n\tbody, err := json.Marshal(request)\n\tif err != nil {\n\t\tbe.logger.WithField(\"resource\", resource).Error(\"backend request serialization error:\", err)\n\t\treturn nil, err\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, be.Endpoint, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"content-type\", \"application/json\")\n\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tbe.logger.WithField(\"resource\", resource).Error(\"backend credential fetch failed:\", err)\n\t\treturn nil, errBackendConnectError\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != 200 {\n\t\terr = fmt.Errorf(\"backend credential fetch received HTTP status code %v\", resp.StatusCode)\n\n\t\tbe.logger.\n\t\t\tWithField(\"resource\", request.Resource).\n\t\t\tWithField(\"status\", resp.StatusCode).\n\t\t\tError(err)\n\n\t\treturn nil, err\n\t}\n\n\tcred := &Credential{}\n\tif err := json.NewDecoder(resp.Body).Decode(cred); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif cred.DatabaseURL == \"\" {\n\t\treturn nil, errConnStringRequired\n\t}\n\n\treturn cred, nil\n}\n"
  },
  {
    "path": "pkg/connect/backend_test.go",
    "content": "package connect\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\t\"net/http\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/sirupsen/logrus\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestBackendFetchCredential(t *testing.T) {\n\texamples := []struct {\n\t\tname         string\n\t\tbackend      Backend\n\t\tresourceName string\n\t\tcred         *Credential\n\t\theaders      http.Header\n\t\tctx          func() (context.Context, context.CancelFunc)\n\t\terr          error\n\t}{\n\t\t{\n\t\t\tname:    \"Bad auth token\",\n\t\t\tbackend: Backend{Endpoint: \"http://localhost:5555/unauthorized\"},\n\t\t\terr:     errors.New(\"backend credential fetch received HTTP status code 401\"),\n\t\t},\n\t\t{\n\t\t\tname:    \"Backend timeout\",\n\t\t\tbackend: Backend{Endpoint: \"http://localhost:5555/timeout\"},\n\t\t\tctx: func() (context.Context, context.CancelFunc) {\n\t\t\t\treturn context.WithTimeout(context.Background(), time.Millisecond*100)\n\t\t\t},\n\t\t\terr: errors.New(\"unable to connect to the auth backend\"),\n\t\t},\n\t\t{\n\t\t\tname:    \"Empty response\",\n\t\t\tbackend: Backend{Endpoint: \"http://localhost:5555/empty-response\"},\n\t\t\terr:     errors.New(\"connection string is required\"),\n\t\t},\n\t\t{\n\t\t\tname:    \"Missing header\",\n\t\t\tbackend: Backend{Endpoint: \"http://localhost:5555/pass-header\"},\n\t\t\terr:     errors.New(\"backend credential fetch received HTTP status code 400\"),\n\t\t},\n\t\t{\n\t\t\tname: \"Require header\",\n\t\t\tbackend: Backend{\n\t\t\t\tEndpoint:    \"http://localhost:5555/pass-header\",\n\t\t\t\tPassHeaders: []string{\"x-foo\"},\n\t\t\t},\n\t\t\theaders: http.Header{\n\t\t\t\t\"X-Foo\": []string{\"bar\"},\n\t\t\t},\n\t\t\tcred: &Credential{DatabaseURL: \"postgres://hostname/bar\"},\n\t\t},\n\t\t{\n\t\t\tname:    \"Success\",\n\t\t\tbackend: Backend{Endpoint: \"http://localhost:5555/success\"},\n\t\t\tcred:    &Credential{DatabaseURL: \"postgres://hostname/dbname\"},\n\t\t},\n\t}\n\n\tsrvCtx, srvCancel := context.WithTimeout(context.Background(), time.Minute)\n\tdefer srvCancel()\n\n\tstartTestBackend(srvCtx, \"localhost:5555\")\n\n\tfor _, ex := range examples {\n\t\tex.backend.logger = logrus.StandardLogger()\n\n\t\tt.Run(ex.name, func(t *testing.T) {\n\t\t\tctx, cancel := context.WithCancel(context.Background())\n\t\t\tif ex.ctx != nil {\n\t\t\t\tctx, cancel = ex.ctx()\n\t\t\t}\n\t\t\tdefer cancel()\n\n\t\t\tcred, err := ex.backend.FetchCredential(ctx, ex.resourceName, ex.headers)\n\t\t\tassert.Equal(t, ex.err, err)\n\t\t\tassert.Equal(t, ex.cred, cred)\n\t\t})\n\t}\n}\n\nfunc startTestBackend(ctx context.Context, listenAddr string) {\n\trouter := gin.New()\n\n\trouter.Use(func(c *gin.Context) {\n\t\tif c.GetHeader(\"content-type\") != \"application/json\" {\n\t\t\tc.AbortWithStatus(http.StatusBadRequest)\n\t\t}\n\t})\n\n\trouter.POST(\"/unauthorized\", func(c *gin.Context) {\n\t\tc.JSON(http.StatusUnauthorized, gin.H{\"error\": \"Unauthorized\"})\n\t})\n\n\trouter.POST(\"/timeout\", func(c *gin.Context) {\n\t\ttime.Sleep(time.Second)\n\t\tc.JSON(http.StatusOK, gin.H{})\n\t})\n\n\trouter.POST(\"/empty-response\", func(c *gin.Context) {\n\t\tc.JSON(http.StatusOK, gin.H{})\n\t})\n\n\trouter.POST(\"/pass-header\", func(c *gin.Context) {\n\t\treq := Request{}\n\t\tif err := c.BindJSON(&req); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\theader := req.Headers[\"x-foo\"]\n\t\tif header == \"\" {\n\t\t\tc.AbortWithStatus(http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\n\t\tc.JSON(http.StatusOK, gin.H{\n\t\t\t\"database_url\": \"postgres://hostname/\" + header,\n\t\t})\n\t})\n\n\trouter.POST(\"/success\", func(c *gin.Context) {\n\t\tc.JSON(http.StatusOK, gin.H{\n\t\t\t\"database_url\": \"postgres://hostname/dbname\",\n\t\t})\n\t})\n\n\tserver := &http.Server{Addr: listenAddr, Handler: router}\n\tmustStartServer(server)\n\n\tgo func() {\n\t\t<-ctx.Done()\n\t\tif err := server.Shutdown(context.Background()); err != nil && err != http.ErrServerClosed {\n\t\t\tpanic(err)\n\t\t}\n\t}()\n}\n\nfunc mustStartServer(server *http.Server) {\n\tgo func() {\n\t\terr := server.ListenAndServe()\n\t\tif err != nil && err != http.ErrServerClosed {\n\t\t\tpanic(err)\n\t\t}\n\t}()\n\n\tif err := waitForServer(server.Addr, 5); err != nil {\n\t\tpanic(err)\n\t}\n}\n\nfunc waitForServer(addr string, n int) error {\n\tvar lastErr error\n\n\tfor i := 0; i < n; i++ {\n\t\tconn, err := net.Dial(\"tcp\", addr)\n\t\tif err == nil {\n\t\t\tconn.Close()\n\t\t\treturn nil\n\t\t}\n\n\t\tlastErr = err\n\t\ttime.Sleep(time.Millisecond * 100)\n\t}\n\n\treturn lastErr\n}\n"
  },
  {
    "path": "pkg/connect/types.go",
    "content": "package connect\n\nimport \"errors\"\n\nvar (\n\terrBackendConnectError = errors.New(\"unable to connect to the auth backend\")\n\terrConnStringRequired  = errors.New(\"connection string is required\")\n)\n\n// Request holds the resource request details\ntype Request struct {\n\tResource string            `json:\"resource\"`\n\tToken    string            `json:\"token\"`\n\tHeaders  map[string]string `json:\"headers,omitempty\"`\n}\n\n// Credential holds the database connection string\ntype Credential struct {\n\tDatabaseURL string `json:\"database_url\"`\n}\n"
  },
  {
    "path": "pkg/connection/connection_string.go",
    "content": "package connection\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\tneturl \"net/url\"\n\t\"os\"\n\t\"os/user\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/jackc/pgpassfile\"\n\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n)\n\n// Common errors\nvar (\n\terrCantDetectUser   = errors.New(\"Could not detect default username\")\n\terrInvalidURLFormat = errors.New(\"Invalid URL. Valid format: postgres://user:password@host:port/db?sslmode=mode\")\n)\n\n// currentUser returns a current user name\nfunc currentUser() (string, error) {\n\tu, err := user.Current()\n\tif err == nil {\n\t\treturn u.Username, nil\n\t}\n\n\tname := os.Getenv(\"USER\")\n\tif name != \"\" {\n\t\treturn name, nil\n\t}\n\n\treturn \"\", errCantDetectUser\n}\n\n// Check if connection url has a correct postgres prefix\nfunc hasValidPrefix(str string) bool {\n\treturn strings.HasPrefix(str, \"postgres://\") || strings.HasPrefix(str, \"postgresql://\")\n}\n\n// Extract all query vals and return as a map\nfunc valsFromQuery(vals neturl.Values) map[string]string {\n\tresult := map[string]string{}\n\tfor k, v := range vals {\n\t\tresult[strings.ToLower(k)] = v[0]\n\t}\n\treturn result\n}\n\n// FormatURL reformats the existing connection string\nfunc FormatURL(opts command.Options) (string, error) {\n\turl := opts.URL\n\n\t// Validate connection string prefix\n\tif !hasValidPrefix(url) {\n\t\treturn \"\", errInvalidURLFormat\n\t}\n\n\t// Validate the URL\n\turi, err := neturl.Parse(url)\n\tif err != nil {\n\t\treturn \"\", errInvalidURLFormat\n\t}\n\n\t// Get query params\n\tparams := valsFromQuery(uri.Query())\n\n\t// Determine if we need to specify sslmode if it's missing\n\tif params[\"sslmode\"] == \"\" {\n\t\tif opts.SSLMode == \"\" {\n\t\t\t// Only modify sslmode for local connections\n\t\t\tif strings.Contains(uri.Host, \"localhost\") || strings.Contains(uri.Host, \"127.0.0.1\") {\n\t\t\t\tparams[\"sslmode\"] = \"disable\"\n\t\t\t}\n\t\t} else {\n\t\t\tparams[\"sslmode\"] = opts.SSLMode\n\t\t}\n\t}\n\n\t// When password is not provided, look it up from a .pgpass file\n\tif uri.User != nil {\n\t\tpass, _ := uri.User.Password()\n\t\tif pass == \"\" && opts.Passfile != \"\" {\n\t\t\tpass = lookupPassword(opts, uri)\n\t\t\tif pass != \"\" {\n\t\t\t\turi.User = neturl.UserPassword(uri.User.Username(), pass)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Configure default connect timeout\n\tif opts.OpenTimeout > 0 {\n\t\tparams[\"connect_timeout\"] = strconv.Itoa(opts.OpenTimeout)\n\t}\n\n\t// Rebuild query params\n\tquery := neturl.Values{}\n\tfor k, v := range params {\n\t\tquery.Add(k, v)\n\t}\n\turi.RawQuery = query.Encode()\n\n\treturn uri.String(), nil\n}\n\n// IsBlank returns true if command options do not contain connection details\nfunc IsBlank(opts command.Options) bool {\n\treturn opts.Host == \"\" && opts.User == \"\" && opts.DbName == \"\" && opts.URL == \"\"\n}\n\n// BuildStringFromOptions returns a new connection string built from options\nfunc BuildStringFromOptions(opts command.Options) (string, error) {\n\tquery := neturl.Values{}\n\n\t// If connection string is provided we just use that\n\tif opts.URL != \"\" {\n\t\treturn FormatURL(opts)\n\t}\n\n\t// Try to detect user from current OS user\n\tif opts.User == \"\" {\n\t\tu, err := currentUser()\n\t\tif err == nil {\n\t\t\topts.User = u\n\t\t}\n\t}\n\n\tif opts.SSLMode != \"\" {\n\t\tquery.Add(\"sslmode\", opts.SSLMode)\n\t} else {\n\t\tif opts.Host == \"localhost\" || opts.Host == \"127.0.0.1\" {\n\t\t\tquery.Add(\"sslmode\", \"disable\")\n\t\t}\n\t}\n\tif opts.SSLCert != \"\" {\n\t\tquery.Add(\"sslcert\", opts.SSLCert)\n\t}\n\tif opts.SSLKey != \"\" {\n\t\tquery.Add(\"sslkey\", opts.SSLKey)\n\t}\n\tif opts.SSLRootCert != \"\" {\n\t\tquery.Add(\"sslrootcert\", opts.SSLRootCert)\n\t}\n\n\t// Grab password from .pgpass file if it's available\n\tif opts.Pass == \"\" && opts.Passfile != \"\" {\n\t\topts.Pass = lookupPassword(opts, nil)\n\t}\n\n\t// Configure default connect timeout\n\tif opts.OpenTimeout > 0 {\n\t\tquery.Add(\"connect_timeout\", strconv.Itoa(opts.OpenTimeout))\n\t}\n\n\turl := neturl.URL{\n\t\tScheme:   \"postgres\",\n\t\tHost:     fmt.Sprintf(\"%v:%v\", opts.Host, opts.Port),\n\t\tUser:     neturl.UserPassword(opts.User, opts.Pass),\n\t\tPath:     fmt.Sprintf(\"/%s\", opts.DbName),\n\t\tRawQuery: query.Encode(),\n\t}\n\n\treturn url.String(), nil\n}\n\nfunc lookupPassword(opts command.Options, url *neturl.URL) string {\n\tif opts.Passfile == \"\" {\n\t\treturn \"\"\n\t}\n\n\tpassfile, err := pgpassfile.ReadPassfile(opts.Passfile)\n\tif err != nil {\n\t\tfmt.Println(\"[WARN] .pgpassfile\", opts.Passfile, \"is not readable\")\n\t\treturn \"\"\n\t}\n\n\tif url != nil {\n\t\tvar dbName string\n\t\tfmt.Sscanf(url.Path, \"/%s\", &dbName) //nolint\n\n\t\treturn passfile.FindPassword(\n\t\t\turl.Hostname(),\n\t\t\turl.Port(),\n\t\t\tdbName,\n\t\t\turl.User.Username(),\n\t\t)\n\t}\n\n\treturn passfile.FindPassword(\n\t\topts.Host,\n\t\tfmt.Sprintf(\"%d\", opts.Port),\n\t\topts.DbName,\n\t\topts.User,\n\t)\n}\n"
  },
  {
    "path": "pkg/connection/connection_string_test.go",
    "content": "package connection\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n\t\"os/user\"\n\t\"testing\"\n\n\t\"github.com/sosedoff/pgweb/pkg/command\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestBuildStringFromOptions(t *testing.T) {\n\tt.Run(\"valid url\", func(t *testing.T) {\n\t\turl := \"postgres://myhost/database\"\n\t\tstr, err := BuildStringFromOptions(command.Options{URL: url})\n\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, url, str)\n\t})\n\n\tt.Run(\"with sslmode param\", func(t *testing.T) {\n\t\tstr, err := BuildStringFromOptions(command.Options{\n\t\t\tURL:     \"postgres://myhost/database\",\n\t\t\tSSLMode: \"disable\",\n\t\t})\n\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://myhost/database?sslmode=disable\", str)\n\t})\n\n\tt.Run(\"sets sslmode param if not set\", func(t *testing.T) {\n\t\tstr, err := BuildStringFromOptions(command.Options{\n\t\t\tURL: \"postgres://localhost/database\",\n\t\t})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://localhost/database?sslmode=disable\", str)\n\n\t\tstr, err = BuildStringFromOptions(command.Options{\n\t\t\tURL: \"postgres://127.0.0.1/database\",\n\t\t})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://127.0.0.1/database?sslmode=disable\", str)\n\t})\n\n\tt.Run(\"sslmode as an option\", func(t *testing.T) {\n\t\tstr, err := BuildStringFromOptions(command.Options{\n\t\t\tURL:     \"postgres://localhost/database\",\n\t\t\tSSLMode: \"require\",\n\t\t})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://localhost/database?sslmode=require\", str)\n\n\t\tstr, err = BuildStringFromOptions(command.Options{\n\t\t\tURL:     \"postgres://127.0.0.1/database\",\n\t\t\tSSLMode: \"require\",\n\t\t})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://127.0.0.1/database?sslmode=require\", str)\n\t})\n\n\tt.Run(\"localhost and sslmode flag\", func(t *testing.T) {\n\t\tstr, err := BuildStringFromOptions(command.Options{\n\t\t\tURL: \"postgres://localhost/database?sslmode=require\",\n\t\t})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://localhost/database?sslmode=require\", str)\n\n\t\tstr, err = BuildStringFromOptions(command.Options{\n\t\t\tURL: \"postgres://127.0.0.1/database?sslmode=require\",\n\t\t})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://127.0.0.1/database?sslmode=require\", str)\n\t})\n\n\tt.Run(\"extended options\", func(t *testing.T) {\n\t\tstr, err := BuildStringFromOptions(command.Options{\n\t\t\tURL: \"postgres://localhost/database?sslmode=require&sslcert=cert&sslkey=key&sslrootcert=ca\",\n\t\t})\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://localhost/database?sslcert=cert&sslkey=key&sslmode=require&sslrootcert=ca\", str)\n\t})\n\n\tt.Run(\"from flags\", func(t *testing.T) {\n\t\tstr, err := BuildStringFromOptions(command.Options{\n\t\t\tHost:   \"host\",\n\t\t\tPort:   5432,\n\t\t\tUser:   \"user\",\n\t\t\tPass:   \"password\",\n\t\t\tDbName: \"db\",\n\t\t})\n\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://user:password@host:5432/db\", str)\n\t})\n\n\tt.Run(\"localhost\", func(t *testing.T) {\n\t\topts := command.Options{\n\t\t\tHost:   \"localhost\",\n\t\t\tPort:   5432,\n\t\t\tUser:   \"user\",\n\t\t\tPass:   \"password\",\n\t\t\tDbName: \"db\",\n\t\t}\n\n\t\tstr, err := BuildStringFromOptions(opts)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://user:password@localhost:5432/db?sslmode=disable\", str)\n\n\t\topts.Host = \"127.0.0.1\"\n\t\tstr, err = BuildStringFromOptions(opts)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://user:password@127.0.0.1:5432/db?sslmode=disable\", str)\n\t})\n\n\tt.Run(\"localhost and ssl\", func(t *testing.T) {\n\t\topts := command.Options{\n\t\t\tHost:        \"localhost\",\n\t\t\tPort:        5432,\n\t\t\tUser:        \"user\",\n\t\t\tPass:        \"password\",\n\t\t\tDbName:      \"db\",\n\t\t\tSSLMode:     \"require\",\n\t\t\tSSLKey:      \"keyPath\",\n\t\t\tSSLCert:     \"certPath\",\n\t\t\tSSLRootCert: \"caPath\",\n\t\t}\n\n\t\tstr, err := BuildStringFromOptions(opts)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://user:password@localhost:5432/db?sslcert=certPath&sslkey=keyPath&sslmode=require&sslrootcert=caPath\", str)\n\t})\n\n\tt.Run(\"no user\", func(t *testing.T) {\n\t\topts := command.Options{Host: \"host\", Port: 5432, DbName: \"db\"}\n\t\tu, _ := user.Current()\n\t\tstr, err := BuildStringFromOptions(opts)\n\t\tuserAndPass := url.UserPassword(u.Username, \"\").String()\n\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, fmt.Sprintf(\"postgres://%s@host:5432/db\", userAndPass), str)\n\t})\n\n\tt.Run(\"port\", func(t *testing.T) {\n\t\topts := command.Options{Host: \"host\", User: \"user\", Port: 5000, DbName: \"db\"}\n\t\tstr, err := BuildStringFromOptions(opts)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://user:@host:5000/db\", str)\n\t})\n\n\tt.Run(\"with pgpass\", func(t *testing.T) {\n\t\topts := command.Options{\n\t\t\tHost:     \"localhost\",\n\t\t\tPort:     5432,\n\t\t\tUser:     \"username\",\n\t\t\tDbName:   \"dbname\",\n\t\t\tPassfile: \"../../data/passfile\",\n\t\t}\n\n\t\tstr, err := BuildStringFromOptions(opts)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://username:password@localhost:5432/dbname?sslmode=disable\", str)\n\n\t\topts.User = \"foobar\"\n\t\tstr, err = BuildStringFromOptions(opts)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://foobar:@localhost:5432/dbname?sslmode=disable\", str)\n\n\t\topts.Host = \"127.0.0.1\"\n\t\topts.DbName = \"foobar2\"\n\t\tstr, err = BuildStringFromOptions(opts)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://foobar:password2@127.0.0.1:5432/foobar2?sslmode=disable\", str)\n\t})\n\n\tt.Run(\"with connection timeout\", func(t *testing.T) {\n\t\topts := command.Options{\n\t\t\tURL:         \"postgres://user:pass@localhost:5432/dbname\",\n\t\t\tOpenTimeout: 30,\n\t\t}\n\t\tstr, err := BuildStringFromOptions(opts)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://user:pass@localhost:5432/dbname?connect_timeout=30&sslmode=disable\", str)\n\n\t\topts = command.Options{\n\t\t\tHost:        \"localhost\",\n\t\t\tPort:        5432,\n\t\t\tUser:        \"username\",\n\t\t\tDbName:      \"dbname\",\n\t\t\tOpenTimeout: 30,\n\t\t}\n\n\t\tstr, err = BuildStringFromOptions(opts)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, \"postgres://username:@localhost:5432/dbname?connect_timeout=30&sslmode=disable\", str)\n\t})\n\n\tt.Run(\"invalid url\", func(t *testing.T) {\n\t\topts := command.Options{}\n\t\texamples := []string{\n\t\t\t\"postgre://foobar\",\n\t\t\t\"tcp://blah\",\n\t\t\t\"foobar\",\n\t\t}\n\n\t\tfor _, val := range examples {\n\t\t\topts.URL = val\n\t\t\tstr, err := BuildStringFromOptions(opts)\n\n\t\t\tassert.Equal(t, \"\", str)\n\t\t\tassert.Error(t, err)\n\t\t\tassert.Equal(t, \"Invalid URL. Valid format: postgres://user:password@host:port/db?sslmode=mode\", err.Error())\n\t\t}\n\t})\n}\n\nfunc TestFormatURL(t *testing.T) {\n\texamples := []struct {\n\t\tname   string\n\t\tinput  command.Options\n\t\tresult string\n\t\terr    string\n\t}{\n\t\t{\n\t\t\tname:  \"empty opts\",\n\t\t\tinput: command.Options{},\n\t\t},\n\t\t{\n\t\t\tname:  \"invalid url\",\n\t\t\tinput: command.Options{URL: \"barurl\"},\n\t\t\terr:   \"Invalid URL\",\n\t\t},\n\t\t{\n\t\t\tname: \"good\",\n\t\t\tinput: command.Options{\n\t\t\t\tURL: \"postgres://user:pass@localhost:5432/dbname\",\n\t\t\t},\n\t\t\tresult: \"postgres://user:pass@localhost:5432/dbname?sslmode=disable\",\n\t\t},\n\t\t{\n\t\t\tname: \"password lookup, password set\",\n\t\t\tinput: command.Options{\n\t\t\t\tURL:      \"postgres://username:@localhost:5432/dbname\",\n\t\t\t\tPassfile: \"../../data/passfile\",\n\t\t\t},\n\t\t\tresult: \"postgres://username:password@localhost:5432/dbname?sslmode=disable\",\n\t\t},\n\t\t{\n\t\t\tname: \"password lookup, password not set\",\n\t\t\tinput: command.Options{\n\t\t\t\tURL:      \"postgres://username@localhost:5432/dbname\",\n\t\t\t\tPassfile: \"../../data/passfile\",\n\t\t\t},\n\t\t\tresult: \"postgres://username:password@localhost:5432/dbname?sslmode=disable\",\n\t\t},\n\t\t{\n\t\t\tname: \"with timeout setting\",\n\t\t\tinput: command.Options{\n\t\t\t\tURL:         \"postgres://username@localhost:5432/dbname\",\n\t\t\t\tOpenTimeout: 30,\n\t\t\t},\n\t\t\tresult: \"postgres://username@localhost:5432/dbname?connect_timeout=30&sslmode=disable\",\n\t\t},\n\t}\n\n\tfor _, ex := range examples {\n\t\tt.Run(ex.name, func(t *testing.T) {\n\t\t\tstr, err := FormatURL(ex.input)\n\n\t\t\tif ex.err != \"\" {\n\t\t\t\tassert.Error(t, err)\n\t\t\t\tassert.Contains(t, err.Error(), ex.err)\n\t\t\t}\n\t\t\tassert.Equal(t, ex.result, str)\n\t\t})\n\t}\n}\n\nfunc TestIsBlank(t *testing.T) {\n\tassert.Equal(t, true, IsBlank(command.Options{}))\n\tassert.Equal(t, false, IsBlank(command.Options{Host: \"host\", User: \"user\"}))\n\tassert.Equal(t, false, IsBlank(command.Options{Host: \"host\", User: \"user\", DbName: \"db\"}))\n\tassert.Equal(t, false, IsBlank(command.Options{URL: \"url\"}))\n}\n"
  },
  {
    "path": "pkg/connection/port.go",
    "content": "package connection\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n)\n\n// IsPortAvailable returns true if there's no listeners on a given port\nfunc IsPortAvailable(port int) bool {\n\tconn, err := net.Dial(\"tcp\", fmt.Sprintf(\"127.0.0.1:%v\", port))\n\tif err != nil {\n\t\treturn strings.Index(err.Error(), \"connection refused\") > 0\n\t}\n\n\tconn.Close()\n\treturn false\n}\n\n// FindAvailablePort returns the first available TCP port in the range\nfunc FindAvailablePort(start int, limit int) (int, error) {\n\tfor i := start; i <= (start + limit); i++ {\n\t\tif IsPortAvailable(i) {\n\t\t\treturn i, nil\n\t\t}\n\t}\n\treturn -1, errors.New(\"No available port\")\n}\n"
  },
  {
    "path": "pkg/connection/port_test.go",
    "content": "package connection\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"runtime\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestIsPortAvailable(t *testing.T) {\n\tif runtime.GOOS == \"windows\" {\n\t\tt.Skip(\"FIXME\")\n\t}\n\n\tassert.Equal(t, true, IsPortAvailable(30000))\n\n\tserv, err := net.Listen(\"tcp\", \"127.0.0.1:30000\")\n\tif err != nil {\n\t\tfmt.Fprintln(os.Stderr, \"Unable to start test tcp listener:\", err)\n\t\tt.Fail()\n\t\treturn\n\t}\n\tdefer serv.Close()\n\n\tgo func() {\n\t\tfor {\n\t\t\tconn, err := serv.Accept()\n\t\t\tif err == nil {\n\t\t\t\tconn.Close()\n\t\t\t}\n\t\t\tserv.Close()\n\t\t}\n\t}()\n\n\tassert.Equal(t, false, IsPortAvailable(30000))\n\tassert.Equal(t, true, IsPortAvailable(30001))\n}\n\nfunc TestFindAvailablePort(t *testing.T) {\n\tif runtime.GOOS == \"windows\" {\n\t\tt.Skip(\"FIXME\")\n\t}\n\n\tport, err := FindAvailablePort(30000, 1)\n\tassert.Equal(t, nil, err)\n\tassert.Equal(t, 30000, port)\n\n\tserv, err := net.Listen(\"tcp\", \"127.0.0.1:30000\")\n\tif err != nil {\n\t\tfmt.Fprintln(os.Stderr, \"Unable to start test tcp listener:\", err)\n\t\tt.Fail()\n\t\treturn\n\t}\n\tdefer serv.Close()\n\n\tgo func() {\n\t\tfor {\n\t\t\tconn, err := serv.Accept()\n\t\t\tif err == nil {\n\t\t\t\tconn.Close()\n\t\t\t}\n\t\t}\n\t}()\n\n\tport, err = FindAvailablePort(30000, 0)\n\tassert.EqualError(t, err, \"No available port\")\n\tassert.Equal(t, -1, port)\n\n\tport, err = FindAvailablePort(30000, 1)\n\tassert.Equal(t, nil, err)\n\tassert.Equal(t, 30001, port)\n}\n"
  },
  {
    "path": "pkg/history/history.go",
    "content": "package history\n\nimport (\n\t\"time\"\n)\n\ntype Record struct {\n\tQuery     string `json:\"query\"`\n\tTimestamp string `json:\"timestamp\"`\n}\n\nfunc New() []Record {\n\treturn make([]Record, 0)\n}\n\nfunc NewRecord(query string) Record {\n\treturn Record{\n\t\tQuery:     query,\n\t\tTimestamp: time.Now().String(),\n\t}\n}\n"
  },
  {
    "path": "pkg/metrics/handler.go",
    "content": "package metrics\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n)\n\ntype Handler struct {\n\tstartTime   time.Time\n\tpromHandler http.Handler\n}\n\nfunc (h Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {\n\tuptimeGauge.Set(time.Since(h.startTime).Seconds())\n\n\th.promHandler.ServeHTTP(rw, req)\n}\n\nfunc NewHandler() http.Handler {\n\treturn Handler{\n\t\tstartTime:   time.Now(),\n\t\tpromHandler: promhttp.Handler(),\n\t}\n}\n"
  },
  {
    "path": "pkg/metrics/metrics.go",
    "content": "package metrics\n\nimport (\n\t\"time\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/client_golang/prometheus/promauto\"\n)\n\nvar (\n\tsessionsGauge = promauto.NewGauge(prometheus.GaugeOpts{\n\t\tName: \"pgweb_sessions_count\",\n\t\tHelp: \"Total number of database sessions\",\n\t})\n\n\tqueriesCounter = promauto.NewCounter(prometheus.CounterOpts{\n\t\tName: \"pgweb_queries_count\",\n\t\tHelp: \"Total number of custom queries executed\",\n\t})\n\n\thealthyGauge = promauto.NewGauge(prometheus.GaugeOpts{\n\t\tName: \"pgweb_healthy\",\n\t\tHelp: \"Server health status\",\n\t})\n\n\tstartTimeGauge = promauto.NewGauge(prometheus.GaugeOpts{\n\t\tName: \"pgweb_process_start_time\",\n\t\tHelp: \"Server start time, seconds since unix epoch\",\n\t})\n\n\tuptimeGauge = promauto.NewGauge(prometheus.GaugeOpts{\n\t\tName: \"pgweb_uptime\",\n\t\tHelp: \"Server application uptime in seconds\",\n\t})\n)\n\nfunc init() {\n\tstartTimeGauge.Set(float64(time.Now().Unix()))\n}\n\nfunc IncrementQueriesCount() {\n\tqueriesCounter.Inc()\n}\n\nfunc SetSessionsCount(val int) {\n\tsessionsGauge.Set(float64(val))\n}\n\nfunc SetHealthy(val bool) {\n\thealthy := 0.0\n\tif val {\n\t\thealthy = 1.0\n\t}\n\thealthyGauge.Set(float64(healthy))\n}\n"
  },
  {
    "path": "pkg/metrics/server.go",
    "content": "package metrics\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/sirupsen/logrus\"\n)\n\nfunc StartServer(logger *logrus.Logger, path string, addr string) error {\n\tlogger.WithField(\"addr\", addr).WithField(\"path\", path).Info(\"starting prometheus metrics server\")\n\n\thttp.Handle(path, NewHandler())\n\treturn http.ListenAndServe(addr, nil)\n}\n"
  },
  {
    "path": "pkg/queries/field.go",
    "content": "package queries\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n)\n\ntype field struct {\n\tvalue string\n\tre    *regexp.Regexp\n}\n\nfunc (f field) String() string {\n\treturn f.value\n}\n\nfunc (f field) matches(input string) bool {\n\tif f.re != nil {\n\t\treturn f.re.MatchString(input)\n\t}\n\treturn f.value == input\n}\n\nfunc newField(value string) (field, error) {\n\tf := field{value: value}\n\n\tif value == \"*\" { // match everything\n\t\tf.re = reMatchAll\n\t} else if reExpression.MatchString(value) { // match by given expression\n\t\t// Make writing expressions easier for values like \"foo_*\"\n\t\tif strings.Count(value, \"*\") == 1 {\n\t\t\tvalue = strings.Replace(value, \"*\", \"(.+)\", 1)\n\t\t}\n\t\tre, err := regexp.Compile(fmt.Sprintf(\"^%s$\", value))\n\t\tif err != nil {\n\t\t\treturn f, err\n\t\t}\n\t\tf.re = re\n\t}\n\n\treturn f, nil\n}\n"
  },
  {
    "path": "pkg/queries/field_test.go",
    "content": "package queries\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc Test_field(t *testing.T) {\n\tfield, err := newField(\"val\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"val\", field.value)\n\tassert.Equal(t, true, field.matches(\"val\"))\n\tassert.Equal(t, false, field.matches(\"value\"))\n\n\tfield, err = newField(\"*\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"*\", field.value)\n\tassert.NotNil(t, field.re)\n\tassert.Equal(t, true, field.matches(\"val\"))\n\tassert.Equal(t, true, field.matches(\"value\"))\n\n\tfield, err = newField(\"(.+\")\n\tassert.EqualError(t, err, \"error parsing regexp: missing closing ): `^(.+$`\")\n\tassert.NotNil(t, field)\n\n\tfield, err = newField(\"foo_*\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"foo_*\", field.value)\n\tassert.NotNil(t, field.re)\n\tassert.Equal(t, false, field.matches(\"foo\"))\n\tassert.Equal(t, true, field.matches(\"foo_bar\"))\n\tassert.Equal(t, true, field.matches(\"foo_bar_widget\"))\n\n}\n\nfunc Test_fieldString(t *testing.T) {\n\tfield, err := newField(\"val\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"val\", field.String())\n}\n"
  },
  {
    "path": "pkg/queries/metadata.go",
    "content": "package queries\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\nvar (\n\treMetaPrefix  = regexp.MustCompile(`(?m)^\\s*--\\s*pgweb:\\s*(.+)`)\n\treMetaContent = regexp.MustCompile(`([\\w]+)\\s*=\\s*\"([^\"]+)\"`)\n\treMatchAll    = regexp.MustCompile(`^(.+)$`)\n\treExpression  = regexp.MustCompile(`[\\[\\]\\(\\)\\+\\*]+`)\n\n\tallowedKeys  = []string{\"title\", \"description\", \"host\", \"user\", \"database\", \"mode\", \"timeout\"}\n\tallowedModes = map[string]bool{\"readonly\": true, \"*\": true}\n)\n\ntype Metadata struct {\n\tTitle       string\n\tDescription string\n\tHost        field\n\tUser        field\n\tDatabase    field\n\tMode        field\n\tTimeout     *time.Duration\n}\n\nfunc parseMetadata(input string) (*Metadata, error) {\n\tfields, err := parseFields(input)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif fields == nil {\n\t\treturn nil, nil\n\t}\n\n\t// Host must be set to limit queries availability\n\tif fields[\"host\"] == \"\" {\n\t\treturn nil, fmt.Errorf(\"host field must be set\")\n\t}\n\n\t// Allow matching for any user, database and mode by default\n\tif fields[\"user\"] == \"\" {\n\t\tfields[\"user\"] = \"*\"\n\t}\n\tif fields[\"database\"] == \"\" {\n\t\tfields[\"database\"] = \"*\"\n\t}\n\tif fields[\"mode\"] == \"\" {\n\t\tfields[\"mode\"] = \"*\"\n\t}\n\n\thostField, err := newField(fields[\"host\"])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(`error initializing \"host\" field: %w`, err)\n\t}\n\n\tuserField, err := newField(fields[\"user\"])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(`error initializing \"user\" field: %w`, err)\n\t}\n\n\tdbField, err := newField(fields[\"database\"])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(`error initializing \"database\" field: %w`, err)\n\t}\n\n\tif !allowedModes[fields[\"mode\"]] {\n\t\treturn nil, fmt.Errorf(`invalid \"mode\" field value: %q`, fields[\"mode\"])\n\t}\n\tmodeField, err := newField(fields[\"mode\"])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(`error initializing \"mode\" field: %w`, err)\n\t}\n\n\tvar timeout *time.Duration\n\tif fields[\"timeout\"] != \"\" {\n\t\ttimeoutSec, err := strconv.Atoi(fields[\"timeout\"])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(`error initializing \"timeout\" field: %w`, err)\n\t\t}\n\t\ttimeoutVal := time.Duration(timeoutSec) * time.Second\n\t\ttimeout = &timeoutVal\n\t}\n\n\treturn &Metadata{\n\t\tTitle:       fields[\"title\"],\n\t\tDescription: fields[\"description\"],\n\t\tHost:        hostField,\n\t\tUser:        userField,\n\t\tDatabase:    dbField,\n\t\tMode:        modeField,\n\t\tTimeout:     timeout,\n\t}, nil\n}\n\nfunc parseFields(input string) (map[string]string, error) {\n\tresult := map[string]string{}\n\tseenKeys := map[string]bool{}\n\n\tallowed := map[string]bool{}\n\tfor _, key := range allowedKeys {\n\t\tallowed[key] = true\n\t}\n\n\tmatches := reMetaPrefix.FindAllStringSubmatch(input, -1)\n\tif len(matches) == 0 {\n\t\treturn nil, nil\n\t}\n\n\tfor _, match := range matches {\n\t\tcontent := reMetaContent.FindAllStringSubmatch(match[1], -1)\n\t\tif len(content) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, field := range content {\n\t\t\tkey := field[1]\n\t\t\tvalue := field[2]\n\n\t\t\tif !allowed[key] {\n\t\t\t\treturn result, fmt.Errorf(\"unknown key: %q\", key)\n\t\t\t}\n\t\t\tif seenKeys[key] {\n\t\t\t\treturn result, fmt.Errorf(\"duplicate key: %q\", key)\n\t\t\t}\n\n\t\t\tseenKeys[key] = true\n\t\t\tresult[key] = value\n\t\t}\n\t}\n\n\treturn result, nil\n}\n\nfunc sanitizeMetadata(input string) string {\n\tlines := []string{}\n\tfor _, line := range strings.Split(input, \"\\n\") {\n\t\tline = reMetaPrefix.ReplaceAllString(line, \"\")\n\t\tif len(line) > 0 {\n\t\t\tlines = append(lines, line)\n\t\t}\n\t}\n\treturn strings.Join(lines, \"\\n\")\n}\n"
  },
  {
    "path": "pkg/queries/metadata_test.go",
    "content": "package queries\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc Test_parseFields(t *testing.T) {\n\texamples := []struct {\n\t\tinput string\n\t\terr   error\n\t\tvals  map[string]string\n\t}{\n\t\t{input: \"\", err: nil, vals: nil},\n\t\t{input: \"foobar\", err: nil, vals: nil},\n\t\t{input: \"-- no pgweb meta\", err: nil, vals: nil},\n\t\t{\n\t\t\tinput: `--pgweb: foo=bar`,\n\t\t\terr:   nil,\n\t\t\tvals:  map[string]string{},\n\t\t},\n\t\t{\n\t\t\tinput: `--pgweb: host=\"localhost\"`,\n\t\t\terr:   nil,\n\t\t\tvals:  map[string]string{\"host\": \"localhost\"},\n\t\t},\n\t\t{\n\t\t\tinput: `--pgweb: host=\"*\" user=\"admin\" database  =\"mydb\"; mode = \"readonly\"`,\n\t\t\terr:   nil,\n\t\t\tvals: map[string]string{\n\t\t\t\t\"host\":     \"*\",\n\t\t\t\t\"database\": \"mydb\",\n\t\t\t\t\"user\":     \"admin\",\n\t\t\t\t\"mode\":     \"readonly\",\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, ex := range examples {\n\t\tt.Run(ex.input, func(t *testing.T) {\n\t\t\tfields, err := parseFields(ex.input)\n\t\t\tassert.Equal(t, ex.err, err)\n\t\t\tassert.Equal(t, ex.vals, fields)\n\t\t})\n\t}\n}\n\nfunc Test_parseMetadata(t *testing.T) {\n\texamples := []struct {\n\t\tinput string\n\t\terr   string\n\t\tcheck func(meta *Metadata) bool\n\t}{\n\t\t{\n\t\t\tinput: `--pgweb: `,\n\t\t\terr:   `host field must be set`,\n\t\t},\n\t\t{\n\t\t\tinput: `--pgweb: hello=\"world\"`,\n\t\t\terr:   `unknown key: \"hello\"`,\n\t\t},\n\t\t{\n\t\t\tinput: `--pgweb: host=\"localhost\" user=\"anyuser\" database=\"anydb\" mode=\"foo\"`,\n\t\t\terr:   `invalid \"mode\" field value: \"foo\"`,\n\t\t},\n\t\t{\n\t\t\tinput: \"--pgweb2:\",\n\t\t\tcheck: func(m *Metadata) bool {\n\t\t\t\treturn m == nil\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tinput: `--pgweb: host=\"localhost\"`,\n\t\t\tcheck: func(m *Metadata) bool {\n\t\t\t\treturn m.Host.value == \"localhost\" &&\n\t\t\t\t\tm.User.value == \"*\" &&\n\t\t\t\t\tm.Database.value == \"*\" &&\n\t\t\t\t\tm.Mode.value == \"*\" &&\n\t\t\t\t\tm.Timeout == nil\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tinput: `--pgweb: host=\"localhost\" user=\"anyuser\" database=\"anydb\" mode=\"*\"`,\n\t\t\tcheck: func(m *Metadata) bool {\n\t\t\t\treturn m.Host.value == \"localhost\" &&\n\t\t\t\t\tm.Host.re == nil &&\n\t\t\t\t\tm.User.value == \"anyuser\" &&\n\t\t\t\t\tm.Database.value == \"anydb\" &&\n\t\t\t\t\tm.Mode.value == \"*\" &&\n\t\t\t\t\tm.Timeout == nil\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tinput: `--pgweb: host=\"localhost\" timeout=\"foo\"`,\n\t\t\terr:   `error initializing \"timeout\" field: strconv.Atoi: parsing \"foo\": invalid syntax`,\n\t\t},\n\t\t{\n\t\t\tinput: `-- pgweb: host=\"local(host|dev)\"`,\n\t\t\tcheck: func(m *Metadata) bool {\n\t\t\t\treturn m.Host.value == \"local(host|dev)\" && m.Host.re != nil &&\n\t\t\t\t\tm.Host.matches(\"localhost\") && m.Host.matches(\"localdev\") &&\n\t\t\t\t\t!m.Host.matches(\"localfoo\") && !m.Host.matches(\"superlocaldev\")\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, ex := range examples {\n\t\tt.Run(ex.input, func(t *testing.T) {\n\t\t\tmeta, err := parseMetadata(ex.input)\n\t\t\tif ex.err != \"\" {\n\t\t\t\tassert.Contains(t, err.Error(), ex.err)\n\t\t\t}\n\t\t\tif ex.check != nil {\n\t\t\t\tassert.Equal(t, true, ex.check(meta))\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc Test_sanitizeMetadata(t *testing.T) {\n\texamples := []struct {\n\t\tinput  string\n\t\toutput string\n\t}{\n\t\t{input: \"\", output: \"\"},\n\t\t{input: \"foo\", output: \"foo\"},\n\t\t{\n\t\t\tinput: `\n-- pgweb: metadata\nquery1\n-- pgweb: more metadata\n\nquery2\n\n`,\n\t\t\toutput: \"query1\\nquery2\",\n\t\t},\n\t}\n\n\tfor _, ex := range examples {\n\t\tt.Run(ex.input, func(t *testing.T) {\n\t\t\tassert.Equal(t, ex.output, sanitizeMetadata(ex.input))\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/queries/query.go",
    "content": "package queries\n\ntype Query struct {\n\tID   string\n\tPath string\n\tMeta *Metadata\n\tData string\n}\n\n// IsPermitted returns true if a query is allowed to execute for a given db context\nfunc (q Query) IsPermitted(host, user, database, mode string) bool {\n\t// All fields must be provided for matching\n\tif q.Meta == nil || host == \"\" || user == \"\" || database == \"\" || mode == \"\" {\n\t\treturn false\n\t}\n\n\tmeta := q.Meta\n\n\treturn meta.Host.matches(host) &&\n\t\tmeta.User.matches(user) &&\n\t\tmeta.Database.matches(database) &&\n\t\tmeta.Mode.matches(mode)\n}\n"
  },
  {
    "path": "pkg/queries/query_test.go",
    "content": "package queries\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestQueryIsPermitted(t *testing.T) {\n\texamples := []struct {\n\t\tname     string\n\t\tquery    Query\n\t\targs     []string\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname:     \"no input provided\",\n\t\t\tquery:    makeQuery(\"localhost\", \"someuser\", \"somedb\", \"default\"),\n\t\t\targs:     makeArgs(\"\", \"\", \"\", \"\"),\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"match on host\",\n\t\t\tquery:    makeQuery(\"localhost\", \"*\", \"*\", \"*\"),\n\t\t\targs:     makeArgs(\"localhost\", \"user\", \"db\", \"default\"),\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"match on full set\",\n\t\t\tquery:    makeQuery(\"localhost\", \"user\", \"database\", \"mode\"),\n\t\t\targs:     makeArgs(\"localhost\", \"someuser\", \"somedb\", \"default\"),\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"match on partial database\",\n\t\t\tquery:    makeQuery(\"localhost\", \"*\", \"myapp_*\", \"*\"),\n\t\t\targs:     makeArgs(\"localhost\", \"user\", \"myapp_development\", \"default\"),\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"match on full set but not mode\",\n\t\t\tquery:    makeQuery(\"localhost\", \"*\", \"*\", \"readonly\"),\n\t\t\targs:     makeArgs(\"localhost\", \"user\", \"db\", \"default\"),\n\t\t\texpected: false,\n\t\t},\n\t}\n\n\tfor _, ex := range examples {\n\t\tt.Run(ex.name, func(t *testing.T) {\n\t\t\tresult := ex.query.IsPermitted(ex.args[0], ex.args[1], ex.args[2], ex.args[3])\n\t\t\tassert.Equal(t, ex.expected, result)\n\t\t})\n\t}\n}\n\nfunc makeArgs(vals ...string) []string {\n\treturn vals\n}\n\nfunc makeQuery(host, user, database, mode string) Query {\n\tmustfield := func(input string) field {\n\t\tf, err := newField(input)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\treturn f\n\t}\n\n\treturn Query{\n\t\tMeta: &Metadata{\n\t\t\tHost:     mustfield(host),\n\t\t\tUser:     mustfield(user),\n\t\t\tDatabase: mustfield(database),\n\t\t\tMode:     mustfield(mode),\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "pkg/queries/store.go",
    "content": "package queries\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\nvar (\n\tErrQueryDirNotExist  = errors.New(\"queries directory does not exist\")\n\tErrQueryFileNotExist = errors.New(\"query file does not exist\")\n)\n\ntype Store struct {\n\tdir string\n}\n\nfunc NewStore(dir string) *Store {\n\treturn &Store{\n\t\tdir: dir,\n\t}\n}\n\nfunc (s Store) Read(id string) (*Query, error) {\n\tpath := filepath.Join(s.dir, fmt.Sprintf(\"%s.sql\", id))\n\treturn readQuery(path)\n}\n\nfunc (s Store) ReadAll() ([]Query, error) {\n\tentries, err := os.ReadDir(s.dir)\n\tif err != nil {\n\t\tif errors.Is(err, os.ErrNotExist) {\n\t\t\terr = ErrQueryDirNotExist\n\t\t}\n\t\treturn nil, err\n\t}\n\n\tqueries := []Query{}\n\n\tfor _, entry := range entries {\n\t\tname := entry.Name()\n\t\tif filepath.Ext(name) != \".sql\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tpath := filepath.Join(s.dir, name)\n\t\tquery, err := readQuery(path)\n\t\tif err != nil {\n\t\t\tfmt.Fprintf(os.Stderr, \"[WARN] skipping %q query file due to error: %v\\n\", name, err)\n\t\t\tcontinue\n\t\t}\n\t\tif query == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tqueries = append(queries, *query)\n\t}\n\n\treturn queries, nil\n}\n\nfunc readQuery(path string) (*Query, error) {\n\tdata, err := os.ReadFile(path)\n\tif err != nil {\n\t\tif errors.Is(err, os.ErrNotExist) {\n\t\t\treturn nil, ErrQueryFileNotExist\n\t\t}\n\t\treturn nil, err\n\t}\n\tdataStr := string(data)\n\n\tmeta, err := parseMetadata(dataStr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif meta == nil {\n\t\treturn nil, nil\n\t}\n\n\treturn &Query{\n\t\tID:   strings.Replace(filepath.Base(path), \".sql\", \"\", 1),\n\t\tPath: path,\n\t\tMeta: meta,\n\t\tData: sanitizeMetadata(dataStr),\n\t}, nil\n}\n"
  },
  {
    "path": "pkg/queries/store_test.go",
    "content": "//go:build !windows\n\npackage queries\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestStoreReadAll(t *testing.T) {\n\tt.Run(\"valid dir\", func(t *testing.T) {\n\t\tqueries, err := NewStore(\"../../data\").ReadAll()\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, 2, len(queries))\n\t})\n\n\tt.Run(\"invalid dir\", func(t *testing.T) {\n\t\tqueries, err := NewStore(\"../../data2\").ReadAll()\n\t\tassert.Equal(t, err.Error(), \"queries directory does not exist\")\n\t\tassert.Equal(t, 0, len(queries))\n\t})\n}\n\nfunc TestStoreRead(t *testing.T) {\n\texamples := []struct {\n\t\tid    string\n\t\terr   string\n\t\tcheck func(*testing.T, *Query)\n\t}{\n\t\t{id: \"foo\", err: \"query file does not exist\"},\n\t\t{id: \"lc_no_meta\"},\n\t\t{id: \"lc_invalid_meta\", err: `invalid \"mode\" field value: \"foo\"`},\n\t\t{\n\t\t\tid: \"lc_example1\",\n\t\t\tcheck: func(t *testing.T, q *Query) {\n\t\t\t\tassert.Equal(t, \"lc_example1\", q.ID)\n\t\t\t\tassert.Equal(t, \"../../data/lc_example1.sql\", q.Path)\n\t\t\t\tassert.Equal(t, \"select 'foo'\", q.Data)\n\t\t\t\tassert.Equal(t, \"localhost\", q.Meta.Host.String())\n\t\t\t\tassert.Equal(t, \"*\", q.Meta.User.String())\n\t\t\t\tassert.Equal(t, \"*\", q.Meta.Database.String())\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tid: \"lc_example2\",\n\t\t\tcheck: func(t *testing.T, q *Query) {\n\t\t\t\tassert.Equal(t, \"lc_example2\", q.ID)\n\t\t\t\tassert.Equal(t, \"../../data/lc_example2.sql\", q.Path)\n\t\t\t\tassert.Equal(t, \"-- some comment\\nselect 'foo'\", q.Data)\n\t\t\t\tassert.Equal(t, \"localhost\", q.Meta.Host.String())\n\t\t\t\tassert.Equal(t, \"foo\", q.Meta.User.String())\n\t\t\t\tassert.Equal(t, \"*\", q.Meta.Database.String())\n\t\t\t},\n\t\t},\n\t}\n\n\tstore := NewStore(\"../../data\")\n\n\tfor _, ex := range examples {\n\t\tt.Run(ex.id, func(t *testing.T) {\n\t\t\tquery, err := store.Read(ex.id)\n\t\t\tif ex.err != \"\" || err != nil {\n\t\t\t\tassert.Equal(t, ex.err, err.Error())\n\t\t\t}\n\t\t\tif ex.check != nil {\n\t\t\t\tex.check(t, query)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/shared/ssh_info.go",
    "content": "package shared\n\nimport (\n\t\"fmt\"\n)\n\n// SSHInfo contains ssh server configuration\ntype SSHInfo struct {\n\tHost        string `json:\"host,omitempty\"`\n\tPort        string `json:\"port,omitempty\"`\n\tUser        string `json:\"user,omitempty\"`\n\tPassword    string `json:\"password,omitempty\"`\n\tKey         string `json:\"key,omitempty\"`\n\tKeyPassword string `json:\"keypassword,omitempty\"`\n}\n\nfunc (info SSHInfo) String() string {\n\treturn fmt.Sprintf(\"%s@%s:%s\", info.User, info.Host, info.Port)\n}\n"
  },
  {
    "path": "pkg/statements/sql/databases.sql",
    "content": "SELECT\n  datname\nFROM\n  pg_database\nWHERE\n  NOT datistemplate\nORDER BY\n  datname ASC\n"
  },
  {
    "path": "pkg/statements/sql/estimated_row_count.sql",
    "content": "SELECT\n  reltuples\nFROM\n  pg_class\nWHERE\n  oid = ('\"' || $1::text || '\".\"' || $2::text || '\"')::regclass\n"
  },
  {
    "path": "pkg/statements/sql/function.sql",
    "content": "SELECT\n  p.oid,\n  p.proname,\n  p.pronamespace,\n  p.proowner,\n  pg_get_functiondef(oid) AS functiondef\nFROM\n  pg_catalog.pg_proc p\nWHERE\n  oid = $1::oid\n"
  },
  {
    "path": "pkg/statements/sql/info.sql",
    "content": "SELECT\n  session_user,\n  current_user,\n  current_database(),\n  current_schemas(false),\n  inet_client_addr(),\n  inet_client_port(),\n  inet_server_addr(),\n  inet_server_port(),\n  version()\n"
  },
  {
    "path": "pkg/statements/sql/info_simple.sql",
    "content": "SELECT\n  session_user,\n  current_user,\n  current_database(),\n  current_schemas(false),\n  version()\n"
  },
  {
    "path": "pkg/statements/sql/materialized_view.sql",
    "content": "SELECT\n  attname AS column_name,\n  atttypid::regtype AS data_type,\n  (CASE WHEN attnotnull IS TRUE THEN 'NO' ELSE 'YES' END) AS is_nullable,\n  NULL AS character_maximum_length,\n  NULL AS character_set_catalog,\n  NULL AS column_default\nFROM\n  pg_attribute\nWHERE\n  attrelid = $1::regclass\n  AND attnum > 0\n  AND NOT attisdropped\n"
  },
  {
    "path": "pkg/statements/sql/objects.sql",
    "content": "WITH all_objects AS (\n  SELECT\n    c.oid,\n    n.nspname AS schema,\n    c.relname AS name,\n    CASE c.relkind\n      WHEN 'r' THEN 'table'\n      WHEN 'v' THEN 'view'\n      WHEN 'm' THEN 'materialized_view'\n      WHEN 'i' THEN 'index'\n      WHEN 'S' THEN 'sequence'\n      WHEN 's' THEN 'special'\n      WHEN 'f' THEN 'foreign_table'\n    END AS type,\n    pg_catalog.pg_get_userbyid(c.relowner) AS owner,\n    pg_catalog.obj_description(c.oid) AS comment\n  FROM\n    pg_catalog.pg_class c\n  LEFT JOIN\n    pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n  WHERE\n    c.relkind IN ('r','v','m','S','s','')\n    AND n.nspname !~ '^pg_(toast|temp)'\n    AND n.nspname NOT IN ('information_schema', 'pg_catalog')\n    AND has_schema_privilege(n.nspname, 'USAGE')\n\n  UNION\n\n  SELECT\n    p.oid,\n    n.nspname AS schema,\n    p.proname AS name,\n    'function' AS function,\n    pg_catalog.pg_get_userbyid(p.proowner) AS owner,\n    NULL AS comment\n  FROM\n    pg_catalog.pg_namespace n\n  JOIN\n    pg_catalog.pg_proc p ON p.pronamespace = n.oid\n  WHERE\n    n.nspname !~ '^pg_(toast|temp)'\n    AND n.nspname NOT IN ('information_schema', 'pg_catalog')\n)\nSELECT * FROM all_objects\nORDER BY 2, 3\n"
  },
  {
    "path": "pkg/statements/sql/schemas.sql",
    "content": "SELECT\n  schema_name\nFROM\n  information_schema.schemata\nWHERE\n  schema_name NOT IN ('information_schema', 'pg_catalog')\n  AND schema_name !~ '^pg_(toast|temp)'\nORDER BY\n  schema_name ASC\n"
  },
  {
    "path": "pkg/statements/sql/settings.sql",
    "content": "SELECT * FROM pg_settings\n"
  },
  {
    "path": "pkg/statements/sql/table_constraints.sql",
    "content": "SELECT\n  conname AS name,\n  pg_get_constraintdef(c.oid, true) AS definition\nFROM\n  pg_constraint c\nJOIN\n  pg_namespace n ON n.oid = c.connamespace\nJOIN\n  pg_class cl ON cl.oid = c.conrelid\nWHERE\n  n.nspname = $1\n  AND relname = $2\n  AND contype != 'n'\nORDER BY\n  contype DESC\n"
  },
  {
    "path": "pkg/statements/sql/table_indexes.sql",
    "content": "SELECT\n  indexname AS index_name,\n  pg_size_pretty(pg_table_size(('\"' || schemaname || '\".\"' || indexname || '\"')::regclass)) AS index_size,\n  indexdef AS index_definition\nFROM\n  pg_indexes\nWHERE\n  schemaname = $1\n  AND tablename = $2\n"
  },
  {
    "path": "pkg/statements/sql/table_info.sql",
    "content": "SELECT\n  pg_size_pretty(pg_table_size($1)) AS data_size,\n  pg_size_pretty(pg_indexes_size($1)) AS index_size,\n  pg_size_pretty(pg_total_relation_size($1)) AS total_size,\n  (SELECT reltuples FROM pg_class WHERE oid = $1::regclass) AS rows_count\n"
  },
  {
    "path": "pkg/statements/sql/table_info_cockroach.sql",
    "content": "SELECT\n  'n/a' AS data_size,\n  'n/a' AS index_size,\n  'n/a' AS total_size,\n  'n/a' AS rows_count\n"
  },
  {
    "path": "pkg/statements/sql/table_schema.sql",
    "content": "SELECT\n  column_name,\n  data_type,\n  is_nullable,\n  character_maximum_length,\n  character_set_catalog,\n  column_default,\n  pg_catalog.col_description(('\"' || $1::text || '\".\"' || $2::text || '\"')::regclass::oid, ordinal_position) as comment\nFROM\n  information_schema.columns\nWHERE\n  table_schema = $1\n  AND table_name = $2\n"
  },
  {
    "path": "pkg/statements/sql/tables_stats.sql",
    "content": "WITH columns_counts AS (\n  SELECT table_schema, table_name, COUNT(1) AS num\n  FROM information_schema.columns\n  GROUP BY table_schema, table_name\n),\nindexes_counts AS (\n  SELECT schemaname, tablename, COUNT(1) AS num\n  FROM pg_indexes\n  GROUP BY schemaname, tablename\n)\nSELECT\n  tables.schemaname AS schema_name,\n  tables.relname AS table_name,\n  pg_size_pretty(pg_total_relation_size(tables.relid)) AS total_size,\n  pg_size_pretty(pg_table_size(tables.relid)) AS data_size,\n  pg_size_pretty(pg_indexes_size(tables.relid)) AS index_size,\n  pg_class.reltuples AS estimated_rows_count,\n  CASE\n    WHEN pg_class.reltuples >= 0 AND pg_class.reltuples < 1000\n      THEN pg_class.reltuples::text\n    WHEN pg_class.reltuples >= 1000 AND pg_class.reltuples < 1000000\n      THEN ROUND((pg_class.reltuples / 1000))::text || 'K'\n    WHEN pg_class.reltuples >= 1000000\n      THEN ROUND(pg_class.reltuples / 1000000)::text || 'M'\n  END AS estimated_rows,\n  CASE\n    WHEN pg_class.reltuples > 1000\n      THEN ROUND(pg_indexes_size(tables.relid)::numeric / pg_table_size(tables.relid), 2)\n  END AS index_to_data_ratio,\n  indexes_counts.num AS indexes_count,\n  columns_counts.num AS columns_count\nFROM\n  pg_catalog.pg_statio_user_tables AS tables\nLEFT JOIN pg_class\n  ON pg_class.oid = tables.relid\nLEFT JOIN indexes_counts\n  ON indexes_counts.schemaname = tables.schemaname\n  AND indexes_counts.tablename = tables.relname\nLEFT JOIN columns_counts\n  ON columns_counts.table_schema = tables.schemaname\n  AND columns_counts.table_name = tables.relname\nORDER BY\n  pg_total_relation_size(tables.relid) DESC,\n  pg_table_size(tables.relid) DESC\n"
  },
  {
    "path": "pkg/statements/sql.go",
    "content": "package statements\n\nimport (\n\t_ \"embed\"\n)\n\nvar (\n\t//go:embed sql/databases.sql\n\tDatabases string\n\n\t//go:embed sql/schemas.sql\n\tSchemas string\n\n\t//go:embed sql/info.sql\n\tInfo string\n\n\t//go:embed sql/info_simple.sql\n\tInfoSimple string\n\n\t//go:embed sql/estimated_row_count.sql\n\tEstimatedTableRowCount string\n\n\t//go:embed sql/table_indexes.sql\n\tTableIndexes string\n\n\t//go:embed sql/table_constraints.sql\n\tTableConstraints string\n\n\t//go:embed sql/table_info.sql\n\tTableInfo string\n\n\t//go:embed sql/table_info_cockroach.sql\n\tTableInfoCockroach string\n\n\t//go:embed sql/table_schema.sql\n\tTableSchema string\n\n\t//go:embed sql/materialized_view.sql\n\tMaterializedView string\n\n\t//go:embed sql/objects.sql\n\tObjects string\n\n\t//go:embed sql/tables_stats.sql\n\tTablesStats string\n\n\t//go:embed sql/function.sql\n\tFunction string\n\n\t//go:embed sql/settings.sql\n\tSettings string\n\n\t// Activity queries for specific PG versions\n\tActivity = map[string]string{\n\t\t\"default\": \"SELECT * FROM pg_stat_activity WHERE datname = current_database()\",\n\t\t\"9.1\":     \"SELECT datname, current_query, waiting, query_start, procpid as pid, datid, application_name, client_addr FROM pg_stat_activity WHERE datname = current_database()\",\n\t\t\"9.2\":     \"SELECT datname, query, state, waiting, query_start, state_change, pid, datid, application_name, client_addr FROM pg_stat_activity WHERE datname = current_database()\",\n\t\t\"9.3\":     \"SELECT datname, query, state, waiting, query_start, state_change, pid, datid, application_name, client_addr FROM pg_stat_activity WHERE datname = current_database()\",\n\t\t\"9.4\":     \"SELECT datname, query, state, waiting, query_start, state_change, pid, datid, application_name, client_addr FROM pg_stat_activity WHERE datname = current_database()\",\n\t\t\"9.5\":     \"SELECT datname, query, state, waiting, query_start, state_change, pid, datid, application_name, client_addr FROM pg_stat_activity WHERE datname = current_database()\",\n\t\t\"9.6\":     \"SELECT datname, query, state, wait_event, wait_event_type, query_start, state_change, pid, datid, application_name, client_addr FROM pg_stat_activity WHERE datname = current_database()\",\n\t}\n)\n"
  },
  {
    "path": "pkg/util/profiler.go",
    "content": "package util\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"runtime\"\n\t\"time\"\n)\n\nconst MEGABYTE = 1024 * 1024\n\nfunc runProfiler() {\n\tlogger := log.New(os.Stdout, \"\", 0)\n\tm := &runtime.MemStats{}\n\n\tfor {\n\t\truntime.ReadMemStats(m)\n\n\t\tlogger.Printf(\n\t\t\t\"[DEBUG] Goroutines: %v, Mem used: %v (%v mb), Mem acquired: %v (%v mb)\\n\",\n\t\t\truntime.NumGoroutine(),\n\t\t\tm.Alloc, m.Alloc/MEGABYTE,\n\t\t\tm.Sys, m.Sys/MEGABYTE,\n\t\t)\n\n\t\ttime.Sleep(time.Second * 30)\n\t}\n}\n\nfunc StartProfiler() {\n\tgo runProfiler()\n}\n"
  },
  {
    "path": "script/build_all.sh",
    "content": "#!/usr/bin/env bash\n\nTARGETS=\"darwin/amd64 darwin/arm64 linux/amd64 linux/arm64 windows/amd64\"\nARM_TARGETS=\"arm/v5 arm64/v7\"\n\nfor target in $TARGETS; do\n  echo \"-> target: $target\"\n\n  parts=(${target//\\// })\n  os=${parts[0]}\n  arch=${parts[1]}\n\n  GOOS=$os GOARCH=$arch go build -ldflags \"$LDFLAGS\" -o \"./bin/pgweb_${os}_${arch}\"\ndone\n\nfor target in $ARM_TARGETS; do\n  echo \"-> target: $target\"\n\n  parts=(${target//\\// })\n  arch=${parts[0]}\n  arm=$(echo ${parts[1]} | sed s/v//g)\n\n  GOOS=linux GOARCH=$arch GOARM=$arm go build -ldflags \"$LDFLAGS\" -o \"./bin/pgweb_linux_${arch}_v${arm}\"\ndone\n"
  },
  {
    "path": "script/check_formatting.sh",
    "content": "#!/bin/bash\n\n# Get list of offending files\nfiles=\"$(go fmt ./pkg/...)\"\n\nif [ -n \"$files\" ]; then\n  echo \"Go code is not formatted:\"\n  for file in $files; do\n    echo \"----> $file\"\n  done\n  exit 1\nfi"
  },
  {
    "path": "script/package.sh",
    "content": "#!/bin/bash\n\nset -e\n\nDIR=\"./bin\"\nrm -f $DIR/*.zip\n\nfor file in $(ls $DIR)\ndo\n  fin=$DIR/$file\n  fout=$DIR/$file.zip\n  shasum -a 256 $fin\n  zip -9 -q -j $fout $fin\n  shasum -a 256 $fout\ndone"
  },
  {
    "path": "script/test_all.sh",
    "content": "#!/bin/bash\n#\n# Integartion testing with dockerized Postgres servers\n#\n# Requires Docker for Mac to run on OSX.\n# Install: https://docs.docker.com/engine/installation/mac/\n#\n\nset -e\n\nexport PGHOST=${PGHOST:-localhost}\nexport PGUSER=\"postgres\"\nexport PGPASSWORD=\"ci\"\nexport PGDATABASE=\"booktown\"\nexport PGPORT=\"15432\"\n\n# TODO: Enable the 10.x branch when it's supported on Travis.\n# Local 10.x version is required so that pg_dump can properly work with older versions.\n# 10.x branch is normally supported.\nversions=\"9.1 9.2 9.3 9.4 9.5 9.6\"\n\nfor i in $versions\ndo\n  export PGVERSION=\"$i\"\n\n  echo \"------------------------------- BEGIN TEST -------------------------------\"\n  echo \"Running tests against PostgreSQL v$PGVERSION\"\n  docker rm -f postgres || true\n  docker run -p $PGPORT:5432 --name postgres -e POSTGRES_PASSWORD=$PGPASSWORD -d postgres:$PGVERSION\n  sleep 5\n  make test\n  echo \"-------------------------------- END TEST --------------------------------\"\ndone\n\n"
  },
  {
    "path": "script/test_cockroach.sh",
    "content": "#!/bin/bash\n\nset -e\n\nfunction killproc() {\n  if [[ $(lsof -i tcp:8888) ]]; then\n    lsof -i tcp:8888 | grep pgweb | awk '{print $2}' | xargs kill\n  fi\n}\n\n# Nuke the old container if exists.\ndocker rm -f cockroach || true\n\n# Start cockroach on 26258 so we dont mess with local server.\ndocker run \\\n  --name=cockroach \\\n  -d \\\n  -t \\\n  -p 26258:26257 \\\n  cockroachdb/cockroach:v20.2.5 \\\n  start-single-node --insecure\n\nsleep 3\n\n# Load the demo database.\ndocker exec -i cockroach ./cockroach sql --insecure < ./data/roach.sql\n\n# Find and destroy the existing pgweb process.\n# Would be great if pgweb had --pid option.\nkillproc\n\n# Start pgweb and connect to cockroach.\nmake build\n\n./pgweb \\\n  --url=postgres://root@localhost:26258/roach?sslmode=disable \\\n  --listen=8888 \\\n  --skip-open &\n\nsleep 1\n\n# Run smoke tests\nbase=\"-w \\\"\\n\\\" -f http://localhost:8888/api\"\ntable=\"product_information\"\n\ncurl $base/info\ncurl $base/connection\ncurl $base/schemas\ncurl $base/objects\ncurl $base/query -F query='select * from product_information;'\ncurl $base/tables/$table\ncurl $base/tables/$table/rows\ncurl $base/tables/$table/info\ncurl $base/tables/$table/indexes\ncurl $base/tables/$table/constraints\n\n# Cleanup\nkillproc"
  },
  {
    "path": "script/update_homebrew.sh",
    "content": "#!/bin/bash\n\nRELEASE_FILE=\"./tmp/release.json\"\nHOMEBREW_ROOT=\"/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core\"\nexport HOMEBREW_GITHUB_API_TOKEN=$(awk '/api.github.com/{getline;getline;print $2}' ~/.netrc)\n\n# Setup directory\nmkdir -p ./tmp\nrm -rf ./tmp/*\n\n# Fetch the latest published version\ncurl -s https://api.github.com/repos/sosedoff/pgweb/releases/latest > $RELEASE_FILE\nVERSION=\"$(jq -r .tag_name < $RELEASE_FILE)\"\nURL=\"https://github.com/sosedoff/pgweb/archive/$VERSION.tar.gz\"\nURL_SHA256=$(wget -qO- $URL | shasum -a 256 | cut -d ' ' -f 1)\n\n# Reset any changes\ngit -C $HOMEBREW_ROOT reset --hard\n\n# Update formula\nbrew bump-formula-pr \\\n  --url=$URL \\\n  --sha256=$URL_SHA256 \\\n  pgweb\n"
  },
  {
    "path": "static/css/app.css",
    "content": "#main {\n  display: none;\n}\n\n#nav {\n  position: fixed;\n  top: 0;\n  left: 250px;\n  right: 0;\n  height: 50px;\n  background: #79589f;\n}\n\n#nav ul {\n  margin: 0px;\n  padding: 0px;\n  height: 50px;\n  display: block;\n}\n\n#nav ul li {\n  margin: 0px;\n  padding: 0px;\n  float: left;\n  height: 49px;\n  line-height: 49px;\n  font-size: 13px;\n  padding: 0px 14px;\n  color: #d6cce2;\n  font-weight: 500;\n  margin: 0 1px;\n  cursor: pointer;\n  display: block;\n  list-style: none;\n  list-style-type: none;\n}\n\n#nav ul li:first-child {\n  margin-left: 0px;\n}\n\n#nav ul li:hover {\n  color: #fff;\n}\n\n#nav ul li.selected {\n  position: relative;\n  background: #fff;\n  color: #000;\n  margin: 0;\n}\n\n#nav ul li.selected:before {\n  content: ' ';\n  position: absolute;\n  bottom: -1px;\n  left: 0; right: 0;\n  height: 1px;\n  widows: 100%;\n  background: #fff;\n}\n\n#nav ul li.selected:first-child {\n  border-left: none;\n}\n\n#sidebar {\n  position: fixed;\n  width: 250px;\n  left: 0px;\n  top: 0px;\n  bottom: 0px;\n  box-sizing: border-box;\n  background: #f9f9f9;\n}\n\n#sidebar .current-database {\n  position: fixed;\n  left: 0px;\n  top: 0px;\n  width: 250px;\n  height: 50px;\n  line-height: 50px;\n  font-weight: bold;\n  font-size: 14px;\n  color: #fff;\n  background: #79589f;\n  z-index: 900;\n}\n\n#sidebar .current-database .wrap {\n  position: relative;\n  height: 50px;\n}\n\n#sidebar .current-database span.current-database-name {\n  margin-left: 30px;\n  display: inline-block;\n  width: 200px;\n  height: 50px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  cursor: pointer;\n}\n\n#sidebar .current-database i.fa-database {\n  position: absolute;\n  left: 8px;\n  top: 18px;\n}\n\n#sidebar .current-database input.typeahead {\n  margin-left: 30px;\n  display: inline-block;\n  width: 200px;\n  height: 50px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n#sidebar .current-database input.typeahead {\n  display: none;\n  background: #79589f;\n  width: 200px;\n  height: 22px;\n  color: #fff;\n  font-weight: normal;\n  outline: none;\n  border: 0px none;\n}\n\n#sidebar .current-database span.refresh {\n  position: absolute;\n  top: 0px;\n  right: 6px;\n  cursor: pointer;\n  color: #fff;\n  display: none;\n}\n\n#sidebar .current-database:hover span.refresh {\n  display: inline-block;\n}\n\n#sidebar .current-database input.typeahead::-webkit-input-placeholder {\n  color: #fff;\n}\n\n#sidebar ul.typeahead {\n  position: absolute;\n  margin-left: 30px;\n  overflow-y: auto;\n  max-height: 300px;\n  z-index: 999;\n}\n\n#sidebar ul.typeahead a {\n  font-size: 13px;\n  padding: 3px 10px;\n}\n\n#sidebar .objects-search {\n  position: fixed;\n  top: 50px;\n  left: 0px;\n  width: 250px;\n  height: 30px;\n  overflow: hidden;\n}\n\n#sidebar .objects-search .wrap {\n  position: relative;\n  background: transparent;\n  height: 30px;\n  padding: 4px;\n  box-sizing: border-box;\n  border-bottom: 1px solid #eee;\n}\n\n#sidebar .objects-search i.fa-search {\n  position: absolute;\n  left: 8px;\n  top: 7px;\n  color: #a1a1a1;\n}\n\n#sidebar .objects-search i.fa-times-circle {\n  position: absolute;\n  right: 8px;\n  top: 7px;\n  color: #a1a1a1;\n  display: none;\n  cursor: pointer;\n}\n\n#sidebar .objects-search i.fa-times-circle:hover {\n  color: #888;\n}\n\n#sidebar .objects-search input[type=\"text\"] {\n  background: transparent;\n  border: 0px none;\n  font-size: 12px;\n  color: #000;\n  height: 22px;\n  line-height: 22px;\n  padding: 0px;\n  margin-left: 25px;\n  width: 200px;\n  outline: none;\n}\n\n#sidebar div.tables-list {\n  position: fixed;\n  width: 250px;\n  top: 80px;\n  left: 0px;\n  bottom: 130px;\n  overflow: auto;\n}\n\n#sidebar div.tables-list .wrap {\n  height: 100%;\n  overflow: auto;\n}\n\n\n#sidebar div.tables-list #tables, #sequences, #objects {\n  font-size: 12px;\n}\n\n#sidebar div.table-information {\n  position: fixed;\n  width: 250px;\n  left: 0px;\n  height: 130px;\n  bottom: 0px;\n  box-sizing: border-box;\n  cursor: default;\n}\n\n#sidebar div.table-information .wrap {\n  height: 100%;\n  overflow-y: auto;\n}\n\n#sidebar div.table-information .title {\n  font-size: 12px;\n  text-transform: uppercase;\n  color: #aaa;\n  line-height: 30px;\n  padding: 0px 8px;\n  border-top: 1px solid #eee;\n}\n\n#sidebar div.table-information .lines {\n  display: none;\n}\n\n#sidebar div.table-information .lines .line {\n  line-height: 24px;\n  height: 24px;\n  padding: 0 8px 0 8px;\n  font-size: 12px;\n  color: #7F7E7F !important;\n}\n\n#sidebar div.table-information .lines .line span {\n  color: #4F4F4F;\n  min-width: 0;\n  padding-left: 0px;\n}\n\n#body {\n  position: fixed;\n  top: 50px;\n  left: 250px;\n  bottom: 0px;\n  right: 0px;\n  overflow: auto;\n}\n\n#input {\n  width: 100%;\n  height: 300px;\n  position: relative;\n}\n\n#input .input-wrapper {\n  height: 250px;\n  padding-top: 12px;\n}\n\n#input_resize_handler {\n  width: 100%;\n  height: 1px;\n  background: #ddd;\n  cursor: row-resize;\n  position: absolute;\n  bottom: 0px;\n}\n\n#input_resize_handler:hover, #input_resize_handler.dragging {\n  height: 3px;\n}\n\n#input .actions {\n  background: #fff;\n  padding: 10px;\n  height: 50px;\n  bottom: 0px;\n}\n\n#input .actions #result-rows-count {\n  font-size: 12px;\n  display: inline-block;\n  height: 30px;\n  line-height: 30px;\n  float: left;\n  margin-right: 10px;\n  color: #999;\n}\n\n#input .actions .btn {\n  line-height: 30px;\n  height: 30px;\n  padding: 0px 13px;\n  margin: 0px;\n  font-size: 13px;\n  color: #555;\n  border: none;\n  box-shadow: none;\n  background: transparent;\n  border: 1px solid #999;\n  float: left;\n  margin-right: 10px;\n}\n\n#input .actions .btn-primary {\n  border-color: #7eb54e;\n  color: #7eb54e;\n}\n\n#input .actions .btn:hover {\n  background: transparent !important;\n  border-color: #444;\n  color: #000;\n}\n\n#input .actions .btn-primary:hover {\n  color: #64903e;\n  border-color: #64903e;\n}\n\n#input .actions #query_progress {\n  display: none;\n  float: left;\n  font-size: 12px;\n  line-height: 30px;\n  height: 30px;\n  color: #aaa;\n}\n\n#input .actions .btn:focus {\n  outline: 0 none;\n  box-shadow: 0;\n}\n\n#input .actions .btn:hover {\n  background: #7eb154;\n}\n\n#input .actions .btn-default:hover {\n  background: #bbb;\n}\n\n#input .actions .btn:last-child {\n  margin-right: 0px;\n}\n\n#output {\n  position: absolute;\n  left: 0px;\n  top: 300px;\n  bottom: 0px;\n  right: 0px;\n  margin: 0px;\n  padding: 0px;\n  overflow: auto;\n}\n\n#pagination {\n  display: none;\n  position: absolute;\n  width: 100%;\n  height: 50px;\n  padding: 10px;\n  top: 0px;\n  left: 0px;\n  background: #fff;\n  border-bottom: 1px solid #eee;\n  box-shadow: 0 1px 3px 0px #f1f1f1;\n}\n\n#pagination .pager-container {\n  float: right;\n}\n\n#pagination .filters {\n  float: left;\n  font-size: 12px;\n}\n\n#pagination .filters span {\n  display: inline-block;\n  float: left;\n  font-weight: bold;\n  line-height: 32px;\n  height: 32px;\n  margin: 0px 8px;\n  color: #999;\n}\n\n#pagination .filters select {\n  font-size: 12px;\n  width: 100px;\n  float: left;\n  line-height: 30px;\n  height: 30px;\n  margin-right: 8px;\n  outline: none;\n}\n\n#pagination .filters select.column {\n  width: 150px;\n}\n\n#pagination .filters select.filter {\n  width: 100px;\n}\n\n#pagination .filters input {\n  float: left;\n  width: 200px;\n  height: 30px;\n  line-height: 30px;\n  margin-right: 8px;\n  font-size: 12px;\n}\n\n#pagination .filters .btn-primary {\n  border-color: #7eb54e;\n  color: #7eb54e;\n  background: #fff;\n  outline: none;\n  float: left;\n  margin-right: 8px;\n}\n\n#pagination .filters .btn-default {\n  float: left;\n  outline: none;\n}\n\n#pagination .btn-group {\n  float: right;\n}\n\n#pagination .current-page {\n  float: right;\n  font-size: 12px;\n  margin-right: 12px;\n  color: #999;\n  line-height: 32px;\n  height: 32px;\n}\n\n#results {\n  font-size: 12px;\n  margin: 0px;\n  padding: 0px;\n}\n\n#results.empty td {\n  border: 0px none;\n}\n\n#results tr:nth-child(even) > td {\n  border: none;\n  background: #ffffff;\n}\n\n#results tr:nth-child(odd) > td {\n  border: none;\n  background: #f9f9f9;\n}\n\n#results th {\n  border-top: none;\n  border-bottom: 1px solid #eae9e9;\n  padding: 3px 9px;\n  line-height: 24px;\n  color: #333;\n  font-weight: bold;\n  cursor: pointer;\n\n  -webkit-font-smoothing: antialiased;\n  -moz-user-select: none;\n  -khtml-user-select: none;\n  -webkit-user-select: none;\n  user-select: none;\n}\n\n#results th:hover {\n  background: #f8f8f8;\n}\n\n#results th.active {\n  background: #f3faff;\n}\n\n#results[data-mode=\"browse\"] th:hover {\n  cursor: pointer;\n  background: #fafafa;\n}\n\n#results tbody tr:hover td {\n  background: #ffe;\n}\n\n#results tbody tr {\n  border-bottom: 1px solid #f2f2f2;\n}\n\n#results tr.selected td {\n  background: #3874d7 !important;\n  color: #fff !important;\n}\n\n#results td {\n  color: #3a3633;\n  vertical-align: middle;\n  border: 0px none;\n}\n\n#results td div {\n  max-width: 350px;\n  max-height: 51px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: pre;\n}\n\n#results td div span.null {\n  color: #bbb;\n  text-transform: uppercase;\n}\n\n#results td textarea {\n  color: #000 !important;\n  font-size: 12px;\n}\n\n#results th:first-child,\n#results td:first-child {\n  padding-left: 15px;\n}\n\n#results.no-crop td div {\n  max-width: none;\n}\n\n#results_view {\n  display: none;\n  padding: 12px;\n  font-size: 14px;\n}\n\n#results_view .title {\n  margin-bottom: 8px;\n}\n\n#results_view pre {\n  border: 0px none;\n  position: relative;\n}\n\n#results_view .copy {\n  position: absolute;\n  display: none;\n  text-align: center;\n  line-height: 30px;\n  right: 4px;\n  top: 4px;\n  width: 30px;\n  height: 30px;\n  background: #fff;\n  border: 1px solid #ddd;\n  border-radius: 3px;\n  cursor: pointer;\n}\n\n#results_view .copy:hover {\n  border-color: #999;\n}\n\n#results_view pre:hover .copy {\n  display: block;\n}\n\n.full #output {\n  top: 0px !important;\n}\n\n.with-pagination #output {\n  top: 50px !important;\n}\n\n.with-pagination #pagination {\n  display: block;\n}\n\n.left {\n  float: left;\n}\n\n#content_modal {\n  display: none;\n  width: 60%;\n  height: 400px;\n  position: fixed;\n  top: 20%;\n  left: 20%;\n  background: #fff;\n  border: 1px solid #ccc;\n  box-shadow: #ddd 0 0 20px;\n}\n\n#content_modal .content {\n  border: 0px none;\n  position: relative;\n  padding: 8px;\n  white-space: break-spaces;\n  background: #fff;\n  overflow-y: scroll;\n  height: 366px;\n  box-sizing: border-box;\n}\n\n#content_modal .title {\n  font-weight: bold;\n  line-height: 24px;\n  background: #f5f5f5;\n  padding: 4px 4px 4px 8px;\n}\n\n#content_modal .actions {\n  float: right;\n}\n\n#content_modal .actions .fa {\n  float: right;\n  width: 24px;\n  height: 24px;\n  line-height: 24px;\n  font-size: 13px;\n  text-align: center;\n  background: #fff;\n  border: 1px solid #ddd;\n  border-radius: 3px;\n  cursor: pointer;\n  margin-left: 4px;\n}\n\n#content_modal .actions .fa:hover {\n  border-color: #999;\n  box-shadow: #eee 0 0 5px;\n}\n\n#error_banner {\n  line-height: 30px;\n  text-align: center;\n  background-color: #be2740;\n  color: #fff;\n  display: none;\n  position: fixed;\n  bottom: 0px;\n  left: 0px;\n  right: 0px;\n  height: 30px;\n}\n\n/* -------------------------------------------------------------------------- */\n\n#custom_query {\n  height: 238px;\n}\n\n#connection_window {\n  z-index: 3;\n  position: fixed;\n  background: #fff;\n  top: 0px;\n  left: 0px;\n  bottom: 0px;\n  right: 0px;\n  display: none;\n  overflow-y: auto;\n}\n\n.connection-actions {\n  position: fixed;\n  right: 8px;\n  top: 10px;\n  display: none;\n}\n\n#edit_connection, #close_connection {\n  background: #79589f;\n  color: #fff;\n  border-color: #fff;\n}\n\n#edit_connection i {\n  margin-right: 4px;\n}\n\n#close_connection_window {\n  display: none;\n}\n\n#connection_error {\n  display: none;\n}\n\n.bookmarks {\n  display: none;\n}\n\n.connection-settings {\n  width: 600px;\n  margin: 0px auto;\n  margin-top: 50px;\n}\n\n.connection-settings .header {\n  margin-bottom: 25px;\n}\n\n.connection-settings .header h1 {\n  text-align: center;\n  text-shadow: 0px 1px 0px #fff;\n  color: #999;\n  font-weight: normal;\n}\n\n.connection-settings .header .version {\n  font-size: 12px;\n  color: #aaa;\n  text-align: center;\n  display: block;\n}\n\n.connection-settings .header .update {\n  font-size: 12px;\n  text-align: center;\n  padding: 4px;\n  margin: 12px 0px;\n  display: none;\n}\n\n.connection-settings form {\n  background: #f6f6f6;\n  padding: 25px;\n  border-radius: 4px;\n  -moz-border-radius: 4px;\n  -webkit-border-radius: 4px;\n}\n\n.connection-settings form p.help-block {\n  font-size: 12px;\n}\n\n.connection-settings form .no-left-padding {\n  padding-left: 0;\n}\n\n.connection-scheme-group {\n  display: none;\n}\n\n.connection-ssh-group {\n  display: none;\n  z-index: 1000;\n}\n\n.connection-ssh-group h3 {\n  font-size: 18px;\n  margin: 0px 0px 20px 0px;\n  color: #aaa;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Sidebar Schema Objects */\n/* -------------------------------------------------------------------------- */\n\n.schema {}\n.schema i                           { display: inline-block; margin-right: 4px; }\n.schema i.fa-folder-o               { display: inline-block; }\n.schema i.fa-folder-open-o          { display: none; }\n.schema.expanded i.fa-folder-open-o { display: inline-block; }\n.schema.expanded i.fa-folder-o      { display: none; }\n\n.schema .schema-name {\n  font-weight: bold;\n  font-size: 13px;\n  display: block;\n  line-height: 30px;\n  height: 30px;\n  padding: 0px 8px;\n  cursor: pointer;\n  white-space: nowrap;\n}\n\n.schema .schema-container {\n  display: none;\n}\n\n.schema.expanded .schema-container {\n  display: block;\n}\n\n.schema .schema-container .schema-group .fa-chevron-down {\n  display: none;\n}\n\n.schema .schema-container .schema-group .schema-group-title {\n  display: block;\n  cursor: pointer;\n  line-height: 30px;\n  height: 30px;\n  padding: 0px 8px;\n  overflow: hidden;\n}\n\n.schema .schema-container .schema-group .schema-group-count {\n  color: #999;\n  display: inline-block;\n  float: right;\n  margin-right: 8px;\n}\n\n.schema .schema-container .schema-group ul {\n  padding: 0px;\n  margin: 0px;\n  display: none;\n}\n\n.schema .schema-container .schema-group ul li {\n  list-style: none;\n  list-style-type: none;\n  margin: 0px;\n  line-height: 30px;\n  height: 30px;\n  cursor: pointer;\n  padding: 0px 8px;\n  padding-left: 16px;\n  white-space: nowrap;\n  overflow: x-scroll;\n}\n\n.schema .schema-container .schema-group ul li i {\n  color: #999;\n}\n\n.schema .schema-container .schema-group ul li.active {\n  background: #f1f1f1;\n  color: #333;\n  font-weight: bold;\n}\n\n.schema .schema-container .schema-group ul li:hover {\n  background: #f1f1f1;\n}\n\n.schema .schema-container .schema-group.expanded .fa-chevron-down {\n  display: inline-block;\n}\n\n.schema .schema-container .schema-group.expanded .fa-chevron-right {\n  display: none;\n}\n\n.schema .schema-container .schema-group.expanded ul {\n  display: block;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Ace Customizations */\n/* -------------------------------------------------------------------------- */\n\n.ace_gutter, .ace_gutter-cell {\n  background: #fff !important;\n  color: #bbb;\n  font-size: 12px;\n}\n\n.ace_content .ace_active-line {\n  background: none !important;\n}\n\n.ace_autocomplete .ace_active-line {\n  background: #eee !important;\n}\n"
  },
  {
    "path": "static/css/bootstrap.css",
    "content": "/*!\n * Bootstrap v3.2.0 (http://getbootstrap.com)\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n *//*! normalize.css v3.0.1 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:\" (\" attr(href) \")\"}abbr[title]:after{content:\" (\" attr(title) \")\"}a[href^=\"javascript:\"]:after,a[href^=\"#\"]:after{content:\"\"}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:\"\\2a\"}.glyphicon-plus:before{content:\"\\2b\"}.glyphicon-euro:before{content:\"\\20ac\"}.glyphicon-minus:before{content:\"\\2212\"}.glyphicon-cloud:before{content:\"\\2601\"}.glyphicon-envelope:before{content:\"\\2709\"}.glyphicon-pencil:before{content:\"\\270f\"}.glyphicon-glass:before{content:\"\\e001\"}.glyphicon-music:before{content:\"\\e002\"}.glyphicon-search:before{content:\"\\e003\"}.glyphicon-heart:before{content:\"\\e005\"}.glyphicon-star:before{content:\"\\e006\"}.glyphicon-star-empty:before{content:\"\\e007\"}.glyphicon-user:before{content:\"\\e008\"}.glyphicon-film:before{content:\"\\e009\"}.glyphicon-th-large:before{content:\"\\e010\"}.glyphicon-th:before{content:\"\\e011\"}.glyphicon-th-list:before{content:\"\\e012\"}.glyphicon-ok:before{content:\"\\e013\"}.glyphicon-remove:before{content:\"\\e014\"}.glyphicon-zoom-in:before{content:\"\\e015\"}.glyphicon-zoom-out:before{content:\"\\e016\"}.glyphicon-off:before{content:\"\\e017\"}.glyphicon-signal:before{content:\"\\e018\"}.glyphicon-cog:before{content:\"\\e019\"}.glyphicon-trash:before{content:\"\\e020\"}.glyphicon-home:before{content:\"\\e021\"}.glyphicon-file:before{content:\"\\e022\"}.glyphicon-time:before{content:\"\\e023\"}.glyphicon-road:before{content:\"\\e024\"}.glyphicon-download-alt:before{content:\"\\e025\"}.glyphicon-download:before{content:\"\\e026\"}.glyphicon-upload:before{content:\"\\e027\"}.glyphicon-inbox:before{content:\"\\e028\"}.glyphicon-play-circle:before{content:\"\\e029\"}.glyphicon-repeat:before{content:\"\\e030\"}.glyphicon-refresh:before{content:\"\\e031\"}.glyphicon-list-alt:before{content:\"\\e032\"}.glyphicon-lock:before{content:\"\\e033\"}.glyphicon-flag:before{content:\"\\e034\"}.glyphicon-headphones:before{content:\"\\e035\"}.glyphicon-volume-off:before{content:\"\\e036\"}.glyphicon-volume-down:before{content:\"\\e037\"}.glyphicon-volume-up:before{content:\"\\e038\"}.glyphicon-qrcode:before{content:\"\\e039\"}.glyphicon-barcode:before{content:\"\\e040\"}.glyphicon-tag:before{content:\"\\e041\"}.glyphicon-tags:before{content:\"\\e042\"}.glyphicon-book:before{content:\"\\e043\"}.glyphicon-bookmark:before{content:\"\\e044\"}.glyphicon-print:before{content:\"\\e045\"}.glyphicon-camera:before{content:\"\\e046\"}.glyphicon-font:before{content:\"\\e047\"}.glyphicon-bold:before{content:\"\\e048\"}.glyphicon-italic:before{content:\"\\e049\"}.glyphicon-text-height:before{content:\"\\e050\"}.glyphicon-text-width:before{content:\"\\e051\"}.glyphicon-align-left:before{content:\"\\e052\"}.glyphicon-align-center:before{content:\"\\e053\"}.glyphicon-align-right:before{content:\"\\e054\"}.glyphicon-align-justify:before{content:\"\\e055\"}.glyphicon-list:before{content:\"\\e056\"}.glyphicon-indent-left:before{content:\"\\e057\"}.glyphicon-indent-right:before{content:\"\\e058\"}.glyphicon-facetime-video:before{content:\"\\e059\"}.glyphicon-picture:before{content:\"\\e060\"}.glyphicon-map-marker:before{content:\"\\e062\"}.glyphicon-adjust:before{content:\"\\e063\"}.glyphicon-tint:before{content:\"\\e064\"}.glyphicon-edit:before{content:\"\\e065\"}.glyphicon-share:before{content:\"\\e066\"}.glyphicon-check:before{content:\"\\e067\"}.glyphicon-move:before{content:\"\\e068\"}.glyphicon-step-backward:before{content:\"\\e069\"}.glyphicon-fast-backward:before{content:\"\\e070\"}.glyphicon-backward:before{content:\"\\e071\"}.glyphicon-play:before{content:\"\\e072\"}.glyphicon-pause:before{content:\"\\e073\"}.glyphicon-stop:before{content:\"\\e074\"}.glyphicon-forward:before{content:\"\\e075\"}.glyphicon-fast-forward:before{content:\"\\e076\"}.glyphicon-step-forward:before{content:\"\\e077\"}.glyphicon-eject:before{content:\"\\e078\"}.glyphicon-chevron-left:before{content:\"\\e079\"}.glyphicon-chevron-right:before{content:\"\\e080\"}.glyphicon-plus-sign:before{content:\"\\e081\"}.glyphicon-minus-sign:before{content:\"\\e082\"}.glyphicon-remove-sign:before{content:\"\\e083\"}.glyphicon-ok-sign:before{content:\"\\e084\"}.glyphicon-question-sign:before{content:\"\\e085\"}.glyphicon-info-sign:before{content:\"\\e086\"}.glyphicon-screenshot:before{content:\"\\e087\"}.glyphicon-remove-circle:before{content:\"\\e088\"}.glyphicon-ok-circle:before{content:\"\\e089\"}.glyphicon-ban-circle:before{content:\"\\e090\"}.glyphicon-arrow-left:before{content:\"\\e091\"}.glyphicon-arrow-right:before{content:\"\\e092\"}.glyphicon-arrow-up:before{content:\"\\e093\"}.glyphicon-arrow-down:before{content:\"\\e094\"}.glyphicon-share-alt:before{content:\"\\e095\"}.glyphicon-resize-full:before{content:\"\\e096\"}.glyphicon-resize-small:before{content:\"\\e097\"}.glyphicon-exclamation-sign:before{content:\"\\e101\"}.glyphicon-gift:before{content:\"\\e102\"}.glyphicon-leaf:before{content:\"\\e103\"}.glyphicon-fire:before{content:\"\\e104\"}.glyphicon-eye-open:before{content:\"\\e105\"}.glyphicon-eye-close:before{content:\"\\e106\"}.glyphicon-warning-sign:before{content:\"\\e107\"}.glyphicon-plane:before{content:\"\\e108\"}.glyphicon-calendar:before{content:\"\\e109\"}.glyphicon-random:before{content:\"\\e110\"}.glyphicon-comment:before{content:\"\\e111\"}.glyphicon-magnet:before{content:\"\\e112\"}.glyphicon-chevron-up:before{content:\"\\e113\"}.glyphicon-chevron-down:before{content:\"\\e114\"}.glyphicon-retweet:before{content:\"\\e115\"}.glyphicon-shopping-cart:before{content:\"\\e116\"}.glyphicon-folder-close:before{content:\"\\e117\"}.glyphicon-folder-open:before{content:\"\\e118\"}.glyphicon-resize-vertical:before{content:\"\\e119\"}.glyphicon-resize-horizontal:before{content:\"\\e120\"}.glyphicon-hdd:before{content:\"\\e121\"}.glyphicon-bullhorn:before{content:\"\\e122\"}.glyphicon-bell:before{content:\"\\e123\"}.glyphicon-certificate:before{content:\"\\e124\"}.glyphicon-thumbs-up:before{content:\"\\e125\"}.glyphicon-thumbs-down:before{content:\"\\e126\"}.glyphicon-hand-right:before{content:\"\\e127\"}.glyphicon-hand-left:before{content:\"\\e128\"}.glyphicon-hand-up:before{content:\"\\e129\"}.glyphicon-hand-down:before{content:\"\\e130\"}.glyphicon-circle-arrow-right:before{content:\"\\e131\"}.glyphicon-circle-arrow-left:before{content:\"\\e132\"}.glyphicon-circle-arrow-up:before{content:\"\\e133\"}.glyphicon-circle-arrow-down:before{content:\"\\e134\"}.glyphicon-globe:before{content:\"\\e135\"}.glyphicon-wrench:before{content:\"\\e136\"}.glyphicon-tasks:before{content:\"\\e137\"}.glyphicon-filter:before{content:\"\\e138\"}.glyphicon-briefcase:before{content:\"\\e139\"}.glyphicon-fullscreen:before{content:\"\\e140\"}.glyphicon-dashboard:before{content:\"\\e141\"}.glyphicon-paperclip:before{content:\"\\e142\"}.glyphicon-heart-empty:before{content:\"\\e143\"}.glyphicon-link:before{content:\"\\e144\"}.glyphicon-phone:before{content:\"\\e145\"}.glyphicon-pushpin:before{content:\"\\e146\"}.glyphicon-usd:before{content:\"\\e148\"}.glyphicon-gbp:before{content:\"\\e149\"}.glyphicon-sort:before{content:\"\\e150\"}.glyphicon-sort-by-alphabet:before{content:\"\\e151\"}.glyphicon-sort-by-alphabet-alt:before{content:\"\\e152\"}.glyphicon-sort-by-order:before{content:\"\\e153\"}.glyphicon-sort-by-order-alt:before{content:\"\\e154\"}.glyphicon-sort-by-attributes:before{content:\"\\e155\"}.glyphicon-sort-by-attributes-alt:before{content:\"\\e156\"}.glyphicon-unchecked:before{content:\"\\e157\"}.glyphicon-expand:before{content:\"\\e158\"}.glyphicon-collapse-down:before{content:\"\\e159\"}.glyphicon-collapse-up:before{content:\"\\e160\"}.glyphicon-log-in:before{content:\"\\e161\"}.glyphicon-flash:before{content:\"\\e162\"}.glyphicon-log-out:before{content:\"\\e163\"}.glyphicon-new-window:before{content:\"\\e164\"}.glyphicon-record:before{content:\"\\e165\"}.glyphicon-save:before{content:\"\\e166\"}.glyphicon-open:before{content:\"\\e167\"}.glyphicon-saved:before{content:\"\\e168\"}.glyphicon-import:before{content:\"\\e169\"}.glyphicon-export:before{content:\"\\e170\"}.glyphicon-send:before{content:\"\\e171\"}.glyphicon-floppy-disk:before{content:\"\\e172\"}.glyphicon-floppy-saved:before{content:\"\\e173\"}.glyphicon-floppy-remove:before{content:\"\\e174\"}.glyphicon-floppy-save:before{content:\"\\e175\"}.glyphicon-floppy-open:before{content:\"\\e176\"}.glyphicon-credit-card:before{content:\"\\e177\"}.glyphicon-transfer:before{content:\"\\e178\"}.glyphicon-cutlery:before{content:\"\\e179\"}.glyphicon-header:before{content:\"\\e180\"}.glyphicon-compressed:before{content:\"\\e181\"}.glyphicon-earphone:before{content:\"\\e182\"}.glyphicon-phone-alt:before{content:\"\\e183\"}.glyphicon-tower:before{content:\"\\e184\"}.glyphicon-stats:before{content:\"\\e185\"}.glyphicon-sd-video:before{content:\"\\e186\"}.glyphicon-hd-video:before{content:\"\\e187\"}.glyphicon-subtitles:before{content:\"\\e188\"}.glyphicon-sound-stereo:before{content:\"\\e189\"}.glyphicon-sound-dolby:before{content:\"\\e190\"}.glyphicon-sound-5-1:before{content:\"\\e191\"}.glyphicon-sound-6-1:before{content:\"\\e192\"}.glyphicon-sound-7-1:before{content:\"\\e193\"}.glyphicon-copyright-mark:before{content:\"\\e194\"}.glyphicon-registration-mark:before{content:\"\\e195\"}.glyphicon-cloud-download:before{content:\"\\e197\"}.glyphicon-cloud-upload:before{content:\"\\e198\"}.glyphicon-tree-conifer:before{content:\"\\e199\"}.glyphicon-tree-deciduous:before{content:\"\\e200\"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;width:100% \\9;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;width:100% \\9;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\\2014 \\00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\\00A0 \\2014'}blockquote:before,blockquote:after{content:\"\"}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,\"Courier New\",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#777;opacity:1}.form-control:-ms-input-placeholder{color:#777}.form-control::-webkit-input-placeholder{color:#777}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px;line-height:1.42857143 \\0}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;min-height:20px;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \\9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm,.form-horizontal .form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg,.form-horizontal .form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:25px;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn:focus,.btn:active:focus,.btn.active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#3071a9;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#428bca;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:\"\";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn>input[type=radio],[data-toggle=buttons]>.btn>input[type=checkbox]{position:absolute;z-index:-1;filter:alpha(opacity=0);opacity:0}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#777}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#777}.navbar-inverse .navbar-nav>li>a{color:#777}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#777}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#777}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:\"/\\00a0\"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#428bca;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar[aria-valuenow=\"1\"],.progress-bar[aria-valuenow=\"2\"]{min-width:30px}.progress-bar[aria-valuenow=\"0\"]{min-width:30px;color:#777;background-color:transparent;background-image:none;-webkit-box-shadow:none;box-shadow:none}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#428bca}.panel-primary>.panel-heading .badge{color:#428bca;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate3d(0,-25%,0);-o-transform:translate3d(0,-25%,0);transform:translate3d(0,-25%,0)}.modal.in .modal-dialog{-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-size:12px;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:\"\";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:\" \";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:\" \";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:\" \";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:\" \";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\\2039'}.carousel-control .icon-next:before{content:'\\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{display:table;content:\" \"}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}"
  },
  {
    "path": "static/css/font-awesome.css",
    "content": "/*!\n *  Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:\"\\f000\"}.fa-music:before{content:\"\\f001\"}.fa-search:before{content:\"\\f002\"}.fa-envelope-o:before{content:\"\\f003\"}.fa-heart:before{content:\"\\f004\"}.fa-star:before{content:\"\\f005\"}.fa-star-o:before{content:\"\\f006\"}.fa-user:before{content:\"\\f007\"}.fa-film:before{content:\"\\f008\"}.fa-th-large:before{content:\"\\f009\"}.fa-th:before{content:\"\\f00a\"}.fa-th-list:before{content:\"\\f00b\"}.fa-check:before{content:\"\\f00c\"}.fa-remove:before,.fa-close:before,.fa-times:before{content:\"\\f00d\"}.fa-search-plus:before{content:\"\\f00e\"}.fa-search-minus:before{content:\"\\f010\"}.fa-power-off:before{content:\"\\f011\"}.fa-signal:before{content:\"\\f012\"}.fa-gear:before,.fa-cog:before{content:\"\\f013\"}.fa-trash-o:before{content:\"\\f014\"}.fa-home:before{content:\"\\f015\"}.fa-file-o:before{content:\"\\f016\"}.fa-clock-o:before{content:\"\\f017\"}.fa-road:before{content:\"\\f018\"}.fa-download:before{content:\"\\f019\"}.fa-arrow-circle-o-down:before{content:\"\\f01a\"}.fa-arrow-circle-o-up:before{content:\"\\f01b\"}.fa-inbox:before{content:\"\\f01c\"}.fa-play-circle-o:before{content:\"\\f01d\"}.fa-rotate-right:before,.fa-repeat:before{content:\"\\f01e\"}.fa-refresh:before{content:\"\\f021\"}.fa-list-alt:before{content:\"\\f022\"}.fa-lock:before{content:\"\\f023\"}.fa-flag:before{content:\"\\f024\"}.fa-headphones:before{content:\"\\f025\"}.fa-volume-off:before{content:\"\\f026\"}.fa-volume-down:before{content:\"\\f027\"}.fa-volume-up:before{content:\"\\f028\"}.fa-qrcode:before{content:\"\\f029\"}.fa-barcode:before{content:\"\\f02a\"}.fa-tag:before{content:\"\\f02b\"}.fa-tags:before{content:\"\\f02c\"}.fa-book:before{content:\"\\f02d\"}.fa-bookmark:before{content:\"\\f02e\"}.fa-print:before{content:\"\\f02f\"}.fa-camera:before{content:\"\\f030\"}.fa-font:before{content:\"\\f031\"}.fa-bold:before{content:\"\\f032\"}.fa-italic:before{content:\"\\f033\"}.fa-text-height:before{content:\"\\f034\"}.fa-text-width:before{content:\"\\f035\"}.fa-align-left:before{content:\"\\f036\"}.fa-align-center:before{content:\"\\f037\"}.fa-align-right:before{content:\"\\f038\"}.fa-align-justify:before{content:\"\\f039\"}.fa-list:before{content:\"\\f03a\"}.fa-dedent:before,.fa-outdent:before{content:\"\\f03b\"}.fa-indent:before{content:\"\\f03c\"}.fa-video-camera:before{content:\"\\f03d\"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:\"\\f03e\"}.fa-pencil:before{content:\"\\f040\"}.fa-map-marker:before{content:\"\\f041\"}.fa-adjust:before{content:\"\\f042\"}.fa-tint:before{content:\"\\f043\"}.fa-edit:before,.fa-pencil-square-o:before{content:\"\\f044\"}.fa-share-square-o:before{content:\"\\f045\"}.fa-check-square-o:before{content:\"\\f046\"}.fa-arrows:before{content:\"\\f047\"}.fa-step-backward:before{content:\"\\f048\"}.fa-fast-backward:before{content:\"\\f049\"}.fa-backward:before{content:\"\\f04a\"}.fa-play:before{content:\"\\f04b\"}.fa-pause:before{content:\"\\f04c\"}.fa-stop:before{content:\"\\f04d\"}.fa-forward:before{content:\"\\f04e\"}.fa-fast-forward:before{content:\"\\f050\"}.fa-step-forward:before{content:\"\\f051\"}.fa-eject:before{content:\"\\f052\"}.fa-chevron-left:before{content:\"\\f053\"}.fa-chevron-right:before{content:\"\\f054\"}.fa-plus-circle:before{content:\"\\f055\"}.fa-minus-circle:before{content:\"\\f056\"}.fa-times-circle:before{content:\"\\f057\"}.fa-check-circle:before{content:\"\\f058\"}.fa-question-circle:before{content:\"\\f059\"}.fa-info-circle:before{content:\"\\f05a\"}.fa-crosshairs:before{content:\"\\f05b\"}.fa-times-circle-o:before{content:\"\\f05c\"}.fa-check-circle-o:before{content:\"\\f05d\"}.fa-ban:before{content:\"\\f05e\"}.fa-arrow-left:before{content:\"\\f060\"}.fa-arrow-right:before{content:\"\\f061\"}.fa-arrow-up:before{content:\"\\f062\"}.fa-arrow-down:before{content:\"\\f063\"}.fa-mail-forward:before,.fa-share:before{content:\"\\f064\"}.fa-expand:before{content:\"\\f065\"}.fa-compress:before{content:\"\\f066\"}.fa-plus:before{content:\"\\f067\"}.fa-minus:before{content:\"\\f068\"}.fa-asterisk:before{content:\"\\f069\"}.fa-exclamation-circle:before{content:\"\\f06a\"}.fa-gift:before{content:\"\\f06b\"}.fa-leaf:before{content:\"\\f06c\"}.fa-fire:before{content:\"\\f06d\"}.fa-eye:before{content:\"\\f06e\"}.fa-eye-slash:before{content:\"\\f070\"}.fa-warning:before,.fa-exclamation-triangle:before{content:\"\\f071\"}.fa-plane:before{content:\"\\f072\"}.fa-calendar:before{content:\"\\f073\"}.fa-random:before{content:\"\\f074\"}.fa-comment:before{content:\"\\f075\"}.fa-magnet:before{content:\"\\f076\"}.fa-chevron-up:before{content:\"\\f077\"}.fa-chevron-down:before{content:\"\\f078\"}.fa-retweet:before{content:\"\\f079\"}.fa-shopping-cart:before{content:\"\\f07a\"}.fa-folder:before{content:\"\\f07b\"}.fa-folder-open:before{content:\"\\f07c\"}.fa-arrows-v:before{content:\"\\f07d\"}.fa-arrows-h:before{content:\"\\f07e\"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:\"\\f080\"}.fa-twitter-square:before{content:\"\\f081\"}.fa-facebook-square:before{content:\"\\f082\"}.fa-camera-retro:before{content:\"\\f083\"}.fa-key:before{content:\"\\f084\"}.fa-gears:before,.fa-cogs:before{content:\"\\f085\"}.fa-comments:before{content:\"\\f086\"}.fa-thumbs-o-up:before{content:\"\\f087\"}.fa-thumbs-o-down:before{content:\"\\f088\"}.fa-star-half:before{content:\"\\f089\"}.fa-heart-o:before{content:\"\\f08a\"}.fa-sign-out:before{content:\"\\f08b\"}.fa-linkedin-square:before{content:\"\\f08c\"}.fa-thumb-tack:before{content:\"\\f08d\"}.fa-external-link:before{content:\"\\f08e\"}.fa-sign-in:before{content:\"\\f090\"}.fa-trophy:before{content:\"\\f091\"}.fa-github-square:before{content:\"\\f092\"}.fa-upload:before{content:\"\\f093\"}.fa-lemon-o:before{content:\"\\f094\"}.fa-phone:before{content:\"\\f095\"}.fa-square-o:before{content:\"\\f096\"}.fa-bookmark-o:before{content:\"\\f097\"}.fa-phone-square:before{content:\"\\f098\"}.fa-twitter:before{content:\"\\f099\"}.fa-facebook:before{content:\"\\f09a\"}.fa-github:before{content:\"\\f09b\"}.fa-unlock:before{content:\"\\f09c\"}.fa-credit-card:before{content:\"\\f09d\"}.fa-rss:before{content:\"\\f09e\"}.fa-hdd-o:before{content:\"\\f0a0\"}.fa-bullhorn:before{content:\"\\f0a1\"}.fa-bell:before{content:\"\\f0f3\"}.fa-certificate:before{content:\"\\f0a3\"}.fa-hand-o-right:before{content:\"\\f0a4\"}.fa-hand-o-left:before{content:\"\\f0a5\"}.fa-hand-o-up:before{content:\"\\f0a6\"}.fa-hand-o-down:before{content:\"\\f0a7\"}.fa-arrow-circle-left:before{content:\"\\f0a8\"}.fa-arrow-circle-right:before{content:\"\\f0a9\"}.fa-arrow-circle-up:before{content:\"\\f0aa\"}.fa-arrow-circle-down:before{content:\"\\f0ab\"}.fa-globe:before{content:\"\\f0ac\"}.fa-wrench:before{content:\"\\f0ad\"}.fa-tasks:before{content:\"\\f0ae\"}.fa-filter:before{content:\"\\f0b0\"}.fa-briefcase:before{content:\"\\f0b1\"}.fa-arrows-alt:before{content:\"\\f0b2\"}.fa-group:before,.fa-users:before{content:\"\\f0c0\"}.fa-chain:before,.fa-link:before{content:\"\\f0c1\"}.fa-cloud:before{content:\"\\f0c2\"}.fa-flask:before{content:\"\\f0c3\"}.fa-cut:before,.fa-scissors:before{content:\"\\f0c4\"}.fa-copy:before,.fa-files-o:before{content:\"\\f0c5\"}.fa-paperclip:before{content:\"\\f0c6\"}.fa-save:before,.fa-floppy-o:before{content:\"\\f0c7\"}.fa-square:before{content:\"\\f0c8\"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:\"\\f0c9\"}.fa-list-ul:before{content:\"\\f0ca\"}.fa-list-ol:before{content:\"\\f0cb\"}.fa-strikethrough:before{content:\"\\f0cc\"}.fa-underline:before{content:\"\\f0cd\"}.fa-table:before{content:\"\\f0ce\"}.fa-magic:before{content:\"\\f0d0\"}.fa-truck:before{content:\"\\f0d1\"}.fa-pinterest:before{content:\"\\f0d2\"}.fa-pinterest-square:before{content:\"\\f0d3\"}.fa-google-plus-square:before{content:\"\\f0d4\"}.fa-google-plus:before{content:\"\\f0d5\"}.fa-money:before{content:\"\\f0d6\"}.fa-caret-down:before{content:\"\\f0d7\"}.fa-caret-up:before{content:\"\\f0d8\"}.fa-caret-left:before{content:\"\\f0d9\"}.fa-caret-right:before{content:\"\\f0da\"}.fa-columns:before{content:\"\\f0db\"}.fa-unsorted:before,.fa-sort:before{content:\"\\f0dc\"}.fa-sort-down:before,.fa-sort-desc:before{content:\"\\f0dd\"}.fa-sort-up:before,.fa-sort-asc:before{content:\"\\f0de\"}.fa-envelope:before{content:\"\\f0e0\"}.fa-linkedin:before{content:\"\\f0e1\"}.fa-rotate-left:before,.fa-undo:before{content:\"\\f0e2\"}.fa-legal:before,.fa-gavel:before{content:\"\\f0e3\"}.fa-dashboard:before,.fa-tachometer:before{content:\"\\f0e4\"}.fa-comment-o:before{content:\"\\f0e5\"}.fa-comments-o:before{content:\"\\f0e6\"}.fa-flash:before,.fa-bolt:before{content:\"\\f0e7\"}.fa-sitemap:before{content:\"\\f0e8\"}.fa-umbrella:before{content:\"\\f0e9\"}.fa-paste:before,.fa-clipboard:before{content:\"\\f0ea\"}.fa-lightbulb-o:before{content:\"\\f0eb\"}.fa-exchange:before{content:\"\\f0ec\"}.fa-cloud-download:before{content:\"\\f0ed\"}.fa-cloud-upload:before{content:\"\\f0ee\"}.fa-user-md:before{content:\"\\f0f0\"}.fa-stethoscope:before{content:\"\\f0f1\"}.fa-suitcase:before{content:\"\\f0f2\"}.fa-bell-o:before{content:\"\\f0a2\"}.fa-coffee:before{content:\"\\f0f4\"}.fa-cutlery:before{content:\"\\f0f5\"}.fa-file-text-o:before{content:\"\\f0f6\"}.fa-building-o:before{content:\"\\f0f7\"}.fa-hospital-o:before{content:\"\\f0f8\"}.fa-ambulance:before{content:\"\\f0f9\"}.fa-medkit:before{content:\"\\f0fa\"}.fa-fighter-jet:before{content:\"\\f0fb\"}.fa-beer:before{content:\"\\f0fc\"}.fa-h-square:before{content:\"\\f0fd\"}.fa-plus-square:before{content:\"\\f0fe\"}.fa-angle-double-left:before{content:\"\\f100\"}.fa-angle-double-right:before{content:\"\\f101\"}.fa-angle-double-up:before{content:\"\\f102\"}.fa-angle-double-down:before{content:\"\\f103\"}.fa-angle-left:before{content:\"\\f104\"}.fa-angle-right:before{content:\"\\f105\"}.fa-angle-up:before{content:\"\\f106\"}.fa-angle-down:before{content:\"\\f107\"}.fa-desktop:before{content:\"\\f108\"}.fa-laptop:before{content:\"\\f109\"}.fa-tablet:before{content:\"\\f10a\"}.fa-mobile-phone:before,.fa-mobile:before{content:\"\\f10b\"}.fa-circle-o:before{content:\"\\f10c\"}.fa-quote-left:before{content:\"\\f10d\"}.fa-quote-right:before{content:\"\\f10e\"}.fa-spinner:before{content:\"\\f110\"}.fa-circle:before{content:\"\\f111\"}.fa-mail-reply:before,.fa-reply:before{content:\"\\f112\"}.fa-github-alt:before{content:\"\\f113\"}.fa-folder-o:before{content:\"\\f114\"}.fa-folder-open-o:before{content:\"\\f115\"}.fa-smile-o:before{content:\"\\f118\"}.fa-frown-o:before{content:\"\\f119\"}.fa-meh-o:before{content:\"\\f11a\"}.fa-gamepad:before{content:\"\\f11b\"}.fa-keyboard-o:before{content:\"\\f11c\"}.fa-flag-o:before{content:\"\\f11d\"}.fa-flag-checkered:before{content:\"\\f11e\"}.fa-terminal:before{content:\"\\f120\"}.fa-code:before{content:\"\\f121\"}.fa-mail-reply-all:before,.fa-reply-all:before{content:\"\\f122\"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:\"\\f123\"}.fa-location-arrow:before{content:\"\\f124\"}.fa-crop:before{content:\"\\f125\"}.fa-code-fork:before{content:\"\\f126\"}.fa-unlink:before,.fa-chain-broken:before{content:\"\\f127\"}.fa-question:before{content:\"\\f128\"}.fa-info:before{content:\"\\f129\"}.fa-exclamation:before{content:\"\\f12a\"}.fa-superscript:before{content:\"\\f12b\"}.fa-subscript:before{content:\"\\f12c\"}.fa-eraser:before{content:\"\\f12d\"}.fa-puzzle-piece:before{content:\"\\f12e\"}.fa-microphone:before{content:\"\\f130\"}.fa-microphone-slash:before{content:\"\\f131\"}.fa-shield:before{content:\"\\f132\"}.fa-calendar-o:before{content:\"\\f133\"}.fa-fire-extinguisher:before{content:\"\\f134\"}.fa-rocket:before{content:\"\\f135\"}.fa-maxcdn:before{content:\"\\f136\"}.fa-chevron-circle-left:before{content:\"\\f137\"}.fa-chevron-circle-right:before{content:\"\\f138\"}.fa-chevron-circle-up:before{content:\"\\f139\"}.fa-chevron-circle-down:before{content:\"\\f13a\"}.fa-html5:before{content:\"\\f13b\"}.fa-css3:before{content:\"\\f13c\"}.fa-anchor:before{content:\"\\f13d\"}.fa-unlock-alt:before{content:\"\\f13e\"}.fa-bullseye:before{content:\"\\f140\"}.fa-ellipsis-h:before{content:\"\\f141\"}.fa-ellipsis-v:before{content:\"\\f142\"}.fa-rss-square:before{content:\"\\f143\"}.fa-play-circle:before{content:\"\\f144\"}.fa-ticket:before{content:\"\\f145\"}.fa-minus-square:before{content:\"\\f146\"}.fa-minus-square-o:before{content:\"\\f147\"}.fa-level-up:before{content:\"\\f148\"}.fa-level-down:before{content:\"\\f149\"}.fa-check-square:before{content:\"\\f14a\"}.fa-pencil-square:before{content:\"\\f14b\"}.fa-external-link-square:before{content:\"\\f14c\"}.fa-share-square:before{content:\"\\f14d\"}.fa-compass:before{content:\"\\f14e\"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:\"\\f150\"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:\"\\f151\"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:\"\\f152\"}.fa-euro:before,.fa-eur:before{content:\"\\f153\"}.fa-gbp:before{content:\"\\f154\"}.fa-dollar:before,.fa-usd:before{content:\"\\f155\"}.fa-rupee:before,.fa-inr:before{content:\"\\f156\"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:\"\\f157\"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:\"\\f158\"}.fa-won:before,.fa-krw:before{content:\"\\f159\"}.fa-bitcoin:before,.fa-btc:before{content:\"\\f15a\"}.fa-file:before{content:\"\\f15b\"}.fa-file-text:before{content:\"\\f15c\"}.fa-sort-alpha-asc:before{content:\"\\f15d\"}.fa-sort-alpha-desc:before{content:\"\\f15e\"}.fa-sort-amount-asc:before{content:\"\\f160\"}.fa-sort-amount-desc:before{content:\"\\f161\"}.fa-sort-numeric-asc:before{content:\"\\f162\"}.fa-sort-numeric-desc:before{content:\"\\f163\"}.fa-thumbs-up:before{content:\"\\f164\"}.fa-thumbs-down:before{content:\"\\f165\"}.fa-youtube-square:before{content:\"\\f166\"}.fa-youtube:before{content:\"\\f167\"}.fa-xing:before{content:\"\\f168\"}.fa-xing-square:before{content:\"\\f169\"}.fa-youtube-play:before{content:\"\\f16a\"}.fa-dropbox:before{content:\"\\f16b\"}.fa-stack-overflow:before{content:\"\\f16c\"}.fa-instagram:before{content:\"\\f16d\"}.fa-flickr:before{content:\"\\f16e\"}.fa-adn:before{content:\"\\f170\"}.fa-bitbucket:before{content:\"\\f171\"}.fa-bitbucket-square:before{content:\"\\f172\"}.fa-tumblr:before{content:\"\\f173\"}.fa-tumblr-square:before{content:\"\\f174\"}.fa-long-arrow-down:before{content:\"\\f175\"}.fa-long-arrow-up:before{content:\"\\f176\"}.fa-long-arrow-left:before{content:\"\\f177\"}.fa-long-arrow-right:before{content:\"\\f178\"}.fa-apple:before{content:\"\\f179\"}.fa-windows:before{content:\"\\f17a\"}.fa-android:before{content:\"\\f17b\"}.fa-linux:before{content:\"\\f17c\"}.fa-dribbble:before{content:\"\\f17d\"}.fa-skype:before{content:\"\\f17e\"}.fa-foursquare:before{content:\"\\f180\"}.fa-trello:before{content:\"\\f181\"}.fa-female:before{content:\"\\f182\"}.fa-male:before{content:\"\\f183\"}.fa-gittip:before{content:\"\\f184\"}.fa-sun-o:before{content:\"\\f185\"}.fa-moon-o:before{content:\"\\f186\"}.fa-archive:before{content:\"\\f187\"}.fa-bug:before{content:\"\\f188\"}.fa-vk:before{content:\"\\f189\"}.fa-weibo:before{content:\"\\f18a\"}.fa-renren:before{content:\"\\f18b\"}.fa-pagelines:before{content:\"\\f18c\"}.fa-stack-exchange:before{content:\"\\f18d\"}.fa-arrow-circle-o-right:before{content:\"\\f18e\"}.fa-arrow-circle-o-left:before{content:\"\\f190\"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:\"\\f191\"}.fa-dot-circle-o:before{content:\"\\f192\"}.fa-wheelchair:before{content:\"\\f193\"}.fa-vimeo-square:before{content:\"\\f194\"}.fa-turkish-lira:before,.fa-try:before{content:\"\\f195\"}.fa-plus-square-o:before{content:\"\\f196\"}.fa-space-shuttle:before{content:\"\\f197\"}.fa-slack:before{content:\"\\f198\"}.fa-envelope-square:before{content:\"\\f199\"}.fa-wordpress:before{content:\"\\f19a\"}.fa-openid:before{content:\"\\f19b\"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:\"\\f19c\"}.fa-mortar-board:before,.fa-graduation-cap:before{content:\"\\f19d\"}.fa-yahoo:before{content:\"\\f19e\"}.fa-google:before{content:\"\\f1a0\"}.fa-reddit:before{content:\"\\f1a1\"}.fa-reddit-square:before{content:\"\\f1a2\"}.fa-stumbleupon-circle:before{content:\"\\f1a3\"}.fa-stumbleupon:before{content:\"\\f1a4\"}.fa-delicious:before{content:\"\\f1a5\"}.fa-digg:before{content:\"\\f1a6\"}.fa-pied-piper:before{content:\"\\f1a7\"}.fa-pied-piper-alt:before{content:\"\\f1a8\"}.fa-drupal:before{content:\"\\f1a9\"}.fa-joomla:before{content:\"\\f1aa\"}.fa-language:before{content:\"\\f1ab\"}.fa-fax:before{content:\"\\f1ac\"}.fa-building:before{content:\"\\f1ad\"}.fa-child:before{content:\"\\f1ae\"}.fa-paw:before{content:\"\\f1b0\"}.fa-spoon:before{content:\"\\f1b1\"}.fa-cube:before{content:\"\\f1b2\"}.fa-cubes:before{content:\"\\f1b3\"}.fa-behance:before{content:\"\\f1b4\"}.fa-behance-square:before{content:\"\\f1b5\"}.fa-steam:before{content:\"\\f1b6\"}.fa-steam-square:before{content:\"\\f1b7\"}.fa-recycle:before{content:\"\\f1b8\"}.fa-automobile:before,.fa-car:before{content:\"\\f1b9\"}.fa-cab:before,.fa-taxi:before{content:\"\\f1ba\"}.fa-tree:before{content:\"\\f1bb\"}.fa-spotify:before{content:\"\\f1bc\"}.fa-deviantart:before{content:\"\\f1bd\"}.fa-soundcloud:before{content:\"\\f1be\"}.fa-database:before{content:\"\\f1c0\"}.fa-file-pdf-o:before{content:\"\\f1c1\"}.fa-file-word-o:before{content:\"\\f1c2\"}.fa-file-excel-o:before{content:\"\\f1c3\"}.fa-file-powerpoint-o:before{content:\"\\f1c4\"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:\"\\f1c5\"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:\"\\f1c6\"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:\"\\f1c7\"}.fa-file-movie-o:before,.fa-file-video-o:before{content:\"\\f1c8\"}.fa-file-code-o:before{content:\"\\f1c9\"}.fa-vine:before{content:\"\\f1ca\"}.fa-codepen:before{content:\"\\f1cb\"}.fa-jsfiddle:before{content:\"\\f1cc\"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:\"\\f1cd\"}.fa-circle-o-notch:before{content:\"\\f1ce\"}.fa-ra:before,.fa-rebel:before{content:\"\\f1d0\"}.fa-ge:before,.fa-empire:before{content:\"\\f1d1\"}.fa-git-square:before{content:\"\\f1d2\"}.fa-git:before{content:\"\\f1d3\"}.fa-hacker-news:before{content:\"\\f1d4\"}.fa-tencent-weibo:before{content:\"\\f1d5\"}.fa-qq:before{content:\"\\f1d6\"}.fa-wechat:before,.fa-weixin:before{content:\"\\f1d7\"}.fa-send:before,.fa-paper-plane:before{content:\"\\f1d8\"}.fa-send-o:before,.fa-paper-plane-o:before{content:\"\\f1d9\"}.fa-history:before{content:\"\\f1da\"}.fa-circle-thin:before{content:\"\\f1db\"}.fa-header:before{content:\"\\f1dc\"}.fa-paragraph:before{content:\"\\f1dd\"}.fa-sliders:before{content:\"\\f1de\"}.fa-share-alt:before{content:\"\\f1e0\"}.fa-share-alt-square:before{content:\"\\f1e1\"}.fa-bomb:before{content:\"\\f1e2\"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:\"\\f1e3\"}.fa-tty:before{content:\"\\f1e4\"}.fa-binoculars:before{content:\"\\f1e5\"}.fa-plug:before{content:\"\\f1e6\"}.fa-slideshare:before{content:\"\\f1e7\"}.fa-twitch:before{content:\"\\f1e8\"}.fa-yelp:before{content:\"\\f1e9\"}.fa-newspaper-o:before{content:\"\\f1ea\"}.fa-wifi:before{content:\"\\f1eb\"}.fa-calculator:before{content:\"\\f1ec\"}.fa-paypal:before{content:\"\\f1ed\"}.fa-google-wallet:before{content:\"\\f1ee\"}.fa-cc-visa:before{content:\"\\f1f0\"}.fa-cc-mastercard:before{content:\"\\f1f1\"}.fa-cc-discover:before{content:\"\\f1f2\"}.fa-cc-amex:before{content:\"\\f1f3\"}.fa-cc-paypal:before{content:\"\\f1f4\"}.fa-cc-stripe:before{content:\"\\f1f5\"}.fa-bell-slash:before{content:\"\\f1f6\"}.fa-bell-slash-o:before{content:\"\\f1f7\"}.fa-trash:before{content:\"\\f1f8\"}.fa-copyright:before{content:\"\\f1f9\"}.fa-at:before{content:\"\\f1fa\"}.fa-eyedropper:before{content:\"\\f1fb\"}.fa-paint-brush:before{content:\"\\f1fc\"}.fa-birthday-cake:before{content:\"\\f1fd\"}.fa-area-chart:before{content:\"\\f1fe\"}.fa-pie-chart:before{content:\"\\f200\"}.fa-line-chart:before{content:\"\\f201\"}.fa-lastfm:before{content:\"\\f202\"}.fa-lastfm-square:before{content:\"\\f203\"}.fa-toggle-off:before{content:\"\\f204\"}.fa-toggle-on:before{content:\"\\f205\"}.fa-bicycle:before{content:\"\\f206\"}.fa-bus:before{content:\"\\f207\"}.fa-ioxhost:before{content:\"\\f208\"}.fa-angellist:before{content:\"\\f209\"}.fa-cc:before{content:\"\\f20a\"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:\"\\f20b\"}.fa-meanpath:before{content:\"\\f20c\"}"
  },
  {
    "path": "static/data.go",
    "content": "package static\n\nimport (\n\t\"embed\"\n\t\"net/http\"\n\t\"os\"\n)\n\n//go:embed img/* js/* css/* fonts/*\n//go:embed index.html\nvar assets embed.FS\n\nfunc GetFilesystem() http.FileSystem {\n\tif os.Getenv(\"PGWEB_ASSETS_DEVMODE\") == \"1\" {\n\t\treturn http.Dir(\"./static\")\n\t}\n\treturn http.FS(assets)\n}\n\nfunc GetHandler() http.Handler {\n\treturn http.FileServer(GetFilesystem())\n}\n"
  },
  {
    "path": "static/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\" xml:lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n  <title>pgweb</title>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <meta http-equiv=\"Content-Language\" content=\"en\">\n  <link rel=\"stylesheet\" href=\"static/css/bootstrap.css\"></link>\n  <link rel=\"stylesheet\" href=\"static/css/font-awesome.css\"></link>\n  <link rel=\"stylesheet\" href=\"static/css/app.css\"></link>\n  <link rel=\"icon\" type=\"image/x-icon\" href=\"static/img/icon.ico\" />\n  <script type=\"text/javascript\" src=\"static/js/jquery.js\"></script>\n  <script type=\"text/javascript\" src=\"static/js/ace.js\"></script>\n  <script type=\"text/javascript\" src=\"static/js/ace-pgsql.js\"></script>\n  <script type=\"text/javascript\" src=\"static/js/ext-language_tools.js\"></script>\n  <script type=\"text/javascript\" src=\"static/js/bootstrap-contextmenu.js\"></script>\n  <script type=\"text/javascript\" src=\"static/js/bootstrap-dropdown.js\"></script>\n  <script type=\"text/javascript\" src=\"static/js/utils.js\"></script>\n  <script type=\"text/javascript\" src=\"static/js/bootstrap3-typeahead.min.js\"></script>\n  <script type=\"text/javascript\" src=\"static/js/app.js\"></script>\n  <script type=\"text/javascript\" src=\"static/js/base64.js\"></script>\n</head>\n<body>\n  <div id=\"main\">\n    <div id=\"nav\">\n      <ul>\n        <li id=\"table_content\">Rows</li>\n        <li id=\"table_structure\">Structure</li>\n        <li id=\"table_indexes\">Indexes</li>\n        <li id=\"table_constraints\">Constraints</li>\n        <li id=\"table_query\" class=\"selected\">Query</li>\n        <li id=\"table_history\">History</li>\n        <li id=\"table_activity\">Activity</li>\n        <li id=\"table_connection\">Connection</li>\n      </ul>\n\n      <div class=\"connection-actions\">\n        <a href=\"#\" id=\"edit_connection\" class=\"btn btn-default btn-sm\"><i class=\"fa fa-database\"></i> Connect</a>\n        <a href=\"#\" id=\"close_connection\" class=\"btn btn-default btn-sm\">Disconnect</a>\n      </div>\n    </div>\n    <div id=\"sidebar\">\n      <div class=\"current-database\">\n        <div class=\"wrap\">\n          <i class=\"fa fa-database\"></i> <span class=\"current-database-name\" id=\"current_database\"></span>\n          <input class=\"typeahead\" id=\"database_search\" type=\"text\" placeholder=\"Search database\" autocomplete=\"off\" />\n          <span class=\"refresh\" id=\"refresh_tables\" title=\"Refresh tables list\"><i class=\"fa fa-refresh\"></i></span>\n        </div>\n      </div>\n      <div class=\"objects-search\">\n        <div class=\"wrap\">\n          <i class=\"fa fa-search\"></i>\n          <i class=\"fa fa-times-circle clear-objects-filter\"></i>\n          <input type=\"text\" placeholder=\"Filter database objects\" id=\"filter_database_objects\" />\n        </div>\n      </div>\n      <div class=\"tables-list\">\n        <div class=\"wrap\">\n          <div id=\"objects\"></div>\n        </div>\n      </div>\n      <div class=\"table-information\">\n        <div class=\"wrap\">\n          <div class=\"title\">Table Information</div>\n          <div class=\"lines\">\n            <div class=\"line\">Size: <span id=\"table_total_size\"></span></div>\n            <div class=\"line\">Data size: <span id=\"table_data_size\"></span></div>\n            <div class=\"line\">Index size: <span id=\"table_index_size\"></span></div>\n            <div class=\"line\">Estimated rows: <span id=\"table_rows_count\"></span></div>\n          </div>\n        </div>\n      </div>\n    </div>\n    <div id=\"body\">\n      <div id=\"input\">\n        <div class=\"input-wrapper\">\n          <div id=\"custom_query\"></div>\n        </div>\n        <div class=\"actions\">\n          <input type=\"button\" id=\"run\" value=\"Run Query\" class=\"btn btn-sm btn-primary\" />\n          <div id=\"explain-dropdown\" class=\"btn-group left\">\n            <button id=\"explain-dropdown-toggle\" type=\"button\" class=\"btn btn-default dropdown-toggle\" data-toggle=\"dropdown\">\n              Explain Query <span class=\"caret\"></span>\n            </button>\n            <ul class=\"dropdown-menu\" role=\"menu\">\n              <li><a href=\"#\" id=\"explain\">Explain Query</a></li>\n              <li><a href=\"#\" id=\"analyze\">Analyze Query</a></li>\n            </ul>\n          </div>\n          <div id=\"load-query-dropdown\" class=\"btn-group left\" style=\"display: none\">\n            <button id=\"load-local-query\" type=\"button\" class=\"btn btn-default dropdown-toggle\" data-toggle=\"dropdown\" disabled=\"disabled\">\n              Template <span class=\"caret\"></span>\n            </button>\n            <ul class=\"dropdown-menu\" role=\"menu\">\n            </ul>\n          </div>\n          <div id=\"query_progress\">Please wait, query is executing...</div>\n          <div class=\"pull-right\">\n            <span id=\"result-rows-count\"></span>\n            <input type=\"button\" id=\"json\" value=\"JSON\" class=\"btn btn-sm btn-default\" />\n            <input type=\"button\" id=\"csv\" value=\"CSV\" class=\"btn btn-sm btn-default\" />\n            <input type=\"button\" id=\"xml\" value=\"XML\" class=\"btn btn-sm btn-default\" />\n          </div>\n        </div>\n        <div id=\"input_resize_handler\"></div>\n      </div>\n      <div id=\"output\">\n        <div class=\"wrapper\">\n          <table id=\"results\" class=\"table\">\n            <thead id=\"results_header\"></thead>\n            <tbody id=\"results_body\"></tbody>\n          </table>\n          <div id=\"results_view\"></div>\n        </div>\n      </div>\n      <div id=\"pagination\">\n        <form class=\"filters\" action=\"#\" id=\"rows_filter\">\n          <span>Search</span>\n          <select class=\"column form-control\"></select>\n          <select class=\"filter form-control\">\n            <option value=\"\">Select filter</option>\n            <option value=\"equal\">=</option>\n            <option value=\"not_equal\">&ne;</option>\n            <option value=\"greater\">&gt;</option>\n            <option value=\"greater_eq\">&ge;</option>\n            <option value=\"less\">&lt;</option>\n            <option value=\"less_eq\">&le;</option>\n            <option value=\"like\">LIKE</option>\n            <option value=\"ilike\">ILIKE</option>\n            <option value=\"null\">IS NULL</option>\n            <option value=\"not_null\">NOT NULL</option>\n          </select>\n          <input type=\"text\" class=\"form-control\" placeholder=\"Filter value\" id=\"table_filter_value\" />\n          <button class=\"btn btn-primary btn-sm apply-filters\" type=\"submit\">Apply</button>\n          <button class=\"btn btn-default btn-sm reset-filters\"><i class=\"fa fa-times\"></i></button>\n        </form>\n        <div class=\"btn-group\">\n          <button type=\"button\" class=\"btn btn-default btn-sm prev-page\" disabled=\"disabled\"><i class=\"fa fa-angle-left\"></i></button>\n          <button type=\"button\" class=\"btn btn-default btn-sm page change-limit\" title=\"Click to change row limit\"></button>\n          <button type=\"button\" class=\"btn btn-default btn-sm next-page\"><i class=\"fa fa-angle-right\"></i></button>\n        </div>\n        <div class=\"current-page\" data-page=\"1\" data-pages=\"1\">\n          <span id=\"total_records\"></span> rows\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <div id=\"content_modal\">\n    <div class=\"title\">\n      Cell Content\n      <div class=\"actions\">\n        <i class=\"fa fa-times content-modal-action\" data-action=\"close\"></i>\n        <i class=\"fa fa-copy content-modal-action\" data-action=\"copy\"></i>\n      </div>\n    </div>\n    <pre class=\"content\"></pre>\n  </div>\n\n  <div id=\"connection_window\">\n    <div class=\"connection-settings\">\n      <div class=\"header\">\n        <h1>pgweb</h1>\n        <div class=\"version\"></div>\n        <div class=\"update alert alert-warning\"></div>\n      </div>\n\n      <form role=\"form\" class=\"form-horizontal\" id=\"connection_form\">\n        <div class=\"text-center\">\n          <div class=\"btn-group btn-group-sm connection-group-switch\">\n            <button type=\"button\" data=\"scheme\" class=\"btn btn-default\" id=\"connection_scheme\">Scheme</button>\n            <button type=\"button\" data=\"standard\" class=\"btn btn-default active\" id=\"connection_standard\">Standard</button>\n            <button type=\"button\" data=\"ssh\" class=\"btn btn-default\" id=\"connection_ssh\">SSH</button>\n          </div>\n        </div>\n\n        <hr/>\n\n        <div class=\"connection-scheme-group\">\n          <div class=\"form-group\">\n            <div class=\"col-sm-12\">\n              <label>Enter server URL scheme</label>\n              <input type=\"text\" class=\"form-control\" id=\"connection_url\" name=\"url\" autocomplete=\"off\">\n              <p class=\"help-block\">\n                URL format: postgres://user:password@host:port/db?sslmode=mode<br/>\n                Read more on PostgreSQL <a href=\"https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING\" target=\"_blank\">connection string format</a>.\n              </p>\n            </div>\n          </div>\n        </div>\n\n        <div class=\"connection-bookmarks-group\">\n          <div class=\"form-group bookmarks\">\n            <label class=\"col-sm-3 control-label\">Bookmark</label>\n            <div class=\"col-sm-9\">\n              <select class=\"form-control\" id=\"connection_bookmarks\"></select>\n            </div>\n          </div>\n        </div>\n\n        <div class=\"connection-standard-group\">\n          <div class=\"form-group\">\n            <label class=\"col-sm-3 control-label\">Host</label>\n            <div class=\"col-sm-9\">\n              <div class=\"row\">\n                <div class=\"col-sm-9 col-xs-9\">\n                  <input type=\"text\" id=\"pg_host\" class=\"form-control\" />\n                </div>\n                <div class=\"col-sm-3 col-xs-3 no-left-padding\">\n                  <input type=\"text\" id=\"pg_port\" class=\"form-control\" placeholder=\"5432\" />\n                </div>\n              </div>\n            </div>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"col-sm-3 control-label\">Username</label>\n            <div class=\"col-sm-9\">\n              <input type=\"text\" id=\"pg_user\" class=\"form-control\" />\n            </div>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"col-sm-3 control-label\">Password</label>\n            <div class=\"col-sm-9\">\n              <input type=\"password\" id=\"pg_password\" class=\"form-control\" />\n            </div>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"col-sm-3 control-label\">Database</label>\n            <div class=\"col-sm-9\">\n              <input type=\"text\" id=\"pg_db\" class=\"form-control\" />\n            </div>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"col-sm-3 control-label\">SSL Mode</label>\n            <div class=\"col-sm-9\">\n              <select class=\"form-control\" id=\"connection_ssl\">\n                <option value=\"disable\">disable</option>\n                <option value=\"require\" selected=\"selected\">require</option>\n                <option value=\"verify-full\">verify-full</option>\n              </select>\n            </div>\n          </div>\n        </div>\n\n        <div class=\"connection-ssh-group\">\n          <hr/>\n\n          <h3 class=\"text-center\">SSH Connection</h3>\n\n          <div class=\"form-group\">\n            <label class=\"col-sm-3 control-label\">Host</label>\n            <div class=\"col-sm-7\">\n              <input type=\"text\" id=\"ssh_host\" class=\"form-control\" />\n            </div>\n            <div class=\"col-sm-2 no-left-padding\">\n              <input type=\"text\" id=\"ssh_port\" class=\"form-control\" placeholder=\"22\" />\n            </div>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"col-sm-3 control-label\">Credentials</label>\n            <div class=\"col-sm-5\">\n              <input type=\"text\" id=\"ssh_user\" class=\"form-control\" placeholder=\"Username\" />\n            </div>\n            <div class=\"col-sm-4 no-left-padding\">\n              <input type=\"password\" id=\"ssh_password\" class=\"form-control\" placeholder=\"Password\" />\n            </div>\n          </div>\n\n          <div class=\"form-group\">\n            <label class=\"col-sm-3 control-label\">Auth Key</label>\n            <div class=\"col-sm-5\">\n              <input type=\"text\" id=\"ssh_key\" class=\"form-control\" placeholder=\"Key path\" />\n            </div>\n            <div class=\"col-sm-4 no-left-padding\">\n              <input type=\"password\" id=\"ssh_key_password\" class=\"form-control\" placeholder=\"Key password\" />\n            </div>\n          </div>\n\n          <hr/>\n        </div>\n\n        <div id=\"connection_error\" class=\"alert alert-danger\"></div>\n\n        <div class=\"form-group\">\n          <div class=\"col-sm-12\">\n            <button type=\"submit\" class=\"btn btn-block btn-primary open-connection\">Connect</button>\n            <button type=\"button\" id=\"close_connection_window\" class=\"btn btn-block btn-default\">Cancel</button>\n          </div>\n        </div>\n      </form>\n    </div>\n  </div>\n  <div id=\"tables_context_menu\">\n    <ul class=\"dropdown-menu\" role=\"menu\">\n      <li><a href=\"#\" data-action=\"copy\">Copy Table Name</a></li>\n      <li><a href=\"#\" data-action=\"analyze\">Analyze Table</a></li>\n      <li class=\"divider\"></li>\n      <li><a href=\"#\" data-action=\"export\" data-format=\"json\">Export to JSON</a></li>\n      <li><a href=\"#\" data-action=\"export\" data-format=\"csv\">Export to CSV</a></li>\n      <li><a href=\"#\" data-action=\"export\" data-format=\"xml\">Export to XML</a></li>\n      <li><a href=\"#\" data-action=\"dump\">Export to SQL</a></li>\n      <li class=\"divider\"></li>\n      <li><a href=\"#\" data-action=\"truncate\">Truncate Table</a></li>\n      <li><a href=\"#\" data-action=\"delete\">Delete Table</a></li>\n    </ul>\n  </div>\n  <div id=\"view_context_menu\">\n    <ul class=\"dropdown-menu\" role=\"menu\">\n      <li><a href=\"#\" data-action=\"view_def\">View Definition</a></li>\n      <li><a href=\"#\" data-action=\"copy\">Copy View Name</a></li>\n      <li><a href=\"#\" data-action=\"copy_def\">Copy View Definition</a></li>\n      <li class=\"divider\"></li>\n      <li><a href=\"#\" data-action=\"export\" data-format=\"json\">Export to JSON</a></li>\n      <li><a href=\"#\" data-action=\"export\" data-format=\"csv\">Export to CSV</a></li>\n      <li><a href=\"#\" data-action=\"export\" data-format=\"xml\">Export to XML</a></li>\n      <li class=\"divider\"></li>\n      <li><a href=\"#\" data-action=\"delete\">Delete View</a></li>\n    </ul>\n  </div>\n  <div id=\"current_database_context_menu\">\n    <ul class=\"dropdown-menu\" role=\"menu\">\n      <li><a href=\"#\" data-action=\"show_db_stats\">Show Database Stats</a></li>\n      <li><a href=\"#\" data-action=\"download_db_stats\">Download Database Stats</a></li>\n      <li class=\"divider\"></li>\n      <li><a href=\"#\" data-action=\"server_settings\">Show Server Settings</a></li>\n      <li class=\"divider\"></li>\n      <li><a href=\"#\" data-action=\"export\">Export SQL dump</a></li>\n    </ul>\n  </div>\n  <div id=\"results_header_menu\">\n    <ul class=\"dropdown-menu\" role=\"menu\">\n      <li><a href=\"#\" data-action=\"unique_values\" data-counts=\"false\">Unique Values</a></li>\n      <li><a href=\"#\" data-action=\"unique_values\" data-counts=\"true\">Unique Values + Counts</a></li>\n      <li><a href=\"#\" data-action=\"num_stats\">Numeric stats (min/max/avg)</a></li>\n      <li><a href=\"#\" data-action=\"copy_name\">Copy Column Name</a></li>\n    </ul>\n  </div>\n  <div id=\"results_row_menu\">\n    <ul class=\"dropdown-menu\" role=\"menu\">\n      <li><a href=\"#\" data-action=\"display_value\">Display Value</a></li>\n      <li><a href=\"#\" data-action=\"copy_value\">Copy Value</a></li>\n      <li><a href=\"#\" data-action=\"filter_by_value\">Filter Rows By Value</a></li>\n    </ul>\n  </div>\n  <div id=\"error_banner\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "static/js/ace-pgsql.js",
    "content": "ace.define(\"ace/mode/doc_comment_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text_highlight_rules\").TextHighlightRules,s=function(){this.$rules={start:[{token:\"comment.doc.tag\",regex:\"@[\\\\w\\\\d_]+\"},s.getTagRule(),{defaultToken:\"comment.doc\",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:\"comment.doc.tag.storage.type\",regex:\"\\\\b(?:TODO|FIXME|XXX|HACK)\\\\b\"}},s.getStartRule=function(e){return{token:\"comment.doc\",regex:\"\\\\/\\\\*(?=\\\\*)\",next:e}},s.getEndRule=function(e){return{token:\"comment.doc\",regex:\"\\\\*\\\\/\",next:e}},t.DocCommentHighlightRules=s}),ace.define(\"ace/mode/perl_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text_highlight_rules\").TextHighlightRules,s=function(){var e=\"base|constant|continue|else|elsif|for|foreach|format|goto|if|last|local|my|next|no|package|parent|redo|require|scalar|sub|unless|until|while|use|vars\",t=\"ARGV|ENV|INC|SIG\",n=\"getprotobynumber|getprotobyname|getservbyname|gethostbyaddr|gethostbyname|getservbyport|getnetbyaddr|getnetbyname|getsockname|getpeername|setpriority|getprotoent|setprotoent|getpriority|endprotoent|getservent|setservent|endservent|sethostent|socketpair|getsockopt|gethostent|endhostent|setsockopt|setnetent|quotemeta|localtime|prototype|getnetent|endnetent|rewinddir|wantarray|getpwuid|closedir|getlogin|readlink|endgrent|getgrgid|getgrnam|shmwrite|shutdown|readline|endpwent|setgrent|readpipe|formline|truncate|dbmclose|syswrite|setpwent|getpwnam|getgrent|getpwent|ucfirst|sysread|setpgrp|shmread|sysseek|sysopen|telldir|defined|opendir|connect|lcfirst|getppid|binmode|syscall|sprintf|getpgrp|readdir|seekdir|waitpid|reverse|unshift|symlink|dbmopen|semget|msgrcv|rename|listen|chroot|msgsnd|shmctl|accept|unpack|exists|fileno|shmget|system|unlink|printf|gmtime|msgctl|semctl|values|rindex|substr|splice|length|msgget|select|socket|return|caller|delete|alarm|ioctl|index|undef|lstat|times|srand|chown|fcntl|close|write|umask|rmdir|study|sleep|chomp|untie|print|utime|mkdir|atan2|split|crypt|flock|chmod|BEGIN|bless|chdir|semop|shift|reset|link|stat|chop|grep|fork|dump|join|open|tell|pipe|exit|glob|warn|each|bind|sort|pack|eval|push|keys|getc|kill|seek|sqrt|send|wait|rand|tied|read|time|exec|recv|eof|chr|int|ord|exp|pos|pop|sin|log|abs|oct|hex|tie|cos|vec|END|ref|map|die|uc|lc|do\",r=this.createKeywordMapper({keyword:e,\"constant.language\":t,\"support.function\":n},\"identifier\");this.$rules={start:[{token:\"comment.doc\",regex:\"^=(?:begin|item)\\\\b\",next:\"block_comment\"},{token:\"string.regexp\",regex:\"[/](?:(?:\\\\[(?:\\\\\\\\]|[^\\\\]])+\\\\])|(?:\\\\\\\\/|[^\\\\]/]))*[/]\\\\w*\\\\s*(?=[).,;]|$)\"},{token:\"string\",regex:'[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]'},{token:\"string\",regex:'[\"].*\\\\\\\\$',next:\"qqstring\"},{token:\"string\",regex:\"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"},{token:\"string\",regex:\"['].*\\\\\\\\$\",next:\"qstring\"},{token:\"constant.numeric\",regex:\"0x[0-9a-fA-F]+\\\\b\"},{token:\"constant.numeric\",regex:\"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"},{token:r,regex:\"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"},{token:\"keyword.operator\",regex:\"%#|\\\\$#|\\\\.\\\\.\\\\.|\\\\|\\\\|=|>>=|<<=|<=>|&&=|=>|!~|\\\\^=|&=|\\\\|=|\\\\.=|x=|%=|\\\\/=|\\\\*=|\\\\-=|\\\\+=|=~|\\\\*\\\\*|\\\\-\\\\-|\\\\.\\\\.|\\\\|\\\\||&&|\\\\+\\\\+|\\\\->|!=|==|>=|<=|>>|<<|,|=|\\\\?\\\\:|\\\\^|\\\\||x|%|\\\\/|\\\\*|<|&|\\\\\\\\|~|!|>|\\\\.|\\\\-|\\\\+|\\\\-C|\\\\-b|\\\\-S|\\\\-u|\\\\-t|\\\\-p|\\\\-l|\\\\-d|\\\\-f|\\\\-g|\\\\-s|\\\\-z|\\\\-k|\\\\-e|\\\\-O|\\\\-T|\\\\-B|\\\\-M|\\\\-A|\\\\-X|\\\\-W|\\\\-c|\\\\-R|\\\\-o|\\\\-x|\\\\-w|\\\\-r|\\\\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)\"},{token:\"comment\",regex:\"#.*$\"},{token:\"lparen\",regex:\"[[({]\"},{token:\"rparen\",regex:\"[\\\\])}]\"},{token:\"text\",regex:\"\\\\s+\"}],qqstring:[{token:\"string\",regex:'(?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?\"',next:\"start\"},{token:\"string\",regex:\".+\"}],qstring:[{token:\"string\",regex:\"(?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?'\",next:\"start\"},{token:\"string\",regex:\".+\"}],block_comment:[{token:\"comment.doc\",regex:\"^=cut\\\\b\",next:\"start\"},{defaultToken:\"comment.doc\"}]}};r.inherits(s,i),t.PerlHighlightRules=s}),ace.define(\"ace/mode/python_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text_highlight_rules\").TextHighlightRules,s=function(){var e=\"and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield|async|await|nonlocal\",t=\"True|False|None|NotImplemented|Ellipsis|__debug__\",n=\"abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|bin|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|apply|delattr|help|next|setattr|set|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern|ascii|breakpoint|bytes\",r=this.createKeywordMapper({\"invalid.deprecated\":\"debugger\",\"support.function\":n,\"variable.language\":\"self|cls\",\"constant.language\":t,keyword:e},\"identifier\"),i=\"[uU]?\",s=\"[rR]\",o=\"[fF]\",u=\"(?:[rR][fF]|[fF][rR])\",a=\"(?:(?:[1-9]\\\\d*)|(?:0))\",f=\"(?:0[oO]?[0-7]+)\",l=\"(?:0[xX][\\\\dA-Fa-f]+)\",c=\"(?:0[bB][01]+)\",h=\"(?:\"+a+\"|\"+f+\"|\"+l+\"|\"+c+\")\",p=\"(?:[eE][+-]?\\\\d+)\",d=\"(?:\\\\.\\\\d+)\",v=\"(?:\\\\d+)\",m=\"(?:(?:\"+v+\"?\"+d+\")|(?:\"+v+\"\\\\.))\",g=\"(?:(?:\"+m+\"|\"+v+\")\"+p+\")\",y=\"(?:\"+g+\"|\"+m+\")\",b=\"\\\\\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\\\\\abfnrtv'\\\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})\";this.$rules={start:[{token:\"comment\",regex:\"#.*$\"},{token:\"string\",regex:i+'\"{3}',next:\"qqstring3\"},{token:\"string\",regex:i+'\"(?=.)',next:\"qqstring\"},{token:\"string\",regex:i+\"'{3}\",next:\"qstring3\"},{token:\"string\",regex:i+\"'(?=.)\",next:\"qstring\"},{token:\"string\",regex:s+'\"{3}',next:\"rawqqstring3\"},{token:\"string\",regex:s+'\"(?=.)',next:\"rawqqstring\"},{token:\"string\",regex:s+\"'{3}\",next:\"rawqstring3\"},{token:\"string\",regex:s+\"'(?=.)\",next:\"rawqstring\"},{token:\"string\",regex:o+'\"{3}',next:\"fqqstring3\"},{token:\"string\",regex:o+'\"(?=.)',next:\"fqqstring\"},{token:\"string\",regex:o+\"'{3}\",next:\"fqstring3\"},{token:\"string\",regex:o+\"'(?=.)\",next:\"fqstring\"},{token:\"string\",regex:u+'\"{3}',next:\"rfqqstring3\"},{token:\"string\",regex:u+'\"(?=.)',next:\"rfqqstring\"},{token:\"string\",regex:u+\"'{3}\",next:\"rfqstring3\"},{token:\"string\",regex:u+\"'(?=.)\",next:\"rfqstring\"},{token:\"keyword.operator\",regex:\"\\\\+|\\\\-|\\\\*|\\\\*\\\\*|\\\\/|\\\\/\\\\/|%|@|<<|>>|&|\\\\||\\\\^|~|<|>|<=|=>|==|!=|<>|=\"},{token:\"punctuation\",regex:\",|:|;|\\\\->|\\\\+=|\\\\-=|\\\\*=|\\\\/=|\\\\/\\\\/=|%=|@=|&=|\\\\|=|^=|>>=|<<=|\\\\*\\\\*=\"},{token:\"paren.lparen\",regex:\"[\\\\[\\\\(\\\\{]\"},{token:\"paren.rparen\",regex:\"[\\\\]\\\\)\\\\}]\"},{token:\"text\",regex:\"\\\\s+\"},{include:\"constants\"}],qqstring3:[{token:\"constant.language.escape\",regex:b},{token:\"string\",regex:'\"{3}',next:\"start\"},{defaultToken:\"string\"}],qstring3:[{token:\"constant.language.escape\",regex:b},{token:\"string\",regex:\"'{3}\",next:\"start\"},{defaultToken:\"string\"}],qqstring:[{token:\"constant.language.escape\",regex:b},{token:\"string\",regex:\"\\\\\\\\$\",next:\"qqstring\"},{token:\"string\",regex:'\"|$',next:\"start\"},{defaultToken:\"string\"}],qstring:[{token:\"constant.language.escape\",regex:b},{token:\"string\",regex:\"\\\\\\\\$\",next:\"qstring\"},{token:\"string\",regex:\"'|$\",next:\"start\"},{defaultToken:\"string\"}],rawqqstring3:[{token:\"string\",regex:'\"{3}',next:\"start\"},{defaultToken:\"string\"}],rawqstring3:[{token:\"string\",regex:\"'{3}\",next:\"start\"},{defaultToken:\"string\"}],rawqqstring:[{token:\"string\",regex:\"\\\\\\\\$\",next:\"rawqqstring\"},{token:\"string\",regex:'\"|$',next:\"start\"},{defaultToken:\"string\"}],rawqstring:[{token:\"string\",regex:\"\\\\\\\\$\",next:\"rawqstring\"},{token:\"string\",regex:\"'|$\",next:\"start\"},{defaultToken:\"string\"}],fqqstring3:[{token:\"constant.language.escape\",regex:b},{token:\"string\",regex:'\"{3}',next:\"start\"},{token:\"paren.lparen\",regex:\"{\",push:\"fqstringParRules\"},{defaultToken:\"string\"}],fqstring3:[{token:\"constant.language.escape\",regex:b},{token:\"string\",regex:\"'{3}\",next:\"start\"},{token:\"paren.lparen\",regex:\"{\",push:\"fqstringParRules\"},{defaultToken:\"string\"}],fqqstring:[{token:\"constant.language.escape\",regex:b},{token:\"string\",regex:\"\\\\\\\\$\",next:\"fqqstring\"},{token:\"string\",regex:'\"|$',next:\"start\"},{token:\"paren.lparen\",regex:\"{\",push:\"fqstringParRules\"},{defaultToken:\"string\"}],fqstring:[{token:\"constant.language.escape\",regex:b},{token:\"string\",regex:\"'|$\",next:\"start\"},{token:\"paren.lparen\",regex:\"{\",push:\"fqstringParRules\"},{defaultToken:\"string\"}],rfqqstring3:[{token:\"string\",regex:'\"{3}',next:\"start\"},{token:\"paren.lparen\",regex:\"{\",push:\"fqstringParRules\"},{defaultToken:\"string\"}],rfqstring3:[{token:\"string\",regex:\"'{3}\",next:\"start\"},{token:\"paren.lparen\",regex:\"{\",push:\"fqstringParRules\"},{defaultToken:\"string\"}],rfqqstring:[{token:\"string\",regex:\"\\\\\\\\$\",next:\"rfqqstring\"},{token:\"string\",regex:'\"|$',next:\"start\"},{token:\"paren.lparen\",regex:\"{\",push:\"fqstringParRules\"},{defaultToken:\"string\"}],rfqstring:[{token:\"string\",regex:\"'|$\",next:\"start\"},{token:\"paren.lparen\",regex:\"{\",push:\"fqstringParRules\"},{defaultToken:\"string\"}],fqstringParRules:[{token:\"paren.lparen\",regex:\"[\\\\[\\\\(]\"},{token:\"paren.rparen\",regex:\"[\\\\]\\\\)]\"},{token:\"string\",regex:\"\\\\s+\"},{token:\"string\",regex:\"'(.)*'\"},{token:\"string\",regex:'\"(.)*\"'},{token:\"function.support\",regex:\"(!s|!r|!a)\"},{include:\"constants\"},{token:\"paren.rparen\",regex:\"}\",next:\"pop\"},{token:\"paren.lparen\",regex:\"{\",push:\"fqstringParRules\"}],constants:[{token:\"constant.numeric\",regex:\"(?:\"+y+\"|\\\\d+)[jJ]\\\\b\"},{token:\"constant.numeric\",regex:y},{token:\"constant.numeric\",regex:h+\"[lL]\\\\b\"},{token:\"constant.numeric\",regex:h+\"\\\\b\"},{token:[\"punctuation\",\"function.support\"],regex:\"(\\\\.)([a-zA-Z_]+)\\\\b\"},{token:r,regex:\"[a-zA-Z_$][a-zA-Z0-9_$]*\\\\b\"}]},this.normalizeRules()};r.inherits(s,i),t.PythonHighlightRules=s}),ace.define(\"ace/mode/json_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text_highlight_rules\").TextHighlightRules,s=function(){this.$rules={start:[{token:\"variable\",regex:'[\"](?:(?:\\\\\\\\.)|(?:[^\"\\\\\\\\]))*?[\"]\\\\s*(?=:)'},{token:\"string\",regex:'\"',next:\"string\"},{token:\"constant.numeric\",regex:\"0[xX][0-9a-fA-F]+\\\\b\"},{token:\"constant.numeric\",regex:\"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"},{token:\"constant.language.boolean\",regex:\"(?:true|false)\\\\b\"},{token:\"text\",regex:\"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"},{token:\"comment\",regex:\"\\\\/\\\\/.*$\"},{token:\"comment.start\",regex:\"\\\\/\\\\*\",next:\"comment\"},{token:\"paren.lparen\",regex:\"[[({]\"},{token:\"paren.rparen\",regex:\"[\\\\])}]\"},{token:\"text\",regex:\"\\\\s+\"}],string:[{token:\"constant.language.escape\",regex:/\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[\"\\\\\\/bfnrt])/},{token:\"string\",regex:'\"|$',next:\"start\"},{defaultToken:\"string\"}],comment:[{token:\"comment.end\",regex:\"\\\\*\\\\/\",next:\"start\"},{defaultToken:\"comment\"}]}};r.inherits(s,i),t.JsonHighlightRules=s}),ace.define(\"ace/mode/javascript_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/doc_comment_highlight_rules\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";function a(){var e=o.replace(\"\\\\d\",\"\\\\d\\\\-\"),t={onMatch:function(e,t,n){var r=e.charAt(1)==\"/\"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:\"meta.tag.punctuation.\"+(r==1?\"\":\"end-\")+\"tag-open.xml\",value:e.slice(0,r)},{type:\"meta.tag.tag-name.xml\",value:e.substr(r)}]},regex:\"</?\"+e+\"\",next:\"jsxAttributes\",nextState:\"jsx\"};this.$rules.start.unshift(t);var n={regex:\"{\",token:\"paren.quasi.start\",push:\"start\"};this.$rules.jsx=[n,t,{include:\"reference\"},{defaultToken:\"string\"}],this.$rules.jsxAttributes=[{token:\"meta.tag.punctuation.tag-close.xml\",regex:\"/?>\",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||\"start\",[{type:this.token,value:e}]},nextState:\"jsx\"},n,f(\"jsxAttributes\"),{token:\"entity.other.attribute-name.xml\",regex:e},{token:\"keyword.operator.attribute-equals.xml\",regex:\"=\"},{token:\"text.tag-whitespace.xml\",regex:\"\\\\s+\"},{token:\"string.attribute-value.xml\",regex:\"'\",stateName:\"jsx_attr_q\",push:[{token:\"string.attribute-value.xml\",regex:\"'\",next:\"pop\"},{include:\"reference\"},{defaultToken:\"string.attribute-value.xml\"}]},{token:\"string.attribute-value.xml\",regex:'\"',stateName:\"jsx_attr_qq\",push:[{token:\"string.attribute-value.xml\",regex:'\"',next:\"pop\"},{include:\"reference\"},{defaultToken:\"string.attribute-value.xml\"}]},t],this.$rules.reference=[{token:\"constant.language.escape.reference.xml\",regex:\"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\\\.-]+;)\"}]}function f(e){return[{token:\"comment\",regex:/\\/\\*/,next:[i.getTagRule(),{token:\"comment\",regex:\"\\\\*\\\\/\",next:e||\"pop\"},{defaultToken:\"comment\",caseInsensitive:!0}]},{token:\"comment\",regex:\"\\\\/\\\\/\",next:[i.getTagRule(),{token:\"comment\",regex:\"$|^\",next:e||\"pop\"},{defaultToken:\"comment\",caseInsensitive:!0}]}]}var r=e(\"../lib/oop\"),i=e(\"./doc_comment_highlight_rules\").DocCommentHighlightRules,s=e(\"./text_highlight_rules\").TextHighlightRules,o=\"[a-zA-Z\\\\$_\\u00a1-\\uffff][a-zA-Z\\\\d\\\\$_\\u00a1-\\uffff]*\",u=function(e){var t=this.createKeywordMapper({\"variable.language\":\"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document\",keyword:\"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static\",\"storage.type\":\"const|let|var|function\",\"constant.language\":\"null|Infinity|NaN|undefined\",\"support.function\":\"alert\",\"constant.language.boolean\":\"true|false\"},\"identifier\"),n=\"case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void\",r=\"\\\\\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)\";this.$rules={no_regex:[i.getStartRule(\"doc-start\"),f(\"no_regex\"),{token:\"string\",regex:\"'(?=.)\",next:\"qstring\"},{token:\"string\",regex:'\"(?=.)',next:\"qqstring\"},{token:\"constant.numeric\",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\\b/},{token:\"constant.numeric\",regex:/(?:\\d\\d*(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+\\b)?/},{token:[\"storage.type\",\"punctuation.operator\",\"support.function\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\"],regex:\"(\"+o+\")(\\\\.)(prototype)(\\\\.)(\"+o+\")(\\\\s*)(=)\",next:\"function_arguments\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\.)(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\.)(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s+)(\\\\w+)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(function)(\\\\s+)(\"+o+\")(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"entity.name.function\",\"text\",\"punctuation.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\s*)(:)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"text\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(:)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:\"keyword\",regex:\"from(?=\\\\s*('|\\\"))\"},{token:\"keyword\",regex:\"(?:\"+n+\")\\\\b\",next:\"start\"},{token:[\"support.constant\"],regex:/that\\b/},{token:[\"storage.type\",\"punctuation.operator\",\"support.function.firebug\"],regex:/(console)(\\.)(warn|info|log|error|time|trace|timeEnd|assert)\\b/},{token:t,regex:o},{token:\"punctuation.operator\",regex:/[.](?![.])/,next:\"property\"},{token:\"storage.type\",regex:/=>/,next:\"start\"},{token:\"keyword.operator\",regex:/--|\\+\\+|\\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\\|\\||\\?:|[!$%&*+\\-~\\/^]=?/,next:\"start\"},{token:\"punctuation.operator\",regex:/[?:,;.]/,next:\"start\"},{token:\"paren.lparen\",regex:/[\\[({]/,next:\"start\"},{token:\"paren.rparen\",regex:/[\\])}]/},{token:\"comment\",regex:/^#!.*$/}],property:[{token:\"text\",regex:\"\\\\s+\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(\"+o+\")(\\\\.)(\"+o+\")(\\\\s*)(=)(\\\\s*)(function)(?:(\\\\s+)(\\\\w+))?(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:\"punctuation.operator\",regex:/[.](?![.])/},{token:\"support.function\",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\\b(?=\\()/},{token:\"support.function.dom\",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\\b(?=\\()/},{token:\"support.constant\",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\\b/},{token:\"identifier\",regex:o},{regex:\"\",token:\"empty\",next:\"no_regex\"}],start:[i.getStartRule(\"doc-start\"),f(\"start\"),{token:\"string.regexp\",regex:\"\\\\/\",next:\"regex\"},{token:\"text\",regex:\"\\\\s+|^$\",next:\"start\"},{token:\"empty\",regex:\"\",next:\"no_regex\"}],regex:[{token:\"regexp.keyword.operator\",regex:\"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"},{token:\"string.regexp\",regex:\"/[sxngimy]*\",next:\"no_regex\"},{token:\"invalid\",regex:/\\{\\d+\\b,?\\d*\\}[+*]|[+*$^?][+*]|[$^][?]|\\?{3,}/},{token:\"constant.language.escape\",regex:/\\(\\?[:=!]|\\)|\\{\\d+\\b,?\\d*\\}|[+*]\\?|[()$^+*?.]/},{token:\"constant.language.delimiter\",regex:/\\|/},{token:\"constant.language.escape\",regex:/\\[\\^?/,next:\"regex_character_class\"},{token:\"empty\",regex:\"$\",next:\"no_regex\"},{defaultToken:\"string.regexp\"}],regex_character_class:[{token:\"regexp.charclass.keyword.operator\",regex:\"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"},{token:\"constant.language.escape\",regex:\"]\",next:\"regex\"},{token:\"constant.language.escape\",regex:\"-\"},{token:\"empty\",regex:\"$\",next:\"no_regex\"},{defaultToken:\"string.regexp.charachterclass\"}],function_arguments:[{token:\"variable.parameter\",regex:o},{token:\"punctuation.operator\",regex:\"[, ]+\"},{token:\"punctuation.operator\",regex:\"$\"},{token:\"empty\",regex:\"\",next:\"no_regex\"}],qqstring:[{token:\"constant.language.escape\",regex:r},{token:\"string\",regex:\"\\\\\\\\$\",consumeLineEnd:!0},{token:\"string\",regex:'\"|$',next:\"no_regex\"},{defaultToken:\"string\"}],qstring:[{token:\"constant.language.escape\",regex:r},{token:\"string\",regex:\"\\\\\\\\$\",consumeLineEnd:!0},{token:\"string\",regex:\"'|$\",next:\"no_regex\"},{defaultToken:\"string\"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:\"[{}]\",onMatch:function(e,t,n){this.next=e==\"{\"?this.nextState:\"\";if(e==\"{\"&&n.length)n.unshift(\"start\",t);else if(e==\"}\"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf(\"string\")!=-1||this.next.indexOf(\"jsx\")!=-1)return\"paren.quasi.end\"}return e==\"{\"?\"paren.lparen\":\"paren.rparen\"},nextState:\"start\"},{token:\"string.quasi.start\",regex:/`/,push:[{token:\"constant.language.escape\",regex:r},{token:\"paren.quasi.start\",regex:/\\${/,push:\"start\"},{token:\"string.quasi.end\",regex:/`/,next:\"pop\"},{defaultToken:\"string.quasi\"}]}),(!e||e.jsx!=0)&&a.call(this);this.embedRules(i,\"doc-\",[i.getEndRule(\"no_regex\")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),ace.define(\"ace/mode/pgsql_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/mode/doc_comment_highlight_rules\",\"ace/mode/text_highlight_rules\",\"ace/mode/perl_highlight_rules\",\"ace/mode/python_highlight_rules\",\"ace/mode/json_highlight_rules\",\"ace/mode/javascript_highlight_rules\"],function(e,t,n){var r=e(\"../lib/oop\"),i=e(\"../lib/lang\"),s=e(\"./doc_comment_highlight_rules\").DocCommentHighlightRules,o=e(\"./text_highlight_rules\").TextHighlightRules,u=e(\"./perl_highlight_rules\").PerlHighlightRules,a=e(\"./python_highlight_rules\").PythonHighlightRules,f=e(\"./json_highlight_rules\").JsonHighlightRules,l=e(\"./javascript_highlight_rules\").JavaScriptHighlightRules,c=function(){var e=\"abort|absolute|abstime|access|aclitem|action|add|admin|after|aggregate|all|also|alter|always|analyse|analyze|and|any|anyarray|anyelement|anyenum|anynonarray|anyrange|array|as|asc|assertion|assignment|asymmetric|at|attribute|authorization|backward|before|begin|between|bigint|binary|bit|bool|boolean|both|box|bpchar|by|bytea|cache|called|cascade|cascaded|case|cast|catalog|chain|char|character|characteristics|check|checkpoint|cid|cidr|circle|class|close|cluster|coalesce|collate|collation|column|comment|comments|commit|committed|concurrently|configuration|connection|constraint|constraints|content|continue|conversion|copy|cost|create|cross|cstring|csv|current|current_catalog|current_date|current_role|current_schema|current_time|current_timestamp|current_user|cursor|cycle|data|database|date|daterange|day|deallocate|dec|decimal|declare|default|defaults|deferrable|deferred|definer|delete|delimiter|delimiters|desc|dictionary|disable|discard|distinct|do|document|domain|double|drop|each|else|enable|encoding|encrypted|end|enum|escape|event|event_trigger|except|exclude|excluding|exclusive|execute|exists|explain|extension|external|extract|false|family|fdw_handler|fetch|first|float|float4|float8|following|for|force|foreign|forward|freeze|from|full|function|functions|global|grant|granted|greatest|group|gtsvector|handler|having|header|hold|hour|identity|if|ilike|immediate|immutable|implicit|in|including|increment|index|indexes|inet|inherit|inherits|initially|inline|inner|inout|input|insensitive|insert|instead|int|int2|int2vector|int4|int4range|int8|int8range|integer|internal|intersect|interval|into|invoker|is|isnull|isolation|join|json|key|label|language|language_handler|large|last|lateral|lc_collate|lc_ctype|leading|leakproof|least|left|level|like|limit|line|listen|load|local|localtime|localtimestamp|location|lock|lseg|macaddr|mapping|match|materialized|maxvalue|minute|minvalue|mode|money|month|move|name|names|national|natural|nchar|next|no|none|not|nothing|notify|notnull|nowait|null|nullif|nulls|numeric|numrange|object|of|off|offset|oid|oids|oidvector|on|only|opaque|operator|option|options|or|order|out|outer|over|overlaps|overlay|owned|owner|parser|partial|partition|passing|password|path|pg_attribute|pg_auth_members|pg_authid|pg_class|pg_database|pg_node_tree|pg_proc|pg_type|placing|plans|point|polygon|position|preceding|precision|prepare|prepared|preserve|primary|prior|privileges|procedural|procedure|program|quote|range|read|real|reassign|recheck|record|recursive|ref|refcursor|references|refresh|regclass|regconfig|regdictionary|regoper|regoperator|regproc|regprocedure|regtype|reindex|relative|release|reltime|rename|repeatable|replace|replica|reset|restart|restrict|returning|returns|revoke|right|role|rollback|row|rows|rule|savepoint|schema|scroll|search|second|security|select|sequence|sequences|serializable|server|session|session_user|set|setof|share|show|similar|simple|smallint|smgr|snapshot|some|stable|standalone|start|statement|statistics|stdin|stdout|storage|strict|strip|substring|symmetric|sysid|system|table|tables|tablespace|temp|template|temporary|text|then|tid|time|timestamp|timestamptz|timetz|tinterval|to|trailing|transaction|treat|trigger|trim|true|truncate|trusted|tsquery|tsrange|tstzrange|tsvector|txid_snapshot|type|types|unbounded|uncommitted|unencrypted|union|unique|unknown|unlisten|unlogged|until|update|user|using|uuid|vacuum|valid|validate|validator|value|values|varbit|varchar|variadic|varying|verbose|version|view|void|volatile|when|where|whitespace|window|with|without|work|wrapper|write|xid|xml|xmlattributes|xmlconcat|xmlelement|xmlexists|xmlforest|xmlparse|xmlpi|xmlroot|xmlserialize|year|yes|zone\",t=\"RI_FKey_cascade_del|RI_FKey_cascade_upd|RI_FKey_check_ins|RI_FKey_check_upd|RI_FKey_noaction_del|RI_FKey_noaction_upd|RI_FKey_restrict_del|RI_FKey_restrict_upd|RI_FKey_setdefault_del|RI_FKey_setdefault_upd|RI_FKey_setnull_del|RI_FKey_setnull_upd|abbrev|abs|abstime|abstimeeq|abstimege|abstimegt|abstimein|abstimele|abstimelt|abstimene|abstimeout|abstimerecv|abstimesend|aclcontains|acldefault|aclexplode|aclinsert|aclitemeq|aclitemin|aclitemout|aclremove|acos|age|any_in|any_out|anyarray_in|anyarray_out|anyarray_recv|anyarray_send|anyelement_in|anyelement_out|anyenum_in|anyenum_out|anynonarray_in|anynonarray_out|anyrange_in|anyrange_out|anytextcat|area|areajoinsel|areasel|array_agg|array_agg_finalfn|array_agg_transfn|array_append|array_cat|array_dims|array_eq|array_fill|array_ge|array_gt|array_in|array_larger|array_le|array_length|array_lower|array_lt|array_ndims|array_ne|array_out|array_prepend|array_recv|array_remove|array_replace|array_send|array_smaller|array_to_json|array_to_string|array_typanalyze|array_upper|arraycontained|arraycontains|arraycontjoinsel|arraycontsel|arrayoverlap|ascii|ascii_to_mic|ascii_to_utf8|asin|atan|atan2|avg|big5_to_euc_tw|big5_to_mic|big5_to_utf8|bit_and|bit_in|bit_length|bit_or|bit_out|bit_recv|bit_send|bitand|bitcat|bitcmp|biteq|bitge|bitgt|bitle|bitlt|bitne|bitnot|bitor|bitshiftleft|bitshiftright|bittypmodin|bittypmodout|bitxor|bool|bool_and|bool_or|booland_statefunc|booleq|boolge|boolgt|boolin|boolle|boollt|boolne|boolor_statefunc|boolout|boolrecv|boolsend|box|box_above|box_above_eq|box_add|box_below|box_below_eq|box_center|box_contain|box_contain_pt|box_contained|box_distance|box_div|box_eq|box_ge|box_gt|box_in|box_intersect|box_le|box_left|box_lt|box_mul|box_out|box_overabove|box_overbelow|box_overlap|box_overleft|box_overright|box_recv|box_right|box_same|box_send|box_sub|bpchar_larger|bpchar_pattern_ge|bpchar_pattern_gt|bpchar_pattern_le|bpchar_pattern_lt|bpchar_smaller|bpcharcmp|bpchareq|bpcharge|bpchargt|bpchariclike|bpcharicnlike|bpcharicregexeq|bpcharicregexne|bpcharin|bpcharle|bpcharlike|bpcharlt|bpcharne|bpcharnlike|bpcharout|bpcharrecv|bpcharregexeq|bpcharregexne|bpcharsend|bpchartypmodin|bpchartypmodout|broadcast|btabstimecmp|btarraycmp|btbeginscan|btboolcmp|btbpchar_pattern_cmp|btbuild|btbuildempty|btbulkdelete|btcanreturn|btcharcmp|btcostestimate|btendscan|btfloat48cmp|btfloat4cmp|btfloat4sortsupport|btfloat84cmp|btfloat8cmp|btfloat8sortsupport|btgetbitmap|btgettuple|btinsert|btint24cmp|btint28cmp|btint2cmp|btint2sortsupport|btint42cmp|btint48cmp|btint4cmp|btint4sortsupport|btint82cmp|btint84cmp|btint8cmp|btint8sortsupport|btmarkpos|btnamecmp|btnamesortsupport|btoidcmp|btoidsortsupport|btoidvectorcmp|btoptions|btrecordcmp|btreltimecmp|btrescan|btrestrpos|btrim|bttext_pattern_cmp|bttextcmp|bttidcmp|bttintervalcmp|btvacuumcleanup|bytea_string_agg_finalfn|bytea_string_agg_transfn|byteacat|byteacmp|byteaeq|byteage|byteagt|byteain|byteale|bytealike|bytealt|byteane|byteanlike|byteaout|bytearecv|byteasend|cash_cmp|cash_div_cash|cash_div_flt4|cash_div_flt8|cash_div_int2|cash_div_int4|cash_eq|cash_ge|cash_gt|cash_in|cash_le|cash_lt|cash_mi|cash_mul_flt4|cash_mul_flt8|cash_mul_int2|cash_mul_int4|cash_ne|cash_out|cash_pl|cash_recv|cash_send|cash_words|cashlarger|cashsmaller|cbrt|ceil|ceiling|center|char|char_length|character_length|chareq|charge|chargt|charin|charle|charlt|charne|charout|charrecv|charsend|chr|cideq|cidin|cidout|cidr|cidr_in|cidr_out|cidr_recv|cidr_send|cidrecv|cidsend|circle|circle_above|circle_add_pt|circle_below|circle_center|circle_contain|circle_contain_pt|circle_contained|circle_distance|circle_div_pt|circle_eq|circle_ge|circle_gt|circle_in|circle_le|circle_left|circle_lt|circle_mul_pt|circle_ne|circle_out|circle_overabove|circle_overbelow|circle_overlap|circle_overleft|circle_overright|circle_recv|circle_right|circle_same|circle_send|circle_sub_pt|clock_timestamp|close_lb|close_ls|close_lseg|close_pb|close_pl|close_ps|close_sb|close_sl|col_description|concat|concat_ws|contjoinsel|contsel|convert|convert_from|convert_to|corr|cos|cot|count|covar_pop|covar_samp|cstring_in|cstring_out|cstring_recv|cstring_send|cume_dist|current_database|current_query|current_schema|current_schemas|current_setting|current_user|currtid|currtid2|currval|cursor_to_xml|cursor_to_xmlschema|database_to_xml|database_to_xml_and_xmlschema|database_to_xmlschema|date|date_cmp|date_cmp_timestamp|date_cmp_timestamptz|date_eq|date_eq_timestamp|date_eq_timestamptz|date_ge|date_ge_timestamp|date_ge_timestamptz|date_gt|date_gt_timestamp|date_gt_timestamptz|date_in|date_larger|date_le|date_le_timestamp|date_le_timestamptz|date_lt|date_lt_timestamp|date_lt_timestamptz|date_mi|date_mi_interval|date_mii|date_ne|date_ne_timestamp|date_ne_timestamptz|date_out|date_part|date_pl_interval|date_pli|date_recv|date_send|date_smaller|date_sortsupport|date_trunc|daterange|daterange_canonical|daterange_subdiff|datetime_pl|datetimetz_pl|dcbrt|decode|degrees|dense_rank|dexp|diagonal|diameter|dispell_init|dispell_lexize|dist_cpoly|dist_lb|dist_pb|dist_pc|dist_pl|dist_ppath|dist_ps|dist_sb|dist_sl|div|dlog1|dlog10|domain_in|domain_recv|dpow|dround|dsimple_init|dsimple_lexize|dsnowball_init|dsnowball_lexize|dsqrt|dsynonym_init|dsynonym_lexize|dtrunc|elem_contained_by_range|encode|enum_cmp|enum_eq|enum_first|enum_ge|enum_gt|enum_in|enum_larger|enum_last|enum_le|enum_lt|enum_ne|enum_out|enum_range|enum_recv|enum_send|enum_smaller|eqjoinsel|eqsel|euc_cn_to_mic|euc_cn_to_utf8|euc_jis_2004_to_shift_jis_2004|euc_jis_2004_to_utf8|euc_jp_to_mic|euc_jp_to_sjis|euc_jp_to_utf8|euc_kr_to_mic|euc_kr_to_utf8|euc_tw_to_big5|euc_tw_to_mic|euc_tw_to_utf8|event_trigger_in|event_trigger_out|every|exp|factorial|family|fdw_handler_in|fdw_handler_out|first_value|float4|float48div|float48eq|float48ge|float48gt|float48le|float48lt|float48mi|float48mul|float48ne|float48pl|float4_accum|float4abs|float4div|float4eq|float4ge|float4gt|float4in|float4larger|float4le|float4lt|float4mi|float4mul|float4ne|float4out|float4pl|float4recv|float4send|float4smaller|float4um|float4up|float8|float84div|float84eq|float84ge|float84gt|float84le|float84lt|float84mi|float84mul|float84ne|float84pl|float8_accum|float8_avg|float8_corr|float8_covar_pop|float8_covar_samp|float8_regr_accum|float8_regr_avgx|float8_regr_avgy|float8_regr_intercept|float8_regr_r2|float8_regr_slope|float8_regr_sxx|float8_regr_sxy|float8_regr_syy|float8_stddev_pop|float8_stddev_samp|float8_var_pop|float8_var_samp|float8abs|float8div|float8eq|float8ge|float8gt|float8in|float8larger|float8le|float8lt|float8mi|float8mul|float8ne|float8out|float8pl|float8recv|float8send|float8smaller|float8um|float8up|floor|flt4_mul_cash|flt8_mul_cash|fmgr_c_validator|fmgr_internal_validator|fmgr_sql_validator|format|format_type|gb18030_to_utf8|gbk_to_utf8|generate_series|generate_subscripts|get_bit|get_byte|get_current_ts_config|getdatabaseencoding|getpgusername|gin_cmp_prefix|gin_cmp_tslexeme|gin_extract_tsquery|gin_extract_tsvector|gin_tsquery_consistent|ginarrayconsistent|ginarrayextract|ginbeginscan|ginbuild|ginbuildempty|ginbulkdelete|gincostestimate|ginendscan|gingetbitmap|gininsert|ginmarkpos|ginoptions|ginqueryarrayextract|ginrescan|ginrestrpos|ginvacuumcleanup|gist_box_compress|gist_box_consistent|gist_box_decompress|gist_box_penalty|gist_box_picksplit|gist_box_same|gist_box_union|gist_circle_compress|gist_circle_consistent|gist_point_compress|gist_point_consistent|gist_point_distance|gist_poly_compress|gist_poly_consistent|gistbeginscan|gistbuild|gistbuildempty|gistbulkdelete|gistcostestimate|gistendscan|gistgetbitmap|gistgettuple|gistinsert|gistmarkpos|gistoptions|gistrescan|gistrestrpos|gistvacuumcleanup|gtsquery_compress|gtsquery_consistent|gtsquery_decompress|gtsquery_penalty|gtsquery_picksplit|gtsquery_same|gtsquery_union|gtsvector_compress|gtsvector_consistent|gtsvector_decompress|gtsvector_penalty|gtsvector_picksplit|gtsvector_same|gtsvector_union|gtsvectorin|gtsvectorout|has_any_column_privilege|has_column_privilege|has_database_privilege|has_foreign_data_wrapper_privilege|has_function_privilege|has_language_privilege|has_schema_privilege|has_sequence_privilege|has_server_privilege|has_table_privilege|has_tablespace_privilege|has_type_privilege|hash_aclitem|hash_array|hash_numeric|hash_range|hashbeginscan|hashbpchar|hashbuild|hashbuildempty|hashbulkdelete|hashchar|hashcostestimate|hashendscan|hashenum|hashfloat4|hashfloat8|hashgetbitmap|hashgettuple|hashinet|hashinsert|hashint2|hashint2vector|hashint4|hashint8|hashmacaddr|hashmarkpos|hashname|hashoid|hashoidvector|hashoptions|hashrescan|hashrestrpos|hashtext|hashvacuumcleanup|hashvarlena|height|host|hostmask|iclikejoinsel|iclikesel|icnlikejoinsel|icnlikesel|icregexeqjoinsel|icregexeqsel|icregexnejoinsel|icregexnesel|inet_client_addr|inet_client_port|inet_in|inet_out|inet_recv|inet_send|inet_server_addr|inet_server_port|inetand|inetmi|inetmi_int8|inetnot|inetor|inetpl|initcap|int2|int24div|int24eq|int24ge|int24gt|int24le|int24lt|int24mi|int24mul|int24ne|int24pl|int28div|int28eq|int28ge|int28gt|int28le|int28lt|int28mi|int28mul|int28ne|int28pl|int2_accum|int2_avg_accum|int2_mul_cash|int2_sum|int2abs|int2and|int2div|int2eq|int2ge|int2gt|int2in|int2larger|int2le|int2lt|int2mi|int2mod|int2mul|int2ne|int2not|int2or|int2out|int2pl|int2recv|int2send|int2shl|int2shr|int2smaller|int2um|int2up|int2vectoreq|int2vectorin|int2vectorout|int2vectorrecv|int2vectorsend|int2xor|int4|int42div|int42eq|int42ge|int42gt|int42le|int42lt|int42mi|int42mul|int42ne|int42pl|int48div|int48eq|int48ge|int48gt|int48le|int48lt|int48mi|int48mul|int48ne|int48pl|int4_accum|int4_avg_accum|int4_mul_cash|int4_sum|int4abs|int4and|int4div|int4eq|int4ge|int4gt|int4in|int4inc|int4larger|int4le|int4lt|int4mi|int4mod|int4mul|int4ne|int4not|int4or|int4out|int4pl|int4range|int4range_canonical|int4range_subdiff|int4recv|int4send|int4shl|int4shr|int4smaller|int4um|int4up|int4xor|int8|int82div|int82eq|int82ge|int82gt|int82le|int82lt|int82mi|int82mul|int82ne|int82pl|int84div|int84eq|int84ge|int84gt|int84le|int84lt|int84mi|int84mul|int84ne|int84pl|int8_accum|int8_avg|int8_avg_accum|int8_sum|int8abs|int8and|int8div|int8eq|int8ge|int8gt|int8in|int8inc|int8inc_any|int8inc_float8_float8|int8larger|int8le|int8lt|int8mi|int8mod|int8mul|int8ne|int8not|int8or|int8out|int8pl|int8pl_inet|int8range|int8range_canonical|int8range_subdiff|int8recv|int8send|int8shl|int8shr|int8smaller|int8um|int8up|int8xor|integer_pl_date|inter_lb|inter_sb|inter_sl|internal_in|internal_out|interval_accum|interval_avg|interval_cmp|interval_div|interval_eq|interval_ge|interval_gt|interval_hash|interval_in|interval_larger|interval_le|interval_lt|interval_mi|interval_mul|interval_ne|interval_out|interval_pl|interval_pl_date|interval_pl_time|interval_pl_timestamp|interval_pl_timestamptz|interval_pl_timetz|interval_recv|interval_send|interval_smaller|interval_transform|interval_um|intervaltypmodin|intervaltypmodout|intinterval|isclosed|isempty|isfinite|ishorizontal|iso8859_1_to_utf8|iso8859_to_utf8|iso_to_koi8r|iso_to_mic|iso_to_win1251|iso_to_win866|isopen|isparallel|isperp|isvertical|johab_to_utf8|json_agg|json_agg_finalfn|json_agg_transfn|json_array_element|json_array_element_text|json_array_elements|json_array_length|json_each|json_each_text|json_extract_path|json_extract_path_op|json_extract_path_text|json_extract_path_text_op|json_in|json_object_field|json_object_field_text|json_object_keys|json_out|json_populate_record|json_populate_recordset|json_recv|json_send|justify_days|justify_hours|justify_interval|koi8r_to_iso|koi8r_to_mic|koi8r_to_utf8|koi8r_to_win1251|koi8r_to_win866|koi8u_to_utf8|lag|language_handler_in|language_handler_out|last_value|lastval|latin1_to_mic|latin2_to_mic|latin2_to_win1250|latin3_to_mic|latin4_to_mic|lead|left|length|like|like_escape|likejoinsel|likesel|line|line_distance|line_eq|line_horizontal|line_in|line_interpt|line_intersect|line_out|line_parallel|line_perp|line_recv|line_send|line_vertical|ln|lo_close|lo_creat|lo_create|lo_export|lo_import|lo_lseek|lo_lseek64|lo_open|lo_tell|lo_tell64|lo_truncate|lo_truncate64|lo_unlink|log|loread|lower|lower_inc|lower_inf|lowrite|lpad|lseg|lseg_center|lseg_distance|lseg_eq|lseg_ge|lseg_gt|lseg_horizontal|lseg_in|lseg_interpt|lseg_intersect|lseg_le|lseg_length|lseg_lt|lseg_ne|lseg_out|lseg_parallel|lseg_perp|lseg_recv|lseg_send|lseg_vertical|ltrim|macaddr_and|macaddr_cmp|macaddr_eq|macaddr_ge|macaddr_gt|macaddr_in|macaddr_le|macaddr_lt|macaddr_ne|macaddr_not|macaddr_or|macaddr_out|macaddr_recv|macaddr_send|makeaclitem|masklen|max|md5|mic_to_ascii|mic_to_big5|mic_to_euc_cn|mic_to_euc_jp|mic_to_euc_kr|mic_to_euc_tw|mic_to_iso|mic_to_koi8r|mic_to_latin1|mic_to_latin2|mic_to_latin3|mic_to_latin4|mic_to_sjis|mic_to_win1250|mic_to_win1251|mic_to_win866|min|mktinterval|mod|money|mul_d_interval|name|nameeq|namege|namegt|nameiclike|nameicnlike|nameicregexeq|nameicregexne|namein|namele|namelike|namelt|namene|namenlike|nameout|namerecv|nameregexeq|nameregexne|namesend|neqjoinsel|neqsel|netmask|network|network_cmp|network_eq|network_ge|network_gt|network_le|network_lt|network_ne|network_sub|network_subeq|network_sup|network_supeq|nextval|nlikejoinsel|nlikesel|notlike|now|npoints|nth_value|ntile|numeric_abs|numeric_accum|numeric_add|numeric_avg|numeric_avg_accum|numeric_cmp|numeric_div|numeric_div_trunc|numeric_eq|numeric_exp|numeric_fac|numeric_ge|numeric_gt|numeric_in|numeric_inc|numeric_larger|numeric_le|numeric_ln|numeric_log|numeric_lt|numeric_mod|numeric_mul|numeric_ne|numeric_out|numeric_power|numeric_recv|numeric_send|numeric_smaller|numeric_sqrt|numeric_stddev_pop|numeric_stddev_samp|numeric_sub|numeric_transform|numeric_uminus|numeric_uplus|numeric_var_pop|numeric_var_samp|numerictypmodin|numerictypmodout|numnode|numrange|numrange_subdiff|obj_description|octet_length|oid|oideq|oidge|oidgt|oidin|oidlarger|oidle|oidlt|oidne|oidout|oidrecv|oidsend|oidsmaller|oidvectoreq|oidvectorge|oidvectorgt|oidvectorin|oidvectorle|oidvectorlt|oidvectorne|oidvectorout|oidvectorrecv|oidvectorsend|oidvectortypes|on_pb|on_pl|on_ppath|on_ps|on_sb|on_sl|opaque_in|opaque_out|overlaps|overlay|path|path_add|path_add_pt|path_center|path_contain_pt|path_distance|path_div_pt|path_in|path_inter|path_length|path_mul_pt|path_n_eq|path_n_ge|path_n_gt|path_n_le|path_n_lt|path_npoints|path_out|path_recv|path_send|path_sub_pt|pclose|percent_rank|pg_advisory_lock|pg_advisory_lock_shared|pg_advisory_unlock|pg_advisory_unlock_all|pg_advisory_unlock_shared|pg_advisory_xact_lock|pg_advisory_xact_lock_shared|pg_available_extension_versions|pg_available_extensions|pg_backend_pid|pg_backup_start_time|pg_cancel_backend|pg_char_to_encoding|pg_client_encoding|pg_collation_for|pg_collation_is_visible|pg_column_is_updatable|pg_column_size|pg_conf_load_time|pg_conversion_is_visible|pg_create_restore_point|pg_current_xlog_insert_location|pg_current_xlog_location|pg_cursor|pg_database_size|pg_describe_object|pg_encoding_max_length|pg_encoding_to_char|pg_event_trigger_dropped_objects|pg_export_snapshot|pg_extension_config_dump|pg_extension_update_paths|pg_function_is_visible|pg_get_constraintdef|pg_get_expr|pg_get_function_arguments|pg_get_function_identity_arguments|pg_get_function_result|pg_get_functiondef|pg_get_indexdef|pg_get_keywords|pg_get_multixact_members|pg_get_ruledef|pg_get_serial_sequence|pg_get_triggerdef|pg_get_userbyid|pg_get_viewdef|pg_has_role|pg_identify_object|pg_indexes_size|pg_is_in_backup|pg_is_in_recovery|pg_is_other_temp_schema|pg_is_xlog_replay_paused|pg_last_xact_replay_timestamp|pg_last_xlog_receive_location|pg_last_xlog_replay_location|pg_listening_channels|pg_lock_status|pg_ls_dir|pg_my_temp_schema|pg_node_tree_in|pg_node_tree_out|pg_node_tree_recv|pg_node_tree_send|pg_notify|pg_opclass_is_visible|pg_operator_is_visible|pg_opfamily_is_visible|pg_options_to_table|pg_postmaster_start_time|pg_prepared_statement|pg_prepared_xact|pg_read_binary_file|pg_read_file|pg_relation_filenode|pg_relation_filepath|pg_relation_is_updatable|pg_relation_size|pg_reload_conf|pg_rotate_logfile|pg_sequence_parameters|pg_show_all_settings|pg_size_pretty|pg_sleep|pg_start_backup|pg_stat_clear_snapshot|pg_stat_file|pg_stat_get_activity|pg_stat_get_analyze_count|pg_stat_get_autoanalyze_count|pg_stat_get_autovacuum_count|pg_stat_get_backend_activity|pg_stat_get_backend_activity_start|pg_stat_get_backend_client_addr|pg_stat_get_backend_client_port|pg_stat_get_backend_dbid|pg_stat_get_backend_idset|pg_stat_get_backend_pid|pg_stat_get_backend_start|pg_stat_get_backend_userid|pg_stat_get_backend_waiting|pg_stat_get_backend_xact_start|pg_stat_get_bgwriter_buf_written_checkpoints|pg_stat_get_bgwriter_buf_written_clean|pg_stat_get_bgwriter_maxwritten_clean|pg_stat_get_bgwriter_requested_checkpoints|pg_stat_get_bgwriter_stat_reset_time|pg_stat_get_bgwriter_timed_checkpoints|pg_stat_get_blocks_fetched|pg_stat_get_blocks_hit|pg_stat_get_buf_alloc|pg_stat_get_buf_fsync_backend|pg_stat_get_buf_written_backend|pg_stat_get_checkpoint_sync_time|pg_stat_get_checkpoint_write_time|pg_stat_get_db_blk_read_time|pg_stat_get_db_blk_write_time|pg_stat_get_db_blocks_fetched|pg_stat_get_db_blocks_hit|pg_stat_get_db_conflict_all|pg_stat_get_db_conflict_bufferpin|pg_stat_get_db_conflict_lock|pg_stat_get_db_conflict_snapshot|pg_stat_get_db_conflict_startup_deadlock|pg_stat_get_db_conflict_tablespace|pg_stat_get_db_deadlocks|pg_stat_get_db_numbackends|pg_stat_get_db_stat_reset_time|pg_stat_get_db_temp_bytes|pg_stat_get_db_temp_files|pg_stat_get_db_tuples_deleted|pg_stat_get_db_tuples_fetched|pg_stat_get_db_tuples_inserted|pg_stat_get_db_tuples_returned|pg_stat_get_db_tuples_updated|pg_stat_get_db_xact_commit|pg_stat_get_db_xact_rollback|pg_stat_get_dead_tuples|pg_stat_get_function_calls|pg_stat_get_function_self_time|pg_stat_get_function_total_time|pg_stat_get_last_analyze_time|pg_stat_get_last_autoanalyze_time|pg_stat_get_last_autovacuum_time|pg_stat_get_last_vacuum_time|pg_stat_get_live_tuples|pg_stat_get_numscans|pg_stat_get_tuples_deleted|pg_stat_get_tuples_fetched|pg_stat_get_tuples_hot_updated|pg_stat_get_tuples_inserted|pg_stat_get_tuples_returned|pg_stat_get_tuples_updated|pg_stat_get_vacuum_count|pg_stat_get_wal_senders|pg_stat_get_xact_blocks_fetched|pg_stat_get_xact_blocks_hit|pg_stat_get_xact_function_calls|pg_stat_get_xact_function_self_time|pg_stat_get_xact_function_total_time|pg_stat_get_xact_numscans|pg_stat_get_xact_tuples_deleted|pg_stat_get_xact_tuples_fetched|pg_stat_get_xact_tuples_hot_updated|pg_stat_get_xact_tuples_inserted|pg_stat_get_xact_tuples_returned|pg_stat_get_xact_tuples_updated|pg_stat_reset|pg_stat_reset_shared|pg_stat_reset_single_function_counters|pg_stat_reset_single_table_counters|pg_stop_backup|pg_switch_xlog|pg_table_is_visible|pg_table_size|pg_tablespace_databases|pg_tablespace_location|pg_tablespace_size|pg_terminate_backend|pg_timezone_abbrevs|pg_timezone_names|pg_total_relation_size|pg_trigger_depth|pg_try_advisory_lock|pg_try_advisory_lock_shared|pg_try_advisory_xact_lock|pg_try_advisory_xact_lock_shared|pg_ts_config_is_visible|pg_ts_dict_is_visible|pg_ts_parser_is_visible|pg_ts_template_is_visible|pg_type_is_visible|pg_typeof|pg_xlog_location_diff|pg_xlog_replay_pause|pg_xlog_replay_resume|pg_xlogfile_name|pg_xlogfile_name_offset|pi|plainto_tsquery|plpgsql_call_handler|plpgsql_inline_handler|plpgsql_validator|point|point_above|point_add|point_below|point_distance|point_div|point_eq|point_horiz|point_in|point_left|point_mul|point_ne|point_out|point_recv|point_right|point_send|point_sub|point_vert|poly_above|poly_below|poly_center|poly_contain|poly_contain_pt|poly_contained|poly_distance|poly_in|poly_left|poly_npoints|poly_out|poly_overabove|poly_overbelow|poly_overlap|poly_overleft|poly_overright|poly_recv|poly_right|poly_same|poly_send|polygon|popen|position|positionjoinsel|positionsel|postgresql_fdw_validator|pow|power|prsd_end|prsd_headline|prsd_lextype|prsd_nexttoken|prsd_start|pt_contained_circle|pt_contained_poly|query_to_xml|query_to_xml_and_xmlschema|query_to_xmlschema|querytree|quote_ident|quote_literal|quote_nullable|radians|radius|random|range_adjacent|range_after|range_before|range_cmp|range_contained_by|range_contains|range_contains_elem|range_eq|range_ge|range_gist_compress|range_gist_consistent|range_gist_decompress|range_gist_penalty|range_gist_picksplit|range_gist_same|range_gist_union|range_gt|range_in|range_intersect|range_le|range_lt|range_minus|range_ne|range_out|range_overlaps|range_overleft|range_overright|range_recv|range_send|range_typanalyze|range_union|rangesel|rank|record_eq|record_ge|record_gt|record_in|record_le|record_lt|record_ne|record_out|record_recv|record_send|regclass|regclassin|regclassout|regclassrecv|regclasssend|regconfigin|regconfigout|regconfigrecv|regconfigsend|regdictionaryin|regdictionaryout|regdictionaryrecv|regdictionarysend|regexeqjoinsel|regexeqsel|regexnejoinsel|regexnesel|regexp_matches|regexp_replace|regexp_split_to_array|regexp_split_to_table|regoperatorin|regoperatorout|regoperatorrecv|regoperatorsend|regoperin|regoperout|regoperrecv|regopersend|regprocedurein|regprocedureout|regprocedurerecv|regproceduresend|regprocin|regprocout|regprocrecv|regprocsend|regr_avgx|regr_avgy|regr_count|regr_intercept|regr_r2|regr_slope|regr_sxx|regr_sxy|regr_syy|regtypein|regtypeout|regtyperecv|regtypesend|reltime|reltimeeq|reltimege|reltimegt|reltimein|reltimele|reltimelt|reltimene|reltimeout|reltimerecv|reltimesend|repeat|replace|reverse|right|round|row_number|row_to_json|rpad|rtrim|scalargtjoinsel|scalargtsel|scalarltjoinsel|scalarltsel|schema_to_xml|schema_to_xml_and_xmlschema|schema_to_xmlschema|session_user|set_bit|set_byte|set_config|set_masklen|setseed|setval|setweight|shell_in|shell_out|shift_jis_2004_to_euc_jis_2004|shift_jis_2004_to_utf8|shobj_description|sign|similar_escape|sin|sjis_to_euc_jp|sjis_to_mic|sjis_to_utf8|slope|smgreq|smgrin|smgrne|smgrout|spg_kd_choose|spg_kd_config|spg_kd_inner_consistent|spg_kd_picksplit|spg_quad_choose|spg_quad_config|spg_quad_inner_consistent|spg_quad_leaf_consistent|spg_quad_picksplit|spg_range_quad_choose|spg_range_quad_config|spg_range_quad_inner_consistent|spg_range_quad_leaf_consistent|spg_range_quad_picksplit|spg_text_choose|spg_text_config|spg_text_inner_consistent|spg_text_leaf_consistent|spg_text_picksplit|spgbeginscan|spgbuild|spgbuildempty|spgbulkdelete|spgcanreturn|spgcostestimate|spgendscan|spggetbitmap|spggettuple|spginsert|spgmarkpos|spgoptions|spgrescan|spgrestrpos|spgvacuumcleanup|split_part|sqrt|statement_timestamp|stddev|stddev_pop|stddev_samp|string_agg|string_agg_finalfn|string_agg_transfn|string_to_array|strip|strpos|substr|substring|sum|suppress_redundant_updates_trigger|table_to_xml|table_to_xml_and_xmlschema|table_to_xmlschema|tan|text|text_ge|text_gt|text_larger|text_le|text_lt|text_pattern_ge|text_pattern_gt|text_pattern_le|text_pattern_lt|text_smaller|textanycat|textcat|texteq|texticlike|texticnlike|texticregexeq|texticregexne|textin|textlen|textlike|textne|textnlike|textout|textrecv|textregexeq|textregexne|textsend|thesaurus_init|thesaurus_lexize|tideq|tidge|tidgt|tidin|tidlarger|tidle|tidlt|tidne|tidout|tidrecv|tidsend|tidsmaller|time_cmp|time_eq|time_ge|time_gt|time_hash|time_in|time_larger|time_le|time_lt|time_mi_interval|time_mi_time|time_ne|time_out|time_pl_interval|time_recv|time_send|time_smaller|time_transform|timedate_pl|timemi|timenow|timeofday|timepl|timestamp_cmp|timestamp_cmp_date|timestamp_cmp_timestamptz|timestamp_eq|timestamp_eq_date|timestamp_eq_timestamptz|timestamp_ge|timestamp_ge_date|timestamp_ge_timestamptz|timestamp_gt|timestamp_gt_date|timestamp_gt_timestamptz|timestamp_hash|timestamp_in|timestamp_larger|timestamp_le|timestamp_le_date|timestamp_le_timestamptz|timestamp_lt|timestamp_lt_date|timestamp_lt_timestamptz|timestamp_mi|timestamp_mi_interval|timestamp_ne|timestamp_ne_date|timestamp_ne_timestamptz|timestamp_out|timestamp_pl_interval|timestamp_recv|timestamp_send|timestamp_smaller|timestamp_sortsupport|timestamp_transform|timestamptypmodin|timestamptypmodout|timestamptz_cmp|timestamptz_cmp_date|timestamptz_cmp_timestamp|timestamptz_eq|timestamptz_eq_date|timestamptz_eq_timestamp|timestamptz_ge|timestamptz_ge_date|timestamptz_ge_timestamp|timestamptz_gt|timestamptz_gt_date|timestamptz_gt_timestamp|timestamptz_in|timestamptz_larger|timestamptz_le|timestamptz_le_date|timestamptz_le_timestamp|timestamptz_lt|timestamptz_lt_date|timestamptz_lt_timestamp|timestamptz_mi|timestamptz_mi_interval|timestamptz_ne|timestamptz_ne_date|timestamptz_ne_timestamp|timestamptz_out|timestamptz_pl_interval|timestamptz_recv|timestamptz_send|timestamptz_smaller|timestamptztypmodin|timestamptztypmodout|timetypmodin|timetypmodout|timetz_cmp|timetz_eq|timetz_ge|timetz_gt|timetz_hash|timetz_in|timetz_larger|timetz_le|timetz_lt|timetz_mi_interval|timetz_ne|timetz_out|timetz_pl_interval|timetz_recv|timetz_send|timetz_smaller|timetzdate_pl|timetztypmodin|timetztypmodout|timezone|tinterval|tintervalct|tintervalend|tintervaleq|tintervalge|tintervalgt|tintervalin|tintervalle|tintervalleneq|tintervallenge|tintervallengt|tintervallenle|tintervallenlt|tintervallenne|tintervallt|tintervalne|tintervalout|tintervalov|tintervalrecv|tintervalrel|tintervalsame|tintervalsend|tintervalstart|to_ascii|to_char|to_date|to_hex|to_json|to_number|to_timestamp|to_tsquery|to_tsvector|transaction_timestamp|translate|trigger_in|trigger_out|trunc|ts_debug|ts_headline|ts_lexize|ts_match_qv|ts_match_tq|ts_match_tt|ts_match_vq|ts_parse|ts_rank|ts_rank_cd|ts_rewrite|ts_stat|ts_token_type|ts_typanalyze|tsmatchjoinsel|tsmatchsel|tsq_mcontained|tsq_mcontains|tsquery_and|tsquery_cmp|tsquery_eq|tsquery_ge|tsquery_gt|tsquery_le|tsquery_lt|tsquery_ne|tsquery_not|tsquery_or|tsqueryin|tsqueryout|tsqueryrecv|tsquerysend|tsrange|tsrange_subdiff|tstzrange|tstzrange_subdiff|tsvector_cmp|tsvector_concat|tsvector_eq|tsvector_ge|tsvector_gt|tsvector_le|tsvector_lt|tsvector_ne|tsvector_update_trigger|tsvector_update_trigger_column|tsvectorin|tsvectorout|tsvectorrecv|tsvectorsend|txid_current|txid_current_snapshot|txid_snapshot_in|txid_snapshot_out|txid_snapshot_recv|txid_snapshot_send|txid_snapshot_xip|txid_snapshot_xmax|txid_snapshot_xmin|txid_visible_in_snapshot|uhc_to_utf8|unique_key_recheck|unknownin|unknownout|unknownrecv|unknownsend|unnest|upper|upper_inc|upper_inf|utf8_to_ascii|utf8_to_big5|utf8_to_euc_cn|utf8_to_euc_jis_2004|utf8_to_euc_jp|utf8_to_euc_kr|utf8_to_euc_tw|utf8_to_gb18030|utf8_to_gbk|utf8_to_iso8859|utf8_to_iso8859_1|utf8_to_johab|utf8_to_koi8r|utf8_to_koi8u|utf8_to_shift_jis_2004|utf8_to_sjis|utf8_to_uhc|utf8_to_win|uuid_cmp|uuid_eq|uuid_ge|uuid_gt|uuid_hash|uuid_in|uuid_le|uuid_lt|uuid_ne|uuid_out|uuid_recv|uuid_send|var_pop|var_samp|varbit_in|varbit_out|varbit_recv|varbit_send|varbit_transform|varbitcmp|varbiteq|varbitge|varbitgt|varbitle|varbitlt|varbitne|varbittypmodin|varbittypmodout|varchar_transform|varcharin|varcharout|varcharrecv|varcharsend|varchartypmodin|varchartypmodout|variance|version|void_in|void_out|void_recv|void_send|width|width_bucket|win1250_to_latin2|win1250_to_mic|win1251_to_iso|win1251_to_koi8r|win1251_to_mic|win1251_to_win866|win866_to_iso|win866_to_koi8r|win866_to_mic|win866_to_win1251|win_to_utf8|xideq|xideqint4|xidin|xidout|xidrecv|xidsend|xml|xml_in|xml_is_well_formed|xml_is_well_formed_content|xml_is_well_formed_document|xml_out|xml_recv|xml_send|xmlagg|xmlcomment|xmlconcat2|xmlexists|xmlvalidate|xpath|xpath_exists\",n=this.createKeywordMapper({\"support.function\":t,keyword:e},\"identifier\",!0),r=[{token:\"string\",regex:\"['](?:(?:\\\\\\\\.)|(?:[^'\\\\\\\\]))*?[']\"},{token:\"variable.language\",regex:'\".*?\"'},{token:\"constant.numeric\",regex:\"[+-]?\\\\d+(?:(?:\\\\.\\\\d*)?(?:[eE][+-]?\\\\d+)?)?\\\\b\"},{token:n,regex:\"[a-zA-Z_][a-zA-Z0-9_$]*\\\\b\"},{token:\"keyword.operator\",regex:\"!|!!|!~|!~\\\\*|!~~|!~~\\\\*|#|##|#<|#<=|#<>|#=|#>|#>=|%|\\\\&|\\\\&\\\\&|\\\\&<|\\\\&<\\\\||\\\\&>|\\\\*|\\\\+|\\\\-|/|<|<#>|<\\\\->|<<|<<=|<<\\\\||<=|<>|<\\\\?>|<@|<\\\\^|=|>|>=|>>|>>=|>\\\\^|\\\\?#|\\\\?\\\\-|\\\\?\\\\-\\\\||\\\\?\\\\||\\\\?\\\\|\\\\||@|@\\\\-@|@>|@@|@@@|\\\\^|\\\\||\\\\|\\\\&>|\\\\|/|\\\\|>>|\\\\|\\\\||\\\\|\\\\|/|~|~\\\\*|~<=~|~<~|~=|~>=~|~>~|~~|~~\\\\*\"},{token:\"paren.lparen\",regex:\"[\\\\(]\"},{token:\"paren.rparen\",regex:\"[\\\\)]\"},{token:\"text\",regex:\"\\\\s+\"}];this.$rules={start:[{token:\"comment\",regex:\"--.*$\"},s.getStartRule(\"doc-start\"),{token:\"comment\",regex:\"\\\\/\\\\*\",next:\"comment\"},{token:\"keyword.statementBegin\",regex:\"[a-zA-Z]+\",next:\"statement\"},{token:\"support.buildin\",regex:\"^\\\\\\\\[\\\\S]+.*$\"}],statement:[{token:\"comment\",regex:\"--.*$\"},{token:\"comment\",regex:\"\\\\/\\\\*\",next:\"commentStatement\"},{token:\"statementEnd\",regex:\";\",next:\"start\"},{token:\"string\",regex:\"\\\\$perl\\\\$\",next:\"perl-start\"},{token:\"string\",regex:\"\\\\$python\\\\$\",next:\"python-start\"},{token:\"string\",regex:\"\\\\$json\\\\$\",next:\"json-start\"},{token:\"string\",regex:\"\\\\$(js|javascript)\\\\$\",next:\"javascript-start\"},{token:\"string\",regex:\"\\\\$[\\\\w_0-9]*\\\\$$\",next:\"dollarSql\"},{token:\"string\",regex:\"\\\\$[\\\\w_0-9]*\\\\$\",next:\"dollarStatementString\"}].concat(r),dollarSql:[{token:\"comment\",regex:\"--.*$\"},{token:\"comment\",regex:\"\\\\/\\\\*\",next:\"commentDollarSql\"},{token:\"string\",regex:\"^\\\\$[\\\\w_0-9]*\\\\$\",next:\"statement\"},{token:\"string\",regex:\"\\\\$[\\\\w_0-9]*\\\\$\",next:\"dollarSqlString\"}].concat(r),comment:[{token:\"comment\",regex:\"\\\\*\\\\/\",next:\"start\"},{defaultToken:\"comment\"}],commentStatement:[{token:\"comment\",regex:\"\\\\*\\\\/\",next:\"statement\"},{defaultToken:\"comment\"}],commentDollarSql:[{token:\"comment\",regex:\"\\\\*\\\\/\",next:\"dollarSql\"},{defaultToken:\"comment\"}],dollarStatementString:[{token:\"string\",regex:\".*?\\\\$[\\\\w_0-9]*\\\\$\",next:\"statement\"},{token:\"string\",regex:\".+\"}],dollarSqlString:[{token:\"string\",regex:\".*?\\\\$[\\\\w_0-9]*\\\\$\",next:\"dollarSql\"},{token:\"string\",regex:\".+\"}]},this.embedRules(s,\"doc-\",[s.getEndRule(\"start\")]),this.embedRules(u,\"perl-\",[{token:\"string\",regex:\"\\\\$perl\\\\$\",next:\"statement\"}]),this.embedRules(a,\"python-\",[{token:\"string\",regex:\"\\\\$python\\\\$\",next:\"statement\"}]),this.embedRules(f,\"json-\",[{token:\"string\",regex:\"\\\\$json\\\\$\",next:\"statement\"}]),this.embedRules(l,\"javascript-\",[{token:\"string\",regex:\"\\\\$(js|javascript)\\\\$\",next:\"statement\"}])};r.inherits(c,o),t.PgsqlHighlightRules=c}),ace.define(\"ace/mode/pgsql\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text\",\"ace/mode/pgsql_highlight_rules\"],function(e,t,n){var r=e(\"../lib/oop\"),i=e(\"../mode/text\").Mode,s=e(\"./pgsql_highlight_rules\").PgsqlHighlightRules,o=function(){this.HighlightRules=s,this.$behaviour=this.$defaultBehaviour};r.inherits(o,i),function(){this.lineCommentStart=\"--\",this.blockComment={start:\"/*\",end:\"*/\"},this.getNextLineIndent=function(e,t,n){return e==\"start\"||e==\"keyword.statementEnd\"?\"\":this.$getIndent(t)},this.$id=\"ace/mode/pgsql\"}.call(o.prototype),t.Mode=o});                (function() {\n    ace.require([\"ace/mode/pgsql\"], function(m) {\n        if (typeof module == \"object\" && typeof exports == \"object\" && module) {\n            module.exports = m;\n        }\n    });\n})();\n"
  },
  {
    "path": "static/js/ace.js",
    "content": "(function(){function o(n){var i=e;n&&(e[n]||(e[n]={}),i=e[n]);if(!i.define||!i.define.packaged)t.original=i.define,i.define=t,i.define.packaged=!0;if(!i.require||!i.require.packaged)r.original=i.require,i.require=r,i.require.packaged=!0}var ACE_NAMESPACE = \"ace\",e=function(){return this}();!e&&typeof window!=\"undefined\"&&(e=window);if(!ACE_NAMESPACE&&typeof requirejs!=\"undefined\")return;var t=function(e,n,r){if(typeof e!=\"string\"){t.original?t.original.apply(this,arguments):(console.error(\"dropping module because define wasn't a string.\"),console.trace());return}arguments.length==2&&(r=n),t.modules[e]||(t.payloads[e]=r,t.modules[e]=null)};t.modules={},t.payloads={};var n=function(e,t,n){if(typeof t==\"string\"){var i=s(e,t);if(i!=undefined)return n&&n(),i}else if(Object.prototype.toString.call(t)===\"[object Array]\"){var o=[];for(var u=0,a=t.length;u<a;++u){var f=s(e,t[u]);if(f==undefined&&r.original)return;o.push(f)}return n&&n.apply(null,o)||!0}},r=function(e,t){var i=n(\"\",e,t);return i==undefined&&r.original?r.original.apply(this,arguments):i},i=function(e,t){if(t.indexOf(\"!\")!==-1){var n=t.split(\"!\");return i(e,n[0])+\"!\"+i(e,n[1])}if(t.charAt(0)==\".\"){var r=e.split(\"/\").slice(0,-1).join(\"/\");t=r+\"/\"+t;while(t.indexOf(\".\")!==-1&&s!=t){var s=t;t=t.replace(/\\/\\.\\//,\"/\").replace(/[^\\/]+\\/\\.\\.\\//,\"\")}}return t},s=function(e,r){r=i(e,r);var s=t.modules[r];if(!s){s=t.payloads[r];if(typeof s==\"function\"){var o={},u={id:r,uri:\"\",exports:o,packaged:!0},a=function(e,t){return n(r,e,t)},f=s(a,o,u);o=f||u.exports,t.modules[r]=o,delete t.payloads[r]}s=t.modules[r]=o||s}return s};o(ACE_NAMESPACE)})(),ace.define(\"ace/lib/regexp\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";function o(e){return(e.global?\"g\":\"\")+(e.ignoreCase?\"i\":\"\")+(e.multiline?\"m\":\"\")+(e.extended?\"x\":\"\")+(e.sticky?\"y\":\"\")}function u(e,t,n){if(Array.prototype.indexOf)return e.indexOf(t,n);for(var r=n||0;r<e.length;r++)if(e[r]===t)return r;return-1}var r={exec:RegExp.prototype.exec,test:RegExp.prototype.test,match:String.prototype.match,replace:String.prototype.replace,split:String.prototype.split},i=r.exec.call(/()??/,\"\")[1]===undefined,s=function(){var e=/^/g;return r.test.call(e,\"\"),!e.lastIndex}();if(s&&i)return;RegExp.prototype.exec=function(e){var t=r.exec.apply(this,arguments),n,a;if(typeof e==\"string\"&&t){!i&&t.length>1&&u(t,\"\")>-1&&(a=RegExp(this.source,r.replace.call(o(this),\"g\",\"\")),r.replace.call(e.slice(t.index),a,function(){for(var e=1;e<arguments.length-2;e++)arguments[e]===undefined&&(t[e]=undefined)}));if(this._xregexp&&this._xregexp.captureNames)for(var f=1;f<t.length;f++)n=this._xregexp.captureNames[f-1],n&&(t[n]=t[f]);!s&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--}return t},s||(RegExp.prototype.test=function(e){var t=r.exec.call(this,e);return t&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,!!t})}),ace.define(\"ace/lib/es5-shim\",[\"require\",\"exports\",\"module\"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,\"sentinel\",{}),\"sentinel\"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t===\"undefined\"||t===\"boolean\"||t===\"number\"||t===\"string\"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n==\"function\"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r==\"function\"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!=\"function\")throw new TypeError(\"Function.prototype.bind called on incompatible \"+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,\"__defineGetter__\"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,\"XXX\"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)==\"[object Array]\"});var m=Object(\"a\"),g=m[0]!=\"a\"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!=\"[object Function]\")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0;if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");if(!i&&arguments.length==1)throw new TypeError(\"reduce of empty array with no initial value\");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError(\"reduce of empty array with no initial value\")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0;if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");if(!i&&arguments.length==1)throw new TypeError(\"reduceRight of empty array with no initial value\");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError(\"reduceRight of empty array with no initial value\")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)==\"[object String]\"?this.split(\"\"):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)==\"[object String]\"?this.split(\"\"):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y=\"Object.getOwnPropertyDescriptor called on a non-object: \";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!=\"object\"&&typeof t!=\"function\"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!=\"object\")throw new TypeError(\"typeof prototype[\"+typeof t+\"] != 'object'\");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document==\"undefined\"||w(document.createElement(\"div\"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T=\"Property description must be an object: \",N=\"Object.defineProperty called on non-object: \",C=\"getters & setters can not be defined on this javascript engine\";Object.defineProperty=function(t,n,r){if(typeof t!=\"object\"&&typeof t!=\"function\"||t===null)throw new TypeError(N+t);if(typeof r!=\"object\"&&typeof r!=\"function\"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,\"value\"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,\"get\")&&l(t,n,r.get),f(r,\"set\")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n==\"function\"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n=\"\";while(f(t,n))n+=\"?\";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=[\"toString\",\"toLocaleString\",\"valueOf\",\"hasOwnProperty\",\"isPrototypeOf\",\"propertyIsEnumerable\",\"constructor\"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!=\"object\"&&typeof e!=\"function\"||e===null)throw new TypeError(\"Object.keys called on a non-object\");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _=\"\t\\n\\x0b\\f\\r \\u00a0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029\\ufeff\";if(!String.prototype.trim||_.trim()){_=\"[\"+_+\"]\";var D=new RegExp(\"^\"+_+_+\"*\"),P=new RegExp(_+_+\"*$\");String.prototype.trim=function(){return String(this).replace(D,\"\").replace(P,\"\")}}var F=function(e){if(e==null)throw new TypeError(\"can't convert \"+e+\" to object\");return Object(e)}}),ace.define(\"ace/lib/fixoldbrowsers\",[\"require\",\"exports\",\"module\",\"ace/lib/regexp\",\"ace/lib/es5-shim\"],function(e,t,n){\"use strict\";e(\"./regexp\"),e(\"./es5-shim\"),typeof Element!=\"undefined\"&&!Element.prototype.remove&&Object.defineProperty(Element.prototype,\"remove\",{enumerable:!1,writable:!0,configurable:!0,value:function(){this.parentNode&&this.parentNode.removeChild(this)}})}),ace.define(\"ace/lib/useragent\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";t.OS={LINUX:\"LINUX\",MAC:\"MAC\",WINDOWS:\"WINDOWS\"},t.getOS=function(){return t.isMac?t.OS.MAC:t.isLinux?t.OS.LINUX:t.OS.WINDOWS};var r=typeof navigator==\"object\"?navigator:{},i=(/mac|win|linux/i.exec(r.platform)||[\"other\"])[0].toLowerCase(),s=r.userAgent||\"\",o=r.appName||\"\";t.isWin=i==\"win\",t.isMac=i==\"mac\",t.isLinux=i==\"linux\",t.isIE=o==\"Microsoft Internet Explorer\"||o.indexOf(\"MSAppHost\")>=0?parseFloat((s.match(/(?:MSIE |Trident\\/[0-9]+[\\.0-9]+;.*rv:)([0-9]+[\\.0-9]+)/)||[])[1]):parseFloat((s.match(/(?:Trident\\/[0-9]+[\\.0-9]+;.*rv:)([0-9]+[\\.0-9]+)/)||[])[1]),t.isOldIE=t.isIE&&t.isIE<9,t.isGecko=t.isMozilla=s.match(/ Gecko\\/\\d+/),t.isOpera=typeof opera==\"object\"&&Object.prototype.toString.call(window.opera)==\"[object Opera]\",t.isWebKit=parseFloat(s.split(\"WebKit/\")[1])||undefined,t.isChrome=parseFloat(s.split(\" Chrome/\")[1])||undefined,t.isEdge=parseFloat(s.split(\" Edge/\")[1])||undefined,t.isAIR=s.indexOf(\"AdobeAIR\")>=0,t.isAndroid=s.indexOf(\"Android\")>=0,t.isChromeOS=s.indexOf(\" CrOS \")>=0,t.isIOS=/iPad|iPhone|iPod/.test(s)&&!window.MSStream,t.isIOS&&(t.isMac=!0),t.isMobile=t.isIOS||t.isAndroid}),ace.define(\"ace/lib/dom\",[\"require\",\"exports\",\"module\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";var r=e(\"./useragent\"),i=\"http://www.w3.org/1999/xhtml\";t.buildDom=function o(e,t,n){if(typeof e==\"string\"&&e){var r=document.createTextNode(e);return t&&t.appendChild(r),r}if(!Array.isArray(e))return e;if(typeof e[0]!=\"string\"||!e[0]){var i=[];for(var s=0;s<e.length;s++){var u=o(e[s],t,n);u&&i.push(u)}return i}var a=document.createElement(e[0]),f=e[1],l=1;f&&typeof f==\"object\"&&!Array.isArray(f)&&(l=2);for(var s=l;s<e.length;s++)o(e[s],a,n);return l==2&&Object.keys(f).forEach(function(e){var t=f[e];e===\"class\"?a.className=Array.isArray(t)?t.join(\" \"):t:typeof t==\"function\"||e==\"value\"?a[e]=t:e===\"ref\"?n&&(n[t]=a):t!=null&&a.setAttribute(e,t)}),t&&t.appendChild(a),a},t.getDocumentHead=function(e){return e||(e=document),e.head||e.getElementsByTagName(\"head\")[0]||e.documentElement},t.createElement=function(e,t){return document.createElementNS?document.createElementNS(t||i,e):document.createElement(e)},t.removeChildren=function(e){e.innerHTML=\"\"},t.createTextNode=function(e,t){var n=t?t.ownerDocument:document;return n.createTextNode(e)},t.createFragment=function(e){var t=e?e.ownerDocument:document;return t.createDocumentFragment()},t.hasCssClass=function(e,t){var n=(e.className+\"\").split(/\\s+/g);return n.indexOf(t)!==-1},t.addCssClass=function(e,n){t.hasCssClass(e,n)||(e.className+=\" \"+n)},t.removeCssClass=function(e,t){var n=e.className.split(/\\s+/g);for(;;){var r=n.indexOf(t);if(r==-1)break;n.splice(r,1)}e.className=n.join(\" \")},t.toggleCssClass=function(e,t){var n=e.className.split(/\\s+/g),r=!0;for(;;){var i=n.indexOf(t);if(i==-1)break;r=!1,n.splice(i,1)}return r&&n.push(t),e.className=n.join(\" \"),r},t.setCssClass=function(e,n,r){r?t.addCssClass(e,n):t.removeCssClass(e,n)},t.hasCssString=function(e,t){var n=0,r;t=t||document;if(r=t.querySelectorAll(\"style\"))while(n<r.length)if(r[n++].id===e)return!0},t.importCssString=function(n,r,i){var s=i;if(!i||!i.getRootNode)s=document;else{s=i.getRootNode();if(!s||s==i)s=document}var o=s.ownerDocument||s;if(r&&t.hasCssString(r,s))return null;r&&(n+=\"\\n/*# sourceURL=ace/css/\"+r+\" */\");var u=t.createElement(\"style\");u.appendChild(o.createTextNode(n)),r&&(u.id=r),s==o&&(s=t.getDocumentHead(o)),s.insertBefore(u,s.firstChild)},t.importCssStylsheet=function(e,n){t.buildDom([\"link\",{rel:\"stylesheet\",href:e}],t.getDocumentHead(n))},t.scrollbarWidth=function(e){var n=t.createElement(\"ace_inner\");n.style.width=\"100%\",n.style.minWidth=\"0px\",n.style.height=\"200px\",n.style.display=\"block\";var r=t.createElement(\"ace_outer\"),i=r.style;i.position=\"absolute\",i.left=\"-10000px\",i.overflow=\"hidden\",i.width=\"200px\",i.minWidth=\"0px\",i.height=\"150px\",i.display=\"block\",r.appendChild(n);var s=e.documentElement;s.appendChild(r);var o=n.offsetWidth;i.overflow=\"scroll\";var u=n.offsetWidth;return o==u&&(u=r.clientWidth),s.removeChild(r),o-u},typeof document==\"undefined\"&&(t.importCssString=function(){}),t.computedStyle=function(e,t){return window.getComputedStyle(e,\"\")||{}},t.setStyle=function(e,t,n){e[t]!==n&&(e[t]=n)},t.HAS_CSS_ANIMATION=!1,t.HAS_CSS_TRANSFORMS=!1,t.HI_DPI=r.isWin?typeof window!=\"undefined\"&&window.devicePixelRatio>=1.5:!0;if(typeof document!=\"undefined\"){var s=document.createElement(\"div\");t.HI_DPI&&s.style.transform!==undefined&&(t.HAS_CSS_TRANSFORMS=!0),!r.isEdge&&typeof s.style.animationName!=\"undefined\"&&(t.HAS_CSS_ANIMATION=!0),s=null}t.HAS_CSS_TRANSFORMS?t.translate=function(e,t,n){e.style.transform=\"translate(\"+Math.round(t)+\"px, \"+Math.round(n)+\"px)\"}:t.translate=function(e,t,n){e.style.top=Math.round(n)+\"px\",e.style.left=Math.round(t)+\"px\"}}),ace.define(\"ace/lib/oop\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define(\"ace/lib/keys\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\"],function(e,t,n){\"use strict\";var r=e(\"./oop\"),i=function(){var e={MODIFIER_KEYS:{16:\"Shift\",17:\"Ctrl\",18:\"Alt\",224:\"Meta\",91:\"MetaLeft\",92:\"MetaRight\",93:\"ContextMenu\"},KEY_MODS:{ctrl:1,alt:2,option:2,shift:4,\"super\":8,meta:8,command:8,cmd:8},FUNCTION_KEYS:{8:\"Backspace\",9:\"Tab\",13:\"Return\",19:\"Pause\",27:\"Esc\",32:\"Space\",33:\"PageUp\",34:\"PageDown\",35:\"End\",36:\"Home\",37:\"Left\",38:\"Up\",39:\"Right\",40:\"Down\",44:\"Print\",45:\"Insert\",46:\"Delete\",96:\"Numpad0\",97:\"Numpad1\",98:\"Numpad2\",99:\"Numpad3\",100:\"Numpad4\",101:\"Numpad5\",102:\"Numpad6\",103:\"Numpad7\",104:\"Numpad8\",105:\"Numpad9\",\"-13\":\"NumpadEnter\",112:\"F1\",113:\"F2\",114:\"F3\",115:\"F4\",116:\"F5\",117:\"F6\",118:\"F7\",119:\"F8\",120:\"F9\",121:\"F10\",122:\"F11\",123:\"F12\",144:\"Numlock\",145:\"Scrolllock\"},PRINTABLE_KEYS:{32:\" \",48:\"0\",49:\"1\",50:\"2\",51:\"3\",52:\"4\",53:\"5\",54:\"6\",55:\"7\",56:\"8\",57:\"9\",59:\";\",61:\"=\",65:\"a\",66:\"b\",67:\"c\",68:\"d\",69:\"e\",70:\"f\",71:\"g\",72:\"h\",73:\"i\",74:\"j\",75:\"k\",76:\"l\",77:\"m\",78:\"n\",79:\"o\",80:\"p\",81:\"q\",82:\"r\",83:\"s\",84:\"t\",85:\"u\",86:\"v\",87:\"w\",88:\"x\",89:\"y\",90:\"z\",107:\"+\",109:\"-\",110:\".\",186:\";\",187:\"=\",188:\",\",189:\"-\",190:\".\",191:\"/\",192:\"`\",219:\"[\",220:\"\\\\\",221:\"]\",222:\"'\",111:\"/\",106:\"*\"}},t,n;for(n in e.FUNCTION_KEYS)t=e.FUNCTION_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);for(n in e.PRINTABLE_KEYS)t=e.PRINTABLE_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);return r.mixin(e,e.MODIFIER_KEYS),r.mixin(e,e.PRINTABLE_KEYS),r.mixin(e,e.FUNCTION_KEYS),e.enter=e[\"return\"],e.escape=e.esc,e.del=e[\"delete\"],e[173]=\"-\",function(){var t=[\"cmd\",\"ctrl\",\"alt\",\"shift\"];for(var n=Math.pow(2,t.length);n--;)e.KEY_MODS[n]=t.filter(function(t){return n&e.KEY_MODS[t]}).join(\"-\")+\"-\"}(),e.KEY_MODS[0]=\"\",e.KEY_MODS[-1]=\"input-\",e}();r.mixin(t,i),t.keyCodeToString=function(e){var t=i[e];return typeof t!=\"string\"&&(t=String.fromCharCode(e)),t.toLowerCase()}}),ace.define(\"ace/lib/event\",[\"require\",\"exports\",\"module\",\"ace/lib/keys\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";function a(e,t,n){var a=u(t);if(!i.isMac&&s){t.getModifierState&&(t.getModifierState(\"OS\")||t.getModifierState(\"Win\"))&&(a|=8);if(s.altGr){if((3&a)==3)return;s.altGr=0}if(n===18||n===17){var f=\"location\"in t?t.location:t.keyLocation;if(n===17&&f===1)s[n]==1&&(o=t.timeStamp);else if(n===18&&a===3&&f===2){var l=t.timeStamp-o;l<50&&(s.altGr=!0)}}}n in r.MODIFIER_KEYS&&(n=-1);if(!a&&n===13){var f=\"location\"in t?t.location:t.keyLocation;if(f===3){e(t,a,-n);if(t.defaultPrevented)return}}if(i.isChromeOS&&a&8){e(t,a,n);if(t.defaultPrevented)return;a&=-9}return!!a||n in r.FUNCTION_KEYS||n in r.PRINTABLE_KEYS?e(t,a,n):!1}function f(){s=Object.create(null)}var r=e(\"./keys\"),i=e(\"./useragent\"),s=null,o=0;t.addListener=function(e,t,n){if(e.addEventListener)return e.addEventListener(t,n,!1);if(e.attachEvent){var r=function(){n.call(e,window.event)};n._wrapper=r,e.attachEvent(\"on\"+t,r)}},t.removeListener=function(e,t,n){if(e.removeEventListener)return e.removeEventListener(t,n,!1);e.detachEvent&&e.detachEvent(\"on\"+t,n._wrapper||n)},t.stopEvent=function(e){return t.stopPropagation(e),t.preventDefault(e),!1},t.stopPropagation=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},t.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},t.getButton=function(e){return e.type==\"dblclick\"?0:e.type==\"contextmenu\"||i.isMac&&e.ctrlKey&&!e.altKey&&!e.shiftKey?2:e.preventDefault?e.button:{1:0,2:2,4:1}[e.button]},t.capture=function(e,n,r){function i(e){n&&n(e),r&&r(e),t.removeListener(document,\"mousemove\",n,!0),t.removeListener(document,\"mouseup\",i,!0),t.removeListener(document,\"dragstart\",i,!0)}return t.addListener(document,\"mousemove\",n,!0),t.addListener(document,\"mouseup\",i,!0),t.addListener(document,\"dragstart\",i,!0),i},t.addMouseWheelListener=function(e,n){\"onmousewheel\"in e?t.addListener(e,\"mousewheel\",function(e){var t=8;e.wheelDeltaX!==undefined?(e.wheelX=-e.wheelDeltaX/t,e.wheelY=-e.wheelDeltaY/t):(e.wheelX=0,e.wheelY=-e.wheelDelta/t),n(e)}):\"onwheel\"in e?t.addListener(e,\"wheel\",function(e){var t=.35;switch(e.deltaMode){case e.DOM_DELTA_PIXEL:e.wheelX=e.deltaX*t||0,e.wheelY=e.deltaY*t||0;break;case e.DOM_DELTA_LINE:case e.DOM_DELTA_PAGE:e.wheelX=(e.deltaX||0)*5,e.wheelY=(e.deltaY||0)*5}n(e)}):t.addListener(e,\"DOMMouseScroll\",function(e){e.axis&&e.axis==e.HORIZONTAL_AXIS?(e.wheelX=(e.detail||0)*5,e.wheelY=0):(e.wheelX=0,e.wheelY=(e.detail||0)*5),n(e)})},t.addMultiMouseDownListener=function(e,n,r,s){function c(e){t.getButton(e)!==0?o=0:e.detail>1?(o++,o>4&&(o=1)):o=1;if(i.isIE){var c=Math.abs(e.clientX-u)>5||Math.abs(e.clientY-a)>5;if(!f||c)o=1;f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),o==1&&(u=e.clientX,a=e.clientY)}e._clicks=o,r[s](\"mousedown\",e);if(o>4)o=0;else if(o>1)return r[s](l[o],e)}function h(e){o=2,f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),r[s](\"mousedown\",e),r[s](l[o],e)}var o=0,u,a,f,l={2:\"dblclick\",3:\"tripleclick\",4:\"quadclick\"};Array.isArray(e)||(e=[e]),e.forEach(function(e){t.addListener(e,\"mousedown\",c),i.isOldIE&&t.addListener(e,\"dblclick\",h)})};var u=!i.isMac||!i.isOpera||\"KeyboardEvent\"in window?function(e){return 0|(e.ctrlKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.metaKey?8:0)}:function(e){return 0|(e.metaKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.ctrlKey?8:0)};t.getModifierString=function(e){return r.KEY_MODS[u(e)]},t.addCommandKeyListener=function(e,n){var r=t.addListener;if(i.isOldGecko||i.isOpera&&!(\"KeyboardEvent\"in window)){var o=null;r(e,\"keydown\",function(e){o=e.keyCode}),r(e,\"keypress\",function(e){return a(n,e,o)})}else{var u=null;r(e,\"keydown\",function(e){s[e.keyCode]=(s[e.keyCode]||0)+1;var t=a(n,e,e.keyCode);return u=e.defaultPrevented,t}),r(e,\"keypress\",function(e){u&&(e.ctrlKey||e.altKey||e.shiftKey||e.metaKey)&&(t.stopEvent(e),u=null)}),r(e,\"keyup\",function(e){s[e.keyCode]=null}),s||(f(),r(window,\"focus\",f))}};if(typeof window==\"object\"&&window.postMessage&&!i.isOldIE){var l=1;t.nextTick=function(e,n){n=n||window;var r=\"zero-timeout-message-\"+l++,i=function(s){s.data==r&&(t.stopPropagation(s),t.removeListener(n,\"message\",i),e())};t.addListener(n,\"message\",i),n.postMessage(r,\"*\")}}t.$idleBlocked=!1,t.onIdle=function(e,n){return setTimeout(function r(){t.$idleBlocked?setTimeout(r,100):e()},n)},t.$idleBlockId=null,t.blockIdle=function(e){t.$idleBlockId&&clearTimeout(t.$idleBlockId),t.$idleBlocked=!0,t.$idleBlockId=setTimeout(function(){t.$idleBlocked=!1},e||100)},t.nextFrame=typeof window==\"object\"&&(window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame),t.nextFrame?t.nextFrame=t.nextFrame.bind(window):t.nextFrame=function(e){setTimeout(e,17)}}),ace.define(\"ace/range\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return\"Range: [\"+this.start.row+\"/\"+this.start.column+\"] -> [\"+this.end.row+\"/\"+this.end.column+\"]\"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e==\"object\"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e==\"object\"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define(\"ace/lib/lang\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split(\"\").reverse().join(\"\")},t.stringRepeat=function(e,t){var n=\"\";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\\s\\s*/,i=/\\s\\s*$/;t.stringTrimLeft=function(e){return e.replace(r,\"\")},t.stringTrimRight=function(e){return e.replace(i,\"\")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]==\"object\"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function s(e){if(typeof e!=\"object\"||!e)return e;var t;if(Array.isArray(e)){t=[];for(var n=0;n<e.length;n++)t[n]=s(e[n]);return t}if(Object.prototype.toString.call(e)!==\"[object Object]\")return e;t={};for(var n in e)t[n]=s(e[n]);return t},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\\]\\/\\\\])/g,\"\\\\$1\")},t.escapeHTML=function(e){return(\"\"+e).replace(/&/g,\"&#38;\").replace(/\"/g,\"&#34;\").replace(/'/g,\"&#39;\").replace(/</g,\"&#60;\")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define(\"ace/clipboard\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r;n.exports={lineMode:!1,pasteCancelled:function(){return r&&r>Date.now()-50?!0:r=!1},cancel:function(){r=Date.now()}}}),ace.define(\"ace/keyboard/textinput\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/clipboard\",\"ace/lib/keys\"],function(e,t,n){\"use strict\";var r=e(\"../lib/event\"),i=e(\"../lib/useragent\"),s=e(\"../lib/dom\"),o=e(\"../lib/lang\"),u=e(\"../clipboard\"),a=i.isChrome<18,f=i.isIE,l=i.isChrome>63,c=400,h=e(\"../lib/keys\"),p=h.KEY_MODS,d=i.isIOS,v=d?/\\s/:/\\n/,m=function(e,t){function z(){S=!0,n.blur(),n.focus(),S=!1}function X(e){e.keyCode==27&&n.value.length<n.selectionStart&&(y||(x=n.value),T=N=-1,L()),W()}function $(){clearTimeout(V),V=setTimeout(function(){w&&(n.style.cssText=w,w=\"\"),t.renderer.$isMousePressed=!1,t.renderer.$keepTextAreaAtCursor&&t.renderer.$moveTextAreaToCursor()},0)}function K(e,t,n){var r=null,i=!1;n.addEventListener(\"keydown\",function(e){r&&clearTimeout(r),i=!0},!0),n.addEventListener(\"keyup\",function(e){r=setTimeout(function(){i=!1},100)},!0);var s=function(e){if(document.activeElement!==n)return;if(i||y||t.$mouseHandler.isMousePressed)return;if(m)return;var r=n.selectionStart,s=n.selectionEnd,o=null,u=0;if(r==0)o=h.up;else if(r==1)o=h.home;else if(s>N&&x[s]==\"\\n\")o=h.end;else if(r<T&&x[r-1]==\" \")o=h.left,u=p.option;else if(r<T||r==T&&N!=T&&r==s)o=h.left;else if(s>N&&x.slice(0,s).split(\"\\n\").length>2)o=h.down;else if(s>N&&x[s-1]==\" \")o=h.right,u=p.option;else if(s>N||s==N&&N!=T&&r==s)o=h.right;r!==s&&(u|=p.shift);if(o){var a=t.onCommandKey({},u,o);if(!a&&t.commands){o=h.keyCodeToString(o);var f=t.commands.findKeyCommand(u,o);f&&t.execCommand(f)}T=r,N=s,L(\"\")}};document.addEventListener(\"selectionchange\",s),t.on(\"destroy\",function(){document.removeEventListener(\"selectionchange\",s)})}var n=s.createElement(\"textarea\");n.className=\"ace_text-input\",n.setAttribute(\"wrap\",\"off\"),n.setAttribute(\"autocorrect\",\"off\"),n.setAttribute(\"autocapitalize\",\"off\"),n.setAttribute(\"spellcheck\",!1),n.style.opacity=\"0\",e.insertBefore(n,e.firstChild);var m=!1,g=!1,y=!1,b=!1,w=\"\";i.isMobile||(n.style.fontSize=\"1px\");var E=!1,S=!1,x=\"\",T=0,N=0;try{var C=document.activeElement===n}catch(k){}r.addListener(n,\"blur\",function(e){if(S)return;t.onBlur(e),C=!1}),r.addListener(n,\"focus\",function(e){if(S)return;C=!0;if(i.isEdge)try{if(!document.hasFocus())return}catch(e){}t.onFocus(e),i.isEdge?setTimeout(L):L()}),this.$focusScroll=!1,this.focus=function(){if(w||l||this.$focusScroll==\"browser\")return n.focus({preventScroll:!0});var e=n.style.top;n.style.position=\"fixed\",n.style.top=\"0px\";try{var t=n.getBoundingClientRect().top!=0}catch(r){return}var i=[];if(t){var s=n.parentElement;while(s&&s.nodeType==1)i.push(s),s.setAttribute(\"ace_nocontext\",!0),!s.parentElement&&s.getRootNode?s=s.getRootNode().host:s=s.parentElement}n.focus({preventScroll:!0}),t&&i.forEach(function(e){e.removeAttribute(\"ace_nocontext\")}),setTimeout(function(){n.style.position=\"\",n.style.top==\"0px\"&&(n.style.top=e)},0)},this.blur=function(){n.blur()},this.isFocused=function(){return C},t.on(\"beforeEndOperation\",function(){if(t.curOp&&t.curOp.command.name==\"insertstring\")return;y&&(x=n.value=\"\",U()),L()});var L=d?function(e){if(!C||m&&!e||b)return;e||(e=\"\");var r=\"\\n ab\"+e+\"cde fg\\n\";r!=n.value&&(n.value=x=r);var i=4,s=4+(e.length||(t.selection.isEmpty()?0:1));(T!=i||N!=s)&&n.setSelectionRange(i,s),T=i,N=s}:function(){if(y||b)return;if(!C&&!_)return;y=!0;var e=t.selection,r=e.getRange(),i=e.cursor.row,s=r.start.column,o=r.end.column,u=t.session.getLine(i);if(r.start.row!=i){var a=t.session.getLine(i-1);s=r.start.row<i-1?0:s,o+=a.length+1,u=a+\"\\n\"+u}else if(r.end.row!=i){var f=t.session.getLine(i+1);o=r.end.row>i+1?f.length:o,o+=u.length+1,u=u+\"\\n\"+f}u.length>c&&(s<c&&o<c?u=u.slice(0,c):(u=\"\\n\",s=0,o=1));var l=u+\"\\n\\n\";l!=x&&(n.value=x=l,T=N=l.length),_&&(T=n.selectionStart,N=n.selectionEnd);if(N!=o||T!=s||n.selectionEnd!=N)try{n.setSelectionRange(s,o),T=s,N=o}catch(h){}y=!1};C&&t.onFocus();var A=function(e){return e.selectionStart===0&&e.selectionEnd>=x.length&&e.value===x&&x&&e.selectionEnd!==N},O=function(e){if(y)return;m?m=!1:A(n)&&(t.selectAll(),L())},M=null;this.setInputHandler=function(e){M=e},this.getInputHandler=function(){return M};var _=!1,D=function(e,r){_&&(_=!1);if(g)return L(),e&&t.onPaste(e),g=!1,\"\";var i=n.selectionStart,s=n.selectionEnd,o=T,u=x.length-N,a=e,f=e.length-i,l=e.length-s,c=0;while(o>0&&x[c]==e[c])c++,o--;a=a.slice(c),c=1;while(u>0&&x.length-c>T-1&&x[x.length-c]==e[e.length-c])c++,u--;f-=c-1,l-=c-1;var h=a.length-c+1;return h<0&&(o=-h,h=0),a=a.slice(0,h),!r&&f==a.length&&!o&&!u&&!l?\"\":(b=!0,a&&!o&&!u&&!f&&!l||E?t.onTextInput(a):t.onTextInput(a,{extendLeft:o,extendRight:u,restoreStart:f,restoreEnd:l}),b=!1,x=e,T=i,N=s,a)},P=function(e){if(y)return R();if(e&&e.inputType){if(e.inputType==\"historyUndo\")return t.execCommand(\"undo\");if(e.inputType==\"historyRedo\")return t.execCommand(\"redo\")}var r=n.value,i=D(r,!0);(r.length>c+100||v.test(i))&&L()},H=function(e,t,n){var r=e.clipboardData||window.clipboardData;if(!r||a)return;var i=f||n?\"Text\":\"text/plain\";try{return t?r.setData(i,t)!==!1:r.getData(i)}catch(e){if(!n)return H(e,t,!0)}},B=function(e,i){var s=t.getCopyText();if(!s)return r.preventDefault(e);H(e,s)?(d&&(L(s),m=s,setTimeout(function(){m=!1},10)),i?t.onCut():t.onCopy(),r.preventDefault(e)):(m=!0,n.value=s,n.select(),setTimeout(function(){m=!1,L(),i?t.onCut():t.onCopy()}))},j=function(e){B(e,!0)},F=function(e){B(e,!1)},I=function(e){var s=H(e);if(u.pasteCancelled())return;typeof s==\"string\"?(s&&t.onPaste(s,e),i.isIE&&setTimeout(L),r.preventDefault(e)):(n.value=\"\",g=!0)};r.addCommandKeyListener(n,t.onCommandKey.bind(t)),r.addListener(n,\"select\",O),r.addListener(n,\"input\",P),r.addListener(n,\"cut\",j),r.addListener(n,\"copy\",F),r.addListener(n,\"paste\",I),(!(\"oncut\"in n)||!(\"oncopy\"in n)||!(\"onpaste\"in n))&&r.addListener(e,\"keydown\",function(e){if(i.isMac&&!e.metaKey||!e.ctrlKey)return;switch(e.keyCode){case 67:F(e);break;case 86:I(e);break;case 88:j(e)}});var q=function(e){if(y||!t.onCompositionStart||t.$readOnly)return;y={};if(E)return;setTimeout(R,0),t.on(\"mousedown\",z);var r=t.getSelectionRange();r.end.row=r.start.row,r.end.column=r.start.column,y.markerRange=r,y.selectionStart=T,t.onCompositionStart(y),y.useTextareaForIME?(n.value=\"\",x=\"\",T=0,N=0):(n.msGetInputContext&&(y.context=n.msGetInputContext()),n.getInputContext&&(y.context=n.getInputContext()))},R=function(){if(!y||!t.onCompositionUpdate||t.$readOnly)return;if(E)return z();if(y.useTextareaForIME)t.onCompositionUpdate(n.value);else{var e=n.value;D(e),y.markerRange&&(y.context&&(y.markerRange.start.column=y.selectionStart=y.context.compositionStartOffset),y.markerRange.end.column=y.markerRange.start.column+N-y.selectionStart)}},U=function(e){if(!t.onCompositionEnd||t.$readOnly)return;y=!1,t.onCompositionEnd(),t.off(\"mousedown\",z),e&&P()},W=o.delayedCall(R,50).schedule.bind(null,null);r.addListener(n,\"compositionstart\",q),r.addListener(n,\"compositionupdate\",R),r.addListener(n,\"keyup\",X),r.addListener(n,\"keydown\",W),r.addListener(n,\"compositionend\",U),this.getElement=function(){return n},this.setCommandMode=function(e){E=e,n.readOnly=!1},this.setReadOnly=function(e){E||(n.readOnly=e)},this.setCopyWithEmptySelection=function(e){},this.onContextMenu=function(e){_=!0,L(),t._emit(\"nativecontextmenu\",{target:t,domEvent:e}),this.moveToMouse(e,!0)},this.moveToMouse=function(e,o){w||(w=n.style.cssText),n.style.cssText=(o?\"z-index:100000;\":\"\")+(i.isIE?\"opacity:0.1;\":\"\")+\"text-indent: -\"+(T+N)*t.renderer.characterWidth*.5+\"px;\";var u=t.container.getBoundingClientRect(),a=s.computedStyle(t.container),f=u.top+(parseInt(a.borderTopWidth)||0),l=u.left+(parseInt(u.borderLeftWidth)||0),c=u.bottom-f-n.clientHeight-2,h=function(e){s.translate(n,e.clientX-l-2,Math.min(e.clientY-f-2,c))};h(e);if(e.type!=\"mousedown\")return;t.renderer.$isMousePressed=!0,clearTimeout(V),i.isWin&&r.capture(t.container,h,$)},this.onContextMenuClose=$;var V,J=function(e){t.textInput.onContextMenu(e),$()};r.addListener(n,\"mouseup\",J),r.addListener(n,\"mousedown\",function(e){e.preventDefault(),$()}),r.addListener(t.renderer.scroller,\"contextmenu\",J),r.addListener(n,\"contextmenu\",J),d&&K(e,t,n)};t.TextInput=m}),ace.define(\"ace/mouse/default_handlers\",[\"require\",\"exports\",\"module\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";function o(e){e.$clickSelection=null;var t=e.editor;t.setDefaultHandler(\"mousedown\",this.onMouseDown.bind(e)),t.setDefaultHandler(\"dblclick\",this.onDoubleClick.bind(e)),t.setDefaultHandler(\"tripleclick\",this.onTripleClick.bind(e)),t.setDefaultHandler(\"quadclick\",this.onQuadClick.bind(e)),t.setDefaultHandler(\"mousewheel\",this.onMouseWheel.bind(e));var n=[\"select\",\"startSelect\",\"selectEnd\",\"selectAllEnd\",\"selectByWordsEnd\",\"selectByLinesEnd\",\"dragWait\",\"dragWaitEnd\",\"focusWait\"];n.forEach(function(t){e[t]=this[t]},this),e.selectByLines=this.extendSelectionBy.bind(e,\"getLineRange\"),e.selectByWords=this.extendSelectionBy.bind(e,\"getWordRange\")}function u(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}function a(e,t){if(e.start.row==e.end.row)var n=2*t.column-e.start.column-e.end.column;else if(e.start.row==e.end.row-1&&!e.start.column&&!e.end.column)var n=t.column-4;else var n=2*t.row-e.start.row-e.end.row;return n<0?{cursor:e.start,anchor:e.end}:{cursor:e.end,anchor:e.start}}var r=e(\"../lib/useragent\"),i=0,s=550;(function(){this.onMouseDown=function(e){var t=e.inSelection(),n=e.getDocumentPosition();this.mousedownEvent=e;var i=this.editor,s=e.getButton();if(s!==0){var o=i.getSelectionRange(),u=o.isEmpty();(u||s==1)&&i.selection.moveToPosition(n),s==2&&(i.textInput.onContextMenu(e.domEvent),r.isMozilla||e.preventDefault());return}this.mousedownEvent.time=Date.now();if(t&&!i.isFocused()){i.focus();if(this.$focusTimeout&&!this.$clickSelection&&!i.inMultiSelectMode){this.setState(\"focusWait\"),this.captureMouse(e);return}}return this.captureMouse(e),this.startSelect(n,e.domEvent._clicks>1),e.preventDefault()},this.startSelect=function(e,t){e=e||this.editor.renderer.screenToTextCoordinates(this.x,this.y);var n=this.editor;if(!this.mousedownEvent)return;this.mousedownEvent.getShiftKey()?n.selection.selectToPosition(e):t||n.selection.moveToPosition(e),t||this.select(),n.renderer.scroller.setCapture&&n.renderer.scroller.setCapture(),n.setStyle(\"ace_selecting\"),this.setState(\"select\")},this.select=function(){var e,t=this.editor,n=t.renderer.screenToTextCoordinates(this.x,this.y);if(this.$clickSelection){var r=this.$clickSelection.comparePoint(n);if(r==-1)e=this.$clickSelection.end;else if(r==1)e=this.$clickSelection.start;else{var i=a(this.$clickSelection,n);n=i.cursor,e=i.anchor}t.selection.setSelectionAnchor(e.row,e.column)}t.selection.selectToPosition(n),t.renderer.scrollCursorIntoView()},this.extendSelectionBy=function(e){var t,n=this.editor,r=n.renderer.screenToTextCoordinates(this.x,this.y),i=n.selection[e](r.row,r.column);if(this.$clickSelection){var s=this.$clickSelection.comparePoint(i.start),o=this.$clickSelection.comparePoint(i.end);if(s==-1&&o<=0){t=this.$clickSelection.end;if(i.end.row!=r.row||i.end.column!=r.column)r=i.start}else if(o==1&&s>=0){t=this.$clickSelection.start;if(i.start.row!=r.row||i.start.column!=r.column)r=i.end}else if(s==-1&&o==1)r=i.end,t=i.start;else{var u=a(this.$clickSelection,r);r=u.cursor,t=u.anchor}n.selection.setSelectionAnchor(t.row,t.column)}n.selection.selectToPosition(r),n.renderer.scrollCursorIntoView()},this.selectEnd=this.selectAllEnd=this.selectByWordsEnd=this.selectByLinesEnd=function(){this.$clickSelection=null,this.editor.unsetStyle(\"ace_selecting\"),this.editor.renderer.scroller.releaseCapture&&this.editor.renderer.scroller.releaseCapture()},this.focusWait=function(){var e=u(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y),t=Date.now();(e>i||t-this.mousedownEvent.time>this.$focusTimeout)&&this.startSelect(this.mousedownEvent.getDocumentPosition())},this.onDoubleClick=function(e){var t=e.getDocumentPosition(),n=this.editor,r=n.session,i=r.getBracketRange(t);i?(i.isEmpty()&&(i.start.column--,i.end.column++),this.setState(\"select\")):(i=n.selection.getWordRange(t.row,t.column),this.setState(\"selectByWords\")),this.$clickSelection=i,this.select()},this.onTripleClick=function(e){var t=e.getDocumentPosition(),n=this.editor;this.setState(\"selectByLines\");var r=n.getSelectionRange();r.isMultiLine()&&r.contains(t.row,t.column)?(this.$clickSelection=n.selection.getLineRange(r.start.row),this.$clickSelection.end=n.selection.getLineRange(r.end.row).end):this.$clickSelection=n.selection.getLineRange(t.row),this.select()},this.onQuadClick=function(e){var t=this.editor;t.selectAll(),this.$clickSelection=t.getSelectionRange(),this.setState(\"selectAll\")},this.onMouseWheel=function(e){if(e.getAccelKey())return;e.getShiftKey()&&e.wheelY&&!e.wheelX&&(e.wheelX=e.wheelY,e.wheelY=0);var t=this.editor;this.$lastScroll||(this.$lastScroll={t:0,vx:0,vy:0,allowed:0});var n=this.$lastScroll,r=e.domEvent.timeStamp,i=r-n.t,o=i?e.wheelX/i:n.vx,u=i?e.wheelY/i:n.vy;i<s&&(o=(o+n.vx)/2,u=(u+n.vy)/2);var a=Math.abs(o/u),f=!1;a>=1&&t.renderer.isScrollableBy(e.wheelX*e.speed,0)&&(f=!0),a<=1&&t.renderer.isScrollableBy(0,e.wheelY*e.speed)&&(f=!0);if(f)n.allowed=r;else if(r-n.allowed<s){var l=Math.abs(o)<=1.5*Math.abs(n.vx)&&Math.abs(u)<=1.5*Math.abs(n.vy);l?(f=!0,n.allowed=r):n.allowed=0}n.t=r,n.vx=o,n.vy=u;if(f)return t.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()}}).call(o.prototype),t.DefaultHandlers=o}),ace.define(\"ace/tooltip\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";function s(e){this.isOpen=!1,this.$element=null,this.$parentNode=e}var r=e(\"./lib/oop\"),i=e(\"./lib/dom\");(function(){this.$init=function(){return this.$element=i.createElement(\"div\"),this.$element.className=\"ace_tooltip\",this.$element.style.display=\"none\",this.$parentNode.appendChild(this.$element),this.$element},this.getElement=function(){return this.$element||this.$init()},this.setText=function(e){this.getElement().textContent=e},this.setHtml=function(e){this.getElement().innerHTML=e},this.setPosition=function(e,t){this.getElement().style.left=e+\"px\",this.getElement().style.top=t+\"px\"},this.setClassName=function(e){i.addCssClass(this.getElement(),e)},this.show=function(e,t,n){e!=null&&this.setText(e),t!=null&&n!=null&&this.setPosition(t,n),this.isOpen||(this.getElement().style.display=\"block\",this.isOpen=!0)},this.hide=function(){this.isOpen&&(this.getElement().style.display=\"none\",this.isOpen=!1)},this.getHeight=function(){return this.getElement().offsetHeight},this.getWidth=function(){return this.getElement().offsetWidth},this.destroy=function(){this.isOpen=!1,this.$element&&this.$element.parentNode&&this.$element.parentNode.removeChild(this.$element)}}).call(s.prototype),t.Tooltip=s}),ace.define(\"ace/mouse/default_gutter_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/oop\",\"ace/lib/event\",\"ace/tooltip\"],function(e,t,n){\"use strict\";function u(e){function l(){var r=u.getDocumentPosition().row,s=n.$annotations[r];if(!s)return c();var o=t.session.getLength();if(r==o){var a=t.renderer.pixelToScreenCoordinates(0,u.y).row,l=u.$pos;if(a>t.session.documentToScreenRow(l.row,l.column))return c()}if(f==s)return;f=s.text.join(\"<br/>\"),i.setHtml(f),i.show(),t._signal(\"showGutterTooltip\",i),t.on(\"mousewheel\",c);if(e.$tooltipFollowsMouse)h(u);else{var p=u.domEvent.target,d=p.getBoundingClientRect(),v=i.getElement().style;v.left=d.right+\"px\",v.top=d.bottom+\"px\"}}function c(){o&&(o=clearTimeout(o)),f&&(i.hide(),f=null,t._signal(\"hideGutterTooltip\",i),t.removeEventListener(\"mousewheel\",c))}function h(e){i.setPosition(e.x,e.y)}var t=e.editor,n=t.renderer.$gutterLayer,i=new a(t.container);e.editor.setDefaultHandler(\"guttermousedown\",function(r){if(!t.isFocused()||r.getButton()!=0)return;var i=n.getRegion(r);if(i==\"foldWidgets\")return;var s=r.getDocumentPosition().row,o=t.session.selection;if(r.getShiftKey())o.selectTo(s,0);else{if(r.domEvent.detail==2)return t.selectAll(),r.preventDefault();e.$clickSelection=t.selection.getLineRange(s)}return e.setState(\"selectByLines\"),e.captureMouse(r),r.preventDefault()});var o,u,f;e.editor.setDefaultHandler(\"guttermousemove\",function(t){var n=t.domEvent.target||t.domEvent.srcElement;if(r.hasCssClass(n,\"ace_fold-widget\"))return c();f&&e.$tooltipFollowsMouse&&h(t),u=t;if(o)return;o=setTimeout(function(){o=null,u&&!e.isMousePressed?l():c()},50)}),s.addListener(t.renderer.$gutter,\"mouseout\",function(e){u=null;if(!f||o)return;o=setTimeout(function(){o=null,c()},50)}),t.on(\"changeSession\",c)}function a(e){o.call(this,e)}var r=e(\"../lib/dom\"),i=e(\"../lib/oop\"),s=e(\"../lib/event\"),o=e(\"../tooltip\").Tooltip;i.inherits(a,o),function(){this.setPosition=function(e,t){var n=window.innerWidth||document.documentElement.clientWidth,r=window.innerHeight||document.documentElement.clientHeight,i=this.getWidth(),s=this.getHeight();e+=15,t+=15,e+i>n&&(e-=e+i-n),t+s>r&&(t-=20+s),o.prototype.setPosition.call(this,e,t)}}.call(a.prototype),t.GutterHandler=u}),ace.define(\"ace/mouse/mouse_event\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";var r=e(\"../lib/event\"),i=e(\"../lib/useragent\"),s=t.MouseEvent=function(e,t){this.domEvent=e,this.editor=t,this.x=this.clientX=e.clientX,this.y=this.clientY=e.clientY,this.$pos=null,this.$inSelection=null,this.propagationStopped=!1,this.defaultPrevented=!1};(function(){this.stopPropagation=function(){r.stopPropagation(this.domEvent),this.propagationStopped=!0},this.preventDefault=function(){r.preventDefault(this.domEvent),this.defaultPrevented=!0},this.stop=function(){this.stopPropagation(),this.preventDefault()},this.getDocumentPosition=function(){return this.$pos?this.$pos:(this.$pos=this.editor.renderer.screenToTextCoordinates(this.clientX,this.clientY),this.$pos)},this.inSelection=function(){if(this.$inSelection!==null)return this.$inSelection;var e=this.editor,t=e.getSelectionRange();if(t.isEmpty())this.$inSelection=!1;else{var n=this.getDocumentPosition();this.$inSelection=t.contains(n.row,n.column)}return this.$inSelection},this.getButton=function(){return r.getButton(this.domEvent)},this.getShiftKey=function(){return this.domEvent.shiftKey},this.getAccelKey=i.isMac?function(){return this.domEvent.metaKey}:function(){return this.domEvent.ctrlKey}}).call(s.prototype)}),ace.define(\"ace/mouse/dragdrop_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";function f(e){function T(e,n){var r=Date.now(),i=!n||e.row!=n.row,s=!n||e.column!=n.column;if(!S||i||s)t.moveCursorToPosition(e),S=r,x={x:p,y:d};else{var o=l(x.x,x.y,p,d);o>a?S=null:r-S>=u&&(t.renderer.scrollCursorIntoView(),S=null)}}function N(e,n){var r=Date.now(),i=t.renderer.layerConfig.lineHeight,s=t.renderer.layerConfig.characterWidth,u=t.renderer.scroller.getBoundingClientRect(),a={x:{left:p-u.left,right:u.right-p},y:{top:d-u.top,bottom:u.bottom-d}},f=Math.min(a.x.left,a.x.right),l=Math.min(a.y.top,a.y.bottom),c={row:e.row,column:e.column};f/s<=2&&(c.column+=a.x.left<a.x.right?-3:2),l/i<=1&&(c.row+=a.y.top<a.y.bottom?-1:1);var h=e.row!=c.row,v=e.column!=c.column,m=!n||e.row!=n.row;h||v&&!m?E?r-E>=o&&t.renderer.scrollCursorIntoView(c):E=r:E=null}function C(){var e=g;g=t.renderer.screenToTextCoordinates(p,d),T(g,e),N(g,e)}function k(){m=t.selection.toOrientedRange(),h=t.session.addMarker(m,\"ace_selection\",t.getSelectionStyle()),t.clearSelection(),t.isFocused()&&t.renderer.$cursorLayer.setBlinking(!1),clearInterval(v),C(),v=setInterval(C,20),y=0,i.addListener(document,\"mousemove\",O)}function L(){clearInterval(v),t.session.removeMarker(h),h=null,t.selection.fromOrientedRange(m),t.isFocused()&&!w&&t.$resetCursorStyle(),m=null,g=null,y=0,E=null,S=null,i.removeListener(document,\"mousemove\",O)}function O(){A==null&&(A=setTimeout(function(){A!=null&&h&&L()},20))}function M(e){var t=e.types;return!t||Array.prototype.some.call(t,function(e){return e==\"text/plain\"||e==\"Text\"})}function _(e){var t=[\"copy\",\"copymove\",\"all\",\"uninitialized\"],n=[\"move\",\"copymove\",\"linkmove\",\"all\",\"uninitialized\"],r=s.isMac?e.altKey:e.ctrlKey,i=\"uninitialized\";try{i=e.dataTransfer.effectAllowed.toLowerCase()}catch(e){}var o=\"none\";return r&&t.indexOf(i)>=0?o=\"copy\":n.indexOf(i)>=0?o=\"move\":t.indexOf(i)>=0&&(o=\"copy\"),o}var t=e.editor,n=r.createElement(\"img\");n.src=\"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\",s.isOpera&&(n.style.cssText=\"width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;\");var f=[\"dragWait\",\"dragWaitEnd\",\"startDrag\",\"dragReadyEnd\",\"onMouseDrag\"];f.forEach(function(t){e[t]=this[t]},this),t.addEventListener(\"mousedown\",this.onMouseDown.bind(e));var c=t.container,h,p,d,v,m,g,y=0,b,w,E,S,x;this.onDragStart=function(e){if(this.cancelDrag||!c.draggable){var r=this;return setTimeout(function(){r.startSelect(),r.captureMouse(e)},0),e.preventDefault()}m=t.getSelectionRange();var i=e.dataTransfer;i.effectAllowed=t.getReadOnly()?\"copy\":\"copyMove\",s.isOpera&&(t.container.appendChild(n),n.scrollTop=0),i.setDragImage&&i.setDragImage(n,0,0),s.isOpera&&t.container.removeChild(n),i.clearData(),i.setData(\"Text\",t.session.getTextRange()),w=!0,this.setState(\"drag\")},this.onDragEnd=function(e){c.draggable=!1,w=!1,this.setState(null);if(!t.getReadOnly()){var n=e.dataTransfer.dropEffect;!b&&n==\"move\"&&t.session.remove(t.getSelectionRange()),t.$resetCursorStyle()}this.editor.unsetStyle(\"ace_dragging\"),this.editor.renderer.setCursorStyle(\"\")},this.onDragEnter=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||k(),y++,e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragOver=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||(k(),y++),A!==null&&(A=null),e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragLeave=function(e){y--;if(y<=0&&h)return L(),b=null,i.preventDefault(e)},this.onDrop=function(e){if(!g)return;var n=e.dataTransfer;if(w)switch(b){case\"move\":m.contains(g.row,g.column)?m={start:g,end:g}:m=t.moveText(m,g);break;case\"copy\":m=t.moveText(m,g,!0)}else{var r=n.getData(\"Text\");m={start:g,end:t.session.insert(g,r)},t.focus(),b=null}return L(),i.preventDefault(e)},i.addListener(c,\"dragstart\",this.onDragStart.bind(e)),i.addListener(c,\"dragend\",this.onDragEnd.bind(e)),i.addListener(c,\"dragenter\",this.onDragEnter.bind(e)),i.addListener(c,\"dragover\",this.onDragOver.bind(e)),i.addListener(c,\"dragleave\",this.onDragLeave.bind(e)),i.addListener(c,\"drop\",this.onDrop.bind(e));var A=null}function l(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}var r=e(\"../lib/dom\"),i=e(\"../lib/event\"),s=e(\"../lib/useragent\"),o=200,u=200,a=5;(function(){this.dragWait=function(){var e=Date.now()-this.mousedownEvent.time;e>this.editor.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(){var e=this.editor.container;e.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()),this.selectEnd()},this.dragReadyEnd=function(e){this.editor.$resetCursorStyle(),this.editor.unsetStyle(\"ace_dragging\"),this.editor.renderer.setCursorStyle(\"\"),this.dragWaitEnd()},this.startDrag=function(){this.cancelDrag=!1;var e=this.editor,t=e.container;t.draggable=!0,e.renderer.$cursorLayer.setBlinking(!1),e.setStyle(\"ace_dragging\");var n=s.isWin?\"default\":\"move\";e.renderer.setCursorStyle(n),this.setState(\"dragReady\")},this.onMouseDrag=function(e){var t=this.editor.container;if(s.isIE&&this.state==\"dragReady\"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>3&&t.dragDrop()}if(this.state===\"dragWait\"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>0&&(t.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()))}},this.onMouseDown=function(e){if(!this.$dragEnabled)return;this.mousedownEvent=e;var t=this.editor,n=e.inSelection(),r=e.getButton(),i=e.domEvent.detail||1;if(i===1&&r===0&&n){if(e.editor.inMultiSelectMode&&(e.getAccelKey()||e.getShiftKey()))return;this.mousedownEvent.time=Date.now();var o=e.domEvent.target||e.domEvent.srcElement;\"unselectable\"in o&&(o.unselectable=\"on\");if(t.getDragDelay()){if(s.isWebKit){this.cancelDrag=!0;var u=t.container;u.draggable=!0}this.setState(\"dragWait\")}else this.startDrag();this.captureMouse(e,this.onMouseDrag.bind(this)),e.defaultPrevented=!0}}}).call(f.prototype),t.DragdropHandler=f}),ace.define(\"ace/mouse/touch_handler\",[\"require\",\"exports\",\"module\",\"ace/mouse/mouse_event\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";var r=e(\"./mouse_event\").MouseEvent,i=e(\"../lib/dom\");t.addTouchListeners=function(e,t){function y(){var e=window.navigator&&window.navigator.clipboard,r=!1,s=function(){var n=t.getCopyText(),s=t.session.getUndoManager().hasUndo();g.replaceChild(i.buildDom(r?[\"span\",!n&&[\"span\",{\"class\":\"ace_mobile-button\",action:\"selectall\"},\"Select All\"],n&&[\"span\",{\"class\":\"ace_mobile-button\",action:\"copy\"},\"Copy\"],n&&[\"span\",{\"class\":\"ace_mobile-button\",action:\"cut\"},\"Cut\"],e&&[\"span\",{\"class\":\"ace_mobile-button\",action:\"paste\"},\"Paste\"],s&&[\"span\",{\"class\":\"ace_mobile-button\",action:\"undo\"},\"Undo\"],[\"span\",{\"class\":\"ace_mobile-button\",action:\"find\"},\"Find\"],[\"span\",{\"class\":\"ace_mobile-button\",action:\"openCommandPallete\"},\"Pallete\"]]:[\"span\"]),g.firstChild)},o=function(n){var i=n.target.getAttribute(\"action\");if(i==\"more\"||!r)return r=!r,s();if(i==\"paste\")e.readText().then(function(e){t.execCommand(i,e)});else if(i){if(i==\"cut\"||i==\"copy\")e?e.writeText(t.getCopyText()):document.execCommand(\"copy\");t.execCommand(i)}g.firstChild.style.display=\"none\",r=!1,i!=\"openCommandPallete\"&&t.focus()};g=i.buildDom([\"div\",{\"class\":\"ace_mobile-menu\",ontouchstart:function(e){n=\"menu\",e.stopPropagation(),e.preventDefault(),t.textInput.focus()},ontouchend:function(e){e.stopPropagation(),e.preventDefault(),o(e)},onclick:o},[\"span\"],[\"span\",{\"class\":\"ace_mobile-button\",action:\"more\"},\"...\"]],t.container)}function b(){g||y();var e=t.selection.cursor,n=t.renderer.textToScreenCoordinates(e.row,e.column),r=t.container.getBoundingClientRect();g.style.top=n.pageY-r.top-3+\"px\",g.style.right=\"10px\",g.style.display=\"\",g.firstChild.style.display=\"none\",t.on(\"input\",w)}function w(e){g&&(g.style.display=\"none\"),t.off(\"input\",w)}function E(){f=null,clearTimeout(f);var e=t.selection.getRange(),r=e.contains(h.row,h.column);if(e.isEmpty()||!r)t.selection.moveToPosition(h),t.selection.selectWord();n=\"wait\",b()}function S(){f=null,clearTimeout(f),t.selection.moveToPosition(h);var e=p>=2?t.selection.getLineRange(h.row):t.session.getBracketRange(h);e&&!e.isEmpty()?t.selection.setRange(e):t.selection.selectWord(),n=\"wait\"}function x(){c+=60,l=setInterval(function(){c--<=0&&(clearInterval(l),l=null),Math.abs(d)<.01&&(d=0),Math.abs(v)<.01&&(v=0),c<20&&(d=.9*d),c<20&&(v=.9*v);var e=t.session.getScrollTop();t.renderer.scrollBy(10*d,10*v),e==t.session.getScrollTop()&&(c=0)},10)}var n=\"scroll\",s,o,u,a,f,l,c=0,h,p=0,d=0,v=0,m,g;e.addEventListener(\"contextmenu\",function(e){if(!m)return;var n=t.textInput.getElement();n.focus()}),e.addEventListener(\"touchstart\",function(e){var i=e.touches;if(f||i.length>1){clearTimeout(f),f=null,u=-1,n=\"zoom\";return}m=t.$mouseHandler.isMousePressed=!0;var l=t.renderer.layerConfig.lineHeight,g=t.renderer.layerConfig.lineHeight,y=e.timeStamp;a=y;var b=i[0],w=b.clientX,x=b.clientY;Math.abs(s-w)+Math.abs(o-x)>l&&(u=-1),s=e.clientX=w,o=e.clientY=x,d=v=0;var T=new r(e,t);h=T.getDocumentPosition();if(y-u<500&&i.length==1&&!c)p++,e.preventDefault(),e.button=0,S();else{p=0;var N=t.selection.cursor,C=t.selection.isEmpty()?N:t.selection.anchor,k=t.renderer.$cursorLayer.getPixelPosition(N,!0),L=t.renderer.$cursorLayer.getPixelPosition(C,!0),A=t.renderer.scroller.getBoundingClientRect(),O=function(e,t){return e/=g,t=t/l-.75,e*e+t*t};if(e.clientX<A.left){n=\"zoom\";return}var M=O(e.clientX-A.left-k.left,e.clientY-A.top-k.top),_=O(e.clientX-A.left-L.left,e.clientY-A.top-L.top);M<3.5&&_<3.5&&(n=M>_?\"cursor\":\"anchor\"),_<3.5?n=\"anchor\":M<3.5?n=\"cursor\":n=\"scroll\",f=setTimeout(E,450)}u=y}),e.addEventListener(\"touchend\",function(e){m=t.$mouseHandler.isMousePressed=!1,l&&clearInterval(l),n==\"zoom\"?(n=\"\",c=0):f?(t.selection.moveToPosition(h),c=0,b()):n==\"scroll\"?(x(),e.preventDefault(),w()):b(),clearTimeout(f),f=null}),e.addEventListener(\"touchmove\",function(e){f&&(clearTimeout(f),f=null);var i=e.touches;if(i.length>1||n==\"zoom\")return;var u=i[0],l=s-u.clientX,c=o-u.clientY;if(n==\"wait\"){if(!(l*l+c*c>4))return e.preventDefault();n=\"cursor\"}s=u.clientX,o=u.clientY,e.clientX=u.clientX,e.clientY=u.clientY;var h=e.timeStamp,p=h-a;a=h;if(n==\"scroll\"){var m=new r(e,t);m.speed=1,m.wheelX=l,m.wheelY=c,10*Math.abs(l)<Math.abs(c)&&(l=0),10*Math.abs(c)<Math.abs(l)&&(c=0),p!=0&&(d=l/p,v=c/p),t._emit(\"mousewheel\",m),m.propagationStopped||(d=v=0)}else{var g=new r(e,t),y=g.getDocumentPosition();n==\"cursor\"?t.selection.moveCursorToPosition(y):n==\"anchor\"&&t.selection.setSelectionAnchor(y.row,y.column),t.renderer.scrollCursorIntoView(y),e.preventDefault()}})}}),ace.define(\"ace/lib/net\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";var r=e(\"./dom\");t.get=function(e,t){var n=new XMLHttpRequest;n.open(\"GET\",e,!0),n.onreadystatechange=function(){n.readyState===4&&t(n.responseText)},n.send(null)},t.loadScript=function(e,t){var n=r.getDocumentHead(),i=document.createElement(\"script\");i.src=e,n.appendChild(i),i.onload=i.onreadystatechange=function(e,n){if(n||!i.readyState||i.readyState==\"loaded\"||i.readyState==\"complete\")i=i.onload=i.onreadystatechange=null,n||t()}},t.qualifyURL=function(e){var t=document.createElement(\"a\");return t.href=e,t.href}}),ace.define(\"ace/lib/event_emitter\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!=\"object\"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)});if(!t)return new Promise(function(e){t=e})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t)r&&this.setDefaultHandler(e,r.pop());else if(r){var i=r.indexOf(t);i!=-1&&r.splice(i,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?\"unshift\":\"push\"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define(\"ace/lib/app_config\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"],function(e,t,n){\"no use strict\";function o(e){typeof console!=\"undefined\"&&console.warn&&console.warn.apply(console,arguments)}function u(e,t){var n=new Error(e);n.data=t,typeof console==\"object\"&&console.error&&console.error(n),setTimeout(function(){throw n})}var r=e(\"./oop\"),i=e(\"./event_emitter\").EventEmitter,s={setOptions:function(e){Object.keys(e).forEach(function(t){this.setOption(t,e[t])},this)},getOptions:function(e){var t={};if(!e){var n=this.$options;e=Object.keys(n).filter(function(e){return!n[e].hidden})}else Array.isArray(e)||(t=e,e=Object.keys(t));return e.forEach(function(e){t[e]=this.getOption(e)},this),t},setOption:function(e,t){if(this[\"$\"+e]===t)return;var n=this.$options[e];if(!n)return o('misspelled option \"'+e+'\"');if(n.forwardTo)return this[n.forwardTo]&&this[n.forwardTo].setOption(e,t);n.handlesSet||(this[\"$\"+e]=t),n&&n.set&&n.set.call(this,t)},getOption:function(e){var t=this.$options[e];return t?t.forwardTo?this[t.forwardTo]&&this[t.forwardTo].getOption(e):t&&t.get?t.get.call(this):this[\"$\"+e]:o('misspelled option \"'+e+'\"')}},a=function(){this.$defaultOptions={}};(function(){r.implement(this,i),this.defineOptions=function(e,t,n){return e.$options||(this.$defaultOptions[t]=e.$options={}),Object.keys(n).forEach(function(t){var r=n[t];typeof r==\"string\"&&(r={forwardTo:r}),r.name||(r.name=t),e.$options[r.name]=r,\"initialValue\"in r&&(e[\"$\"+r.name]=r.initialValue)}),r.implement(e,s),this},this.resetOptions=function(e){Object.keys(e.$options).forEach(function(t){var n=e.$options[t];\"value\"in n&&e.setOption(t,n.value)})},this.setDefaultValue=function(e,t,n){if(!e){for(e in this.$defaultOptions)if(this.$defaultOptions[e][t])break;if(!this.$defaultOptions[e][t])return!1}var r=this.$defaultOptions[e]||(this.$defaultOptions[e]={});r[t]&&(r.forwardTo?this.setDefaultValue(r.forwardTo,t,n):r[t].value=n)},this.setDefaultValues=function(e,t){Object.keys(t).forEach(function(n){this.setDefaultValue(e,n,t[n])},this)},this.warn=o,this.reportError=u}).call(a.prototype),t.AppConfig=a}),ace.define(\"ace/config\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/lib/oop\",\"ace/lib/net\",\"ace/lib/app_config\"],function(e,t,n){\"no use strict\";function l(r){if(!u||!u.document)return;a.packaged=r||e.packaged||n.packaged||u.define&&define.packaged;var i={},s=\"\",o=document.currentScript||document._currentScript,f=o&&o.ownerDocument||document,l=f.getElementsByTagName(\"script\");for(var h=0;h<l.length;h++){var p=l[h],d=p.src||p.getAttribute(\"src\");if(!d)continue;var v=p.attributes;for(var m=0,g=v.length;m<g;m++){var y=v[m];y.name.indexOf(\"data-ace-\")===0&&(i[c(y.name.replace(/^data-ace-/,\"\"))]=y.value)}var b=d.match(/^(.*)\\/ace(\\-\\w+)?\\.js(\\?|$)/);b&&(s=b[1])}s&&(i.base=i.base||s,i.packaged=!0),i.basePath=i.base,i.workerPath=i.workerPath||i.base,i.modePath=i.modePath||i.base,i.themePath=i.themePath||i.base,delete i.base;for(var w in i)typeof i[w]!=\"undefined\"&&t.set(w,i[w])}function c(e){return e.replace(/-(.)/g,function(e,t){return t.toUpperCase()})}var r=e(\"./lib/lang\"),i=e(\"./lib/oop\"),s=e(\"./lib/net\"),o=e(\"./lib/app_config\").AppConfig;n.exports=t=new o;var u=function(){return this||typeof window!=\"undefined\"&&window}(),a={packaged:!1,workerPath:null,modePath:null,themePath:null,basePath:\"\",suffix:\".js\",$moduleUrls:{},loadWorkerFromBlob:!0,sharedPopups:!1};t.get=function(e){if(!a.hasOwnProperty(e))throw new Error(\"Unknown config key: \"+e);return a[e]},t.set=function(e,t){if(a.hasOwnProperty(e))a[e]=t;else if(this.setDefaultValue(\"\",e,t)==0)throw new Error(\"Unknown config key: \"+e)},t.all=function(){return r.copyObject(a)},t.$modes={},t.moduleUrl=function(e,t){if(a.$moduleUrls[e])return a.$moduleUrls[e];var n=e.split(\"/\");t=t||n[n.length-2]||\"\";var r=t==\"snippets\"?\"/\":\"-\",i=n[n.length-1];if(t==\"worker\"&&r==\"-\"){var s=new RegExp(\"^\"+t+\"[\\\\-_]|[\\\\-_]\"+t+\"$\",\"g\");i=i.replace(s,\"\")}(!i||i==t)&&n.length>1&&(i=n[n.length-2]);var o=a[t+\"Path\"];return o==null?o=a.basePath:r==\"/\"&&(t=r=\"\"),o&&o.slice(-1)!=\"/\"&&(o+=\"/\"),o+t+r+i+this.get(\"suffix\")},t.setModuleUrl=function(e,t){return a.$moduleUrls[e]=t},t.$loading={},t.loadModule=function(n,r){var i,o;Array.isArray(n)&&(o=n[0],n=n[1]);try{i=e(n)}catch(u){}if(i&&!t.$loading[n])return r&&r(i);t.$loading[n]||(t.$loading[n]=[]),t.$loading[n].push(r);if(t.$loading[n].length>1)return;var a=function(){e([n],function(e){t._emit(\"load.module\",{name:n,module:e});var r=t.$loading[n];t.$loading[n]=null,r.forEach(function(t){t&&t(e)})})};if(!t.get(\"packaged\"))return a();s.loadScript(t.moduleUrl(n,o),a),f()};var f=function(){!a.basePath&&!a.workerPath&&!a.modePath&&!a.themePath&&!Object.keys(a.$moduleUrls).length&&(console.error(\"Unable to infer path to ace from script src,\",\"use ace.config.set('basePath', 'path') to enable dynamic loading of modes and themes\",\"or with webpack use ace/webpack-resolver\"),f=function(){})};t.init=l,t.version=\"1.4.6\"}),ace.define(\"ace/mouse/mouse_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\",\"ace/mouse/default_handlers\",\"ace/mouse/default_gutter_handler\",\"ace/mouse/mouse_event\",\"ace/mouse/dragdrop_handler\",\"ace/mouse/touch_handler\",\"ace/config\"],function(e,t,n){\"use strict\";var r=e(\"../lib/event\"),i=e(\"../lib/useragent\"),s=e(\"./default_handlers\").DefaultHandlers,o=e(\"./default_gutter_handler\").GutterHandler,u=e(\"./mouse_event\").MouseEvent,a=e(\"./dragdrop_handler\").DragdropHandler,f=e(\"./touch_handler\").addTouchListeners,l=e(\"../config\"),c=function(e){var t=this;this.editor=e,new s(this),new o(this),new a(this);var n=function(t){var n=!document.hasFocus||!document.hasFocus()||!e.isFocused()&&document.activeElement==(e.textInput&&e.textInput.getElement());n&&window.focus(),e.focus()},u=e.renderer.getMouseEventTarget();r.addListener(u,\"click\",this.onMouseEvent.bind(this,\"click\")),r.addListener(u,\"mousemove\",this.onMouseMove.bind(this,\"mousemove\")),r.addMultiMouseDownListener([u,e.renderer.scrollBarV&&e.renderer.scrollBarV.inner,e.renderer.scrollBarH&&e.renderer.scrollBarH.inner,e.textInput&&e.textInput.getElement()].filter(Boolean),[400,300,250],this,\"onMouseEvent\"),r.addMouseWheelListener(e.container,this.onMouseWheel.bind(this,\"mousewheel\")),f(e.container,e);var l=e.renderer.$gutter;r.addListener(l,\"mousedown\",this.onMouseEvent.bind(this,\"guttermousedown\")),r.addListener(l,\"click\",this.onMouseEvent.bind(this,\"gutterclick\")),r.addListener(l,\"dblclick\",this.onMouseEvent.bind(this,\"gutterdblclick\")),r.addListener(l,\"mousemove\",this.onMouseEvent.bind(this,\"guttermousemove\")),r.addListener(u,\"mousedown\",n),r.addListener(l,\"mousedown\",n),i.isIE&&e.renderer.scrollBarV&&(r.addListener(e.renderer.scrollBarV.element,\"mousedown\",n),r.addListener(e.renderer.scrollBarH.element,\"mousedown\",n)),e.on(\"mousemove\",function(n){if(t.state||t.$dragDelay||!t.$dragEnabled)return;var r=e.renderer.screenToTextCoordinates(n.x,n.y),i=e.session.selection.getRange(),s=e.renderer;!i.isEmpty()&&i.insideStart(r.row,r.column)?s.setCursorStyle(\"default\"):s.setCursorStyle(\"\")})};(function(){this.onMouseEvent=function(e,t){this.editor._emit(e,new u(t,this.editor))},this.onMouseMove=function(e,t){var n=this.editor._eventRegistry&&this.editor._eventRegistry.mousemove;if(!n||!n.length)return;this.editor._emit(e,new u(t,this.editor))},this.onMouseWheel=function(e,t){var n=new u(t,this.editor);n.speed=this.$scrollSpeed*2,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.setState=function(e){this.state=e},this.captureMouse=function(e,t){this.x=e.x,this.y=e.y,this.isMousePressed=!0;var n=this.editor,s=this.editor.renderer;s.$isMousePressed=!0;var o=this,a=function(e){if(!e)return;if(i.isWebKit&&!e.which&&o.releaseMouse)return o.releaseMouse();o.x=e.clientX,o.y=e.clientY,t&&t(e),o.mouseEvent=new u(e,o.editor),o.$mouseMoved=!0},f=function(e){n.off(\"beforeEndOperation\",c),clearInterval(h),l(),o[o.state+\"End\"]&&o[o.state+\"End\"](e),o.state=\"\",o.isMousePressed=s.$isMousePressed=!1,s.$keepTextAreaAtCursor&&s.$moveTextAreaToCursor(),o.$onCaptureMouseMove=o.releaseMouse=null,e&&o.onMouseEvent(\"mouseup\",e),n.endOperation()},l=function(){o[o.state]&&o[o.state](),o.$mouseMoved=!1};if(i.isOldIE&&e.domEvent.type==\"dblclick\")return setTimeout(function(){f(e)});var c=function(e){if(!o.releaseMouse)return;n.curOp.command.name&&n.curOp.selectionChanged&&(o[o.state+\"End\"]&&o[o.state+\"End\"](),o.state=\"\",o.releaseMouse())};n.on(\"beforeEndOperation\",c),n.startOperation({command:{name:\"mouse\"}}),o.$onCaptureMouseMove=a,o.releaseMouse=r.capture(this.editor.container,a,f);var h=setInterval(l,20)},this.releaseMouse=null,this.cancelContextMenu=function(){var e=function(t){if(t&&t.domEvent&&t.domEvent.type!=\"contextmenu\")return;this.editor.off(\"nativecontextmenu\",e),t&&t.domEvent&&r.stopEvent(t.domEvent)}.bind(this);setTimeout(e,10),this.editor.on(\"nativecontextmenu\",e)}}).call(c.prototype),l.defineOptions(c.prototype,\"mouseHandler\",{scrollSpeed:{initialValue:2},dragDelay:{initialValue:i.isMac?150:0},dragEnabled:{initialValue:!0},focusTimeout:{initialValue:0},tooltipFollowsMouse:{initialValue:!0}}),t.MouseHandler=c}),ace.define(\"ace/mouse/fold_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";function i(e){e.on(\"click\",function(t){var n=t.getDocumentPosition(),i=e.session,s=i.getFoldAt(n.row,n.column,1);s&&(t.getAccelKey()?i.removeFold(s):i.expandFold(s),t.stop());var o=t.domEvent&&t.domEvent.target;o&&r.hasCssClass(o,\"ace_inline_button\")&&r.hasCssClass(o,\"ace_toggle_wrap\")&&(i.setOption(\"wrap\",!i.getUseWrapMode()),e.renderer.scrollCursorIntoView())}),e.on(\"gutterclick\",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n==\"foldWidgets\"){var r=t.getDocumentPosition().row,i=e.session;i.foldWidgets&&i.foldWidgets[r]&&e.session.onFoldWidgetClick(r,t),e.isFocused()||e.focus(),t.stop()}}),e.on(\"gutterdblclick\",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n==\"foldWidgets\"){var r=t.getDocumentPosition().row,i=e.session,s=i.getParentFoldRangeData(r,!0),o=s.range||s.firstRange;if(o){r=o.start.row;var u=i.getFoldAt(r,i.getLine(r).length,1);u?i.removeFold(u):(i.addFold(\"...\",o),e.renderer.scrollCursorIntoView({row:o.start.row,column:0}))}t.stop()}})}var r=e(\"../lib/dom\");t.FoldHandler=i}),ace.define(\"ace/keyboard/keybinding\",[\"require\",\"exports\",\"module\",\"ace/lib/keys\",\"ace/lib/event\"],function(e,t,n){\"use strict\";var r=e(\"../lib/keys\"),i=e(\"../lib/event\"),s=function(e){this.$editor=e,this.$data={editor:e},this.$handlers=[],this.setDefaultHandler(e.commands)};(function(){this.setDefaultHandler=function(e){this.removeKeyboardHandler(this.$defaultHandler),this.$defaultHandler=e,this.addKeyboardHandler(e,0)},this.setKeyboardHandler=function(e){var t=this.$handlers;if(t[t.length-1]==e)return;while(t[t.length-1]&&t[t.length-1]!=this.$defaultHandler)this.removeKeyboardHandler(t[t.length-1]);this.addKeyboardHandler(e,1)},this.addKeyboardHandler=function(e,t){if(!e)return;typeof e==\"function\"&&!e.handleKeyboard&&(e.handleKeyboard=e);var n=this.$handlers.indexOf(e);n!=-1&&this.$handlers.splice(n,1),t==undefined?this.$handlers.push(e):this.$handlers.splice(t,0,e),n==-1&&e.attach&&e.attach(this.$editor)},this.removeKeyboardHandler=function(e){var t=this.$handlers.indexOf(e);return t==-1?!1:(this.$handlers.splice(t,1),e.detach&&e.detach(this.$editor),!0)},this.getKeyboardHandler=function(){return this.$handlers[this.$handlers.length-1]},this.getStatusText=function(){var e=this.$data,t=e.editor;return this.$handlers.map(function(n){return n.getStatusText&&n.getStatusText(t,e)||\"\"}).filter(Boolean).join(\" \")},this.$callKeyboardHandlers=function(e,t,n,r){var s,o=!1,u=this.$editor.commands;for(var a=this.$handlers.length;a--;){s=this.$handlers[a].handleKeyboard(this.$data,e,t,n,r);if(!s||!s.command)continue;s.command==\"null\"?o=!0:o=u.exec(s.command,this.$editor,s.args,r),o&&r&&e!=-1&&s.passEvent!=1&&s.command.passEvent!=1&&i.stopEvent(r);if(o)break}return!o&&e==-1&&(s={command:\"insertstring\"},o=u.exec(\"insertstring\",this.$editor,t)),o&&this.$editor._signal&&this.$editor._signal(\"keyboardActivity\",s),o},this.onCommandKey=function(e,t,n){var i=r.keyCodeToString(n);return this.$callKeyboardHandlers(t,i,n,e)},this.onTextInput=function(e){return this.$callKeyboardHandlers(-1,e)}}).call(s.prototype),t.KeyBinding=s}),ace.define(\"ace/lib/bidiutil\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";function F(e,t,n,r){var i=s?d:p,c=null,h=null,v=null,m=0,g=null,y=null,b=-1,w=null,E=null,T=[];if(!r)for(w=0,r=[];w<n;w++)r[w]=R(e[w]);o=s,u=!1,a=!1,f=!1,l=!1;for(E=0;E<n;E++){c=m,T[E]=h=q(e,r,T,E),m=i[c][h],g=m&240,m&=15,t[E]=v=i[m][5];if(g>0)if(g==16){for(w=b;w<E;w++)t[w]=1;b=-1}else b=-1;y=i[m][6];if(y)b==-1&&(b=E);else if(b>-1){for(w=b;w<E;w++)t[w]=v;b=-1}r[E]==S&&(t[E]=0),o|=v}if(l)for(w=0;w<n;w++)if(r[w]==x){t[w]=s;for(var C=w-1;C>=0;C--){if(r[C]!=N)break;t[C]=s}}}function I(e,t,n){if(o<e)return;if(e==1&&s==m&&!f){n.reverse();return}var r=n.length,i=0,u,a,l,c;while(i<r){if(t[i]>=e){u=i+1;while(u<r&&t[u]>=e)u++;for(a=i,l=u-1;a<l;a++,l--)c=n[a],n[a]=n[l],n[l]=c;i=u}i++}}function q(e,t,n,r){var i=t[r],o,c,h,p;switch(i){case g:case y:u=!1;case E:case w:return i;case b:return u?w:b;case T:return u=!0,a=!0,y;case N:return E;case C:if(r<1||r+1>=t.length||(o=n[r-1])!=b&&o!=w||(c=t[r+1])!=b&&c!=w)return E;return u&&(c=w),c==o?c:E;case k:o=r>0?n[r-1]:S;if(o==b&&r+1<t.length&&t[r+1]==b)return b;return E;case L:if(r>0&&n[r-1]==b)return b;if(u)return E;p=r+1,h=t.length;while(p<h&&t[p]==L)p++;if(p<h&&t[p]==b)return b;return E;case A:h=t.length,p=r+1;while(p<h&&t[p]==A)p++;if(p<h){var d=e[r],v=d>=1425&&d<=2303||d==64286;o=t[p];if(v&&(o==y||o==T))return y}if(r<1||(o=t[r-1])==S)return E;return n[r-1];case S:return u=!1,f=!0,s;case x:return l=!0,E;case O:case M:case D:case P:case _:u=!1;case H:return E}}function R(e){var t=e.charCodeAt(0),n=t>>8;return n==0?t>191?g:B[t]:n==5?/[\\u0591-\\u05f4]/.test(e)?y:g:n==6?/[\\u0610-\\u061a\\u064b-\\u065f\\u06d6-\\u06e4\\u06e7-\\u06ed]/.test(e)?A:/[\\u0660-\\u0669\\u066b-\\u066c]/.test(e)?w:t==1642?L:/[\\u06f0-\\u06f9]/.test(e)?b:T:n==32&&t<=8287?j[t&255]:n==254?t>=65136?T:E:E}function U(e){return e>=\"\\u064b\"&&e<=\"\\u0655\"}var r=[\"\\u0621\",\"\\u0641\"],i=[\"\\u063a\",\"\\u064a\"],s=0,o=0,u=!1,a=!1,f=!1,l=!1,c=!1,h=!1,p=[[0,3,0,1,0,0,0],[0,3,0,1,2,2,0],[0,3,0,17,2,0,1],[0,3,5,5,4,1,0],[0,3,21,21,4,0,1],[0,3,5,5,4,2,0]],d=[[2,0,1,1,0,1,0],[2,0,1,1,0,2,0],[2,0,2,1,3,2,0],[2,0,2,33,3,1,1]],v=0,m=1,g=0,y=1,b=2,w=3,E=4,S=5,x=6,T=7,N=8,C=9,k=10,L=11,A=12,O=13,M=14,_=15,D=16,P=17,H=18,B=[H,H,H,H,H,H,H,H,H,x,S,x,N,S,H,H,H,H,H,H,H,H,H,H,H,H,H,H,S,S,S,x,N,E,E,L,L,L,E,E,E,E,E,k,C,k,C,C,b,b,b,b,b,b,b,b,b,b,C,E,E,E,E,E,E,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,E,E,E,E,E,E,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,E,E,E,E,H,H,H,H,H,H,S,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,C,E,L,L,L,L,E,E,E,E,g,E,E,H,E,E,L,L,b,b,E,g,E,E,E,b,g,E,E,E,E,E],j=[N,N,N,N,N,N,N,N,N,N,N,H,H,H,g,y,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,N,S,O,M,_,D,P,C,L,L,L,L,L,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,C,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,N];t.L=g,t.R=y,t.EN=b,t.ON_R=3,t.AN=4,t.R_H=5,t.B=6,t.RLE=7,t.DOT=\"\\u00b7\",t.doBidiReorder=function(e,n,r){if(e.length<2)return{};var i=e.split(\"\"),o=new Array(i.length),u=new Array(i.length),a=[];s=r?m:v,F(i,a,i.length,n);for(var f=0;f<o.length;o[f]=f,f++);I(2,a,o),I(1,a,o);for(var f=0;f<o.length-1;f++)n[f]===w?a[f]=t.AN:a[f]===y&&(n[f]>T&&n[f]<O||n[f]===E||n[f]===H)?a[f]=t.ON_R:f>0&&i[f-1]===\"\\u0644\"&&/\\u0622|\\u0623|\\u0625|\\u0627/.test(i[f])&&(a[f-1]=a[f]=t.R_H,f++);i[i.length-1]===t.DOT&&(a[i.length-1]=t.B),i[0]===\"\\u202b\"&&(a[0]=t.RLE);for(var f=0;f<o.length;f++)u[f]=a[o[f]];return{logicalFromVisual:o,bidiLevels:u}},t.hasBidiCharacters=function(e,t){var n=!1;for(var r=0;r<e.length;r++)t[r]=R(e.charAt(r)),!n&&(t[r]==y||t[r]==T||t[r]==w)&&(n=!0);return n},t.getVisualFromLogicalIdx=function(e,t){for(var n=0;n<t.logicalFromVisual.length;n++)if(t.logicalFromVisual[n]==e)return n;return 0}}),ace.define(\"ace/bidihandler\",[\"require\",\"exports\",\"module\",\"ace/lib/bidiutil\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"./lib/bidiutil\"),i=e(\"./lib/lang\"),s=/[\\u0590-\\u05f4\\u0600-\\u06ff\\u0700-\\u08ac\\u202B]/,o=function(e){this.session=e,this.bidiMap={},this.currentRow=null,this.bidiUtil=r,this.charWidths=[],this.EOL=\"\\u00ac\",this.showInvisibles=!0,this.isRtlDir=!1,this.$isRtl=!1,this.line=\"\",this.wrapIndent=0,this.EOF=\"\\u00b6\",this.RLE=\"\\u202b\",this.contentWidth=0,this.fontMetrics=null,this.rtlLineOffset=0,this.wrapOffset=0,this.isMoveLeftOperation=!1,this.seenBidi=s.test(e.getValue())};(function(){this.isBidiRow=function(e,t,n){return this.seenBidi?(e!==this.currentRow&&(this.currentRow=e,this.updateRowLine(t,n),this.updateBidiMap()),this.bidiMap.bidiLevels):!1},this.onChange=function(e){this.seenBidi?this.currentRow=null:e.action==\"insert\"&&s.test(e.lines.join(\"\\n\"))&&(this.seenBidi=!0,this.currentRow=null)},this.getDocumentRow=function(){var e=0,t=this.session.$screenRowCache;if(t.length){var n=this.session.$getRowCacheIndex(t,this.currentRow);n>=0&&(e=this.session.$docRowCache[n])}return e},this.getSplitIndex=function(){var e=0,t=this.session.$screenRowCache;if(t.length){var n,r=this.session.$getRowCacheIndex(t,this.currentRow);while(this.currentRow-e>0){n=this.session.$getRowCacheIndex(t,this.currentRow-e-1);if(n!==r)break;r=n,e++}}else e=this.currentRow;return e},this.updateRowLine=function(e,t){e===undefined&&(e=this.getDocumentRow());var n=e===this.session.getLength()-1,s=n?this.EOF:this.EOL;this.wrapIndent=0,this.line=this.session.getLine(e),this.isRtlDir=this.$isRtl||this.line.charAt(0)===this.RLE;if(this.session.$useWrapMode){var o=this.session.$wrapData[e];o&&(t===undefined&&(t=this.getSplitIndex()),t>0&&o.length?(this.wrapIndent=o.indent,this.wrapOffset=this.wrapIndent*this.charWidths[r.L],this.line=t<o.length?this.line.substring(o[t-1],o[t]):this.line.substring(o[o.length-1])):this.line=this.line.substring(0,o[t])),t==o.length&&(this.line+=this.showInvisibles?s:r.DOT)}else this.line+=this.showInvisibles?s:r.DOT;var u=this.session,a=0,f;this.line=this.line.replace(/\\t|[\\u1100-\\u2029, \\u202F-\\uFFE6]/g,function(e,t){return e===\"\t\"||u.isFullWidth(e.charCodeAt(0))?(f=e===\"\t\"?u.getScreenTabSize(t+a):2,a+=f-1,i.stringRepeat(r.DOT,f)):e}),this.isRtlDir&&(this.fontMetrics.$main.textContent=this.line.charAt(this.line.length-1)==r.DOT?this.line.substr(0,this.line.length-1):this.line,this.rtlLineOffset=this.contentWidth-this.fontMetrics.$main.getBoundingClientRect().width)},this.updateBidiMap=function(){var e=[];r.hasBidiCharacters(this.line,e)||this.isRtlDir?this.bidiMap=r.doBidiReorder(this.line,e,this.isRtlDir):this.bidiMap={}},this.markAsDirty=function(){this.currentRow=null},this.updateCharacterWidths=function(e){if(this.characterWidth===e.$characterSize.width)return;this.fontMetrics=e;var t=this.characterWidth=e.$characterSize.width,n=e.$measureCharWidth(\"\\u05d4\");this.charWidths[r.L]=this.charWidths[r.EN]=this.charWidths[r.ON_R]=t,this.charWidths[r.R]=this.charWidths[r.AN]=n,this.charWidths[r.R_H]=n*.45,this.charWidths[r.B]=this.charWidths[r.RLE]=0,this.currentRow=null},this.setShowInvisibles=function(e){this.showInvisibles=e,this.currentRow=null},this.setEolChar=function(e){this.EOL=e},this.setContentWidth=function(e){this.contentWidth=e},this.isRtlLine=function(e){return this.$isRtl?!0:e!=undefined?this.session.getLine(e).charAt(0)==this.RLE:this.isRtlDir},this.setRtlDirection=function(e,t){var n=e.getCursorPosition();for(var r=e.selection.getSelectionAnchor().row;r<=n.row;r++)!t&&e.session.getLine(r).charAt(0)===e.session.$bidiHandler.RLE?e.session.doc.removeInLine(r,0,1):t&&e.session.getLine(r).charAt(0)!==e.session.$bidiHandler.RLE&&e.session.doc.insert({column:0,row:r},e.session.$bidiHandler.RLE)},this.getPosLeft=function(e){e-=this.wrapIndent;var t=this.line.charAt(0)===this.RLE?1:0,n=e>t?this.session.getOverwrite()?e:e-1:t,i=r.getVisualFromLogicalIdx(n,this.bidiMap),s=this.bidiMap.bidiLevels,o=0;!this.session.getOverwrite()&&e<=t&&s[i]%2!==0&&i++;for(var u=0;u<i;u++)o+=this.charWidths[s[u]];return!this.session.getOverwrite()&&e>t&&s[i]%2===0&&(o+=this.charWidths[s[i]]),this.wrapIndent&&(o+=this.isRtlDir?-1*this.wrapOffset:this.wrapOffset),this.isRtlDir&&(o+=this.rtlLineOffset),o},this.getSelections=function(e,t){var n=this.bidiMap,r=n.bidiLevels,i,s=[],o=0,u=Math.min(e,t)-this.wrapIndent,a=Math.max(e,t)-this.wrapIndent,f=!1,l=!1,c=0;this.wrapIndent&&(o+=this.isRtlDir?-1*this.wrapOffset:this.wrapOffset);for(var h,p=0;p<r.length;p++)h=n.logicalFromVisual[p],i=r[p],f=h>=u&&h<a,f&&!l?c=o:!f&&l&&s.push({left:c,width:o-c}),o+=this.charWidths[i],l=f;f&&p===r.length&&s.push({left:c,width:o-c});if(this.isRtlDir)for(var d=0;d<s.length;d++)s[d].left+=this.rtlLineOffset;return s},this.offsetToCol=function(e){this.isRtlDir&&(e-=this.rtlLineOffset);var t=0,e=Math.max(e,0),n=0,r=0,i=this.bidiMap.bidiLevels,s=this.charWidths[i[r]];this.wrapIndent&&(e-=this.isRtlDir?-1*this.wrapOffset:this.wrapOffset);while(e>n+s/2){n+=s;if(r===i.length-1){s=0;break}s=this.charWidths[i[++r]]}return r>0&&i[r-1]%2!==0&&i[r]%2===0?(e<n&&r--,t=this.bidiMap.logicalFromVisual[r]):r>0&&i[r-1]%2===0&&i[r]%2!==0?t=1+(e>n?this.bidiMap.logicalFromVisual[r]:this.bidiMap.logicalFromVisual[r-1]):this.isRtlDir&&r===i.length-1&&s===0&&i[r-1]%2===0||!this.isRtlDir&&r===0&&i[r]%2!==0?t=1+this.bidiMap.logicalFromVisual[r]:(r>0&&i[r-1]%2!==0&&s!==0&&r--,t=this.bidiMap.logicalFromVisual[r]),t===0&&this.isRtlDir&&t++,t+this.wrapIndent}}).call(o.prototype),t.BidiHandler=o}),ace.define(\"ace/selection\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/lib/event_emitter\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/lang\"),s=e(\"./lib/event_emitter\").EventEmitter,o=e(\"./range\").Range,u=function(e){this.session=e,this.doc=e.getDocument(),this.clearSelection(),this.cursor=this.lead=this.doc.createAnchor(0,0),this.anchor=this.doc.createAnchor(0,0),this.$silent=!1;var t=this;this.cursor.on(\"change\",function(e){t.$cursorChanged=!0,t.$silent||t._emit(\"changeCursor\"),!t.$isEmpty&&!t.$silent&&t._emit(\"changeSelection\"),!t.$keepDesiredColumnOnChange&&e.old.column!=e.value.column&&(t.$desiredColumn=null)}),this.anchor.on(\"change\",function(){t.$anchorChanged=!0,!t.$isEmpty&&!t.$silent&&t._emit(\"changeSelection\")})};(function(){r.implement(this,s),this.isEmpty=function(){return this.$isEmpty||this.anchor.row==this.lead.row&&this.anchor.column==this.lead.column},this.isMultiLine=function(){return!this.$isEmpty&&this.anchor.row!=this.cursor.row},this.getCursor=function(){return this.lead.getPosition()},this.setSelectionAnchor=function(e,t){this.$isEmpty=!1,this.anchor.setPosition(e,t)},this.getAnchor=this.getSelectionAnchor=function(){return this.$isEmpty?this.getSelectionLead():this.anchor.getPosition()},this.getSelectionLead=function(){return this.lead.getPosition()},this.isBackwards=function(){var e=this.anchor,t=this.lead;return e.row>t.row||e.row==t.row&&e.column>t.column},this.getRange=function(){var e=this.anchor,t=this.lead;return this.$isEmpty?o.fromPoints(t,t):this.isBackwards()?o.fromPoints(t,e):o.fromPoints(e,t)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._emit(\"changeSelection\"))},this.selectAll=function(){this.$setSelection(0,0,Number.MAX_VALUE,Number.MAX_VALUE)},this.setRange=this.setSelectionRange=function(e,t){var n=t?e.end:e.start,r=t?e.start:e.end;this.$setSelection(n.row,n.column,r.row,r.column)},this.$setSelection=function(e,t,n,r){var i=this.$isEmpty,s=this.inMultiSelectMode;this.$silent=!0,this.$cursorChanged=this.$anchorChanged=!1,this.anchor.setPosition(e,t),this.cursor.setPosition(n,r),this.$isEmpty=!o.comparePoints(this.anchor,this.cursor),this.$silent=!1,this.$cursorChanged&&this._emit(\"changeCursor\"),(this.$cursorChanged||this.$anchorChanged||i!=this.$isEmpty||s)&&this._emit(\"changeSelection\")},this.$moveSelection=function(e){var t=this.lead;this.$isEmpty&&this.setSelectionAnchor(t.row,t.column),e.call(this)},this.selectTo=function(e,t){this.$moveSelection(function(){this.moveCursorTo(e,t)})},this.selectToPosition=function(e){this.$moveSelection(function(){this.moveCursorToPosition(e)})},this.moveTo=function(e,t){this.clearSelection(),this.moveCursorTo(e,t)},this.moveToPosition=function(e){this.clearSelection(),this.moveCursorToPosition(e)},this.selectUp=function(){this.$moveSelection(this.moveCursorUp)},this.selectDown=function(){this.$moveSelection(this.moveCursorDown)},this.selectRight=function(){this.$moveSelection(this.moveCursorRight)},this.selectLeft=function(){this.$moveSelection(this.moveCursorLeft)},this.selectLineStart=function(){this.$moveSelection(this.moveCursorLineStart)},this.selectLineEnd=function(){this.$moveSelection(this.moveCursorLineEnd)},this.selectFileEnd=function(){this.$moveSelection(this.moveCursorFileEnd)},this.selectFileStart=function(){this.$moveSelection(this.moveCursorFileStart)},this.selectWordRight=function(){this.$moveSelection(this.moveCursorWordRight)},this.selectWordLeft=function(){this.$moveSelection(this.moveCursorWordLeft)},this.getWordRange=function(e,t){if(typeof t==\"undefined\"){var n=e||this.lead;e=n.row,t=n.column}return this.session.getWordRange(e,t)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var e=this.getCursor(),t=this.session.getAWordRange(e.row,e.column);this.setSelectionRange(t)},this.getLineRange=function(e,t){var n=typeof e==\"number\"?e:this.lead.row,r,i=this.session.getFoldLine(n);return i?(n=i.start.row,r=i.end.row):r=n,t===!0?new o(n,0,r,this.session.getLine(r).length):new o(n,0,r+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.wouldMoveIntoSoftTab=function(e,t,n){var r=e.column,i=e.column+t;return n<0&&(r=e.column-t,i=e.column),this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(r,i).split(\" \").length-1==t},this.moveCursorLeft=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,-1))this.moveCursorTo(t.start.row,t.start.column);else if(e.column===0)e.row>0&&this.moveCursorTo(e.row-1,this.doc.getLine(e.row-1).length);else{var n=this.session.getTabSize();this.wouldMoveIntoSoftTab(e,n,-1)&&!this.session.getNavigateWithinSoftTabs()?this.moveCursorBy(0,-n):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,1))this.moveCursorTo(t.end.row,t.end.column);else if(this.lead.column==this.doc.getLine(this.lead.row).length)this.lead.row<this.doc.getLength()-1&&this.moveCursorTo(this.lead.row+1,0);else{var n=this.session.getTabSize(),e=this.lead;this.wouldMoveIntoSoftTab(e,n,1)&&!this.session.getNavigateWithinSoftTabs()?this.moveCursorBy(0,n):this.moveCursorBy(0,1)}},this.moveCursorLineStart=function(){var e=this.lead.row,t=this.lead.column,n=this.session.documentToScreenRow(e,t),r=this.session.screenToDocumentPosition(n,0),i=this.session.getDisplayLine(e,null,r.row,r.column),s=i.match(/^\\s*/);s[0].length!=t&&!this.session.$useEmacsStyleLineStart&&(r.column+=s[0].length),this.moveCursorToPosition(r)},this.moveCursorLineEnd=function(){var e=this.lead,t=this.session.getDocumentLastRowColumnPosition(e.row,e.column);if(this.lead.column==t.column){var n=this.session.getLine(t.row);if(t.column==n.length){var r=n.search(/\\s+$/);r>0&&(t.column=r)}}this.moveCursorTo(t.row,t.column)},this.moveCursorFileEnd=function(){var e=this.doc.getLength()-1,t=this.doc.getLine(e).length;this.moveCursorTo(e,t)},this.moveCursorFileStart=function(){this.moveCursorTo(0,0)},this.moveCursorLongWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t);this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;var i=this.session.getFoldAt(e,t,1);if(i){this.moveCursorTo(i.end.row,i.end.column);return}this.session.nonTokenRe.exec(r)&&(t+=this.session.nonTokenRe.lastIndex,this.session.nonTokenRe.lastIndex=0,r=n.substring(t));if(t>=n.length){this.moveCursorTo(e,n.length),this.moveCursorRight(),e<this.doc.getLength()-1&&this.moveCursorWordRight();return}this.session.tokenRe.exec(r)&&(t+=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0),this.moveCursorTo(e,t)},this.moveCursorLongWordLeft=function(){var e=this.lead.row,t=this.lead.column,n;if(n=this.session.getFoldAt(e,t,-1)){this.moveCursorTo(n.start.row,n.start.column);return}var r=this.session.getFoldStringAt(e,t,-1);r==null&&(r=this.doc.getLine(e).substring(0,t));var s=i.stringReverse(r);this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0,this.session.nonTokenRe.exec(s)&&(t-=this.session.nonTokenRe.lastIndex,s=s.slice(this.session.nonTokenRe.lastIndex),this.session.nonTokenRe.lastIndex=0);if(t<=0){this.moveCursorTo(e,0),this.moveCursorLeft(),e>0&&this.moveCursorWordLeft();return}this.session.tokenRe.exec(s)&&(t-=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0),this.moveCursorTo(e,t)},this.$shortWordEndIndex=function(e){var t=0,n,r=/\\s/,i=this.session.tokenRe;i.lastIndex=0;if(this.session.tokenRe.exec(e))t=this.session.tokenRe.lastIndex;else{while((n=e[t])&&r.test(n))t++;if(t<1){i.lastIndex=0;while((n=e[t])&&!i.test(n)){i.lastIndex=0,t++;if(r.test(n)){if(t>2){t--;break}while((n=e[t])&&r.test(n))t++;if(t>2)break}}}}return i.lastIndex=0,t},this.moveCursorShortWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i=this.session.getFoldAt(e,t,1);if(i)return this.moveCursorTo(i.end.row,i.end.column);if(t==n.length){var s=this.doc.getLength();do e++,r=this.doc.getLine(e);while(e<s&&/^\\s*$/.test(r));/^\\s+/.test(r)||(r=\"\"),t=0}var o=this.$shortWordEndIndex(r);this.moveCursorTo(e,t+o)},this.moveCursorShortWordLeft=function(){var e=this.lead.row,t=this.lead.column,n;if(n=this.session.getFoldAt(e,t,-1))return this.moveCursorTo(n.start.row,n.start.column);var r=this.session.getLine(e).substring(0,t);if(t===0){do e--,r=this.doc.getLine(e);while(e>0&&/^\\s*$/.test(r));t=r.length,/\\s+$/.test(r)||(r=\"\")}var s=i.stringReverse(r),o=this.$shortWordEndIndex(s);return this.moveCursorTo(e,t-o)},this.moveCursorWordRight=function(){this.session.$selectLongWords?this.moveCursorLongWordRight():this.moveCursorShortWordRight()},this.moveCursorWordLeft=function(){this.session.$selectLongWords?this.moveCursorLongWordLeft():this.moveCursorShortWordLeft()},this.moveCursorBy=function(e,t){var n=this.session.documentToScreenPosition(this.lead.row,this.lead.column),r;t===0&&(e!==0&&(this.session.$bidiHandler.isBidiRow(n.row,this.lead.row)?(r=this.session.$bidiHandler.getPosLeft(n.column),n.column=Math.round(r/this.session.$bidiHandler.charWidths[0])):r=n.column*this.session.$bidiHandler.charWidths[0]),this.$desiredColumn?n.column=this.$desiredColumn:this.$desiredColumn=n.column);var i=this.session.screenToDocumentPosition(n.row+e,n.column,r);e!==0&&t===0&&i.row===this.lead.row&&i.column===this.lead.column&&this.session.lineWidgets&&this.session.lineWidgets[i.row]&&(i.row>0||e>0)&&i.row++,this.moveCursorTo(i.row,i.column+t,t===0)},this.moveCursorToPosition=function(e){this.moveCursorTo(e.row,e.column)},this.moveCursorTo=function(e,t,n){var r=this.session.getFoldAt(e,t,1);r&&(e=r.start.row,t=r.start.column),this.$keepDesiredColumnOnChange=!0;var i=this.session.getLine(e);/[\\uDC00-\\uDFFF]/.test(i.charAt(t))&&i.charAt(t-1)&&(this.lead.row==e&&this.lead.column==t+1?t-=1:t+=1),this.lead.setPosition(e,t),this.$keepDesiredColumnOnChange=!1,n||(this.$desiredColumn=null)},this.moveCursorToScreen=function(e,t,n){var r=this.session.screenToDocumentPosition(e,t);this.moveCursorTo(r.row,r.column,n)},this.detach=function(){this.lead.detach(),this.anchor.detach(),this.session=this.doc=null},this.fromOrientedRange=function(e){this.setSelectionRange(e,e.cursor==e.start),this.$desiredColumn=e.desiredColumn||this.$desiredColumn},this.toOrientedRange=function(e){var t=this.getRange();return e?(e.start.column=t.start.column,e.start.row=t.start.row,e.end.column=t.end.column,e.end.row=t.end.row):e=t,e.cursor=this.isBackwards()?e.start:e.end,e.desiredColumn=this.$desiredColumn,e},this.getRangeOfMovements=function(e){var t=this.getCursor();try{e(this);var n=this.getCursor();return o.fromPoints(t,n)}catch(r){return o.fromPoints(t,t)}finally{this.moveCursorToPosition(t)}},this.toJSON=function(){if(this.rangeCount)var e=this.ranges.map(function(e){var t=e.clone();return t.isBackwards=e.cursor==e.start,t});else{var e=this.getRange();e.isBackwards=this.isBackwards()}return e},this.fromJSON=function(e){if(e.start==undefined){if(this.rangeList&&e.length>1){this.toSingleRange(e[0]);for(var t=e.length;t--;){var n=o.fromPoints(e[t].start,e[t].end);e[t].isBackwards&&(n.cursor=n.start),this.addRange(n,!0)}return}e=e[0]}this.rangeList&&this.toSingleRange(e),this.setSelectionRange(e,e.isBackwards)},this.isEqual=function(e){if((e.length||this.rangeCount)&&e.length!=this.rangeCount)return!1;if(!e.length||!this.ranges)return this.getRange().isEqual(e);for(var t=this.ranges.length;t--;)if(!this.ranges[t].isEqual(e[t]))return!1;return!0}}).call(u.prototype),t.Selection=u}),ace.define(\"ace/tokenizer\",[\"require\",\"exports\",\"module\",\"ace/config\"],function(e,t,n){\"use strict\";var r=e(\"./config\"),i=2e3,s=function(e){this.states=e,this.regExps={},this.matchMappings={};for(var t in this.states){var n=this.states[t],r=[],i=0,s=this.matchMappings[t]={defaultToken:\"text\"},o=\"g\",u=[];for(var a=0;a<n.length;a++){var f=n[a];f.defaultToken&&(s.defaultToken=f.defaultToken),f.caseInsensitive&&(o=\"gi\");if(f.regex==null)continue;f.regex instanceof RegExp&&(f.regex=f.regex.toString().slice(1,-1));var l=f.regex,c=(new RegExp(\"(?:(\"+l+\")|(.))\")).exec(\"a\").length-2;Array.isArray(f.token)?f.token.length==1||c==1?f.token=f.token[0]:c-1!=f.token.length?(this.reportError(\"number of classes and regexp groups doesn't match\",{rule:f,groupCount:c-1}),f.token=f.token[0]):(f.tokenArray=f.token,f.token=null,f.onMatch=this.$arrayTokens):typeof f.token==\"function\"&&!f.onMatch&&(c>1?f.onMatch=this.$applyToken:f.onMatch=f.token),c>1&&(/\\\\\\d/.test(f.regex)?l=f.regex.replace(/\\\\([0-9]+)/g,function(e,t){return\"\\\\\"+(parseInt(t,10)+i+1)}):(c=1,l=this.removeCapturingGroups(f.regex)),!f.splitRegex&&typeof f.token!=\"string\"&&u.push(f)),s[i]=a,i+=c,r.push(l),f.onMatch||(f.onMatch=null)}r.length||(s[0]=0,r.push(\"$\")),u.forEach(function(e){e.splitRegex=this.createSplitterRegexp(e.regex,o)},this),this.regExps[t]=new RegExp(\"(\"+r.join(\")|(\")+\")|($)\",o)}};(function(){this.$setMaxTokenCount=function(e){i=e|0},this.$applyToken=function(e){var t=this.splitRegex.exec(e).slice(1),n=this.token.apply(this,t);if(typeof n==\"string\")return[{type:n,value:e}];var r=[];for(var i=0,s=n.length;i<s;i++)t[i]&&(r[r.length]={type:n[i],value:t[i]});return r},this.$arrayTokens=function(e){if(!e)return[];var t=this.splitRegex.exec(e);if(!t)return\"text\";var n=[],r=this.tokenArray;for(var i=0,s=r.length;i<s;i++)t[i+1]&&(n[n.length]={type:r[i],value:t[i+1]});return n},this.removeCapturingGroups=function(e){var t=e.replace(/\\\\.|\\[(?:\\\\.|[^\\\\\\]])*|\\(\\?[:=!]|(\\()/g,function(e,t){return t?\"(?:\":e});return t},this.createSplitterRegexp=function(e,t){if(e.indexOf(\"(?=\")!=-1){var n=0,r=!1,i={};e.replace(/(\\\\.)|(\\((?:\\?[=!])?)|(\\))|([\\[\\]])/g,function(e,t,s,o,u,a){return r?r=u!=\"]\":u?r=!0:o?(n==i.stack&&(i.end=a+1,i.stack=-1),n--):s&&(n++,s.length!=1&&(i.stack=n,i.start=a)),e}),i.end!=null&&/^\\)*$/.test(e.substr(i.end))&&(e=e.substring(0,i.start)+e.substr(i.end))}return e.charAt(0)!=\"^\"&&(e=\"^\"+e),e.charAt(e.length-1)!=\"$\"&&(e+=\"$\"),new RegExp(e,(t||\"\").replace(\"g\",\"\"))},this.getLineTokens=function(e,t){if(t&&typeof t!=\"string\"){var n=t.slice(0);t=n[0],t===\"#tmp\"&&(n.shift(),t=n.shift())}else var n=[];var r=t||\"start\",s=this.states[r];s||(r=\"start\",s=this.states[r]);var o=this.matchMappings[r],u=this.regExps[r];u.lastIndex=0;var a,f=[],l=0,c=0,h={type:null,value:\"\"};while(a=u.exec(e)){var p=o.defaultToken,d=null,v=a[0],m=u.lastIndex;if(m-v.length>l){var g=e.substring(l,m-v.length);h.type==p?h.value+=g:(h.type&&f.push(h),h={type:p,value:g})}for(var y=0;y<a.length-2;y++){if(a[y+1]===undefined)continue;d=s[o[y]],d.onMatch?p=d.onMatch(v,r,n,e):p=d.token,d.next&&(typeof d.next==\"string\"?r=d.next:r=d.next(r,n),s=this.states[r],s||(this.reportError(\"state doesn't exist\",r),r=\"start\",s=this.states[r]),o=this.matchMappings[r],l=m,u=this.regExps[r],u.lastIndex=m),d.consumeLineEnd&&(l=m);break}if(v)if(typeof p==\"string\")!!d&&d.merge===!1||h.type!==p?(h.type&&f.push(h),h={type:p,value:v}):h.value+=v;else if(p){h.type&&f.push(h),h={type:null,value:\"\"};for(var y=0;y<p.length;y++)f.push(p[y])}if(l==e.length)break;l=m;if(c++>i){c>2*e.length&&this.reportError(\"infinite loop with in ace tokenizer\",{startState:t,line:e});while(l<e.length)h.type&&f.push(h),h={value:e.substring(l,l+=500),type:\"overflow\"};r=\"start\",n=[];break}}return h.type&&f.push(h),n.length>1&&n[0]!==r&&n.unshift(\"#tmp\",r),{tokens:f,state:n.length?n:r}},this.reportError=r.reportError}).call(s.prototype),t.Tokenizer=s}),ace.define(\"ace/mode/text_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../lib/lang\"),i=function(){this.$rules={start:[{token:\"empty_line\",regex:\"^$\"},{defaultToken:\"text\"}]}};(function(){this.addRules=function(e,t){if(!t){for(var n in e)this.$rules[n]=e[n];return}for(var n in e){var r=e[n];for(var i=0;i<r.length;i++){var s=r[i];if(s.next||s.onMatch)typeof s.next==\"string\"&&s.next.indexOf(t)!==0&&(s.next=t+s.next),s.nextState&&s.nextState.indexOf(t)!==0&&(s.nextState=t+s.nextState)}this.$rules[t+n]=r}},this.getRules=function(){return this.$rules},this.embedRules=function(e,t,n,i,s){var o=typeof e==\"function\"?(new e).getRules():e;if(i)for(var u=0;u<i.length;u++)i[u]=t+i[u];else{i=[];for(var a in o)i.push(t+a)}this.addRules(o,t);if(n){var f=Array.prototype[s?\"push\":\"unshift\"];for(var u=0;u<i.length;u++)f.apply(this.$rules[i[u]],r.deepCopy(n))}this.$embeds||(this.$embeds=[]),this.$embeds.push(t)},this.getEmbeds=function(){return this.$embeds};var e=function(e,t){return(e!=\"start\"||t.length)&&t.unshift(this.nextState,e),this.nextState},t=function(e,t){return t.shift(),t.shift()||\"start\"};this.normalizeRules=function(){function i(s){var o=r[s];o.processed=!0;for(var u=0;u<o.length;u++){var a=o[u],f=null;Array.isArray(a)&&(f=a,a={}),!a.regex&&a.start&&(a.regex=a.start,a.next||(a.next=[]),a.next.push({defaultToken:a.token},{token:a.token+\".end\",regex:a.end||a.start,next:\"pop\"}),a.token=a.token+\".start\",a.push=!0);var l=a.next||a.push;if(l&&Array.isArray(l)){var c=a.stateName;c||(c=a.token,typeof c!=\"string\"&&(c=c[0]||\"\"),r[c]&&(c+=n++)),r[c]=l,a.next=c,i(c)}else l==\"pop\"&&(a.next=t);a.push&&(a.nextState=a.next||a.push,a.next=e,delete a.push);if(a.rules)for(var h in a.rules)r[h]?r[h].push&&r[h].push.apply(r[h],a.rules[h]):r[h]=a.rules[h];var p=typeof a==\"string\"?a:a.include;p&&(Array.isArray(p)?f=p.map(function(e){return r[e]}):f=r[p]);if(f){var d=[u,1].concat(f);a.noEscape&&(d=d.filter(function(e){return!e.next})),o.splice.apply(o,d),u--}a.keywordMap&&(a.token=this.createKeywordMapper(a.keywordMap,a.defaultToken||\"text\",a.caseInsensitive),delete a.defaultToken)}}var n=0,r=this.$rules;Object.keys(r).forEach(i,this)},this.createKeywordMapper=function(e,t,n,r){var i=Object.create(null);return Object.keys(e).forEach(function(t){var s=e[t];n&&(s=s.toLowerCase());var o=s.split(r||\"|\");for(var u=o.length;u--;)i[o[u]]=t}),Object.getPrototypeOf(i)&&(i.__proto__=null),this.$keywordList=Object.keys(i),e=null,n?function(e){return i[e.toLowerCase()]||t}:function(e){return i[e]||t}},this.getKeywords=function(){return this.$keywords}}).call(i.prototype),t.TextHighlightRules=i}),ace.define(\"ace/mode/behaviour\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=function(){this.$behaviours={}};(function(){this.add=function(e,t,n){switch(undefined){case this.$behaviours:this.$behaviours={};case this.$behaviours[e]:this.$behaviours[e]={}}this.$behaviours[e][t]=n},this.addBehaviours=function(e){for(var t in e)for(var n in e[t])this.add(t,n,e[t][n])},this.remove=function(e){this.$behaviours&&this.$behaviours[e]&&delete this.$behaviours[e]},this.inherit=function(e,t){if(typeof e==\"function\")var n=(new e).getBehaviours(t);else var n=e.getBehaviours(t);this.addBehaviours(n)},this.getBehaviours=function(e){if(!e)return this.$behaviours;var t={};for(var n=0;n<e.length;n++)this.$behaviours[e[n]]&&(t[e[n]]=this.$behaviours[e[n]]);return t}}).call(r.prototype),t.Behaviour=r}),ace.define(\"ace/token_iterator\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"./range\").Range,i=function(e,t,n){this.$session=e,this.$row=t,this.$rowTokens=e.getTokens(t);var r=e.getTokenAt(t,n);this.$tokenIndex=r?r.index:-1};(function(){this.stepBackward=function(){this.$tokenIndex-=1;while(this.$tokenIndex<0){this.$row-=1;if(this.$row<0)return this.$row=0,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=this.$rowTokens.length-1}return this.$rowTokens[this.$tokenIndex]},this.stepForward=function(){this.$tokenIndex+=1;var e;while(this.$tokenIndex>=this.$rowTokens.length){this.$row+=1,e||(e=this.$session.getLength());if(this.$row>=e)return this.$row=e-1,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=0}return this.$rowTokens[this.$tokenIndex]},this.getCurrentToken=function(){return this.$rowTokens[this.$tokenIndex]},this.getCurrentTokenRow=function(){return this.$row},this.getCurrentTokenColumn=function(){var e=this.$rowTokens,t=this.$tokenIndex,n=e[t].start;if(n!==undefined)return n;n=0;while(t>0)t-=1,n+=e[t].value.length;return n},this.getCurrentTokenPosition=function(){return{row:this.$row,column:this.getCurrentTokenColumn()}},this.getCurrentTokenRange=function(){var e=this.$rowTokens[this.$tokenIndex],t=this.getCurrentTokenColumn();return new r(this.$row,t,this.$row,t+e.value.length)}}).call(i.prototype),t.TokenIterator=i}),ace.define(\"ace/mode/behaviour/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/behaviour\",\"ace/token_iterator\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"../behaviour\").Behaviour,s=e(\"../../token_iterator\").TokenIterator,o=e(\"../../lib/lang\"),u=[\"text\",\"paren.rparen\",\"rparen\",\"paren\",\"punctuation.operator\"],a=[\"text\",\"paren.rparen\",\"rparen\",\"paren\",\"punctuation.operator\",\"comment\"],f,l={},c={'\"':'\"',\"'\":\"'\"},h=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:\"\",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:\"\",maybeInsertedLineEnd:\"\"}},p=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},d=function(e){this.add(\"braces\",\"insertion\",function(t,n,r,i,s){var u=r.getCursorPosition(),a=i.doc.getLine(u.row);if(s==\"{\"){h(r);var l=r.getSelectionRange(),c=i.doc.getTextRange(l);if(c!==\"\"&&c!==\"{\"&&r.getWrapBehavioursEnabled())return p(l,c,\"{\",\"}\");if(d.isSaneInsertion(r,i))return/[\\]\\}\\)]/.test(a[u.column])||r.inMultiSelectMode||e&&e.braces?(d.recordAutoInsert(r,i,\"}\"),{text:\"{}\",selection:[1,1]}):(d.recordMaybeInsert(r,i,\"{\"),{text:\"{\",selection:[1,1]})}else if(s==\"}\"){h(r);var v=a.substring(u.column,u.column+1);if(v==\"}\"){var m=i.$findOpeningBracket(\"}\",{column:u.column+1,row:u.row});if(m!==null&&d.isAutoInsertedClosing(u,a,s))return d.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}else{if(s==\"\\n\"||s==\"\\r\\n\"){h(r);var g=\"\";d.isMaybeInsertedClosing(u,a)&&(g=o.stringRepeat(\"}\",f.maybeInsertedBrackets),d.clearMaybeInsertedClosing());var v=a.substring(u.column,u.column+1);if(v===\"}\"){var y=i.findMatchingBracket({row:u.row,column:u.column+1},\"}\");if(!y)return null;var b=this.$getIndent(i.getLine(y.row))}else{if(!g){d.clearMaybeInsertedClosing();return}var b=this.$getIndent(a)}var w=b+i.getTabString();return{text:\"\\n\"+w+\"\\n\"+b+g,selection:[1,w.length,1,w.length]}}d.clearMaybeInsertedClosing()}}),this.add(\"braces\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"{\"){h(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u==\"}\")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add(\"parens\",\"insertion\",function(e,t,n,r,i){if(i==\"(\"){h(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return p(s,o,\"(\",\")\");if(d.isSaneInsertion(n,r))return d.recordAutoInsert(n,r,\")\"),{text:\"()\",selection:[1,1]}}else if(i==\")\"){h(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\")\"){var l=r.$findOpeningBracket(\")\",{column:u.column+1,row:u.row});if(l!==null&&d.isAutoInsertedClosing(u,a,i))return d.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"parens\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"(\"){h(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\")\")return i.end.column++,i}}),this.add(\"brackets\",\"insertion\",function(e,t,n,r,i){if(i==\"[\"){h(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return p(s,o,\"[\",\"]\");if(d.isSaneInsertion(n,r))return d.recordAutoInsert(n,r,\"]\"),{text:\"[]\",selection:[1,1]}}else if(i==\"]\"){h(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\"]\"){var l=r.$findOpeningBracket(\"]\",{column:u.column+1,row:u.row});if(l!==null&&d.isAutoInsertedClosing(u,a,i))return d.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"brackets\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"[\"){h(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\"]\")return i.end.column++,i}}),this.add(\"string_dquotes\",\"insertion\",function(e,t,n,r,i){var s=r.$mode.$quotes||c;if(i.length==1&&s[i]){if(this.lineCommentStart&&this.lineCommentStart.indexOf(i)!=-1)return;h(n);var o=i,u=n.getSelectionRange(),a=r.doc.getTextRange(u);if(a!==\"\"&&(a.length!=1||!s[a])&&n.getWrapBehavioursEnabled())return p(u,a,o,o);if(!a){var f=n.getCursorPosition(),l=r.doc.getLine(f.row),d=l.substring(f.column-1,f.column),v=l.substring(f.column,f.column+1),m=r.getTokenAt(f.row,f.column),g=r.getTokenAt(f.row,f.column+1);if(d==\"\\\\\"&&m&&/escape/.test(m.type))return null;var y=m&&/string|escape/.test(m.type),b=!g||/string|escape/.test(g.type),w;if(v==o)w=y!==b,w&&/string\\.end/.test(g.type)&&(w=!1);else{if(y&&!b)return null;if(y&&b)return null;var E=r.$mode.tokenRe;E.lastIndex=0;var S=E.test(d);E.lastIndex=0;var x=E.test(d);if(S||x)return null;if(v&&!/[\\s;,.})\\]\\\\]/.test(v))return null;var T=l[f.column-2];if(!(d!=o||T!=o&&!E.test(T)))return null;w=!0}return{text:w?o+o:\"\",selection:[1,1]}}}}),this.add(\"string_dquotes\",\"deletion\",function(e,t,n,r,i){var s=r.$mode.$quotes||c,o=r.doc.getTextRange(i);if(!i.isMultiLine()&&s.hasOwnProperty(o)){h(n);var u=r.doc.getLine(i.start.row),a=u.substring(i.start.column+1,i.start.column+2);if(a==o)return i.end.column++,i}})};d.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||\"text\",u)){if(/[)}\\]]/.test(e.session.getLine(n.row)[n.column]))return!0;var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||\"text\",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||\"text\",a)},d.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},d.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},d.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},d.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},d.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},d.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},d.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(d,i),t.CstyleBehaviour=d}),ace.define(\"ace/unicode\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=[48,9,8,25,5,0,2,25,48,0,11,0,5,0,6,22,2,30,2,457,5,11,15,4,8,0,2,0,18,116,2,1,3,3,9,0,2,2,2,0,2,19,2,82,2,138,2,4,3,155,12,37,3,0,8,38,10,44,2,0,2,1,2,1,2,0,9,26,6,2,30,10,7,61,2,9,5,101,2,7,3,9,2,18,3,0,17,58,3,100,15,53,5,0,6,45,211,57,3,18,2,5,3,11,3,9,2,1,7,6,2,2,2,7,3,1,3,21,2,6,2,0,4,3,3,8,3,1,3,3,9,0,5,1,2,4,3,11,16,2,2,5,5,1,3,21,2,6,2,1,2,1,2,1,3,0,2,4,5,1,3,2,4,0,8,3,2,0,8,15,12,2,2,8,2,2,2,21,2,6,2,1,2,4,3,9,2,2,2,2,3,0,16,3,3,9,18,2,2,7,3,1,3,21,2,6,2,1,2,4,3,8,3,1,3,2,9,1,5,1,2,4,3,9,2,0,17,1,2,5,4,2,2,3,4,1,2,0,2,1,4,1,4,2,4,11,5,4,4,2,2,3,3,0,7,0,15,9,18,2,2,7,2,2,2,22,2,9,2,4,4,7,2,2,2,3,8,1,2,1,7,3,3,9,19,1,2,7,2,2,2,22,2,9,2,4,3,8,2,2,2,3,8,1,8,0,2,3,3,9,19,1,2,7,2,2,2,22,2,15,4,7,2,2,2,3,10,0,9,3,3,9,11,5,3,1,2,17,4,23,2,8,2,0,3,6,4,0,5,5,2,0,2,7,19,1,14,57,6,14,2,9,40,1,2,0,3,1,2,0,3,0,7,3,2,6,2,2,2,0,2,0,3,1,2,12,2,2,3,4,2,0,2,5,3,9,3,1,35,0,24,1,7,9,12,0,2,0,2,0,5,9,2,35,5,19,2,5,5,7,2,35,10,0,58,73,7,77,3,37,11,42,2,0,4,328,2,3,3,6,2,0,2,3,3,40,2,3,3,32,2,3,3,6,2,0,2,3,3,14,2,56,2,3,3,66,5,0,33,15,17,84,13,619,3,16,2,25,6,74,22,12,2,6,12,20,12,19,13,12,2,2,2,1,13,51,3,29,4,0,5,1,3,9,34,2,3,9,7,87,9,42,6,69,11,28,4,11,5,11,11,39,3,4,12,43,5,25,7,10,38,27,5,62,2,28,3,10,7,9,14,0,89,75,5,9,18,8,13,42,4,11,71,55,9,9,4,48,83,2,2,30,14,230,23,280,3,5,3,37,3,5,3,7,2,0,2,0,2,0,2,30,3,52,2,6,2,0,4,2,2,6,4,3,3,5,5,12,6,2,2,6,67,1,20,0,29,0,14,0,17,4,60,12,5,0,4,11,18,0,5,0,3,9,2,0,4,4,7,0,2,0,2,0,2,3,2,10,3,3,6,4,5,0,53,1,2684,46,2,46,2,132,7,6,15,37,11,53,10,0,17,22,10,6,2,6,2,6,2,6,2,6,2,6,2,6,2,6,2,31,48,0,470,1,36,5,2,4,6,1,5,85,3,1,3,2,2,89,2,3,6,40,4,93,18,23,57,15,513,6581,75,20939,53,1164,68,45,3,268,4,27,21,31,3,13,13,1,2,24,9,69,11,1,38,8,3,102,3,1,111,44,25,51,13,68,12,9,7,23,4,0,5,45,3,35,13,28,4,64,15,10,39,54,10,13,3,9,7,22,4,1,5,66,25,2,227,42,2,1,3,9,7,11171,13,22,5,48,8453,301,3,61,3,105,39,6,13,4,6,11,2,12,2,4,2,0,2,1,2,1,2,107,34,362,19,63,3,53,41,11,5,15,17,6,13,1,25,2,33,4,2,134,20,9,8,25,5,0,2,25,12,88,4,5,3,5,3,5,3,2],i=0,s=[];for(var o=0;o<r.length;o+=2)s.push(i+=r[o]),r[o+1]&&s.push(45,i+=r[o+1]);t.wordChars=String.fromCharCode.apply(null,s)}),ace.define(\"ace/mode/text\",[\"require\",\"exports\",\"module\",\"ace/config\",\"ace/tokenizer\",\"ace/mode/text_highlight_rules\",\"ace/mode/behaviour/cstyle\",\"ace/unicode\",\"ace/lib/lang\",\"ace/token_iterator\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../config\"),i=e(\"../tokenizer\").Tokenizer,s=e(\"./text_highlight_rules\").TextHighlightRules,o=e(\"./behaviour/cstyle\").CstyleBehaviour,u=e(\"../unicode\"),a=e(\"../lib/lang\"),f=e(\"../token_iterator\").TokenIterator,l=e(\"../range\").Range,c=function(){this.HighlightRules=s};(function(){this.$defaultBehaviour=new o,this.tokenRe=new RegExp(\"^[\"+u.wordChars+\"\\\\$_]+\",\"g\"),this.nonTokenRe=new RegExp(\"^(?:[^\"+u.wordChars+\"\\\\$_]|\\\\s])+\",\"g\"),this.getTokenizer=function(){return this.$tokenizer||(this.$highlightRules=this.$highlightRules||new this.HighlightRules(this.$highlightRuleConfig),this.$tokenizer=new i(this.$highlightRules.getRules())),this.$tokenizer},this.lineCommentStart=\"\",this.blockComment=\"\",this.toggleCommentLines=function(e,t,n,r){function w(e){for(var t=n;t<=r;t++)e(i.getLine(t),t)}var i=t.doc,s=!0,o=!0,u=Infinity,f=t.getTabSize(),l=!1;if(!this.lineCommentStart){if(!this.blockComment)return!1;var c=this.blockComment.start,h=this.blockComment.end,p=new RegExp(\"^(\\\\s*)(?:\"+a.escapeRegExp(c)+\")\"),d=new RegExp(\"(?:\"+a.escapeRegExp(h)+\")\\\\s*$\"),v=function(e,t){if(g(e,t))return;if(!s||/\\S/.test(e))i.insertInLine({row:t,column:e.length},h),i.insertInLine({row:t,column:u},c)},m=function(e,t){var n;(n=e.match(d))&&i.removeInLine(t,e.length-n[0].length,e.length),(n=e.match(p))&&i.removeInLine(t,n[1].length,n[0].length)},g=function(e,n){if(p.test(e))return!0;var r=t.getTokens(n);for(var i=0;i<r.length;i++)if(r[i].type===\"comment\")return!0}}else{if(Array.isArray(this.lineCommentStart))var p=this.lineCommentStart.map(a.escapeRegExp).join(\"|\"),c=this.lineCommentStart[0];else var p=a.escapeRegExp(this.lineCommentStart),c=this.lineCommentStart;p=new RegExp(\"^(\\\\s*)(?:\"+p+\") ?\"),l=t.getUseSoftTabs();var m=function(e,t){var n=e.match(p);if(!n)return;var r=n[1].length,s=n[0].length;!b(e,r,s)&&n[0][s-1]==\" \"&&s--,i.removeInLine(t,r,s)},y=c+\" \",v=function(e,t){if(!s||/\\S/.test(e))b(e,u,u)?i.insertInLine({row:t,column:u},y):i.insertInLine({row:t,column:u},c)},g=function(e,t){return p.test(e)},b=function(e,t,n){var r=0;while(t--&&e.charAt(t)==\" \")r++;if(r%f!=0)return!1;var r=0;while(e.charAt(n++)==\" \")r++;return f>2?r%f!=f-1:r%f==0}}var E=Infinity;w(function(e,t){var n=e.search(/\\S/);n!==-1?(n<u&&(u=n),o&&!g(e,t)&&(o=!1)):E>e.length&&(E=e.length)}),u==Infinity&&(u=E,s=!1,o=!1),l&&u%f!=0&&(u=Math.floor(u/f)*f),w(o?m:v)},this.toggleBlockComment=function(e,t,n,r){var i=this.blockComment;if(!i)return;!i.start&&i[0]&&(i=i[0]);var s=new f(t,r.row,r.column),o=s.getCurrentToken(),u=t.selection,a=t.selection.toOrientedRange(),c,h;if(o&&/comment/.test(o.type)){var p,d;while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.start);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;p=new l(m,g,m,g+i.start.length);break}o=s.stepBackward()}var s=new f(t,r.row,r.column),o=s.getCurrentToken();while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.end);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;d=new l(m,g,m,g+i.end.length);break}o=s.stepForward()}d&&t.remove(d),p&&(t.remove(p),c=p.start.row,h=-i.start.length)}else h=i.start.length,c=n.start.row,t.insert(n.end,i.end),t.insert(n.start,i.start);a.start.row==c&&(a.start.column+=h),a.end.row==c&&(a.end.column+=h),t.selection.fromOrientedRange(a)},this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.autoOutdent=function(e,t,n){},this.$getIndent=function(e){return e.match(/^\\s*/)[0]},this.createWorker=function(e){return null},this.createModeDelegates=function(e){this.$embeds=[],this.$modes={};for(var t in e)if(e[t]){var n=e[t],i=n.prototype.$id,s=r.$modes[i];s||(r.$modes[i]=s=new n),r.$modes[t]||(r.$modes[t]=s),this.$embeds.push(t),this.$modes[t]=s}var o=[\"toggleBlockComment\",\"toggleCommentLines\",\"getNextLineIndent\",\"checkOutdent\",\"autoOutdent\",\"transformAction\",\"getCompletions\"];for(var t=0;t<o.length;t++)(function(e){var n=o[t],r=e[n];e[o[t]]=function(){return this.$delegator(n,arguments,r)}})(this)},this.$delegator=function(e,t,n){var r=t[0]||\"start\";if(typeof r!=\"string\"){if(Array.isArray(r[2])){var i=r[2][r[2].length-1],s=this.$modes[i];if(s)return s[e].apply(s,[r[1]].concat([].slice.call(t,1)))}r=r[0]||\"start\"}for(var o=0;o<this.$embeds.length;o++){if(!this.$modes[this.$embeds[o]])continue;var u=r.split(this.$embeds[o]);if(!u[0]&&u[1]){t[0]=u[1];var s=this.$modes[this.$embeds[o]];return s[e].apply(s,t)}}var a=n.apply(this,t);return n?a:undefined},this.transformAction=function(e,t,n,r,i){if(this.$behaviour){var s=this.$behaviour.getBehaviours();for(var o in s)if(s[o][t]){var u=s[o][t].apply(this,arguments);if(u)return u}}},this.getKeywords=function(e){if(!this.completionKeywords){var t=this.$tokenizer.rules,n=[];for(var r in t){var i=t[r];for(var s=0,o=i.length;s<o;s++)if(typeof i[s].token==\"string\")/keyword|support|storage/.test(i[s].token)&&n.push(i[s].regex);else if(typeof i[s].token==\"object\")for(var u=0,a=i[s].token.length;u<a;u++)if(/keyword|support|storage/.test(i[s].token[u])){var r=i[s].regex.match(/\\(.+?\\)/g)[u];n.push(r.substr(1,r.length-2))}}this.completionKeywords=n}return e?n.concat(this.$keywordList||[]):this.$keywordList},this.$createKeywordList=function(){return this.$highlightRules||this.getTokenizer(),this.$keywordList=this.$highlightRules.$keywordList||[]},this.getCompletions=function(e,t,n,r){var i=this.$keywordList||this.$createKeywordList();return i.map(function(e){return{name:e,value:e,score:0,meta:\"keyword\"}})},this.$id=\"ace/mode/text\"}).call(c.prototype),t.Mode=c}),ace.define(\"ace/apply_delta\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";function r(e,t){throw console.log(\"Invalid Delta:\",e),\"Invalid Delta: \"+t}function i(e,t){return t.row>=0&&t.row<e.length&&t.column>=0&&t.column<=e[t.row].length}function s(e,t){t.action!=\"insert\"&&t.action!=\"remove\"&&r(t,\"delta.action must be 'insert' or 'remove'\"),t.lines instanceof Array||r(t,\"delta.lines must be an Array\"),(!t.start||!t.end)&&r(t,\"delta.start/end must be an present\");var n=t.start;i(e,t.start)||r(t,\"delta.start must be contained in document\");var s=t.end;t.action==\"remove\"&&!i(e,s)&&r(t,\"delta.end must contained in document for 'remove' actions\");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,\"delta.range must match delta lines\")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||\"\";switch(t.action){case\"insert\":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case\"remove\":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),ace.define(\"ace/anchor\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/event_emitter\").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n==\"undefined\"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.column<t.column;return e.row<t.row||e.row==t.row&&r}function t(t,n,r){var i=t.action==\"insert\",s=(i?1:-1)*(t.end.row-t.start.row),o=(i?1:-1)*(t.end.column-t.start.column),u=t.start,a=i?u:t.end;return e(n,u,r)?{row:n.row,column:n.column}:e(a,n,!r)?{row:n.row+s,column:n.column+(n.row==a.row?o:0)}:{row:u.row,column:u.column}}r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){if(e.start.row==e.end.row&&e.start.row!=this.row)return;if(e.start.row>this.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal(\"change\",{old:i,value:r})},this.detach=function(){this.document.removeEventListener(\"change\",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on(\"change\",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define(\"ace/document\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/apply_delta\",\"ace/lib/event_emitter\",\"ace/range\",\"ace/anchor\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./apply_delta\").applyDelta,s=e(\"./lib/event_emitter\").EventEmitter,o=e(\"./range\").Range,u=e(\"./anchor\").Anchor,a=function(e){this.$lines=[\"\"],e.length===0?this.$lines=[\"\"]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},\"aaa\".split(/a/).length===0?this.$split=function(e){return e.replace(/\\r\\n|\\r/g,\"\\n\").split(\"\\n\")}:this.$split=function(e){return e.split(/\\r\\n|\\r|\\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\\r\\n|\\r|\\n)/m);this.$autoNewLine=t?t[1]:\"\\n\",this._signal(\"changeNewLineMode\")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case\"windows\":return\"\\r\\n\";case\"unix\":return\"\\n\";default:return this.$autoNewLine||\"\\n\"}},this.$autoNewLine=\"\",this.$newLineMode=\"auto\",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal(\"changeNewLineMode\")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e==\"\\r\\n\"||e==\"\\r\"||e==\"\\n\"},this.getLine=function(e){return this.$lines[e]||\"\"},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||\"\").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn(\"Use of document.insertLines is deprecated. Use the insertFullLines method instead.\"),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn(\"Use of document.removeLines is deprecated. Use the removeFullLines method instead.\"),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn(\"Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead.\"),this.insertMergedLines(e,[\"\",\"\"])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:\"insert\",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e<this.getLength()?(t=t.concat([\"\"]),n=0):(t=[\"\"].concat(t),e--,n=this.$lines[e].length),this.insertMergedLines({row:e,column:n},t)},this.insertMergedLines=function(e,t){var n=this.clippedPos(e.row,e.column),r={row:n.row+t.length-1,column:(t.length==1?n.column:0)+t[t.length-1].length};return this.applyDelta({start:n,end:r,action:\"insert\",lines:t}),this.clonePos(r)},this.remove=function(e){var t=this.clippedPos(e.start.row,e.start.column),n=this.clippedPos(e.end.row,e.end.column);return this.applyDelta({start:t,end:n,action:\"remove\",lines:this.getLinesForRange({start:t,end:n})}),this.clonePos(t)},this.removeInLine=function(e,t,n){var r=this.clippedPos(e,t),i=this.clippedPos(e,n);return this.applyDelta({start:r,end:i,action:\"remove\",lines:this.getLinesForRange({start:r,end:i})},!0),this.clonePos(r)},this.removeFullLines=function(e,t){e=Math.min(Math.max(0,e),this.getLength()-1),t=Math.min(Math.max(0,t),this.getLength()-1);var n=t==this.getLength()-1&&e>0,r=t<this.getLength()-1,i=n?e-1:e,s=n?this.getLine(i).length:0,u=r?t+1:t,a=r?0:this.getLine(u).length,f=new o(i,s,u,a),l=this.$lines.slice(e,t+1);return this.applyDelta({start:f.start,end:f.end,action:\"remove\",lines:this.getLinesForRange(f)}),l},this.removeNewLine=function(e){e<this.getLength()-1&&e>=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:\"remove\",lines:[\"\",\"\"]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++)this.applyDelta(e[t])},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action==\"insert\";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(i(this.$lines,e,t),this._signal(\"change\",e))},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length-t+1,i=e.start.row,s=e.start.column;for(var o=0,u=0;o<r;o=u){u+=t-1;var a=n.slice(o,u);a.push(\"\"),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}e.lines=n.slice(o),e.start.row=i+o,e.start.column=s,this.applyDelta(e,!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action==\"insert\"?\"remove\":\"insert\",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:e+n[s-1].length+r}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(a.prototype),t.Document=a}),ace.define(\"ace/background_tokenizer\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/event_emitter\").EventEmitter,s=function(e,t){this.running=!1,this.lines=[],this.states=[],this.currentLine=0,this.tokenizer=e;var n=this;this.$worker=function(){if(!n.running)return;var e=new Date,t=n.currentLine,r=-1,i=n.doc,s=t;while(n.lines[t])t++;var o=i.getLength(),u=0;n.running=!1;while(t<o){n.$tokenizeRow(t),r=t;do t++;while(n.lines[t]);u++;if(u%5===0&&new Date-e>20){n.running=setTimeout(n.$worker,20);break}}n.currentLine=t,r==-1&&(r=t),s<=r&&n.fireUpdateEvent(s,r)}};(function(){r.implement(this,i),this.setTokenizer=function(e){this.tokenizer=e,this.lines=[],this.states=[],this.start(0)},this.setDocument=function(e){this.doc=e,this.lines=[],this.states=[],this.stop()},this.fireUpdateEvent=function(e,t){var n={first:e,last:t};this._signal(\"update\",{data:n})},this.start=function(e){this.currentLine=Math.min(e||0,this.currentLine,this.doc.getLength()),this.lines.splice(this.currentLine,this.lines.length),this.states.splice(this.currentLine,this.states.length),this.stop(),this.running=setTimeout(this.$worker,700)},this.scheduleStart=function(){this.running||(this.running=setTimeout(this.$worker,700))},this.$updateOnChange=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.lines[t]=null;else if(e.action==\"remove\")this.lines.splice(t,n+1,null),this.states.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.lines.splice.apply(this.lines,r),this.states.splice.apply(this.states,r)}this.currentLine=Math.min(t,this.currentLine,this.doc.getLength()),this.stop()},this.stop=function(){this.running&&clearTimeout(this.running),this.running=!1},this.getTokens=function(e){return this.lines[e]||this.$tokenizeRow(e)},this.getState=function(e){return this.currentLine==e&&this.$tokenizeRow(e),this.states[e]||\"start\"},this.$tokenizeRow=function(e){var t=this.doc.getLine(e),n=this.states[e-1],r=this.tokenizer.getLineTokens(t,n,e);return this.states[e]+\"\"!=r.state+\"\"?(this.states[e]=r.state,this.lines[e+1]=null,this.currentLine>e+1&&(this.currentLine=e+1)):this.currentLine==e&&(this.currentLine=e+1),this.lines[e]=r.tokens}}).call(s.prototype),t.BackgroundTokenizer=s}),ace.define(\"ace/search_highlight\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/lib/oop\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"./lib/lang\"),i=e(\"./lib/oop\"),s=e(\"./range\").Range,o=function(e,t,n){this.setRegexp(e),this.clazz=t,this.type=n||\"text\"};(function(){this.MAX_RANGES=500,this.setRegexp=function(e){if(this.regExp+\"\"==e+\"\")return;this.regExp=e,this.cache=[]},this.update=function(e,t,n,i){if(!this.regExp)return;var o=i.firstRow,u=i.lastRow;for(var a=o;a<=u;a++){var f=this.cache[a];f==null&&(f=r.getMatchOffsets(n.getLine(a),this.regExp),f.length>this.MAX_RANGES&&(f=f.slice(0,this.MAX_RANGES)),f=f.map(function(e){return new s(a,e.offset,a,e.offset+e.length)}),this.cache[a]=f.length?f:\"\");for(var l=f.length;l--;)t.drawSingleLineMarker(e,f[l].toScreenRange(n),this.clazz,i)}}}).call(o.prototype),t.SearchHighlight=o}),ace.define(\"ace/edit_session/fold_line\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";function i(e,t){this.foldData=e,Array.isArray(t)?this.folds=t:t=this.folds=[t];var n=t[t.length-1];this.range=new r(t[0].start.row,t[0].start.column,n.end.row,n.end.column),this.start=this.range.start,this.end=this.range.end,this.folds.forEach(function(e){e.setFoldLine(this)},this)}var r=e(\"../range\").Range;(function(){this.shiftRow=function(e){this.start.row+=e,this.end.row+=e,this.folds.forEach(function(t){t.start.row+=e,t.end.row+=e})},this.addFold=function(e){if(e.sameRow){if(e.start.row<this.startRow||e.endRow>this.endRow)throw new Error(\"Can't add a fold to this FoldLine as it has no connection\");this.folds.push(e),this.folds.sort(function(e,t){return-e.range.compareEnd(t.start.row,t.start.column)}),this.range.compareEnd(e.start.row,e.start.column)>0?(this.end.row=e.end.row,this.end.column=e.end.column):this.range.compareStart(e.end.row,e.end.column)<0&&(this.start.row=e.start.row,this.start.column=e.start.column)}else if(e.start.row==this.end.row)this.folds.push(e),this.end.row=e.end.row,this.end.column=e.end.column;else{if(e.end.row!=this.start.row)throw new Error(\"Trying to add fold to FoldRow that doesn't have a matching row\");this.folds.unshift(e),this.start.row=e.start.row,this.start.column=e.start.column}e.foldLine=this},this.containsRow=function(e){return e>=this.start.row&&e<=this.end.row},this.walk=function(e,t,n){var r=0,i=this.folds,s,o,u,a=!0;t==null&&(t=this.end.row,n=this.end.column);for(var f=0;f<i.length;f++){s=i[f],o=s.range.compareStart(t,n);if(o==-1){e(null,t,n,r,a);return}u=e(null,s.start.row,s.start.column,r,a),u=!u&&e(s.placeholder,s.start.row,s.start.column,r);if(u||o===0)return;a=!s.sameRow,r=s.end.column}e(null,t,n,r,a)},this.getNextFoldTo=function(e,t){var n,r;for(var i=0;i<this.folds.length;i++){n=this.folds[i],r=n.range.compareEnd(e,t);if(r==-1)return{fold:n,kind:\"after\"};if(r===0)return{fold:n,kind:\"inside\"}}return null},this.addRemoveChars=function(e,t,n){var r=this.getNextFoldTo(e,t),i,s;if(r){i=r.fold;if(r.kind==\"inside\"&&i.start.column!=t&&i.start.row!=e)window.console&&window.console.log(e,t,i);else if(i.start.row==e){s=this.folds;var o=s.indexOf(i);o===0&&(this.start.column+=n);for(o;o<s.length;o++){i=s[o],i.start.column+=n;if(!i.sameRow)return;i.end.column+=n}this.end.column+=n}}},this.split=function(e,t){var n=this.getNextFoldTo(e,t);if(!n||n.kind==\"inside\")return null;var r=n.fold,s=this.folds,o=this.foldData,u=s.indexOf(r),a=s[u-1];this.end.row=a.end.row,this.end.column=a.end.column,s=s.splice(u,s.length-u);var f=new i(o,s);return o.splice(o.indexOf(this)+1,0,f),f},this.merge=function(e){var t=e.folds;for(var n=0;n<t.length;n++)this.addFold(t[n]);var r=this.foldData;r.splice(r.indexOf(e),1)},this.toString=function(){var e=[this.range.toString()+\": [\"];return this.folds.forEach(function(t){e.push(\"  \"+t.toString())}),e.push(\"]\"),e.join(\"\\n\")},this.idxToPosition=function(e){var t=0;for(var n=0;n<this.folds.length;n++){var r=this.folds[n];e-=r.start.column-t;if(e<0)return{row:r.start.row,column:r.start.column+e};e-=r.placeholder.length;if(e<0)return r.start;t=r.end.column}return{row:this.end.row,column:this.end.column+e}}}).call(i.prototype),t.FoldLine=i}),ace.define(\"ace/range_list\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"./range\").Range,i=r.comparePoints,s=function(){this.ranges=[],this.$bias=1};(function(){this.comparePoints=i,this.pointIndex=function(e,t,n){var r=this.ranges;for(var s=n||0;s<r.length;s++){var o=r[s],u=i(e,o.end);if(u>0)continue;var a=i(e,o.start);return u===0?t&&a!==0?-s-2:s:a>0||a===0&&!t?s:-s-1}return-s-1},this.add=function(e){var t=!e.isEmpty(),n=this.pointIndex(e.start,t);n<0&&(n=-n-1);var r=this.pointIndex(e.end,t,n);return r<0?r=-r-1:r++,this.ranges.splice(n,r-n,e)},this.addList=function(e){var t=[];for(var n=e.length;n--;)t.push.apply(t,this.add(e[n]));return t},this.substractPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges.splice(t,1)},this.merge=function(){var e=[],t=this.ranges;t=t.sort(function(e,t){return i(e.start,t.start)});var n=t[0],r;for(var s=1;s<t.length;s++){r=n,n=t[s];var o=i(r.end,n.start);if(o<0)continue;if(o==0&&!r.isEmpty()&&!n.isEmpty())continue;i(r.end,n.end)<0&&(r.end.row=n.end.row,r.end.column=n.end.column),t.splice(s,1),e.push(n),n=r,s--}return this.ranges=t,e},this.contains=function(e,t){return this.pointIndex({row:e,column:t})>=0},this.containsPoint=function(e){return this.pointIndex(e)>=0},this.rangeAtPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges[t]},this.clipRows=function(e,t){var n=this.ranges;if(n[0].start.row>t||n[n.length-1].start.row<e)return[];var r=this.pointIndex({row:e,column:0});r<0&&(r=-r-1);var i=this.pointIndex({row:t,column:0},r);i<0&&(i=-i-1);var s=[];for(var o=r;o<i;o++)s.push(n[o]);return s},this.removeAll=function(){return this.ranges.splice(0,this.ranges.length)},this.attach=function(e){this.session&&this.detach(),this.session=e,this.onChange=this.$onChange.bind(this),this.session.on(\"change\",this.onChange)},this.detach=function(){if(!this.session)return;this.session.removeListener(\"change\",this.onChange),this.session=null},this.$onChange=function(e){var t=e.start,n=e.end,r=t.row,i=n.row,s=this.ranges;for(var o=0,u=s.length;o<u;o++){var a=s[o];if(a.end.row>=r)break}if(e.action==\"insert\"){var f=i-r,l=-t.column+n.column;for(;o<u;o++){var a=s[o];if(a.start.row>r)break;a.start.row==r&&a.start.column>=t.column&&(a.start.column==t.column&&this.$bias<=0||(a.start.column+=l,a.start.row+=f));if(a.end.row==r&&a.end.column>=t.column){if(a.end.column==t.column&&this.$bias<0)continue;a.end.column==t.column&&l>0&&o<u-1&&a.end.column>a.start.column&&a.end.column==s[o+1].start.column&&(a.end.column-=l),a.end.column+=l,a.end.row+=f}}}else{var f=r-i,l=t.column-n.column;for(;o<u;o++){var a=s[o];if(a.start.row>i)break;if(a.end.row<i&&(r<a.end.row||r==a.end.row&&t.column<a.end.column))a.end.row=r,a.end.column=t.column;else if(a.end.row==i)if(a.end.column<=n.column){if(f||a.end.column>t.column)a.end.column=t.column,a.end.row=t.row}else a.end.column+=l,a.end.row+=f;else a.end.row>i&&(a.end.row+=f);if(a.start.row<i&&(r<a.start.row||r==a.start.row&&t.column<a.start.column))a.start.row=r,a.start.column=t.column;else if(a.start.row==i)if(a.start.column<=n.column){if(f||a.start.column>t.column)a.start.column=t.column,a.start.row=t.row}else a.start.column+=l,a.start.row+=f;else a.start.row>i&&(a.start.row+=f)}}if(f!=0&&o<u)for(;o<u;o++){var a=s[o];a.start.row+=f,a.end.row+=f}}}).call(s.prototype),t.RangeList=s}),ace.define(\"ace/edit_session/fold\",[\"require\",\"exports\",\"module\",\"ace/range_list\",\"ace/lib/oop\"],function(e,t,n){\"use strict\";function o(e,t){e.row-=t.row,e.row==0&&(e.column-=t.column)}function u(e,t){o(e.start,t),o(e.end,t)}function a(e,t){e.row==0&&(e.column+=t.column),e.row+=t.row}function f(e,t){a(e.start,t),a(e.end,t)}var r=e(\"../range_list\").RangeList,i=e(\"../lib/oop\"),s=t.Fold=function(e,t){this.foldLine=null,this.placeholder=t,this.range=e,this.start=e.start,this.end=e.end,this.sameRow=e.start.row==e.end.row,this.subFolds=this.ranges=[]};i.inherits(s,r),function(){this.toString=function(){return'\"'+this.placeholder+'\" '+this.range.toString()},this.setFoldLine=function(e){this.foldLine=e,this.subFolds.forEach(function(t){t.setFoldLine(e)})},this.clone=function(){var e=this.range.clone(),t=new s(e,this.placeholder);return this.subFolds.forEach(function(e){t.subFolds.push(e.clone())}),t.collapseChildren=this.collapseChildren,t},this.addSubFold=function(e){if(this.range.isEqual(e))return;u(e,this.start);var t=e.start.row,n=e.start.column;for(var r=0,i=-1;r<this.subFolds.length;r++){i=this.subFolds[r].range.compare(t,n);if(i!=1)break}var s=this.subFolds[r],o=0;if(i==0){if(s.range.containsRange(e))return s.addSubFold(e);o=1}var t=e.range.end.row,n=e.range.end.column;for(var a=r,i=-1;a<this.subFolds.length;a++){i=this.subFolds[a].range.compare(t,n);if(i!=1)break}i==0&&a++;var f=this.subFolds.splice(r,a-r,e),l=i==0?f.length-1:f.length;for(var c=o;c<l;c++)e.addSubFold(f[c]);return e.setFoldLine(this.foldLine),e},this.restoreRange=function(e){return f(e,this.start)}}.call(s.prototype)}),ace.define(\"ace/edit_session/folding\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/edit_session/fold_line\",\"ace/edit_session/fold\",\"ace/token_iterator\"],function(e,t,n){\"use strict\";function u(){this.getFoldAt=function(e,t,n){var r=this.getFoldLine(e);if(!r)return null;var i=r.folds;for(var s=0;s<i.length;s++){var o=i[s].range;if(o.contains(e,t)){if(n==1&&o.isEnd(e,t)&&!o.isEmpty())continue;if(n==-1&&o.isStart(e,t)&&!o.isEmpty())continue;return i[s]}}},this.getFoldsInRange=function(e){var t=e.start,n=e.end,r=this.$foldData,i=[];t.column+=1,n.column-=1;for(var s=0;s<r.length;s++){var o=r[s].range.compareRange(e);if(o==2)continue;if(o==-2)break;var u=r[s].folds;for(var a=0;a<u.length;a++){var f=u[a];o=f.range.compareRange(e);if(o==-2)break;if(o==2)continue;if(o==42)break;i.push(f)}}return t.column-=1,n.column+=1,i},this.getFoldsInRangeList=function(e){if(Array.isArray(e)){var t=[];e.forEach(function(e){t=t.concat(this.getFoldsInRange(e))},this)}else var t=this.getFoldsInRange(e);return t},this.getAllFolds=function(){var e=[],t=this.$foldData;for(var n=0;n<t.length;n++)for(var r=0;r<t[n].folds.length;r++)e.push(t[n].folds[r]);return e},this.getFoldStringAt=function(e,t,n,r){r=r||this.getFoldLine(e);if(!r)return null;var i={end:{column:0}},s,o;for(var u=0;u<r.folds.length;u++){o=r.folds[u];var a=o.range.compareEnd(e,t);if(a==-1){s=this.getLine(o.start.row).substring(i.end.column,o.start.column);break}if(a===0)return null;i=o}return s||(s=this.getLine(o.start.row).substring(i.end.column)),n==-1?s.substring(0,t-i.end.column):n==1?s.substring(t-i.end.column):s},this.getFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r<n.length;r++){var i=n[r];if(i.start.row<=e&&i.end.row>=e)return i;if(i.end.row>e)return null}return null},this.getNextFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r<n.length;r++){var i=n[r];if(i.end.row>=e)return i}return null},this.getFoldedRowCount=function(e,t){var n=this.$foldData,r=t-e+1;for(var i=0;i<n.length;i++){var s=n[i],o=s.end.row,u=s.start.row;if(o>=t){u<t&&(u>=e?r-=t-u:r=0);break}o>=e&&(u>=e?r-=o-u:r-=o-e+1)}return r},this.$addFoldLine=function(e){return this.$foldData.push(e),this.$foldData.sort(function(e,t){return e.start.row-t.start.row}),e},this.addFold=function(e,t){var n=this.$foldData,r=!1,o;e instanceof s?o=e:(o=new s(t,e),o.collapseChildren=t.collapseChildren),this.$clipRangeToDocument(o.range);var u=o.start.row,a=o.start.column,f=o.end.row,l=o.end.column,c=this.getFoldAt(u,a,1),h=this.getFoldAt(f,l,-1);if(c&&h==c)return c.addSubFold(o);c&&!c.range.isStart(u,a)&&this.removeFold(c),h&&!h.range.isEnd(f,l)&&this.removeFold(h);var p=this.getFoldsInRange(o.range);p.length>0&&(this.removeFolds(p),p.forEach(function(e){o.addSubFold(e)}));for(var d=0;d<n.length;d++){var v=n[d];if(f==v.start.row){v.addFold(o),r=!0;break}if(u==v.end.row){v.addFold(o),r=!0;if(!o.sameRow){var m=n[d+1];if(m&&m.start.row==f){v.merge(m);break}}break}if(f<=v.start.row)break}return r||(v=this.$addFoldLine(new i(this.$foldData,o))),this.$useWrapMode?this.$updateWrapData(v.start.row,v.start.row):this.$updateRowLengthCache(v.start.row,v.start.row),this.$modified=!0,this._signal(\"changeFold\",{data:o,action:\"add\"}),o},this.addFolds=function(e){e.forEach(function(e){this.addFold(e)},this)},this.removeFold=function(e){var t=e.foldLine,n=t.start.row,r=t.end.row,i=this.$foldData,s=t.folds;if(s.length==1)i.splice(i.indexOf(t),1);else if(t.range.isEnd(e.end.row,e.end.column))s.pop(),t.end.row=s[s.length-1].end.row,t.end.column=s[s.length-1].end.column;else if(t.range.isStart(e.start.row,e.start.column))s.shift(),t.start.row=s[0].start.row,t.start.column=s[0].start.column;else if(e.sameRow)s.splice(s.indexOf(e),1);else{var o=t.split(e.start.row,e.start.column);s=o.folds,s.shift(),o.start.row=s[0].start.row,o.start.column=s[0].start.column}this.$updating||(this.$useWrapMode?this.$updateWrapData(n,r):this.$updateRowLengthCache(n,r)),this.$modified=!0,this._signal(\"changeFold\",{data:e,action:\"remove\"})},this.removeFolds=function(e){var t=[];for(var n=0;n<e.length;n++)t.push(e[n]);t.forEach(function(e){this.removeFold(e)},this),this.$modified=!0},this.expandFold=function(e){this.removeFold(e),e.subFolds.forEach(function(t){e.restoreRange(t),this.addFold(t)},this),e.collapseChildren>0&&this.foldAll(e.start.row+1,e.end.row,e.collapseChildren-1),e.subFolds=[]},this.expandFolds=function(e){e.forEach(function(e){this.expandFold(e)},this)},this.unfold=function(e,t){var n,i;e==null?(n=new r(0,0,this.getLength(),0),t=!0):typeof e==\"number\"?n=new r(e,0,e,this.getLine(e).length):\"row\"in e?n=r.fromPoints(e,e):n=e,i=this.getFoldsInRangeList(n);if(t)this.removeFolds(i);else{var s=i;while(s.length)this.expandFolds(s),s=this.getFoldsInRangeList(n)}if(i.length)return i},this.isRowFolded=function(e,t){return!!this.getFoldLine(e,t)},this.getRowFoldEnd=function(e,t){var n=this.getFoldLine(e,t);return n?n.end.row:e},this.getRowFoldStart=function(e,t){var n=this.getFoldLine(e,t);return n?n.start.row:e},this.getFoldDisplayLine=function(e,t,n,r,i){r==null&&(r=e.start.row),i==null&&(i=0),t==null&&(t=e.end.row),n==null&&(n=this.getLine(t).length);var s=this.doc,o=\"\";return e.walk(function(e,t,n,u){if(t<r)return;if(t==r){if(n<i)return;u=Math.max(i,u)}e!=null?o+=e:o+=s.getLine(t).substring(u,n)},t,n),o},this.getDisplayLine=function(e,t,n,r){var i=this.getFoldLine(e);if(!i){var s;return s=this.doc.getLine(e),s.substring(r||0,t||s.length)}return this.getFoldDisplayLine(i,e,t,n,r)},this.$cloneFoldData=function(){var e=[];return e=this.$foldData.map(function(t){var n=t.folds.map(function(e){return e.clone()});return new i(e,n)}),e},this.toggleFold=function(e){var t=this.selection,n=t.getRange(),r,i;if(n.isEmpty()){var s=n.start;r=this.getFoldAt(s.row,s.column);if(r){this.expandFold(r);return}(i=this.findMatchingBracket(s))?n.comparePoint(i)==1?n.end=i:(n.start=i,n.start.column++,n.end.column--):(i=this.findMatchingBracket({row:s.row,column:s.column+1}))?(n.comparePoint(i)==1?n.end=i:n.start=i,n.start.column++):n=this.getCommentFoldRange(s.row,s.column)||n}else{var o=this.getFoldsInRange(n);if(e&&o.length){this.expandFolds(o);return}o.length==1&&(r=o[0])}r||(r=this.getFoldAt(n.start.row,n.start.column));if(r&&r.range.toString()==n.toString()){this.expandFold(r);return}var u=\"...\";if(!n.isMultiLine()){u=this.getTextRange(n);if(u.length<4)return;u=u.trim().substring(0,2)+\"..\"}this.addFold(u,n)},this.getCommentFoldRange=function(e,t,n){var i=new o(this,e,t),s=i.getCurrentToken(),u=s.type;if(s&&/^comment|string/.test(u)){u=u.match(/comment|string/)[0],u==\"comment\"&&(u+=\"|doc-start\");var a=new RegExp(u),f=new r;if(n!=1){do s=i.stepBackward();while(s&&a.test(s.type));i.stepForward()}f.start.row=i.getCurrentTokenRow(),f.start.column=i.getCurrentTokenColumn()+2,i=new o(this,e,t);if(n!=-1){var l=-1;do{s=i.stepForward();if(l==-1){var c=this.getState(i.$row);a.test(c)||(l=i.$row)}else if(i.$row>l)break}while(s&&a.test(s.type));s=i.stepBackward()}else s=i.getCurrentToken();return f.end.row=i.getCurrentTokenRow(),f.end.column=i.getCurrentTokenColumn()+s.value.length-2,f}},this.foldAll=function(e,t,n){n==undefined&&(n=1e5);var r=this.foldWidgets;if(!r)return;t=t||this.getLength(),e=e||0;for(var i=e;i<t;i++){r[i]==null&&(r[i]=this.getFoldWidget(i));if(r[i]!=\"start\")continue;var s=this.getFoldWidgetRange(i);if(s&&s.isMultiLine()&&s.end.row<=t&&s.start.row>=e){i=s.end.row;try{var o=this.addFold(\"...\",s);o&&(o.collapseChildren=n)}catch(u){}}}},this.$foldStyles={manual:1,markbegin:1,markbeginend:1},this.$foldStyle=\"markbegin\",this.setFoldStyle=function(e){if(!this.$foldStyles[e])throw new Error(\"invalid fold style: \"+e+\"[\"+Object.keys(this.$foldStyles).join(\", \")+\"]\");if(this.$foldStyle==e)return;this.$foldStyle=e,e==\"manual\"&&this.unfold();var t=this.$foldMode;this.$setFolding(null),this.$setFolding(t)},this.$setFolding=function(e){if(this.$foldMode==e)return;this.$foldMode=e,this.off(\"change\",this.$updateFoldWidgets),this.off(\"tokenizerUpdate\",this.$tokenizerUpdateFoldWidgets),this._signal(\"changeAnnotation\");if(!e||this.$foldStyle==\"manual\"){this.foldWidgets=null;return}this.foldWidgets=[],this.getFoldWidget=e.getFoldWidget.bind(e,this,this.$foldStyle),this.getFoldWidgetRange=e.getFoldWidgetRange.bind(e,this,this.$foldStyle),this.$updateFoldWidgets=this.updateFoldWidgets.bind(this),this.$tokenizerUpdateFoldWidgets=this.tokenizerUpdateFoldWidgets.bind(this),this.on(\"change\",this.$updateFoldWidgets),this.on(\"tokenizerUpdate\",this.$tokenizerUpdateFoldWidgets)},this.getParentFoldRangeData=function(e,t){var n=this.foldWidgets;if(!n||t&&n[e])return{};var r=e-1,i;while(r>=0){var s=n[r];s==null&&(s=n[r]=this.getFoldWidget(r));if(s==\"start\"){var o=this.getFoldWidgetRange(r);i||(i=o);if(o&&o.end.row>=e)break}r--}return{range:r!==-1&&o,firstRange:i}},this.onFoldWidgetClick=function(e,t){t=t.domEvent;var n={children:t.shiftKey,all:t.ctrlKey||t.metaKey,siblings:t.altKey},r=this.$toggleFoldWidget(e,n);if(!r){var i=t.target||t.srcElement;i&&/ace_fold-widget/.test(i.className)&&(i.className+=\" ace_invalid\")}},this.$toggleFoldWidget=function(e,t){if(!this.getFoldWidget)return;var n=this.getFoldWidget(e),r=this.getLine(e),i=n===\"end\"?-1:1,s=this.getFoldAt(e,i===-1?0:r.length,i);if(s)return t.children||t.all?this.removeFold(s):this.expandFold(s),s;var o=this.getFoldWidgetRange(e,!0);if(o&&!o.isMultiLine()){s=this.getFoldAt(o.start.row,o.start.column,1);if(s&&o.isEqual(s.range))return this.removeFold(s),s}if(t.siblings){var u=this.getParentFoldRangeData(e);if(u.range)var a=u.range.start.row+1,f=u.range.end.row;this.foldAll(a,f,t.all?1e4:0)}else t.children?(f=o?o.end.row:this.getLength(),this.foldAll(e+1,f,t.all?1e4:0)):o&&(t.all&&(o.collapseChildren=1e4),this.addFold(\"...\",o));return o},this.toggleFoldWidget=function(e){var t=this.selection.getCursor().row;t=this.getRowFoldStart(t);var n=this.$toggleFoldWidget(t,{});if(n)return;var r=this.getParentFoldRangeData(t,!0);n=r.range||r.firstRange;if(n){t=n.start.row;var i=this.getFoldAt(t,this.getLine(t).length,1);i?this.removeFold(i):this.addFold(\"...\",n)}},this.updateFoldWidgets=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.foldWidgets[t]=null;else if(e.action==\"remove\")this.foldWidgets.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.foldWidgets.splice.apply(this.foldWidgets,r)}},this.tokenizerUpdateFoldWidgets=function(e){var t=e.data;t.first!=t.last&&this.foldWidgets.length>t.first&&this.foldWidgets.splice(t.first,this.foldWidgets.length)}}var r=e(\"../range\").Range,i=e(\"./fold_line\").FoldLine,s=e(\"./fold\").Fold,o=e(\"../token_iterator\").TokenIterator;t.Folding=u}),ace.define(\"ace/edit_session/bracket_match\",[\"require\",\"exports\",\"module\",\"ace/token_iterator\",\"ace/range\"],function(e,t,n){\"use strict\";function s(){this.findMatchingBracket=function(e,t){if(e.column==0)return null;var n=t||this.getLine(e.row).charAt(e.column-1);if(n==\"\")return null;var r=n.match(/([\\(\\[\\{])|([\\)\\]\\}])/);return r?r[1]?this.$findClosingBracket(r[1],e):this.$findOpeningBracket(r[2],e):null},this.getBracketRange=function(e){var t=this.getLine(e.row),n=!0,r,s=t.charAt(e.column-1),o=s&&s.match(/([\\(\\[\\{])|([\\)\\]\\}])/);o||(s=t.charAt(e.column),e={row:e.row,column:e.column+1},o=s&&s.match(/([\\(\\[\\{])|([\\)\\]\\}])/),n=!1);if(!o)return null;if(o[1]){var u=this.$findClosingBracket(o[1],e);if(!u)return null;r=i.fromPoints(e,u),n||(r.end.column++,r.start.column--),r.cursor=r.end}else{var u=this.$findOpeningBracket(o[2],e);if(!u)return null;r=i.fromPoints(u,e),n||(r.start.column++,r.end.column--),r.cursor=r.start}return r},this.$brackets={\")\":\"(\",\"(\":\")\",\"]\":\"[\",\"[\":\"]\",\"{\":\"}\",\"}\":\"{\",\"<\":\">\",\">\":\"<\"},this.$findOpeningBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp(\"(\\\\.?\"+u.type.replace(\".\",\"\\\\.\").replace(\"rparen\",\".paren\").replace(/\\b(?:end)\\b/,\"(?:start|begin|end)\")+\")+\"));var a=t.column-o.getCurrentTokenColumn()-2,f=u.value;for(;;){while(a>=0){var l=f.charAt(a);if(l==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else l==e&&(s+=1);a-=1}do u=o.stepBackward();while(u&&!n.test(u.type));if(u==null)break;f=u.value,a=f.length-1}return null},this.$findClosingBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp(\"(\\\\.?\"+u.type.replace(\".\",\"\\\\.\").replace(\"lparen\",\".paren\").replace(/\\b(?:start|begin)\\b/,\"(?:start|begin|end)\")+\")+\"));var a=t.column-o.getCurrentTokenColumn();for(;;){var f=u.value,l=f.length;while(a<l){var c=f.charAt(a);if(c==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else c==e&&(s+=1);a+=1}do u=o.stepForward();while(u&&!n.test(u.type));if(u==null)break;a=0}return null}}var r=e(\"../token_iterator\").TokenIterator,i=e(\"../range\").Range;t.BracketMatch=s}),ace.define(\"ace/edit_session\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/bidihandler\",\"ace/config\",\"ace/lib/event_emitter\",\"ace/selection\",\"ace/mode/text\",\"ace/range\",\"ace/document\",\"ace/background_tokenizer\",\"ace/search_highlight\",\"ace/edit_session/folding\",\"ace/edit_session/bracket_match\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/lang\"),s=e(\"./bidihandler\").BidiHandler,o=e(\"./config\"),u=e(\"./lib/event_emitter\").EventEmitter,a=e(\"./selection\").Selection,f=e(\"./mode/text\").Mode,l=e(\"./range\").Range,c=e(\"./document\").Document,h=e(\"./background_tokenizer\").BackgroundTokenizer,p=e(\"./search_highlight\").SearchHighlight,d=function(e,t){this.$breakpoints=[],this.$decorations=[],this.$frontMarkers={},this.$backMarkers={},this.$markerId=1,this.$undoSelect=!0,this.$foldData=[],this.id=\"session\"+ ++d.$uid,this.$foldData.toString=function(){return this.join(\"\\n\")},this.on(\"changeFold\",this.onChangeFold.bind(this)),this.$onChange=this.onChange.bind(this);if(typeof e!=\"object\"||!e.getLine)e=new c(e);this.setDocument(e),this.selection=new a(this),this.$bidiHandler=new s(this),o.resetOptions(this),this.setMode(t),o._signal(\"session\",this)};d.$uid=0,function(){function m(e){return e<4352?!1:e>=4352&&e<=4447||e>=4515&&e<=4519||e>=4602&&e<=4607||e>=9001&&e<=9002||e>=11904&&e<=11929||e>=11931&&e<=12019||e>=12032&&e<=12245||e>=12272&&e<=12283||e>=12288&&e<=12350||e>=12353&&e<=12438||e>=12441&&e<=12543||e>=12549&&e<=12589||e>=12593&&e<=12686||e>=12688&&e<=12730||e>=12736&&e<=12771||e>=12784&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=13054||e>=13056&&e<=19903||e>=19968&&e<=42124||e>=42128&&e<=42182||e>=43360&&e<=43388||e>=44032&&e<=55203||e>=55216&&e<=55238||e>=55243&&e<=55291||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=65281&&e<=65376||e>=65504&&e<=65510}r.implement(this,u),this.setDocument=function(e){this.doc&&this.doc.removeListener(\"change\",this.$onChange),this.doc=e,e.on(\"change\",this.$onChange),this.bgTokenizer&&this.bgTokenizer.setDocument(this.getDocument()),this.resetCaches()},this.getDocument=function(){return this.doc},this.$resetRowCache=function(e){if(!e){this.$docRowCache=[],this.$screenRowCache=[];return}var t=this.$docRowCache.length,n=this.$getRowCacheIndex(this.$docRowCache,e)+1;t>n&&(this.$docRowCache.splice(n,t),this.$screenRowCache.splice(n,t))},this.$getRowCacheIndex=function(e,t){var n=0,r=e.length-1;while(n<=r){var i=n+r>>1,s=e[i];if(t>s)n=i+1;else{if(!(t<s))return i;r=i-1}}return n-1},this.resetCaches=function(){this.$modified=!0,this.$wrapData=[],this.$rowLengthCache=[],this.$resetRowCache(0),this.bgTokenizer&&this.bgTokenizer.start(0)},this.onChangeFold=function(e){var t=e.data;this.$resetRowCache(t.start.row)},this.onChange=function(e){this.$modified=!0,this.$bidiHandler.onChange(e),this.$resetRowCache(e.start.row);var t=this.$updateInternalDataOnChange(e);!this.$fromUndo&&this.$undoManager&&(t&&t.length&&(this.$undoManager.add({action:\"removeFolds\",folds:t},this.mergeUndoDeltas),this.mergeUndoDeltas=!0),this.$undoManager.add(e,this.mergeUndoDeltas),this.mergeUndoDeltas=!0,this.$informUndoManager.schedule()),this.bgTokenizer&&this.bgTokenizer.$updateOnChange(e),this._signal(\"change\",e)},this.setValue=function(e){this.doc.setValue(e),this.selection.moveTo(0,0),this.$resetRowCache(0),this.setUndoManager(this.$undoManager),this.getUndoManager().reset()},this.getValue=this.toString=function(){return this.doc.getValue()},this.getSelection=function(){return this.selection},this.getState=function(e){return this.bgTokenizer.getState(e)},this.getTokens=function(e){return this.bgTokenizer.getTokens(e)},this.getTokenAt=function(e,t){var n=this.bgTokenizer.getTokens(e),r,i=0;if(t==null){var s=n.length-1;i=this.getLine(e).length}else for(var s=0;s<n.length;s++){i+=n[s].value.length;if(i>=t)break}return r=n[s],r?(r.index=s,r.start=i-r.value.length,r):null},this.setUndoManager=function(e){this.$undoManager=e,this.$informUndoManager&&this.$informUndoManager.cancel();if(e){var t=this;e.addSession(this),this.$syncInformUndoManager=function(){t.$informUndoManager.cancel(),t.mergeUndoDeltas=!1},this.$informUndoManager=i.delayedCall(this.$syncInformUndoManager)}else this.$syncInformUndoManager=function(){}},this.markUndoGroup=function(){this.$syncInformUndoManager&&this.$syncInformUndoManager()},this.$defaultUndoManager={undo:function(){},redo:function(){},hasUndo:function(){},hasRedo:function(){},reset:function(){},add:function(){},addSelection:function(){},startNewGroup:function(){},addSession:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?i.stringRepeat(\" \",this.getTabSize()):\"\t\"},this.setUseSoftTabs=function(e){this.setOption(\"useSoftTabs\",e)},this.getUseSoftTabs=function(){return this.$useSoftTabs&&!this.$mode.$indentWithTabs},this.setTabSize=function(e){this.setOption(\"tabSize\",e)},this.getTabSize=function(){return this.$tabSize},this.isTabStop=function(e){return this.$useSoftTabs&&e.column%this.$tabSize===0},this.setNavigateWithinSoftTabs=function(e){this.setOption(\"navigateWithinSoftTabs\",e)},this.getNavigateWithinSoftTabs=function(){return this.$navigateWithinSoftTabs},this.$overwrite=!1,this.setOverwrite=function(e){this.setOption(\"overwrite\",e)},this.getOverwrite=function(){return this.$overwrite},this.toggleOverwrite=function(){this.setOverwrite(!this.$overwrite)},this.addGutterDecoration=function(e,t){this.$decorations[e]||(this.$decorations[e]=\"\"),this.$decorations[e]+=\" \"+t,this._signal(\"changeBreakpoint\",{})},this.removeGutterDecoration=function(e,t){this.$decorations[e]=(this.$decorations[e]||\"\").replace(\" \"+t,\"\"),this._signal(\"changeBreakpoint\",{})},this.getBreakpoints=function(){return this.$breakpoints},this.setBreakpoints=function(e){this.$breakpoints=[];for(var t=0;t<e.length;t++)this.$breakpoints[e[t]]=\"ace_breakpoint\";this._signal(\"changeBreakpoint\",{})},this.clearBreakpoints=function(){this.$breakpoints=[],this._signal(\"changeBreakpoint\",{})},this.setBreakpoint=function(e,t){t===undefined&&(t=\"ace_breakpoint\"),t?this.$breakpoints[e]=t:delete this.$breakpoints[e],this._signal(\"changeBreakpoint\",{})},this.clearBreakpoint=function(e){delete this.$breakpoints[e],this._signal(\"changeBreakpoint\",{})},this.addMarker=function(e,t,n,r){var i=this.$markerId++,s={range:e,type:n||\"line\",renderer:typeof n==\"function\"?n:null,clazz:t,inFront:!!r,id:i};return r?(this.$frontMarkers[i]=s,this._signal(\"changeFrontMarker\")):(this.$backMarkers[i]=s,this._signal(\"changeBackMarker\")),i},this.addDynamicMarker=function(e,t){if(!e.update)return;var n=this.$markerId++;return e.id=n,e.inFront=!!t,t?(this.$frontMarkers[n]=e,this._signal(\"changeFrontMarker\")):(this.$backMarkers[n]=e,this._signal(\"changeBackMarker\")),e},this.removeMarker=function(e){var t=this.$frontMarkers[e]||this.$backMarkers[e];if(!t)return;var n=t.inFront?this.$frontMarkers:this.$backMarkers;delete n[e],this._signal(t.inFront?\"changeFrontMarker\":\"changeBackMarker\")},this.getMarkers=function(e){return e?this.$frontMarkers:this.$backMarkers},this.highlight=function(e){if(!this.$searchHighlight){var t=new p(null,\"ace_selected-word\",\"text\");this.$searchHighlight=this.addDynamicMarker(t)}this.$searchHighlight.setRegexp(e)},this.highlightLines=function(e,t,n,r){typeof t!=\"number\"&&(n=t,t=e),n||(n=\"ace_step\");var i=new l(e,0,t,Infinity);return i.id=this.addMarker(i,n,\"fullLine\",r),i},this.setAnnotations=function(e){this.$annotations=e,this._signal(\"changeAnnotation\",{})},this.getAnnotations=function(){return this.$annotations||[]},this.clearAnnotations=function(){this.setAnnotations([])},this.$detectNewLine=function(e){var t=e.match(/^.*?(\\r?\\n)/m);t?this.$autoNewLine=t[1]:this.$autoNewLine=\"\\n\"},this.getWordRange=function(e,t){var n=this.getLine(e),r=!1;t>0&&(r=!!n.charAt(t-1).match(this.tokenRe)),r||(r=!!n.charAt(t).match(this.tokenRe));if(r)var i=this.tokenRe;else if(/^\\s+$/.test(n.slice(t-1,t+1)))var i=/\\s/;else var i=this.nonTokenRe;var s=t;if(s>0){do s--;while(s>=0&&n.charAt(s).match(i));s++}var o=t;while(o<n.length&&n.charAt(o).match(i))o++;return new l(e,s,e,o)},this.getAWordRange=function(e,t){var n=this.getWordRange(e,t),r=this.getLine(n.end.row);while(r.charAt(n.end.column).match(/[ \\t]/))n.end.column+=1;return n},this.setNewLineMode=function(e){this.doc.setNewLineMode(e)},this.getNewLineMode=function(){return this.doc.getNewLineMode()},this.setUseWorker=function(e){this.setOption(\"useWorker\",e)},this.getUseWorker=function(){return this.$useWorker},this.onReloadTokenizer=function(e){var t=e.data;this.bgTokenizer.start(t.first),this._signal(\"tokenizerUpdate\",e)},this.$modes=o.$modes,this.$mode=null,this.$modeId=null,this.setMode=function(e,t){if(e&&typeof e==\"object\"){if(e.getTokenizer)return this.$onChangeMode(e);var n=e,r=n.path}else r=e||\"ace/mode/text\";this.$modes[\"ace/mode/text\"]||(this.$modes[\"ace/mode/text\"]=new f);if(this.$modes[r]&&!n){this.$onChangeMode(this.$modes[r]),t&&t();return}this.$modeId=r,o.loadModule([\"mode\",r],function(e){if(this.$modeId!==r)return t&&t();this.$modes[r]&&!n?this.$onChangeMode(this.$modes[r]):e&&e.Mode&&(e=new e.Mode(n),n||(this.$modes[r]=e,e.$id=r),this.$onChangeMode(e)),t&&t()}.bind(this)),this.$mode||this.$onChangeMode(this.$modes[\"ace/mode/text\"],!0)},this.$onChangeMode=function(e,t){t||(this.$modeId=e.$id);if(this.$mode===e)return;this.$mode=e,this.$stopWorker(),this.$useWorker&&this.$startWorker();var n=e.getTokenizer();if(n.addEventListener!==undefined){var r=this.onReloadTokenizer.bind(this);n.addEventListener(\"update\",r)}if(!this.bgTokenizer){this.bgTokenizer=new h(n);var i=this;this.bgTokenizer.addEventListener(\"update\",function(e){i._signal(\"tokenizerUpdate\",e)})}else this.bgTokenizer.setTokenizer(n);this.bgTokenizer.setDocument(this.getDocument()),this.tokenRe=e.tokenRe,this.nonTokenRe=e.nonTokenRe,t||(e.attachToSession&&e.attachToSession(this),this.$options.wrapMethod.set.call(this,this.$wrapMethod),this.$setFolding(e.foldingRules),this.bgTokenizer.start(0),this._emit(\"changeMode\"))},this.$stopWorker=function(){this.$worker&&(this.$worker.terminate(),this.$worker=null)},this.$startWorker=function(){try{this.$worker=this.$mode.createWorker(this)}catch(e){o.warn(\"Could not load worker\",e),this.$worker=null}},this.getMode=function(){return this.$mode},this.$scrollTop=0,this.setScrollTop=function(e){if(this.$scrollTop===e||isNaN(e))return;this.$scrollTop=e,this._signal(\"changeScrollTop\",e)},this.getScrollTop=function(){return this.$scrollTop},this.$scrollLeft=0,this.setScrollLeft=function(e){if(this.$scrollLeft===e||isNaN(e))return;this.$scrollLeft=e,this._signal(\"changeScrollLeft\",e)},this.getScrollLeft=function(){return this.$scrollLeft},this.getScreenWidth=function(){return this.$computeWidth(),this.lineWidgets?Math.max(this.getLineWidgetMaxWidth(),this.screenWidth):this.screenWidth},this.getLineWidgetMaxWidth=function(){if(this.lineWidgetsWidth!=null)return this.lineWidgetsWidth;var e=0;return this.lineWidgets.forEach(function(t){t&&t.screenWidth>e&&(e=t.screenWidth)}),this.lineWidgetWidth=e},this.$computeWidth=function(e){if(this.$modified||e){this.$modified=!1;if(this.$useWrapMode)return this.screenWidth=this.$wrapLimit;var t=this.doc.getAllLines(),n=this.$rowLengthCache,r=0,i=0,s=this.$foldData[i],o=s?s.start.row:Infinity,u=t.length;for(var a=0;a<u;a++){if(a>o){a=s.end.row+1;if(a>=u)break;s=this.$foldData[i++],o=s?s.start.row:Infinity}n[a]==null&&(n[a]=this.$getStringScreenWidth(t[a])[0]),n[a]>r&&(r=n[a])}this.screenWidth=r}},this.getLine=function(e){return this.doc.getLine(e)},this.getLines=function(e,t){return this.doc.getLines(e,t)},this.getLength=function(){return this.doc.getLength()},this.getTextRange=function(e){return this.doc.getTextRange(e||this.selection.getRange())},this.insert=function(e,t){return this.doc.insert(e,t)},this.remove=function(e){return this.doc.remove(e)},this.removeFullLines=function(e,t){return this.doc.removeFullLines(e,t)},this.undoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;for(var n=e.length-1;n!=-1;n--){var r=e[n];r.action==\"insert\"||r.action==\"remove\"?this.doc.revertDelta(r):r.folds&&this.addFolds(r.folds)}!t&&this.$undoSelect&&(e.selectionBefore?this.selection.fromJSON(e.selectionBefore):this.selection.setRange(this.$getUndoSelection(e,!0))),this.$fromUndo=!1},this.redoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;for(var n=0;n<e.length;n++){var r=e[n];(r.action==\"insert\"||r.action==\"remove\")&&this.doc.applyDelta(r)}!t&&this.$undoSelect&&(e.selectionAfter?this.selection.fromJSON(e.selectionAfter):this.selection.setRange(this.$getUndoSelection(e,!1))),this.$fromUndo=!1},this.setUndoSelect=function(e){this.$undoSelect=e},this.$getUndoSelection=function(e,t){function n(e){return t?e.action!==\"insert\":e.action===\"insert\"}var r,i,s;for(var o=0;o<e.length;o++){var u=e[o];if(!u.start)continue;if(!r){n(u)?(r=l.fromPoints(u.start,u.end),s=!0):(r=l.fromPoints(u.start,u.start),s=!1);continue}n(u)?(i=u.start,r.compare(i.row,i.column)==-1&&r.setStart(i),i=u.end,r.compare(i.row,i.column)==1&&r.setEnd(i),s=!0):(i=u.start,r.compare(i.row,i.column)==-1&&(r=l.fromPoints(u.start,u.start)),s=!1)}return r},this.replace=function(e,t){return this.doc.replace(e,t)},this.moveText=function(e,t,n){var r=this.getTextRange(e),i=this.getFoldsInRange(e),s=l.fromPoints(t,t);if(!n){this.remove(e);var o=e.start.row-e.end.row,u=o?-e.end.column:e.start.column-e.end.column;u&&(s.start.row==e.end.row&&s.start.column>e.end.column&&(s.start.column+=u),s.end.row==e.end.row&&s.end.column>e.end.column&&(s.end.column+=u)),o&&s.start.row>=e.end.row&&(s.start.row+=o,s.end.row+=o)}s.end=this.insert(s.start,r);if(i.length){var a=e.start,f=s.start,o=f.row-a.row,u=f.column-a.column;this.addFolds(i.map(function(e){return e=e.clone(),e.start.row==a.row&&(e.start.column+=u),e.end.row==a.row&&(e.end.column+=u),e.start.row+=o,e.end.row+=o,e}))}return s},this.indentRows=function(e,t,n){n=n.replace(/\\t/g,this.getTabString());for(var r=e;r<=t;r++)this.doc.insertInLine({row:r,column:0},n)},this.outdentRows=function(e){var t=e.collapseRows(),n=new l(0,0,0,0),r=this.getTabSize();for(var i=t.start.row;i<=t.end.row;++i){var s=this.getLine(i);n.start.row=i,n.end.row=i;for(var o=0;o<r;++o)if(s.charAt(o)!=\" \")break;o<r&&s.charAt(o)==\"\t\"?(n.start.column=o,n.end.column=o+1):(n.start.column=0,n.end.column=o),this.remove(n)}},this.$moveLines=function(e,t,n){e=this.getRowFoldStart(e),t=this.getRowFoldEnd(t);if(n<0){var r=this.getRowFoldStart(e+n);if(r<0)return 0;var i=r-e}else if(n>0){var r=this.getRowFoldEnd(t+n);if(r>this.doc.getLength()-1)return 0;var i=r-t}else{e=this.$clipRowToDocument(e),t=this.$clipRowToDocument(t);var i=t-e+1}var s=new l(e,0,t,Number.MAX_VALUE),o=this.getFoldsInRange(s).map(function(e){return e=e.clone(),e.start.row+=i,e.end.row+=i,e}),u=n==0?this.doc.getLines(e,t):this.doc.removeFullLines(e,t);return this.doc.insertFullLines(e+i,u),o.length&&this.addFolds(o),i},this.moveLinesUp=function(e,t){return this.$moveLines(e,t,-1)},this.moveLinesDown=function(e,t){return this.$moveLines(e,t,1)},this.duplicateLines=function(e,t){return this.$moveLines(e,t,0)},this.$clipRowToDocument=function(e){return Math.max(0,Math.min(e,this.doc.getLength()-1))},this.$clipColumnToRow=function(e,t){return t<0?0:Math.min(this.doc.getLine(e).length,t)},this.$clipPositionToDocument=function(e,t){t=Math.max(0,t);if(e<0)e=0,t=0;else{var n=this.doc.getLength();e>=n?(e=n-1,t=this.doc.getLine(n-1).length):t=Math.min(this.doc.getLine(e).length,t)}return{row:e,column:t}},this.$clipRangeToDocument=function(e){e.start.row<0?(e.start.row=0,e.start.column=0):e.start.column=this.$clipColumnToRow(e.start.row,e.start.column);var t=this.doc.getLength()-1;return e.end.row>t?(e.end.row=t,e.end.column=this.doc.getLine(t).length):e.end.column=this.$clipColumnToRow(e.end.row,e.end.column),e},this.$wrapLimit=80,this.$useWrapMode=!1,this.$wrapLimitRange={min:null,max:null},this.setUseWrapMode=function(e){if(e!=this.$useWrapMode){this.$useWrapMode=e,this.$modified=!0,this.$resetRowCache(0);if(e){var t=this.getLength();this.$wrapData=Array(t),this.$updateWrapData(0,t-1)}this._signal(\"changeWrapMode\")}},this.getUseWrapMode=function(){return this.$useWrapMode},this.setWrapLimitRange=function(e,t){if(this.$wrapLimitRange.min!==e||this.$wrapLimitRange.max!==t)this.$wrapLimitRange={min:e,max:t},this.$modified=!0,this.$bidiHandler.markAsDirty(),this.$useWrapMode&&this._signal(\"changeWrapMode\")},this.adjustWrapLimit=function(e,t){var n=this.$wrapLimitRange;n.max<0&&(n={min:t,max:t});var r=this.$constrainWrapLimit(e,n.min,n.max);return r!=this.$wrapLimit&&r>1?(this.$wrapLimit=r,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this.$resetRowCache(0),this._signal(\"changeWrapLimit\")),!0):!1},this.$constrainWrapLimit=function(e,t,n){return t&&(e=Math.max(t,e)),n&&(e=Math.min(n,e)),e},this.getWrapLimit=function(){return this.$wrapLimit},this.setWrapLimit=function(e){this.setWrapLimitRange(e,e)},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateInternalDataOnChange=function(e){var t=this.$useWrapMode,n=e.action,r=e.start,i=e.end,s=r.row,o=i.row,u=o-s,a=null;this.$updating=!0;if(u!=0)if(n===\"remove\"){this[t?\"$wrapData\":\"$rowLengthCache\"].splice(s,u);var f=this.$foldData;a=this.getFoldsInRange(e),this.removeFolds(a);var l=this.getFoldLine(i.row),c=0;if(l){l.addRemoveChars(i.row,i.column,r.column-i.column),l.shiftRow(-u);var h=this.getFoldLine(s);h&&h!==l&&(h.merge(l),l=h),c=f.indexOf(l)+1}for(c;c<f.length;c++){var l=f[c];l.start.row>=i.row&&l.shiftRow(-u)}o=s}else{var p=Array(u);p.unshift(s,0);var d=t?this.$wrapData:this.$rowLengthCache;d.splice.apply(d,p);var f=this.$foldData,l=this.getFoldLine(s),c=0;if(l){var v=l.range.compareInside(r.row,r.column);v==0?(l=l.split(r.row,r.column),l&&(l.shiftRow(u),l.addRemoveChars(o,0,i.column-r.column))):v==-1&&(l.addRemoveChars(s,0,i.column-r.column),l.shiftRow(u)),c=f.indexOf(l)+1}for(c;c<f.length;c++){var l=f[c];l.start.row>=s&&l.shiftRow(u)}}else{u=Math.abs(e.start.column-e.end.column),n===\"remove\"&&(a=this.getFoldsInRange(e),this.removeFolds(a),u=-u);var l=this.getFoldLine(s);l&&l.addRemoveChars(s,r.column,u)}return t&&this.$wrapData.length!=this.doc.getLength()&&console.error(\"doc.getLength() and $wrapData.length have to be the same!\"),this.$updating=!1,t?this.$updateWrapData(s,o):this.$updateRowLengthCache(s,o),a},this.$updateRowLengthCache=function(e,t,n){this.$rowLengthCache[e]=null,this.$rowLengthCache[t]=null},this.$updateWrapData=function(e,t){var r=this.doc.getAllLines(),i=this.getTabSize(),o=this.$wrapData,u=this.$wrapLimit,a,f,l=e;t=Math.min(t,r.length-1);while(l<=t)f=this.getFoldLine(l,f),f?(a=[],f.walk(function(e,t,i,o){var u;if(e!=null){u=this.$getDisplayTokens(e,a.length),u[0]=n;for(var f=1;f<u.length;f++)u[f]=s}else u=this.$getDisplayTokens(r[t].substring(o,i),a.length);a=a.concat(u)}.bind(this),f.end.row,r[f.end.row].length+1),o[f.start.row]=this.$computeWrapSplits(a,u,i),l=f.end.row+1):(a=this.$getDisplayTokens(r[l]),o[l]=this.$computeWrapSplits(a,u,i),l++)};var e=1,t=2,n=3,s=4,a=9,c=10,d=11,v=12;this.$computeWrapSplits=function(e,r,i){function g(){var t=0;if(m===0)return t;if(p)for(var n=0;n<e.length;n++){var r=e[n];if(r==c)t+=1;else{if(r!=d){if(r==v)continue;break}t+=i}}return h&&p!==!1&&(t+=i),Math.min(t,m)}function y(t){var n=t-f;for(var r=f;r<t;r++){var i=e[r];if(i===12||i===2)n-=1}o.length||(b=g(),o.indent=b),l+=n,o.push(l),f=t}if(e.length==0)return[];var o=[],u=e.length,f=0,l=0,h=this.$wrapAsCode,p=this.$indentedSoftWrap,m=r<=Math.max(2*i,8)||p===!1?0:Math.floor(r/2),b=0;while(u-f>r-b){var w=f+r-b;if(e[w-1]>=c&&e[w]>=c){y(w);continue}if(e[w]==n||e[w]==s){for(w;w!=f-1;w--)if(e[w]==n)break;if(w>f){y(w);continue}w=f+r;for(w;w<e.length;w++)if(e[w]!=s)break;if(w==e.length)break;y(w);continue}var E=Math.max(w-(r-(r>>2)),f-1);while(w>E&&e[w]<n)w--;if(h){while(w>E&&e[w]<n)w--;while(w>E&&e[w]==a)w--}else while(w>E&&e[w]<c)w--;if(w>E){y(++w);continue}w=f+r,e[w]==t&&w--,y(w-b)}return o},this.$getDisplayTokens=function(n,r){var i=[],s;r=r||0;for(var o=0;o<n.length;o++){var u=n.charCodeAt(o);if(u==9){s=this.getScreenTabSize(i.length+r),i.push(d);for(var f=1;f<s;f++)i.push(v)}else u==32?i.push(c):u>39&&u<48||u>57&&u<64?i.push(a):u>=4352&&m(u)?i.push(e,t):i.push(e)}return i},this.$getStringScreenWidth=function(e,t,n){if(t==0)return[0,0];t==null&&(t=Infinity),n=n||0;var r,i;for(i=0;i<e.length;i++){r=e.charCodeAt(i),r==9?n+=this.getScreenTabSize(n):r>=4352&&m(r)?n+=2:n+=1;if(n>t)break}return[n,i]},this.lineWidgets=null,this.getRowLength=function(e){if(this.lineWidgets)var t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0;else t=0;return!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.getRowLineCount=function(e){return!this.$useWrapMode||!this.$wrapData[e]?1:this.$wrapData[e].length+1},this.getRowWrapIndent=function(e){if(this.$useWrapMode){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE),n=this.$wrapData[t.row];return n.length&&n[0]<t.column?n.indent:0}return 0},this.getScreenLastRowColumn=function(e){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE);return this.documentToScreenColumn(t.row,t.column)},this.getDocumentLastRowColumn=function(e,t){var n=this.documentToScreenRow(e,t);return this.getScreenLastRowColumn(n)},this.getDocumentLastRowColumnPosition=function(e,t){var n=this.documentToScreenRow(e,t);return this.screenToDocumentPosition(n,Number.MAX_VALUE/10)},this.getRowSplitData=function(e){return this.$useWrapMode?this.$wrapData[e]:undefined},this.getScreenTabSize=function(e){return this.$tabSize-(e%this.$tabSize|0)},this.screenToDocumentRow=function(e,t){return this.screenToDocumentPosition(e,t).row},this.screenToDocumentColumn=function(e,t){return this.screenToDocumentPosition(e,t).column},this.screenToDocumentPosition=function(e,t,n){if(e<0)return{row:0,column:0};var r,i=0,s=0,o,u=0,a=0,f=this.$screenRowCache,l=this.$getRowCacheIndex(f,e),c=f.length;if(c&&l>=0)var u=f[l],i=this.$docRowCache[l],h=e>f[c-1];else var h=!c;var p=this.getLength()-1,d=this.getNextFoldLine(i),v=d?d.start.row:Infinity;while(u<=e){a=this.getRowLength(i);if(u+a>e||i>=p)break;u+=a,i++,i>v&&(i=d.end.row+1,d=this.getNextFoldLine(i,d),v=d?d.start.row:Infinity),h&&(this.$docRowCache.push(i),this.$screenRowCache.push(u))}if(d&&d.start.row<=i)r=this.getFoldDisplayLine(d),i=d.start.row;else{if(u+a<=e||i>p)return{row:p,column:this.getLine(p).length};r=this.getLine(i),d=null}var m=0,g=Math.floor(e-u);if(this.$useWrapMode){var y=this.$wrapData[i];y&&(o=y[g],g>0&&y.length&&(m=y.indent,s=y[g-1]||y[y.length-1],r=r.substring(s)))}return n!==undefined&&this.$bidiHandler.isBidiRow(u+g,i,g)&&(t=this.$bidiHandler.offsetToCol(n)),s+=this.$getStringScreenWidth(r,t-m)[1],this.$useWrapMode&&s>=o&&(s=o-1),d?d.idxToPosition(s):{row:i,column:s}},this.documentToScreenPosition=function(e,t){if(typeof t==\"undefined\")var n=this.$clipPositionToDocument(e.row,e.column);else n=this.$clipPositionToDocument(e,t);e=n.row,t=n.column;var r=0,i=null,s=null;s=this.getFoldAt(e,t,1),s&&(e=s.start.row,t=s.start.column);var o,u=0,a=this.$docRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var u=a[f],r=this.$screenRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getNextFoldLine(u),p=h?h.start.row:Infinity;while(u<e){if(u>=p){o=h.end.row+1;if(o>e)break;h=this.getNextFoldLine(o,h),p=h?h.start.row:Infinity}else o=u+1;r+=this.getRowLength(u),u=o,c&&(this.$docRowCache.push(u),this.$screenRowCache.push(r))}var d=\"\";h&&u>=p?(d=this.getFoldDisplayLine(h,e,t),i=h.start.row):(d=this.getLine(e).substring(0,t),i=e);var v=0;if(this.$useWrapMode){var m=this.$wrapData[i];if(m){var g=0;while(d.length>=m[g])r++,g++;d=d.substring(m[g-1]||0,d.length),v=g>0?m.indent:0}}return{row:r,column:v+this.$getStringScreenWidth(d)[0]}},this.documentToScreenColumn=function(e,t){return this.documentToScreenPosition(e,t).column},this.documentToScreenRow=function(e,t){return this.documentToScreenPosition(e,t).row},this.getScreenLength=function(){var e=0,t=null;if(!this.$useWrapMode){e=this.getLength();var n=this.$foldData;for(var r=0;r<n.length;r++)t=n[r],e-=t.end.row-t.start.row}else{var i=this.$wrapData.length,s=0,r=0,t=this.$foldData[r++],o=t?t.start.row:Infinity;while(s<i){var u=this.$wrapData[s];e+=u?u.length+1:1,s++,s>o&&(s=t.end.row+1,t=this.$foldData[r++],o=t?t.start.row:Infinity)}}return this.lineWidgets&&(e+=this.$getWidgetScreenLength()),e},this.$setFontMetrics=function(e){if(!this.$enableVarChar)return;this.$getStringScreenWidth=function(t,n,r){if(n===0)return[0,0];n||(n=Infinity),r=r||0;var i,s;for(s=0;s<t.length;s++){i=t.charAt(s),i===\"\t\"?r+=this.getScreenTabSize(r):r+=e.getCharacterWidth(i);if(r>n)break}return[r,s]}},this.destroy=function(){this.bgTokenizer&&(this.bgTokenizer.setDocument(null),this.bgTokenizer=null),this.$stopWorker()},this.isFullWidth=m}.call(d.prototype),e(\"./edit_session/folding\").Folding.call(d.prototype),e(\"./edit_session/bracket_match\").BracketMatch.call(d.prototype),o.defineOptions(d.prototype,\"session\",{wrap:{set:function(e){!e||e==\"off\"?e=!1:e==\"free\"?e=!0:e==\"printMargin\"?e=-1:typeof e==\"string\"&&(e=parseInt(e,10)||!1);if(this.$wrap==e)return;this.$wrap=e;if(!e)this.setUseWrapMode(!1);else{var t=typeof e==\"number\"?e:null;this.setWrapLimitRange(t,t),this.setUseWrapMode(!0)}},get:function(){return this.getUseWrapMode()?this.$wrap==-1?\"printMargin\":this.getWrapLimitRange().min?this.$wrap:\"free\":\"off\"},handlesSet:!0},wrapMethod:{set:function(e){e=e==\"auto\"?this.$mode.type!=\"text\":e!=\"text\",e!=this.$wrapAsCode&&(this.$wrapAsCode=e,this.$useWrapMode&&(this.$useWrapMode=!1,this.setUseWrapMode(!0)))},initialValue:\"auto\"},indentedSoftWrap:{set:function(){this.$useWrapMode&&(this.$useWrapMode=!1,this.setUseWrapMode(!0))},initialValue:!0},firstLineNumber:{set:function(){this._signal(\"changeBreakpoint\")},initialValue:1},useWorker:{set:function(e){this.$useWorker=e,this.$stopWorker(),e&&this.$startWorker()},initialValue:!0},useSoftTabs:{initialValue:!0},tabSize:{set:function(e){e=parseInt(e),e>0&&this.$tabSize!==e&&(this.$modified=!0,this.$rowLengthCache=[],this.$tabSize=e,this._signal(\"changeTabSize\"))},initialValue:4,handlesSet:!0},navigateWithinSoftTabs:{initialValue:!1},foldStyle:{set:function(e){this.setFoldStyle(e)},handlesSet:!0},overwrite:{set:function(e){this._signal(\"changeOverwrite\")},initialValue:!1},newLineMode:{set:function(e){this.doc.setNewLineMode(e)},get:function(){return this.doc.getNewLineMode()},handlesSet:!0},mode:{set:function(e){this.setMode(e)},get:function(){return this.$modeId},handlesSet:!0}}),t.EditSession=d}),ace.define(\"ace/search\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/lib/oop\",\"ace/range\"],function(e,t,n){\"use strict\";function u(e,t){function n(e){return/\\w/.test(e)||t.regExp?\"\\\\b\":\"\"}return n(e[0])+e+n(e[e.length-1])}var r=e(\"./lib/lang\"),i=e(\"./lib/oop\"),s=e(\"./range\").Range,o=function(){this.$options={}};(function(){this.set=function(e){return i.mixin(this.$options,e),this},this.getOptions=function(){return r.copyObject(this.$options)},this.setOptions=function(e){this.$options=e},this.find=function(e){var t=this.$options,n=this.$matchIterator(e,t);if(!n)return!1;var r=null;return n.forEach(function(e,n,i,o){return r=new s(e,n,i,o),n==o&&t.start&&t.start.start&&t.skipCurrent!=0&&r.isEqual(t.start)?(r=null,!1):!0}),r},this.findAll=function(e){var t=this.$options;if(!t.needle)return[];this.$assembleRegExp(t);var n=t.range,i=n?e.getLines(n.start.row,n.end.row):e.doc.getAllLines(),o=[],u=t.re;if(t.$isMultiLine){var a=u.length,f=i.length-a,l;e:for(var c=u.offset||0;c<=f;c++){for(var h=0;h<a;h++)if(i[c+h].search(u[h])==-1)continue e;var p=i[c],d=i[c+a-1],v=p.length-p.match(u[0])[0].length,m=d.match(u[a-1])[0].length;if(l&&l.end.row===c&&l.end.column>v)continue;o.push(l=new s(c,v,c+a-1,m)),a>2&&(c=c+a-2)}}else for(var g=0;g<i.length;g++){var y=r.getMatchOffsets(i[g],u);for(var h=0;h<y.length;h++){var b=y[h];o.push(new s(g,b.offset,g,b.offset+b.length))}}if(n){var w=n.start.column,E=n.start.column,g=0,h=o.length-1;while(g<h&&o[g].start.column<w&&o[g].start.row==n.start.row)g++;while(g<h&&o[h].end.column>E&&o[h].end.row==n.end.row)h--;o=o.slice(g,h+1);for(g=0,h=o.length;g<h;g++)o[g].start.row+=n.start.row,o[g].end.row+=n.start.row}return o},this.replace=function(e,t){var n=this.$options,r=this.$assembleRegExp(n);if(n.$isMultiLine)return t;if(!r)return;var i=r.exec(e);if(!i||i[0].length!=e.length)return null;t=e.replace(r,t);if(n.preserveCase){t=t.split(\"\");for(var s=Math.min(e.length,e.length);s--;){var o=e[s];o&&o.toLowerCase()!=o?t[s]=t[s].toUpperCase():t[s]=t[s].toLowerCase()}t=t.join(\"\")}return t},this.$assembleRegExp=function(e,t){if(e.needle instanceof RegExp)return e.re=e.needle;var n=e.needle;if(!e.needle)return e.re=!1;e.regExp||(n=r.escapeRegExp(n)),e.wholeWord&&(n=u(n,e));var i=e.caseSensitive?\"gm\":\"gmi\";e.$isMultiLine=!t&&/[\\n\\r]/.test(n);if(e.$isMultiLine)return e.re=this.$assembleMultilineRegExp(n,i);try{var s=new RegExp(n,i)}catch(o){s=!1}return e.re=s},this.$assembleMultilineRegExp=function(e,t){var n=e.replace(/\\r\\n|\\r|\\n/g,\"$\\n^\").split(\"\\n\"),r=[];for(var i=0;i<n.length;i++)try{r.push(new RegExp(n[i],t))}catch(s){return!1}return r},this.$matchIterator=function(e,t){var n=this.$assembleRegExp(t);if(!n)return!1;var r=t.backwards==1,i=t.skipCurrent!=0,s=t.range,o=t.start;o||(o=s?s[r?\"end\":\"start\"]:e.selection.getRange()),o.start&&(o=o[i!=r?\"end\":\"start\"]);var u=s?s.start.row:0,a=s?s.end.row:e.getLength()-1;if(r)var f=function(e){var n=o.row;if(c(n,o.column,e))return;for(n--;n>=u;n--)if(c(n,Number.MAX_VALUE,e))return;if(t.wrap==0)return;for(n=a,u=o.row;n>=u;n--)if(c(n,Number.MAX_VALUE,e))return};else var f=function(e){var n=o.row;if(c(n,o.column,e))return;for(n+=1;n<=a;n++)if(c(n,0,e))return;if(t.wrap==0)return;for(n=u,a=o.row;n<=a;n++)if(c(n,0,e))return};if(t.$isMultiLine)var l=n.length,c=function(t,i,s){var o=r?t-l+1:t;if(o<0)return;var u=e.getLine(o),a=u.search(n[0]);if(!r&&a<i||a===-1)return;for(var f=1;f<l;f++){u=e.getLine(o+f);if(u.search(n[f])==-1)return}var c=u.match(n[l-1])[0].length;if(r&&c>i)return;if(s(o,a,o+l-1,c))return!0};else if(r)var c=function(t,r,i){var s=e.getLine(t),o=[],u,a=0;n.lastIndex=0;while(u=n.exec(s)){var f=u[0].length;a=u.index;if(!f){if(a>=s.length)break;n.lastIndex=a+=1}if(u.index+f>r)break;o.push(u.index,f)}for(var l=o.length-1;l>=0;l-=2){var c=o[l-1],f=o[l];if(i(t,c,t,c+f))return!0}};else var c=function(t,r,i){var s=e.getLine(t),o,u;n.lastIndex=r;while(u=n.exec(s)){var a=u[0].length;o=u.index;if(i(t,o,t,o+a))return!0;if(!a){n.lastIndex=o+=1;if(o>=s.length)return!1}}};return{forEach:f}}}).call(o.prototype),t.Search=o}),ace.define(\"ace/keyboard/hash_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/keys\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";function o(e,t){this.platform=t||(i.isMac?\"mac\":\"win\"),this.commands={},this.commandKeyBinding={},this.addCommands(e),this.$singleCommand=!0}function u(e,t){o.call(this,e,t),this.$singleCommand=!1}var r=e(\"../lib/keys\"),i=e(\"../lib/useragent\"),s=r.KEY_MODS;u.prototype=o.prototype,function(){function e(e){return typeof e==\"object\"&&e.bindKey&&e.bindKey.position||(e.isDefault?-100:0)}this.addCommand=function(e){this.commands[e.name]&&this.removeCommand(e),this.commands[e.name]=e,e.bindKey&&this._buildKeyHash(e)},this.removeCommand=function(e,t){var n=e&&(typeof e==\"string\"?e:e.name);e=this.commands[n],t||delete this.commands[n];var r=this.commandKeyBinding;for(var i in r){var s=r[i];if(s==e)delete r[i];else if(Array.isArray(s)){var o=s.indexOf(e);o!=-1&&(s.splice(o,1),s.length==1&&(r[i]=s[0]))}}},this.bindKey=function(e,t,n){typeof e==\"object\"&&e&&(n==undefined&&(n=e.position),e=e[this.platform]);if(!e)return;if(typeof t==\"function\")return this.addCommand({exec:t,bindKey:e,name:t.name||e});e.split(\"|\").forEach(function(e){var r=\"\";if(e.indexOf(\" \")!=-1){var i=e.split(/\\s+/);e=i.pop(),i.forEach(function(e){var t=this.parseKeys(e),n=s[t.hashId]+t.key;r+=(r?\" \":\"\")+n,this._addCommandToBinding(r,\"chainKeys\")},this),r+=\" \"}var o=this.parseKeys(e),u=s[o.hashId]+o.key;this._addCommandToBinding(r+u,t,n)},this)},this._addCommandToBinding=function(t,n,r){var i=this.commandKeyBinding,s;if(!n)delete i[t];else if(!i[t]||this.$singleCommand)i[t]=n;else{Array.isArray(i[t])?(s=i[t].indexOf(n))!=-1&&i[t].splice(s,1):i[t]=[i[t]],typeof r!=\"number\"&&(r=e(n));var o=i[t];for(s=0;s<o.length;s++){var u=o[s],a=e(u);if(a>r)break}o.splice(s,0,n)}},this.addCommands=function(e){e&&Object.keys(e).forEach(function(t){var n=e[t];if(!n)return;if(typeof n==\"string\")return this.bindKey(n,t);typeof n==\"function\"&&(n={exec:n});if(typeof n!=\"object\")return;n.name||(n.name=t),this.addCommand(n)},this)},this.removeCommands=function(e){Object.keys(e).forEach(function(t){this.removeCommand(e[t])},this)},this.bindKeys=function(e){Object.keys(e).forEach(function(t){this.bindKey(t,e[t])},this)},this._buildKeyHash=function(e){this.bindKey(e.bindKey,e)},this.parseKeys=function(e){var t=e.toLowerCase().split(/[\\-\\+]([\\-\\+])?/).filter(function(e){return e}),n=t.pop(),i=r[n];if(r.FUNCTION_KEYS[i])n=r.FUNCTION_KEYS[i].toLowerCase();else{if(!t.length)return{key:n,hashId:-1};if(t.length==1&&t[0]==\"shift\")return{key:n.toUpperCase(),hashId:-1}}var s=0;for(var o=t.length;o--;){var u=r.KEY_MODS[t[o]];if(u==null)return typeof console!=\"undefined\"&&console.error(\"invalid modifier \"+t[o]+\" in \"+e),!1;s|=u}return{key:n,hashId:s}},this.findKeyCommand=function(t,n){var r=s[t]+n;return this.commandKeyBinding[r]},this.handleKeyboard=function(e,t,n,r){if(r<0)return;var i=s[t]+n,o=this.commandKeyBinding[i];e.$keyChain&&(e.$keyChain+=\" \"+i,o=this.commandKeyBinding[e.$keyChain]||o);if(o)if(o==\"chainKeys\"||o[o.length-1]==\"chainKeys\")return e.$keyChain=e.$keyChain||i,{command:\"null\"};if(e.$keyChain)if(!!t&&t!=4||n.length!=1){if(t==-1||r>0)e.$keyChain=\"\"}else e.$keyChain=e.$keyChain.slice(0,-i.length-1);return{command:o}},this.getStatusText=function(e,t){return t.$keyChain||\"\"}}.call(o.prototype),t.HashHandler=o,t.MultiHashHandler=u}),ace.define(\"ace/commands/command_manager\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/keyboard/hash_handler\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"../keyboard/hash_handler\").MultiHashHandler,s=e(\"../lib/event_emitter\").EventEmitter,o=function(e,t){i.call(this,t,e),this.byName=this.commands,this.setDefaultHandler(\"exec\",function(e){return e.command.exec(e.editor,e.args||{})})};r.inherits(o,i),function(){r.implement(this,s),this.exec=function(e,t,n){if(Array.isArray(e)){for(var r=e.length;r--;)if(this.exec(e[r],t,n))return!0;return!1}typeof e==\"string\"&&(e=this.commands[e]);if(!e)return!1;if(t&&t.$readOnly&&!e.readOnly)return!1;if(this.$checkCommandState!=0&&e.isAvailable&&!e.isAvailable(t))return!1;var i={editor:t,command:e,args:n};return i.returnValue=this._emit(\"exec\",i),this._signal(\"afterExec\",i),i.returnValue===!1?!1:!0},this.toggleRecording=function(e){if(this.$inReplay)return;return e&&e._emit(\"changeStatus\"),this.recording?(this.macro.pop(),this.removeEventListener(\"exec\",this.$addCommandToMacro),this.macro.length||(this.macro=this.oldMacro),this.recording=!1):(this.$addCommandToMacro||(this.$addCommandToMacro=function(e){this.macro.push([e.command,e.args])}.bind(this)),this.oldMacro=this.macro,this.macro=[],this.on(\"exec\",this.$addCommandToMacro),this.recording=!0)},this.replay=function(e){if(this.$inReplay||!this.macro)return;if(this.recording)return this.toggleRecording(e);try{this.$inReplay=!0,this.macro.forEach(function(t){typeof t==\"string\"?this.exec(t,e):this.exec(t[0],e,t[1])},this)}finally{this.$inReplay=!1}},this.trimMacro=function(e){return e.map(function(e){return typeof e[0]!=\"string\"&&(e[0]=e[0].name),e[1]||(e=e[0]),e})}}.call(o.prototype),t.CommandManager=o}),ace.define(\"ace/commands/default_commands\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/config\",\"ace/range\"],function(e,t,n){\"use strict\";function o(e,t){return{win:e,mac:t}}var r=e(\"../lib/lang\"),i=e(\"../config\"),s=e(\"../range\").Range;t.commands=[{name:\"showSettingsMenu\",bindKey:o(\"Ctrl-,\",\"Command-,\"),exec:function(e){i.loadModule(\"ace/ext/settings_menu\",function(t){t.init(e),e.showSettingsMenu()})},readOnly:!0},{name:\"goToNextError\",bindKey:o(\"Alt-E\",\"F4\"),exec:function(e){i.loadModule(\"./ext/error_marker\",function(t){t.showErrorMarker(e,1)})},scrollIntoView:\"animate\",readOnly:!0},{name:\"goToPreviousError\",bindKey:o(\"Alt-Shift-E\",\"Shift-F4\"),exec:function(e){i.loadModule(\"./ext/error_marker\",function(t){t.showErrorMarker(e,-1)})},scrollIntoView:\"animate\",readOnly:!0},{name:\"selectall\",description:\"Select all\",bindKey:o(\"Ctrl-A\",\"Command-A\"),exec:function(e){e.selectAll()},readOnly:!0},{name:\"centerselection\",description:\"Center selection\",bindKey:o(null,\"Ctrl-L\"),exec:function(e){e.centerSelection()},readOnly:!0},{name:\"gotoline\",description:\"Go to line...\",bindKey:o(\"Ctrl-L\",\"Command-L\"),exec:function(e,t){typeof t==\"number\"&&!isNaN(t)&&e.gotoLine(t),e.prompt({$type:\"gotoLine\"})},readOnly:!0},{name:\"fold\",bindKey:o(\"Alt-L|Ctrl-F1\",\"Command-Alt-L|Command-F1\"),exec:function(e){e.session.toggleFold(!1)},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"unfold\",bindKey:o(\"Alt-Shift-L|Ctrl-Shift-F1\",\"Command-Alt-Shift-L|Command-Shift-F1\"),exec:function(e){e.session.toggleFold(!0)},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"toggleFoldWidget\",bindKey:o(\"F2\",\"F2\"),exec:function(e){e.session.toggleFoldWidget()},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"toggleParentFoldWidget\",bindKey:o(\"Alt-F2\",\"Alt-F2\"),exec:function(e){e.session.toggleFoldWidget(!0)},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"foldall\",description:\"Fold all\",bindKey:o(null,\"Ctrl-Command-Option-0\"),exec:function(e){e.session.foldAll()},scrollIntoView:\"center\",readOnly:!0},{name:\"foldOther\",description:\"Fold other\",bindKey:o(\"Alt-0\",\"Command-Option-0\"),exec:function(e){e.session.foldAll(),e.session.unfold(e.selection.getAllRanges())},scrollIntoView:\"center\",readOnly:!0},{name:\"unfoldall\",description:\"Unfold all\",bindKey:o(\"Alt-Shift-0\",\"Command-Option-Shift-0\"),exec:function(e){e.session.unfold()},scrollIntoView:\"center\",readOnly:!0},{name:\"findnext\",description:\"Find next\",bindKey:o(\"Ctrl-K\",\"Command-G\"),exec:function(e){e.findNext()},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"findprevious\",description:\"Find previous\",bindKey:o(\"Ctrl-Shift-K\",\"Command-Shift-G\"),exec:function(e){e.findPrevious()},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"selectOrFindNext\",description:\"Select or find next\",bindKey:o(\"Alt-K\",\"Ctrl-G\"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findNext()},readOnly:!0},{name:\"selectOrFindPrevious\",description:\"Select or find previous\",bindKey:o(\"Alt-Shift-K\",\"Ctrl-Shift-G\"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findPrevious()},readOnly:!0},{name:\"find\",description:\"Find\",bindKey:o(\"Ctrl-F\",\"Command-F\"),exec:function(e){i.loadModule(\"ace/ext/searchbox\",function(t){t.Search(e)})},readOnly:!0},{name:\"overwrite\",description:\"Overwrite\",bindKey:\"Insert\",exec:function(e){e.toggleOverwrite()},readOnly:!0},{name:\"selecttostart\",description:\"Select to start\",bindKey:o(\"Ctrl-Shift-Home\",\"Command-Shift-Home|Command-Shift-Up\"),exec:function(e){e.getSelection().selectFileStart()},multiSelectAction:\"forEach\",readOnly:!0,scrollIntoView:\"animate\",aceCommandGroup:\"fileJump\"},{name:\"gotostart\",description:\"Go to start\",bindKey:o(\"Ctrl-Home\",\"Command-Home|Command-Up\"),exec:function(e){e.navigateFileStart()},multiSelectAction:\"forEach\",readOnly:!0,scrollIntoView:\"animate\",aceCommandGroup:\"fileJump\"},{name:\"selectup\",description:\"Select up\",bindKey:o(\"Shift-Up\",\"Shift-Up|Ctrl-Shift-P\"),exec:function(e){e.getSelection().selectUp()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"golineup\",description:\"Go line up\",bindKey:o(\"Up\",\"Up|Ctrl-P\"),exec:function(e,t){e.navigateUp(t.times)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selecttoend\",description:\"Select to end\",bindKey:o(\"Ctrl-Shift-End\",\"Command-Shift-End|Command-Shift-Down\"),exec:function(e){e.getSelection().selectFileEnd()},multiSelectAction:\"forEach\",readOnly:!0,scrollIntoView:\"animate\",aceCommandGroup:\"fileJump\"},{name:\"gotoend\",description:\"Go to end\",bindKey:o(\"Ctrl-End\",\"Command-End|Command-Down\"),exec:function(e){e.navigateFileEnd()},multiSelectAction:\"forEach\",readOnly:!0,scrollIntoView:\"animate\",aceCommandGroup:\"fileJump\"},{name:\"selectdown\",description:\"Select down\",bindKey:o(\"Shift-Down\",\"Shift-Down|Ctrl-Shift-N\"),exec:function(e){e.getSelection().selectDown()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"golinedown\",description:\"Go line down\",bindKey:o(\"Down\",\"Down|Ctrl-N\"),exec:function(e,t){e.navigateDown(t.times)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectwordleft\",description:\"Select word left\",bindKey:o(\"Ctrl-Shift-Left\",\"Option-Shift-Left\"),exec:function(e){e.getSelection().selectWordLeft()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotowordleft\",description:\"Go to word left\",bindKey:o(\"Ctrl-Left\",\"Option-Left\"),exec:function(e){e.navigateWordLeft()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selecttolinestart\",description:\"Select to line start\",bindKey:o(\"Alt-Shift-Left\",\"Command-Shift-Left|Ctrl-Shift-A\"),exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotolinestart\",description:\"Go to line start\",bindKey:o(\"Alt-Left|Home\",\"Command-Left|Home|Ctrl-A\"),exec:function(e){e.navigateLineStart()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectleft\",description:\"Select left\",bindKey:o(\"Shift-Left\",\"Shift-Left|Ctrl-Shift-B\"),exec:function(e){e.getSelection().selectLeft()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotoleft\",description:\"Go to left\",bindKey:o(\"Left\",\"Left|Ctrl-B\"),exec:function(e,t){e.navigateLeft(t.times)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectwordright\",description:\"Select word right\",bindKey:o(\"Ctrl-Shift-Right\",\"Option-Shift-Right\"),exec:function(e){e.getSelection().selectWordRight()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotowordright\",description:\"Go to word right\",bindKey:o(\"Ctrl-Right\",\"Option-Right\"),exec:function(e){e.navigateWordRight()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selecttolineend\",description:\"Select to line end\",bindKey:o(\"Alt-Shift-Right\",\"Command-Shift-Right|Shift-End|Ctrl-Shift-E\"),exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotolineend\",description:\"Go to line end\",bindKey:o(\"Alt-Right|End\",\"Command-Right|End|Ctrl-E\"),exec:function(e){e.navigateLineEnd()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectright\",description:\"Select right\",bindKey:o(\"Shift-Right\",\"Shift-Right\"),exec:function(e){e.getSelection().selectRight()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotoright\",description:\"Go to right\",bindKey:o(\"Right\",\"Right|Ctrl-F\"),exec:function(e,t){e.navigateRight(t.times)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectpagedown\",description:\"Select page down\",bindKey:\"Shift-PageDown\",exec:function(e){e.selectPageDown()},readOnly:!0},{name:\"pagedown\",description:\"Page down\",bindKey:o(null,\"Option-PageDown\"),exec:function(e){e.scrollPageDown()},readOnly:!0},{name:\"gotopagedown\",description:\"Go to page down\",bindKey:o(\"PageDown\",\"PageDown|Ctrl-V\"),exec:function(e){e.gotoPageDown()},readOnly:!0},{name:\"selectpageup\",description:\"Select page up\",bindKey:\"Shift-PageUp\",exec:function(e){e.selectPageUp()},readOnly:!0},{name:\"pageup\",description:\"Page up\",bindKey:o(null,\"Option-PageUp\"),exec:function(e){e.scrollPageUp()},readOnly:!0},{name:\"gotopageup\",description:\"Go to page up\",bindKey:\"PageUp\",exec:function(e){e.gotoPageUp()},readOnly:!0},{name:\"scrollup\",description:\"Scroll up\",bindKey:o(\"Ctrl-Up\",null),exec:function(e){e.renderer.scrollBy(0,-2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:\"scrolldown\",description:\"Scroll down\",bindKey:o(\"Ctrl-Down\",null),exec:function(e){e.renderer.scrollBy(0,2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:\"selectlinestart\",description:\"Select line start\",bindKey:\"Shift-Home\",exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectlineend\",description:\"Select line end\",bindKey:\"Shift-End\",exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"togglerecording\",description:\"Toggle recording\",bindKey:o(\"Ctrl-Alt-E\",\"Command-Option-E\"),exec:function(e){e.commands.toggleRecording(e)},readOnly:!0},{name:\"replaymacro\",description:\"Replay macro\",bindKey:o(\"Ctrl-Shift-E\",\"Command-Shift-E\"),exec:function(e){e.commands.replay(e)},readOnly:!0},{name:\"jumptomatching\",description:\"Jump to matching\",bindKey:o(\"Ctrl-\\\\|Ctrl-P\",\"Command-\\\\\"),exec:function(e){e.jumpToMatching()},multiSelectAction:\"forEach\",scrollIntoView:\"animate\",readOnly:!0},{name:\"selecttomatching\",description:\"Select to matching\",bindKey:o(\"Ctrl-Shift-\\\\|Ctrl-Shift-P\",\"Command-Shift-\\\\\"),exec:function(e){e.jumpToMatching(!0)},multiSelectAction:\"forEach\",scrollIntoView:\"animate\",readOnly:!0},{name:\"expandToMatching\",description:\"Expand to matching\",bindKey:o(\"Ctrl-Shift-M\",\"Ctrl-Shift-M\"),exec:function(e){e.jumpToMatching(!0,!0)},multiSelectAction:\"forEach\",scrollIntoView:\"animate\",readOnly:!0},{name:\"passKeysToBrowser\",description:\"Pass keys to browser\",bindKey:o(null,null),exec:function(){},passEvent:!0,readOnly:!0},{name:\"copy\",description:\"Copy\",exec:function(e){},readOnly:!0},{name:\"cut\",description:\"Cut\",exec:function(e){var t=e.$copyWithEmptySelection&&e.selection.isEmpty(),n=t?e.selection.getLineRange():e.selection.getRange();e._emit(\"cut\",n),n.isEmpty()||e.session.remove(n),e.clearSelection()},scrollIntoView:\"cursor\",multiSelectAction:\"forEach\"},{name:\"paste\",description:\"Paste\",exec:function(e,t){e.$handlePaste(t)},scrollIntoView:\"cursor\"},{name:\"removeline\",description:\"Remove line\",bindKey:o(\"Ctrl-D\",\"Command-D\"),exec:function(e){e.removeLines()},scrollIntoView:\"cursor\",multiSelectAction:\"forEachLine\"},{name:\"duplicateSelection\",description:\"Duplicate selection\",bindKey:o(\"Ctrl-Shift-D\",\"Command-Shift-D\"),exec:function(e){e.duplicateSelection()},scrollIntoView:\"cursor\",multiSelectAction:\"forEach\"},{name:\"sortlines\",description:\"Sort lines\",bindKey:o(\"Ctrl-Alt-S\",\"Command-Alt-S\"),exec:function(e){e.sortLines()},scrollIntoView:\"selection\",multiSelectAction:\"forEachLine\"},{name:\"togglecomment\",description:\"Toggle comment\",bindKey:o(\"Ctrl-/\",\"Command-/\"),exec:function(e){e.toggleCommentLines()},multiSelectAction:\"forEachLine\",scrollIntoView:\"selectionPart\"},{name:\"toggleBlockComment\",description:\"Toggle block comment\",bindKey:o(\"Ctrl-Shift-/\",\"Command-Shift-/\"),exec:function(e){e.toggleBlockComment()},multiSelectAction:\"forEach\",scrollIntoView:\"selectionPart\"},{name:\"modifyNumberUp\",description:\"Modify number up\",bindKey:o(\"Ctrl-Shift-Up\",\"Alt-Shift-Up\"),exec:function(e){e.modifyNumber(1)},scrollIntoView:\"cursor\",multiSelectAction:\"forEach\"},{name:\"modifyNumberDown\",description:\"Modify number down\",bindKey:o(\"Ctrl-Shift-Down\",\"Alt-Shift-Down\"),exec:function(e){e.modifyNumber(-1)},scrollIntoView:\"cursor\",multiSelectAction:\"forEach\"},{name:\"replace\",description:\"Replace\",bindKey:o(\"Ctrl-H\",\"Command-Option-F\"),exec:function(e){i.loadModule(\"ace/ext/searchbox\",function(t){t.Search(e,!0)})}},{name:\"undo\",description:\"Undo\",bindKey:o(\"Ctrl-Z\",\"Command-Z\"),exec:function(e){e.undo()}},{name:\"redo\",description:\"Redo\",bindKey:o(\"Ctrl-Shift-Z|Ctrl-Y\",\"Command-Shift-Z|Command-Y\"),exec:function(e){e.redo()}},{name:\"copylinesup\",description:\"Copy lines up\",bindKey:o(\"Alt-Shift-Up\",\"Command-Option-Up\"),exec:function(e){e.copyLinesUp()},scrollIntoView:\"cursor\"},{name:\"movelinesup\",description:\"Move lines up\",bindKey:o(\"Alt-Up\",\"Option-Up\"),exec:function(e){e.moveLinesUp()},scrollIntoView:\"cursor\"},{name:\"copylinesdown\",description:\"Copy lines down\",bindKey:o(\"Alt-Shift-Down\",\"Command-Option-Down\"),exec:function(e){e.copyLinesDown()},scrollIntoView:\"cursor\"},{name:\"movelinesdown\",description:\"Move lines down\",bindKey:o(\"Alt-Down\",\"Option-Down\"),exec:function(e){e.moveLinesDown()},scrollIntoView:\"cursor\"},{name:\"del\",description:\"Delete\",bindKey:o(\"Delete\",\"Delete|Ctrl-D|Shift-Delete\"),exec:function(e){e.remove(\"right\")},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"backspace\",description:\"Backspace\",bindKey:o(\"Shift-Backspace|Backspace\",\"Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H\"),exec:function(e){e.remove(\"left\")},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"cut_or_delete\",description:\"Cut or delete\",bindKey:o(\"Shift-Delete\",null),exec:function(e){if(!e.selection.isEmpty())return!1;e.remove(\"left\")},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removetolinestart\",description:\"Remove to line start\",bindKey:o(\"Alt-Backspace\",\"Command-Backspace\"),exec:function(e){e.removeToLineStart()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removetolineend\",description:\"Remove to line end\",bindKey:o(\"Alt-Delete\",\"Ctrl-K|Command-Delete\"),exec:function(e){e.removeToLineEnd()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removetolinestarthard\",description:\"Remove to line start hard\",bindKey:o(\"Ctrl-Shift-Backspace\",null),exec:function(e){var t=e.selection.getRange();t.start.column=0,e.session.remove(t)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removetolineendhard\",description:\"Remove to line end hard\",bindKey:o(\"Ctrl-Shift-Delete\",null),exec:function(e){var t=e.selection.getRange();t.end.column=Number.MAX_VALUE,e.session.remove(t)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removewordleft\",description:\"Remove word left\",bindKey:o(\"Ctrl-Backspace\",\"Alt-Backspace|Ctrl-Alt-Backspace\"),exec:function(e){e.removeWordLeft()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removewordright\",description:\"Remove word right\",bindKey:o(\"Ctrl-Delete\",\"Alt-Delete\"),exec:function(e){e.removeWordRight()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"outdent\",description:\"Outdent\",bindKey:o(\"Shift-Tab\",\"Shift-Tab\"),exec:function(e){e.blockOutdent()},multiSelectAction:\"forEach\",scrollIntoView:\"selectionPart\"},{name:\"indent\",description:\"Indent\",bindKey:o(\"Tab\",\"Tab\"),exec:function(e){e.indent()},multiSelectAction:\"forEach\",scrollIntoView:\"selectionPart\"},{name:\"blockoutdent\",description:\"Block outdent\",bindKey:o(\"Ctrl-[\",\"Ctrl-[\"),exec:function(e){e.blockOutdent()},multiSelectAction:\"forEachLine\",scrollIntoView:\"selectionPart\"},{name:\"blockindent\",description:\"Block indent\",bindKey:o(\"Ctrl-]\",\"Ctrl-]\"),exec:function(e){e.blockIndent()},multiSelectAction:\"forEachLine\",scrollIntoView:\"selectionPart\"},{name:\"insertstring\",description:\"Insert string\",exec:function(e,t){e.insert(t)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"inserttext\",description:\"Insert text\",exec:function(e,t){e.insert(r.stringRepeat(t.text||\"\",t.times||1))},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"splitline\",description:\"Split line\",bindKey:o(null,\"Ctrl-O\"),exec:function(e){e.splitLine()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"transposeletters\",description:\"Transpose letters\",bindKey:o(\"Alt-Shift-X\",\"Ctrl-T\"),exec:function(e){e.transposeLetters()},multiSelectAction:function(e){e.transposeSelections(1)},scrollIntoView:\"cursor\"},{name:\"touppercase\",description:\"To uppercase\",bindKey:o(\"Ctrl-U\",\"Ctrl-U\"),exec:function(e){e.toUpperCase()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"tolowercase\",description:\"To lowercase\",bindKey:o(\"Ctrl-Shift-U\",\"Ctrl-Shift-U\"),exec:function(e){e.toLowerCase()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"expandtoline\",description:\"Expand to line\",bindKey:o(\"Ctrl-Shift-L\",\"Command-Shift-L\"),exec:function(e){var t=e.selection.getRange();t.start.column=t.end.column=0,t.end.row++,e.selection.setRange(t,!1)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"joinlines\",description:\"Join lines\",bindKey:o(null,null),exec:function(e){var t=e.selection.isBackwards(),n=t?e.selection.getSelectionLead():e.selection.getSelectionAnchor(),i=t?e.selection.getSelectionAnchor():e.selection.getSelectionLead(),o=e.session.doc.getLine(n.row).length,u=e.session.doc.getTextRange(e.selection.getRange()),a=u.replace(/\\n\\s*/,\" \").length,f=e.session.doc.getLine(n.row);for(var l=n.row+1;l<=i.row+1;l++){var c=r.stringTrimLeft(r.stringTrimRight(e.session.doc.getLine(l)));c.length!==0&&(c=\" \"+c),f+=c}i.row+1<e.session.doc.getLength()-1&&(f+=e.session.doc.getNewLineCharacter()),e.clearSelection(),e.session.doc.replace(new s(n.row,0,i.row+2,0),f),a>0?(e.selection.moveCursorTo(n.row,n.column),e.selection.selectTo(n.row,n.column+a)):(o=e.session.doc.getLine(n.row).length>o?o+1:o,e.selection.moveCursorTo(n.row,o))},multiSelectAction:\"forEach\",readOnly:!0},{name:\"invertSelection\",description:\"Invert selection\",bindKey:o(null,null),exec:function(e){var t=e.session.doc.getLength()-1,n=e.session.doc.getLine(t).length,r=e.selection.rangeList.ranges,i=[];r.length<1&&(r=[e.selection.getRange()]);for(var o=0;o<r.length;o++)o==r.length-1&&(r[o].end.row!==t||r[o].end.column!==n)&&i.push(new s(r[o].end.row,r[o].end.column,t,n)),o===0?(r[o].start.row!==0||r[o].start.column!==0)&&i.push(new s(0,0,r[o].start.row,r[o].start.column)):i.push(new s(r[o-1].end.row,r[o-1].end.column,r[o].start.row,r[o].start.column));e.exitMultiSelectMode(),e.clearSelection();for(var o=0;o<i.length;o++)e.selection.addRange(i[o],!1)},readOnly:!0,scrollIntoView:\"none\"},{name:\"openCommandPallete\",description:\"Open command pallete\",bindKey:o(\"F1\",\"F1\"),exec:function(e){e.prompt({$type:\"commands\"})},readOnly:!0},{name:\"modeSelect\",description:\"Change language mode...\",bindKey:o(null,null),exec:function(e){e.prompt({$type:\"modes\"})},readOnly:!0}]}),ace.define(\"ace/editor\",[\"require\",\"exports\",\"module\",\"ace/lib/fixoldbrowsers\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/lib/useragent\",\"ace/keyboard/textinput\",\"ace/mouse/mouse_handler\",\"ace/mouse/fold_handler\",\"ace/keyboard/keybinding\",\"ace/edit_session\",\"ace/search\",\"ace/range\",\"ace/lib/event_emitter\",\"ace/commands/command_manager\",\"ace/commands/default_commands\",\"ace/config\",\"ace/token_iterator\",\"ace/clipboard\"],function(e,t,n){\"use strict\";e(\"./lib/fixoldbrowsers\");var r=e(\"./lib/oop\"),i=e(\"./lib/dom\"),s=e(\"./lib/lang\"),o=e(\"./lib/useragent\"),u=e(\"./keyboard/textinput\").TextInput,a=e(\"./mouse/mouse_handler\").MouseHandler,f=e(\"./mouse/fold_handler\").FoldHandler,l=e(\"./keyboard/keybinding\").KeyBinding,c=e(\"./edit_session\").EditSession,h=e(\"./search\").Search,p=e(\"./range\").Range,d=e(\"./lib/event_emitter\").EventEmitter,v=e(\"./commands/command_manager\").CommandManager,m=e(\"./commands/default_commands\").commands,g=e(\"./config\"),y=e(\"./token_iterator\").TokenIterator,b=e(\"./clipboard\"),w=function(e,t,n){var r=e.getContainerElement();this.container=r,this.renderer=e,this.id=\"editor\"+ ++w.$uid,this.commands=new v(o.isMac?\"mac\":\"win\",m),typeof document==\"object\"&&(this.textInput=new u(e.getTextAreaContainer(),this),this.renderer.textarea=this.textInput.getElement(),this.$mouseHandler=new a(this),new f(this)),this.keyBinding=new l(this),this.$search=(new h).set({wrap:!0}),this.$historyTracker=this.$historyTracker.bind(this),this.commands.on(\"exec\",this.$historyTracker),this.$initOperationListeners(),this._$emitInputEvent=s.delayedCall(function(){this._signal(\"input\",{}),this.session&&this.session.bgTokenizer&&this.session.bgTokenizer.scheduleStart()}.bind(this)),this.on(\"change\",function(e,t){t._$emitInputEvent.schedule(31)}),this.setSession(t||n&&n.session||new c(\"\")),g.resetOptions(this),n&&this.setOptions(n),g._signal(\"editor\",this)};w.$uid=0,function(){r.implement(this,d),this.$initOperationListeners=function(){this.commands.on(\"exec\",this.startOperation.bind(this),!0),this.commands.on(\"afterExec\",this.endOperation.bind(this),!0),this.$opResetTimer=s.delayedCall(this.endOperation.bind(this,!0)),this.on(\"change\",function(){this.curOp||(this.startOperation(),this.curOp.selectionBefore=this.$lastSel),this.curOp.docChanged=!0}.bind(this),!0),this.on(\"changeSelection\",function(){this.curOp||(this.startOperation(),this.curOp.selectionBefore=this.$lastSel),this.curOp.selectionChanged=!0}.bind(this),!0)},this.curOp=null,this.prevOp={},this.startOperation=function(e){if(this.curOp){if(!e||this.curOp.command)return;this.prevOp=this.curOp}e||(this.previousCommand=null,e={}),this.$opResetTimer.schedule(),this.curOp=this.session.curOp={command:e.command||{},args:e.args,scrollTop:this.renderer.scrollTop},this.curOp.selectionBefore=this.selection.toJSON()},this.endOperation=function(e){if(this.curOp){if(e&&e.returnValue===!1)return this.curOp=null;if(e==1&&this.curOp.command&&this.curOp.command.name==\"mouse\")return;this._signal(\"beforeEndOperation\");if(!this.curOp)return;var t=this.curOp.command,n=t&&t.scrollIntoView;if(n){switch(n){case\"center-animate\":n=\"animate\";case\"center\":this.renderer.scrollCursorIntoView(null,.5);break;case\"animate\":case\"cursor\":this.renderer.scrollCursorIntoView();break;case\"selectionPart\":var r=this.selection.getRange(),i=this.renderer.layerConfig;(r.start.row>=i.lastRow||r.end.row<=i.firstRow)&&this.renderer.scrollSelectionIntoView(this.selection.anchor,this.selection.lead);break;default:}n==\"animate\"&&this.renderer.animateScrolling(this.curOp.scrollTop)}var s=this.selection.toJSON();this.curOp.selectionAfter=s,this.$lastSel=this.selection.toJSON(),this.session.getUndoManager().addSelection(s),this.prevOp=this.curOp,this.curOp=null}},this.$mergeableCommands=[\"backspace\",\"del\",\"insertstring\"],this.$historyTracker=function(e){if(!this.$mergeUndoDeltas)return;var t=this.prevOp,n=this.$mergeableCommands,r=t.command&&e.command.name==t.command.name;if(e.command.name==\"insertstring\"){var i=e.args;this.mergeNextCommand===undefined&&(this.mergeNextCommand=!0),r=r&&this.mergeNextCommand&&(!/\\s/.test(i)||/\\s/.test(t.args)),this.mergeNextCommand=!0}else r=r&&n.indexOf(e.command.name)!==-1;this.$mergeUndoDeltas!=\"always\"&&Date.now()-this.sequenceStartTime>2e3&&(r=!1),r?this.session.mergeUndoDeltas=!0:n.indexOf(e.command.name)!==-1&&(this.sequenceStartTime=Date.now())},this.setKeyboardHandler=function(e,t){if(e&&typeof e==\"string\"&&e!=\"ace\"){this.$keybindingId=e;var n=this;g.loadModule([\"keybinding\",e],function(r){n.$keybindingId==e&&n.keyBinding.setKeyboardHandler(r&&r.handler),t&&t()})}else this.$keybindingId=null,this.keyBinding.setKeyboardHandler(e),t&&t()},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(e){if(this.session==e)return;this.curOp&&this.endOperation(),this.curOp={};var t=this.session;if(t){this.session.off(\"change\",this.$onDocumentChange),this.session.off(\"changeMode\",this.$onChangeMode),this.session.off(\"tokenizerUpdate\",this.$onTokenizerUpdate),this.session.off(\"changeTabSize\",this.$onChangeTabSize),this.session.off(\"changeWrapLimit\",this.$onChangeWrapLimit),this.session.off(\"changeWrapMode\",this.$onChangeWrapMode),this.session.off(\"changeFold\",this.$onChangeFold),this.session.off(\"changeFrontMarker\",this.$onChangeFrontMarker),this.session.off(\"changeBackMarker\",this.$onChangeBackMarker),this.session.off(\"changeBreakpoint\",this.$onChangeBreakpoint),this.session.off(\"changeAnnotation\",this.$onChangeAnnotation),this.session.off(\"changeOverwrite\",this.$onCursorChange),this.session.off(\"changeScrollTop\",this.$onScrollTopChange),this.session.off(\"changeScrollLeft\",this.$onScrollLeftChange);var n=this.session.getSelection();n.off(\"changeCursor\",this.$onCursorChange),n.off(\"changeSelection\",this.$onSelectionChange)}this.session=e,e?(this.$onDocumentChange=this.onDocumentChange.bind(this),e.on(\"change\",this.$onDocumentChange),this.renderer.setSession(e),this.$onChangeMode=this.onChangeMode.bind(this),e.on(\"changeMode\",this.$onChangeMode),this.$onTokenizerUpdate=this.onTokenizerUpdate.bind(this),e.on(\"tokenizerUpdate\",this.$onTokenizerUpdate),this.$onChangeTabSize=this.renderer.onChangeTabSize.bind(this.renderer),e.on(\"changeTabSize\",this.$onChangeTabSize),this.$onChangeWrapLimit=this.onChangeWrapLimit.bind(this),e.on(\"changeWrapLimit\",this.$onChangeWrapLimit),this.$onChangeWrapMode=this.onChangeWrapMode.bind(this),e.on(\"changeWrapMode\",this.$onChangeWrapMode),this.$onChangeFold=this.onChangeFold.bind(this),e.on(\"changeFold\",this.$onChangeFold),this.$onChangeFrontMarker=this.onChangeFrontMarker.bind(this),this.session.on(\"changeFrontMarker\",this.$onChangeFrontMarker),this.$onChangeBackMarker=this.onChangeBackMarker.bind(this),this.session.on(\"changeBackMarker\",this.$onChangeBackMarker),this.$onChangeBreakpoint=this.onChangeBreakpoint.bind(this),this.session.on(\"changeBreakpoint\",this.$onChangeBreakpoint),this.$onChangeAnnotation=this.onChangeAnnotation.bind(this),this.session.on(\"changeAnnotation\",this.$onChangeAnnotation),this.$onCursorChange=this.onCursorChange.bind(this),this.session.on(\"changeOverwrite\",this.$onCursorChange),this.$onScrollTopChange=this.onScrollTopChange.bind(this),this.session.on(\"changeScrollTop\",this.$onScrollTopChange),this.$onScrollLeftChange=this.onScrollLeftChange.bind(this),this.session.on(\"changeScrollLeft\",this.$onScrollLeftChange),this.selection=e.getSelection(),this.selection.on(\"changeCursor\",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.on(\"changeSelection\",this.$onSelectionChange),this.onChangeMode(),this.onCursorChange(),this.onScrollTopChange(),this.onScrollLeftChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onChangeBreakpoint(),this.onChangeAnnotation(),this.session.getUseWrapMode()&&this.renderer.adjustWrapLimit(),this.renderer.updateFull()):(this.selection=null,this.renderer.setSession(e)),this._signal(\"changeSession\",{session:e,oldSession:t}),this.curOp=null,t&&t._signal(\"changeEditor\",{oldEditor:this}),e&&e._signal(\"changeEditor\",{editor:this}),e&&e.bgTokenizer&&e.bgTokenizer.scheduleStart()},this.getSession=function(){return this.session},this.setValue=function(e,t){return this.session.doc.setValue(e),t?t==1?this.navigateFileEnd():t==-1&&this.navigateFileStart():this.selectAll(),e},this.getValue=function(){return this.session.getValue()},this.getSelection=function(){return this.selection},this.resize=function(e){this.renderer.onResize(e)},this.setTheme=function(e,t){this.renderer.setTheme(e,t)},this.getTheme=function(){return this.renderer.getTheme()},this.setStyle=function(e){this.renderer.setStyle(e)},this.unsetStyle=function(e){this.renderer.unsetStyle(e)},this.getFontSize=function(){return this.getOption(\"fontSize\")||i.computedStyle(this.container).fontSize},this.setFontSize=function(e){this.setOption(\"fontSize\",e)},this.$highlightBrackets=function(){this.session.$bracketHighlight&&(this.session.removeMarker(this.session.$bracketHighlight),this.session.$bracketHighlight=null);if(this.$highlightPending)return;var e=this;this.$highlightPending=!0,setTimeout(function(){e.$highlightPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=t.findMatchingBracket(e.getCursorPosition());if(n)var r=new p(n.row,n.column,n.row,n.column+1);else if(t.$mode.getMatching)var r=t.$mode.getMatching(e.session);r&&(t.$bracketHighlight=t.addMarker(r,\"ace_bracket\",\"text\"))},50)},this.$highlightTags=function(){if(this.$highlightTagPending)return;var e=this;this.$highlightTagPending=!0,setTimeout(function(){e.$highlightTagPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=e.getCursorPosition(),r=new y(e.session,n.row,n.column),i=r.getCurrentToken();if(!i||!/\\b(?:tag-open|tag-name)/.test(i.type)){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}if(i.type.indexOf(\"tag-open\")!=-1){i=r.stepForward();if(!i)return}var s=i.value,o=0,u=r.stepBackward();if(u.value==\"<\"){do u=i,i=r.stepForward(),i&&i.value===s&&i.type.indexOf(\"tag-name\")!==-1&&(u.value===\"<\"?o++:u.value===\"</\"&&o--);while(i&&o>=0)}else{do i=u,u=r.stepBackward(),i&&i.value===s&&i.type.indexOf(\"tag-name\")!==-1&&(u.value===\"<\"?o++:u.value===\"</\"&&o--);while(u&&o<=0);r.stepForward()}if(!i){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}var a=r.getCurrentTokenRow(),f=r.getCurrentTokenColumn(),l=new p(a,f,a,f+i.value.length),c=t.$backMarkers[t.$tagHighlight];t.$tagHighlight&&c!=undefined&&l.compareRange(c.range)!==0&&(t.removeMarker(t.$tagHighlight),t.$tagHighlight=null),t.$tagHighlight||(t.$tagHighlight=t.addMarker(l,\"ace_bracket\",\"text\"))},50)},this.focus=function(){var e=this;setTimeout(function(){e.isFocused()||e.textInput.focus()}),this.textInput.focus()},this.isFocused=function(){return this.textInput.isFocused()},this.blur=function(){this.textInput.blur()},this.onFocus=function(e){if(this.$isFocused)return;this.$isFocused=!0,this.renderer.showCursor(),this.renderer.visualizeFocus(),this._emit(\"focus\",e)},this.onBlur=function(e){if(!this.$isFocused)return;this.$isFocused=!1,this.renderer.hideCursor(),this.renderer.visualizeBlur(),this._emit(\"blur\",e)},this.$cursorChange=function(){this.renderer.updateCursor()},this.onDocumentChange=function(e){var t=this.session.$useWrapMode,n=e.start.row==e.end.row?e.end.row:Infinity;this.renderer.updateLines(e.start.row,n,t),this._signal(\"change\",e),this.$cursorChange(),this.$updateHighlightActiveLine()},this.onTokenizerUpdate=function(e){var t=e.data;this.renderer.updateLines(t.first,t.last)},this.onScrollTopChange=function(){this.renderer.scrollToY(this.session.getScrollTop())},this.onScrollLeftChange=function(){this.renderer.scrollToX(this.session.getScrollLeft())},this.onCursorChange=function(){this.$cursorChange(),this.$highlightBrackets(),this.$highlightTags(),this.$updateHighlightActiveLine(),this._signal(\"changeSelection\")},this.$updateHighlightActiveLine=function(){var e=this.getSession(),t;if(this.$highlightActiveLine){if(this.$selectionStyle!=\"line\"||!this.selection.isMultiLine())t=this.getCursorPosition();this.renderer.theme&&this.renderer.theme.$selectionColorConflict&&!this.selection.isEmpty()&&(t=!1),this.renderer.$maxLines&&this.session.getLength()===1&&!(this.renderer.$minLines>1)&&(t=!1)}if(e.$highlightLineMarker&&!t)e.removeMarker(e.$highlightLineMarker.id),e.$highlightLineMarker=null;else if(!e.$highlightLineMarker&&t){var n=new p(t.row,t.column,t.row,Infinity);n.id=e.addMarker(n,\"ace_active-line\",\"screenLine\"),e.$highlightLineMarker=n}else t&&(e.$highlightLineMarker.start.row=t.row,e.$highlightLineMarker.end.row=t.row,e.$highlightLineMarker.start.column=t.column,e._signal(\"changeBackMarker\"))},this.onSelectionChange=function(e){var t=this.session;t.$selectionMarker&&t.removeMarker(t.$selectionMarker),t.$selectionMarker=null;if(!this.selection.isEmpty()){var n=this.selection.getRange(),r=this.getSelectionStyle();t.$selectionMarker=t.addMarker(n,\"ace_selection\",r)}else this.$updateHighlightActiveLine();var i=this.$highlightSelectedWord&&this.$getSelectionHighLightRegexp();this.session.highlight(i),this._signal(\"changeSelection\")},this.$getSelectionHighLightRegexp=function(){var e=this.session,t=this.getSelectionRange();if(t.isEmpty()||t.isMultiLine())return;var n=t.start.column,r=t.end.column,i=e.getLine(t.start.row),s=i.substring(n,r);if(s.length>5e3||!/[\\w\\d]/.test(s))return;var o=this.$search.$assembleRegExp({wholeWord:!0,caseSensitive:!0,needle:s}),u=i.substring(n-1,r+1);if(!o.test(u))return;return o},this.onChangeFrontMarker=function(){this.renderer.updateFrontMarkers()},this.onChangeBackMarker=function(){this.renderer.updateBackMarkers()},this.onChangeBreakpoint=function(){this.renderer.updateBreakpoints()},this.onChangeAnnotation=function(){this.renderer.setAnnotations(this.session.getAnnotations())},this.onChangeMode=function(e){this.renderer.updateText(),this._emit(\"changeMode\",e)},this.onChangeWrapLimit=function(){this.renderer.updateFull()},this.onChangeWrapMode=function(){this.renderer.onResize(!0)},this.onChangeFold=function(){this.$updateHighlightActiveLine(),this.renderer.updateFull()},this.getSelectedText=function(){return this.session.getTextRange(this.getSelectionRange())},this.getCopyText=function(){var e=this.getSelectedText(),t=this.session.doc.getNewLineCharacter(),n=!1;if(!e&&this.$copyWithEmptySelection){n=!0;var r=this.selection.getAllRanges();for(var i=0;i<r.length;i++){var s=r[i];if(i&&r[i-1].start.row==s.start.row)continue;e+=this.session.getLine(s.start.row)+t}}var o={text:e};return this._signal(\"copy\",o),b.lineMode=n?o.text:\"\",o.text},this.onCopy=function(){this.commands.exec(\"copy\",this)},this.onCut=function(){this.commands.exec(\"cut\",this)},this.onPaste=function(e,t){var n={text:e,event:t};this.commands.exec(\"paste\",this,n)},this.$handlePaste=function(e){typeof e==\"string\"&&(e={text:e}),this._signal(\"paste\",e);var t=e.text,n=t==b.lineMode,r=this.session;if(!this.inMultiSelectMode||this.inVirtualSelectionMode)n?r.insert({row:this.selection.lead.row,column:0},t):this.insert(t);else if(n)this.selection.rangeList.ranges.forEach(function(e){r.insert({row:e.start.row,column:0},t)});else{var i=t.split(/\\r\\n|\\r|\\n/),s=this.selection.rangeList.ranges,o=i.length==2&&(!i[0]||!i[1]);if(i.length!=s.length||o)return this.commands.exec(\"insertstring\",this,t);for(var u=s.length;u--;){var a=s[u];a.isEmpty()||r.remove(a),r.insert(a.start,i[u])}}},this.execCommand=function(e,t){return this.commands.exec(e,this,t)},this.insert=function(e,t){var n=this.session,r=n.getMode(),i=this.getCursorPosition();if(this.getBehavioursEnabled()&&!t){var s=r.transformAction(n.getState(i.row),\"insertion\",this,n,e);s&&(e!==s.text&&(this.inVirtualSelectionMode||(this.session.mergeUndoDeltas=!1,this.mergeNextCommand=!1)),e=s.text)}e==\"\t\"&&(e=this.session.getTabString());if(!this.selection.isEmpty()){var o=this.getSelectionRange();i=this.session.remove(o),this.clearSelection()}else if(this.session.getOverwrite()&&e.indexOf(\"\\n\")==-1){var o=new p.fromPoints(i,i);o.end.column+=e.length,this.session.remove(o)}if(e==\"\\n\"||e==\"\\r\\n\"){var u=n.getLine(i.row);if(i.column>u.search(/\\S|$/)){var a=u.substr(i.column).search(/\\S|$/);n.doc.removeInLine(i.row,i.column,i.column+a)}}this.clearSelection();var f=i.column,l=n.getState(i.row),u=n.getLine(i.row),c=r.checkOutdent(l,u,e);n.insert(i,e),s&&s.selection&&(s.selection.length==2?this.selection.setSelectionRange(new p(i.row,f+s.selection[0],i.row,f+s.selection[1])):this.selection.setSelectionRange(new p(i.row+s.selection[0],s.selection[1],i.row+s.selection[2],s.selection[3])));if(n.getDocument().isNewLine(e)){var h=r.getNextLineIndent(l,u.slice(0,i.column),n.getTabString());n.insert({row:i.row+1,column:0},h)}c&&r.autoOutdent(l,n,i.row)},this.onTextInput=function(e,t){if(!t)return this.keyBinding.onTextInput(e);this.startOperation({command:{name:\"insertstring\"}});var n=this.applyComposition.bind(this,e,t);this.selection.rangeCount?this.forEachSelection(n):n(),this.endOperation()},this.applyComposition=function(e,t){if(t.extendLeft||t.extendRight){var n=this.selection.getRange();n.start.column-=t.extendLeft,n.end.column+=t.extendRight,this.selection.setRange(n),!e&&!n.isEmpty()&&this.remove()}(e||!this.selection.isEmpty())&&this.insert(e,!0);if(t.restoreStart||t.restoreEnd){var n=this.selection.getRange();n.start.column-=t.restoreStart,n.end.column-=t.restoreEnd,this.selection.setRange(n)}},this.onCommandKey=function(e,t,n){return this.keyBinding.onCommandKey(e,t,n)},this.setOverwrite=function(e){this.session.setOverwrite(e)},this.getOverwrite=function(){return this.session.getOverwrite()},this.toggleOverwrite=function(){this.session.toggleOverwrite()},this.setScrollSpeed=function(e){this.setOption(\"scrollSpeed\",e)},this.getScrollSpeed=function(){return this.getOption(\"scrollSpeed\")},this.setDragDelay=function(e){this.setOption(\"dragDelay\",e)},this.getDragDelay=function(){return this.getOption(\"dragDelay\")},this.setSelectionStyle=function(e){this.setOption(\"selectionStyle\",e)},this.getSelectionStyle=function(){return this.getOption(\"selectionStyle\")},this.setHighlightActiveLine=function(e){this.setOption(\"highlightActiveLine\",e)},this.getHighlightActiveLine=function(){return this.getOption(\"highlightActiveLine\")},this.setHighlightGutterLine=function(e){this.setOption(\"highlightGutterLine\",e)},this.getHighlightGutterLine=function(){return this.getOption(\"highlightGutterLine\")},this.setHighlightSelectedWord=function(e){this.setOption(\"highlightSelectedWord\",e)},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setAnimatedScroll=function(e){this.renderer.setAnimatedScroll(e)},this.getAnimatedScroll=function(){return this.renderer.getAnimatedScroll()},this.setShowInvisibles=function(e){this.renderer.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.renderer.getShowInvisibles()},this.setDisplayIndentGuides=function(e){this.renderer.setDisplayIndentGuides(e)},this.getDisplayIndentGuides=function(){return this.renderer.getDisplayIndentGuides()},this.setShowPrintMargin=function(e){this.renderer.setShowPrintMargin(e)},this.getShowPrintMargin=function(){return this.renderer.getShowPrintMargin()},this.setPrintMarginColumn=function(e){this.renderer.setPrintMarginColumn(e)},this.getPrintMarginColumn=function(){return this.renderer.getPrintMarginColumn()},this.setReadOnly=function(e){this.setOption(\"readOnly\",e)},this.getReadOnly=function(){return this.getOption(\"readOnly\")},this.setBehavioursEnabled=function(e){this.setOption(\"behavioursEnabled\",e)},this.getBehavioursEnabled=function(){return this.getOption(\"behavioursEnabled\")},this.setWrapBehavioursEnabled=function(e){this.setOption(\"wrapBehavioursEnabled\",e)},this.getWrapBehavioursEnabled=function(){return this.getOption(\"wrapBehavioursEnabled\")},this.setShowFoldWidgets=function(e){this.setOption(\"showFoldWidgets\",e)},this.getShowFoldWidgets=function(){return this.getOption(\"showFoldWidgets\")},this.setFadeFoldWidgets=function(e){this.setOption(\"fadeFoldWidgets\",e)},this.getFadeFoldWidgets=function(){return this.getOption(\"fadeFoldWidgets\")},this.remove=function(e){this.selection.isEmpty()&&(e==\"left\"?this.selection.selectLeft():this.selection.selectRight());var t=this.getSelectionRange();if(this.getBehavioursEnabled()){var n=this.session,r=n.getState(t.start.row),i=n.getMode().transformAction(r,\"deletion\",this,n,t);if(t.end.column===0){var s=n.getTextRange(t);if(s[s.length-1]==\"\\n\"){var o=n.getLine(t.end.row);/^\\s+$/.test(o)&&(t.end.column=o.length)}}i&&(t=i)}this.session.remove(t),this.clearSelection()},this.removeWordRight=function(){this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeWordLeft=function(){this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineStart=function(){this.selection.isEmpty()&&this.selection.selectLineStart(),this.selection.isEmpty()&&this.selection.selectLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineEnd=function(){this.selection.isEmpty()&&this.selection.selectLineEnd();var e=this.getSelectionRange();e.start.column==e.end.column&&e.start.row==e.end.row&&(e.end.column=0,e.end.row++),this.session.remove(e),this.clearSelection()},this.splitLine=function(){this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection());var e=this.getCursorPosition();this.insert(\"\\n\"),this.moveCursorToPosition(e)},this.transposeLetters=function(){if(!this.selection.isEmpty())return;var e=this.getCursorPosition(),t=e.column;if(t===0)return;var n=this.session.getLine(e.row),r,i;t<n.length?(r=n.charAt(t)+n.charAt(t-1),i=new p(e.row,t-1,e.row,t+1)):(r=n.charAt(t-1)+n.charAt(t-2),i=new p(e.row,t-2,e.row,t)),this.session.replace(i,r),this.session.selection.moveToPosition(i.end)},this.toLowerCase=function(){var e=this.getSelectionRange();this.selection.isEmpty()&&this.selection.selectWord();var t=this.getSelectionRange(),n=this.session.getTextRange(t);this.session.replace(t,n.toLowerCase()),this.selection.setSelectionRange(e)},this.toUpperCase=function(){var e=this.getSelectionRange();this.selection.isEmpty()&&this.selection.selectWord();var t=this.getSelectionRange(),n=this.session.getTextRange(t);this.session.replace(t,n.toUpperCase()),this.selection.setSelectionRange(e)},this.indent=function(){var e=this.session,t=this.getSelectionRange();if(t.start.row<t.end.row){var n=this.$getSelectedRows();e.indentRows(n.first,n.last,\"\t\");return}if(t.start.column<t.end.column){var r=e.getTextRange(t);if(!/^\\s+$/.test(r)){var n=this.$getSelectedRows();e.indentRows(n.first,n.last,\"\t\");return}}var i=e.getLine(t.start.row),o=t.start,u=e.getTabSize(),a=e.documentToScreenColumn(o.row,o.column);if(this.session.getUseSoftTabs())var f=u-a%u,l=s.stringRepeat(\" \",f);else{var f=a%u;while(i[t.start.column-1]==\" \"&&f)t.start.column--,f--;this.selection.setSelectionRange(t),l=\"\t\"}return this.insert(l)},this.blockIndent=function(){var e=this.$getSelectedRows();this.session.indentRows(e.first,e.last,\"\t\")},this.blockOutdent=function(){var e=this.session.getSelection();this.session.outdentRows(e.getRange())},this.sortLines=function(){var e=this.$getSelectedRows(),t=this.session,n=[];for(var r=e.first;r<=e.last;r++)n.push(t.getLine(r));n.sort(function(e,t){return e.toLowerCase()<t.toLowerCase()?-1:e.toLowerCase()>t.toLowerCase()?1:0});var i=new p(0,0,0,0);for(var r=e.first;r<=e.last;r++){var s=t.getLine(r);i.start.row=r,i.end.row=r,i.end.column=s.length,t.replace(i,n[r-e.first])}},this.toggleCommentLines=function(){var e=this.session.getState(this.getCursorPosition().row),t=this.$getSelectedRows();this.session.getMode().toggleCommentLines(e,this.session,t.first,t.last)},this.toggleBlockComment=function(){var e=this.getCursorPosition(),t=this.session.getState(e.row),n=this.getSelectionRange();this.session.getMode().toggleBlockComment(t,this.session,n,e)},this.getNumberAt=function(e,t){var n=/[\\-]?[0-9]+(?:\\.[0-9]+)?/g;n.lastIndex=0;var r=this.session.getLine(e);while(n.lastIndex<t){var i=n.exec(r);if(i.index<=t&&i.index+i[0].length>=t){var s={value:i[0],start:i.index,end:i.index+i[0].length};return s}}return null},this.modifyNumber=function(e){var t=this.selection.getCursor().row,n=this.selection.getCursor().column,r=new p(t,n-1,t,n),i=this.session.getTextRange(r);if(!isNaN(parseFloat(i))&&isFinite(i)){var s=this.getNumberAt(t,n);if(s){var o=s.value.indexOf(\".\")>=0?s.start+s.value.indexOf(\".\")+1:s.end,u=s.start+s.value.length-o,a=parseFloat(s.value);a*=Math.pow(10,u),o!==s.end&&n<o?e*=Math.pow(10,s.end-n-1):e*=Math.pow(10,s.end-n),a+=e,a/=Math.pow(10,u);var f=a.toFixed(u),l=new p(t,s.start,t,s.end);this.session.replace(l,f),this.moveCursorTo(t,Math.max(s.start+1,n+f.length-s.value.length))}}else this.toggleWord()},this.$toggleWordPairs=[[\"first\",\"last\"],[\"true\",\"false\"],[\"yes\",\"no\"],[\"width\",\"height\"],[\"top\",\"bottom\"],[\"right\",\"left\"],[\"on\",\"off\"],[\"x\",\"y\"],[\"get\",\"set\"],[\"max\",\"min\"],[\"horizontal\",\"vertical\"],[\"show\",\"hide\"],[\"add\",\"remove\"],[\"up\",\"down\"],[\"before\",\"after\"],[\"even\",\"odd\"],[\"inside\",\"outside\"],[\"next\",\"previous\"],[\"increase\",\"decrease\"],[\"attach\",\"detach\"],[\"&&\",\"||\"],[\"==\",\"!=\"]],this.toggleWord=function(){var e=this.selection.getCursor().row,t=this.selection.getCursor().column;this.selection.selectWord();var n=this.getSelectedText(),r=this.selection.getWordRange().start.column,i=n.replace(/([a-z]+|[A-Z]+)(?=[A-Z_]|$)/g,\"$1 \").split(/\\s/),o=t-r-1;o<0&&(o=0);var u=0,a=0,f=this;n.match(/[A-Za-z0-9_]+/)&&i.forEach(function(t,i){a=u+t.length,o>=u&&o<=a&&(n=t,f.selection.clearSelection(),f.moveCursorTo(e,u+r),f.selection.selectTo(e,a+r)),u=a});var l=this.$toggleWordPairs,c;for(var h=0;h<l.length;h++){var p=l[h];for(var d=0;d<=1;d++){var v=+!d,m=n.match(new RegExp(\"^\\\\s?_?(\"+s.escapeRegExp(p[d])+\")\\\\s?$\",\"i\"));if(m){var g=n.match(new RegExp(\"([_]|^|\\\\s)(\"+s.escapeRegExp(m[1])+\")($|\\\\s)\",\"g\"));g&&(c=n.replace(new RegExp(s.escapeRegExp(p[d]),\"i\"),function(e){var t=p[v];return e.toUpperCase()==e?t=t.toUpperCase():e.charAt(0).toUpperCase()==e.charAt(0)&&(t=t.substr(0,0)+p[v].charAt(0).toUpperCase()+t.substr(1)),t}),this.insert(c),c=\"\")}}}},this.removeLines=function(){var e=this.$getSelectedRows();this.session.removeFullLines(e.first,e.last),this.clearSelection()},this.duplicateSelection=function(){var e=this.selection,t=this.session,n=e.getRange(),r=e.isBackwards();if(n.isEmpty()){var i=n.start.row;t.duplicateLines(i,i)}else{var s=r?n.start:n.end,o=t.insert(s,t.getTextRange(n),!1);n.start=s,n.end=o,e.setSelectionRange(n,r)}},this.moveLinesDown=function(){this.$moveLines(1,!1)},this.moveLinesUp=function(){this.$moveLines(-1,!1)},this.moveText=function(e,t,n){return this.session.moveText(e,t,n)},this.copyLinesUp=function(){this.$moveLines(-1,!0)},this.copyLinesDown=function(){this.$moveLines(1,!0)},this.$moveLines=function(e,t){var n,r,i=this.selection;if(!i.inMultiSelectMode||this.inVirtualSelectionMode){var s=i.toOrientedRange();n=this.$getSelectedRows(s),r=this.session.$moveLines(n.first,n.last,t?0:e),t&&e==-1&&(r=0),s.moveBy(r,0),i.fromOrientedRange(s)}else{var o=i.rangeList.ranges;i.rangeList.detach(this.session),this.inVirtualSelectionMode=!0;var u=0,a=0,f=o.length;for(var l=0;l<f;l++){var c=l;o[l].moveBy(u,0),n=this.$getSelectedRows(o[l]);var h=n.first,p=n.last;while(++l<f){a&&o[l].moveBy(a,0);var d=this.$getSelectedRows(o[l]);if(t&&d.first!=p)break;if(!t&&d.first>p+1)break;p=d.last}l--,u=this.session.$moveLines(h,p,t?0:e),t&&e==-1&&(c=l+1);while(c<=l)o[c].moveBy(u,0),c++;t||(u=0),a+=u}i.fromOrientedRange(i.ranges[0]),i.rangeList.attach(this.session),this.inVirtualSelectionMode=!1}},this.$getSelectedRows=function(e){return e=(e||this.getSelectionRange()).collapseRows(),{first:this.session.getRowFoldStart(e.start.row),last:this.session.getRowFoldEnd(e.end.row)}},this.onCompositionStart=function(e){this.renderer.showComposition(e)},this.onCompositionUpdate=function(e){this.renderer.setCompositionText(e)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(e){return e>=this.getFirstVisibleRow()&&e<=this.getLastVisibleRow()},this.isRowFullyVisible=function(e){return e>=this.renderer.getFirstFullyVisibleRow()&&e<=this.renderer.getLastFullyVisibleRow()},this.$getVisibleRowCount=function(){return this.renderer.getScrollBottomRow()-this.renderer.getScrollTopRow()+1},this.$moveByPage=function(e,t){var n=this.renderer,r=this.renderer.layerConfig,i=e*Math.floor(r.height/r.lineHeight);t===!0?this.selection.$moveSelection(function(){this.moveCursorBy(i,0)}):t===!1&&(this.selection.moveCursorBy(i,0),this.selection.clearSelection());var s=n.scrollTop;n.scrollBy(0,i*r.lineHeight),t!=null&&n.scrollCursorIntoView(null,.5),n.animateScrolling(s)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(e){this.renderer.scrollToRow(e)},this.scrollToLine=function(e,t,n,r){this.renderer.scrollToLine(e,t,n,r)},this.centerSelection=function(){var e=this.getSelectionRange(),t={row:Math.floor(e.start.row+(e.end.row-e.start.row)/2),column:Math.floor(e.start.column+(e.end.column-e.start.column)/2)};this.renderer.alignCursor(t,.5)},this.getCursorPosition=function(){return this.selection.getCursor()},this.getCursorPositionScreen=function(){return this.session.documentToScreenPosition(this.getCursorPosition())},this.getSelectionRange=function(){return this.selection.getRange()},this.selectAll=function(){this.selection.selectAll()},this.clearSelection=function(){this.selection.clearSelection()},this.moveCursorTo=function(e,t){this.selection.moveCursorTo(e,t)},this.moveCursorToPosition=function(e){this.selection.moveCursorToPosition(e)},this.jumpToMatching=function(e,t){var n=this.getCursorPosition(),r=new y(this.session,n.row,n.column),i=r.getCurrentToken(),s=i||r.stepForward();if(!s)return;var o,u=!1,a={},f=n.column-s.start,l,c={\")\":\"(\",\"(\":\"(\",\"]\":\"[\",\"[\":\"[\",\"{\":\"{\",\"}\":\"{\"};do{if(s.value.match(/[{}()\\[\\]]/g))for(;f<s.value.length&&!u;f++){if(!c[s.value[f]])continue;l=c[s.value[f]]+\".\"+s.type.replace(\"rparen\",\"lparen\"),isNaN(a[l])&&(a[l]=0);switch(s.value[f]){case\"(\":case\"[\":case\"{\":a[l]++;break;case\")\":case\"]\":case\"}\":a[l]--,a[l]===-1&&(o=\"bracket\",u=!0)}}else s.type.indexOf(\"tag-name\")!==-1&&(isNaN(a[s.value])&&(a[s.value]=0),i.value===\"<\"?a[s.value]++:i.value===\"</\"&&a[s.value]--,a[s.value]===-1&&(o=\"tag\",u=!0));u||(i=s,s=r.stepForward(),f=0)}while(s&&!u);if(!o)return;var h,d;if(o===\"bracket\"){h=this.session.getBracketRange(n);if(!h){h=new p(r.getCurrentTokenRow(),r.getCurrentTokenColumn()+f-1,r.getCurrentTokenRow(),r.getCurrentTokenColumn()+f-1),d=h.start;if(t||d.row===n.row&&Math.abs(d.column-n.column)<2)h=this.session.getBracketRange(d)}}else if(o===\"tag\"){if(!s||s.type.indexOf(\"tag-name\")===-1)return;var v=s.value;h=new p(r.getCurrentTokenRow(),r.getCurrentTokenColumn()-2,r.getCurrentTokenRow(),r.getCurrentTokenColumn()-2);if(h.compare(n.row,n.column)===0){u=!1;do s=i,i=r.stepBackward(),i&&(i.type.indexOf(\"tag-close\")!==-1&&h.setEnd(r.getCurrentTokenRow(),r.getCurrentTokenColumn()+1),s.value===v&&s.type.indexOf(\"tag-name\")!==-1&&(i.value===\"<\"?a[v]++:i.value===\"</\"&&a[v]--,a[v]===0&&(u=!0)));while(i&&!u)}s&&s.type.indexOf(\"tag-name\")&&(d=h.start,d.row==n.row&&Math.abs(d.column-n.column)<2&&(d=h.end))}d=h&&h.cursor||d,d&&(e?h&&t?this.selection.setRange(h):h&&h.isEqual(this.getSelectionRange())?this.clearSelection():this.selection.selectTo(d.row,d.column):this.selection.moveTo(d.row,d.column))},this.gotoLine=function(e,t,n){this.selection.clearSelection(),this.session.unfold({row:e-1,column:t||0}),this.exitMultiSelectMode&&this.exitMultiSelectMode(),this.moveCursorTo(e-1,t||0),this.isRowFullyVisible(e-1)||this.scrollToLine(e-1,!0,n)},this.navigateTo=function(e,t){this.selection.moveTo(e,t)},this.navigateUp=function(e){if(this.selection.isMultiLine()&&!this.selection.isBackwards()){var t=this.selection.anchor.getPosition();return this.moveCursorToPosition(t)}this.selection.clearSelection(),this.selection.moveCursorBy(-e||-1,0)},this.navigateDown=function(e){if(this.selection.isMultiLine()&&this.selection.isBackwards()){var t=this.selection.anchor.getPosition();return this.moveCursorToPosition(t)}this.selection.clearSelection(),this.selection.moveCursorBy(e||1,0)},this.navigateLeft=function(e){if(!this.selection.isEmpty()){var t=this.getSelectionRange().start;this.moveCursorToPosition(t)}else{e=e||1;while(e--)this.selection.moveCursorLeft()}this.clearSelection()},this.navigateRight=function(e){if(!this.selection.isEmpty()){var t=this.getSelectionRange().end;this.moveCursorToPosition(t)}else{e=e||1;while(e--)this.selection.moveCursorRight()}this.clearSelection()},this.navigateLineStart=function(){this.selection.moveCursorLineStart(),this.clearSelection()},this.navigateLineEnd=function(){this.selection.moveCursorLineEnd(),this.clearSelection()},this.navigateFileEnd=function(){this.selection.moveCursorFileEnd(),this.clearSelection()},this.navigateFileStart=function(){this.selection.moveCursorFileStart(),this.clearSelection()},this.navigateWordRight=function(){this.selection.moveCursorWordRight(),this.clearSelection()},this.navigateWordLeft=function(){this.selection.moveCursorWordLeft(),this.clearSelection()},this.replace=function(e,t){t&&this.$search.set(t);var n=this.$search.find(this.session),r=0;return n?(this.$tryReplace(n,e)&&(r=1),this.selection.setSelectionRange(n),this.renderer.scrollSelectionIntoView(n.start,n.end),r):r},this.replaceAll=function(e,t){t&&this.$search.set(t);var n=this.$search.findAll(this.session),r=0;if(!n.length)return r;var i=this.getSelectionRange();this.selection.moveTo(0,0);for(var s=n.length-1;s>=0;--s)this.$tryReplace(n[s],e)&&r++;return this.selection.setSelectionRange(i),r},this.$tryReplace=function(e,t){var n=this.session.getTextRange(e);return t=this.$search.replace(n,t),t!==null?(e.end=this.session.replace(e,t),e):null},this.getLastSearchOptions=function(){return this.$search.getOptions()},this.find=function(e,t,n){t||(t={}),typeof e==\"string\"||e instanceof RegExp?t.needle=e:typeof e==\"object\"&&r.mixin(t,e);var i=this.selection.getRange();t.needle==null&&(e=this.session.getTextRange(i)||this.$search.$options.needle,e||(i=this.session.getWordRange(i.start.row,i.start.column),e=this.session.getTextRange(i)),this.$search.set({needle:e})),this.$search.set(t),t.start||this.$search.set({start:i});var s=this.$search.find(this.session);if(t.preventScroll)return s;if(s)return this.revealRange(s,n),s;t.backwards?i.start=i.end:i.end=i.start,this.selection.setRange(i)},this.findNext=function(e,t){this.find({skipCurrent:!0,backwards:!1},e,t)},this.findPrevious=function(e,t){this.find(e,{skipCurrent:!0,backwards:!0},t)},this.revealRange=function(e,t){this.session.unfold(e),this.selection.setSelectionRange(e);var n=this.renderer.scrollTop;this.renderer.scrollSelectionIntoView(e.start,e.end,.5),t!==!1&&this.renderer.animateScrolling(n)},this.undo=function(){this.session.getUndoManager().undo(this.session),this.renderer.scrollCursorIntoView(null,.5)},this.redo=function(){this.session.getUndoManager().redo(this.session),this.renderer.scrollCursorIntoView(null,.5)},this.destroy=function(){this.renderer.destroy(),this._signal(\"destroy\",this),this.session&&this.session.destroy()},this.setAutoScrollEditorIntoView=function(e){if(!e)return;var t,n=this,r=!1;this.$scrollAnchor||(this.$scrollAnchor=document.createElement(\"div\"));var i=this.$scrollAnchor;i.style.cssText=\"position:absolute\",this.container.insertBefore(i,this.container.firstChild);var s=this.on(\"changeSelection\",function(){r=!0}),o=this.renderer.on(\"beforeRender\",function(){r&&(t=n.renderer.container.getBoundingClientRect())}),u=this.renderer.on(\"afterRender\",function(){if(r&&t&&(n.isFocused()||n.searchBox&&n.searchBox.isFocused())){var e=n.renderer,s=e.$cursorLayer.$pixelPos,o=e.layerConfig,u=s.top-o.offset;s.top>=0&&u+t.top<0?r=!0:s.top<o.height&&s.top+t.top+o.lineHeight>window.innerHeight?r=!1:r=null,r!=null&&(i.style.top=u+\"px\",i.style.left=s.left+\"px\",i.style.height=o.lineHeight+\"px\",i.scrollIntoView(r)),r=t=null}});this.setAutoScrollEditorIntoView=function(e){if(e)return;delete this.setAutoScrollEditorIntoView,this.off(\"changeSelection\",s),this.renderer.off(\"afterRender\",u),this.renderer.off(\"beforeRender\",o)}},this.$resetCursorStyle=function(){var e=this.$cursorStyle||\"ace\",t=this.renderer.$cursorLayer;if(!t)return;t.setSmoothBlinking(/smooth/.test(e)),t.isBlinking=!this.$readOnly&&e!=\"wide\",i.setCssClass(t.element,\"ace_slim-cursors\",/slim/.test(e))},this.prompt=function(e,t,n){var r=this;g.loadModule(\"./ext/prompt\",function(i){i.prompt(r,e,t,n)})}}.call(w.prototype),g.defineOptions(w.prototype,\"editor\",{selectionStyle:{set:function(e){this.onSelectionChange(),this._signal(\"changeSelectionStyle\",{data:e})},initialValue:\"line\"},highlightActiveLine:{set:function(){this.$updateHighlightActiveLine()},initialValue:!0},highlightSelectedWord:{set:function(e){this.$onSelectionChange()},initialValue:!0},readOnly:{set:function(e){this.textInput.setReadOnly(e),this.$resetCursorStyle()},initialValue:!1},copyWithEmptySelection:{set:function(e){this.textInput.setCopyWithEmptySelection(e)},initialValue:!1},cursorStyle:{set:function(e){this.$resetCursorStyle()},values:[\"ace\",\"slim\",\"smooth\",\"wide\"],initialValue:\"ace\"},mergeUndoDeltas:{values:[!1,!0,\"always\"],initialValue:!0},behavioursEnabled:{initialValue:!0},wrapBehavioursEnabled:{initialValue:!0},autoScrollEditorIntoView:{set:function(e){this.setAutoScrollEditorIntoView(e)}},keyboardHandler:{set:function(e){this.setKeyboardHandler(e)},get:function(){return this.$keybindingId},handlesSet:!0},value:{set:function(e){this.session.setValue(e)},get:function(){return this.getValue()},handlesSet:!0,hidden:!0},session:{set:function(e){this.setSession(e)},get:function(){return this.session},handlesSet:!0,hidden:!0},showLineNumbers:{set:function(e){this.renderer.$gutterLayer.setShowLineNumbers(e),this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER),e&&this.$relativeLineNumbers?E.attach(this):E.detach(this)},initialValue:!0},relativeLineNumbers:{set:function(e){this.$showLineNumbers&&e?E.attach(this):E.detach(this)}},hScrollBarAlwaysVisible:\"renderer\",vScrollBarAlwaysVisible:\"renderer\",highlightGutterLine:\"renderer\",animatedScroll:\"renderer\",showInvisibles:\"renderer\",showPrintMargin:\"renderer\",printMarginColumn:\"renderer\",printMargin:\"renderer\",fadeFoldWidgets:\"renderer\",showFoldWidgets:\"renderer\",displayIndentGuides:\"renderer\",showGutter:\"renderer\",fontSize:\"renderer\",fontFamily:\"renderer\",maxLines:\"renderer\",minLines:\"renderer\",scrollPastEnd:\"renderer\",fixedWidthGutter:\"renderer\",theme:\"renderer\",hasCssTransforms:\"renderer\",maxPixelHeight:\"renderer\",useTextareaForIME:\"renderer\",scrollSpeed:\"$mouseHandler\",dragDelay:\"$mouseHandler\",dragEnabled:\"$mouseHandler\",focusTimeout:\"$mouseHandler\",tooltipFollowsMouse:\"$mouseHandler\",firstLineNumber:\"session\",overwrite:\"session\",newLineMode:\"session\",useWorker:\"session\",useSoftTabs:\"session\",navigateWithinSoftTabs:\"session\",tabSize:\"session\",wrap:\"session\",indentedSoftWrap:\"session\",foldStyle:\"session\",mode:\"session\"});var E={getText:function(e,t){return(Math.abs(e.selection.lead.row-t)||t+1+(t<9?\"\\u00b7\":\"\"))+\"\"},getWidth:function(e,t,n){return Math.max(t.toString().length,(n.lastRow+1).toString().length,2)*n.characterWidth},update:function(e,t){t.renderer.$loop.schedule(t.renderer.CHANGE_GUTTER)},attach:function(e){e.renderer.$gutterLayer.$renderer=this,e.on(\"changeSelection\",this.update),this.update(null,e)},detach:function(e){e.renderer.$gutterLayer.$renderer==this&&(e.renderer.$gutterLayer.$renderer=null),e.off(\"changeSelection\",this.update),this.update(null,e)}};t.Editor=w}),ace.define(\"ace/undomanager\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";function i(e,t){for(var n=t;n--;){var r=e[n];if(r&&!r[0].ignore){while(n<t-1){var i=d(e[n],e[n+1]);e[n]=i[0],e[n+1]=i[1],n++}return!0}}}function a(e){var t=e.action==\"insert\",n=e.start,r=e.end,i=(r.row-n.row)*(t?1:-1),s=(r.column-n.column)*(t?1:-1);t&&(r=n);for(var o in this.marks){var a=this.marks[o],f=u(a,n);if(f<0)continue;if(f===0&&t){if(a.bias!=1){a.bias==-1;continue}f=1}var l=t?f:u(a,r);if(l>0){a.row+=i,a.column+=a.row==r.row?s:0;continue}!t&&l<=0&&(a.row=n.row,a.column=n.column,l===0&&(a.bias=1))}}function f(e){return{row:e.row,column:e.column}}function l(e){return{start:f(e.start),end:f(e.end),action:e.action,lines:e.lines.slice()}}function c(e){e=e||this;if(Array.isArray(e))return e.map(c).join(\"\\n\");var t=\"\";e.action?(t=e.action==\"insert\"?\"+\":\"-\",t+=\"[\"+e.lines+\"]\"):e.value&&(Array.isArray(e.value)?t=e.value.map(h).join(\"\\n\"):t=h(e.value)),e.start&&(t+=h(e));if(e.id||e.rev)t+=\"\t(\"+(e.id||e.rev)+\")\";return t}function h(e){return e.start.row+\":\"+e.start.column+\"=>\"+e.end.row+\":\"+e.end.column}function p(e,t){var n=e.action==\"insert\",r=t.action==\"insert\";if(n&&r)if(o(t.start,e.end)>=0)m(t,e,-1);else{if(!(o(t.start,e.start)<=0))return null;m(e,t,1)}else if(n&&!r)if(o(t.start,e.end)>=0)m(t,e,-1);else{if(!(o(t.end,e.start)<=0))return null;m(e,t,-1)}else if(!n&&r)if(o(t.start,e.start)>=0)m(t,e,1);else{if(!(o(t.start,e.start)<=0))return null;m(e,t,1)}else if(!n&&!r)if(o(t.start,e.start)>=0)m(t,e,1);else{if(!(o(t.end,e.start)<=0))return null;m(e,t,-1)}return[t,e]}function d(e,t){for(var n=e.length;n--;)for(var r=0;r<t.length;r++)if(!p(e[n],t[r])){while(n<e.length){while(r--)p(t[r],e[n]);r=t.length,n++}return[e,t]}return e.selectionBefore=t.selectionBefore=e.selectionAfter=t.selectionAfter=null,[t,e]}function v(e,t){var n=e.action==\"insert\",r=t.action==\"insert\";if(n&&r)o(e.start,t.start)<0?m(t,e,1):m(e,t,1);else if(n&&!r)o(e.start,t.end)>=0?m(e,t,-1):o(e.start,t.start)<=0?m(t,e,1):(m(e,s.fromPoints(t.start,e.start),-1),m(t,e,1));else if(!n&&r)o(t.start,e.end)>=0?m(t,e,-1):o(t.start,e.start)<=0?m(e,t,1):(m(t,s.fromPoints(e.start,t.start),-1),m(e,t,1));else if(!n&&!r)if(o(t.start,e.end)>=0)m(t,e,-1);else{if(!(o(t.end,e.start)<=0)){var i,u;return o(e.start,t.start)<0&&(i=e,e=y(e,t.start)),o(e.end,t.end)>0&&(u=y(e,t.end)),g(t.end,e.start,e.end,-1),u&&!i&&(e.lines=u.lines,e.start=u.start,e.end=u.end,u=e),[t,i,u].filter(Boolean)}m(e,t,-1)}return[t,e]}function m(e,t,n){g(e.start,t.start,t.end,n),g(e.end,t.start,t.end,n)}function g(e,t,n,r){e.row==(r==1?t:n).row&&(e.column+=r*(n.column-t.column)),e.row+=r*(n.row-t.row)}function y(e,t){var n=e.lines,r=e.end;e.end=f(t);var i=e.end.row-e.start.row,s=n.splice(i,n.length),o=i?t.column:t.column-e.start.column;n.push(s[0].substring(0,o)),s[0]=s[0].substr(o);var u={start:f(t),end:r,lines:s,action:e.action};return u}function b(e,t){t=l(t);for(var n=e.length;n--;){var r=e[n];for(var i=0;i<r.length;i++){var s=r[i],o=v(s,t);t=o[0],o.length!=2&&(o[2]?(r.splice(i+1,1,o[1],o[2]),i++):o[1]||(r.splice(i,1),i--))}r.length||e.splice(n,1)}return e}function w(e,t){for(var n=0;n<t.length;n++){var r=t[n];for(var i=0;i<r.length;i++)b(e,r[i])}}var r=function(){this.$maxRev=0,this.$fromUndo=!1,this.reset()};(function(){this.addSession=function(e){this.$session=e},this.add=function(e,t,n){if(this.$fromUndo)return;if(e==this.$lastDelta)return;if(t===!1||!this.lastDeltas)this.lastDeltas=[],this.$undoStack.push(this.lastDeltas),e.id=this.$rev=++this.$maxRev;if(e.action==\"remove\"||e.action==\"insert\")this.$lastDelta=e;this.lastDeltas.push(e)},this.addSelection=function(e,t){this.selections.push({value:e,rev:t||this.$rev})},this.startNewGroup=function(){return this.lastDeltas=null,this.$rev},this.markIgnored=function(e,t){t==null&&(t=this.$rev+1);var n=this.$undoStack;for(var r=n.length;r--;){var i=n[r][0];if(i.id<=e)break;i.id<t&&(i.ignore=!0)}this.lastDeltas=null},this.getSelection=function(e,t){var n=this.selections;for(var r=n.length;r--;){var i=n[r];if(i.rev<e)return t&&(i=n[r+1]),i}},this.getRevision=function(){return this.$rev},this.getDeltas=function(e,t){t==null&&(t=this.$rev+1);var n=this.$undoStack,r=null,i=0;for(var s=n.length;s--;){var o=n[s][0];o.id<t&&!r&&(r=s+1);if(o.id<=e){i=s+1;break}}return n.slice(i,r)},this.getChangedRanges=function(e,t){t==null&&(t=this.$rev+1)},this.getChangedLines=function(e,t){t==null&&(t=this.$rev+1)},this.undo=function(e,t){this.lastDeltas=null;var n=this.$undoStack;if(!i(n,n.length))return;e||(e=this.$session),this.$redoStackBaseRev!==this.$rev&&this.$redoStack.length&&(this.$redoStack=[]),this.$fromUndo=!0;var r=n.pop(),s=null;return r&&r.length&&(s=e.undoChanges(r,t),this.$redoStack.push(r),this.$syncRev()),this.$fromUndo=!1,s},this.redo=function(e,t){this.lastDeltas=null,e||(e=this.$session),this.$fromUndo=!0;if(this.$redoStackBaseRev!=this.$rev){var n=this.getDeltas(this.$redoStackBaseRev,this.$rev+1);w(this.$redoStack,n),this.$redoStackBaseRev=this.$rev,this.$redoStack.forEach(function(e){e[0].id=++this.$maxRev},this)}var r=this.$redoStack.pop(),i=null;return r&&(i=e.redoChanges(r,t),this.$undoStack.push(r),this.$syncRev()),this.$fromUndo=!1,i},this.$syncRev=function(){var e=this.$undoStack,t=e[e.length-1],n=t&&t[0].id||0;this.$redoStackBaseRev=n,this.$rev=n},this.reset=function(){this.lastDeltas=null,this.$lastDelta=null,this.$undoStack=[],this.$redoStack=[],this.$rev=0,this.mark=0,this.$redoStackBaseRev=this.$rev,this.selections=[]},this.canUndo=function(){return this.$undoStack.length>0},this.canRedo=function(){return this.$redoStack.length>0},this.bookmark=function(e){e==undefined&&(e=this.$rev),this.mark=e},this.isAtBookmark=function(){return this.$rev===this.mark},this.toJSON=function(){},this.fromJSON=function(){},this.hasUndo=this.canUndo,this.hasRedo=this.canRedo,this.isClean=this.isAtBookmark,this.markClean=this.bookmark,this.$prettyPrint=function(e){return e?c(e):c(this.$undoStack)+\"\\n---\\n\"+c(this.$redoStack)}}).call(r.prototype);var s=e(\"./range\").Range,o=s.comparePoints,u=s.comparePoints;t.UndoManager=r}),ace.define(\"ace/layer/lines\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";var r=e(\"../lib/dom\"),i=function(e,t){this.element=e,this.canvasHeight=t||5e5,this.element.style.height=this.canvasHeight*2+\"px\",this.cells=[],this.cellCache=[],this.$offsetCoefficient=0};(function(){this.moveContainer=function(e){r.translate(this.element,0,-(e.firstRowScreen*e.lineHeight%this.canvasHeight)-e.offset*this.$offsetCoefficient)},this.pageChanged=function(e,t){return Math.floor(e.firstRowScreen*e.lineHeight/this.canvasHeight)!==Math.floor(t.firstRowScreen*t.lineHeight/this.canvasHeight)},this.computeLineTop=function(e,t,n){var r=t.firstRowScreen*t.lineHeight,i=Math.floor(r/this.canvasHeight),s=n.documentToScreenRow(e,0)*t.lineHeight;return s-i*this.canvasHeight},this.computeLineHeight=function(e,t,n){return t.lineHeight*n.getRowLength(e)},this.getLength=function(){return this.cells.length},this.get=function(e){return this.cells[e]},this.shift=function(){this.$cacheCell(this.cells.shift())},this.pop=function(){this.$cacheCell(this.cells.pop())},this.push=function(e){if(Array.isArray(e)){this.cells.push.apply(this.cells,e);var t=r.createFragment(this.element);for(var n=0;n<e.length;n++)t.appendChild(e[n].element);this.element.appendChild(t)}else this.cells.push(e),this.element.appendChild(e.element)},this.unshift=function(e){if(Array.isArray(e)){this.cells.unshift.apply(this.cells,e);var t=r.createFragment(this.element);for(var n=0;n<e.length;n++)t.appendChild(e[n].element);this.element.firstChild?this.element.insertBefore(t,this.element.firstChild):this.element.appendChild(t)}else this.cells.unshift(e),this.element.insertAdjacentElement(\"afterbegin\",e.element)},this.last=function(){return this.cells.length?this.cells[this.cells.length-1]:null},this.$cacheCell=function(e){if(!e)return;e.element.remove(),this.cellCache.push(e)},this.createCell=function(e,t,n,i){var s=this.cellCache.pop();if(!s){var o=r.createElement(\"div\");i&&i(o),this.element.appendChild(o),s={element:o,text:\"\",row:e}}return s.row=e,s}}).call(i.prototype),t.Lines=i}),ace.define(\"ace/layer/gutter\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/lib/event_emitter\",\"ace/layer/lines\"],function(e,t,n){\"use strict\";function f(e){var t=document.createTextNode(\"\");e.appendChild(t);var n=r.createElement(\"span\");return e.appendChild(n),e}var r=e(\"../lib/dom\"),i=e(\"../lib/oop\"),s=e(\"../lib/lang\"),o=e(\"../lib/event_emitter\").EventEmitter,u=e(\"./lines\").Lines,a=function(e){this.element=r.createElement(\"div\"),this.element.className=\"ace_layer ace_gutter-layer\",e.appendChild(this.element),this.setShowFoldWidgets(this.$showFoldWidgets),this.gutterWidth=0,this.$annotations=[],this.$updateAnnotations=this.$updateAnnotations.bind(this),this.$lines=new u(this.element),this.$lines.$offsetCoefficient=1};(function(){i.implement(this,o),this.setSession=function(e){this.session&&this.session.removeEventListener(\"change\",this.$updateAnnotations),this.session=e,e&&e.on(\"change\",this.$updateAnnotations)},this.addGutterDecoration=function(e,t){window.console&&console.warn&&console.warn(\"deprecated use session.addGutterDecoration\"),this.session.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){window.console&&console.warn&&console.warn(\"deprecated use session.removeGutterDecoration\"),this.session.removeGutterDecoration(e,t)},this.setAnnotations=function(e){this.$annotations=[];for(var t=0;t<e.length;t++){var n=e[t],r=n.row,i=this.$annotations[r];i||(i=this.$annotations[r]={text:[]});var o=n.text;o=o?s.escapeHTML(o):n.html||\"\",i.text.indexOf(o)===-1&&i.text.push(o);var u=n.type;u==\"error\"?i.className=\" ace_error\":u==\"warning\"&&i.className!=\" ace_error\"?i.className=\" ace_warning\":u==\"info\"&&!i.className&&(i.className=\" ace_info\")}},this.$updateAnnotations=function(e){if(!this.$annotations.length)return;var t=e.start.row,n=e.end.row-t;if(n!==0)if(e.action==\"remove\")this.$annotations.splice(t,n+1,null);else{var r=new Array(n+1);r.unshift(t,1),this.$annotations.splice.apply(this.$annotations,r)}},this.update=function(e){this.config=e;var t=this.session,n=e.firstRow,r=Math.min(e.lastRow+e.gutterOffset,t.getLength()-1);this.oldLastRow=r,this.config=e,this.$lines.moveContainer(e),this.$updateCursorRow();var i=t.getNextFoldLine(n),s=i?i.start.row:Infinity,o=null,u=-1,a=n;for(;;){a>s&&(a=i.end.row+1,i=t.getNextFoldLine(a,i),s=i?i.start.row:Infinity);if(a>r){while(this.$lines.getLength()>u+1)this.$lines.pop();break}o=this.$lines.get(++u),o?o.row=a:(o=this.$lines.createCell(a,e,this.session,f),this.$lines.push(o)),this.$renderCell(o,e,i,a),a++}this._signal(\"afterRender\"),this.$updateGutterWidth(e)},this.$updateGutterWidth=function(e){var t=this.session,n=t.gutterRenderer||this.$renderer,r=t.$firstLineNumber,i=this.$lines.last()?this.$lines.last().text:\"\";if(this.$fixedWidth||t.$useWrapMode)i=t.getLength()+r-1;var s=n?n.getWidth(t,i,e):i.toString().length*e.characterWidth,o=this.$padding||this.$computePadding();s+=o.left+o.right,s!==this.gutterWidth&&!isNaN(s)&&(this.gutterWidth=s,this.element.parentNode.style.width=this.element.style.width=Math.ceil(this.gutterWidth)+\"px\",this._signal(\"changeGutterWidth\",s))},this.$updateCursorRow=function(){if(!this.$highlightGutterLine)return;var e=this.session.selection.getCursor();if(this.$cursorRow===e.row)return;this.$cursorRow=e.row},this.updateLineHighlight=function(){if(!this.$highlightGutterLine)return;var e=this.session.selection.cursor.row;this.$cursorRow=e;if(this.$cursorCell&&this.$cursorCell.row==e)return;this.$cursorCell&&(this.$cursorCell.element.className=this.$cursorCell.element.className.replace(\"ace_gutter-active-line \",\"\"));var t=this.$lines.cells;this.$cursorCell=null;for(var n=0;n<t.length;n++){var r=t[n];if(r.row>=this.$cursorRow){if(r.row>this.$cursorRow){var i=this.session.getFoldLine(this.$cursorRow);if(!(n>0&&i&&i.start.row==t[n-1].row))break;r=t[n-1]}r.element.className=\"ace_gutter-active-line \"+r.element.className,this.$cursorCell=r;break}}},this.scrollLines=function(e){var t=this.config;this.config=e,this.$updateCursorRow();if(this.$lines.pageChanged(t,e))return this.update(e);this.$lines.moveContainer(e);var n=Math.min(e.lastRow+e.gutterOffset,this.session.getLength()-1),r=this.oldLastRow;this.oldLastRow=n;if(!t||r<e.firstRow)return this.update(e);if(n<t.firstRow)return this.update(e);if(t.firstRow<e.firstRow)for(var i=this.session.getFoldedRowCount(t.firstRow,e.firstRow-1);i>0;i--)this.$lines.shift();if(r>n)for(var i=this.session.getFoldedRowCount(n+1,r);i>0;i--)this.$lines.pop();e.firstRow<t.firstRow&&this.$lines.unshift(this.$renderLines(e,e.firstRow,t.firstRow-1)),n>r&&this.$lines.push(this.$renderLines(e,r+1,n)),this.updateLineHighlight(),this._signal(\"afterRender\"),this.$updateGutterWidth(e)},this.$renderLines=function(e,t,n){var r=[],i=t,s=this.session.getNextFoldLine(i),o=s?s.start.row:Infinity;for(;;){i>o&&(i=s.end.row+1,s=this.session.getNextFoldLine(i,s),o=s?s.start.row:Infinity);if(i>n)break;var u=this.$lines.createCell(i,e,this.session,f);this.$renderCell(u,e,s,i),r.push(u),i++}return r},this.$renderCell=function(e,t,n,i){var s=e.element,o=this.session,u=s.childNodes[0],a=s.childNodes[1],f=o.$firstLineNumber,l=o.$breakpoints,c=o.$decorations,h=o.gutterRenderer||this.$renderer,p=this.$showFoldWidgets&&o.foldWidgets,d=n?n.start.row:Number.MAX_VALUE,v=\"ace_gutter-cell \";this.$highlightGutterLine&&(i==this.$cursorRow||n&&i<this.$cursorRow&&i>=d&&this.$cursorRow<=n.end.row)&&(v+=\"ace_gutter-active-line \",this.$cursorCell!=e&&(this.$cursorCell&&(this.$cursorCell.element.className=this.$cursorCell.element.className.replace(\"ace_gutter-active-line \",\"\")),this.$cursorCell=e)),l[i]&&(v+=l[i]),c[i]&&(v+=c[i]),this.$annotations[i]&&(v+=this.$annotations[i].className),s.className!=v&&(s.className=v);if(p){var m=p[i];m==null&&(m=p[i]=o.getFoldWidget(i))}if(m){var v=\"ace_fold-widget ace_\"+m;m==\"start\"&&i==d&&i<n.end.row?v+=\" ace_closed\":v+=\" ace_open\",a.className!=v&&(a.className=v);var g=t.lineHeight+\"px\";r.setStyle(a.style,\"height\",g),r.setStyle(a.style,\"display\",\"inline-block\")}else a&&r.setStyle(a.style,\"display\",\"none\");var y=(h?h.getText(o,i):i+f).toString();return y!==u.data&&(u.data=y),r.setStyle(e.element.style,\"height\",this.$lines.computeLineHeight(i,t,o)+\"px\"),r.setStyle(e.element.style,\"top\",this.$lines.computeLineTop(i,t,o)+\"px\"),e.text=y,e},this.$fixedWidth=!1,this.$highlightGutterLine=!0,this.$renderer=\"\",this.setHighlightGutterLine=function(e){this.$highlightGutterLine=e},this.$showLineNumbers=!0,this.$renderer=\"\",this.setShowLineNumbers=function(e){this.$renderer=!e&&{getWidth:function(){return 0},getText:function(){return\"\"}}},this.getShowLineNumbers=function(){return this.$showLineNumbers},this.$showFoldWidgets=!0,this.setShowFoldWidgets=function(e){e?r.addCssClass(this.element,\"ace_folding-enabled\"):r.removeCssClass(this.element,\"ace_folding-enabled\"),this.$showFoldWidgets=e,this.$padding=null},this.getShowFoldWidgets=function(){return this.$showFoldWidgets},this.$computePadding=function(){if(!this.element.firstChild)return{left:0,right:0};var e=r.computedStyle(this.element.firstChild);return this.$padding={},this.$padding.left=(parseInt(e.borderLeftWidth)||0)+(parseInt(e.paddingLeft)||0)+1,this.$padding.right=(parseInt(e.borderRightWidth)||0)+(parseInt(e.paddingRight)||0),this.$padding},this.getRegion=function(e){var t=this.$padding||this.$computePadding(),n=this.element.getBoundingClientRect();if(e.x<t.left+n.left)return\"markers\";if(this.$showFoldWidgets&&e.x>n.right-t.right)return\"foldWidgets\"}}).call(a.prototype),t.Gutter=a}),ace.define(\"ace/layer/marker\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";var r=e(\"../range\").Range,i=e(\"../lib/dom\"),s=function(e){this.element=i.createElement(\"div\"),this.element.className=\"ace_layer ace_marker-layer\",e.appendChild(this.element)};(function(){function e(e,t,n,r){return(e?1:0)|(t?2:0)|(n?4:0)|(r?8:0)}this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setMarkers=function(e){this.markers=e},this.elt=function(e,t){var n=this.i!=-1&&this.element.childNodes[this.i];n?this.i++:(n=document.createElement(\"div\"),this.element.appendChild(n),this.i=-1),n.style.cssText=t,n.className=e},this.update=function(e){if(!e)return;this.config=e,this.i=0;var t;for(var n in this.markers){var r=this.markers[n];if(!r.range){r.update(t,this,this.session,e);continue}var i=r.range.clipRows(e.firstRow,e.lastRow);if(i.isEmpty())continue;i=i.toScreenRange(this.session);if(r.renderer){var s=this.$getTop(i.start.row,e),o=this.$padding+i.start.column*e.characterWidth;r.renderer(t,i,o,s,e)}else r.type==\"fullLine\"?this.drawFullLineMarker(t,i,r.clazz,e):r.type==\"screenLine\"?this.drawScreenLineMarker(t,i,r.clazz,e):i.isMultiLine()?r.type==\"text\"?this.drawTextMarker(t,i,r.clazz,e):this.drawMultiLineMarker(t,i,r.clazz,e):this.drawSingleLineMarker(t,i,r.clazz+\" ace_start\"+\" ace_br15\",e)}if(this.i!=-1)while(this.i<this.element.childElementCount)this.element.removeChild(this.element.lastChild)},this.$getTop=function(e,t){return(e-t.firstRowScreen)*t.lineHeight},this.drawTextMarker=function(t,n,i,s,o){var u=this.session,a=n.start.row,f=n.end.row,l=a,c=0,h=0,p=u.getScreenLastRowColumn(l),d=new r(l,n.start.column,l,h);for(;l<=f;l++)d.start.row=d.end.row=l,d.start.column=l==a?n.start.column:u.getRowWrapIndent(l),d.end.column=p,c=h,h=p,p=l+1<f?u.getScreenLastRowColumn(l+1):l==f?0:n.end.column,this.drawSingleLineMarker(t,d,i+(l==a?\" ace_start\":\"\")+\" ace_br\"+e(l==a||l==a+1&&n.start.column,c<h,h>p,l==f),s,l==f?0:1,o)},this.drawMultiLineMarker=function(e,t,n,r,i){var s=this.$padding,o=r.lineHeight,u=this.$getTop(t.start.row,r),a=s+t.start.column*r.characterWidth;i=i||\"\";if(this.session.$bidiHandler.isBidiRow(t.start.row)){var f=t.clone();f.end.row=f.start.row,f.end.column=this.session.getLine(f.start.row).length,this.drawBidiSingleLineMarker(e,f,n+\" ace_br1 ace_start\",r,null,i)}else this.elt(n+\" ace_br1 ace_start\",\"height:\"+o+\"px;\"+\"right:0;\"+\"top:\"+u+\"px;left:\"+a+\"px;\"+(i||\"\"));if(this.session.$bidiHandler.isBidiRow(t.end.row)){var f=t.clone();f.start.row=f.end.row,f.start.column=0,this.drawBidiSingleLineMarker(e,f,n+\" ace_br12\",r,null,i)}else{u=this.$getTop(t.end.row,r);var l=t.end.column*r.characterWidth;this.elt(n+\" ace_br12\",\"height:\"+o+\"px;\"+\"width:\"+l+\"px;\"+\"top:\"+u+\"px;\"+\"left:\"+s+\"px;\"+(i||\"\"))}o=(t.end.row-t.start.row-1)*r.lineHeight;if(o<=0)return;u=this.$getTop(t.start.row+1,r);var c=(t.start.column?1:0)|(t.end.column?0:8);this.elt(n+(c?\" ace_br\"+c:\"\"),\"height:\"+o+\"px;\"+\"right:0;\"+\"top:\"+u+\"px;\"+\"left:\"+s+\"px;\"+(i||\"\"))},this.drawSingleLineMarker=function(e,t,n,r,i,s){if(this.session.$bidiHandler.isBidiRow(t.start.row))return this.drawBidiSingleLineMarker(e,t,n,r,i,s);var o=r.lineHeight,u=(t.end.column+(i||0)-t.start.column)*r.characterWidth,a=this.$getTop(t.start.row,r),f=this.$padding+t.start.column*r.characterWidth;this.elt(n,\"height:\"+o+\"px;\"+\"width:\"+u+\"px;\"+\"top:\"+a+\"px;\"+\"left:\"+f+\"px;\"+(s||\"\"))},this.drawBidiSingleLineMarker=function(e,t,n,r,i,s){var o=r.lineHeight,u=this.$getTop(t.start.row,r),a=this.$padding,f=this.session.$bidiHandler.getSelections(t.start.column,t.end.column);f.forEach(function(e){this.elt(n,\"height:\"+o+\"px;\"+\"width:\"+e.width+(i||0)+\"px;\"+\"top:\"+u+\"px;\"+\"left:\"+(a+e.left)+\"px;\"+(s||\"\"))},this)},this.drawFullLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;t.start.row!=t.end.row&&(o+=this.$getTop(t.end.row,r)-s),this.elt(n,\"height:\"+o+\"px;\"+\"top:\"+s+\"px;\"+\"left:0;right:0;\"+(i||\"\"))},this.drawScreenLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;this.elt(n,\"height:\"+o+\"px;\"+\"top:\"+s+\"px;\"+\"left:0;right:0;\"+(i||\"\"))}}).call(s.prototype),t.Marker=s}),ace.define(\"ace/layer/text\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/layer/lines\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"../lib/dom\"),s=e(\"../lib/lang\"),o=e(\"./lines\").Lines,u=e(\"../lib/event_emitter\").EventEmitter,a=function(e){this.dom=i,this.element=this.dom.createElement(\"div\"),this.element.className=\"ace_layer ace_text-layer\",e.appendChild(this.element),this.$updateEolChar=this.$updateEolChar.bind(this),this.$lines=new o(this.element)};(function(){r.implement(this,u),this.EOF_CHAR=\"\\u00b6\",this.EOL_CHAR_LF=\"\\u00ac\",this.EOL_CHAR_CRLF=\"\\u00a4\",this.EOL_CHAR=this.EOL_CHAR_LF,this.TAB_CHAR=\"\\u2014\",this.SPACE_CHAR=\"\\u00b7\",this.$padding=0,this.MAX_LINE_LENGTH=1e4,this.$updateEolChar=function(){var e=this.session.doc,t=e.getNewLineCharacter()==\"\\n\"&&e.getNewLineMode()!=\"windows\",n=t?this.EOL_CHAR_LF:this.EOL_CHAR_CRLF;if(this.EOL_CHAR!=n)return this.EOL_CHAR=n,!0},this.setPadding=function(e){this.$padding=e,this.element.style.margin=\"0 \"+e+\"px\"},this.getLineHeight=function(){return this.$fontMetrics.$characterSize.height||0},this.getCharacterWidth=function(){return this.$fontMetrics.$characterSize.width||0},this.$setFontMetrics=function(e){this.$fontMetrics=e,this.$fontMetrics.on(\"changeCharacterSize\",function(e){this._signal(\"changeCharacterSize\",e)}.bind(this)),this.$pollSizeChanges()},this.checkForSizeChanges=function(){this.$fontMetrics.checkForSizeChanges()},this.$pollSizeChanges=function(){return this.$pollSizeChangesTimer=this.$fontMetrics.$pollSizeChanges()},this.setSession=function(e){this.session=e,e&&this.$computeTabString()},this.showInvisibles=!1,this.setShowInvisibles=function(e){return this.showInvisibles==e?!1:(this.showInvisibles=e,this.$computeTabString(),!0)},this.displayIndentGuides=!0,this.setDisplayIndentGuides=function(e){return this.displayIndentGuides==e?!1:(this.displayIndentGuides=e,this.$computeTabString(),!0)},this.$tabStrings=[],this.onChangeTabSize=this.$computeTabString=function(){var e=this.session.getTabSize();this.tabSize=e;var t=this.$tabStrings=[0];for(var n=1;n<e+1;n++)if(this.showInvisibles){var r=this.dom.createElement(\"span\");r.className=\"ace_invisible ace_invisible_tab\",r.textContent=s.stringRepeat(this.TAB_CHAR,n),t.push(r)}else t.push(this.dom.createTextNode(s.stringRepeat(\" \",n),this.element));if(this.displayIndentGuides){this.$indentGuideRe=/\\s\\S| \\t|\\t |\\s$/;var i=\"ace_indent-guide\",o=\"\",u=\"\";if(this.showInvisibles){i+=\" ace_invisible\",o=\" ace_invisible_space\",u=\" ace_invisible_tab\";var a=s.stringRepeat(this.SPACE_CHAR,this.tabSize),f=s.stringRepeat(this.TAB_CHAR,this.tabSize)}else var a=s.stringRepeat(\" \",this.tabSize),f=a;var r=this.dom.createElement(\"span\");r.className=i+o,r.textContent=a,this.$tabStrings[\" \"]=r;var r=this.dom.createElement(\"span\");r.className=i+u,r.textContent=f,this.$tabStrings[\"\t\"]=r}},this.updateLines=function(e,t,n){if(this.config.lastRow!=e.lastRow||this.config.firstRow!=e.firstRow)return this.update(e);this.config=e;var r=Math.max(t,e.firstRow),i=Math.min(n,e.lastRow),s=this.element.childNodes,o=0;for(var u=e.firstRow;u<r;u++){var a=this.session.getFoldLine(u);if(a){if(a.containsRow(r)){r=a.start.row;break}u=a.end.row}o++}var f=!1,u=r,a=this.session.getNextFoldLine(u),l=a?a.start.row:Infinity;for(;;){u>l&&(u=a.end.row+1,a=this.session.getNextFoldLine(u,a),l=a?a.start.row:Infinity);if(u>i)break;var c=s[o++];if(c){this.dom.removeChildren(c),this.$renderLine(c,u,u==l?a:!1),f&&(c.style.top=this.$lines.computeLineTop(u,e,this.session)+\"px\");var h=e.lineHeight*this.session.getRowLength(u)+\"px\";c.style.height!=h&&(f=!0,c.style.height=h)}u++}if(f)while(o<this.$lines.cells.length){var p=this.$lines.cells[o++];p.element.style.top=this.$lines.computeLineTop(p.row,e,this.session)+\"px\"}},this.scrollLines=function(e){var t=this.config;this.config=e;if(this.$lines.pageChanged(t,e))return this.update(e);this.$lines.moveContainer(e);var n=e.lastRow,r=t?t.lastRow:-1;if(!t||r<e.firstRow)return this.update(e);if(n<t.firstRow)return this.update(e);if(!t||t.lastRow<e.firstRow)return this.update(e);if(e.lastRow<t.firstRow)return this.update(e);if(t.firstRow<e.firstRow)for(var i=this.session.getFoldedRowCount(t.firstRow,e.firstRow-1);i>0;i--)this.$lines.shift();if(t.lastRow>e.lastRow)for(var i=this.session.getFoldedRowCount(e.lastRow+1,t.lastRow);i>0;i--)this.$lines.pop();e.firstRow<t.firstRow&&this.$lines.unshift(this.$renderLinesFragment(e,e.firstRow,t.firstRow-1)),e.lastRow>t.lastRow&&this.$lines.push(this.$renderLinesFragment(e,t.lastRow+1,e.lastRow))},this.$renderLinesFragment=function(e,t,n){var r=[],s=t,o=this.session.getNextFoldLine(s),u=o?o.start.row:Infinity;for(;;){s>u&&(s=o.end.row+1,o=this.session.getNextFoldLine(s,o),u=o?o.start.row:Infinity);if(s>n)break;var a=this.$lines.createCell(s,e,this.session),f=a.element;this.dom.removeChildren(f),i.setStyle(f.style,\"height\",this.$lines.computeLineHeight(s,e,this.session)+\"px\"),i.setStyle(f.style,\"top\",this.$lines.computeLineTop(s,e,this.session)+\"px\"),this.$renderLine(f,s,s==u?o:!1),this.$useLineGroups()?f.className=\"ace_line_group\":f.className=\"ace_line\",r.push(a),s++}return r},this.update=function(e){this.$lines.moveContainer(e),this.config=e;var t=e.firstRow,n=e.lastRow,r=this.$lines;while(r.getLength())r.pop();r.push(this.$renderLinesFragment(e,t,n))},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(e,t,n,r){var i=this,o=/(\\t)|( +)|([\\x00-\\x1f\\x80-\\xa0\\xad\\u1680\\u180E\\u2000-\\u200f\\u2028\\u2029\\u202F\\u205F\\uFEFF\\uFFF9-\\uFFFC]+)|(\\u3000)|([\\u1100-\\u115F\\u11A3-\\u11A7\\u11FA-\\u11FF\\u2329-\\u232A\\u2E80-\\u2E99\\u2E9B-\\u2EF3\\u2F00-\\u2FD5\\u2FF0-\\u2FFB\\u3001-\\u303E\\u3041-\\u3096\\u3099-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u3190-\\u31BA\\u31C0-\\u31E3\\u31F0-\\u321E\\u3220-\\u3247\\u3250-\\u32FE\\u3300-\\u4DBF\\u4E00-\\uA48C\\uA490-\\uA4C6\\uA960-\\uA97C\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFAFF\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE66\\uFE68-\\uFE6B\\uFF01-\\uFF60\\uFFE0-\\uFFE6]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF])/g,u=this.dom.createFragment(this.element),a,f=0;while(a=o.exec(r)){var l=a[1],c=a[2],h=a[3],p=a[4],d=a[5];if(!i.showInvisibles&&c)continue;var v=f!=a.index?r.slice(f,a.index):\"\";f=a.index+a[0].length,v&&u.appendChild(this.dom.createTextNode(v,this.element));if(l){var m=i.session.getScreenTabSize(t+a.index);u.appendChild(i.$tabStrings[m].cloneNode(!0)),t+=m-1}else if(c)if(i.showInvisibles){var g=this.dom.createElement(\"span\");g.className=\"ace_invisible ace_invisible_space\",g.textContent=s.stringRepeat(i.SPACE_CHAR,c.length),u.appendChild(g)}else u.appendChild(this.com.createTextNode(c,this.element));else if(h){var g=this.dom.createElement(\"span\");g.className=\"ace_invisible ace_invisible_space ace_invalid\",g.textContent=s.stringRepeat(i.SPACE_CHAR,h.length),u.appendChild(g)}else if(p){t+=1;var g=this.dom.createElement(\"span\");g.style.width=i.config.characterWidth*2+\"px\",g.className=i.showInvisibles?\"ace_cjk ace_invisible ace_invisible_space\":\"ace_cjk\",g.textContent=i.showInvisibles?i.SPACE_CHAR:p,u.appendChild(g)}else if(d){t+=1;var g=this.dom.createElement(\"span\");g.style.width=i.config.characterWidth*2+\"px\",g.className=\"ace_cjk\",g.textContent=d,u.appendChild(g)}}u.appendChild(this.dom.createTextNode(f?r.slice(f):r,this.element));if(!this.$textToken[n.type]){var y=\"ace_\"+n.type.replace(/\\./g,\" ace_\"),g=this.dom.createElement(\"span\");n.type==\"fold\"&&(g.style.width=n.value.length*this.config.characterWidth+\"px\"),g.className=y,g.appendChild(u),e.appendChild(g)}else e.appendChild(u);return t+r.length},this.renderIndentGuide=function(e,t,n){var r=t.search(this.$indentGuideRe);if(r<=0||r>=n)return t;if(t[0]==\" \"){r-=r%this.tabSize;var i=r/this.tabSize;for(var s=0;s<i;s++)e.appendChild(this.$tabStrings[\" \"].cloneNode(!0));return t.substr(r)}if(t[0]==\"\t\"){for(var s=0;s<r;s++)e.appendChild(this.$tabStrings[\"\t\"].cloneNode(!0));return t.substr(r)}return t},this.$createLineElement=function(e){var t=this.dom.createElement(\"div\");return t.className=\"ace_line\",t.style.height=this.config.lineHeight+\"px\",t},this.$renderWrappedLine=function(e,t,n){var r=0,i=0,o=n[0],u=0,a=this.$createLineElement();e.appendChild(a);for(var f=0;f<t.length;f++){var l=t[f],c=l.value;if(f==0&&this.displayIndentGuides){r=c.length,c=this.renderIndentGuide(a,c,o);if(!c)continue;r-=c.length}if(r+c.length<o)u=this.$renderToken(a,u,l,c),r+=c.length;else{while(r+c.length>=o)u=this.$renderToken(a,u,l,c.substring(0,o-r)),c=c.substring(o-r),r=o,a=this.$createLineElement(),e.appendChild(a),a.appendChild(this.dom.createTextNode(s.stringRepeat(\"\\u00a0\",n.indent),this.element)),i++,u=0,o=n[i]||Number.MAX_VALUE;c.length!=0&&(r+=c.length,u=this.$renderToken(a,u,l,c))}}n[n.length-1]>this.MAX_LINE_LENGTH&&this.$renderOverflowMessage(a,u,null,\"\",!0)},this.$renderSimpleLine=function(e,t){var n=0,r=t[0],i=r.value;this.displayIndentGuides&&(i=this.renderIndentGuide(e,i)),i&&(n=this.$renderToken(e,n,r,i));for(var s=1;s<t.length;s++){r=t[s],i=r.value;if(n+i.length>this.MAX_LINE_LENGTH)return this.$renderOverflowMessage(e,n,r,i);n=this.$renderToken(e,n,r,i)}},this.$renderOverflowMessage=function(e,t,n,r,i){n&&this.$renderToken(e,t,n,r.slice(0,this.MAX_LINE_LENGTH-t));var s=this.dom.createElement(\"span\");s.className=\"ace_inline_button ace_keyword ace_toggle_wrap\",s.textContent=i?\"<hide>\":\"<click to see more...>\",e.appendChild(s)},this.$renderLine=function(e,t,n){!n&&n!=0&&(n=this.session.getFoldLine(t));if(n)var r=this.$getFoldLineTokens(t,n);else var r=this.session.getTokens(t);var i=e;if(r.length){var s=this.session.getRowSplitData(t);if(s&&s.length){this.$renderWrappedLine(e,r,s);var i=e.lastChild}else{var i=e;this.$useLineGroups()&&(i=this.$createLineElement(),e.appendChild(i)),this.$renderSimpleLine(i,r)}}else this.$useLineGroups()&&(i=this.$createLineElement(),e.appendChild(i));if(this.showInvisibles&&i){n&&(t=n.end.row);var o=this.dom.createElement(\"span\");o.className=\"ace_invisible ace_invisible_eol\",o.textContent=t==this.session.getLength()-1?this.EOF_CHAR:this.EOL_CHAR,i.appendChild(o)}},this.$getFoldLineTokens=function(e,t){function i(e,t,n){var i=0,s=0;while(s+e[i].value.length<t){s+=e[i].value.length,i++;if(i==e.length)return}if(s!=t){var o=e[i].value.substring(t-s);o.length>n-t&&(o=o.substring(0,n-t)),r.push({type:e[i].type,value:o}),s=t+o.length,i+=1}while(s<n&&i<e.length){var o=e[i].value;o.length+s>n?r.push({type:e[i].type,value:o.substring(0,n-s)}):r.push(e[i]),s+=o.length,i+=1}}var n=this.session,r=[],s=n.getTokens(e);return t.walk(function(e,t,o,u,a){e!=null?r.push({type:\"fold\",value:e}):(a&&(s=n.getTokens(t)),s.length&&i(s,u,o))},t.end.row,this.session.getLine(t.end.row).length),r},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){}}).call(a.prototype),t.Text=a}),ace.define(\"ace/layer/cursor\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";var r=e(\"../lib/dom\"),i=function(e){this.element=r.createElement(\"div\"),this.element.className=\"ace_layer ace_cursor-layer\",e.appendChild(this.element),this.isVisible=!1,this.isBlinking=!0,this.blinkInterval=1e3,this.smoothBlinking=!1,this.cursors=[],this.cursor=this.addCursor(),r.addCssClass(this.element,\"ace_hidden-cursors\"),this.$updateCursors=this.$updateOpacity.bind(this)};(function(){this.$updateOpacity=function(e){var t=this.cursors;for(var n=t.length;n--;)r.setStyle(t[n].style,\"opacity\",e?\"\":\"0\")},this.$startCssAnimation=function(){var e=this.cursors;for(var t=e.length;t--;)e[t].style.animationDuration=this.blinkInterval+\"ms\";setTimeout(function(){r.addCssClass(this.element,\"ace_animate-blinking\")}.bind(this))},this.$stopCssAnimation=function(){r.removeCssClass(this.element,\"ace_animate-blinking\")},this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setBlinking=function(e){e!=this.isBlinking&&(this.isBlinking=e,this.restartTimer())},this.setBlinkInterval=function(e){e!=this.blinkInterval&&(this.blinkInterval=e,this.restartTimer())},this.setSmoothBlinking=function(e){e!=this.smoothBlinking&&(this.smoothBlinking=e,r.setCssClass(this.element,\"ace_smooth-blinking\",e),this.$updateCursors(!0),this.restartTimer())},this.addCursor=function(){var e=r.createElement(\"div\");return e.className=\"ace_cursor\",this.element.appendChild(e),this.cursors.push(e),e},this.removeCursor=function(){if(this.cursors.length>1){var e=this.cursors.pop();return e.parentNode.removeChild(e),e}},this.hideCursor=function(){this.isVisible=!1,r.addCssClass(this.element,\"ace_hidden-cursors\"),this.restartTimer()},this.showCursor=function(){this.isVisible=!0,r.removeCssClass(this.element,\"ace_hidden-cursors\"),this.restartTimer()},this.restartTimer=function(){var e=this.$updateCursors;clearInterval(this.intervalId),clearTimeout(this.timeoutId),this.$stopCssAnimation(),this.smoothBlinking&&r.removeCssClass(this.element,\"ace_smooth-blinking\"),e(!0);if(!this.isBlinking||!this.blinkInterval||!this.isVisible){this.$stopCssAnimation();return}this.smoothBlinking&&setTimeout(function(){r.addCssClass(this.element,\"ace_smooth-blinking\")}.bind(this));if(r.HAS_CSS_ANIMATION)this.$startCssAnimation();else{var t=function(){this.timeoutId=setTimeout(function(){e(!1)},.6*this.blinkInterval)}.bind(this);this.intervalId=setInterval(function(){e(!0),t()},this.blinkInterval),t()}},this.getPixelPosition=function(e,t){if(!this.config||!this.session)return{left:0,top:0};e||(e=this.session.selection.getCursor());var n=this.session.documentToScreenPosition(e),r=this.$padding+(this.session.$bidiHandler.isBidiRow(n.row,e.row)?this.session.$bidiHandler.getPosLeft(n.column):n.column*this.config.characterWidth),i=(n.row-(t?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:r,top:i}},this.isCursorInView=function(e,t){return e.top>=0&&e.top<t.maxHeight},this.update=function(e){this.config=e;var t=this.session.$selectionMarkers,n=0,i=0;if(t===undefined||t.length===0)t=[{cursor:null}];for(var n=0,s=t.length;n<s;n++){var o=this.getPixelPosition(t[n].cursor,!0);if((o.top>e.height+e.offset||o.top<0)&&n>1)continue;var u=this.cursors[i++]||this.addCursor(),a=u.style;this.drawCursor?this.drawCursor(u,o,e,t[n],this.session):this.isCursorInView(o,e)?(r.setStyle(a,\"display\",\"block\"),r.translate(u,o.left,o.top),r.setStyle(a,\"width\",Math.round(e.characterWidth)+\"px\"),r.setStyle(a,\"height\",e.lineHeight+\"px\")):r.setStyle(a,\"display\",\"none\")}while(this.cursors.length>i)this.removeCursor();var f=this.session.getOverwrite();this.$setOverwrite(f),this.$pixelPos=o,this.restartTimer()},this.drawCursor=null,this.$setOverwrite=function(e){e!=this.overwrite&&(this.overwrite=e,e?r.addCssClass(this.element,\"ace_overwrite-cursors\"):r.removeCssClass(this.element,\"ace_overwrite-cursors\"))},this.destroy=function(){clearInterval(this.intervalId),clearTimeout(this.timeoutId)}}).call(i.prototype),t.Cursor=i}),ace.define(\"ace/scrollbar\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/dom\"),s=e(\"./lib/event\"),o=e(\"./lib/event_emitter\").EventEmitter,u=32768,a=function(e){this.element=i.createElement(\"div\"),this.element.className=\"ace_scrollbar ace_scrollbar\"+this.classSuffix,this.inner=i.createElement(\"div\"),this.inner.className=\"ace_scrollbar-inner\",this.inner.textContent=\"\\u00a0\",this.element.appendChild(this.inner),e.appendChild(this.element),this.setVisible(!1),this.skipEvent=!1,s.addListener(this.element,\"scroll\",this.onScroll.bind(this)),s.addListener(this.element,\"mousedown\",s.preventDefault)};(function(){r.implement(this,o),this.setVisible=function(e){this.element.style.display=e?\"\":\"none\",this.isVisible=e,this.coeff=1}}).call(a.prototype);var f=function(e,t){a.call(this,e),this.scrollTop=0,this.scrollHeight=0,t.$scrollbarWidth=this.width=i.scrollbarWidth(e.ownerDocument),this.inner.style.width=this.element.style.width=(this.width||15)+5+\"px\",this.$minWidth=0};r.inherits(f,a),function(){this.classSuffix=\"-v\",this.onScroll=function(){if(!this.skipEvent){this.scrollTop=this.element.scrollTop;if(this.coeff!=1){var e=this.element.clientHeight/this.scrollHeight;this.scrollTop=this.scrollTop*(1-e)/(this.coeff-e)}this._emit(\"scroll\",{data:this.scrollTop})}this.skipEvent=!1},this.getWidth=function(){return Math.max(this.isVisible?this.width:0,this.$minWidth||0)},this.setHeight=function(e){this.element.style.height=e+\"px\"},this.setInnerHeight=this.setScrollHeight=function(e){this.scrollHeight=e,e>u?(this.coeff=u/e,e=u):this.coeff!=1&&(this.coeff=1),this.inner.style.height=e+\"px\"},this.setScrollTop=function(e){this.scrollTop!=e&&(this.skipEvent=!0,this.scrollTop=e,this.element.scrollTop=e*this.coeff)}}.call(f.prototype);var l=function(e,t){a.call(this,e),this.scrollLeft=0,this.height=t.$scrollbarWidth,this.inner.style.height=this.element.style.height=(this.height||15)+5+\"px\"};r.inherits(l,a),function(){this.classSuffix=\"-h\",this.onScroll=function(){this.skipEvent||(this.scrollLeft=this.element.scrollLeft,this._emit(\"scroll\",{data:this.scrollLeft})),this.skipEvent=!1},this.getHeight=function(){return this.isVisible?this.height:0},this.setWidth=function(e){this.element.style.width=e+\"px\"},this.setInnerWidth=function(e){this.inner.style.width=e+\"px\"},this.setScrollWidth=function(e){this.inner.style.width=e+\"px\"},this.setScrollLeft=function(e){this.scrollLeft!=e&&(this.skipEvent=!0,this.scrollLeft=this.element.scrollLeft=e)}}.call(l.prototype),t.ScrollBar=f,t.ScrollBarV=f,t.ScrollBarH=l,t.VScrollBar=f,t.HScrollBar=l}),ace.define(\"ace/renderloop\",[\"require\",\"exports\",\"module\",\"ace/lib/event\"],function(e,t,n){\"use strict\";var r=e(\"./lib/event\"),i=function(e,t){this.onRender=e,this.pending=!1,this.changes=0,this.$recursionLimit=2,this.window=t||window;var n=this;this._flush=function(e){n.pending=!1;var t=n.changes;t&&(r.blockIdle(100),n.changes=0,n.onRender(t));if(n.changes){if(n.$recursionLimit--<0)return;n.schedule()}else n.$recursionLimit=2}};(function(){this.schedule=function(e){this.changes=this.changes|e,this.changes&&!this.pending&&(r.nextFrame(this._flush),this.pending=!0)},this.clear=function(e){var t=this.changes;return this.changes=0,t}}).call(i.prototype),t.RenderLoop=i}),ace.define(\"ace/layer/font_metrics\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/lib/event\",\"ace/lib/useragent\",\"ace/lib/event_emitter\"],function(e,t,n){var r=e(\"../lib/oop\"),i=e(\"../lib/dom\"),s=e(\"../lib/lang\"),o=e(\"../lib/event\"),u=e(\"../lib/useragent\"),a=e(\"../lib/event_emitter\").EventEmitter,f=256,l=typeof ResizeObserver==\"function\",c=200,h=t.FontMetrics=function(e){this.el=i.createElement(\"div\"),this.$setMeasureNodeStyles(this.el.style,!0),this.$main=i.createElement(\"div\"),this.$setMeasureNodeStyles(this.$main.style),this.$measureNode=i.createElement(\"div\"),this.$setMeasureNodeStyles(this.$measureNode.style),this.el.appendChild(this.$main),this.el.appendChild(this.$measureNode),e.appendChild(this.el),this.$measureNode.innerHTML=s.stringRepeat(\"X\",f),this.$characterSize={width:0,height:0},l?this.$addObserver():this.checkForSizeChanges()};(function(){r.implement(this,a),this.$characterSize={width:0,height:0},this.$setMeasureNodeStyles=function(e,t){e.width=e.height=\"auto\",e.left=e.top=\"0px\",e.visibility=\"hidden\",e.position=\"absolute\",e.whiteSpace=\"pre\",u.isIE<8?e[\"font-family\"]=\"inherit\":e.font=\"inherit\",e.overflow=t?\"hidden\":\"visible\"},this.checkForSizeChanges=function(e){e===undefined&&(e=this.$measureSizes());if(e&&(this.$characterSize.width!==e.width||this.$characterSize.height!==e.height)){this.$measureNode.style.fontWeight=\"bold\";var t=this.$measureSizes();this.$measureNode.style.fontWeight=\"\",this.$characterSize=e,this.charSizes=Object.create(null),this.allowBoldFonts=t&&t.width===e.width&&t.height===e.height,this._emit(\"changeCharacterSize\",{data:e})}},this.$addObserver=function(){var e=this;this.$observer=new window.ResizeObserver(function(t){var n=t[0].contentRect;e.checkForSizeChanges({height:n.height,width:n.width/f})}),this.$observer.observe(this.$measureNode)},this.$pollSizeChanges=function(){if(this.$pollSizeChangesTimer||this.$observer)return this.$pollSizeChangesTimer;var e=this;return this.$pollSizeChangesTimer=o.onIdle(function t(){e.checkForSizeChanges(),o.onIdle(t,500)},500)},this.setPolling=function(e){e?this.$pollSizeChanges():this.$pollSizeChangesTimer&&(clearInterval(this.$pollSizeChangesTimer),this.$pollSizeChangesTimer=0)},this.$measureSizes=function(e){var t={height:(e||this.$measureNode).clientHeight,width:(e||this.$measureNode).clientWidth/f};return t.width===0||t.height===0?null:t},this.$measureCharWidth=function(e){this.$main.innerHTML=s.stringRepeat(e,f);var t=this.$main.getBoundingClientRect();return t.width/f},this.getCharacterWidth=function(e){var t=this.charSizes[e];return t===undefined&&(t=this.charSizes[e]=this.$measureCharWidth(e)/this.$characterSize.width),t},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$observer&&this.$observer.disconnect(),this.el&&this.el.parentNode&&this.el.parentNode.removeChild(this.el)},this.$getZoom=function e(t){return t?(window.getComputedStyle(t).zoom||1)*e(t.parentElement):1},this.$initTransformMeasureNodes=function(){var e=function(e,t){return[\"div\",{style:\"position: absolute;top:\"+e+\"px;left:\"+t+\"px;\"}]};this.els=i.buildDom([e(0,0),e(c,0),e(0,c),e(c,c)],this.el)},this.transformCoordinates=function(e,t){function r(e,t,n){var r=e[1]*t[0]-e[0]*t[1];return[(-t[1]*n[0]+t[0]*n[1])/r,(+e[1]*n[0]-e[0]*n[1])/r]}function i(e,t){return[e[0]-t[0],e[1]-t[1]]}function s(e,t){return[e[0]+t[0],e[1]+t[1]]}function o(e,t){return[e*t[0],e*t[1]]}function u(e){var t=e.getBoundingClientRect();return[t.left,t.top]}if(e){var n=this.$getZoom(this.el);e=o(1/n,e)}this.els||this.$initTransformMeasureNodes();var a=u(this.els[0]),f=u(this.els[1]),l=u(this.els[2]),h=u(this.els[3]),p=r(i(h,f),i(h,l),i(s(f,l),s(h,a))),d=o(1+p[0],i(f,a)),v=o(1+p[1],i(l,a));if(t){var m=t,g=p[0]*m[0]/c+p[1]*m[1]/c+1,y=s(o(m[0],d),o(m[1],v));return s(o(1/g/c,y),a)}var b=i(e,a),w=r(i(d,o(p[0],b)),i(v,o(p[1],b)),b);return o(c,w)}}).call(h.prototype)}),ace.define(\"ace/virtual_renderer\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/config\",\"ace/layer/gutter\",\"ace/layer/marker\",\"ace/layer/text\",\"ace/layer/cursor\",\"ace/scrollbar\",\"ace/scrollbar\",\"ace/renderloop\",\"ace/layer/font_metrics\",\"ace/lib/event_emitter\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/dom\"),s=e(\"./config\"),o=e(\"./layer/gutter\").Gutter,u=e(\"./layer/marker\").Marker,a=e(\"./layer/text\").Text,f=e(\"./layer/cursor\").Cursor,l=e(\"./scrollbar\").HScrollBar,c=e(\"./scrollbar\").VScrollBar,h=e(\"./renderloop\").RenderLoop,p=e(\"./layer/font_metrics\").FontMetrics,d=e(\"./lib/event_emitter\").EventEmitter,v='.ace_br1 {border-top-left-radius    : 3px;}.ace_br2 {border-top-right-radius   : 3px;}.ace_br3 {border-top-left-radius    : 3px; border-top-right-radius:    3px;}.ace_br4 {border-bottom-right-radius: 3px;}.ace_br5 {border-top-left-radius    : 3px; border-bottom-right-radius: 3px;}.ace_br6 {border-top-right-radius   : 3px; border-bottom-right-radius: 3px;}.ace_br7 {border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-right-radius: 3px;}.ace_br8 {border-bottom-left-radius : 3px;}.ace_br9 {border-top-left-radius    : 3px; border-bottom-left-radius:  3px;}.ace_br10{border-top-right-radius   : 3px; border-bottom-left-radius:  3px;}.ace_br11{border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-left-radius:  3px;}.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}.ace_br13{border-top-left-radius    : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}.ace_br14{border-top-right-radius   : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}.ace_br15{border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_editor {position: relative;overflow: hidden;font: 12px/normal \\'Monaco\\', \\'Menlo\\', \\'Ubuntu Mono\\', \\'Consolas\\', \\'source-code-pro\\', monospace;direction: ltr;text-align: left;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}.ace_scroller {position: absolute;overflow: hidden;top: 0;bottom: 0;background-color: inherit;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;cursor: text;}.ace_content {position: absolute;box-sizing: border-box;min-width: 100%;contain: style size layout;}.ace_dragging .ace_scroller:before{position: absolute;top: 0;left: 0;right: 0;bottom: 0;content: \\'\\';background: rgba(250, 250, 250, 0.01);z-index: 1000;}.ace_dragging.ace_dark .ace_scroller:before{background: rgba(0, 0, 0, 0.01);}.ace_selecting, .ace_selecting * {cursor: text !important;}.ace_gutter {position: absolute;overflow : hidden;width: auto;top: 0;bottom: 0;left: 0;cursor: default;z-index: 4;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;contain: style size layout;}.ace_gutter-active-line {position: absolute;left: 0;right: 0;}.ace_scroller.ace_scroll-left {box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;}.ace_gutter-cell {position: absolute;top: 0;left: 0;right: 0;padding-left: 19px;padding-right: 6px;background-repeat: no-repeat;}.ace_gutter-cell.ace_error {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==\");background-repeat: no-repeat;background-position: 2px center;}.ace_gutter-cell.ace_warning {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==\");background-position: 2px center;}.ace_gutter-cell.ace_info {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=\");background-position: 2px center;}.ace_dark .ace_gutter-cell.ace_info {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC\");}.ace_scrollbar {contain: strict;position: absolute;right: 0;bottom: 0;z-index: 6;}.ace_scrollbar-inner {position: absolute;cursor: text;left: 0;top: 0;}.ace_scrollbar-v{overflow-x: hidden;overflow-y: scroll;top: 0;}.ace_scrollbar-h {overflow-x: scroll;overflow-y: hidden;left: 0;}.ace_print-margin {position: absolute;height: 100%;}.ace_text-input {position: absolute;z-index: 0;width: 0.5em;height: 1em;opacity: 0;background: transparent;-moz-appearance: none;appearance: none;border: none;resize: none;outline: none;overflow: hidden;font: inherit;padding: 0 1px;margin: 0 -1px;contain: strict;-ms-user-select: text;-moz-user-select: text;-webkit-user-select: text;user-select: text;white-space: pre!important;}.ace_text-input.ace_composition {background: transparent;color: inherit;z-index: 1000;opacity: 1;}.ace_composition_placeholder { color: transparent }.ace_composition_marker { border-bottom: 1px solid;position: absolute;border-radius: 0;margin-top: 1px;}[ace_nocontext=true] {transform: none!important;filter: none!important;perspective: none!important;clip-path: none!important;mask : none!important;contain: none!important;perspective: none!important;mix-blend-mode: initial!important;z-index: auto;}.ace_layer {z-index: 1;position: absolute;overflow: hidden;word-wrap: normal;white-space: pre;height: 100%;width: 100%;box-sizing: border-box;pointer-events: none;}.ace_gutter-layer {position: relative;width: auto;text-align: right;pointer-events: auto;height: 1000000px;contain: style size layout;}.ace_text-layer {font: inherit !important;position: absolute;height: 1000000px;width: 1000000px;contain: style size layout;}.ace_text-layer > .ace_line, .ace_text-layer > .ace_line_group {contain: style size layout;position: absolute;top: 0;left: 0;right: 0;}.ace_hidpi .ace_text-layer,.ace_hidpi .ace_gutter-layer,.ace_hidpi .ace_content,.ace_hidpi .ace_gutter {contain: strict;will-change: transform;}.ace_hidpi .ace_text-layer > .ace_line, .ace_hidpi .ace_text-layer > .ace_line_group {contain: strict;}.ace_cjk {display: inline-block;text-align: center;}.ace_cursor-layer {z-index: 4;}.ace_cursor {z-index: 4;position: absolute;box-sizing: border-box;border-left: 2px solid;transform: translatez(0);}.ace_multiselect .ace_cursor {border-left-width: 1px;}.ace_slim-cursors .ace_cursor {border-left-width: 1px;}.ace_overwrite-cursors .ace_cursor {border-left-width: 0;border-bottom: 1px solid;}.ace_hidden-cursors .ace_cursor {opacity: 0.2;}.ace_smooth-blinking .ace_cursor {transition: opacity 0.18s;}.ace_animate-blinking .ace_cursor {animation-duration: 1000ms;animation-timing-function: step-end;animation-name: blink-ace-animate;animation-iteration-count: infinite;}.ace_animate-blinking.ace_smooth-blinking .ace_cursor {animation-duration: 1000ms;animation-timing-function: ease-in-out;animation-name: blink-ace-animate-smooth;}@keyframes blink-ace-animate {from, to { opacity: 1; }60% { opacity: 0; }}@keyframes blink-ace-animate-smooth {from, to { opacity: 1; }45% { opacity: 1; }60% { opacity: 0; }85% { opacity: 0; }}.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {position: absolute;z-index: 3;}.ace_marker-layer .ace_selection {position: absolute;z-index: 5;}.ace_marker-layer .ace_bracket {position: absolute;z-index: 6;}.ace_marker-layer .ace_active-line {position: absolute;z-index: 2;}.ace_marker-layer .ace_selected-word {position: absolute;z-index: 4;box-sizing: border-box;}.ace_line .ace_fold {box-sizing: border-box;display: inline-block;height: 11px;margin-top: -2px;vertical-align: middle;background-image:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=\");background-repeat: no-repeat, repeat-x;background-position: center center, top left;color: transparent;border: 1px solid black;border-radius: 2px;cursor: pointer;pointer-events: auto;}.ace_dark .ace_fold {}.ace_fold:hover{background-image:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC\");}.ace_tooltip {background-color: #FFF;background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));border: 1px solid gray;border-radius: 1px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);color: black;max-width: 100%;padding: 3px 4px;position: fixed;z-index: 999999;box-sizing: border-box;cursor: default;white-space: pre;word-wrap: break-word;line-height: normal;font-style: normal;font-weight: normal;letter-spacing: normal;pointer-events: none;}.ace_folding-enabled > .ace_gutter-cell {padding-right: 13px;}.ace_fold-widget {box-sizing: border-box;margin: 0 -12px 0 1px;display: none;width: 11px;vertical-align: top;background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==\");background-repeat: no-repeat;background-position: center;border-radius: 3px;border: 1px solid transparent;cursor: pointer;}.ace_folding-enabled .ace_fold-widget {display: inline-block;   }.ace_fold-widget.ace_end {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==\");}.ace_fold-widget.ace_closed {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==\");}.ace_fold-widget:hover {border: 1px solid rgba(0, 0, 0, 0.3);background-color: rgba(255, 255, 255, 0.2);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);}.ace_fold-widget:active {border: 1px solid rgba(0, 0, 0, 0.4);background-color: rgba(0, 0, 0, 0.05);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);}.ace_dark .ace_fold-widget {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\");}.ace_dark .ace_fold-widget.ace_end {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\");}.ace_dark .ace_fold-widget.ace_closed {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\");}.ace_dark .ace_fold-widget:hover {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);background-color: rgba(255, 255, 255, 0.1);}.ace_dark .ace_fold-widget:active {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);}.ace_inline_button {border: 1px solid lightgray;display: inline-block;margin: -1px 8px;padding: 0 5px;pointer-events: auto;cursor: pointer;}.ace_inline_button:hover {border-color: gray;background: rgba(200,200,200,0.2);display: inline-block;pointer-events: auto;}.ace_fold-widget.ace_invalid {background-color: #FFB4B4;border-color: #DE5555;}.ace_fade-fold-widgets .ace_fold-widget {transition: opacity 0.4s ease 0.05s;opacity: 0;}.ace_fade-fold-widgets:hover .ace_fold-widget {transition: opacity 0.05s ease 0.05s;opacity:1;}.ace_underline {text-decoration: underline;}.ace_bold {font-weight: bold;}.ace_nobold .ace_bold {font-weight: normal;}.ace_italic {font-style: italic;}.ace_error-marker {background-color: rgba(255, 0, 0,0.2);position: absolute;z-index: 9;}.ace_highlight-marker {background-color: rgba(255, 255, 0,0.2);position: absolute;z-index: 8;}.ace_mobile-menu {position: absolute;line-height: 1.5;border-radius: 4px;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;background: white;box-shadow: 1px 3px 2px grey;border: 1px solid #dcdcdc;color: black;}.ace_dark > .ace_mobile-menu {background: #333;color: #ccc;box-shadow: 1px 3px 2px grey;border: 1px solid #444;}.ace_mobile-button {padding: 2px;cursor: pointer;overflow: hidden;}.ace_mobile-button:hover {background-color: #eee;opacity:1;}.ace_mobile-button:active {background-color: #ddd;}',m=e(\"./lib/useragent\"),g=m.isIE;i.importCssString(v,\"ace_editor.css\");var y=function(e,t){var n=this;this.container=e||i.createElement(\"div\"),i.addCssClass(this.container,\"ace_editor\"),i.HI_DPI&&i.addCssClass(this.container,\"ace_hidpi\"),this.setTheme(t),this.$gutter=i.createElement(\"div\"),this.$gutter.className=\"ace_gutter\",this.container.appendChild(this.$gutter),this.$gutter.setAttribute(\"aria-hidden\",!0),this.scroller=i.createElement(\"div\"),this.scroller.className=\"ace_scroller\",this.container.appendChild(this.scroller),this.content=i.createElement(\"div\"),this.content.className=\"ace_content\",this.scroller.appendChild(this.content),this.$gutterLayer=new o(this.$gutter),this.$gutterLayer.on(\"changeGutterWidth\",this.onGutterResize.bind(this)),this.$markerBack=new u(this.content);var r=this.$textLayer=new a(this.content);this.canvas=r.element,this.$markerFront=new u(this.content),this.$cursorLayer=new f(this.content),this.$horizScroll=!1,this.$vScroll=!1,this.scrollBar=this.scrollBarV=new c(this.container,this),this.scrollBarH=new l(this.container,this),this.scrollBarV.addEventListener(\"scroll\",function(e){n.$scrollAnimation||n.session.setScrollTop(e.data-n.scrollMargin.top)}),this.scrollBarH.addEventListener(\"scroll\",function(e){n.$scrollAnimation||n.session.setScrollLeft(e.data-n.scrollMargin.left)}),this.scrollTop=0,this.scrollLeft=0,this.cursorPos={row:0,column:0},this.$fontMetrics=new p(this.container),this.$textLayer.$setFontMetrics(this.$fontMetrics),this.$textLayer.addEventListener(\"changeCharacterSize\",function(e){n.updateCharacterSize(),n.onResize(!0,n.gutterWidth,n.$size.width,n.$size.height),n._signal(\"changeCharacterSize\",e)}),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0,$dirty:!0},this.layerConfig={width:1,padding:0,firstRow:0,firstRowScreen:0,lastRow:0,lineHeight:0,characterWidth:0,minHeight:1,maxHeight:1,offset:0,height:1,gutterOffset:1},this.scrollMargin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.margin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.$keepTextAreaAtCursor=!m.isIOS,this.$loop=new h(this.$renderChanges.bind(this),this.container.ownerDocument.defaultView),this.$loop.schedule(this.CHANGE_FULL),this.updateCharacterSize(),this.setPadding(4),s.resetOptions(this),s._signal(\"renderer\",this)};(function(){this.CHANGE_CURSOR=1,this.CHANGE_MARKER=2,this.CHANGE_GUTTER=4,this.CHANGE_SCROLL=8,this.CHANGE_LINES=16,this.CHANGE_TEXT=32,this.CHANGE_SIZE=64,this.CHANGE_MARKER_BACK=128,this.CHANGE_MARKER_FRONT=256,this.CHANGE_FULL=512,this.CHANGE_H_SCROLL=1024,r.implement(this,d),this.updateCharacterSize=function(){this.$textLayer.allowBoldFonts!=this.$allowBoldFonts&&(this.$allowBoldFonts=this.$textLayer.allowBoldFonts,this.setStyle(\"ace_nobold\",!this.$allowBoldFonts)),this.layerConfig.characterWidth=this.characterWidth=this.$textLayer.getCharacterWidth(),this.layerConfig.lineHeight=this.lineHeight=this.$textLayer.getLineHeight(),this.$updatePrintMargin(),i.setStyle(this.scroller.style,\"line-height\",this.lineHeight+\"px\")},this.setSession=function(e){this.session&&this.session.doc.off(\"changeNewLineMode\",this.onChangeNewLineMode),this.session=e,e&&this.scrollMargin.top&&e.getScrollTop()<=0&&e.setScrollTop(-this.scrollMargin.top),this.$cursorLayer.setSession(e),this.$markerBack.setSession(e),this.$markerFront.setSession(e),this.$gutterLayer.setSession(e),this.$textLayer.setSession(e);if(!e)return;this.$loop.schedule(this.CHANGE_FULL),this.session.$setFontMetrics(this.$fontMetrics),this.scrollBarH.scrollLeft=this.scrollBarV.scrollTop=null,this.onChangeNewLineMode=this.onChangeNewLineMode.bind(this),this.onChangeNewLineMode(),this.session.doc.on(\"changeNewLineMode\",this.onChangeNewLineMode)},this.updateLines=function(e,t,n){t===undefined&&(t=Infinity),this.$changedLines?(this.$changedLines.firstRow>e&&(this.$changedLines.firstRow=e),this.$changedLines.lastRow<t&&(this.$changedLines.lastRow=t)):this.$changedLines={firstRow:e,lastRow:t};if(this.$changedLines.lastRow<this.layerConfig.firstRow){if(!n)return;this.$changedLines.lastRow=this.layerConfig.lastRow}if(this.$changedLines.firstRow>this.layerConfig.lastRow)return;this.$loop.schedule(this.CHANGE_LINES)},this.onChangeNewLineMode=function(){this.$loop.schedule(this.CHANGE_TEXT),this.$textLayer.$updateEolChar(),this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR)},this.onChangeTabSize=function(){this.$loop.schedule(this.CHANGE_TEXT|this.CHANGE_MARKER),this.$textLayer.onChangeTabSize()},this.updateText=function(){this.$loop.schedule(this.CHANGE_TEXT)},this.updateFull=function(e){e?this.$renderChanges(this.CHANGE_FULL,!0):this.$loop.schedule(this.CHANGE_FULL)},this.updateFontSize=function(){this.$textLayer.checkForSizeChanges()},this.$changes=0,this.$updateSizeAsync=function(){this.$loop.pending?this.$size.$dirty=!0:this.onResize()},this.onResize=function(e,t,n,r){if(this.resizing>2)return;this.resizing>0?this.resizing++:this.resizing=e?1:0;var i=this.container;r||(r=i.clientHeight||i.scrollHeight),n||(n=i.clientWidth||i.scrollWidth);var s=this.$updateCachedSize(e,t,n,r);if(!this.$size.scrollerHeight||!n&&!r)return this.resizing=0;e&&(this.$gutterLayer.$padding=null),e?this.$renderChanges(s|this.$changes,!0):this.$loop.schedule(s|this.$changes),this.resizing&&(this.resizing=0),this.scrollBarV.scrollLeft=this.scrollBarV.scrollTop=null},this.$updateCachedSize=function(e,t,n,r){r-=this.$extraHeight||0;var s=0,o=this.$size,u={width:o.width,height:o.height,scrollerHeight:o.scrollerHeight,scrollerWidth:o.scrollerWidth};r&&(e||o.height!=r)&&(o.height=r,s|=this.CHANGE_SIZE,o.scrollerHeight=o.height,this.$horizScroll&&(o.scrollerHeight-=this.scrollBarH.getHeight()),this.scrollBarV.element.style.bottom=this.scrollBarH.getHeight()+\"px\",s|=this.CHANGE_SCROLL);if(n&&(e||o.width!=n)){s|=this.CHANGE_SIZE,o.width=n,t==null&&(t=this.$showGutter?this.$gutter.offsetWidth:0),this.gutterWidth=t,i.setStyle(this.scrollBarH.element.style,\"left\",t+\"px\"),i.setStyle(this.scroller.style,\"left\",t+this.margin.left+\"px\"),o.scrollerWidth=Math.max(0,n-t-this.scrollBarV.getWidth()-this.margin.h),i.setStyle(this.$gutter.style,\"left\",this.margin.left+\"px\");var a=this.scrollBarV.getWidth()+\"px\";i.setStyle(this.scrollBarH.element.style,\"right\",a),i.setStyle(this.scroller.style,\"right\",a),i.setStyle(this.scroller.style,\"bottom\",this.scrollBarH.getHeight());if(this.session&&this.session.getUseWrapMode()&&this.adjustWrapLimit()||e)s|=this.CHANGE_FULL}return o.$dirty=!n||!r,s&&this._signal(\"resize\",u),s},this.onGutterResize=function(e){var t=this.$showGutter?e:0;t!=this.gutterWidth&&(this.$changes|=this.$updateCachedSize(!0,t,this.$size.width,this.$size.height)),this.session.getUseWrapMode()&&this.adjustWrapLimit()?this.$loop.schedule(this.CHANGE_FULL):this.$size.$dirty?this.$loop.schedule(this.CHANGE_FULL):this.$computeLayerConfig()},this.adjustWrapLimit=function(){var e=this.$size.scrollerWidth-this.$padding*2,t=Math.floor(e/this.characterWidth);return this.session.adjustWrapLimit(t,this.$showPrintMargin&&this.$printMarginColumn)},this.setAnimatedScroll=function(e){this.setOption(\"animatedScroll\",e)},this.getAnimatedScroll=function(){return this.$animatedScroll},this.setShowInvisibles=function(e){this.setOption(\"showInvisibles\",e),this.session.$bidiHandler.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.getOption(\"showInvisibles\")},this.getDisplayIndentGuides=function(){return this.getOption(\"displayIndentGuides\")},this.setDisplayIndentGuides=function(e){this.setOption(\"displayIndentGuides\",e)},this.setShowPrintMargin=function(e){this.setOption(\"showPrintMargin\",e)},this.getShowPrintMargin=function(){return this.getOption(\"showPrintMargin\")},this.setPrintMarginColumn=function(e){this.setOption(\"printMarginColumn\",e)},this.getPrintMarginColumn=function(){return this.getOption(\"printMarginColumn\")},this.getShowGutter=function(){return this.getOption(\"showGutter\")},this.setShowGutter=function(e){return this.setOption(\"showGutter\",e)},this.getFadeFoldWidgets=function(){return this.getOption(\"fadeFoldWidgets\")},this.setFadeFoldWidgets=function(e){this.setOption(\"fadeFoldWidgets\",e)},this.setHighlightGutterLine=function(e){this.setOption(\"highlightGutterLine\",e)},this.getHighlightGutterLine=function(){return this.getOption(\"highlightGutterLine\")},this.$updatePrintMargin=function(){if(!this.$showPrintMargin&&!this.$printMarginEl)return;if(!this.$printMarginEl){var e=i.createElement(\"div\");e.className=\"ace_layer ace_print-margin-layer\",this.$printMarginEl=i.createElement(\"div\"),this.$printMarginEl.className=\"ace_print-margin\",e.appendChild(this.$printMarginEl),this.content.insertBefore(e,this.content.firstChild)}var t=this.$printMarginEl.style;t.left=Math.round(this.characterWidth*this.$printMarginColumn+this.$padding)+\"px\",t.visibility=this.$showPrintMargin?\"visible\":\"hidden\",this.session&&this.session.$wrap==-1&&this.adjustWrapLimit()},this.getContainerElement=function(){return this.container},this.getMouseEventTarget=function(){return this.scroller},this.getTextAreaContainer=function(){return this.container},this.$moveTextAreaToCursor=function(){if(this.$isMousePressed)return;var e=this.textarea.style,t=this.$composition;if(!this.$keepTextAreaAtCursor&&!t){i.translate(this.textarea,-100,0);return}var n=this.$cursorLayer.$pixelPos;if(!n)return;t&&t.markerRange&&(n=this.$cursorLayer.getPixelPosition(t.markerRange.start,!0));var r=this.layerConfig,s=n.top,o=n.left;s-=r.offset;var u=t&&t.useTextareaForIME?this.lineHeight:g?0:1;if(s<0||s>r.height-u){i.translate(this.textarea,0,0);return}var a=1,f=this.$size.height-u;if(!t)s+=this.lineHeight;else if(t.useTextareaForIME){var l=this.textarea.value;a=this.characterWidth*this.session.$getStringScreenWidth(l)[0],u+=2}else s+=this.lineHeight+2;o-=this.scrollLeft,o>this.$size.scrollerWidth-a&&(o=this.$size.scrollerWidth-a),o+=this.gutterWidth+this.margin.left,i.setStyle(e,\"height\",u+\"px\"),i.setStyle(e,\"width\",a+\"px\"),i.translate(this.textarea,Math.min(o,this.$size.scrollerWidth-a),Math.min(s,f))},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(this.layerConfig.offset===0?0:1)},this.getLastFullyVisibleRow=function(){var e=this.layerConfig,t=e.lastRow,n=this.session.documentToScreenRow(t,0)*e.lineHeight;return n-this.session.getScrollTop()>e.height-e.lineHeight?t-1:t},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(e){this.$padding=e,this.$textLayer.setPadding(e),this.$cursorLayer.setPadding(e),this.$markerFront.setPadding(e),this.$markerBack.setPadding(e),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.setScrollMargin=function(e,t,n,r){var i=this.scrollMargin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,i.top&&this.scrollTop<=0&&this.session&&this.session.setScrollTop(-i.top),this.updateFull()},this.setMargin=function(e,t,n,r){var i=this.margin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,this.$updateCachedSize(!0,this.gutterWidth,this.$size.width,this.$size.height),this.updateFull()},this.getHScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setHScrollBarAlwaysVisible=function(e){this.setOption(\"hScrollBarAlwaysVisible\",e)},this.getVScrollBarAlwaysVisible=function(){return this.$vScrollBarAlwaysVisible},this.setVScrollBarAlwaysVisible=function(e){this.setOption(\"vScrollBarAlwaysVisible\",e)},this.$updateScrollBarV=function(){var e=this.layerConfig.maxHeight,t=this.$size.scrollerHeight;!this.$maxLines&&this.$scrollPastEnd&&(e-=(t-this.lineHeight)*this.$scrollPastEnd,this.scrollTop>e-t&&(e=this.scrollTop+t,this.scrollBarV.scrollTop=null)),this.scrollBarV.setScrollHeight(e+this.scrollMargin.v),this.scrollBarV.setScrollTop(this.scrollTop+this.scrollMargin.top)},this.$updateScrollBarH=function(){this.scrollBarH.setScrollWidth(this.layerConfig.width+2*this.$padding+this.scrollMargin.h),this.scrollBarH.setScrollLeft(this.scrollLeft+this.scrollMargin.left)},this.$frozen=!1,this.freeze=function(){this.$frozen=!0},this.unfreeze=function(){this.$frozen=!1},this.$renderChanges=function(e,t){this.$changes&&(e|=this.$changes,this.$changes=0);if(!this.session||!this.container.offsetWidth||this.$frozen||!e&&!t){this.$changes|=e;return}if(this.$size.$dirty)return this.$changes|=e,this.onResize(!0);this.lineHeight||this.$textLayer.checkForSizeChanges(),this._signal(\"beforeRender\"),this.session&&this.session.$bidiHandler&&this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics);var n=this.layerConfig;if(e&this.CHANGE_FULL||e&this.CHANGE_SIZE||e&this.CHANGE_TEXT||e&this.CHANGE_LINES||e&this.CHANGE_SCROLL||e&this.CHANGE_H_SCROLL){e|=this.$computeLayerConfig()|this.$loop.clear();if(n.firstRow!=this.layerConfig.firstRow&&n.firstRowScreen==this.layerConfig.firstRowScreen){var r=this.scrollTop+(n.firstRow-this.layerConfig.firstRow)*this.lineHeight;r>0&&(this.scrollTop=r,e|=this.CHANGE_SCROLL,e|=this.$computeLayerConfig()|this.$loop.clear())}n=this.layerConfig,this.$updateScrollBarV(),e&this.CHANGE_H_SCROLL&&this.$updateScrollBarH(),i.translate(this.content,-this.scrollLeft,-n.offset);var s=n.width+2*this.$padding+\"px\",o=n.minHeight+\"px\";i.setStyle(this.content.style,\"width\",s),i.setStyle(this.content.style,\"height\",o)}e&this.CHANGE_H_SCROLL&&(i.translate(this.content,-this.scrollLeft,-n.offset),this.scroller.className=this.scrollLeft<=0?\"ace_scroller\":\"ace_scroller ace_scroll-left\");if(e&this.CHANGE_FULL){this.$changedLines=null,this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this._signal(\"afterRender\");return}if(e&this.CHANGE_SCROLL){this.$changedLines=null,e&this.CHANGE_TEXT||e&this.CHANGE_LINES?this.$textLayer.update(n):this.$textLayer.scrollLines(n),this.$showGutter&&(e&this.CHANGE_GUTTER||e&this.CHANGE_LINES?this.$gutterLayer.update(n):this.$gutterLayer.scrollLines(n)),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this._signal(\"afterRender\");return}e&this.CHANGE_TEXT?(this.$changedLines=null,this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n)):e&this.CHANGE_LINES?(this.$updateLines()||e&this.CHANGE_GUTTER&&this.$showGutter)&&this.$gutterLayer.update(n):e&this.CHANGE_TEXT||e&this.CHANGE_GUTTER?this.$showGutter&&this.$gutterLayer.update(n):e&this.CHANGE_CURSOR&&this.$highlightGutterLine&&this.$gutterLayer.updateLineHighlight(n),e&this.CHANGE_CURSOR&&(this.$cursorLayer.update(n),this.$moveTextAreaToCursor()),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_FRONT)&&this.$markerFront.update(n),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_BACK)&&this.$markerBack.update(n),this._signal(\"afterRender\")},this.$autosize=function(){var e=this.session.getScreenLength()*this.lineHeight,t=this.$maxLines*this.lineHeight,n=Math.min(t,Math.max((this.$minLines||1)*this.lineHeight,e))+this.scrollMargin.v+(this.$extraHeight||0);this.$horizScroll&&(n+=this.scrollBarH.getHeight()),this.$maxPixelHeight&&n>this.$maxPixelHeight&&(n=this.$maxPixelHeight);var r=n<=2*this.lineHeight,i=!r&&e>t;if(n!=this.desiredHeight||this.$size.height!=this.desiredHeight||i!=this.$vScroll){i!=this.$vScroll&&(this.$vScroll=i,this.scrollBarV.setVisible(i));var s=this.container.clientWidth;this.container.style.height=n+\"px\",this.$updateCachedSize(!0,this.$gutterWidth,s,n),this.desiredHeight=n,this._signal(\"autosize\")}},this.$computeLayerConfig=function(){var e=this.session,t=this.$size,n=t.height<=2*this.lineHeight,r=this.session.getScreenLength(),i=r*this.lineHeight,s=this.$getLongestLine(),o=!n&&(this.$hScrollBarAlwaysVisible||t.scrollerWidth-s-2*this.$padding<0),u=this.$horizScroll!==o;u&&(this.$horizScroll=o,this.scrollBarH.setVisible(o));var a=this.$vScroll;this.$maxLines&&this.lineHeight>1&&this.$autosize();var f=t.scrollerHeight+this.lineHeight,l=!this.$maxLines&&this.$scrollPastEnd?(t.scrollerHeight-this.lineHeight)*this.$scrollPastEnd:0;i+=l;var c=this.scrollMargin;this.session.setScrollTop(Math.max(-c.top,Math.min(this.scrollTop,i-t.scrollerHeight+c.bottom))),this.session.setScrollLeft(Math.max(-c.left,Math.min(this.scrollLeft,s+2*this.$padding-t.scrollerWidth+c.right)));var h=!n&&(this.$vScrollBarAlwaysVisible||t.scrollerHeight-i+l<0||this.scrollTop>c.top),p=a!==h;p&&(this.$vScroll=h,this.scrollBarV.setVisible(h));var d=this.scrollTop%this.lineHeight,v=Math.ceil(f/this.lineHeight)-1,m=Math.max(0,Math.round((this.scrollTop-d)/this.lineHeight)),g=m+v,y,b,w=this.lineHeight;m=e.screenToDocumentRow(m,0);var E=e.getFoldLine(m);E&&(m=E.start.row),y=e.documentToScreenRow(m,0),b=e.getRowLength(m)*w,g=Math.min(e.screenToDocumentRow(g,0),e.getLength()-1),f=t.scrollerHeight+e.getRowLength(g)*w+b,d=this.scrollTop-y*w;var S=0;if(this.layerConfig.width!=s||u)S=this.CHANGE_H_SCROLL;if(u||p)S|=this.$updateCachedSize(!0,this.gutterWidth,t.width,t.height),this._signal(\"scrollbarVisibilityChanged\"),p&&(s=this.$getLongestLine());return this.layerConfig={width:s,padding:this.$padding,firstRow:m,firstRowScreen:y,lastRow:g,lineHeight:w,characterWidth:this.characterWidth,minHeight:f,maxHeight:i,offset:d,gutterOffset:w?Math.max(0,Math.ceil((d+t.height-t.scrollerHeight)/w)):0,height:this.$size.scrollerHeight},this.session.$bidiHandler&&this.session.$bidiHandler.setContentWidth(s-this.$padding),S},this.$updateLines=function(){if(!this.$changedLines)return;var e=this.$changedLines.firstRow,t=this.$changedLines.lastRow;this.$changedLines=null;var n=this.layerConfig;if(e>n.lastRow+1)return;if(t<n.firstRow)return;if(t===Infinity){this.$showGutter&&this.$gutterLayer.update(n),this.$textLayer.update(n);return}return this.$textLayer.updateLines(n,e,t),!0},this.$getLongestLine=function(){var e=this.session.getScreenWidth();return this.showInvisibles&&!this.session.$useWrapMode&&(e+=1),this.$textLayer&&e>this.$textLayer.MAX_LINE_LENGTH&&(e=this.$textLayer.MAX_LINE_LENGTH+30),Math.max(this.$size.scrollerWidth-2*this.$padding,Math.round(e*this.characterWidth))},this.updateFrontMarkers=function(){this.$markerFront.setMarkers(this.session.getMarkers(!0)),this.$loop.schedule(this.CHANGE_MARKER_FRONT)},this.updateBackMarkers=function(){this.$markerBack.setMarkers(this.session.getMarkers()),this.$loop.schedule(this.CHANGE_MARKER_BACK)},this.addGutterDecoration=function(e,t){this.$gutterLayer.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){this.$gutterLayer.removeGutterDecoration(e,t)},this.updateBreakpoints=function(e){this.$loop.schedule(this.CHANGE_GUTTER)},this.setAnnotations=function(e){this.$gutterLayer.setAnnotations(e),this.$loop.schedule(this.CHANGE_GUTTER)},this.updateCursor=function(){this.$loop.schedule(this.CHANGE_CURSOR)},this.hideCursor=function(){this.$cursorLayer.hideCursor()},this.showCursor=function(){this.$cursorLayer.showCursor()},this.scrollSelectionIntoView=function(e,t,n){this.scrollCursorIntoView(e,n),this.scrollCursorIntoView(t,n)},this.scrollCursorIntoView=function(e,t,n){if(this.$size.scrollerHeight===0)return;var r=this.$cursorLayer.getPixelPosition(e),i=r.left,s=r.top,o=n&&n.top||0,u=n&&n.bottom||0,a=this.$scrollAnimation?this.session.getScrollTop():this.scrollTop;a+o>s?(t&&a+o>s+this.lineHeight&&(s-=t*this.$size.scrollerHeight),s===0&&(s=-this.scrollMargin.top),this.session.setScrollTop(s)):a+this.$size.scrollerHeight-u<s+this.lineHeight&&(t&&a+this.$size.scrollerHeight-u<s-this.lineHeight&&(s+=t*this.$size.scrollerHeight),this.session.setScrollTop(s+this.lineHeight+u-this.$size.scrollerHeight));var f=this.scrollLeft;f>i?(i<this.$padding+2*this.layerConfig.characterWidth&&(i=-this.scrollMargin.left),this.session.setScrollLeft(i)):f+this.$size.scrollerWidth<i+this.characterWidth?this.session.setScrollLeft(Math.round(i+this.characterWidth-this.$size.scrollerWidth)):f<=this.$padding&&i-f<this.characterWidth&&this.session.setScrollLeft(0)},this.getScrollTop=function(){return this.session.getScrollTop()},this.getScrollLeft=function(){return this.session.getScrollLeft()},this.getScrollTopRow=function(){return this.scrollTop/this.lineHeight},this.getScrollBottomRow=function(){return Math.max(0,Math.floor((this.scrollTop+this.$size.scrollerHeight)/this.lineHeight)-1)},this.scrollToRow=function(e){this.session.setScrollTop(e*this.lineHeight)},this.alignCursor=function(e,t){typeof e==\"number\"&&(e={row:e,column:0});var n=this.$cursorLayer.getPixelPosition(e),r=this.$size.scrollerHeight-this.lineHeight,i=n.top-r*(t||0);return this.session.setScrollTop(i),i},this.STEPS=8,this.$calcSteps=function(e,t){var n=0,r=this.STEPS,i=[],s=function(e,t,n){return n*(Math.pow(e-1,3)+1)+t};for(n=0;n<r;++n)i.push(s(n/this.STEPS,e,t-e));return i},this.scrollToLine=function(e,t,n,r){var i=this.$cursorLayer.getPixelPosition({row:e,column:0}),s=i.top;t&&(s-=this.$size.scrollerHeight/2);var o=this.scrollTop;this.session.setScrollTop(s),n!==!1&&this.animateScrolling(o,r)},this.animateScrolling=function(e,t){var n=this.scrollTop;if(!this.$animatedScroll)return;var r=this;if(e==n)return;if(this.$scrollAnimation){var i=this.$scrollAnimation.steps;if(i.length){e=i[0];if(e==n)return}}var s=r.$calcSteps(e,n);this.$scrollAnimation={from:e,to:n,steps:s},clearInterval(this.$timer),r.session.setScrollTop(s.shift()),r.session.$scrollTop=n,this.$timer=setInterval(function(){s.length?(r.session.setScrollTop(s.shift()),r.session.$scrollTop=n):n!=null?(r.session.$scrollTop=-1,r.session.setScrollTop(n),n=null):(r.$timer=clearInterval(r.$timer),r.$scrollAnimation=null,t&&t())},10)},this.scrollToY=function(e){this.scrollTop!==e&&(this.$loop.schedule(this.CHANGE_SCROLL),this.scrollTop=e)},this.scrollToX=function(e){this.scrollLeft!==e&&(this.scrollLeft=e),this.$loop.schedule(this.CHANGE_H_SCROLL)},this.scrollTo=function(e,t){this.session.setScrollTop(t),this.session.setScrollLeft(t)},this.scrollBy=function(e,t){t&&this.session.setScrollTop(this.session.getScrollTop()+t),e&&this.session.setScrollLeft(this.session.getScrollLeft()+e)},this.isScrollableBy=function(e,t){if(t<0&&this.session.getScrollTop()>=1-this.scrollMargin.top)return!0;if(t>0&&this.session.getScrollTop()+this.$size.scrollerHeight-this.layerConfig.maxHeight<-1+this.scrollMargin.bottom)return!0;if(e<0&&this.session.getScrollLeft()>=1-this.scrollMargin.left)return!0;if(e>0&&this.session.getScrollLeft()+this.$size.scrollerWidth-this.layerConfig.width<-1+this.scrollMargin.right)return!0},this.pixelToScreenCoordinates=function(e,t){var n;if(this.$hasCssTransforms){n={top:0,left:0};var r=this.$fontMetrics.transformCoordinates([e,t]);e=r[1]-this.gutterWidth-this.margin.left,t=r[0]}else n=this.scroller.getBoundingClientRect();var i=e+this.scrollLeft-n.left-this.$padding,s=i/this.characterWidth,o=Math.floor((t+this.scrollTop-n.top)/this.lineHeight),u=this.$blockCursor?Math.floor(s):Math.round(s);return{row:o,column:u,side:s-u>0?1:-1,offsetX:i}},this.screenToTextCoordinates=function(e,t){var n;if(this.$hasCssTransforms){n={top:0,left:0};var r=this.$fontMetrics.transformCoordinates([e,t]);e=r[1]-this.gutterWidth-this.margin.left,t=r[0]}else n=this.scroller.getBoundingClientRect();var i=e+this.scrollLeft-n.left-this.$padding,s=i/this.characterWidth,o=this.$blockCursor?Math.floor(s):Math.round(s),u=Math.floor((t+this.scrollTop-n.top)/this.lineHeight);return this.session.screenToDocumentPosition(u,Math.max(o,0),i)},this.textToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=this.session.documentToScreenPosition(e,t),i=this.$padding+(this.session.$bidiHandler.isBidiRow(r.row,e)?this.session.$bidiHandler.getPosLeft(r.column):Math.round(r.column*this.characterWidth)),s=r.row*this.lineHeight;return{pageX:n.left+i-this.scrollLeft,pageY:n.top+s-this.scrollTop}},this.visualizeFocus=function(){i.addCssClass(this.container,\"ace_focus\")},this.visualizeBlur=function(){i.removeCssClass(this.container,\"ace_focus\")},this.showComposition=function(e){this.$composition=e,e.cssText||(e.cssText=this.textarea.style.cssText),e.useTextareaForIME=this.$useTextareaForIME,this.$useTextareaForIME?(i.addCssClass(this.textarea,\"ace_composition\"),this.textarea.style.cssText=\"\",this.$moveTextAreaToCursor(),this.$cursorLayer.element.style.display=\"none\"):e.markerId=this.session.addMarker(e.markerRange,\"ace_composition_marker\",\"text\")},this.setCompositionText=function(e){var t=this.session.selection.cursor;this.addToken(e,\"composition_placeholder\",t.row,t.column),this.$moveTextAreaToCursor()},this.hideComposition=function(){if(!this.$composition)return;this.$composition.markerId&&this.session.removeMarker(this.$composition.markerId),i.removeCssClass(this.textarea,\"ace_composition\"),this.textarea.style.cssText=this.$composition.cssText,this.$composition=null,this.$cursorLayer.element.style.display=\"\"},this.addToken=function(e,t,n,r){var i=this.session;i.bgTokenizer.lines[n]=null;var s={type:t,value:e},o=i.getTokens(n);if(r==null)o.push(s);else{var u=0;for(var a=0;a<o.length;a++){var f=o[a];u+=f.value.length;if(r<=u){var l=f.value.length-(u-r),c=f.value.slice(0,l),h=f.value.slice(l);o.splice(a,1,{type:f.type,value:c},s,{type:f.type,value:h});break}}}this.updateLines(n,n)},this.setTheme=function(e,t){function o(r){if(n.$themeId!=e)return t&&t();if(!r||!r.cssClass)throw new Error(\"couldn't load module \"+e+\" or it didn't call define\");r.$id&&(n.$themeId=r.$id),i.importCssString(r.cssText,r.cssClass,n.container),n.theme&&i.removeCssClass(n.container,n.theme.cssClass);var s=\"padding\"in r?r.padding:\"padding\"in(n.theme||{})?4:n.$padding;n.$padding&&s!=n.$padding&&n.setPadding(s),n.$theme=r.cssClass,n.theme=r,i.addCssClass(n.container,r.cssClass),i.setCssClass(n.container,\"ace_dark\",r.isDark),n.$size&&(n.$size.width=0,n.$updateSizeAsync()),n._dispatchEvent(\"themeLoaded\",{theme:r}),t&&t()}var n=this;this.$themeId=e,n._dispatchEvent(\"themeChange\",{theme:e});if(!e||typeof e==\"string\"){var r=e||this.$options.theme.initialValue;s.loadModule([\"theme\",r],o)}else o(e)},this.getTheme=function(){return this.$themeId},this.setStyle=function(e,t){i.setCssClass(this.container,e,t!==!1)},this.unsetStyle=function(e){i.removeCssClass(this.container,e)},this.setCursorStyle=function(e){i.setStyle(this.scroller.style,\"cursor\",e)},this.setMouseCursor=function(e){i.setStyle(this.scroller.style,\"cursor\",e)},this.attachToShadowRoot=function(){i.importCssString(v,\"ace_editor.css\",this.container)},this.destroy=function(){this.freeze(),this.$fontMetrics.destroy(),this.$cursorLayer.destroy()}}).call(y.prototype),s.defineOptions(y.prototype,\"renderer\",{animatedScroll:{initialValue:!1},showInvisibles:{set:function(e){this.$textLayer.setShowInvisibles(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!1},showPrintMargin:{set:function(){this.$updatePrintMargin()},initialValue:!0},printMarginColumn:{set:function(){this.$updatePrintMargin()},initialValue:80},printMargin:{set:function(e){typeof e==\"number\"&&(this.$printMarginColumn=e),this.$showPrintMargin=!!e,this.$updatePrintMargin()},get:function(){return this.$showPrintMargin&&this.$printMarginColumn}},showGutter:{set:function(e){this.$gutter.style.display=e?\"block\":\"none\",this.$loop.schedule(this.CHANGE_FULL),this.onGutterResize()},initialValue:!0},fadeFoldWidgets:{set:function(e){i.setCssClass(this.$gutter,\"ace_fade-fold-widgets\",e)},initialValue:!1},showFoldWidgets:{set:function(e){this.$gutterLayer.setShowFoldWidgets(e),this.$loop.schedule(this.CHANGE_GUTTER)},initialValue:!0},displayIndentGuides:{set:function(e){this.$textLayer.setDisplayIndentGuides(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!0},highlightGutterLine:{set:function(e){this.$gutterLayer.setHighlightGutterLine(e),this.$loop.schedule(this.CHANGE_GUTTER)},initialValue:!0},hScrollBarAlwaysVisible:{set:function(e){(!this.$hScrollBarAlwaysVisible||!this.$horizScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},vScrollBarAlwaysVisible:{set:function(e){(!this.$vScrollBarAlwaysVisible||!this.$vScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},fontSize:{set:function(e){typeof e==\"number\"&&(e+=\"px\"),this.container.style.fontSize=e,this.updateFontSize()},initialValue:12},fontFamily:{set:function(e){this.container.style.fontFamily=e,this.updateFontSize()}},maxLines:{set:function(e){this.updateFull()}},minLines:{set:function(e){this.$minLines<562949953421311||(this.$minLines=0),this.updateFull()}},maxPixelHeight:{set:function(e){this.updateFull()},initialValue:0},scrollPastEnd:{set:function(e){e=+e||0;if(this.$scrollPastEnd==e)return;this.$scrollPastEnd=e,this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:0,handlesSet:!0},fixedWidthGutter:{set:function(e){this.$gutterLayer.$fixedWidth=!!e,this.$loop.schedule(this.CHANGE_GUTTER)}},theme:{set:function(e){this.setTheme(e)},get:function(){return this.$themeId||this.theme},initialValue:\"./theme/textmate\",handlesSet:!0},hasCssTransforms:{},useTextareaForIME:{initialValue:!m.isMobile&&!m.isIE}}),t.VirtualRenderer=y}),ace.define(\"ace/worker/worker_client\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/net\",\"ace/lib/event_emitter\",\"ace/config\"],function(e,t,n){\"use strict\";function u(e){var t=\"importScripts('\"+i.qualifyURL(e)+\"');\";try{return new Blob([t],{type:\"application/javascript\"})}catch(n){var r=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder,s=new r;return s.append(t),s.getBlob(\"application/javascript\")}}function a(e){if(typeof Worker==\"undefined\")return{postMessage:function(){},terminate:function(){}};if(o.get(\"loadWorkerFromBlob\")){var t=u(e),n=window.URL||window.webkitURL,r=n.createObjectURL(t);return new Worker(r)}return new Worker(e)}var r=e(\"../lib/oop\"),i=e(\"../lib/net\"),s=e(\"../lib/event_emitter\").EventEmitter,o=e(\"../config\"),f=function(e){e.postMessage||(e=this.$createWorkerFromOldConfig.apply(this,arguments)),this.$worker=e,this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.onMessage=this.onMessage.bind(this),this.callbackId=1,this.callbacks={},this.$worker.onmessage=this.onMessage};(function(){r.implement(this,s),this.$createWorkerFromOldConfig=function(t,n,r,i,s){e.nameToUrl&&!e.toUrl&&(e.toUrl=e.nameToUrl);if(o.get(\"packaged\")||!e.toUrl)i=i||o.moduleUrl(n,\"worker\");else{var u=this.$normalizePath;i=i||u(e.toUrl(\"ace/worker/worker.js\",null,\"_\"));var f={};t.forEach(function(t){f[t]=u(e.toUrl(t,null,\"_\").replace(/(\\.js)?(\\?.*)?$/,\"\"))})}return this.$worker=a(i),s&&this.send(\"importScripts\",s),this.$worker.postMessage({init:!0,tlns:f,module:n,classname:r}),this.$worker},this.onMessage=function(e){var t=e.data;switch(t.type){case\"event\":this._signal(t.name,{data:t.data});break;case\"call\":var n=this.callbacks[t.id];n&&(n(t.data),delete this.callbacks[t.id]);break;case\"error\":this.reportError(t.data);break;case\"log\":window.console&&console.log&&console.log.apply(console,t.data)}},this.reportError=function(e){window.console&&console.error&&console.error(e)},this.$normalizePath=function(e){return i.qualifyURL(e)},this.terminate=function(){this._signal(\"terminate\",{}),this.deltaQueue=null,this.$worker.terminate(),this.$worker=null,this.$doc&&this.$doc.off(\"change\",this.changeListener),this.$doc=null},this.send=function(e,t){this.$worker.postMessage({command:e,args:t})},this.call=function(e,t,n){if(n){var r=this.callbackId++;this.callbacks[r]=n,t.push(r)}this.send(e,t)},this.emit=function(e,t){try{t.data&&t.data.err&&(t.data.err={message:t.data.err.message,stack:t.data.err.stack,code:t.data.err.code}),this.$worker.postMessage({event:e,data:{data:t.data}})}catch(n){console.error(n.stack)}},this.attachToDocument=function(e){this.$doc&&this.terminate(),this.$doc=e,this.call(\"setValue\",[e.getValue()]),e.on(\"change\",this.changeListener)},this.changeListener=function(e){this.deltaQueue||(this.deltaQueue=[],setTimeout(this.$sendDeltaQueue,0)),e.action==\"insert\"?this.deltaQueue.push(e.start,e.lines):this.deltaQueue.push(e.start,e.end)},this.$sendDeltaQueue=function(){var e=this.deltaQueue;if(!e)return;this.deltaQueue=null,e.length>50&&e.length>this.$doc.getLength()>>1?this.call(\"setValue\",[this.$doc.getValue()]):this.emit(\"change\",{data:e})}}).call(f.prototype);var l=function(e,t,n){var r=null,i=!1,u=Object.create(s),a=[],l=new f({messageBuffer:a,terminate:function(){},postMessage:function(e){a.push(e);if(!r)return;i?setTimeout(c):c()}});l.setEmitSync=function(e){i=e};var c=function(){var e=a.shift();e.command?r[e.command].apply(r,e.args):e.event&&u._signal(e.event,e.data)};return u.postMessage=function(e){l.onMessage({data:e})},u.callback=function(e,t){this.postMessage({type:\"call\",id:t,data:e})},u.emit=function(e,t){this.postMessage({type:\"event\",name:e,data:t})},o.loadModule([\"worker\",t],function(e){r=new e[n](u);while(a.length)c()}),l};t.UIWorkerClient=l,t.WorkerClient=f,t.createWorker=a}),ace.define(\"ace/placeholder\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/lib/event_emitter\",\"ace/lib/oop\"],function(e,t,n){\"use strict\";var r=e(\"./range\").Range,i=e(\"./lib/event_emitter\").EventEmitter,s=e(\"./lib/oop\"),o=function(e,t,n,r,i,s){var o=this;this.length=t,this.session=e,this.doc=e.getDocument(),this.mainClass=i,this.othersClass=s,this.$onUpdate=this.onUpdate.bind(this),this.doc.on(\"change\",this.$onUpdate),this.$others=r,this.$onCursorChange=function(){setTimeout(function(){o.onCursorChange()})},this.$pos=n;var u=e.getUndoManager().$undoStack||e.getUndoManager().$undostack||{length:-1};this.$undoStackDepth=u.length,this.setup(),e.selection.on(\"changeCursor\",this.$onCursorChange)};(function(){s.implement(this,i),this.setup=function(){var e=this,t=this.doc,n=this.session;this.selectionBefore=n.selection.toJSON(),n.selection.inMultiSelectMode&&n.selection.toSingleRange(),this.pos=t.createAnchor(this.$pos.row,this.$pos.column);var i=this.pos;i.$insertRight=!0,i.detach(),i.markerId=n.addMarker(new r(i.row,i.column,i.row,i.column+this.length),this.mainClass,null,!1),this.others=[],this.$others.forEach(function(n){var r=t.createAnchor(n.row,n.column);r.$insertRight=!0,r.detach(),e.others.push(r)}),n.setUndoSelect(!1)},this.showOtherMarkers=function(){if(this.othersActive)return;var e=this.session,t=this;this.othersActive=!0,this.others.forEach(function(n){n.markerId=e.addMarker(new r(n.row,n.column,n.row,n.column+t.length),t.othersClass,null,!1)})},this.hideOtherMarkers=function(){if(!this.othersActive)return;this.othersActive=!1;for(var e=0;e<this.others.length;e++)this.session.removeMarker(this.others[e].markerId)},this.onUpdate=function(e){if(this.$updating)return this.updateAnchors(e);var t=e;if(t.start.row!==t.end.row)return;if(t.start.row!==this.pos.row)return;this.$updating=!0;var n=e.action===\"insert\"?t.end.column-t.start.column:t.start.column-t.end.column,i=t.start.column>=this.pos.column&&t.start.column<=this.pos.column+this.length+1,s=t.start.column-this.pos.column;this.updateAnchors(e),i&&(this.length+=n);if(i&&!this.session.$fromUndo)if(e.action===\"insert\")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.insertMergedLines(a,e.lines)}else if(e.action===\"remove\")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.remove(new r(a.row,a.column,a.row,a.column-n))}this.$updating=!1,this.updateMarkers()},this.updateAnchors=function(e){this.pos.onChange(e);for(var t=this.others.length;t--;)this.others[t].onChange(e);this.updateMarkers()},this.updateMarkers=function(){if(this.$updating)return;var e=this,t=this.session,n=function(n,i){t.removeMarker(n.markerId),n.markerId=t.addMarker(new r(n.row,n.column,n.row,n.column+e.length),i,null,!1)};n(this.pos,this.mainClass);for(var i=this.others.length;i--;)n(this.others[i],this.othersClass)},this.onCursorChange=function(e){if(this.$updating||!this.session)return;var t=this.session.selection.getCursor();t.row===this.pos.row&&t.column>=this.pos.column&&t.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit(\"cursorEnter\",e)):(this.hideOtherMarkers(),this._emit(\"cursorLeave\",e))},this.detach=function(){this.session.removeMarker(this.pos&&this.pos.markerId),this.hideOtherMarkers(),this.doc.removeEventListener(\"change\",this.$onUpdate),this.session.selection.removeEventListener(\"changeCursor\",this.$onCursorChange),this.session.setUndoSelect(!0),this.session=null},this.cancel=function(){if(this.$undoStackDepth===-1)return;var e=this.session.getUndoManager(),t=(e.$undoStack||e.$undostack).length-this.$undoStackDepth;for(var n=0;n<t;n++)e.undo(this.session,!0);this.selectionBefore&&this.session.selection.fromJSON(this.selectionBefore)}}).call(o.prototype),t.PlaceHolder=o}),ace.define(\"ace/mouse/multi_select_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\"],function(e,t,n){function s(e,t){return e.row==t.row&&e.column==t.column}function o(e){var t=e.domEvent,n=t.altKey,o=t.shiftKey,u=t.ctrlKey,a=e.getAccelKey(),f=e.getButton();u&&i.isMac&&(f=t.button);if(e.editor.inMultiSelectMode&&f==2){e.editor.textInput.onContextMenu(e.domEvent);return}if(!u&&!n&&!a){f===0&&e.editor.inMultiSelectMode&&e.editor.exitMultiSelectMode();return}if(f!==0)return;var l=e.editor,c=l.selection,h=l.inMultiSelectMode,p=e.getDocumentPosition(),d=c.getCursor(),v=e.inSelection()||c.isEmpty()&&s(p,d),m=e.x,g=e.y,y=function(e){m=e.clientX,g=e.clientY},b=l.session,w=l.renderer.pixelToScreenCoordinates(m,g),E=w,S;if(l.$mouseHandler.$enableJumpToDef)u&&n||a&&n?S=o?\"block\":\"add\":n&&l.$blockSelectEnabled&&(S=\"block\");else if(a&&!n){S=\"add\";if(!h&&o)return}else n&&l.$blockSelectEnabled&&(S=\"block\");S&&i.isMac&&t.ctrlKey&&l.$mouseHandler.cancelContextMenu();if(S==\"add\"){if(!h&&v)return;if(!h){var x=c.toOrientedRange();l.addSelectionMarker(x)}var T=c.rangeList.rangeAtPoint(p);l.inVirtualSelectionMode=!0,o&&(T=null,x=c.ranges[0]||x,l.removeSelectionMarker(x)),l.once(\"mouseup\",function(){var e=c.toOrientedRange();T&&e.isEmpty()&&s(T.cursor,e.cursor)?c.substractPoint(e.cursor):(o?c.substractPoint(x.cursor):x&&(l.removeSelectionMarker(x),c.addRange(x)),c.addRange(e)),l.inVirtualSelectionMode=!1})}else if(S==\"block\"){e.stop(),l.inVirtualSelectionMode=!0;var N,C=[],k=function(){var e=l.renderer.pixelToScreenCoordinates(m,g),t=b.screenToDocumentPosition(e.row,e.column,e.offsetX);if(s(E,e)&&s(t,c.lead))return;E=e,l.selection.moveToPosition(t),l.renderer.scrollCursorIntoView(),l.removeSelectionMarkers(C),C=c.rectangularRangeBlock(E,w),l.$mouseHandler.$clickSelection&&C.length==1&&C[0].isEmpty()&&(C[0]=l.$mouseHandler.$clickSelection.clone()),C.forEach(l.addSelectionMarker,l),l.updateSelectionMarkers()};h&&!a?c.toSingleRange():!h&&a&&(N=c.toOrientedRange(),l.addSelectionMarker(N)),o?w=b.documentToScreenPosition(c.lead):c.moveToPosition(p),E={row:-1,column:-1};var L=function(e){k(),clearInterval(O),l.removeSelectionMarkers(C),C.length||(C=[c.toOrientedRange()]),N&&(l.removeSelectionMarker(N),c.toSingleRange(N));for(var t=0;t<C.length;t++)c.addRange(C[t]);l.inVirtualSelectionMode=!1,l.$mouseHandler.$clickSelection=null},A=k;r.capture(l.container,y,L);var O=setInterval(function(){A()},20);return e.preventDefault()}}var r=e(\"../lib/event\"),i=e(\"../lib/useragent\");t.onMouseDown=o}),ace.define(\"ace/commands/multi_select_commands\",[\"require\",\"exports\",\"module\",\"ace/keyboard/hash_handler\"],function(e,t,n){t.defaultCommands=[{name:\"addCursorAbove\",description:\"Add cursor above\",exec:function(e){e.selectMoreLines(-1)},bindKey:{win:\"Ctrl-Alt-Up\",mac:\"Ctrl-Alt-Up\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"addCursorBelow\",description:\"Add cursor below\",exec:function(e){e.selectMoreLines(1)},bindKey:{win:\"Ctrl-Alt-Down\",mac:\"Ctrl-Alt-Down\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"addCursorAboveSkipCurrent\",description:\"Add cursor above (skip current)\",exec:function(e){e.selectMoreLines(-1,!0)},bindKey:{win:\"Ctrl-Alt-Shift-Up\",mac:\"Ctrl-Alt-Shift-Up\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"addCursorBelowSkipCurrent\",description:\"Add cursor below (skip current)\",exec:function(e){e.selectMoreLines(1,!0)},bindKey:{win:\"Ctrl-Alt-Shift-Down\",mac:\"Ctrl-Alt-Shift-Down\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectMoreBefore\",description:\"Select more before\",exec:function(e){e.selectMore(-1)},bindKey:{win:\"Ctrl-Alt-Left\",mac:\"Ctrl-Alt-Left\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectMoreAfter\",description:\"Select more after\",exec:function(e){e.selectMore(1)},bindKey:{win:\"Ctrl-Alt-Right\",mac:\"Ctrl-Alt-Right\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectNextBefore\",description:\"Select next before\",exec:function(e){e.selectMore(-1,!0)},bindKey:{win:\"Ctrl-Alt-Shift-Left\",mac:\"Ctrl-Alt-Shift-Left\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectNextAfter\",description:\"Select next after\",exec:function(e){e.selectMore(1,!0)},bindKey:{win:\"Ctrl-Alt-Shift-Right\",mac:\"Ctrl-Alt-Shift-Right\"},scrollIntoView:\"cursor\",readOnly:!0},{name:\"splitIntoLines\",description:\"Split into lines\",exec:function(e){e.multiSelect.splitIntoLines()},bindKey:{win:\"Ctrl-Alt-L\",mac:\"Ctrl-Alt-L\"},readOnly:!0},{name:\"alignCursors\",description:\"Align cursors\",exec:function(e){e.alignCursors()},bindKey:{win:\"Ctrl-Alt-A\",mac:\"Ctrl-Alt-A\"},scrollIntoView:\"cursor\"},{name:\"findAll\",description:\"Find all\",exec:function(e){e.findAll()},bindKey:{win:\"Ctrl-Alt-K\",mac:\"Ctrl-Alt-G\"},scrollIntoView:\"cursor\",readOnly:!0}],t.multiSelectCommands=[{name:\"singleSelection\",description:\"Single selection\",bindKey:\"esc\",exec:function(e){e.exitMultiSelectMode()},scrollIntoView:\"cursor\",readOnly:!0,isAvailable:function(e){return e&&e.inMultiSelectMode}}];var r=e(\"../keyboard/hash_handler\").HashHandler;t.keyboardHandler=new r(t.multiSelectCommands)}),ace.define(\"ace/multi_select\",[\"require\",\"exports\",\"module\",\"ace/range_list\",\"ace/range\",\"ace/selection\",\"ace/mouse/multi_select_handler\",\"ace/lib/event\",\"ace/lib/lang\",\"ace/commands/multi_select_commands\",\"ace/search\",\"ace/edit_session\",\"ace/editor\",\"ace/config\"],function(e,t,n){function h(e,t,n){return c.$options.wrap=!0,c.$options.needle=t,c.$options.backwards=n==-1,c.find(e)}function v(e,t){return e.row==t.row&&e.column==t.column}function m(e){if(e.$multiselectOnSessionChange)return;e.$onAddRange=e.$onAddRange.bind(e),e.$onRemoveRange=e.$onRemoveRange.bind(e),e.$onMultiSelect=e.$onMultiSelect.bind(e),e.$onSingleSelect=e.$onSingleSelect.bind(e),e.$multiselectOnSessionChange=t.onSessionChange.bind(e),e.$checkMultiselectChange=e.$checkMultiselectChange.bind(e),e.$multiselectOnSessionChange(e),e.on(\"changeSession\",e.$multiselectOnSessionChange),e.on(\"mousedown\",o),e.commands.addCommands(f.defaultCommands),g(e)}function g(e){function r(t){n&&(e.renderer.setMouseCursor(\"\"),n=!1)}if(!e.textInput)return;var t=e.textInput.getElement(),n=!1;u.addListener(t,\"keydown\",function(t){var i=t.keyCode==18&&!(t.ctrlKey||t.shiftKey||t.metaKey);e.$blockSelectEnabled&&i?n||(e.renderer.setMouseCursor(\"crosshair\"),n=!0):n&&r()}),u.addListener(t,\"keyup\",r),u.addListener(t,\"blur\",r)}var r=e(\"./range_list\").RangeList,i=e(\"./range\").Range,s=e(\"./selection\").Selection,o=e(\"./mouse/multi_select_handler\").onMouseDown,u=e(\"./lib/event\"),a=e(\"./lib/lang\"),f=e(\"./commands/multi_select_commands\");t.commands=f.defaultCommands.concat(f.multiSelectCommands);var l=e(\"./search\").Search,c=new l,p=e(\"./edit_session\").EditSession;(function(){this.getSelectionMarkers=function(){return this.$selectionMarkers}}).call(p.prototype),function(){this.ranges=null,this.rangeList=null,this.addRange=function(e,t){if(!e)return;if(!this.inMultiSelectMode&&this.rangeCount===0){var n=this.toOrientedRange();this.rangeList.add(n),this.rangeList.add(e);if(this.rangeList.ranges.length!=2)return this.rangeList.removeAll(),t||this.fromOrientedRange(e);this.rangeList.removeAll(),this.rangeList.add(n),this.$onAddRange(n)}e.cursor||(e.cursor=e.end);var r=this.rangeList.add(e);return this.$onAddRange(e),r.length&&this.$onRemoveRange(r),this.rangeCount>1&&!this.inMultiSelectMode&&(this._signal(\"multiSelect\"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),t||this.fromOrientedRange(e)},this.toSingleRange=function(e){e=e||this.ranges[0];var t=this.rangeList.removeAll();t.length&&this.$onRemoveRange(t),e&&this.fromOrientedRange(e)},this.substractPoint=function(e){var t=this.rangeList.substractPoint(e);if(t)return this.$onRemoveRange(t),t[0]},this.mergeOverlappingRanges=function(){var e=this.rangeList.merge();e.length&&this.$onRemoveRange(e)},this.$onAddRange=function(e){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(e),this._signal(\"addRange\",{range:e})},this.$onRemoveRange=function(e){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var t=this.rangeList.ranges.pop();e.push(t),this.rangeCount=0}for(var n=e.length;n--;){var r=this.ranges.indexOf(e[n]);this.ranges.splice(r,1)}this._signal(\"removeRange\",{ranges:e}),this.rangeCount===0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._signal(\"singleSelect\"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),t=t||this.ranges[0],t&&!t.isEqual(this.getRange())&&this.fromOrientedRange(t)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new r,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeCount?this.rangeList.ranges.concat():[this.getRange()]},this.splitIntoLines=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var n=this.getRange(),r=this.isBackwards(),s=n.start.row,o=n.end.row;if(s==o){if(r)var u=n.end,a=n.start;else var u=n.start,a=n.end;this.addRange(i.fromPoints(a,a)),this.addRange(i.fromPoints(u,u));return}var f=[],l=this.getLineRange(s,!0);l.start.column=n.start.column,f.push(l);for(var c=s+1;c<o;c++)f.push(this.getLineRange(c,!0));l=this.getLineRange(o,!0),l.end.column=n.end.column,f.push(l),f.forEach(this.addRange,this)}},this.toggleBlockSelection=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var r=this.session.documentToScreenPosition(this.cursor),s=this.session.documentToScreenPosition(this.anchor),o=this.rectangularRangeBlock(r,s);o.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(e,t,n){var r=[],s=e.column<t.column;if(s)var o=e.column,u=t.column,a=e.offsetX,f=t.offsetX;else var o=t.column,u=e.column,a=t.offsetX,f=e.offsetX;var l=e.row<t.row;if(l)var c=e.row,h=t.row;else var c=t.row,h=e.row;o<0&&(o=0),c<0&&(c=0),c==h&&(n=!0);var p;for(var d=c;d<=h;d++){var m=i.fromPoints(this.session.screenToDocumentPosition(d,o,a),this.session.screenToDocumentPosition(d,u,f));if(m.isEmpty()){if(p&&v(m.end,p))break;p=m.end}m.cursor=s?m.start:m.end,r.push(m)}l&&r.reverse();if(!n){var g=r.length-1;while(r[g].isEmpty()&&g>0)g--;if(g>0){var y=0;while(r[y].isEmpty())y++}for(var b=g;b>=y;b--)r[b].isEmpty()&&r.splice(b,1)}return r}}.call(s.prototype);var d=e(\"./editor\").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(e){e.cursor||(e.cursor=e.end);var t=this.getSelectionStyle();return e.marker=this.session.addMarker(e,\"ace_selection\",t),this.session.$selectionMarkers.push(e),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,e},this.removeSelectionMarker=function(e){if(!e.marker)return;this.session.removeMarker(e.marker);var t=this.session.$selectionMarkers.indexOf(e);t!=-1&&this.session.$selectionMarkers.splice(t,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(e){var t=this.session.$selectionMarkers;for(var n=e.length;n--;){var r=e[n];if(!r.marker)continue;this.session.removeMarker(r.marker);var i=t.indexOf(r);i!=-1&&t.splice(i,1)}this.session.selectionMarkerCount=t.length},this.$onAddRange=function(e){this.addSelectionMarker(e.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(e){this.removeSelectionMarkers(e.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(e){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle(\"ace_multiselect\"),this.keyBinding.addKeyboardHandler(f.keyboardHandler),this.commands.setDefaultHandler(\"exec\",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(e){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle(\"ace_multiselect\"),this.keyBinding.removeKeyboardHandler(f.keyboardHandler),this.commands.removeDefaultHandler(\"exec\",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers(),this._emit(\"changeSelection\")},this.$onMultiSelectExec=function(e){var t=e.command,n=e.editor;if(!n.multiSelect)return;if(!t.multiSelectAction){var r=t.exec(n,e.args||{});n.multiSelect.addRange(n.multiSelect.toOrientedRange()),n.multiSelect.mergeOverlappingRanges()}else t.multiSelectAction==\"forEach\"?r=n.forEachSelection(t,e.args):t.multiSelectAction==\"forEachLine\"?r=n.forEachSelection(t,e.args,!0):t.multiSelectAction==\"single\"?(n.exitMultiSelectMode(),r=t.exec(n,e.args||{})):r=t.multiSelectAction(n,e.args||{});return r},this.forEachSelection=function(e,t,n){if(this.inVirtualSelectionMode)return;var r=n&&n.keepOrder,i=n==1||n&&n.$byLines,o=this.session,u=this.selection,a=u.rangeList,f=(r?u:a).ranges,l;if(!f.length)return e.exec?e.exec(this,t||{}):e(this,t||{});var c=u._eventRegistry;u._eventRegistry={};var h=new s(o);this.inVirtualSelectionMode=!0;for(var p=f.length;p--;){if(i)while(p>0&&f[p].start.row==f[p-1].end.row)p--;h.fromOrientedRange(f[p]),h.index=p,this.selection=o.selection=h;var d=e.exec?e.exec(this,t||{}):e(this,t||{});!l&&d!==undefined&&(l=d),h.toOrientedRange(f[p])}h.detach(),this.selection=o.selection=u,this.inVirtualSelectionMode=!1,u._eventRegistry=c,u.mergeOverlappingRanges(),u.ranges[0]&&u.fromOrientedRange(u.ranges[0]);var v=this.renderer.$scrollAnimation;return this.onCursorChange(),this.onSelectionChange(),v&&v.from==v.to&&this.renderer.animateScrolling(v.from),l},this.exitMultiSelectMode=function(){if(!this.inMultiSelectMode||this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getSelectedText=function(){var e=\"\";if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var t=this.multiSelect.rangeList.ranges,n=[];for(var r=0;r<t.length;r++)n.push(this.session.getTextRange(t[r]));var i=this.session.getDocument().getNewLineCharacter();e=n.join(i),e.length==(n.length-1)*i.length&&(e=\"\")}else this.selection.isEmpty()||(e=this.session.getTextRange(this.getSelectionRange()));return e},this.$checkMultiselectChange=function(e,t){if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var n=this.multiSelect.ranges[0];if(this.multiSelect.isEmpty()&&t==this.multiSelect.anchor)return;var r=t==this.multiSelect.anchor?n.cursor==n.start?n.end:n.start:n.cursor;r.row!=t.row||this.session.$clipPositionToDocument(r.row,r.column).column!=t.column?this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange()):this.multiSelect.mergeOverlappingRanges()}},this.findAll=function(e,t,n){t=t||{},t.needle=e||t.needle;if(t.needle==undefined){var r=this.selection.isEmpty()?this.selection.getWordRange():this.selection.getRange();t.needle=this.session.getTextRange(r)}this.$search.set(t);var i=this.$search.findAll(this.session);if(!i.length)return 0;var s=this.multiSelect;n||s.toSingleRange(i[0]);for(var o=i.length;o--;)s.addRange(i[o],!0);return r&&s.rangeList.rangeAtPoint(r.start)&&s.addRange(r,!0),i.length},this.selectMoreLines=function(e,t){var n=this.selection.toOrientedRange(),r=n.cursor==n.end,s=this.session.documentToScreenPosition(n.cursor);this.selection.$desiredColumn&&(s.column=this.selection.$desiredColumn);var o=this.session.screenToDocumentPosition(s.row+e,s.column);if(!n.isEmpty())var u=this.session.documentToScreenPosition(r?n.end:n.start),a=this.session.screenToDocumentPosition(u.row+e,u.column);else var a=o;if(r){var f=i.fromPoints(o,a);f.cursor=f.start}else{var f=i.fromPoints(a,o);f.cursor=f.end}f.desiredColumn=s.column;if(!this.selection.inMultiSelectMode)this.selection.addRange(n);else if(t)var l=n.cursor;this.selection.addRange(f),l&&this.selection.substractPoint(l)},this.transposeSelections=function(e){var t=this.session,n=t.multiSelect,r=n.ranges;for(var i=r.length;i--;){var s=r[i];if(s.isEmpty()){var o=t.getWordRange(s.start.row,s.start.column);s.start.row=o.start.row,s.start.column=o.start.column,s.end.row=o.end.row,s.end.column=o.end.column}}n.mergeOverlappingRanges();var u=[];for(var i=r.length;i--;){var s=r[i];u.unshift(t.getTextRange(s))}e<0?u.unshift(u.pop()):u.push(u.shift());for(var i=r.length;i--;){var s=r[i],o=s.clone();t.replace(s,u[i]),s.start.row=o.start.row,s.start.column=o.start.column}n.fromOrientedRange(n.ranges[0])},this.selectMore=function(e,t,n){var r=this.session,i=r.multiSelect,s=i.toOrientedRange();if(s.isEmpty()){s=r.getWordRange(s.start.row,s.start.column),s.cursor=e==-1?s.start:s.end,this.multiSelect.addRange(s);if(n)return}var o=r.getTextRange(s),u=h(r,o,e);u&&(u.cursor=e==-1?u.start:u.end,this.session.unfold(u),this.multiSelect.addRange(u),this.renderer.scrollCursorIntoView(null,.5)),t&&this.multiSelect.substractPoint(s.cursor)},this.alignCursors=function(){var e=this.session,t=e.multiSelect,n=t.ranges,r=-1,s=n.filter(function(e){if(e.cursor.row==r)return!0;r=e.cursor.row});if(!n.length||s.length==n.length-1){var o=this.selection.getRange(),u=o.start.row,f=o.end.row,l=u==f;if(l){var c=this.session.getLength(),h;do h=this.session.getLine(f);while(/[=:]/.test(h)&&++f<c);do h=this.session.getLine(u);while(/[=:]/.test(h)&&--u>0);u<0&&(u=0),f>=c&&(f=c-1)}var p=this.session.removeFullLines(u,f);p=this.$reAlignText(p,l),this.session.insert({row:u,column:0},p.join(\"\\n\")+\"\\n\"),l||(o.start.column=0,o.end.column=p[p.length-1].length),this.selection.setRange(o)}else{s.forEach(function(e){t.substractPoint(e.cursor)});var d=0,v=Infinity,m=n.map(function(t){var n=t.cursor,r=e.getLine(n.row),i=r.substr(n.column).search(/\\S/g);return i==-1&&(i=0),n.column>d&&(d=n.column),i<v&&(v=i),i});n.forEach(function(t,n){var r=t.cursor,s=d-r.column,o=m[n]-v;s>o?e.insert(r,a.stringRepeat(\" \",s-o)):e.remove(new i(r.row,r.column,r.row,r.column-s+o)),t.start.column=t.end.column=d,t.start.row=t.end.row=r.row,t.cursor=t.end}),t.fromOrientedRange(n[0]),this.renderer.updateCursor(),this.renderer.updateBackMarkers()}},this.$reAlignText=function(e,t){function u(e){return a.stringRepeat(\" \",e)}function f(e){return e[2]?u(i)+e[2]+u(s-e[2].length+o)+e[4].replace(/^([=:])\\s+/,\"$1 \"):e[0]}function l(e){return e[2]?u(i+s-e[2].length)+e[2]+u(o)+e[4].replace(/^([=:])\\s+/,\"$1 \"):e[0]}function c(e){return e[2]?u(i)+e[2]+u(o)+e[4].replace(/^([=:])\\s+/,\"$1 \"):e[0]}var n=!0,r=!0,i,s,o;return e.map(function(e){var t=e.match(/(\\s*)(.*?)(\\s*)([=:].*)/);return t?i==null?(i=t[1].length,s=t[2].length,o=t[3].length,t):(i+s+o!=t[1].length+t[2].length+t[3].length&&(r=!1),i!=t[1].length&&(n=!1),i>t[1].length&&(i=t[1].length),s<t[2].length&&(s=t[2].length),o>t[3].length&&(o=t[3].length),t):[e]}).map(t?f:n?r?l:f:c)}}).call(d.prototype),t.onSessionChange=function(e){var t=e.session;t&&!t.multiSelect&&(t.$selectionMarkers=[],t.selection.$initRangeList(),t.multiSelect=t.selection),this.multiSelect=t&&t.multiSelect;var n=e.oldSession;n&&(n.multiSelect.off(\"addRange\",this.$onAddRange),n.multiSelect.off(\"removeRange\",this.$onRemoveRange),n.multiSelect.off(\"multiSelect\",this.$onMultiSelect),n.multiSelect.off(\"singleSelect\",this.$onSingleSelect),n.multiSelect.lead.off(\"change\",this.$checkMultiselectChange),n.multiSelect.anchor.off(\"change\",this.$checkMultiselectChange)),t&&(t.multiSelect.on(\"addRange\",this.$onAddRange),t.multiSelect.on(\"removeRange\",this.$onRemoveRange),t.multiSelect.on(\"multiSelect\",this.$onMultiSelect),t.multiSelect.on(\"singleSelect\",this.$onSingleSelect),t.multiSelect.lead.on(\"change\",this.$checkMultiselectChange),t.multiSelect.anchor.on(\"change\",this.$checkMultiselectChange)),t&&this.inMultiSelectMode!=t.selection.inMultiSelectMode&&(t.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},t.MultiSelect=m,e(\"./config\").defineOptions(d.prototype,\"editor\",{enableMultiselect:{set:function(e){m(this),e?(this.on(\"changeSession\",this.$multiselectOnSessionChange),this.on(\"mousedown\",o)):(this.off(\"changeSession\",this.$multiselectOnSessionChange),this.off(\"mousedown\",o))},value:!0},enableBlockSelect:{set:function(e){this.$blockSelectEnabled=e},value:!0}})}),ace.define(\"ace/mode/folding/fold_mode\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../../range\").Range,i=t.FoldMode=function(){};(function(){this.foldingStartMarker=null,this.foldingStopMarker=null,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?\"start\":t==\"markbeginend\"&&this.foldingStopMarker&&this.foldingStopMarker.test(r)?\"end\":\"\"},this.getFoldWidgetRange=function(e,t,n){return null},this.indentationBlock=function(e,t,n){var i=/\\S/,s=e.getLine(t),o=s.search(i);if(o==-1)return;var u=n||s.length,a=e.getLength(),f=t,l=t;while(++t<a){var c=e.getLine(t).search(i);if(c==-1)continue;if(c<=o){var h=e.getTokenAt(t,0);if(!h||h.type!==\"string\")break}l=t}if(l>f){var p=e.getLine(l).length;return new r(f,u,l,p)}},this.openingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i+1},u=e.$findClosingBracket(t,o,s);if(!u)return;var a=e.foldWidgets[u.row];return a==null&&(a=e.getFoldWidget(u.row)),a==\"start\"&&u.row>o.row&&(u.row--,u.column=e.getLine(u.row).length),r.fromPoints(o,u)},this.closingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i},u=e.$findOpeningBracket(t,o);if(!u)return;return u.column++,o.column--,r.fromPoints(u,o)}}).call(i.prototype)}),ace.define(\"ace/theme/textmate\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";t.isDark=!1,t.cssClass=\"ace-tm\",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;}',t.$id=\"ace/theme/textmate\";var r=e(\"../lib/dom\");r.importCssString(t.cssText,t.cssClass)}),ace.define(\"ace/line_widgets\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/range\"],function(e,t,n){\"use strict\";function o(e){this.session=e,this.session.widgetManager=this,this.session.getRowLength=this.getRowLength,this.session.$getWidgetScreenLength=this.$getWidgetScreenLength,this.updateOnChange=this.updateOnChange.bind(this),this.renderWidgets=this.renderWidgets.bind(this),this.measureWidgets=this.measureWidgets.bind(this),this.session._changedWidgets=[],this.$onChangeEditor=this.$onChangeEditor.bind(this),this.session.on(\"change\",this.updateOnChange),this.session.on(\"changeFold\",this.updateOnFold),this.session.on(\"changeEditor\",this.$onChangeEditor)}var r=e(\"./lib/oop\"),i=e(\"./lib/dom\"),s=e(\"./range\").Range;(function(){this.getRowLength=function(e){var t;return this.lineWidgets?t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0:t=0,!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.$getWidgetScreenLength=function(){var e=0;return this.lineWidgets.forEach(function(t){t&&t.rowCount&&!t.hidden&&(e+=t.rowCount)}),e},this.$onChangeEditor=function(e){this.attach(e.editor)},this.attach=function(e){e&&e.widgetManager&&e.widgetManager!=this&&e.widgetManager.detach();if(this.editor==e)return;this.detach(),this.editor=e,e&&(e.widgetManager=this,e.renderer.on(\"beforeRender\",this.measureWidgets),e.renderer.on(\"afterRender\",this.renderWidgets))},this.detach=function(e){var t=this.editor;if(!t)return;this.editor=null,t.widgetManager=null,t.renderer.off(\"beforeRender\",this.measureWidgets),t.renderer.off(\"afterRender\",this.renderWidgets);var n=this.session.lineWidgets;n&&n.forEach(function(e){e&&e.el&&e.el.parentNode&&(e._inDocument=!1,e.el.parentNode.removeChild(e.el))})},this.updateOnFold=function(e,t){var n=t.lineWidgets;if(!n||!e.action)return;var r=e.data,i=r.start.row,s=r.end.row,o=e.action==\"add\";for(var u=i+1;u<s;u++)n[u]&&(n[u].hidden=o);n[s]&&(o?n[i]?n[s].hidden=o:n[i]=n[s]:(n[i]==n[s]&&(n[i]=undefined),n[s].hidden=o))},this.updateOnChange=function(e){var t=this.session.lineWidgets;if(!t)return;var n=e.start.row,r=e.end.row-n;if(r!==0)if(e.action==\"remove\"){var i=t.splice(n+1,r);i.forEach(function(e){e&&this.removeLineWidget(e)},this),this.$updateRows()}else{var s=new Array(r);s.unshift(n,0),t.splice.apply(t,s),this.$updateRows()}},this.$updateRows=function(){var e=this.session.lineWidgets;if(!e)return;var t=!0;e.forEach(function(e,n){if(e){t=!1,e.row=n;while(e.$oldWidget)e.$oldWidget.row=n,e=e.$oldWidget}}),t&&(this.session.lineWidgets=null)},this.addLineWidget=function(e){this.session.lineWidgets||(this.session.lineWidgets=new Array(this.session.getLength()));var t=this.session.lineWidgets[e.row];t&&(e.$oldWidget=t,t.el&&t.el.parentNode&&(t.el.parentNode.removeChild(t.el),t._inDocument=!1)),this.session.lineWidgets[e.row]=e,e.session=this.session;var n=this.editor.renderer;e.html&&!e.el&&(e.el=i.createElement(\"div\"),e.el.innerHTML=e.html),e.el&&(i.addCssClass(e.el,\"ace_lineWidgetContainer\"),e.el.style.position=\"absolute\",e.el.style.zIndex=5,n.container.appendChild(e.el),e._inDocument=!0),e.coverGutter||(e.el.style.zIndex=3),e.pixelHeight==null&&(e.pixelHeight=e.el.offsetHeight),e.rowCount==null&&(e.rowCount=e.pixelHeight/n.layerConfig.lineHeight);var r=this.session.getFoldAt(e.row,0);e.$fold=r;if(r){var s=this.session.lineWidgets;e.row==r.end.row&&!s[r.start.row]?s[r.start.row]=e:e.hidden=!0}return this.session._emit(\"changeFold\",{data:{start:{row:e.row}}}),this.$updateRows(),this.renderWidgets(null,n),this.onWidgetChanged(e),e},this.removeLineWidget=function(e){e._inDocument=!1,e.session=null,e.el&&e.el.parentNode&&e.el.parentNode.removeChild(e.el);if(e.editor&&e.editor.destroy)try{e.editor.destroy()}catch(t){}if(this.session.lineWidgets){var n=this.session.lineWidgets[e.row];if(n==e)this.session.lineWidgets[e.row]=e.$oldWidget,e.$oldWidget&&this.onWidgetChanged(e.$oldWidget);else while(n){if(n.$oldWidget==e){n.$oldWidget=e.$oldWidget;break}n=n.$oldWidget}}this.session._emit(\"changeFold\",{data:{start:{row:e.row}}}),this.$updateRows()},this.getWidgetsAtRow=function(e){var t=this.session.lineWidgets,n=t&&t[e],r=[];while(n)r.push(n),n=n.$oldWidget;return r},this.onWidgetChanged=function(e){this.session._changedWidgets.push(e),this.editor&&this.editor.renderer.updateFull()},this.measureWidgets=function(e,t){var n=this.session._changedWidgets,r=t.layerConfig;if(!n||!n.length)return;var i=Infinity;for(var s=0;s<n.length;s++){var o=n[s];if(!o||!o.el)continue;if(o.session!=this.session)continue;if(!o._inDocument){if(this.session.lineWidgets[o.row]!=o)continue;o._inDocument=!0,t.container.appendChild(o.el)}o.h=o.el.offsetHeight,o.fixedWidth||(o.w=o.el.offsetWidth,o.screenWidth=Math.ceil(o.w/r.characterWidth));var u=o.h/r.lineHeight;o.coverLine&&(u-=this.session.getRowLineCount(o.row),u<0&&(u=0)),o.rowCount!=u&&(o.rowCount=u,o.row<i&&(i=o.row))}i!=Infinity&&(this.session._emit(\"changeFold\",{data:{start:{row:i}}}),this.session.lineWidgetWidth=null),this.session._changedWidgets=[]},this.renderWidgets=function(e,t){var n=t.layerConfig,r=this.session.lineWidgets;if(!r)return;var i=Math.min(this.firstRow,n.firstRow),s=Math.max(this.lastRow,n.lastRow,r.length);while(i>0&&!r[i])i--;this.firstRow=n.firstRow,this.lastRow=n.lastRow,t.$cursorLayer.config=n;for(var o=i;o<=s;o++){var u=r[o];if(!u||!u.el)continue;if(u.hidden){u.el.style.top=-100-(u.pixelHeight||0)+\"px\";continue}u._inDocument||(u._inDocument=!0,t.container.appendChild(u.el));var a=t.$cursorLayer.getPixelPosition({row:o,column:0},!0).top;u.coverLine||(a+=n.lineHeight*this.session.getRowLineCount(u.row)),u.el.style.top=a-n.offset+\"px\";var f=u.coverGutter?0:t.gutterWidth;u.fixedWidth||(f-=t.scrollLeft),u.el.style.left=f+\"px\",u.fullWidth&&u.screenWidth&&(u.el.style.minWidth=n.width+2*n.padding+\"px\"),u.fixedWidth?u.el.style.right=t.scrollBar.getWidth()+\"px\":u.el.style.right=\"\"}}}).call(o.prototype),t.LineWidgets=o}),ace.define(\"ace/ext/error_marker\",[\"require\",\"exports\",\"module\",\"ace/line_widgets\",\"ace/lib/dom\",\"ace/range\"],function(e,t,n){\"use strict\";function o(e,t,n){var r=0,i=e.length-1;while(r<=i){var s=r+i>>1,o=n(t,e[s]);if(o>0)r=s+1;else{if(!(o<0))return s;i=s-1}}return-(r+1)}function u(e,t,n){var r=e.getAnnotations().sort(s.comparePoints);if(!r.length)return;var i=o(r,{row:t,column:-1},s.comparePoints);i<0&&(i=-i-1),i>=r.length?i=n>0?0:r.length-1:i===0&&n<0&&(i=r.length-1);var u=r[i];if(!u||!n)return;if(u.row===t){do u=r[i+=n];while(u&&u.row===t);if(!u)return r.slice()}var a=[];t=u.row;do a[n<0?\"unshift\":\"push\"](u),u=r[i+=n];while(u&&u.row==t);return a.length&&a}var r=e(\"../line_widgets\").LineWidgets,i=e(\"../lib/dom\"),s=e(\"../range\").Range;t.showErrorMarker=function(e,t){var n=e.session;n.widgetManager||(n.widgetManager=new r(n),n.widgetManager.attach(e));var s=e.getCursorPosition(),o=s.row,a=n.widgetManager.getWidgetsAtRow(o).filter(function(e){return e.type==\"errorMarker\"})[0];a?a.destroy():o-=t;var f=u(n,o,t),l;if(f){var c=f[0];s.column=(c.pos&&typeof c.column!=\"number\"?c.pos.sc:c.column)||0,s.row=c.row,l=e.renderer.$gutterLayer.$annotations[s.row]}else{if(a)return;l={text:[\"Looks good!\"],className:\"ace_ok\"}}e.session.unfold(s.row),e.selection.moveToPosition(s);var h={row:s.row,fixedWidth:!0,coverGutter:!0,el:i.createElement(\"div\"),type:\"errorMarker\"},p=h.el.appendChild(i.createElement(\"div\")),d=h.el.appendChild(i.createElement(\"div\"));d.className=\"error_widget_arrow \"+l.className;var v=e.renderer.$cursorLayer.getPixelPosition(s).left;d.style.left=v+e.renderer.gutterWidth-5+\"px\",h.el.className=\"error_widget_wrapper\",p.className=\"error_widget \"+l.className,p.innerHTML=l.text.join(\"<br>\"),p.appendChild(i.createElement(\"div\"));var m=function(e,t,n){if(t===0&&(n===\"esc\"||n===\"return\"))return h.destroy(),{command:\"null\"}};h.destroy=function(){if(e.$mouseHandler.isMousePressed)return;e.keyBinding.removeKeyboardHandler(m),n.widgetManager.removeLineWidget(h),e.off(\"changeSelection\",h.destroy),e.off(\"changeSession\",h.destroy),e.off(\"mouseup\",h.destroy),e.off(\"change\",h.destroy)},e.keyBinding.addKeyboardHandler(m),e.on(\"changeSelection\",h.destroy),e.on(\"changeSession\",h.destroy),e.on(\"mouseup\",h.destroy),e.on(\"change\",h.destroy),e.session.widgetManager.addLineWidget(h),h.el.onmousedown=e.focus.bind(e),e.renderer.scrollCursorIntoView(null,.5,{bottom:h.el.offsetHeight})},i.importCssString(\"    .error_widget_wrapper {        background: inherit;        color: inherit;        border:none    }    .error_widget {        border-top: solid 2px;        border-bottom: solid 2px;        margin: 5px 0;        padding: 10px 40px;        white-space: pre-wrap;    }    .error_widget.ace_error, .error_widget_arrow.ace_error{        border-color: #ff5a5a    }    .error_widget.ace_warning, .error_widget_arrow.ace_warning{        border-color: #F1D817    }    .error_widget.ace_info, .error_widget_arrow.ace_info{        border-color: #5a5a5a    }    .error_widget.ace_ok, .error_widget_arrow.ace_ok{        border-color: #5aaa5a    }    .error_widget_arrow {        position: absolute;        border: solid 5px;        border-top-color: transparent!important;        border-right-color: transparent!important;        border-left-color: transparent!important;        top: -5px;    }\",\"\")}),ace.define(\"ace/ace\",[\"require\",\"exports\",\"module\",\"ace/lib/fixoldbrowsers\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/range\",\"ace/editor\",\"ace/edit_session\",\"ace/undomanager\",\"ace/virtual_renderer\",\"ace/worker/worker_client\",\"ace/keyboard/hash_handler\",\"ace/placeholder\",\"ace/multi_select\",\"ace/mode/folding/fold_mode\",\"ace/theme/textmate\",\"ace/ext/error_marker\",\"ace/config\"],function(e,t,n){\"use strict\";e(\"./lib/fixoldbrowsers\");var r=e(\"./lib/dom\"),i=e(\"./lib/event\"),s=e(\"./range\").Range,o=e(\"./editor\").Editor,u=e(\"./edit_session\").EditSession,a=e(\"./undomanager\").UndoManager,f=e(\"./virtual_renderer\").VirtualRenderer;e(\"./worker/worker_client\"),e(\"./keyboard/hash_handler\"),e(\"./placeholder\"),e(\"./multi_select\"),e(\"./mode/folding/fold_mode\"),e(\"./theme/textmate\"),e(\"./ext/error_marker\"),t.config=e(\"./config\"),t.require=e,typeof define==\"function\"&&(t.define=define),t.edit=function(e,n){if(typeof e==\"string\"){var s=e;e=document.getElementById(s);if(!e)throw new Error(\"ace.edit can't find div #\"+s)}if(e&&e.env&&e.env.editor instanceof o)return e.env.editor;var u=\"\";if(e&&/input|textarea/i.test(e.tagName)){var a=e;u=a.value,e=r.createElement(\"pre\"),a.parentNode.replaceChild(e,a)}else e&&(u=e.textContent,e.innerHTML=\"\");var l=t.createEditSession(u),c=new o(new f(e),l,n),h={document:l,editor:c,onResize:c.resize.bind(c,null)};return a&&(h.textarea=a),i.addListener(window,\"resize\",h.onResize),c.on(\"destroy\",function(){i.removeListener(window,\"resize\",h.onResize),h.editor.container.env=null}),c.container.env=c.env=h,c},t.createEditSession=function(e,t){var n=new u(e,t);return n.setUndoManager(new a),n},t.Range=s,t.Editor=o,t.EditSession=u,t.UndoManager=a,t.VirtualRenderer=f,t.version=t.config.version});            (function() {\n    ace.require([\"ace/ace\"], function(a) {\n        if (a) {\n            a.config.init(true);\n            a.define = ace.define;\n        }\n        if (!window.ace)\n            window.ace = a;\n        for (var key in a) if (a.hasOwnProperty(key))\n            window.ace[key] = a[key];\n        window.ace[\"default\"] = window.ace;\n        if (typeof module == \"object\" && typeof exports == \"object\" && module) {\n            module.exports = window.ace;\n        }\n    });\n})();\n"
  },
  {
    "path": "static/js/app.js",
    "content": "var appInfo             = {};\nvar appFeatures         = {};\nvar editor              = null;\nvar connected           = false;\nvar bookmarks           = {};\nvar default_rows_limit  = 100;\nvar currentObject       = null;\nvar autocompleteObjects = [];\nvar inputResizing       = false;\nvar inputResizeOffset   = null;\n\nvar filterOptions = {\n  \"equal\":      \"= 'DATA'\",\n  \"not_equal\":  \"!= 'DATA'\",\n  \"greater\":    \"> 'DATA'\" ,\n  \"greater_eq\": \">= 'DATA'\",\n  \"less\":       \"< 'DATA'\",\n  \"less_eq\":    \"<= 'DATA'\",\n  \"like\":       \"LIKE 'DATA'\",\n  \"ilike\":      \"ILIKE 'DATA'\",\n  \"null\":       \"IS NULL\",\n  \"not_null\":   \"IS NOT NULL\"\n};\n\nfunction getSessionId() {\n  var id = sessionStorage.getItem(\"session_id\");\n\n  if (!id) {\n    id = guid();\n    sessionStorage.setItem(\"session_id\", id);\n  }\n\n  return id;\n}\n\nfunction setRowsLimit(num) {\n  localStorage.setItem(\"rows_limit\", num);\n}\n\nfunction getRowsLimit() {\n  return parseInt(localStorage.getItem(\"rows_limit\") || default_rows_limit);\n}\n\nfunction getPaginationOffset() {\n  var page  = $(\".current-page\").data(\"page\");\n  var limit = getRowsLimit();\n  return (page - 1) * limit;\n}\n\nfunction getPagesCount(rowsCount) {\n  var limit = getRowsLimit();\n  var num = parseInt(rowsCount / limit);\n\n  if ((num * limit) < rowsCount) {\n    num++;\n  }\n\n  return num;\n}\n\nfunction apiCall(method, path, params, cb) {\n  var timeout = appFeatures.query_timeout;\n  if (timeout == null) {\n    timeout = 300; // in seconds\n  }\n\n  $.ajax({\n    timeout: timeout * 1000, // in milliseconds\n    url: \"api\" + path,\n    method: method,\n    cache: false,\n    data: params,\n    headers: {\n      \"x-session-id\": getSessionId()\n    },\n    success: cb,\n    error: function(xhr, status, data) {\n      switch(status) {\n        case \"error\":\n          if (xhr.readyState == 0) { // 0 = UNSENT\n            showErrorBanner(\"Sorry, something went wrong with your request. Refresh the page and try again!\");\n          }\n          break;\n        case \"timeout\":\n          return cb({ error: \"Query timeout after \" + timeout + \"s\" });\n      }\n\n      var responseText;\n      try {\n        responseText = jQuery.parseJSON(xhr.responseText);\n      }\n      catch {\n        responseText = { error: \"Failed to parse the JSON response.\" };\n      }\n      cb(responseText);\n    }\n  });\n}\n\nfunction getInfo(cb)                        { apiCall(\"get\", \"/info\", {}, cb); }\nfunction getConnection(cb)                  { apiCall(\"get\", \"/connection\", {}, cb); }\nfunction getServerSettings(cb)              { apiCall(\"get\", \"/server_settings\", {}, cb); }\nfunction getSchemas(cb)                     { apiCall(\"get\", \"/schemas\", {}, cb); }\nfunction getObjects(cb)                     { apiCall(\"get\", \"/objects\", {}, cb); }\nfunction getTables(cb)                      { apiCall(\"get\", \"/tables\", {}, cb); }\nfunction getTableRows(table, opts, cb)      { apiCall(\"get\", \"/tables/\" + table + \"/rows\", opts, cb); }\nfunction getTableStructure(table, opts, cb) { apiCall(\"get\", \"/tables/\" + table, opts, cb); }\nfunction getTableIndexes(table, cb)         { apiCall(\"get\", \"/tables/\" + table + \"/indexes\", {}, cb); }\nfunction getTableConstraints(table, cb)     { apiCall(\"get\", \"/tables/\" + table + \"/constraints\", {}, cb); }\nfunction getTablesStats(cb)                 { apiCall(\"get\", \"/tables_stats\", {}, cb); }\nfunction getFunction(id, cb)                { apiCall(\"get\", \"/functions/\" + id, {}, cb); }\nfunction getHistory(cb)                     { apiCall(\"get\", \"/history\", {}, cb); }\nfunction getBookmarks(cb)                   { apiCall(\"get\", \"/bookmarks\", {}, cb); }\nfunction executeQuery(query, cb)            { apiCall(\"post\", \"/query\", { query: query }, cb); }\nfunction explainQuery(query, cb)            { apiCall(\"post\", \"/explain\", { query: query }, cb); }\nfunction analyzeQuery(query, cb)            { apiCall(\"post\", \"/analyze\", { query: query }, cb); }\nfunction disconnect(cb)                     { apiCall(\"post\", \"/disconnect\", {}, cb); }\n\nfunction encodeQuery(query) {\n  return Base64.encode(query).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \".\");\n}\n\nfunction showErrorBanner(text) {\n  if (window.errBannerTimeout != null) {\n    clearTimeout(window.errBannerTimeout);\n  }\n\n  window.errBannerTimeout = setTimeout(function() {\n    $(\"#error_banner\").fadeOut(\"fast\").text(\"\");\n  }, 3000);\n\n  $(\"#error_banner\").text(text).show();\n}\n\nfunction buildSchemaSection(name, objects) {\n  var section = \"\";\n\n  var titles = {\n    \"table\":             \"Tables\",\n    \"view\":              \"Views\",\n    \"materialized_view\": \"Materialized Views\",\n    \"function\":          \"Functions\",\n    \"sequence\":          \"Sequences\"\n  };\n\n  var icons = {\n    \"table\":             '<i class=\"fa fa-table\"></i>',\n    \"view\":              '<i class=\"fa fa-table\"></i>',\n    \"materialized_view\": '<i class=\"fa fa-table\"></i>',\n    \"function\":          '<i class=\"fa fa-bolt\"></i>',\n    \"sequence\":          '<i class=\"fa fa-circle-o\"></i>'\n  };\n\n  var klass = \"\";\n  if (name == \"public\") klass = \"expanded\";\n\n  section += \"<div class='schema \" + klass + \"'>\";\n  section += \"<div class='schema-name'><i class='fa fa-folder-o'></i><i class='fa fa-folder-open-o'></i> \" + name + \"</div>\";\n  section += \"<div class='schema-container'>\";\n\n  [\"table\", \"view\", \"materialized_view\", \"function\", \"sequence\"].forEach(function(group) {\n    group_klass = \"\";\n    if (name == \"public\" && group == \"table\") group_klass = \"expanded\";\n\n    section += \"<div class='schema-group \" + group_klass + \"'>\";\n    section += \"<div class='schema-group-title'><i class='fa fa-chevron-right'></i><i class='fa fa-chevron-down'></i> \" + titles[group] + \" <span class='schema-group-count'>\" + objects[group].length + \"</span></div>\";\n    section += \"<ul data-group='\" + group + \"'>\";\n\n    if (objects[group]) {\n      objects[group].forEach(function(item) {\n        var id = name + \".\" + item.name;\n\n        // Use function OID since multiple functions with the same name might exist\n        if (group == \"function\") {\n          id = item.oid;\n        }\n\n        section += \"<li class='schema-item schema-\" + group + \"' data-type='\" + group + \"' data-id='\" + id + \"' data-name='\" + item.name + \"'>\" + icons[group] + \"&nbsp;\" + item.name + \"</li>\";\n      });\n      section += \"</ul></div>\";\n    }\n  });\n\n  section += \"</div></div>\";\n\n  return section;\n}\n\nfunction loadLocalQueries() {\n  if (!appFeatures.local_queries) return;\n\n  $(\"body\").on(\"click\", \"a.load-local-query\", function(e) {\n    var id = $(this).data(\"id\");\n\n    apiCall(\"get\", \"/local_queries/\" + id, {}, function(resp) {\n      editor.setValue(resp.query);\n      editor.clearSelection();\n    });\n  });\n\n  apiCall(\"get\", \"/local_queries\", {}, function(resp) {\n    if (resp.error) return;\n\n    var container = $(\"#load-query-dropdown\").find(\".dropdown-menu\");\n\n    resp.forEach(function(item) {\n      var title = item.title || item.id;\n      $(\"<li><a href='#' class='load-local-query' data-id='\" + item.id + \"'>\" + title + \"</a></li>\").appendTo(container);\n    });\n\n    if (resp.length > 0) $(\"#load-local-query\").prop(\"disabled\", \"\");\n    $(\"#load-query-dropdown\").show();\n  });\n}\n\nfunction loadSchemas() {\n  $(\"#objects\").html(\"\");\n\n  var emptyObjectList = function() {\n    return {\n      table: [],\n      view: [],\n      materialized_view: [],\n      function: [],\n      sequence: []\n    }\n  }\n\n  getSchemas(function(schemasData) {\n    if (schemasData.error) {\n      alert(\"Error while fetching schemas: \" + schemasData.error);\n      return;\n    }\n\n    getObjects(function(data) {\n      if (data.error) {\n        alert(\"Error while fetching database objects: \" + data.error);\n        return;\n      }\n\n      if (Object.keys(data).length == 0) {\n        data[\"public\"] = emptyObjectList();\n      }\n\n      for (schemaName of schemasData) {\n        // Allow users to see empty schemas if we dont have any objects in them\n        if (!data[schemaName]) {\n          data[schemaName] = emptyObjectList();\n        }\n\n        $(buildSchemaSection(schemaName, data[schemaName])).appendTo(\"#objects\");\n      }\n\n      if (Object.keys(data).length == 1) {\n        $(\".schema\").addClass(\"expanded\");\n      }\n\n      // Clear out all autocomplete objects\n      autocompleteObjects = [];\n      for (schema in data) {\n        for (kind in data[schema]) {\n          if (!(kind == \"table\" || kind == \"view\" || kind == \"materialized_view\" || kind == \"function\")) {\n            continue\n          }\n\n          for (item in data[schema][kind]) {\n            autocompleteObjects.push({\n              caption: data[schema][kind][item].name,\n              value: data[schema][kind][item].name,\n              meta: kind\n            });\n          }\n        }\n      }\n\n      bindContextMenus();\n    });\n  });\n}\n\nfunction escapeHtml(str) {\n  if (str != null || str != undefined) {\n    return jQuery(\"<div/>\").text(str).html();\n  }\n\n  return \"<span class='null'>null</span>\";\n}\n\nfunction unescapeHtml(str){\n  var e = document.createElement(\"div\");\n  e.innerHTML = str;\n  return e.childNodes.length === 0 ? \"\" : e.childNodes[0].nodeValue;\n}\n\nfunction getCurrentObject() {\n  return currentObject || { name: \"\", type: \"\" };\n}\n\nfunction resetTable() {\n  $(\"#results_header\").html(\"\");\n  $(\"#results_body\").html(\"\");\n  $(\"#results_view\").html(\"\").hide();\n\n  $(\"#results\").\n    data(\"mode\", \"\").\n    removeClass(\"empty\").\n    removeClass(\"no-crop\").\n    show();\n}\n\nfunction performTableAction(table, action, el) {\n  if (action == \"truncate\" || action == \"delete\") {\n    var message = \"Are you sure you want to \" + action + \" table \" + table + \" ?\";\n    if (!confirm(message)) return;\n  }\n\n  switch(action) {\n    case \"truncate\":\n      executeQuery(\"TRUNCATE TABLE \" + table, function(data) {\n        if (data.error) alert(data.error);\n        resetTable();\n      });\n      break;\n    case \"delete\":\n      executeQuery(\"DROP TABLE \" + table, function(data) {\n        if (data.error) alert(data.error);\n        loadSchemas();\n        resetTable();\n      });\n      break;\n    case \"export\":\n      var format = el.data(\"format\");\n      var db = $(\"#current_database\").text();\n      var filename = db + \".\" + table + \".\" + format;\n      var query = \"SELECT * FROM \" + table;\n      openInNewWindow(\"api/query\", { \"format\": format, \"filename\": filename, \"query\": query });\n      break;\n    case \"dump\":\n      openInNewWindow(\"api/export\", { \"table\": table });\n      break;\n    case \"copy\":\n      copyToClipboard(table.split('.')[1]);\n      break;\n    case \"analyze\":\n      executeQuery(\"ANALYZE \" + table, function(data) {\n        if (data.error) alert(data.error);\n        resetTable();\n      });\n      break;\n  }\n}\n\nfunction performViewAction(view, action, el) {\n  if (action == \"delete\") {\n    var message = \"Are you sure you want to \" + action + \" view \" + view + \" ?\";\n    if (!confirm(message)) return;\n  }\n\n  switch(action) {\n    case \"delete\":\n      executeQuery(\"DROP VIEW \" + view, function(data) {\n        if (data.error) alert(data.error);\n        loadSchemas();\n        resetTable();\n      });\n      break;\n    case \"export\":\n      var format = el.data(\"format\");\n      var db = $(\"#current_database\").text();\n      var filename = db + \".\" + view + \".\" + format;\n      var query = \"SELECT * FROM \" + view;\n      openInNewWindow(\"api/query\", { \"format\": format, \"filename\": filename, \"query\": query });\n      break;\n    case \"copy\":\n      copyToClipboard(view.split('.')[1]);\n      break;\n    case \"copy_def\":\n      executeQuery(\"SELECT pg_get_viewdef('\" + view + \"', true);\", function(data) {\n        if (data.error) {\n          alert(data.error);\n          return;\n        }\n        copyToClipboard(data.rows[0]);\n      });\n      break;\n    case \"view_def\":\n      executeQuery(\"SELECT pg_get_viewdef('\" + view + \"', true);\", function(data) {\n        if (data.error) {\n          alert(data.error);\n          return;\n        }\n        showViewDefinition(view, data.rows[0]);\n      });\n      break;\n  }\n}\n\nfunction performRowAction(action, value) {\n  if (action == \"stop_query\") {\n    if (!confirm(\"Are you sure you want to stop the query?\")) return;\n    executeQuery(\"SELECT pg_cancel_backend(\" + value + \");\", function(data) {\n      if (data.error) alert(data.error);\n      setTimeout(showActivityPanel, 1000);\n    });\n  }\n}\n\nfunction sortArrow(direction) {\n  switch (direction) {\n    case \"ASC\":\n      return \"&#x25B2;\";\n    case \"DESC\":\n      return \"&#x25BC;\";\n    default:\n      return \"\";\n  }\n}\n\nfunction buildTable(results, sortColumn, sortOrder, options) {\n  if (!options) options = {};\n  var action = options.action;\n\n  resetTable();\n\n  if (results.error) {\n    $(\"#results_header\").html(\"\");\n    $(\"#results_body\").html(\"<tr><td>ERROR: \" + results.error + \"</tr></tr>\");\n    return;\n  }\n\n  if (results.rows.length == 0) {\n    $(\"#results_header\").html(\"\");\n    $(\"#results_body\").html(\"<tr><td>No records found</td></tr>\");\n    if (results.stats) {\n      $(\"#result-rows-count\").html(results.stats.query_duration_ms + \" ms\");\n    } else {\n      $(\"#result-rows-count\").html(\"\");\n    }\n    $(\"#results\").addClass(\"empty\");\n    return;\n  }\n\n  var cols = \"\";\n  var rows = \"\";\n\n  results.columns.forEach(function(col) {\n    if (col === sortColumn) {\n      cols += \"<th class='table-header-col active' data-name='\" + col + \"' data-order=\" + sortOrder + \">\" + col + \"&nbsp;\" + sortArrow(sortOrder) + \"</th>\";\n    } else {\n      cols += \"<th class='table-header-col' data-name='\" + col + \"'>\" + col + \"</th>\";\n    }\n  });\n\n  // No header to make the column non-sortable\n  if (action) {\n    cols += \"<th></th>\";\n\n    // Determine which column contains the data attribute\n    action.dataColumn = results.columns.indexOf(action.data);\n  }\n\n  results.rows.forEach(function(row) {\n    var r = \"\";\n\n    // Add all actual row data here\n    for (i in row) {\n      r += \"<td data-col='\" + i + \"'><div>\" + escapeHtml(row[i]) + \"</div></td>\";\n    }\n\n    // Add row action button\n    if (action) {\n      r += \"<td><a class='btn btn-xs btn-\" + action.style + \" row-action' data-action='\" + action.name + \"' data-value='\" + row[action.dataColumn] + \"' href='#'>\" + action.title + \"</a></td>\";\n    }\n\n    rows += \"<tr>\" + r + \"</tr>\";\n  });\n\n  $(\"#results_header\").html(cols);\n  $(\"#results_body\").html(rows);\n\n  // Show number of rows rendered on the page\n  if (results.stats) {\n    $(\"#result-rows-count\").html(results.stats.rows_count + \" rows in \" + results.stats.query_duration_ms + \" ms\");\n  } else {\n    $(\"#result-rows-count\").html(results.rows.length + \" rows\");\n  }\n}\n\nfunction setCurrentTab(id) {\n  // Pagination should only be visible on rows tab\n  if (id != \"table_content\") {\n    $(\"#body\").removeClass(\"with-pagination\");\n  }\n\n  $(\"#nav ul li.selected\").removeClass(\"selected\");\n  $(\"#\" + id).addClass(\"selected\");\n\n  // Persist tab selection into the session storage\n  sessionStorage.setItem(\"tab\", id);\n}\n\nfunction showQueryHistory() {\n  getHistory(function(data) {\n    var rows = [];\n\n    for(i in data) {\n      rows.unshift([parseInt(i) + 1, data[i].query, data[i].timestamp]);\n    }\n\n    buildTable({ columns: [\"id\", \"query\", \"timestamp\"], rows: rows });\n\n    setCurrentTab(\"table_history\");\n    $(\"#input\").hide();\n    $(\"#body\").prop(\"class\", \"full\");\n    $(\"#results\").addClass(\"no-crop\");\n  });\n}\n\nfunction showTableIndexes() {\n  var name = getCurrentObject().name;\n\n  if (name.length == 0) {\n    alert(\"Please select a table!\");\n    return;\n  }\n\n  getTableIndexes(name, function(data) {\n    setCurrentTab(\"table_indexes\");\n    buildTable(data);\n\n    $(\"#input\").hide();\n    $(\"#body\").prop(\"class\", \"full\");\n    $(\"#results\").addClass(\"no-crop\");\n  });\n}\n\nfunction showTableConstraints() {\n  var name = getCurrentObject().name;\n\n  if (name.length == 0) {\n    alert(\"Please select a table!\");\n    return;\n  }\n\n  getTableConstraints(name, function(data) {\n    setCurrentTab(\"table_constraints\");\n    buildTable(data);\n\n    $(\"#input\").hide();\n    $(\"#body\").prop(\"class\", \"full\");\n    $(\"#results\").addClass(\"no-crop\");\n  });\n}\n\nfunction showTableInfo() {\n  var name = getCurrentObject().name;\n\n  if (name.length == 0) {\n    alert(\"Please select a table!\");\n    return;\n  }\n\n  apiCall(\"get\", \"/tables/\" + name + \"/info\", {}, function(data) {\n    $(\".table-information .lines\").show();\n    $(\"#table_total_size\").text(data.total_size);\n    $(\"#table_data_size\").text(data.data_size);\n    $(\"#table_index_size\").text(data.index_size);\n    $(\"#table_rows_count\").text(data.rows_count);\n    $(\"#table_encoding\").text(\"Unknown\");\n  });\n\n  buildTableFilters(name, getCurrentObject().type);\n}\n\nfunction updatePaginator(pagination) {\n  if (!pagination) {\n    $(\".current-page\").data(\"page\", 1).data(\"pages\", 1);\n    $(\"button.page\").text(\"1 of 1\");\n    $(\".prev-page, .next-page\").prop(\"disabled\", \"disabled\");\n    return;\n  }\n\n  $(\".current-page\").\n    data(\"page\", pagination.page).\n    data(\"pages\", pagination.pages_count);\n\n  if (pagination.page > 1) {\n    $(\".prev-page\").prop(\"disabled\", \"\");\n  }\n  else {\n    $(\".prev-page\").prop(\"disabled\", \"disabled\");\n  }\n\n  if (pagination.pages_count > 1 && pagination.page < pagination.pages_count) {\n    $(\".next-page\").prop(\"disabled\", \"\");\n  }\n  else {\n    $(\".next-page\").prop(\"disabled\", \"disabled\");\n  }\n\n  $(\"#total_records\").text(pagination.rows_count);\n  if (pagination.pages_count == 0) pagination.pages_count = 1;\n  $(\"button.page\").text(pagination.page + \" of \" + pagination.pages_count);\n}\n\nfunction showTableContent(sortColumn, sortOrder) {\n  var name = getCurrentObject().name;\n\n  if (name.length == 0) {\n    alert(\"Please select a table!\");\n    return;\n  }\n\n  if (getCurrentObject().type == \"function\") {\n    alert(\"Cant view rows for a function\");\n    return;\n  }\n\n  var opts = {\n    limit:       getRowsLimit(),\n    offset:      getPaginationOffset(),\n    sort_column: sortColumn,\n    sort_order:  sortOrder\n  };\n\n  var filter = {\n    column: $(\".filters select.column\").val(),\n    op:     $(\".filters select.filter\").val(),\n    input:  $(\".filters input\").val()\n  };\n\n  // Apply filtering only if column is selected\n  if (filter.column && filter.op) {\n    var where = [\n      '\"' + filter.column + '\"',\n      filterOptions[filter.op].replace(\"DATA\", filter.input)\n    ].join(\" \");\n\n    opts[\"where\"] = where;\n  }\n\n  getTableRows(name, opts, function(data) {\n    $(\"#input\").hide();\n    $(\"#body\").prop(\"class\", \"with-pagination\");\n\n    buildTable(data, sortColumn, sortOrder);\n    setCurrentTab(\"table_content\");\n    updatePaginator(data.pagination);\n\n    $(\"#results\").data(\"mode\", \"browse\").data(\"table\", name);\n  });\n}\n\nfunction showPaginatedTableContent() {\n  var activeColumn = $(\"#results th.active\");\n  var sortColumn = null;\n  var sortOrder = null;\n\n  if (activeColumn.length) {\n    sortColumn = activeColumn.data(\"name\");\n    sortOrder = activeColumn.data(\"order\");\n  }\n\n  showTableContent(sortColumn, sortOrder);\n}\n\nfunction showDatabaseStats() {\n  getTablesStats(function(data) {\n    buildTable(data);\n\n    setCurrentTab(\"table_structure\");\n    $(\"#input\").hide();\n    $(\"#body\").prop(\"class\", \"full\");\n    $(\"#results\").addClass(\"no-crop\");\n  });\n}\n\nfunction downloadDatabaseStats() {\n  openInNewWindow(\"api/tables_stats\", { format: \"csv\", export: \"true\" });\n}\n\nfunction showServerSettings() {\n  getServerSettings(function(data) {\n    buildTable(data);\n\n    setCurrentTab(\"table_content\");\n    $(\"#input\").hide();\n    $(\"#body\").prop(\"class\", \"full\");\n    $(\"#results\").addClass(\"no-crop\");\n  });\n}\n\nfunction showTableStructure() {\n  var name = getCurrentObject().name;\n\n  if (name.length == 0) {\n    alert(\"Please select a table!\");\n    return;\n  }\n\n  setCurrentTab(\"table_structure\");\n\n  $(\"#input\").hide();\n  $(\"#body\").prop(\"class\", \"full\");\n\n  getTableStructure(name, { type: getCurrentObject().type }, function(data) {\n    if (getCurrentObject().type == \"function\") {\n      var name = data.rows[0][data.columns.indexOf(\"proname\")];\n      var definition = data.rows[0][data.columns.indexOf(\"functiondef\")];\n      showFunctionDefinition(name, definition);\n      return\n    }\n\n    buildTable(data);\n    $(\"#results\").addClass(\"no-crop\");\n  });\n}\n\nfunction showViewDefinition(viewName, viewDefintion) {\n  setCurrentTab(\"table_structure\");\n  renderResultsView(\"View definition for: <strong>\" + viewName + \"</strong>\", viewDefintion);\n}\n\nfunction showFunctionDefinition(functionName, definition) {\n  setCurrentTab(\"table_structure\");\n  renderResultsView(\"Function definition for: <strong>\" + functionName + \"</strong>\", definition)\n}\n\nfunction renderResultsView(title, content) {\n  $(\"#results\").addClass(\"no-crop\");\n  $(\"#input\").hide();\n  $(\"#body\").prop(\"class\", \"full\");\n  $(\"#results\").hide();\n\n  var title = $(\"<div/>\").prop(\"class\", \"title\").html(title);\n  var content = $(\"<pre/>\").text(content);\n\n  $(\"<div/>\").\n    html(\"<i class='fa fa-copy'></i>\").\n    addClass(\"copy\").\n    appendTo(content);\n\n  $(\"#results_view\").html(\"\");\n  title.appendTo(\"#results_view\");\n  content.appendTo(\"#results_view\");\n  $(\"#results_view\").show();\n}\n\nfunction showQueryPanel() {\n  if (!$(\"#table_query\").hasClass(\"selected\")) {\n    resetTable();\n  }\n\n  setCurrentTab(\"table_query\");\n  editor.focus();\n\n  $(\"#input\").show();\n  $(\"#body\").prop(\"class\", \"\")\n}\n\nfunction showConnectionPanel() {\n  setCurrentTab(\"table_connection\");\n  $(\"#input\").hide();\n  $(\"#body\").addClass(\"full\");\n\n  getConnection(function(data) {\n    var rows = [];\n\n    for(key in data) {\n      rows.push([key, data[key]]);\n    }\n\n    buildTable({\n      columns: [\"attribute\", \"value\"],\n      rows: rows\n    });\n  });\n}\n\nfunction showActivityPanel() {\n  var options = {\n    action: {\n      name: \"stop_query\",\n      title: \"stop\",\n      data: \"pid\",\n      style: \"danger\"\n    }\n  }\n\n  setCurrentTab(\"table_activity\");\n  $(\"#input\").hide();\n  $(\"#body\").addClass(\"full\");\n\n  apiCall(\"get\", \"/activity\", {}, function(data) {\n    buildTable(data, null, null, options);\n  });\n}\n\nfunction showQueryProgressMessage() {\n  $(\"#run, #explain-dropdown-toggle, #csv, #json, #xml, #load-local-query\").prop(\"disabled\", true);\n  $(\"#explain-dropdown\").removeClass(\"open\");\n  $(\"#query_progress\").show();\n}\n\nfunction hideQueryProgressMessage() {\n  $(\"#run, #explain-dropdown-toggle, #csv, #json, #xml, #load-local-query\").prop(\"disabled\", false);\n  $(\"#query_progress\").hide();\n}\n\nfunction getEditorSelection() {\n  // Return the exact selection if user has one\n  var query = $.trim(editor.getSelectedText());\n  if (query.length > 0) {\n    return query;\n  }\n\n  query = editor.getValue();\n\n  // Determine which query we should run when there are multiple queries without a delimiter\n  if (query.indexOf(\";\") == -1) {\n    var subquery = getSubquery(query, editor.getCursorPosition());\n\n    if (subquery) {\n      // Highlight query selection so user knows what is being executed\n      if (subquery.numChunks > 1) {\n        editor.selection.setSelectionRange({\n          start: { row: subquery.startRow, column: 0 },\n          end: { row: subquery.endRow, column: 0 },\n        })\n      }\n\n      return subquery.text;\n    }\n  }\n\n  return query;\n}\n\nfunction getSubquery(text, cursor) {\n  var lines = text.split(\"\\n\");\n  var startRow = undefined;\n  var numChunks = 0;\n  var ranges = [];\n\n  for (i = 0; i < lines.length; i++) {\n    if (lines[i].trim().length == 0) {\n      if (startRow >= 0 && cursor.row >= startRow && cursor.row <= i) {\n        ranges.push([startRow, i]);\n      }\n\n      numChunks++;\n      startRow = undefined;\n      continue;\n    }\n\n    if (startRow === undefined) {\n      startRow = i;\n    }\n\n    if (i == lines.length - 1) {\n      ranges.push([startRow, i + 1]);\n      numChunks++;\n    }\n  }\n\n  if (ranges.length > 0) {\n    return {\n      text: lines.slice(ranges[0][0], ranges[0][1]).join(\"\\n\"),\n      startRow: ranges[0][0],\n      endRow: ranges[0][1],\n      numChunks: numChunks\n    };\n  }\n}\n\nfunction runQuery() {\n  setCurrentTab(\"table_query\");\n  showQueryProgressMessage();\n\n  var query = getEditorSelection();\n  if (query.length == 0) {\n    hideQueryProgressMessage();\n    return;\n  }\n\n  executeQuery(query, function(data) {\n    buildTable(data);\n\n    hideQueryProgressMessage();\n    $(\"#input\").show();\n    $(\"#body\").removeClass(\"full\");\n    $(\"#results\").data(\"mode\", \"query\");\n\n    if (query.toLowerCase().indexOf(\"explain\") != -1) {\n      $(\"#results\").addClass(\"no-crop\");\n    }\n\n    // Reload objects list if anything was created/deleted\n    if (query.match(/(create|drop)\\s/i)) {\n      loadSchemas();\n    }\n  });\n}\n\nfunction runExplain() {\n  setCurrentTab(\"table_query\");\n  showQueryProgressMessage();\n\n  var query = getEditorSelection();\n  if (query.length == 0) {\n    hideQueryProgressMessage();\n    return;\n  }\n\n  explainQuery(query, function(data) {\n    buildTable(data);\n\n    hideQueryProgressMessage();\n    $(\"#input\").show();\n    $(\"#body\").removeClass(\"full\");\n    $(\"#results\").addClass(\"no-crop\");\n  });\n}\n\nfunction runAnalyze() {\n  setCurrentTab(\"table_query\");\n  showQueryProgressMessage();\n\n  var query = getEditorSelection();\n  if (query.length == 0) {\n    hideQueryProgressMessage();\n    return;\n  }\n\n  analyzeQuery(query, function(data) {\n    buildTable(data);\n\n    hideQueryProgressMessage();\n    $(\"#input\").show();\n    $(\"#body\").removeClass(\"full\");\n    $(\"#results\").addClass(\"no-crop\");\n  });\n}\n\nfunction generateURL(path, params) {\n  var url = new URL(window.location.href.split(\"#\")[0]);\n\n  url.pathname += path;\n  for (key in params) {\n    url.searchParams.append(key, params[key]);\n  }\n\n  // Automatically append session id so we dont have to do that everywhere\n  url.searchParams.append(\"_session_id\", getSessionId());\n\n  return url.toString();\n}\n\nfunction openInNewWindow(path, params) {\n  var url = generateURL(path, params);\n  var win = window.open(url, '_blank');\n  win.focus();\n}\n\nfunction exportTo(format) {\n  var query = getEditorSelection();\n  if (query.length == 0) {\n    return;\n  }\n\n  setCurrentTab(\"table_query\");\n\n  openInNewWindow(\"api/query\", {\n    \"format\": format,\n    \"query\": encodeQuery(query)\n  })\n}\n\n// Fetch all unique values for the selected column in the table\nfunction showUniqueColumnsValues(table, column, showCounts) {\n  var query = 'SELECT DISTINCT \"' + column + '\" FROM ' + table;\n\n  // Display results ordered by counts.\n  // This could be slow on large sets without an index.\n  if (showCounts) {\n    query = 'SELECT DISTINCT \"' + column + '\", COUNT(1) AS total_count FROM ' + table + ' GROUP BY \"' + column + '\" ORDER BY total_count DESC';\n  }\n\n  executeQuery(query, function(data) {\n    $(\"#input\").hide();\n    $(\"#body\").prop(\"class\", \"full\");\n    $(\"#results\").data(\"mode\", \"query\");\n    buildTable(data);\n  });\n}\n\n// Show numeric stats on the field\nfunction showFieldNumStats(table, column) {\n  var query = 'SELECT count(1), min(' + column + '), max(' + column + '), avg(' + column + ') FROM ' + table;\n\n  executeQuery(query, function(data) {\n    $(\"#input\").hide();\n    $(\"#body\").prop(\"class\", \"full\");\n    $(\"#results\").data(\"mode\", \"query\");\n    buildTable(data);\n  });\n}\n\nfunction buildTableFilters(name, type) {\n  getTableStructure(name, { type: type }, function(data) {\n    if (data.rows.length == 0) {\n      $(\"#pagination .filters\").hide();\n    }\n    else {\n      $(\"#pagination .filters\").show();\n    }\n\n    $(\"#pagination select.column\").html(\"<option value='' selected>Select column</option>\");\n\n    for (var i = 0; i < data.rows.length; i++) {\n      var row = data.rows[i];\n\n      var el = $(\"<option/>\").attr(\"value\", row[0]).text(row[0]);\n      $(\"#pagination select.column\").append(el);\n    }\n  });\n}\n\nvar objectAutocompleter = {\n  getCompletions: function (editor, session, pos, prefix, callback) {\n    callback(null, autocompleteObjects);\n  }\n}\n\nfunction initEditor() {\n  var writeQueryTimeout = null;\n\n  editor = ace.edit(\"custom_query\");\n  editor.setOptions({\n    enableBasicAutocompletion: true,\n    enableLiveAutocompletion: true,\n  });\n  editor.completers.push(objectAutocompleter);\n\n  editor.setFontSize(13);\n  editor.setTheme(\"ace/theme/tomorrow\");\n  editor.setShowPrintMargin(false);\n  editor.getSession().setMode(\"ace/mode/pgsql\");\n  editor.getSession().setTabSize(2);\n  editor.getSession().setUseSoftTabs(true);\n\n  editor.commands.addCommands([{\n    name: \"run_query\",\n    bindKey: {\n      win: \"Ctrl-Enter\",\n      mac: \"Command-Enter\"\n    },\n    exec: function(editor) {\n      runQuery();\n    }\n  }, {\n    name: \"explain_query\",\n    bindKey: {\n      win: \"Ctrl-E\",\n      mac: \"Command-E\"\n    },\n    exec: function(editor) {\n      runExplain();\n    }\n  }]);\n\n  editor.on(\"change\", function() {\n    if (writeQueryTimeout) {\n      clearTimeout(writeQueryTimeout);\n    }\n\n    writeQueryTimeout = setTimeout(function() {\n      localStorage.setItem(\"pgweb_query\", editor.getValue());\n    }, 1000);\n  });\n\n  var query = localStorage.getItem(\"pgweb_query\");\n  if (query && query.length > 0) {\n    editor.setValue(query);\n    editor.clearSelection();\n  }\n}\n\nfunction addShortcutTooltips() {\n  if (navigator.userAgent.indexOf(\"OS X\") > 0) {\n    $(\"#run\").attr(\"title\", \"Shortcut: ⌘+Enter\");\n    $(\"#explain\").attr(\"title\", \"Shortcut: ⌘+E\");\n  }\n  else {\n    $(\"#run\").attr(\"title\", \"Shortcut: Ctrl+Enter\");\n    $(\"#explain\").attr(\"title\", \"Shortcut: Ctrl+E\");\n  }\n}\n\n// Get the latest release from Github API\nfunction getLatestReleaseInfo(current) {\n  try {\n    $.get(\"https://api.github.com/repos/sosedoff/pgweb/releases/latest\", function(release) {\n      if (release.name != current.version) {\n        var message = \"Update available. Check out \" + release.tag_name + \" on <a target='_blank' href='\" + release.html_url + \"'>Github</a>\";\n        $(\".connection-settings .update\").html(message).fadeIn();\n      }\n    });\n  }\n  catch(error) {\n    console.log(\"Cant get last release from github:\", error);\n  }\n}\n\nfunction showConnectionSettings() {\n  // Show the current postgres version\n  $(\".connection-settings .version\").text(\"v\" + appInfo.version).show();\n  $(\"#connection_window\").show();\n  initConnectionWindow();\n\n  // Check github release page for updates\n  getLatestReleaseInfo(appInfo);\n\n  getBookmarks(function(data) {\n    if (data.error) {\n      console.log(\"Error while fetching bookmarks:\", data.error);\n      return;\n    }\n\n    if (data.length > 0) {\n      // Set bookmarks in global var\n      bookmarks = data;\n\n      // Remove all existing bookmark options\n      $(\"#connection_bookmarks\").html(\"\");\n\n      // Add blank option\n      $(\"<option value=''>Select a bookmarked database to connect to</option>\").appendTo(\"#connection_bookmarks\");\n\n      // Add all available bookmarks\n      for (key of data) {\n        $(\"<option value='\" + key + \"''>\" + key + \"</option>\").appendTo(\"#connection_bookmarks\");\n      }\n\n      $(\".bookmarks\").show();\n    }\n    else {\n      if (appFeatures.bookmarks_only) {\n        $(\"#connection_error\").html(\"Running in <b>bookmarks-only</b> mode but <b>NO</b> bookmarks configured.\").show();\n        $(\".open-connection\").hide();\n      } else {\n        $(\".bookmarks\").hide();\n      }\n    }\n  });\n}\n\nfunction initConnectionWindow() {\n  if (appFeatures.bookmarks_only) {\n    $(\".connection-group-switch\").hide();\n    $(\".connection-scheme-group\").hide();\n    $(\".connection-bookmarks-group\").show();\n    $(\".connection-standard-group\").hide();\n    $(\".connection-ssh-group\").hide();\n  } else {\n    $(\".connection-group-switch\").show();\n    $(\".connection-scheme-group\").hide();\n    $(\".connection-bookmarks-group\").show();\n    $(\".connection-standard-group\").show();\n    $(\".connection-ssh-group\").hide();\n  }\n}\n\nfunction getConnectionString() {\n  var url  = $.trim($(\"#connection_url\").val());\n  var mode = $(\".connection-group-switch button.active\").attr(\"data\");\n  var ssl  = $(\"#connection_ssl\").val();\n\n  if (mode == \"standard\" || mode == \"ssh\") {\n    var host = $(\"#pg_host\").val();\n    var port = $(\"#pg_port\").val();\n    var user = $(\"#pg_user\").val();\n    var pass = encodeURIComponent($(\"#pg_password\").val());\n    var db   = $(\"#pg_db\").val();\n\n    if (port.length == 0) {\n      port = \"5432\";\n    }\n\n    url = \"postgres://\" + user + \":\" + pass + \"@\" + host + \":\" + port + \"/\" + db + \"?sslmode=\" + ssl;\n  }\n  else {\n    var local = url.indexOf(\"localhost\") != -1 || url.indexOf(\"127.0.0.1\") != -1;\n\n    if (local && url.indexOf(\"sslmode\") == -1) {\n      url += \"?sslmode=\" + ssl;\n    }\n  }\n\n  return url;\n}\n\n// Add a context menu to the results table header columns\nfunction bindTableHeaderMenu() {\n  $(\"#results_header\").contextmenu({\n    scopes: \"th\",\n    target: \"#results_header_menu\",\n    before: function(e, element, target) {\n      // Enable menu for browsing table rows view only.\n      if ($(\"#results\").data(\"mode\") != \"browse\") {\n        e.preventDefault();\n        this.closemenu();\n        return false;\n      }\n    },\n    onItem: function(context, e) {\n      var menuItem = $(e.target);\n\n      switch(menuItem.data(\"action\")) {\n        case \"copy_name\":\n          copyToClipboard($(context).data(\"name\"));\n          break;\n\n        case \"unique_values\":\n          showUniqueColumnsValues(\n            $(\"#results\").data(\"table\"), // table name\n            $(context).data(\"name\"),     // column name\n            menuItem.data(\"counts\")      // display counts\n          );\n          break;\n\n        case \"num_stats\":\n          showFieldNumStats(\n            $(\"#results\").data(\"table\"), // table name\n            $(context).data(\"name\")      // column name\n          );\n          break;\n      }\n    }\n  });\n\n  $(\"#results_body\").contextmenu({\n    scopes: \"td\",\n    target: \"#results_row_menu\",\n    before: function(e, element, target) {\n      var browseMode = $(\"#results\").data(\"mode\");\n      var isEmpty    = $(\"#results\").hasClass(\"empty\");\n      var isAllowed  = browseMode == \"browse\" || browseMode == \"query\";\n\n      if (isEmpty || !isAllowed) {\n        e.preventDefault();\n        this.closemenu();\n        return false;\n      }\n    },\n    onItem: function(context, e) {\n      var menuItem = $(e.target);\n\n      switch(menuItem.data(\"action\")) {\n        case \"display_value\":\n          var value = $(context).text();\n          $(\"#content_modal .content\").text(value);\n          $(\"#content_modal\").show();\n          break;\n        case \"copy_value\":\n          copyToClipboard($(context).text());\n          break;\n        case \"filter_by_value\":\n          var colIdx   = $(context).data(\"col\");\n          var colValue = $(context).text();\n          var colName  = $(\"#results_header th\").eq(colIdx).data(\"name\");\n\n          $(\"select.column\").val(colName);\n          $(\"select.filter\").val(\"equal\");\n          $(\"#table_filter_value\").val(colValue);\n          $(\"#rows_filter\").submit();\n      }\n    }\n  });\n}\n\nfunction bindCurrentDatabaseMenu() {\n  $(\"#current_database\").contextmenu({\n    target: \"#current_database_context_menu\",\n    onItem: function(context, e) {\n      var menuItem = $(e.target);\n\n      switch(menuItem.data(\"action\")) {\n        case \"show_db_stats\":\n          showDatabaseStats();\n          break;\n        case \"download_db_stats\":\n          downloadDatabaseStats();\n          break;\n        case \"server_settings\":\n          showServerSettings();\n          break;\n        case \"export\":\n          openInNewWindow(\"api/export\");\n          break;\n      }\n    }\n  });\n}\n\nfunction bindDatabaseObjectsFilter() {\n  var filterTimeout = null;\n\n  $(\"#filter_database_objects\").on(\"keyup\", function (e) {\n    clearTimeout(filterTimeout);\n\n    var val = $(this).val().trim();\n\n    // Reset search on ESC\n    if (e.keyCode == 27 || val == \"\") {\n      resetObjectsFilter();\n      return;\n    }\n\n    $(\".clear-objects-filter\").show();\n    $(\".schema-group\").addClass(\"expanded\");\n\n    filterTimeout = setTimeout(function() {\n      filterObjectsByName(val)\n    }, 200);\n  });\n\n  $(\".clear-objects-filter\").on(\"click\", function(e) {\n    resetObjectsFilter();\n  });\n}\n\nfunction resetObjectsFilter() {\n  $(\"#filter_database_objects\").val(\"\");\n  $(\"#objects li.schema-item\").show();\n  $(\".clear-objects-filter\").hide();\n}\n\nfunction filterObjectsByName(query) {\n  $(\"#objects li.schema-item\").each(function (idx, el) {\n    var item = $(el);\n    var name = $(el).data(\"name\");\n\n    if (name.indexOf(query) < 0) {\n      item.hide();\n    } else {\n      item.show();\n    }\n  });\n}\n\nfunction getQuotedSchemaTableName(table) {\n  if (typeof table === \"string\" && table.indexOf(\".\") > -1) {\n    var schemaTableComponents = table.split(\".\");\n    return ['\"', schemaTableComponents[0], '\".\"', schemaTableComponents[1], '\"'].join('');\n  }\n  return table;\n}\n\nfunction bindContextMenus() {\n  bindTableHeaderMenu();\n  bindCurrentDatabaseMenu();\n\n  $(\".schema-group ul\").each(function(id, el) {\n    var group = $(el).data(\"group\");\n\n    if (group == \"table\") {\n      $(el).contextmenu({\n        target: \"#tables_context_menu\",\n        scopes: \"li.schema-table\",\n        onItem: function(context, e) {\n          var el      = $(e.target);\n          var table   = getQuotedSchemaTableName($(context[0]).data(\"id\"));\n          var action  = el.data(\"action\");\n          performTableAction(table, action, el);\n        }\n      });\n    }\n\n    if (group == \"view\") {\n      $(el).contextmenu({\n        target: \"#view_context_menu\",\n        scopes: \"li.schema-view\",\n        onItem: function(context, e) {\n          var el      = $(e.target);\n          var table   = getQuotedSchemaTableName($(context[0]).data(\"id\"));\n          var action  = el.data(\"action\");\n          performViewAction(table, action, el);\n        }\n      });\n    }\n\n    if (group == \"materialized_view\") {\n      $(el).contextmenu({\n        target: \"#view_context_menu\",\n        scopes: \"li.schema-materialized_view\",\n        onItem: function(context, e) {\n          var el      = $(e.target);\n          var table   = getQuotedSchemaTableName($(context[0]).data(\"id\"));\n          var action  = el.data(\"action\");\n          performViewAction(table, action, el);\n        }\n      });\n    }\n  });\n}\n\nfunction toggleDatabaseSearch() {\n  $(\"#current_database\").toggle();\n  $(\"#database_search\").toggle();\n}\n\nfunction enableDatabaseSearch(data) {\n  var input = $(\"#database_search\");\n\n  input.typeahead(\"destroy\");\n\n  input.typeahead({\n    source: data,\n    minLength: 0,\n    items: \"all\",\n    autoSelect: false,\n    fitToElement: true\n  });\n\n  input.typeahead(\"lookup\").focus();\n\n  input.on(\"focusout\", function(e){\n    toggleDatabaseSearch();\n    input.off(\"focusout\");\n  });\n}\n\nfunction bindInputResizeEvents() {\n  var height = sessionStorage.getItem(\"input_height\");\n  if (height) {\n    resizeInput(height);\n    checkInputSize();\n  }\n\n  $(\"body\").on(\"mousemove\", onInputResize);\n  $(\"body\").on(\"mouseup\", endInputResize);\n  $(\"#input_resize_handler\").on(\"mousedown\", beginInputResize);\n  $(window).on(\"resize\", checkInputSize);\n}\n\nfunction checkInputSize() {\n  var inputHeight = $(\"#input\").height();\n  var bodyHeight = $(\"#body\").height();\n\n  if (bodyHeight == 0 || inputHeight == 0) return;\n\n  if (inputHeight > bodyHeight || bodyHeight - inputHeight < 200) {\n    resizeInput(bodyHeight - 200);\n  }\n}\n\nfunction resizeInput(height) {\n  if (height < 100) height = 100;\n\n  var diff = 50 + 12; // actions box + padding\n\n  $(\"#input\").height(height);\n  $(\"#input .input-wrapper\").height(height - diff);\n  $(\"#custom_query\").height(height - diff);\n  $(\"#output\").css(\"top\", height + \"px\");\n\n  if (editor) {\n    editor.resize();\n  }\n}\n\nfunction beginInputResize() {\n  inputResizing = true;\n  inputResizeOffset = $(\"#input\").offset().top;\n\n  $(\"html\").css(\"cursor\", \"row-resize\");\n  $(\"#input_resize_handler\").addClass(\"dragging\");\n}\n\nfunction endInputResize() {\n  if (!inputResizing) return;\n\n  inputResizing = false;\n  inputResizeOffset = null;\n\n  $(\"html\").css(\"cursor\", \"auto\");\n  $(\"#input_resize_handler\").removeClass(\"dragging\");\n\n  // Save current settings for page reloads\n  sessionStorage.setItem(\"input_height\", $(\"#input\").height());\n}\n\nfunction onInputResize(event) {\n  if (!inputResizing) return;\n\n  var computedHeight = event.clientY - inputResizeOffset;\n  if (computedHeight < 150) computedHeight = 150;\n\n  resizeInput(computedHeight);\n}\n\nfunction bindContentModalEvents() {\n  var contentModal = document.getElementById(\"content_modal\");\n\n  $(window).on(\"click\", function(e) {\n    // Automatically hide the modal on any click outside of the modal window\n    if (e.target && !contentModal.contains(e.target)) {\n      $(\"#content_modal\").hide();\n    }\n  });\n\n  $(\"#content_modal .content-modal-action\").on(\"click\", function() {\n    switch ($(this).data(\"action\")) {\n      case \"copy\":\n        copyToClipboard($(\"#content_modal pre\").text());\n        break;\n      case \"close\":\n        $(\"#content_modal\").hide();\n        break;\n    }\n  });\n\n  $(\"#results\").on(\"dblclick\", \"td > div\", function() {\n    var value = unescapeHtml($(this).html());\n    if (!value) return;\n\n    $(\"#content_modal pre\").html(value);\n    $(\"#content_modal\").show();\n  })\n}\n\n$(document).ready(function() {\n  bindInputResizeEvents();\n  bindContentModalEvents();\n\n  $(\"#table_content\").on(\"click\",     function() { showTableContent();     });\n  $(\"#table_structure\").on(\"click\",   function() { showTableStructure();   });\n  $(\"#table_indexes\").on(\"click\",     function() { showTableIndexes();     });\n  $(\"#table_constraints\").on(\"click\", function() { showTableConstraints(); });\n  $(\"#table_history\").on(\"click\",     function() { showQueryHistory();     });\n  $(\"#table_query\").on(\"click\",       function() { showQueryPanel();       });\n  $(\"#table_connection\").on(\"click\",  function() { showConnectionPanel();  });\n  $(\"#table_activity\").on(\"click\",    function() { showActivityPanel();    });\n\n  $(\"#run\").on(\"click\", function() {\n    runQuery();\n  });\n\n  $(\"#explain\").on(\"click\", function() {\n    runExplain();\n  });\n\n  $(\"#analyze\").on(\"click\", function() {\n    runAnalyze();\n  });\n\n  $(\"#csv\").on(\"click\", function() {\n    exportTo(\"csv\");\n  });\n\n  $(\"#json\").on(\"click\", function() {\n    exportTo(\"json\");\n  });\n\n  $(\"#xml\").on(\"click\", function() {\n    exportTo(\"xml\");\n  });\n\n  $(\"#results_view\").on(\"click\", \".copy\", function() {\n    copyToClipboard($(this).parent().text());\n  });\n\n  $(\"#results\").on(\"click\", \"tr\", function(e) {\n    $(\"#results tr.selected\").removeClass();\n    $(this).addClass(\"selected\");\n  });\n\n  $(\"#objects\").on(\"click\", \".schema-group-title\", function(e) {\n    $(this).parent().toggleClass(\"expanded\");\n  });\n\n  $(\"#objects\").on(\"click\", \".schema-name\", function(e) {\n    $(this).parent().toggleClass(\"expanded\");\n  });\n\n  $(\"#objects\").on(\"click\", \"li\", function(e) {\n    currentObject = {\n      name: $(this).data(\"id\"),\n      type: $(this).data(\"type\")\n    };\n\n    $(\"#objects li\").removeClass(\"active\");\n    $(this).addClass(\"active\");\n    $(\".current-page\").data(\"page\", 1);\n    $(\".filters select, .filters input\").val(\"\");\n\n    if (currentObject.type == \"function\") {\n      sessionStorage.setItem(\"tab\", \"table_structure\");\n    } else {\n      showTableInfo();\n    }\n\n    switch(sessionStorage.getItem(\"tab\")) {\n      case \"table_content\":\n        showTableContent();\n        break;\n      case \"table_structure\":\n        showTableStructure();\n        break;\n      case \"table_constraints\":\n        showTableConstraints();\n        break;\n      case \"table_indexes\":\n        showTableIndexes();\n        break;\n      default:\n        showTableContent();\n    }\n  });\n\n  $(\"#results\").on(\"click\", \"a.row-action\", function(e) {\n    e.preventDefault();\n\n    var action = $(this).data(\"action\");\n    var value  = $(this).data(\"value\");\n\n    performRowAction(action, value);\n  })\n\n  $(\"#results\").on(\"click\", \"th\", function(e) {\n    if (!$(\"#table_content\").hasClass(\"selected\")) return;\n\n    var sortColumn = $(this).data(\"name\");\n    var sortOrder  = $(this).data(\"order\") === \"ASC\" ? \"DESC\" : \"ASC\";\n\n    $(this).data(\"order\", sortOrder);\n    showTableContent(sortColumn, sortOrder);\n  });\n\n  $(\"#refresh_tables\").on(\"click\", function() {\n    loadSchemas();\n  });\n\n  $(\"#rows_filter\").on(\"submit\", function(e) {\n    e.preventDefault();\n    $(\".current-page\").data(\"page\", 1);\n\n    var column = $(this).find(\"select.column\").val();\n    var filter = $(this).find(\"select.filter\").val();\n    var query  = $.trim($(this).find(\"input\").val());\n\n    if (filter && filterOptions[filter].indexOf(\"DATA\") > 0 && query == \"\") {\n      alert(\"Please specify filter query\");\n      return\n    }\n\n    showTableContent();\n  });\n\n  $(\".change-limit\").on(\"click\", function() {\n    var limit = prompt(\"Please specify a new rows limit\", getRowsLimit());\n\n    if (limit && limit >= 1) {\n      $(\".current-page\").data(\"page\", 1);\n      setRowsLimit(limit);\n      showTableContent();\n    }\n  });\n\n  $(\"select.filter\").on(\"change\", function(e) {\n    var val = $(this).val();\n\n    if ([\"null\", \"not_null\"].indexOf(val) >= 0) {\n      $(\".filters input\").hide().val(\"\");\n    }\n    else {\n      $(\".filters input\").show();\n    }\n  });\n\n  $(\"button.reset-filters\").on(\"click\", function() {\n    $(\".filters select, .filters input\").val(\"\");\n    showTableContent();\n  });\n\n  // Automatically prefill the filter if it's not set yet\n  $(\"select.column\").on(\"change\", function() {\n    if ($(\"select.filter\").val() == \"\") {\n      $(\"select.filter\").val(\"equal\");\n      $(\"#table_filter_value\").focus();\n    }\n  });\n\n  $(\"#pagination .next-page\").on(\"click\", function() {\n    var current = $(\".current-page\").data(\"page\");\n    var total   = $(\".current-page\").data(\"pages\");\n\n    if (total > current) {\n      $(\".current-page\").data(\"page\", current + 1);\n      showPaginatedTableContent();\n\n      if (current + 1 == total) {\n        $(this).prop(\"disabled\", \"disabled\");\n      }\n    }\n\n    if (current > 1) {\n      $(\".prev-page\").prop(\"disabled\", \"\");\n    }\n  });\n\n  $(\"#pagination .prev-page\").on(\"click\", function() {\n    var current = $(\".current-page\").data(\"page\");\n\n    if (current > 1) {\n      $(\".current-page\").data(\"page\", current - 1);\n      $(\".next-page\").prop(\"disabled\", \"\");\n      showPaginatedTableContent();\n    }\n\n    if (current == 1) {\n      $(this).prop(\"disabled\", \"disabled\");\n    }\n  });\n\n  $(\"#current_database\").on(\"click\", function(e) {\n    apiCall(\"get\", \"/databases\", {}, function(resp) {\n      toggleDatabaseSearch();\n      enableDatabaseSearch(resp);\n    });\n  });\n\n  $(\"#database_search\").change(function(e) {\n    var current = $(\"#database_search\").typeahead(\"getActive\");\n    if (current && current == $(\"#database_search\").val()) {\n      apiCall(\"post\", \"/switchdb\", { db: current }, function(resp) {\n        if (resp.error) {\n          alert(resp.error);\n          return;\n        };\n        window.location.reload();\n      });\n    };\n  });\n\n  $(\"#edit_connection\").on(\"click\", function() {\n    if (connected) {\n      $(\"#close_connection_window\").show();\n    }\n\n    showConnectionSettings();\n  });\n\n  $(\"#close_connection\").on(\"click\", function() {\n    if (!confirm(\"Are you sure you want to disconnect?\")) return;\n\n    disconnect(function() {\n      showConnectionSettings();\n      resetTable();\n      $(\"#close_connection_window\").hide();\n    });\n  });\n\n  $(\"#close_connection_window\").on(\"click\", function() {\n    $(\"#connection_window\").hide();\n  });\n\n  $(\"#connection_url\").on(\"change\", function() {\n    if ($(this).val().indexOf(\"localhost\") != -1) {\n      $(\"#connection_ssl\").val(\"disable\");\n    }\n  });\n\n  $(\"#pg_host\").on(\"change\", function() {\n    var value = $(this).val();\n\n    if (value.indexOf(\"localhost\") != -1 || value.indexOf(\"127.0.0.1\") != -1) {\n      $(\"#connection_ssl\").val(\"disable\");\n    }\n  });\n\n  $(\".connection-group-switch button\").on(\"click\", function() {\n    $(\".connection-group-switch button\").removeClass(\"active\");\n    $(this).addClass(\"active\");\n\n    switch($(this).attr(\"data\")) {\n      case \"scheme\":\n        $(\".connection-scheme-group\").show();\n        $(\".connection-standard-group\").hide();\n        $(\".connection-ssh-group\").hide();\n        return;\n      case \"standard\":\n        $(\".connection-scheme-group\").hide();\n        $(\".connection-standard-group\").show();\n        $(\".connection-ssh-group\").hide();\n        return;\n      case \"ssh\":\n        $(\".connection-scheme-group\").hide();\n        $(\".connection-standard-group\").show();\n        $(\".connection-ssh-group\").show();\n        return;\n    }\n  });\n\n  $(\"#connection_bookmarks\").on(\"change\", function(e) {\n    var selection = $(this).val();\n\n    var inputs = [\n      $(\"#connection_form input[type='text']\"),\n      $(\"#connection_form input[type='password']\"),\n      $(\"#connection_ssl\")\n    ];\n\n    inputs.forEach(function(selector) {\n      selector.val(\"\").prop(\"disabled\", selection == \"\" ? \"\" : \"disabled\");\n    });\n  });\n\n  $(\"#connection_form\").on(\"submit\", function(e) {\n    e.preventDefault();\n\n    var button = $(this).find(\"button.open-connection\");\n    var params = {};\n    var bookmarkID = $.trim($(\"#connection_bookmarks\").val());\n\n    if (bookmarkID != \"\") {\n      params[\"bookmark_id\"] = $(\"#connection_bookmarks\").val();\n    }\n    else {\n      params.url = getConnectionString();\n      if (params.url.length == 0) {\n        return;\n      }\n\n      if ($(\".connection-group-switch button.active\").attr(\"data\") == \"ssh\") {\n        params[\"ssh\"]              = 1\n        params[\"ssh_host\"]         = $(\"#ssh_host\").val();\n        params[\"ssh_port\"]         = $(\"#ssh_port\").val();\n        params[\"ssh_user\"]         = $(\"#ssh_user\").val();\n        params[\"ssh_password\"]     = $(\"#ssh_password\").val();\n        params[\"ssh_key\"]          = $(\"#ssh_key\").val();\n        params[\"ssh_key_password\"] = $(\"#ssh_key_password\").val()\n      }\n    }\n\n    $(\"#connection_error\").hide();\n    button.prop(\"disabled\", true).text(\"Please wait...\");\n\n    apiCall(\"post\", \"/connect\", params, function(resp) {\n      button.prop(\"disabled\", false).text(\"Connect\");\n\n      if (resp.error) {\n        connected = false;\n        $(\"#connection_error\").text(resp.error).show();\n      }\n      else {\n        connected = true;\n        loadSchemas();\n        loadLocalQueries();\n\n        $(\"#connection_window\").hide();\n        $(\"#current_database\").text(resp.current_database);\n        $(\"#main\").show();\n      }\n    });\n  });\n\n  initEditor();\n  addShortcutTooltips();\n  bindDatabaseObjectsFilter();\n\n  // Set session from the url\n  var reqUrl = new URL(window.location);\n  var sessionId = reqUrl.searchParams.get(\"session\");\n\n  if (sessionId && sessionId != \"\") {\n    sessionStorage.setItem(\"session_id\", sessionId);\n    window.history.pushState({}, document.title, window.location.pathname);\n  }\n\n  getInfo(function(resp) {\n    if (resp.error) {\n      alert(\"Unable to fetch app info: \" + resp.error + \". Please reload the browser page.\");\n      return;\n    }\n\n    appInfo = resp.app;\n    appFeatures = resp.features;\n\n    getConnection(function(resp) {\n      if (resp.error) {\n        connected = false;\n        showConnectionSettings();\n        $(\".connection-actions\").show();\n        return;\n      }\n\n      connected = true;\n      loadSchemas();\n      loadLocalQueries();\n\n      $(\"#current_database\").text(resp.current_database);\n      $(\"#main\").show();\n\n      if (!appFeatures.session_lock) {\n        $(\".connection-actions\").show();\n      }\n    });\n  });\n});\n\n"
  },
  {
    "path": "static/js/base64.js",
    "content": "/**\n*\n*  Base64 encode / decode\n*  http://www.webtoolkit.info/\n*\n**/\nvar Base64 = {\n  // private property\n  _keyStr : \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\",\n  // public method for encoding\n  encode : function (input) {\n      var output = \"\";\n      var chr1, chr2, chr3, enc1, enc2, enc3, enc4;\n      var i = 0;\n      input = Base64._utf8_encode(input);\n      while (i < input.length) {\n          chr1 = input.charCodeAt(i++);\n          chr2 = input.charCodeAt(i++);\n          chr3 = input.charCodeAt(i++);\n          enc1 = chr1 >> 2;\n          enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n          enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n          enc4 = chr3 & 63;\n          if (isNaN(chr2)) {\n              enc3 = enc4 = 64;\n          } else if (isNaN(chr3)) {\n              enc4 = 64;\n          }\n          output = output +\n          this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +\n          this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);\n      }\n      return output;\n  },\n  // public method for decoding\n  decode : function (input) {\n      var output = \"\";\n      var chr1, chr2, chr3;\n      var enc1, enc2, enc3, enc4;\n      var i = 0;\n      input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\n      while (i < input.length) {\n          enc1 = this._keyStr.indexOf(input.charAt(i++));\n          enc2 = this._keyStr.indexOf(input.charAt(i++));\n          enc3 = this._keyStr.indexOf(input.charAt(i++));\n          enc4 = this._keyStr.indexOf(input.charAt(i++));\n          chr1 = (enc1 << 2) | (enc2 >> 4);\n          chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n          chr3 = ((enc3 & 3) << 6) | enc4;\n          output = output + String.fromCharCode(chr1);\n          if (enc3 != 64) {\n              output = output + String.fromCharCode(chr2);\n          }\n          if (enc4 != 64) {\n              output = output + String.fromCharCode(chr3);\n          }\n      }\n      output = Base64._utf8_decode(output);\n      return output;\n  },\n  // private method for UTF-8 encoding\n  _utf8_encode : function (string) {\n      string = string.replace(/\\r\\n/g,\"\\n\");\n      var utftext = \"\";\n      for (var n = 0; n < string.length; n++) {\n          var c = string.charCodeAt(n);\n          if (c < 128) {\n              utftext += String.fromCharCode(c);\n          }\n          else if((c > 127) && (c < 2048)) {\n              utftext += String.fromCharCode((c >> 6) | 192);\n              utftext += String.fromCharCode((c & 63) | 128);\n          }\n          else {\n              utftext += String.fromCharCode((c >> 12) | 224);\n              utftext += String.fromCharCode(((c >> 6) & 63) | 128);\n              utftext += String.fromCharCode((c & 63) | 128);\n          }\n      }\n      return utftext;\n  },\n  // private method for UTF-8 decoding\n  _utf8_decode : function (utftext) {\n      var string = \"\";\n      var i = 0;\n      var c = c1 = c2 = 0;\n      while ( i < utftext.length ) {\n          c = utftext.charCodeAt(i);\n          if (c < 128) {\n              string += String.fromCharCode(c);\n              i++;\n          }\n          else if((c > 191) && (c < 224)) {\n              c2 = utftext.charCodeAt(i+1);\n              string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));\n              i += 2;\n          }\n          else {\n              c2 = utftext.charCodeAt(i+1);\n              c3 = utftext.charCodeAt(i+2);\n              string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));\n              i += 3;\n          }\n      }\n      return string;\n  }\n}"
  },
  {
    "path": "static/js/bootstrap-contextmenu.js",
    "content": "/*!\n * Bootstrap Context Menu\n * Author: @sydcanem\n * https://github.com/sydcanem/bootstrap-contextmenu\n *\n * Inspired by Bootstrap's dropdown plugin.\n * Bootstrap (http://getbootstrap.com).\n *\n * Licensed under MIT\n * ========================================================= */\n\n;(function($) {\n\n\t'use strict';\n\n\t/* CONTEXTMENU CLASS DEFINITION\n\t * ============================ */\n\tvar toggle = '[data-toggle=\"context\"]';\n\n\tvar ContextMenu = function (element, options) {\n\t\tthis.$element = $(element);\n\n\t\tthis.before = options.before || this.before;\n\t\tthis.onItem = options.onItem || this.onItem;\n\t\tthis.scopes = options.scopes || null;\n\n\t\tif (options.target) {\n\t\t\tthis.$element.data('target', options.target);\n\t\t}\n\n\t\tthis.listen();\n\t};\n\n\tContextMenu.prototype = {\n\n\t\tconstructor: ContextMenu\n\t\t,show: function(e) {\n\n\t\t\tvar $menu\n\t\t\t\t, evt\n\t\t\t\t, tp\n\t\t\t\t, items\n\t\t\t\t, relatedTarget = { relatedTarget: this, target: e.currentTarget };\n\n\t\t\tif (this.isDisabled()) return;\n\n\t\t\tthis.closemenu();\n\n\t\t\tif (this.before.call(this,e,$(e.currentTarget)) === false) return;\n\n\t\t\t$menu = this.getMenu();\n\t\t\t$menu.trigger(evt = $.Event('show.bs.context', relatedTarget));\n\n\t\t\ttp = this.getPosition(e, $menu);\n\t\t\titems = 'li:not(.divider)';\n\t\t\t$menu.attr('style', '')\n\t\t\t\t.css(tp)\n\t\t\t\t.addClass('open')\n\t\t\t\t.on('click.context.data-api', items, $.proxy(this.onItem, this, $(e.currentTarget)))\n\t\t\t\t.trigger('shown.bs.context', relatedTarget);\n\n\t\t\t// Delegating the `closemenu` only on the currently opened menu.\n\t\t\t// This prevents other opened menus from closing.\n\t\t\t$('html')\n\t\t\t\t.on('click.context.data-api', $menu.selector, $.proxy(this.closemenu, this));\n\n\t\t\treturn false;\n\t\t}\n\n\t\t,closemenu: function(e) {\n\t\t\tvar $menu\n\t\t\t\t, evt\n\t\t\t\t, items\n\t\t\t\t, relatedTarget;\n\n\t\t\t$menu = this.getMenu();\n\n\t\t\tif(!$menu.hasClass('open')) return;\n\n\t\t\trelatedTarget = { relatedTarget: this };\n\t\t\t$menu.trigger(evt = $.Event('hide.bs.context', relatedTarget));\n\n\t\t\titems = 'li:not(.divider)';\n\t\t\t$menu.removeClass('open')\n\t\t\t\t.off('click.context.data-api', items)\n\t\t\t\t.trigger('hidden.bs.context', relatedTarget);\n\n\t\t\t$('html')\n\t\t\t\t.off('click.context.data-api', $menu.selector);\n\t\t\t// Don't propagate click event so other currently\n\t\t\t// opened menus won't close.\n\t\t\te.stopPropagation();\n\t\t}\n\n\t\t,keydown: function(e) {\n\t\t\tif (e.which == 27) this.closemenu(e);\n\t\t}\n\n\t\t,before: function(e) {\n\t\t\treturn true;\n\t\t}\n\n\t\t,onItem: function(e) {\n\t\t\treturn true;\n\t\t}\n\n\t\t,listen: function () {\n\t\t\tthis.$element.on('contextmenu.context.data-api', this.scopes, $.proxy(this.show, this));\n\t\t\t$('html').on('click.context.data-api', $.proxy(this.closemenu, this));\n\t\t\t$('html').on('keydown.context.data-api', $.proxy(this.keydown, this));\n\t\t}\n\n\t\t,destroy: function() {\n\t\t\tthis.$element.off('.context.data-api').removeData('context');\n\t\t\t$('html').off('.context.data-api');\n\t\t}\n\n\t\t,isDisabled: function() {\n\t\t\treturn this.$element.hasClass('disabled') || \n\t\t\t\t\tthis.$element.attr('disabled');\n\t\t}\n\n\t\t,getMenu: function () {\n\t\t\tvar selector = this.$element.data('target')\n\t\t\t\t, $menu;\n\n\t\t\tif (!selector) {\n\t\t\t\tselector = this.$element.attr('href');\n\t\t\t\tselector = selector && selector.replace(/.*(?=#[^\\s]*$)/, ''); //strip for ie7\n\t\t\t}\n\n\t\t\t$menu = $(selector);\n\n\t\t\treturn $menu && $menu.length ? $menu : this.$element.find(selector);\n\t\t}\n\n\t\t,getPosition: function(e, $menu) {\n\t\t\tvar mouseX = e.clientX\n\t\t\t\t, mouseY = e.clientY\n\t\t\t\t, boundsX = $(window).width()\n\t\t\t\t, boundsY = $(window).height()\n\t\t\t\t, menuWidth = $menu.find('.dropdown-menu').outerWidth()\n\t\t\t\t, menuHeight = $menu.find('.dropdown-menu').outerHeight()\n\t\t\t\t, tp = {\"position\":\"absolute\",\"z-index\":9999}\n\t\t\t\t, Y, X, parentOffset;\n\n\t\t\tif (mouseY + menuHeight > boundsY) {\n\t\t\t\tY = {\"top\": mouseY - menuHeight + $(window).scrollTop()};\n\t\t\t} else {\n\t\t\t\tY = {\"top\": mouseY + $(window).scrollTop()};\n\t\t\t}\n\n\t\t\tif ((mouseX + menuWidth > boundsX) && ((mouseX - menuWidth) > 0)) {\n\t\t\t\tX = {\"left\": mouseX - menuWidth + $(window).scrollLeft()};\n\t\t\t} else {\n\t\t\t\tX = {\"left\": mouseX + $(window).scrollLeft()};\n\t\t\t}\n\n\t\t\t// If context-menu's parent is positioned using absolute or relative positioning,\n\t\t\t// the calculated mouse position will be incorrect.\n\t\t\t// Adjust the position of the menu by its offset parent position.\n\t\t\tparentOffset = $menu.offsetParent().offset();\n\t\t\tX.left = X.left - parentOffset.left;\n\t\t\tY.top = Y.top - parentOffset.top;\n \n\t\t\treturn $.extend(tp, Y, X);\n\t\t}\n\n\t};\n\n\t/* CONTEXT MENU PLUGIN DEFINITION\n\t * ========================== */\n\n\t$.fn.contextmenu = function (option,e) {\n\t\treturn this.each(function () {\n\t\t\tvar $this = $(this)\n\t\t\t\t, data = $this.data('context')\n\t\t\t\t, options = (typeof option == 'object') && option;\n\n\t\t\tif (!data) $this.data('context', (data = new ContextMenu($this, options)));\n\t\t\tif (typeof option == 'string') data[option].call(data, e);\n\t\t});\n\t};\n\n\t$.fn.contextmenu.Constructor = ContextMenu;\n\n\t/* APPLY TO STANDARD CONTEXT MENU ELEMENTS\n\t * =================================== */\n\n\t$(document)\n\t   .on('contextmenu.context.data-api', function() {\n\t\t\t$(toggle).each(function () {\n\t\t\t\tvar data = $(this).data('context');\n\t\t\t\tif (!data) return;\n\t\t\t\tdata.closemenu();\n\t\t\t});\n\t\t})\n\t\t.on('contextmenu.context.data-api', toggle, function(e) {\n\t\t\t$(this).contextmenu('show', e);\n\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t});\n\t\t\n}(jQuery));\n"
  },
  {
    "path": "static/js/bootstrap-dropdown.js",
    "content": "/* ========================================================================\n * Bootstrap: dropdown.js v3.2.0\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2011-2014 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n+function ($) {\n  'use strict';\n\n  // DROPDOWN CLASS DEFINITION\n  // =========================\n\n  var backdrop = '.dropdown-backdrop'\n  var toggle   = '[data-toggle=\"dropdown\"]'\n  var Dropdown = function (element) {\n    $(element).on('click.bs.dropdown', this.toggle)\n  }\n\n  Dropdown.VERSION = '3.2.0'\n\n  Dropdown.prototype.toggle = function (e) {\n    var $this = $(this)\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    clearMenus()\n\n    if (!isActive) {\n      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n        // if mobile we use a backdrop because click events don't delegate\n        $('<div class=\"dropdown-backdrop\"/>').insertAfter($(this)).on('click', clearMenus)\n      }\n\n      var relatedTarget = { relatedTarget: this }\n      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this.trigger('focus')\n\n      $parent\n        .toggleClass('open')\n        .trigger('shown.bs.dropdown', relatedTarget)\n    }\n\n    return false\n  }\n\n  Dropdown.prototype.keydown = function (e) {\n    if (!/(38|40|27)/.test(e.keyCode)) return\n\n    var $this = $(this)\n\n    e.preventDefault()\n    e.stopPropagation()\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    if (!isActive || (isActive && e.keyCode == 27)) {\n      if (e.which == 27) $parent.find(toggle).trigger('focus')\n      return $this.trigger('click')\n    }\n\n    var desc = ' li:not(.divider):visible a'\n    var $items = $parent.find('[role=\"menu\"]' + desc + ', [role=\"listbox\"]' + desc)\n\n    if (!$items.length) return\n\n    var index = $items.index($items.filter(':focus'))\n\n    if (e.keyCode == 38 && index > 0)                 index--                        // up\n    if (e.keyCode == 40 && index < $items.length - 1) index++                        // down\n    if (!~index)                                      index = 0\n\n    $items.eq(index).trigger('focus')\n  }\n\n  function clearMenus(e) {\n    if (e && e.which === 3) return\n    $(backdrop).remove()\n    $(toggle).each(function () {\n      var $parent = getParent($(this))\n      var relatedTarget = { relatedTarget: this }\n      if (!$parent.hasClass('open')) return\n      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))\n      if (e.isDefaultPrevented()) return\n      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)\n    })\n  }\n\n  function getParent($this) {\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = selector && $(selector)\n\n    return $parent && $parent.length ? $parent : $this.parent()\n  }\n\n\n  // DROPDOWN PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.dropdown')\n\n      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.dropdown\n\n  $.fn.dropdown             = Plugin\n  $.fn.dropdown.Constructor = Dropdown\n\n\n  // DROPDOWN NO CONFLICT\n  // ====================\n\n  $.fn.dropdown.noConflict = function () {\n    $.fn.dropdown = old\n    return this\n  }\n\n\n  // APPLY TO STANDARD DROPDOWN ELEMENTS\n  // ===================================\n\n  $(document)\n    .on('click.bs.dropdown.data-api', clearMenus)\n    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n    .on('keydown.bs.dropdown.data-api', toggle + ', [role=\"menu\"], [role=\"listbox\"]', Dropdown.prototype.keydown)\n\n}(jQuery);\n"
  },
  {
    "path": "static/js/ext-language_tools.js",
    "content": "ace.define(\"ace/snippets\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\",\"ace/lib/lang\",\"ace/range\",\"ace/range_list\",\"ace/keyboard/hash_handler\",\"ace/tokenizer\",\"ace/clipboard\",\"ace/lib/dom\",\"ace/editor\"],function(e,t,n){\"use strict\";function h(e){var t=(new Date).toLocaleString(\"en-us\",e);return t.length==1?\"0\"+t:t}var r=e(\"./lib/oop\"),i=e(\"./lib/event_emitter\").EventEmitter,s=e(\"./lib/lang\"),o=e(\"./range\").Range,u=e(\"./range_list\").RangeList,a=e(\"./keyboard/hash_handler\").HashHandler,f=e(\"./tokenizer\").Tokenizer,l=e(\"./clipboard\"),c={CURRENT_WORD:function(e){return e.session.getTextRange(e.session.getWordRange())},SELECTION:function(e,t,n){var r=e.session.getTextRange();return n?r.replace(/\\n\\r?([ \\t]*\\S)/g,\"\\n\"+n+\"$1\"):r},CURRENT_LINE:function(e){return e.session.getLine(e.getCursorPosition().row)},PREV_LINE:function(e){return e.session.getLine(e.getCursorPosition().row-1)},LINE_INDEX:function(e){return e.getCursorPosition().row},LINE_NUMBER:function(e){return e.getCursorPosition().row+1},SOFT_TABS:function(e){return e.session.getUseSoftTabs()?\"YES\":\"NO\"},TAB_SIZE:function(e){return e.session.getTabSize()},CLIPBOARD:function(e){return l.getText&&l.getText()},FILENAME:function(e){return/[^/\\\\]*$/.exec(this.FILEPATH(e))[0]},FILENAME_BASE:function(e){return/[^/\\\\]*$/.exec(this.FILEPATH(e))[0].replace(/\\.[^.]*$/,\"\")},DIRECTORY:function(e){return this.FILEPATH(e).replace(/[^/\\\\]*$/,\"\")},FILEPATH:function(e){return\"/not implemented.txt\"},WORKSPACE_NAME:function(){return\"Unknown\"},FULLNAME:function(){return\"Unknown\"},BLOCK_COMMENT_START:function(e){var t=e.session.$mode||{};return t.blockComment&&t.blockComment.start||\"\"},BLOCK_COMMENT_END:function(e){var t=e.session.$mode||{};return t.blockComment&&t.blockComment.end||\"\"},LINE_COMMENT:function(e){var t=e.session.$mode||{};return t.lineCommentStart||\"\"},CURRENT_YEAR:h.bind(null,{year:\"numeric\"}),CURRENT_YEAR_SHORT:h.bind(null,{year:\"2-digit\"}),CURRENT_MONTH:h.bind(null,{month:\"numeric\"}),CURRENT_MONTH_NAME:h.bind(null,{month:\"long\"}),CURRENT_MONTH_NAME_SHORT:h.bind(null,{month:\"short\"}),CURRENT_DATE:h.bind(null,{day:\"2-digit\"}),CURRENT_DAY_NAME:h.bind(null,{weekday:\"long\"}),CURRENT_DAY_NAME_SHORT:h.bind(null,{weekday:\"short\"}),CURRENT_HOUR:h.bind(null,{hour:\"2-digit\",hour12:!1}),CURRENT_MINUTE:h.bind(null,{minute:\"2-digit\"}),CURRENT_SECOND:h.bind(null,{second:\"2-digit\"})};c.SELECTED_TEXT=c.SELECTION;var p=function(){this.snippetMap={},this.snippetNameMap={}};(function(){r.implement(this,i),this.getTokenizer=function(){return p.$tokenizer||this.createTokenizer()},this.createTokenizer=function(){function e(e){return e=e.substr(1),/^\\d+$/.test(e)?[{tabstopId:parseInt(e,10)}]:[{text:e}]}function t(e){return\"(?:[^\\\\\\\\\"+e+\"]|\\\\\\\\.)\"}var n={regex:\"/(\"+t(\"/\")+\"+)/\",onMatch:function(e,t,n){var r=n[0];return r.fmtString=!0,r.guard=e.slice(1,-1),r.flag=\"\",\"\"},next:\"formatString\"};return p.$tokenizer=new f({start:[{regex:/\\\\./,onMatch:function(e,t,n){var r=e[1];return r==\"}\"&&n.length?e=r:\"`$\\\\\".indexOf(r)!=-1&&(e=r),[e]}},{regex:/}/,onMatch:function(e,t,n){return[n.length?n.shift():e]}},{regex:/\\$(?:\\d+|\\w+)/,onMatch:e},{regex:/\\$\\{[\\dA-Z_a-z]+/,onMatch:function(t,n,r){var i=e(t.substr(1));return r.unshift(i[0]),i},next:\"snippetVar\"},{regex:/\\n/,token:\"newline\",merge:!1}],snippetVar:[{regex:\"\\\\|\"+t(\"\\\\|\")+\"*\\\\|\",onMatch:function(e,t,n){var r=e.slice(1,-1).replace(/\\\\[,|\\\\]|,/g,function(e){return e.length==2?e[1]:\"\\0\"}).split(\"\\0\");return n[0].choices=r,[r[0]]},next:\"start\"},n,{regex:\"([^:}\\\\\\\\]|\\\\\\\\.)*:?\",token:\"\",next:\"start\"}],formatString:[{regex:/:/,onMatch:function(e,t,n){return n.length&&n[0].expectElse?(n[0].expectElse=!1,n[0].ifEnd={elseEnd:n[0]},[n[0].ifEnd]):\":\"}},{regex:/\\\\./,onMatch:function(e,t,n){var r=e[1];return r==\"}\"&&n.length?e=r:\"`$\\\\\".indexOf(r)!=-1?e=r:r==\"n\"?e=\"\\n\":r==\"t\"?e=\"\t\":\"ulULE\".indexOf(r)!=-1&&(e={changeCase:r,local:r>\"a\"}),[e]}},{regex:\"/\\\\w*}\",onMatch:function(e,t,n){var r=n.shift();return r&&(r.flag=e.slice(1,-1)),this.next=r&&r.tabstopId?\"start\":\"\",[r||e]},next:\"start\"},{regex:/\\$(?:\\d+|\\w+)/,onMatch:function(e,t,n){return[{text:e.slice(1)}]}},{regex:/\\${\\w+/,onMatch:function(e,t,n){var r={text:e.slice(2)};return n.unshift(r),[r]},next:\"formatStringVar\"},{regex:/\\n/,token:\"newline\",merge:!1},{regex:/}/,onMatch:function(e,t,n){var r=n.shift();return this.next=r&&r.tabstopId?\"start\":\"\",[r||e]},next:\"start\"}],formatStringVar:[{regex:/:\\/\\w+}/,onMatch:function(e,t,n){var r=n[0];return r.formatFunction=e.slice(2,-1),[n.shift()]},next:\"formatString\"},n,{regex:/:[\\?\\-+]?/,onMatch:function(e,t,n){e[1]==\"+\"&&(n[0].ifEnd=n[0]),e[1]==\"?\"&&(n[0].expectElse=!0)},next:\"formatString\"},{regex:\"([^:}\\\\\\\\]|\\\\\\\\.)*:?\",token:\"\",next:\"formatString\"}]}),p.$tokenizer},this.tokenizeTmSnippet=function(e,t){return this.getTokenizer().getLineTokens(e,t).tokens.map(function(e){return e.value||e})},this.getVariableValue=function(e,t,n){if(/^\\d+$/.test(t))return(this.variables.__||{})[t]||\"\";if(/^[A-Z]\\d+$/.test(t))return(this.variables[t[0]+\"__\"]||{})[t.substr(1)]||\"\";t=t.replace(/^TM_/,\"\");if(!this.variables.hasOwnProperty(t))return\"\";var r=this.variables[t];return typeof r==\"function\"&&(r=this.variables[t](e,t,n)),r==null?\"\":r},this.variables=c,this.tmStrFormat=function(e,t,n){if(!t.fmt)return e;var r=t.flag||\"\",i=t.guard;i=new RegExp(i,r.replace(/[^gim]/g,\"\"));var s=typeof t.fmt==\"string\"?this.tokenizeTmSnippet(t.fmt,\"formatString\"):t.fmt,o=this,u=e.replace(i,function(){var e=o.variables.__;o.variables.__=[].slice.call(arguments);var t=o.resolveVariables(s,n),r=\"E\";for(var i=0;i<t.length;i++){var u=t[i];if(typeof u==\"object\"){t[i]=\"\";if(u.changeCase&&u.local){var a=t[i+1];a&&typeof a==\"string\"&&(u.changeCase==\"u\"?t[i]=a[0].toUpperCase():t[i]=a[0].toLowerCase(),t[i+1]=a.substr(1))}else u.changeCase&&(r=u.changeCase)}else r==\"U\"?t[i]=u.toUpperCase():r==\"L\"&&(t[i]=u.toLowerCase())}return o.variables.__=e,t.join(\"\")});return u},this.tmFormatFunction=function(e,t,n){return t.formatFunction==\"upcase\"?e.toUpperCase():t.formatFunction==\"downcase\"?e.toLowerCase():e},this.resolveVariables=function(e,t){function f(t){var n=e.indexOf(t,s+1);n!=-1&&(s=n)}var n=[],r=\"\",i=!0;for(var s=0;s<e.length;s++){var o=e[s];if(typeof o==\"string\"){n.push(o),o==\"\\n\"?(i=!0,r=\"\"):i&&(r=/^\\t*/.exec(o)[0],i=/\\S/.test(o));continue}if(!o)continue;i=!1;if(o.fmtString){var u=e.indexOf(o,s+1);u==-1&&(u=e.length),o.fmt=e.slice(s+1,u),s=u}if(o.text){var a=this.getVariableValue(t,o.text,r)+\"\";o.fmtString&&(a=this.tmStrFormat(a,o,t)),o.formatFunction&&(a=this.tmFormatFunction(a,o,t)),a&&!o.ifEnd?(n.push(a),f(o)):!a&&o.ifEnd&&f(o.ifEnd)}else o.elseEnd?f(o.elseEnd):o.tabstopId!=null?n.push(o):o.changeCase!=null&&n.push(o)}return n},this.insertSnippetForSelection=function(e,t){function f(e){var t=[];for(var n=0;n<e.length;n++){var r=e[n];if(typeof r==\"object\"){if(a[r.tabstopId])continue;var i=e.lastIndexOf(r,n-1);r=t[i]||{tabstopId:r.tabstopId}}t[n]=r}return t}var n=e.getCursorPosition(),r=e.session.getLine(n.row),i=e.session.getTabString(),s=r.match(/^\\s*/)[0];n.column<s.length&&(s=s.slice(0,n.column)),t=t.replace(/\\r/g,\"\");var o=this.tokenizeTmSnippet(t);o=this.resolveVariables(o,e),o=o.map(function(e){return e==\"\\n\"?e+s:typeof e==\"string\"?e.replace(/\\t/g,i):e});var u=[];o.forEach(function(e,t){if(typeof e!=\"object\")return;var n=e.tabstopId,r=u[n];r||(r=u[n]=[],r.index=n,r.value=\"\",r.parents={});if(r.indexOf(e)!==-1)return;e.choices&&!r.choices&&(r.choices=e.choices),r.push(e);var i=o.indexOf(e,t+1);if(i===-1)return;var s=o.slice(t+1,i),a=s.some(function(e){return typeof e==\"object\"});a&&!r.value?r.value=s:s.length&&(!r.value||typeof r.value!=\"string\")&&(r.value=s.join(\"\"))}),u.forEach(function(e){e.length=0});var a={};for(var l=0;l<o.length;l++){var c=o[l];if(typeof c!=\"object\")continue;var h=c.tabstopId,p=u[h],v=o.indexOf(c,l+1);if(a[h]){a[h]===c&&(delete a[h],Object.keys(a).forEach(function(e){p.parents[e]=!0}));continue}a[h]=c;var m=p.value;typeof m!=\"string\"?m=f(m):c.fmt&&(m=this.tmStrFormat(m,c,e)),o.splice.apply(o,[l+1,Math.max(0,v-l)].concat(m,c)),p.indexOf(c)===-1&&p.push(c)}var g=0,y=0,b=\"\";o.forEach(function(e){if(typeof e==\"string\"){var t=e.split(\"\\n\");t.length>1?(y=t[t.length-1].length,g+=t.length-1):y+=e.length,b+=e}else e&&(e.start?e.end={row:g,column:y}:e.start={row:g,column:y})});var w=e.getSelectionRange(),E=e.session.replace(w,b),S=new d(e),x=e.inVirtualSelectionMode&&e.selection.index;S.addTabstops(u,w.start,E,x)},this.insertSnippet=function(e,t){var n=this;if(e.inVirtualSelectionMode)return n.insertSnippetForSelection(e,t);e.forEachSelection(function(){n.insertSnippetForSelection(e,t)},null,{keepOrder:!0}),e.tabstopManager&&e.tabstopManager.tabNext()},this.$getScope=function(e){var t=e.session.$mode.$id||\"\";t=t.split(\"/\").pop();if(t===\"html\"||t===\"php\"){t===\"php\"&&!e.session.$mode.inlinePhp&&(t=\"html\");var n=e.getCursorPosition(),r=e.session.getState(n.row);typeof r==\"object\"&&(r=r[0]),r.substring&&(r.substring(0,3)==\"js-\"?t=\"javascript\":r.substring(0,4)==\"css-\"?t=\"css\":r.substring(0,4)==\"php-\"&&(t=\"php\"))}return t},this.getActiveScopes=function(e){var t=this.$getScope(e),n=[t],r=this.snippetMap;return r[t]&&r[t].includeScopes&&n.push.apply(n,r[t].includeScopes),n.push(\"_\"),n},this.expandWithTab=function(e,t){var n=this,r=e.forEachSelection(function(){return n.expandSnippetForSelection(e,t)},null,{keepOrder:!0});return r&&e.tabstopManager&&e.tabstopManager.tabNext(),r},this.expandSnippetForSelection=function(e,t){var n=e.getCursorPosition(),r=e.session.getLine(n.row),i=r.substring(0,n.column),s=r.substr(n.column),o=this.snippetMap,u;return this.getActiveScopes(e).some(function(e){var t=o[e];return t&&(u=this.findMatchingSnippet(t,i,s)),!!u},this),u?t&&t.dryRun?!0:(e.session.doc.removeInLine(n.row,n.column-u.replaceBefore.length,n.column+u.replaceAfter.length),this.variables.M__=u.matchBefore,this.variables.T__=u.matchAfter,this.insertSnippetForSelection(e,u.content),this.variables.M__=this.variables.T__=null,!0):!1},this.findMatchingSnippet=function(e,t,n){for(var r=e.length;r--;){var i=e[r];if(i.startRe&&!i.startRe.test(t))continue;if(i.endRe&&!i.endRe.test(n))continue;if(!i.startRe&&!i.endRe)continue;return i.matchBefore=i.startRe?i.startRe.exec(t):[\"\"],i.matchAfter=i.endRe?i.endRe.exec(n):[\"\"],i.replaceBefore=i.triggerRe?i.triggerRe.exec(t)[0]:\"\",i.replaceAfter=i.endTriggerRe?i.endTriggerRe.exec(n)[0]:\"\",i}},this.snippetMap={},this.snippetNameMap={},this.register=function(e,t){function o(e){return e&&!/^\\^?\\(.*\\)\\$?$|^\\\\b$/.test(e)&&(e=\"(?:\"+e+\")\"),e||\"\"}function u(e,t,n){return e=o(e),t=o(t),n?(e=t+e,e&&e[e.length-1]!=\"$\"&&(e+=\"$\")):(e+=t,e&&e[0]!=\"^\"&&(e=\"^\"+e)),new RegExp(e)}function a(e){e.scope||(e.scope=t||\"_\"),t=e.scope,n[t]||(n[t]=[],r[t]={});var o=r[t];if(e.name){var a=o[e.name];a&&i.unregister(a),o[e.name]=e}n[t].push(e),e.tabTrigger&&!e.trigger&&(!e.guard&&/^\\w/.test(e.tabTrigger)&&(e.guard=\"\\\\b\"),e.trigger=s.escapeRegExp(e.tabTrigger));if(!e.trigger&&!e.guard&&!e.endTrigger&&!e.endGuard)return;e.startRe=u(e.trigger,e.guard,!0),e.triggerRe=new RegExp(e.trigger),e.endRe=u(e.endTrigger,e.endGuard,!0),e.endTriggerRe=new RegExp(e.endTrigger)}var n=this.snippetMap,r=this.snippetNameMap,i=this;e||(e=[]),e&&e.content?a(e):Array.isArray(e)&&e.forEach(a),this._signal(\"registerSnippets\",{scope:t})},this.unregister=function(e,t){function i(e){var i=r[e.scope||t];if(i&&i[e.name]){delete i[e.name];var s=n[e.scope||t],o=s&&s.indexOf(e);o>=0&&s.splice(o,1)}}var n=this.snippetMap,r=this.snippetNameMap;e.content?i(e):Array.isArray(e)&&e.forEach(i)},this.parseSnippetFile=function(e){e=e.replace(/\\r/g,\"\");var t=[],n={},r=/^#.*|^({[\\s\\S]*})\\s*$|^(\\S+) (.*)$|^((?:\\n*\\t.*)+)/gm,i;while(i=r.exec(e)){if(i[1])try{n=JSON.parse(i[1]),t.push(n)}catch(s){}if(i[4])n.content=i[4].replace(/^\\t/gm,\"\"),t.push(n),n={};else{var o=i[2],u=i[3];if(o==\"regex\"){var a=/\\/((?:[^\\/\\\\]|\\\\.)*)|$/g;n.guard=a.exec(u)[1],n.trigger=a.exec(u)[1],n.endTrigger=a.exec(u)[1],n.endGuard=a.exec(u)[1]}else o==\"snippet\"?(n.tabTrigger=u.match(/^\\S*/)[0],n.name||(n.name=u)):n[o]=u}}return t},this.getSnippetByName=function(e,t){var n=this.snippetNameMap,r;return this.getActiveScopes(t).some(function(t){var i=n[t];return i&&(r=i[e]),!!r},this),r}}).call(p.prototype);var d=function(e){if(e.tabstopManager)return e.tabstopManager;e.tabstopManager=this,this.$onChange=this.onChange.bind(this),this.$onChangeSelection=s.delayedCall(this.onChangeSelection.bind(this)).schedule,this.$onChangeSession=this.onChangeSession.bind(this),this.$onAfterExec=this.onAfterExec.bind(this),this.attach(e)};(function(){this.attach=function(e){this.index=0,this.ranges=[],this.tabstops=[],this.$openTabstops=null,this.selectedTabstop=null,this.editor=e,this.editor.on(\"change\",this.$onChange),this.editor.on(\"changeSelection\",this.$onChangeSelection),this.editor.on(\"changeSession\",this.$onChangeSession),this.editor.commands.on(\"afterExec\",this.$onAfterExec),this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)},this.detach=function(){this.tabstops.forEach(this.removeTabstopMarkers,this),this.ranges=null,this.tabstops=null,this.selectedTabstop=null,this.editor.removeListener(\"change\",this.$onChange),this.editor.removeListener(\"changeSelection\",this.$onChangeSelection),this.editor.removeListener(\"changeSession\",this.$onChangeSession),this.editor.commands.removeListener(\"afterExec\",this.$onAfterExec),this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler),this.editor.tabstopManager=null,this.editor=null},this.onChange=function(e){var t=e.action[0]==\"r\",n=this.selectedTabstop&&this.selectedTabstop.parents||{},r=(this.tabstops||[]).slice();for(var i=0;i<r.length;i++){var s=r[i],o=s==this.selectedTabstop||n[s.index];s.rangeList.$bias=o?0:1;if(e.action==\"remove\"&&s!==this.selectedTabstop){var u=s.parents&&s.parents[this.selectedTabstop.index],a=s.rangeList.pointIndex(e.start,u);a=a<0?-a-1:a+1;var f=s.rangeList.pointIndex(e.end,u);f=f<0?-f-1:f-1;var l=s.rangeList.ranges.slice(a,f);for(var c=0;c<l.length;c++)this.removeRange(l[c])}s.rangeList.$onChange(e)}var h=this.editor.session;!this.$inChange&&t&&h.getLength()==1&&!h.getValue()&&this.detach()},this.updateLinkedFields=function(){var e=this.selectedTabstop;if(!e||!e.hasLinkedRanges||!e.firstNonLinked)return;this.$inChange=!0;var n=this.editor.session,r=n.getTextRange(e.firstNonLinked);for(var i=0;i<e.length;i++){var s=e[i];if(!s.linked)continue;var o=s.original,u=t.snippetManager.tmStrFormat(r,o,this.editor);n.replace(s,u)}this.$inChange=!1},this.onAfterExec=function(e){e.command&&!e.command.readOnly&&this.updateLinkedFields()},this.onChangeSelection=function(){if(!this.editor)return;var e=this.editor.selection.lead,t=this.editor.selection.anchor,n=this.editor.selection.isEmpty();for(var r=0;r<this.ranges.length;r++){if(this.ranges[r].linked)continue;var i=this.ranges[r].contains(e.row,e.column),s=n||this.ranges[r].contains(t.row,t.column);if(i&&s)return}this.detach()},this.onChangeSession=function(){this.detach()},this.tabNext=function(e){var t=this.tabstops.length,n=this.index+(e||1);n=Math.min(Math.max(n,1),t),n==t&&(n=0),this.selectTabstop(n),n===0&&this.detach()},this.selectTabstop=function(e){this.$openTabstops=null;var t=this.tabstops[this.index];t&&this.addTabstopMarkers(t),this.index=e,t=this.tabstops[this.index];if(!t||!t.length)return;this.selectedTabstop=t;var n=t.firstNonLinked||t;if(!this.editor.inVirtualSelectionMode){var r=this.editor.multiSelect;r.toSingleRange(n.clone());for(var i=0;i<t.length;i++){if(t.hasLinkedRanges&&t[i].linked)continue;r.addRange(t[i].clone(),!0)}r.ranges[0]&&r.addRange(r.ranges[0].clone())}else this.editor.selection.setRange(n);this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler),this.selectedTabstop&&this.selectedTabstop.choices&&this.editor.execCommand(\"startAutocomplete\",{matches:this.selectedTabstop.choices})},this.addTabstops=function(e,t,n){var r=this.useLink||!this.editor.getOption(\"enableMultiselect\");this.$openTabstops||(this.$openTabstops=[]);if(!e[0]){var i=o.fromPoints(n,n);m(i.start,t),m(i.end,t),e[0]=[i],e[0].index=0}var s=this.index,a=[s+1,0],f=this.ranges;e.forEach(function(e,n){var i=this.$openTabstops[n]||e;e.rangeList=new u,e.rangeList.$bias=0;for(var s=0;s<e.length;s++){var l=e[s],c=o.fromPoints(l.start,l.end||l.start);v(c.start,t),v(c.end,t),c.original=l,c.tabstop=i,f.push(c),e.rangeList.ranges.push(c),i!=e?i.unshift(c):i[s]=c,l.fmtString||i.firstNonLinked&&r?(c.linked=!0,i.hasLinkedRanges=!0):i.firstNonLinked||(i.firstNonLinked=c)}i.firstNonLinked||(i.hasLinkedRanges=!1),i===e&&(a.push(i),this.$openTabstops[n]=i),this.addTabstopMarkers(i)},this),a.length>2&&(this.tabstops.length&&a.push(a.splice(2,1)[0]),this.tabstops.splice.apply(this.tabstops,a))},this.addTabstopMarkers=function(e){var t=this.editor.session;e.forEach(function(e){e.markerId||(e.markerId=t.addMarker(e,\"ace_snippet-marker\",\"text\"))})},this.removeTabstopMarkers=function(e){var t=this.editor.session;e.forEach(function(e){t.removeMarker(e.markerId),e.markerId=null})},this.removeRange=function(e){var t=e.tabstop.indexOf(e);t!=-1&&e.tabstop.splice(t,1),t=this.ranges.indexOf(e),t!=-1&&this.ranges.splice(t,1),t=e.tabstop.rangeList.ranges.indexOf(e),t!=-1&&e.tabstop.splice(t,1),this.editor.session.removeMarker(e.markerId),e.tabstop.length||(t=this.tabstops.indexOf(e.tabstop),t!=-1&&this.tabstops.splice(t,1),this.tabstops.length||this.detach())},this.keyboardHandler=new a,this.keyboardHandler.bindKeys({Tab:function(e){if(t.snippetManager&&t.snippetManager.expandWithTab(e))return;e.tabstopManager.tabNext(1)},\"Shift-Tab\":function(e){e.tabstopManager.tabNext(-1)},Esc:function(e){e.tabstopManager.detach()},Return:function(e){return!1}})}).call(d.prototype);var v=function(e,t){e.row==0&&(e.column+=t.column),e.row+=t.row},m=function(e,t){e.row==t.row&&(e.column-=t.column),e.row-=t.row};e(\"./lib/dom\").importCssString(\".ace_snippet-marker {    -moz-box-sizing: border-box;    box-sizing: border-box;    background: rgba(194, 193, 208, 0.09);    border: 1px dotted rgba(211, 208, 235, 0.62);    position: absolute;}\"),t.snippetManager=new p;var g=e(\"./editor\").Editor;(function(){this.insertSnippet=function(e,n){return t.snippetManager.insertSnippet(this,e,n)},this.expandSnippet=function(e){return t.snippetManager.expandWithTab(this,e)}}).call(g.prototype)}),ace.define(\"ace/autocomplete/popup\",[\"require\",\"exports\",\"module\",\"ace/virtual_renderer\",\"ace/editor\",\"ace/range\",\"ace/lib/event\",\"ace/lib/lang\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";var r=e(\"../virtual_renderer\").VirtualRenderer,i=e(\"../editor\").Editor,s=e(\"../range\").Range,o=e(\"../lib/event\"),u=e(\"../lib/lang\"),a=e(\"../lib/dom\"),f=function(e){var t=new r(e);t.$maxLines=4;var n=new i(t);return n.setHighlightActiveLine(!1),n.setShowPrintMargin(!1),n.renderer.setShowGutter(!1),n.renderer.setHighlightGutterLine(!1),n.$mouseHandler.$focusTimeout=0,n.$highlightTagPending=!0,n},l=function(e){var t=a.createElement(\"div\"),n=new f(t);e&&e.appendChild(t),t.style.display=\"none\",n.renderer.content.style.cursor=\"default\",n.renderer.setStyle(\"ace_autocomplete\"),n.setOption(\"displayIndentGuides\",!1),n.setOption(\"dragDelay\",150);var r=function(){};n.focus=r,n.$isFocused=!0,n.renderer.$cursorLayer.restartTimer=r,n.renderer.$cursorLayer.element.style.opacity=0,n.renderer.$maxLines=8,n.renderer.$keepTextAreaAtCursor=!1,n.setHighlightActiveLine(!1),n.session.highlight(\"\"),n.session.$searchHighlight.clazz=\"ace_highlight-marker\",n.on(\"mousedown\",function(e){var t=e.getDocumentPosition();n.selection.moveToPosition(t),c.start.row=c.end.row=t.row,e.stop()});var i,l=new s(-1,0,-1,Infinity),c=new s(-1,0,-1,Infinity);c.id=n.session.addMarker(c,\"ace_active-line\",\"fullLine\"),n.setSelectOnHover=function(e){e?l.id&&(n.session.removeMarker(l.id),l.id=null):l.id=n.session.addMarker(l,\"ace_line-hover\",\"fullLine\")},n.setSelectOnHover(!1),n.on(\"mousemove\",function(e){if(!i){i=e;return}if(i.x==e.x&&i.y==e.y)return;i=e,i.scrollTop=n.renderer.scrollTop;var t=i.getDocumentPosition().row;l.start.row!=t&&(l.id||n.setRow(t),p(t))}),n.renderer.on(\"beforeRender\",function(){if(i&&l.start.row!=-1){i.$pos=null;var e=i.getDocumentPosition().row;l.id||n.setRow(e),p(e,!0)}}),n.renderer.on(\"afterRender\",function(){var e=n.getRow(),t=n.renderer.$textLayer,r=t.element.childNodes[e-t.config.firstRow];r!==t.selectedNode&&t.selectedNode&&a.removeCssClass(t.selectedNode,\"ace_selected\"),t.selectedNode=r,r&&a.addCssClass(r,\"ace_selected\")});var h=function(){p(-1)},p=function(e,t){e!==l.start.row&&(l.start.row=l.end.row=e,t||n.session._emit(\"changeBackMarker\"),n._emit(\"changeHoverMarker\"))};n.getHoveredRow=function(){return l.start.row},o.addListener(n.container,\"mouseout\",h),n.on(\"hide\",h),n.on(\"changeSelection\",h),n.session.doc.getLength=function(){return n.data.length},n.session.doc.getLine=function(e){var t=n.data[e];return typeof t==\"string\"?t:t&&t.value||\"\"};var d=n.session.bgTokenizer;return d.$tokenizeRow=function(e){function s(e,n){e&&r.push({type:(t.className||\"\")+(n||\"\"),value:e})}var t=n.data[e],r=[];if(!t)return r;typeof t==\"string\"&&(t={value:t});var i=t.caption||t.value||t.name,o=i.toLowerCase(),u=(n.filterText||\"\").toLowerCase(),a=0,f=0;for(var l=0;l<=u.length;l++)if(l!=f&&(t.matchMask&1<<l||l==u.length)){var c=u.slice(f,l);f=l;var h=o.indexOf(c,a);if(h==-1)continue;s(i.slice(a,h),\"\"),a=h+c.length,s(i.slice(h,a),\"completion-highlight\")}return s(i.slice(a,i.length),\"\"),t.meta&&r.push({type:\"completion-meta\",value:t.meta}),t.message&&r.push({type:\"completion-message\",value:t.message}),r},d.$updateOnChange=r,d.start=r,n.session.$computeWidth=function(){return this.screenWidth=0},n.isOpen=!1,n.isTopdown=!1,n.autoSelect=!0,n.filterText=\"\",n.data=[],n.setData=function(e,t){n.filterText=t||\"\",n.setValue(u.stringRepeat(\"\\n\",e.length),-1),n.data=e||[],n.setRow(0)},n.getData=function(e){return n.data[e]},n.getRow=function(){return c.start.row},n.setRow=function(e){e=Math.max(this.autoSelect?0:-1,Math.min(this.data.length,e)),c.start.row!=e&&(n.selection.clearSelection(),c.start.row=c.end.row=e||0,n.session._emit(\"changeBackMarker\"),n.moveCursorTo(e||0,0),n.isOpen&&n._signal(\"select\"))},n.on(\"changeSelection\",function(){n.isOpen&&n.setRow(n.selection.lead.row),n.renderer.scrollCursorIntoView()}),n.hide=function(){this.container.style.display=\"none\",this._signal(\"hide\"),n.isOpen=!1},n.show=function(e,t,r){var s=this.container,o=window.innerHeight,u=window.innerWidth,a=this.renderer,f=a.$maxLines*t*1.4,l=e.top+this.$borderSize,c=l>o/2&&!r;c&&l+t+f>o?(a.$maxPixelHeight=l-2*this.$borderSize,s.style.top=\"\",s.style.bottom=o-l+\"px\",n.isTopdown=!1):(l+=t,a.$maxPixelHeight=o-l-.2*t,s.style.top=l+\"px\",s.style.bottom=\"\",n.isTopdown=!0),s.style.display=\"\";var h=e.left;h+s.offsetWidth>u&&(h=u-s.offsetWidth),s.style.left=h+\"px\",this._signal(\"show\"),i=null,n.isOpen=!0},n.goTo=function(e){var t=this.getRow(),n=this.session.getLength()-1;switch(e){case\"up\":t=t<=0?n:t-1;break;case\"down\":t=t>=n?-1:t+1;break;case\"start\":t=0;break;case\"end\":t=n}this.setRow(t)},n.getTextLeftOffset=function(){return this.$borderSize+this.renderer.$padding+this.$imageSize},n.$imageSize=0,n.$borderSize=1,n};a.importCssString(\".ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {    background-color: #CAD6FA;    z-index: 1;}.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {    background-color: #3a674e;}.ace_editor.ace_autocomplete .ace_line-hover {    border: 1px solid #abbffe;    margin-top: -1px;    background: rgba(233,233,253,0.4);    position: absolute;    z-index: 2;}.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {    border: 1px solid rgba(109, 150, 13, 0.8);    background: rgba(58, 103, 78, 0.62);}.ace_completion-meta {    opacity: 0.5;    margin: 0.9em;}.ace_completion-message {    color: blue;}.ace_editor.ace_autocomplete .ace_completion-highlight{    color: #2d69c7;}.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{    color: #93ca12;}.ace_editor.ace_autocomplete {    width: 300px;    z-index: 200000;    border: 1px lightgray solid;    position: fixed;    box-shadow: 2px 3px 5px rgba(0,0,0,.2);    line-height: 1.4;    background: #fefefe;    color: #111;}.ace_dark.ace_editor.ace_autocomplete {    border: 1px #484747 solid;    box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51);    line-height: 1.4;    background: #25282c;    color: #c1c1c1;}\",\"autocompletion.css\"),t.AcePopup=l,t.$singleLineEditor=f}),ace.define(\"ace/autocomplete/util\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";t.parForEach=function(e,t,n){var r=0,i=e.length;i===0&&n();for(var s=0;s<i;s++)t(e[s],function(e,t){r++,r===i&&n(e,t)})};var r=/[a-zA-Z_0-9\\$\\-\\u00A2-\\uFFFF]/;t.retrievePrecedingIdentifier=function(e,t,n){n=n||r;var i=[];for(var s=t-1;s>=0;s--){if(!n.test(e[s]))break;i.push(e[s])}return i.reverse().join(\"\")},t.retrieveFollowingIdentifier=function(e,t,n){n=n||r;var i=[];for(var s=t;s<e.length;s++){if(!n.test(e[s]))break;i.push(e[s])}return i},t.getCompletionPrefix=function(e){var t=e.getCursorPosition(),n=e.session.getLine(t.row),r;return e.completers.forEach(function(e){e.identifierRegexps&&e.identifierRegexps.forEach(function(e){!r&&e&&(r=this.retrievePrecedingIdentifier(n,t.column,e))}.bind(this))}.bind(this)),r||this.retrievePrecedingIdentifier(n,t.column)}}),ace.define(\"ace/autocomplete\",[\"require\",\"exports\",\"module\",\"ace/keyboard/hash_handler\",\"ace/autocomplete/popup\",\"ace/autocomplete/util\",\"ace/lib/lang\",\"ace/lib/dom\",\"ace/snippets\",\"ace/config\"],function(e,t,n){\"use strict\";var r=e(\"./keyboard/hash_handler\").HashHandler,i=e(\"./autocomplete/popup\").AcePopup,s=e(\"./autocomplete/util\"),o=e(\"./lib/lang\"),u=e(\"./lib/dom\"),a=e(\"./snippets\").snippetManager,f=e(\"./config\"),l=function(){this.autoInsert=!1,this.autoSelect=!0,this.exactMatch=!1,this.gatherCompletionsId=0,this.keyboardHandler=new r,this.keyboardHandler.bindKeys(this.commands),this.blurListener=this.blurListener.bind(this),this.changeListener=this.changeListener.bind(this),this.mousedownListener=this.mousedownListener.bind(this),this.mousewheelListener=this.mousewheelListener.bind(this),this.changeTimer=o.delayedCall(function(){this.updateCompletions(!0)}.bind(this)),this.tooltipTimer=o.delayedCall(this.updateDocTooltip.bind(this),50)};(function(){this.$init=function(){return this.popup=new i(document.body||document.documentElement),this.popup.on(\"click\",function(e){this.insertMatch(),e.stop()}.bind(this)),this.popup.focus=this.editor.focus.bind(this.editor),this.popup.on(\"show\",this.tooltipTimer.bind(null,null)),this.popup.on(\"select\",this.tooltipTimer.bind(null,null)),this.popup.on(\"changeHoverMarker\",this.tooltipTimer.bind(null,null)),this.popup},this.getPopup=function(){return this.popup||this.$init()},this.openPopup=function(e,t,n){this.popup||this.$init(),this.popup.autoSelect=this.autoSelect,this.popup.setData(this.completions.filtered,this.completions.filterText),e.keyBinding.addKeyboardHandler(this.keyboardHandler);var r=e.renderer;this.popup.setRow(this.autoSelect?0:-1);if(!n){this.popup.setTheme(e.getTheme()),this.popup.setFontSize(e.getFontSize());var i=r.layerConfig.lineHeight,s=r.$cursorLayer.getPixelPosition(this.base,!0);s.left-=this.popup.getTextLeftOffset();var o=e.container.getBoundingClientRect();s.top+=o.top-r.layerConfig.offset,s.left+=o.left-e.renderer.scrollLeft,s.left+=r.gutterWidth,this.popup.show(s,i)}else n&&!t&&this.detach()},this.detach=function(){this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler),this.editor.off(\"changeSelection\",this.changeListener),this.editor.off(\"blur\",this.blurListener),this.editor.off(\"mousedown\",this.mousedownListener),this.editor.off(\"mousewheel\",this.mousewheelListener),this.changeTimer.cancel(),this.hideDocTooltip(),this.gatherCompletionsId+=1,this.popup&&this.popup.isOpen&&this.popup.hide(),this.base&&this.base.detach(),this.activated=!1,this.completions=this.base=null},this.changeListener=function(e){var t=this.editor.selection.lead;(t.row!=this.base.row||t.column<this.base.column)&&this.detach(),this.activated?this.changeTimer.schedule():this.detach()},this.blurListener=function(e){var t=document.activeElement,n=this.editor.textInput.getElement(),r=e.relatedTarget&&this.tooltipNode&&this.tooltipNode.contains(e.relatedTarget),i=this.popup&&this.popup.container;t!=n&&t.parentNode!=i&&!r&&t!=this.tooltipNode&&e.relatedTarget!=n&&this.detach()},this.mousedownListener=function(e){this.detach()},this.mousewheelListener=function(e){this.detach()},this.goTo=function(e){this.popup.goTo(e)},this.insertMatch=function(e,t){e||(e=this.popup.getData(this.popup.getRow()));if(!e)return!1;if(e.completer&&e.completer.insertMatch)e.completer.insertMatch(this.editor,e);else{if(this.completions.filterText){var n=this.editor.selection.getAllRanges();for(var r=0,i;i=n[r];r++)i.start.column-=this.completions.filterText.length,this.editor.session.remove(i)}e.snippet?a.insertSnippet(this.editor,e.snippet):this.editor.execCommand(\"insertstring\",e.value||e)}this.detach()},this.commands={Up:function(e){e.completer.goTo(\"up\")},Down:function(e){e.completer.goTo(\"down\")},\"Ctrl-Up|Ctrl-Home\":function(e){e.completer.goTo(\"start\")},\"Ctrl-Down|Ctrl-End\":function(e){e.completer.goTo(\"end\")},Esc:function(e){e.completer.detach()},Return:function(e){return e.completer.insertMatch()},\"Shift-Return\":function(e){e.completer.insertMatch(null,{deleteSuffix:!0})},Tab:function(e){var t=e.completer.insertMatch();if(!!t||!!e.tabstopManager)return t;e.completer.goTo(\"down\")},PageUp:function(e){e.completer.popup.gotoPageUp()},PageDown:function(e){e.completer.popup.gotoPageDown()}},this.gatherCompletions=function(e,t){var n=e.getSession(),r=e.getCursorPosition(),i=s.getCompletionPrefix(e);this.base=n.doc.createAnchor(r.row,r.column-i.length),this.base.$insertRight=!0;var o=[],u=e.completers.length;return e.completers.forEach(function(a,f){a.getCompletions(e,n,r,i,function(n,r){!n&&r&&(o=o.concat(r)),t(null,{prefix:s.getCompletionPrefix(e),matches:o,finished:--u===0})})}),!0},this.showPopup=function(e,t){this.editor&&this.detach(),this.activated=!0,this.editor=e,e.completer!=this&&(e.completer&&e.completer.detach(),e.completer=this),e.on(\"changeSelection\",this.changeListener),e.on(\"blur\",this.blurListener),e.on(\"mousedown\",this.mousedownListener),e.on(\"mousewheel\",this.mousewheelListener),this.updateCompletions(!1,t)},this.updateCompletions=function(e,t){if(e&&this.base&&this.completions){var n=this.editor.getCursorPosition(),r=this.editor.session.getTextRange({start:this.base,end:n});if(r==this.completions.filterText)return;this.completions.setFilter(r);if(!this.completions.filtered.length)return this.detach();if(this.completions.filtered.length==1&&this.completions.filtered[0].value==r&&!this.completions.filtered[0].snippet)return this.detach();this.openPopup(this.editor,r,e);return}if(t&&t.matches){var n=this.editor.getSelectionRange().start;return this.base=this.editor.session.doc.createAnchor(n.row,n.column),this.base.$insertRight=!0,this.completions=new c(t.matches),this.openPopup(this.editor,\"\",e)}var i=this.gatherCompletionsId;this.gatherCompletions(this.editor,function(t,n){var r=function(){if(!n.finished)return;return this.detach()}.bind(this),s=n.prefix,o=n&&n.matches;if(!o||!o.length)return r();if(s.indexOf(n.prefix)!==0||i!=this.gatherCompletionsId)return;this.completions=new c(o),this.exactMatch&&(this.completions.exactMatch=!0),this.completions.setFilter(s);var u=this.completions.filtered;if(!u.length)return r();if(u.length==1&&u[0].value==s&&!u[0].snippet)return r();if(this.autoInsert&&u.length==1&&n.finished)return this.insertMatch(u[0]);this.openPopup(this.editor,s,e)}.bind(this))},this.cancelContextMenu=function(){this.editor.$mouseHandler.cancelContextMenu()},this.updateDocTooltip=function(){var e=this.popup,t=e.data,n=t&&(t[e.getHoveredRow()]||t[e.getRow()]),r=null;if(!n||!this.editor||!this.popup.isOpen)return this.hideDocTooltip();this.editor.completers.some(function(e){return e.getDocTooltip&&(r=e.getDocTooltip(n)),r}),!r&&typeof n!=\"string\"&&(r=n),typeof r==\"string\"&&(r={docText:r});if(!r||!r.docHTML&&!r.docText)return this.hideDocTooltip();this.showDocTooltip(r)},this.showDocTooltip=function(e){this.tooltipNode||(this.tooltipNode=u.createElement(\"div\"),this.tooltipNode.className=\"ace_tooltip ace_doc-tooltip\",this.tooltipNode.style.margin=0,this.tooltipNode.style.pointerEvents=\"auto\",this.tooltipNode.tabIndex=-1,this.tooltipNode.onblur=this.blurListener.bind(this),this.tooltipNode.onclick=this.onTooltipClick.bind(this));var t=this.tooltipNode;e.docHTML?t.innerHTML=e.docHTML:e.docText&&(t.textContent=e.docText),t.parentNode||document.body.appendChild(t);var n=this.popup,r=n.container.getBoundingClientRect();t.style.top=n.container.style.top,t.style.bottom=n.container.style.bottom,t.style.display=\"block\",window.innerWidth-r.right<320?r.left<320?n.isTopdown?(t.style.top=r.bottom+\"px\",t.style.left=r.left+\"px\",t.style.right=\"\",t.style.bottom=\"\"):(t.style.top=n.container.offsetTop-t.offsetHeight+\"px\",t.style.left=r.left+\"px\",t.style.right=\"\",t.style.bottom=\"\"):(t.style.right=window.innerWidth-r.left+\"px\",t.style.left=\"\"):(t.style.left=r.right+1+\"px\",t.style.right=\"\")},this.hideDocTooltip=function(){this.tooltipTimer.cancel();if(!this.tooltipNode)return;var e=this.tooltipNode;!this.editor.isFocused()&&document.activeElement==e&&this.editor.focus(),this.tooltipNode=null,e.parentNode&&e.parentNode.removeChild(e)},this.onTooltipClick=function(e){var t=e.target;while(t&&t!=this.tooltipNode){if(t.nodeName==\"A\"&&t.href){t.rel=\"noreferrer\",t.target=\"_blank\";break}t=t.parentNode}},this.destroy=function(){this.detach();if(this.popup){this.popup.destroy();var e=this.popup.container;e&&e.parentNode&&e.parentNode.removeChild(e)}this.editor&&this.editor.completer==this&&this.editor.completer==null,this.popup=null}}).call(l.prototype),l.for=function(e){return e.completer?e.completer:(f.get(\"sharedPopups\")?(l.$shared||(l.$sharedInstance=new l),e.completer=l.$sharedInstance):(e.completer=new l,e.once(\"destroy\",function(e,t){t.completer.destroy()})),e.completer)},l.startCommand={name:\"startAutocomplete\",exec:function(e,t){var n=l.for(e);n.autoInsert=!1,n.autoSelect=!0,n.showPopup(e,t),n.cancelContextMenu()},bindKey:\"Ctrl-Space|Ctrl-Shift-Space|Alt-Space\"};var c=function(e,t){this.all=e,this.filtered=e,this.filterText=t||\"\",this.exactMatch=!1};(function(){this.setFilter=function(e){if(e.length>this.filterText&&e.lastIndexOf(this.filterText,0)===0)var t=this.filtered;else var t=this.all;this.filterText=e,t=this.filterCompletions(t,this.filterText),t=t.sort(function(e,t){return t.exactMatch-e.exactMatch||t.$score-e.$score||(e.caption||e.value).localeCompare(t.caption||t.value)});var n=null;t=t.filter(function(e){var t=e.snippet||e.caption||e.value;return t===n?!1:(n=t,!0)}),this.filtered=t},this.filterCompletions=function(e,t){var n=[],r=t.toUpperCase(),i=t.toLowerCase();e:for(var s=0,o;o=e[s];s++){var u=o.caption||o.value||o.snippet;if(!u)continue;var a=-1,f=0,l=0,c,h;if(this.exactMatch){if(t!==u.substr(0,t.length))continue e}else{var p=u.toLowerCase().indexOf(i);if(p>-1)l=p;else for(var d=0;d<t.length;d++){var v=u.indexOf(i[d],a+1),m=u.indexOf(r[d],a+1);c=v>=0?m<0||v<m?v:m:m;if(c<0)continue e;h=c-a-1,h>0&&(a===-1&&(l+=10),l+=h,f|=1<<d),a=c}}o.matchMask=f,o.exactMatch=l?0:1,o.$score=(o.score||0)-l,n.push(o)}return n}}).call(c.prototype),t.Autocomplete=l,t.FilteredList=c}),ace.define(\"ace/autocomplete/text_completer\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){function s(e,t){var n=e.getTextRange(r.fromPoints({row:0,column:0},t));return n.split(i).length-1}function o(e,t){var n=s(e,t),r=e.getValue().split(i),o=Object.create(null),u=r[n];return r.forEach(function(e,t){if(!e||e===u)return;var i=Math.abs(n-t),s=r.length-i;o[e]?o[e]=Math.max(s,o[e]):o[e]=s}),o}var r=e(\"../range\").Range,i=/[^a-zA-Z_0-9\\$\\-\\u00C0-\\u1FFF\\u2C00-\\uD7FF\\w]+/;t.getCompletions=function(e,t,n,r,i){var s=o(t,n),u=Object.keys(s);i(null,u.map(function(e){return{caption:e,value:e,score:s[e],meta:\"local\"}}))}}),ace.define(\"ace/ext/language_tools\",[\"require\",\"exports\",\"module\",\"ace/snippets\",\"ace/autocomplete\",\"ace/config\",\"ace/lib/lang\",\"ace/autocomplete/util\",\"ace/autocomplete/text_completer\",\"ace/editor\",\"ace/config\"],function(e,t,n){\"use strict\";var r=e(\"../snippets\").snippetManager,i=e(\"../autocomplete\").Autocomplete,s=e(\"../config\"),o=e(\"../lib/lang\"),u=e(\"../autocomplete/util\"),a=e(\"../autocomplete/text_completer\"),f={getCompletions:function(e,t,n,r,i){if(t.$mode.completer)return t.$mode.completer.getCompletions(e,t,n,r,i);var s=e.session.getState(n.row),o=t.$mode.getCompletions(s,t,n,r);i(null,o)}},l={getCompletions:function(e,t,n,i,s){var o=[],u=t.getTokenAt(n.row,n.column);u&&u.type.match(/(tag-name|tag-open|tag-whitespace|attribute-name|attribute-value)\\.xml$/)?o.push(\"html-tag\"):o=r.getActiveScopes(e);var a=r.snippetMap,f=[];o.forEach(function(e){var t=a[e]||[];for(var n=t.length;n--;){var r=t[n],i=r.name||r.tabTrigger;if(!i)continue;f.push({caption:i,snippet:r.content,meta:r.tabTrigger&&!r.name?r.tabTrigger+\"\\u21e5 \":\"snippet\",type:\"snippet\"})}},this),s(null,f)},getDocTooltip:function(e){e.type==\"snippet\"&&!e.docHTML&&(e.docHTML=[\"<b>\",o.escapeHTML(e.caption),\"</b>\",\"<hr></hr>\",o.escapeHTML(e.snippet)].join(\"\"))}},c=[l,a,f];t.setCompleters=function(e){c.length=0,e&&c.push.apply(c,e)},t.addCompleter=function(e){c.push(e)},t.textCompleter=a,t.keyWordCompleter=f,t.snippetCompleter=l;var h={name:\"expandSnippet\",exec:function(e){return r.expandWithTab(e)},bindKey:\"Tab\"},p=function(e,t){d(t.session.$mode)},d=function(e){var t=e.$id;r.files||(r.files={}),v(t),e.modes&&e.modes.forEach(d)},v=function(e){if(!e||r.files[e])return;var t=e.replace(\"mode\",\"snippets\");r.files[e]={},s.loadModule(t,function(t){t&&(r.files[e]=t,!t.snippets&&t.snippetText&&(t.snippets=r.parseSnippetFile(t.snippetText)),r.register(t.snippets||[],t.scope),t.includeScopes&&(r.snippetMap[t.scope].includeScopes=t.includeScopes,t.includeScopes.forEach(function(e){v(\"ace/mode/\"+e)})))})},m=function(e){var t=e.editor,n=t.completer&&t.completer.activated;if(e.command.name===\"backspace\")n&&!u.getCompletionPrefix(t)&&t.completer.detach();else if(e.command.name===\"insertstring\"){var r=u.getCompletionPrefix(t);if(r&&!n){var s=i.for(t);s.autoInsert=!1,s.showPopup(t)}}},g=e(\"../editor\").Editor;e(\"../config\").defineOptions(g.prototype,\"editor\",{enableBasicAutocompletion:{set:function(e){e?(this.completers||(this.completers=Array.isArray(e)?e:c),this.commands.addCommand(i.startCommand)):this.commands.removeCommand(i.startCommand)},value:!1},enableLiveAutocompletion:{set:function(e){e?(this.completers||(this.completers=Array.isArray(e)?e:c),this.commands.on(\"afterExec\",m)):this.commands.removeListener(\"afterExec\",m)},value:!1},enableSnippets:{set:function(e){e?(this.commands.addCommand(h),this.on(\"changeMode\",p),p(null,this)):(this.commands.removeCommand(h),this.off(\"changeMode\",p))},value:!1}})});                (function() {\n    ace.require([\"ace/ext/language_tools\"], function(m) {\n        if (typeof module == \"object\" && typeof exports == \"object\" && module) {\n            module.exports = m;\n        }\n    });\n})();\n            "
  },
  {
    "path": "static/js/jquery.js",
    "content": "/*! jQuery v2.1.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */\n!function(a,b){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error(\"jQuery requires a window with a document\");return b(a)}:b(a)}(\"undefined\"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m=\"2.1.1\",n=function(a,b){return new n.fn.init(a,b)},o=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,p=/^-ms-/,q=/-([\\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:\"\",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for(\"boolean\"==typeof g&&(j=g,g=arguments[h]||{},h++),\"object\"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:\"jQuery\"+(m+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return\"function\"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return\"object\"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,\"isPrototypeOf\")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+\"\":\"object\"==typeof a||\"function\"==typeof a?h[i.call(a)]||\"object\":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf(\"use strict\")?(b=l.createElement(\"script\"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,\"ms-\").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?\"\":(a+\"\").replace(o,\"\")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,\"string\"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return\"string\"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"),function(a,b){h[\"[object \"+b+\"]\"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return\"function\"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:\"array\"===c||0===b||\"number\"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u=\"sizzle\"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C=\"undefined\",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",M=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",N=\"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",O=N.replace(\"w\",\"w#\"),P=\"\\\\[\"+M+\"*(\"+N+\")(?:\"+M+\"*([*^$|!~]?=)\"+M+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+O+\"))|)\"+M+\"*\\\\]\",Q=\":(\"+N+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+P+\")*)|.*)\\\\)|)\",R=new RegExp(\"^\"+M+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+M+\"+$\",\"g\"),S=new RegExp(\"^\"+M+\"*,\"+M+\"*\"),T=new RegExp(\"^\"+M+\"*([>+~]|\"+M+\")\"+M+\"*\"),U=new RegExp(\"=\"+M+\"*([^\\\\]'\\\"]*?)\"+M+\"*\\\\]\",\"g\"),V=new RegExp(Q),W=new RegExp(\"^\"+O+\"$\"),X={ID:new RegExp(\"^#(\"+N+\")\"),CLASS:new RegExp(\"^\\\\.(\"+N+\")\"),TAG:new RegExp(\"^(\"+N.replace(\"w\",\"w*\")+\")\"),ATTR:new RegExp(\"^\"+P),PSEUDO:new RegExp(\"^\"+Q),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+M+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+M+\"*(?:([+-]|)\"+M+\"*(\\\\d+)|))\"+M+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+L+\")$\",\"i\"),needsContext:new RegExp(\"^\"+M+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+M+\"*((?:-\\\\d)?\\\\d*)\"+M+\"*\\\\)|)(?=[^-]|$)\",\"i\")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\\d$/i,$=/^[^{]+\\{\\s*\\[native \\w/,_=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ab=/[+~]/,bb=/'|\\\\/g,cb=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+M+\"?|(\"+M+\")|.)\",\"ig\"),db=function(a,b,c){var d=\"0x\"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||\"string\"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&\"object\"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute(\"id\"))?s=r.replace(bb,\"\\\\$&\"):b.setAttribute(\"id\",s),s=\"[id='\"+s+\"'] \",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(\",\")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute(\"id\")}}}return i(a.replace(R,\"$1\"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+\" \")>d.cacheLength&&delete b[a.shift()],b[c+\" \"]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement(\"div\");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split(\"|\"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return\"input\"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return(\"input\"===c||\"button\"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?\"HTML\"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener(\"unload\",function(){m()},!1):g.attachEvent&&g.attachEvent(\"onunload\",function(){m()})),c.attributes=ib(function(a){return a.className=\"i\",!a.getAttribute(\"className\")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment(\"\")),!a.getElementsByTagName(\"*\").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML=\"<div class='a'></div><div class='a i'></div>\",a.firstChild.className=\"i\",2===a.getElementsByClassName(\"i\").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute(\"id\")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode(\"id\");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if(\"*\"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML=\"<select msallowclip=''><option selected=''></option></select>\",a.querySelectorAll(\"[msallowclip^='']\").length&&q.push(\"[*^$]=\"+M+\"*(?:''|\\\"\\\")\"),a.querySelectorAll(\"[selected]\").length||q.push(\"\\\\[\"+M+\"*(?:value|\"+L+\")\"),a.querySelectorAll(\":checked\").length||q.push(\":checked\")}),ib(function(a){var b=e.createElement(\"input\");b.setAttribute(\"type\",\"hidden\"),a.appendChild(b).setAttribute(\"name\",\"D\"),a.querySelectorAll(\"[name=d]\").length&&q.push(\"name\"+M+\"*[*^$|!~]?=\"),a.querySelectorAll(\":enabled\").length||q.push(\":enabled\",\":disabled\"),a.querySelectorAll(\"*,:x\"),q.push(\",.*:\")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,\"div\"),s.call(a,\"[s!='']:x\"),r.push(\"!=\",Q)}),q=q.length&&new RegExp(q.join(\"|\")),r=r.length&&new RegExp(r.join(\"|\")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,\"='$1']\"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error(\"Syntax error, unrecognized expression: \"+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c=\"\",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if(\"string\"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||\"\").replace(cb,db),\"~=\"===a[2]&&(a[3]=\" \"+a[3]+\" \"),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),\"nth\"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*(\"even\"===a[3]||\"odd\"===a[3])),a[5]=+(a[7]+a[8]||\"odd\"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||\"\":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(\")\",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return\"*\"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+\" \"];return b||(b=new RegExp(\"(^|\"+M+\")\"+a+\"(\"+M+\"|$)\"))&&y(a,function(a){return b.test(\"string\"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute(\"class\")||\"\")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?\"!=\"===b:b?(e+=\"\",\"=\"===b?e===c:\"!=\"===b?e!==c:\"^=\"===b?c&&0===e.indexOf(c):\"*=\"===b?c&&e.indexOf(c)>-1:\"$=\"===b?c&&e.slice(-c.length)===c:\"~=\"===b?(\" \"+e+\" \").indexOf(c)>-1:\"|=\"===b?e===c||e.slice(0,c.length+1)===c+\"-\":!1):!0}},CHILD:function(a,b,c,d,e){var f=\"nth\"!==a.slice(0,3),g=\"last\"!==a.slice(-4),h=\"of-type\"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?\"nextSibling\":\"previousSibling\",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p=\"only\"===a&&!o&&\"nextSibling\"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error(\"unsupported pseudo: \"+a);return e[u]?e(b):e.length>1?(c=[a,a,\"\",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,\"$1\"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||\"\")||fb.error(\"unsupported lang: \"+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute(\"xml:lang\")||b.getAttribute(\"lang\"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+\"-\");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&!!a.checked||\"option\"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&\"button\"===a.type||\"button\"===b},text:function(a){var b;return\"input\"===a.nodeName.toLowerCase()&&\"text\"===a.type&&(null==(b=a.getAttribute(\"type\"))||\"text\"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=lb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=mb(b);function pb(){}pb.prototype=d.filters=d.pseudos,d.setFilters=new pb,g=fb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+\" \"];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R,\" \")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fb.error(a):z(a,i).slice(0)};function qb(a){for(var b=0,c=a.length,d=\"\";c>b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&\"parentNode\"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||\"*\",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[\" \"],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:\" \"===a[i-2].type?\"*\":\"\"})).replace(R,\"$1\"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q=\"0\",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG(\"*\",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+\" \"];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n=\"function\"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&\"ID\"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split(\"\").sort(B).join(\"\")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement(\"div\"))}),ib(function(a){return a.innerHTML=\"<a href='#'></a>\",\"#\"===a.firstChild.getAttribute(\"href\")})||jb(\"type|href|height|width\",function(a,b,c){return c?void 0:a.getAttribute(b,\"type\"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML=\"<input/>\",a.firstChild.setAttribute(\"value\",\"\"),\"\"===a.firstChild.getAttribute(\"value\")})||jb(\"value\",function(a,b,c){return c||\"input\"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute(\"disabled\")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);n.find=t,n.expr=t.selectors,n.expr[\":\"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,w=/^.[^:#\\[\\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if(\"string\"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=\":not(\"+a+\")\"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if(\"string\"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+\" \"+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,\"string\"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if(\"string\"==typeof a){if(c=\"<\"===a[0]&&\">\"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?\"undefined\"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||\"string\"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?\"string\"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,\"parentNode\")},parentsUntil:function(a,b,c){return n.dir(a,\"parentNode\",c)},next:function(a){return D(a,\"nextSibling\")},prev:function(a){return D(a,\"previousSibling\")},nextAll:function(a){return n.dir(a,\"nextSibling\")},prevAll:function(a){return n.dir(a,\"previousSibling\")},nextUntil:function(a,b,c){return n.dir(a,\"nextSibling\",c)},prevUntil:function(a,b,c){return n.dir(a,\"previousSibling\",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return\"Until\"!==a.slice(-5)&&(d=c),d&&\"string\"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a=\"string\"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);\"function\"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&\"string\"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[[\"resolve\",\"done\",n.Callbacks(\"once memory\"),\"resolved\"],[\"reject\",\"fail\",n.Callbacks(\"once memory\"),\"rejected\"],[\"notify\",\"progress\",n.Callbacks(\"memory\")]],c=\"pending\",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+\"With\"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+\"With\"](this===e?d:this,arguments),this},e[f[0]+\"With\"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler(\"ready\"),n(l).off(\"ready\"))))}});function I(){l.removeEventListener(\"DOMContentLoaded\",I,!1),a.removeEventListener(\"load\",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),\"complete\"===l.readyState?setTimeout(n.ready):(l.addEventListener(\"DOMContentLoaded\",I,!1),a.addEventListener(\"load\",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if(\"object\"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+Math.random()}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if(\"string\"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&\"string\"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d=\"data-\"+b.replace(O,\"-$1\").toLowerCase(),c=a.getAttribute(d),\"string\"==typeof c){try{c=\"true\"===c?!0:\"false\"===c?!1:\"null\"===c?null:+c+\"\"===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)\n},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,\"hasDataAttrs\"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf(\"data-\")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,\"hasDataAttrs\",!0)}return e}return\"object\"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf(\"-\")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||\"fx\")+\"queue\",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||\"fx\";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};\"inprogress\"===e&&(e=c.shift(),d--),e&&(\"fx\"===b&&c.unshift(\"inprogress\"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+\"queueHooks\";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks(\"once memory\").add(function(){L.remove(a,[b+\"queue\",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return\"string\"!=typeof a&&(b=a,a=\"fx\",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),\"fx\"===a&&\"inprogress\"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||\"fx\",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};\"string\"!=typeof a&&(b=a,a=void 0),a=a||\"fx\";while(g--)c=L.get(f[g],a+\"queueHooks\"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,R=[\"Top\",\"Right\",\"Bottom\",\"Left\"],S=function(a,b){return a=b||a,\"none\"===n.css(a,\"display\")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement(\"div\")),c=l.createElement(\"input\");c.setAttribute(\"type\",\"radio\"),c.setAttribute(\"checked\",\"checked\"),c.setAttribute(\"name\",\"t\"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML=\"<textarea>x</textarea>\",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U=\"undefined\";k.focusinBubbles=\"onfocusin\"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||\"\").match(E)||[\"\"],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||\"\").split(\".\").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(\".\")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||\"\").match(E)||[\"\"],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||\"\").split(\".\").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp(\"(^|\\\\.)\"+p.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&(\"**\"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,\"events\"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,\"type\")?b.type:b,r=j.call(b,\"namespace\")?b.namespace.split(\".\"):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(\".\")>=0&&(r=q.split(\".\"),q=r.shift(),r.sort()),k=q.indexOf(\":\")<0&&\"on\"+q,b=b[n.expando]?b:new n.Event(q,\"object\"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join(\".\"),b.namespace_re=b.namespace?new RegExp(\"(^|\\\\.)\"+r.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,\"events\")||{})[b.type]&&L.get(g,\"handle\"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,\"events\")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||\"click\"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||\"click\"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+\" \",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:\"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),fixHooks:{},keyHooks:{props:\"char charCode key keyCode\".split(\" \"),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:\"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:\"focusin\"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:\"focusout\"},click:{trigger:function(){return\"checkbox\"===this.type&&this.click&&n.nodeName(this,\"input\")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,\"a\")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?Z:$):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.focusinBubbles||n.each({focus:\"focusin\",blur:\"focusout\"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if(\"object\"==typeof a){\"string\"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&(\"string\"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+\".\"+d.namespace:d.origType,d.selector,d.handler),this;if(\"object\"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||\"function\"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ab=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,bb=/<([\\w:]+)/,cb=/<|&#?\\w+;/,db=/<(?:script|style|link)/i,eb=/checked\\s*(?:[^=]|=\\s*.checked.)/i,fb=/^$|\\/(?:java|ecma)script/i,gb=/^true\\/(.*)/,hb=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,ib={option:[1,\"<select multiple='multiple'>\",\"</select>\"],thead:[1,\"<table>\",\"</table>\"],col:[2,\"<table><colgroup>\",\"</colgroup></table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:[0,\"\",\"\"]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,\"table\")&&n.nodeName(11!==b.nodeType?b:b.firstChild,\"tr\")?a.getElementsByTagName(\"tbody\")[0]||a.appendChild(a.ownerDocument.createElement(\"tbody\")):a}function kb(a){return a.type=(null!==a.getAttribute(\"type\"))+\"/\"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute(\"type\"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],\"globalEval\",!b||L.get(b[c],\"globalEval\"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||\"*\"):a.querySelectorAll?a.querySelectorAll(b||\"*\"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();\"input\"===c&&T.test(a.type)?b.checked=a.checked:(\"input\"===c||\"textarea\"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,\"script\"),g.length>0&&mb(g,!i&&ob(a,\"script\")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if(\"object\"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement(\"div\")),g=(bb.exec(e)||[\"\",\"\"])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,\"<$1></$2>\")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=\"\"}else l.push(b.createTextNode(e));k.textContent=\"\",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),\"script\"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||\"\")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,\"script\")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent=\"\");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if(\"string\"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||[\"\",\"\"])[1].toLowerCase()]){a=a.replace(ab,\"<$1></$2>\");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&\"string\"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,\"script\"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,\"script\"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||\"\")&&!L.access(h,\"globalEval\")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,\"\")))}return this}}),n.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],\"display\");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),\"none\"!==c&&c||(qb=(qb||n(\"<iframe frameborder='0' width='0' height='0'/>\")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp(\"^(\"+Q+\")(?!px)[a-z%]+$\",\"i\"),wb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(\"\"!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+\"\":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement(\"div\"),f=l.createElement(\"div\");if(f.style){f.style.backgroundClip=\"content-box\",f.cloneNode(!0).style.backgroundClip=\"\",k.clearCloneStyle=\"content-box\"===f.style.backgroundClip,e.style.cssText=\"border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute\",e.appendChild(f);function g(){f.style.cssText=\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute\",f.innerHTML=\"\",d.appendChild(e);var g=a.getComputedStyle(f,null);b=\"1%\"!==g.top,c=\"4px\"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement(\"div\"));return c.style.cssText=f.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0\",c.style.marginRight=c.style.width=\"0\",f.style.width=\"1px\",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp(\"^(\"+Q+\")(.*)$\",\"i\"),Bb=new RegExp(\"^([+-])=(\"+Q+\")\",\"i\"),Cb={position:\"absolute\",visibility:\"hidden\",display:\"block\"},Db={letterSpacing:\"0\",fontWeight:\"400\"},Eb=[\"Webkit\",\"O\",\"Moz\",\"ms\"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||\"px\"):b}function Hb(a,b,c,d,e){for(var f=c===(d?\"border\":\"content\")?4:\"width\"===b?1:0,g=0;4>f;f+=2)\"margin\"===c&&(g+=n.css(a,c+R[f],!0,e)),d?(\"content\"===c&&(g-=n.css(a,\"padding\"+R[f],!0,e)),\"margin\"!==c&&(g-=n.css(a,\"border\"+R[f]+\"Width\",!0,e))):(g+=n.css(a,\"padding\"+R[f],!0,e),\"padding\"!==c&&(g+=n.css(a,\"border\"+R[f]+\"Width\",!0,e)));return g}function Ib(a,b,c){var d=!0,e=\"width\"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g=\"border-box\"===n.css(a,\"boxSizing\",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?\"border\":\"content\"),d,f)+\"px\"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,\"olddisplay\"),c=d.style.display,b?(f[g]||\"none\"!==c||(d.style.display=\"\"),\"\"===d.style.display&&S(d)&&(f[g]=L.access(d,\"olddisplay\",tb(d.nodeName)))):(e=S(d),\"none\"===c&&e||L.set(d,\"olddisplay\",e?c:n.css(d,\"display\"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&\"none\"!==d.style.display&&\"\"!==d.style.display||(d.style.display=b?f[g]||\"\":\"none\"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,\"opacity\");return\"\"===c?\"1\":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\"float\":\"cssFloat\"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&\"get\"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,\"string\"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f=\"number\"),null!=c&&c===c&&(\"number\"!==f||n.cssNumber[h]||(c+=\"px\"),k.clearCloneStyle||\"\"!==c||0!==b.indexOf(\"background\")||(i[b]=\"inherit\"),g&&\"set\"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&\"get\"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),\"normal\"===e&&b in Db&&(e=Db[b]),\"\"===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each([\"height\",\"width\"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?zb.test(n.css(a,\"display\"))&&0===a.offsetWidth?n.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,\"border-box\"===n.css(a,\"boxSizing\",!1,e),e):0)}}}),n.cssHooks.marginRight=yb(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:\"inline-block\"},xb,[a,\"marginRight\"]):void 0}),n.each({margin:\"\",padding:\"\",border:\"Width\"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f=\"string\"==typeof c?c.split(\" \"):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(n.cssHooks[a+b].set=Gb)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return\"boolean\"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}n.Tween=Kb,Kb.prototype={constructor:Kb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||\"swing\",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?\"\":\"px\")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,\"\"),b&&\"auto\"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Kb.prototype.init,n.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp(\"^(?:([+-])=|)(\"+Q+\")([a-z%]*)$\",\"i\"),Pb=/queueHooks$/,Qb=[Vb],Rb={\"*\":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(n.cssNumber[a]?\"\":\"px\"),g=(n.cssNumber[a]||\"px\"!==f&&+d)&&Ob.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||\".5\",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=n.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e[\"margin\"+c]=e[\"padding\"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb[\"*\"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,\"fxshow\");c.queue||(h=n._queueHooks(a,\"fx\"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,\"fx\").length||h.empty.fire()})})),1===a.nodeType&&(\"height\"in b||\"width\"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,\"display\"),k=\"none\"===j?L.get(a,\"olddisplay\")||tb(a.nodeName):j,\"inline\"===k&&\"none\"===n.css(a,\"float\")&&(o.display=\"inline-block\")),c.overflow&&(o.overflow=\"hidden\",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||\"toggle\"===e,e===(p?\"hide\":\"show\")){if(\"show\"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))\"inline\"===(\"none\"===j?tb(a.nodeName):j)&&(o.display=j);else{q?\"hidden\"in q&&(p=q.hidden):q=L.access(a,\"fxshow\",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,\"fxshow\");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ub(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start=\"width\"===d||\"height\"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&\"expand\"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xb(a,b,c){var d,e,f=0,g=Qb.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return n.map(k,Ub,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xb,{tweener:function(a,b){n.isFunction(a)?(b=a,a=[\"*\"]):a=a.split(\" \");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),n.speed=function(a,b,c){var d=a&&\"object\"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:\"number\"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue=\"fx\"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css(\"opacity\",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xb(this,n.extend({},a),f);(e||L.get(this,\"finish\"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return\"string\"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||\"fx\",[]),this.each(function(){var b=!0,e=null!=a&&a+\"queueHooks\",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||\"fx\"),this.each(function(){var b,c=L.get(this),d=c[a+\"queue\"],e=c[a+\"queueHooks\"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each([\"toggle\",\"show\",\"hide\"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||\"boolean\"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),n.each({slideDown:Tb(\"show\"),slideUp:Tb(\"hide\"),slideToggle:Tb(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(Lb=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),Lb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Mb||(Mb=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Mb),Mb=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||\"fx\",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=l.createElement(\"input\"),b=l.createElement(\"select\"),c=b.appendChild(l.createElement(\"option\"));a.type=\"checkbox\",k.checkOn=\"\"!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement(\"input\"),a.value=\"t\",a.type=\"radio\",k.radioValue=\"t\"===a.value}();var Yb,Zb,$b=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&\"get\"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&\"set\"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+\"\"),c):void n.removeAttr(a,b))\n},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&\"radio\"===b&&n.nodeName(a,\"input\")){var c=a.value;return a.setAttribute(\"type\",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\\w+/g),function(a,b){var c=$b[b]||n.find.attr;$b[b]=function(a,b,d){var e,f;return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{\"for\":\"htmlFor\",\"class\":\"className\"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&\"set\"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&\"get\"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute(\"tabindex\")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){n.propFix[this.toLowerCase()]=this});var ac=/[\\t\\r\\n\\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=\"string\"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||\"\").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(\" \"+c.className+\" \").replace(ac,\" \"):\" \")){f=0;while(e=b[f++])d.indexOf(\" \"+e+\" \")<0&&(d+=e+\" \");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||\"string\"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||\"\").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(\" \"+c.className+\" \").replace(ac,\" \"):\"\")){f=0;while(e=b[f++])while(d.indexOf(\" \"+e+\" \")>=0)d=d.replace(\" \"+e+\" \",\" \");g=a?n.trim(d):\"\",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return\"boolean\"==typeof b&&\"string\"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if(\"string\"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||\"boolean\"===c)&&(this.className&&L.set(this,\"__className__\",this.className),this.className=this.className||a===!1?\"\":L.get(this,\"__className__\")||\"\")})},hasClass:function(a){for(var b=\" \"+a+\" \",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(\" \"+this[c].className+\" \").replace(ac,\" \").indexOf(b)>=0)return!0;return!1}});var bc=/\\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e=\"\":\"number\"==typeof e?e+=\"\":n.isArray(e)&&(e=n.map(e,function(a){return null==a?\"\":a+\"\"})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&\"set\"in b&&void 0!==b.set(this,e,\"value\")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&\"get\"in b&&void 0!==(c=b.get(e,\"value\"))?c:(c=e.value,\"string\"==typeof c?c.replace(bc,\"\"):null==c?\"\":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,\"value\");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f=\"select-one\"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute(\"disabled\"))||c.parentNode.disabled&&n.nodeName(c.parentNode,\"optgroup\"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each([\"radio\",\"checkbox\"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute(\"value\")?\"on\":a.value})}),n.each(\"blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu\".split(\" \"),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,\"**\"):this.off(b,a||\"**\",c)}});var cc=n.now(),dc=/\\?/;n.parseJSON=function(a){return JSON.parse(a+\"\")},n.parseXML=function(a){var b,c;if(!a||\"string\"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,\"text/xml\")}catch(d){b=void 0}return(!b||b.getElementsByTagName(\"parsererror\").length)&&n.error(\"Invalid XML: \"+a),b};var ec,fc,gc=/#.*$/,hc=/([?&])_=[^&]*/,ic=/^(.*?):[ \\t]*([^\\r\\n]*)$/gm,jc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,kc=/^(?:GET|HEAD)$/,lc=/^\\/\\//,mc=/^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,nc={},oc={},pc=\"*/\".concat(\"*\");try{fc=location.href}catch(qc){fc=l.createElement(\"a\"),fc.href=\"\",fc=fc.href}ec=mc.exec(fc.toLowerCase())||[];function rc(a){return function(b,c){\"string\"!=typeof b&&(c=b,b=\"*\");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])\"+\"===d[0]?(d=d.slice(1)||\"*\",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function sc(a,b,c,d){var e={},f=a===oc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return\"string\"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e[\"*\"]&&g(\"*\")}function tc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function uc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while(\"*\"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader(\"Content-Type\"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+\" \"+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function vc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if(\"*\"===f)f=i;else if(\"*\"!==i&&i!==f){if(g=j[i+\" \"+f]||j[\"* \"+f],!g)for(e in j)if(h=e.split(\" \"),h[1]===f&&(g=j[i+\" \"+h[0]]||j[\"* \"+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a[\"throws\"])b=g(b);else try{b=g(b)}catch(l){return{state:\"parsererror\",error:g?l:\"No conversion from \"+i+\" to \"+f}}}return{state:\"success\",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:fc,type:\"GET\",isLocal:jc.test(ec[1]),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":pc,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":n.parseJSON,\"text xml\":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?tc(tc(a,n.ajaxSettings),b):tc(n.ajaxSettings,a)},ajaxPrefilter:rc(nc),ajaxTransport:rc(oc),ajax:function(a,b){\"object\"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks(\"once memory\"),q=k.statusCode||{},r={},s={},t=0,u=\"canceled\",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||fc)+\"\").replace(gc,\"\").replace(lc,ec[1]+\"//\"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||\"*\").toLowerCase().match(E)||[\"\"],null==k.crossDomain&&(h=mc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===ec[1]&&h[2]===ec[2]&&(h[3]||(\"http:\"===h[1]?\"80\":\"443\"))===(ec[3]||(\"http:\"===ec[1]?\"80\":\"443\")))),k.data&&k.processData&&\"string\"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),sc(nc,k,b,v),2===t)return v;i=k.global,i&&0===n.active++&&n.event.trigger(\"ajaxStart\"),k.type=k.type.toUpperCase(),k.hasContent=!kc.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?\"&\":\"?\")+k.data,delete k.data),k.cache===!1&&(k.url=hc.test(d)?d.replace(hc,\"$1_=\"+cc++):d+(dc.test(d)?\"&\":\"?\")+\"_=\"+cc++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader(\"If-Modified-Since\",n.lastModified[d]),n.etag[d]&&v.setRequestHeader(\"If-None-Match\",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader(\"Content-Type\",k.contentType),v.setRequestHeader(\"Accept\",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+(\"*\"!==k.dataTypes[0]?\", \"+pc+\"; q=0.01\":\"\"):k.accepts[\"*\"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u=\"abort\";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=sc(oc,k,b,v)){v.readyState=1,i&&m.trigger(\"ajaxSend\",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort(\"timeout\")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,\"No Transport\");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||\"\",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=uc(k,v,f)),u=vc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader(\"Last-Modified\"),w&&(n.lastModified[d]=w),w=v.getResponseHeader(\"etag\"),w&&(n.etag[d]=w)),204===a||\"HEAD\"===k.type?x=\"nocontent\":304===a?x=\"notmodified\":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x=\"error\",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+\"\",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?\"ajaxSuccess\":\"ajaxError\",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger(\"ajaxComplete\",[v,k]),--n.active||n.event.trigger(\"ajaxStop\")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,\"json\")},getScript:function(a,b){return n.get(a,void 0,b,\"script\")}}),n.each([\"get\",\"post\"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:\"GET\",dataType:\"script\",async:!1,global:!1,\"throws\":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,\"body\")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var wc=/%20/g,xc=/\\[\\]$/,yc=/\\r?\\n/g,zc=/^(?:submit|button|image|reset|file)$/i,Ac=/^(?:input|select|textarea|keygen)/i;function Bc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||xc.test(a)?d(a,e):Bc(a+\"[\"+(\"object\"==typeof e?b:\"\")+\"]\",e,c,d)});else if(c||\"object\"!==n.type(b))d(a,b);else for(e in b)Bc(a+\"[\"+e+\"]\",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?\"\":b,d[d.length]=encodeURIComponent(a)+\"=\"+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Bc(c,a[c],b,e);return d.join(\"&\").replace(wc,\"+\")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,\"elements\");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(\":disabled\")&&Ac.test(this.nodeName)&&!zc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(yc,\"\\r\\n\")}}):{name:b.name,value:c.replace(yc,\"\\r\\n\")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Cc=0,Dc={},Ec={0:200,1223:204},Fc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on(\"unload\",function(){for(var a in Dc)Dc[a]()}),k.cors=!!Fc&&\"withCredentials\"in Fc,k.ajax=Fc=!!Fc,n.ajaxTransport(function(a){var b;return k.cors||Fc&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Cc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c[\"X-Requested-With\"]||(c[\"X-Requested-With\"]=\"XMLHttpRequest\");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Dc[g],b=f.onload=f.onerror=null,\"abort\"===a?f.abort():\"error\"===a?d(f.status,f.statusText):d(Ec[f.status]||f.status,f.statusText,\"string\"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b(\"error\"),b=Dc[g]=b(\"abort\");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/(?:java|ecma)script/},converters:{\"text script\":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter(\"script\",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type=\"GET\")}),n.ajaxTransport(\"script\",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n(\"<script>\").prop({async:!0,charset:a.scriptCharset,src:a.url}).on(\"load error\",c=function(a){b.remove(),c=null,a&&e(\"error\"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Gc=[],Hc=/(=)\\?(?=&|$)|\\?\\?/;n.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var a=Gc.pop()||n.expando+\"_\"+cc++;return this[a]=!0,a}}),n.ajaxPrefilter(\"json jsonp\",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Hc.test(b.url)?\"url\":\"string\"==typeof b.data&&!(b.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&Hc.test(b.data)&&\"data\");return h||\"jsonp\"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Hc,\"$1\"+e):b.jsonp!==!1&&(b.url+=(dc.test(b.url)?\"&\":\"?\")+b.jsonp+\"=\"+e),b.converters[\"script json\"]=function(){return g||n.error(e+\" was not called\"),g[0]},b.dataTypes[0]=\"json\",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Gc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),\"script\"):void 0}),n.parseHTML=function(a,b,c){if(!a||\"string\"!=typeof a)return null;\"boolean\"==typeof b&&(c=b,b=!1),b=b||l;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var Ic=n.fn.load;n.fn.load=function(a,b,c){if(\"string\"!=typeof a&&Ic)return Ic.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(\" \");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&\"object\"==typeof b&&(e=\"POST\"),g.length>0&&n.ajax({url:a,type:e,dataType:\"html\",data:b}).done(function(a){f=arguments,g.html(d?n(\"<div>\").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Jc=a.document.documentElement;function Kc(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,\"position\"),l=n(a),m={};\"static\"===k&&(a.style.position=\"relative\"),h=l.offset(),f=n.css(a,\"top\"),i=n.css(a,\"left\"),j=(\"absolute\"===k||\"fixed\"===k)&&(f+i).indexOf(\"auto\")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),\"using\"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Kc(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return\"fixed\"===n.css(c,\"position\")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],\"html\")||(d=a.offset()),d.top+=n.css(a[0],\"borderTopWidth\",!0),d.left+=n.css(a[0],\"borderLeftWidth\",!0)),{top:b.top-d.top-n.css(c,\"marginTop\",!0),left:b.left-d.left-n.css(c,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Jc;while(a&&!n.nodeName(a,\"html\")&&\"static\"===n.css(a,\"position\"))a=a.offsetParent;return a||Jc})}}),n.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(b,c){var d=\"pageYOffset\"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Kc(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each([\"top\",\"left\"],function(a,b){n.cssHooks[b]=yb(k.pixelPosition,function(a,c){return c?(c=xb(a,b),vb.test(c)?n(a).position()[b]+\"px\":c):void 0})}),n.each({Height:\"height\",Width:\"width\"},function(a,b){n.each({padding:\"inner\"+a,content:b,\"\":\"outer\"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||\"boolean\"!=typeof d),g=c||(d===!0||e===!0?\"margin\":\"border\");return J(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement[\"client\"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body[\"scroll\"+a],e[\"scroll\"+a],b.body[\"offset\"+a],e[\"offset\"+a],e[\"client\"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return n});var Lc=a.jQuery,Mc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Mc),b&&a.jQuery===n&&(a.jQuery=Lc),n},typeof b===U&&(a.jQuery=a.$=n),n});\n"
  },
  {
    "path": "static/js/theme-tomorrow.js",
    "content": "ace.define(\"ace/theme/tomorrow\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){t.isDark=!1,t.cssClass=\"ace-tomorrow\",t.cssText=\".ace-tomorrow .ace_gutter {background: #f6f6f6;color: #4D4D4C}.ace-tomorrow .ace_print-margin {width: 1px;background: #f6f6f6}.ace-tomorrow {background-color: #FFFFFF;color: #4D4D4C}.ace-tomorrow .ace_cursor {color: #AEAFAD}.ace-tomorrow .ace_marker-layer .ace_selection {background: #D6D6D6}.ace-tomorrow.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #FFFFFF;}.ace-tomorrow .ace_marker-layer .ace_step {background: rgb(255, 255, 0)}.ace-tomorrow .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #D1D1D1}.ace-tomorrow .ace_marker-layer .ace_active-line {background: #EFEFEF}.ace-tomorrow .ace_gutter-active-line {background-color : #dcdcdc}.ace-tomorrow .ace_marker-layer .ace_selected-word {border: 1px solid #D6D6D6}.ace-tomorrow .ace_invisible {color: #D1D1D1}.ace-tomorrow .ace_keyword,.ace-tomorrow .ace_meta,.ace-tomorrow .ace_storage,.ace-tomorrow .ace_storage.ace_type,.ace-tomorrow .ace_support.ace_type {color: #8959A8}.ace-tomorrow .ace_keyword.ace_operator {color: #3E999F}.ace-tomorrow .ace_constant.ace_character,.ace-tomorrow .ace_constant.ace_language,.ace-tomorrow .ace_constant.ace_numeric,.ace-tomorrow .ace_keyword.ace_other.ace_unit,.ace-tomorrow .ace_support.ace_constant,.ace-tomorrow .ace_variable.ace_parameter {color: #F5871F}.ace-tomorrow .ace_constant.ace_other {color: #666969}.ace-tomorrow .ace_invalid {color: #FFFFFF;background-color: #C82829}.ace-tomorrow .ace_invalid.ace_deprecated {color: #FFFFFF;background-color: #8959A8}.ace-tomorrow .ace_fold {background-color: #4271AE;border-color: #4D4D4C}.ace-tomorrow .ace_entity.ace_name.ace_function,.ace-tomorrow .ace_support.ace_function,.ace-tomorrow .ace_variable {color: #4271AE}.ace-tomorrow .ace_support.ace_class,.ace-tomorrow .ace_support.ace_type {color: #C99E00}.ace-tomorrow .ace_heading,.ace-tomorrow .ace_markup.ace_heading,.ace-tomorrow .ace_string {color: #718C00}.ace-tomorrow .ace_entity.ace_name.ace_tag,.ace-tomorrow .ace_entity.ace_other.ace_attribute-name,.ace-tomorrow .ace_meta.ace_tag,.ace-tomorrow .ace_string.ace_regexp,.ace-tomorrow .ace_variable {color: #C82829}.ace-tomorrow .ace_comment {color: #8E908C}.ace-tomorrow .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bdu3f/BwAlfgctduB85QAAAABJRU5ErkJggg==) right repeat-y}\";var r=e(\"../lib/dom\");r.importCssString(t.cssText,t.cssClass)})"
  },
  {
    "path": "static/js/utils.js",
    "content": "if (!Array.prototype.forEach) {\n  // Simplified iterator for browsers without forEach support\n  Array.prototype.forEach = function(cb) {\n    if (typeof this.length != 'number') return;\n    if (typeof callback != 'function') return;\n\n    for (var i = 0; i < this.length; i++) cb(this[i]);\n  }\n}\n\nfunction copyToClipboard(text) {\n  const element = document.createElement(\"textarea\");\n  element.style.display = \"none;\"\n  element.value = text;\n\n  document.body.appendChild(element);\n  element.focus();\n  element.setSelectionRange(0, element.value.length);\n\n  document.execCommand(\"copy\");\n  document.body.removeChild(element);\n}\n\nfunction guid() {\n  function s4() { return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); }\n  return [s4(), s4(), \"-\", s4(), \"-\", s4(), \"-\", s4(), \"-\", s4(), s4(), s4()].join(\"\");\n}\n\n"
  }
]