needOpacityUpdate = (this.options.opacity < 1);

function noSpecs() {
	xit('should have specs');
}

if (!Array.prototype.map) {
  Array.prototype.map = function(fun /*, thisp */) {
    "use strict";

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== "function")
      throw new TypeError();

    var res = new Array(len);
    var thisp = arguments[1];
    for (var i = 0; i < len; i++) {
      if (i in t)
        res[i] = fun.call(thisp, t[i], i, t);
    }

    return res;
  };
}


keep keep keep keep replace keep keep keep keep

/*
 * L.Projection contains various geographical projections used by CRS classes.
 */

L.Projection = {};


/*
 * L.Handler.ScrollWheelZoom is used internally by L.Map to enable mouse scroll wheel zooming on the map.
 */

L.Map.mergeOptions({
	scrollWheelZoom: !L.Browser.touch
});

L.Map.ScrollWheelZoom = L.Handler.extend({
	addHooks: function () {
		L.DomEvent.on(this._map._container, 'mousewheel', this._onWheelScroll, this);
		this._delta = 0;
	},

	removeHooks: function () {
		L.DomEvent.off(this._map._container, 'mousewheel', this._onWheelScroll);
	},

	_onWheelScroll: function (e) {
		var delta = L.DomEvent.getWheelDelta(e);

		this._delta += delta;
		this._lastMousePos = this._map.mouseEventToContainerPoint(e);

		clearTimeout(this._timer);
		this._timer = setTimeout(L.Util.bind(this._performZoom, this), 40);

		L.DomEvent.preventDefault(e);
	},

	_performZoom: function () {
		var map = this._map,
			delta = Math.round(this._delta),
			zoom = map.getZoom();

		delta = Math.max(Math.min(delta, 4), -4);
		delta = map._limitZoom(zoom + delta) - zoom;

		this._delta = 0;

		if (!delta) { return; }

		var newZoom = zoom + delta,
			newCenter = this._getCenterForScrollWheelZoom(this._lastMousePos, newZoom);

		map.setView(newCenter, newZoom);
	},

	_getCenterForScrollWheelZoom: function (mousePos, newZoom) {
		var map = this._map,
			scale = map.getZoomScale(newZoom),
			viewHalf = map.getSize().divideBy(2),
			centerOffset = mousePos.subtract(viewHalf).multiplyBy(1 - 1 / scale),
			newCenterPoint = map._getTopLeftPoint().add(viewHalf).add(centerOffset);

		return map.unproject(newCenterPoint);
	}
});

L.Map.addInitHook('addHandler', 'scrollWheelZoom', L.Map.ScrollWheelZoom);


keep keep keep keep keep replace keep keep keep

if (process.env.APPVEYOR && e.message.match('timeout')) {

// AppVeyor VM is so slow that there's a large chance this test cases will time out,

jest.setTimeout(60000)

const path = require('path')
const fs = require('fs-extra')
const { defaultPreset } = require('@vue/cli/lib/options')
const create = require('@vue/cli-test-utils/createTestProject')
const serve = require('@vue/cli-test-utils/serveWithPuppeteer')

test('serve', async () => {
  const project = await create('e2e-serve', defaultPreset)

  await serve(
    () => project.run('vue-cli-service serve'),
    async ({ page, nextUpdate, helpers }) => {
      const msg = `Welcome to Your Vue.js App`
      expect(await helpers.getText('h1')).toMatch(msg)

      // test hot reload
      const file = await project.read(`src/App.vue`)
      project.write(`src/App.vue`, file.replace(msg, `Updated`))
      await nextUpdate() // wait for child stdout update signal
      await page.waitForXPath('//h1[contains(text(), "Updated")]')
    }
  )
})

test('serve with router', async () => {
  const project = await create('e2e-serve-router', Object.assign({}, defaultPreset, {
    plugins: {
      '@vue/cli-plugin-router': {}
    }
  }))

  await serve(
    () => project.run('vue-cli-service serve'),
    async ({ page, helpers }) => {
      expect(await helpers.getText('h1')).toMatch(`Welcome to Your Vue.js App`)
      expect(await helpers.hasElement('#nav')).toBe(true)
      expect(await helpers.hasClass('a[href="#/"]', 'router-link-exact-active')).toBe(true)
      expect(await helpers.hasClass('a[href="#/about"]', 'router-link-exact-active')).toBe(false)

      await page.click('a[href="#/about"]')
      expect(await helpers.getText('h1')).toMatch(`This is an about page`)
      expect(await helpers.hasElement('#nav')).toBe(true)
      expect(await helpers.hasClass('a[href="#/"]', 'router-link-exact-active')).toBe(false)
      expect(await helpers.hasClass('a[href="#/about"]', 'router-link-exact-active')).toBe(true)
    }
  )
})

test('serve with legacy router option', async () => {
  const project = await create('e2e-serve-legacy-router', Object.assign({}, defaultPreset, {
    router: true,
    routerHistoryMode: true
  }))

  await serve(
    () => project.run('vue-cli-service serve'),
    async ({ page, helpers }) => {
      expect(await helpers.getText('h1')).toMatch(`Welcome to Your Vue.js App`)
      expect(await helpers.hasElement('#nav')).toBe(true)
      expect(await helpers.hasClass('a[href="/"]', 'router-link-exact-active')).toBe(true)
      expect(await helpers.hasClass('a[href="/about"]', 'router-link-exact-active')).toBe(false)

      await page.click('a[href="/about"]')
      expect(await helpers.getText('h1')).toMatch(`This is an about page`)
      expect(await helpers.hasElement('#nav')).toBe(true)
      expect(await helpers.hasClass('a[href="/"]', 'router-link-exact-active')).toBe(false)
      expect(await helpers.hasClass('a[href="/about"]', 'router-link-exact-active')).toBe(true)
    }
  )
})

test('serve with legacy vuex option', async () => {
  const project = await create('e2e-serve-legacy-vuex', Object.assign({}, defaultPreset, {
    vuex: true
  }))

  await serve(
    () => project.run('vue-cli-service serve'),
    async ({ page, helpers }) => {
      expect(await helpers.getText('h1')).toMatch(`Welcome to Your Vue.js App`)
    }
  )
})

test('serve with inline entry', async () => {
  const project = await create('e2e-serve-inline-entry', defaultPreset)

  await fs.move(
    path.resolve(project.dir, 'src/main.js'),
    path.resolve(project.dir, 'src/index.js')
  )

  await serve(
    () => project.run('vue-cli-service serve src/index.js'),
    async ({ page, nextUpdate, helpers }) => {
      const msg = `Welcome to Your Vue.js App`
      expect(await helpers.getText('h1')).toMatch(msg)

      // test hot reload
      const file = await project.read(`src/App.vue`)
      project.write(`src/App.vue`, file.replace(msg, `Updated`))
      await nextUpdate() // wait for child stdout update signal
      await page.waitForXPath('//h1[contains(text(), "Updated")]')
    }
  )
})

test('serve with no public dir', async () => {
  const project = await create('e2e-serve-no-public', defaultPreset)

  await fs.remove(path.resolve(project.dir, 'public'))

  await serve(
    () => project.run('vue-cli-service serve'),
    async ({ page, nextUpdate, helpers }) => {
      const msg = `Welcome to Your Vue.js App`
      expect(await helpers.getText('h1')).toMatch(msg)

      // test hot reload
      const file = await project.read(`src/App.vue`)
      project.write(`src/App.vue`, file.replace(msg, `Updated`))
      await nextUpdate() // wait for child stdout update signal
      await page.waitForXPath('//h1[contains(text(), "Updated")]')
    }
  )
})

test('dart sass', async () => {
  const project = await create('test-dart-sass', exports.defaultPreset = {
    useConfigFiles: false,
    cssPreprocessor: 'dart-sass',
    plugins: {}
  })

  // should build successfully
  await project.run('vue-cli-service build')
})


# @vue/cli

``` sh
npm install -g @vue/cli
vue create my-project
```

[Full Docs](https://cli.vuejs.org/)


<template>

        {{ $t('org.vue.vue-webpack.dashboard.speed-stats.title') }}

      <VueIcon
        v-if="!assetsTotalSize"
        icon="more_horiz"
        class="blank-icon"
      />

        <SpeedStatsItem
          v-for="(stats, key) of speeds"
          :key="key"
          :stats="stats"
        />

</template>


<template>

        {{ $t('org.vue.vue-webpack.dashboard.asset-list.title') }}

      <VueIcon
        v-if="!assetsSorted.length"
        icon="more_horiz"
        class="blank-icon"
      />

      <template v-else>

{{ sizeField }}

Global

3G Slow

3G Fast

          <AssetListItem
            v-for="asset of assetsSorted"
            :key="asset.name"
            :asset="asset"
          />

      </template>

</template>


() => execa(binPath, ['serve'], { cwd }),

async ({ page, nextUpdate, helpers }) => {

write('App.vue', entryVue.replace(`{{ msg }}`, 'Updated'))

keep keep keep keep keep replace keep keep keep keep


import store from '../store'

// @vue/component
export default {
  store,

  inject: [
    'TaskDetails'
  ],

  data () {
    return {
      mode: null
    }
  },

  sharedData () {
    return {
      serveUrl: `org.vue.webpack.serve-url`,
      modernMode: `org.vue.webpack.modern-mode`
    }
  },

  computed: {
    sizeField: {
      get () { return this.$store.getters.sizeField },
      set (value) { this.$store.commit('sizeField', value) }
    },

    showModernBuild: {
      get () { return this.$store.state.showModernBuild },
      set (value) { this.$store.commit('showModernBuild', value) }
    }
  },

  watch: {
    modernMode: {
      handler (value) {
        this.showModernBuild = value
      },
      immediate: true
    }
  },

  created () {
    const mode = this.mode = this.TaskDetails.task.command.match(/vue-cli-service\s+(\S+)/)[1]
    this.$store.commit('mode', mode)
    if (mode === 'build') {
      this.syncMode('build-modern')
    }
    this.syncMode(mode)
  },

  methods: {
    syncMode (mode) {
      this.$watchSharedData(`org.vue.webpack.${mode}-stats`, value => {
        this.$store.commit('stats', {
          mode,
          value
        })
      })
    }
  }
}


# HTML and Static Assets

## HTML

### The Index File

The file `public/index.html` is a template that will be processed with [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin). During build, asset links will be injected automatically. In addition, Vue CLI also automatically injects resource hints (`preload/prefetch`), manifest/icon links (when PWA plugin is used), and the asset links for the JavaScript and CSS files produced during the build.

### Interpolation

Since the index file is used as a template, you can use the [lodash template](https://lodash.com/docs/4.17.10#template) syntax to interpolate values in it:

- `<%= VALUE %>` for unescaped interpolation;
- `<%- VALUE %>` for HTML-escaped interpolation;
- `<% expression %>` for JavaScript control flows.

In addition to the [default values exposed by `html-webpack-plugin`](https://github.com/jantimon/html-webpack-plugin#writing-your-own-templates), all [client-side env variables](./mode-and-env.md#using-env-variables-in-client-side-code) are also available directly. For example, to use the `BASE_URL` value:

``` html
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
```

See also:
- [publicPath](../config/#publicpath)

### Preload

[`<link rel="preload">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content) is a type of resource hint that is used to specify resources that your pages will need very soon after loading, which you therefore want to start preloading early in the lifecycle of a page load, before the browser's main rendering machinery kicks in.

By default, a Vue CLI app will automatically generate preload hints for all files that are needed for the initial rendering of your app.

The hints are injected using [@vue/preload-webpack-plugin](https://github.com/vuejs/preload-webpack-plugin) and can be modified / deleted via `chainWebpack` as `config.plugin('preload')`.

### Prefetch

[`<link rel="prefetch">`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Link_prefetching_FAQ) is a type of resource hint that tells the browser to prefetch content that the user may visit in the near future in the browser's idle time, after the page finishes loading.

By default, a Vue CLI app will automatically generate prefetch hints for all JavaScript files generated for async chunks (as a result of [on-demand code splitting via dynamic `import()`](https://webpack.js.org/guides/code-splitting/#dynamic-imports)).

The hints are injected using [@vue/preload-webpack-plugin](https://github.com/vuejs/preload-webpack-plugin) and can be modified / deleted via `chainWebpack` as `config.plugin('prefetch')`.

::: tip Note for multi page setups
When using a multipage setup, the plugin name above should be changed to match the structure 'prefetch-{pagename}', for example 'prefetch-app'.
:::

Example:

``` js
// vue.config.js
module.exports = {
  chainWebpack: config => {
    // remove the prefetch plugin
    config.plugins.delete('prefetch')

    // or:
    // modify its options:
    config.plugin('prefetch').tap(options => {
      options[0].fileBlacklist = options[0].fileBlacklist || []
      options[0].fileBlacklist.push(/myasyncRoute(.)+?\.js$/)
      return options
    })
  }
}
```

When the prefetch plugin is disabled, you can manually select specific chunks to prefetch using webpack's inline comments:

``` js
import(/* webpackPrefetch: true */ './someAsyncComponent.vue')
```

webpack's runtime will inject prefetch links when the parent chunk is loaded.

::: tip
Prefetch links will consume bandwidth. If you have a large app with many async chunks and your user are primarily mobile and thus bandwidth-aware, you may want to disable prefetch links and manually select chunks to prefetch.
:::

### Disable Index Generation

When using Vue CLI with an existing backend, you may need to disable the generation of `index.html` so that the generated assets can be used in a server-rendered page. To do so, the following can be added to [`vue.config.js`](../config/#vue-config-js):

``` js
// vue.config.js
module.exports = {
  // disable hashes in filenames
  filenameHashing: false,
  // delete HTML related webpack plugins
  chainWebpack: config => {
    config.plugins.delete('html')
    config.plugins.delete('preload')
    config.plugins.delete('prefetch')
  }
}
```

However, this is not really recommended because:

- Hard-coded file names makes it more difficult to implement efficient cache control.
- Hard-coded file names also do not play well with code-splitting, which generates additional JavaScript files with varying filenames.
- Hard-coded file names do not work with [Modern Mode](../guide/browser-compatibility.md#modern-mode).

Instead, you should consider using the [indexPath](../config/#indexpath) option to use the generated HTML as a view template in your server-side framework.

### Building a Multi-Page App

Not every app has to be an SPA. Vue CLI supports building a multi-paged app using the [`pages` option in `vue.config.js`](../config/#pages). The built app will efficiently share common chunks between multiple entries for optimal loading performance.

## Static Assets Handling

Static assets can be handled in two different ways:

- Imported in JavaScript or referenced in templates/CSS via relative paths. Such references will be handled by webpack.

- Placed in the `public` directory and referenced via absolute paths. These assets will simply be copied and not go through webpack.

### Relative Path Imports

When you reference a static asset using relative path (must start with `.`) inside JavaScript, CSS or `*.vue` files, the asset will be included into webpack's dependency graph. During this compilation process, all asset URLs such as `<img src="...">`, `background: url(...)` and CSS `@import` are **resolved as module dependencies**.

For example, `url(./image.png)` will be translated into `require('./image.png')`, and

``` html
<img src="./image.png">
```

will be compiled into:

``` js
h('img', { attrs: { src: require('./image.png') }})
```

Internally, we use `file-loader` to determine the final file location with version hashes and correct public base paths, and use `url-loader` to conditionally inline assets that are smaller than 4kb, reducing the amount of HTTP requests.

You can adjust the inline file size limit via [chainWebpack](../config/#chainwebpack). For example, to set the limit to 10kb instead:

``` js
// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('images')
        .use('url-loader')
          .loader('url-loader')
          .tap(options => Object.assign(options, { limit: 10240 }))
  }
}
```

### URL Transform Rules

- If the URL is an absolute path (e.g. `/images/foo.png`), it will be preserved as-is.

- If the URL starts with `.`, it's interpreted as a relative module request and resolved based on the folder structure on your file system.

- If the URL starts with `~`, anything after it is interpreted as a module request. This means you can even reference assets inside node modules:

  ``` html
  <img src="~some-npm-package/foo.png">
  ```

- If the URL starts with `@`, it's also interpreted as a module request. This is useful because Vue CLI by default aliases `@` to `<projectRoot>/src`. **(templates only)**

### The `public` Folder

Any static assets placed in the `public` folder will simply be copied and not go through webpack. You need to reference them using absolute paths.

Note we recommend importing assets as part of your module dependency graph so that they will go through webpack with the following benefits:

- Scripts and stylesheets get minified and bundled together to avoid extra network requests.
- Missing files cause compilation errors instead of 404 errors for your users.
- Result filenames include content hashes so you don’t need to worry about browsers caching their old versions.

The `public` directory is provided as an **escape hatch**, and when you reference it via absolute path, you need to take into account where your app will be deployed. If your app is not deployed at the root of a domain, you will need to prefix your URLs with the [publicPath](../config/#publicpath):

- In `public/index.html` or other HTML files used as templates by `html-webpack-plugin`, you need to prefix the link with `<%= BASE_URL %>`:

  ``` html
  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
  ```

- In templates, you will need to first pass the base URL to your component:

  ``` js
  data () {
    return {
      publicPath: process.env.BASE_URL
    }
  }
  ```

  Then:

  ``` html
  <img :src="`${publicPath}my-image.png`">
  ```

### When to use the `public` folder

- You need a file with a specific name in the build output.
- You have thousands of images and need to dynamically reference their paths.
- Some library may be incompatible with Webpack and you have no other option but to include it as a `<script>` tag.


const fs = require('fs')
const path = require('path')
const LRU = require('lru-cache')
const semver = require('semver')
const execa = require('execa')
const chalk = require('chalk')
// Connectors
const cwd = require('./cwd')
const folders = require('./folders')
const progress = require('./progress')
const logs = require('./logs')
// Context
const getContext = require('../context')
// Utils
const { isPlugin, hasYarn, resolveModule } = require('@vue/cli-shared-utils')
const { progress: installProgress } = require('@vue/cli/lib/util/executeCommand')
const PackageManager = require('@vue/cli/lib/util/ProjectPackageManager')
const { resolveModuleRoot } = require('../util/resolve-path')
const { notify } = require('../util/notification')
const { log } = require('../util/logger')

const PROGRESS_ID = 'dependency-installation'
const CLI_SERVICE = '@vue/cli-service'

// Caches
const metadataCache = new LRU({
  max: 200,
  maxAge: 1000 * 60 * 30 // 30 min.
})

// Local
let dependencies

function list (file, context) {
  const pkg = folders.readPackage(file, context)
  dependencies = []
  dependencies = dependencies.concat(
    findDependencies(pkg.devDependencies || {}, 'devDependencies', file, context)
  )
  dependencies = dependencies.concat(
    findDependencies(pkg.dependencies || {}, 'dependencies', file, context)
  )
  return dependencies
}

function findOne (id, context) {
  return dependencies.find(
    p => p.id === id
  )
}

function findDependencies (deps, type, file, context) {
  return Object.keys(deps).filter(
    id => !isPlugin(id) && id !== CLI_SERVICE
  ).map(
    id => ({
      id,
      versionRange: deps[id],
      installed: isInstalled({ id, file }),
      website: getLink({ id, file }, context),
      type,
      baseFir: file
    })
  )
}

function getPath ({ id, file = cwd.get() }) {
  const filePath = resolveModule(path.join(id, 'package.json'), file)
  if (!filePath) return
  return resolveModuleRoot(filePath, id)
}

function isInstalled ({ id, file = cwd.get() }) {
  const resolvedPath = getPath({ id, file })
  return resolvedPath && fs.existsSync(resolvedPath)
}

function readPackage ({ id, file }, context) {
  try {
    return folders.readPackage(getPath({ id, file }), context)
  } catch (e) {
    console.log(e)
  }
  return {}
}

function invalidatePackage ({ id, file }, context) {
  return folders.invalidatePackage(getPath({ id, file }), context)
}

async function getMetadata (id, context) {
  let metadata = metadataCache.get(id)
  if (metadata) {
    return metadata
  }

  if (hasYarn()) {
    try {
      const { stdout } = await execa('yarn', ['info', id, '--json'], {
        cwd: cwd.get()
      })
      metadata = JSON.parse(stdout).data
    } catch (e) {
      // yarn info failed
    }
  }

  if (!metadata) {
    try {
      metadata = await (new PackageManager({ context: cwd.get() })).getMetadata()
    } catch (e) {
      // No connection?
    }
  }

  if (metadata) {
    metadataCache.set(id, metadata)
    return metadata
  } else {
    log('Dependencies', chalk.yellow(`Can't load metadata`), id)
  }
}

async function getVersion ({ id, installed, versionRange, baseDir }, context) {
  let current

  // Is local dep
  const localPath = getLocalPath(id, context)

  // Read module package.json
  if (installed) {
    const pkg = readPackage({ id, file: baseDir }, context)
    current = pkg.version
  } else {
    current = null
  }

  // Metadata
  let latest, wanted
  const metadata = await getMetadata(id, context)
  if (metadata) {
    latest = metadata['dist-tags'].latest

    const versions = Array.isArray(metadata.versions) ? metadata.versions : Object.keys(metadata.versions)
    wanted = semver.maxSatisfying(versions, versionRange)
  }

  if (!latest) latest = current
  if (!wanted) wanted = current

  return {
    current,
    latest,
    wanted,
    range: versionRange,
    localPath
  }
}

function getLocalPath (id, context) {
  const projects = require('./projects')
  const projectPkg = folders.readPackage(projects.getCurrent(context).path, context, true)
  const deps = Object.assign(
    {},
    projectPkg.dependencies || {},
    projectPkg.devDependencies || {}
  )
  const range = deps[id]
  if (range && range.match(/^file:/)) {
    const localPath = range.substr('file:'.length)
    return path.resolve(cwd.get(), localPath)
  }
  return null
}

async function getDescription ({ id }, context) {
  const metadata = await getMetadata(id, context)
  if (metadata) {
    return metadata.description
  }
  return null
}

function getLink ({ id, file }, context) {
  const pkg = readPackage({ id, file }, context)
  return pkg.homepage ||
    (pkg.repository && pkg.repository.url) ||
    `https://www.npmjs.com/package/${id.replace(`/`, `%2F`)}`
}

function install ({ id, type, range }, context) {
  return progress.wrap(PROGRESS_ID, context, async setProgress => {
    setProgress({
      status: 'dependency-install',
      args: [id]
    })

    let arg
    if (range) {
      arg = `${id}@${range}`
    } else {
      arg = id
    }

    const pm = new PackageManager({ context: cwd.get() })
    await pm.add(arg, type === 'devDependencies')

    logs.add({
      message: `Dependency ${id} installed`,
      type: 'info'
    }, context)

    notify({
      title: `Dependency installed`,
      message: `Dependency ${id} successfully installed`,
      icon: 'done'
    })

    list(cwd.get(), context)

    return findOne(id, context)
  })
}

function uninstall ({ id }, context) {
  return progress.wrap(PROGRESS_ID, context, async setProgress => {
    setProgress({
      status: 'dependency-uninstall',
      args: [id]
    })

    const dep = findOne(id, context)

    const pm = new PackageManager({ context: cwd.get() })
    await pm.remove(id)

    logs.add({
      message: `Dependency ${id} uninstalled`,
      type: 'info'
    }, context)

    notify({
      title: `Dependency uninstalled`,
      message: `Dependency ${id} successfully uninstalled`,
      icon: 'done'
    })

    return dep
  })
}

function update ({ id }, context) {
  return progress.wrap(PROGRESS_ID, context, async setProgress => {
    setProgress({
      status: 'dependency-update',
      args: [id]
    })

    const dep = findOne(id, context)
    const { current, wanted } = await getVersion(dep, context)

    const pm = new PackageManager({ context: cwd.get() })
    await pm.upgrade(id)

    logs.add({
      message: `Dependency ${id} updated from ${current} to ${wanted}`,
      type: 'info'
    }, context)

    notify({
      title: `Dependency updated`,
      message: `Dependency ${id} was successfully updated`,
      icon: 'done'
    })

    invalidatePackage({ id }, context)

    return findOne(id)
  })
}

function updateAll (context) {
  return progress.wrap(PROGRESS_ID, context, async setProgress => {
    const deps = list(cwd.get(), context)
    let updatedDeps = []
    for (const dep of deps) {
      const version = await getVersion(dep, context)
      if (version.current !== version.wanted) {
        updatedDeps.push(dep)
        invalidatePackage({ id: dep.id }, context)
      }
    }

    if (!updatedDeps.length) {
      notify({
        title: `No updates available`,
        message: `No dependency to update in the version ranges declared in package.json`,
        icon: 'done'
      })
      return []
    }

    setProgress({
      status: 'dependencies-update',
      args: [updatedDeps.length]
    })

    const pm = new PackageManager({ context: cwd.get() })
    await pm.upgrade(updatedDeps.map(p => p.id).join(' '))

    notify({
      title: `Dependencies updated`,
      message: `${updatedDeps.length} dependencies were successfully updated`,
      icon: 'done'
    })

    return updatedDeps
  })
}

function setup (context) {
  // Package installation progress events
  installProgress.on('progress', value => {
    if (progress.get(PROGRESS_ID)) {
      progress.set({ id: PROGRESS_ID, progress: value }, context)
    }
  })
  installProgress.on('log', message => {
    if (progress.get(PROGRESS_ID)) {
      progress.set({ id: PROGRESS_ID, info: message }, context)
    }
  })
}

setup(getContext())

module.exports = {
  list,
  findOne,
  getPath,
  getMetadata,
  getLink,
  getDescription,
  getVersion,
  install,
  uninstall,
  update,
  updateAll,
  invalidatePackage
}


keep keep keep keep keep replace keep keep keep keep keep


# UI Localization

## Translate the standard UI

To make collaboration and synchronisation easier, the English source locale from the `dev` branch is automatically imported to [Transifex](https://www.transifex.com/vuejs/vue-cli/dashboard/), a platform for collaborative translation.

For existing languages, you can [sign up as a translator](https://www.transifex.com/vuejs/vue-cli/dashboard/).
For new languages, you can [request the new language](https://www.transifex.com/vuejs/vue-cli/dashboard/) after signing up.

In either case you will be able to translate keys as they are added or changed in the source locale.

## Translate your plugin

You can put locale files compatible with [vue-i18n](https://github.com/kazupon/vue-i18n) in a `locales` folder at the root of your plugin. They will be automatically loaded into the client when the project is opened. You can then use `$t` to translate strings in your components and other vue-i18n helpers. Also, the strings used in the UI API (like `describeTask`) will go through vue-i18n as well to you can localize them.

Example `locales` folder:

```
vue-cli-plugin/locales/en.json
vue-cli-plugin/locales/fr.json
```

Example usage in API:

```js
api.describeConfig({
  // vue-i18n path
  description: 'com.my-name.my-plugin.config.foo'
})
```

::: danger
Make sure to namespace the id correctly, since it must be unique across all plugins. It's recommended to use the [reverse domain name notation](https://en.wikipedia.org/wiki/Reverse_domain_name_notation).
:::

Example usage in components:

```html
<VueButton>{{ $t('com.my-name.my-plugin.actions.bar') }}</VueButton>
```

You can also load the locale files in a client addon if you prefer, using the `ClientAddonApi`:

```js
// Load the locale files (uses vue-i18n)
const locales = require.context('./locales', true, /[a-z0-9]+\.json$/i)
locales.keys().forEach(key => {
  const locale = key.match(/([a-z0-9]+)\./i)[1]
  ClientAddonApi.addLocalization(locale, locales(key))
})
```


<template>
  <component
    v-if="component"
    :is="component"
  />

    <VueIcon
      icon="cake"
      class="big"
    />

      {{ $t('org.vue.components.client-addon-component.timeout') }}

      {{ $t('org.vue.components.client-addon-component.timeout-info') }}

    <VueLoadingIndicator />

</template>


const generateWithPlugin = require('@vue/cli-test-utils/generateWithPlugin')

test('base', async () => {
  const { pkg, files } = await generateWithPlugin([
    {
      id: 'unit-jest',
      apply: require('../generator'),
      options: {}
    },
    // mock presence of the babel & eslint plugin
    {
      id: 'babel',
      apply: () => {},
      options: {}
    },
    {
      id: 'eslint',
      apply: () => {},
      options: {}
    }
  ])

  expect(pkg.scripts['test:unit']).toBe('vue-cli-service test:unit')
  expect(pkg.devDependencies).toHaveProperty('@vue/test-utils')

  // should inject babel-jest
  expect(pkg.devDependencies).toHaveProperty('babel-jest')
  expect(pkg.devDependencies).toHaveProperty('@babel/core')
  // eslint
  expect(files['tests/unit/.eslintrc.js']).toMatch('jest: true')

  const spec = files['tests/unit/example.spec.js']
  expect(spec).toMatch(`expect(wrapper.text()).toMatch(msg)`)
})

test('without babel/eslint', async () => {
  const { pkg, files } = await generateWithPlugin([
    {
      id: 'unit-jest',
      apply: require('../generator'),
      options: {}
    }
  ])

  expect(pkg.devDependencies).not.toHaveProperty('babel-jest')
  expect(files['tests/unit/.eslintrc.js']).toBeUndefined()
})

test('with TS', async () => {
  const { files } = await generateWithPlugin([
    {
      id: 'unit-jest',
      apply: require('../generator'),
      options: {}
    },
    // mock presence of the ts plugin
    {
      id: 'typescript',
      apply: () => {},
      options: {}
    }
  ])

  const spec = files['tests/unit/example.spec.ts']
  expect(spec).toMatch(`expect(wrapper.text()).toMatch(msg)`)
})

test('bare', async () => {
  const { files } = await generateWithPlugin([
    {
      id: 'unit-jest',
      apply: require('../generator'),
      options: {}
    },
    {
      id: '@vue/cli-service',
      apply: () => {},
      options: { bare: true }
    }
  ])

  const spec = files['tests/unit/example.spec.js']
  expect(spec).toMatch(`const wrapper = shallowMount(App)`)
  expect(spec).toMatch(`expect(wrapper.text()).toMatch(\`Welcome to Your Vue.js App\`)`)
})

test('TS + bare', async () => {
  const { files } = await generateWithPlugin([
    {
      id: 'unit-jest',
      apply: require('../generator'),
      options: {}
    },
    {
      id: 'typescript',
      apply: () => {},
      options: {}
    },
    {
      id: '@vue/cli-service',
      apply: () => {},
      options: { bare: true }
    }
  ])

  const spec = files['tests/unit/example.spec.ts']
  expect(spec).toMatch(`const wrapper = shallowMount(App)`)
  expect(spec).toMatch(`expect(wrapper.text()).toMatch(\`Welcome to Your Vue.js + TypeScript App\`)`)
})


<template functional>

{{ props.module.name }}

{{ props.module.size | size('B') }}

        <VueLoadingBar :value="props.module.ratio" class="primary"/>

</template>


keep keep keep keep replace keep keep keep keep keep


module.exports = function injectOptions (fileInfo, api, { injections }) {
  const j = api.jscodeshift
  const root = j(fileInfo.source)

  const toPropertyAST = i => {
    return j(`({${i}})`).nodes()[0].program.body[0].expression.properties[0]
  }

  const properties = root
    .find(j.NewExpression, {
      callee: { name: 'Vue' },
      arguments: [{ type: 'ObjectExpression' }]
    })
    .map(path => path.get('arguments', 0))
    .get()
    .node
    .properties

  const toPropertyHash = p => `${p.key.name}: ${j(p.value).toSource()}`
  const propertySet = new Set(properties.map(toPropertyHash))
  const nonDuplicates = p => !propertySet.has(toPropertyHash(p))

  // inject at index length - 1 as it's usually the render fn
  properties.splice(-1, 0, ...injections.map(toPropertyAST).filter(nonDuplicates))

  return root.toSource()
}


(*
Copyright (c) 2015-present, Facebook, Inc.

This source code is licensed under the MIT license found in the
LICENSE file at
https://github.com/facebookincubator/create-react-app/blob/master/LICENSE
*)

property targetTab: null
property targetTabIndex: -1
property targetWindow: null

on run argv
  set theURL to item 1 of argv

  tell application "Chrome"

    if (count every window) = 0 then
      make new window
    end if

    -- 1: Looking for tab running debugger
    -- then, Reload debugging tab if found
    -- then return
    set found to my lookupTabWithUrl(theURL)
    if found then
      set targetWindow's active tab index to targetTabIndex
      tell targetTab to reload
      tell targetWindow to activate
      set index of targetWindow to 1
      return
    end if

    -- 2: Looking for Empty tab
    -- In case debugging tab was not found
    -- We try to find an empty tab instead
    set found to my lookupTabWithUrl("chrome://newtab/")
    if found then
      set targetWindow's active tab index to targetTabIndex
      set URL of targetTab to theURL
      tell targetWindow to activate
      return
    end if

    -- 3: Create new tab
    -- both debugging and empty tab were not found
    -- make a new tab with url
    tell window 1
      activate
      make new tab with properties {URL:theURL}
    end tell
  end tell
end run

-- Function:
-- Lookup tab with given url
-- if found, store tab, index, and window in properties
-- (properties were declared on top of file)
on lookupTabWithUrl(lookupUrl)
  tell application "Chrome"
    -- Find a tab with the given url
    set found to false
    set theTabIndex to -1
    repeat with theWindow in every window
      set theTabIndex to 0
      repeat with theTab in every tab of theWindow
        set theTabIndex to theTabIndex + 1
        if (theTab's URL as string) contains lookupUrl then
          -- assign tab, tab index, and window to properties
          set targetTab to theTab
          set targetTabIndex to theTabIndex
          set targetWindow to theWindow
          set found to true
          exit repeat
        end if
      end repeat

      if found then
        exit repeat
      end if
    end repeat
  end tell
  return found
end lookupTabWithUrl


module.exports = (api, options) => {
  api.chainWebpack(webpackConfig => {
    const target = process.env.VUE_CLI_BUILD_TARGET
    if (target && target !== 'app') {
      return
    }

    const name = api.service.pkg.name
    const userOptions = options.pwa || {}

    // the pwa plugin hooks on to html-webpack-plugin
    // and injects icons, manifest links & other PWA related tags into <head>
    webpackConfig
      .plugin('pwa')
        .use(require('./lib/HtmlPwaPlugin'), [Object.assign({
          name
        }, userOptions)])
        .after('html')

    // generate /service-worker.js in production mode
    if (process.env.NODE_ENV === 'production') {
      // Default to GenerateSW mode, though InjectManifest also might be used.
      const workboxPluginMode = userOptions.workboxPluginMode || 'GenerateSW'
      const workboxWebpackModule = require('workbox-webpack-plugin')

      if (!(workboxPluginMode in workboxWebpackModule)) {
        throw new Error(
          `${workboxPluginMode} is not a supported Workbox webpack plugin mode. ` +
          `Valid modes are: ${Object.keys(workboxWebpackModule).join(', ')}`
        )
      }

      const defaultOptions = {
        exclude: [
          /\.map$/,
          /img\/icons\//,
          /favicon\.ico$/,
          /^manifest.*\.js?$/
        ]
      }

      const defaultGenerateSWOptions = workboxPluginMode === 'GenerateSW' ? {
        cacheId: name
      } : {}

      const workBoxConfig = Object.assign(defaultOptions, defaultGenerateSWOptions, userOptions.workboxOptions)

      webpackConfig
        .plugin('workbox')
        .use(workboxWebpackModule[workboxPluginMode], [workBoxConfig])
    }
  })

  // install dev server middleware for resetting service worker during dev
  const createNoopServiceWorkerMiddleware = require('./lib/noopServiceWorkerMiddleware')
  api.configureDevServer(app => {
    app.use(createNoopServiceWorkerMiddleware())
  })
}


* Fixed a bug where double click zoom wouldn't work if popup is opened on map click

Leaflet Changelog
=================

## 0.2 (master)

 * Added **WMS support** (L.TileLayer.WMS), currently EPSG:3857 only.
 * `L.Circle` is now zoom-dependent (with radius in meters); circle of a permanent size is now called `L.CircleMarker`.
 * Disabled zoom animation on Android by default because it's buggy on some devices (will be enabled back when it's stable enough). [#32](https://github.com/CloudMade/Leaflet/issues/32)
 * Added `mouseover` and `mouseout` events to map, markers and paths; added map `mousemove` event.
 * Added `setLatLng` method to `L.Marker`.
 * Added `maxZoom` argument to `map.locateAndSetView` method.
 * Improved geolocation error handling: better error messages, explicit timeout, set world view on locateAndSetView failure. [#61](https://github.com/CloudMade/Leaflet/issues/61)
 * Fixed a bug where paths would not appear in IE8.
 * Fixed a bug where zooming is broken if the map contains a polygon and you zoom to an area where it's not visible. [#47](https://github.com/CloudMade/Leaflet/issues/47)
 * Fixed a bug where closed polylines would not appear on the map.
 * Fixed a bug where map isn't displayed in Firefox when there's an `img { max-width: 100% }` rule.

## 0.1 (2011-05-13)

 * Initial Leaflet release.


L.Map.include({
	openPopup: function(popup) {
		this.closePopup();
		this._popup = popup;
		return this.addLayer(popup);
	},

	closePopup: function() {
		if (this._popup) {
			this.removeLayer(this._popup);
		}
		return this;
	}
});


/*
 * L.Transformation is an utility class to perform simple point transformations through a 2d-matrix.
 */

L.Transformation = L.Class.extend({
	initialize: function(/*Number*/ a, /*Number*/ b, /*Number*/ c, /*Number*/ d) {
		this._a = a;
		this._b = b;
		this._c = c;
		this._d = d;
	},

	transform: function(point, scale) {
		return this._transform(point.clone(), scale);
	},

	// destructive transform (faster)
	_transform: function(/*Point*/ point, /*Number*/ scale) /*-> Point*/ {
		scale = scale || 1;
		point.x = scale * (this._a * point.x + this._b);
		point.y = scale * (this._c * point.y + this._d);
		return point;
	},

	untransform: function(/*Point*/ point, /*Number*/ scale) /*-> Point*/ {
		scale = scale || 1;
		return new L.Point(
			(point.x/scale - this._b) / this._a,
			(point.y/scale - this._d) / this._c);
	}
});


describe('Events', function() {
	var Klass;

	beforeEach(function() {
		Klass = L.Class.extend({
			includes: L.Mixin.Events
		});
	});

	describe('#fireEvent', function() {

		it('should fire all listeners added through #addEventListener', function() {
			var obj = new Klass(),
				spy = jasmine.createSpy(),
				spy2 = jasmine.createSpy(),
				spy3 = jasmine.createSpy();

			obj.addEventListener('test', spy);
			obj.addEventListener('test', spy2);
			obj.addEventListener('other', spy3);

			expect(spy).not.toHaveBeenCalled();
			expect(spy2).not.toHaveBeenCalled();
			expect(spy3).not.toHaveBeenCalled();

			obj.fireEvent('test');

			expect(spy).toHaveBeenCalled();
			expect(spy2).toHaveBeenCalled();
			expect(spy3).not.toHaveBeenCalled();
		});

		it('should provide event object to listeners and execute them in the right context', function() {
			var obj = new Klass(),
				obj2 = new Klass(),
				foo = {};

			function listener1(e) {
				expect(e.type).toEqual('test');
				expect(e.target).toEqual(obj);
				expect(this).toEqual(obj);
				expect(e.bar).toEqual(3);
			};

			function listener2(e) {
				expect(e.target).toEqual(obj2);
				expect(this).toEqual(foo);
			};

			obj.addEventListener('test', listener1);
			obj2.addEventListener('test', listener2, foo);

			obj.fireEvent('test', {bar: 3});
		});

		it('should not call listeners removed through #removeEventListener', function() {
			var obj = new Klass(),
				spy = jasmine.createSpy();

			obj.addEventListener('test', spy);
			obj.removeEventListener('test', spy);

			obj.fireEvent('test');

			expect(spy).not.toHaveBeenCalled();
		});
	});

	describe('#on, #off & #fire', function() {

		it('should work like #addEventListener && #removeEventListener', function() {
			var obj = new Klass(),
				spy = jasmine.createSpy();

			obj.on('test', spy);
			obj.fire('test');

			expect(spy).toHaveBeenCalled();

			obj.off('test', spy);
			obj.fireEvent('test');

			expect(spy.callCount).toBeLessThan(2);
		});

		it('should not override existing methods with the same name', function() {
			var spy1 = jasmine.createSpy(),
				spy2 = jasmine.createSpy(),
				spy3 = jasmine.createSpy();

			var Klass2 = L.Class.extend({
				includes: L.Mixin.Events,
				on: spy1,
				off: spy2,
				fire: spy3
			});

			var obj = new Klass2();

			obj.on();
			expect(spy1).toHaveBeenCalled();

			obj.off();
			expect(spy2).toHaveBeenCalled();

			obj.fire();
			expect(spy3).toHaveBeenCalled();
		});
	});
});