mirror of
https://github.com/kremalicious/umami.git
synced 2024-12-18 15:23:38 +01:00
commit
eba1b1d874
26
app.json
Normal file
26
app.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "Umami",
|
||||
"description": "Umami is a simple, fast, website analytics alternative to Google Analytics.",
|
||||
"keywords": [
|
||||
"analytics",
|
||||
"charts",
|
||||
"statistics",
|
||||
"web-analytics"
|
||||
],
|
||||
"website": "https://umami.is",
|
||||
"repository": "https://github.com/mikecao/umami",
|
||||
"addons": [
|
||||
"heroku-postgresql"
|
||||
],
|
||||
"env": {
|
||||
"HASH_SALT": {
|
||||
"description": "Used to generate unique values for your installation",
|
||||
"required": true,
|
||||
"generator": "secret"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"postdeploy": "psql $DATABASE_URL -f sql/schema.postgresql.sql"
|
||||
},
|
||||
"success_url": "/"
|
||||
}
|
1
assets/arrow-up-right-from-square.svg
Normal file
1
assets/arrow-up-right-from-square.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Pro 6.0.0-alpha2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M392 320C378.75 320 368 330.75 368 344V456C368 460.406 364.406 464 360 464H56C51.594 464 48 460.406 48 456V152C48 147.594 51.594 144 56 144H168C181.25 144 192 133.25 192 120S181.25 96 168 96H56C25.125 96 0 121.125 0 152V456C0 486.875 25.125 512 56 512H360C390.875 512 416 486.875 416 456V344C416 330.75 405.25 320 392 320ZM488 0H320C306.75 0 296 10.75 296 24S306.75 48 320 48H430.062L183.031 295.031C173.656 304.406 173.656 319.594 183.031 328.969C187.719 333.656 193.844 336 200 336S212.281 333.656 216.969 328.969L464 81.938V192C464 205.25 474.75 216 488 216S512 205.25 512 192V24C512 10.75 501.25 0 488 0Z"/></svg>
|
After Width: | Height: | Size: 831 B |
@ -20,7 +20,7 @@ import Button from './Button';
|
||||
import useLocale from 'hooks/useLocale';
|
||||
import { dateFormat } from 'lib/date';
|
||||
import { chunk } from 'lib/array';
|
||||
import { dateLocales } from 'lib/lang';
|
||||
import { getDateLocale } from 'lib/lang';
|
||||
import Chevron from 'assets/chevron-down.svg';
|
||||
import Cross from 'assets/times.svg';
|
||||
import styles from './Calendar.module.css';
|
||||
@ -106,8 +106,8 @@ export default function Calendar({ date, minDate, maxDate, onChange }) {
|
||||
}
|
||||
|
||||
const DaySelector = ({ date, minDate, maxDate, locale, onSelect }) => {
|
||||
const startWeek = startOfWeek(date, { locale: dateLocales[locale] });
|
||||
const startMonth = startOfMonth(date, { locale: dateLocales[locale] });
|
||||
const startWeek = startOfWeek(date, { locale: getDateLocale(locale) });
|
||||
const startMonth = startOfMonth(date, { locale: getDateLocale(locale) });
|
||||
const startDay = subDays(startMonth, startMonth.getDay());
|
||||
const month = date.getMonth();
|
||||
const year = date.getFullYear();
|
||||
|
@ -6,6 +6,8 @@
|
||||
margin: auto;
|
||||
display: flex;
|
||||
z-index: 1;
|
||||
background-color: var(--gray50);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
|
@ -16,6 +16,7 @@ function MenuButton({
|
||||
menuAlign = 'right',
|
||||
onSelect,
|
||||
renderValue,
|
||||
hideLabel,
|
||||
}) {
|
||||
const [showMenu, setShowMenu] = useState(false);
|
||||
const ref = useRef();
|
||||
@ -44,7 +45,9 @@ function MenuButton({
|
||||
onClick={toggleMenu}
|
||||
variant="light"
|
||||
>
|
||||
<div className={styles.text}>{renderValue ? renderValue(selectedOption) : value}</div>
|
||||
{!hideLabel && (
|
||||
<div className={styles.text}>{renderValue ? renderValue(selectedOption) : value}</div>
|
||||
)}
|
||||
</Button>
|
||||
{showMenu && (
|
||||
<Menu
|
||||
|
@ -5,14 +5,13 @@ import Link from 'components/common/Link';
|
||||
import styles from './Footer.module.css';
|
||||
import useVersion from 'hooks/useVersion';
|
||||
import useLocale from 'hooks/useLocale';
|
||||
import { rtlLocales } from 'lib/lang';
|
||||
|
||||
export default function Footer() {
|
||||
const { current } = useVersion();
|
||||
const { locale } = useLocale();
|
||||
const { dir } = useLocale();
|
||||
|
||||
return (
|
||||
<footer className="container" dir={rtlLocales.includes(locale) ? 'rtl' : 'ltr'}>
|
||||
<footer className="container" dir={dir}>
|
||||
<div className={classNames(styles.footer, 'row')}>
|
||||
<div className="col-12 col-md-4" />
|
||||
<div className="col-12 col-md-4">
|
||||
|
@ -12,21 +12,20 @@ import Button from 'components/common/Button';
|
||||
import Logo from 'assets/logo.svg';
|
||||
import styles from './Header.module.css';
|
||||
import useLocale from 'hooks/useLocale';
|
||||
import { rtlLocales } from 'lib/lang';
|
||||
import XMark from 'assets/xmark.svg';
|
||||
import Bars from 'assets/bars.svg';
|
||||
|
||||
export default function Header() {
|
||||
const user = useSelector(state => state.user);
|
||||
const [active, setActive] = useState(false);
|
||||
const { locale } = useLocale();
|
||||
const { locale, dir } = useLocale();
|
||||
|
||||
function handleClick() {
|
||||
setActive(state => !state);
|
||||
}
|
||||
|
||||
return (
|
||||
<nav className="container" dir={rtlLocales.includes(locale) ? 'rtl' : 'ltr'}>
|
||||
<nav className="container" dir={dir}>
|
||||
{user?.is_admin && <UpdateNotice />}
|
||||
<div className={classNames(styles.header, 'row align-items-center')}>
|
||||
<div className={styles.nav}>
|
||||
|
@ -3,11 +3,9 @@ import Head from 'next/head';
|
||||
import Header from 'components/layout/Header';
|
||||
import Footer from 'components/layout/Footer';
|
||||
import useLocale from 'hooks/useLocale';
|
||||
import { rtlLocales } from 'lib/lang';
|
||||
|
||||
export default function Layout({ title, children, header = true, footer = true }) {
|
||||
const { locale } = useLocale();
|
||||
const dir = rtlLocales.includes(locale) ? 'rtl' : 'ltr';
|
||||
const { dir } = useLocale();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -5,4 +5,5 @@
|
||||
align-content: center;
|
||||
min-height: 80px;
|
||||
align-self: stretch;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
27
components/metrics/FilterTags.js
Normal file
27
components/metrics/FilterTags.js
Normal file
@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import Button from 'components/common/Button';
|
||||
import Times from 'assets/times.svg';
|
||||
import styles from './FilterTags.module.css';
|
||||
|
||||
export default function FilterTags({ params, onClick }) {
|
||||
if (Object.keys(params).filter(key => params[key]).length === 0) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div className={classNames(styles.filters, 'col-12')}>
|
||||
{Object.keys(params).map(key => {
|
||||
if (!params[key]) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div className={styles.tag}>
|
||||
<Button icon={<Times />} onClick={() => onClick(key)} variant="action" iconRight>
|
||||
{`${key}: ${params[key]}`}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
14
components/metrics/FilterTags.module.css
Normal file
14
components/metrics/FilterTags.module.css
Normal file
@ -0,0 +1,14 @@
|
||||
.filters {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.tag {
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.tag + .tag {
|
||||
margin-left: 20px;
|
||||
}
|
@ -18,7 +18,7 @@ export default function MetricsBar({ websiteId, className }) {
|
||||
const { startDate, endDate, modified } = dateRange;
|
||||
const [format, setFormat] = useState(true);
|
||||
const {
|
||||
query: { url },
|
||||
query: { url, ref },
|
||||
} = usePageQuery();
|
||||
|
||||
const { data, error, loading } = useFetch(
|
||||
@ -28,10 +28,11 @@ export default function MetricsBar({ websiteId, className }) {
|
||||
start_at: +startDate,
|
||||
end_at: +endDate,
|
||||
url,
|
||||
ref,
|
||||
},
|
||||
headers: { [TOKEN_HEADER]: shareToken?.token },
|
||||
},
|
||||
[url, modified],
|
||||
[modified, url, ref],
|
||||
);
|
||||
|
||||
const formatFunc = format
|
||||
|
@ -4,6 +4,7 @@ import classNames from 'classnames';
|
||||
import Link from 'next/link';
|
||||
import FilterButtons from 'components/common/FilterButtons';
|
||||
import { urlFilter } from 'lib/filters';
|
||||
import { safeDecodeURI } from 'lib/url';
|
||||
import usePageQuery from 'hooks/usePageQuery';
|
||||
import MetricsTable from './MetricsTable';
|
||||
import styles from './PagesTable.module.css';
|
||||
@ -15,7 +16,7 @@ export default function PagesTable({ websiteId, websiteDomain, showFilters, ...p
|
||||
const [filter, setFilter] = useState(FILTER_COMBINED);
|
||||
const {
|
||||
resolve,
|
||||
query: { url },
|
||||
query: { url: currentUrl },
|
||||
} = usePageQuery();
|
||||
|
||||
const buttons = [
|
||||
@ -26,16 +27,16 @@ export default function PagesTable({ websiteId, websiteDomain, showFilters, ...p
|
||||
{ label: <FormattedMessage id="metrics.filter.raw" defaultMessage="Raw" />, value: FILTER_RAW },
|
||||
];
|
||||
|
||||
const renderLink = ({ x }) => {
|
||||
const renderLink = ({ x: url }) => {
|
||||
return (
|
||||
<Link href={resolve({ url: x })} replace={true}>
|
||||
<Link href={resolve({ url })} replace={true}>
|
||||
<a
|
||||
className={classNames({
|
||||
[styles.inactive]: url && x !== url,
|
||||
[styles.active]: x === url,
|
||||
[styles.inactive]: currentUrl && url !== currentUrl,
|
||||
[styles.active]: url === currentUrl,
|
||||
})}
|
||||
>
|
||||
{decodeURI(x)}
|
||||
{safeDecodeURI(url)}
|
||||
</a>
|
||||
</Link>
|
||||
);
|
||||
|
@ -3,6 +3,13 @@ import { FormattedMessage } from 'react-intl';
|
||||
import MetricsTable from './MetricsTable';
|
||||
import FilterButtons from 'components/common/FilterButtons';
|
||||
import { refFilter } from 'lib/filters';
|
||||
import { safeDecodeURI } from 'lib/url';
|
||||
import Link from 'next/link';
|
||||
import classNames from 'classnames';
|
||||
import usePageQuery from 'hooks/usePageQuery';
|
||||
import External from 'assets/arrow-up-right-from-square.svg';
|
||||
import Icon from '../common/Icon';
|
||||
import styles from './ReferrersTable.module.css';
|
||||
|
||||
export const FILTER_DOMAIN_ONLY = 0;
|
||||
export const FILTER_COMBINED = 1;
|
||||
@ -10,6 +17,10 @@ export const FILTER_RAW = 2;
|
||||
|
||||
export default function ReferrersTable({ websiteId, websiteDomain, showFilters, ...props }) {
|
||||
const [filter, setFilter] = useState(FILTER_COMBINED);
|
||||
const {
|
||||
resolve,
|
||||
query: { ref: currentRef },
|
||||
} = usePageQuery();
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
@ -23,13 +34,24 @@ export default function ReferrersTable({ websiteId, websiteDomain, showFilters,
|
||||
{ label: <FormattedMessage id="metrics.filter.raw" defaultMessage="Raw" />, value: FILTER_RAW },
|
||||
];
|
||||
|
||||
const renderLink = ({ w: href, x: url }) => {
|
||||
return (href || url).startsWith('http') ? (
|
||||
<a href={href || url} target="_blank" rel="noreferrer">
|
||||
{decodeURI(url)}
|
||||
</a>
|
||||
) : (
|
||||
decodeURI(url)
|
||||
const renderLink = ({ w: link, x: label }) => {
|
||||
console.log({ link, label });
|
||||
return (
|
||||
<div className={styles.row}>
|
||||
<Link href={resolve({ ref: label })} replace={true}>
|
||||
<a
|
||||
className={classNames(styles.label, {
|
||||
[styles.inactive]: currentRef && label !== currentRef,
|
||||
[styles.active]: label === currentRef,
|
||||
})}
|
||||
>
|
||||
{safeDecodeURI(label)}
|
||||
</a>
|
||||
</Link>
|
||||
<a href={link || label} target="_blank" rel="noreferrer noopener" className={styles.link}>
|
||||
<Icon icon={<External />} className={styles.icon} />
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
31
components/metrics/ReferrersTable.module.css
Normal file
31
components/metrics/ReferrersTable.module.css
Normal file
@ -0,0 +1,31 @@
|
||||
body .inactive {
|
||||
color: var(--gray500);
|
||||
}
|
||||
|
||||
body .active {
|
||||
color: var(--gray900);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.row .link {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.row .label {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.row:hover .link {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.icon {
|
||||
cursor: pointer;
|
||||
}
|
@ -5,17 +5,16 @@ import MetricsBar from './MetricsBar';
|
||||
import WebsiteHeader from './WebsiteHeader';
|
||||
import DateFilter from 'components/common/DateFilter';
|
||||
import StickyHeader from 'components/helpers/StickyHeader';
|
||||
import Button from 'components/common/Button';
|
||||
import useFetch from 'hooks/useFetch';
|
||||
import useDateRange from 'hooks/useDateRange';
|
||||
import useTimezone from 'hooks/useTimezone';
|
||||
import usePageQuery from 'hooks/usePageQuery';
|
||||
import { getDateArray, getDateLength } from 'lib/date';
|
||||
import Times from 'assets/times.svg';
|
||||
import ErrorMessage from 'components/common/ErrorMessage';
|
||||
import FilterTags from 'components/metrics/FilterTags';
|
||||
import useShareToken from 'hooks/useShareToken';
|
||||
import { TOKEN_HEADER } from 'lib/constants';
|
||||
import styles from './WebsiteChart.module.css';
|
||||
import ErrorMessage from '../common/ErrorMessage';
|
||||
import useShareToken from '../../hooks/useShareToken';
|
||||
import { TOKEN_HEADER } from '../../lib/constants';
|
||||
|
||||
export default function WebsiteChart({
|
||||
websiteId,
|
||||
@ -33,7 +32,7 @@ export default function WebsiteChart({
|
||||
const {
|
||||
router,
|
||||
resolve,
|
||||
query: { url },
|
||||
query: { url, ref },
|
||||
} = usePageQuery();
|
||||
|
||||
const { data, loading, error } = useFetch(
|
||||
@ -45,11 +44,12 @@ export default function WebsiteChart({
|
||||
unit,
|
||||
tz: timezone,
|
||||
url,
|
||||
ref,
|
||||
},
|
||||
onDataLoad,
|
||||
headers: { [TOKEN_HEADER]: shareToken?.token },
|
||||
},
|
||||
[url, modified],
|
||||
[modified, url, ref],
|
||||
);
|
||||
|
||||
const chartData = useMemo(() => {
|
||||
@ -62,8 +62,8 @@ export default function WebsiteChart({
|
||||
return { pageviews: [], sessions: [] };
|
||||
}, [data]);
|
||||
|
||||
function handleCloseFilter() {
|
||||
router.push(resolve({ url: undefined }));
|
||||
function handleCloseFilter(param) {
|
||||
router.push(resolve({ [param]: undefined }));
|
||||
}
|
||||
|
||||
return (
|
||||
@ -75,7 +75,7 @@ export default function WebsiteChart({
|
||||
stickyClassName={styles.sticky}
|
||||
enabled={stickyHeader}
|
||||
>
|
||||
{url && <PageFilter url={url} onClick={handleCloseFilter} />}
|
||||
<FilterTags params={{ url, ref }} onClick={handleCloseFilter} />
|
||||
<div className="col-12 col-lg-9">
|
||||
<MetricsBar websiteId={websiteId} />
|
||||
</div>
|
||||
@ -90,7 +90,7 @@ export default function WebsiteChart({
|
||||
</StickyHeader>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col">
|
||||
<div className={classNames(styles.chart, 'col')}>
|
||||
{error && <ErrorMessage />}
|
||||
{!hideChart && (
|
||||
<PageviewsChart
|
||||
@ -106,13 +106,3 @@ export default function WebsiteChart({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const PageFilter = ({ url, onClick }) => {
|
||||
return (
|
||||
<div className={classNames(styles.url, 'col-12')}>
|
||||
<Button icon={<Times />} onClick={onClick} variant="action" iconRight>
|
||||
{url}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,9 +1,14 @@
|
||||
.container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.chart {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: var(--font-size-large);
|
||||
line-height: 60px;
|
||||
@ -37,11 +42,6 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.url {
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 992px) {
|
||||
.filter {
|
||||
display: block;
|
||||
|
@ -3,6 +3,7 @@ import { useSelector } from 'react-redux';
|
||||
import classNames from 'classnames';
|
||||
import Head from 'next/head';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import Page from '../layout/Page';
|
||||
import PageHeader from '../layout/PageHeader';
|
||||
import useFetch from '../../hooks/useFetch';
|
||||
@ -16,6 +17,7 @@ import EmptyPlaceholder from '../common/EmptyPlaceholder';
|
||||
export default function TestConsole() {
|
||||
const user = useSelector(state => state.user);
|
||||
const [website, setWebsite] = useState();
|
||||
const { basePath } = useRouter();
|
||||
const { data } = useFetch('/api/websites');
|
||||
|
||||
if (!data || !user?.is_admin) {
|
||||
@ -39,7 +41,7 @@ export default function TestConsole() {
|
||||
<Page>
|
||||
<Head>
|
||||
{typeof window !== 'undefined' && website && (
|
||||
<script async defer data-website-id={website.website_uuid} src="/umami.js" />
|
||||
<script async defer data-website-id={website.website_uuid} src={`${basePath}/umami.js`} />
|
||||
)}
|
||||
</Head>
|
||||
<PageHeader>
|
||||
|
@ -118,9 +118,9 @@ export default function WebsiteDetails({ websiteId }) {
|
||||
showLink={false}
|
||||
stickyHeader
|
||||
/>
|
||||
{!chartLoaded && <Loading />}
|
||||
</div>
|
||||
</div>
|
||||
{!chartLoaded && <Loading />}
|
||||
{chartLoaded && !view && (
|
||||
<GridLayout>
|
||||
<GridRow>
|
||||
|
@ -40,7 +40,11 @@ export default function WebsiteList({ userId }) {
|
||||
return (
|
||||
<Page>
|
||||
<div className={styles.menubar}>
|
||||
<Button icon={<Chart />} onClick={() => setHideCharts(!hideCharts)} />
|
||||
<Button
|
||||
tooltip={<FormattedMessage id="message.toggle-charts" defaultMessage="Toggle charts" />}
|
||||
icon={<Chart />}
|
||||
onClick={() => setHideCharts(!hideCharts)}
|
||||
/>
|
||||
</div>
|
||||
{data.map(({ website_id, name, domain }) => (
|
||||
<div key={website_id} className={styles.website}>
|
||||
|
@ -13,32 +13,14 @@ export default function LanguageButton() {
|
||||
saveLocale(value);
|
||||
}
|
||||
|
||||
switch (locale) {
|
||||
case 'zh-CN':
|
||||
import(/* webpackMode: "eager" */ '@fontsource/noto-sans-sc/chinese-simplified-400.css');
|
||||
import(/* webpackMode: "eager" */ '@fontsource/noto-sans-sc/chinese-simplified-500.css');
|
||||
import(/* webpackMode: "eager" */ '@fontsource/noto-sans-sc/chinese-simplified-700.css');
|
||||
break;
|
||||
case 'zh-TW':
|
||||
import(/* webpackMode: "eager" */ '@fontsource/noto-sans-tc/chinese-traditional-400.css');
|
||||
import(/* webpackMode: "eager" */ '@fontsource/noto-sans-tc/chinese-traditional-500.css');
|
||||
import(/* webpackMode: "eager" */ '@fontsource/noto-sans-tc/chinese-traditional-700.css');
|
||||
break;
|
||||
case 'ja-JP':
|
||||
import(/* webpackMode: "eager" */ '@fontsource/noto-sans-jp/japanese-400.css');
|
||||
import(/* webpackMode: "eager" */ '@fontsource/noto-sans-jp/japanese-500.css');
|
||||
import(/* webpackMode: "eager" */ '@fontsource/noto-sans-jp/japanese-700.css');
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<MenuButton
|
||||
icon={<Globe />}
|
||||
options={menuOptions}
|
||||
value={locale}
|
||||
menuClassName={styles.menu}
|
||||
renderValue={option => option?.display}
|
||||
onSelect={handleSelect}
|
||||
hideLabel
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import { setLocale } from 'redux/actions/app';
|
||||
import { useRouter } from 'next/router';
|
||||
import { get, setItem } from 'lib/web';
|
||||
import { LOCALE_CONFIG } from 'lib/constants';
|
||||
import { getDateLocale, getTextDirection } from 'lib/lang';
|
||||
import useForceUpdate from 'hooks/useForceUpdate';
|
||||
import enUS from 'public/lang/en-US.json';
|
||||
|
||||
@ -16,6 +17,8 @@ export default function useLocale() {
|
||||
const dispatch = useDispatch();
|
||||
const { basePath } = useRouter();
|
||||
const forceUpdate = useForceUpdate();
|
||||
const dir = getTextDirection(locale);
|
||||
const dateLocale = getDateLocale(locale);
|
||||
|
||||
async function loadMessages(locale) {
|
||||
const { ok, data } = await get(`${basePath}/lang/${locale}.json`);
|
||||
@ -45,5 +48,5 @@ export default function useLocale() {
|
||||
}
|
||||
}, [locale]);
|
||||
|
||||
return { locale, saveLocale, messages };
|
||||
return { locale, saveLocale, messages, dir, dateLocale };
|
||||
}
|
||||
|
@ -43,6 +43,7 @@
|
||||
"label.refresh": "تحديث",
|
||||
"label.required": "اجباري",
|
||||
"label.reset": "اعادة تعيين",
|
||||
"label.reset-website": "اعادة تعيين الإحصائيات",
|
||||
"label.save": "حفظ",
|
||||
"label.settings": "اعدادات",
|
||||
"label.share-url": "مشاركة الرابط",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "المواقع",
|
||||
"message.active-users": "{x} حاليا {x, plural, one {زائر واحد} other {زوار}}",
|
||||
"message.confirm-delete": "هل أنت متأكد من حذف {target}?",
|
||||
"message.confirm-reset": "هل أنت متأكد من اعادة تعيين الإحصائيات لـ {target}؟",
|
||||
"message.copied": "تم النسخ!",
|
||||
"message.delete-warning": "كافة البيانات المرتبطة سيم حذفها ايضا.",
|
||||
"message.failure": "حدث خطأ ما.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "لم تقم بإعداد اي موقع.",
|
||||
"message.page-not-found": "الصفحة غير موجودة.",
|
||||
"message.powered-by": "مشغل بواسطة {name}",
|
||||
"message.reset-warning": "سيتم اعادة تعيين كافة الإحصائيات لهذا الموقع، لكن لن يتم تعيير كود التتبع",
|
||||
"message.save-success": "تم الحفظ بنجاح.",
|
||||
"message.share-url": "هذا الرابط الذي تم مشاركته بشكل عام لـ {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "لتتبع الاحصاىيات لـ {target}, ضع الكود التالي في منطقة {head} في موقعك.",
|
||||
"message.type-delete": "اكتب {delete} في الحقل التالي لتأكيد الحذف.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "اجراءات",
|
||||
"metrics.average-visit-time": "متوسط وقت الزيارة",
|
||||
"metrics.bounce-rate": "معدل الارتداد",
|
||||
|
@ -43,6 +43,7 @@
|
||||
"label.refresh": "Refresca",
|
||||
"label.required": "Obligatori",
|
||||
"label.reset": "Restableix",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Desa",
|
||||
"label.settings": "Configuració",
|
||||
"label.share-url": "Enllaç per compartir",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "Llocs web",
|
||||
"message.active-users": "{x} {x, plural, one {visitant actual} other {visitants actuals}}",
|
||||
"message.confirm-delete": "Segur que vols esborrar {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "S'ha copiat",
|
||||
"message.delete-warning": "També s'esborraran totes les dades relacionades.",
|
||||
"message.failure": "S'ha produït un error.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "No hi ha cap lloc web configurat.",
|
||||
"message.page-not-found": "No s'ha trobat la pàgina.",
|
||||
"message.powered-by": "Funciona amb {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "S'ha desat amb èxit.",
|
||||
"message.share-url": "Aquest és l'enllaç públic per compartir de {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Per seguir les estadístiques de {target}, col·loca el codi següent a la secció {head} del teu lloc web.",
|
||||
"message.type-delete": "Escriu {delete} al quadre següent per confirmar.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Accions",
|
||||
"metrics.average-visit-time": "Temps mitjà de visita",
|
||||
"metrics.bounce-rate": "Percentatge de rebot",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Přidat web",
|
||||
"label.administrator": "Administrátor",
|
||||
"label.all": "Vše",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "Všechny weby",
|
||||
"label.back": "Zpět",
|
||||
"label.cancel": "Zrušit",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Obnovit",
|
||||
"label.required": "Vyžadováno",
|
||||
"label.reset": "Reset",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Uložit",
|
||||
"label.settings": "Nastavení",
|
||||
"label.share-url": "Sdílet URL",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Weby",
|
||||
"message.active-users": "{x} aktuálně {x, plural, one {návštěvník} other {návštěvníci}}",
|
||||
"message.confirm-delete": "Opravdu smazat {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Zkopírováno!",
|
||||
"message.delete-warning": "Všechna související data budou také smazána.",
|
||||
"message.failure": "Něco se pokazilo.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Nemáte nastavený žádný web.",
|
||||
"message.page-not-found": "Stránka nenalezena.",
|
||||
"message.powered-by": "Běží na {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Úspěšně uloženo.",
|
||||
"message.share-url": "Toto je sdílené URL pro {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Pro sledování návštěv na {target}, přidejte následující kód do {head} části vašeho webu.",
|
||||
"message.type-delete": "Napište {delete} pro potvrzení.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Akce",
|
||||
"metrics.average-visit-time": "Průměrný čas návštěvy",
|
||||
"metrics.bounce-rate": "Okamžité opuštění",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Tilføj hjemmeside",
|
||||
"label.administrator": "Administrator",
|
||||
"label.all": "Alle",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "Alle websites",
|
||||
"label.back": "Tilbage",
|
||||
"label.cancel": "Afvis",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Opdater",
|
||||
"label.required": "Påkrævet",
|
||||
"label.reset": "Reset",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Gem",
|
||||
"label.settings": "Indstillinger",
|
||||
"label.share-url": "Del URL",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Hjemmesider",
|
||||
"message.active-users": "{x} nuværende {x, plural, one {bruger} other {brugere}}",
|
||||
"message.confirm-delete": "Er du sikker på at du vil slette {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Kopieret!",
|
||||
"message.delete-warning": "Alle tilknyttede data slettes også.",
|
||||
"message.failure": "Noget gik galt.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Du har ikke konfigureret nogen websteder.",
|
||||
"message.page-not-found": "Side ikke fundet.",
|
||||
"message.powered-by": "Drevet af {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Gemt!",
|
||||
"message.share-url": "Dette er den offentligt delings-URL til {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "For at spore statistik for {target} skal du placere følgende kode i {head} sektionen på dit websted.",
|
||||
"message.type-delete": "Skriv {delete} i boksen nedenfor, for at bekræfte.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Handlinger",
|
||||
"metrics.average-visit-time": "Gennemsnitlig besøgstid",
|
||||
"metrics.bounce-rate": "Afvisningsprocent",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Webseite hinzufügen",
|
||||
"label.administrator": "Administrator",
|
||||
"label.all": "Alle",
|
||||
"label.all-websites": "Alle Webseiten",
|
||||
"label.all-events": "Alle Ereignisse",
|
||||
"label.all-websites": "Alle Webseiten",
|
||||
"label.back": "Zurück",
|
||||
"label.cancel": "Abbrechen",
|
||||
"label.change-password": "Passwort ändern",
|
||||
@ -43,6 +43,7 @@
|
||||
"label.refresh": "Aktualisieren",
|
||||
"label.required": "Erforderlich",
|
||||
"label.reset": "Zurücksetzen",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Speichern",
|
||||
"label.settings": "Einstellungen",
|
||||
"label.share-url": "Freigabe-URL",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "Webseiten",
|
||||
"message.active-users": "{x} {x, plural, one {aktiver Besucher} other {aktive Besucher}}",
|
||||
"message.confirm-delete": "Sind Sie sich sicher {target} zu löschen?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "In Zwischenablage kopiert!",
|
||||
"message.delete-warning": "Alle zugehörigen Daten werden ebenfalls gelöscht.",
|
||||
"message.failure": "Es ist ein Fehler aufgetreten.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "Es ist keine Webseite vorhanden.",
|
||||
"message.page-not-found": "Seite nicht gefunden.",
|
||||
"message.powered-by": "Betrieben durch {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Erfolgreich gespeichert.",
|
||||
"message.share-url": "Dies ist die öffentliche URL zum Teilen für {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Um die Statistiken für {target} zu übermitteln, platzieren Sie bitte den folgenden Quelltext im {head} ihrer Webseite.",
|
||||
"message.type-delete": "Geben Sie {delete} in das Feld unten ein um zu bestätigen.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Aktionen",
|
||||
"metrics.average-visit-time": "Durchschn. Besuchszeit",
|
||||
"metrics.bounce-rate": "Absprungrate",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Προσθήκη ιστότοπου",
|
||||
"label.administrator": "Διαχειριστής",
|
||||
"label.all": "All",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "All websites",
|
||||
"label.back": "Πίσω",
|
||||
"label.cancel": "Ακύρωση",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Ανανέωση",
|
||||
"label.required": "Απαιτείται",
|
||||
"label.reset": "Επαναφορά",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Αποθήκευση",
|
||||
"label.settings": "Ρυθμίσεις",
|
||||
"label.share-url": "Κοινοποίηση διεύθυνσης URL",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Ιστότοποι",
|
||||
"message.active-users": "{x} ενεργοί {x, plural, one {επισκέπτης} other {επισκέπτες}}",
|
||||
"message.confirm-delete": "Είστε βέβαιοι ότι θέλετε να διαγράψετε το {target};",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Αντιγράφηκε!",
|
||||
"message.delete-warning": "Όλα τα σχετικά δεδομένα θα διαγραφούν επίσης.",
|
||||
"message.failure": "Κάτι πήγε στραβά.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Δεν έχετε ρυθμίσει κανένα ιστότοπο.",
|
||||
"message.page-not-found": "Η σελίδα δεν βρέθηκε.",
|
||||
"message.powered-by": "Με την υποστήριξη του {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Αποθηκεύτηκε επιτυχώς.",
|
||||
"message.share-url": "Αυτό είναι το κοινόχρηστο URL για το {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Για να παρακολουθείτε στατιστικά στοιχεία για {target}, τοποθετήστε τον ακόλουθο κώδικα στην ενότητα {head} του ιστότοπού σας.",
|
||||
"message.type-delete": "Πληκτρολογήστε {delete} στο παρακάτω πλαίσιο για επιβεβαίωση.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Ενέργειες",
|
||||
"metrics.average-visit-time": "Μέσος χρόνος επίσκεψης",
|
||||
"metrics.bounce-rate": "Ποσοστό αναπήδησης",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Add website",
|
||||
"label.administrator": "Administrator",
|
||||
"label.all": "All",
|
||||
"label.all-websites": "All websites",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "All websites",
|
||||
"label.back": "Back",
|
||||
"label.cancel": "Cancel",
|
||||
"label.change-password": "Change password",
|
||||
@ -19,7 +19,6 @@
|
||||
"label.delete": "Delete",
|
||||
"label.delete-account": "Delete account",
|
||||
"label.delete-website": "Delete website",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.dismiss": "Dismiss",
|
||||
"label.domain": "Domain",
|
||||
"label.edit": "Edit",
|
||||
@ -44,6 +43,7 @@
|
||||
"label.refresh": "Refresh",
|
||||
"label.required": "Required",
|
||||
"label.reset": "Reset",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Save",
|
||||
"label.settings": "Settings",
|
||||
"label.share-url": "Share URL",
|
||||
@ -59,10 +59,9 @@
|
||||
"label.view-details": "View details",
|
||||
"label.websites": "Websites",
|
||||
"message.active-users": "{x} current {x, plural, one {visitor} other {visitors}}",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.confirm-delete": "Are your sure you want to delete {target}?",
|
||||
"message.confirm-delete": "Are you sure you want to delete {target}?",
|
||||
"message.confirm-reset": "Are you sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Copied!",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.delete-warning": "All associated data will be deleted as well.",
|
||||
"message.failure": "Something went wrong.",
|
||||
"message.get-share-url": "Get share URL",
|
||||
@ -75,10 +74,13 @@
|
||||
"message.no-websites-configured": "You don't have any websites configured.",
|
||||
"message.page-not-found": "Page not found.",
|
||||
"message.powered-by": "Powered by {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Saved successfully.",
|
||||
"message.share-url": "This is the publicly shared URL for {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "To track stats for {target}, place the following code in the {head} section of your website.",
|
||||
"message.type-delete": "Type {delete} in the box below to confirm.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Actions",
|
||||
"metrics.average-visit-time": "Average visit time",
|
||||
"metrics.bounce-rate": "Bounce rate",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Add website",
|
||||
"label.administrator": "Administrator",
|
||||
"label.all": "All",
|
||||
"label.all-websites": "All websites",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "All websites",
|
||||
"label.back": "Back",
|
||||
"label.cancel": "Cancel",
|
||||
"label.change-password": "Change password",
|
||||
@ -19,7 +19,6 @@
|
||||
"label.delete": "Delete",
|
||||
"label.delete-account": "Delete account",
|
||||
"label.delete-website": "Delete website",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.dismiss": "Dismiss",
|
||||
"label.domain": "Domain",
|
||||
"label.edit": "Edit",
|
||||
@ -44,6 +43,7 @@
|
||||
"label.refresh": "Refresh",
|
||||
"label.required": "Required",
|
||||
"label.reset": "Reset",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Save",
|
||||
"label.settings": "Settings",
|
||||
"label.share-url": "Share URL",
|
||||
@ -59,10 +59,9 @@
|
||||
"label.view-details": "View details",
|
||||
"label.websites": "Websites",
|
||||
"message.active-users": "{x} current {x, plural, one {visitor} other {visitors}}",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.confirm-delete": "Are your sure you want to delete {target}?",
|
||||
"message.confirm-delete": "Are you sure you want to delete {target}?",
|
||||
"message.confirm-reset": "Are you sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Copied!",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.delete-warning": "All associated data will be deleted as well.",
|
||||
"message.failure": "Something went wrong.",
|
||||
"message.get-share-url": "Get share URL",
|
||||
@ -75,10 +74,13 @@
|
||||
"message.no-websites-configured": "You don't have any websites configured.",
|
||||
"message.page-not-found": "Page not found.",
|
||||
"message.powered-by": "Powered by {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Saved successfully.",
|
||||
"message.share-url": "This is the publicly shared URL for {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "To track stats for {target}, place the following code in the {head} section of your website.",
|
||||
"message.type-delete": "Type {delete} in the box below to confirm.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Actions",
|
||||
"metrics.average-visit-time": "Average visit time",
|
||||
"metrics.bounce-rate": "Bounce rate",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Agregar sitio",
|
||||
"label.administrator": "Administrador",
|
||||
"label.all": "Todos",
|
||||
"label.all-websites": "Todos los sitios",
|
||||
"label.all-events": "Todos los eventos",
|
||||
"label.all-websites": "Todos los sitios",
|
||||
"label.back": "Atrás",
|
||||
"label.cancel": "Cancelar",
|
||||
"label.change-password": "Cambiar contraseña",
|
||||
@ -43,6 +43,7 @@
|
||||
"label.refresh": "Actualizar",
|
||||
"label.required": "Requerido",
|
||||
"label.reset": "Reiniciar",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Guardar",
|
||||
"label.settings": "Configuraciones",
|
||||
"label.share-url": "Compartir URL",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "Sitios",
|
||||
"message.active-users": "{x} {x, plural, one {activo} other {activos}}",
|
||||
"message.confirm-delete": "¿Estás seguro(a) de querer eliminar {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Copiado!",
|
||||
"message.delete-warning": "Toda la información relacionada será eliminada.",
|
||||
"message.failure": "Algo falló.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "No tienes ningún sitio configurado.",
|
||||
"message.page-not-found": "Page not found",
|
||||
"message.powered-by": "Desarrollado con {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Guardado exitosamente.",
|
||||
"message.share-url": "Esta es la URL compartida públicamente para {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Para registrar estadísticas para {target}, copia el siguiente código dentro de la etiqueta {head} de tu sitio.",
|
||||
"message.type-delete": "Escribe {delete} abajo para confirmar.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Acciones",
|
||||
"metrics.average-visit-time": "Tiempo promedio de visita",
|
||||
"metrics.bounce-rate": "Porcentaje de rebote",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "افزودن وبسایت",
|
||||
"label.administrator": "مدیر",
|
||||
"label.all": "همه",
|
||||
"label.all-websites": "همهی وبسایتها",
|
||||
"label.all-events": "همهی رویدادها",
|
||||
"label.all-websites": "همهی وبسایتها",
|
||||
"label.back": "برگشت",
|
||||
"label.cancel": "انصراف",
|
||||
"label.change-password": "تغییر رمز",
|
||||
@ -43,6 +43,7 @@
|
||||
"label.refresh": "بهروزرسانی",
|
||||
"label.required": "ضروری",
|
||||
"label.reset": "بازنشانی",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "ذخیره",
|
||||
"label.settings": "تنظیمات",
|
||||
"label.share-url": "به اشتراک گذاری URL",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "وبسایتها",
|
||||
"message.active-users": "{x} هم اکنون {x, plural, one {یک} other {از میان}}",
|
||||
"message.confirm-delete": "آیا مطمئن هستید میخواهید {target} را حذف کنید?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "کپی شد!",
|
||||
"message.delete-warning": "همهی دادههای مرتبط هم حذف خواهد شد.",
|
||||
"message.failure": "مشکلی پیش آمده است.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "شما هیچ وبسایتی را پیکربندی نکردهاید.",
|
||||
"message.page-not-found": "صفحه یافت نشد.",
|
||||
"message.powered-by": "قدرت گرفته توسط {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "با موفقیت ذخیره شد.",
|
||||
"message.share-url": "این URL به اشتراک گذاشته شده عمومی برای {target} است.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "برای ردیابی آمار {target}, کد روبرو را در قسمت {head} وبسایت قرار دهید.",
|
||||
"message.type-delete": "جهت اطمینان '{delete}' را در کادر زیر بنویسید.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "اقدامات",
|
||||
"metrics.average-visit-time": "میانگین زمان بازدید",
|
||||
"metrics.bounce-rate": "نرخ Bounce",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Lisää verkkosivu",
|
||||
"label.administrator": "Järjestelmänvalvoja",
|
||||
"label.all": "Kaikki",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "Kaikki verkkosivut",
|
||||
"label.back": "Takaisin",
|
||||
"label.cancel": "Peruuta",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Päivitä",
|
||||
"label.required": "Vaaditaan",
|
||||
"label.reset": "Nollaa",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Tallenna",
|
||||
"label.settings": "Asetukset",
|
||||
"label.share-url": "Jaa URL",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Verkkosivut",
|
||||
"message.active-users": "{x} nykyinen {x, plural, one {yksi} other {muut}}",
|
||||
"message.confirm-delete": "Haluatko varmasti poistaa {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Kopioitu!",
|
||||
"message.delete-warning": "Kaikki siihen liittyvät tiedot poistetaan.",
|
||||
"message.failure": "Jotain meni väärin.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Sinulla ei ole määritettyjä verkkosivustoja.",
|
||||
"message.page-not-found": "Sivua ei löydetty.",
|
||||
"message.powered-by": "Voimanlähteenä {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Tallennettu onnistuneesti.",
|
||||
"message.share-url": "Tämä on julkisesti jaettu URL-osoitteelle {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Jos haluat seurata kohteen {target} tilastoja, aseta seuraava koodi verkkosivustosi {head} osioon.",
|
||||
"message.type-delete": "Kirjoita {delete} alla olevaan ruutuun vahvistaaksesi.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Toiminnat",
|
||||
"metrics.average-visit-time": "Keskimääräinen vierailuaika",
|
||||
"metrics.bounce-rate": "Välitön poistuminen",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Legg heimasíðu afturat",
|
||||
"label.administrator": "Fyrisitari",
|
||||
"label.all": "Alt",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "Allar heimasíður",
|
||||
"label.back": "Aftur",
|
||||
"label.cancel": "Strika",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Endurskapa",
|
||||
"label.required": "Kravt",
|
||||
"label.reset": "Nulstilla",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Goym",
|
||||
"label.settings": "Stillingar",
|
||||
"label.share-url": "Deil leinku",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Heimasíður",
|
||||
"message.active-users": "{x} í løtuni {x, plural, one {vitjandi} other { vitjandi }}",
|
||||
"message.confirm-delete": "Ert tú sikkur at tú ynskir at strika {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Avrita!",
|
||||
"message.delete-warning": "Øll data ið er knýtt at verður eisini strika.",
|
||||
"message.failure": "Okkurt bleiv gali.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Tú hevur ongar heimasíður stillaða til.",
|
||||
"message.page-not-found": "Síðan bleiv ikki funnin.",
|
||||
"message.powered-by": "Powered by {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Goymt.",
|
||||
"message.share-url": "Hettar er tann almenna leinkan av {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Fyri at spora hagtøl fyri {target}, koyr kotuna í {head} partin á tínari heimasíðu.",
|
||||
"message.type-delete": "Skriva {delete} í feltið fyri at vátta",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Gerðir",
|
||||
"metrics.average-visit-time": "Miðal vitjurnartíð ",
|
||||
"metrics.bounce-rate": "Bounce prosenttal",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Ajouter un site",
|
||||
"label.administrator": "Administrateur",
|
||||
"label.all": "Tout",
|
||||
"label.all-websites": "Tous les sites web",
|
||||
"label.all-events": "Tous les événements",
|
||||
"label.all-websites": "Tous les sites web",
|
||||
"label.back": "Retour",
|
||||
"label.cancel": "Annuler",
|
||||
"label.change-password": "Changer le mot de passe",
|
||||
@ -43,6 +43,7 @@
|
||||
"label.refresh": "Rafraîchir",
|
||||
"label.required": "Requis",
|
||||
"label.reset": "Réinitialiser",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Sauvegarder",
|
||||
"label.settings": "Paramètres",
|
||||
"label.share-url": "Partager l'URL",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "Sites",
|
||||
"message.active-users": "{x} {x, plural, one {visiteur} other {visiteurs}} actuellement",
|
||||
"message.confirm-delete": "Êtes-vous sûr de vouloir supprimer {target} ?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Copié !",
|
||||
"message.delete-warning": "Toutes les données associées seront également supprimées.",
|
||||
"message.failure": "Un problème est survenu.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "Vous n'avez configuré aucun site Web.",
|
||||
"message.page-not-found": "Page non trouvée.",
|
||||
"message.powered-by": "Propulsé par {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Enregistré avec succès.",
|
||||
"message.share-url": "Ceci est l'URL partagée pour {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Pour suivre les statistiques de {target}, placez le code suivant dans la section {head} de votre site Web.",
|
||||
"message.type-delete": "Tapez {delete} dans la case ci-dessous pour confirmer.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Actions",
|
||||
"metrics.average-visit-time": "Temps de visite moyen",
|
||||
"metrics.bounce-rate": "Taux de rebond",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "הוספת אתר",
|
||||
"label.administrator": "מנהל",
|
||||
"label.all": "הכל",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "כל האתרים",
|
||||
"label.back": "חזרה",
|
||||
"label.cancel": "ביטול",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "רענון",
|
||||
"label.required": "נדרש",
|
||||
"label.reset": "איפוס",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "שמירה",
|
||||
"label.settings": "הגדרות",
|
||||
"label.share-url": "שיתוף URL",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "אתרים",
|
||||
"message.active-users": "{x} נוכחיים {x, plural, one {מבקר} other {מבקרים}}",
|
||||
"message.confirm-delete": "האם באמת למחוק את {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "הועתק!",
|
||||
"message.delete-warning": "כל המידע המקושר יימחק",
|
||||
"message.failure": "משהו השתבש",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "לא מוגדרים אתרים",
|
||||
"message.page-not-found": "דף לא נמצא",
|
||||
"message.powered-by": "Powered by {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "נשמר בהצלחה",
|
||||
"message.share-url": "זהו URL ציבורי עבור {target}",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "יש להוסיף את הקוד הבא לאזור ה-{head} של האתר",
|
||||
"message.type-delete": "הקלידו {delete} בתיבה על מנת לאשר",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "פעולות",
|
||||
"metrics.average-visit-time": "זמן ביקור ממוצע",
|
||||
"metrics.bounce-rate": "Bounce rate",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "वेबसाइट",
|
||||
"label.administrator": "प्रशासक",
|
||||
"label.all": "सब",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "सभी वेबसाइटें",
|
||||
"label.back": "पीछे",
|
||||
"label.cancel": "रद्द करें",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "रिफ्रेश",
|
||||
"label.required": "अपेक्षित",
|
||||
"label.reset": "रीसेट",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "सहेजें",
|
||||
"label.settings": "समायोजन",
|
||||
"label.share-url": "यूआरएल साझा करें",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "वेबसाइटों",
|
||||
"message.active-users": "{x} मौजूद {x, plural, one {आगंतुक} other {आगंतुकों}}",
|
||||
"message.confirm-delete": "क्या आप वाकई में {target} हटाना चाहते हैं?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "कॉपी हो गया!",
|
||||
"message.delete-warning": "सभी संबद्ध डेटा को भी हटा दिया जाएगा।",
|
||||
"message.failure": "कुछ गलत हो गया।",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "आपके पास कोई वेबसाइट कॉन्फ़िगर नहीं है।",
|
||||
"message.page-not-found": "पृष्ठ नहीं मिला।",
|
||||
"message.powered-by": "{name} द्वारा संचालित",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "सफलतापूर्वक संचित कर लिया गया है।",
|
||||
"message.share-url": "यह {target} के लिए सार्वजनिक रूप से साझा किया गया URL है।",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "{target} के आँकड़ों को ट्रैक करने के लिए, अपनी वेबसाइट के {head} अनुभाग में निम्नलिखित कोड रखें।",
|
||||
"message.type-delete": "पुष्टि करने के लिए नीचे दिए गए बॉक्स में {delete} टाइप करें।",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "कार्य",
|
||||
"metrics.average-visit-time": "औसत दृश्य समय",
|
||||
"metrics.bounce-rate": "उछाल दर",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Weboldal hozzáadása",
|
||||
"label.administrator": "Adminisztrátor",
|
||||
"label.all": "Összes",
|
||||
"label.all-websites": "Összes weboldal",
|
||||
"label.all-events": "Összes esemény",
|
||||
"label.all-websites": "Összes weboldal",
|
||||
"label.back": "Vissza",
|
||||
"label.cancel": "Mégsem",
|
||||
"label.change-password": "Jelszó módosítása",
|
||||
@ -43,6 +43,7 @@
|
||||
"label.refresh": "Frissítés",
|
||||
"label.required": "Kötelező",
|
||||
"label.reset": "Visszaállítás",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Mentés",
|
||||
"label.settings": "Beállítások",
|
||||
"label.share-url": "URL megosztása",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "Weboldalak",
|
||||
"message.active-users": "{x} {x, plural, one {látogató} other {latógató}} jelenleg",
|
||||
"message.confirm-delete": "Biztos, hogy törölni szeretnéd {target} elemet?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Kimásolva!",
|
||||
"message.delete-warning": "Minden társított adat törlésre kerül.",
|
||||
"message.failure": "Valami baj történt.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "Még nem állítottál be egyetlen weboldalt sem.",
|
||||
"message.page-not-found": "Oldal nem található.",
|
||||
"message.powered-by": "Működteti az {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Sikeres mentés.",
|
||||
"message.share-url": "{target} nyilvánosan megosztott URL címe.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "{target} statisztikáinak nyomon követéséhez, helyezd el az alábbi kódot a weboldalad {head} részébe.",
|
||||
"message.type-delete": "Megerősítéshez írd be az alábbi mezőbe azt, hogy {delete}.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Műveletek",
|
||||
"metrics.average-visit-time": "Átlagos látogatási idő",
|
||||
"metrics.bounce-rate": "Visszafordulási arány",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Tambah situs web",
|
||||
"label.administrator": "Pengelola",
|
||||
"label.all": "Semua",
|
||||
"label.all-events": "Semua peristiwa",
|
||||
"label.all-websites": "Semua website",
|
||||
"label.back": "Kembali",
|
||||
"label.cancel": "Batal",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Segarkan",
|
||||
"label.required": "Wajib",
|
||||
"label.reset": "Atur ulang",
|
||||
"label.reset-website": "Atur ulang statistik",
|
||||
"label.save": "Simpan",
|
||||
"label.settings": "Pengaturan",
|
||||
"label.share-url": "Bagikan URL",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Situs web",
|
||||
"message.active-users": "{x} pengunjung saat ini",
|
||||
"message.confirm-delete": "Apakah kamu yakin ingin menghapus {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Tersalin!",
|
||||
"message.delete-warning": "Semua data terkait juga akan dihapus.",
|
||||
"message.failure": "Ada yang salah.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Anda tidak memiliki situs web yang dikonfigurasi.",
|
||||
"message.page-not-found": "Halaman tidak ditemukan.",
|
||||
"message.powered-by": "Didukung oleh {name}",
|
||||
"message.reset-warning": "Semua statistik pada website ini akan dihapus, tetapi kode lacak akan tetap terpasang",
|
||||
"message.save-success": "Berhasil disimpan.",
|
||||
"message.share-url": "Ini adalah URL yang dibagikan secara publik untuk {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Untuk melacak statistik {target}, tempatkan kode berikut di bagian {head} situs web anda.",
|
||||
"message.type-delete": "Ketikkan {delete} pada kotak di bawah untuk konfirmasi.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Aksi",
|
||||
"metrics.average-visit-time": "Waktu kunjungan rata-rata",
|
||||
"metrics.bounce-rate": "Rasio pentalan",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Aggiungi sito",
|
||||
"label.administrator": "Amministratore",
|
||||
"label.all": "Tutto",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "Tutti i siti web",
|
||||
"label.back": "Indietro",
|
||||
"label.cancel": "Annulla",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Ricarica",
|
||||
"label.required": "Obbligatorio",
|
||||
"label.reset": "Reset",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Salva",
|
||||
"label.settings": "Impostazioni",
|
||||
"label.share-url": "Share URL",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Siti web",
|
||||
"message.active-users": "{x} {x, plural, one {visitatore} other {visitatori}} online",
|
||||
"message.confirm-delete": "Sei sicuro di voler eliminare {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Copiato!",
|
||||
"message.delete-warning": "Saranno eliminati anche tutti i dati associati.",
|
||||
"message.failure": "Si è verificato un errore.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Non hai ancora configurato alcun sito.",
|
||||
"message.page-not-found": "Pagina non trovata",
|
||||
"message.powered-by": "Powered by {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Salvato!",
|
||||
"message.share-url": "Questo è l'URL di condivisione per {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Per tracciare le statistiche di {target}, inserisci questo codice nella sezione {head} del tuo sito web.",
|
||||
"message.type-delete": "Digita {delete} nel box qui sotto per confermare.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Azioni",
|
||||
"metrics.average-visit-time": "Tempo medio di visita",
|
||||
"metrics.bounce-rate": "Frequenza di rimbalzo",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Webサイトの追加",
|
||||
"label.administrator": "管理者",
|
||||
"label.all": "すべて表示",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "すべてのWebサイト",
|
||||
"label.back": "戻る",
|
||||
"label.cancel": "キャンセル",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "更新",
|
||||
"label.required": "必須",
|
||||
"label.reset": "リセット",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "保存",
|
||||
"label.settings": "設定",
|
||||
"label.share-url": "共有リンク",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Webサイト",
|
||||
"message.active-users": "{x}人が閲覧中です。",
|
||||
"message.confirm-delete": "{target}を削除してもよろしいですか?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "コピーしました!",
|
||||
"message.delete-warning": "関連するすべてのデータも削除されます。",
|
||||
"message.failure": "問題が発生しました。",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Webサイトが設定されていません。",
|
||||
"message.page-not-found": "ページが見つかりません。",
|
||||
"message.powered-by": "このシステムは {name} で実行されています。",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "正常に保存されました。",
|
||||
"message.share-url": "これは {target} の共有リンクです。",
|
||||
"message.share-url": "これは{target}の共有リンクです。",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "{target}のアクセス解析を開始するには、次のコードをWebサイトの{head}セクションへ追加してください。",
|
||||
"message.type-delete": "確認のため、下のフォームに{delete}と入力してください。",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "アクション",
|
||||
"metrics.average-visit-time": "平均滞在時間",
|
||||
"metrics.bounce-rate": "直帰率",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "웹사이트 추가",
|
||||
"label.administrator": "관리자",
|
||||
"label.all": "전체",
|
||||
"label.all-websites": "모든 웹사이트",
|
||||
"label.all-events": "모든 이벤트",
|
||||
"label.all-websites": "모든 웹사이트",
|
||||
"label.back": "뒤로",
|
||||
"label.cancel": "취소",
|
||||
"label.change-password": "비밀번호 변경",
|
||||
@ -43,6 +43,7 @@
|
||||
"label.refresh": "새로고침",
|
||||
"label.required": "필수",
|
||||
"label.reset": "리셋",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "저장",
|
||||
"label.settings": "설정",
|
||||
"label.share-url": "공유 URL",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "웹사이트",
|
||||
"message.active-users": "{x}명의 사용자가 보는 중입니다.",
|
||||
"message.confirm-delete": "{target}을(를) 삭제하시겠습니까?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "복사했습니다!",
|
||||
"message.delete-warning": "관련된 모든 데이터도 삭제됩니다.",
|
||||
"message.failure": "오류가 발생하였습니다.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "구성된 웹 사이트가 없습니다.",
|
||||
"message.page-not-found": "페이지를 찾을 수 없습니다.",
|
||||
"message.powered-by": "이 시스템은 {name}에서 구동되고 있습니다.",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "성공적으로 저장되었습니다.",
|
||||
"message.share-url": "이것은 {target}의 공개적으로 공유된 URL입니다.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "{target}에 대한 통계를 추적하려면 웹사이트의 {head} 섹션에 다음 코드를 입력하십시오.",
|
||||
"message.type-delete": "확인을 위해 아래 박스에 {delete}값을 입력하십시오.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "액션",
|
||||
"metrics.average-visit-time": "평균 방문 시간",
|
||||
"metrics.bounce-rate": "이탈률",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Веб нэмэх",
|
||||
"label.administrator": "Админ",
|
||||
"label.all": "Бүх",
|
||||
"label.all-websites": "Бүх вебүүд",
|
||||
"label.all-events": "Бүх үйл явдал",
|
||||
"label.all-websites": "Бүх вебүүд",
|
||||
"label.back": "Буцах",
|
||||
"label.cancel": "Цуцлах",
|
||||
"label.change-password": "Нууц үг солих",
|
||||
@ -43,6 +43,7 @@
|
||||
"label.refresh": "Сэргээх",
|
||||
"label.required": "Шаардлагатай",
|
||||
"label.reset": "Хуучин хэвд нь оруулах",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Хадгалах",
|
||||
"label.settings": "Тохиргоо",
|
||||
"label.share-url": "Хуваалцах холбоос",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "Вебүүд",
|
||||
"message.active-users": "одоо {x} {x, plural, one {зочин} other {зочин}} байна",
|
||||
"message.confirm-delete": "Та {target}-г устгахдаа итгэлтэй байна уу?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Хуулсан!",
|
||||
"message.delete-warning": "Үүнтэй холбоотой бүх өгөгдөл устах болно.",
|
||||
"message.failure": "Ямар нэг зүйл буруу боллоо.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "Та ямар нэгэн веб тохируулаагүй байна.",
|
||||
"message.page-not-found": "Хуудас олдсонгүй.",
|
||||
"message.powered-by": "{name} дээр суурилсан",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Амжилттай хадгаллаа.",
|
||||
"message.share-url": "{target}-г нийтэд хуваалцах холбоос.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "{target} вебийн статистикийг бүртгэхийн тулд доорх кодыг вебийнхээ {head} хэсэгт байрлуулна уу.",
|
||||
"message.type-delete": "Доорх хэсэгт {delete} гэж бичиж баталгаажуулна уу.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Үйлдлүүд",
|
||||
"metrics.average-visit-time": "Зочилсон дундаж хугацаа",
|
||||
"metrics.bounce-rate": "Нэг хуудас үзээд гарсан",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Tambah laman web",
|
||||
"label.administrator": "Pentadbir",
|
||||
"label.all": "Semua",
|
||||
"label.all-websites": "Semua laman web",
|
||||
"label.all-events": "Semua peristiwa",
|
||||
"label.all-websites": "Semua laman web",
|
||||
"label.back": "Kembali",
|
||||
"label.cancel": "Batal",
|
||||
"label.change-password": "Tukar kata laluan",
|
||||
@ -43,6 +43,7 @@
|
||||
"label.refresh": "Muat semula",
|
||||
"label.required": "Diperlukan",
|
||||
"label.reset": "Tetapkan semula",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Simpan",
|
||||
"label.settings": "Tetapan",
|
||||
"label.share-url": "Kongsikan URL",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "Laman web",
|
||||
"message.active-users": "{x} semasa {x, plural, one {pelawat} other {pelawat}}",
|
||||
"message.confirm-delete": "Pastikah anda ingin memadam {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Disalin!",
|
||||
"message.delete-warning": "Semua data yang berkaitan juga akan dihapuskan.",
|
||||
"message.failure": "Ada yang tidak kena.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "Anda tidak ada sebarang laman web yang telah dikonfigurasikan.",
|
||||
"message.page-not-found": "Halaman tidak dijumpai.",
|
||||
"message.powered-by": "Disediakan oleh {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Berjaya disimpan.",
|
||||
"message.share-url": "Ini adalah URL berkongsi untuk {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Untuk menjejak statistik bagi {target}, letakkan kod berikut di bahagian {head} laman web anda.",
|
||||
"message.type-delete": "Taip {delete} di dalam kotak di bawah untuk pengesahan.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Aksi",
|
||||
"metrics.average-visit-time": "Purata tempoh masa lawatan",
|
||||
"metrics.bounce-rate": "Kadar lantunan",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Legg til nettsted",
|
||||
"label.administrator": "Administrator",
|
||||
"label.all": "Alle",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "Alle nettsteder",
|
||||
"label.back": "Tilbake",
|
||||
"label.cancel": "Avvis",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Oppdater",
|
||||
"label.required": "Påkrevd",
|
||||
"label.reset": "Nullstill",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Lagre",
|
||||
"label.settings": "Innstillinger",
|
||||
"label.share-url": "Del URL",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Nettsteder",
|
||||
"message.active-users": "{x} {x, plural, one {besøkende} other {besøkende}} nå",
|
||||
"message.confirm-delete": "Er du sikker på at du vil slette {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Kopiert!",
|
||||
"message.delete-warning": "Alle tilknyttede data slettes også.",
|
||||
"message.failure": "Noe gikk galt.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Du har ikke satt opp noen nettsteder.",
|
||||
"message.page-not-found": "Side ikke funnet.",
|
||||
"message.powered-by": "Drevet av {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Lagret!",
|
||||
"message.share-url": "Dette er den offentlige delings-URL-en for {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "For å spore statistikk for {target}, plasser følgende kode i {head}-delen av nettstedet ditt.",
|
||||
"message.type-delete": "Skriv inn {delete} i boksen nedenfor for å bekrefte.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Handlinger",
|
||||
"metrics.average-visit-time": "Gjennomsnittlig besøkelsestid",
|
||||
"metrics.bounce-rate": "Avvisningsfrekvens",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Website toevoegen",
|
||||
"label.administrator": "Administrator",
|
||||
"label.all": "Alles",
|
||||
"label.all-websites": "Alle websites",
|
||||
"label.all-events": "Alle gebeurtenissen",
|
||||
"label.all-websites": "Alle websites",
|
||||
"label.back": "Terug",
|
||||
"label.cancel": "Annuleren",
|
||||
"label.change-password": "Wachtwoord wijzigen",
|
||||
@ -43,6 +43,7 @@
|
||||
"label.refresh": "Vernieuwen",
|
||||
"label.required": "Verplicht",
|
||||
"label.reset": "Resetten",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Opslaan",
|
||||
"label.settings": "Instellingen",
|
||||
"label.share-url": "URL delen",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "Websites",
|
||||
"message.active-users": "{x} actieve {x, plural, one {bezoeker} other {bezoekers}}",
|
||||
"message.confirm-delete": "Weet je zeker dat je {target} wilt verwijderen?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Gekopiëerd!",
|
||||
"message.delete-warning": "Alle verwante gegezens zullen ook verwijderd worden.",
|
||||
"message.failure": "Er is iets misgegaan.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "Je hebt geen websites ingesteld.",
|
||||
"message.page-not-found": "Pagina niet gevonden.",
|
||||
"message.powered-by": "mogelijk gemaakt door {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Opslaan succesvol.",
|
||||
"message.share-url": "Met deze URL kan {target} openbaar gedeeld worden.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Om statistieken voor {target} bij te houden, plaats je de volgende code in het {head} gedeelte van je website.",
|
||||
"message.type-delete": "Type {delete} in onderstaande veld om dit te bevestigen.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Acties",
|
||||
"metrics.average-visit-time": "Gemiddelde bezoektijd",
|
||||
"metrics.bounce-rate": "Bouncepercentage",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Dodaj witrynę",
|
||||
"label.administrator": "Administrator",
|
||||
"label.all": "Wszystkie",
|
||||
"label.all-websites": "Wszystkie witryny",
|
||||
"label.all-events": "Wszystkie wydarzenia",
|
||||
"label.all-websites": "Wszystkie witryny",
|
||||
"label.back": "Powrót",
|
||||
"label.cancel": "Anuluj",
|
||||
"label.change-password": "Zmień hasło",
|
||||
@ -43,6 +43,7 @@
|
||||
"label.refresh": "Odśwież",
|
||||
"label.required": "Wymagany",
|
||||
"label.reset": "Zresetuj",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Zapisz",
|
||||
"label.settings": "Ustawienia",
|
||||
"label.share-url": "Udostępnij adres URL",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "Witryny",
|
||||
"message.active-users": "{x} aktualnie {x, plural, one {odwiedzający} other {odwiedzających}}",
|
||||
"message.confirm-delete": "Czy na pewno chcesz usunąć {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Skopiowano!",
|
||||
"message.delete-warning": "Wszystkie powiązane dane również zostaną usunięte.",
|
||||
"message.failure": "Coś poszło nie tak.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "Nie masz skonfigurowanych żadnych witryn internetowych.",
|
||||
"message.page-not-found": "Strona nie znaleziona.",
|
||||
"message.powered-by": "Obsługiwane przez {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Zapisano pomyślnie.",
|
||||
"message.share-url": "To jest publicznie udostępniany adres URL dla {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Aby śledzić statystyki dla {target}, umieść poniższy kod w sekcji {head} swojej witryny.",
|
||||
"message.type-delete": "Wpisz {delete} w polu poniżej, aby potwierdzić.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Działania",
|
||||
"metrics.average-visit-time": "Średni czas wizyty",
|
||||
"metrics.bounce-rate": "Współczynnik odrzuceń",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Adicionar site",
|
||||
"label.administrator": "Administrador",
|
||||
"label.all": "Todos",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "Todos os sites",
|
||||
"label.back": "Voltar",
|
||||
"label.cancel": "Cancelar",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Atualizar",
|
||||
"label.required": "Obrigatório",
|
||||
"label.reset": "Redefinir",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Salvar",
|
||||
"label.settings": "Configurações",
|
||||
"label.share-url": "Link de compartilhamento",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Sites",
|
||||
"message.active-users": "{x} {x, plural, one {visitante} other {visitantes}} neste momento",
|
||||
"message.confirm-delete": "Deseja realmente remover {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Copiado!",
|
||||
"message.delete-warning": "Todos os dados associados também serão eliminados.",
|
||||
"message.failure": "Ocorreu um erro.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Nenhum site foi configurado ainda.",
|
||||
"message.page-not-found": "Página não encontrada.",
|
||||
"message.powered-by": "Distribuído por {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Salvo com sucesso.",
|
||||
"message.share-url": "Este é o link público de compartilhamento para {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Para gerar estatística para {target}, coloque o seguinte código no {head} do html do seu site.",
|
||||
"message.type-delete": "Escreva {delete} abaixo para continuar.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Ações",
|
||||
"metrics.average-visit-time": "Tempo médio da visita",
|
||||
"metrics.bounce-rate": "Taxa de rejeição",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Adicionar website",
|
||||
"label.administrator": "Administrador",
|
||||
"label.all": "Todos",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "Todos os websites",
|
||||
"label.back": "Voltar",
|
||||
"label.cancel": "Cancelar",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Atualizar",
|
||||
"label.required": "Obrigatório",
|
||||
"label.reset": "Repor",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Guardar",
|
||||
"label.settings": "Definições",
|
||||
"label.share-url": "Partilhar link",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Websites",
|
||||
"message.active-users": "{x} {x, plural, one {visitante} other {visitantes}} neste momento",
|
||||
"message.confirm-delete": "Tens a certeza que queres eliminar {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Copiado!",
|
||||
"message.delete-warning": "Todos os dados associados também serão eliminados.",
|
||||
"message.failure": "Ocorreu um erro.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Não tens nenhum website configurado.",
|
||||
"message.page-not-found": "Página não encontrada.",
|
||||
"message.powered-by": "Distribuído por {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Guardado com sucesso.",
|
||||
"message.share-url": "Este é o link de partilha público para {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Para recolheres estatísticas para {target}, coloca o seguinte código na secção {head} do teu website.",
|
||||
"message.type-delete": "Escreve {delete} abaixo para confirmares.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Ações",
|
||||
"metrics.average-visit-time": "Tempo médio de visita",
|
||||
"metrics.bounce-rate": "Taxa de rejeição",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Adăugare site web",
|
||||
"label.administrator": "Administrator",
|
||||
"label.all": "All",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "All websites",
|
||||
"label.back": "Înapoi",
|
||||
"label.cancel": "Anulează",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Reîmprospătare",
|
||||
"label.required": "Obligatoriu",
|
||||
"label.reset": "Resetează",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Salvează",
|
||||
"label.settings": "Setări",
|
||||
"label.share-url": "Partajare URL",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Site-uri web",
|
||||
"message.active-users": "{x} {x, plural, one {vizitator activ} other {vizitatori activi}}",
|
||||
"message.confirm-delete": "Sunteți sigur că doriți să ștergeți {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Copiat!",
|
||||
"message.delete-warning": "Toate datele asociate vor fi șterse, de asemenea.",
|
||||
"message.failure": "Ceva n-a mers bine.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Nu aveți niciun site web configurat.",
|
||||
"message.page-not-found": "Pagina nu a fost găsită.",
|
||||
"message.powered-by": "Cu sprijinul {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Salvat cu succes.",
|
||||
"message.share-url": "Aceasta este adresa URL de partajare pentru {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Pentru a urmări statisticile pentru {target}, plasați următorul cod în secțiunea {head} a site-ului dvs. web.",
|
||||
"message.type-delete": "Tastați {delete} în casuța de mai jos pentru a confirma.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Acțiuni",
|
||||
"metrics.average-visit-time": "Timp mediu de vizitare",
|
||||
"metrics.bounce-rate": "Rata de respingere",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Добавить сайт",
|
||||
"label.administrator": "Администратор",
|
||||
"label.all": "Все",
|
||||
"label.all-websites": "Все сайты",
|
||||
"label.all-events": "Все события",
|
||||
"label.all-websites": "Все сайты",
|
||||
"label.back": "Назад",
|
||||
"label.cancel": "Отменить",
|
||||
"label.change-password": "Изменить пароль",
|
||||
@ -19,7 +19,6 @@
|
||||
"label.delete": "Удалить",
|
||||
"label.delete-account": "Удалить аккаунт",
|
||||
"label.delete-website": "Удалить сайт",
|
||||
"label.reset-website": "Сбросить статистику",
|
||||
"label.dismiss": "Отклонить",
|
||||
"label.domain": "Домен",
|
||||
"label.edit": "Редактировать",
|
||||
@ -44,6 +43,7 @@
|
||||
"label.refresh": "Обновить",
|
||||
"label.required": "Обязательное",
|
||||
"label.reset": "Сбросить",
|
||||
"label.reset-website": "Сбросить статистику",
|
||||
"label.save": "Сохранить",
|
||||
"label.settings": "Настройки",
|
||||
"label.share-url": "Поделиться ссылкой",
|
||||
@ -59,10 +59,9 @@
|
||||
"label.view-details": "Посмотреть детали",
|
||||
"label.websites": "Сайты",
|
||||
"message.active-users": "{x} текущих посетителей",
|
||||
"message.confirm-reset": "Вы уверены, что хотите сбросить статистику {target}?",
|
||||
"message.confirm-delete": "Вы уверены, что хотите удалить {target}?",
|
||||
"message.confirm-reset": "Вы уверены, что хотите сбросить статистику {target}?",
|
||||
"message.copied": "Скопировано!",
|
||||
"message.reset-warning": "Вся статистика для этого сайта будет удалена, но ваш код отслеживания останется нетронутым.",
|
||||
"message.delete-warning": "Все связанные данные будут также удалены.",
|
||||
"message.failure": "Что-то пошло не так.",
|
||||
"message.get-share-url": "Получить публичную ссылку",
|
||||
@ -75,10 +74,13 @@
|
||||
"message.no-websites-configured": "У вас нет настроенных сайтов.",
|
||||
"message.page-not-found": "Страница не найдена.",
|
||||
"message.powered-by": "На движке {name}",
|
||||
"message.reset-warning": "Вся статистика для этого сайта будет удалена, но ваш код отслеживания останется нетронутым.",
|
||||
"message.save-success": "Успешно сохранено.",
|
||||
"message.share-url": "Это публичная ссылка для {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Чтобы отслеживать статистику для {target}, поместите следующий код в раздел {head} вашего сайта.",
|
||||
"message.type-delete": "Напишите {delete} в поле ниже, чтобы подтвердить.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Действия",
|
||||
"metrics.average-visit-time": "Среднее время посещения",
|
||||
"metrics.bounce-rate": "Отказы",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Pridať web",
|
||||
"label.administrator": "Administrátor",
|
||||
"label.all": "Všetko",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "Všetky weby",
|
||||
"label.back": "Späť",
|
||||
"label.cancel": "Zrušiť",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Obnoviť",
|
||||
"label.required": "Povinné",
|
||||
"label.reset": "Reset",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Uložiť",
|
||||
"label.settings": "Nastavenia",
|
||||
"label.share-url": "Zdielanie URL",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Weby",
|
||||
"message.active-users": "{x} aktuálne {x, plural, one {návštevník} other {návštěvníci}}",
|
||||
"message.confirm-delete": "Naozaj zmazať {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Skopírované!",
|
||||
"message.delete-warning": "Všetky príbuzné data budu tiež zmazané.",
|
||||
"message.failure": "Niečo sa pokazilo.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Nemáte nastavený žiadny web.",
|
||||
"message.page-not-found": "Stránka sa nenašla.",
|
||||
"message.powered-by": "Powered by {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Úspešne uložené.",
|
||||
"message.share-url": "Toto je zdielané URL pre {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Pre sledovanie návštev na {target}, pridajte následujúci kód do {head} časti vašeho webu.",
|
||||
"message.type-delete": "Napíšte {delete} pre potvrdenie.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Akcie",
|
||||
"metrics.average-visit-time": "Priemerný čas návštevy",
|
||||
"metrics.bounce-rate": "Okamžité opustenie",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Dodaj spletno mesto",
|
||||
"label.administrator": "Administrator",
|
||||
"label.all": "Vse",
|
||||
"label.all-websites": "Vsa spletna mesta",
|
||||
"label.all-events": "Vsi dogodki",
|
||||
"label.all-websites": "Vsa spletna mesta",
|
||||
"label.back": "Nazaj",
|
||||
"label.cancel": "Prekliči",
|
||||
"label.change-password": "Zamenjaj geslo",
|
||||
@ -43,6 +43,7 @@
|
||||
"label.refresh": "Osveži",
|
||||
"label.required": "Zahtevano",
|
||||
"label.reset": "Ponastavi",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Shrani",
|
||||
"label.settings": "Nastavitve",
|
||||
"label.share-url": "Deli URL",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "Spletna mesta",
|
||||
"message.active-users": "{x} trenutni {x, plural, one {obiskovalec} other {obiskovalcev}}",
|
||||
"message.confirm-delete": "Ste prepričani, da želite izbrisati {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Kopirano!",
|
||||
"message.delete-warning": "Izbrisani bodo tudi vsi povezani podatki.",
|
||||
"message.failure": "Prišlo je do napake.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "Ni nastavljenih spletnih mest.",
|
||||
"message.page-not-found": "Stran ni bila najdena.",
|
||||
"message.powered-by": "Zagotavlja {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Uspešno shranjeno.",
|
||||
"message.share-url": "To je javno dostopen naslov URL za {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Če želite spremljati statistične podatke za {target}, v {head} del vašega spletnega mesta namestite naslednjo kodo.",
|
||||
"message.type-delete": "V spodnje polje vnesite {delete} za potrditev.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Dejanja",
|
||||
"metrics.average-visit-time": "Povprečni čas obiska",
|
||||
"metrics.bounce-rate": "Zapustna stopnja",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Lägg till webbsajt",
|
||||
"label.administrator": "Administratör",
|
||||
"label.all": "Alla",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "Alla sajter",
|
||||
"label.back": "Tillbaka",
|
||||
"label.cancel": "Avbryt",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Uppdatera",
|
||||
"label.required": "Krävs",
|
||||
"label.reset": "Återställ",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Spara",
|
||||
"label.settings": "Inställningar",
|
||||
"label.share-url": "Delnings-URL",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Webbsajt",
|
||||
"message.active-users": "{x} {x, plural, one {besökare} other {besökare}} just nu",
|
||||
"message.confirm-delete": "Är du säker på att du vill radera {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Kopierad!",
|
||||
"message.delete-warning": "All tillhörande data kommer också raderas.",
|
||||
"message.failure": "Något gick fel.",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Du har inga webbsajter.",
|
||||
"message.page-not-found": "Sidan kan inte hittas.",
|
||||
"message.powered-by": "Drivs av {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Sparades!",
|
||||
"message.share-url": "Det här är den offentliga delnings-URL:en {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "För att spåra statistik för {target}, placera följande kod i {head}-avsnittet på din webbsajt.",
|
||||
"message.type-delete": "Skriv {delete} i rutan nedan för att radera.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Händelser",
|
||||
"metrics.average-visit-time": "Medelbesökstid",
|
||||
"metrics.bounce-rate": "Avvisningfrekvens",
|
||||
|
@ -43,6 +43,7 @@
|
||||
"label.refresh": "புதுப்பிப்பு",
|
||||
"label.required": "தேவையானவை",
|
||||
"label.reset": "மீட்டமை",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "சேமி",
|
||||
"label.settings": "அமைப்புகள்",
|
||||
"label.share-url": "வலைத்தள களத்தைப் பகிரவும்",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "வலைத்தளங்கள்",
|
||||
"message.active-users": "{x} தற்போதைய {x, plural, one {ஒன்று} other {மற்ற}}",
|
||||
"message.confirm-delete": "நீங்கள் நிச்சயமாக {target} நீக்க விரும்புகிறீர்களா?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "நகலெடுக்கப்பட்டது!",
|
||||
"message.delete-warning": "தொடர்புடைய எல்லா தரவும் நீக்கப்படும்.",
|
||||
"message.failure": "ஏதோ தவறு நடந்துவிட்டது.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "உங்களிடம் எந்த வலைத்தளங்களும் கட்டமைக்கப்படவில்லை.",
|
||||
"message.page-not-found": "பக்கம் கிடைக்கவில்லை.",
|
||||
"message.powered-by": "{name} ஆல் இயக்கப்படுகிறது",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "வெற்றிகரமாக சேமிக்கப்பட்டது.",
|
||||
"message.share-url": "{target} இது பொதுவில் பகிரும் வலைத்தள முகவரி.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "{target}க்கான புள்ளிவிவரங்களைக் கண்காணிக்க, {head}ல் பின்வரும் குறியீட்டை வைக்கவும்.",
|
||||
"message.type-delete": "உறுதிப்படுத்த கீழே உள்ள பெட்டியில் {delete} என தட்டச்சு செய்க.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "செயல்கள்",
|
||||
"metrics.average-visit-time": "சராசரி வருகை நேரம்",
|
||||
"metrics.bounce-rate": "துள்ளல் விகிதம்",
|
||||
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "Web sitesi ekle",
|
||||
"label.administrator": "Yönetici",
|
||||
"label.all": "Tümü",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "Tüm web siteleri",
|
||||
"label.back": "Geri",
|
||||
"label.cancel": "İptal",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "Yenile",
|
||||
"label.required": "Zorunlu alan",
|
||||
"label.reset": "Sıfırla",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Kaydet",
|
||||
"label.settings": "Ayarlar",
|
||||
"label.share-url": "Paylaşım adresi",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "Web siteleri",
|
||||
"message.active-users": "{x} aktif ziyaretçi",
|
||||
"message.confirm-delete": "{target} kaydını silmek istediğinizden emin misiniz?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Panoya kopyalandı!",
|
||||
"message.delete-warning": "İlişkili tüm veriler de silinecektir.",
|
||||
"message.failure": "Bir şeyler ters gitti!",
|
||||
@ -71,10 +74,13 @@
|
||||
"message.no-websites-configured": "Henüz hiç web sitesi tanımlamadınız",
|
||||
"message.page-not-found": "Sayfa bulunamadı.",
|
||||
"message.powered-by": "Sağlayıcı: {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Başarıyla kaydedildi.",
|
||||
"message.share-url": "{target} için kullanılabilir anonim paylaşım adresidir.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "{target} alanı adı istatistiklerini takip etmek için, aşağıdaki kodu web sitenizin {head} bloğuna yerleştirin.",
|
||||
"message.type-delete": "Onaylamak için kutuya {delete} yazın.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Hareketler",
|
||||
"metrics.average-visit-time": "Ortalama ziyaret süresi",
|
||||
"metrics.bounce-rate": "Çıkma oranı",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"label.add-website": "Додати сайт",
|
||||
"label.administrator": "Адміністратор",
|
||||
"label.all": "Всі",
|
||||
"label.all-websites": "Всі сайти",
|
||||
"label.all-events": "Всі події",
|
||||
"label.all-websites": "Всі сайти",
|
||||
"label.back": "Назад",
|
||||
"label.cancel": "Відмінити",
|
||||
"label.change-password": "Змінити пароль",
|
||||
@ -43,6 +43,7 @@
|
||||
"label.refresh": "Оновити",
|
||||
"label.required": "Обов'язкове",
|
||||
"label.reset": "Скинути",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "Зберегти",
|
||||
"label.settings": "Налаштування",
|
||||
"label.share-url": "Поділитися посилання",
|
||||
@ -59,6 +60,7 @@
|
||||
"label.websites": "Сайти",
|
||||
"message.active-users": "{x} поточних відвідувачів",
|
||||
"message.confirm-delete": "Ви впевнені, що бажаєте видалити {target}?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "Скопійовано!",
|
||||
"message.delete-warning": "Усі пов'язані дані будуть видалені також.",
|
||||
"message.failure": "Щось пішло не так.",
|
||||
@ -72,10 +74,13 @@
|
||||
"message.no-websites-configured": "У вас немає налаштованих сайтів.",
|
||||
"message.page-not-found": "Сторінку не знайдено.",
|
||||
"message.powered-by": "На базі {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "Збережено успішно.",
|
||||
"message.share-url": "Це публічне посилання для {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Аби відслідковувати статистику для {target}, розмістіть наступний код у {head} секції вашого сайту.",
|
||||
"message.type-delete": "Введіть {delete} у полі нижче щоб підтвердити.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Дії",
|
||||
"metrics.average-visit-time": "Середній час візиту",
|
||||
"metrics.bounce-rate": "Показник відмов",
|
||||
|
105
lang/vi-VN.json
Normal file
105
lang/vi-VN.json
Normal file
@ -0,0 +1,105 @@
|
||||
{
|
||||
"label.accounts": "Tài khoản",
|
||||
"label.add-account": "Thêm tài khoản",
|
||||
"label.add-website": "Thêm website",
|
||||
"label.administrator": "Quản Trị",
|
||||
"label.all": "Tất cả",
|
||||
"label.all-events": "Tất cả events",
|
||||
"label.all-websites": "Tất cả websites",
|
||||
"label.back": "Quay về",
|
||||
"label.cancel": "Huỷ bỏ",
|
||||
"label.change-password": "Đổi mật khẩu",
|
||||
"label.confirm-password": "Xác nhận mật khẩu",
|
||||
"label.copy-to-clipboard": "Lưu vào bộ nhớ tạm",
|
||||
"label.current-password": "Mật khẩu hiện tại",
|
||||
"label.custom-range": "Phạm vi ngày tuỳ chọn",
|
||||
"label.dashboard": "Bảng điều khiển",
|
||||
"label.date-range": "Phạm vi ngày",
|
||||
"label.default-date-range": "Phạm vi ngày mặc định",
|
||||
"label.delete": "Xoá",
|
||||
"label.delete-account": "Xoá tài khoản",
|
||||
"label.delete-website": "Xáo website",
|
||||
"label.dismiss": "Laoị trừ",
|
||||
"label.domain": "Tên miền",
|
||||
"label.edit": "Chỉnh sửa",
|
||||
"label.edit-account": "Chỉnh sửa tài khoản",
|
||||
"label.edit-website": "Chỉnh sửa website",
|
||||
"label.enable-share-url": "Bật khả năng chia sẻ URL",
|
||||
"label.invalid": "Không hợp lệ",
|
||||
"label.invalid-domain": "Tên miền không hợp lệ",
|
||||
"label.last-days": "{x} ngày gần nhất",
|
||||
"label.last-hours": "{x} giờ gần nhất",
|
||||
"label.logged-in-as": "Đăng nhập như {username}",
|
||||
"label.login": "Đăng nhập",
|
||||
"label.logout": "Đăng xuất",
|
||||
"label.more": "Thêm",
|
||||
"label.name": "Tên",
|
||||
"label.new-password": "Mật khẩu mới",
|
||||
"label.password": "Mật khẩu",
|
||||
"label.passwords-dont-match": "Mật khẩu không đồng nhất",
|
||||
"label.profile": "Hồ sơ",
|
||||
"label.realtime": "Thời gian thực",
|
||||
"label.realtime-logs": "Nhật ký thời gian thực",
|
||||
"label.refresh": "Làm mới",
|
||||
"label.required": "Yêu cầu",
|
||||
"label.reset": "Tái thiết lập",
|
||||
"label.reset-website": "Tái thiết lập thống kê",
|
||||
"label.save": "Lưu",
|
||||
"label.settings": "Cài đặt",
|
||||
"label.share-url": "Chia sẻ URL",
|
||||
"label.single-day": "Trong ngày",
|
||||
"label.this-month": "Tháng này",
|
||||
"label.this-week": "Tuần này",
|
||||
"label.this-year": "Năm nay",
|
||||
"label.timezone": "Múi giờ",
|
||||
"label.today": "Hôm nay",
|
||||
"label.tracking-code": "Mã theo dõi",
|
||||
"label.unknown": "Không rõ",
|
||||
"label.username": "Tên đăng nhập",
|
||||
"label.view-details": "Xem chi tiết",
|
||||
"label.websites": "Websites",
|
||||
"message.active-users": "{x} hiện tại {x, plural, one {một} other {trên}}",
|
||||
"message.confirm-delete": "Bạn có chắc chắn muốn xoá {target}?",
|
||||
"message.confirm-reset": "Bạn có chắc chắn muốn tái thiết lập thống kê {target}?",
|
||||
"message.copied": "Đã copy!",
|
||||
"message.delete-warning": "Tất cả các dữ liệu liên quan cũng sẽ bị xoá.",
|
||||
"message.failure": "Đã xảy ra lỗi.",
|
||||
"message.get-share-url": "Lấy URL chia sẻ",
|
||||
"message.get-tracking-code": "Lấy mã theo dõi",
|
||||
"message.go-to-settings": "Đến cài đặt",
|
||||
"message.incorrect-username-password": "Sai tên đăng nhập/mật khẩu.",
|
||||
"message.log.visitor": "Khách từ {country} đang dùng {browser} trên {os} {device}",
|
||||
"message.new-version-available": "Có một phiên bản mới của umami!",
|
||||
"message.no-data-available": "Không có dữ liệu.",
|
||||
"message.no-websites-configured": "Bạn chưa có bất cứ website nào.",
|
||||
"message.page-not-found": "Trang không tìm thấy.",
|
||||
"message.powered-by": "Bản quyền bởi {name}",
|
||||
"message.reset-warning": "Tất cả số liệu thống kê của website này sẽ bị xoá, nhưng mã theo dõi sẽ vẫn giữ nguyên.",
|
||||
"message.save-success": "Đã lưu thành công.",
|
||||
"message.share-url": "Đây là đường dẫn URL cho {target}.",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "Để theo dõi {target}, dán mã theo dõi vào {head} của website bạn.",
|
||||
"message.type-delete": "Nhập {delete} bên dưới để xác nhận.",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "Hành động",
|
||||
"metrics.average-visit-time": "Thời gian truy cập trung bình",
|
||||
"metrics.bounce-rate": "Tỷ lệ thoát trang",
|
||||
"metrics.browsers": "Trình duyệt",
|
||||
"metrics.countries": "Quốc gia",
|
||||
"metrics.device.desktop": "Máy bàn",
|
||||
"metrics.device.laptop": "Laptop",
|
||||
"metrics.device.mobile": "Di động",
|
||||
"metrics.device.tablet": "Máy tính bảng",
|
||||
"metrics.devices": "Thiết bị",
|
||||
"metrics.events": "Sự kiện",
|
||||
"metrics.filter.combined": "Kết hợp",
|
||||
"metrics.filter.domain-only": "Chỉ tên miền",
|
||||
"metrics.filter.raw": "Gốc",
|
||||
"metrics.operating-systems": "Hệ điều hành",
|
||||
"metrics.page-views": "Lượt xem",
|
||||
"metrics.pages": "Trang",
|
||||
"metrics.referrers": "Liên kết giới thiệu",
|
||||
"metrics.unique-visitors": "Khách truy cập duy nhất",
|
||||
"metrics.views": "Xem",
|
||||
"metrics.visitors": "Khách"
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
"label.add-website": "添加网站",
|
||||
"label.administrator": "管理员",
|
||||
"label.all": "所有",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "全部网站",
|
||||
"label.back": "返回",
|
||||
"label.cancel": "取消",
|
||||
@ -42,6 +43,7 @@
|
||||
"label.refresh": "刷新",
|
||||
"label.required": "必填",
|
||||
"label.reset": "重置",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "保存",
|
||||
"label.settings": "设置",
|
||||
"label.share-url": "共享链接",
|
||||
@ -58,6 +60,7 @@
|
||||
"label.websites": "网站",
|
||||
"message.active-users": "当前在线 {x} 人",
|
||||
"message.confirm-delete": "你确定要删除 {target} 吗?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "复制成功!",
|
||||
"message.delete-warning": "所有相关数据将会被删除。",
|
||||
"message.failure": "出现错误。",
|
||||
@ -65,16 +68,19 @@
|
||||
"message.get-tracking-code": "获取跟踪代码",
|
||||
"message.go-to-settings": "去设置",
|
||||
"message.incorrect-username-password": "用户名或密码不正确。",
|
||||
"message.log.visitor": "来自 {country} 的访客在搭载 {os} 的 {device} 上使用 {browser} 浏览器进行访问。",
|
||||
"message.log.visitor": "来自{country}的访客在搭载 {os} 的{device}上使用 {browser} 浏览器进行访问。",
|
||||
"message.new-version-available": "umami 有新版本 {version} 发布啦!",
|
||||
"message.no-data-available": "无可用数据。",
|
||||
"message.no-websites-configured": "你还没有设置任何网站。",
|
||||
"message.page-not-found": "网页未找到。",
|
||||
"message.powered-by": "由 {name} 提供支持",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "保存成功。",
|
||||
"message.share-url": "这是 {target} 的共享链接。",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "把以下代码放到你的网站的 {head} 部分来收集 {target} 的数据。",
|
||||
"message.type-delete": "在下方输入框输入 {delete} 以确认删除。",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "用户行为",
|
||||
"metrics.average-visit-time": "平均访问时间",
|
||||
"metrics.bounce-rate": "跳出率",
|
||||
|
200
lang/zh-TW.json
200
lang/zh-TW.json
@ -1,99 +1,105 @@
|
||||
{
|
||||
"label.accounts": "帳戶",
|
||||
"label.add-account": "增加帳戶",
|
||||
"label.add-website": "增加網站",
|
||||
"label.administrator": "管理員",
|
||||
"label.all": "所有",
|
||||
"label.all-websites": "全部網站",
|
||||
"label.back": "返回",
|
||||
"label.cancel": "取消",
|
||||
"label.change-password": "更新密碼",
|
||||
"label.confirm-password": "確認密碼",
|
||||
"label.copy-to-clipboard": "複製",
|
||||
"label.current-password": "目前密碼",
|
||||
"label.custom-range": "自定義時段",
|
||||
"label.dashboard": "管理面板",
|
||||
"label.date-range": "多日",
|
||||
"label.default-date-range": "默認日期範圍",
|
||||
"label.delete": "刪除",
|
||||
"label.delete-account": "刪除帳戶",
|
||||
"label.delete-website": "删除網站",
|
||||
"label.dismiss": "關閉",
|
||||
"label.domain": "域名",
|
||||
"label.edit": "編輯",
|
||||
"label.edit-account": "編輯帳戶",
|
||||
"label.edit-website": "編輯網站",
|
||||
"label.enable-share-url": "啟用分享連結",
|
||||
"label.invalid": "無效輸入",
|
||||
"label.invalid-domain": "無效域名",
|
||||
"label.last-days": "最近 {x} 天",
|
||||
"label.last-hours": "最近 {x} 小時",
|
||||
"label.logged-in-as": "用戶名: {username}",
|
||||
"label.login": "登入",
|
||||
"label.logout": "退出",
|
||||
"label.more": "更多",
|
||||
"label.name": "名字",
|
||||
"label.new-password": "新密碼",
|
||||
"label.password": "密碼",
|
||||
"label.passwords-dont-match": "密碼不一致",
|
||||
"label.profile": "個人資料",
|
||||
"label.realtime": "實時",
|
||||
"label.realtime-logs": "實時日志",
|
||||
"label.refresh": "刷新",
|
||||
"label.required": "必填",
|
||||
"label.reset": "重置",
|
||||
"label.save": "保存",
|
||||
"label.settings": "設置",
|
||||
"label.share-url": "分享連結",
|
||||
"label.single-day": "單日",
|
||||
"label.this-month": "本月",
|
||||
"label.this-week": "本週",
|
||||
"label.this-year": "今年",
|
||||
"label.timezone": "時區",
|
||||
"label.today": "今天",
|
||||
"label.tracking-code": "追蹤代碼",
|
||||
"label.unknown": "未知",
|
||||
"label.username": "用户名",
|
||||
"label.view-details": "查看更多",
|
||||
"label.websites": "網站",
|
||||
"message.active-users": "当前線上 {x} 人",
|
||||
"message.confirm-delete": "你確定要删除 {target} 嗎?",
|
||||
"message.copied": "複製成功!",
|
||||
"message.delete-warning": "所有相關數據將會被删除。",
|
||||
"message.failure": "出現錯誤。",
|
||||
"message.get-share-url": "獲得分享連結",
|
||||
"message.get-tracking-code": "獲得追蹤代碼",
|
||||
"message.go-to-settings": "去設定",
|
||||
"message.incorrect-username-password": "用户名或密碼不正確。",
|
||||
"message.log.visitor": "自 {country} 的訪客在搭載 {os} 的 {device} 上使用 {browser} 進行訪問。",
|
||||
"message.new-version-available": "umami 有新版本 {version} 發佈啦!",
|
||||
"message.no-data-available": "無可用數據。",
|
||||
"message.no-websites-configured": "目前無任何網站設定。",
|
||||
"message.page-not-found": "網頁未找到。",
|
||||
"message.powered-by": "運行 {name}",
|
||||
"message.save-success": "成功保存。",
|
||||
"message.share-url": "這是 {target} 的分享連結。",
|
||||
"message.track-stats": "將以下代碼放入被設定網站的 {head} 部分来收集 {target} 的資料。",
|
||||
"message.type-delete": "在下方空格輸入 {delete} 確認",
|
||||
"metrics.actions": "用戶行為",
|
||||
"metrics.average-visit-time": "平均訪問時間",
|
||||
"metrics.bounce-rate": "跳出率",
|
||||
"metrics.browsers": "瀏覽器",
|
||||
"metrics.countries": "國家/地區",
|
||||
"metrics.device.desktop": "桌機",
|
||||
"metrics.device.laptop": "筆記本",
|
||||
"metrics.device.mobile": "手機",
|
||||
"metrics.device.tablet": "平板",
|
||||
"metrics.devices": "裝置",
|
||||
"metrics.events": "行為類別",
|
||||
"metrics.filter.combined": "總和",
|
||||
"metrics.filter.domain-only": "僅域名",
|
||||
"metrics.filter.raw": "原始",
|
||||
"metrics.operating-systems": "操作系统",
|
||||
"metrics.page-views": "網頁流量",
|
||||
"metrics.pages": "網頁",
|
||||
"metrics.referrers": "指入域名",
|
||||
"metrics.unique-visitors": "獨立訪客",
|
||||
"metrics.views": "頁面流量",
|
||||
"metrics.visitors": "獨立訪客"
|
||||
"label.accounts": "帳戶",
|
||||
"label.add-account": "增加帳戶",
|
||||
"label.add-website": "增加網站",
|
||||
"label.administrator": "管理員",
|
||||
"label.all": "所有",
|
||||
"label.all-events": "All events",
|
||||
"label.all-websites": "全部網站",
|
||||
"label.back": "返回",
|
||||
"label.cancel": "取消",
|
||||
"label.change-password": "更新密碼",
|
||||
"label.confirm-password": "確認密碼",
|
||||
"label.copy-to-clipboard": "複製",
|
||||
"label.current-password": "目前密碼",
|
||||
"label.custom-range": "自定義時段",
|
||||
"label.dashboard": "管理面板",
|
||||
"label.date-range": "多日",
|
||||
"label.default-date-range": "默認日期範圍",
|
||||
"label.delete": "刪除",
|
||||
"label.delete-account": "刪除帳戶",
|
||||
"label.delete-website": "删除網站",
|
||||
"label.dismiss": "關閉",
|
||||
"label.domain": "域名",
|
||||
"label.edit": "編輯",
|
||||
"label.edit-account": "編輯帳戶",
|
||||
"label.edit-website": "編輯網站",
|
||||
"label.enable-share-url": "啟用分享連結",
|
||||
"label.invalid": "無效輸入",
|
||||
"label.invalid-domain": "無效域名",
|
||||
"label.last-days": "最近 {x} 天",
|
||||
"label.last-hours": "最近 {x} 小時",
|
||||
"label.logged-in-as": "用戶名: {username}",
|
||||
"label.login": "登入",
|
||||
"label.logout": "退出",
|
||||
"label.more": "更多",
|
||||
"label.name": "名字",
|
||||
"label.new-password": "新密碼",
|
||||
"label.password": "密碼",
|
||||
"label.passwords-dont-match": "密碼不一致",
|
||||
"label.profile": "個人資料",
|
||||
"label.realtime": "實時",
|
||||
"label.realtime-logs": "實時日志",
|
||||
"label.refresh": "刷新",
|
||||
"label.required": "必填",
|
||||
"label.reset": "重置",
|
||||
"label.reset-website": "Reset statistics",
|
||||
"label.save": "保存",
|
||||
"label.settings": "設置",
|
||||
"label.share-url": "分享連結",
|
||||
"label.single-day": "單日",
|
||||
"label.this-month": "本月",
|
||||
"label.this-week": "本週",
|
||||
"label.this-year": "今年",
|
||||
"label.timezone": "時區",
|
||||
"label.today": "今天",
|
||||
"label.tracking-code": "追蹤代碼",
|
||||
"label.unknown": "未知",
|
||||
"label.username": "用户名",
|
||||
"label.view-details": "查看更多",
|
||||
"label.websites": "網站",
|
||||
"message.active-users": "当前線上 {x} 人",
|
||||
"message.confirm-delete": "你確定要删除 {target} 嗎?",
|
||||
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
|
||||
"message.copied": "複製成功!",
|
||||
"message.delete-warning": "所有相關數據將會被删除。",
|
||||
"message.failure": "出現錯誤。",
|
||||
"message.get-share-url": "獲得分享連結",
|
||||
"message.get-tracking-code": "獲得追蹤代碼",
|
||||
"message.go-to-settings": "去設定",
|
||||
"message.incorrect-username-password": "用户名或密碼不正確。",
|
||||
"message.log.visitor": "自{country}的訪客在搭載 {os} 的{device}上使用 {browser} 進行訪問。",
|
||||
"message.new-version-available": "umami 有新版本 {version} 發佈啦!",
|
||||
"message.no-data-available": "無可用數據。",
|
||||
"message.no-websites-configured": "目前無任何網站設定。",
|
||||
"message.page-not-found": "網頁未找到。",
|
||||
"message.powered-by": "運行 {name}",
|
||||
"message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.",
|
||||
"message.save-success": "成功保存。",
|
||||
"message.share-url": "這是 {target} 的分享連結。",
|
||||
"message.toggle-charts": "Toggle charts",
|
||||
"message.track-stats": "將以下代碼放入被設定網站的 {head} 部分来收集 {target} 的資料。",
|
||||
"message.type-delete": "在下方空格輸入 {delete} 確認",
|
||||
"message.type-reset": "Type {reset} in the box below to confirm.",
|
||||
"metrics.actions": "用戶行為",
|
||||
"metrics.average-visit-time": "平均訪問時間",
|
||||
"metrics.bounce-rate": "跳出率",
|
||||
"metrics.browsers": "瀏覽器",
|
||||
"metrics.countries": "國家/地區",
|
||||
"metrics.device.desktop": "桌機",
|
||||
"metrics.device.laptop": "筆記本",
|
||||
"metrics.device.mobile": "手機",
|
||||
"metrics.device.tablet": "平板",
|
||||
"metrics.devices": "裝置",
|
||||
"metrics.events": "行為類別",
|
||||
"metrics.filter.combined": "總和",
|
||||
"metrics.filter.domain-only": "僅域名",
|
||||
"metrics.filter.raw": "原始",
|
||||
"metrics.operating-systems": "操作系统",
|
||||
"metrics.page-views": "網頁流量",
|
||||
"metrics.pages": "網頁",
|
||||
"metrics.referrers": "指入域名",
|
||||
"metrics.unique-visitors": "獨立訪客",
|
||||
"metrics.views": "頁面流量",
|
||||
"metrics.visitors": "獨立訪客"
|
||||
}
|
11
lib/date.js
11
lib/date.js
@ -25,8 +25,7 @@ import {
|
||||
differenceInCalendarYears,
|
||||
format,
|
||||
} from 'date-fns';
|
||||
import { enUS } from 'date-fns/locale';
|
||||
import { dateLocales } from 'lib/lang';
|
||||
import { getDateLocale } from 'lib/lang';
|
||||
|
||||
export function getTimezone() {
|
||||
return moment.tz.guess();
|
||||
@ -38,7 +37,7 @@ export function getLocalTime(t) {
|
||||
|
||||
export function getDateRange(value, locale = 'en-US') {
|
||||
const now = new Date();
|
||||
const localeOptions = dateLocales[locale];
|
||||
const dateLocale = getDateLocale(locale);
|
||||
|
||||
const { num, unit } = value.match(/^(?<num>[0-9]+)(?<unit>hour|day|week|month|year)$/).groups;
|
||||
|
||||
@ -53,8 +52,8 @@ export function getDateRange(value, locale = 'en-US') {
|
||||
};
|
||||
case 'week':
|
||||
return {
|
||||
startDate: startOfWeek(now, { locale: localeOptions }),
|
||||
endDate: endOfWeek(now, { locale: localeOptions }),
|
||||
startDate: startOfWeek(now, { locale: dateLocale }),
|
||||
endDate: endOfWeek(now, { locale: dateLocale }),
|
||||
unit: 'day',
|
||||
value,
|
||||
};
|
||||
@ -164,6 +163,6 @@ export const customFormats = {
|
||||
|
||||
export function dateFormat(date, str, locale = 'en-US') {
|
||||
return format(date, customFormats?.[locale]?.[str] || str, {
|
||||
locale: dateLocales[locale] || enUS,
|
||||
locale: getDateLocale(locale),
|
||||
});
|
||||
}
|
||||
|
@ -95,9 +95,7 @@ export const refFilter = (data, { domain, domainOnly, raw }) => {
|
||||
|
||||
const url = cleanUrl(x);
|
||||
|
||||
if (!domainOnly && !raw) {
|
||||
links[url] = x;
|
||||
}
|
||||
links[url] = x;
|
||||
|
||||
if (url) {
|
||||
if (!obj[url]) {
|
||||
|
122
lib/lang.js
122
lib/lang.js
@ -35,86 +35,54 @@ import {
|
||||
zhTW,
|
||||
ca,
|
||||
hu,
|
||||
vi,
|
||||
} from 'date-fns/locale';
|
||||
|
||||
export const languages = {
|
||||
'ar-SA': { label: 'العربية', display: 'ar' },
|
||||
'zh-CN': { label: '中文', display: 'cn' },
|
||||
'zh-TW': { label: '中文(繁體)', display: 'tw' },
|
||||
'ca-ES': { label: 'Català', display: 'ca' },
|
||||
'cs-CZ': { label: 'Čeština', display: 'cs' },
|
||||
'da-DK': { label: 'Dansk', display: 'da' },
|
||||
'de-DE': { label: 'Deutsch', display: 'de' },
|
||||
'en-US': { label: 'English (US)', display: 'en' },
|
||||
'en-GB': { label: 'English (UK)', display: 'en-GB'},
|
||||
'es-MX': { label: 'Español', display: 'es' },
|
||||
'fa-IR': { label: 'فارسی', display: 'fa' },
|
||||
'fo-FO': { label: 'Føroyskt', display: 'fo' },
|
||||
'fr-FR': { label: 'Français', display: 'fr' },
|
||||
'el-GR': { label: 'Ελληνικά', display: 'el' },
|
||||
'he-IL': { label: 'עברית', display: 'he' },
|
||||
'hi-IN': { label: 'हिन्दी', display: 'hi' },
|
||||
'hu-HU': { label: 'Hungarian', display: 'hu' },
|
||||
'it-IT': { label: 'Italiano', display: 'it' },
|
||||
'id-ID': { label: 'Bahasa Indonesia', display: 'id' },
|
||||
'ja-JP': { label: '日本語', display: 'ja' },
|
||||
'ko-KR': { label: '한국어', display: 'ko' },
|
||||
'ms-MY': { label: 'Malay', display: 'ms' },
|
||||
'mn-MN': { label: 'Монгол', display: 'mn' },
|
||||
'nl-NL': { label: 'Nederlands', display: 'nl' },
|
||||
'nb-NO': { label: 'Norsk Bokmål', display: 'nb' },
|
||||
'pl-PL': { label: 'Polski', display: 'pl' },
|
||||
'pt-PT': { label: 'Português', display: 'pt' },
|
||||
'pt-BR': { label: 'Português do Brasil', display: 'pt-BR' },
|
||||
'ru-RU': { label: 'Русский', display: 'ru' },
|
||||
'ro-RO': { label: 'Română', display: 'ro' },
|
||||
'sk-SK': { label: 'Slovenčina', display: 'sk' },
|
||||
'sl-SI': { label: 'Slovenščina', display: 'sl' },
|
||||
'fi-FI': { label: 'Suomi', display: 'fi' },
|
||||
'sv-SE': { label: 'Svenska', display: 'sv' },
|
||||
'ta-IN': { label: 'தமிழ்', display: 'ta' },
|
||||
'tr-TR': { label: 'Türkçe', display: 'tr' },
|
||||
'uk-UA': { label: 'українська', display: 'uk' },
|
||||
'ar-SA': { label: 'العربية', dateLocale: arSA, dir: 'rtl' },
|
||||
'zh-CN': { label: '中文', dateLocale: zhCN },
|
||||
'zh-TW': { label: '中文(繁體)', dateLocale: zhTW },
|
||||
'ca-ES': { label: 'Català', dateLocale: ca },
|
||||
'cs-CZ': { label: 'Čeština', dateLocale: cs },
|
||||
'da-DK': { label: 'Dansk', dateLocale: da },
|
||||
'de-DE': { label: 'Deutsch', dateLocale: de },
|
||||
'en-US': { label: 'English (US)', dateLocale: enUS },
|
||||
'en-GB': { label: 'English (UK)', dateLocale: enGB },
|
||||
'es-MX': { label: 'Español', dateLocale: es },
|
||||
'fa-IR': { label: 'فارسی', dateLocale: faIR, dir: 'rtl' },
|
||||
'fo-FO': { label: 'Føroyskt' },
|
||||
'fr-FR': { label: 'Français', dateLocale: fr },
|
||||
'el-GR': { label: 'Ελληνικά', dateLocale: el },
|
||||
'he-IL': { label: 'עברית', dateLocale: he },
|
||||
'hi-IN': { label: 'हिन्दी', dateLocale: hi },
|
||||
'hu-HU': { label: 'Hungarian', dateLocale: hu },
|
||||
'it-IT': { label: 'Italiano', dateLocale: it },
|
||||
'id-ID': { label: 'Bahasa Indonesia', dateLocale: id },
|
||||
'ja-JP': { label: '日本語', dateLocale: ja },
|
||||
'ko-KR': { label: '한국어', dateLocale: ko },
|
||||
'ms-MY': { label: 'Malay', dateLocale: ms },
|
||||
'mn-MN': { label: 'Монгол', dateLocale: mn },
|
||||
'nl-NL': { label: 'Nederlands', dateLocale: nl },
|
||||
'nb-NO': { label: 'Norsk Bokmål', dateLocale: nb },
|
||||
'pl-PL': { label: 'Polski', dateLocale: pl },
|
||||
'pt-PT': { label: 'Português', dateLocale: pt },
|
||||
'pt-BR': { label: 'Português do Brasil', dateLocale: ptBR },
|
||||
'ru-RU': { label: 'Русский', dateLocale: ru },
|
||||
'ro-RO': { label: 'Română', dateLocale: ro },
|
||||
'sk-SK': { label: 'Slovenčina', dateLocale: sk },
|
||||
'sl-SI': { label: 'Slovenščina', dateLocale: sl },
|
||||
'fi-FI': { label: 'Suomi', dateLocale: fi },
|
||||
'sv-SE': { label: 'Svenska', dateLocale: sv },
|
||||
'ta-IN': { label: 'தமிழ்', dateLocale: ta },
|
||||
'tr-TR': { label: 'Türkçe', dateLocale: tr },
|
||||
'uk-UA': { label: 'українська', dateLocale: uk },
|
||||
'vi-VN': { label: 'Tiếng Việt', dateLocale: vi },
|
||||
};
|
||||
|
||||
export const rtlLocales = ['ar-SA', 'fa-IR'];
|
||||
export function getDateLocale(locale) {
|
||||
return languages[locale]?.dateLocale || enUS;
|
||||
}
|
||||
|
||||
export const dateLocales = {
|
||||
'ar-SA': arSA,
|
||||
'en-US': enUS,
|
||||
'en-GB': enGB,
|
||||
'nl-NL': nl,
|
||||
'zh-CN': zhCN,
|
||||
'zh-TW': zhTW,
|
||||
'de-DE': de,
|
||||
'da-DK': da,
|
||||
'ru-RU': ru,
|
||||
'sv-SE': sv,
|
||||
'tr-TR': tr,
|
||||
'ja-JP': ja,
|
||||
'es-MX': es,
|
||||
'fr-FR': fr,
|
||||
'mn-MN': mn,
|
||||
'el-GR': el,
|
||||
'fo-FO': da,
|
||||
'pt-PT': pt,
|
||||
'pt-BR': ptBR,
|
||||
'ro-RO': ro,
|
||||
'nb-NO': nb,
|
||||
'id-ID': id,
|
||||
'uk-UA': uk,
|
||||
'fi-FI': fi,
|
||||
'cs-CZ': cs,
|
||||
'sk-SK': sk,
|
||||
'pl-PL': pl,
|
||||
'ta-In': ta,
|
||||
'hi-IN': hi,
|
||||
'he-IL': he,
|
||||
'it-IT': it,
|
||||
'fa-IR': faIR,
|
||||
'ms-MY': ms,
|
||||
'ca-ES': ca,
|
||||
'hu-HU': hu,
|
||||
'ko-KR': ko,
|
||||
'sl-SI': sl,
|
||||
};
|
||||
export function getTextDirection(locale) {
|
||||
return languages[locale]?.dir || 'ltr';
|
||||
}
|
||||
|
@ -318,14 +318,20 @@ export async function getEvents(websites, start_at) {
|
||||
|
||||
export function getWebsiteStats(website_id, start_at, end_at, filters = {}) {
|
||||
const params = [website_id, start_at, end_at];
|
||||
const { url } = filters;
|
||||
const { url, ref } = filters;
|
||||
let urlFilter = '';
|
||||
let refFilter = '';
|
||||
|
||||
if (url) {
|
||||
urlFilter = `and url=$${params.length + 1}`;
|
||||
params.push(decodeURIComponent(url));
|
||||
}
|
||||
|
||||
if (ref) {
|
||||
refFilter = `and referrer like $${params.length + 1}`;
|
||||
params.push(`%${decodeURIComponent(ref)}%`);
|
||||
}
|
||||
|
||||
return rawQuery(
|
||||
`
|
||||
select sum(t.c) as "pageviews",
|
||||
@ -341,6 +347,7 @@ export function getWebsiteStats(website_id, start_at, end_at, filters = {}) {
|
||||
where website_id=$1
|
||||
and created_at between $2 and $3
|
||||
${urlFilter}
|
||||
${refFilter}
|
||||
group by 1, 2
|
||||
) t
|
||||
`,
|
||||
@ -355,16 +362,24 @@ export function getPageviewStats(
|
||||
timezone = 'utc',
|
||||
unit = 'day',
|
||||
count = '*',
|
||||
url,
|
||||
filters = {},
|
||||
) {
|
||||
const params = [website_id, start_at, end_at];
|
||||
const { url, ref } = filters;
|
||||
|
||||
let urlFilter = '';
|
||||
let refFilter = '';
|
||||
|
||||
if (url) {
|
||||
urlFilter = `and url=$${params.length + 1}`;
|
||||
params.push(decodeURIComponent(url));
|
||||
}
|
||||
|
||||
if (ref) {
|
||||
refFilter = `and referrer like $${params.length + 1}`;
|
||||
params.push(`%${decodeURIComponent(ref)}%`);
|
||||
}
|
||||
|
||||
return rawQuery(
|
||||
`
|
||||
select ${getDateQuery('created_at', unit, timezone)} t,
|
||||
@ -373,6 +388,7 @@ export function getPageviewStats(
|
||||
where website_id=$1
|
||||
and created_at between $2 and $3
|
||||
${urlFilter}
|
||||
${refFilter}
|
||||
group by 1
|
||||
order by 1
|
||||
`,
|
||||
@ -411,7 +427,7 @@ export function getSessionMetrics(website_id, start_at, end_at, field, filters =
|
||||
|
||||
export function getPageviewMetrics(website_id, start_at, end_at, field, table, filters = {}) {
|
||||
const params = [website_id, start_at, end_at];
|
||||
const { domain, url } = filters;
|
||||
const { domain, url, ref } = filters;
|
||||
|
||||
let domainFilter = '';
|
||||
let urlFilter = '';
|
||||
|
@ -15,8 +15,12 @@ import {
|
||||
let lookup;
|
||||
|
||||
export function getIpAddress(req) {
|
||||
// Custom header
|
||||
if (req.headers[process.env.CLIENT_IP_HEADER]) {
|
||||
return req.headers[process.env.CLIENT_IP_HEADER];
|
||||
}
|
||||
// Cloudflare
|
||||
if (req.headers['cf-connecting-ip']) {
|
||||
else if (req.headers['cf-connecting-ip']) {
|
||||
return req.headers['cf-connecting-ip'];
|
||||
}
|
||||
|
||||
|
@ -32,3 +32,12 @@ export function getQueryString(params = {}) {
|
||||
export function makeUrl(url, params) {
|
||||
return `${url}${getQueryString(params)}`;
|
||||
}
|
||||
|
||||
export function safeDecodeURI(s) {
|
||||
try {
|
||||
return decodeURI(s);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
@ -44,17 +44,14 @@ export const hook = (_this, method, callback) => {
|
||||
export const doNotTrack = () => {
|
||||
const { doNotTrack, navigator, external } = window;
|
||||
|
||||
const msTrackProtection = 'msTrackingProtectionEnabled';
|
||||
const msTracking = () => {
|
||||
return (
|
||||
external &&
|
||||
typeof external.msTrackingProtectionEnabled === 'function' &&
|
||||
external.msTrackingProtectionEnabled()
|
||||
);
|
||||
return external && msTrackProtection in external && external[msTrackProtection]();
|
||||
};
|
||||
|
||||
const dnt = doNotTrack || navigator.doNotTrack || navigator.msDoNotTrack || msTracking();
|
||||
|
||||
return dnt === true || dnt === 1 || dnt === 'yes' || dnt === '1';
|
||||
return dnt == '1' || dnt === 'yes';
|
||||
};
|
||||
|
||||
export const setItem = (key, data, session) => {
|
||||
|
29
package.json
29
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "umami",
|
||||
"version": "1.23.0",
|
||||
"version": "1.24.0",
|
||||
"description": "A simple, fast, website analytics alternative to Google Analytics. ",
|
||||
"author": "Mike Cao <mike@mikecao.com>",
|
||||
"license": "MIT",
|
||||
@ -27,7 +27,7 @@
|
||||
"build-postgresql-client": "dotenv prisma generate -- --schema=./prisma/schema.postgresql.prisma",
|
||||
"copy-db-schema": "node scripts/copy-db-schema.js",
|
||||
"generate-lang": "npm-run-all extract-lang merge-lang",
|
||||
"extract-lang": "formatjs extract '{pages,components}/**/*.js' --out-file build/messages.json",
|
||||
"extract-lang": "formatjs extract \"{pages,components}/**/*.js\" --out-file build/messages.json",
|
||||
"merge-lang": "node scripts/merge-lang.js",
|
||||
"format-lang": "node scripts/format-lang.js",
|
||||
"compile-lang": "formatjs compile-folder --ast build public/lang",
|
||||
@ -57,9 +57,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/inter": "4.5.0",
|
||||
"@fontsource/noto-sans-jp": "4.5.0",
|
||||
"@fontsource/noto-sans-sc": "4.5.0",
|
||||
"@fontsource/noto-sans-tc": "4.5.0",
|
||||
"@prisma/client": "2.29.1",
|
||||
"@reduxjs/toolkit": "^1.6.1",
|
||||
"bcryptjs": "^2.4.3",
|
||||
@ -71,7 +68,7 @@
|
||||
"date-fns": "^2.23.0",
|
||||
"date-fns-tz": "^1.1.4",
|
||||
"detect-browser": "^5.2.0",
|
||||
"dotenv": "^8.2.0",
|
||||
"dotenv": "^10.0.0",
|
||||
"formik": "^2.2.9",
|
||||
"immer": "^9.0.6",
|
||||
"ipaddr.js": "^2.0.1",
|
||||
@ -80,8 +77,8 @@
|
||||
"jose": "2.0.5",
|
||||
"maxmind": "^4.3.2",
|
||||
"moment-timezone": "^0.5.33",
|
||||
"next": "10.2.2",
|
||||
"prompts": "2.4.1",
|
||||
"next": "12.0.1",
|
||||
"prompts": "2.4.2",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
@ -110,31 +107,31 @@
|
||||
"cross-env": "^7.0.3",
|
||||
"del": "^6.0.0",
|
||||
"dotenv-cli": "^4.0.0",
|
||||
"eslint": "^7.31.0",
|
||||
"eslint-config-next": "^11.0.1",
|
||||
"eslint": "^8.1.0",
|
||||
"eslint-config-next": "^12.0.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.24.0",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"extract-react-intl-messages": "^4.1.1",
|
||||
"husky": "^4.3.8",
|
||||
"husky": "^7.0.4",
|
||||
"lint-staged": "^11.0.0",
|
||||
"loadtest": "5.1.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.2.15",
|
||||
"postcss-flexbugs-fixes": "^5.0.2",
|
||||
"postcss-import": "^13.0.0",
|
||||
"postcss-import": "^14.0.2",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"postcss-rtlcss": "^3.3.2",
|
||||
"prettier": "^2.3.2",
|
||||
"prettier-eslint": "^12.0.0",
|
||||
"prettier-eslint": "^13.0.0",
|
||||
"prisma": "2.29.1",
|
||||
"rollup": "^2.48.0",
|
||||
"rollup-plugin-hashbang": "^2.2.2",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"stylelint": "^13.13.1",
|
||||
"stylelint": "^14.0.1",
|
||||
"stylelint-config-css-modules": "^2.2.0",
|
||||
"stylelint-config-prettier": "^8.0.1",
|
||||
"stylelint-config-prettier": "^9.0.3",
|
||||
"stylelint-config-recommended": "^5.0.0",
|
||||
"tar": "^6.1.2"
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ export default function App({ Component, pageProps }) {
|
||||
<link rel="manifest" href={`${basePath}/site.webmanifest`} />
|
||||
<link rel="mask-icon" href={`${basePath}/safari-pinned-tab.svg`} color="#5bbad5" />
|
||||
<meta name="msapplication-TileColor" content="#da532c" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta name="theme-color" content="#fafafa" media="(prefers-color-scheme: light)" />
|
||||
<meta name="theme-color" content="#2f2f2f" media="(prefers-color-scheme: dark)" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</Head>
|
||||
<Intl>
|
||||
|
@ -11,7 +11,7 @@ export default async (req, res) => {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
const { id, start_at, end_at, unit, tz, url } = req.query;
|
||||
const { id, start_at, end_at, unit, tz, url, ref } = req.query;
|
||||
|
||||
const websiteId = +id;
|
||||
const startDate = new Date(+start_at);
|
||||
@ -22,8 +22,11 @@ export default async (req, res) => {
|
||||
}
|
||||
|
||||
const [pageviews, sessions] = await Promise.all([
|
||||
getPageviewStats(websiteId, startDate, endDate, tz, unit, '*', url),
|
||||
getPageviewStats(websiteId, startDate, endDate, tz, unit, 'distinct session_id', url),
|
||||
getPageviewStats(websiteId, startDate, endDate, tz, unit, '*', { url, ref }),
|
||||
getPageviewStats(websiteId, startDate, endDate, tz, unit, 'distinct session_id', {
|
||||
url,
|
||||
ref,
|
||||
}),
|
||||
]);
|
||||
|
||||
return ok(res, { pageviews, sessions });
|
||||
|
@ -8,7 +8,7 @@ export default async (req, res) => {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
const { id, start_at, end_at, url } = req.query;
|
||||
const { id, start_at, end_at, url, ref } = req.query;
|
||||
|
||||
const websiteId = +id;
|
||||
const startDate = new Date(+start_at);
|
||||
@ -18,8 +18,8 @@ export default async (req, res) => {
|
||||
const prevStartDate = new Date(+start_at - distance);
|
||||
const prevEndDate = new Date(+end_at - distance);
|
||||
|
||||
const metrics = await getWebsiteStats(websiteId, startDate, endDate, { url });
|
||||
const prevPeriod = await getWebsiteStats(websiteId, prevStartDate, prevEndDate, { url });
|
||||
const metrics = await getWebsiteStats(websiteId, startDate, endDate, { url, ref });
|
||||
const prevPeriod = await getWebsiteStats(websiteId, prevStartDate, prevEndDate, { url, ref });
|
||||
|
||||
const stats = Object.keys(metrics[0]).reduce((obj, key) => {
|
||||
obj[key] = {
|
||||
|
1
public/country/vi-VN.json
Normal file
1
public/country/vi-VN.json
Normal file
File diff suppressed because one or more lines are too long
@ -1,6 +1,8 @@
|
||||
html,
|
||||
body {
|
||||
font-family: Inter, -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
font-family: Inter, -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans,
|
||||
Ubuntu, Cantrell, 'Helvetica Neue', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
||||
'Segoe UI Symbol';
|
||||
font-weight: 400;
|
||||
line-height: 1.8;
|
||||
padding: 0;
|
||||
@ -21,15 +23,33 @@ body {
|
||||
}
|
||||
|
||||
.zh-CN {
|
||||
font-family: 'Noto Sans SC', sans-serif !important;
|
||||
font-family: '方体', 'PingFang SC', '黑体', 'Heiti SC', 'Microsoft JhengHei UI',
|
||||
'Microsoft JhengHei', Roboto, Noto, 'Noto Sans CJK SC', sans-serif !important;
|
||||
}
|
||||
|
||||
.zh-TW {
|
||||
font-family: 'Noto Sans TC', sans-serif !important;
|
||||
font-family: '方體', 'PingFang TC', '黑體', 'Heiti TC', 'Microsoft JhengHei UI',
|
||||
'Microsoft JhengHei', Roboto, Noto, 'Noto Sans CJK TC', sans-serif !important;
|
||||
}
|
||||
|
||||
.ja-JP {
|
||||
font-family: 'Noto Sans JP', sans-serif !important;
|
||||
font-family: '游ゴシック体', YuGothic, 'ヒラギノ丸ゴ', 'Hiragino Sans', 'Yu Gothic UI',
|
||||
'Meiryo UI', 'MS Gothic', Roboto, Noto, 'Noto Sans CJK JP', sans-serif !important;
|
||||
}
|
||||
|
||||
.ko-KR {
|
||||
font-family: 'Nanum Gothic', 'Apple SD Gothic Neo', 'Malgun Gothic', Roboto, Noto,
|
||||
'Noto Sans CJK KR', sans-serif !important;
|
||||
}
|
||||
|
||||
.ar-SA {
|
||||
font-family: 'Geeza Pro', 'Arabic Typesetting', Roboto, Noto, 'Noto Naskh Arabic',
|
||||
'Times New Roman', serif !important;
|
||||
}
|
||||
|
||||
.he-IL {
|
||||
font-family: 'New Peninim MT', 'Arial Hebrew', Gisha, 'Times New Roman', Roboto, Noto,
|
||||
'Noto Sans Hebrew', sans-serif !important;
|
||||
}
|
||||
|
||||
.he-IL {
|
||||
|
105
tracker/index.js
105
tracker/index.js
@ -16,28 +16,29 @@ import { removeTrailingSlash } from '../lib/url';
|
||||
|
||||
if (!script) return;
|
||||
|
||||
const attr = key => script && script.getAttribute(key);
|
||||
const attr = script.getAttribute.bind(script);
|
||||
const website = attr('data-website-id');
|
||||
const hostUrl = attr('data-host-url');
|
||||
const autoTrack = attr('data-auto-track') !== 'false';
|
||||
const dnt = attr('data-do-not-track');
|
||||
const useCache = attr('data-cache');
|
||||
const domains = attr('data-domains');
|
||||
const domain = attr('data-domains') || '';
|
||||
const domains = domain.split(',').map(n => n.trim());
|
||||
|
||||
const disableTracking =
|
||||
localStorage.getItem('umami.disabled') ||
|
||||
const eventClass = /^umami--([a-z]+)--([\w]+[\w-]*)$/;
|
||||
const eventSelect = "[class*='umami--']";
|
||||
const cacheKey = 'umami.cache';
|
||||
|
||||
const disableTracking = () =>
|
||||
(localStorage && localStorage.getItem('umami.disabled')) ||
|
||||
(dnt && doNotTrack()) ||
|
||||
(domains &&
|
||||
!domains
|
||||
.split(',')
|
||||
.map(n => n.trim())
|
||||
.includes(hostname));
|
||||
(domain && !domains.includes(hostname));
|
||||
|
||||
const root = hostUrl
|
||||
? removeTrailingSlash(hostUrl)
|
||||
: script.src.split('/').slice(0, -1).join('/');
|
||||
const screen = `${width}x${height}`;
|
||||
const listeners = [];
|
||||
const listeners = {};
|
||||
let currentUrl = `${pathname}${search}`;
|
||||
let currentRef = document.referrer;
|
||||
|
||||
@ -50,7 +51,7 @@ import { removeTrailingSlash } from '../lib/url';
|
||||
|
||||
req.onreadystatechange = () => {
|
||||
if (req.readyState === 4) {
|
||||
callback && callback(req.response);
|
||||
callback(req.response);
|
||||
}
|
||||
};
|
||||
|
||||
@ -58,23 +59,19 @@ import { removeTrailingSlash } from '../lib/url';
|
||||
};
|
||||
|
||||
const collect = (type, params, uuid) => {
|
||||
if (disableTracking) return;
|
||||
|
||||
const key = 'umami.cache';
|
||||
if (disableTracking()) return;
|
||||
|
||||
const payload = {
|
||||
website: uuid,
|
||||
hostname,
|
||||
screen,
|
||||
language,
|
||||
cache: useCache && sessionStorage.getItem(key),
|
||||
cache: useCache && sessionStorage.getItem(cacheKey),
|
||||
};
|
||||
|
||||
if (params) {
|
||||
Object.keys(params).forEach(key => {
|
||||
payload[key] = params[key];
|
||||
});
|
||||
}
|
||||
Object.keys(params).forEach(key => {
|
||||
payload[key] = params[key];
|
||||
});
|
||||
|
||||
post(
|
||||
`${root}/api/collect`,
|
||||
@ -82,11 +79,11 @@ import { removeTrailingSlash } from '../lib/url';
|
||||
type,
|
||||
payload,
|
||||
},
|
||||
res => useCache && sessionStorage.setItem(key, res),
|
||||
res => useCache && sessionStorage.setItem(cacheKey, res),
|
||||
);
|
||||
};
|
||||
|
||||
const trackView = (url = currentUrl, referrer = currentRef, uuid = website) =>
|
||||
const trackView = (url = currentUrl, referrer = currentRef, uuid = website) => {
|
||||
collect(
|
||||
'pageview',
|
||||
{
|
||||
@ -95,8 +92,9 @@ import { removeTrailingSlash } from '../lib/url';
|
||||
},
|
||||
uuid,
|
||||
);
|
||||
};
|
||||
|
||||
const trackEvent = (event_value, event_type = 'custom', url = currentUrl, uuid = website) =>
|
||||
const trackEvent = (event_value, event_type = 'custom', url = currentUrl, uuid = website) => {
|
||||
collect(
|
||||
'event',
|
||||
{
|
||||
@ -106,28 +104,29 @@ import { removeTrailingSlash } from '../lib/url';
|
||||
},
|
||||
uuid,
|
||||
);
|
||||
};
|
||||
|
||||
/* Handle events */
|
||||
|
||||
const addEvents = () => {
|
||||
document.querySelectorAll("[class*='umami--']").forEach(element => {
|
||||
element.className.split(' ').forEach(className => {
|
||||
if (/^umami--([a-z]+)--([\w]+[\w-]*)$/.test(className)) {
|
||||
const [, type, value] = className.split('--');
|
||||
const listener = () => trackEvent(value, type);
|
||||
const addEvent = element => {
|
||||
element.className.split(' ').forEach(className => {
|
||||
if (!eventClass.test(className)) return;
|
||||
|
||||
listeners.push([element, type, listener]);
|
||||
element.addEventListener(type, listener, true);
|
||||
}
|
||||
});
|
||||
const [, type, value] = className.split('--');
|
||||
const listener = listeners[className]
|
||||
? listeners[className]
|
||||
: (listeners[className] = () => trackEvent(value, type));
|
||||
|
||||
element.addEventListener(type, listener, true);
|
||||
});
|
||||
};
|
||||
|
||||
const removeEvents = () => {
|
||||
listeners.forEach(([element, type, listener]) => {
|
||||
element && element.removeEventListener(type, listener, true);
|
||||
const monitorMutate = mutations => {
|
||||
mutations.forEach(mutation => {
|
||||
const element = mutation.target;
|
||||
addEvent(element);
|
||||
element.querySelectorAll(eventSelect).forEach(addEvent);
|
||||
});
|
||||
listeners.length = 0;
|
||||
};
|
||||
|
||||
/* Handle history changes */
|
||||
@ -135,8 +134,6 @@ import { removeTrailingSlash } from '../lib/url';
|
||||
const handlePush = (state, title, url) => {
|
||||
if (!url) return;
|
||||
|
||||
removeEvents();
|
||||
|
||||
currentRef = currentUrl;
|
||||
const newUrl = url.toString();
|
||||
|
||||
@ -147,32 +144,42 @@ import { removeTrailingSlash } from '../lib/url';
|
||||
}
|
||||
|
||||
if (currentUrl !== currentRef) {
|
||||
trackView(currentUrl, currentRef);
|
||||
trackView();
|
||||
}
|
||||
|
||||
setTimeout(addEvents, 300);
|
||||
};
|
||||
|
||||
/* Global */
|
||||
|
||||
if (!window.umami) {
|
||||
const umami = event_value => trackEvent(event_value);
|
||||
const umami = eventValue => trackEvent(eventValue);
|
||||
umami.trackView = trackView;
|
||||
umami.trackEvent = trackEvent;
|
||||
umami.addEvents = addEvents;
|
||||
umami.removeEvents = removeEvents;
|
||||
|
||||
window.umami = umami;
|
||||
}
|
||||
|
||||
/* Start */
|
||||
|
||||
if (autoTrack && !disableTracking) {
|
||||
if (autoTrack && !disableTracking()) {
|
||||
history.pushState = hook(history, 'pushState', handlePush);
|
||||
history.replaceState = hook(history, 'replaceState', handlePush);
|
||||
|
||||
trackView(currentUrl, currentRef);
|
||||
|
||||
addEvents();
|
||||
const update = () => {
|
||||
switch (document.readyState) {
|
||||
/* DOM rendered, add event listeners */
|
||||
case 'interactive': {
|
||||
document.querySelectorAll(eventSelect).forEach(addEvent);
|
||||
const observer = new MutationObserver(monitorMutate);
|
||||
observer.observe(document, { childList: true, subtree: true });
|
||||
break;
|
||||
}
|
||||
/* Page loaded, track our view */
|
||||
case 'complete':
|
||||
trackView();
|
||||
break;
|
||||
}
|
||||
};
|
||||
document.addEventListener('readystatechange', update, true);
|
||||
update();
|
||||
}
|
||||
})(window);
|
||||
|
Loading…
Reference in New Issue
Block a user