├── .eslintignore ├── .browserslistrc ├── .npmignore ├── postcss.config.js ├── babel.config.js ├── .prettierrc ├── src ├── helpers │ ├── index.js │ ├── lang │ │ ├── countries │ │ │ ├── jp.js │ │ │ ├── zh_CN.js │ │ │ ├── zh_TW.js │ │ │ ├── ar.js │ │ │ ├── ko.js │ │ │ ├── tr.js │ │ │ ├── id.js │ │ │ ├── th.js │ │ │ ├── en.js │ │ │ ├── he.js │ │ │ ├── it.js │ │ │ ├── nl.js │ │ │ ├── pt_BR.js │ │ │ ├── vi.js │ │ │ ├── es.js │ │ │ ├── fr.js │ │ │ ├── pl.js │ │ │ ├── de.js │ │ │ ├── da.js │ │ │ ├── no.js │ │ │ ├── se.js │ │ │ ├── bg.js │ │ │ ├── ro.js │ │ │ ├── ru.js │ │ │ └── uk.js │ │ └── index.js │ ├── timeago.js │ └── helper.js ├── main.js ├── components │ ├── index.js │ └── TimeAgo.vue └── App.vue ├── .gitignore ├── .eslintrc.js ├── vue.config.js ├── LICENSE ├── package.json ├── dist ├── vue2-timeago.css └── vue2-timeago.common.js ├── CHANGELOG.md └── README.md /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/**/* 2 | node_modules -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | .babelrc 4 | node_modules 5 | src 6 | .cache -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {}, 4 | }, 5 | } 6 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@vue/app'], 3 | plugins: ['transform-flow-comments'], 4 | } 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "useTabs": false, 5 | "tabWidth": 2, 6 | "printWidth": 120 7 | } -------------------------------------------------------------------------------- /src/helpers/index.js: -------------------------------------------------------------------------------- 1 | import TimeAgo from './timeago' 2 | 3 | const factory = (nowDate, { locale, type }) => new TimeAgo(nowDate, locale, type).getTimeAgo() 4 | 5 | export default factory 6 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/jp.js: -------------------------------------------------------------------------------- 1 | export default { 2 | short: { 3 | now: 'すこし前', 4 | sec: ' 秒', 5 | min: ' 分', 6 | hour: ' 時間', 7 | day: ' 日', 8 | }, 9 | long: { 10 | now: 'すこし前', 11 | sec: ' 秒前', 12 | min: ' 分前', 13 | hour: ' 時間前', 14 | day: ' 日前', 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/zh_CN.js: -------------------------------------------------------------------------------- 1 | export default { 2 | short: { 3 | now: '刚刚', 4 | sec: ' 秒', 5 | min: ' 分', 6 | hour: ' 小时', 7 | day: ' 天', 8 | }, 9 | long: { 10 | now: '刚刚', 11 | sec: ' 秒钟前', 12 | min: ' 分钟前', 13 | hour: ' 小时前', 14 | day: ' 天前', 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/zh_TW.js: -------------------------------------------------------------------------------- 1 | export default { 2 | short: { 3 | now: '剛剛', 4 | sec: ' 秒', 5 | min: ' 分', 6 | hour: ' 小時', 7 | day: ' 天', 8 | }, 9 | long: { 10 | now: '剛剛', 11 | sec: ' 秒鐘前', 12 | min: ' 分鐘前', 13 | hour: ' 小時前', 14 | day: ' 天前', 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | #/dist 4 | dist/demo.html 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # Editor directories and files 16 | .idea 17 | .vscode 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw* 23 | 24 | yarn.lock 25 | yarn-error.log 26 | 27 | website/docs/dist 28 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/ar.js: -------------------------------------------------------------------------------- 1 | export default { 2 | short: { 3 | now: 'قبل قليل', 4 | sec: ' ثانية', 5 | min: ' دقيقة', 6 | hour: ' ساعة', 7 | day: ' يوم', 8 | }, 9 | long: { 10 | now: 'قبل قليل', 11 | sec: (time) => ` قبل ${time} ثواني`, 12 | min: (time) => ` قبل ${time} دقائق`, 13 | hour: (time) => ` قبل ${time} ساعات`, 14 | day: (time) => ` قبل ${time} أيام`, 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import 'element-ui/lib/theme-chalk/index.css' 2 | import 'vue2-timeago/dist/vue2-timeago.css' 3 | 4 | import App from './App.vue' 5 | import ElementUI from 'element-ui' 6 | // import { TimeAgo } from './components/index' 7 | import { TimeAgo } from 'vue2-timeago' 8 | import Vue from 'vue' 9 | 10 | Vue.use(ElementUI) 11 | Vue.component(TimeAgo.name, TimeAgo) 12 | 13 | new Vue({ 14 | render: (h) => h(App), 15 | }).$mount('#app') 16 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true, 5 | }, 6 | extends: ['plugin:vue/recommended', 'eslint:recommended', 'prettier/vue', 'plugin:prettier/recommended'], 7 | rules: { 8 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 9 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 10 | }, 11 | parserOptions: { 12 | parser: 'babel-eslint', 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/ko.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return `${time} ${type}${time > 1 ? '초' : ''} 전` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: '지금', 8 | sec: '초', 9 | min: '분', 10 | hour: '시간', 11 | day: '일', 12 | }, 13 | long: { 14 | now: '지금', 15 | sec: (time) => formatToLongString(time, '초'), 16 | min: (time) => formatToLongString(time, '분'), 17 | hour: (time) => formatToLongString(time, '시간'), 18 | day: (time) => formatToLongString(time, '일'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/tr.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return ` ${time} ${type} önce` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'şimdi', 8 | sec: 'sn', 9 | min: 'dk', 10 | hour: 's', 11 | day: 'g', 12 | }, 13 | long: { 14 | now: 'şimdi', 15 | sec: (time) => formatToLongString(time, 'saniye'), 16 | min: (time) => formatToLongString(time, 'dakika'), 17 | hour: (time) => formatToLongString(time, 'saat'), 18 | day: (time) => formatToLongString(time, 'gün'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/id.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return ` ${time} ${type} yg lalu` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'baru saja', 8 | sec: 'd', 9 | min: 'm', 10 | hour: 'j', 11 | day: 'h', 12 | }, 13 | long: { 14 | now: 'baru saja', 15 | sec: (time) => formatToLongString(time, 'detik'), 16 | min: (time) => formatToLongString(time, 'menit'), 17 | hour: (time) => formatToLongString(time, 'jam'), 18 | day: (time) => formatToLongString(time, 'hari'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/th.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return `${time} ${type}ที่แล้ว` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'ขณะนี้', 8 | sec: 'วินาที', 9 | min: 'นาที', 10 | hour: 'ชั่วโมง', 11 | day: 'วัน', 12 | }, 13 | long: { 14 | now: 'ขณะนี้', 15 | sec: (time) => formatToLongString(time, 'วินาที'), 16 | min: (time) => formatToLongString(time, 'นาที'), 17 | hour: (time) => formatToLongString(time, 'ชั่วโมง'), 18 | day: (time) => formatToLongString(time, 'วัน'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/en.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return `${time} ${type}${time > 1 ? 's' : ''} ago` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'just now', 8 | sec: 's', 9 | min: 'm', 10 | hour: 'h', 11 | day: 'd', 12 | }, 13 | long: { 14 | now: 'just now', 15 | sec: (time) => formatToLongString(time, 'second'), 16 | min: (time) => formatToLongString(time, 'minute'), 17 | hour: (time) => formatToLongString(time, 'hour'), 18 | day: (time) => formatToLongString(time, 'day'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/he.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return `לִפנֵי ${type} ${time}` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'זֶה עַתָה', 8 | sec: 'שניות', 9 | min: 'דַקָה', 10 | hour: 'שָׁעָה', 11 | day: 'יְוֹם', 12 | }, 13 | long: { 14 | now: 'זֶה עַתָה', 15 | sec: (time) => formatToLongString(time, 'שנייה'), 16 | min: (time) => formatToLongString(time, 'דַקָה'), 17 | hour: (time) => formatToLongString(time, 'שָׁעָה'), 18 | day: (time) => formatToLongString(time, 'יְוֹם'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/it.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return `${time} ${type}${time > 1 ? 's' : ''} fa` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'adesso', 8 | sec: 's', 9 | min: 'm', 10 | hour: 'h', 11 | day: 'g', 12 | }, 13 | long: { 14 | now: 'adesso', 15 | sec: (time) => formatToLongString(time, 'secondo'), 16 | min: (time) => formatToLongString(time, 'minuto'), 17 | hour: (time) => formatToLongString(time, 'ora'), 18 | day: (time) => formatToLongString(time, 'giorno'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/nl.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return `${time} ${type}${time > 1 ? 's' : ''} geleden` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'zojuist', 8 | sec: 's', 9 | min: 'm', 10 | hour: 'h', 11 | day: 'd', 12 | }, 13 | long: { 14 | now: 'zojuist', 15 | sec: (time) => formatToLongString(time, 'seconde'), 16 | min: (time) => formatToLongString(time, 'minuut'), 17 | hour: (time) => formatToLongString(time, 'uur'), 18 | day: (time) => formatToLongString(time, 'dag'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/pt_BR.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return ` ${time} ${type}${time > 1 ? 's' : ''} atrás` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'agora', 8 | sec: 's', 9 | min: 'm', 10 | hour: 'h', 11 | day: 'd', 12 | }, 13 | long: { 14 | now: 'agora', 15 | sec: (time) => formatToLongString(time, 'segundo'), 16 | min: (time) => formatToLongString(time, 'minuto'), 17 | hour: (time) => formatToLongString(time, 'hora'), 18 | day: (time) => formatToLongString(time, 'dia'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/vi.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return `${time} ${type}${time > 1 ? 'giây' : ''} trước` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'vừa xong', 8 | sec: 's', 9 | min: 'p', 10 | hour: 'g', 11 | day: 'N', 12 | }, 13 | long: { 14 | now: 'Vừa xong', 15 | sec: (time) => formatToLongString(time, 'giây'), 16 | min: (time) => formatToLongString(time, 'phút'), 17 | hour: (time) => formatToLongString(time, 'giờ'), 18 | day: (time) => formatToLongString(time, 'ngày'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/es.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return ` ${time} ${type}${time > 1 ? 's' : ''} atrás` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'ahora mismo', 8 | sec: 's', 9 | min: 'm', 10 | hour: 'h', 11 | day: 'd', 12 | }, 13 | long: { 14 | now: 'ahora mismo', 15 | sec: (time) => formatToLongString(time, 'segundo'), 16 | min: (time) => formatToLongString(time, 'minuto'), 17 | hour: (time) => formatToLongString(time, 'hora'), 18 | day: (time) => formatToLongString(time, 'dia'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/fr.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return `il y a ${time} ${type}${time > 1 ? 's' : ''}` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'maintenant', 8 | sec: 's', 9 | min: 'm', 10 | hour: 'h', 11 | day: 'j', 12 | }, 13 | long: { 14 | now: 'maintenant', 15 | sec: (time) => formatToLongString(time, 'seconde'), 16 | min: (time) => formatToLongString(time, 'minute'), 17 | hour: (time) => formatToLongString(time, 'heure'), 18 | day: (time) => formatToLongString(time, 'jour'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/pl.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return ` ${time} ${type}${time > 1 ? 's' : ''} temu` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'przed chwilą', 8 | sec: 's', 9 | min: 'm', 10 | hour: 'g', 11 | day: 'd', 12 | }, 13 | long: { 14 | now: 'przed chwilą', 15 | sec: (time) => formatToLongString(time, 'sekund'), 16 | min: (time) => formatToLongString(time, 'minut'), 17 | hour: (time) => formatToLongString(time, 'godzin'), 18 | day: (time) => formatToLongString(time, 'dni'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/de.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return `vor ${time} ${type}${time > 1 ? (type === 'Tag' ? 'en' : 'n') : ''}` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'Gerade eben', 8 | sec: 'Sek.', 9 | min: 'Min.', 10 | hour: 'Std.', 11 | day: 'Tg', 12 | }, 13 | long: { 14 | now: 'Gerade eben', 15 | sec: (time) => formatToLongString(time, 'Sekunde'), 16 | min: (time) => formatToLongString(time, 'Minute'), 17 | hour: (time) => formatToLongString(time, 'Stunde'), 18 | day: (time) => formatToLongString(time, 'Tag'), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/da.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return `${time} ${time > 1 ? type[1] : type[0]} sen` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'lige nu', 8 | sec: 's', 9 | min: 'm', 10 | hour: 't', 11 | day: 'd', 12 | }, 13 | long: { 14 | now: 'lige nu', 15 | sec: (time) => formatToLongString(time, ['sekund', 'sekunder']), 16 | min: (time) => formatToLongString(time, ['minut', 'minutter']), 17 | hour: (time) => formatToLongString(time, ['time', 'timer']), 18 | day: (time) => formatToLongString(time, ['dag', 'dage']), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/no.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return `${time} ${time > 1 ? type[1] : type[0]} siden` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'akkurat nå', 8 | sec: 's', 9 | min: 'm', 10 | hour: 't', 11 | day: 'd', 12 | }, 13 | long: { 14 | now: 'akkurat nå', 15 | sec: (time) => formatToLongString(time, ['sekund', 'sekunder']), 16 | min: (time) => formatToLongString(time, ['minutt', 'minutter']), 17 | hour: (time) => formatToLongString(time, ['time', 'timer']), 18 | day: (time) => formatToLongString(time, ['dag', 'dager']), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/se.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | return `${time} ${time > 1 ? type[1] : type[0]} sen` 3 | } 4 | 5 | export default { 6 | short: { 7 | now: 'alldeles nyss', 8 | sec: 's', 9 | min: 'm', 10 | hour: 't', 11 | day: 'd', 12 | }, 13 | long: { 14 | now: 'alldeles nyss', 15 | sec: (time) => formatToLongString(time, ['sekund', 'sekunder']), 16 | min: (time) => formatToLongString(time, ['minut', 'minuter']), 17 | hour: (time) => formatToLongString(time, ['timme', 'timmar']), 18 | day: (time) => formatToLongString(time, ['dag', 'dagar']), 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/bg.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, words) { 2 | if (time > 1) { 3 | return `преди ${time} ${words[1]}` 4 | } 5 | return `преди ${time} ${words[0]}` 6 | } 7 | 8 | export default { 9 | short: { 10 | now: 'сега', 11 | sec: 'с', 12 | min: 'м', 13 | hour: 'ч', 14 | day: 'д', 15 | }, 16 | long: { 17 | now: 'сега', 18 | sec: (time) => formatToLongString(time, ['секунда', 'секунди']), 19 | min: (time) => formatToLongString(time, ['минута', 'минути']), 20 | hour: (time) => formatToLongString(time, ['час', 'часа']), 21 | day: (time) => formatToLongString(time, ['ден', 'дни']), 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/ro.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, type) { 2 | if (type == 'zi') { 3 | if (time == 1) return 'o zi în urmă' 4 | else return time + ' zile în urmă' 5 | } 6 | 7 | return ` ${time == 1 ? 'o ' : time} ${type}${time == 1 ? 'ă' : 'e'} în urmă` 8 | } 9 | 10 | export default { 11 | short: { 12 | now: 'chiar acum', 13 | sec: 's', 14 | min: 'm', 15 | hour: 'o', 16 | day: 'z', 17 | }, 18 | long: { 19 | now: 'chiar acum', 20 | sec: (time) => formatToLongString(time, 'secund'), 21 | min: (time) => formatToLongString(time, 'minut'), 22 | hour: (time) => formatToLongString(time, 'or'), 23 | day: (time) => formatToLongString(time, 'zi'), 24 | }, 25 | } 26 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | import TimeAgo from './TimeAgo.vue' 2 | import { addLocale } from '../helpers/lang' 3 | 4 | const components = { 5 | TimeAgo, 6 | } 7 | 8 | export function install(Vue) { 9 | if (install.installed) return 10 | install.installed = true 11 | Object.keys(components).forEach((name) => { 12 | Vue.component(name, components[name]) 13 | }) 14 | } 15 | 16 | const plugin = { 17 | install, 18 | } 19 | 20 | let GlobalVue = null 21 | if (typeof window !== 'undefined') { 22 | GlobalVue = window.Vue 23 | } else if (typeof global !== 'undefined') { 24 | GlobalVue = global.Vue 25 | } 26 | if (GlobalVue) { 27 | GlobalVue.use(plugin) 28 | } 29 | 30 | export default components 31 | export { TimeAgo, addLocale } 32 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 3 | const PACKAGE = require('./package.json') 4 | 5 | const banner = 6 | PACKAGE.name + 7 | ' - ' + 8 | PACKAGE.version + 9 | ' | ' + 10 | '(c) 2018, ' + 11 | new Date().getFullYear() + 12 | ' ' + 13 | PACKAGE.author + 14 | ' | ' + 15 | PACKAGE.homepage 16 | 17 | module.exports = { 18 | productionSourceMap: false, 19 | lintOnSave: true, 20 | configureWebpack: { 21 | mode: 'production', 22 | performance: { 23 | hints:false 24 | }, 25 | output: { 26 | library: 'TimeAgo', 27 | libraryExport: 'default', 28 | }, 29 | plugins: [ 30 | new webpack.BannerPlugin(banner), 31 | new UglifyJsPlugin() 32 | ] 33 | }, 34 | css: { 35 | extract: true, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/ru.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, words) { 2 | let _time = time % 100 3 | 4 | if (_time > 19) { 5 | _time = _time % 10 6 | } 7 | 8 | switch (_time) { 9 | case 1: { 10 | return ` ${time} ${words[0]} назад` 11 | } 12 | case 2: 13 | case 3: 14 | case 4: { 15 | return ` ${time} ${words[1]} назад` 16 | } 17 | default: { 18 | return ` ${time} ${words[2]} назад` 19 | } 20 | } 21 | } 22 | 23 | export default { 24 | short: { 25 | now: 'только что', 26 | sec: 'с', 27 | min: 'м', 28 | hour: 'ч', 29 | day: 'дн', 30 | }, 31 | long: { 32 | now: 'только что', 33 | sec: (time) => formatToLongString(time, ['секунда', 'секунды', 'секунд']), 34 | min: (time) => formatToLongString(time, ['минута', 'минуты', 'минут']), 35 | hour: (time) => formatToLongString(time, ['час', 'часа', 'часов']), 36 | day: (time) => formatToLongString(time, ['день', 'дня', 'дней']), 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /src/helpers/lang/countries/uk.js: -------------------------------------------------------------------------------- 1 | function formatToLongString(time, words) { 2 | let _time = time % 100 3 | 4 | if (_time > 19) { 5 | _time = _time % 10 6 | } 7 | 8 | switch (_time) { 9 | case 1: { 10 | return ` ${time} ${words[0]} тому` 11 | } 12 | case 2: 13 | case 3: 14 | case 4: { 15 | return ` ${time} ${words[1]} тому` 16 | } 17 | default: { 18 | return ` ${time} ${words[2]} тому` 19 | } 20 | } 21 | } 22 | 23 | export default { 24 | short: { 25 | now: 'щойно', 26 | sec: 'с', 27 | min: 'хв', 28 | hour: 'год', 29 | day: 'дн', 30 | }, 31 | long: { 32 | now: 'щойно', 33 | sec: (time) => formatToLongString(time, ['секунда', 'секунди', 'секунд']), 34 | min: (time) => formatToLongString(time, ['хвилина', 'хвилини', 'хвилин']), 35 | hour: (time) => formatToLongString(time, ['година', 'години', 'годин']), 36 | day: (time) => formatToLongString(time, ['день', 'дні', 'днів']), 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Willy Hong 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/helpers/timeago.js: -------------------------------------------------------------------------------- 1 | import { getNow, getNowString, getNowMoreString, toTimestamp } from './helper' 2 | 3 | import lang from './lang/index' 4 | 5 | class TimeAgo { 6 | constructor(dateTime, locale, type) { 7 | this.dateTime = dateTime 8 | this.locale = locale || 'en' 9 | this.type = type || 'short' 10 | } 11 | 12 | setLocale(locale) { 13 | this.locale = locale 14 | } 15 | 16 | getTimeAgoString(timer, type) { 17 | return typeof type === 'string' ? `${timer}${type}` : type(timer) 18 | } 19 | 20 | getTimeAgo() { 21 | let { now, min, hour, day } = lang[this.locale][this.type] 22 | let timestamp = toTimestamp(this.dateTime) //轉成timestamp 23 | let nowTime = getNow() 24 | let timer = (nowTime - timestamp) / 1000 //轉成秒 25 | let timeago = '' 26 | 27 | if (timer <= 0 || Math.floor(timer / 60) <= 0) { 28 | timeago = now 29 | } else if (timer < 3600) { 30 | timeago = this.getTimeAgoString(Math.round(timer / 60), min) 31 | } else if (timer >= 3600 && Math.round(timer / 3600) < 24) { 32 | timeago = this.getTimeAgoString(Math.round(timer / 3600), hour) 33 | } else if (timer / 86400 <= 31) { 34 | timeago = this.getTimeAgoString(Math.round(timer / 86400), day) 35 | } else { 36 | timeago = getNowString(timestamp) 37 | } 38 | 39 | return { 40 | timeago, 41 | timestamp, 42 | nowString: getNowMoreString(timestamp), 43 | } 44 | } 45 | } 46 | 47 | export default TimeAgo 48 | -------------------------------------------------------------------------------- /src/helpers/lang/index.js: -------------------------------------------------------------------------------- 1 | import ar from './countries/ar' 2 | import bg from './countries/bg' 3 | import da from './countries/da' 4 | import de from './countries/de' 5 | import en from './countries/en' 6 | import es from './countries/es' 7 | import fr from './countries/fr' 8 | import he from './countries/he' 9 | import id from './countries/id' 10 | import jp from './countries/jp' 11 | import ko from './countries/ko' 12 | import nl from './countries/nl' 13 | import no from './countries/no' 14 | import pl from './countries/pl' 15 | import pt_BR from './countries/pt_BR' 16 | import ro from './countries/ro' 17 | import ru from './countries/ru' 18 | import se from './countries/se' 19 | import th from './countries/th' 20 | import tr from './countries/tr' 21 | import uk from './countries/uk' 22 | import vi from './countries/vi' 23 | import zh_CN from './countries/zh_CN' 24 | import zh_TW from './countries/zh_TW' 25 | import it from './countries/it' 26 | 27 | const locales = { 28 | zh_TW, 29 | zh_CN, 30 | en, 31 | jp, 32 | ko, // Korean 33 | th, // Thai 34 | pt_BR, // Portugal(Brazil) 葡萄牙文 (巴西) 35 | es, // Spain 西班牙文 36 | ar, // Arabia 阿拉伯文 37 | fr, // French 38 | pl, // Polish 波蘭語 39 | tr, // Turkish 土耳其 40 | he, // Hebrew 41 | id, // Indonesian 印度尼西雅, 42 | ro, // Romanian 43 | ru, // Russian 44 | de, // German 45 | uk, // Ukrainian 烏克蘭語 46 | bg, // Bulgarian 47 | se, // Swedish 48 | nl, // Dutch / Netherlands 49 | no, // Norwegian 50 | da, // Danish 51 | vi, // Vietnam 52 | it, // Italian 53 | } 54 | 55 | export function addLocale(name, locale) { 56 | locales[name] = locale 57 | } 58 | 59 | export default locales 60 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue2-timeago", 3 | "version": "2.1.0", 4 | "description": "A vue component used to format date with time ago statement.", 5 | "main": "dist/vue2-timeago.common.js", 6 | "unpkg": "dist/vue2-timeago.umd.min.js", 7 | "style": "dist/vue2-timeago.css", 8 | "keywords": [ 9 | "vue", 10 | "time", 11 | "ago", 12 | "timeago" 13 | ], 14 | "homepage": "https://github.com/runkids/vue2-timeago", 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/runkids/vue2-timeago.git" 18 | }, 19 | "author": "runkids ", 20 | "license": "MIT", 21 | "scripts": { 22 | "serve": "vue-cli-service serve", 23 | "build": "rimraf dist && vue-cli-service build", 24 | "build-lib": "rimraf dist && vue-cli-service build --target lib ./src/components/index.js", 25 | "lint": "vue-cli-service lint" 26 | }, 27 | "devDependencies": { 28 | "@vue/cli-plugin-babel": "^4.5.11", 29 | "@vue/cli-plugin-eslint": "^4.5.11", 30 | "@vue/cli-service": "^4.5.11", 31 | "@vue/eslint-config-standard": "^6.0.0", 32 | "babel-eslint": "^10.1.0", 33 | "babel-plugin-transform-flow-comments": "^6.22.0", 34 | "core-js": "^3.8.3", 35 | "element-ui": "^2.15.0", 36 | "eslint": "^7.18.0", 37 | "eslint-config-prettier": "^7.2.0", 38 | "eslint-plugin-prettier": "^3.3.1", 39 | "eslint-plugin-vue": "^7.5.0", 40 | "node-sass": "^7.0.0", 41 | "prettier": "^2.2.1", 42 | "rimraf": "^2.6.2", 43 | "sass-loader": "^10.1.1", 44 | "uglifyjs-webpack-plugin": "^2.2.0", 45 | "vue": "^2.6.12", 46 | "vue-template-compiler": "^2.6.12", 47 | "webpack-bundle-analyzer": "^4.4.0" 48 | }, 49 | "dependencies": { 50 | "v-tooltip": "^2.1.2", 51 | "vue2-timeago": "2.0.9" 52 | }, 53 | "peerDependencies": { 54 | "v-tooltip": "^2.1.2" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/helpers/helper.js: -------------------------------------------------------------------------------- 1 | export function getNow() { 2 | return new Date().getTime() 3 | } 4 | 5 | /** 6 | * Get today ex. 2018-01-01 00:00:00 7 | **/ 8 | export function getToday() { 9 | let date = new Date() 10 | date.setHours(0) 11 | date.setMinutes(0) 12 | date.setSeconds(0) 13 | date.setMilliseconds(0) 14 | return date.getTime() 15 | } 16 | 17 | /** 18 | * Get first day with this year ex. 2018-01-01 00:00:00 19 | **/ 20 | export function getFirstDate() { 21 | let date = new Date() 22 | date.setMonth(0) 23 | date.setDate(1) 24 | date.setHours(0) 25 | date.setMinutes(0) 26 | date.setSeconds(0) 27 | date.setMilliseconds(0) 28 | return date.getTime() 29 | } 30 | 31 | /** 32 | * Get time by string format ex. 1999-02-21 33 | **/ 34 | export function getNowString(time) { 35 | let date = new Date(time) 36 | let realMonth = date.getMonth() + 1 37 | let month = realMonth < 10 ? `0${realMonth}` : realMonth 38 | let day = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate() 39 | return `${date.getFullYear()}-${month}-${day}` 40 | } 41 | 42 | /** 43 | * Get time by string format ex. 1999-02-21 01:40 44 | **/ 45 | export function getNowMoreString(time) { 46 | let date = new Date(time) 47 | let realMonth = date.getMonth() + 1 48 | let month = realMonth < 10 ? `0${realMonth}` : realMonth 49 | let day = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate() 50 | let hour = date.getHours() < 10 ? `0${date.getHours()}` : date.getHours() 51 | let min = date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes() 52 | return `${date.getFullYear()}-${month}-${day} ${hour}:${min}` 53 | } 54 | 55 | /** 56 | * Format Date/string/timestamp to timestamp 57 | **/ 58 | export function toTimestamp(input) { 59 | if (!isNaN(input) || /^\d+$/.test(input)) return input 60 | 61 | if (input instanceof Date) return input.getTime() 62 | 63 | input = (input || '') 64 | .trim() 65 | .replace(/\.\d+/, '') 66 | .replace(/-/, '/') 67 | .replace(/-/, '/') 68 | .replace(/(\d)T(\d)/, '$1 $2') 69 | .replace(/Z/, ' UTC') 70 | // eslint-disable-next-line no-useless-escape 71 | .replace(/([\+\-]\d\d)\:?(\d\d)/, ' $1$2') 72 | return new Date(input).getTime() 73 | } 74 | -------------------------------------------------------------------------------- /dist/vue2-timeago.css: -------------------------------------------------------------------------------- 1 | /*! vue2-timeago - 2.1.0 | (c) 2018, 2025 runkids | https://github.com/runkids/vue2-timeago */.v-timeago{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;cursor:pointer;color:#657786;text-decoration:none;line-height:20px;list-style-image:none;list-style-position:outside;list-style-type:none;letter-spacing:.1px}.tooltip{display:block!important;font-size:12px;z-index:10000}.tooltip .tooltip-inner{background:#303133;color:#fff;border-radius:4px;padding:5px 10px 4px}.tooltip .tooltip-arrow{width:0;height:0;border-style:solid;position:absolute;margin:5px;border-color:#303133;z-index:1}.tooltip[x-placement^=top]{margin-bottom:5px}.tooltip[x-placement^=top] .tooltip-arrow{border-width:5px 5px 0 5px;border-left-color:transparent!important;border-right-color:transparent!important;border-bottom-color:transparent!important;bottom:-5px;left:calc(50% - 5px);margin-top:0;margin-bottom:0}.tooltip[x-placement^=bottom]{margin-top:5px}.tooltip[x-placement^=bottom] .tooltip-arrow{border-width:0 5px 5px 5px;border-left-color:transparent!important;border-right-color:transparent!important;border-top-color:transparent!important;top:-5px;left:calc(50% - 5px);margin-top:0;margin-bottom:0}.tooltip[x-placement^=right]{margin-left:5px}.tooltip[x-placement^=right] .tooltip-arrow{border-width:5px 5px 5px 0;border-left-color:transparent!important;border-top-color:transparent!important;border-bottom-color:transparent!important;left:-5px;top:calc(50% - 5px);margin-left:0;margin-right:0}.tooltip[x-placement^=left]{margin-right:5px}.tooltip[x-placement^=left] .tooltip-arrow{border-width:5px 0 5px 5px;border-top-color:transparent!important;border-right-color:transparent!important;border-bottom-color:transparent!important;right:-5px;top:calc(50% - 5px);margin-left:0;margin-right:0}.tooltip.popover .popover-inner{background:#f9f9f9;color:#fff;padding:24px;border-radius:4px;-webkit-box-shadow:0 5px 30px rgba(#303133,.1);box-shadow:0 5px 30px rgba(#303133,.1)}.tooltip.popover .popover-arrow{border-color:#f9f9f9}.tooltip[aria-hidden=true]{visibility:hidden;opacity:0;-webkit-transition:opacity .15s,visibility .15s;transition:opacity .15s,visibility .15s}.tooltip[aria-hidden=false]{visibility:visible;opacity:1;-webkit-transition:opacity .15s;transition:opacity .15s} -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 2.1.0 2 | - Add Italian translation [#65](https://github.com/runkids/vue2-timeago/pull/65). 3 | - Add runtime locale registration [#66](https://github.com/runkids/vue2-timeago/pull/66). 4 | 5 | # 2.0.9 6 | - (fix) vi translation bug. 7 | # 2.0.8 8 | - Add Vietnam translation [#57](https://github.com/runkids/vue2-timeago/pull/57). 9 | 10 | # 2.0.7 11 | 12 | - Add Danish translation [#51](https://github.com/runkids/vue2-timeago/pull/51). 13 | - Add Norwegian translation [#54](https://github.com/runkids/vue2-timeago/pull/54). 14 | 15 | # 2.0.6 16 | 17 | - Add Thai translation [#45](https://github.com/runkids/vue2-timeago/pull/45). 18 | # 2.0.5 19 | 20 | - (fix) typo of slots 21 | 22 | # 2.0.4 23 | 24 | - (fix) Korean translation code kor -> ko 25 | 26 | # 2.0.3 27 | 28 | - Add Korean translation [#43](https://github.com/runkids/vue2-timeago/pull/43). 29 | 30 | # 2.0.2 31 | 32 | - Add Hebrew translation [#42](https://github.com/runkids/vue2-timeago/pull/42). 33 | 34 | # 2.0.1 35 | 36 | - Add Dutch / Netherlands translation [#33](https://github.com/runkids/vue2-timeago/pull/33). 37 | 38 | # 2.0.0 39 | 40 | - Release 2.0.0 41 | - Add Swedish translation [#27](https://github.com/runkids/vue2-timeago/pull/27). 42 | 43 | # 2.0.0-beta.5 44 | 45 | - Refresh timer after datetime changed 46 | 47 | # 2.0.0-beta.4 48 | 49 | - Fix tooltip bug 50 | 51 | # 2.0.0-beta.3 52 | 53 | - Modify build setting 54 | 55 | # 2.0.0-beta.2 56 | 57 | - Fix long string bug 58 | 59 | # 2.0.0-beta.1 60 | 61 | - Fix refresh config bug 62 | - Modify props (See README.md) 63 | 64 | # 1.2.12 65 | 66 | - Fixed refresh setting bug 67 | 68 | # 1.2.11 69 | 70 | - Turkish translation is improved [#25](https://github.com/runkids/vue2-timeago/pull/25). 71 | 72 | # 1.2.10 73 | 74 | - Modify Romanian translation [#19](https://github.com/runkids/vue2-timeago/pull/24). 75 | 76 | - Add Bulgarian translation [#23](https://github.com/runkids/vue2-timeago/pull/23). 77 | 78 | # 1.2.9 79 | 80 | - Modify Germany translation [#22](https://github.com/runkids/vue2-timeago/pull/22). 81 | 82 | # 1.2.8 83 | 84 | - Ukrainian translation [#21](https://github.com/runkids/vue2-timeago/pull/21). 85 | 86 | # 1.2.7 87 | 88 | - Germany translation [#19](https://github.com/runkids/vue2-timeago/pull/19). 89 | 90 | # 1.2.6 91 | 92 | - Romanian translation [#17](https://github.com/runkids/vue2-timeago/issues/17). 93 | - Russian translation [#16](https://github.com/runkids/vue2-timeago/issues/16). 94 | 95 | # 1.2.5 96 | 97 | - Modify build setting. 98 | 99 | # 1.2.4 100 | 101 | - Indonesian translation [#18](https://github.com/runkids/vue2-timeago/pull/18). 102 | 103 | # 1.2.3 104 | 105 | - Turkish translation [#15](https://github.com/runkids/vue2-timeago/pull/15). 106 | - Polish translation [#14](https://github.com/runkids/vue2-timeago/issues/14). 107 | - Fixed typo in spanish [#12](https://github.com/runkids/vue2-timeago/pull/12). 108 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 50 | 51 | 108 | 109 | 135 | -------------------------------------------------------------------------------- /src/components/TimeAgo.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 114 | 115 | 236 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue2-timeago 2 | 3 | [![vue2](https://img.shields.io/badge/vue-2.x-brightgreen.svg)](https://vuejs.org/) [![npm](https://img.shields.io/npm/v/vue2-timeago.svg)](https://www.npmjs.com/package/vue2-timeago) [![npm](https://img.shields.io/npm/dt/vue2-timeago.svg)](https://www.npmjs.com/package/vue2-timeago) [![](https://data.jsdelivr.com/v1/package/npm/vue2-timeago/badge)](https://www.jsdelivr.com/package/npm/vue2-timeago) [![npm](https://img.shields.io/npm/l/vue2-timeago.svg)](https://github.com/runkids/vue2-timeago/blob/master/LICENSE) 4 | 5 | # vue2-timeago V2 6 | 7 | ### 🔥 NEW [vue2-timeago for Vue 3](https://vue2-timeago.netlify.app/) 8 | 9 | - Localization supported 10 | - Show tooltip 11 | - Auto refresh time 12 | - When time refresh call a customizable function 13 | - Formats a date/timestamp to: 14 | - just now 15 | - 5m 16 | - 3h 17 | - 2 days ago 18 | - 2017-08-03 19 | - Rules: 20 | - less than 1 minute , show `just now` 21 | - 1 minute ~ 1 hour , show `** minutes ago` 22 | - 1 hour ~ 1 day , show `** hours ago` 23 | - 1 day ~ 1 month( 31 days ) , show `** days ago` 24 | - more than 1 month( 31 days ) , show `yyyy-mm-dd hh:mm` 25 | 26 | ##### FOR 1.X PLEASE GO TO [THE 1.x BRANCH](https://github.com/runkids/vue2-timeago/tree/v1) 27 | 28 | ## Navigation 29 | 30 | - [Changelog](https://github.com/runkids/vue2-timeago/blob/master/CHANGELOG.md) 31 | - [Installation](#Installation) 32 | - [Usage](#Usage) 33 | - [Examples](#Examples) 34 | - [Props](#Props) 35 | - [Contributions](#Contributions) 36 | 37 | ## Live Demo 38 | 39 | [![Edit vue2_timeago_demo](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/embed/myomwvkojj) 40 | 41 | ## Local Demo 42 | 43 | ```js 44 | yarn 45 | yarn serve 46 | ``` 47 | 48 | ## Installation 49 | 50 | Get from npm / yarn: 51 | 52 | ```js 53 | npm i vue2-timeago@2.1.0 54 | ``` 55 | 56 | ```js 57 | yarn add vue2-timeago@2.1.0 58 | ``` 59 | 60 | or just include [vue2-timeago.umd.min.js](https://cdn.jsdelivr.net/npm/vue2-timeago@2.1.0/dist/vue2-timeago.umd.min.js) to your view like 61 | 62 | ```js 63 | 64 | ``` 65 | 66 | ## Usage 67 | 68 | Use this inside your app: 69 | 70 | ``` js 71 | import { TimeAgo } from 'vue2-timeago' 72 | 73 | export default { 74 | name: 'app', 75 | components: { 76 | TimeAgo, 77 | } 78 | } 79 | ``` 80 | 81 | ##### With Default CSS 82 | 83 | ```js 84 | import 'vue2-timeago/dist/vue2-timeago.css' 85 | ``` 86 | 87 | or just include [vue2-timeago.css](https://cdn.jsdelivr.net/npm/vue2-timeago@2.1.0/dist/vue2-timeago.css) 88 | 89 | ##### HTML 90 | 91 | ```html 92 | 93 | ``` 94 | 95 | ### Custom locale 96 | 97 | You can register new locales at runtime without editing library files. 98 | 99 | ```javascript 100 | import Vue from 'vue' 101 | import Vue2Timeago, { addLocale } from 'vue2-timeago' 102 | 103 | addLocale('pirate', { 104 | short: { now: 'arr', sec: 's', min: 'm', hour: 'h', day: 'd' }, 105 | long: { 106 | now: 'arr', 107 | sec: (n) => `${n} second${n > 1 ? 's' : ''} arr`, 108 | min: (n) => `${n} minute${n > 1 ? 's' : ''} arr`, 109 | hour: (n) => `${n} hour${n > 1 ? 's' : ''} arr`, 110 | day: (n) => `${n} day${n > 1 ? 's' : ''} arr`, 111 | }, 112 | }) 113 | 114 | Vue.use(Vue2Timeago) 115 | ``` 116 | 117 | ```html 118 | 119 | ``` 120 | 121 | ## Examples 122 | 123 | ##### 1. locale 124 | 125 | Default locale is en, and the library supports en and zh_TW. 126 | 127 | ```html 128 | 129 | use v-bind 130 | ``` 131 | 132 | ```js 133 | export default { 134 | ... 135 | data(){ 136 | return{ 137 | locale:"zh_TW", 138 | } 139 | }, 140 | ... 141 | ``` 142 | 143 | ##### 2. datetime 144 | 145 | ```html 146 | 147 | use v-bind 148 | timestamp 149 | ``` 150 | 151 | - Note. Don't bind with `new Date()` when you use refresh property. 152 | Because every time refresh will get a new date value. 153 | 154 | ```html 155 | --> OK 156 | --> not OK 157 | ``` 158 | 159 | If you want use new Date() , just remove datetime property. 160 | 161 | ```html 162 | 163 | ``` 164 | 165 | ##### 3. refresh 166 | 167 | ```html 168 | Boolean , default refresh time 60/s 169 | bind value with a number 170 | Refresh time 1 second 171 | ``` 172 | 173 | ##### 4. tooltip 174 | 175 | 176 | 177 | - Base on [v-tooltip](https://github.com/Akryum/v-tooltip "v-tooltip"), you can use placement attribute that are allowed in v-tooltip. 178 | 179 | ```html 180 | Show tooltip 181 | Disabled tooltip 182 | ``` 183 | 184 | ##### 5. tooltip options 185 | 186 | - Default options: 187 | 188 | ```javascript 189 | { 190 | placement: 'top', 191 | content: {datetime string} 192 | } 193 | ``` 194 | 195 | - Custom options 196 | 197 | ```html 198 | 199 | ``` 200 | 201 | ```javascript 202 | data () { 203 | return { 204 | tooltipOptions: { 205 | placement: 'bottom', 206 | } 207 | } 208 | } 209 | ``` 210 | 211 | - More info see . 212 | 213 | ##### 6. long 214 | 215 | ```html 216 | show : 2d 217 | show : 2 days ago 218 | ``` 219 | 220 | ##### 7. vue2-timeago event 221 | 222 | You can do something when time refresh every time 223 | 224 | 225 | ```html 226 | 227 | ``` 228 | 229 | Parameters example: 230 | 231 | ```javascript 232 | methods: { 233 | timeRefresh({ timeago, nowString, timestamp }) { 234 | console.log(timeago) // 51m 235 | console.log(nowString) // 2021-01-21 10:55 236 | console.log(timestamp) // Thu Jan 21 2021 10:55:18 GMT+0800 (台北標準時間) 237 | } 238 | } 239 | ``` 240 | 241 | ##### 8. native event 242 | 243 | ```html 244 | 245 | 246 | ``` 247 | 248 | ## Props 249 | 250 | | Property | Type | Default | Description | 251 | | ------------ | ------------ | ------------ | ------------ | 252 | | datetime | Date, String, Number | new Date() | The datetime to be formatted.| 253 | | locale | String | en | message language | 254 | | refresh | Boolean, Number | false | The period to update the component, in seconds. When true it will be 60s. Also you can bind a number.| 255 | | long | Boolean | false | Show long string with time message . ex. 3h -> 3 hours age| 256 | | tooltip | Boolean | false | Show tooltip.| 257 | | tooltip-options | Object | { placement: 'top', content: #datetime string } | tooltip options| 258 | 259 | ## Event 260 | 261 | | Property | Description | 262 | | ------------ | ------------ | 263 | | update | After timer refreshed will trigger this event | 264 | 265 | ## Nuxt (global registration) 266 | 267 | To install in nuxt run 268 | 269 | ```shell 270 | npm i vue2-timeago 271 | ``` 272 | 273 | In `nuxt.config.js` add 274 | 275 | ```javascript 276 | plugins: [ 277 | { src: '~/plugins/vue2-timeago' } 278 | ], 279 | ``` 280 | 281 | In `plugins/vue2-timeago.js` type: 282 | 283 | ```javascript 284 | import Vue from 'vue'; 285 | import { TimeAgo } from 'vue2-timeago'; 286 | 287 | import 'vue2-timeago/dist/vue2-timeago.css'; 288 | 289 | Vue.component('time-ago', TimeAgo); 290 | ``` 291 | 292 | Then in components use as: 293 | 294 | ```html 295 | 296 | ``` 297 | 298 | ## Contributions 299 | 300 | locale translations: The component needs more locale translations. You can `Open an issue to write the locale translations, or submit a pull request`. 301 | See example [here](https://github.com/runkids/vue2-timeago/blob/master/src/helpers/lang). 302 | 303 | 304 | locale support list : 305 | 306 | - English ( en ) 307 | - 繁體中文 ( zh_TW ) 308 | - 简体中文 ( zh_CN ) 309 | - 日本語 ( jp ) 310 | - Korean ( ko ) 311 | - Portugal(Brazil) ( pt_BR ) 312 | - Spain ( es ) 313 | - Arabia ( ar ) 314 | - French ( fr ) 315 | - Polish ( pl ) 316 | - Turkish ( tr ) 317 | - Indonesian ( id ) 318 | - Romanian ( ro ) 319 | - Russian ( ru ) 320 | - Germany ( de ) 321 | - Ukrainian ( uk ) 322 | - Bulgarian ( bg ) 323 | - Swedish ( se ) 324 | - Dutch / Netherlands ( nl ) 325 | - Hebrew ( he ) 326 | - Thai ( th ) 327 | - Danish ( da ) 328 | - Norwegian ( no ) 329 | - Vietnam ( vi ) 330 | - Italian ( it ) 331 | 332 | Thanks for help: 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | -------------------------------------------------------------------------------- /dist/vue2-timeago.common.js: -------------------------------------------------------------------------------- 1 | /*! vue2-timeago - 2.1.0 | (c) 2018, 2025 runkids | https://github.com/runkids/vue2-timeago */ 2 | module.exports=(n=>{var r={};function o(t){var e;return(r[t]||(e=r[t]={i:t,l:!1,exports:{}},n[t].call(e.exports,e,e.exports,o),e.l=!0,e)).exports}return o.m=n,o.c=r,o.d=function(t,e,n){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)o.d(n,r,function(t){return e[t]}.bind(null,r));return n},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s="fb15")})({"00b4":function(t,e,n){n("ac1f");var r,o=n("23e7"),i=n("c65b"),c=n("1626"),a=n("825a"),s=n("577e"),n=(r=!1,(n=/[ac]/).exec=function(){return r=!0,/./.exec.apply(this,arguments)},!0===n.test("abc")&&r),u=/./.test;o({target:"RegExp",proto:!0,forced:!n},{test:function(t){var e=a(this),t=s(t),n=e.exec;return c(n)?null!==(n=i(n,e,t))&&(a(n),!0):i(u,e,t)}})},"00ee":function(t,e,n){var r={};r[n("b622")("toStringTag")]="z",t.exports="[object z]"===String(r)},"00fd":function(t,e,n){var n=n("9e69"),r=Object.prototype,i=r.hasOwnProperty,c=r.toString,a=n?n.toStringTag:void 0;t.exports=function(t){var e=i.call(t,a),n=t[a];try{var r=!(t[a]=void 0)}catch(t){}var o=c.call(t);return r&&(e?t[a]=n:delete t[a]),o}},"0366":function(t,e,n){var r=n("4625"),o=n("59ed"),i=n("40d5"),c=r(r.bind);t.exports=function(t,e){return o(t),void 0===e?t:i?c(t,e):function(){return t.apply(e,arguments)}}},"03dd":function(t,e,n){var r=n("eac5"),o=n("57a5"),i=Object.prototype.hasOwnProperty;t.exports=function(t){if(!r(t))return o(t);var e,n=[];for(e in Object(t))i.call(t,e)&&"constructor"!=e&&n.push(e);return n}},"04f8":function(t,e,n){var r=n("1212"),o=n("d039"),i=n("cfe9").String;t.exports=!!Object.getOwnPropertySymbols&&!o(function(){var t=Symbol("symbol detection");return!i(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&r&&r<41})},"0517":function(t,e,n){n.d(e,"a",function(){return S});n("99af");function r(t,e){return 1]*>)/g,m=/\$([$&'`]|\d{1,2})/g;t.exports=function(i,c,a,s,u,t){var f=a+i.length,p=s.length,e=m;return void 0!==u&&(u=o(u),e=b),h(t,e,function(t,e){var n;switch(l(e,0)){case"$":return"$";case"&":return i;case"`":return v(c,0,a);case"'":return v(c,f);case"<":n=u[v(e,1,-1)];break;default:var r,o=+e;if(0==o)return t;if(p{Object.defineProperty(n,t,{get:function(){return r+=e,!0}})})(t,i[t]);return Object.getOwnPropertyDescriptor(c.prototype,"flags").get.call(n)!==o||r!==o});t.exports={correct:r}},"100e":function(t,e,n){var r=n("cd9d"),o=n("2286"),i=n("c1c9");t.exports=function(t,e){return i(o(t,e,r),t+"")}},"107c":function(t,e,n){var r=n("d039"),o=n("cfe9").RegExp;t.exports=r(function(){var t=o("(?b)","g");return"b"!==t.exec("b").groups.a||"bc"!=="b".replace(t,"$c")})},1212:function(t,e,n){var r,o,i=n("cfe9"),n=n("b5db"),c=i.process,i=i.Deno,c=c&&c.versions||i&&i.version,i=c&&c.v8;!(o=i?0<(r=i.split("."))[0]&&r[0]<4?1:+(r[0]+r[1]):o)&&n&&(!(r=n.match(/Edge\/(\d+)/))||74<=r[1])&&(r=n.match(/Chrome\/(\d+)/))&&(o=+r[1]),t.exports=o},1290:function(t,e){t.exports=function(t){var e=typeof t;return"string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t}},1310:function(t,e){t.exports=function(t){return null!=t&&"object"==typeof t}},1368:function(t,e,n){var n=n("da03"),r=(n=/[^.]+$/.exec(n&&n.keys&&n.keys.IE_PROTO||""))?"Symbol(src)_1."+n:"";t.exports=function(t){return!!r&&r in t}},"13d2":function(t,e,n){var r=n("e330"),o=n("d039"),i=n("1626"),c=n("1a2d"),a=n("83ab"),s=n("5e77").CONFIGURABLE,u=n("8925"),n=n("69f3"),f=n.enforce,p=n.get,d=String,l=Object.defineProperty,h=r("".slice),v=r("".replace),b=r([].join),m=a&&!o(function(){return 8!==l(function(){},"length",{value:8}).length}),g=String(String).split("String"),n=t.exports=function(t,e,n){"Symbol("===h(d(e),0,7)&&(e="["+v(d(e),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),n&&n.getter&&(e="get "+e),n&&n.setter&&(e="set "+e),(!c(t,"name")||s&&t.name!==e)&&(a?l(t,"name",{value:e,configurable:!0}):t.name=e),m&&n&&c(n,"arity")&&t.length!==n.arity&&l(t,"length",{value:n.arity});try{n&&c(n,"constructor")&&n.constructor?a&&l(t,"prototype",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(t){}n=f(t);return c(n,"source")||(n.source=b(g,"string"==typeof e?e:"")),t};Function.prototype.toString=n(function(){return i(this)&&p(this).source||u(this)},"toString")},"14c3":function(t,e,n){var r=n("c65b"),o=n("825a"),i=n("1626"),c=n("c6b6"),a=n("9263"),s=TypeError;t.exports=function(t,e){var n=t.exec;if(i(n))return null!==(n=r(n,t,e))&&o(n),n;if("RegExp"===c(t))return r(a,t,e);throw new s("RegExp#exec called on incompatible receiver")}},"14d9":function(t,e,n){var r=n("23e7"),i=n("7b0b"),c=n("07fa"),a=n("3a34"),s=n("3511");r({target:"Array",proto:!0,arity:1,forced:n("d039")(function(){return 4294967297!==[].push.call({length:4294967296},1)})||!(()=>{try{Object.defineProperty([],"length",{writable:!1}).push()}catch(t){return t instanceof TypeError}})()},{push:function(t){var e=i(this),n=c(e),r=arguments.length;s(n+r);for(var o=0;o{try{var t=r(Object,"defineProperty");return t({},"",{}),t}catch(t){}})();t.exports=n},"3bbe":function(t,e,n){var r=n("1787"),o=String,i=TypeError;t.exports=function(t){if(r(t))return t;throw new i("Can't set "+o(t)+" as a prototype")}},"3ca3":function(t,e,n){var r=n("6547").charAt,o=n("577e"),i=n("69f3"),c=n("c6d2"),a=n("4754"),s="String Iterator",u=i.set,f=i.getterFor(s);c(String,"String",function(t){u(this,{type:s,string:o(t),index:0})},function(){var t=f(this),e=t.string,n=t.index;return n>=e.length?a(void 0,!0):(e=r(e,n),t.index+=e.length,a(e,!1))})},"3f8c":function(t,e,n){t.exports={}},"408a":function(t,e,n){n=n("e330");t.exports=n(1.1.valueOf)},"40d5":function(t,e,n){n=n("d039");t.exports=!n(function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")})},"41c3":function(t,e,n){var o=n("1a8c"),i=n("eac5"),c=n("ec8c"),a=Object.prototype.hasOwnProperty;t.exports=function(t){if(!o(t))return c(t);var e,n=i(t),r=[];for(e in t)("constructor"!=e||!n&&a.call(t,e))&&r.push(e);return r}},4245:function(t,e,n){var r=n("1290");t.exports=function(t,e){return t=t.__data__,r(e)?t["string"==typeof e?"string":"hash"]:t.map}},42454:function(t,e,n){var r=n("f909"),n=n("2ec1")(function(t,e,n){r(t,e,n)});t.exports=n},4284:function(t,e){t.exports=function(t,e){for(var n=-1,r=null==t?0:t.length;++n")})||!n||p)},"55a3":function(t,e){t.exports=function(t){return this.__data__.has(t)}},5692:function(t,e,n){var r=n("c6cd");t.exports=function(t,e){return r[t]||(r[t]=e||{})}},"56ef":function(t,e,n){var r=n("d066"),o=n("e330"),i=n("241c"),c=n("7418"),a=n("825a"),s=o([].concat);t.exports=r("Reflect","ownKeys")||function(t){var e=i.f(a(t)),n=c.f;return n?s(e,n(t)):e}},"577e":function(t,e,n){var r=n("f5df"),o=String;t.exports=function(t){if("Symbol"===r(t))throw new TypeError("Cannot convert a Symbol value to a string");return o(t)}},"57a5":function(t,e,n){n=n("91e9")(Object.keys,Object);t.exports=n},"57b9":function(t,e,n){var r=n("c65b"),o=n("d066"),i=n("b622"),c=n("cb2d");t.exports=function(){var t=o("Symbol"),t=t&&t.prototype,e=t&&t.valueOf,n=i("toPrimitive");t&&!t[n]&&c(t,n,function(t){return r(e,this)},{arity:1})}},"585a":function(e,t,n){!function(t){t="object"==typeof t&&t&&t.Object===Object&&t;e.exports=t}.call(this,n("c8ba"))},5899:function(t,e,n){t.exports="\t\n\v\f\r                 \u2028\u2029\ufeff"},"58a8":function(t,e,n){function r(e){return function(t){t=c(i(t));return 1&e&&(t=a(t,s,"")),t=2&e?a(t,u,"$1"):t}}var o=n("e330"),i=n("1d80"),c=n("577e"),n=n("5899"),a=o("".replace),s=RegExp("^["+n+"]+"),u=RegExp("(^|[^"+n+"])["+n+"]+$");t.exports={start:r(1),end:r(2),trim:r(3)}},5926:function(t,e,n){var r=n("b42e");t.exports=function(t){t=+t;return t!=t||0==t?0:r(t)}},"59ed":function(t,e,n){var r=n("1626"),o=n("0d51"),i=TypeError;t.exports=function(t){if(r(t))return t;throw new i(o(t)+" is not a function")}},"5a47":function(t,e,n){var r=n("23e7"),o=n("04f8"),i=n("d039"),c=n("7418"),a=n("7b0b");r({target:"Object",stat:!0,forced:!o||i(function(){c.f(1)})},{getOwnPropertySymbols:function(t){var e=c.f;return e?e(a(t)):[]}})},"5bc3":function(t,e,n){var o=n("a395");function r(t,e){for(var n=0;n{if("object"!=r(t)||!t)return t;var n=t[Symbol.toPrimitive];if(void 0===n)return("string"===e?String:Number)(t);if("object"!=r(n=n.call(t,e||"default")))return n;throw new TypeError("@@toPrimitive must return a primitive value.")})(t,"string");return"symbol"==r(t)?t:t+""}function c(e,t){var n,r=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)),r}function o(r){for(var t=1;t{function r(t,e,n){if(!(this instanceof r))throw new TypeError("Cannot call a class as a function");this.dateTime=t,this.locale=e||"en",this.type=n||"short"}return t=r,(e=[{key:"setLocale",value:function(t){this.locale=t}},{key:"getTimeAgoString",value:function(t,e){return"string"==typeof e?"".concat(t).concat(e):e(t)}},{key:"getTimeAgo",value:function(){var t=s.b[this.locale][this.type],e=t.now,n=t.min,r=t.hour,t=t.day,o=(o=this.dateTime,!isNaN(o)||/^\d+$/.test(o)?o:(o instanceof Date?o:(o=(o||"").trim().replace(/\.\d+/,"").replace(/-/,"/").replace(/-/,"/").replace(/(\d)T(\d)/,"$1 $2").replace(/Z/," UTC").replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"),new Date(o))).getTime()),i=((new Date).getTime()-o)/1e3;return{timeago:i<=0||Math.floor(i/60)<=0?e:i<3600?this.getTimeAgoString(Math.round(i/60),n):3600<=i&&Math.round(i/3600)<24?this.getTimeAgoString(Math.round(i/3600),r):i/86400<=31?this.getTimeAgoString(Math.round(i/86400),t):(e=o,e=new Date(e),n=(n=e.getMonth()+1)<10?"0".concat(n):n,r=e.getDate()<10?"0".concat(e.getDate()):e.getDate(),"".concat(e.getFullYear(),"-").concat(n,"-").concat(r)),timestamp:o,nowString:(i=o,i=new Date(i),t=(t=i.getMonth()+1)<10?"0".concat(t):t,e=i.getDate()<10?"0".concat(i.getDate()):i.getDate(),n=i.getHours()<10?"0".concat(i.getHours()):i.getHours(),r=i.getMinutes()<10?"0".concat(i.getMinutes()):i.getMinutes(),"".concat(i.getFullYear(),"-").concat(t,"-").concat(e," ").concat(n,":").concat(r))}}}])&&a(t.prototype,e),n&&a(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t;var t,e,n})(),f=function(t,e){var n=e.locale;return new u(t,n,e.type).getTimeAgo()},p={name:"TimeAgo",directives:{tooltip:n("e37d").a},props:{datetime:{type:[String,Date,Number],default:function(){return new Date}},locale:{type:String,default:"en"},refresh:{type:[Number,Boolean],default:!1},long:{type:Boolean,default:!1},tooltip:{type:Boolean,default:!1},tooltipOptions:{type:Object,default:function(){return{placement:"top"}}}},data:function(){return{timeago:"",datetimeString:"",timer:null}},computed:{eventListeners:function(){return o({},this.$listeners)},options:function(){return o({content:this.datetimeString},this.tooltipOptions)},timerConfig:function(){return{locale:this.locale,type:this.long?"long":"short"}}},watch:{timerConfig:{deep:!0,handler:"reloadTime"},datetime:{deep:!0,handler:"reloadTime"}},mounted:function(){this.createTimer()},beforeDestroy:function(){this.clearTimer()},methods:{createTimer:function(){var e=this;this.$nextTick(function(){var t;e.reloadTime(),e.refresh&&(t=!0===e.refresh?60:e.refresh,e.timer=setInterval(e.reloadTime,1e3*t))})},clearTimer:function(){this.timer&&clearInterval(this.timer)},reloadTime:function(){var t=f(this.datetime,this.timerConfig),e=t.timeago,n=t.nowString,t=t.timestamp;this.timeago=e,this.datetimeString=n,this.timer&&this.$emit("update",{timeago:e,nowString:n,timestamp:t})}}};n("627e");n=function(){var t=this,e=t._self._c;return e("span",t._g({staticClass:"v-timeago"},t.eventListeners),[t._t("tooltip",function(){return[t.tooltip?e("span",{directives:[{name:"tooltip",rawName:"v-tooltip",value:t.options,expression:"options"}]},[t._v(t._s(t.timeago))]):e("span",[t._v(t._s(t.timeago))])]},{timeago:t.timeago})],2)},d=!(w=[]),v=h=l=null,y="function"==typeof(p=p)?p.options:p,n&&(y.render=n,y.staticRenderFns=w,y._compiled=!0),d&&(y.functional=!0),h&&(y._scopeId="data-v-"+h),v?(m=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),l&&l.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(v)},y._ssrRegister=m):l&&(m=b?function(){l.call(this,(y.functional?this.parent:this).$root.$options.shadowRoot)}:l),m&&(y.functional?(y._injectStyles=m,g=y.render,y.render=function(t,e){return m.call(e),g(t,e)}):(n=y.beforeCreate,y.beforeCreate=n?[].concat(n,m):[m]));var d,l,h,v,b,m,g,y,w={exports:p,options:y};e.a=w.exports},"7b97":function(t,e,n){var p=n("7e64"),d=n("a2be"),l=n("1c3c"),h=n("b1e5"),v=n("42a2"),b=n("6747"),m=n("0d24"),g=n("73ac"),y="[object Arguments]",w="[object Array]",x="[object Object]",_=Object.prototype.hasOwnProperty;t.exports=function(t,e,n,r,o,i){var c=b(t),a=b(e),s=c?w:v(t),a=a?w:v(e),u=(s=s==y?x:s)==x,f=(a=a==y?x:a)==x;if((a=s==a)&&m(t)){if(!m(e))return!1;u=!(c=!0)}if(a&&!u)return i=i||new p,c||g(t)?d(t,e,n,r,o,i):l(t,e,s,n,r,o,i);if(!(1&n)){c=u&&_.call(t,"__wrapped__"),s=f&&_.call(e,"__wrapped__");if(c||s)return o(c?t.value():t,s?e.value():e,n,r,i=i||new p)}return a&&(i=i||new p,h(t,e,n,r,o,i))}},"7c64":function(t,e,n){var r=n("e24b"),o=n("5e2e"),i=n("79bc");t.exports=function(){this.size=0,this.__data__={hash:new r,map:new(i||o),string:new r}}},"7c73":function(t,e,n){function r(){}function o(t){t.write(m("")),t.close();var e=t.parentWindow.Object;return t=null,e}var i,c=n("825a"),a=n("37e8"),s=n("7839"),u=n("d012"),f=n("1be4"),p=n("cc12"),n=n("f772"),d=">",l="<",h="prototype",v="script",b=n("IE_PROTO"),m=function(t){return l+v+d+t+l+"/"+v+d},g=function(){try{i=new ActiveXObject("htmlfile")}catch(t){}g="undefined"==typeof document||document.domain&&i?o(i):(t=p("iframe"),e="java"+v+":",t.style.display="none",f.appendChild(t),t.src=String(e),(e=t.contentWindow.document).open(),e.write(m("document.F=Object")),e.close(),e.F);for(var t,e,n=s.length;n--;)delete g[h][s[n]];return g()};u[b]=!0,t.exports=Object.create||function(t,e){var n;return null!==t?(r[h]=c(t),n=new r,r[h]=null,n[b]=t):n=g(),void 0===e?n:a.f(n,e)}},"7d1f":function(t,e,n){var r=n("087d"),o=n("6747");t.exports=function(t,e,n){return e=e(t),o(t)?e:r(e,n(t))}},"7d54":function(t,e,n){var r=n("23e7"),o=n("c65b"),i=n("2266"),c=n("59ed"),a=n("825a"),s=n("46c4"),u=n("2a62"),f=n("f99f")("forEach",TypeError);r({target:"Iterator",proto:!0,real:!0,forced:f},{forEach:function(e){a(this);try{c(e)}catch(t){u(this,"throw",t)}if(f)return o(f,this,e);var t=s(this),n=0;i(t,function(t){e(t,n++)},{IS_RECORD:!0})}})},"7e64":function(t,e,n){var r=n("5e2e"),o=n("efb6"),i=n("2fcc"),c=n("802a"),a=n("55a3"),n=n("d02c");function s(t){t=this.__data__=new r(t);this.size=t.size}s.prototype.clear=o,s.prototype.delete=i,s.prototype.get=c,s.prototype.has=a,s.prototype.set=n,t.exports=s},"7ed2":function(t,e){t.exports=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this}},"802a":function(t,e){t.exports=function(t){return this.__data__.get(t)}},8172:function(t,e,n){var r=n("e065"),n=n("57b9");r("toPrimitive"),n()},"825a":function(t,e,n){var r=n("861d"),o=String,i=TypeError;t.exports=function(t){if(r(t))return t;throw new i(o(t)+" is not an object")}},"83ab":function(t,e,n){n=n("d039");t.exports=!n(function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]})},8418:function(t,e,n){var r=n("83ab"),o=n("9bf2"),i=n("5c6c");t.exports=function(t,e,n){r?o.f(t,e,i(0,n)):t[e]=n}},"85e3":function(t,e){t.exports=function(t,e,n){switch(n.length){case 0:return t.call(e);case 1:return t.call(e,n[0]);case 2:return t.call(e,n[0],n[1]);case 3:return t.call(e,n[0],n[1],n[2])}return t.apply(e,n)}},"861d":function(t,e,n){var r=n("1626");t.exports=function(t){return"object"==typeof t?null!==t:r(t)}},"872a":function(t,e,n){var r=n("3b4a");t.exports=function(t,e,n){"__proto__"==e&&r?r(t,e,{configurable:!0,enumerable:!0,value:n,writable:!0}):t[e]=n}},8875:function(t,e,n){var r;void 0!==(e="function"==typeof(r=function(){function d(){var t=Object.getOwnPropertyDescriptor(document,"currentScript");if(!t&&"currentScript"in document&&document.currentScript)return document.currentScript;if(t&&t.get!==d&&document.currentScript)return document.currentScript;try{throw new Error}catch(t){var e=/.*at [^(]*\((.*):(.+):(.+)\)$/gi,n=/@([^@]*):(\d+):(\d+)\s*$/gi,r=e.exec(t.stack)||n.exec(t.stack),o=r&&r[1]||false,i=r&&r[2]||false,c=document.location.href.replace(document.location.hash,""),a,s,u,f=document.getElementsByTagName("script");if(o===c){a=document.documentElement.outerHTML;s=new RegExp("(?:[^\\n]+?\\n){0,"+(i-2)+"}[^<]*