L.Projection.SphericalMercator = {
	MAX_LATITUDE: 85.0511287798,

	project: function(/*LatLng*/ latlng) /*-> Point*/ {
		var d = L.LatLng.DEG_TO_RAD,
			max = this.MAX_LATITUDE,
			lat = Math.max(Math.min(max, latlng.lat), -max),
			x = latlng.lng * d,
			y = lat * d;
		y = Math.log(Math.tan(Math.PI/4 + y/2));

		return new L.Point(x, y);
	},

	unproject: function(/*Point*/ point, /*Boolean*/ unbounded) /*-> LatLng*/ {
		var d = L.LatLng.RAD_TO_DEG,
			lng = point.x * d,
			lat = (2 * Math.atan(Math.exp(point.y)) - Math.PI/2) * d;

		return new L.LatLng(lat, lng, unbounded);
	}
};


/*
 * L.TileLayer is used for standard xyz-numbered tile layers.
 */

L.TileLayer = L.Class.extend({
	includes: L.Mixin.Events,

	options: {
		minZoom: 0,
		maxZoom: 18,
		tileSize: 256,
		subdomains: 'abc',
		errorTileUrl: '',
		attribution: '',
		opacity: 1,
		scheme: 'xyz',
		noWrap: false,

		unloadInvisibleTiles: L.Browser.mobile,
		updateWhenIdle: L.Browser.mobile
	},

	initialize: function(url, options) {
		L.Util.setOptions(this, options);

		this._url = url;

		if (typeof this.options.subdomains == 'string') {
			this.options.subdomains = this.options.subdomains.split('');
		}
	},

	onAdd: function(map, insertAtTheBottom) {
		this._map = map;
		this._insertAtTheBottom = insertAtTheBottom;

		// create a container div for tiles
		this._initContainer();

		// create an image to clone for tiles
		this._createTileProto();

		// set up events
		map.on('viewreset', this._reset, this);

		if (this.options.updateWhenIdle) {
			map.on('moveend', this._update, this);
		} else {
			this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this);
			map.on('move', this._limitedUpdate, this);
		}

		this._reset();
		this._update();
	},

	onRemove: function(map) {
		this._map.getPanes().tilePane.removeChild(this._container);
		this._container = null;

		this._map.off('viewreset', this._reset, this);

		if (this.options.updateWhenIdle) {
			this._map.off('moveend', this._update, this);
		} else {
			this._map.off('move', this._limitedUpdate, this);
		}
	},

	getAttribution: function() {
		return this.options.attribution;
	},

	setOpacity: function(opacity) {
		this.options.opacity = opacity;

		this._setOpacity(opacity);

		// stupid webkit hack to force redrawing of tiles
		if (L.Browser.webkit) {
			for (i in this._tiles) {
				this._tiles[i].style.webkitTransform += ' translate(0,0)';
			}
		}
	},

	_setOpacity: function(opacity) {
		if (opacity < 1) {
			L.DomUtil.setOpacity(this._container, opacity);
		}
	},

	_initContainer: function() {
		var tilePane = this._map.getPanes().tilePane,
			first = tilePane.firstChild;

		if (!this._container || tilePane.empty) {
			this._container = L.DomUtil.create('div', 'leaflet-layer');

			if (this._insertAtTheBottom && first) {
				tilePane.insertBefore(this._container, first);
			} else {
				tilePane.appendChild(this._container);
			}

			this._setOpacity(this.options.opacity);
		}
	},

	_reset: function() {
		this._tiles = {};
		this._container.innerHTML = '';
		this._initContainer();
	},

	_update: function() {
		var bounds = this._map.getPixelBounds(),
			tileSize = this.options.tileSize;

		var nwTilePoint = new L.Point(
				Math.floor(bounds.min.x / tileSize),
				Math.floor(bounds.min.y / tileSize)),
			seTilePoint = new L.Point(
				Math.floor(bounds.max.x / tileSize),
				Math.floor(bounds.max.y / tileSize)),
			tileBounds = new L.Bounds(nwTilePoint, seTilePoint);

		this._addTilesFromCenterOut(tileBounds);

		if (this.options.unloadInvisibleTiles) {
			this._removeOtherTiles(tileBounds);
		}
	},

	_addTilesFromCenterOut: function(bounds) {
		var queue = [],
			center = bounds.getCenter();

		for (var j = bounds.min.y; j <= bounds.max.y; j++) {
			for (var i = bounds.min.x; i <= bounds.max.x; i++) {
				if ((i + ':' + j) in this._tiles) { continue; }
				queue.push(new L.Point(i, j));
			}
		}

		// load tiles in order of their distance to center
		queue.sort(function(a, b) {
			return a.distanceTo(center) - b.distanceTo(center);
		});

		var fragment = document.createDocumentFragment();

		this._tilesToLoad = queue.length;
		for (var k = 0, len = this._tilesToLoad; k < len; k++) {
			this._addTile(queue[k], fragment);
		}

		this._container.appendChild(fragment);
	},

	_removeOtherTiles: function(bounds) {
		var kArr, x, y, key;

		for (key in this._tiles) {
			if (this._tiles.hasOwnProperty(key)) {
				kArr = key.split(':');
				x = parseInt(kArr[0], 10);
				y = parseInt(kArr[1], 10);

				// remove tile if it's out of bounds
				if (x < bounds.min.x || x > bounds.max.x || y < bounds.min.y || y > bounds.max.y) {

					// evil, don't do this! crashes Android 3, produces load errors, doesn't solve memory leaks
					// this._tiles[key].src = '';

					if (this._tiles[key].parentNode == this._container) {
						this._container.removeChild(this._tiles[key]);
					}
					delete this._tiles[key];
				}
			}
		}
	},

	_addTile: function(tilePoint, container) {
		var tilePos = this._getTilePos(tilePoint),
			zoom = this._map.getZoom(),
			key = tilePoint.x + ':' + tilePoint.y,
			tileLimit = (1 << zoom);

		// wrap tile coordinates
		if (!this.options.noWrap) {
			tilePoint.x = ((tilePoint.x % tileLimit) + tileLimit) % tileLimit;
		}
		if (tilePoint.y < 0 || tilePoint.y >= tileLimit) { return; }

		// create tile
		var tile = this._createTile();
		L.DomUtil.setPosition(tile, tilePos);

		this._tiles[key] = tile;

		if (this.options.scheme == 'tms') {
			tilePoint.y = tileLimit - tilePoint.y - 1;
		}

		this._loadTile(tile, tilePoint, zoom);

		container.appendChild(tile);
	},

	_getTilePos: function(tilePoint) {
		var origin = this._map.getPixelOrigin(),
			tileSize = this.options.tileSize;

		return tilePoint.multiplyBy(tileSize).subtract(origin);
	},

	// image-specific code (override to implement e.g. Canvas or SVG tile layer)

	getTileUrl: function(tilePoint, zoom) {
		var subdomains = this.options.subdomains,
			s = this.options.subdomains[(tilePoint.x + tilePoint.y) % subdomains.length];

		return this._url
				.replace('{s}', s)
				.replace('{z}', zoom)
				.replace('{x}', tilePoint.x)
				.replace('{y}', tilePoint.y);
	},

	_createTileProto: function() {
		this._tileImg = L.DomUtil.create('img', 'leaflet-tile');
		this._tileImg.galleryimg = 'no';

		var tileSize = this.options.tileSize;
		this._tileImg.style.width = tileSize + 'px';
		this._tileImg.style.height = tileSize + 'px';
	},

	_createTile: function() {
		var tile = this._tileImg.cloneNode(false);
		tile.onselectstart = tile.onmousemove = L.Util.falseFn;
		return tile;
	},

	_loadTile: function(tile, tilePoint, zoom) {
		tile._layer = this;
		tile.onload = this._tileOnLoad;
		tile.onerror = this._tileOnError;
		tile.src = this.getTileUrl(tilePoint, zoom);
	},

	_tileOnLoad: function(e) {
		var layer = this._layer;

		this.className += ' leaflet-tile-loaded';

		layer.fire('tileload', {tile: this, url: this.src});

		layer._tilesToLoad--;
		if (!layer._tilesToLoad) {
			layer.fire('load');
		}
	},

	_tileOnError: function(e) {
		var layer = this._layer;

		layer.fire('tileerror', {tile: this, url: this.src});

		var newUrl = layer.options.errorTileUrl;
		if (newUrl) {
			this.src = newUrl;
		}
	}
});


L.Transition = L.Class.extend({
	includes: L.Mixin.Events,

	statics: {
		CUSTOM_PROPS_SETTERS: {
			position: L.DomUtil.setPosition
			//TODO transform custom attr
		},

		implemented: function() {
			return L.Transition.NATIVE || L.Transition.TIMER;
		}
	},

	options: {
		easing: 'ease',
		duration: 0.5
	},

	_setProperty: function(prop, value) {
		var setters = L.Transition.CUSTOM_PROPS_SETTERS;
		if (prop in setters) {
			setters[prop](this._el, value);
		} else {
			this._el.style[prop] = value;
		}
	}
});


/*
 * Provides L.Map with convenient shortcuts for W3C geolocation.
 */

L.Map.include({
	locate: function(/*Object*/ options) {
		// W3C Geolocation API Spec position options, http://dev.w3.org/geo/api/spec-source.html#position-options
		var opts = {timeout: 10000};
		L.Util.extend(opts, options);

		if (navigator.geolocation) {
			navigator.geolocation.getCurrentPosition(
					L.Util.bind(this._handleGeolocationResponse, this),
					L.Util.bind(this._handleGeolocationError, this),
					opts);
		} else {
			this.fire('locationerror', {
				code: 0,
				message: "Geolocation not supported."
			});
		}
		return this;
	},

	locateAndSetView: function(maxZoom, options) {
		this._setViewOnLocate = true;
		this._maxLocateZoom = maxZoom || Infinity;
		return this.locate(options);
	},

	_handleGeolocationError: function(error) {
		var c = error.code,
			message = (c == 1 ? "permission denied" :
				(c == 2 ? "position unavailable" : "timeout"));

		if (this._setViewOnLocate) {
			this.fitWorld();
			this._setViewOnLocate = false;
		}

		this.fire('locationerror', {
			code: c,
			message: "Geolocation error: " + message + "."
		});
	},

	_handleGeolocationResponse: function(pos) {
		var latAccuracy = 180 * pos.coords.accuracy / 4e7,
			lngAccuracy = latAccuracy * 2,
			lat = pos.coords.latitude,
			lng = pos.coords.longitude;

		var sw = new L.LatLng(lat - latAccuracy, lng - lngAccuracy),
			ne = new L.LatLng(lat + latAccuracy, lng + lngAccuracy),
			bounds = new L.LatLngBounds(sw, ne);

		if (this._setViewOnLocate) {
			var zoom = Math.min(this.getBoundsZoom(bounds), this._maxLocateZoom);
			this.setView(bounds.getCenter(), zoom);
			this._setViewOnLocate = false;
		}

		this.fire('locationfound', {
			latlng: new L.LatLng(lat, lng),
			bounds: bounds,
			accuracy: pos.coords.accuracy
		});
	}
});


L.Util.extend(L.DomEvent, {
	// inspired by Zepto touch code by Thomas Fuchs
	addDoubleTapListener: function(obj, handler, id) {
		var last,
			doubleTap = false,
			delay = 250,
			touch,
			pre = '_leaflet_',
			touchstart = 'touchstart',
			touchend = 'touchend';

		function onTouchStart(e) {
			if (e.touches.length != 1) return;

			var now = Date.now(),
				delta = now - (last || now);

			touch = e.touches[0];
			doubleTap = (delta > 0 && delta <= delay);
			last = now;
		}
		function onTouchEnd(e) {
			if (doubleTap) {
				touch.type = 'dblclick';
				handler(touch);
				last = null;
			}
		}
		obj[pre + touchstart + id] = onTouchStart;
		obj[pre + touchend + id] = onTouchEnd;

		obj.addEventListener(touchstart, onTouchStart, false);
		obj.addEventListener(touchend, onTouchEnd, false);
	},

	removeDoubleTapListener: function(obj, id) {
		var pre = '_leaflet_';
		obj.removeEventListener(obj, obj[pre + 'touchstart' + id], false);
		obj.removeEventListener(obj, obj[pre + 'touchend' + id], false);
	}
});


const prefix = input.replace(/-input\.[^.]+/, '');

keep keep keep replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep

import {
  findWSDLForServiceName,
  getJsonForWSDL,
  getSwaggerForService,
  getWSDLServices,
  Swagger,
} from 'apiconnect-wsdl';

import { Converter } from '../entities';
import * as postman from './postman';

export const id = 'wsdl';
export const name = 'WSDL';
export const description = 'Importer for WSDL files';

const convertToPostman = (items: Swagger[]) => {
  const item = items.map(swagger => {
    const item = [];
    const url = swagger['x-ibm-configuration'].assembly.execute[0].proxy['target-url'];

    for (const path of Object.keys(swagger.paths)) {
      const methods = swagger.paths[path];

      for (const method of Object.keys(methods)) {
        const api = methods[method];
        const paths = api.parameters[0].schema.$ref.split('/');
        paths.shift();
        paths.push('example');
        const example = swagger.paths.join('.');
        item.push({
          name: api.operationId,
          description: api.description || '',
          request: {
            url,
            method,
            header: [
              {
                key: 'SOAPAction',
                value: api['x-ibm-soap.soap-action'],
                disabled: false,
              },
              {
                key: 'Content-Type',
                value: swagger.consumes[0],
                disabled: false,
              },
              {
                key: 'Accept',
                value: swagger.produces[0],
                disabled: false,
              },
            ],
            body: {
              mode: 'raw',
              raw: example,
            },
          },
        });
      }
    }

    return {
      name: swagger.info.title,
      item,
    };
  });
  return {
    info: {
      name: items[0].info.title,
      schema: 'https://schema.getpostman.com/json/collection/v2.0.0/', // required
    },
    item,
  };
};

const convertWsdlToPostman = async (input: string) => {
  const wsdls = await getJsonForWSDL(input);
  const { services } = getWSDLServices(wsdls);

  const items = services.map(({ service, filename }) => {
    const wsdlEntry = findWSDLForServiceName(wsdls, service);
    return getSwaggerForService(wsdlEntry, service, filename);
  });

  return convertToPostman(items);
};

export const convert: Converter = async rawData => {
  try {
    if (rawData.indexOf('wsdl:definition') !== -1) {
      const postmanData = await convertWsdlToPostman(
        `<?xml version="1.0" encoding="UTF-8" ?>${rawData}`,
      );
      postmanData.info.schema += 'collection.json';
      const postmanJson = JSON.stringify(postmanData);
      return postman.convert(postmanJson);
    }
  } catch (e) {
    // Nothing
  }

  return null;
};


hello world!

foo

This is a comment


import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React, { FC } from 'react';

import { globalBeforeEach } from '../../../../../../__jest__/before-each';
import { createMockStoreWithRequest } from '../../../../../../__jest__/create-mock-store-with-active-request';
import { MockCodeEditor } from '../../../../../../__jest__/mock-code-editor';
import { withReduxStore } from '../../../../../../__jest__/with-redux-store';
import * as models from '../../../../../../models';
import { AuthInputRow } from '../auth-input-row';

jest.mock('../../../../codemirror/code-editor', () => ({
  CodeEditor: MockCodeEditor,
}));

const Table: FC = ({ children }) =>

{children}

;

describe('<AuthInputRow />', () => {
  beforeEach(globalBeforeEach);

  it('should mask and toggle the input', async () => {
    // Arrange
    await models.settings.patch({  showPasswords: false });
    const { store } = await createMockStoreWithRequest();

    // Render with mask enabled
    const { findByLabelText, findByTestId } = render(
      <AuthInputRow label='inputLabel' property='inputProperty' mask />,
      { wrapper: withReduxStore(store, Table) }
    );

    let input = await findByLabelText('inputLabel');
    expect(input).toHaveAttribute('type', 'password');

    // Act
    await userEvent.click(await findByTestId('reveal-password-icon'));

    // Assert
    input = await findByLabelText('inputLabel');
    expect(input).toHaveAttribute('type', 'text');

    // Act
    await userEvent.click(await findByTestId('mask-password-icon'));

    // Assert
    input = await findByLabelText('inputLabel');
    expect(input).toHaveAttribute('type', 'password');
  });

  it('should not show masking toggle if all passwords are shown', async () => {
    // Arrange
    await models.settings.patch({ showPasswords: true });
    const { store } = await createMockStoreWithRequest();

    // Render with mask enabled
    const { findByLabelText, queryAllByTestId } = render(
      <AuthInputRow label='inputLabel' property='inputProperty' mask />,
      { wrapper: withReduxStore(store, Table) }
    );

    // Assert
    const input = await findByLabelText('inputLabel');
    expect(input).toHaveAttribute('type', 'text');
    expect(queryAllByTestId('reveal-password-icon')).toHaveLength(0);
    expect(queryAllByTestId('mask-password-icon')).toHaveLength(0);
  });

  it('should update the authentication property on typing', async () => {
    // Arrange
    const { store, requestId } = await createMockStoreWithRequest();

    const { findByLabelText } = render(
      <AuthInputRow label='inputLabel' property='inputProperty' />,
      { wrapper: withReduxStore(store, Table) }
    );

    // This is a function because the underlying component changes as the element gets focus
    const getInput = () => findByLabelText('inputLabel');

    // Act
    expect(await getInput()).not.toHaveFocus();
    await userEvent.click(await getInput());
    expect(await getInput()).toHaveFocus();

    // NOTE: we are typing into a mocked CodeEditor component.
    await userEvent.type(await getInput(), 'inputValue');

    // Assert
    const request = await models.request.getById(requestId);
    expect(request?.authentication.inputProperty).toEqual('inputValue');
  });

  it('should pre-fill existing authentication property value', async () => {
    // Arrange
    const { store } = await createMockStoreWithRequest({ requestPatch: { authentication: { inputProperty: 'existing' } } });

    const { findByLabelText } = render(
      <AuthInputRow label='inputLabel' property='inputProperty' />,
      { wrapper: withReduxStore(store, Table) }
    );

    // Assert
    expect(await findByLabelText('inputLabel')).toHaveValue('existing');
  });
});


# Insomnia API Client

[![Slack Channel](https://chat.insomnia.rest/badge.svg)](https://chat.insomnia.rest/)
[![license](https://img.shields.io/github/license/Kong/insomnia.svg)](https://github.com/Kong/insomnia/blob/master/LICENSE)

Insomnia is an open-source, cross-platform API client for GraphQL, REST, and gRPC.

![Insomnia API Client](https://raw.githubusercontent.com/Kong/insomnia/develop/screenshots/main.png)

## Download

Insomnia is available for Mac, Windows, and Linux and can be downloaded
from the website.

**[https://insomnia.rest/download](https://insomnia.rest/download/)**

## Bugs and Feature Requests

Have a bug or a feature request? First, read the
[issue guidelines](CONTRIBUTING.md#using-the-issue-tracker) and search for existing and
closed issues. If your problem or idea is not addressed yet, [please open a new issue](/issues).

For more generic product questions and feedback, join the [Slack Team](https://chat.insomnia.rest) or email
[support@insomnia.rest](mailto:support@insomnia.rest)

## Contributing

Please read through our [contributing guidelines](CONTRIBUTING.md) and [code of conduct](CODE_OF_CONDUCT.md). Included are directions for opening issues, coding standards, and notes on development.

## Documentation

Check out our open-source [Insomnia Documentation](https://docs.insomnia.rest/).

## Develop Insomnia app

Development on Insomnia can be done on Mac, Windows, or Linux as long as you have [Node.js](https://nodejs.org) and [Git](https://git-scm.com/). See the `.nvmrc` file located in the project for the correct Node version.

Initial Dev Setup

This repository is structured as a monorepo and contains many Node.JS packages. Each package has its own set of commands, but the most common commands are available from the root [`package.json`](package.json) and can be accessed using the `npm run ...` command. Here are the only three commands you should need to start developing on the app.

```shell
# Install and Link Dependencies
npm run bootstrap

# Run Tests
npm test

# Start App with Live Reload
npm run app-start
```

### Linux

If you are on Linux, you may need to install the following supporting packages:

Ubuntu/Debian

```shell
# Update library
sudo apt-get update

# Install font configuration library & support
sudo apt-get install libfontconfig-dev
```

Fedora

```shell
# Install libcurl for node-libcurl
sudo dnf install libcurl-devel
```

Also on Linux, if Electron is failing during the bootstrap process, run the following

```shell
# Clear Electron install conflicts
rm -rf ~/.cache/electron
```

### Windows

If you are on Windows and have problems, you may need to install [Windows Build Tools](https://github.com/felixrieseberg/windows-build-tools)

Editor Requirements

You can use any editor you'd like, but make sure to have support/plugins for the following tools:

- [ESLint](http://eslint.org/) – For catching syntax problems and common errors
- [JSX Syntax](https://facebook.github.io/react/docs/jsx-in-depth.html) – For React components

## Develop Inso CLI

- Bootstrap: `npm run bootstrap`
- Start the compiler in watch mode: `npm run inso-start`
- Run: `./packages/insomnia-inso/bin/inso -v`

## Plugins

Search for, discover, and install plugins from the Insomnia [Plugin Hub](https://insomnia.rest/plugins/)!

## Community Projects

- [Insomnia Documenter](https://github.com/jozsefsallai/insomnia-documenter) – Generate beautiful API documentation pages using the [documenter plugin](https://insomnia.rest/plugins/insomnia-plugin-documenter) or your Insomnia export file.
- [GitHub API Spec Importer](https://github.com/swinton/github-rest-apis-for-insomnia) – A complete set of GitHub REST API route specifications that can be imported straight into Insomnia.
- [Swaggymnia](https://github.com/mlabouardy/swaggymnia) – Generate [Swagger](https://swagger.io/) documentation for your existing API in Insomnia.

## License

[MIT](LICENSE) © [Insomnia](https://insomnia.rest)


import { Converter } from '../entities';

keep keep keep add keep keep keep keep keep

import { path as ramdaPath } from 'ramda';


/** @type { import('@jest/types').Config.InitialOptions } */
module.exports = {
  preset: '../../jest-preset.js',
};


import fs from 'fs';
import path from 'path';
import React from 'react';

import { database as db } from '../../../common/database';
import { selectFileOrFolder } from '../../../common/select-file-or-folder';
import * as models from '../../../models';
import type { ProtoDirectory } from '../../../models/proto-directory';
import { isProtoFile, ProtoFile } from '../../../models/proto-file';
import { showAlert, showError } from '../../../ui/components/modals';
import * as protoLoader from '../proto-loader';
import ingestProtoDirectory from './ingest-proto-directory';

export async function deleteFile(protoFile: ProtoFile, callback: (arg0: string) => void) {
  showAlert({
    title: `Delete ${protoFile.name}`,
    message: (

        Really delete {protoFile.name}? All requests that use this proto file will
        stop working.

    ),
    addCancel: true,
    onConfirm: async () => {
      await models.protoFile.remove(protoFile);
      callback(protoFile._id);
    },
  });
}

export async function deleteDirectory(protoDirectory: ProtoDirectory, callback: (arg0: string[]) => void) {
  showAlert({
    title: `Delete ${protoDirectory.name}`,
    message: (

        Really delete {protoDirectory.name} and all proto files contained within?
        All requests that use these proto files will stop working.

    ),
    addCancel: true,
    onConfirm: async () => {
      const descendant = await db.withDescendants(protoDirectory);
      await models.protoDirectory.remove(protoDirectory);
      callback(descendant.map(c => c._id));
    },
  });
}

export async function addDirectory(workspaceId: string) {
  let rollback = false;
  let createdIds: string[];
  const bufferId = await db.bufferChangesIndefinitely();

  try {
    // Select file
    const { filePath, canceled } = await selectFileOrFolder({
      itemTypes: ['directory'],
      extensions: ['proto'],
    });

    // Exit if no file selected
    if (canceled || !filePath) {
      return;
    }

    const result = await ingestProtoDirectory(filePath, workspaceId);
    createdIds = result.createdIds;
    const { error, createdDir } = result;

    if (error) {
      showError({
        title: 'Failed to import',
        message: `An unexpected error occurred when reading ${filePath}`,
        error,
      });
      rollback = true;
      return;
    }

    // Show warning if no files found
    if (!createdDir) {
      showAlert({
        title: 'No files found',
        message: `No .proto files were found under ${filePath}.`,
      });
      return;
    }

    // Try parse all loaded proto files to make sure they are valid
    const loadedEntities = await db.withDescendants(createdDir);
    const loadedFiles = loadedEntities.filter(isProtoFile);

    for (const file of loadedFiles) {
      try {
        await protoLoader.loadMethods(file);
      } catch (e) {
        showError({
          title: 'Invalid Proto File',
          message: `The file ${file.name} could not be parsed`,
          error: e,
        });
        rollback = true;
        return;
      }
    }
  } catch (e) {
    rollback = true;
    showError({
      error: e,
    });
  } finally {
    // Fake flushing changes (or, rollback) only prevents change notifications being sent to the UI
    // It does NOT revert changes written to the database, as is typical of a db transaction rollback
    // As such, if rolling back, the created directory needs to be deleted manually
    await db.flushChanges(bufferId, rollback);

    if (rollback) {
      // @ts-expect-error -- TSCONVERSION
      await models.protoDirectory.batchRemoveIds(createdIds);
      // @ts-expect-error -- TSCONVERSION
      await models.protoFile.batchRemoveIds(createdIds);
    }
  }
}

async function _readFile() {
  try {
    // Select file
    const { filePath, canceled } = await selectFileOrFolder({
      itemTypes: ['file'],
      extensions: ['proto'],
    });

    // Exit if no file selected
    if (canceled || !filePath) {
      return;
    }

    // Try parse proto file to make sure the file is valid
    try {
      await protoLoader.loadMethodsFromPath(filePath);
    } catch (e) {
      showError({
        title: 'Invalid Proto File',
        message: `The file ${filePath} and could not be parsed`,
        error: e,
      });
      return;
    }

    // Read contents
    const contents = await fs.promises.readFile(filePath, 'utf-8');
    const name = path.basename(filePath);
    return {
      fileName: name,
      fileContents: contents,
    };
  } catch (e) {
    showError({
      error: e,
    });
  }
  return undefined;
}

export async function addFile(workspaceId: string, callback: (arg0: string) => void) {
  const result = await _readFile();

  if (result) {
    const newFile = await models.protoFile.create({
      name: result.fileName,
      parentId: workspaceId,
      protoText: result.fileContents,
    });
    callback(newFile._id);
  }
}

export async function updateFile(protoFile: ProtoFile, callback: (arg0: string) => void) {
  const result = await _readFile();

  if (result) {
    const updatedFile = await models.protoFile.update(protoFile, {
      name: result.fileName,
      protoText: result.fileContents,
    });
    callback(updatedFile._id);
  }
}

export async function renameFile(protoFile: ProtoFile, name: string) {
  await models.protoFile.update(protoFile, {
    name,
  });
}


import type { Schema } from '@develohpanda/fluent-builder';

import type { GrpcRequestState } from '../grpc-reducer';

export const requestStateSchema: Schema<GrpcRequestState> = {
  running: () => false,
  requestMessages: () => [],
  responseMessages: () => [],
  status: () => undefined,
  error: () => undefined,
  methods: () => [],
  reloadMethods: () => false,
};


const paths = api.parameters[0].schema.$ref.split('/');

const example = swagger.paths.join('.');

const example = ramdaPath(paths, swagger);


import 'codemirror/addon/mode/simple';

import CodeMirror from 'codemirror';

/** regular key-value header tokens */
const keyValueHeaders = [
  {
    regex: /^(> )([^:]*:)(.*)$/,
    token: ['curl-prefix curl-out', 'curl-out', 'curl-out curl-value'],
  },
  {
    regex: /^(< )([^:]*:)(.*)$/,
    token: ['curl-prefix curl-in', 'curl-in', 'curl-in curl-value'],
  },
];

/**
 * @example POST /foo/bar HTTP/1.1
 */
const headerFields = [
  {
    regex: /^(> )([^:]+ .*)$/,
    token: ['curl-prefix curl-out curl-header', 'curl-out curl-header'],
  },
  {
    regex: /^(< )([^:]+ .*)$/,
    token: ['curl-prefix curl-in curl-header', 'curl-in curl-header'],
  },
];

const data = [
  {
    regex: /^(\| )(.*)$/,
    token: ['curl-prefix curl-data', 'curl-data'],
  },
];

const informationalText = [
  {
    regex: /^(\* )(.*)$/,
    token: ['curl-prefix curl-comment', 'curl-comment'],
  },
];

CodeMirror.defineSimpleMode('curl', {
  start: [
    ...keyValueHeaders,
    ...headerFields,
    ...data,
    ...informationalText,
  ],
  comment: [],
  meta: {},
});


import { ValueOf } from 'type-fest';

export const GrpcRequestEventEnum = {
  start: 'GRPC_START',
  sendMessage: 'GRPC_SEND_MESSAGE',
  commit: 'GRPC_COMMIT',
  cancel: 'GRPC_CANCEL',
  cancelMultiple: 'GRPC_CANCEL_MULTIPLE',
} as const;

export type GrpcRequestEvent = ValueOf<typeof GrpcRequestEventEnum>;

export const GrpcResponseEventEnum = {
  start: 'GRPC_START',
  data: 'GRPC_DATA',
  error: 'GRPC_ERROR',
  end: 'GRPC_END',
  status: 'GRPC_STATUS',
} as const;

export type GrpcResponseEvent = ValueOf<typeof GrpcResponseEventEnum>;


import { database as db } from '../../common/database';
import { GrpcRequest, type as GrpcRequestType } from '../grpc-request';
import { Request, type as RequestType } from '../request';
import { Workspace } from '../workspace';

export const queryAllWorkspaceUrls = async (
  workspace: Workspace | null,
  reqType: typeof RequestType | typeof GrpcRequestType,
  reqId = 'n/a',
): Promise<string[]> => {
  const docs = await db.withDescendants(workspace, reqType);
  const urls = docs
    .filter(
      (d: Request | GrpcRequest) =>
        d.type === reqType &&
        d._id !== reqId && // Not current request
        (d.url || ''), // Only ones with non-empty URLs
    )
    .map((r: Request | GrpcRequest) => (r.url || '').trim());
  return Array.from(new Set(urls));
};


keep keep keep replace keep keep keep keep


_id: ut_97a197104e83454ebf5f4e0dc0ba4bc6
code: expect(true).to.equal(true);
created: 1593668468718
modified: 1593669244289
name: Test should succeed
parentId: uts_7f0f85548b0147f4ba6b5e442d137613
requestId: null
type: UnitTest


const {
  ERROR,
  OFF,
  SUCCESSOR,
  TYPESCRIPT_CONVERSION,
  TYPESCRIPT_EXTENSION,
  UNKNOWN,
  WARN,
} = require('eslint-config-helpers');

/** @type { import('eslint').Linter.Config } */
module.exports = {
  settings: {
    react: {
      version: '16.8', // note: remember to always keep this in sync with `"react": "^16.8.3",` which is present in any package.json of a project using React.
    },
  },
  parser: '@typescript-eslint/parser',
  parserOptions: {
    project: [
      './tsconfig.eslint.json',
      './packages/*/tsconfig.json',
      './plugins/*/tsconfig.json',
    ],
    tsconfigRootDir: __dirname,
    ecmaFeatures: {
      jsx: true,
    },
  },
  extends: [
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:react/recommended',
    'plugin:react-hooks/recommended',
  ],
  plugins: [
    '@typescript-eslint',
    'react',
    'jest',
    'html',
    'json',
    'filenames',
    'react-hooks',
    'import',
    'simple-import-sort',
  ],
  globals: {
    __DEV__: true,
    fail: true,
    NodeJS: true,
    HTMLDivElement: true,
    HTMLElement: true,
    HTMLInputElement: true,
    HTMLSelectElement: true,
    JSX: true,
  },
  env: {
    browser: true,
    commonjs: true,
    es6: true,
    'jest/globals': true,
    node: true,
  },
  overrides: [
    {
      files: ['*.js'],
      rules: {
        '@typescript-eslint/no-var-requires': OFF(UNKNOWN),
      },
    },
  ],
  rules: {
    'array-bracket-spacing': ERROR,
    'brace-style': SUCCESSOR(TYPESCRIPT_EXTENSION),
    'camelcase': [ERROR, { allow: ['__export_format', '__export_date', '__export_source'] }],
    'comma-dangle': [ERROR, 'always-multiline'],
    'comma-spacing': ERROR,
    'consistent-return': OFF('found to be too many false positives'),
    'default-case': ERROR,
    'default-case-last': ERROR,
    'filenames/match-exported': [ERROR, 'kebab'],
    'indent': [ERROR, 2, { SwitchCase: 1 }],
    'eol-last': [ERROR, 'always'],
    'eqeqeq': [ERROR, 'smart'],
    'arrow-parens': [ERROR, 'as-needed'],
    'arrow-spacing': ERROR,
    'keyword-spacing': SUCCESSOR(TYPESCRIPT_EXTENSION),
    'no-async-promise-executor': OFF(UNKNOWN),
    'no-case-declarations': OFF(UNKNOWN),
    'no-duplicate-imports': OFF(UNKNOWN),
    'no-prototype-builtins': OFF(UNKNOWN),
    'no-redeclare': OFF(UNKNOWN),
    'no-unused-vars': OFF(UNKNOWN),
    'no-use-before-define': OFF(UNKNOWN),
    'no-var': ERROR,
    'no-trailing-spaces': ERROR,
    'no-multiple-empty-lines': [ERROR, { 'max': 1, 'maxEOF': 0 }],
    'object-curly-spacing': [ERROR, 'always'],
    'quotes': OFF(UNKNOWN),
    'semi': SUCCESSOR(TYPESCRIPT_EXTENSION),
    'space-before-function-paren': [ERROR, { anonymous: 'never', named: 'never', asyncArrow: 'always' }],
    'space-infix-ops': SUCCESSOR(TYPESCRIPT_EXTENSION),
    'space-unary-ops': ERROR,
    'space-in-parens': ERROR,
    'spaced-comment': [ERROR, 'always', {
      exceptions: ['/', '*', '-', '* '], // for ASCII art :)
      markers: [
        '/', // for TypeScript directives, doxygen, vsdoc, etc. (which use `///`)
        '?', // for Quokka
      ],
    }],

    'filenames/match-exported': [ERROR, 'kebab'],

    'react/no-find-dom-node': OFF(UNKNOWN),
    'react/no-unescaped-entities': OFF(TYPESCRIPT_CONVERSION),
    'react/jsx-first-prop-new-line': [ERROR, 'multiline'],
    'react/jsx-max-props-per-line': [ERROR, { maximum: 1, when: 'multiline' }],
    'react/jsx-uses-react': ERROR,
    'react/jsx-uses-vars': ERROR,
    'react/jsx-indent': [ERROR, 2],
    'react/jsx-indent-props': [ERROR, 2],
    'react/prop-types': OFF(UNKNOWN),
    'react/function-component-definition': [ERROR, {
      'namedComponents':  'arrow-function',
      'unnamedComponents': 'arrow-function',
    }],
    'react/jsx-max-props-per-line': [ERROR, { 'maximum': 1, 'when': 'multiline' }],
    'react/jsx-closing-bracket-location': [ERROR, 'line-aligned'],
    'react/prefer-stateless-function': ERROR,
    'react/jsx-key': [ERROR, { 'checkFragmentShorthand': true }],
    'react/no-array-index-key': WARN(UNKNOWN),
    'react/self-closing-comp': ERROR,

    'react-hooks/exhaustive-deps': [ERROR, {
      // From react-use https://github.com/streamich/react-use/issues/1703#issuecomment-770972824
      'additionalHooks': '^use(Async|AsyncFn|AsyncRetry|Debounce|UpdateEffect|IsomorphicLayoutEffect|DeepCompareEffect|ShallowCompareEffect)$',
    }],
    'react-hooks/rules-of-hooks': ERROR,

    '@typescript-eslint/array-type': [ERROR, { default: 'array', readonly: 'array' }],
    '@typescript-eslint/ban-types': OFF(UNKNOWN),
    '@typescript-eslint/brace-style': [ERROR, '1tbs', { 'allowSingleLine': true }],
    '@typescript-eslint/consistent-type-definitions': [ERROR, 'interface'],
    '@typescript-eslint/explicit-module-boundary-types': OFF(UNKNOWN),
    '@typescript-eslint/keyword-spacing': ERROR,
    '@typescript-eslint/member-delimiter-style': ERROR,
    '@typescript-eslint/no-empty-function': OFF(UNKNOWN),
    '@typescript-eslint/no-empty-interface': [ERROR, { 'allowSingleExtends': true }],
    '@typescript-eslint/no-namespace': [ERROR, { allowDeclarations: true }],
    '@typescript-eslint/no-redeclare': ERROR,
    '@typescript-eslint/no-unused-vars': [ERROR, { ignoreRestSiblings: true }],
    '@typescript-eslint/no-use-before-define': ERROR,
    '@typescript-eslint/space-infix-ops': ERROR,
    '@typescript-eslint/semi': [ERROR, 'always'],
    '@typescript-eslint/quotes': [ERROR, 'single', { avoidEscape: true }],

    'simple-import-sort/imports': ERROR,
  },
};


AWS Signature Test

A collection for testing


var tagInfo = CodeHintUtils.getTagInfo(editor, pos);

if (tagInfo.editing.token === CodeHintUtils.ATTR_VALUE) {

} else if (tagInfo.attr.name === "id") {

keep keep keep keep replace keep keep keep keep

if (tagInfo.hint.type === CodeHintUtils.ATTR_VALUE) {

/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define: false */

define(function (require, exports, module) {
    'use strict';

    //constants
    var TAG_NAME = "tagName",
        ATTR_NAME = "attr.name",
        ATTR_VALUE = "att.value";

    /**
     * @private
     * moves the current context backwards by one token
     * @param {editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}} ctx
     * @return {boolean} whether the context changed
     */
    function _movePrevToken(ctx) {
        if (ctx.pos.ch <= 0 || ctx.token.start <= 0) {
            //move up a line
            if (ctx.pos.line <= 0) {
                return false; //at the top already
            }
            ctx.pos.line--;
            ctx.pos.ch = ctx.editor.getLine(ctx.pos.line).length;
        } else {
            ctx.pos.ch = ctx.token.start;
        }
        ctx.token = ctx.editor.getTokenAt(ctx.pos);
        return true;
    }

    /**
     * @private
     * moves the current context forward by one token
     * @param {editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}} ctx
     * @return {boolean} whether the context changed
     */
    function _moveNextToken(ctx) {
        var eol = ctx.editor.getLine(ctx.pos.line).length;
        if (ctx.pos.ch >= eol || ctx.token.end >= eol) {
            //move down a line
            if (ctx.pos.line === ctx.editor.lineCount()) {
                return false; //at the bottom
            }
            ctx.pos.line++;
            ctx.pos.ch = 0;
        } else {
            ctx.pos.ch = ctx.token.end + 1;
        }
        ctx.token = ctx.editor.getTokenAt(ctx.pos);
        return true;
    }

   /**
     * @private
     * creates a context object
     * @param {CodeMirror} editor
     * @param {{ch:{string}, line:{number}} pos
     * @return {editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}}
     */
    function _getInitialContext(editor, pos) {
        return {
            "editor": editor,
            "pos": pos,
            "token": editor.getTokenAt(pos)
        };
    }

    /**
     * @private
     * in the given context, get the character offset of pos from the start of the token
     * @param {editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}} context
     * @return {number}
     */
    function _offsetInToken(ctx) {
        var offset = ctx.pos.ch - ctx.token.start;
        if (offset < 0) {
            console.log("CodeHintUtils: _offsetInToken - Invalid context: the pos what not in the current token!");
        }
        return offset;
    }

   /**
     * @private
     * Sometimes as attr values are getting typed, if the quotes aren't balanced yet
     * some extra 'non attribute value' text gets included in the token. This attempts
     * to assure the attribute value we grab is always good
     * @param {editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}} context
     * @return { val:{string}, offset{number}}
     */
    function _extractAttrVal(ctx) {
        var attrValue = ctx.token.string;
        var startChar = attrValue.charAt(0);
        var endChar = attrValue.charAt(attrValue.length - 1);
        var offset = _offsetInToken(ctx);

        //If this is a fully quoted value, return the whole
        //thing regardless of position
        if (attrValue.length > 1 &&
                (startChar === "'" || startChar === '"') &&
                endChar === startChar) {
            //strip the quotes and return;
            attrValue = attrValue.substring(1, attrValue.length - 1);
            offset = offset - 1 > attrValue.length ? attrValue.length : offset - 1;
            return {val: attrValue, offset: offset};
        }

        //The att value it getting edit in progress. There is possible extra
        //stuff in this token state since the quote isn't closed, so we assume
        //the stuff from the quote to the current pos is definitely in the attribute
        //value.
        if (offset > 0) {
            attrValue = attrValue.substring(0, offset);
        }

        //If the attrValue start with a quote, trim that now
        startChar = attrValue.charAt(0);
        if (startChar === "'" || startChar === '"') {
            attrValue = attrValue.substring(1);
            offset--;
        }

        return {val: attrValue, offset: offset};
    }

      /**
     * @private
     * Gets the tagname from where ever you are in the currect state
     * @param {editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}} context
     * @return {string}
     */
    function _extractTagName(ctx) {
        if (ctx.token.state.tagName) {
            return ctx.token.state.tagName; //XML mode
        } else {
            return ctx.token.state.htmlState.tagName; //HTML mode
        }
    }

    /**
     * Creates a tagInfo object and assures all the values are entered or are empty strings
     * @param {string} token what is getting edited
     * @param {string} tagName The name of the tag
     * @param {string} attrName The name of the attribute
     * @param {string} attrValue The value of the attribute
     * @return {{tagName:string, attr{name:string, value:string}} A tagInfo object with some context
     *              about the current tag hint.
     */
    function createTagInfo(token, offset, tagName, attrName, attrValue) {
        return { tagName: tagName || "",
                 attr:
                    { name: attrName || "",
                      value: attrValue || ""},
                 editing:
                    { token: token || "",
                      offsetInToken: offset || 0} };
    }

    function _getTagInfoStartingFromAttrValue(ctx) {
        // Assume we in the attr value
        // and validate that by going backwards
        var attrInfo = _extractAttrVal(ctx);
        var attrVal = attrInfo.val;
        var offset = attrInfo.offset;

        //Move to the prev token, and check if it's "="
        if (!_movePrevToken(ctx) || ctx.token.string !== "=") {
            return createTagInfo();
        }

        //Move to the prev token, and check if it's an attribute
        if (!_movePrevToken(ctx) || ctx.token.className !== "attribute") {
            return createTagInfo();
        }

        var attrName = ctx.token.string;
        var tagName = _extractTagName(ctx);

        //We're good.
        return createTagInfo(ATTR_VALUE, offset, tagName, attrName, attrVal);
    }

    function _getTagInfoStartingFromAttrName(ctx) {
        //Verify We're in the attribute name, move forward and try to extract the rest of
        //the info. If the user it typing the attr the rest might not be here
        if (ctx.token.className !== "attribute") {
            return createTagInfo();
        }

        var tagName = _extractTagName(ctx);
        var attrName = ctx.token.string;
        var offset = _offsetInToken(ctx);

        if (!_moveNextToken(ctx) || ctx.token.string !== "=") {
            return createTagInfo(ATTR_NAME, offset, tagName, attrName);
        }

        if (!_moveNextToken(ctx)) {
            //The user just typed "=" so they are about to add the attr val
            return createTagInfo(ATTR_NAME, offset, tagName, attrName);
        }
        //this should be the attrvalue
        var attrInfo = _extractAttrVal(ctx);
        var attrVal = attrInfo.val;

        return createTagInfo(ATTR_NAME, offset, tagName, attrName, attrVal);
    }

    /**
     * Figure out if we're in a tag, and if we are
     * An example token stream for this tag is  :
     *      className:tag       string:""
     * @param {CodeMirror} editor An instance of a CodeMirror editor
     * @param {{ch: number, line: number}} pos  A CM pos (likely from editor.getCursor())
     * @return {{tagName:string, attr{name:string, value:string}} A tagInfo object with some context
     *              about the current tag hint.
     */
    function getTagInfo(editor, pos) {
        var ctx = _getInitialContext(editor, pos),
            offset = _offsetInToken(ctx),
            tagInfo,
            editingToken;

        //check and see where we are in the tag
        //first check, if we're in an all whitespace token and move back
        //and see what's before us
        if (ctx.token.string.length > 0 && ctx.token.string.trim().length === 0) {
            if (!_movePrevToken(ctx)) {
                return createTagInfo();
            }

            if (ctx.token.className !== "tag") {
                //if wasn't the tag name, assume it was an attr value
                tagInfo = _getTagInfoStartingFromAttrValue(ctx);
                //We don't want to give context for the previous attr
                //and we want it to look like the user is going to add a new attr
                if (tagInfo.tagName) {
                    return createTagInfo(ATTR_NAME, 0, tagInfo.tagName);
                }
                return createTagInfo();
            }

            //we know the tag was here, so they user is adding an attr name
            editingToken = ATTR_NAME;
            offset = 0;
        }

        if (ctx.token.className === "tag") {
            //check to see if this is the closing of a tag (either the start or end)
            if (ctx.token.string === ">") {
                return createTagInfo();
            }

            if (!editingToken) {
                editingToken = TAG_NAME;
                offset--; //need to take off 1 for the leading "<"
            }

            //we're actually in the tag, just return that as we have no relevant
            //info about what attr is selected
            return createTagInfo(editingToken, offset, _extractTagName(ctx));
        }

        if (ctx.token.string === "=") {
            //we could be between the attr and the value
            //step back and check
            if (!_movePrevToken(ctx) || ctx.token.className !== "attribute") {
                return createTagInfo();
            }

            //This the the = as the are going to add an value now
            editingToken = ATTR_VALUE;
            offset = 0;
        }

        if (ctx.token.className === "attribute") {
            tagInfo = _getTagInfoStartingFromAttrName(ctx);
        } else {
            // if we're not at a tag, "=", or attribute name, assume we're in the value
            tagInfo = _getTagInfoStartingFromAttrValue(ctx);
        }

        if (editingToken && tagInfo.tagName) {
            tagInfo.editing.token = editingToken;
            tagInfo.editing.offsetInToken = offset;
        }

        return tagInfo;
    }

    // Define public API
    exports.TAG_NAME = TAG_NAME;
    exports.ATTR_NAME = ATTR_NAME;
    exports.ATTR_VALUE = ATTR_VALUE;

    exports.getTagInfo = getTagInfo;
    //The createTagInfo is really only for the unit tests so they can make the same structure to
    //compare results with
    exports.createTagInfo = createTagInfo;
});


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>Jasmine Spec Runner</title>

  <link rel="stylesheet" type="text/css" href="../jasmine.css">
  <script type="text/javascript" src="../jasmine.js"></script>
  <script type="text/javascript" src="../jasmine-html.js"></script>

  <!-- include spec files here... -->
  <script type="text/javascript" src="spec/SpecHelper.js"></script>
  <script type="text/javascript" src="spec/PlayerSpec.js"></script>

  <!-- include source files here... -->
  <script type="text/javascript" src="src/Player.js"></script>
  <script type="text/javascript" src="src/Song.js"></script>

  <script type="text/javascript">
    (function() {
      var jasmineEnv = jasmine.getEnv();
      jasmineEnv.updateInterval = 1000;

      var trivialReporter = new jasmine.TrivialReporter();

      jasmineEnv.addReporter(trivialReporter);

      jasmineEnv.specFilter = function(spec) {
        return trivialReporter.specFilter(spec);
      };

      var currentWindowOnload = window.onload;

      window.onload = function() {
        if (currentWindowOnload) {
          currentWindowOnload();
        }
        execJasmine();
      };

      function execJasmine() {
        jasmineEnv.execute();
      }

    })();
  </script>

</head>

<body>
</body>
</html>


/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define: false, $: false */

/**
 * PreferencesManager
 *
 */
define(function (require, exports, module) {
    'use strict';

    var PREFERENCES_KEY = "com.adobe.brackets.preferences";

    // Private Properties
    var preferencesKey,
        callbacks = {}, /* associative array with clientID keys */
        prefStorage,
        persistentStorage,
        doLoadPreferences   = false;

    /**
     * Retrieves a copy of the client's preferences object.
     *
     * @param {string}  unique identifier clientID
     * @return {object} preference
     */
    function getPreferences(clientID) {
        if ((clientID === undefined) || (clientID === null)) {
            throw new Error("Invalid clientID");
        }

        var prefs = prefStorage[clientID];

        if (prefs === undefined) {
            return undefined;
        }

        // create a deep copy to return to the client
        return JSON.parse(JSON.stringify(prefs));
    }

    /**
     * Saves to persistent storage.
     */
    function saveToPersistentStorage() {
        // save all preferences
        persistentStorage.setItem(preferencesKey, JSON.stringify(prefStorage));
    }

    /**
     * Registers a save participant callback for a client. The callback is
     * fired when Brackets quits (window.unload). When fired, callbacks may
     * persist data (e.g. preferences or current state) as valid JSON values
     * to the storage argument.
     *
     * @param {string}          unique identifier clientID for this client
     * @param {function(...)}   callback function
     * @param {object}          optional "this" object for the callback
     * @param {object}          optional default preferences object for this client
     */
    function addPreferencesClient(clientID, callback, instance, defaults) {
        if (typeof callback !== "function") {
            throw new Error("Invalid arguments");
        }

        // attempt to load existing preferences
        var clientPrefs = getPreferences(clientID);

        // if clientPrefs is undefined, try defaults
        if (clientPrefs === undefined) {
            if (JSON.stringify(defaults)) {
                // use defaults if it is a valid JSON object
                clientPrefs = defaults;
            } else {
                // use empty defaults if JSON validation fails
                clientPrefs = {};
            }

            // save defaults in-memory, storage
            prefStorage[clientID] = clientPrefs;
            saveToPersistentStorage();
        }

        var callbackData = { clientID: clientID,
                             callback: callback,
                             instance: instance };

        // add to callbacks list
        callbacks[clientID] = callbackData;
    }

    /**
     * Save all preference clients.
     */
    function savePreferences() {
        var data,
            storage;

        // iterate over all preference clients
        $.each(callbacks, function (index, value) {
            data = callbacks[index];
            storage = getPreferences(data.clientID);

            // fire callback with thisArg and preference storage
            try {
                data.callback.call(data.instance, storage);
            } catch (e) {
                console.log("PreferenceManager.savePreferences(): Failed to save data for clientID " + data.clientID);
            }

            // only save preferences that can be serialized with JSON
            if (JSON.stringify(storage)) {
                prefStorage[data.clientID] = storage;
            }
        });

        saveToPersistentStorage();
    }

    /**
     * @private
     * Reset preferences and callbacks
     */
    function _reset() {
        callbacks = {};
        prefStorage = {};

        // Note that storage.clear() is not used. Production and unit test code
        // both rely on the same backing storage but unique item keys.
        persistentStorage.setItem(preferencesKey, JSON.stringify(prefStorage));
    }

    /**
     * @private
     * Initialize persistent storage implementation
     */
    function _initStorage(storage) {
        persistentStorage = storage;

        if (doLoadPreferences) {
            prefStorage = JSON.parse(persistentStorage.getItem(preferencesKey));
        }

        // initialize empty preferences if none were found in storage
        if (!prefStorage) {
            _reset();
        }
    }

    // check localStorage for a preferencesKey
    preferencesKey = localStorage.getItem("preferencesKey");

    if (!preferencesKey) {
        // use default key if none is found
        preferencesKey = PREFERENCES_KEY;
        doLoadPreferences = true;
    } else {
        // using a non-default key, check for additional settings
        doLoadPreferences = !!(localStorage.getItem("doLoadPreferences"));
    }

    // Use localStorage by default
    _initStorage(localStorage);

    // Public API
    exports.getPreferences          = getPreferences;
    exports.addPreferencesClient    = addPreferencesClient;
    exports.savePreferences         = savePreferences;

    // Internal Use Only
    exports._reset                  = _reset;
});


return {val: attrValue, offset: offset};

* Gets the tagname from where ever you are in the currect state

* @param {editor:{CodeMirror}, pos:{ch:{string}, line:{number}}, token:{object}} context

keep keep keep keep replace keep keep keep


/*
 * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define: false, $: false, brackets: false, PathUtils: false */

define(function (require, exports, module) {
    'use strict';

    require("thirdparty/path-utils/path-utils.min");

    // Load dependent modules
    var CommandManager      = require("CommandManager"),
        Commands            = require("Commands"),
        NativeFileSystem    = require("NativeFileSystem").NativeFileSystem,
        ProjectManager      = require("ProjectManager"),
        DocumentManager     = require("DocumentManager"),
        EditorManager       = require("EditorManager"),
        EditorUtils         = require("EditorUtils"),
        Async               = require("Async"),
        Strings             = require("strings"),
        PreferencesManager  = require("PreferencesManager"),
        PerfUtils           = require("PerfUtils");

    /**
     * Handlers for commands related to file handling (opening, saving, etc.)
     */

    /** @type {jQueryObject} Container for label shown above editor */
    var _title = null;
    /** @type {string} Label shown above editor for current document: filename and potentially some of its path */
    var _currentTitlePath = null;

    function updateTitle() {
        var currentDoc = DocumentManager.getCurrentDocument();
        if (currentDoc) {
            _title.text(_currentTitlePath + (currentDoc.isDirty ? " \u2022" : ""));
        } else {
            _title.text("");
        }
    }

    function handleCurrentDocumentChange() {
        var newDocument = DocumentManager.getCurrentDocument();

        if (newDocument) {
            var fullPath = newDocument.file.fullPath;

            // In the main toolbar, show the project-relative path (if the file is inside the current project)
            // or the full absolute path (if it's not in the project).
            _currentTitlePath = ProjectManager.makeProjectRelativeIfPossible(fullPath);

        } else {
            _currentTitlePath = null;
        }

        // Update title text & "dirty dot" display
        updateTitle();
    }

    function handleDirtyChange(event, changedDoc) {
        var currentDoc = DocumentManager.getCurrentDocument();

        if (currentDoc && changedDoc.file.fullPath === currentDoc.file.fullPath) {
            updateTitle();
        }
    }

    /**
     * @private
     * Creates a document and displays an editor for the specified file path.
     * @param {!string} fullPath
     * @return {Deferred} a jQuery Deferred that will be resolved with a new
     *  document for the specified file path, or rejected if the file can not be read.
     */
    function doOpen(fullPath) {

        var result = new $.Deferred();
        if (!fullPath) {
            console.log("doOpen() called without fullPath");
            return result.reject();
        }

        PerfUtils.markStart("Open File: " + fullPath);
        result.always(function () {
            PerfUtils.addMeasurement("Open File: " + fullPath);
        });

        var doc = DocumentManager.getDocumentForPath(fullPath);
        if (doc) {
            // File already open - don't need to load it, just switch to it in the UI
            DocumentManager.showInEditor(doc);
            result.resolve(doc);

        } else {
            // File wasn't open before, so we must create a new document for it
            var fileEntry = new NativeFileSystem.FileEntry(fullPath);
            var docResult = EditorManager.createDocumentAndEditor(fileEntry);

            docResult.done(function (doc) {
                DocumentManager.showInEditor(doc);
                result.resolve(doc);
            });

            docResult.fail(function (error) {
                EditorUtils.showFileOpenError(error.code, fullPath);
                result.reject();
            });
        }

        return result;
    }

    /**
     * @private
     * Used to track the default directory for the file open dialog
     */
    var _defaultOpenDialogFullPath = null;

    /**
     * @private
     * Creates a document and displays an editor for the specified file path.
     * If no path is specified, a file prompt is provided for input.
     * @param {?string} fullPath - The path of the file to open; if it's null we'll prompt for it
     * @return {Deferred} a jQuery Deferred that will be resolved with a new
     *  document for the specified file path, or rejected if the file can not be read.
     */
    function _doOpenWithOptionalPath(fullPath) {
        var result;
        if (!fullPath) {
            //first time through, default to the current project path
            if (!_defaultOpenDialogFullPath) {
                _defaultOpenDialogFullPath = ProjectManager.getProjectRoot().fullPath;
            }
            // Prompt the user with a dialog
            // TODO (issue #117): we're relying on this to not be asynchronous--is that safe?
            NativeFileSystem.showOpenDialog(false, false, Strings.OPEN_FILE, _defaultOpenDialogFullPath,
                ["htm", "html", "js", "css"], function (files) {
                    if (files.length > 0) {
                        result = doOpen(files[0])
                            .done(function updateDefualtOpenDialogFullPath(doc) {
                                var url = PathUtils.parseUrl(doc.file.fullPath);
                                //reconstruct the url but use the directory and stop there
                                _defaultOpenDialogFullPath = url.protocol + url.doubleSlash + url.authority + url.directory;
                            });
                        return;
                    }
                });
        } else {
            result = doOpen(fullPath);
        }
        if (!result) {
            result = (new $.Deferred()).reject();
        }
        return result;
    }

    function handleFileOpen(commandData) {
        var fullPath = null;
        if (commandData) {
            fullPath = commandData.fullPath;
        }

        return _doOpenWithOptionalPath(fullPath)
                 .always(EditorManager.focusEditor);
    }

    function handleFileAddToWorkingSet(commandData) {
        handleFileOpen(commandData).done(function (doc) {
            DocumentManager.addToWorkingSet(doc);
        });
    }

    /**
     * @private
     * Ensures the suggested file name doesn't already exit.
     * @param {string} dir  The directory to use
     * @param {string} baseFileName  The base to start with, "-n" will get appened to make unique
     * @param {string} fileExt  The file extension
     */
    function _getUntitledFileSuggestion(dir, baseFileName, fileExt) {
        var result = new $.Deferred();
        var suggestedName = baseFileName + fileExt;
        var dirEntry = new NativeFileSystem.DirectoryEntry(dir);

        result.progress(function attemptNewName(suggestedName, nextIndexToUse) {
            if (nextIndexToUse > 99) {
                //we've tried this enough
                result.reject();
                return;
            }

            //check this name
            dirEntry.getFile(
                suggestedName,
                {},
                function successCallback(entry) {
                    //file exists, notify to the next progress
                    result.notify(baseFileName + "-" + nextIndexToUse + fileExt, nextIndexToUse + 1);
                },
                function errorCallback(error) {
                    //most likely error is FNF, user is better equiped to handle the rest
                    result.resolve(suggestedName);
                }
            );
        });

        //kick it off
        result.notify(baseFileName + fileExt, 1);

        return result;
    }

    function handleFileNewInProject() {
        // Determine the directory to put the new file
        // If a file is currently selected, put it next to it.
        // If a directory is currently selected, put it in it.
        // If nothing is selected, put it at the root of the project
        var baseDir,
            selected = ProjectManager.getSelectedItem() || ProjectManager.getProjectRoot();

        baseDir = selected.fullPath;
        if (selected.isFile) {
            baseDir = baseDir.substr(0, baseDir.lastIndexOf("/"));
        }

        // Create the new node. The createNewItem function does all the heavy work
        // of validating file name, creating the new file and selecting.
        var deferred = _getUntitledFileSuggestion(baseDir, "Untitled", ".js");
        var createWithSuggestedName = function (suggestedName) {
            ProjectManager.createNewItem(baseDir, suggestedName, false).pipe(deferred.resolve, deferred.reject, deferred.notify);
        };

        deferred.done(createWithSuggestedName);
        deferred.fail(function createWithDefault() { createWithSuggestedName("Untitled.js"); });
        return deferred;
    }

    function showSaveFileError(code, path) {
        return brackets.showModalDialog(
            brackets.DIALOG_ID_ERROR,
            Strings.ERROR_SAVING_FILE_TITLE,
            Strings.format(
                Strings.ERROR_SAVING_FILE,
                path,
                EditorUtils.getFileErrorString(code)
            )
        );
    }

    /** Note: if there is an error, the Deferred is not rejected until the user has dimissed the dialog */
    function doSave(docToSave) {
        var result = new $.Deferred();

        function handleError(error, fileEntry) {
            showSaveFileError(error.code, fileEntry.fullPath)
                .always(function () {
                    result.reject(error);
                });
        }

        if (docToSave && docToSave.isDirty) {
            var fileEntry = docToSave.file;
            var writeError = false;

            fileEntry.createWriter(
                function (writer) {
                    writer.onwriteend = function () {
                        // Per spec, onwriteend is called after onerror too
                        if (!writeError) {
                            docToSave.notifySaved();
                            result.resolve();
                        }
                    };
                    writer.onerror = function (error) {
                        writeError = true;
                        handleError(error, fileEntry);
                    };

                    // TODO (issue #241): Blob instead of string
                    writer.write(docToSave.getText());
                },
                function (error) {
                    handleError(error, fileEntry);
                }
            );
        } else {
            result.resolve();
        }
        result.always(function () {
            EditorManager.focusEditor();
        });
        return result;
    }

    /**
     * Saves the given file. If no file specified, assumes the current document.
     * @param {?{doc: Document}} commandData  Document to close, or null
     * @return {$.Deferred}
     */
    function handleFileSave(commandData) {
        // Default to current document if doc is null
        var doc = null;
        if (commandData) {
            doc = commandData.doc;
        }
        if (!doc) {
            doc = DocumentManager.getCurrentDocument();
        }

        return doSave(doc);
    }

    /**
     * Saves all unsaved documents. Returns a Promise that will be resolved once ALL the save
     * operations have been completed. If ANY save operation fails, an error dialog is immediately
     * shown and the other files wait to save until it is dismissed; after all files have been
     * processed, the Promise is rejected if any ONE save operation failed.
     *
     * @return {$.Promise}
     */
    function saveAll() {
        // Do in serial because doSave shows error UI for each file, and we don't want to stack
        // multiple dialogs on top of each other
        return Async.doSequentially(DocumentManager.getWorkingSet(), doSave, false);
    }

    /**
     * Closes the specified document. Prompts user about saving file if document is dirty.
     *
     * @param {?{doc: Document}} commandData  Document to close; assumes the current document if null.
     * @param {boolean} promptOnly  If true, only displays the relevant confirmation UI and does NOT
     *          actually close the document. This is useful when chaining file-close together with
     *          other user prompts that may be cancelable.
     * @return {$.Deferred}
     */
    function handleFileClose(commandData) {
        var doc = null;
        if (commandData) {
            doc = commandData.doc;
        }

        // utility function for handleFileClose: closes document & removes from working set
        function doClose(doc) {
            if (!commandData || !commandData.promptOnly) {
                // This selects a different document if the working set has any other options
                DocumentManager.closeDocument(doc);

                EditorManager.focusEditor();
            }
        }

        var result = new $.Deferred();

        // Default to current document if doc is null
        if (!doc) {
            doc = DocumentManager.getCurrentDocument();
        }

        // No-op if called when nothing is open; TODO: (issue #273) should command be grayed out instead?
        if (!doc) {
            return;
        }

        if (doc.isDirty) {
            var filename = PathUtils.parseUrl(doc.file.fullPath).filename;

            brackets.showModalDialog(
                brackets.DIALOG_ID_SAVE_CLOSE,
                Strings.SAVE_CLOSE_TITLE,
                Strings.format(Strings.SAVE_CLOSE_MESSAGE, filename)
            ).done(function (id) {
                if (id === brackets.DIALOG_BTN_CANCEL) {
                    result.reject();
                } else if (id === brackets.DIALOG_BTN_OK) {
                    doSave(doc)
                        .done(function () {
                            doClose(doc);
                            result.resolve();
                        })
                        .fail(function () {
                            result.reject();
                        });
                } else {
                    // This is the "Don't Save" case--we can just go ahead and close the file.
                    doClose(doc);
                    result.resolve();
                }
            });
            result.always(function () {
                EditorManager.focusEditor();
            });
        } else {
            // Doc is not dirty, just close
            doClose(doc);
            EditorManager.focusEditor();
            result.resolve();
        }
        return result;
    }

    /**
     * Closes all open documents; equivalent to calling handleFileClose() for each document, except
     * that unsaved changes are confirmed once, in bulk.
     * @param {?{promptOnly: boolean}}  If true, only displays the relevant confirmation UI and does NOT
     *          actually close any documents. This is useful when chaining close-all together with
     *          other user prompts that may be cancelable.
     * @return {$.Deferred}
     */
    function handleFileCloseAll(commandData) {
        var result = new $.Deferred();

        var unsavedDocs = DocumentManager.getWorkingSet().filter(function (doc) {
            return doc.isDirty;
        });

        if (unsavedDocs.length === 0) {
            // No unsaved changes, so we can proceed without a prompt
            result.resolve();

        } else if (unsavedDocs.length === 1) {
            // Only one unsaved file: show the usual single-file-close confirmation UI
            var fileCloseArgs = { doc: unsavedDocs[0], promptOnly: commandData.promptOnly };

            handleFileClose(fileCloseArgs).done(function () {
                // still need to close any other, non-unsaved documents
                result.resolve();
            }).fail(function () {
                result.reject();
            });

        } else {
            // Multiple unsaved files: show a single bulk prompt listing all files
            var message = Strings.SAVE_CLOSE_MULTI_MESSAGE;

            message += "
";
            unsavedDocs.forEach(function (doc) {
                message += "
" + ProjectManager.makeProjectRelativeIfPossible(doc.file.fullPath) + "
";
            });
            message += "
";

            brackets.showModalDialog(
                brackets.DIALOG_ID_SAVE_CLOSE,
                Strings.SAVE_CLOSE_TITLE,
                message
            ).done(function (id) {
                if (id === brackets.DIALOG_BTN_CANCEL) {
                    result.reject();
                } else if (id === brackets.DIALOG_BTN_OK) {
                    // Save all unsaved files, then if that succeeds, close all
                    saveAll().done(function () {
                        result.resolve();
                    }).fail(function () {
                        result.reject();
                    });
                } else {
                    // "Don't Save" case--we can just go ahead and close all  files.
                    result.resolve();
                }
            });
        }

        // If all the unsaved-changes confirmations pan out above, then go ahead & close all editors
        // NOTE: this still happens before any done() handlers added by our caller, because jQ
        // guarantees that handlers run in the order they are added.
        result.done(function () {
            if (!commandData || !commandData.promptOnly) {
                DocumentManager.closeAll();
            }
        });

        return result;
    }

    /**
    * @private - tracks our closing state if we get called again
    */
    var _windowGoingAway = false;

    /**
    * @private
    * Common implementation for close/quit/reload which all mostly
    * the same except for the final step
    */
    function _handleWindowGoingAway(commandData, postCloseHandler) {
        if (_windowGoingAway) {
            //if we get called back while we're closing, then just return
            return (new $.Deferred()).resolve();
        }

        //prevent the default action of closing the window until we can save all the files
        if (commandData && commandData.evt && commandData.evt.cancelable) {
            commandData.evt.preventDefault();
        }

        return CommandManager.execute(Commands.FILE_CLOSE_ALL, { promptOnly: true })
            .done(function () {
                _windowGoingAway = true;
                PreferencesManager.savePreferences();
                postCloseHandler();
            });
    }

    /** Confirms any unsaved changes, then closes the window */
    function handleFileCloseWindow(commandData) {
        return _handleWindowGoingAway(commandData, function () {
            window.close();
        });
    }

    /** Closes the window, then quits the app */
    function handleFileQuit(commandData) {
        return _handleWindowGoingAway(commandData, function () {
            brackets.app.quit();
        });
        // if fail, don't exit: user canceled (or asked us to save changes first, but we failed to do so)
    }

     /** Does a full reload of the browser window */
    function handleFileReload(commandData) {
        return _handleWindowGoingAway(commandData, function () {
            window.location.reload();
        });
    }

    function init(title) {
        _title = title;

        // Register global commands
        CommandManager.register(Commands.FILE_OPEN, handleFileOpen);
        CommandManager.register(Commands.FILE_ADD_TO_WORKING_SET, handleFileAddToWorkingSet);
        // TODO: (issue #274) For now, hook up File > New to the "new in project" handler. Eventually
        // File > New should open a new blank tab, and handleFileNewInProject should
        // be called from a "+" button in the project
        CommandManager.register(Commands.FILE_NEW, handleFileNewInProject);
        CommandManager.register(Commands.FILE_SAVE, handleFileSave);
        CommandManager.register(Commands.FILE_CLOSE, handleFileClose);
        CommandManager.register(Commands.FILE_CLOSE_ALL, handleFileCloseAll);
        CommandManager.register(Commands.FILE_CLOSE_WINDOW, handleFileCloseWindow);
        CommandManager.register(Commands.FILE_QUIT, handleFileQuit);
        CommandManager.register(Commands.FILE_RELOAD, handleFileReload);

        $(DocumentManager).on("dirtyFlagChange", handleDirtyChange);
        $(DocumentManager).on("currentDocumentChange", handleCurrentDocumentChange);
    }

    // Define public API
    exports.init = init;
});


/*
 RequireJS 1.0.3 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
 Available via the MIT or new BSD license.
 see: http://github.com/jrburke/requirejs for details
*/
var requirejs,require,define;
(function(){function J(a){return M.call(a)==="[object Function]"}function E(a){return M.call(a)==="[object Array]"}function Z(a,c,h){for(var k in c)if(!(k in K)&&(!(k in a)||h))a[k]=c[k];return d}function N(a,c,d){a=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+a);if(d)a.originalError=d;return a}function $(a,c,d){var k,j,q;for(k=0;q=c[k];k++){q=typeof q==="string"?{name:q}:q;j=q.location;if(d&&(!j||j.indexOf("/")!==0&&j.indexOf(":")===-1))j=d+"/"+(j||q.name);a[q.name]={name:q.name,location:j||
q.name,main:(q.main||"main").replace(ea,"").replace(aa,"")}}}function U(a,c){a.holdReady?a.holdReady(c):c?a.readyWait+=1:a.ready(!0)}function fa(a){function c(b,l){var f,a;if(b&&b.charAt(0)===".")if(l){p.pkgs[l]?l=[l]:(l=l.split("/"),l=l.slice(0,l.length-1));f=b=l.concat(b.split("/"));var c;for(a=0;c=f[a];a++)if(c===".")f.splice(a,1),a-=1;else if(c==="..")if(a===1&&(f[2]===".."||f[0]===".."))break;else a>0&&(f.splice(a-1,2),a-=2);a=p.pkgs[f=b[0]];b=b.join("/");a&&b===f+"/"+a.main&&(b=f)}else b.indexOf("./")===
0&&(b=b.substring(2));return b}function h(b,l){var f=b?b.indexOf("!"):-1,a=null,d=l?l.name:null,i=b,e,h;f!==-1&&(a=b.substring(0,f),b=b.substring(f+1,b.length));a&&(a=c(a,d));b&&(a?e=(f=m[a])&&f.normalize?f.normalize(b,function(b){return c(b,d)}):c(b,d):(e=c(b,d),h=E[e],h||(h=g.nameToUrl(e,null,l),E[e]=h)));return{prefix:a,name:e,parentMap:l,url:h,originalName:i,fullName:a?a+"!"+(e||""):e}}function k(){var b=!0,l=p.priorityWait,f,a;if(l){for(a=0;f=l[a];a++)if(!s[f]){b=!1;break}b&&delete p.priorityWait}return b}
function j(b,l,f){return function(){var a=ga.call(arguments,0),c;if(f&&J(c=a[a.length-1]))c.__requireJsBuild=!0;a.push(l);return b.apply(null,a)}}function q(b,l){var a=j(g.require,b,l);Z(a,{nameToUrl:j(g.nameToUrl,b),toUrl:j(g.toUrl,b),defined:j(g.requireDefined,b),specified:j(g.requireSpecified,b),isBrowser:d.isBrowser});return a}function o(b){var l,a,c,B=b.callback,i=b.map,e=i.fullName,ba=b.deps;c=b.listeners;if(B&&J(B)){if(p.catchError.define)try{a=d.execCb(e,b.callback,ba,m[e])}catch(k){l=k}else a=
d.execCb(e,b.callback,ba,m[e]);if(e)(B=b.cjsModule)&&B.exports!==void 0&&B.exports!==m[e]?a=m[e]=b.cjsModule.exports:a===void 0&&b.usingExports?a=m[e]:(m[e]=a,F[e]&&(Q[e]=!0))}else e&&(a=m[e]=B,F[e]&&(Q[e]=!0));if(C[b.id])delete C[b.id],b.isDone=!0,g.waitCount-=1,g.waitCount===0&&(I=[]);delete R[e];if(d.onResourceLoad&&!b.placeholder)d.onResourceLoad(g,i,b.depArray);if(l)return a=(e?h(e).url:"")||l.fileName||l.sourceURL,c=l.moduleTree,l=N("defineerror",'Error evaluating module "'+e+'" at location "'+
a+'":\n'+l+"\nfileName:"+a+"\nlineNumber: "+(l.lineNumber||l.line),l),l.moduleName=e,l.moduleTree=c,d.onError(l);for(l=0;B=c[l];l++)B(a)}function r(b,a){return function(f){b.depDone[a]||(b.depDone[a]=!0,b.deps[a]=f,b.depCount-=1,b.depCount||o(b))}}function u(b,a){var f=a.map,c=f.fullName,h=f.name,i=L[b]||(L[b]=m[b]),e;if(!a.loading)a.loading=!0,e=function(b){a.callback=function(){return b};o(a);s[a.id]=!0;w()},e.fromText=function(b,a){var l=O;s[b]=!1;g.scriptCount+=1;g.fake[b]=!0;l&&(O=!1);d.exec(a);
l&&(O=!0);g.completeLoad(b)},c in m?e(m[c]):i.load(h,q(f.parentMap,!0),e,p)}function v(b){C[b.id]||(C[b.id]=b,I.push(b),g.waitCount+=1)}function D(b){this.listeners.push(b)}function t(b,a){var f=b.fullName,c=b.prefix,d=c?L[c]||(L[c]=m[c]):null,i,e;f&&(i=R[f]);if(!i&&(e=!0,i={id:(c&&!d?M++ +"__p@:":"")+(f||"__r@"+M++),map:b,depCount:0,depDone:[],depCallbacks:[],deps:[],listeners:[],add:D},x[i.id]=!0,f&&(!c||L[c])))R[f]=i;c&&!d?(f=t(h(c),!0),f.add(function(){var a=h(b.originalName,b.parentMap),a=t(a,
!0);i.placeholder=!0;a.add(function(b){i.callback=function(){return b};o(i)})})):e&&a&&(s[i.id]=!1,g.paused.push(i),v(i));return i}function A(b,a,f,c){var b=h(b,c),d=b.name,i=b.fullName,e=t(b),k=e.id,j=e.deps,n;if(i){if(i in m||s[k]===!0||i==="jquery"&&p.jQuery&&p.jQuery!==f().fn.jquery)return;x[k]=!0;s[k]=!0;i==="jquery"&&f&&V(f())}e.depArray=a;e.callback=f;for(f=0;f<a.length;f++)if(k=a[f])k=h(k,d?b:c),n=k.fullName,a[f]=n,n==="require"?j[f]=q(b):n==="exports"?(j[f]=m[i]={},e.usingExports=!0):n===
"module"?e.cjsModule=j[f]={id:d,uri:d?g.nameToUrl(d,null,c):void 0,exports:m[i]}:n in m&&!(n in C)&&(!(i in F)||i in F&&Q[n])?j[f]=m[n]:(i in F&&(F[n]=!0,delete m[n],S[k.url]=!1),e.depCount+=1,e.depCallbacks[f]=r(e,f),t(k,!0).add(e.depCallbacks[f]));e.depCount?v(e):o(e)}function n(b){A.apply(null,b)}function y(b,a){if(!b.isDone){var c=b.map.fullName,d=b.depArray,g,i,e,k;if(c){if(a[c])return m[c];a[c]=!0}if(d)for(g=0;g<d.length;g++)if(i=d[g])if((e=h(i).prefix)&&(k=C[e])&&y(k,a),(e=C[i])&&!e.isDone&&
s[i])i=y(e,a),b.depCallbacks[g](i);return c?m[c]:void 0}}function z(){var b=p.waitSeconds*1E3,a=b&&g.startTime+b<(new Date).getTime(),b="",c=!1,h=!1,j;if(!(g.pausedCount>0)){if(p.priorityWait)if(k())w();else return;for(j in s)if(!(j in K)&&(c=!0,!s[j]))if(a)b+=j+" ";else{h=!0;break}if(c||g.waitCount){if(a&&b)return j=N("timeout","Load timeout for modules: "+b),j.requireType="timeout",j.requireModules=b,d.onError(j);if(h||g.scriptCount){if((G||ca)&&!W)W=setTimeout(function(){W=0;z()},50)}else{if(g.waitCount){for(H=
0;b=I[H];H++)y(b,{});g.paused.length&&w();X<5&&(X+=1,z())}X=0;d.checkReadyState()}}}}var g,w,p={waitSeconds:7,baseUrl:"./",paths:{},pkgs:{},catchError:{}},P=[],x={require:!0,exports:!0,module:!0},E={},m={},s={},C={},I=[],S={},M=0,R={},L={},F={},Q={},Y=0;V=function(b){if(!g.jQuery&&(b=b||(typeof jQuery!=="undefined"?jQuery:null))&&!(p.jQuery&&b.fn.jquery!==p.jQuery)&&("holdReady"in b||"readyWait"in b))if(g.jQuery=b,n(["jquery",[],function(){return jQuery}]),g.scriptCount)U(b,!0),g.jQueryIncremented=
!0};w=function(){var b,a,c,h,j,i;Y+=1;if(g.scriptCount<=0)g.scriptCount=0;for(;P.length;)if(b=P.shift(),b[0]===null)return d.onError(N("mismatch","Mismatched anonymous define() module: "+b[b.length-1]));else n(b);if(!p.priorityWait||k())for(;g.paused.length;){j=g.paused;g.pausedCount+=j.length;g.paused=[];for(h=0;b=j[h];h++)a=b.map,c=a.url,i=a.fullName,a.prefix?u(a.prefix,b):!S[c]&&!s[i]&&(d.load(g,i,c),c.indexOf("empty:")!==0&&(S[c]=!0));g.startTime=(new Date).getTime();g.pausedCount-=j.length}Y===
1&&z();Y-=1};g={contextName:a,config:p,defQueue:P,waiting:C,waitCount:0,specified:x,loaded:s,urlMap:E,urlFetched:S,scriptCount:0,defined:m,paused:[],pausedCount:0,plugins:L,needFullExec:F,fake:{},fullExec:Q,managerCallbacks:R,makeModuleMap:h,normalize:c,configure:function(b){var a,c,d;b.baseUrl&&b.baseUrl.charAt(b.baseUrl.length-1)!=="/"&&(b.baseUrl+="/");a=p.paths;d=p.pkgs;Z(p,b,!0);if(b.paths){for(c in b.paths)c in K||(a[c]=b.paths[c]);p.paths=a}if((a=b.packagePaths)||b.packages){if(a)for(c in a)c in
K||$(d,a[c],c);b.packages&&$(d,b.packages);p.pkgs=d}if(b.priority)c=g.requireWait,g.requireWait=!1,g.takeGlobalQueue(),w(),g.require(b.priority),w(),g.requireWait=c,p.priorityWait=b.priority;if(b.deps||b.callback)g.require(b.deps||[],b.callback)},requireDefined:function(b,a){return h(b,a).fullName in m},requireSpecified:function(b,a){return h(b,a).fullName in x},require:function(b,c,f){if(typeof b==="string"){if(J(c))return d.onError(N("requireargs","Invalid require call"));if(d.get)return d.get(g,
b,c);c=h(b,c);b=c.fullName;return!(b in m)?d.onError(N("notloaded","Module name '"+c.fullName+"' has not been loaded yet for context: "+a)):m[b]}(b&&b.length||c)&&A(null,b,c,f);if(!g.requireWait)for(;!g.scriptCount&&g.paused.length;)g.takeGlobalQueue(),w();return g.require},takeGlobalQueue:function(){T.length&&(ha.apply(g.defQueue,[g.defQueue.length-1,0].concat(T)),T=[])},completeLoad:function(b){var a;for(g.takeGlobalQueue();P.length;)if(a=P.shift(),a[0]===null){a[0]=b;break}else if(a[0]===b)break;
else n(a),a=null;a?n(a):n([b,[],b==="jquery"&&typeof jQuery!=="undefined"?function(){return jQuery}:null]);d.isAsync&&(g.scriptCount-=1);w();d.isAsync||(g.scriptCount-=1)},toUrl:function(a,c){var d=a.lastIndexOf("."),h=null;d!==-1&&(h=a.substring(d,a.length),a=a.substring(0,d));return g.nameToUrl(a,h,c)},nameToUrl:function(a,h,f){var j,k,i,e,m=g.config,a=c(a,f&&f.fullName);if(d.jsExtRegExp.test(a))h=a+(h?h:"");else{j=m.paths;k=m.pkgs;f=a.split("/");for(e=f.length;e>0;e--)if(i=f.slice(0,e).join("/"),
j[i]){f.splice(0,e,j[i]);break}else if(i=k[i]){a=a===i.name?i.location+"/"+i.main:i.location;f.splice(0,e,a);break}h=f.join("/")+(h||".js");h=(h.charAt(0)==="/"||h.match(/^\w+:/)?"":m.baseUrl)+h}return m.urlArgs?h+((h.indexOf("?")===-1?"?":"&")+m.urlArgs):h}};g.jQueryCheck=V;g.resume=w;return g}function ia(){var a,c,d;if(n&&n.readyState==="interactive")return n;a=document.getElementsByTagName("script");for(c=a.length-1;c>-1&&(d=a[c]);c--)if(d.readyState==="interactive")return n=d;return null}var ja=
/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ka=/require\(\s*["']([^'"\s]+)["']\s*\)/g,ea=/^\.\//,aa=/\.js$/,M=Object.prototype.toString,r=Array.prototype,ga=r.slice,ha=r.splice,G=!!(typeof window!=="undefined"&&navigator&&document),ca=!G&&typeof importScripts!=="undefined",la=G&&navigator.platform==="PLAYSTATION 3"?/^complete$/:/^(complete|loaded)$/,da=typeof opera!=="undefined"&&opera.toString()==="[object Opera]",K={},D={},T=[],n=null,X=0,O=!1,d,r={},I,v,t,x,u,y,z,H,A,V,W;if(typeof define==="undefined"){if(typeof requirejs!==
"undefined")if(J(requirejs))return;else r=requirejs,requirejs=void 0;typeof require!=="undefined"&&!J(require)&&(r=require,require=void 0);d=requirejs=function(a,c,d){var k="_",j;!E(a)&&typeof a!=="string"&&(j=a,E(c)?(a=c,c=d):a=[]);if(j&&j.context)k=j.context;d=D[k]||(D[k]=fa(k));j&&d.configure(j);return d.require(a,c)};d.config=function(a){return d(a)};require||(require=d);d.toUrl=function(a){return D._.toUrl(a)};d.version="1.0.3";d.jsExtRegExp=/^\/|:|\?|\.js$/;v=d.s={contexts:D,skipAsync:{}};if(d.isAsync=
d.isBrowser=G)if(t=v.head=document.getElementsByTagName("head")[0],x=document.getElementsByTagName("base")[0])t=v.head=x.parentNode;d.onError=function(a){throw a;};d.load=function(a,c,h){d.resourcesReady(!1);a.scriptCount+=1;d.attach(h,a,c);if(a.jQuery&&!a.jQueryIncremented)U(a.jQuery,!0),a.jQueryIncremented=!0};define=function(a,c,d){var k,j;typeof a!=="string"&&(d=c,c=a,a=null);E(c)||(d=c,c=[]);!c.length&&J(d)&&d.length&&(d.toString().replace(ja,"").replace(ka,function(a,d){c.push(d)}),c=(d.length===
1?["require"]:["require","exports","module"]).concat(c));if(O&&(k=I||ia()))a||(a=k.getAttribute("data-requiremodule")),j=D[k.getAttribute("data-requirecontext")];(j?j.defQueue:T).push([a,c,d])};define.amd={multiversion:!0,plugins:!0,jQuery:!0};d.exec=function(a){return eval(a)};d.execCb=function(a,c,d,k){return c.apply(k,d)};d.addScriptToDom=function(a){I=a;x?t.insertBefore(a,x):t.appendChild(a);I=null};d.onScriptLoad=function(a){var c=a.currentTarget||a.srcElement,h;if(a.type==="load"||c&&la.test(c.readyState))n=
null,a=c.getAttribute("data-requirecontext"),h=c.getAttribute("data-requiremodule"),D[a].completeLoad(h),c.detachEvent&&!da?c.detachEvent("onreadystatechange",d.onScriptLoad):c.removeEventListener("load",d.onScriptLoad,!1)};d.attach=function(a,c,h,k,j,n){var o;if(G)return k=k||d.onScriptLoad,o=c&&c.config&&c.config.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script"),o.type=j||"text/javascript",o.charset="utf-8",o.async=!v.skipAsync[a],c&&o.setAttribute("data-requirecontext",
c.contextName),o.setAttribute("data-requiremodule",h),o.attachEvent&&!da?(O=!0,n?o.onreadystatechange=function(){if(o.readyState==="loaded")o.onreadystatechange=null,o.attachEvent("onreadystatechange",k),n(o)}:o.attachEvent("onreadystatechange",k)):o.addEventListener("load",k,!1),o.src=a,n||d.addScriptToDom(o),o;else ca&&(importScripts(a),c.completeLoad(h));return null};if(G){u=document.getElementsByTagName("script");for(H=u.length-1;H>-1&&(y=u[H]);H--){if(!t)t=y.parentNode;if(z=y.getAttribute("data-main")){if(!r.baseUrl)u=
z.split("/"),y=u.pop(),u=u.length?u.join("/")+"/":"./",r.baseUrl=u,z=y.replace(aa,"");r.deps=r.deps?r.deps.concat(z):[z];break}}}d.checkReadyState=function(){var a=v.contexts,c;for(c in a)if(!(c in K)&&a[c].waitCount)return;d.resourcesReady(!0)};d.resourcesReady=function(a){var c,h;d.resourcesDone=a;if(d.resourcesDone)for(h in a=v.contexts,a)if(!(h in K)&&(c=a[h],c.jQueryIncremented))U(c.jQuery,!1),c.jQueryIncremented=!1};d.pageLoaded=function(){if(document.readyState!=="complete")document.readyState=
"complete"};if(G&&document.addEventListener&&!document.readyState)document.readyState="loading",window.addEventListener("load",d.pageLoaded,!1);d(r);if(d.isAsync&&typeof setTimeout!=="undefined")A=v.contexts[r.context||"_"],A.requireWait=!0,setTimeout(function(){A.requireWait=!1;A.takeGlobalQueue();A.scriptCount||A.resume();d.checkReadyState()},0)}})();