[
  {
    "path": ".babelrc",
    "content": "{\n    \"presets\": [\n        [\"env\", {\n            \"modules\": false\n        }]\n    ],\n    \"plugins\": [\n        \"syntax-dynamic-import\",\n        \"external-helpers\"\n    ],\n    \"ignore\": [\n        \"dist/*.js\"\n    ]\n}\n"
  },
  {
    "path": ".circleci/config.yml",
    "content": "# Javascript Node CircleCI 2.0 configuration file\n#\n# Check https://circleci.com/docs/2.0/language-javascript/ for more details\n#\nversion: 2\njobs:\n  build:\n    docker:\n      # specify the version you desire here\n      - image: circleci/node:10.23.3\n      \n      # Specify service dependencies here if necessary\n      # CircleCI maintains a library of pre-built images\n      # documented at https://circleci.com/docs/2.0/circleci-images/\n      # - image: circleci/mongo:3.4.4\n\n    working_directory: ~/repo\n\n    steps:\n      - checkout\n\n      # Download and cache dependencies\n      - restore_cache:\n          keys:\n          - v1-dependencies-{{ checksum \"package.json\" }}\n          # fallback to using the latest cache if no exact match is found\n          - v1-dependencies-\n\n      - run:\n          name: Workaround for GoogleChrome/puppeteer#290\n          command: 'sh .circleci/setup_puppeteer.sh'\n\n      - run: yarn install\n\n      - save_cache:\n          paths:\n            - node_modules\n          key: v1-dependencies-{{ checksum \"package.json\" }}\n        \n      # run tests!\n      - run: yarn lint\n      - run: yarn test\n"
  },
  {
    "path": ".circleci/setup_puppeteer.sh",
    "content": "#!/bin/bash\n\nsudo apt-get update\nsudo apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \\\n  libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \\\n  libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \\\n  libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \\\n  ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = space\nindent_size = 4\ntab_width = 4\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"extends\": \"standard\",\n  \"env\": {\n    \"browser\": true,\n    \"es6\": true,\n    \"jest\": true,\n    \"mocha\": true\n  }\n}"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "content": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# You may wish to alter this file to override the set of languages analyzed,\n# or to provide custom queries or build logic.\n#\n# ******** NOTE ********\n# We have attempted to detect the languages in your repository. Please check\n# the `language` matrix defined below to confirm you have the correct set of\n# supported CodeQL languages.\n#\nname: \"CodeQL\"\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    # The branches below must be a subset of the branches above\n    branches: [ master ]\n  schedule:\n    - cron: '40 0 * * 4'\n\njobs:\n  analyze:\n    name: Analyze\n    runs-on: ubuntu-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [ 'javascript' ]\n        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]\n        # Learn more:\n        # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed\n\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v2\n\n    # Initializes the CodeQL tools for scanning.\n    - name: Initialize CodeQL\n      uses: github/codeql-action/init@v1\n      with:\n        languages: ${{ matrix.language }}\n        # If you wish to specify custom queries, you can do so here or in a config file.\n        # By default, queries listed here will override any specified in a config file.\n        # Prefix the list here with \"+\" to use these queries and those in the config file.\n        # queries: ./path/to/local/query, your-org/your-repo/queries@main\n\n    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).\n    # If this step fails, then you should remove it and run the build manually (see below)\n    - name: Autobuild\n      uses: github/codeql-action/autobuild@v1\n\n    # ℹ️ Command-line programs to run using the OS shell.\n    # 📚 https://git.io/JvXDl\n\n    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines\n    #    and modify them (or add more) to build your code if your project\n    #    uses a compiled language\n\n    #- run: |\n    #   make bootstrap\n    #   make release\n\n    - name: Perform CodeQL Analysis\n      uses: github/codeql-action/analyze@v1\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules\ndist\nlib\nnpm-debug.log\npackage-lock.json\n.idea\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 Awe\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Vue-Lazyload\n\n[![Build Status](https://img.shields.io/circleci/project/hilongjw/vue-lazyload/master.svg?style=flat-square)](https://circleci.com/gh/hilongjw/vue-lazyload)\n[![npm version](https://img.shields.io/npm/v/vue-lazyload.svg?style=flat-square)](http://badge.fury.io/js/vue-lazyload)\n[![npm downloads](https://img.shields.io/npm/dm/vue-lazyload.svg?style=flat-square)](http://badge.fury.io/js/vue-lazyload)\n[![npm license](https://img.shields.io/npm/l/vue-lazyload.svg?style=flat-square)](http://badge.fury.io/js/vue-lazyload)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)\n[![CDNJS version](https://img.shields.io/cdnjs/v/vue-lazyload.svg)](https://cdnjs.com/libraries/vue-lazyload)\n\nVue module for lazyloading images in your applications. Some of goals of this project worth noting include:\n\n* Be lightweight, powerful and easy to use\n* Work on any image type\n* Add loading class while image is loading\n* Supports both of Vue 1.0 and Vue 2.0\n\n# For Vue 3\nPlease use vue-lazyload@3.x, see [here](https://github.com/hilongjw/vue-lazyload/tree/next)\n\n# Table of Contents\n\n* [___Demo___](#demo)\n* [___Requirements___](#requirements)\n* [___Installation___](#installation)\n* [___Usage___](#usage)\n * [___Constructor Options___](#constructor-options)\n * [___Implementation___](#implementation)\n    * [___Basic___](#basic)\n    * [___Css state___](#css-state)\n* [___Methods___](#methods)\n  * [__Event hook__](#event-hook)\n  * [__LazyLoadHandler__](#lazyloadhandler)\n  * [__Performance__](#performance)\n* [___Authors && Contributors___](#authors-&&-Contributors)\n* [___License___](#license)\n\n\n# Demo\n\n[___Demo___](http://hilongjw.github.io/vue-lazyload/)\n\n# Requirements\n\n- [Vue.js](https://github.com/vuejs/vue) `1.x` or `2.x`\n\n\n# Installation\n\n## npm\n\n```bash\n\n$ npm i vue-lazyload -S\n\n```\n\n## yarn\n\n```bash\n\n$ yarn add vue-lazyload\n\n```\n\n## CDN\n\nCDN: [https://unpkg.com/vue-lazyload/vue-lazyload.js](https://unpkg.com/vue-lazyload/vue-lazyload.js)\n\n```html\n<script src=\"https://unpkg.com/vue-lazyload/vue-lazyload.js\"></script>\n<script>\n  Vue.use(VueLazyload)\n  ...\n</script>\n\n```\n\n# Usage\n\nmain.js:\n\n```javascript\n\nimport Vue from 'vue'\nimport App from './App.vue'\nimport VueLazyload from 'vue-lazyload'\n\nVue.use(VueLazyload)\n\n// or with options\nconst loadimage = require('./assets/loading.gif')\nconst errorimage = require('./assets/error.gif')\n\nVue.use(VueLazyload, {\n  preLoad: 1.3,\n  error: errorimage,\n  loading: loadimage,\n  attempt: 1\n})\n\nnew Vue({\n  el: 'body',\n  components: {\n    App\n  }\n})\n```\n\ntemplate:\n\n```html\n<ul>\n  <li v-for=\"img in list\">\n    <img v-lazy=\"img.src\" >\n  </li>\n</ul>\n```\n\nuse `v-lazy-container` work with raw HTML\n\n```html\n<div v-lazy-container=\"{ selector: 'img' }\">\n  <img data-src=\"//domain.com/img1.jpg\">\n  <img data-src=\"//domain.com/img2.jpg\">\n  <img data-src=\"//domain.com/img3.jpg\">  \n</div>\n```\n\ncustom `error` and `loading` placeholder image\n\n```html\n<div v-lazy-container=\"{ selector: 'img', error: 'xxx.jpg', loading: 'xxx.jpg' }\">\n  <img data-src=\"//domain.com/img1.jpg\">\n  <img data-src=\"//domain.com/img2.jpg\">\n  <img data-src=\"//domain.com/img3.jpg\">  \n</div>\n```\n\n```html\n<div v-lazy-container=\"{ selector: 'img' }\">\n  <img data-src=\"//domain.com/img1.jpg\" data-error=\"xxx.jpg\">\n  <img data-src=\"//domain.com/img2.jpg\" data-loading=\"xxx.jpg\">\n  <img data-src=\"//domain.com/img3.jpg\">  \n</div>\n```\n\n## Constructor Options\n\n|key|description|default|options|\n|:---|---|---|---|\n| `preLoad`|proportion of pre-loading height|`1.3`|`Number`|\n|`error`|src of the image upon load fail|`'data-src'`|`String`\n|`loading`|src of the image while loading|`'data-src'`|`String`|\n|`attempt`|attempts count|`3`|`Number`|\n|`listenEvents`|events that you want vue listen for|`['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove']`| [Desired Listen Events](#desired-listen-events) |\n|`adapter`| dynamically modify the attribute of element |`{ }`| [Element Adapter](#element-adapter) |\n|`filter`| the image's listener filter |`{ }`| [Image listener filter](#image-listener-filter) |\n|`lazyComponent`| lazyload component | `false` | [Lazy Component](#lazy-component)\n| `dispatchEvent`|trigger the dom event|`false`|`Boolean`|\n| `throttleWait`|throttle wait|`200`|`Number`|\n| `observer`|use IntersectionObserver|`false`|`Boolean`|\n| `observerOptions`|IntersectionObserver options|{ rootMargin: '0px', threshold: 0.1 }|[IntersectionObserver](#intersectionobserver)|\n| `silent`|do not print debug info|`true`|`Boolean`|\n\n### Desired Listen Events\n\nYou can configure which events you want vue-lazyload by passing in an array\nof listener names.\n\n```javascript\nVue.use(VueLazyload, {\n  preLoad: 1.3,\n  error: 'dist/error.png',\n  loading: 'dist/loading.gif',\n  attempt: 1,\n  // the default is ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend']\n  listenEvents: [ 'scroll' ]\n})\n```\n\nThis is useful if you are having trouble with this plugin resetting itself to loading\nwhen you have certain animations and transitions taking place\n\n\n### Image listener filter\n\ndynamically modify the src of image\n\n```javascript\nVue.use(vueLazy, {\n    filter: {\n      progressive (listener, options) {\n          const isCDN = /qiniudn.com/\n          if (isCDN.test(listener.src)) {\n              listener.el.setAttribute('lazy-progressive', 'true')\n              listener.loading = listener.src + '?imageView2/1/w/10/h/10'\n          }\n      },\n      webp (listener, options) {\n          if (!options.supportWebp) return\n          const isCDN = /qiniudn.com/\n          if (isCDN.test(listener.src)) {\n              listener.src += '?imageView2/2/format/webp'\n          }\n      }\n    }\n})\n```\n\n\n### Element Adapter\n\n```javascript\nVue.use(vueLazy, {\n    adapter: {\n        loaded ({ bindType, el, naturalHeight, naturalWidth, $parent, src, loading, error, Init }) {\n            // do something here\n            // example for call LoadedHandler\n            LoadedHandler(el)\n        },\n        loading (listender, Init) {\n            console.log('loading')\n        },\n        error (listender, Init) {\n            console.log('error')\n        }\n    }\n})\n```\n\n### IntersectionObserver\n\nuse [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) to to improve performance of a large number of nodes.\n\n```javascript\nVue.use(vueLazy, {\n  // set observer to true\n  observer: true,\n\n  // optional\n  observerOptions: {\n    rootMargin: '0px',\n    threshold: 0.1\n  }\n})\n```\n\n\n### Lazy Component\n```javascript\nVue.use(VueLazyload, {\n  lazyComponent: true\n});\n```\n\n```html\n<lazy-component @show=\"handler\">\n  <img class=\"mini-cover\" :src=\"img.src\" width=\"100%\" height=\"400\">\n</lazy-component>\n\n<script>\n  {\n    ...\n    methods: {\n      handler (component) {\n        console.log('this component is showing')\n      }\n    }\n\n  }\n</script>\n```\nUse in list\n```html\n<lazy-component v-for=\"(item, index) in list\" :key=\"item.src\" >\n  <img class=\"mini-cover\" :src=\"item.src\" width=\"100%\" height=\"400\">\n</lazy-component>\n```\n\n\n## Implementation\n\n### Basic\n\nvue-lazyload will set this img element's `src` with `imgUrl` string\n\n```html\n<script>\nexport default {\n  data () {\n    return {\n      imgObj: {\n        src: 'http://xx.com/logo.png',\n        error: 'http://xx.com/error.png',\n        loading: 'http://xx.com/loading-spin.svg'\n      },\n      imgUrl: 'http://xx.com/logo.png' // String\n    }\n  }\n}\n</script>\n\n<template>\n  <div ref=\"container\">\n     <img v-lazy=\"imgUrl\"/>\n     <div v-lazy:background-image=\"imgUrl\"></div>\n\n     <!-- with customer error and loading -->\n     <img v-lazy=\"imgObj\"/>\n     <div v-lazy:background-image=\"imgObj\"></div>\n\n     <!-- Customer scrollable element -->\n     <img v-lazy.container =\"imgUrl\"/>\n     <div v-lazy:background-image.container=\"img\"></div>\n\n    <!-- srcset -->\n    <img v-lazy=\"'img.400px.jpg'\" data-srcset=\"img.400px.jpg 400w, img.800px.jpg 800w, img.1200px.jpg 1200w\">\n    <img v-lazy=\"imgUrl\" :data-srcset=\"imgUrl' + '?size=400 400w, ' + imgUrl + ' ?size=800 800w, ' + imgUrl +'/1200.jpg 1200w'\" />\n  </div>\n</template>\n```\n\n### CSS state\n\nThere are three states while img loading\n\n`loading`  `loaded`  `error`\n\n```html\n<img src=\"imgUrl\" lazy=\"loading\">\n<img src=\"imgUrl\" lazy=\"loaded\">\n<img src=\"imgUrl\" lazy=\"error\">\n```\n\n```html\n<style>\n  img[lazy=loading] {\n    /*your style here*/\n  }\n  img[lazy=error] {\n    /*your style here*/\n  }\n  img[lazy=loaded] {\n    /*your style here*/\n  }\n  /*\n  or background-image\n  */\n  .yourclass[lazy=loading] {\n    /*your style here*/\n  }\n  .yourclass[lazy=error] {\n    /*your style here*/\n  }\n  .yourclass[lazy=loaded] {\n    /*your style here*/\n  }\n</style>\n```\n\n## Methods\n\n### Event Hook\n\n`vm.$Lazyload.$on(event, callback)`\n`vm.$Lazyload.$off(event, callback)`\n`vm.$Lazyload.$once(event, callback)`\n\n- `$on` Listen for a custom events `loading`, `loaded`, `error`\n- `$once` Listen for a custom event, but only once. The listener will be removed once it triggers for the first time.\n- `$off` Remove event listener(s).\n\n#### `vm.$Lazyload.$on`\n\n#### Arguments:\n\n * `{string} event`\n * `{Function} callback`\n\n#### Example\n\n```javascript\nvm.$Lazyload.$on('loaded', function ({ bindType, el, naturalHeight, naturalWidth, $parent, src, loading, error }, formCache) {\n  console.log(el, src)\n})\n```\n\n#### `vm.$Lazyload.$once`\n\n#### Arguments:\n\n * `{string} event`\n * `{Function} callback`\n\n#### Example\n\n```javascript\nvm.$Lazyload.$once('loaded', function ({ el, src }) {\n  console.log(el, src)\n})\n```\n\n#### `vm.$Lazyload.$off`\n\nIf only the event is provided, remove all listeners for that event\n\n#### Arguments:\n\n * `{string} event`\n * `{Function} callback`\n\n#### Example\n\n```javascript\nfunction handler ({ el, src }, formCache) {\n  console.log(el, src)\n}\nvm.$Lazyload.$on('loaded', handler)\nvm.$Lazyload.$off('loaded', handler)\nvm.$Lazyload.$off('loaded')\n```\n\n### LazyLoadHandler\n\n`vm.$Lazyload.lazyLoadHandler`\n\nManually trigger lazy loading position calculation\n\n#### Example\n\n```javascript\n\nthis.$Lazyload.lazyLoadHandler()\n\n```\n\n### Performance\n\n```javascript\nthis.$Lazyload.$on('loaded', function (listener) {\n  console.table(this.$Lazyload.performance())\n})\n```\n\n![performance-demo](http://ww1.sinaimg.cn/large/69402bf8gw1fbo62ocvlaj213k09w78w.jpg)\n\n### Dynamic switching pictures\n\n```vue\n <img v-lazy=\"lazyImg\" :key=\"lazyImg.src\">\n```\n\n\n# Authors && Contributors\n\n- [hilongjw](https://github.com/hilongjw)\n- [imcvampire](https://github.com/imcvampire)\n- [darrynten](https://github.com/darrynten)\n- [biluochun](https://github.com/biluochun)\n- [whwnow](https://github.com/whwnow)\n- [Leopoldthecoder](https://github.com/Leopoldthecoder)\n- [michalbcz](https://github.com/michalbcz)\n- [blue0728](https://github.com/blue0728)\n- [JounQin](https://github.com/JounQin)\n- [llissery](https://github.com/llissery)\n- [mega667](https://github.com/mega667)\n- [RobinCK](https://github.com/RobinCK)\n- [GallenHu](https://github.com/GallenHu)\n\n# License\n\n[The MIT License](http://opensource.org/licenses/MIT)\n"
  },
  {
    "path": "build.js",
    "content": "const path = require('path')\nconst rollup = require('rollup')\nconst babel = require('rollup-plugin-babel')\nconst replace = require('@rollup/plugin-replace')\nconst { terser } = require('rollup-plugin-terser')\nconst resolve = require('rollup-plugin-node-resolve')\nconst commonjs = require('rollup-plugin-commonjs')\nconst version = process.env.VERSION || require('./package.json').version\n\nconst banner =\n    '/*!\\n' +\n    ' * Vue-Lazyload.js v' + version + '\\n' +\n    ' * (c) ' + new Date().getFullYear() + ' Awe <hilongjw@gmail.com>\\n' +\n    ' * Released under the MIT License.\\n' +\n    ' */\\n'\n\nasync function build (options, _outputOptions) {\n  try {\n    const bundle = await rollup.rollup(options)\n    const outputOptions = {\n      format: _outputOptions.format,\n      exports: 'named',\n      banner: banner,\n      file: path.resolve(__dirname, _outputOptions.filename),\n      name: 'VueLazyload'\n    }\n    const { output } = await bundle.generate(outputOptions)\n    await bundle.write(outputOptions)\n    const code = output[0].code\n    console.log(blue(outputOptions.file) + ' ' + getSize(code))\n  } catch (e) {\n    console.error(e)\n  }\n}\n\nfunction getSize (code) {\n  return (Buffer.byteLength(code, 'utf8') / 1024).toFixed(2) + 'kb'\n}\n\nfunction blue (str) {\n  return '\\x1b[1m\\x1b[34m' + str + '\\x1b[39m\\x1b[22m'\n}\n\nbuild({\n  input: path.resolve(__dirname, 'src/index.js'),\n  plugins: [\n    resolve(),\n    commonjs(),\n    babel({ runtimeHelpers: true }),\n    replace({\n      '__VUE_LAZYLOAD_VERSION__': JSON.stringify(version)\n    }),\n    terser()\n  ]\n}, {\n  format: 'umd',\n  filename: 'vue-lazyload.js'\n})\n\nbuild({\n  input: path.resolve(__dirname, 'src/index.js'),\n  plugins: [\n    resolve(),\n    commonjs(),\n    replace({\n      '__VUE_LAZYLOAD_VERSION__': JSON.stringify(version)\n    }),\n    babel({ runtimeHelpers: true })\n  ]\n}, {\n  format: 'esm',\n  filename: 'vue-lazyload.esm.js'\n})\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"vue-lazyload\",\n  \"version\": \"1.3.5\",\n  \"description\": \"Vue module for lazy-loading images in your vue.js applications.\",\n  \"main\": \"vue-lazyload.js\",\n  \"module\": \"vue-lazyload.esm.js\",\n  \"unpkg\": \"vue-lazyload.js\",\n  \"scripts\": {\n    \"build\": \"node build\",\n    \"lint\": \"eslint ./src\",\n    \"test\": \"jest\"\n  },\n  \"dependencies\": {},\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/hilongjw/vue-lazyload.git\"\n  },\n  \"typings\": \"types/index.d.ts\",\n  \"keywords\": [\n    \"vue-lazyload\",\n    \"vue\",\n    \"lazyload\",\n    \"vue-directive\"\n  ],\n  \"author\": \"Awe <hilongjw@gmail.com>\",\n  \"bugs\": {\n    \"url\": \"https://github.com/hilongjw/vue-lazyload/issues\"\n  },\n  \"browserslist\": [\n    \"> 1%\",\n    \"last 2 versions\",\n    \"not ie <= 8\"\n  ],\n  \"license\": \"MIT\",\n  \"jest\": {\n    \"setupFiles\": [\n      \"jest-canvas-mock\"\n    ]\n  },\n  \"devDependencies\": {\n    \"@rollup/plugin-replace\": \"^2.3.4\",\n    \"assign-deep\": \"^1.0.1\",\n    \"babel-cli\": \"^6.26.0\",\n    \"babel-core\": \"^6.26.3\",\n    \"babel-plugin-external-helpers\": \"^6.22.0\",\n    \"babel-plugin-syntax-dynamic-import\": \"^6.18.0\",\n    \"babel-polyfill\": \"^6.26.0\",\n    \"babel-preset-env\": \"^1.7.0\",\n    \"babel-preset-stage-0\": \"^6.24.1\",\n    \"babel-register\": \"^6.26.0\",\n    \"chai\": \"^4.3.0\",\n    \"eslint\": \"^4.19.1\",\n    \"eslint-config-standard\": \"^11.0.0\",\n    \"eslint-plugin-import\": \"^2.22.1\",\n    \"eslint-plugin-node\": \"^5.2.1\",\n    \"eslint-plugin-promise\": \"^3.8.0\",\n    \"eslint-plugin-standard\": \"^3.1.0\",\n    \"jest\": \"^26.6.3\",\n    \"jest-canvas-mock\": \"^2.3.1\",\n    \"mocha\": \"^4.0.1\",\n    \"rollup\": \"^2.39.0\",\n    \"rollup-plugin-babel\": \"^2.6.1\",\n    \"rollup-plugin-commonjs\": \"^8.4.1\",\n    \"rollup-plugin-node-resolve\": \"^3.4.0\",\n    \"rollup-plugin-replace\": \"^2.2.0\",\n    \"rollup-plugin-terser\": \"^7.0.2\",\n    \"rollup-plugin-uglify\": \"^1.0.1\",\n    \"vue\": \"^2.6.12\"\n  }\n}\n"
  },
  {
    "path": "src/index.js",
    "content": "import Lazy from './lazy'\nimport LazyComponent from './lazy-component'\nimport LazyContainer from './lazy-container'\nimport LazyImage from './lazy-image'\nimport { assign } from './util'\n\nexport default {\n  /*\n  * install function\n  * @param  {Vue} Vue\n  * @param  {object} options  lazyload options\n  */\n  install (Vue, options = {}) {\n    const LazyClass = Lazy(Vue)\n    const lazy = new LazyClass(options)\n    const lazyContainer = new LazyContainer({ lazy })\n\n    const isVue2 = Vue.version.split('.')[0] === '2'\n\n    Vue.prototype.$Lazyload = lazy\n\n    if (options.lazyComponent) {\n      Vue.component('lazy-component', LazyComponent(lazy))\n    }\n\n    if (options.lazyImage) {\n      Vue.component('lazy-image', LazyImage(lazy))\n    }\n\n    if (isVue2) {\n      Vue.directive('lazy', {\n        bind: lazy.add.bind(lazy),\n        update: lazy.update.bind(lazy),\n        componentUpdated: lazy.lazyLoadHandler.bind(lazy),\n        unbind: lazy.remove.bind(lazy)\n      })\n      Vue.directive('lazy-container', {\n        bind: lazyContainer.bind.bind(lazyContainer),\n        componentUpdated: lazyContainer.update.bind(lazyContainer),\n        unbind: lazyContainer.unbind.bind(lazyContainer)\n      })\n    } else {\n      Vue.directive('lazy', {\n        bind: lazy.lazyLoadHandler.bind(lazy),\n        update (newValue, oldValue) {\n          assign(this.vm.$refs, this.vm.$els)\n          lazy.add(this.el, {\n            modifiers: this.modifiers || {},\n            arg: this.arg,\n            value: newValue,\n            oldValue: oldValue\n          }, {\n            context: this.vm\n          })\n        },\n        unbind () {\n          lazy.remove(this.el)\n        }\n      })\n\n      Vue.directive('lazy-container', {\n        update (newValue, oldValue) {\n          lazyContainer.update(this.el, {\n            modifiers: this.modifiers || {},\n            arg: this.arg,\n            value: newValue,\n            oldValue: oldValue\n          }, {\n            context: this.vm\n          })\n        },\n        unbind () {\n          lazyContainer.unbind(this.el)\n        }\n      })\n    }\n  }\n}\n\nexport {\n  Lazy,\n  LazyComponent,\n  LazyImage,\n  LazyContainer\n}\n"
  },
  {
    "path": "src/lazy-component.js",
    "content": "import { inBrowser } from './util'\nimport Lazy from './lazy'\n\nconst LazyComponent = (lazy) => {\n  return {\n    props: {\n      tag: {\n        type: String,\n        default: 'div'\n      }\n    },\n    render (h) {\n      return h(this.tag, null, this.show ? this.$slots.default : null)\n    },\n    data () {\n      return {\n        el: null,\n        state: {\n          loaded: false\n        },\n        rect: {},\n        show: false\n      }\n    },\n    mounted () {\n      this.el = this.$el\n      lazy.addLazyBox(this)\n      lazy.lazyLoadHandler()\n    },\n    beforeDestroy () {\n      lazy.removeComponent(this)\n    },\n    methods: {\n      getRect () {\n        this.rect = this.$el.getBoundingClientRect()\n      },\n      checkInView () {\n        this.getRect()\n        return inBrowser &&\n                    (this.rect.top < window.innerHeight * lazy.options.preLoad && this.rect.bottom > 0) &&\n                    (this.rect.left < window.innerWidth * lazy.options.preLoad && this.rect.right > 0)\n      },\n      load () {\n        this.show = true\n        this.state.loaded = true\n        this.$emit('show', this)\n      },\n      destroy () {\n        return this.$destroy\n      }\n    }\n  }\n}\n\nLazyComponent.install = function (Vue, options = {}) {\n  const LazyClass = Lazy(Vue)\n  const lazy = new LazyClass(options)\n  Vue.component('lazy-component', LazyComponent(lazy))\n}\n\nexport default LazyComponent\n"
  },
  {
    "path": "src/lazy-container.js",
    "content": "import {\n  find,\n  remove,\n  assign,\n  ArrayFrom\n} from './util'\nimport Lazy from './lazy'\n\nexport default class LazyContainerMananger {\n  constructor ({ lazy }) {\n    this.lazy = lazy\n    lazy.lazyContainerMananger = this\n    this._queue = []\n  }\n\n  bind (el, binding, vnode) {\n    const container = new LazyContainer({ el, binding, vnode, lazy: this.lazy })\n    this._queue.push(container)\n  }\n\n  update (el, binding, vnode) {\n    const container = find(this._queue, item => item.el === el)\n    if (!container) return\n    container.update({ el, binding, vnode })\n  }\n\n  unbind (el, binding, vnode) {\n    const container = find(this._queue, item => item.el === el)\n    if (!container) return\n    container.clear()\n    remove(this._queue, container)\n  }\n}\n\nconst defaultOptions = {\n  selector: 'img'\n}\n\nclass LazyContainer {\n  constructor ({ el, binding, vnode, lazy }) {\n    this.el = null\n    this.vnode = vnode\n    this.binding = binding\n    this.options = {}\n    this.lazy = lazy\n\n    this._queue = []\n    this.update({ el, binding })\n  }\n\n  update ({ el, binding }) {\n    this.el = el\n    this.options = assign({}, defaultOptions, binding.value)\n\n    const imgs = this.getImgs()\n    imgs.forEach(el => {\n      this.lazy.add(el, assign({}, this.binding, {\n        value: {\n          src: 'dataset' in el ? el.dataset.src : el.getAttribute('data-src'),\n          error: ('dataset' in el ? el.dataset.error : el.getAttribute('data-error')) || this.options.error,\n          loading: ('dataset' in el ? el.dataset.loading : el.getAttribute('data-loading')) || this.options.loading\n        }\n      }), this.vnode)\n    })\n  }\n\n  getImgs () {\n    return ArrayFrom(this.el.querySelectorAll(this.options.selector))\n  }\n\n  clear () {\n    const imgs = this.getImgs()\n    imgs.forEach(el => this.lazy.remove(el))\n\n    this.vnode = null\n    this.binding = null\n    this.lazy = null\n  }\n}\n\nLazyContainer.install = (Vue, options = {}) => {\n  const LazyClass = Lazy(Vue)\n  const lazy = new LazyClass(options)\n  const lazyContainer = new LazyContainer({ lazy })\n\n  const isVue2 = Vue.version.split('.')[0] === '2'\n  if (isVue2) {\n    Vue.directive('lazy-container', {\n      bind: lazyContainer.bind.bind(lazyContainer),\n      componentUpdated: lazyContainer.update.bind(lazyContainer),\n      unbind: lazyContainer.unbind.bind(lazyContainer)\n    })\n  } else {\n    Vue.directive('lazy-container', {\n      update (newValue, oldValue) {\n        lazyContainer.update(this.el, {\n          modifiers: this.modifiers || {},\n          arg: this.arg,\n          value: newValue,\n          oldValue: oldValue\n        }, {\n          context: this.vm\n        })\n      },\n      unbind () {\n        lazyContainer.unbind(this.el)\n      }\n    })\n  }\n}\n"
  },
  {
    "path": "src/lazy-image.js",
    "content": "import {\n  inBrowser,\n  loadImageAsync,\n  noop\n} from './util'\nimport Lazy from './lazy'\n\nconst LazyImage = (lazyManager) => {\n  return {\n    props: {\n      src: [String, Object],\n      tag: {\n        type: String,\n        default: 'img'\n      }\n    },\n    render (h) {\n      return h(this.tag, {\n        attrs: {\n          src: this.renderSrc\n        }\n      }, this.$slots.default)\n    },\n    data () {\n      return {\n        el: null,\n        options: {\n          src: '',\n          error: '',\n          loading: '',\n          attempt: lazyManager.options.attempt\n        },\n        state: {\n          loaded: false,\n          error: false,\n          attempt: 0\n        },\n        rect: {},\n        renderSrc: ''\n      }\n    },\n    watch: {\n      src () {\n        this.init()\n        lazyManager.addLazyBox(this)\n        lazyManager.lazyLoadHandler()\n      }\n    },\n    created () {\n      this.init()\n      this.renderSrc = this.options.loading\n    },\n    mounted () {\n      this.el = this.$el\n      lazyManager.addLazyBox(this)\n      lazyManager.lazyLoadHandler()\n    },\n    beforeDestroy () {\n      lazyManager.removeComponent(this)\n    },\n    methods: {\n      init () {\n        const { src, loading, error } = lazyManager._valueFormatter(this.src)\n        this.state.loaded = false\n        this.options.src = src\n        this.options.error = error\n        this.options.loading = loading\n        this.renderSrc = this.options.loading\n      },\n      getRect () {\n        this.rect = this.$el.getBoundingClientRect()\n      },\n      checkInView () {\n        this.getRect()\n        return inBrowser &&\n                    (this.rect.top < window.innerHeight * lazyManager.options.preLoad && this.rect.bottom > 0) &&\n                    (this.rect.left < window.innerWidth * lazyManager.options.preLoad && this.rect.right > 0)\n      },\n      load (onFinish = noop) {\n        if ((this.state.attempt > this.options.attempt - 1) && this.state.error) {\n          if (!lazyManager.options.silent) console.log(`VueLazyload log: ${this.options.src} tried too more than ${this.options.attempt} times`)\n          onFinish()\n          return\n        }\n        const src = this.options.src\n        loadImageAsync({ src }, ({ src }) => {\n          this.renderSrc = src\n          this.state.loaded = true\n        }, e => {\n          this.state.attempt++\n          this.renderSrc = this.options.error\n          this.state.error = true\n        })\n      }\n    }\n  }\n}\n\nLazyImage.install = (Vue, options = {}) => {\n  const LazyClass = Lazy(Vue)\n  const lazy = new LazyClass(options)\n  Vue.component('lazy-image', LazyImage(lazy))\n}\n\nexport default LazyImage\n"
  },
  {
    "path": "src/lazy.js",
    "content": "import {\n  inBrowser,\n  CustomEvent,\n  remove,\n  some,\n  find,\n  _,\n  throttle,\n  supportWebp,\n  getDPR,\n  scrollParent,\n  getBestSelectionFromSrcset,\n  assign,\n  isObject,\n  hasIntersectionObserver,\n  modeType,\n  ImageCache\n} from './util'\n\nimport ReactiveListener from './listener'\n\nconst DEFAULT_URL = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'\nconst DEFAULT_EVENTS = ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove']\nconst DEFAULT_OBSERVER_OPTIONS = {\n  rootMargin: '0px',\n  threshold: 0\n}\n\nexport default function Lazy (Vue) {\n  return class Lazy {\n    constructor ({ preLoad, error, throttleWait, preLoadTop, dispatchEvent, loading, attempt, silent = true, scale, listenEvents, hasbind, filter, adapter, observer, observerOptions }) {\n      this.version = '__VUE_LAZYLOAD_VERSION__'\n      this.mode = modeType.event\n      this.ListenerQueue = []\n      this.TargetIndex = 0\n      this.TargetQueue = []\n      this.options = {\n        silent: silent,\n        dispatchEvent: !!dispatchEvent,\n        throttleWait: throttleWait || 200,\n        preLoad: preLoad || 1.3,\n        preLoadTop: preLoadTop || 0,\n        error: error || DEFAULT_URL,\n        loading: loading || DEFAULT_URL,\n        attempt: attempt || 3,\n        scale: scale || getDPR(scale),\n        ListenEvents: listenEvents || DEFAULT_EVENTS,\n        hasbind: false,\n        supportWebp: supportWebp(),\n        filter: filter || {},\n        adapter: adapter || {},\n        observer: !!observer,\n        observerOptions: observerOptions || DEFAULT_OBSERVER_OPTIONS\n      }\n      this._initEvent()\n      this._imageCache = new ImageCache({ max: 200 })\n      this.lazyLoadHandler = throttle(this._lazyLoadHandler.bind(this), this.options.throttleWait)\n\n      this.setMode(this.options.observer ? modeType.observer : modeType.event)\n    }\n\n    /**\n     * update config\n     * @param  {Object} config params\n     * @return\n     */\n    config (options = {}) {\n      assign(this.options, options)\n    }\n\n    /**\n     * output listener's load performance\n     * @return {Array}\n     */\n    performance () {\n      let list = []\n\n      this.ListenerQueue.map(item => {\n        list.push(item.performance())\n      })\n\n      return list\n    }\n\n    /*\n     * add lazy component to queue\n     * @param  {Vue} vm lazy component instance\n     * @return\n     */\n    addLazyBox (vm) {\n      this.ListenerQueue.push(vm)\n      if (inBrowser) {\n        this._addListenerTarget(window)\n        this._observer && this._observer.observe(vm.el)\n        if (vm.$el && vm.$el.parentNode) {\n          this._addListenerTarget(vm.$el.parentNode)\n        }\n      }\n    }\n\n    /*\n     * add image listener to queue\n     * @param  {DOM} el\n     * @param  {object} binding vue directive binding\n     * @param  {vnode} vnode vue directive vnode\n     * @return\n     */\n    add (el, binding, vnode) {\n      if (some(this.ListenerQueue, item => item.el === el)) {\n        this.update(el, binding)\n        return Vue.nextTick(this.lazyLoadHandler)\n      }\n\n      let { src, loading, error, cors } = this._valueFormatter(binding.value)\n\n      Vue.nextTick(() => {\n        src = getBestSelectionFromSrcset(el, this.options.scale) || src\n        this._observer && this._observer.observe(el)\n\n        const container = Object.keys(binding.modifiers)[0]\n        let $parent\n\n        if (container) {\n          $parent = vnode.context.$refs[container]\n          // if there is container passed in, try ref first, then fallback to getElementById to support the original usage\n          $parent = $parent ? $parent.$el || $parent : document.getElementById(container)\n        }\n\n        if (!$parent) {\n          $parent = scrollParent(el)\n        }\n\n        const newListener = new ReactiveListener({\n          bindType: binding.arg,\n          $parent,\n          el,\n          loading,\n          error,\n          src,\n          cors,\n          elRenderer: this._elRenderer.bind(this),\n          options: this.options,\n          imageCache: this._imageCache\n        })\n\n        this.ListenerQueue.push(newListener)\n\n        if (inBrowser) {\n          this._addListenerTarget(window)\n          this._addListenerTarget($parent)\n        }\n\n        this.lazyLoadHandler()\n        Vue.nextTick(() => this.lazyLoadHandler())\n      })\n    }\n\n    /**\n    * update image src\n    * @param  {DOM} el\n    * @param  {object} vue directive binding\n    * @return\n    */\n    update (el, binding, vnode) {\n      let { src, loading, error } = this._valueFormatter(binding.value)\n      src = getBestSelectionFromSrcset(el, this.options.scale) || src\n\n      const exist = find(this.ListenerQueue, item => item.el === el)\n      if (!exist) {\n        this.add(el, binding, vnode)\n      } else {\n        exist.update({\n          src,\n          loading,\n          error\n        })\n      }\n      if (this._observer) {\n        this._observer.unobserve(el)\n        this._observer.observe(el)\n      }\n      this.lazyLoadHandler()\n      Vue.nextTick(() => this.lazyLoadHandler())\n    }\n\n    /**\n    * remove listener form list\n    * @param  {DOM} el\n    * @return\n    */\n    remove (el) {\n      if (!el) return\n      this._observer && this._observer.unobserve(el)\n      const existItem = find(this.ListenerQueue, item => item.el === el)\n      if (existItem) {\n        this._removeListenerTarget(existItem.$parent)\n        this._removeListenerTarget(window)\n        remove(this.ListenerQueue, existItem)\n        existItem.$destroy()\n      }\n    }\n\n    /*\n     * remove lazy components form list\n     * @param  {Vue} vm Vue instance\n     * @return\n     */\n    removeComponent (vm) {\n      if (!vm) return\n      remove(this.ListenerQueue, vm)\n      this._observer && this._observer.unobserve(vm.el)\n      if (vm.$parent && vm.$el.parentNode) {\n        this._removeListenerTarget(vm.$el.parentNode)\n      }\n      this._removeListenerTarget(window)\n    }\n\n    setMode (mode) {\n      if (!hasIntersectionObserver && mode === modeType.observer) {\n        mode = modeType.event\n      }\n\n      this.mode = mode // event or observer\n\n      if (mode === modeType.event) {\n        if (this._observer) {\n          this.ListenerQueue.forEach(listener => {\n            this._observer.unobserve(listener.el)\n          })\n          this._observer = null\n        }\n\n        this.TargetQueue.forEach(target => {\n          this._initListen(target.el, true)\n        })\n      } else {\n        this.TargetQueue.forEach(target => {\n          this._initListen(target.el, false)\n        })\n        this._initIntersectionObserver()\n      }\n    }\n\n    /*\n    *** Private functions ***\n    */\n\n    /*\n     * add listener target\n     * @param  {DOM} el listener target\n     * @return\n     */\n    _addListenerTarget (el) {\n      if (!el) return\n      let target = find(this.TargetQueue, target => target.el === el)\n      if (!target) {\n        target = {\n          el: el,\n          id: ++this.TargetIndex,\n          childrenCount: 1,\n          listened: true\n        }\n        this.mode === modeType.event && this._initListen(target.el, true)\n        this.TargetQueue.push(target)\n      } else {\n        target.childrenCount++\n      }\n      return this.TargetIndex\n    }\n\n    /*\n     * remove listener target or reduce target childrenCount\n     * @param  {DOM} el or window\n     * @return\n     */\n    _removeListenerTarget (el) {\n      this.TargetQueue.forEach((target, index) => {\n        if (target.el === el) {\n          target.childrenCount--\n          if (!target.childrenCount) {\n            this._initListen(target.el, false)\n            this.TargetQueue.splice(index, 1)\n            target = null\n          }\n        }\n      })\n    }\n\n    /*\n     * add or remove eventlistener\n     * @param  {DOM} el DOM or Window\n     * @param  {boolean} start flag\n     * @return\n     */\n    _initListen (el, start) {\n      this.options.ListenEvents.forEach((evt) => _[start ? 'on' : 'off'](el, evt, this.lazyLoadHandler))\n    }\n\n    _initEvent () {\n      this.Event = {\n        listeners: {\n          loading: [],\n          loaded: [],\n          error: []\n        }\n      }\n\n      this.$on = (event, func) => {\n        if (!this.Event.listeners[event]) this.Event.listeners[event] = []\n        this.Event.listeners[event].push(func)\n      }\n\n      this.$once = (event, func) => {\n        const vm = this\n        function on () {\n          vm.$off(event, on)\n          func.apply(vm, arguments)\n        }\n        this.$on(event, on)\n      }\n\n      this.$off = (event, func) => {\n        if (!func) {\n          if (!this.Event.listeners[event]) return\n          this.Event.listeners[event].length = 0\n          return\n        }\n        remove(this.Event.listeners[event], func)\n      }\n\n      this.$emit = (event, context, inCache) => {\n        if (!this.Event.listeners[event]) return\n        this.Event.listeners[event].forEach(func => func(context, inCache))\n      }\n    }\n\n    /**\n     * find nodes which in viewport and trigger load\n     * @return\n     */\n    _lazyLoadHandler () {\n      const freeList = []\n      this.ListenerQueue.forEach((listener, index) => {\n        if (!listener.el || !listener.el.parentNode) {\n          freeList.push(listener)\n        }\n        const catIn = listener.checkInView()\n        if (!catIn) return\n        listener.load()\n      })\n      freeList.forEach(item => {\n        remove(this.ListenerQueue, item)\n        item.$destroy()\n      })\n    }\n    /**\n    * init IntersectionObserver\n    * set mode to observer\n    * @return\n    */\n    _initIntersectionObserver () {\n      if (!hasIntersectionObserver) return\n      this._observer = new IntersectionObserver(this._observerHandler.bind(this), this.options.observerOptions)\n      if (this.ListenerQueue.length) {\n        this.ListenerQueue.forEach(listener => {\n          this._observer.observe(listener.el)\n        })\n      }\n    }\n\n    /**\n    * init IntersectionObserver\n    * @return\n    */\n    _observerHandler (entries, observer) {\n      entries.forEach(entry => {\n        if (entry.isIntersecting) {\n          this.ListenerQueue.forEach(listener => {\n            if (listener.el === entry.target) {\n              if (listener.state.loaded) return this._observer.unobserve(listener.el)\n              listener.load()\n            }\n          })\n        }\n      })\n    }\n\n    /**\n    * set element attribute with image'url and state\n    * @param  {object} lazyload listener object\n    * @param  {string} state will be rendered\n    * @param  {bool} inCache  is rendered from cache\n    * @return\n    */\n    _elRenderer (listener, state, cache) {\n      if (!listener.el) return\n      const { el, bindType } = listener\n\n      let src\n      switch (state) {\n        case 'loading':\n          src = listener.loading\n          break\n        case 'error':\n          src = listener.error\n          break\n        default:\n          src = listener.src\n          break\n      }\n\n      if (bindType) {\n        el.style[bindType] = 'url(\"' + src + '\")'\n      } else if (el.getAttribute('src') !== src) {\n        el.setAttribute('src', src)\n      }\n\n      el.setAttribute('lazy', state)\n\n      this.$emit(state, listener, cache)\n      this.options.adapter[state] && this.options.adapter[state](listener, this.options)\n\n      if (this.options.dispatchEvent) {\n        const event = new CustomEvent(state, {\n          detail: listener\n        })\n        el.dispatchEvent(event)\n      }\n    }\n\n    /**\n    * generate loading loaded error image url\n    * @param {string} image's src\n    * @return {object} image's loading, loaded, error url\n    */\n    _valueFormatter (value) {\n      let src = value\n      let loading = this.options.loading\n      let error = this.options.error\n\n      // value is object\n      if (isObject(value)) {\n        if (!value.src && !this.options.silent) console.error('Vue Lazyload warning: miss src with ' + value)\n        src = value.src\n        loading = value.loading || this.options.loading\n        error = value.error || this.options.error\n      }\n      return {\n        src,\n        loading,\n        error\n      }\n    }\n  }\n}\n\nLazy.install = (Vue, options = {}) => {\n  const LazyClass = Lazy(Vue)\n  const lazy = new LazyClass(options)\n\n  const isVue2 = Vue.version.split('.')[0] === '2'\n  if (isVue2) {\n    Vue.directive('lazy', {\n      bind: lazy.add.bind(lazy),\n      update: lazy.update.bind(lazy),\n      componentUpdated: lazy.lazyLoadHandler.bind(lazy),\n      unbind: lazy.remove.bind(lazy)\n    })\n  } else {\n    Vue.directive('lazy', {\n      bind: lazy.lazyLoadHandler.bind(lazy),\n      update (newValue, oldValue) {\n        assign(this.vm.$refs, this.vm.$els)\n        lazy.add(this.el, {\n          modifiers: this.modifiers || {},\n          arg: this.arg,\n          value: newValue,\n          oldValue: oldValue\n        }, {\n          context: this.vm\n        })\n      },\n      unbind () {\n        lazy.remove(this.el)\n      }\n    })\n  }\n}\n"
  },
  {
    "path": "src/listener.js",
    "content": "import {\n  loadImageAsync,\n  ObjectKeys,\n  noop\n} from './util'\n\n// el: {\n//     state,\n//     src,\n//     error,\n//     loading\n// }\n\nexport default class ReactiveListener {\n  constructor ({ el, src, error, loading, bindType, $parent, options, cors, elRenderer, imageCache }) {\n    this.el = el\n    this.src = src\n    this.error = error\n    this.loading = loading\n    this.bindType = bindType\n    this.attempt = 0\n    this.cors = cors\n\n    this.naturalHeight = 0\n    this.naturalWidth = 0\n\n    this.options = options\n\n    this.rect = null\n\n    this.$parent = $parent\n    this.elRenderer = elRenderer\n    this._imageCache = imageCache\n    this.performanceData = {\n      init: Date.now(),\n      loadStart: 0,\n      loadEnd: 0\n    }\n\n    this.filter()\n    this.initState()\n    this.render('loading', false)\n  }\n\n  /*\n   * init listener state\n   * @return\n   */\n  initState () {\n    if ('dataset' in this.el) {\n      this.el.dataset.src = this.src\n    } else {\n      this.el.setAttribute('data-src', this.src)\n    }\n\n    this.state = {\n      loading: false,\n      error: false,\n      loaded: false,\n      rendered: false\n    }\n  }\n\n  /*\n   * record performance\n   * @return\n   */\n  record (event) {\n    this.performanceData[event] = Date.now()\n  }\n\n  /*\n   * update image listener data\n   * @param  {String} image uri\n   * @param  {String} loading image uri\n   * @param  {String} error image uri\n   * @return\n   */\n  update ({ src, loading, error }) {\n    const oldSrc = this.src\n    this.src = src\n    this.loading = loading\n    this.error = error\n    this.filter()\n    if (oldSrc !== this.src) {\n      this.attempt = 0\n      this.initState()\n    }\n  }\n\n  /*\n   * get el node rect\n   * @return\n   */\n  getRect () {\n    this.rect = this.el.getBoundingClientRect()\n  }\n\n  /*\n   *  check el is in view\n   * @return {Boolean} el is in view\n   */\n  checkInView () {\n    this.getRect()\n    return (this.rect.top < window.innerHeight * this.options.preLoad && this.rect.bottom > this.options.preLoadTop) &&\n            (this.rect.left < window.innerWidth * this.options.preLoad && this.rect.right > 0)\n  }\n\n  /*\n   * listener filter\n   */\n  filter () {\n    ObjectKeys(this.options.filter).map(key => {\n      this.options.filter[key](this, this.options)\n    })\n  }\n\n  /*\n   * render loading first\n   * @params cb:Function\n   * @return\n   */\n  renderLoading (cb) {\n    this.state.loading = true\n    loadImageAsync({\n      src: this.loading,\n      cors: this.cors\n    }, data => {\n      this.render('loading', false)\n      this.state.loading = false\n      cb()\n    }, () => {\n      // handler `loading image` load failed\n      cb()\n      this.state.loading = false\n      if (!this.options.silent) console.warn(`VueLazyload log: load failed with loading image(${this.loading})`)\n    })\n  }\n\n  /*\n   * try load image and  render it\n   * @return\n   */\n  load (onFinish = noop) {\n    if ((this.attempt > this.options.attempt - 1) && this.state.error) {\n      if (!this.options.silent) console.log(`VueLazyload log: ${this.src} tried too more than ${this.options.attempt} times`)\n      onFinish()\n      return\n    }\n    if (this.state.rendered && this.state.loaded) return\n    if (this._imageCache.has(this.src)) {\n      this.state.loaded = true\n      this.render('loaded', true)\n      this.state.rendered = true\n      return onFinish()\n    }\n\n    this.renderLoading(() => {\n      this.attempt++\n\n      this.options.adapter['beforeLoad'] && this.options.adapter['beforeLoad'](this, this.options)\n      this.record('loadStart')\n\n      loadImageAsync({\n        src: this.src,\n        cors: this.cors\n      }, data => {\n        this.naturalHeight = data.naturalHeight\n        this.naturalWidth = data.naturalWidth\n        this.state.loaded = true\n        this.state.error = false\n        this.record('loadEnd')\n        this.render('loaded', false)\n        this.state.rendered = true\n        this._imageCache.add(this.src)\n        onFinish()\n      }, err => {\n        !this.options.silent && console.error(err)\n        this.state.error = true\n        this.state.loaded = false\n        this.render('error', false)\n      })\n    })\n  }\n\n  /*\n   * render image\n   * @param  {String} state to render // ['loading', 'src', 'error']\n   * @param  {String} is form cache\n   * @return\n   */\n  render (state, cache) {\n    this.elRenderer(this, state, cache)\n  }\n\n  /*\n   * output performance data\n   * @return {Object} performance data\n   */\n  performance () {\n    let state = 'loading'\n    let time = 0\n\n    if (this.state.loaded) {\n      state = 'loaded'\n      time = (this.performanceData.loadEnd - this.performanceData.loadStart) / 1000\n    }\n\n    if (this.state.error) state = 'error'\n\n    return {\n      src: this.src,\n      state,\n      time\n    }\n  }\n\n  /*\n   * $destroy\n   * @return\n   */\n  $destroy () {\n    this.el = null\n    this.src = null\n    this.error = null\n    this.loading = null\n    this.bindType = null\n    this.attempt = 0\n  }\n}\n"
  },
  {
    "path": "src/util.js",
    "content": "import assign from 'assign-deep'\n\nconst inBrowser = typeof window !== 'undefined' && window !== null\n\nexport const hasIntersectionObserver = checkIntersectionObserver()\n\nfunction checkIntersectionObserver () {\n  if (inBrowser &&\n    'IntersectionObserver' in window &&\n    'IntersectionObserverEntry' in window &&\n    'intersectionRatio' in window.IntersectionObserverEntry.prototype) {\n  // Minimal polyfill for Edge 15's lack of `isIntersecting`\n  // See: https://github.com/w3c/IntersectionObserver/issues/211\n    if (!('isIntersecting' in window.IntersectionObserverEntry.prototype)) {\n      Object.defineProperty(window.IntersectionObserverEntry.prototype,\n        'isIntersecting', {\n          get: function () {\n            return this.intersectionRatio > 0\n          }\n        })\n    }\n    return true\n  }\n  return false\n}\n\nexport const modeType = {\n  event: 'event',\n  observer: 'observer'\n}\n\n// CustomEvent polyfill for IE\nconst CustomEvent = (function () {\n  if (!inBrowser) return\n  // not IE\n  if (typeof window.CustomEvent === 'function') return window.CustomEvent\n  function CustomEvent (event, params) {\n    params = params || { bubbles: false, cancelable: false, detail: undefined }\n    var evt = document.createEvent('CustomEvent')\n    evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)\n    return evt\n  }\n  CustomEvent.prototype = window.Event.prototype\n  return CustomEvent\n})()\n\nfunction remove (arr, item) {\n  if (!arr.length) return\n  const index = arr.indexOf(item)\n  if (index > -1) return arr.splice(index, 1)\n}\n\nfunction some (arr, fn) {\n  let has = false\n  for (let i = 0, len = arr.length; i < len; i++) {\n    if (fn(arr[i])) {\n      has = true\n      break\n    }\n  }\n  return has\n}\n\nfunction getBestSelectionFromSrcset (el, scale) {\n  if (el.tagName !== 'IMG' || !el.getAttribute('data-srcset')) return\n\n  let options = el.getAttribute('data-srcset')\n  const result = []\n  const container = el.parentNode\n  const containerWidth = container.offsetWidth * scale\n\n  let spaceIndex\n  let tmpSrc\n  let tmpWidth\n\n  options = options.trim().split(',')\n\n  options.map(item => {\n    item = item.trim()\n    spaceIndex = item.lastIndexOf(' ')\n    if (spaceIndex === -1) {\n      tmpSrc = item\n      tmpWidth = 999998\n    } else {\n      tmpSrc = item.substr(0, spaceIndex)\n      tmpWidth = parseInt(item.substr(spaceIndex + 1, item.length - spaceIndex - 2), 10)\n    }\n    result.push([tmpWidth, tmpSrc])\n  })\n\n  result.sort(function (a, b) {\n    if (a[0] < b[0]) {\n      return 1\n    }\n    if (a[0] > b[0]) {\n      return -1\n    }\n    if (a[0] === b[0]) {\n      if (b[1].indexOf('.webp', b[1].length - 5) !== -1) {\n        return 1\n      }\n      if (a[1].indexOf('.webp', a[1].length - 5) !== -1) {\n        return -1\n      }\n    }\n    return 0\n  })\n  let bestSelectedSrc = ''\n  let tmpOption\n\n  for (let i = 0; i < result.length; i++) {\n    tmpOption = result[i]\n    bestSelectedSrc = tmpOption[1]\n    const next = result[i + 1]\n    if (next && next[0] < containerWidth) {\n      bestSelectedSrc = tmpOption[1]\n      break\n    } else if (!next) {\n      bestSelectedSrc = tmpOption[1]\n      break\n    }\n  }\n\n  return bestSelectedSrc\n}\n\nfunction find (arr, fn) {\n  let item\n  for (let i = 0, len = arr.length; i < len; i++) {\n    if (fn(arr[i])) {\n      item = arr[i]\n      break\n    }\n  }\n  return item\n}\n\nconst getDPR = (scale = 1) => inBrowser ? (window.devicePixelRatio || scale) : scale\n\nfunction supportWebp () {\n  if (!inBrowser) return false\n\n  let support = true\n\n  try {\n    const elem = document.createElement('canvas')\n\n    if (elem.getContext && elem.getContext('2d')) {\n      support = elem.toDataURL('image/webp').indexOf('data:image/webp') === 0\n    }\n  } catch (err) {\n    support = false\n  }\n\n  return support\n}\n\nfunction throttle (action, delay) {\n  let timeout = null\n  let movement = null\n  let lastRun = 0\n  let needRun = false\n  return function () {\n    needRun = true\n    if (timeout) {\n      return\n    }\n    let elapsed = Date.now() - lastRun\n    let context = this\n    let args = arguments\n    let runCallback = function () {\n      lastRun = Date.now()\n      timeout = false\n      action.apply(context, args)\n    }\n    if (elapsed >= delay) {\n      runCallback()\n    } else {\n      timeout = setTimeout(runCallback, delay)\n    }\n    if (needRun) {\n      clearTimeout(movement)\n      movement = setTimeout(runCallback, 2 * delay)\n    }\n  }\n}\n\nfunction testSupportsPassive () {\n  if (!inBrowser) return\n  let support = false\n  try {\n    let opts = Object.defineProperty({}, 'passive', {\n      get: function () {\n        support = true\n      }\n    })\n    window.addEventListener('test', null, opts)\n  } catch (e) {}\n  return support\n}\n\nconst supportsPassive = testSupportsPassive()\n\nconst _ = {\n  on (el, type, func, capture = false) {\n    if (supportsPassive) {\n      el.addEventListener(type, func, {\n        capture: capture,\n        passive: true\n      })\n    } else {\n      el.addEventListener(type, func, capture)\n    }\n  },\n  off (el, type, func, capture = false) {\n    el.removeEventListener(type, func, capture)\n  }\n}\n\nconst loadImageAsync = (item, resolve, reject) => {\n  let image = new Image()\n  if (!item || !item.src) {\n    const err = new Error('image src is required')\n    return reject(err)\n  }\n\n  image.src = item.src\n  if (item.cors) {\n    image.crossOrigin = item.cors\n  }\n\n  image.onload = function () {\n    resolve({\n      naturalHeight: image.naturalHeight,\n      naturalWidth: image.naturalWidth,\n      src: image.src\n    })\n  }\n\n  image.onerror = function (e) {\n    reject(e)\n  }\n}\n\nconst style = (el, prop) => {\n  return typeof getComputedStyle !== 'undefined'\n    ? getComputedStyle(el, null).getPropertyValue(prop)\n    : el.style[prop]\n}\n\nconst overflow = (el) => {\n  return style(el, 'overflow') + style(el, 'overflow-y') + style(el, 'overflow-x')\n}\n\nconst scrollParent = (el) => {\n  if (!inBrowser) return\n  if (!(el instanceof HTMLElement)) {\n    return window\n  }\n\n  let parent = el\n\n  while (parent) {\n    if (parent === document.body || parent === document.documentElement) {\n      break\n    }\n\n    if (!parent.parentNode) {\n      break\n    }\n\n    if (/(scroll|auto)/.test(overflow(parent))) {\n      return parent\n    }\n\n    parent = parent.parentNode\n  }\n\n  return window\n}\n\nfunction isObject (obj) {\n  return obj !== null && typeof obj === 'object'\n}\n\nfunction ObjectKeys (obj) {\n  if (!(obj instanceof Object)) return []\n  if (Object.keys) {\n    return Object.keys(obj)\n  } else {\n    let keys = []\n    for (let key in obj) {\n      if (obj.hasOwnProperty(key)) {\n        keys.push(key)\n      }\n    }\n    return keys\n  }\n}\n\nfunction ArrayFrom (arrLike) {\n  let len = arrLike.length\n  const list = []\n  for (let i = 0; i < len; i++) {\n    list.push(arrLike[i])\n  }\n  return list\n}\n\nfunction noop () {}\n\nclass ImageCache {\n  constructor ({ max }) {\n    this.options = {\n      max: max || 100\n    }\n    this._caches = []\n  }\n\n  has (key) {\n    return this._caches.indexOf(key) > -1\n  }\n\n  add (key) {\n    if (this.has(key)) return\n    this._caches.push(key)\n    if (this._caches.length > this.options.max) {\n      this.free()\n    }\n  }\n\n  free () {\n    this._caches.shift()\n  }\n}\n\nexport {\n  ImageCache,\n  inBrowser,\n  CustomEvent,\n  remove,\n  some,\n  find,\n  assign,\n  noop,\n  ArrayFrom,\n  _,\n  isObject,\n  throttle,\n  supportWebp,\n  getDPR,\n  scrollParent,\n  loadImageAsync,\n  getBestSelectionFromSrcset,\n  ObjectKeys\n}\n"
  },
  {
    "path": "test/test.spec.js",
    "content": "import Vue from 'vue'\nimport VueLazyload from '../src'\nimport genLazyCore from '../src/lazy'\nimport assert from 'assert'\n\ndescribe('VueLazyload.js Test Suite', function () {\n  it('install', function () {\n    Vue.use(VueLazyload)\n    const vm = new Vue()\n    assert(vm.$Lazyload, 'has $Lazyload')\n  })\n\n  it('_valueFormatter', function () {\n    const LazyCore = genLazyCore(Vue)\n\n    const lazyload = new LazyCore({\n      error: 'error',\n      loading: 'loading'\n    })\n\n    expect(lazyload._valueFormatter('src').src).toBe('src')\n    expect(lazyload._valueFormatter('src').error).toBe('error')\n    expect(lazyload._valueFormatter('src').loading).toBe('loading')\n\n    expect(lazyload._valueFormatter({\n      src: 'src',\n      error: 'error',\n      loading: 'loading'\n    }).src).toBe('src')\n\n    expect(lazyload._valueFormatter({\n      src: 'src',\n      error: 'error',\n      loading: 'loading'\n    }).error).toBe('error')\n\n    expect(lazyload._valueFormatter({\n      src: 'src',\n      error: 'error',\n      loading: 'loading'\n    }).loading).toBe('loading')\n  })\n})\n"
  },
  {
    "path": "types/index.d.ts",
    "content": "import \"./vue\";\nimport { VueLazyloadPluginObject } from \"./lazyload\";\n\ndeclare var VueLazyload: VueLazyloadPluginObject;\nexport default VueLazyload;\n\nexport {\n  VueLazyloadImage,\n  VueLazyloadOptions,\n  VueLazyloadHandler,\n  VueReactiveListener\n} from \"./lazyload\";\n"
  },
  {
    "path": "types/lazyload.d.ts",
    "content": "import { PluginObject } from \"vue\";\n\ninterface IntersectionObserverInit {\n  root?: Element | null;\n  rootMargin?: string;\n  threshold?: number | number[];\n}\n\nexport interface VueLazyloadImage {\n  src: string;\n  error?: string;\n  loading?: string;\n}\n\nexport interface VueLazyloadOptions {\n  lazyComponent?: boolean;\n  preLoad?: number;\n  error?: string;\n  loading?: string;\n  attempt?: number;\n  listenEvents?: string[];\n  adapter?: any;\n  filter?: any;\n  dispatchEvent?: boolean;\n  throttleWait?: number;\n  observer?: boolean;\n  observerOptions?: IntersectionObserverInit;\n  silent?: boolean;\n  preLoadTop?: number;\n  scale?: number;\n  hasbind?: boolean;\n}\n\nexport interface VueReactiveListener {\n  el: Element;\n  src: string;\n  error: string;\n  loading: string;\n  bindType: string;\n  attempt: number;\n  naturalHeight: number;\n  naturalWidth: number;\n  options: VueLazyloadOptions;\n  rect: DOMRect;\n  $parent: Element\n  elRenderer: Function;\n  performanceData: {\n    init: number,\n    loadStart: number,\n    loadEnd: number\n  };\n}\n\nexport interface VueLazyloadListenEvent {\n  (listener: VueReactiveListener, cache: boolean) : void;\n}\n\nexport interface VueLazyloadHandler {\n  $on (event: string, callback: VueLazyloadListenEvent): void;\n  $once (event: string, callback: VueLazyloadListenEvent): void;\n  $off (event: string, callback?: VueLazyloadListenEvent): void;\n  lazyLoadHandler (): void;\n}\n\nexport interface VueLazyloadPluginObject extends PluginObject<VueLazyloadOptions> {}\n"
  },
  {
    "path": "types/test/index.ts",
    "content": "import Vue from \"vue\";\nimport VueLazyload, { VueLazyloadOptions } from \"../index\";\n\nVue.use<VueLazyloadOptions>(VueLazyload);\n\nVue.use<VueLazyloadOptions>(VueLazyload, {\n  preLoad: 0,\n});\n\nconst vm = new Vue({});\n\nvm.$Lazyload.lazyLoadHandler();\nvm.$Lazyload.$on('loading', function (state, cache) {\n  const err: string = state.error;\n  const el: Element = state.el;\n  const bol: boolean = cache;\n});"
  },
  {
    "path": "types/test/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"module\": \"es2015\",\n    \"moduleResolution\": \"node\",\n    \"lib\": [\n      \"es5\",\n      \"dom\",\n      \"es2015.promise\",\n      \"es2015.core\"\n    ],\n    \"strict\": true,\n    \"noEmit\": true\n  },\n  \"include\": [\n    \"*.ts\",\n    \"../*.d.ts\"\n  ]\n}"
  },
  {
    "path": "types/vue.d.ts",
    "content": "/**\n * Augment the typings of Vue.js\n */\n\nimport Vue from \"vue\";\nimport { VueLazyloadHandler } from \"./index\";\n\ndeclare module \"vue/types/vue\" {\n  interface Vue {\n    $Lazyload: VueLazyloadHandler;\n  }\n}\n\n"
  },
  {
    "path": "vue-lazyload.esm.js",
    "content": "/*!\n * Vue-Lazyload.js v1.3.5\n * (c) 2023 Awe <hilongjw@gmail.com>\n * Released under the MIT License.\n */\n\nfunction createCommonjsModule(fn, module) {\n\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n}\n\nvar assignSymbols$1 = createCommonjsModule(function (module) {\n\n  var toString = Object.prototype.toString;\n  var isEnumerable = Object.prototype.propertyIsEnumerable;\n  var getSymbols = Object.getOwnPropertySymbols;\n\n  module.exports = function (target) {\n    for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n      args[_key - 1] = arguments[_key];\n    }\n\n    if (!isObject(target)) {\n      throw new TypeError('expected the first argument to be an object');\n    }\n\n    if (args.length === 0 || typeof Symbol !== 'function' || typeof getSymbols !== 'function') {\n      return target;\n    }\n\n    var _iteratorNormalCompletion = true;\n    var _didIteratorError = false;\n    var _iteratorError = undefined;\n\n    try {\n      for (var _iterator = args[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n        var arg = _step.value;\n\n        var names = getSymbols(arg);\n\n        var _iteratorNormalCompletion2 = true;\n        var _didIteratorError2 = false;\n        var _iteratorError2 = undefined;\n\n        try {\n          for (var _iterator2 = names[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n            var key = _step2.value;\n\n            if (isEnumerable.call(arg, key)) {\n              target[key] = arg[key];\n            }\n          }\n        } catch (err) {\n          _didIteratorError2 = true;\n          _iteratorError2 = err;\n        } finally {\n          try {\n            if (!_iteratorNormalCompletion2 && _iterator2.return) {\n              _iterator2.return();\n            }\n          } finally {\n            if (_didIteratorError2) {\n              throw _iteratorError2;\n            }\n          }\n        }\n      }\n    } catch (err) {\n      _didIteratorError = true;\n      _iteratorError = err;\n    } finally {\n      try {\n        if (!_iteratorNormalCompletion && _iterator.return) {\n          _iterator.return();\n        }\n      } finally {\n        if (_didIteratorError) {\n          throw _iteratorError;\n        }\n      }\n    }\n\n    return target;\n  };\n\n  function isObject(val) {\n    return typeof val === 'function' || toString.call(val) === '[object Object]' || Array.isArray(val);\n  }\n});\n\nvar assignSymbols$2 = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\t'default': assignSymbols$1,\n\t__moduleExports: assignSymbols$1\n});\n\nvar assignSymbols = ( assignSymbols$2 && assignSymbols$1 ) || assignSymbols$2;\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n  return typeof obj;\n} : function (obj) {\n  return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n};\n\nvar classCallCheck = function (instance, Constructor) {\n  if (!(instance instanceof Constructor)) {\n    throw new TypeError(\"Cannot call a class as a function\");\n  }\n};\n\nvar createClass = function () {\n  function defineProperties(target, props) {\n    for (var i = 0; i < props.length; i++) {\n      var descriptor = props[i];\n      descriptor.enumerable = descriptor.enumerable || false;\n      descriptor.configurable = true;\n      if (\"value\" in descriptor) descriptor.writable = true;\n      Object.defineProperty(target, descriptor.key, descriptor);\n    }\n  }\n\n  return function (Constructor, protoProps, staticProps) {\n    if (protoProps) defineProperties(Constructor.prototype, protoProps);\n    if (staticProps) defineProperties(Constructor, staticProps);\n    return Constructor;\n  };\n}();\n\nvar assignDeep = createCommonjsModule(function (module) {\n\n  var toString = Object.prototype.toString;\n\n  var isValidKey = function isValidKey(key) {\n    return key !== '__proto__' && key !== 'constructor' && key !== 'prototype';\n  };\n\n  var assign = module.exports = function (target) {\n    for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n      args[_key - 1] = arguments[_key];\n    }\n\n    var i = 0;\n    if (isPrimitive(target)) target = args[i++];\n    if (!target) target = {};\n    for (; i < args.length; i++) {\n      if (isObject(args[i])) {\n        var _iteratorNormalCompletion = true;\n        var _didIteratorError = false;\n        var _iteratorError = undefined;\n\n        try {\n          for (var _iterator = Object.keys(args[i])[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n            var key = _step.value;\n\n            if (isValidKey(key)) {\n              if (isObject(target[key]) && isObject(args[i][key])) {\n                assign(target[key], args[i][key]);\n              } else {\n                target[key] = args[i][key];\n              }\n            }\n          }\n        } catch (err) {\n          _didIteratorError = true;\n          _iteratorError = err;\n        } finally {\n          try {\n            if (!_iteratorNormalCompletion && _iterator.return) {\n              _iterator.return();\n            }\n          } finally {\n            if (_didIteratorError) {\n              throw _iteratorError;\n            }\n          }\n        }\n\n        assignSymbols(target, args[i]);\n      }\n    }\n    return target;\n  };\n\n  function isObject(val) {\n    return typeof val === 'function' || toString.call(val) === '[object Object]';\n  }\n\n  function isPrimitive(val) {\n    return (typeof val === 'undefined' ? 'undefined' : _typeof(val)) === 'object' ? val === null : typeof val !== 'function';\n  }\n});\n\nvar inBrowser = typeof window !== 'undefined' && window !== null;\n\nvar hasIntersectionObserver = checkIntersectionObserver();\n\nfunction checkIntersectionObserver() {\n  if (inBrowser && 'IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype) {\n    // Minimal polyfill for Edge 15's lack of `isIntersecting`\n    // See: https://github.com/w3c/IntersectionObserver/issues/211\n    if (!('isIntersecting' in window.IntersectionObserverEntry.prototype)) {\n      Object.defineProperty(window.IntersectionObserverEntry.prototype, 'isIntersecting', {\n        get: function get() {\n          return this.intersectionRatio > 0;\n        }\n      });\n    }\n    return true;\n  }\n  return false;\n}\n\nvar modeType = {\n  event: 'event',\n  observer: 'observer'\n\n  // CustomEvent polyfill for IE\n};var CustomEvent = function () {\n  if (!inBrowser) return;\n  // not IE\n  if (typeof window.CustomEvent === 'function') return window.CustomEvent;\n  function CustomEvent(event, params) {\n    params = params || { bubbles: false, cancelable: false, detail: undefined };\n    var evt = document.createEvent('CustomEvent');\n    evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n    return evt;\n  }\n  CustomEvent.prototype = window.Event.prototype;\n  return CustomEvent;\n}();\n\nfunction remove(arr, item) {\n  if (!arr.length) return;\n  var index = arr.indexOf(item);\n  if (index > -1) return arr.splice(index, 1);\n}\n\nfunction some(arr, fn) {\n  var has = false;\n  for (var i = 0, len = arr.length; i < len; i++) {\n    if (fn(arr[i])) {\n      has = true;\n      break;\n    }\n  }\n  return has;\n}\n\nfunction getBestSelectionFromSrcset(el, scale) {\n  if (el.tagName !== 'IMG' || !el.getAttribute('data-srcset')) return;\n\n  var options = el.getAttribute('data-srcset');\n  var result = [];\n  var container = el.parentNode;\n  var containerWidth = container.offsetWidth * scale;\n\n  var spaceIndex = void 0;\n  var tmpSrc = void 0;\n  var tmpWidth = void 0;\n\n  options = options.trim().split(',');\n\n  options.map(function (item) {\n    item = item.trim();\n    spaceIndex = item.lastIndexOf(' ');\n    if (spaceIndex === -1) {\n      tmpSrc = item;\n      tmpWidth = 999998;\n    } else {\n      tmpSrc = item.substr(0, spaceIndex);\n      tmpWidth = parseInt(item.substr(spaceIndex + 1, item.length - spaceIndex - 2), 10);\n    }\n    result.push([tmpWidth, tmpSrc]);\n  });\n\n  result.sort(function (a, b) {\n    if (a[0] < b[0]) {\n      return 1;\n    }\n    if (a[0] > b[0]) {\n      return -1;\n    }\n    if (a[0] === b[0]) {\n      if (b[1].indexOf('.webp', b[1].length - 5) !== -1) {\n        return 1;\n      }\n      if (a[1].indexOf('.webp', a[1].length - 5) !== -1) {\n        return -1;\n      }\n    }\n    return 0;\n  });\n  var bestSelectedSrc = '';\n  var tmpOption = void 0;\n\n  for (var i = 0; i < result.length; i++) {\n    tmpOption = result[i];\n    bestSelectedSrc = tmpOption[1];\n    var next = result[i + 1];\n    if (next && next[0] < containerWidth) {\n      bestSelectedSrc = tmpOption[1];\n      break;\n    } else if (!next) {\n      bestSelectedSrc = tmpOption[1];\n      break;\n    }\n  }\n\n  return bestSelectedSrc;\n}\n\nfunction find(arr, fn) {\n  var item = void 0;\n  for (var i = 0, len = arr.length; i < len; i++) {\n    if (fn(arr[i])) {\n      item = arr[i];\n      break;\n    }\n  }\n  return item;\n}\n\nvar getDPR = function getDPR() {\n  var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;\n  return inBrowser ? window.devicePixelRatio || scale : scale;\n};\n\nfunction supportWebp() {\n  if (!inBrowser) return false;\n\n  var support = true;\n\n  try {\n    var elem = document.createElement('canvas');\n\n    if (elem.getContext && elem.getContext('2d')) {\n      support = elem.toDataURL('image/webp').indexOf('data:image/webp') === 0;\n    }\n  } catch (err) {\n    support = false;\n  }\n\n  return support;\n}\n\nfunction throttle(action, delay) {\n  var timeout = null;\n  var movement = null;\n  var lastRun = 0;\n  var needRun = false;\n  return function () {\n    needRun = true;\n    if (timeout) {\n      return;\n    }\n    var elapsed = Date.now() - lastRun;\n    var context = this;\n    var args = arguments;\n    var runCallback = function runCallback() {\n      lastRun = Date.now();\n      timeout = false;\n      action.apply(context, args);\n    };\n    if (elapsed >= delay) {\n      runCallback();\n    } else {\n      timeout = setTimeout(runCallback, delay);\n    }\n    if (needRun) {\n      clearTimeout(movement);\n      movement = setTimeout(runCallback, 2 * delay);\n    }\n  };\n}\n\nfunction testSupportsPassive() {\n  if (!inBrowser) return;\n  var support = false;\n  try {\n    var opts = Object.defineProperty({}, 'passive', {\n      get: function get() {\n        support = true;\n      }\n    });\n    window.addEventListener('test', null, opts);\n  } catch (e) {}\n  return support;\n}\n\nvar supportsPassive = testSupportsPassive();\n\nvar _ = {\n  on: function on(el, type, func) {\n    var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n\n    if (supportsPassive) {\n      el.addEventListener(type, func, {\n        capture: capture,\n        passive: true\n      });\n    } else {\n      el.addEventListener(type, func, capture);\n    }\n  },\n  off: function off(el, type, func) {\n    var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n\n    el.removeEventListener(type, func, capture);\n  }\n};\n\nvar loadImageAsync = function loadImageAsync(item, resolve, reject) {\n  var image = new Image();\n  if (!item || !item.src) {\n    var err = new Error('image src is required');\n    return reject(err);\n  }\n\n  image.src = item.src;\n  if (item.cors) {\n    image.crossOrigin = item.cors;\n  }\n\n  image.onload = function () {\n    resolve({\n      naturalHeight: image.naturalHeight,\n      naturalWidth: image.naturalWidth,\n      src: image.src\n    });\n  };\n\n  image.onerror = function (e) {\n    reject(e);\n  };\n};\n\nvar style = function style(el, prop) {\n  return typeof getComputedStyle !== 'undefined' ? getComputedStyle(el, null).getPropertyValue(prop) : el.style[prop];\n};\n\nvar overflow = function overflow(el) {\n  return style(el, 'overflow') + style(el, 'overflow-y') + style(el, 'overflow-x');\n};\n\nvar scrollParent = function scrollParent(el) {\n  if (!inBrowser) return;\n  if (!(el instanceof HTMLElement)) {\n    return window;\n  }\n\n  var parent = el;\n\n  while (parent) {\n    if (parent === document.body || parent === document.documentElement) {\n      break;\n    }\n\n    if (!parent.parentNode) {\n      break;\n    }\n\n    if (/(scroll|auto)/.test(overflow(parent))) {\n      return parent;\n    }\n\n    parent = parent.parentNode;\n  }\n\n  return window;\n};\n\nfunction isObject(obj) {\n  return obj !== null && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object';\n}\n\nfunction ObjectKeys(obj) {\n  if (!(obj instanceof Object)) return [];\n  if (Object.keys) {\n    return Object.keys(obj);\n  } else {\n    var keys = [];\n    for (var key in obj) {\n      if (obj.hasOwnProperty(key)) {\n        keys.push(key);\n      }\n    }\n    return keys;\n  }\n}\n\nfunction ArrayFrom(arrLike) {\n  var len = arrLike.length;\n  var list = [];\n  for (var i = 0; i < len; i++) {\n    list.push(arrLike[i]);\n  }\n  return list;\n}\n\nfunction noop() {}\n\nvar ImageCache = function () {\n  function ImageCache(_ref) {\n    var max = _ref.max;\n    classCallCheck(this, ImageCache);\n\n    this.options = {\n      max: max || 100\n    };\n    this._caches = [];\n  }\n\n  createClass(ImageCache, [{\n    key: 'has',\n    value: function has(key) {\n      return this._caches.indexOf(key) > -1;\n    }\n  }, {\n    key: 'add',\n    value: function add(key) {\n      if (this.has(key)) return;\n      this._caches.push(key);\n      if (this._caches.length > this.options.max) {\n        this.free();\n      }\n    }\n  }, {\n    key: 'free',\n    value: function free() {\n      this._caches.shift();\n    }\n  }]);\n  return ImageCache;\n}();\n\n// el: {\n//     state,\n//     src,\n//     error,\n//     loading\n// }\n\nvar ReactiveListener = function () {\n  function ReactiveListener(_ref) {\n    var el = _ref.el,\n        src = _ref.src,\n        error = _ref.error,\n        loading = _ref.loading,\n        bindType = _ref.bindType,\n        $parent = _ref.$parent,\n        options = _ref.options,\n        cors = _ref.cors,\n        elRenderer = _ref.elRenderer,\n        imageCache = _ref.imageCache;\n    classCallCheck(this, ReactiveListener);\n\n    this.el = el;\n    this.src = src;\n    this.error = error;\n    this.loading = loading;\n    this.bindType = bindType;\n    this.attempt = 0;\n    this.cors = cors;\n\n    this.naturalHeight = 0;\n    this.naturalWidth = 0;\n\n    this.options = options;\n\n    this.rect = null;\n\n    this.$parent = $parent;\n    this.elRenderer = elRenderer;\n    this._imageCache = imageCache;\n    this.performanceData = {\n      init: Date.now(),\n      loadStart: 0,\n      loadEnd: 0\n    };\n\n    this.filter();\n    this.initState();\n    this.render('loading', false);\n  }\n\n  /*\n   * init listener state\n   * @return\n   */\n\n\n  createClass(ReactiveListener, [{\n    key: 'initState',\n    value: function initState() {\n      if ('dataset' in this.el) {\n        this.el.dataset.src = this.src;\n      } else {\n        this.el.setAttribute('data-src', this.src);\n      }\n\n      this.state = {\n        loading: false,\n        error: false,\n        loaded: false,\n        rendered: false\n      };\n    }\n\n    /*\n     * record performance\n     * @return\n     */\n\n  }, {\n    key: 'record',\n    value: function record(event) {\n      this.performanceData[event] = Date.now();\n    }\n\n    /*\n     * update image listener data\n     * @param  {String} image uri\n     * @param  {String} loading image uri\n     * @param  {String} error image uri\n     * @return\n     */\n\n  }, {\n    key: 'update',\n    value: function update(_ref2) {\n      var src = _ref2.src,\n          loading = _ref2.loading,\n          error = _ref2.error;\n\n      var oldSrc = this.src;\n      this.src = src;\n      this.loading = loading;\n      this.error = error;\n      this.filter();\n      if (oldSrc !== this.src) {\n        this.attempt = 0;\n        this.initState();\n      }\n    }\n\n    /*\n     * get el node rect\n     * @return\n     */\n\n  }, {\n    key: 'getRect',\n    value: function getRect() {\n      this.rect = this.el.getBoundingClientRect();\n    }\n\n    /*\n     *  check el is in view\n     * @return {Boolean} el is in view\n     */\n\n  }, {\n    key: 'checkInView',\n    value: function checkInView() {\n      this.getRect();\n      return this.rect.top < window.innerHeight * this.options.preLoad && this.rect.bottom > this.options.preLoadTop && this.rect.left < window.innerWidth * this.options.preLoad && this.rect.right > 0;\n    }\n\n    /*\n     * listener filter\n     */\n\n  }, {\n    key: 'filter',\n    value: function filter() {\n      var _this = this;\n\n      ObjectKeys(this.options.filter).map(function (key) {\n        _this.options.filter[key](_this, _this.options);\n      });\n    }\n\n    /*\n     * render loading first\n     * @params cb:Function\n     * @return\n     */\n\n  }, {\n    key: 'renderLoading',\n    value: function renderLoading(cb) {\n      var _this2 = this;\n\n      this.state.loading = true;\n      loadImageAsync({\n        src: this.loading,\n        cors: this.cors\n      }, function (data) {\n        _this2.render('loading', false);\n        _this2.state.loading = false;\n        cb();\n      }, function () {\n        // handler `loading image` load failed\n        cb();\n        _this2.state.loading = false;\n        if (!_this2.options.silent) console.warn('VueLazyload log: load failed with loading image(' + _this2.loading + ')');\n      });\n    }\n\n    /*\n     * try load image and  render it\n     * @return\n     */\n\n  }, {\n    key: 'load',\n    value: function load() {\n      var _this3 = this;\n\n      var onFinish = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : noop;\n\n      if (this.attempt > this.options.attempt - 1 && this.state.error) {\n        if (!this.options.silent) console.log('VueLazyload log: ' + this.src + ' tried too more than ' + this.options.attempt + ' times');\n        onFinish();\n        return;\n      }\n      if (this.state.rendered && this.state.loaded) return;\n      if (this._imageCache.has(this.src)) {\n        this.state.loaded = true;\n        this.render('loaded', true);\n        this.state.rendered = true;\n        return onFinish();\n      }\n\n      this.renderLoading(function () {\n        _this3.attempt++;\n\n        _this3.options.adapter['beforeLoad'] && _this3.options.adapter['beforeLoad'](_this3, _this3.options);\n        _this3.record('loadStart');\n\n        loadImageAsync({\n          src: _this3.src,\n          cors: _this3.cors\n        }, function (data) {\n          _this3.naturalHeight = data.naturalHeight;\n          _this3.naturalWidth = data.naturalWidth;\n          _this3.state.loaded = true;\n          _this3.state.error = false;\n          _this3.record('loadEnd');\n          _this3.render('loaded', false);\n          _this3.state.rendered = true;\n          _this3._imageCache.add(_this3.src);\n          onFinish();\n        }, function (err) {\n          !_this3.options.silent && console.error(err);\n          _this3.state.error = true;\n          _this3.state.loaded = false;\n          _this3.render('error', false);\n        });\n      });\n    }\n\n    /*\n     * render image\n     * @param  {String} state to render // ['loading', 'src', 'error']\n     * @param  {String} is form cache\n     * @return\n     */\n\n  }, {\n    key: 'render',\n    value: function render(state, cache) {\n      this.elRenderer(this, state, cache);\n    }\n\n    /*\n     * output performance data\n     * @return {Object} performance data\n     */\n\n  }, {\n    key: 'performance',\n    value: function performance() {\n      var state = 'loading';\n      var time = 0;\n\n      if (this.state.loaded) {\n        state = 'loaded';\n        time = (this.performanceData.loadEnd - this.performanceData.loadStart) / 1000;\n      }\n\n      if (this.state.error) state = 'error';\n\n      return {\n        src: this.src,\n        state: state,\n        time: time\n      };\n    }\n\n    /*\n     * $destroy\n     * @return\n     */\n\n  }, {\n    key: '$destroy',\n    value: function $destroy() {\n      this.el = null;\n      this.src = null;\n      this.error = null;\n      this.loading = null;\n      this.bindType = null;\n      this.attempt = 0;\n    }\n  }]);\n  return ReactiveListener;\n}();\n\nvar DEFAULT_URL = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';\nvar DEFAULT_EVENTS = ['scroll', 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove'];\nvar DEFAULT_OBSERVER_OPTIONS = {\n  rootMargin: '0px',\n  threshold: 0\n};\n\nfunction Lazy(Vue) {\n  return function () {\n    function Lazy(_ref) {\n      var preLoad = _ref.preLoad,\n          error = _ref.error,\n          throttleWait = _ref.throttleWait,\n          preLoadTop = _ref.preLoadTop,\n          dispatchEvent = _ref.dispatchEvent,\n          loading = _ref.loading,\n          attempt = _ref.attempt,\n          _ref$silent = _ref.silent,\n          silent = _ref$silent === undefined ? true : _ref$silent,\n          scale = _ref.scale,\n          listenEvents = _ref.listenEvents;\n          _ref.hasbind;\n          var filter = _ref.filter,\n          adapter = _ref.adapter,\n          observer = _ref.observer,\n          observerOptions = _ref.observerOptions;\n      classCallCheck(this, Lazy);\n\n      this.version = '\"1.3.5\"';\n      this.mode = modeType.event;\n      this.ListenerQueue = [];\n      this.TargetIndex = 0;\n      this.TargetQueue = [];\n      this.options = {\n        silent: silent,\n        dispatchEvent: !!dispatchEvent,\n        throttleWait: throttleWait || 200,\n        preLoad: preLoad || 1.3,\n        preLoadTop: preLoadTop || 0,\n        error: error || DEFAULT_URL,\n        loading: loading || DEFAULT_URL,\n        attempt: attempt || 3,\n        scale: scale || getDPR(scale),\n        ListenEvents: listenEvents || DEFAULT_EVENTS,\n        hasbind: false,\n        supportWebp: supportWebp(),\n        filter: filter || {},\n        adapter: adapter || {},\n        observer: !!observer,\n        observerOptions: observerOptions || DEFAULT_OBSERVER_OPTIONS\n      };\n      this._initEvent();\n      this._imageCache = new ImageCache({ max: 200 });\n      this.lazyLoadHandler = throttle(this._lazyLoadHandler.bind(this), this.options.throttleWait);\n\n      this.setMode(this.options.observer ? modeType.observer : modeType.event);\n    }\n\n    /**\n     * update config\n     * @param  {Object} config params\n     * @return\n     */\n\n\n    createClass(Lazy, [{\n      key: 'config',\n      value: function config() {\n        var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        assignDeep(this.options, options);\n      }\n\n      /**\n       * output listener's load performance\n       * @return {Array}\n       */\n\n    }, {\n      key: 'performance',\n      value: function performance() {\n        var list = [];\n\n        this.ListenerQueue.map(function (item) {\n          list.push(item.performance());\n        });\n\n        return list;\n      }\n\n      /*\n       * add lazy component to queue\n       * @param  {Vue} vm lazy component instance\n       * @return\n       */\n\n    }, {\n      key: 'addLazyBox',\n      value: function addLazyBox(vm) {\n        this.ListenerQueue.push(vm);\n        if (inBrowser) {\n          this._addListenerTarget(window);\n          this._observer && this._observer.observe(vm.el);\n          if (vm.$el && vm.$el.parentNode) {\n            this._addListenerTarget(vm.$el.parentNode);\n          }\n        }\n      }\n\n      /*\n       * add image listener to queue\n       * @param  {DOM} el\n       * @param  {object} binding vue directive binding\n       * @param  {vnode} vnode vue directive vnode\n       * @return\n       */\n\n    }, {\n      key: 'add',\n      value: function add(el, binding, vnode) {\n        var _this = this;\n\n        if (some(this.ListenerQueue, function (item) {\n          return item.el === el;\n        })) {\n          this.update(el, binding);\n          return Vue.nextTick(this.lazyLoadHandler);\n        }\n\n        var _valueFormatter2 = this._valueFormatter(binding.value),\n            src = _valueFormatter2.src,\n            loading = _valueFormatter2.loading,\n            error = _valueFormatter2.error,\n            cors = _valueFormatter2.cors;\n\n        Vue.nextTick(function () {\n          src = getBestSelectionFromSrcset(el, _this.options.scale) || src;\n          _this._observer && _this._observer.observe(el);\n\n          var container = Object.keys(binding.modifiers)[0];\n          var $parent = void 0;\n\n          if (container) {\n            $parent = vnode.context.$refs[container];\n            // if there is container passed in, try ref first, then fallback to getElementById to support the original usage\n            $parent = $parent ? $parent.$el || $parent : document.getElementById(container);\n          }\n\n          if (!$parent) {\n            $parent = scrollParent(el);\n          }\n\n          var newListener = new ReactiveListener({\n            bindType: binding.arg,\n            $parent: $parent,\n            el: el,\n            loading: loading,\n            error: error,\n            src: src,\n            cors: cors,\n            elRenderer: _this._elRenderer.bind(_this),\n            options: _this.options,\n            imageCache: _this._imageCache\n          });\n\n          _this.ListenerQueue.push(newListener);\n\n          if (inBrowser) {\n            _this._addListenerTarget(window);\n            _this._addListenerTarget($parent);\n          }\n\n          _this.lazyLoadHandler();\n          Vue.nextTick(function () {\n            return _this.lazyLoadHandler();\n          });\n        });\n      }\n\n      /**\n      * update image src\n      * @param  {DOM} el\n      * @param  {object} vue directive binding\n      * @return\n      */\n\n    }, {\n      key: 'update',\n      value: function update(el, binding, vnode) {\n        var _this2 = this;\n\n        var _valueFormatter3 = this._valueFormatter(binding.value),\n            src = _valueFormatter3.src,\n            loading = _valueFormatter3.loading,\n            error = _valueFormatter3.error;\n\n        src = getBestSelectionFromSrcset(el, this.options.scale) || src;\n\n        var exist = find(this.ListenerQueue, function (item) {\n          return item.el === el;\n        });\n        if (!exist) {\n          this.add(el, binding, vnode);\n        } else {\n          exist.update({\n            src: src,\n            loading: loading,\n            error: error\n          });\n        }\n        if (this._observer) {\n          this._observer.unobserve(el);\n          this._observer.observe(el);\n        }\n        this.lazyLoadHandler();\n        Vue.nextTick(function () {\n          return _this2.lazyLoadHandler();\n        });\n      }\n\n      /**\n      * remove listener form list\n      * @param  {DOM} el\n      * @return\n      */\n\n    }, {\n      key: 'remove',\n      value: function remove$1(el) {\n        if (!el) return;\n        this._observer && this._observer.unobserve(el);\n        var existItem = find(this.ListenerQueue, function (item) {\n          return item.el === el;\n        });\n        if (existItem) {\n          this._removeListenerTarget(existItem.$parent);\n          this._removeListenerTarget(window);\n          remove(this.ListenerQueue, existItem);\n          existItem.$destroy();\n        }\n      }\n\n      /*\n       * remove lazy components form list\n       * @param  {Vue} vm Vue instance\n       * @return\n       */\n\n    }, {\n      key: 'removeComponent',\n      value: function removeComponent(vm) {\n        if (!vm) return;\n        remove(this.ListenerQueue, vm);\n        this._observer && this._observer.unobserve(vm.el);\n        if (vm.$parent && vm.$el.parentNode) {\n          this._removeListenerTarget(vm.$el.parentNode);\n        }\n        this._removeListenerTarget(window);\n      }\n    }, {\n      key: 'setMode',\n      value: function setMode(mode) {\n        var _this3 = this;\n\n        if (!hasIntersectionObserver && mode === modeType.observer) {\n          mode = modeType.event;\n        }\n\n        this.mode = mode; // event or observer\n\n        if (mode === modeType.event) {\n          if (this._observer) {\n            this.ListenerQueue.forEach(function (listener) {\n              _this3._observer.unobserve(listener.el);\n            });\n            this._observer = null;\n          }\n\n          this.TargetQueue.forEach(function (target) {\n            _this3._initListen(target.el, true);\n          });\n        } else {\n          this.TargetQueue.forEach(function (target) {\n            _this3._initListen(target.el, false);\n          });\n          this._initIntersectionObserver();\n        }\n      }\n\n      /*\n      *** Private functions ***\n      */\n\n      /*\n       * add listener target\n       * @param  {DOM} el listener target\n       * @return\n       */\n\n    }, {\n      key: '_addListenerTarget',\n      value: function _addListenerTarget(el) {\n        if (!el) return;\n        var target = find(this.TargetQueue, function (target) {\n          return target.el === el;\n        });\n        if (!target) {\n          target = {\n            el: el,\n            id: ++this.TargetIndex,\n            childrenCount: 1,\n            listened: true\n          };\n          this.mode === modeType.event && this._initListen(target.el, true);\n          this.TargetQueue.push(target);\n        } else {\n          target.childrenCount++;\n        }\n        return this.TargetIndex;\n      }\n\n      /*\n       * remove listener target or reduce target childrenCount\n       * @param  {DOM} el or window\n       * @return\n       */\n\n    }, {\n      key: '_removeListenerTarget',\n      value: function _removeListenerTarget(el) {\n        var _this4 = this;\n\n        this.TargetQueue.forEach(function (target, index) {\n          if (target.el === el) {\n            target.childrenCount--;\n            if (!target.childrenCount) {\n              _this4._initListen(target.el, false);\n              _this4.TargetQueue.splice(index, 1);\n              target = null;\n            }\n          }\n        });\n      }\n\n      /*\n       * add or remove eventlistener\n       * @param  {DOM} el DOM or Window\n       * @param  {boolean} start flag\n       * @return\n       */\n\n    }, {\n      key: '_initListen',\n      value: function _initListen(el, start) {\n        var _this5 = this;\n\n        this.options.ListenEvents.forEach(function (evt) {\n          return _[start ? 'on' : 'off'](el, evt, _this5.lazyLoadHandler);\n        });\n      }\n    }, {\n      key: '_initEvent',\n      value: function _initEvent() {\n        var _this6 = this;\n\n        this.Event = {\n          listeners: {\n            loading: [],\n            loaded: [],\n            error: []\n          }\n        };\n\n        this.$on = function (event, func) {\n          if (!_this6.Event.listeners[event]) _this6.Event.listeners[event] = [];\n          _this6.Event.listeners[event].push(func);\n        };\n\n        this.$once = function (event, func) {\n          var vm = _this6;\n          function on() {\n            vm.$off(event, on);\n            func.apply(vm, arguments);\n          }\n          _this6.$on(event, on);\n        };\n\n        this.$off = function (event, func) {\n          if (!func) {\n            if (!_this6.Event.listeners[event]) return;\n            _this6.Event.listeners[event].length = 0;\n            return;\n          }\n          remove(_this6.Event.listeners[event], func);\n        };\n\n        this.$emit = function (event, context, inCache) {\n          if (!_this6.Event.listeners[event]) return;\n          _this6.Event.listeners[event].forEach(function (func) {\n            return func(context, inCache);\n          });\n        };\n      }\n\n      /**\n       * find nodes which in viewport and trigger load\n       * @return\n       */\n\n    }, {\n      key: '_lazyLoadHandler',\n      value: function _lazyLoadHandler() {\n        var _this7 = this;\n\n        var freeList = [];\n        this.ListenerQueue.forEach(function (listener, index) {\n          if (!listener.el || !listener.el.parentNode) {\n            freeList.push(listener);\n          }\n          var catIn = listener.checkInView();\n          if (!catIn) return;\n          listener.load();\n        });\n        freeList.forEach(function (item) {\n          remove(_this7.ListenerQueue, item);\n          item.$destroy();\n        });\n      }\n      /**\n      * init IntersectionObserver\n      * set mode to observer\n      * @return\n      */\n\n    }, {\n      key: '_initIntersectionObserver',\n      value: function _initIntersectionObserver() {\n        var _this8 = this;\n\n        if (!hasIntersectionObserver) return;\n        this._observer = new IntersectionObserver(this._observerHandler.bind(this), this.options.observerOptions);\n        if (this.ListenerQueue.length) {\n          this.ListenerQueue.forEach(function (listener) {\n            _this8._observer.observe(listener.el);\n          });\n        }\n      }\n\n      /**\n      * init IntersectionObserver\n      * @return\n      */\n\n    }, {\n      key: '_observerHandler',\n      value: function _observerHandler(entries, observer) {\n        var _this9 = this;\n\n        entries.forEach(function (entry) {\n          if (entry.isIntersecting) {\n            _this9.ListenerQueue.forEach(function (listener) {\n              if (listener.el === entry.target) {\n                if (listener.state.loaded) return _this9._observer.unobserve(listener.el);\n                listener.load();\n              }\n            });\n          }\n        });\n      }\n\n      /**\n      * set element attribute with image'url and state\n      * @param  {object} lazyload listener object\n      * @param  {string} state will be rendered\n      * @param  {bool} inCache  is rendered from cache\n      * @return\n      */\n\n    }, {\n      key: '_elRenderer',\n      value: function _elRenderer(listener, state, cache) {\n        if (!listener.el) return;\n        var el = listener.el,\n            bindType = listener.bindType;\n\n\n        var src = void 0;\n        switch (state) {\n          case 'loading':\n            src = listener.loading;\n            break;\n          case 'error':\n            src = listener.error;\n            break;\n          default:\n            src = listener.src;\n            break;\n        }\n\n        if (bindType) {\n          el.style[bindType] = 'url(\"' + src + '\")';\n        } else if (el.getAttribute('src') !== src) {\n          el.setAttribute('src', src);\n        }\n\n        el.setAttribute('lazy', state);\n\n        this.$emit(state, listener, cache);\n        this.options.adapter[state] && this.options.adapter[state](listener, this.options);\n\n        if (this.options.dispatchEvent) {\n          var event = new CustomEvent(state, {\n            detail: listener\n          });\n          el.dispatchEvent(event);\n        }\n      }\n\n      /**\n      * generate loading loaded error image url\n      * @param {string} image's src\n      * @return {object} image's loading, loaded, error url\n      */\n\n    }, {\n      key: '_valueFormatter',\n      value: function _valueFormatter(value) {\n        var src = value;\n        var loading = this.options.loading;\n        var error = this.options.error;\n\n        // value is object\n        if (isObject(value)) {\n          if (!value.src && !this.options.silent) console.error('Vue Lazyload warning: miss src with ' + value);\n          src = value.src;\n          loading = value.loading || this.options.loading;\n          error = value.error || this.options.error;\n        }\n        return {\n          src: src,\n          loading: loading,\n          error: error\n        };\n      }\n    }]);\n    return Lazy;\n  }();\n}\n\nLazy.install = function (Vue) {\n  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n  var LazyClass = Lazy(Vue);\n  var lazy = new LazyClass(options);\n\n  var isVue2 = Vue.version.split('.')[0] === '2';\n  if (isVue2) {\n    Vue.directive('lazy', {\n      bind: lazy.add.bind(lazy),\n      update: lazy.update.bind(lazy),\n      componentUpdated: lazy.lazyLoadHandler.bind(lazy),\n      unbind: lazy.remove.bind(lazy)\n    });\n  } else {\n    Vue.directive('lazy', {\n      bind: lazy.lazyLoadHandler.bind(lazy),\n      update: function update(newValue, oldValue) {\n        assignDeep(this.vm.$refs, this.vm.$els);\n        lazy.add(this.el, {\n          modifiers: this.modifiers || {},\n          arg: this.arg,\n          value: newValue,\n          oldValue: oldValue\n        }, {\n          context: this.vm\n        });\n      },\n      unbind: function unbind() {\n        lazy.remove(this.el);\n      }\n    });\n  }\n};\n\nvar LazyComponent = function LazyComponent(lazy) {\n  return {\n    props: {\n      tag: {\n        type: String,\n        default: 'div'\n      }\n    },\n    render: function render(h) {\n      return h(this.tag, null, this.show ? this.$slots.default : null);\n    },\n    data: function data() {\n      return {\n        el: null,\n        state: {\n          loaded: false\n        },\n        rect: {},\n        show: false\n      };\n    },\n    mounted: function mounted() {\n      this.el = this.$el;\n      lazy.addLazyBox(this);\n      lazy.lazyLoadHandler();\n    },\n    beforeDestroy: function beforeDestroy() {\n      lazy.removeComponent(this);\n    },\n\n    methods: {\n      getRect: function getRect() {\n        this.rect = this.$el.getBoundingClientRect();\n      },\n      checkInView: function checkInView() {\n        this.getRect();\n        return inBrowser && this.rect.top < window.innerHeight * lazy.options.preLoad && this.rect.bottom > 0 && this.rect.left < window.innerWidth * lazy.options.preLoad && this.rect.right > 0;\n      },\n      load: function load() {\n        this.show = true;\n        this.state.loaded = true;\n        this.$emit('show', this);\n      },\n      destroy: function destroy() {\n        return this.$destroy;\n      }\n    }\n  };\n};\n\nLazyComponent.install = function (Vue) {\n  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n  var LazyClass = Lazy(Vue);\n  var lazy = new LazyClass(options);\n  Vue.component('lazy-component', LazyComponent(lazy));\n};\n\nvar LazyContainerMananger = function () {\n  function LazyContainerMananger(_ref) {\n    var lazy = _ref.lazy;\n    classCallCheck(this, LazyContainerMananger);\n\n    this.lazy = lazy;\n    lazy.lazyContainerMananger = this;\n    this._queue = [];\n  }\n\n  createClass(LazyContainerMananger, [{\n    key: 'bind',\n    value: function bind(el, binding, vnode) {\n      var container = new LazyContainer({ el: el, binding: binding, vnode: vnode, lazy: this.lazy });\n      this._queue.push(container);\n    }\n  }, {\n    key: 'update',\n    value: function update(el, binding, vnode) {\n      var container = find(this._queue, function (item) {\n        return item.el === el;\n      });\n      if (!container) return;\n      container.update({ el: el, binding: binding, vnode: vnode });\n    }\n  }, {\n    key: 'unbind',\n    value: function unbind(el, binding, vnode) {\n      var container = find(this._queue, function (item) {\n        return item.el === el;\n      });\n      if (!container) return;\n      container.clear();\n      remove(this._queue, container);\n    }\n  }]);\n  return LazyContainerMananger;\n}();\n\n\nvar defaultOptions = {\n  selector: 'img'\n};\n\nvar LazyContainer = function () {\n  function LazyContainer(_ref2) {\n    var el = _ref2.el,\n        binding = _ref2.binding,\n        vnode = _ref2.vnode,\n        lazy = _ref2.lazy;\n    classCallCheck(this, LazyContainer);\n\n    this.el = null;\n    this.vnode = vnode;\n    this.binding = binding;\n    this.options = {};\n    this.lazy = lazy;\n\n    this._queue = [];\n    this.update({ el: el, binding: binding });\n  }\n\n  createClass(LazyContainer, [{\n    key: 'update',\n    value: function update(_ref3) {\n      var _this = this;\n\n      var el = _ref3.el,\n          binding = _ref3.binding;\n\n      this.el = el;\n      this.options = assignDeep({}, defaultOptions, binding.value);\n\n      var imgs = this.getImgs();\n      imgs.forEach(function (el) {\n        _this.lazy.add(el, assignDeep({}, _this.binding, {\n          value: {\n            src: 'dataset' in el ? el.dataset.src : el.getAttribute('data-src'),\n            error: ('dataset' in el ? el.dataset.error : el.getAttribute('data-error')) || _this.options.error,\n            loading: ('dataset' in el ? el.dataset.loading : el.getAttribute('data-loading')) || _this.options.loading\n          }\n        }), _this.vnode);\n      });\n    }\n  }, {\n    key: 'getImgs',\n    value: function getImgs() {\n      return ArrayFrom(this.el.querySelectorAll(this.options.selector));\n    }\n  }, {\n    key: 'clear',\n    value: function clear() {\n      var _this2 = this;\n\n      var imgs = this.getImgs();\n      imgs.forEach(function (el) {\n        return _this2.lazy.remove(el);\n      });\n\n      this.vnode = null;\n      this.binding = null;\n      this.lazy = null;\n    }\n  }]);\n  return LazyContainer;\n}();\n\nLazyContainer.install = function (Vue) {\n  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n  var LazyClass = Lazy(Vue);\n  var lazy = new LazyClass(options);\n  var lazyContainer = new LazyContainer({ lazy: lazy });\n\n  var isVue2 = Vue.version.split('.')[0] === '2';\n  if (isVue2) {\n    Vue.directive('lazy-container', {\n      bind: lazyContainer.bind.bind(lazyContainer),\n      componentUpdated: lazyContainer.update.bind(lazyContainer),\n      unbind: lazyContainer.unbind.bind(lazyContainer)\n    });\n  } else {\n    Vue.directive('lazy-container', {\n      update: function update(newValue, oldValue) {\n        lazyContainer.update(this.el, {\n          modifiers: this.modifiers || {},\n          arg: this.arg,\n          value: newValue,\n          oldValue: oldValue\n        }, {\n          context: this.vm\n        });\n      },\n      unbind: function unbind() {\n        lazyContainer.unbind(this.el);\n      }\n    });\n  }\n};\n\nvar LazyImage = function LazyImage(lazyManager) {\n  return {\n    props: {\n      src: [String, Object],\n      tag: {\n        type: String,\n        default: 'img'\n      }\n    },\n    render: function render(h) {\n      return h(this.tag, {\n        attrs: {\n          src: this.renderSrc\n        }\n      }, this.$slots.default);\n    },\n    data: function data() {\n      return {\n        el: null,\n        options: {\n          src: '',\n          error: '',\n          loading: '',\n          attempt: lazyManager.options.attempt\n        },\n        state: {\n          loaded: false,\n          error: false,\n          attempt: 0\n        },\n        rect: {},\n        renderSrc: ''\n      };\n    },\n\n    watch: {\n      src: function src() {\n        this.init();\n        lazyManager.addLazyBox(this);\n        lazyManager.lazyLoadHandler();\n      }\n    },\n    created: function created() {\n      this.init();\n      this.renderSrc = this.options.loading;\n    },\n    mounted: function mounted() {\n      this.el = this.$el;\n      lazyManager.addLazyBox(this);\n      lazyManager.lazyLoadHandler();\n    },\n    beforeDestroy: function beforeDestroy() {\n      lazyManager.removeComponent(this);\n    },\n\n    methods: {\n      init: function init() {\n        var _lazyManager$_valueFo = lazyManager._valueFormatter(this.src),\n            src = _lazyManager$_valueFo.src,\n            loading = _lazyManager$_valueFo.loading,\n            error = _lazyManager$_valueFo.error;\n\n        this.state.loaded = false;\n        this.options.src = src;\n        this.options.error = error;\n        this.options.loading = loading;\n        this.renderSrc = this.options.loading;\n      },\n      getRect: function getRect() {\n        this.rect = this.$el.getBoundingClientRect();\n      },\n      checkInView: function checkInView() {\n        this.getRect();\n        return inBrowser && this.rect.top < window.innerHeight * lazyManager.options.preLoad && this.rect.bottom > 0 && this.rect.left < window.innerWidth * lazyManager.options.preLoad && this.rect.right > 0;\n      },\n      load: function load() {\n        var _this = this;\n\n        var onFinish = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : noop;\n\n        if (this.state.attempt > this.options.attempt - 1 && this.state.error) {\n          if (!lazyManager.options.silent) console.log('VueLazyload log: ' + this.options.src + ' tried too more than ' + this.options.attempt + ' times');\n          onFinish();\n          return;\n        }\n        var src = this.options.src;\n        loadImageAsync({ src: src }, function (_ref) {\n          var src = _ref.src;\n\n          _this.renderSrc = src;\n          _this.state.loaded = true;\n        }, function (e) {\n          _this.state.attempt++;\n          _this.renderSrc = _this.options.error;\n          _this.state.error = true;\n        });\n      }\n    }\n  };\n};\n\nLazyImage.install = function (Vue) {\n  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n  var LazyClass = Lazy(Vue);\n  var lazy = new LazyClass(options);\n  Vue.component('lazy-image', LazyImage(lazy));\n};\n\nvar index = {\n  /*\n  * install function\n  * @param  {Vue} Vue\n  * @param  {object} options  lazyload options\n  */\n  install: function install(Vue) {\n    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n    var LazyClass = Lazy(Vue);\n    var lazy = new LazyClass(options);\n    var lazyContainer = new LazyContainerMananger({ lazy: lazy });\n\n    var isVue2 = Vue.version.split('.')[0] === '2';\n\n    Vue.prototype.$Lazyload = lazy;\n\n    if (options.lazyComponent) {\n      Vue.component('lazy-component', LazyComponent(lazy));\n    }\n\n    if (options.lazyImage) {\n      Vue.component('lazy-image', LazyImage(lazy));\n    }\n\n    if (isVue2) {\n      Vue.directive('lazy', {\n        bind: lazy.add.bind(lazy),\n        update: lazy.update.bind(lazy),\n        componentUpdated: lazy.lazyLoadHandler.bind(lazy),\n        unbind: lazy.remove.bind(lazy)\n      });\n      Vue.directive('lazy-container', {\n        bind: lazyContainer.bind.bind(lazyContainer),\n        componentUpdated: lazyContainer.update.bind(lazyContainer),\n        unbind: lazyContainer.unbind.bind(lazyContainer)\n      });\n    } else {\n      Vue.directive('lazy', {\n        bind: lazy.lazyLoadHandler.bind(lazy),\n        update: function update(newValue, oldValue) {\n          assignDeep(this.vm.$refs, this.vm.$els);\n          lazy.add(this.el, {\n            modifiers: this.modifiers || {},\n            arg: this.arg,\n            value: newValue,\n            oldValue: oldValue\n          }, {\n            context: this.vm\n          });\n        },\n        unbind: function unbind() {\n          lazy.remove(this.el);\n        }\n      });\n\n      Vue.directive('lazy-container', {\n        update: function update(newValue, oldValue) {\n          lazyContainer.update(this.el, {\n            modifiers: this.modifiers || {},\n            arg: this.arg,\n            value: newValue,\n            oldValue: oldValue\n          }, {\n            context: this.vm\n          });\n        },\n        unbind: function unbind() {\n          lazyContainer.unbind(this.el);\n        }\n      });\n    }\n  }\n};\n\nexport { Lazy, LazyComponent, LazyContainerMananger as LazyContainer, LazyImage, index as default };\n"
  },
  {
    "path": "vue-lazyload.js",
    "content": "/*!\n * Vue-Lazyload.js v1.3.5\n * (c) 2023 Awe <hilongjw@gmail.com>\n * Released under the MIT License.\n */\n!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?e(exports):\"function\"==typeof define&&define.amd?define([\"exports\"],e):e((t=\"undefined\"!=typeof globalThis?globalThis:t||self).VueLazyload={})}(this,(function(t){\"use strict\";function e(t,e){return t(e={exports:{}},e.exports),e.exports}var n=e((function(t){var e=Object.prototype.toString,n=Object.prototype.propertyIsEnumerable,i=Object.getOwnPropertySymbols;t.exports=function(t){for(var r=arguments.length,o=Array(r>1?r-1:0),s=1;s<r;s++)o[s-1]=arguments[s];if(\"function\"!=typeof(a=t)&&\"[object Object]\"!==e.call(a)&&!Array.isArray(a))throw new TypeError(\"expected the first argument to be an object\");var a;if(0===o.length||\"function\"!=typeof Symbol||\"function\"!=typeof i)return t;var u=!0,l=!1,d=void 0;try{for(var c,h=o[Symbol.iterator]();!(u=(c=h.next()).done);u=!0){var f=c.value,v=i(f),p=!0,y=!1,g=void 0;try{for(var b,m=v[Symbol.iterator]();!(p=(b=m.next()).done);p=!0){var w=b.value;n.call(f,w)&&(t[w]=f[w])}}catch(t){y=!0,g=t}finally{try{!p&&m.return&&m.return()}finally{if(y)throw g}}}}catch(t){l=!0,d=t}finally{try{!u&&h.return&&h.return()}finally{if(l)throw d}}return t}})),i=Object.freeze({__proto__:null,default:n,__moduleExports:n}),r=i&&n||i,o=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&\"function\"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?\"symbol\":typeof t},s=function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")},a=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,\"value\"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}(),u=e((function(t){var e=Object.prototype.toString,n=function(t){return\"__proto__\"!==t&&\"constructor\"!==t&&\"prototype\"!==t},i=t.exports=function(t){for(var e=arguments.length,a=Array(e>1?e-1:0),u=1;u<e;u++)a[u-1]=arguments[u];var l,d=0;for((\"object\"===(void 0===(l=t)?\"undefined\":o(l))?null===l:\"function\"!=typeof l)&&(t=a[d++]),t||(t={});d<a.length;d++)if(s(a[d])){var c=!0,h=!1,f=void 0;try{for(var v,p=Object.keys(a[d])[Symbol.iterator]();!(c=(v=p.next()).done);c=!0){var y=v.value;n(y)&&(s(t[y])&&s(a[d][y])?i(t[y],a[d][y]):t[y]=a[d][y])}}catch(t){h=!0,f=t}finally{try{!c&&p.return&&p.return()}finally{if(h)throw f}}r(t,a[d])}return t};function s(t){return\"function\"==typeof t||\"[object Object]\"===e.call(t)}})),l=\"undefined\"!=typeof window&&null!==window,d=function(){if(l&&\"IntersectionObserver\"in window&&\"IntersectionObserverEntry\"in window&&\"intersectionRatio\"in window.IntersectionObserverEntry.prototype)return\"isIntersecting\"in window.IntersectionObserverEntry.prototype||Object.defineProperty(window.IntersectionObserverEntry.prototype,\"isIntersecting\",{get:function(){return this.intersectionRatio>0}}),!0;return!1}();var c=\"event\",h=\"observer\",f=function(){if(l)return\"function\"==typeof window.CustomEvent?window.CustomEvent:(t.prototype=window.Event.prototype,t);function t(t,e){e=e||{bubbles:!1,cancelable:!1,detail:void 0};var n=document.createEvent(\"CustomEvent\");return n.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),n}}();function v(t,e){if(t.length){var n=t.indexOf(e);return n>-1?t.splice(n,1):void 0}}function p(t,e){if(\"IMG\"===t.tagName&&t.getAttribute(\"data-srcset\")){var n=t.getAttribute(\"data-srcset\"),i=[],r=t.parentNode.offsetWidth*e,o=void 0,s=void 0,a=void 0;(n=n.trim().split(\",\")).map((function(t){t=t.trim(),-1===(o=t.lastIndexOf(\" \"))?(s=t,a=999998):(s=t.substr(0,o),a=parseInt(t.substr(o+1,t.length-o-2),10)),i.push([a,s])})),i.sort((function(t,e){if(t[0]<e[0])return 1;if(t[0]>e[0])return-1;if(t[0]===e[0]){if(-1!==e[1].indexOf(\".webp\",e[1].length-5))return 1;if(-1!==t[1].indexOf(\".webp\",t[1].length-5))return-1}return 0}));for(var u=\"\",l=void 0,d=0;d<i.length;d++){u=(l=i[d])[1];var c=i[d+1];if(c&&c[0]<r){u=l[1];break}if(!c){u=l[1];break}}return u}}function y(t,e){for(var n=void 0,i=0,r=t.length;i<r;i++)if(e(t[i])){n=t[i];break}return n}var g=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return l&&window.devicePixelRatio||t};function b(){if(!l)return!1;var t=!0;try{var e=document.createElement(\"canvas\");e.getContext&&e.getContext(\"2d\")&&(t=0===e.toDataURL(\"image/webp\").indexOf(\"data:image/webp\"))}catch(e){t=!1}return t}var m=function(){if(l){var t=!1;try{var e=Object.defineProperty({},\"passive\",{get:function(){t=!0}});window.addEventListener(\"test\",null,e)}catch(t){}return t}}(),w={on:function(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];m?t.addEventListener(e,n,{capture:i,passive:!0}):t.addEventListener(e,n,i)},off:function(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];t.removeEventListener(e,n,i)}},L=function(t,e,n){var i=new Image;if(!t||!t.src){var r=new Error(\"image src is required\");return n(r)}i.src=t.src,t.cors&&(i.crossOrigin=t.cors),i.onload=function(){e({naturalHeight:i.naturalHeight,naturalWidth:i.naturalWidth,src:i.src})},i.onerror=function(t){n(t)}},_=function(t,e){return\"undefined\"!=typeof getComputedStyle?getComputedStyle(t,null).getPropertyValue(e):t.style[e]},z=function(t){return _(t,\"overflow\")+_(t,\"overflow-y\")+_(t,\"overflow-x\")};function E(){}var k=function(){function t(e){var n=e.max;s(this,t),this.options={max:n||100},this._caches=[]}return a(t,[{key:\"has\",value:function(t){return this._caches.indexOf(t)>-1}},{key:\"add\",value:function(t){this.has(t)||(this._caches.push(t),this._caches.length>this.options.max&&this.free())}},{key:\"free\",value:function(){this._caches.shift()}}]),t}(),x=function(){function t(e){var n=e.el,i=e.src,r=e.error,o=e.loading,a=e.bindType,u=e.$parent,l=e.options,d=e.cors,c=e.elRenderer,h=e.imageCache;s(this,t),this.el=n,this.src=i,this.error=r,this.loading=o,this.bindType=a,this.attempt=0,this.cors=d,this.naturalHeight=0,this.naturalWidth=0,this.options=l,this.rect=null,this.$parent=u,this.elRenderer=c,this._imageCache=h,this.performanceData={init:Date.now(),loadStart:0,loadEnd:0},this.filter(),this.initState(),this.render(\"loading\",!1)}return a(t,[{key:\"initState\",value:function(){\"dataset\"in this.el?this.el.dataset.src=this.src:this.el.setAttribute(\"data-src\",this.src),this.state={loading:!1,error:!1,loaded:!1,rendered:!1}}},{key:\"record\",value:function(t){this.performanceData[t]=Date.now()}},{key:\"update\",value:function(t){var e=t.src,n=t.loading,i=t.error,r=this.src;this.src=e,this.loading=n,this.error=i,this.filter(),r!==this.src&&(this.attempt=0,this.initState())}},{key:\"getRect\",value:function(){this.rect=this.el.getBoundingClientRect()}},{key:\"checkInView\",value:function(){return this.getRect(),this.rect.top<window.innerHeight*this.options.preLoad&&this.rect.bottom>this.options.preLoadTop&&this.rect.left<window.innerWidth*this.options.preLoad&&this.rect.right>0}},{key:\"filter\",value:function(){var t=this;(function(t){if(!(t instanceof Object))return[];if(Object.keys)return Object.keys(t);var e=[];for(var n in t)t.hasOwnProperty(n)&&e.push(n);return e})(this.options.filter).map((function(e){t.options.filter[e](t,t.options)}))}},{key:\"renderLoading\",value:function(t){var e=this;this.state.loading=!0,L({src:this.loading,cors:this.cors},(function(n){e.render(\"loading\",!1),e.state.loading=!1,t()}),(function(){t(),e.state.loading=!1,e.options.silent||console.warn(\"VueLazyload log: load failed with loading image(\"+e.loading+\")\")}))}},{key:\"load\",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:E;return this.attempt>this.options.attempt-1&&this.state.error?(this.options.silent||console.log(\"VueLazyload log: \"+this.src+\" tried too more than \"+this.options.attempt+\" times\"),void e()):this.state.rendered&&this.state.loaded?void 0:this._imageCache.has(this.src)?(this.state.loaded=!0,this.render(\"loaded\",!0),this.state.rendered=!0,e()):void this.renderLoading((function(){t.attempt++,t.options.adapter.beforeLoad&&t.options.adapter.beforeLoad(t,t.options),t.record(\"loadStart\"),L({src:t.src,cors:t.cors},(function(n){t.naturalHeight=n.naturalHeight,t.naturalWidth=n.naturalWidth,t.state.loaded=!0,t.state.error=!1,t.record(\"loadEnd\"),t.render(\"loaded\",!1),t.state.rendered=!0,t._imageCache.add(t.src),e()}),(function(e){!t.options.silent&&console.error(e),t.state.error=!0,t.state.loaded=!1,t.render(\"error\",!1)}))}))}},{key:\"render\",value:function(t,e){this.elRenderer(this,t,e)}},{key:\"performance\",value:function(){var t=\"loading\",e=0;return this.state.loaded&&(t=\"loaded\",e=(this.performanceData.loadEnd-this.performanceData.loadStart)/1e3),this.state.error&&(t=\"error\"),{src:this.src,state:t,time:e}}},{key:\"$destroy\",value:function(){this.el=null,this.src=null,this.error=null,this.loading=null,this.bindType=null,this.attempt=0}}]),t}(),A=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\",T=[\"scroll\",\"wheel\",\"mousewheel\",\"resize\",\"animationend\",\"transitionend\",\"touchmove\"],O={rootMargin:\"0px\",threshold:0};function $(t){return function(){function e(t){var n=t.preLoad,i=t.error,r=t.throttleWait,o=t.preLoadTop,a=t.dispatchEvent,u=t.loading,l=t.attempt,d=t.silent,f=void 0===d||d,v=t.scale,p=t.listenEvents;t.hasbind;var y,m,w,L,_,z,E=t.filter,x=t.adapter,$=t.observer,I=t.observerOptions;s(this,e),this.version='\"1.3.5\"',this.mode=c,this.ListenerQueue=[],this.TargetIndex=0,this.TargetQueue=[],this.options={silent:f,dispatchEvent:!!a,throttleWait:r||200,preLoad:n||1.3,preLoadTop:o||0,error:i||A,loading:u||A,attempt:l||3,scale:v||g(v),ListenEvents:p||T,hasbind:!1,supportWebp:b(),filter:E||{},adapter:x||{},observer:!!$,observerOptions:I||O},this._initEvent(),this._imageCache=new k({max:200}),this.lazyLoadHandler=(y=this._lazyLoadHandler.bind(this),m=this.options.throttleWait,w=null,L=null,_=0,z=!1,function(){if(z=!0,!w){var t=Date.now()-_,e=this,n=arguments,i=function(){_=Date.now(),w=!1,y.apply(e,n)};t>=m?i():w=setTimeout(i,m),z&&(clearTimeout(L),L=setTimeout(i,2*m))}}),this.setMode(this.options.observer?h:c)}return a(e,[{key:\"config\",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};u(this.options,t)}},{key:\"performance\",value:function(){var t=[];return this.ListenerQueue.map((function(e){t.push(e.performance())})),t}},{key:\"addLazyBox\",value:function(t){this.ListenerQueue.push(t),l&&(this._addListenerTarget(window),this._observer&&this._observer.observe(t.el),t.$el&&t.$el.parentNode&&this._addListenerTarget(t.$el.parentNode))}},{key:\"add\",value:function(e,n,i){var r=this;if(function(t,e){for(var n=!1,i=0,r=t.length;i<r;i++)if(e(t[i])){n=!0;break}return n}(this.ListenerQueue,(function(t){return t.el===e})))return this.update(e,n),t.nextTick(this.lazyLoadHandler);var o=this._valueFormatter(n.value),s=o.src,a=o.loading,u=o.error,d=o.cors;t.nextTick((function(){s=p(e,r.options.scale)||s,r._observer&&r._observer.observe(e);var o=Object.keys(n.modifiers)[0],c=void 0;o&&(c=(c=i.context.$refs[o])?c.$el||c:document.getElementById(o)),c||(c=function(t){if(l){if(!(t instanceof HTMLElement))return window;for(var e=t;e&&e!==document.body&&e!==document.documentElement&&e.parentNode;){if(/(scroll|auto)/.test(z(e)))return e;e=e.parentNode}return window}}(e));var h=new x({bindType:n.arg,$parent:c,el:e,loading:a,error:u,src:s,cors:d,elRenderer:r._elRenderer.bind(r),options:r.options,imageCache:r._imageCache});r.ListenerQueue.push(h),l&&(r._addListenerTarget(window),r._addListenerTarget(c)),r.lazyLoadHandler(),t.nextTick((function(){return r.lazyLoadHandler()}))}))}},{key:\"update\",value:function(e,n,i){var r=this,o=this._valueFormatter(n.value),s=o.src,a=o.loading,u=o.error;s=p(e,this.options.scale)||s;var l=y(this.ListenerQueue,(function(t){return t.el===e}));l?l.update({src:s,loading:a,error:u}):this.add(e,n,i),this._observer&&(this._observer.unobserve(e),this._observer.observe(e)),this.lazyLoadHandler(),t.nextTick((function(){return r.lazyLoadHandler()}))}},{key:\"remove\",value:function(t){if(t){this._observer&&this._observer.unobserve(t);var e=y(this.ListenerQueue,(function(e){return e.el===t}));e&&(this._removeListenerTarget(e.$parent),this._removeListenerTarget(window),v(this.ListenerQueue,e),e.$destroy())}}},{key:\"removeComponent\",value:function(t){t&&(v(this.ListenerQueue,t),this._observer&&this._observer.unobserve(t.el),t.$parent&&t.$el.parentNode&&this._removeListenerTarget(t.$el.parentNode),this._removeListenerTarget(window))}},{key:\"setMode\",value:function(t){var e=this;d||t!==h||(t=c),this.mode=t,t===c?(this._observer&&(this.ListenerQueue.forEach((function(t){e._observer.unobserve(t.el)})),this._observer=null),this.TargetQueue.forEach((function(t){e._initListen(t.el,!0)}))):(this.TargetQueue.forEach((function(t){e._initListen(t.el,!1)})),this._initIntersectionObserver())}},{key:\"_addListenerTarget\",value:function(t){if(t){var e=y(this.TargetQueue,(function(e){return e.el===t}));return e?e.childrenCount++:(e={el:t,id:++this.TargetIndex,childrenCount:1,listened:!0},this.mode===c&&this._initListen(e.el,!0),this.TargetQueue.push(e)),this.TargetIndex}}},{key:\"_removeListenerTarget\",value:function(t){var e=this;this.TargetQueue.forEach((function(n,i){n.el===t&&(n.childrenCount--,n.childrenCount||(e._initListen(n.el,!1),e.TargetQueue.splice(i,1),n=null))}))}},{key:\"_initListen\",value:function(t,e){var n=this;this.options.ListenEvents.forEach((function(i){return w[e?\"on\":\"off\"](t,i,n.lazyLoadHandler)}))}},{key:\"_initEvent\",value:function(){var t=this;this.Event={listeners:{loading:[],loaded:[],error:[]}},this.$on=function(e,n){t.Event.listeners[e]||(t.Event.listeners[e]=[]),t.Event.listeners[e].push(n)},this.$once=function(e,n){var i=t;t.$on(e,(function t(){i.$off(e,t),n.apply(i,arguments)}))},this.$off=function(e,n){if(n)v(t.Event.listeners[e],n);else{if(!t.Event.listeners[e])return;t.Event.listeners[e].length=0}},this.$emit=function(e,n,i){t.Event.listeners[e]&&t.Event.listeners[e].forEach((function(t){return t(n,i)}))}}},{key:\"_lazyLoadHandler\",value:function(){var t=this,e=[];this.ListenerQueue.forEach((function(t,n){t.el&&t.el.parentNode||e.push(t),t.checkInView()&&t.load()})),e.forEach((function(e){v(t.ListenerQueue,e),e.$destroy()}))}},{key:\"_initIntersectionObserver\",value:function(){var t=this;d&&(this._observer=new IntersectionObserver(this._observerHandler.bind(this),this.options.observerOptions),this.ListenerQueue.length&&this.ListenerQueue.forEach((function(e){t._observer.observe(e.el)})))}},{key:\"_observerHandler\",value:function(t,e){var n=this;t.forEach((function(t){t.isIntersecting&&n.ListenerQueue.forEach((function(e){if(e.el===t.target){if(e.state.loaded)return n._observer.unobserve(e.el);e.load()}}))}))}},{key:\"_elRenderer\",value:function(t,e,n){if(t.el){var i=t.el,r=t.bindType,o=void 0;switch(e){case\"loading\":o=t.loading;break;case\"error\":o=t.error;break;default:o=t.src}if(r?i.style[r]='url(\"'+o+'\")':i.getAttribute(\"src\")!==o&&i.setAttribute(\"src\",o),i.setAttribute(\"lazy\",e),this.$emit(e,t,n),this.options.adapter[e]&&this.options.adapter[e](t,this.options),this.options.dispatchEvent){var s=new f(e,{detail:t});i.dispatchEvent(s)}}}},{key:\"_valueFormatter\",value:function(t){var e,n=t,i=this.options.loading,r=this.options.error;return null!==(e=t)&&\"object\"===(void 0===e?\"undefined\":o(e))&&(t.src||this.options.silent||console.error(\"Vue Lazyload warning: miss src with \"+t),n=t.src,i=t.loading||this.options.loading,r=t.error||this.options.error),{src:n,loading:i,error:r}}}]),e}()}$.install=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=new($(t))(e);\"2\"===t.version.split(\".\")[0]?t.directive(\"lazy\",{bind:n.add.bind(n),update:n.update.bind(n),componentUpdated:n.lazyLoadHandler.bind(n),unbind:n.remove.bind(n)}):t.directive(\"lazy\",{bind:n.lazyLoadHandler.bind(n),update:function(t,e){u(this.vm.$refs,this.vm.$els),n.add(this.el,{modifiers:this.modifiers||{},arg:this.arg,value:t,oldValue:e},{context:this.vm})},unbind:function(){n.remove(this.el)}})};var I=function(t){return{props:{tag:{type:String,default:\"div\"}},render:function(t){return t(this.tag,null,this.show?this.$slots.default:null)},data:function(){return{el:null,state:{loaded:!1},rect:{},show:!1}},mounted:function(){this.el=this.$el,t.addLazyBox(this),t.lazyLoadHandler()},beforeDestroy:function(){t.removeComponent(this)},methods:{getRect:function(){this.rect=this.$el.getBoundingClientRect()},checkInView:function(){return this.getRect(),l&&this.rect.top<window.innerHeight*t.options.preLoad&&this.rect.bottom>0&&this.rect.left<window.innerWidth*t.options.preLoad&&this.rect.right>0},load:function(){this.show=!0,this.state.loaded=!0,this.$emit(\"show\",this)},destroy:function(){return this.$destroy}}}};I.install=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=new($(t))(e);t.component(\"lazy-component\",I(n))};var C=function(){function t(e){var n=e.lazy;s(this,t),this.lazy=n,n.lazyContainerMananger=this,this._queue=[]}return a(t,[{key:\"bind\",value:function(t,e,n){var i=new H({el:t,binding:e,vnode:n,lazy:this.lazy});this._queue.push(i)}},{key:\"update\",value:function(t,e,n){var i=y(this._queue,(function(e){return e.el===t}));i&&i.update({el:t,binding:e,vnode:n})}},{key:\"unbind\",value:function(t,e,n){var i=y(this._queue,(function(e){return e.el===t}));i&&(i.clear(),v(this._queue,i))}}]),t}(),S={selector:\"img\"},H=function(){function t(e){var n=e.el,i=e.binding,r=e.vnode,o=e.lazy;s(this,t),this.el=null,this.vnode=r,this.binding=i,this.options={},this.lazy=o,this._queue=[],this.update({el:n,binding:i})}return a(t,[{key:\"update\",value:function(t){var e=this,n=t.el,i=t.binding;this.el=n,this.options=u({},S,i.value),this.getImgs().forEach((function(t){e.lazy.add(t,u({},e.binding,{value:{src:\"dataset\"in t?t.dataset.src:t.getAttribute(\"data-src\"),error:(\"dataset\"in t?t.dataset.error:t.getAttribute(\"data-error\"))||e.options.error,loading:(\"dataset\"in t?t.dataset.loading:t.getAttribute(\"data-loading\"))||e.options.loading}}),e.vnode)}))}},{key:\"getImgs\",value:function(){return function(t){for(var e=t.length,n=[],i=0;i<e;i++)n.push(t[i]);return n}(this.el.querySelectorAll(this.options.selector))}},{key:\"clear\",value:function(){var t=this;this.getImgs().forEach((function(e){return t.lazy.remove(e)})),this.vnode=null,this.binding=null,this.lazy=null}}]),t}();H.install=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=new($(t))(e),i=new H({lazy:n});\"2\"===t.version.split(\".\")[0]?t.directive(\"lazy-container\",{bind:i.bind.bind(i),componentUpdated:i.update.bind(i),unbind:i.unbind.bind(i)}):t.directive(\"lazy-container\",{update:function(t,e){i.update(this.el,{modifiers:this.modifiers||{},arg:this.arg,value:t,oldValue:e},{context:this.vm})},unbind:function(){i.unbind(this.el)}})};var j=function(t){return{props:{src:[String,Object],tag:{type:String,default:\"img\"}},render:function(t){return t(this.tag,{attrs:{src:this.renderSrc}},this.$slots.default)},data:function(){return{el:null,options:{src:\"\",error:\"\",loading:\"\",attempt:t.options.attempt},state:{loaded:!1,error:!1,attempt:0},rect:{},renderSrc:\"\"}},watch:{src:function(){this.init(),t.addLazyBox(this),t.lazyLoadHandler()}},created:function(){this.init(),this.renderSrc=this.options.loading},mounted:function(){this.el=this.$el,t.addLazyBox(this),t.lazyLoadHandler()},beforeDestroy:function(){t.removeComponent(this)},methods:{init:function(){var e=t._valueFormatter(this.src),n=e.src,i=e.loading,r=e.error;this.state.loaded=!1,this.options.src=n,this.options.error=r,this.options.loading=i,this.renderSrc=this.options.loading},getRect:function(){this.rect=this.$el.getBoundingClientRect()},checkInView:function(){return this.getRect(),l&&this.rect.top<window.innerHeight*t.options.preLoad&&this.rect.bottom>0&&this.rect.left<window.innerWidth*t.options.preLoad&&this.rect.right>0},load:function(){var e=this,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:E;if(this.state.attempt>this.options.attempt-1&&this.state.error)return t.options.silent||console.log(\"VueLazyload log: \"+this.options.src+\" tried too more than \"+this.options.attempt+\" times\"),void n();var i=this.options.src;L({src:i},(function(t){var n=t.src;e.renderSrc=n,e.state.loaded=!0}),(function(t){e.state.attempt++,e.renderSrc=e.options.error,e.state.error=!0}))}}}};j.install=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=new($(t))(e);t.component(\"lazy-image\",j(n))};var Q={install:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=new($(t))(e),i=new C({lazy:n}),r=\"2\"===t.version.split(\".\")[0];t.prototype.$Lazyload=n,e.lazyComponent&&t.component(\"lazy-component\",I(n)),e.lazyImage&&t.component(\"lazy-image\",j(n)),r?(t.directive(\"lazy\",{bind:n.add.bind(n),update:n.update.bind(n),componentUpdated:n.lazyLoadHandler.bind(n),unbind:n.remove.bind(n)}),t.directive(\"lazy-container\",{bind:i.bind.bind(i),componentUpdated:i.update.bind(i),unbind:i.unbind.bind(i)})):(t.directive(\"lazy\",{bind:n.lazyLoadHandler.bind(n),update:function(t,e){u(this.vm.$refs,this.vm.$els),n.add(this.el,{modifiers:this.modifiers||{},arg:this.arg,value:t,oldValue:e},{context:this.vm})},unbind:function(){n.remove(this.el)}}),t.directive(\"lazy-container\",{update:function(t,e){i.update(this.el,{modifiers:this.modifiers||{},arg:this.arg,value:t,oldValue:e},{context:this.vm})},unbind:function(){i.unbind(this.el)}}))}};t.Lazy=$,t.LazyComponent=I,t.LazyContainer=C,t.LazyImage=j,t.default=Q,Object.defineProperty(t,\"__esModule\",{value:!0})}));\n"
  }
]