Compare commits

...

883 commits

Author SHA1 Message Date
Mike Cao
81e27fc18c
Fix formatting for Docker compose instructions
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-12-04 00:37:13 -08:00
Mike Cao
2b771ff2b4
Merge pull request #3832 from umami-software/dev
v3.0.2
2025-12-03 23:54:31 -08:00
Mike Cao
60271779de Fixed Docker build.
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-12-03 23:53:22 -08:00
Mike Cao
33e927ed1f Bump version 3.0.2.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-12-03 23:01:22 -08:00
Mike Cao
7e42b5b35e
Merge pull request #3827 from umami-software/dependabot/npm_and_yarn/next-15.5.7
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Bump next from 15.5.3 to 15.5.7
2025-12-03 21:27:43 -08:00
Mike Cao
2993db14f0 Updated README. 2025-12-03 19:37:51 -08:00
Mike Cao
1483241494 Merge branch 'dev' of https://github.com/umami-software/umami into dev
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-12-03 18:39:45 -08:00
Mike Cao
c427c6f547 Fixed replica logic. 2025-12-03 17:05:14 -08:00
Mike Cao
33cb195fd0 Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
# Conflicts:
#	package.json
#	pnpm-lock.yaml
#	src/app/(main)/links/[linkId]/LinkHeader.tsx
#	src/app/(main)/pixels/[pixelId]/PixelHeader.tsx
2025-12-03 15:13:50 -08:00
Mike Cao
64767b1896 Updated next. Fixed link RSC fetch. 2025-12-03 15:11:40 -08:00
Francis Cao
be1b787789 Merge branch 'dependabot/npm_and_yarn/next-15.5.7' of https://github.com/umami-software/umami into dev 2025-12-03 15:00:47 -08:00
Francis Cao
dae7327ed3 Fix date range increment function
Closes #3828
2025-12-03 14:47:56 -08:00
dependabot[bot]
a06490af74
Bump next from 15.5.3 to 15.5.7
Bumps [next](https://github.com/vercel/next.js) from 15.5.3 to 15.5.7.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.5.3...v15.5.7)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 15.5.7
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-03 19:53:10 +00:00
Francis Cao
65f657dd23 Revert "prisma schema boards + varchar length increase"
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
This reverts commit cb034a1371.
2025-12-03 11:08:54 -08:00
Francis Cao
6b584338e3 fix PageHeader type errors 2025-12-03 11:06:03 -08:00
Mike Cao
41d2a24f9d Merge branch 'master' into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
# Conflicts:
#	src/components/common/PageHeader.tsx
#	src/components/metrics/ActiveUsers.tsx
2025-12-03 00:17:44 -08:00
Mike Cao
1ae13513d2 Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-12-03 00:16:22 -08:00
Mike Cao
9a269ab811
Merge pull request #3805 from prince0xdev/feat/mobile-navigation-improvement
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Improve mobile navigation: clickable “online” badge & page title
2025-12-03 00:16:16 -08:00
Mike Cao
32aee652a5
Merge pull request #3824 from IndraGunawan/disable-prefetch-view-link
fix: disable prefetch for Links view button
2025-12-03 00:14:11 -08:00
Mike Cao
16cae691f6 Don't prefetch links/pixels. Closes #3814 2025-12-03 00:03:56 -08:00
Mike Cao
1390e09400 Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-12-03 00:01:36 -08:00
Mike Cao
23ff20a10b
Merge pull request #3809 from RaenonX/master
Allow `browser` / `os` / `device` override in `payload` & return `cache` from `/api/batch`
2025-12-03 00:01:30 -08:00
Mike Cao
58acee8d25 Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-12-02 23:32:53 -08:00
Mike Cao
a0940d78a7 Updated packages. 2025-12-02 23:32:44 -08:00
Indra Gunawan
89b985652a fix: disable prefetch for Links view button 2025-12-03 15:31:54 +08:00
Mike Cao
7b3be59c8d
Merge pull request #3819 from Lokimorty/seed-sample-data
feat(dev): add sample data generator script
2025-12-02 23:30:55 -08:00
Mike Cao
b08413ebea
Merge branch 'dev' into seed-sample-data 2025-12-02 23:30:47 -08:00
Francis Cao
f47e1072d9 remove locale code from SharePage
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-12-02 16:10:11 -08:00
Francis Cao
22f1b7d7c9 add theme and locale url parameter options to share page
Closes #3754
2025-12-02 15:57:45 -08:00
Francis Cao
b0f38b266b truncate large legend labels
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Closes #3813
2025-12-02 14:44:10 -08:00
Mike Cao
e7cb613cec Merge remote-tracking branch 'origin/dev' into dev 2025-12-02 13:47:01 -08:00
Mike Cao
170821e2f9 Populate teams on login.
Closes #3796
2025-12-02 13:45:49 -08:00
Francis Cao
935517ce3a add cascading deletes to revenue/segment table
Closes #3798
2025-12-02 09:41:46 -08:00
Arthur Sepiol
c481bc5dcc chore: exclude seed scripts from Docker builds 2025-12-02 20:25:25 +03:00
Arthur Sepiol
b7807ed466 feat(dev): add sample data generator script
Adds a CLI tool to generate realistic analytics data for local development and testing.
Creates two demo websites with varying traffic patterns and realistic user behavior distributions.
2025-12-02 13:43:59 +03:00
Mike Cao
f5896f071b Handle user account redirect.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-12-01 23:33:57 -08:00
Mike Cao
06251e1317
Merge pull request #3803 from imsyedabdullah/3802-team-to-user-switch
Issue#3802 - Team to user switch fixed
2025-12-01 23:15:00 -08:00
Mike Cao
9a2827b50d
Merge pull request #3811 from IndraGunawan/support-uuidv7
add support for UUID v7
2025-12-01 23:11:23 -08:00
Mike Cao
b0c1f9041d
Merge pull request #3760 from umami-software/dependabot/npm_and_yarn/js-yaml-3.14.2
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Bump js-yaml from 3.14.1 to 3.14.2
2025-12-01 15:25:48 -08:00
Francis Cao
cb034a1371 prisma schema boards + varchar length increase
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-12-01 11:34:43 -08:00
Mike Cao
4b954fbc7c
Merge pull request #3806 from prince0xdev/feat/thumbnail-team-memory
Add favicon icons and auto-redirect to last selected team
2025-12-01 10:43:58 -08:00
Mike Cao
f5d6d0ebaf
Merge branch 'dev' into feat/thumbnail-team-memory 2025-12-01 10:43:48 -08:00
Mike Cao
3071ee8b88
Merge branch 'dev' into 3802-team-to-user-switch 2025-12-01 10:12:19 -08:00
Indra Gunawan
b16b98ffe8
Merge branch 'dev' into support-uuidv7 2025-12-01 17:02:26 +08:00
Indra Gunawan
4d70c3baf1 add support for UUID v7 2025-12-01 16:48:58 +08:00
RaenonX
c86ea1a74f
Updated /api/batch to return cache 2025-12-01 04:06:17 +08:00
RaenonX
805bc57bbb
Added browser / os / device override in payload 2025-12-01 04:06:17 +08:00
RaenonX
92a7355ce3
Fixed /api/batch request recreation failure 2025-12-01 04:06:10 +08:00
Mike Cao
875c03bca1
Merge pull request #3801 from Lokimorty/skip-realtime-anim
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
fix: skip realtime chart animation when data unchanged
2025-11-29 23:31:36 -08:00
Prince EKPINSE
e5a5aeecb5 feat(#3748): redirect user to last selected team on login 2025-11-29 16:54:45 +01:00
Prince EKPINSE
046cb6ef62 feat(#3748): restore favicon icons in websites list 2025-11-29 16:43:21 +01:00
Prince EKPINSE
beb2bc0a06 feat: improve mobile navigation with clickable page elements (#3770) 2025-11-29 13:53:32 +01:00
Prince EKPINSE
776e404c6f fix: [#3778] update 'Edit' word to support translation 2025-11-29 12:40:22 +01:00
Mike Cao
3379cc6e89 Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	pnpm-lock.yaml
2025-11-28 00:34:12 -08:00
Mike Cao
d7fd22645c Fixed nav menus. 2025-11-28 00:33:53 -08:00
Syed Abdullah
50bfee3328 Moved the redirect to else statement 2025-11-28 06:30:22 +00:00
Syed Abdullah
a645dc7ba5 Issue#3802 - Team to user switch fixed 2025-11-28 06:10:19 +00:00
Arthur Sepiol
f5b5f159ec fix: skip realtime chart animation when data unchanged 2025-11-28 02:17:16 +03:00
Francis Cao
3cc2c5b7a8 downgrade prisma until 3.1 release
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-26 11:09:21 -08:00
Francis Cao
5c9403f748 Merge branch 'analytics' of https://github.com/umami-software/umami into dev 2025-11-26 11:03:50 -08:00
Francis Cao
ac6ed9d762 add case-insensitivity to currency comparison
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-26 11:01:58 -08:00
Mike Cao
5ea2a8659c
Merge pull request #3755 from Maxime-J/docker-prisma-engine
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Permit Docker use in read-only mode and/or offline env.
2025-11-25 21:33:37 -08:00
Mike Cao
a19b92a5cb
Merge pull request #3756 from Abrar74774/master
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
docs: remove underlines between badges in README.md
2025-11-25 21:31:35 -08:00
Mike Cao
dcc1ae1864
Merge pull request #3787 from RaenonX/master
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Fixed `/api/batch` request recreation failure
2025-11-25 16:08:02 -08:00
Mike Cao
5a44e6deb2
Merge pull request #3791 from travzhang/master
fix: fix SQL syntax error in getPageviewExpandedMetrics query
2025-11-25 16:05:58 -08:00
Travis Zhang
67e1af7e55
fix: fix SQL syntax error in getPageviewExpandedMetrics query 2025-11-25 21:13:35 +08:00
RaenonX
2b34cbeb37
Fixed /api/batch request recreation failure 2025-11-24 08:07:31 +08:00
Mike Cao
0ddec97bf0 Merge remote-tracking branch 'origin/dev' into dev
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-22 22:43:39 -08:00
Mike Cao
fa8d8055df Reformatted files with biome. 2025-11-22 22:42:42 -08:00
Francis Cao
67981db524 Remove no longer applicable CloudFlare header test
Closes #3773
2025-11-22 22:28:24 -08:00
Francis Cao
099c8bf1b4 Revert "remove relationMode from schema file"
This reverts commit bc737268b6.
2025-11-22 22:24:52 -08:00
Mike Cao
d51f0641a6 Merge branch 'dev' of https://github.com/umami-software/umami into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
# Conflicts:
#	prisma/schema.prisma
2025-11-22 16:40:42 -08:00
Mike Cao
b9d52af215 Updated prisma. 2025-11-21 21:35:11 -08:00
Francis Cao
94321192b8 Allow view-only to still join team
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Closes #3764
2025-11-21 14:43:58 -08:00
Francis Cao
ffa97d34e2 Fix Revenue country sums error
Closes #3769
2025-11-21 14:34:12 -08:00
Francis Cao
bc737268b6 remove relationMode from schema file 2025-11-21 13:43:54 -08:00
Mike Cao
b45971da33 Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-20 20:56:29 -08:00
Mike Cao
15fda927ce Switched to biome. 2025-11-20 20:56:16 -08:00
Francis Cao
af958b6462 fix DateDistance null logic
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-20 11:24:59 -08:00
Mike Cao
aaa1f9dc58 Merge branch 'dev'
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-18 10:27:02 -08:00
Mike Cao
abc1b50ad0 Reordered IP headers.
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-18 10:25:08 -08:00
Mike Cao
24b017cad8
Merge pull request #3765 from umami-software/dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
v3.0.1
2025-11-17 22:39:48 -08:00
Mike Cao
ef3f7274e3 Remember last team.
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-17 19:12:25 -08:00
dependabot[bot]
e6586c60b1
Bump js-yaml from 3.14.1 to 3.14.2
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.14.1 to 3.14.2.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.14.1...3.14.2)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 3.14.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-17 18:44:11 +00:00
Abrar74774
d34ad1d07f docs: remove underlines between bandges in README.md 2025-11-15 23:34:26 +03:00
Maxime-J
46388f8b41 Include prisma engine in Docker image 2025-11-15 15:32:06 +01:00
Mike Cao
1852acc333 Merge remote-tracking branch 'origin/dev' into dev
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-14 15:46:59 -08:00
Mike Cao
cb63e49a9b Fixed triggered event lookup. Closes #3742. 2025-11-14 15:42:23 -08:00
Mike Cao
d382ad2975
Merge pull request #3682 from rkoh-rq/patch-1
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
fix: quote "event" reserved keyword in journey queries
2025-11-14 11:44:31 -08:00
Mike Cao
b1dc690e2f
Merge branch 'dev' into patch-1 2025-11-14 11:44:20 -08:00
Francis Cao
cc8254985b Increase resetWebsite timeout. fix retention bug returning decimal day_number in CH.
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
Closes #3698
2025-11-14 09:11:26 -08:00
Francis Cao
a3f32b036d revert getDateStringSQL for CH 2025-11-14 08:10:13 -08:00
Mike Cao
5ded9abbfe Added data-fetch-credentials attribute. Closes #3644
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-13 19:42:04 -08:00
Francis Cao
6751bf88bb fix chart and timezone issues, pass consistent dates to DB.
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
Closes #3700
2025-11-13 15:52:24 -08:00
Mike Cao
81bedec6d5
Merge pull request #3749 from Maxime-J/os-formatting
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Restore OS formatting in tables
2025-11-13 13:06:39 -08:00
Maxime-J
4531538ad3 Restore OS formatting in tables 2025-11-13 15:46:05 +01:00
Mike Cao
9fbcec46af
Merge pull request #3737 from prince0xdev/fix/login-autocomplete-username
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
fix: correct autocomplete attributes to enable password manager autofill
2025-11-12 21:38:12 -08:00
Mike Cao
d98cc35208
Merge pull request #3743 from Mintimate/master
feat(geo): add redirect support for direct .mmdb downloads
2025-11-12 21:33:19 -08:00
Mike Cao
97ebdc1bab Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-12 16:40:50 -08:00
Mike Cao
8a66603d32 Responsive fixes. 2025-11-12 16:39:58 -08:00
Mintimate
e13362bfec feat(geo): add redirect support for direct .mmdb downloads 2025-11-12 19:18:44 +08:00
Mintimate
371ff47325 feat(geo): add support for direct .mmdb URL and custom GEO_DATABASE_URL
- Support GEO_DATABASE_URL environment variable for custom database URL

- Auto-detect .mmdb files and skip decompression

- Maintain backward compatibility with tar.gz archives
2025-11-12 17:51:19 +08:00
Francis Cao
3aa09572f5 Merge branch 'master' of https://github.com/umami-software/umami into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-11 21:40:28 -08:00
Prince EKPINSE
a56746ce6d fix: enable password manager autofill on login form (#3735) 2025-11-12 00:15:05 +01:00
Prince EKPINSE
678a2ccdf3 fix: correct autocomplete attributes to enable password manager autofill 2025-11-12 00:08:36 +01:00
Francis Cao
bf498d9239 add RealtimeData to types
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-11 13:45:41 -08:00
Francis Cao
30781430c5 remove timezone from realtime. Closes #3700 2025-11-11 13:13:25 -08:00
Francis Cao
14f5babea7
Merge pull request #3731 from Maxime-J/unique-constraint
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Prevent duplicate key db errors on session creation
2025-11-11 11:13:14 -08:00
Maxime-J
14f3db550b Use raw query with on conflict in createSession 2025-11-11 10:32:31 +01:00
Mike Cao
3d8402d2f1 Merge branch 'master' into dev 2025-11-10 22:44:36 -08:00
Mike Cao
7ac5913c86
Merge pull request #3704 from prince0xdev/fix/disable-download-when-no-data
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
Fix: Disable download button when no data available
2025-11-10 22:43:42 -08:00
Mike Cao
a6e130ab2e
Fix DownloadButton to avoid duplicate downloadCsv call
Removed redundant downloadCsv call from handleClick.
2025-11-10 22:43:22 -08:00
Mike Cao
4fe4bb99b7
Apply suggestion from @greptile-apps[bot]
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-11-10 22:42:20 -08:00
Mike Cao
592f7c0ae7 Added check for REDIS_URL. Closes #3677.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-10 21:08:55 -08:00
Francis Cao
8787764e0e Merge branch 'analytics' of https://github.com/umami-software/umami into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-10 17:32:18 -08:00
Francis Cao
839bf3898f add canonicalizeTimezone conversions
Co-authored-by: Om Mishra <contact@om-mishra.com>
2025-11-10 17:27:45 -08:00
Francis Cao
13ab84d50e Revert "add canonicalizeTimezone conversions"
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
This reverts commit a1d6204373.
2025-11-10 17:26:06 -08:00
Francis Cao
a1d6204373 add canonicalizeTimezone conversions
Co-authored-by: Om Mishra <contact@om-mishra.com>
2025-11-10 17:24:51 -08:00
Francis Cao
49e1582c28 implement generateTimeSeries for eventsChart 2025-11-10 15:36:43 -08:00
Francis Cao
64a6379c3c fix realtime logs for mobile
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-10 01:07:11 -08:00
Francis Cao
f3e246c64b fix hasdata queries, add hasData to website events, fix sessionactivity truncation, 2025-11-09 23:58:20 -08:00
Francis Cao
9230f3cb7b manually include basePath 2025-11-09 22:03:06 -08:00
Francis Cao
f30724629c Fix null and string return types from getWebsiteStats 2025-11-09 21:37:35 -08:00
Francis Cao
c44f6f8c9c Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-11-09 21:19:46 -08:00
Francis Cao
bf548c5aca Fix revenue bigInt but and case insensitive currency 2025-11-09 21:19:38 -08:00
Prince EKPINSE
b9e90268d1 chore [#3699] : fix .gitignore syntax and untrack package-lock.json 2025-11-08 22:33:22 +01:00
Mike Cao
227201a73c
Merge pull request #3706 from metaloozee/3703
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
fix: Redirect loop on auth failure
2025-11-08 11:32:02 -08:00
Mike Cao
03c892aac0
Merge pull request #3688 from mathis5711/patch-docker-image-name
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
Fixing docker image name
2025-11-08 11:26:31 -08:00
metaloozee
1879c161ee fix: Redirect loop on auth failure 2025-11-09 00:22:06 +05:30
Prince EKPINSE
cf31ca20b9 Fix: disable download button when no data available 2025-11-08 18:22:38 +01:00
Prince EKPINSE
c3f3a7db3f Fix: disable download button when no data available 2025-11-08 18:17:22 +01:00
Mike Cao
6ba9c1c40c New docker workflow.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-07 22:41:10 -08:00
Mike Cao
de6515139e Fixed Docker permissions.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-07 18:17:51 -08:00
Mike Cao
e3ca002d77 Fixed tags in build. 2025-11-07 14:35:05 -08:00
Mike Cao
8119dae3c3 Updated GH workflow. 2025-11-07 13:59:50 -08:00
Mike Cao
6ee93f7ac9 Updated README and cd.yml. 2025-11-07 12:21:17 -08:00
Mike Cao
3e9ca8761e Removed workflow script.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-07 09:15:01 -08:00
Mike Cao
d2f512cae7 Don't publish .sig files. 2025-11-07 09:14:19 -08:00
Mike Cao
df3ca02e8b Always push latest for Docker. 2025-11-07 08:52:16 -08:00
mathis5711
e49624a6da
Apply suggestions from code review
Edit for better formatting warning message

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-11-07 10:14:55 +01:00
mathis5711
9ad17e0f62
Fix warning message for updating from Umami V2
Fixing markdown from last commit
2025-11-07 09:36:44 +01:00
mathis5711
6d16642a6c
Update README with deprecation notice for PostgreSQL image
Added warning about deprecation of 'postgresql-latest' image.
2025-11-07 09:36:14 +01:00
mathis5711
b200346fd3
Change Umami Docker image tag to 'latest'
Updated Docker pull command to use the latest image, because "postgresql-latest" is deprecated.
2025-11-07 09:31:30 +01:00
Mike Cao
a90b788138 Updated cd script.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-07 00:09:53 -08:00
Mike Cao
dd6556968c Updated image tag. 2025-11-06 23:58:12 -08:00
Mike Cao
04a05bbf26 Added workflow input. 2025-11-06 23:35:14 -08:00
Mike Cao
437c9603db Fixed build. 2025-11-06 22:58:26 -08:00
Mike Cao
03ed5349f4 Merge branch 'dev' 2025-11-06 22:50:30 -08:00
Mike Cao
4272bb4c4d Removed db types from docker build. 2025-11-06 22:48:34 -08:00
Mike Cao
6135ef9dd2 Fixed test. 2025-11-06 22:24:08 -08:00
Mike Cao
b5795a8b3f Fixed update notice.
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-06 16:16:53 -08:00
Mike Cao
98092004b6
Merge pull request #3683 from umami-software/dev
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
v3
2025-11-05 18:34:36 -08:00
Francis Cao
a6d4519a98 set maxHeight for DialogButton. remove from individual buttons
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-11-04 09:34:37 -08:00
Mike Cao
5398cd89fe Reordered IP headers.
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-03 21:01:12 -08:00
rkoh-rq
3cb7fa34b0
fix: quote "event" reserved keyword in journey queries
Fixes PostgreSQL syntax error by quoting the "event" column alias. This was causing the journey query to fail.

"event" is a reserved keyword in PostgreSQL. Added double quotes to treat it as an identifier rather than a keyword.

Changes:
- Quote "event" in PostgreSQL
- Quote "event" in ClickHouse for consistency
2025-11-04 11:00:33 +08:00
Mike Cao
79e324aace Updated Dockerfile to match current Prisma version.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-11-03 16:54:58 -08:00
Mike Cao
684863d6c7 Added laptop detection. Reorganized IP headers. 2025-11-03 16:44:01 -08:00
Francis Cao
c9f522b24d remove MySQL references from README
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-10-31 09:12:32 -07:00
Mike Cao
eb3cfbfa88 Updated lock file.
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-10-31 00:21:02 -07:00
Mike Cao
067567cbf6 Force geo build with BUILD_GEO env var.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-31 00:13:02 -07:00
Mike Cao
751568d871 Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-30 17:05:49 -07:00
Mike Cao
b08a6e1113 Don't prefetch pixel links. 2025-10-30 17:05:11 -07:00
Francis Cao
504c459090 update schema validation for link/pixel updates
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-10-30 16:13:36 -07:00
Mike Cao
dfe969cabe Fixed pixels/links collect.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-30 12:53:12 -07:00
Francis Cao
f073fb1996 Add DialogTrigger to overflow menus
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-29 12:38:52 -07:00
Francis Cao
72fba187db separate Admin/Settings Nav and add to MobileNav 2025-10-29 11:32:52 -07:00
Francis Cao
ef55b63a3b Fix admin layout and data refresh after update/delete 2025-10-29 11:04:54 -07:00
Francis Cao
c81b1c16c8 fix geteventdatavalues query 2025-10-29 10:10:46 -07:00
Francis Cao
6eefb4173c add improved truncation between tablets and phones
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-10-27 13:54:15 -07:00
Francis Cao
74972bccb1 add isMobile truncation logic to ListTable
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-10-27 13:18:26 -07:00
Francis Cao
2ffde37f5b v3 prisma queries update 2025-10-27 11:48:35 -07:00
Francis Cao
61b667c587 update psql expanded metrics queries
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-10-24 10:38:35 -07:00
Francis Cao
e71a34d1fa fix getChannelMetrics prisma query
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-23 16:24:58 -07:00
Francis Cao
1d3e980eed revert saveLocale change
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-10-22 16:40:14 -07:00
Francis Cao
d87ae84a29 fix reports permissions, long team overflow, language settings 2025-10-22 16:09:31 -07:00
Francis Cao
f5bf148b2b add close button on session modal
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-21 21:59:20 -07:00
Francis Cao
2e1a5b444a revenue, events, and session activity optimization 2025-10-21 21:12:22 -07:00
Francis Cao
533a42eb2e clean-up session api endpoints and queries 2025-10-21 19:54:50 -07:00
Francis Cao
f98e683979 add zod schema to realtime endpoint
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-21 17:20:35 -07:00
Francis Cao
b7747b33e4 clean-up hooks for passing uneccessary date params
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-21 16:52:04 -07:00
Francis Cao
06230ad2e9 clean up teams api messaging and permissions 2025-10-21 15:35:17 -07:00
Mike Cao
d8fdba77db Updated packages. 2025-10-21 13:39:43 -07:00
Mike Cao
ddc7affa6a More mobile fixes.
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-10-18 02:20:11 -07:00
Mike Cao
9a5604f236 Fixes for mobile.
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-18 01:12:45 -07:00
Mike Cao
bcafa12349 Small fixes.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-17 16:54:33 -07:00
Mike Cao
40492ec7c4 Added DialogButton to handle mobile.
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-16 23:59:18 -07:00
Mike Cao
036748cdeb Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
# Conflicts:
#	src/app/(main)/websites/[websiteId]/ExpandedViewModal.tsx
#	src/app/(main)/websites/[websiteId]/WebsiteExpandedView.tsx
2025-10-16 02:43:43 -07:00
Mike Cao
4d2a7ea947 Responsive everything. 2025-10-16 02:42:13 -07:00
Francis Cao
f23d5694ec clean up events/event-data endpoints
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-15 16:44:14 -07:00
Francis Cao
a7a7293d73 dvh height for mobile expanded view 2025-10-15 12:03:40 -07:00
Francis Cao
a2b1089e62 clean-up event/event-data endpoints. fix for expanded view for mobile 2025-10-15 11:32:19 -07:00
Mike Cao
9df012084d Mobile fixes.
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-14 23:10:27 -07:00
Mike Cao
5c3a6ce8ce Merge remote-tracking branch 'origin/dev' into dev 2025-10-14 21:59:45 -07:00
Mike Cao
10bc2895eb New mobile menu. 2025-10-14 21:57:31 -07:00
Mike Cao
be5f0494cc Added MobileMenuButton component. 2025-10-14 15:43:57 -07:00
Mike Cao
d9b08d9491 Card mode for tables. 2025-10-14 13:04:14 -07:00
Francis Cao
ba45972bd3 fix filter passthrough into event-data endpoints 2025-10-14 11:22:21 -07:00
Francis Cao
9fb38f6970 fix zod validations and prisma query for admin teams 2025-10-14 09:41:02 -07:00
Mike Cao
df3ae72ab7 Removed text.
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
2025-10-10 18:03:02 -07:00
Mike Cao
14981717b9 Responsive updates. 2025-10-10 17:28:53 -07:00
Mike Cao
53929626cf Fixed regex for filter params.
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-10 11:33:13 -07:00
Mike Cao
ac9edb8b5f Updated realtime page.
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-09 18:08:59 -07:00
Mike Cao
8aa4192576 Responsive updates. 2025-10-09 17:14:09 -07:00
Mike Cao
e4ce7c9071 Created ExpandedViewModal component. 2025-10-09 14:31:53 -07:00
Francis Cao
038f397503 change event labels to match other cards 2025-10-09 13:32:19 -07:00
Francis Cao
654156d239 add event header 2025-10-09 13:26:54 -07:00
Francis Cao
64b5a72963 add eventchart and metrictable to sharepage 2025-10-09 12:36:05 -07:00
Mike Cao
a8e3b5efbc Add rewrite for script in cloud mode.
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-08 16:01:47 -07:00
Mike Cao
8a13e2c70a Fixed reports fetch. 2025-10-08 15:56:38 -07:00
Francis Cao
bac3ab2c1a add maxwidth on event/session activity
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-07 11:35:28 -07:00
Francis Cao
1b43aa8d37 add max width to listtable label 2025-10-07 11:22:58 -07:00
Francis Cao
d948e122ea fix resetAt logic
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-07 09:44:59 -07:00
Francis Cao
36ae53654d Merge branch 'analytics' of https://github.com/umami-software/umami into analytics 2025-10-07 09:11:34 -07:00
Francis Cao
d440a44d96 clean-up useWebsite query params 2025-10-07 09:07:34 -07:00
Mike Cao
5a7c6a9816 Merge remote-tracking branch 'origin/analytics' into analytics 2025-10-07 01:55:33 -07:00
Mike Cao
d0aa266dce Fixed resetAt lookup. Added teams GET. 2025-10-07 01:55:19 -07:00
Francis Cao
0d67f1fdaa optimize getSessionActivity hasData 2025-10-06 22:56:34 -07:00
Francis Cao
cc3710880c optimize getWebsiteEvent hasData 2025-10-06 22:50:49 -07:00
Mike Cao
5244d8608b Fixed links/pixel lookup. 2025-10-06 22:08:33 -07:00
Mike Cao
895b41cb78 Updated login form. 2025-10-06 21:15:28 -07:00
Mike Cao
767b373484 Fixed issue with read replica initialization.
Some checks failed
Create docker images (cloud) / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-10-06 14:49:36 -07:00
Mike Cao
3e163940da Updated lang files. 2025-10-06 12:11:26 -07:00
Mike Cao
dbc9525c9c Fixed docker build.
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-06 02:12:57 -07:00
Mike Cao
e7f565f143 Don't allow saving segments on share page.
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-05 23:55:17 -07:00
Mike Cao
dbac6192db Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Create docker images (cloud) / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-05 23:16:01 -07:00
Mike Cao
f733690d38 Added lookup for cloud account. Added SessionModal component. 2025-10-05 23:15:36 -07:00
Francis Cao
e64a01d8f1 fix redis set for resetWebsite cloudMode 2025-10-05 22:37:06 -07:00
Mike Cao
777515f754
Merge pull request #3637 from mdotme/uz-lang
Some checks failed
Node.js CI / build (mysql, 18.18, 10) (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
feat: add missing uzbek language
2025-10-05 18:04:26 -07:00
Francis Cao
aa376d25df Fix margin on website edit
Some checks are pending
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-05 17:39:36 -07:00
Mike Cao
caf04015bb Fixed default date range handling. Added header to share page. 2025-10-05 16:02:23 -07:00
Mike Cao
c5994e5eb6 Save name after website select. Fixed types. 2025-10-05 15:34:37 -07:00
Mike Cao
3496952769 Fixed empty website select. Converted session profile to popover. 2025-10-05 14:11:25 -07:00
Mike Cao
d23ad5f272 Merge branch 'master' into dev
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
# Conflicts:
#	.github/workflows/cd.yml
#	package.json
#	pnpm-lock.yaml
#	src/lib/date.ts
#	src/lib/schema.ts
2025-10-04 13:38:58 -07:00
Mike Cao
35c27589b7 Updated workflow to only run on tag publish.
Some checks failed
Node.js CI / build (mysql, 18.18, 10) (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-10-04 13:32:40 -07:00
Mike Cao
aaf92058d4 Merge remote-tracking branch 'origin/master' 2025-10-04 12:36:49 -07:00
Mike Cao
b152cfe480 Added workflow to delete untagged images. 2025-10-04 12:36:39 -07:00
Mike Cao
82813f312a Added workflow to delete untagged images. 2025-10-04 12:12:39 -07:00
Mike Cao
2d0104382c Don't build Docker images for dev. 2025-10-04 11:44:37 -07:00
Mike Cao
5c0dacf58d Fix build. 2025-10-04 11:29:34 -07:00
Mike Cao
03adb6b7e1 Added website check for cloud.
Some checks failed
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Create docker images / Build, push, and deploy (push) Has been cancelled
2025-10-04 00:38:10 -07:00
Mike Cao
ed013d5d58 Fixed spacing issue in confirmation form. 2025-10-04 00:04:11 -07:00
Mike Cao
eabfec9075 Updated website edit. 2025-10-03 23:05:15 -07:00
Mike Cao
fdfa8b08f9 Added expanded view for pixels/links. Made filter form into a popover. 2025-10-03 20:25:06 -07:00
Mike Cao
8971f23e72 Should clear all parameter. 2025-10-03 18:08:01 -07:00
Mike Cao
904c313a64 Always cache prisma. Renamed WebsiteMonthSelect to MonthFilter. 2025-10-03 18:06:18 -07:00
Mike Cao
92ee44756c Refactored useDateRange to always use query string. Fixed all time filter. 2025-10-03 17:55:39 -07:00
Francis Cao
4d06b0ca5b fix compare screens
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-03 10:52:57 -07:00
Mike Cao
f70f98fed0 Updated replica handling. Fixed types.
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-03 01:20:48 -07:00
Mike Cao
b36cd48b4a Separated query string date handling. Fixed all time date. 2025-10-03 01:19:35 -07:00
Mike Cao
1def80ba42 Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-02 16:57:23 -07:00
Mike Cao
da572864ac Added more function names to queries. 2025-10-02 16:56:56 -07:00
Francis Cao
16451dd5cd update CH view to account for new event types
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-02 10:18:13 -07:00
Francis Cao
ec81cd665f Merge branch 'dev' of https://github.com/umami-software/umami into dev
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-01 12:29:41 -07:00
Francis Cao
1809959b99 fix event type queries for pixels/links. remove hardcoded event types 2025-10-01 12:29:31 -07:00
Mike Cao
cd6ad0add2 Updated CSP. 2025-10-01 11:16:33 -07:00
Mike Cao
8ca73268ba Merge remote-tracking branch 'origin/dev' into dev 2025-10-01 10:33:28 -07:00
Mike Cao
98bdc82239 Updated CSP generation. 2025-10-01 10:32:38 -07:00
Francis Cao
f86c21b25b kafka no longer needed 2025-10-01 10:21:20 -07:00
Francis Cao
a8b4ddd054 Revert "fix "Last X unit" minDate cutoff"
This reverts commit 55c8a6f7cc.
2025-10-01 10:12:07 -07:00
Mike Cao
8e05921227 Try to fix avatar.
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-10-01 00:23:09 -07:00
Mike Cao
25e8e18b73 Fix Avatar for Vercel. 2025-10-01 00:00:40 -07:00
Mike Cao
581ddc0233 Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-09-30 16:18:48 -07:00
Mike Cao
8a977b0164 Updated pixel/link endpoints. Added name to rawQuery. 2025-09-30 16:11:21 -07:00
Francis Cao
55c8a6f7cc fix "Last X unit" minDate cutoff
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-09-30 13:38:55 -07:00
Francis Cao
89d3cd4f5a add timezone to revenue chartData. Fix min/max date for 7day value 2025-09-30 13:11:11 -07:00
Francis Cao
bf99068bd7 Remove tables result set from getRevenue. Fix min/max date for revenuechart 2025-09-30 12:03:15 -07:00
Francis Cao
1b54ba3e6e MetricsTable anchor more to bottom of component 2025-09-30 11:19:13 -07:00
Francis Cao
81dea02379 fix transfer website dropdown and values 2025-09-30 09:38:37 -07:00
Mike Cao
b9fbbc6453 Split queries into prisma and sql.
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-09-29 16:55:07 -07:00
Mike Cao
1a66e3df73 Merge remote-tracking branch 'origin/dev' into dev 2025-09-29 15:13:43 -07:00
Mike Cao
1d7759408f Fixed build. 2025-09-29 15:13:01 -07:00
Francis Cao
9f027427b7 fix svg imports
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-09-29 09:54:52 -07:00
Manuchehr
87f5cea636 feat: add missing uzbek language 2025-09-29 09:15:53 +05:00
Mike Cao
257050f749 Updated edit forms and icons.
Some checks failed
Create docker images / Build, push, and deploy (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
2025-09-26 01:46:36 -07:00
Mike Cao
554054d3a1 Merged nav menus.
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-09-25 20:46:00 -07:00
Mike Cao
2f5e69229c Merge remote-tracking branch 'origin/dev' into dev 2025-09-25 15:58:34 -07:00
Mike Cao
805b3ec853 WIP: Nav merge 2025-09-25 15:58:25 -07:00
Francis Cao
5bbc1a94b3 Merge branch 'dev' of https://github.com/umami-software/umami into dev
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-09-25 11:31:26 -07:00
Francis Cao
c28c022366 update FilterEditForm for pixels/links, update attribution action dropdown 2025-09-25 11:31:16 -07:00
Mike Cao
dfc6161a53 Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	src/app/share/[...shareId]/Header.tsx
2025-09-25 11:23:36 -07:00
Mike Cao
1b400da7b2 Fixed share page. Updated device detect. Updated teams fetch. 2025-09-25 11:21:44 -07:00
Francis Cao
f11773ad3f fix user delete and Logo import
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-09-24 16:44:58 -07:00
Mike Cao
eca6b069f6
Merge pull request #3633 from mcnaveen/fix/asia-kolkata-tz
Some checks failed
Create docker images / Build, push, and deploy (push) Has been cancelled
Create docker images / Build, push, and deploy-1 (push) Has been cancelled
Node.js CI / build (mysql, 18.18, 10) (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
feat (timezone): normalization function for handling legacy timezone identifiers
2025-09-24 12:55:20 -07:00
Francis Cao
ce1120c3ff fix comparison for d in generateTimeSeries
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-09-24 11:07:13 -07:00
Francis Cao
b777441788 correct date labeling for previous pageviews/sessions 2025-09-24 11:04:22 -07:00
Francis Cao
9d49eaebac fix cohort query for retention report, add filters to weekly traffic route 2025-09-24 10:06:34 -07:00
mcnaveen
9e1fe2e363
Enhance timezone handling by adding normalization for 'Asia/Calcutta' to 'Asia/Kolkata' and updating validation schema to use normalized timezones. 2025-09-24 16:45:58 +05:30
Mike Cao
27c342811e Added label to PageHeader. Style fixes.
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
2025-09-24 00:07:17 -07:00
Mike Cao
8115709a8b Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	src/app/(main)/teams/TeamsDataTable.tsx
#	src/app/(main)/teams/TeamsJoinButton.tsx
#	src/app/(main)/teams/[teamId]/TeamSettings.tsx
2025-09-23 23:10:05 -07:00
Mike Cao
83a014e884 Use FormattedMessage. Updated icons. Fixed bugs. 2025-09-23 23:08:40 -07:00
Mike Cao
9ee8f301ed
Merge pull request #3582 from fnwbr/master
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Create docker images / Build, push, and deploy-1 (push) Waiting to run
Node.js CI / build (mysql, 18.18, 10) (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
`POST /api/websites/<id>`: Make name and domain optional in the validation schema
2025-09-23 17:53:40 -07:00
Mike Cao
077eeceb88
Merge pull request #3628 from umami-software/dependabot/npm_and_yarn/next-15.4.7
Bump next from 15.3.3 to 15.4.7
2025-09-23 17:52:43 -07:00
Mike Cao
e191d9dae4
Merge pull request #3631 from umami-software/mikecao-patch-1
Add ISO country codes to constants
2025-09-23 17:51:40 -07:00
Mike Cao
a6966179f5
Add ISO country codes to constants 2025-09-23 17:50:40 -07:00
Mike Cao
3afe843461 Fixed ISO countries. 2025-09-23 17:49:36 -07:00
Mike Cao
c51dd7e606 Merge branch 'master' into dev
# Conflicts:
#	.github/workflows/cd-manual.yml
#	.github/workflows/cd.yml
#	.github/workflows/ci.yml
#	src/lib/detect.ts
2025-09-23 17:43:24 -07:00
Mike Cao
050df528a6
Merge pull request #3629 from kronthto/patch-1
Incomplete ISO Countries Constants
2025-09-23 17:39:41 -07:00
Francis Cao
8c703eff93 resolve bug. reset queryparams when selecting segment/cohort from screens. add cohort prefix to event and path
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-23 15:00:07 -07:00
Francis Cao
1a5c7df671 Fix broken icons, remove showActions from TeamsTable, fix margins for pixel/link overview 2025-09-23 13:55:27 -07:00
Mike Cao
ee70baaeb7 Fixed admin link.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-23 09:56:38 -07:00
Mike Cao
b115131f4c Fixed async issues. 2025-09-23 09:20:51 -07:00
Mike Cao
f639bb07f4 Added menu options for cloud mode. Async fixes. 2025-09-23 09:14:01 -07:00
Tobias Kronthaler
cb209eee81
Fix map display for DACH 2025-09-23 10:09:58 +02:00
Mike Cao
4df6f06485 Added scrolling menu. 2025-09-22 22:45:37 -07:00
Mike Cao
6faf16e9aa Convert all mutate to mutateAsync. 2025-09-22 22:39:25 -07:00
dependabot[bot]
9a543d8966
Bump next from 15.3.3 to 15.4.7
Bumps [next](https://github.com/vercel/next.js) from 15.3.3 to 15.4.7.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.3.3...v15.4.7)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 15.4.7
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-23 05:31:11 +00:00
Mike Cao
6497cd0cd4
Merge pull request #3611 from halkeye/migrate-docker-gha
Some checks are pending
Create docker images / Build, push, and deploy (push) Waiting to run
Create docker images / Build, push, and deploy-1 (push) Waiting to run
Node.js CI / build (mysql, 18.18, 10) (push) Waiting to run
Node.js CI / build (postgresql, 18.18, 10) (push) Waiting to run
Migrate to docker actions
2025-09-22 22:29:46 -07:00
Mike Cao
3a4f4c1e27
Merge pull request #3627 from malwarepad/master
URGENT! Resolve IPv6 address destruction on GeoIP query
2025-09-22 22:26:33 -07:00
Mike Cao
980e4e6b41 Fixed funnel report saving invalid data.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-22 22:03:26 -07:00
Mike Cao
bf16ade184 Updated icons. 2025-09-22 20:11:31 -07:00
Mike Cao
d8b3c8d13c Pass headers for links and pixels.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-22 14:19:57 -07:00
Mike Cao
656fb8a3d1 Removed duplicate saved messages. 2025-09-22 14:10:35 -07:00
Mike Cao
5c9f97182e Removed grant checks. 2025-09-22 13:57:42 -07:00
Mike Cao
48c7028a3a Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	pnpm-lock.yaml
2025-09-22 13:11:04 -07:00
Mike Cao
9897c725de Updated cloud mode checks. 2025-09-22 13:09:07 -07:00
Francis Cao
26bd498a05 add margin to website layout. remove from overview
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-22 11:01:58 -07:00
Panagiotis
7d9fe30626
Resolve IPv6 address destruction 2025-09-21 22:56:59 +03:00
Mike Cao
d8075764e2 Merge remote-tracking branch 'origin/dev' into dev
Some checks failed
Node.js CI / build (postgresql, 18.18) (push) Has been cancelled
# Conflicts:
#	src/app/(main)/teams/[teamId]/TeamSettings.tsx
2025-09-19 18:01:42 -07:00
Mike Cao
7effa16f00 Updated edit permissions on settings components. 2025-09-19 17:58:52 -07:00
Francis Cao
c66553c023 Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-09-19 11:32:39 -07:00
Francis Cao
5767208d8c push to websites on login, css fix for teams screens 2025-09-19 11:32:20 -07:00
Mike Cao
ffc8f6faae Fixed config fetch.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-18 15:38:55 -07:00
Mike Cao
2a559aa661 Replaced server action with api route. 2025-09-18 11:32:21 -07:00
Mike Cao
93e71d900f Updated settings button. 2025-09-18 10:37:42 -07:00
Mike Cao
1c7f9da320 Updated redirect config.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-17 22:41:54 -07:00
Mike Cao
a84b890b23 Merge remote-tracking branch 'origin/dev' into dev 2025-09-17 22:04:24 -07:00
Mike Cao
0ae5c28da7 Export preference components. Updates for cloud. 2025-09-17 22:03:58 -07:00
Mike Cao
9c36f76e1b
Merge pull request #3623 from nickcmaynard/fix-ci
Some checks failed
Node.js CI / build (mysql, 18.18, 10) (push) Has been cancelled
Node.js CI / build (postgresql, 18.18, 10) (push) Has been cancelled
Add setup-pnpm to hopefully fix CI tests etc.
2025-09-17 21:43:28 -07:00
Nick Maynard
b2c829a077 Add setup-pnpm to hopefully fix CI tests etc. 2025-09-17 21:37:57 +01:00
Francis Cao
6d9d8b353f update property names for list table to label, count, percent
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-17 11:43:58 -07:00
Mike Cao
23838c57fb Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-09-17 08:38:19 -07:00
Mike Cao
03933bea7a Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-17 08:38:13 -07:00
Mike Cao
8150b86a9c Fixed websites lookup. 2025-09-17 08:37:41 -07:00
Mike Cao
3acb34d599 Merge branch 'master' into dev 2025-09-16 22:45:10 -07:00
Mike Cao
39c99997ce
Merge pull request #3608 from fauzora/fix/tracker-configuration
Some checks are pending
Node.js CI / build (mysql, 18.18) (push) Waiting to run
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
fix(hash): improve URL normalization and handling in tracking functions
2025-09-16 22:44:51 -07:00
Mike Cao
a4a9d6c227 Added stripPort function. Reorganized constants.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-16 21:23:08 -07:00
Mike Cao
04c06443a8 Merge branch 'master' into dev
# Conflicts:
#	.github/workflows/ci.yml
#	src/lang/es-ES.json
#	src/lang/sl-SI.json
#	src/lib/constants.ts
#	src/lib/detect.ts
#	src/queries/sql/reports/getRevenue.ts
2025-09-16 21:11:12 -07:00
Mike Cao
aa398201be
Merge pull request #3613 from nickcmaynard/fix-ip-header-ordering
Fix ordering to allow X-Forwarded-For to be correctly managed by Cloudflare
2025-09-16 20:57:20 -07:00
Mike Cao
2826daad1a
Merge branch 'master' into fix-ip-header-ordering 2025-09-16 20:57:12 -07:00
Mike Cao
840e0314f5
Merge pull request #3619 from go-task/geolocation-netlify
fix(geo): parse netlify ip header by default: `x-nf-client-connection-ip`
2025-09-16 20:55:15 -07:00
Francis Cao
28ba2a1666 fix margins, teams button, and remove boards
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-16 13:31:21 -07:00
Francis Cao
cfd49e1742 set maxheight to modals
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-15 10:31:31 -07:00
Francis Cao
8083482ba8 fix response error return type 2025-09-15 10:18:28 -07:00
Mike Cao
460200dfef useApi should return an actual Error.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-14 23:57:15 -07:00
Mike Cao
fc01ee9f56 Get localized error messages. 2025-09-14 23:43:22 -07:00
Andrey Nering
bfcc822b40 fix(geo): parse netlify ip header by default: x-nf-client-connection-ip
This header is not clearly documented, but it is mentioned in
semi-official sources, and I have tested it to ensure it's working
properly.

Without this, Umami is unable to detect geolocation by default if
deployed on Netlify.

* https://answers.netlify.com/t/is-the-client-ip-header-going-to-be-supported-long-term/11203/2
* https://httptoolkit.com/blog/what-is-x-forwarded-for/#and-others
2025-09-14 22:10:21 -03:00
Mike Cao
baba06c692 Added lib/password. Small tweaks.
Some checks failed
Node.js CI / build (postgresql, 18.18) (push) Has been cancelled
2025-09-13 09:40:20 -07:00
Mike Cao
9ccafc390a Add includeTeams param for fetching websites.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-12 10:15:13 -07:00
Mike Cao
433ce98719 Allow getting team websites. 2025-09-12 08:21:29 -07:00
Mike Cao
e610de383a Fix for schema selection in pg adapter.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-11 12:37:24 -07:00
Mike Cao
366c52d703 Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-10 17:16:15 -07:00
Mike Cao
67105f2cff Updated packages. 2025-09-10 17:16:04 -07:00
Francis Cao
f3125c2add clean up funnel migration and report errors 2025-09-10 16:38:51 -07:00
Francis Cao
1825524e95 convert report type before data migratino
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-10 09:29:49 -07:00
Francis Cao
54437ee9b8 Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-09-10 09:21:35 -07:00
Francis Cao
964651bad3 add data migration to convert funnel and goals reports to new structure 2025-09-10 09:21:27 -07:00
Mike Cao
503a1f740c
Merge pull request #3615 from matiasfacello/master
Some checks failed
Node.js CI / build (mysql, 18.18) (push) Has been cancelled
Node.js CI / build (postgresql, 18.18) (push) Has been cancelled
Adds missing spanish translations
2025-09-09 22:12:59 -07:00
Matias Facello
d471a972eb Adds missing spanish translations 2025-09-09 22:04:06 -03:00
Mike Cao
6799bd113a Allow async beforeSend function. Closes #3584
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-09 15:23:49 -07:00
Mike Cao
aa7d3cd1aa New components build.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-08 22:52:43 -07:00
Mike Cao
303947fe9b Fixed uuid references in schemas.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-08 15:28:01 -07:00
Nick Maynard
2177256a2c Fix ordering to allow X-Forwarded-For to be correctly managed by Cloudflare 2025-09-08 23:05:22 +01:00
Gavin Mogan
bf4e6ea96f Migrate to docker actions
Originally just wanted to add the standard opencontainer labels that
docker/metadata provide

but with "mr-smithers-excellent" seemed to only half implement docker
support, and a higher risk than docker for supply chain issues, so I
went all out and also added cosign to sign the images.

Docker metadata tags supports all the custom code to create version
tags, out of the box and fully maintained

Also dropped the manual workflow, just merged it into cd.yml since you
can select tags when you manual dispatch, and thats less to maintain
2025-09-06 07:06:23 -07:00
Mike Cao
f40e1b44f3 Updates for cloud mode.
Some checks failed
Node.js CI / build (postgresql, 18.18) (push) Has been cancelled
2025-09-04 20:27:42 -07:00
Chairil Fauzi Firmansyah
c5298d5d45 fix(hash): improve URL normalization and handling in tracking functions 2025-09-04 18:00:28 +07:00
Mike Cao
dc1736458b Export metrics components.
Some checks failed
Node.js CI / build (postgresql, 18.18) (push) Has been cancelled
2025-09-03 17:16:03 -07:00
Mike Cao
c4114f4349 Fixed build.
Some checks failed
Node.js CI / build (postgresql, 18.18) (push) Has been cancelled
2025-09-02 09:27:37 -07:00
Mike Cao
c916e4ff9c Fixed components build. Renamed validations to permissions. 2025-09-02 09:23:35 -07:00
Mike Cao
f0ec24e8f5 Updated funnel edit form.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-01 20:18:38 -07:00
Mike Cao
d534c0b221 Bump components version. 2025-09-01 16:21:04 -07:00
Mike Cao
0d19e9a247 Fixed outputs.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-09-01 16:17:55 -07:00
Mike Cao
56af91950a Updated components build. 2025-09-01 15:59:06 -07:00
Mike Cao
5f27ba149b New overview layout.
Some checks failed
Node.js CI / build (postgresql, 18.18) (push) Has been cancelled
2025-08-29 00:17:59 -07:00
Mike Cao
bab4f8ebcc Cohort selection. 2025-08-28 23:29:42 -07:00
Mike Cao
1b6da0aaa0
Merge pull request #3599 from 0xflotus/patch-2
Some checks failed
Node.js CI / build (mysql, 18.18) (push) Has been cancelled
Node.js CI / build (postgresql, 18.18) (push) Has been cancelled
fix: put Google in the right order of grouped domains
2025-08-28 10:59:31 -07:00
0xflotus
de3e9d0be3
fix: put Google in the right order of grouped domains 2025-08-28 08:29:30 +02:00
Mike Cao
df786d1fbc
Merge pull request #3590 from halkeye/halkeye/chore/pnpm
Some checks are pending
Node.js CI / build (mysql, 18.18) (push) Waiting to run
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
chore: finish migration of yarn/npm to pnpm everywhere
2025-08-27 22:29:51 -07:00
Mike Cao
19a87388cd
Merge pull request #3594 from 0xflotus/patch-2
chore: sort properties alphabetically
2025-08-27 20:41:27 -07:00
Mike Cao
d972765760
Merge pull request #3597 from badmike/feat/cloudfront-location-headers
feat: Add AWS CloudFront geolocation headers support
2025-08-27 20:38:52 -07:00
Mike Cao
05f9a67727 Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-08-27 17:24:28 -07:00
Mike Cao
dfaebcd1b7 Updated Next, Prisma, react-zen. 2025-08-27 17:23:58 -07:00
Mike Cao
8d5e8b072d Updated WebsiteSelect behavior. Fixed date select. 2025-08-27 16:59:44 -07:00
Francis Cao
7800fce2ec set maxheight to modals 2025-08-27 16:28:15 -07:00
Mike Cao
f9442001e4 Updated cohort processing.
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-08-27 14:05:46 -07:00
Michael Wallner
58c2d068e7
refactor getLocation to use lookup array for cleaner header extraction 2025-08-27 17:47:24 +02:00
Mike Cao
c3b62e3a74 Merge remote-tracking branch 'origin/dev' into dev
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-08-26 23:57:02 -07:00
Mike Cao
8c8e36c63b Cohorts editing. 2025-08-26 23:55:57 -07:00
Francis Cao
78c1fd8283 fix settings margins
Some checks are pending
Node.js CI / build (postgresql, 18.18) (push) Waiting to run
2025-08-26 11:16:42 -07:00
Mike Cao
07665f4824 Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-08-26 10:26:11 -07:00
Francis Cao
984f426cfe update getQueryFilters to support new segment/cohort data structure 2025-08-26 09:02:55 -07:00
Michael Wallner
8df72c55e5
add support for CloudFront headers in getLocation 2025-08-26 17:28:13 +02:00
0xflotus
ea2206f2e9
chore: sort properties alphabetically
I have sorted some of the properties alphabetically so that you can see more quickly in the future which ones may still be missing. I think it's easier to add some new ones this way.

I also fixed the `alibaba.com` domain from the typo `alibab.com`.
2025-08-25 21:02:13 +02:00
Francis Cao
f06ef6fbc9 fix visitDuration calculation and conditionally show bounce/visitDuration on session columns
Some checks failed
Node.js CI / build (postgresql, 18.18) (push) Has been cancelled
2025-08-25 09:26:49 -07:00
Francis Cao
6c832bd0db Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-08-25 07:40:32 -07:00
Francis Cao
b2e03390da translate dateRange and cohort prefix for filtering 2025-08-25 07:39:51 -07:00
Mike Cao
0f9669f886 Converted mutation queries. 2025-08-24 15:20:19 -07:00
Mike Cao
04fd5d370c
Merge pull request #3568 from markkuhar/update-slovenian-translation
Some checks failed
Node.js CI / build (mysql, 18.18) (push) Has been cancelled
Node.js CI / build (postgresql, 18.18) (push) Has been cancelled
Update Slovenian translation
2025-08-24 13:20:25 -07:00
Mike Cao
3f167e05ba New compare page. 2025-08-23 22:21:25 -07:00
Mike Cao
08f9adaddf Updated expanded view. Some style fixes. 2025-08-23 03:05:21 -07:00
Mike Cao
c8fe93dd9d Refactored tables. 2025-08-23 01:12:37 -07:00
Gavin Mogan
0e6442c469 chore: finish migration of yarn/npm to pnpm everywhere 2025-08-22 16:21:57 -07:00
Mike Cao
600a3d28c3 Use context hooks. 2025-08-21 03:15:47 -07:00
Mike Cao
00adb00d2d Fix build. 2025-08-21 03:06:41 -07:00
Mike Cao
f7ca583410 Redesigned overview page. 2025-08-21 03:01:37 -07:00
Mike Cao
5d1f2a6f2d Updated Next. 2025-08-21 01:43:51 -07:00
Mike Cao
3a332b5947 Merge remote-tracking branch 'origin/dev' into dev 2025-08-21 01:33:43 -07:00
Mike Cao
8e766e2db7 Pixel/link metrics pages. 2025-08-21 01:33:20 -07:00
Francis Cao
65024d4bf7 fix search for segments, fix hooks endpoint for cohorts 2025-08-19 16:20:21 -07:00
Francis Cao
2f1f704728 implement filtering and cohorts to all relevant queries 2025-08-19 15:26:41 -07:00
Florian Weber
49055ebc7d Add test for updating a website with only shareId 2025-08-19 14:43:42 +00:00
Florian Weber
7343ee4593 /api/website/<id>: Make name and domain fields optional in POST request schema 2025-08-19 14:43:33 +00:00
Mike Cao
789b8b36d8 Link route. 2025-08-18 22:30:22 -07:00
Mike Cao
2631fa51da Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-08-18 21:37:57 -07:00
Mike Cao
0ac8bd41b6 Pixel route. 2025-08-18 15:49:10 -07:00
Francis Cao
32febf0fbb add unique index to slug columns 2025-08-18 09:58:26 -07:00
Mike Cao
3c5c1e48e9 Refactored settings. Updated sidebar. 2025-08-15 22:16:28 -07:00
Mike Cao
d130242a0a Pixel editing. 2025-08-15 13:04:13 -07:00
Mike Cao
eabdd18604 Updated Prisma build. 2025-08-15 12:29:33 -07:00
Mike Cao
7abfa1cb5b Fixed build. 2025-08-15 11:38:37 -07:00
Mike Cao
b96b4941f4 Missing lock file. 2025-08-15 11:34:00 -07:00
Mike Cao
7838204186 Fixed imports. 2025-08-15 11:31:53 -07:00
Mike Cao
5f4b83b09c Link editing. 2025-08-15 11:11:24 -07:00
Mike Cao
0558563d35 Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-08-15 10:08:41 -07:00
Mike Cao
247e14646b Pixel/links development. New validations folder. More refactoring. 2025-08-14 23:48:11 -07:00
Mike Cao
88639dfe83 New schema for pixels and links. 2025-08-13 20:27:54 -07:00
Mark Kuhar
a1e3b5fd4a fix 2025-08-13 12:51:06 +02:00
Mark Kuhar
438baea956 update slovenian translation 2025-08-13 11:15:35 +02:00
Francis Cao
69aa4ca035 cleanup cohort/filtering for some queries 2025-08-12 16:13:44 -07:00
Francis Cao
6829d96862 update UTM report to use new UTM columns 2025-08-12 11:30:46 -07:00
Francis Cao
822ddee9ae update ch schema for custom data numbers 2025-08-12 09:15:42 -07:00
Mike Cao
c60e8b3d23 Moved panel button. 2025-08-09 17:46:27 -07:00
Mike Cao
a97445fb82 Fixed sidenav rendering. 2025-08-09 02:06:54 -07:00
Mike Cao
8897c2508d Fixed scrolling on expanded view. 2025-08-08 17:39:17 -07:00
Mike Cao
4e25c07160 Implemented expanded view in dialog. 2025-08-07 22:10:02 -07:00
Mike Cao
0b4851125d Updated next and prisma. 2025-08-07 12:36:11 -07:00
Mike Cao
274d654833 Merge branch 'dev' of https://github.com/umami-software/umami into dev
# Conflicts:
#	src/components/metrics/ReferrersTable.tsx
2025-08-07 10:08:14 -07:00
Francis Cao
38f251ead5 finish expanded queries and ui. 2025-08-07 09:47:18 -07:00
Mike Cao
2e67e27b2f Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	src/app/(main)/App.tsx
2025-08-07 05:16:07 -07:00
Mike Cao
eb7b6978d3 New settings layouts. Segment management screen. 2025-08-07 05:14:35 -07:00
Francis Cao
0a0c1f27c6 implement pageviews, events, and channels queries 2025-08-05 00:37:44 -07:00
Francis Cao
c1cad16cb9 implement sessions metric expanded queries 2025-08-04 18:27:31 -07:00
Mike Cao
2dbcf63eeb Segment editing. 2025-07-31 21:32:22 -07:00
Francis Cao
c8b4ee8ca5 update psql getChannelMetrics 2025-07-31 09:45:19 -07:00
Mike Cao
fba7e12c36 Updated segment handling. 2025-07-31 02:33:35 -07:00
Mike Cao
554c627a58 Merge branch 'dev' into jajaja
# Conflicts:
#	src/app/api/websites/[websiteId]/metrics/route.ts
#	src/queries/sql/getChannelMetrics.ts
2025-07-29 19:15:55 -07:00
Francis Cao
86e0fc2262 convert clickhouse getChannels to SQL query 2025-07-28 17:13:13 -07:00
Mike Cao
b552868e0a Merge branch 'dev' into jajaja
# Conflicts:
#	next.config.ts
#	src/app/(main)/settings/preferences/LanguageSetting.tsx
#	src/components/hooks/useConfig.ts
2025-07-27 02:11:32 -07:00
Mike Cao
2ad624ccc8 Added segment filtering to filter form. 2025-07-27 02:08:19 -07:00
Mike Cao
60eaaaff60
Merge pull request #3528 from umami-software/analytics
v2.19.0
2025-07-26 18:34:00 -07:00
Mike Cao
827c1074b6 Merge branch 'dev' into analytics 2025-07-24 23:38:09 -07:00
Mike Cao
784677e180 Moved env checks to server pages. 2025-07-24 23:05:51 -07:00
Mike Cao
5b6292dd11 Converted variables to be runtime. 2025-07-24 22:41:23 -07:00
Mike Cao
b6862de2be Made FAVICON_URL a runtime variable. Closes #3412 2025-07-24 21:54:10 -07:00
Mike Cao
6e6c1df858 Made FAVICON_URL a runtime variable. Closes #3412 2025-07-24 21:47:40 -07:00
Mike Cao
2e69e57445 Support event type filtering. 2025-07-24 16:09:49 -07:00
Mike Cao
45c9ea9c22 Merge branch 'dev' into jajaja
# Conflicts:
#	db/mysql/schema.prisma
#	package.json
#	pnpm-lock.yaml
#	src/app/(main)/reports/[reportId]/ReportBody.tsx
#	src/app/(main)/reports/[reportId]/ReportPage.tsx
#	src/app/(main)/reports/utm/UTMView.tsx
#	src/app/(main)/websites/[websiteId]/WebsiteMetricsBar.tsx
#	src/app/(main)/websites/[websiteId]/WebsiteTableView.tsx
#	src/app/(main)/websites/[websiteId]/events/EventsPage.tsx
#	src/app/api/reports/[reportId]/route.ts
#	src/app/api/websites/[websiteId]/metrics/route.ts
#	src/components/hooks/queries/useReport.ts
#	src/components/icons.ts
#	src/components/messages.ts
#	src/components/metrics/MetricsTable.module.css
#	src/components/metrics/MetricsTable.tsx
#	src/queries/sql/events/getEventMetrics.ts
#	src/queries/sql/reports/getUTM.ts
2025-07-23 23:39:28 -07:00
Mike Cao
a025fc9552 Updated nav. 2025-07-23 17:47:56 -07:00
Francis Cao
630b91fbd2 remove stringify json on updatereport 2025-07-23 10:19:20 -07:00
Francis Cao
038d3d6000 remove stringify json on updatereport 2025-07-23 10:18:43 -07:00
Francis Cao
e8ff32b063 Merge branch 'dev' of https://github.com/umami-software/umami into analytics 2025-07-23 09:38:59 -07:00
Francis Cao
2203ba1fe7 move parseParameters to UTMView 2025-07-23 09:38:39 -07:00
Francis Cao
6d124e7bb0 fix export report route 2025-07-22 11:10:37 -07:00
Mike Cao
7670ec4136 Added download functionality. 2025-07-22 00:24:37 -07:00
Francis Cao
dc39ba75c6 Merge branch 'dev' of https://github.com/umami-software/umami into analytics 2025-07-21 11:04:55 -07:00
Mike Cao
0debe89d05 Merge remote-tracking branch 'origin/dev' into dev 2025-07-21 10:59:31 -07:00
Mike Cao
5828445313 Updated packages. 2025-07-21 10:58:58 -07:00
Francis Cao
4dd4d66a3b Merge branch 'dev' of https://github.com/umami-software/umami into analytics 2025-07-21 10:56:08 -07:00
Francis Cao
a81b144cd6 fix get event metrics card and create it's own query 2025-07-21 10:49:48 -07:00
Mike Cao
ab0826d91a
Merge pull request #3517 from vicke4/feature/persistent-event-tab
feat: persistent event tab selection
2025-07-21 00:47:03 -07:00
Mike Cao
60c310fd77
Apply suggestion from @greptile-apps[bot]
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-07-21 00:46:12 -07:00
Mike Cao
25f96f6b6b Fixed nav display. 2025-07-20 00:38:15 -07:00
Francis Cao
da7f4cb2d0 create and apply mysql migrations 2025-07-18 10:26:24 -07:00
Mike Cao
2f7f8911cd Merge branch 'dev' into jajaja
# Conflicts:
#	pnpm-lock.yaml
#	src/queries/sql/getWebsiteStats.ts
#	src/queries/sql/pageviews/getPageviewMetrics.ts
#	src/queries/sql/sessions/getWebsiteSessionStats.ts
#	src/queries/sql/sessions/getWebsiteSessions.ts
#	src/queries/sql/sessions/getWebsiteSessionsWeekly.ts
2025-07-18 10:13:21 -07:00
Mike Cao
876f4c883e Updated layout. Fixed properties rendering. 2025-07-18 00:22:06 -07:00
Francis Cao
90682b79d2 Merge branch 'dev' of https://github.com/umami-software/umami into analytics 2025-07-17 11:22:21 -07:00
Francis Cao
ccfb228509 Fix Vercel build: regenerate pnpm-lock.yaml 2025-07-17 09:06:06 -07:00
Mike Cao
01bfd7f52e New properties screens. New website nav. 2025-07-17 01:18:31 -07:00
vicke4
2c0b7a6408 feat: persistent event tab selection 2025-07-17 11:49:35 +05:30
Francis Cao
954404f8df route to view or raw table based on filters 2025-07-15 16:26:03 -07:00
Mike Cao
a9a9b57f80 Merge branch 'dev' into jajaja
# Conflicts:
#	pnpm-lock.yaml
#	src/app/(main)/websites/[websiteId]/events/EventProperties.tsx
#	src/components/messages.ts
#	src/lib/constants.ts
#	src/queries/sql/pageviews/getPageviewMetrics.ts
#	src/queries/sql/sessions/getWebsiteSessions.ts
2025-07-15 13:01:50 -07:00
Mike Cao
a534c51b5e New website nav. 2025-07-15 03:35:18 -07:00
Mike Cao
5e6799a715 Fixed properties queries. 2025-07-15 01:31:08 -07:00
Francis Cao
2dcb9e21bd change pagestable to visitors and update clickhouse hostname column to array 2025-07-13 22:44:09 -07:00
Mike Cao
195619aeed
Merge pull request #3507 from basbroek/feature/table-view-events
Feature: Table view for event properties
2025-07-13 22:03:59 -07:00
Mike Cao
31f9b17942
Merge branch 'dev' into feature/table-view-events 2025-07-13 22:03:52 -07:00
Mike Cao
465a03f987 Fixed paging in events/sessions. 2025-07-13 21:10:59 -07:00
Mike Cao
8c26e310f7 Fixed editing and navigation issues. 2025-07-13 00:37:43 -07:00
Mike Cao
bf6c9395c6 Revert Prisma build. 2025-07-12 15:18:01 -07:00
Mike Cao
77131158f7 Updated build config for Vercel. 2025-07-12 14:41:10 -07:00
Mike Cao
514ea70d2a Removed queryCompiler. 2025-07-12 14:24:51 -07:00
Mike Cao
b255b4738f Fixed imports. 2025-07-12 14:12:59 -07:00
Mike Cao
2a8c707519 Updated db build again. 2025-07-12 14:08:15 -07:00
Mike Cao
2dbe80b7ca Updated db build. 2025-07-12 13:56:45 -07:00
Mike Cao
3650204519 Styling for all forms. 2025-07-12 13:20:32 -07:00
Mike Cao
c98f324c22 Settings refactor. 2025-07-11 22:55:30 -07:00
Mike Cao
1b81074752 Admin section updates. 2025-07-10 20:04:17 -07:00
Bas Broekhuizen
23120ec011 Replace loading text with icon 2025-07-09 09:10:02 +02:00
Mike Cao
87449ece9e Merge branch 'dev' into jajaja
# Conflicts:
#	db/postgresql/schema.prisma
#	pnpm-lock.yaml
#	src/app/(main)/websites/[websiteId]/WebsiteDetailsPage.tsx
#	src/app/(main)/websites/[websiteId]/compare/WebsiteComparePage.tsx
#	src/app/api/reports/route.ts
#	src/app/api/websites/[websiteId]/events/series/route.ts
#	src/app/api/websites/[websiteId]/metrics/route.ts
#	src/app/api/websites/[websiteId]/pageviews/route.ts
#	src/app/api/websites/[websiteId]/sessions/stats/route.ts
#	src/app/api/websites/[websiteId]/stats/route.ts
#	src/app/api/websites/[websiteId]/values/route.ts
#	src/components/hooks/useFields.ts
#	src/components/hooks/useFilterParams.ts
#	src/lang/vi-VN.json
#	src/lib/clickhouse.ts
#	src/lib/detect.ts
#	src/lib/prisma.ts
#	src/lib/request.ts
#	src/lib/schema.ts
#	src/lib/types.ts
#	src/queries/sql/events/getEventDataFields.ts
#	src/queries/sql/events/getEventDataProperties.ts
#	src/queries/sql/events/getEventDataStats.ts
#	src/queries/sql/events/getEventDataValues.ts
#	src/queries/sql/events/getEventMetrics.ts
#	src/queries/sql/events/getWebsiteEvents.ts
#	src/queries/sql/getChannelMetrics.ts
#	src/queries/sql/getRealtimeActivity.ts
#	src/queries/sql/getWebsiteStats.ts
#	src/queries/sql/pageviews/getPageviewMetrics.ts
#	src/queries/sql/pageviews/getPageviewStats.ts
#	src/queries/sql/reports/getBreakdown.ts
#	src/queries/sql/sessions/getSessionDataProperties.ts
#	src/queries/sql/sessions/getSessionDataValues.ts
#	src/queries/sql/sessions/getSessionMetrics.ts
#	src/queries/sql/sessions/getSessionStats.ts
#	src/queries/sql/sessions/getWebsiteSessionStats.ts
#	src/queries/sql/sessions/getWebsiteSessions.ts
2025-07-08 22:03:55 -07:00
Mike Cao
5ed1d710cb Merge branch 'master' into jajaja
# Conflicts:
#	package.json
#	pnpm-lock.yaml
#	src/lib/detect.ts
2025-07-08 18:45:02 -07:00
Mike Cao
ce1f6c3618 New admin section. 2025-07-08 18:40:47 -07:00
Bas Broekhuizen
0c78e31300 Add table view as alternative to donut chart for event properties 2025-07-08 10:17:18 +02:00
Mike Cao
abc02465e3
Merge pull request #3503 from umami-software/dependabot/npm_and_yarn/next-15.3.3
Bump next from 15.3.1 to 15.3.3
2025-07-07 22:59:44 -07:00
Mike Cao
f64aab1495
Merge pull request #3506 from abcsnoob/add-vietnamese-translation
Add full Vietnamese translation for Umami (vi-VN.json)
2025-07-07 22:59:11 -07:00
Mike Cao
b2a6e3f842
Merge pull request #3505 from eoussama/master
Added optional website ID for creation
2025-07-07 22:58:16 -07:00
abcsnoobytb
426157d32c Add full Vietnamese translation for Umami (vi-VN.json) 2025-07-08 08:18:15 +07:00
eoussama
b73a67915d Added optional website ID for creation 2025-07-06 21:18:04 +01:00
Mike Cao
b78ff3b477 New admin section. 2025-07-06 08:22:29 -07:00
Mike Cao
cdf391d5c2 Refactor part 2: Electric Boogaloo. Standardize way of passing filter parameters. 2025-07-04 01:23:11 -07:00
dependabot[bot]
9503d2aaf1
Bump next from 15.3.1 to 15.3.3
Bumps [next](https://github.com/vercel/next.js) from 15.3.1 to 15.3.3.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.3.1...v15.3.3)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 15.3.3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-03 21:05:25 +00:00
Francis Cao
5257b7b3e3 hide segment/cohort fields 2025-07-03 12:16:44 -07:00
Francis Cao
e75d009df3 implement cohorts to clickhouse/pg library and all relevant queries 2025-07-03 12:06:49 -07:00
Mike Cao
f26f1b0581 Updated next and pg packages. 2025-07-02 11:54:17 -07:00
Mike Cao
dfeac89236 Changed Prisma provider. 2025-07-02 11:10:47 -07:00
Mike Cao
d6ae09ac18 Changed CI build. 2025-07-02 10:48:17 -07:00
Mike Cao
b6d7b6443a Upgraded Prisma 6.11.0. 2025-07-02 10:12:17 -07:00
Mike Cao
ee6c68d27c Refactor filter handling for queries. 2025-07-02 01:44:12 -07:00
Mike Cao
74f0bdab89
Merge pull request #3498 from AlexEscalante/sanitize-ip
Sanitize IP to remove port for geolocation lookup
2025-07-01 21:26:36 -07:00
Mike Cao
5b300f1ff5 Updated events/sessions pages. Added DateDistance component. 2025-06-30 21:34:56 -07:00
Alex Escalante
26ddfd5a80
Sanitize IP to remove port for geolocation lookup
Sanitize IP address to remove port number before geolocation lookup. This ensures proper MaxMind database resolution in setups where IP:PORT is passed by the proxy.
2025-06-30 18:40:21 -06:00
Mike Cao
8b64029409 Made filters work for all reports. 2025-06-29 23:57:11 -07:00
Mike Cao
ea83afbc13 Fixed retention report showing wrong dates. Changed Breakdown field select to modal. 2025-06-29 15:36:43 -07:00
Mike Cao
ee8750d9df Update Retention report. 2025-06-28 21:16:50 -07:00
Mike Cao
0c2070771b
Merge pull request #3489 from Sov3rain/master
Feature: Add keepalive option to tracker fetch request
2025-06-27 09:16:10 -07:00
Mike Cao
d09b3cc029
Merge pull request #3494 from alasjo/master
Malformed CSP: prevent frameAncestors to be undefined
2025-06-27 09:15:05 -07:00
Mike Cao
184a387ecd Lang updates. 2025-06-27 08:53:10 -07:00
Mike Cao
5c5ec18e67 Added turbo build for CI. 2025-06-26 21:44:00 -07:00
Mike Cao
0692134ea5 AI generated translations. 2025-06-26 13:59:46 -07:00
Francis Cao
a753809a74 Merge branch 'dev' of https://github.com/umami-software/umami into feat/add-segments 2025-06-26 09:12:51 -07:00
Alexander Alasjö
5a5e3a1502 Nullish coalescing 2025-06-26 11:45:42 +02:00
Alexander Alasjö
d72833af13 Default empty string, prevent frameAncestors to be undefined 2025-06-26 11:37:05 +02:00
Mike Cao
5171bdaf47 Use getRequestDateRange in all routes. 2025-06-25 22:53:07 -07:00
Mike Cao
b0023feee9 Merge branch 'dev' into jajaja 2025-06-25 14:49:36 -07:00
Mike Cao
5ca51b3e8f Updated date range handling. 2025-06-25 14:27:17 -07:00
Francis Cao
d5f5716c90 remove limit from websiteevents also 2025-06-24 11:37:22 -07:00
Brian Cao
863a0bb15b Remove limit 1000 on sessions 2025-06-24 11:37:22 -07:00
Francis Cao
87e364d707 remove limit from websiteevents also 2025-06-24 11:35:37 -07:00
Francis Cao
657ae8ebdb udpate constants and references to filter groups 2025-06-24 11:09:36 -07:00
Brian Cao
99c9eeeb72 Remove limit 1000 on sessions 2025-06-24 11:08:07 -07:00
Sov3rain
42c0ccc2eb Add keepalive option to tracker fetch request 2025-06-23 15:17:22 +02:00
Mike Cao
6d1603fa28 New share URL form. 2025-06-21 01:45:36 -07:00
Mike Cao
543674c7f2 Updated hooks. Changed url, host to path, hostname. 2025-06-20 22:35:02 -07:00
Francis Cao
5ffafc71fc finish segments, update migration from filters to parameters 2025-06-20 10:27:57 -07:00
Mike Cao
25a9c011b3 Removed check-lang script. 2025-06-20 09:42:37 -07:00
Mike Cao
bc1bd35efc Updated packages. 2025-06-20 09:26:48 -07:00
Mike Cao
0a43ef7b1b Filtering via FilterBar. 2025-06-19 16:47:18 -07:00
Mike Cao
da173779e0 Website compare fix. Updated date functions. 2025-06-19 00:40:21 -07:00
Mike Cao
5a85433e63 Fix CI. 2025-06-18 22:48:03 -07:00
Mike Cao
a1654e88af Update CI. 2025-06-18 22:46:05 -07:00
Mike Cao
fb7f671b32 Upgraded Prisma v6.10.1. 2025-06-18 22:13:51 -07:00
Mike Cao
8abb470234 Merge branch 'dev' into jajaja 2025-06-18 21:43:58 -07:00
Mike Cao
c61f089729 Pass original date in dataset. 2025-06-18 21:43:38 -07:00
Mike Cao
3a737e7e25 Fixed bar chart rendering. 2025-06-18 21:31:42 -07:00
Mike Cao
96fcdefeed Updated Goal loading. 2025-06-18 20:12:42 -07:00
Mike Cao
f41c9a635f
Merge pull request #3456 from vedantbhavsar26/feat-1
fix: decode location fields in user detection
2025-06-18 14:30:24 -07:00
Mike Cao
acc323dbc9
Merge pull request #3469 from KrakenWagen/create_session_slow
improv: Improved performance of send
2025-06-18 14:29:03 -07:00
Mike Cao
f444c6373d Updated packages. Fixed loading errors. 2025-06-18 01:39:12 -07:00
Francis Cao
8408bbd25c add api routes for segments 2025-06-17 10:08:08 -07:00
Mike Cao
da8c7e99c5 Unified loading states. 2025-06-13 21:13:11 -07:00
Mike Cao
768583e991
Merge pull request #3474 from querry43/master
fixing the clickhouse schema file
2025-06-13 19:26:52 -07:00
Matt Harrington
19ccfa0745 fixing the clickhouse schema file 2025-06-13 12:17:18 -07:00
Francis Cao
f61421b742 segments implementation and migration update. update getRequestFilters to include filter groups. 2025-06-13 07:34:54 -07:00
Mike Cao
7b5591a3ce Fixed chart rendering when using date nav buttons. 2025-06-12 23:07:25 -07:00
Mike Cao
1649992654 Updates session details page. 2025-06-12 00:31:09 -07:00
Mike Cao
095d1f2070 Updates to Revenue report. 2025-06-11 23:12:10 -07:00
Francis Cao
1ccc8a1a86 Merge branch 'dev' of https://github.com/umami-software/umami into feat/add-segments 2025-06-11 06:46:31 -07:00
Mike Cao
4995a0e1e4 Fixed attribution report. New metric cards. Converted ListTable. 2025-06-11 00:05:34 -07:00
Mike Cao
b2aa37a3df Merge branch 'dev' into jajaja
# Conflicts:
#	db/postgresql/schema.prisma
#	src/queries/sql/reports/getRevenue.ts
2025-06-10 21:11:44 -07:00
Mike Cao
e3cc19638c Breakdown report. 2025-06-10 20:59:27 -07:00
Mike Cao
34a154e513
Merge pull request #3471 from sufyanfa/feat/ar-translation
docs: improve and update Arabic translations
2025-06-10 11:52:17 -07:00
Francis Cao
a4465aaa43 update psql revenue and attribution report to use new revenue table 2025-06-10 09:58:39 -07:00
Mike Cao
fdaf4b5688
Merge pull request #3470 from sancho1952007/master
Updated the MacOS Icon
2025-06-09 20:32:07 -07:00
Sufyan Farea
e20db80fa1
Update src/lang/ar-SA.json
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-06-09 22:54:35 +03:00
Sufyan Farea
796952698c docs: improve and update Arabic translations 2025-06-09 22:34:58 +03:00
Francis Cao
49b4948d0f add revenue table and save 2025-06-09 11:59:39 -07:00
Sancho Godinho
5be7ff224f
Updated MacOS icon
The current MacOS icon highly resembles the iOS icon. MacOS is easily identifiable by its unique finder icon. Hence, uploaded a new icon to display the MacOS traffic.
2025-06-10 00:08:24 +05:30
Sancho Godinho
8c42d9ef02
Delete mac-os.png
Will update with new icon
2025-06-10 00:07:05 +05:30
Felix Bernal
3a119acd10 improv: Improved performance of send due to slow session creation retrieving session every time. 2025-06-09 14:42:16 +02:00
Mike Cao
79ea9974b7 Added attribution report page. 2025-06-09 00:42:09 -07:00
Mike Cao
0027502707 Merge branch 'dev' into jajaja
# Conflicts:
#	src/lib/detect.ts
#	src/queries/sql/reports/getRevenue.ts
2025-06-08 22:26:26 -07:00
Mike Cao
01bd21c5b4 Updated reports. 2025-06-08 22:21:28 -07:00
Mike Cao
883fd2580f Merge branch 'master' into dev 2025-06-08 22:10:42 -07:00
Mike Cao
6c6555d00b
Merge pull request #3445 from Nambers/master
fix: URL hash is not included in record
2025-06-08 22:08:13 -07:00
Mike Cao
bfb7b611e8
Merge pull request #3465 from undefined-moe/patch-1
allow custom geolite database path
2025-06-08 22:06:01 -07:00
Mike Cao
28e872f219 Fixed journey calculations. 2025-06-07 11:28:35 -07:00
Francis Cao
9cc717f054 convert attribution report 2025-06-07 07:53:40 -07:00
Francis Cao
e799d89606 add website_revenue table and view. update revenue report to use view 2025-06-07 07:53:40 -07:00
Francis Cao
9a437dcfa2 convert attribution report 2025-06-07 07:43:36 -07:00
Mike Cao
fd7dddb43a Fixed check-db for new Prisma adapter. 2025-06-07 00:27:22 -07:00
Mike Cao
d4bc72e90b Removed useReport hook. Journey styles. 2025-06-07 00:20:57 -07:00
Mike Cao
2af95b5802 Upgraded Prisma, use new query compiler. Removed old reports. 2025-06-07 00:15:30 -07:00
Mike Cao
a167c590c5 New standalone Journey page. 2025-06-06 23:31:30 -07:00
Mike Cao
cee05d762c Added journey page. Removed dashboard. 2025-06-06 19:44:09 -07:00
Francis Cao
a16846f4ce add website_revenue table and view. update revenue report to use view 2025-06-06 08:47:52 -07:00
Mike Cao
3847e32f39 More work on reports. Added Funnel page. 2025-06-05 22:19:35 -07:00
undefined
826f29bbc0
chore: allow custom geolite database path 2025-06-05 17:34:09 +01:00
Francis Cao
21d081f7d3 fix ordering for revenue country card 2025-06-05 07:31:47 -07:00
Francis Cao
57acaf9855 remove data conversion 2025-06-04 16:06:11 -07:00
Mike Cao
5159dd470f Merge branch 'dev' into jajaja 2025-06-04 13:47:11 -07:00
Francis Cao
a9c7938887 add data conversion to report param migration 2025-06-04 09:53:31 -07:00
Francis Cao
76519e0d14 add segment and report param migrations 2025-06-04 09:27:28 -07:00
Francis Cao
1840b8b419 segment migration and support 2025-06-04 08:47:42 -07:00
Exlaso
bf94c5dc73 fix: use safeDecodeURIComponent for location fields in user detection 2025-06-04 12:43:02 +05:30
Mike Cao
65f3628ed7
Merge pull request #3446 from ruchernchong/ruchernchong-patch-1
Update ci.yml
2025-06-03 16:00:18 -07:00
Mike Cao
f6c3ad5aa6 Fixed goals query. 2025-05-31 09:46:36 -07:00
Mike Cao
49bcbfd7f9 New goals page. Upgraded prisma. 2025-05-31 02:11:18 -07:00
Exlaso
0736289ce1 fix: handle unknown location fields in user detection 2025-05-30 11:19:19 +05:30
Exlaso
ebdd9095ab fix: decode location fields in user detection 2025-05-30 11:14:03 +05:30
Mike Cao
99330a1a4d Refactored icons. 2025-05-27 00:50:28 -07:00
Mike Cao
18eceee4c4 Updated SVG generation. 2025-05-26 23:13:15 -07:00
Mike Cao
4552256930 Goals components. Removed some completed reports. 2025-05-25 08:58:38 -07:00
Mike Cao
7662b77ce3 Added revenue screen. 2025-05-24 17:08:47 -07:00
Ru Chern Chong
e8f166cc69
Update ci.yml
Only run the CI if it belongs to the original repository
2025-05-22 15:19:34 +08:00
Eritque arcus
33110a44ec
fix: fix remove trailing slash regex 2025-05-22 00:24:48 -05:00
Eritque arcus
8d483d9283
fix: hash is not included in record 2025-05-22 00:19:50 -05:00
Mike Cao
bce6737f29 Added retention screen. 2025-05-21 19:19:43 -07:00
Mike Cao
d0d11225f4 Converted UTM report to a view. 2025-05-20 21:25:06 -07:00
Mike Cao
06f76dda13 Refactored website components. New layout. 2025-05-20 01:12:07 -07:00
Mike Cao
6e41ba2e2c New website layout. 2025-05-18 03:34:37 -07:00
Mike Cao
b04077db02
Merge pull request #3429 from monyasau/patch-1
Correct example description for Umami version in bug report template
2025-05-15 12:50:13 -07:00
360
68fab48ab7
fix: correct example description for Umami version in bug report template 2025-05-15 10:13:07 +01:00
Mike Cao
c5086be6eb Updated column widths. 2025-05-14 15:29:03 -07:00
Mike Cao
1c22c18de5 New menu layout. 2025-05-14 13:31:07 -07:00
Mike Cao
0cfee43814 Merge branch 'master' into jajaja 2025-05-12 20:55:46 -07:00
Mike Cao
12cf66861c Merge branch 'master' of https://github.com/umami-software/umami 2025-05-12 00:01:42 -07:00
Mike Cao
907a6850db Update migration script. 2025-05-12 00:01:24 -07:00
Mike Cao
7aa0c83e66 Updated migration script. 2025-05-11 23:54:22 -07:00
Mike Cao
6ced493c22
Merge pull request #3414 from umami-software/dev
v2.18.1
2025-05-11 23:07:13 -07:00
Mike Cao
6235aaf1c7 Merge branch 'dev' into analytics 2025-05-09 23:03:40 -07:00
Mike Cao
42be91b736 Bump version v2.18.1. 2025-05-09 23:03:16 -07:00
Mike Cao
ba2f74c6ca Removed mysql schema. 2025-05-09 22:06:39 -07:00
Mike Cao
94b4b66a3d Merge branch 'dev' into jajaja
# Conflicts:
#	package.json
#	pnpm-lock.yaml
2025-05-09 21:56:07 -07:00
Mike Cao
f91dc8e73d Merge branch 'dev' into analytics 2025-05-09 21:48:42 -07:00
Mike Cao
b93bcecd7b Fixed data migration script. 2025-05-09 21:47:44 -07:00
Mike Cao
75d4614a9d Ignore generated folder used by Prisma. 2025-05-09 20:11:06 -07:00
Mike Cao
d18b0271c9 Merge branch 'analytics' of https://github.com/umami-software/umami into analytics 2025-05-09 20:05:14 -07:00
Mike Cao
0cdb374130 Merge branch 'dev' into analytics 2025-05-09 20:04:28 -07:00
Mike Cao
97381f300a Fixed wrong Prisma version in Docker. 2025-05-09 17:16:24 -07:00
Mike Cao
3f1ecf4c1b Fixed identify. Closes #3409 2025-05-09 16:54:49 -07:00
Mike Cao
d3977eef7d
Merge pull request #3406 from tsykin/master
fix: Incorrect Channel Metrics caused by missing ReferrerQuery data
2025-05-09 17:27:51 -05:00
Mike Cao
3e01c7732b
Merge pull request #3405 from Maxime-J/fix-docker-manifest
Fix customized docker image issue
2025-05-09 16:46:08 -05:00
Maxime-J
ed8cac4a3b Consider base path in set-routes-manifest 2025-05-09 14:48:45 +02:00
tsykin
c23f08fd23 changed sql query for channels metrics due to missing referrer_query data 2025-05-09 14:37:27 +02:00
Francis Cao
5b144e0953 Merge branch 'dev' of https://github.com/umami-software/umami into analytics 2025-05-08 10:34:51 -07:00
Francis Cao
edbe52611e fix session activity order 2025-05-08 10:31:25 -07:00
Francis Cao
d2a3ed732a fix realtime activity ordering 2025-05-08 10:04:21 -07:00
Francis Cao
51d6f88a21 Merge branch 'dev' of https://github.com/umami-software/umami into analytics 2025-05-08 09:17:19 -07:00
Francis Cao
98eb26fd9e fixed getAttribution table alias typo 2025-05-08 09:15:27 -07:00
Francis Cao
3b24ea3175 remove split code 2025-05-08 09:06:27 -07:00
Francis Cao
cd532fd53d fix minute x-axis date labels 2025-05-08 09:05:44 -07:00
Mike Cao
1552a3f2f1 Merge branch 'dev' 2025-05-08 00:13:59 -07:00
Mike Cao
4d54f50739 PR fixes. 2025-05-08 00:12:44 -07:00
Mike Cao
f5a8be5add Fixed README. 2025-05-07 23:30:09 -07:00
Mike Cao
f7593718dc
Merge pull request #3392 from umami-software/dev
v2.18.0
2025-05-07 19:10:40 -05:00
Mike Cao
1ed74d5769 Merge branch 'dev' into analytics 2025-05-07 16:17:16 -07:00
Mike Cao
64505bb417 Added before-send attribute to tracker. 2025-05-07 16:16:38 -07:00
Mike Cao
36b3233d4e Merge branch 'dev' into analytics 2025-05-07 14:40:47 -07:00
Mike Cao
1a794a8520 Updated language build. 2025-05-07 13:40:21 -07:00
Mike Cao
3004c37ccf Updated settings components. 2025-05-07 12:33:53 -07:00
Mike Cao
a15c7cd596 Updated tables. Added MenuButton. 2025-05-07 04:10:27 -07:00
Mike Cao
519395c033
Merge pull request #3386 from gjelbrim/fix/display-kosovo-correctly
Fix: Display Kosovo Correctly
2025-05-07 00:08:34 -05:00
Mike Cao
3e9a7ee9ad
Merge pull request #3381 from YektaDev/script-simplification
Script Simplification
2025-05-05 19:19:26 -05:00
Mike Cao
9101f8a478
Merge branch 'dev' into script-simplification 2025-05-05 18:59:11 -05:00
Mike Cao
92b283486e Updated menus, chart tooltips, styles. 2025-05-05 01:36:16 -07:00
Ali Khaleqi Yekta
9b9cf32ee7
Script simplification: Final minor cleanups 2025-05-04 12:24:23 +03:30
Ali Khaleqi Yekta
5369144b64
Script simplification: Less nesting 2025-05-04 12:18:49 +03:30
Ali Khaleqi Yekta
b26fc15fa0
Script simplification: Greatly clarify element tracking logic 2025-05-04 12:17:08 +03:30
Ali Khaleqi Yekta
671dcfceb5
Script simplification: Use Element.closest + less nesting 2025-05-04 12:13:15 +03:30
Ali Khaleqi Yekta
e12e5b0d2e
Script simplification: In-place headers + re-order 2025-05-04 12:12:23 +03:30
Gjelbrim Haskaj
5974a3672d
Merge branch 'dev' into fix/display-kosovo-correctly 2025-05-04 02:26:05 +02:00
Gjelbrim Haskaj
f4781169cc
Update public/intl/country/sv-SE.json
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-04 02:25:50 +02:00
Gjelbrim Haskaj
946a71fd87
Update public/intl/country/nb-NO.json
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-04 02:25:43 +02:00
Gjelbrim Haskaj
03ba2819cb
Update public/intl/country/de-DE.json
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-04 02:25:33 +02:00
Gjelbrim Haskaj
6595978522
Update country JSONs file to include Kosovo (XK) 2025-05-04 01:35:37 +02:00
Gjelbrim Haskaj
a6f4270303
Updated Kosovo ID in datamaps.world.json from "-99" to "XKX" 2025-05-04 01:34:55 +02:00
Mike Cao
0a16ab38e4 Reworked settings screens. 2025-05-03 00:31:37 -07:00
Mike Cao
c1d301ffdc Fixed realtime page. 2025-05-02 15:20:20 -07:00
Mike Cao
65ebd736b9 Merged compare logic. Removed compare page. 2025-05-02 12:32:23 -07:00
Ali Khaleqi Yekta
1f36726f73
Minor enhancements and clarifications 2025-05-01 18:34:18 +03:30
Ali Khaleqi Yekta
130c024c3e
Simplify title: No need to observe 2025-05-01 17:33:46 +03:30
Mike Cao
f69f793b87 Fixed script. 2025-05-01 04:39:52 -07:00
Mike Cao
6594c31a70 Use esbuild to build prisma client. 2025-05-01 04:38:43 -07:00
Mike Cao
63e0873b5d Use generated prisma client. 2025-05-01 04:24:56 -07:00
Mike Cao
c0ccffeab4 Merge branch 'dev' into jajaja
# Conflicts:
#	pnpm-lock.yaml
#	postcss.config.js
#	src/app/(main)/websites/[websiteId]/sessions/SessionsDataTable.tsx
#	src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionInfo.tsx
2025-05-01 03:31:51 -07:00
Mike Cao
aa5fa0a07e Merge branch 'dev' into analytics 2025-05-01 00:49:34 -07:00
Mike Cao
63a0460ab7 Updated packages. Next 15.3.1. Prisma 6.7.0. 2025-05-01 00:35:10 -07:00
Mike Cao
64d4418d94 Merge branch 'dev' into analytics 2025-05-01 00:14:18 -07:00
Mike Cao
211e1826da Fixed import again. 2025-04-30 21:36:31 -07:00
Mike Cao
8ccaeb96b6 Fixed import. 2025-04-30 21:31:00 -07:00
Mike Cao
a97752545d Merge remote-tracking branch 'origin/dev' into dev 2025-04-30 21:28:11 -07:00
Mike Cao
e89cf9e930 Removed generated prisma. 2025-04-30 21:28:02 -07:00
Mike Cao
665a60dbc2 Updated session details. 2025-04-30 20:18:36 -07:00
Mike Cao
039dcd96e6 Theme change. Render custom date ranges. 2025-04-30 19:54:24 -07:00
Mike Cao
54dbb43b5c Merge branch 'dev' into analytics 2025-04-30 10:09:05 -07:00
Francis Cao
f522db44f9 add distinct ID to session info, add logic for /undefined 2025-04-29 15:26:08 -07:00
Mike Cao
4e37e10b6d Switched to type: module. 2025-04-29 14:36:52 -07:00
Mike Cao
615a6d444f Updated script requires. 2025-04-29 14:16:20 -07:00
Mike Cao
ec7d5bdfe2 Fixed build. 2025-04-29 14:04:55 -07:00
Mike Cao
13755417b1 Fixed build. 2025-04-29 13:53:14 -07:00
Mike Cao
848f8d3ecf Fixed build. Updated packages. 2025-04-29 13:42:36 -07:00
Mike Cao
b3e1aef4ef Added workspace file. 2025-04-29 10:41:12 -07:00
Mike Cao
510503045b Prisma stuff. 2025-04-29 10:39:48 -07:00
Mike Cao
73b45a9f5e Replaced __dirname usage. 2025-04-29 09:53:11 -07:00
Francis Cao
de54290af6 add distinct id to saves and fix schema mapping 2025-04-29 09:31:46 -07:00
Francis Cao
c5efc27c07 distinct_id schema changes and search on sessions page 2025-04-29 08:57:58 -07:00
Mike Cao
b5efbbbb2e Missing package. 2025-04-28 23:41:42 -07:00
Mike Cao
6a29f2ef6f Prisma generation. 2025-04-28 23:37:45 -07:00
Mike Cao
c969603001 Converted global to globalThis. 2025-04-28 23:05:18 -07:00
Mike Cao
886b7e9e56 Revert check-db. 2025-04-28 21:27:26 -07:00
Mike Cao
9d3c926d69 Removed prisma config. 2025-04-28 21:24:57 -07:00
Mike Cao
21367e166e Updated check-db. 2025-04-28 21:21:04 -07:00
Mike Cao
6f551d5e0d Removed prisma config. 2025-04-28 21:04:25 -07:00
Mike Cao
fc6aa80176 Updated prisma config. 2025-04-28 20:59:06 -07:00
Mike Cao
fe2fcf2082 Removed files. 2025-04-28 20:52:22 -07:00
Mike Cao
d667fd5fbe Removed workspace file. 2025-04-28 20:45:09 -07:00
Mike Cao
335f775d66 Updated packages. 2025-04-28 20:42:22 -07:00
Mike Cao
be1b2fc272 Merge dev. 2025-04-28 20:09:58 -07:00
Francis Cao
901a6c558a add data migration scripts 2025-04-28 16:56:49 -07:00
Mike Cao
5aaff55a70 Use custom path for generated Prisma client. 2025-04-28 16:51:24 -07:00
Mike Cao
5cbf5a567c Upgrade Prisma v6.6.0. 2025-04-26 21:25:55 -07:00
Mike Cao
be3972bfb6 Removed yarn references. 2025-04-26 11:11:22 -07:00
Mike Cao
79b4c1312e Merge branch 'dev' into analytics 2025-04-25 21:59:57 -07:00
Mike Cao
d44be466d8 Changed session id generation. 2025-04-25 21:48:59 -07:00
Mike Cao
d4b786380b Events filtering. Closes #3356 2025-04-25 18:06:41 -07:00
Mike Cao
b8a582c8da Fixed events search. Closes #3329 2025-04-25 14:18:23 -07:00
Mike Cao
84f7032f8e Merge remote-tracking branch 'origin/dev' into dev 2025-04-25 13:59:50 -07:00
Mike Cao
02f0df3a2e Allow custom favicon URL. Closes #3365 2025-04-25 13:59:23 -07:00
Francis Cao
9ca5ce1812 fix region constant 2025-04-25 10:54:07 -07:00
Mike Cao
dcd04e8572 Merge branch 'analytics' into dev 2025-04-25 10:25:05 -07:00
Mike Cao
ffa8d8dd88 Merge remote-tracking branch 'origin/dev' into dev 2025-04-25 03:20:00 -07:00
Mike Cao
e8a933f80e Updated id logic. 2025-04-25 03:19:37 -07:00
Francis Cao
f659450f99 Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-04-24 22:42:44 -07:00
Francis Cao
12b8ac4272 app and db schema - region rename, hostname move 2025-04-24 22:42:33 -07:00
Mike Cao
340cdce1dc Dockerfile tweaks. 2025-04-24 19:23:10 -07:00
Mike Cao
0fd2d09dba
Merge pull request #3334 from perso182/props-in-session-definition
Use the props passed to identify to determine sessions
2025-04-24 19:22:24 -07:00
Mike Cao
5dccca0c3f
Merge pull request #3360 from thomasdn/master
Added support for deployment using podman
2025-04-23 16:43:01 -07:00
Mike Cao
48f5465334 Removed version endpoint. 2025-04-23 16:40:14 -07:00
Mike Cao
5be38adf7a Switched to pnpm from yarn. 2025-04-23 16:38:52 -07:00
Mike Cao
466316fb31 Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-04-22 23:20:24 -07:00
Mike Cao
5cfaffa3ff
Merge pull request #3363 from Maxime-J/docker-rewrites
Replace Docker middleware
2025-04-22 23:18:41 -07:00
Mike Cao
c0ff7a31a4 Updated lang. 2025-04-22 23:09:17 -07:00
Mike Cao
54380dd929
Merge pull request #3364 from Maxime-J/fr-update
Update fr-FR
2025-04-22 23:07:05 -07:00
Mike Cao
48b6dfe72f Fixed realtime activity sort. Closes #3330 2025-04-22 23:01:37 -07:00
Mike Cao
afad255e5b t Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-04-22 22:20:26 -07:00
Francis Cao
e44992fb2b add missing import 2025-04-22 07:45:19 -07:00
Francis Cao
7a0765fb4b add missing import 2025-04-22 07:44:43 -07:00
Mike Cao
b6ba1d4ca8 Fixed auth verify method. Closes #3339 2025-04-21 22:25:40 -07:00
Mike Cao
8d3aad8454 Fixed formatRegion method. Closes #3344 2025-04-21 22:07:38 -07:00
Mike Cao
337a5b6e33 Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-04-21 21:42:48 -07:00
Maxime-J
8cc0860b64 Update fr-FR 2025-04-21 14:24:21 +02:00
Maxime-J
b88432fcf4 Change Docker handling of custom rewrites 2025-04-21 12:42:36 +02:00
Maxime-J
3b5e1da39e Replace deprecated Docker config 2025-04-21 08:58:35 +02:00
Maxime-J
b542dc265a Remove unnecessary Dockerfile steps 2025-04-21 08:55:51 +02:00
Mike Cao
52e1440089 Custom date range select. 2025-04-19 10:09:59 -07:00
Francis Cao
88d658f72e resolve psql/mysql attribution bugs and optimize queries 2025-04-17 15:23:48 -07:00
thomasdn
bf01817cd4 Fixed typo in README.md 2025-04-17 19:08:25 +02:00
thomasdn
05f0e7ba76 Added support for deployment using podman 2025-04-17 18:36:56 +02:00
Mike Cao
afb8fd3894 Updated Next. 2025-04-16 21:29:47 -07:00
Mike Cao
cffddd2073
Merge pull request #3351 from God-2077/umami
Update zh-CN translations
2025-04-16 13:27:01 -07:00
Francis Cao
5280fb4310 optimize attribution report 2025-04-15 15:58:49 -07:00
Mike Cao
e79f4717e7 Updated filter params logic. Added inline compare dates. 2025-04-15 15:32:25 -07:00
Francis Cao
b97a790acd temp remove attribution report 2025-04-15 10:37:04 -07:00
Francis Cao
e648b4178f udpate oss attribution logic 2025-04-15 10:36:03 -07:00
Mike Cao
caae77c576 Merge branch 'dev' into analytics 2025-04-15 10:05:47 -07:00
Mike Cao
b192d90aaf Added missing files. 2025-04-14 14:49:33 -07:00
Mike Cao
2c4c99f069 Updated report icon. Removed failing test. 2025-04-14 14:43:16 -07:00
Francis Cao
e7fc482a30 add mysql/psql migrations for utm/click IDs 2025-04-14 13:12:06 -07:00
Francis Cao
7ffb3f7b52 update send and saveEvent with utm/clickIds 2025-04-13 21:45:26 -07:00
Francis Cao
e51ec70093 fix ch migration script 2025-04-13 18:46:53 -07:00
Francis Cao
3da61989b7 fix sorting on UTM queries, add more ads in case logic 2025-04-13 18:31:59 -07:00
Francis Cao
40ca861c69 Merge branch 'feat/attribution-report' into dev 2025-04-13 18:17:43 -07:00
Francis Cao
b9a2145766 ch attribution report, schema changes, and migration 2025-04-13 18:12:03 -07:00
Mike Cao
65e46a1885
Merge pull request #3350 from Maxime-J/fix-netlify
Fix Netlify and possible other cache issues
2025-04-12 18:48:04 -07:00
Kissablecho
f0c6a9713c
Update zh-CN translations 2025-04-12 23:39:54 +08:00
Maxime-J
edaa30f7b1 Add Cache-Control header to api responses 2025-04-12 15:21:51 +02:00
Francis Cao
9708915c45 update role to optional for user update 2025-04-11 07:30:59 -07:00
Francis Cao
e1a5a610bb update role to optional for user update 2025-04-11 07:30:21 -07:00
Mike Cao
bfdd3f9525 New filter bar and filter edit form. 2025-04-09 21:15:12 -07:00
Mike Cao
2f77e15bbc Bump version v2.18.0. 2025-04-08 08:47:50 -07:00
Mike Cao
47e89afcb4 Updated packages. 2025-04-06 15:42:45 -07:00
Mike Cao
1d24e23a34 Updated grid layouts. Fixed chart tooltip. 2025-04-06 08:13:55 -07:00
Mike Cao
96c2c32d14 Website header updates. 2025-04-04 23:26:52 -07:00
Mike Cao
2b99274895 Updated filter bar. 2025-04-02 23:18:03 -05:00
Mike Cao
34a8fa100c Updated theme handling. 2025-04-01 22:58:38 -05:00
perso182
d966668257 Added type check for id 2025-04-01 16:56:17 +02:00
perso182
37ae0374d8 Added id as a parameter to identify and include it in the payload. Removed the usage of localstorage 2025-04-01 11:24:06 +02:00
Mike Cao
c71e9b5707 Merge branch 'dev' into jajaja
# Conflicts:
#	package.json
#	yarn.lock
2025-03-31 23:31:09 -05:00
Mike Cao
97b7a14a29 Fix test. 2025-03-31 22:49:34 -05:00
Mike Cao
0ad58ec07c
Merge pull request #3323 from Cibiyanna26/auth-test
Added tests for /lib/charts
2025-03-31 20:25:36 -05:00
Mike Cao
33c5a0f7e9
Merge pull request #3338 from astappiev/fix-batch
fix: move isbot check after body parsing
2025-03-31 20:23:13 -05:00
Mike Cao
a9dbd9a646
Merge pull request #3333 from Maxime-J/dev
Match CORS config in Docker middleware
2025-03-31 20:20:42 -05:00
Oleh Astappiev
eafd08b4ee
fix: move isbot check after body parsing 2025-03-31 22:56:52 +02:00
perso182
224961447c Refactored index.js 2025-03-31 11:04:57 +02:00
perso182
109e8d6d31 Added error handling for JSON.parse 2025-03-31 10:14:31 +02:00
perso182
2c80aa0b24 Use props passed to identify to define session 2025-03-28 11:02:56 +01:00
Maxime-J
7f9f4957d3 Update Docker middleware 2025-03-28 08:58:21 +01:00
Mike Cao
acbcd05190
Merge pull request #3331 from YoSev/fix-dockerCors
fix(docker): add cors support when using a custom endpoint
2025-03-27 21:01:32 -07:00
Mike Cao
7d2c361725 Fixed field parameters. 2025-03-27 15:33:24 -07:00
Yo Sev
53d6adf299 fix(docker): add cors support when using a custom endpoint 2025-03-27 08:59:21 +01:00
Mike Cao
0f6cdf8b80 Updated reports components. 2025-03-26 21:54:23 -07:00
Mike Cao
f5bc3dc6c2 Panels redesign. 2025-03-25 14:47:51 -07:00
Cibiyanna26
42739c660e modifing yyy label, spy reset after each test gets finished 2025-03-25 14:01:03 +05:30
Mike Cao
bc2518a369
Merge pull request #3306 from harryo/bugfix/other-domain-groups
Fix counting _other domain groups
2025-03-24 20:20:55 -07:00
Mike Cao
5d01d778aa
Merge pull request #3322 from umami-software/dependabot/npm_and_yarn/next-15.2.3
Bump next from 15.0.4 to 15.2.3
2025-03-24 20:17:44 -07:00
Mike Cao
501d7aba5f
Merge pull request #3305 from harryo/bugfix/fix_key
Fix key in SessionActivity
2025-03-24 20:16:20 -07:00
Mike Cao
6a6b9df36a
Merge pull request #3304 from harryo/bugfix/localized
Bugfix/localized
2025-03-24 20:15:17 -07:00
Cibiyanna26
85d89de072 Added tests for /lib/charts 2025-03-23 13:24:41 +05:30
Mike Cao
7886c3f393 Renamed query hooks. Fixed conversion bugs. 2025-03-22 03:48:18 -07:00
Mike Cao
adca3c36d0 Moved collapse button. 2025-03-22 01:31:51 -07:00
dependabot[bot]
4888ecbcee
Bump next from 15.0.4 to 15.2.3
Bumps [next](https://github.com/vercel/next.js) from 15.0.4 to 15.2.3.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.0.4...v15.2.3)

---
updated-dependencies:
- dependency-name: next
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-21 16:00:37 +00:00
Mike Cao
5d2c1e27c2 Added Panel component. New color scheme. 2025-03-20 23:12:56 -07:00
Francis Cao
64dcc5af80 add attribution report params 2025-03-20 09:09:28 -07:00
Mike Cao
a7dad20d8a Merge branch 'dev' into jajaja
# Conflicts:
#	package.json
#	pnpm-lock.yaml
2025-03-20 01:00:33 -07:00
Mike Cao
a3fb27a0db Fixed error messages. 2025-03-19 23:52:44 -07:00
Mike Cao
f5c4e1b46e Layout changes. 2025-03-19 19:50:45 -07:00
Francis Cao
203e782530 Create attribution report template and parameters 2025-03-18 10:00:23 -07:00
Mike Cao
16f1b15dee Added search to settings. 2025-03-16 22:12:13 -07:00
Mike Cao
efd4f4ca00 Small fixes. 2025-03-15 20:34:42 -07:00
Mike Cao
5536e0b7e7 Scrollable content area. 2025-03-13 19:49:04 -07:00
Mike Cao
a9ba2504d7 Use FloatingTooltip from zen. 2025-03-13 17:52:45 -07:00
Mike Cao
e7163c4e7e Updated channel logic. 2025-03-13 13:38:08 -07:00
Mike Cao
556cc1b205 Updated channel logic. 2025-03-13 13:36:54 -07:00
Mike Cao
b5078e3fcc Package updates. 2025-03-13 10:34:14 -07:00
Harry Oosterveen
5120805e0b Fix counting _other domain groups 2025-03-12 20:51:39 +01:00
Harry Oosterveen
32d44e6c65 Fix key in SessionActivity
There is no eventId
2025-03-12 20:50:32 +01:00
Harry Oosterveen
fa15a470fd Localized date and time in charts 2025-03-12 20:49:12 +01:00
Harry Oosterveen
1aa213d342 Localized time in SessionActivity 2025-03-12 20:49:12 +01:00
Francis Cao
a407ff4693 add api-testing to cypress tests 2025-03-12 10:32:54 -07:00
Mike Cao
e1e6493dec Lint fixes. 2025-03-08 08:40:41 -08:00
Mike Cao
c948bbca12 Merge branch 'jajaja' of https://github.com/umami-software/umami into jajaja 2025-03-08 08:09:18 -08:00
Mike Cao
b331da193f Merge branch 'dev' into jajaja 2025-03-08 07:25:40 -08:00
Mike Cao
38ab685143 Merge branch 'dev' 2025-03-07 21:46:44 -08:00
Mike Cao
abde966647 Fixed wrong country lookup. 2025-03-07 21:41:02 -08:00
Mike Cao
36c4645e5b
Merge pull request #3294 from umami-software/analytics
v2.17.0
2025-03-07 21:23:42 -08:00
Mike Cao
97c687ff05 Fixed group referrers count. Closes #3257 2025-03-07 20:29:31 -08:00
Mike Cao
833de1a1af Added decoding to URL elements. 2025-03-07 18:42:15 -08:00
Mike Cao
1b21f264b0 Added more paid ad params. Closes #3270 2025-03-07 13:37:19 -08:00
Francis Cao
3c1ea69a39 Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-03-07 13:06:47 -08:00
Francis Cao
b1901c7278 update cypress tests, update zod validation error messaging to UI 2025-03-07 13:06:38 -08:00
Mike Cao
b4be6cb221 More conversions. 2025-03-07 12:21:20 -08:00
Mike Cao
5999bf6256 Zen components conversion. 2025-03-07 03:11:58 -08:00
Mike Cao
21a1487735
Merge pull request #3292 from Maxime-J/journey-report-fix
Fix journey report
2025-03-06 14:47:11 -08:00
Maxime-J
51f2a1c431 Make journey report steps optional 2025-03-06 15:41:27 +01:00
Mike Cao
1205fc8c01 Merge branch 'jajaja' of https://github.com/umami-software/umami into jajaja 2025-03-05 16:31:00 -08:00
Mike Cao
aac1a12e51 Fixed exports. 2025-03-03 19:25:39 -08:00
Mike Cao
5682b4d217 Build svg into components. 2025-03-03 18:37:49 -08:00
Francis Cao
72ac97c5d9 fix unique key prop error on forms 2025-03-03 12:24:54 -08:00
Mike Cao
cfc3662c29 Merge branch 'dev' of https://github.com/umami-software/umami into dev 2025-03-01 20:28:08 -08:00
Mike Cao
c52774c787 Bump version 2.17.0. 2025-03-01 20:27:31 -08:00
Mike Cao
fdc73268b7 Merge branch 'dev' into jajaja 2025-03-01 17:31:30 -08:00
Mike Cao
cb7eef200c Added check for do not track to tracker. 2025-03-01 17:18:46 -08:00
Mike Cao
925c756215 Updated salt methods. 2025-03-01 16:29:35 -08:00
Mike Cao
0a5a79e046
Merge pull request #3157 from DavidVentura/allowCreatedDate
Allow populating event's createdAt on the send endpoint
2025-03-01 15:22:56 -08:00
Mike Cao
f3ad9a3146
Merge branch 'dev' into allowCreatedDate 2025-03-01 15:21:06 -08:00
Mike Cao
65f18d12ab Added timestamp property to payload. 2025-03-01 14:40:37 -08:00
David Ventura
30b28793cf Allow populating event's createdAt on the send endpoint 2025-03-01 12:04:16 +01:00
Mike Cao
9a87442870 Added SKIP_DB_MIGRATION var. 2025-02-28 21:04:53 -08:00
Mike Cao
05db1a8ba2 Removed css rule. Fixes #3272 2025-02-28 17:37:56 -08:00
Mike Cao
a8835f385e Refactored batch route. 2025-02-28 16:58:57 -08:00
Mike Cao
3f00d88668
Merge pull request #3282 from LouisVallat/dev
add CORS headers to any value of COLLECT_API_ENDPOINT in addition to /api/* endpoints
2025-02-28 15:24:28 -08:00
Louis Vallat
0d153a27dc
feat: add CORS headers to any value of COLLECT_API_ENDPOINT in addition to /api/* endpoints
Signed-off-by: Louis Vallat <contact@louis-vallat.dev>
2025-03-01 00:01:53 +01:00
Mike Cao
bf9a069aa0
Merge pull request #3274 from harryo/master
Fix duplicate key errors
2025-02-28 14:13:11 -08:00
Mike Cao
f166a01b2a
Merge pull request #3275 from zeroCoder1/master
Enhance Batch Processing by Reusing Existing Event Handling Logic
2025-02-28 13:59:37 -08:00
Mike Cao
75009f7e76
Merge pull request #3278 from harryo/bugfix/error-with-referrer
Fix https://github.com/umami-software/umami/issues/3255
2025-02-28 13:56:54 -08:00
Harry Oosterveen
4c45285010 Fix https://github.com/umami-software/umami/issues/3255 2025-02-27 14:47:46 +01:00
Shrutesh
796f6d448c
Update batch.ts 2025-02-26 11:49:33 +05:30
Harry Oosterveen
4e307ba985 Add keys for RealTime Session events 2025-02-25 13:17:53 +01:00
Harry Oosterveen
bdeaa9e5c6 Fix duplicate key errors 2025-02-25 12:33:02 +01:00
Mike Cao
14077167ea Merge branch 'dev' into jajaja 2025-02-22 23:36:33 -05:00
Mike Cao
75b0b2e677 Make user id optional. 2025-02-22 08:09:01 -08:00
Mike Cao
5c988ab5ff Merge branch 'dev' into jajaja 2025-02-21 20:04:04 -08:00
Mike Cao
b5c6194f36 Converted user and website settings. 2025-02-21 16:55:05 -08:00
Mike Cao
4c24e54fdd Consistent error responses. Updated login page. 2025-02-20 09:57:59 -08:00
Mike Cao
88f2ac20bc Updated packages. 2025-02-19 23:39:47 -08:00
Mike Cao
edb7022c55 Merge branch 'dev' into jajaja
# Conflicts:
#	package.json
#	src/components/hooks/useTimezone.ts
#	yarn.lock
2025-02-19 22:55:40 -08:00
Shrutesh Sharma
de8f5c4413 Added batching 2025-02-20 11:11:27 +05:30
Mike Cao
1c5ef97f84 Updated icons. 2025-02-18 20:46:03 -08:00
Mike Cao
b53606d497 Added side nav. 2025-02-16 01:11:45 -08:00
Mike Cao
a8a1ccce18 Added AnimatedDiv component. 2025-02-14 17:16:09 -08:00
Mike Cao
2978bf3c6f Updated packages. 2025-02-14 16:41:48 -08:00
Mike Cao
d2f829a9b2 Merge branch 'dev' into jajaja 2025-02-14 11:45:34 -08:00
Mike Cao
f83a12d6cd Refactor: removed default exports. 2025-02-13 22:53:25 -08:00
Mike Cao
cd944e14ce Merge branch 'dev' into jajaja 2025-02-13 20:22:25 -08:00
Mike Cao
71e4f8f49b Start using react-zen. 2025-02-12 23:34:27 -08:00
1299 changed files with 113644 additions and 38810 deletions

View file

@ -4,4 +4,8 @@ Dockerfile
.gitignore
.DS_Store
node_modules
.idea
.idea
.env
.env.*
scripts/seed
scripts/seed-data.ts

View file

@ -1,46 +0,0 @@
{
"env": {
"browser": true,
"es2020": true,
"node": true,
"jest": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 11,
"sourceType": "module"
},
"extends": [
"plugin:@typescript-eslint/recommended",
"eslint:recommended",
"plugin:prettier/recommended",
"plugin:import/errors",
"plugin:import/typescript",
"plugin:css-modules/recommended",
"plugin:cypress/recommended",
"prettier",
"next"
],
"plugins": ["@typescript-eslint", "prettier", "promise", "css-modules", "cypress"],
"rules": {
"no-console": "error",
"react/display-name": "off",
"react-hooks/exhaustive-deps": "off",
"react/react-in-jsx-scope": "off",
"react/prop-types": "off",
"import/no-anonymous-default-export": "off",
"import/no-named-as-default": "off",
"@next/next/no-img-element": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-unused-vars": ["error", { "ignoreRestSiblings": true }]
},
"globals": {
"React": "writable"
}
}

View file

@ -25,7 +25,7 @@ body:
- type: input
attributes:
label: Which Umami version are you using? (if relevant)
description: 'For example: Chrome, Edge, Firefox, etc'
description: 'For example: 2.18.0, 2.15.1, 1.39.0, etc'
- type: input
attributes:
label: Which browser are you using? (if relevant)

View file

@ -1,4 +1,4 @@
name: Create docker images
name: Create docker images (cloud)
on:
push:

View file

@ -1,58 +0,0 @@
name: Create docker images (manual)
on:
workflow_dispatch:
inputs:
version:
type: string
description: Version
required: true
jobs:
build:
name: Build, push, and deploy
runs-on: ubuntu-latest
strategy:
matrix:
db-type: [postgresql, mysql]
steps:
- uses: actions/checkout@v3
- name: Extract version parts from input
id: extract_version
run: |
echo "version=$(echo ${{ github.event.inputs.version }})" >> $GITHUB_ENV
echo "major=$(echo ${{ github.event.inputs.version }} | cut -d. -f1)" >> $GITHUB_ENV
echo "minor=$(echo ${{ github.event.inputs.version }} | cut -d. -f2)" >> $GITHUB_ENV
- name: Generate tags
id: generate_tags
run: |
echo "tag_major=$(echo ${{ matrix.db-type }}-${{ env.major }})" >> $GITHUB_ENV
echo "tag_minor=$(echo ${{ matrix.db-type }}-${{ env.major }}.${{ env.minor }})" >> $GITHUB_ENV
echo "tag_patch=$(echo ${{ matrix.db-type }}-${{ env.version }})" >> $GITHUB_ENV
echo "tag_latest=$(echo ${{ matrix.db-type }}-latest)" >> $GITHUB_ENV
- uses: mr-smithers-excellent/docker-build-push@v6
name: Build & push Docker image to ghcr.io for ${{ matrix.db-type }}
with:
image: umami
tags: ${{ env.tag_major }}, ${{ env.tag_minor }}, ${{ env.tag_patch }}, ${{ env.tag_latest }}
buildArgs: DATABASE_TYPE=${{ matrix.db-type }}
registry: ghcr.io
multiPlatform: true
platform: linux/amd64,linux/arm64
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: mr-smithers-excellent/docker-build-push@v6
name: Build & push Docker image to docker.io for ${{ matrix.db-type }}
with:
image: umamisoftware/umami
tags: ${{ env.tag_major }}, ${{ env.tag_minor }}, ${{ env.tag_patch }}, ${{ env.tag_latest }}
buildArgs: DATABASE_TYPE=${{ matrix.db-type }}
registry: docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

View file

@ -1,50 +1,100 @@
name: Create docker images
on: [create]
on:
push:
tags:
- 'v*.*.*'
workflow_dispatch:
inputs:
version:
description: 'Optional image version (e.g. 3.0.0, v3.0.0, or 3.0.0-beta.1)'
required: false
default: ''
jobs:
build:
name: Build, push, and deploy
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
runs-on: ubuntu-latest
strategy:
matrix:
db-type: [postgresql, mysql]
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v5
- name: Set env
run: |
echo "NOW=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
- name: Generate tags
id: generate_tags
run: |
echo "tag_patch=$(echo ${{ matrix.db-type }})-${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
echo "tag_minor=$(echo ${{ matrix.db-type }})-$(echo ${GITHUB_REF#refs/tags/} | cut -d. -f1,2)" >> $GITHUB_ENV
echo "tag_major=$(echo ${{ matrix.db-type }})-$(echo ${GITHUB_REF#refs/tags/} | cut -d. -f1)" >> $GITHUB_ENV
echo "tag_latest=$(echo ${{ matrix.db-type }})-latest" >> $GITHUB_ENV
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- uses: mr-smithers-excellent/docker-build-push@v6
name: Build & push Docker image to ghcr.io for ${{ matrix.db-type }}
- name: Log into GHCR
uses: docker/login-action@v3
with:
image: umami
tags: ${{ env.tag_major }}, ${{ env.tag_minor }}, ${{ env.tag_patch }}, ${{ env.tag_latest }}
buildArgs: DATABASE_TYPE=${{ matrix.db-type }}
registry: ghcr.io
multiPlatform: true
platform: linux/amd64,linux/arm64
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: mr-smithers-excellent/docker-build-push@v6
name: Build & push Docker image to docker.io for ${{ matrix.db-type }}
- name: Log into Docker Hub
if: github.repository == 'umami-software/umami'
uses: docker/login-action@v3
with:
image: umamisoftware/umami
tags: ${{ env.tag_major }}, ${{ env.tag_minor }}, ${{ env.tag_patch }}, ${{ env.tag_latest }}
buildArgs: DATABASE_TYPE=${{ matrix.db-type }}
registry: docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Compute version tags
id: compute
run: |
INPUT="${{ github.event.inputs.version }}"
REF_TYPE="${{ github.ref_type }}"
REF_NAME="${{ github.ref_name }}"
# Determine version source
if [[ -n "$INPUT" ]]; then
VERSION="${INPUT#v}"
elif [[ "$REF_TYPE" == "tag" ]]; then
VERSION="${REF_NAME#v}"
else
VERSION=""
fi
TAGS=""
if [[ -n "$VERSION" ]]; then
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
if [[ "$VERSION" == *-* ]]; then
# prerelease: only version tag
TAGS="$VERSION"
else
# stable release: version + hierarchy + latest
TAGS="$VERSION,${MAJOR}.${MINOR},${MAJOR},postgresql-latest,latest"
fi
else
# Non-tag build (e.g. from main branch)
TAGS="${REF_NAME}"
fi
echo "tags=$TAGS" >> $GITHUB_OUTPUT
echo "Computed tags: $TAGS"
- name: Build and push Docker image
run: |
TAGS="${{ steps.compute.outputs.tags }}"
# Set image targets conditionally
if [[ "${{ github.repository }}" == "umami-software/umami" ]]; then
IMAGES=("umamisoftware/umami" "ghcr.io/${{ github.repository }}")
else
IMAGES=("ghcr.io/${{ github.repository }}")
fi
for IMAGE in "${IMAGES[@]}"; do
echo "Building and pushing $IMAGE with tags: $TAGS"
docker buildx build \
--platform linux/amd64,linux/arm64 \
--push \
$(echo "$TAGS" | tr ',' '\n' | sed "s|^|--tag ${IMAGE}:|") \
--cache-from type=gha \
--cache-to type=gha,mode=max \
.
done

View file

@ -1,6 +1,3 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Node.js CI
on: [push]
@ -11,26 +8,30 @@ env:
jobs:
build:
if: github.repository == 'umami-software/umami'
runs-on: ubuntu-latest
strategy:
matrix:
include:
- node-version: 18.18
pnpm-version: 10
db-type: postgresql
- node-version: 18.18
db-type: mysql
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4 # required so that setup-node will work
with:
version: ${{ matrix.pnpm-version }}
run_install: false
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
cache: 'pnpm'
env:
DATABASE_TYPE: ${{ matrix.db-type }}
- run: npm install --global yarn
- run: yarn install
- run: yarn test
- run: yarn build
- run: npm install --global pnpm
- run: pnpm install
- run: pnpm test
- run: pnpm build

9
.gitignore vendored
View file

@ -4,20 +4,23 @@
node_modules
.pnp
.pnp.js
.pnpm-store
package-lock.json
# testing
/coverage
# next.js
/.next/
/out/
/prisma/
/.next
/out
# production
/build
/public/script.js
/geo
/dist
/generated
/src/generated
# misc
.DS_Store

View file

@ -1,4 +1 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged

View file

@ -1 +0,0 @@
/public/script.js

View file

@ -1,7 +0,0 @@
{
"arrowParens": "avoid",
"endOfLine": "lf",
"printWidth": 100,
"singleQuote": true,
"trailingComma": "all"
}

View file

@ -1,11 +1,6 @@
{
"extends": [
"stylelint-config-recommended",
"stylelint-config-css-modules",
"stylelint-config-prettier"
],
"extends": ["stylelint-config-recommended", "stylelint-config-css-modules"],
"rules": {
"no-descending-specificity": null
},
"ignoreFiles": ["**/*.js", "**/*.md"]
}
}

View file

@ -1,53 +1,55 @@
ARG NODE_IMAGE_VERSION="22-alpine"
# Install dependencies only when needed
FROM node:22-alpine AS deps
FROM node:${NODE_IMAGE_VERSION} AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
# Add yarn timeout to handle slow CPU when Github Actions
RUN yarn config set network-timeout 300000
RUN yarn install --frozen-lockfile
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm
RUN pnpm install --frozen-lockfile
# Rebuild the source code only when needed
FROM node:22-alpine AS builder
FROM node:${NODE_IMAGE_VERSION} AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
COPY docker/middleware.js ./src
COPY docker/middleware.ts ./src
ARG DATABASE_TYPE
ARG BASE_PATH
ENV DATABASE_TYPE $DATABASE_TYPE
ENV BASE_PATH $BASE_PATH
ENV BASE_PATH=$BASE_PATH
ENV NEXT_TELEMETRY_DISABLED=1
ENV DATABASE_URL="postgresql://user:pass@localhost:5432/dummy"
ENV NEXT_TELEMETRY_DISABLED 1
RUN yarn build-docker
RUN npm run build-docker
# Production image, copy all the files and run next
FROM node:22-alpine AS runner
FROM node:${NODE_IMAGE_VERSION} AS runner
WORKDIR /app
ARG PRISMA_VERSION="6.19.0"
ARG NODE_OPTIONS
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
ENV NODE_OPTIONS $NODE_OPTIONS
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_OPTIONS=$NODE_OPTIONS
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
RUN set -x \
&& apk add --no-cache curl \
&& yarn add npm-run-all dotenv semver prisma@6.1.0
&& npm install -g pnpm
# Script dependencies
RUN pnpm --allow-build='@prisma/engines' add npm-run-all dotenv chalk semver \
prisma@${PRISMA_VERSION} \
@prisma/adapter-pg@${PRISMA_VERSION}
# You only need to copy next.config.js if you are NOT using the default configuration
COPY --from=builder /app/next.config.js .
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/scripts ./scripts
COPY --from=builder /app/generated ./generated
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
@ -58,7 +60,7 @@ USER nextjs
EXPOSE 3000
ENV HOSTNAME 0.0.0.0
ENV PORT 3000
ENV HOSTNAME=0.0.0.0
ENV PORT=3000
CMD ["yarn", "start-docker"]
CMD ["pnpm", "start-docker"]

View file

@ -9,18 +9,10 @@
</p>
<p align="center">
<a href="https://github.com/umami-software/umami/releases">
<img src="https://img.shields.io/github/release/umami-software/umami.svg" alt="GitHub Release" />
</a>
<a href="https://github.com/umami-software/umami/blob/master/LICENSE">
<img src="https://img.shields.io/github/license/umami-software/umami.svg" alt="MIT License" />
</a>
<a href="https://github.com/umami-software/umami/actions">
<img src="https://img.shields.io/github/actions/workflow/status/umami-software/umami/ci.yml" alt="Build Status" />
</a>
<a href="https://analytics.umami.is/share/LGazGOecbDtaIwDr/umami.is" style="text-decoration: none;">
<img src="https://img.shields.io/badge/Try%20Demo%20Now-Click%20Here-brightgreen" alt="Umami Demo" />
</a>
<a href="https://github.com/umami-software/umami/releases"><img src="https://img.shields.io/github/release/umami-software/umami.svg" alt="GitHub Release" /></a>
<a href="https://github.com/umami-software/umami/blob/master/LICENSE"><img src="https://img.shields.io/github/license/umami-software/umami.svg" alt="MIT License" /></a>
<a href="https://github.com/umami-software/umami/actions"><img src="https://img.shields.io/github/actions/workflow/status/umami-software/umami/ci.yml" alt="Build Status" /></a>
<a href="https://analytics.umami.is/share/LGazGOecbDtaIwDr/umami.is" style="text-decoration: none;"><img src="https://img.shields.io/badge/Try%20Demo%20Now-Click%20Here-brightgreen" alt="Umami Demo" /></a>
</p>
---
@ -35,21 +27,15 @@ A detailed getting started guide can be found at [umami.is/docs](https://umami.i
### Requirements
- A server with Node.js version 18.18 or newer
- A database. Umami supports [MariaDB](https://www.mariadb.org/) (minimum v10.5), [MySQL](https://www.mysql.com/) (minimum v8.0) and [PostgreSQL](https://www.postgresql.org/) (minimum v12.14) databases.
- A server with Node.js version 18.18+.
- A PostgreSQL database version v12.14+.
### Install Yarn
```bash
npm install -g yarn
```
### Get the Source Code and Install Packages
### Get the source code and install packages
```bash
git clone https://github.com/umami-software/umami.git
cd umami
yarn install
pnpm install
```
### Configure Umami
@ -64,47 +50,42 @@ The connection URL format:
```bash
postgresql://username:mypassword@localhost:5432/mydb
mysql://username:mypassword@localhost:3306/mydb
```
### Build the Application
```bash
yarn build
pnpm run build
```
*The build step will create tables in your database if you are installing for the first time. It will also create a login user with username **admin** and password **umami**.*
The build step will create tables in your database if you are installing for the first time. It will also create a login user with username **admin** and password **umami**.
### Start the Application
```bash
yarn start
pnpm run start
```
*By default, this will launch the application on `http://localhost:3000`. You will need to either [proxy](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) requests from your web server or change the [port](https://nextjs.org/docs/api-reference/cli#production) to serve the application directly.*
By default, this will launch the application on `http://localhost:3000`. You will need to either [proxy](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) requests from your web server or change the [port](https://nextjs.org/docs/api-reference/cli#production) to serve the application directly.
---
## 🐳 Installing with Docker
To build the Umami container and start up a Postgres database, run:
Umami provides Docker images as well as a Docker compose file for easy deployment.
Docker image:
```bash
docker pull docker.umami.is/umami-software/umami:latest
```
Docker compose (Runs Umami with a PostgreSQL database):
```bash
docker compose up -d
```
Alternatively, to pull just the Umami Docker image with PostgreSQL support:
```bash
docker pull docker.umami.is/umami-software/umami:postgresql-latest
```
Or with MySQL support:
```bash
docker pull docker.umami.is/umami-software/umami:mysql-latest
```
---
## 🔄 Getting Updates
@ -113,8 +94,8 @@ To get the latest features, simply do a pull, install any new dependencies, and
```bash
git pull
yarn install
yarn build
pnpm install
pnpm build
```
To update the Docker image, simply pull the new images and rebuild:
@ -129,18 +110,10 @@ docker compose up --force-recreate -d
## 🛟 Support
<p align="center">
<a href="https://github.com/umami-software/umami">
<img src="https://img.shields.io/badge/GitHub--blue?style=social&logo=github" alt="GitHub" />
</a>
<a href="https://twitter.com/umami_software">
<img src="https://img.shields.io/badge/Twitter--blue?style=social&logo=twitter" alt="Twitter" />
</a>
<a href="https://linkedin.com/company/umami-software">
<img src="https://img.shields.io/badge/LinkedIn--blue?style=social&logo=linkedin" alt="LinkedIn" />
</a>
<a href="https://umami.is/discord">
<img src="https://img.shields.io/badge/Discord--blue?style=social&logo=discord" alt="Discord" />
</a>
<a href="https://github.com/umami-software/umami"><img src="https://img.shields.io/badge/GitHub--blue?style=social&logo=github" alt="GitHub" /></a>
<a href="https://twitter.com/umami_software"><img src="https://img.shields.io/badge/Twitter--blue?style=social&logo=twitter" alt="Twitter" /></a>
<a href="https://linkedin.com/company/umami-software"><img src="https://img.shields.io/badge/LinkedIn--blue?style=social&logo=linkedin" alt="LinkedIn" /></a>
<a href="https://umami.is/discord"><img src="https://img.shields.io/badge/Discord--blue?style=social&logo=discord" alt="Discord" /></a>
</p>
[release-shield]: https://img.shields.io/github/release/umami-software/umami.svg

65
biome.json Normal file
View file

@ -0,0 +1,65 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.6/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"includes": ["**", "!!**/dist"]
},
"formatter": {
"enabled": true,
"lineWidth": 100,
"indentStyle": "space",
"indentWidth": 2,
"lineEnding": "lf"
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"a11y": "off",
"correctness": {
"useExhaustiveDependencies": "off"
},
"style": {
"noDescendingSpecificity": "off"
},
"complexity": {
"noImportantStyles": "off"
},
"suspicious": {
"noArrayIndexKey": "off",
"noExplicitAny": "off",
"noImplicitAnyLet": "off"
},
"performance": {
"noImgElement": "off"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"trailingCommas": "all",
"arrowParentheses": "asNeeded"
}
},
"css": {
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineEnding": "lf"
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}

View file

@ -8,5 +8,6 @@ export default defineConfig({
env: {
umami_user: 'admin',
umami_password: 'umami',
umami_user_id: '41e2b680-648e-4b09-bcd7-3e2b10c06264',
},
});

209
cypress/e2e/api-team.cy.ts Normal file
View file

@ -0,0 +1,209 @@
describe('Team API tests', () => {
Cypress.session.clearAllSavedSessions();
let teamId;
let userId;
before(() => {
cy.login(Cypress.env('umami_user'), Cypress.env('umami_password'));
cy.fixture('users').then(data => {
const userCreate = data.userCreate;
cy.request({
method: 'POST',
url: '/api/users',
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: userCreate,
}).then(response => {
userId = response.body.id;
expect(response.status).to.eq(200);
expect(response.body).to.have.property('username', 'cypress1');
expect(response.body).to.have.property('role', 'user');
});
});
});
it('Creates a team.', () => {
cy.fixture('teams').then(data => {
const teamCreate = data.teamCreate;
cy.request({
method: 'POST',
url: '/api/teams',
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: teamCreate,
}).then(response => {
teamId = response.body[0].id;
expect(response.status).to.eq(200);
expect(response.body[0]).to.have.property('name', 'cypress');
expect(response.body[1]).to.have.property('role', 'team-owner');
});
});
});
it('Gets a teams by ID.', () => {
cy.request({
method: 'GET',
url: `/api/teams/${teamId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('id', teamId);
});
});
it('Updates a team.', () => {
cy.fixture('teams').then(data => {
const teamUpdate = data.teamUpdate;
cy.request({
method: 'POST',
url: `/api/teams/${teamId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: teamUpdate,
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('id', teamId);
expect(response.body).to.have.property('name', 'cypressUpdate');
});
});
});
it('Get all users that belong to a team.', () => {
cy.request({
method: 'GET',
url: `/api/teams/${teamId}/users`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body.data[0]).to.have.property('id');
expect(response.body.data[0]).to.have.property('teamId');
expect(response.body.data[0]).to.have.property('userId');
expect(response.body.data[0]).to.have.property('user');
});
});
it('Get a user belonging to a team.', () => {
cy.request({
method: 'GET',
url: `/api/teams/${teamId}/users/${Cypress.env('umami_user_id')}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('teamId');
expect(response.body).to.have.property('userId');
expect(response.body).to.have.property('role');
});
});
it('Get all websites belonging to a team.', () => {
cy.request({
method: 'GET',
url: `/api/teams/${teamId}/websites`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('data');
});
});
it('Add a user to a team.', () => {
cy.request({
method: 'POST',
url: `/api/teams/${teamId}/users`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: {
userId,
role: 'team-member',
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('userId', userId);
expect(response.body).to.have.property('role', 'team-member');
});
});
it(`Update a user's role on a team.`, () => {
cy.request({
method: 'POST',
url: `/api/teams/${teamId}/users/${userId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: {
role: 'team-view-only',
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('userId', userId);
expect(response.body).to.have.property('role', 'team-view-only');
});
});
it(`Remove a user from a team.`, () => {
cy.request({
method: 'DELETE',
url: `/api/teams/${teamId}/users/${userId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
});
});
it('Deletes a team.', () => {
cy.request({
method: 'DELETE',
url: `/api/teams/${teamId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('ok', true);
});
});
// it('Gets all teams that belong to a user.', () => {
// cy.request({
// method: 'GET',
// url: `/api/users/${userId}/teams`,
// headers: {
// 'Content-Type': 'application/json',
// Authorization: Cypress.env('authorization'),
// },
// }).then(response => {
// expect(response.status).to.eq(200);
// expect(response.body).to.have.property('data');
// });
// });
after(() => {
cy.deleteUser(userId);
});
});

125
cypress/e2e/api-user.cy.ts Normal file
View file

@ -0,0 +1,125 @@
describe('User API tests', () => {
Cypress.session.clearAllSavedSessions();
before(() => {
cy.login(Cypress.env('umami_user'), Cypress.env('umami_password'));
});
let userId;
it('Creates a user.', () => {
cy.fixture('users').then(data => {
const userCreate = data.userCreate;
cy.request({
method: 'POST',
url: '/api/users',
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: userCreate,
}).then(response => {
userId = response.body.id;
expect(response.status).to.eq(200);
expect(response.body).to.have.property('username', 'cypress1');
expect(response.body).to.have.property('role', 'user');
});
});
});
it('Returns all users. Admin access is required.', () => {
cy.request({
method: 'GET',
url: '/api/admin/users',
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body.data[0]).to.have.property('id');
expect(response.body.data[0]).to.have.property('username');
expect(response.body.data[0]).to.have.property('password');
expect(response.body.data[0]).to.have.property('role');
});
});
it('Updates a user.', () => {
cy.fixture('users').then(data => {
const userUpdate = data.userUpdate;
cy.request({
method: 'POST',
url: `/api/users/${userId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: userUpdate,
}).then(response => {
userId = response.body.id;
expect(response.status).to.eq(200);
expect(response.body).to.have.property('id', userId);
expect(response.body).to.have.property('username', 'cypress1');
expect(response.body).to.have.property('role', 'view-only');
});
});
});
it('Gets a user by ID.', () => {
cy.request({
method: 'GET',
url: `/api/users/${userId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('id', userId);
expect(response.body).to.have.property('username', 'cypress1');
expect(response.body).to.have.property('role', 'view-only');
});
});
it('Deletes a user.', () => {
cy.request({
method: 'DELETE',
url: `/api/users/${userId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('ok', true);
});
});
it('Gets all websites that belong to a user.', () => {
cy.request({
method: 'GET',
url: `/api/users/${userId}/websites`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('data');
});
});
it('Gets all teams that belong to a user.', () => {
cy.request({
method: 'GET',
url: `/api/users/${userId}/teams`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('data');
});
});
});

View file

@ -0,0 +1,198 @@
import { uuid } from '../../src/lib/crypto';
describe('Website API tests', () => {
Cypress.session.clearAllSavedSessions();
let websiteId;
let teamId;
before(() => {
cy.login(Cypress.env('umami_user'), Cypress.env('umami_password'));
cy.fixture('teams').then(data => {
const teamCreate = data.teamCreate;
cy.request({
method: 'POST',
url: '/api/teams',
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: teamCreate,
}).then(response => {
teamId = response.body[0].id;
expect(response.status).to.eq(200);
expect(response.body[0]).to.have.property('name', 'cypress');
expect(response.body[1]).to.have.property('role', 'team-owner');
});
});
});
it('Creates a website for user.', () => {
cy.fixture('websites').then(data => {
const websiteCreate = data.websiteCreate;
cy.request({
method: 'POST',
url: '/api/websites',
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: websiteCreate,
}).then(response => {
websiteId = response.body.id;
expect(response.status).to.eq(200);
expect(response.body).to.have.property('name', 'Cypress Website');
expect(response.body).to.have.property('domain', 'cypress.com');
});
});
});
it('Creates a website for team.', () => {
cy.request({
method: 'POST',
url: '/api/websites',
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: {
name: 'Team Website',
domain: 'teamwebsite.com',
teamId: teamId,
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('name', 'Team Website');
expect(response.body).to.have.property('domain', 'teamwebsite.com');
});
});
it('Creates a website with a fixed ID.', () => {
cy.fixture('websites').then(data => {
const websiteCreate = data.websiteCreate;
const fixedId = uuid();
cy.request({
method: 'POST',
url: '/api/websites',
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: { ...websiteCreate, id: fixedId },
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('id', fixedId);
expect(response.body).to.have.property('name', 'Cypress Website');
expect(response.body).to.have.property('domain', 'cypress.com');
// cleanup
cy.request({
method: 'DELETE',
url: `/api/websites/${fixedId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
});
});
});
});
it('Returns all tracked websites.', () => {
cy.request({
method: 'GET',
url: '/api/websites',
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body.data[0]).to.have.property('id');
expect(response.body.data[0]).to.have.property('name');
expect(response.body.data[0]).to.have.property('domain');
});
});
it('Gets a website by ID.', () => {
cy.request({
method: 'GET',
url: `/api/websites/${websiteId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('name', 'Cypress Website');
expect(response.body).to.have.property('domain', 'cypress.com');
});
});
it('Updates a website.', () => {
cy.fixture('websites').then(data => {
const websiteUpdate = data.websiteUpdate;
cy.request({
method: 'POST',
url: `/api/websites/${websiteId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: websiteUpdate,
}).then(response => {
websiteId = response.body.id;
expect(response.status).to.eq(200);
expect(response.body).to.have.property('name', 'Cypress Website Updated');
expect(response.body).to.have.property('domain', 'cypressupdated.com');
});
});
});
it('Updates a website with only shareId.', () => {
cy.request({
method: 'POST',
url: `/api/websites/${websiteId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: { shareId: 'ABCDEF' },
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('shareId', 'ABCDEF');
});
});
it('Resets a website by removing all data related to the website.', () => {
cy.request({
method: 'POST',
url: `/api/websites/${websiteId}/reset`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('ok', true);
});
});
it('Deletes a website.', () => {
cy.request({
method: 'DELETE',
url: `/api/websites/${websiteId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('ok', true);
});
});
after(() => {
cy.deleteTeam(teamId);
});
});

View file

@ -1,22 +1,36 @@
describe('Login tests', () => {
beforeEach(() => {
cy.visit('/login');
});
it(
'logs user in with correct credentials and logs user out',
{
defaultCommandTimeout: 10000,
},
() => {
cy.visit('/login');
cy.getDataTest('input-username').find('input').click();
cy.getDataTest('input-username').find('input').type(Cypress.env('umami_user'), { delay: 50 });
cy.getDataTest('input-password').find('input').click();
cy.getDataTest('input-username').find('input').as('inputUsername').click();
cy.get('@inputUsername').type(Cypress.env('umami_user'), { delay: 0 });
cy.get('@inputUsername').click();
cy.getDataTest('input-password')
.find('input')
.type(Cypress.env('umami_password'), { delay: 50 });
.type(Cypress.env('umami_password'), { delay: 0 });
cy.getDataTest('button-submit').click();
cy.url().should('eq', Cypress.config().baseUrl + '/dashboard');
cy.getDataTest('button-profile').click();
cy.getDataTest('item-logout').click();
cy.url().should('eq', Cypress.config().baseUrl + '/login');
cy.logout();
},
);
it('login with blank inputs or incorrect credentials', () => {
cy.getDataTest('button-submit').click();
cy.contains(/Required/i).should('be.visible');
cy.getDataTest('input-username').find('input').as('inputUsername');
cy.get('@inputUsername').click();
cy.get('@inputUsername').type(Cypress.env('umami_user'), { delay: 0 });
cy.get('@inputUsername').click();
cy.getDataTest('input-password').find('input').type('wrongpassword', { delay: 0 });
cy.getDataTest('button-submit').click();
cy.contains(/Incorrect username and\/or password./i).should('be.visible');
});
});

65
cypress/e2e/user.cy.ts Normal file
View file

@ -0,0 +1,65 @@
describe('User tests', () => {
Cypress.session.clearAllSavedSessions();
beforeEach(() => {
cy.login(Cypress.env('umami_user'), Cypress.env('umami_password'));
cy.visit('/settings/users');
});
it('Add a User', () => {
// add user
cy.contains(/Create user/i).should('be.visible');
cy.getDataTest('button-create-user').click();
cy.getDataTest('input-username').find('input').as('inputName').click();
cy.get('@inputName').type('Test-user', { delay: 0 });
cy.getDataTest('input-password').find('input').as('inputPassword').click();
cy.get('@inputPassword').type('testPasswordCypress', { delay: 0 });
cy.getDataTest('dropdown-role').click();
cy.getDataTest('dropdown-item-user').click();
cy.getDataTest('button-submit').click();
cy.get('td[label="Username"]').should('contain.text', 'Test-user');
cy.get('td[label="Role"]').should('contain.text', 'User');
});
it('Edit a User role and password', () => {
// edit user
cy.get('table tbody tr')
.contains('td', /Test-user/i)
.parent()
.within(() => {
cy.getDataTest('link-button-edit').click(); // Clicks the button inside the row
});
cy.getDataTest('input-password').find('input').as('inputPassword').click();
cy.get('@inputPassword').type('newPassword', { delay: 0 });
cy.getDataTest('dropdown-role').click();
cy.getDataTest('dropdown-item-viewOnly').click();
cy.getDataTest('button-submit').click();
cy.visit('/settings/users');
cy.get('table tbody tr')
.contains('td', /Test-user/i)
.parent()
.should('contain.text', 'View only');
cy.logout();
cy.url().should('eq', Cypress.config().baseUrl + '/login');
cy.getDataTest('input-username').find('input').as('inputUsername').click();
cy.get('@inputUsername').type('Test-user', { delay: 0 });
cy.get('@inputUsername').click();
cy.getDataTest('input-password').find('input').type('newPassword', { delay: 0 });
cy.getDataTest('button-submit').click();
cy.url().should('eq', Cypress.config().baseUrl + '/dashboard');
});
it('Delete a user', () => {
// delete user
cy.get('table tbody tr')
.contains('td', /Test-user/i)
.parent()
.within(() => {
cy.getDataTest('button-delete').click(); // Clicks the button inside the row
});
cy.contains(/Are you sure you want to delete Test-user?/i).should('be.visible');
cy.getDataTest('button-confirm').click();
});
});

View file

@ -10,10 +10,10 @@ describe('Website tests', () => {
cy.visit('/settings/websites');
cy.getDataTest('button-website-add').click();
cy.contains(/Add website/i).should('be.visible');
cy.getDataTest('input-name').find('input').click();
cy.getDataTest('input-name').find('input').type('Add test', { delay: 50 });
cy.getDataTest('input-name').find('input').as('inputUsername').click();
cy.getDataTest('input-name').find('input').type('Add test', { delay: 0 });
cy.getDataTest('input-domain').find('input').click();
cy.getDataTest('input-domain').find('input').type('addtest.com', { delay: 50 });
cy.getDataTest('input-domain').find('input').type('addtest.com', { delay: 0 });
cy.getDataTest('button-submit').click();
cy.get('td[label="Name"]').should('contain.text', 'Add test');
cy.get('td[label="Domain"]').should('contain.text', 'addtest.com');
@ -41,10 +41,10 @@ describe('Website tests', () => {
cy.contains(/Details/i).should('be.visible');
cy.getDataTest('input-name').find('input').click();
cy.getDataTest('input-name').find('input').clear();
cy.getDataTest('input-name').find('input').type('Updated website', { delay: 50 });
cy.getDataTest('input-name').find('input').type('Updated website', { delay: 0 });
cy.getDataTest('input-domain').find('input').click();
cy.getDataTest('input-domain').find('input').clear();
cy.getDataTest('input-domain').find('input').type('updatedwebsite.com', { delay: 50 });
cy.getDataTest('input-domain').find('input').type('updatedwebsite.com', { delay: 0 });
cy.getDataTest('button-submit').click({ force: true });
cy.getDataTest('input-name').find('input').should('have.value', 'Updated website');
cy.getDataTest('input-domain').find('input').should('have.value', 'updatedwebsite.com');

View file

@ -0,0 +1,8 @@
{
"teamCreate": {
"name": "cypress"
},
"teamUpdate": {
"name": "cypressUpdate"
}
}

View file

@ -0,0 +1,11 @@
{
"userCreate": {
"username": "cypress1",
"password": "password",
"role": "user"
},
"userUpdate": {
"username": "cypress1",
"role": "view-only"
}
}

View file

@ -0,0 +1,10 @@
{
"websiteCreate": {
"name": "Cypress Website",
"domain": "cypress.com"
},
"websiteUpdate": {
"name": "Cypress Website Updated",
"domain": "cypressupdated.com"
}
}

View file

@ -5,6 +5,12 @@ Cypress.Commands.add('getDataTest', (value: string) => {
return cy.get(`[data-test=${value}]`);
});
Cypress.Commands.add('logout', () => {
cy.getDataTest('button-profile').click();
cy.getDataTest('item-logout').click();
cy.url().should('eq', Cypress.config().baseUrl + '/login');
});
Cypress.Commands.add('login', (username: string, password: string) => {
cy.session([username, password], () => {
cy.request({
@ -55,3 +61,63 @@ Cypress.Commands.add('deleteWebsite', (websiteId: string) => {
expect(response.status).to.eq(200);
});
});
Cypress.Commands.add('addUser', (username: string, password: string, role: string) => {
cy.request({
method: 'POST',
url: '/api/users',
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: {
username: username,
password: password,
role: role,
},
}).then(response => {
expect(response.status).to.eq(200);
});
});
Cypress.Commands.add('deleteUser', (userId: string) => {
cy.request({
method: 'DELETE',
url: `/api/users/${userId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
});
});
Cypress.Commands.add('addTeam', (name: string) => {
cy.request({
method: 'POST',
url: '/api/teams',
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: {
name: name,
},
}).then(response => {
expect(response.status).to.eq(200);
});
});
Cypress.Commands.add('deleteTeam', (teamId: string) => {
cy.request({
method: 'DELETE',
url: `/api/teams/${teamId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
}).then(response => {
expect(response.status).to.eq(200);
});
});

View file

@ -1,4 +1,5 @@
/// <reference types="cypress" />
/* global JQuery */
declare namespace Cypress {
interface Chainable {
@ -7,6 +8,11 @@ declare namespace Cypress {
* @example cy.getDataTest('greeting')
*/
getDataTest(value: string): Chainable<JQuery<HTMLElement>>;
/**
* Custom command to logout through UI.
* @example cy.logout()
*/
logout(): Chainable<JQuery<HTMLElement>>;
/**
* Custom command to login user into the app.
* @example cy.login('admin', 'password)
@ -18,9 +24,33 @@ declare namespace Cypress {
*/
addWebsite(name: string, domain: string): Chainable<JQuery<HTMLElement>>;
/**
* Custom command to create a website
* Custom command to delete a website
* @example cy.deleteWebsite('02d89813-7a72-41e1-87f0-8d668f85008b')
*/
deleteWebsite(websiteId: string): Chainable<JQuery<HTMLElement>>;
/**
* Custom command to create a website
* @example cy.deleteWebsite('02d89813-7a72-41e1-87f0-8d668f85008b')
*/
/**
* Custom command to create a user
* @example cy.addUser('cypress', 'password', 'User')
*/
addUser(username: string, password: string, role: string): Chainable<JQuery<HTMLElement>>;
/**
* Custom command to delete a user
* @example cy.deleteUser('02d89813-7a72-41e1-87f0-8d668f85008b')
*/
deleteUser(userId: string): Chainable<JQuery<HTMLElement>>;
/**
* Custom command to create a team
* @example cy.addTeam('cypressTeam')
*/
addTeam(name: string): Chainable<JQuery<HTMLElement>>;
/**
* Custom command to create a website
* @example cy.deleteTeam('02d89813-7a72-41e1-87f0-8d668f85008b')
*/
deleteTeam(teamId: string): Chainable<JQuery<HTMLElement>>;
}
}

View file

@ -0,0 +1,332 @@
-- Create Event
CREATE TABLE umami.website_event_new
(
website_id UUID,
session_id UUID,
visit_id UUID,
event_id UUID,
--sessions
hostname LowCardinality(String),
browser LowCardinality(String),
os LowCardinality(String),
device LowCardinality(String),
screen LowCardinality(String),
language LowCardinality(String),
country LowCardinality(String),
subdivision1 LowCardinality(String),
subdivision2 LowCardinality(String),
city String,
--pageviews
url_path String,
url_query String,
utm_source String,
utm_medium String,
utm_campaign String,
utm_content String,
utm_term String,
referrer_path String,
referrer_query String,
referrer_domain String,
page_title String,
--clickIDs
gclid String,
fbclid String,
msclkid String,
ttclid String,
li_fat_id String,
twclid String,
--events
event_type UInt32,
event_name String,
tag String,
created_at DateTime('UTC'),
job_id Nullable(UUID)
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(created_at)
ORDER BY (toStartOfHour(created_at), website_id, session_id, visit_id, created_at)
PRIMARY KEY (toStartOfHour(created_at), website_id, session_id, visit_id)
SETTINGS index_granularity = 8192;
-- stats hourly
CREATE TABLE umami.website_event_stats_hourly_new
(
website_id UUID,
session_id UUID,
visit_id UUID,
hostname LowCardinality(String),
browser LowCardinality(String),
os LowCardinality(String),
device LowCardinality(String),
screen LowCardinality(String),
language LowCardinality(String),
country LowCardinality(String),
subdivision1 LowCardinality(String),
city String,
entry_url AggregateFunction(argMin, String, DateTime('UTC')),
exit_url AggregateFunction(argMax, String, DateTime('UTC')),
url_path SimpleAggregateFunction(groupArrayArray, Array(String)),
url_query SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_source SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_medium SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_campaign SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_content SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_term SimpleAggregateFunction(groupArrayArray, Array(String)),
referrer_domain SimpleAggregateFunction(groupArrayArray, Array(String)),
page_title SimpleAggregateFunction(groupArrayArray, Array(String)),
gclid SimpleAggregateFunction(groupArrayArray, Array(String)),
fbclid SimpleAggregateFunction(groupArrayArray, Array(String)),
msclkid SimpleAggregateFunction(groupArrayArray, Array(String)),
ttclid SimpleAggregateFunction(groupArrayArray, Array(String)),
li_fat_id SimpleAggregateFunction(groupArrayArray, Array(String)),
twclid SimpleAggregateFunction(groupArrayArray, Array(String)),
event_type UInt32,
event_name SimpleAggregateFunction(groupArrayArray, Array(String)),
views SimpleAggregateFunction(sum, UInt64),
min_time SimpleAggregateFunction(min, DateTime('UTC')),
max_time SimpleAggregateFunction(max, DateTime('UTC')),
tag SimpleAggregateFunction(groupArrayArray, Array(String)),
created_at Datetime('UTC')
)
ENGINE = AggregatingMergeTree
PARTITION BY toYYYYMM(created_at)
ORDER BY (
website_id,
event_type,
toStartOfHour(created_at),
cityHash64(visit_id),
visit_id
)
SAMPLE BY cityHash64(visit_id);
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv_new
TO umami.website_event_stats_hourly_new
AS
SELECT
website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
subdivision1,
city,
entry_url,
exit_url,
url_paths as url_path,
url_query,
utm_source,
utm_medium,
utm_campaign,
utm_content,
utm_term,
referrer_domain,
page_title,
gclid,
fbclid,
msclkid,
ttclid,
li_fat_id,
twclid,
event_type,
event_name,
views,
min_time,
max_time,
tag,
timestamp as created_at
FROM (SELECT
website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
subdivision1,
city,
argMinState(url_path, created_at) entry_url,
argMaxState(url_path, created_at) exit_url,
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
arrayFilter(x -> x != '', groupArray(referrer_domain)) referrer_domain,
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
event_type,
if(event_type = 2, groupArray(event_name), []) event_name,
sumIf(1, event_type = 1) views,
min(created_at) min_time,
max(created_at) max_time,
arrayFilter(x -> x != '', groupArray(tag)) tag,
toStartOfHour(created_at) timestamp
FROM umami.website_event_new
GROUP BY website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
subdivision1,
city,
event_type,
timestamp);
-- projections
ALTER TABLE umami.website_event_new
ADD PROJECTION website_event_url_path_projection (
SELECT * ORDER BY toStartOfDay(created_at), website_id, url_path, created_at
);
ALTER TABLE umami.website_event_new MATERIALIZE PROJECTION website_event_url_path_projection;
ALTER TABLE umami.website_event_new
ADD PROJECTION website_event_referrer_domain_projection (
SELECT * ORDER BY toStartOfDay(created_at), website_id, referrer_domain, created_at
);
ALTER TABLE umami.website_event_new MATERIALIZE PROJECTION website_event_referrer_domain_projection;
-- migration
INSERT INTO umami.website_event_new
SELECT website_id, session_id, visit_id, event_id, hostname, browser, os, device, screen, language, country, subdivision1, subdivision2, city, url_path, url_query,
extract(url_query, 'utm_source=([^&]*)') AS utm_source,
extract(url_query, 'utm_medium=([^&]*)') AS utm_medium,
extract(url_query, 'utm_campaign=([^&]*)') AS utm_campaign,
extract(url_query, 'utm_content=([^&]*)') AS utm_content,
extract(url_query, 'utm_term=([^&]*)') AS utm_term,referrer_path, referrer_query, referrer_domain,
page_title,
extract(url_query, 'gclid=([^&]*)') gclid,
extract(url_query, 'fbclid=([^&]*)') fbclid,
extract(url_query, 'msclkid=([^&]*)') msclkid,
extract(url_query, 'ttclid=([^&]*)') ttclid,
extract(url_query, 'li_fat_id=([^&]*)') li_fat_id,
extract(url_query, 'twclid=([^&]*)') twclid,
event_type, event_name, tag, created_at, job_id
FROM umami.website_event
-- rename tables
RENAME TABLE umami.website_event TO umami.website_event_old;
RENAME TABLE umami.website_event_new TO umami.website_event;
RENAME TABLE umami.website_event_stats_hourly TO umami.website_event_stats_hourly_old;
RENAME TABLE umami.website_event_stats_hourly_new TO umami.website_event_stats_hourly;
RENAME TABLE umami.website_event_stats_hourly_mv TO umami.website_event_stats_hourly_mv_old;
RENAME TABLE umami.website_event_stats_hourly_mv_new TO umami.website_event_stats_hourly_mv;
-- recreate view
DROP TABLE umami.website_event_stats_hourly_mv;
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv
TO umami.website_event_stats_hourly
AS
SELECT
website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
subdivision1,
city,
entry_url,
exit_url,
url_paths as url_path,
url_query,
utm_source,
utm_medium,
utm_campaign,
utm_content,
utm_term,
referrer_domain,
page_title,
gclid,
fbclid,
msclkid,
ttclid,
li_fat_id,
twclid,
event_type,
event_name,
views,
min_time,
max_time,
tag,
timestamp as created_at
FROM (SELECT
website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
subdivision1,
city,
argMinState(url_path, created_at) entry_url,
argMaxState(url_path, created_at) exit_url,
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
arrayFilter(x -> x != '', groupArray(referrer_domain)) referrer_domain,
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
event_type,
if(event_type = 2, groupArray(event_name), []) event_name,
sumIf(1, event_type = 1) views,
min(created_at) min_time,
max(created_at) max_time,
arrayFilter(x -> x != '', groupArray(tag)) tag,
toStartOfHour(created_at) timestamp
FROM umami.website_event
GROUP BY website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
subdivision1,
city,
event_type,
timestamp);

View file

@ -0,0 +1,122 @@
-- drop projections
ALTER TABLE umami.website_event DROP PROJECTION website_event_url_path_projection;
ALTER TABLE umami.website_event DROP PROJECTION website_event_referrer_domain_projection;
--drop view
DROP TABLE umami.website_event_stats_hourly_mv;
-- rename columns
ALTER TABLE umami.website_event RENAME COLUMN "subdivision1" TO "region";
ALTER TABLE umami.website_event_stats_hourly RENAME COLUMN "subdivision1" TO "region";
-- drop columns
ALTER TABLE umami.website_event DROP COLUMN "subdivision2";
-- recreate projections
ALTER TABLE umami.website_event
ADD PROJECTION website_event_url_path_projection (
SELECT * ORDER BY toStartOfDay(created_at), website_id, url_path, created_at
);
ALTER TABLE umami.website_event MATERIALIZE PROJECTION website_event_url_path_projection;
ALTER TABLE umami.website_event
ADD PROJECTION website_event_referrer_domain_projection (
SELECT * ORDER BY toStartOfDay(created_at), website_id, referrer_domain, created_at
);
ALTER TABLE umami.website_event MATERIALIZE PROJECTION website_event_referrer_domain_projection;
-- recreate view
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv
TO umami.website_event_stats_hourly
AS
SELECT
website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
region,
city,
entry_url,
exit_url,
url_paths as url_path,
url_query,
utm_source,
utm_medium,
utm_campaign,
utm_content,
utm_term,
referrer_domain,
page_title,
gclid,
fbclid,
msclkid,
ttclid,
li_fat_id,
twclid,
event_type,
event_name,
views,
min_time,
max_time,
tag,
timestamp as created_at
FROM (SELECT
website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
region,
city,
argMinState(url_path, created_at) entry_url,
argMaxState(url_path, created_at) exit_url,
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
arrayFilter(x -> x != '', groupArray(referrer_domain)) referrer_domain,
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
event_type,
if(event_type = 2, groupArray(event_name), []) event_name,
sumIf(1, event_type = 1) views,
min(created_at) min_time,
max(created_at) max_time,
arrayFilter(x -> x != '', groupArray(tag)) tag,
toStartOfHour(created_at) timestamp
FROM umami.website_event
GROUP BY website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
region,
city,
event_type,
timestamp);

View file

@ -0,0 +1,103 @@
-- add tag column
ALTER TABLE umami.website_event ADD COLUMN "distinct_id" String AFTER "tag";
ALTER TABLE umami.website_event_stats_hourly ADD COLUMN "distinct_id" String AFTER "tag";
ALTER TABLE umami.session_data ADD COLUMN "distinct_id" String AFTER "data_type";
-- update materialized view
DROP TABLE umami.website_event_stats_hourly_mv;
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv
TO umami.website_event_stats_hourly
AS
SELECT
website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
region,
city,
entry_url,
exit_url,
url_paths as url_path,
url_query,
utm_source,
utm_medium,
utm_campaign,
utm_content,
utm_term,
referrer_domain,
page_title,
gclid,
fbclid,
msclkid,
ttclid,
li_fat_id,
twclid,
event_type,
event_name,
views,
min_time,
max_time,
tag,
distinct_id,
timestamp as created_at
FROM (SELECT
website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
region,
city,
argMinState(url_path, created_at) entry_url,
argMaxState(url_path, created_at) exit_url,
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
arrayFilter(x -> x != '', groupArray(referrer_domain)) referrer_domain,
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
event_type,
if(event_type = 2, groupArray(event_name), []) event_name,
sumIf(1, event_type = 1) views,
min(created_at) min_time,
max(created_at) max_time,
arrayFilter(x -> x != '', groupArray(tag)) tag,
distinct_id,
toStartOfHour(created_at) timestamp
FROM umami.website_event
GROUP BY website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
region,
city,
event_type,
distinct_id,
timestamp);

View file

@ -0,0 +1,253 @@
-- create new hourly table
CREATE TABLE umami.website_event_stats_hourly_new
(
website_id UUID,
session_id UUID,
visit_id UUID,
hostname SimpleAggregateFunction(groupArrayArray, Array(String)),
browser LowCardinality(String),
os LowCardinality(String),
device LowCardinality(String),
screen LowCardinality(String),
language LowCardinality(String),
country LowCardinality(String),
region LowCardinality(String),
city String,
entry_url AggregateFunction(argMin, String, DateTime('UTC')),
exit_url AggregateFunction(argMax, String, DateTime('UTC')),
url_path SimpleAggregateFunction(groupArrayArray, Array(String)),
url_query SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_source SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_medium SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_campaign SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_content SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_term SimpleAggregateFunction(groupArrayArray, Array(String)),
referrer_domain SimpleAggregateFunction(groupArrayArray, Array(String)),
page_title SimpleAggregateFunction(groupArrayArray, Array(String)),
gclid SimpleAggregateFunction(groupArrayArray, Array(String)),
fbclid SimpleAggregateFunction(groupArrayArray, Array(String)),
msclkid SimpleAggregateFunction(groupArrayArray, Array(String)),
ttclid SimpleAggregateFunction(groupArrayArray, Array(String)),
li_fat_id SimpleAggregateFunction(groupArrayArray, Array(String)),
twclid SimpleAggregateFunction(groupArrayArray, Array(String)),
event_type UInt32,
event_name SimpleAggregateFunction(groupArrayArray, Array(String)),
views SimpleAggregateFunction(sum, UInt64),
min_time SimpleAggregateFunction(min, DateTime('UTC')),
max_time SimpleAggregateFunction(max, DateTime('UTC')),
tag SimpleAggregateFunction(groupArrayArray, Array(String)),
distinct_id String,
created_at Datetime('UTC')
)
ENGINE = AggregatingMergeTree
PARTITION BY toYYYYMM(created_at)
ORDER BY (
website_id,
event_type,
toStartOfHour(created_at),
cityHash64(visit_id),
visit_id
)
SAMPLE BY cityHash64(visit_id);
-- create view
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv_new
TO umami.website_event_stats_hourly_new
AS
SELECT
website_id,
session_id,
visit_id,
hostnames as hostname,
browser,
os,
device,
screen,
language,
country,
region,
city,
entry_url,
exit_url,
url_paths as url_path,
url_query,
utm_source,
utm_medium,
utm_campaign,
utm_content,
utm_term,
referrer_domain,
page_title,
gclid,
fbclid,
msclkid,
ttclid,
li_fat_id,
twclid,
event_type,
event_name,
views,
min_time,
max_time,
tag,
distinct_id,
timestamp as created_at
FROM (SELECT
website_id,
session_id,
visit_id,
arrayFilter(x -> x != '', groupArray(hostname)) hostnames,
browser,
os,
device,
screen,
language,
country,
region,
city,
argMinState(url_path, created_at) entry_url,
argMaxState(url_path, created_at) exit_url,
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
arrayFilter(x -> x != '' and x != hostname, groupArray(referrer_domain)) referrer_domain,
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
event_type,
if(event_type = 2, groupArray(event_name), []) event_name,
sumIf(1, event_type = 1) views,
min(created_at) min_time,
max(created_at) max_time,
arrayFilter(x -> x != '', groupArray(tag)) tag,
distinct_id,
toStartOfHour(created_at) timestamp
FROM umami.website_event
GROUP BY website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
region,
city,
event_type,
distinct_id,
timestamp);
-- rename tables
RENAME TABLE umami.website_event_stats_hourly TO umami.website_event_stats_hourly_old;
RENAME TABLE umami.website_event_stats_hourly_new TO umami.website_event_stats_hourly;
-- drop views
DROP TABLE umami.website_event_stats_hourly_mv;
DROP TABLE umami.website_event_stats_hourly_mv_new;
-- recreate view
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv
TO umami.website_event_stats_hourly
AS
SELECT
website_id,
session_id,
visit_id,
hostnames as hostname,
browser,
os,
device,
screen,
language,
country,
region,
city,
entry_url,
exit_url,
url_paths as url_path,
url_query,
utm_source,
utm_medium,
utm_campaign,
utm_content,
utm_term,
referrer_domain,
page_title,
gclid,
fbclid,
msclkid,
ttclid,
li_fat_id,
twclid,
event_type,
event_name,
views,
min_time,
max_time,
tag,
distinct_id,
timestamp as created_at
FROM (SELECT
website_id,
session_id,
visit_id,
arrayFilter(x -> x != '', groupArray(hostname)) hostnames,
browser,
os,
device,
screen,
language,
country,
region,
city,
argMinState(url_path, created_at) entry_url,
argMaxState(url_path, created_at) exit_url,
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
arrayFilter(x -> x != '' and x != hostname, groupArray(referrer_domain)) referrer_domain,
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
event_type,
if(event_type = 2, groupArray(event_name), []) event_name,
sumIf(1, event_type = 1) views,
min(created_at) min_time,
max(created_at) max_time,
arrayFilter(x -> x != '', groupArray(tag)) tag,
distinct_id,
toStartOfHour(created_at) timestamp
FROM umami.website_event
GROUP BY website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
region,
city,
event_type,
distinct_id,
timestamp);

View file

@ -13,20 +13,32 @@ CREATE TABLE umami.website_event
screen LowCardinality(String),
language LowCardinality(String),
country LowCardinality(String),
subdivision1 LowCardinality(String),
subdivision2 LowCardinality(String),
region LowCardinality(String),
city String,
--pageviews
url_path String,
url_query String,
utm_source String,
utm_medium String,
utm_campaign String,
utm_content String,
utm_term String,
referrer_path String,
referrer_query String,
referrer_domain String,
page_title String,
--clickIDs
gclid String,
fbclid String,
msclkid String,
ttclid String,
li_fat_id String,
twclid String,
--events
event_type UInt32,
event_name String,
tag String,
distinct_id String,
created_at DateTime('UTC'),
job_id Nullable(UUID)
)
@ -45,7 +57,7 @@ CREATE TABLE umami.event_data
event_name String,
data_key String,
string_value Nullable(String),
number_value Nullable(Decimal64(4)),
number_value Nullable(Decimal(22, 4)),
date_value Nullable(DateTime('UTC')),
data_type UInt32,
created_at DateTime('UTC'),
@ -61,9 +73,10 @@ CREATE TABLE umami.session_data
session_id UUID,
data_key String,
string_value Nullable(String),
number_value Nullable(Decimal64(4)),
number_value Nullable(Decimal(22, 4)),
date_value Nullable(DateTime('UTC')),
data_type UInt32,
distinct_id String,
created_at DateTime('UTC'),
job_id Nullable(UUID)
)
@ -77,27 +90,39 @@ CREATE TABLE umami.website_event_stats_hourly
website_id UUID,
session_id UUID,
visit_id UUID,
hostname LowCardinality(String),
hostname SimpleAggregateFunction(groupArrayArray, Array(String)),
browser LowCardinality(String),
os LowCardinality(String),
device LowCardinality(String),
screen LowCardinality(String),
language LowCardinality(String),
country LowCardinality(String),
subdivision1 LowCardinality(String),
region LowCardinality(String),
city String,
entry_url AggregateFunction(argMin, String, DateTime('UTC')),
exit_url AggregateFunction(argMax, String, DateTime('UTC')),
url_path SimpleAggregateFunction(groupArrayArray, Array(String)),
url_query SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_source SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_medium SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_campaign SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_content SimpleAggregateFunction(groupArrayArray, Array(String)),
utm_term SimpleAggregateFunction(groupArrayArray, Array(String)),
referrer_domain SimpleAggregateFunction(groupArrayArray, Array(String)),
page_title SimpleAggregateFunction(groupArrayArray, Array(String)),
gclid SimpleAggregateFunction(groupArrayArray, Array(String)),
fbclid SimpleAggregateFunction(groupArrayArray, Array(String)),
msclkid SimpleAggregateFunction(groupArrayArray, Array(String)),
ttclid SimpleAggregateFunction(groupArrayArray, Array(String)),
li_fat_id SimpleAggregateFunction(groupArrayArray, Array(String)),
twclid SimpleAggregateFunction(groupArrayArray, Array(String)),
event_type UInt32,
event_name SimpleAggregateFunction(groupArrayArray, Array(String)),
views SimpleAggregateFunction(sum, UInt64),
min_time SimpleAggregateFunction(min, DateTime('UTC')),
max_time SimpleAggregateFunction(max, DateTime('UTC')),
tag SimpleAggregateFunction(groupArrayArray, Array(String)),
distinct_id String,
created_at Datetime('UTC')
)
ENGINE = AggregatingMergeTree
@ -118,53 +143,77 @@ SELECT
website_id,
session_id,
visit_id,
hostname,
hostnames as hostname,
browser,
os,
device,
screen,
language,
country,
subdivision1,
region,
city,
entry_url,
exit_url,
url_paths as url_path,
url_query,
utm_source,
utm_medium,
utm_campaign,
utm_content,
utm_term,
referrer_domain,
page_title,
gclid,
fbclid,
msclkid,
ttclid,
li_fat_id,
twclid,
event_type,
event_name,
views,
min_time,
max_time,
tag,
distinct_id,
timestamp as created_at
FROM (SELECT
website_id,
session_id,
visit_id,
hostname,
arrayFilter(x -> x != '', groupArray(hostname)) hostnames,
browser,
os,
device,
screen,
language,
country,
subdivision1,
region,
city,
argMinState(url_path, created_at) entry_url,
argMaxState(url_path, created_at) exit_url,
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
arrayFilter(x -> x != '', groupArray(referrer_domain)) referrer_domain,
arrayFilter(x -> x != '', groupArray(utm_source)) utm_source,
arrayFilter(x -> x != '', groupArray(utm_medium)) utm_medium,
arrayFilter(x -> x != '', groupArray(utm_campaign)) utm_campaign,
arrayFilter(x -> x != '', groupArray(utm_content)) utm_content,
arrayFilter(x -> x != '', groupArray(utm_term)) utm_term,
arrayFilter(x -> x != '' and x != hostname, groupArray(referrer_domain)) referrer_domain,
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
arrayFilter(x -> x != '', groupArray(gclid)) gclid,
arrayFilter(x -> x != '', groupArray(fbclid)) fbclid,
arrayFilter(x -> x != '', groupArray(msclkid)) msclkid,
arrayFilter(x -> x != '', groupArray(ttclid)) ttclid,
arrayFilter(x -> x != '', groupArray(li_fat_id)) li_fat_id,
arrayFilter(x -> x != '', groupArray(twclid)) twclid,
event_type,
if(event_type = 2, groupArray(event_name), []) event_name,
sumIf(1, event_type = 1) views,
sumIf(1, event_type != 2) views,
min(created_at) min_time,
max(created_at) max_time,
arrayFilter(x -> x != '', groupArray(tag)) tag,
distinct_id,
toStartOfHour(created_at) timestamp
FROM umami.website_event
GROUP BY website_id,
@ -177,9 +226,10 @@ GROUP BY website_id,
screen,
language,
country,
subdivision1,
region,
city,
event_type,
distinct_id,
timestamp);
-- projections
@ -196,3 +246,38 @@ SELECT * ORDER BY toStartOfDay(created_at), website_id, referrer_domain, created
);
ALTER TABLE umami.website_event MATERIALIZE PROJECTION website_event_referrer_domain_projection;
-- revenue
CREATE TABLE umami.website_revenue
(
website_id UUID,
session_id UUID,
event_id UUID,
event_name String,
currency String,
revenue DECIMAL(18,4),
created_at DateTime('UTC')
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(created_at)
ORDER BY (website_id, session_id, created_at)
SETTINGS index_granularity = 8192;
CREATE MATERIALIZED VIEW umami.website_revenue_mv
TO umami.website_revenue
AS
SELECT DISTINCT
ed.website_id,
ed.session_id,
ed.event_id,
ed.event_name,
c.currency,
coalesce(toDecimal64(ed.number_value, 2), toDecimal64(ed.string_value, 2)) revenue,
ed.created_at
FROM umami.event_data ed
JOIN (SELECT event_id, string_value as currency
FROM umami.event_data
WHERE positionCaseInsensitive(data_key, 'currency') > 0) c
ON c.event_id = ed.event_id
WHERE positionCaseInsensitive(data_key, 'revenue') > 0;

View file

@ -1,143 +0,0 @@
-- CreateTable
CREATE TABLE `user` (
`user_id` VARCHAR(36) NOT NULL,
`username` VARCHAR(255) NOT NULL,
`password` VARCHAR(60) NOT NULL,
`role` VARCHAR(50) NOT NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`updated_at` TIMESTAMP(0) NULL,
`deleted_at` TIMESTAMP(0) NULL,
UNIQUE INDEX `user_user_id_key`(`user_id`),
UNIQUE INDEX `user_username_key`(`username`),
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `session` (
`session_id` VARCHAR(36) NOT NULL,
`website_id` VARCHAR(36) NOT NULL,
`hostname` VARCHAR(100) NULL,
`browser` VARCHAR(20) NULL,
`os` VARCHAR(20) NULL,
`device` VARCHAR(20) NULL,
`screen` VARCHAR(11) NULL,
`language` VARCHAR(35) NULL,
`country` CHAR(2) NULL,
`subdivision1` CHAR(20) NULL,
`subdivision2` VARCHAR(50) NULL,
`city` VARCHAR(50) NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
UNIQUE INDEX `session_session_id_key`(`session_id`),
INDEX `session_created_at_idx`(`created_at`),
INDEX `session_website_id_idx`(`website_id`),
PRIMARY KEY (`session_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `website` (
`website_id` VARCHAR(36) NOT NULL,
`name` VARCHAR(100) NOT NULL,
`domain` VARCHAR(500) NULL,
`share_id` VARCHAR(50) NULL,
`reset_at` TIMESTAMP(0) NULL,
`user_id` VARCHAR(36) NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`updated_at` TIMESTAMP(0) NULL,
`deleted_at` TIMESTAMP(0) NULL,
UNIQUE INDEX `website_website_id_key`(`website_id`),
UNIQUE INDEX `website_share_id_key`(`share_id`),
INDEX `website_user_id_idx`(`user_id`),
INDEX `website_created_at_idx`(`created_at`),
INDEX `website_share_id_idx`(`share_id`),
PRIMARY KEY (`website_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `website_event` (
`event_id` VARCHAR(36) NOT NULL,
`website_id` VARCHAR(36) NOT NULL,
`session_id` VARCHAR(36) NOT NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`url_path` VARCHAR(500) NOT NULL,
`url_query` VARCHAR(500) NULL,
`referrer_path` VARCHAR(500) NULL,
`referrer_query` VARCHAR(500) NULL,
`referrer_domain` VARCHAR(500) NULL,
`page_title` VARCHAR(500) NULL,
`event_type` INTEGER UNSIGNED NOT NULL DEFAULT 1,
`event_name` VARCHAR(50) NULL,
INDEX `website_event_created_at_idx`(`created_at`),
INDEX `website_event_session_id_idx`(`session_id`),
INDEX `website_event_website_id_idx`(`website_id`),
INDEX `website_event_website_id_created_at_idx`(`website_id`, `created_at`),
INDEX `website_event_website_id_session_id_created_at_idx`(`website_id`, `session_id`, `created_at`),
PRIMARY KEY (`event_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `event_data` (
`event_id` VARCHAR(36) NOT NULL,
`website_event_id` VARCHAR(36) NOT NULL,
`website_id` VARCHAR(36) NOT NULL,
`event_key` VARCHAR(500) NOT NULL,
`event_string_value` VARCHAR(500) NULL,
`event_numeric_value` DECIMAL(19, 4) NULL,
`event_date_value` TIMESTAMP(0) NULL,
`event_data_type` INTEGER UNSIGNED NOT NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
INDEX `event_data_created_at_idx`(`created_at`),
INDEX `event_data_website_id_idx`(`website_id`),
INDEX `event_data_website_event_id_idx`(`website_event_id`),
INDEX `event_data_website_id_website_event_id_created_at_idx`(`website_id`, `website_event_id`, `created_at`),
PRIMARY KEY (`event_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `team` (
`team_id` VARCHAR(36) NOT NULL,
`name` VARCHAR(50) NOT NULL,
`access_code` VARCHAR(50) NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`updated_at` TIMESTAMP(0) NULL,
UNIQUE INDEX `team_team_id_key`(`team_id`),
UNIQUE INDEX `team_access_code_key`(`access_code`),
INDEX `team_access_code_idx`(`access_code`),
PRIMARY KEY (`team_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `team_user` (
`team_user_id` VARCHAR(36) NOT NULL,
`team_id` VARCHAR(36) NOT NULL,
`user_id` VARCHAR(36) NOT NULL,
`role` VARCHAR(50) NOT NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`updated_at` TIMESTAMP(0) NULL,
UNIQUE INDEX `team_user_team_user_id_key`(`team_user_id`),
INDEX `team_user_team_id_idx`(`team_id`),
INDEX `team_user_user_id_idx`(`user_id`),
PRIMARY KEY (`team_user_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `team_website` (
`team_website_id` VARCHAR(36) NOT NULL,
`team_id` VARCHAR(36) NOT NULL,
`website_id` VARCHAR(36) NOT NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
UNIQUE INDEX `team_website_team_website_id_key`(`team_website_id`),
INDEX `team_website_team_id_idx`(`team_id`),
INDEX `team_website_website_id_idx`(`website_id`),
PRIMARY KEY (`team_website_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddSystemUser
INSERT INTO user (user_id, username, role, password) VALUES ('41e2b680-648e-4b09-bcd7-3e2b10c06264' , 'admin', 'admin', '$2b$10$BUli0c.muyCW1ErNJc3jL.vFRFtFJWrT8/GcR4A.sUdCznaXiqFXa');

View file

@ -1,53 +0,0 @@
-- AlterTable
ALTER TABLE `event_data` CHANGE `event_data_type` `data_type` INTEGER UNSIGNED NOT NULL;
ALTER TABLE `event_data` CHANGE `event_date_value` `date_value` TIMESTAMP(0) NULL;
ALTER TABLE `event_data` CHANGE `event_id` `event_data_id` VARCHAR(36) NOT NULL;
ALTER TABLE `event_data` CHANGE `event_numeric_value` `number_value` DECIMAL(19,4) NULL;
ALTER TABLE `event_data` CHANGE `event_string_value` `string_value` VARCHAR(500) NULL;
-- CreateTable
CREATE TABLE `session_data` (
`session_data_id` VARCHAR(36) NOT NULL,
`website_id` VARCHAR(36) NOT NULL,
`session_id` VARCHAR(36) NOT NULL,
`event_key` VARCHAR(500) NOT NULL,
`string_value` VARCHAR(500) NULL,
`number_value` DECIMAL(19, 4) NULL,
`date_value` TIMESTAMP(0) NULL,
`data_type` INTEGER UNSIGNED NOT NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
INDEX `session_data_created_at_idx`(`created_at`),
INDEX `session_data_website_id_idx`(`website_id`),
INDEX `session_data_session_id_idx`(`session_id`),
PRIMARY KEY (`session_data_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `report` (
`report_id` VARCHAR(36) NOT NULL,
`user_id` VARCHAR(36) NOT NULL,
`website_id` VARCHAR(36) NOT NULL,
`type` VARCHAR(200) NOT NULL,
`name` VARCHAR(200) NOT NULL,
`description` VARCHAR(500) NOT NULL,
`parameters` VARCHAR(6000) NOT NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`updated_at` TIMESTAMP(0) NULL,
UNIQUE INDEX `report_report_id_key`(`report_id`),
INDEX `report_user_id_idx`(`user_id`),
INDEX `report_website_id_idx`(`website_id`),
INDEX `report_type_idx`(`type`),
INDEX `report_name_idx`(`name`),
PRIMARY KEY (`report_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- EventData migration
UPDATE event_data
SET string_value = number_value
WHERE data_type = 2;
UPDATE event_data
SET string_value = CONCAT(REPLACE(DATE_FORMAT(date_value, '%Y-%m-%d %T'), ' ', 'T'), 'Z')
WHERE data_type = 4;

View file

@ -1,50 +0,0 @@
-- CreateIndex
CREATE INDEX `event_data_website_id_created_at_idx` ON `event_data`(`website_id`, `created_at`);
-- CreateIndex
CREATE INDEX `event_data_website_id_created_at_event_key_idx` ON `event_data`(`website_id`, `created_at`, `event_key`);
-- CreateIndex
CREATE INDEX `session_website_id_created_at_idx` ON `session`(`website_id`, `created_at`);
-- CreateIndex
CREATE INDEX `session_website_id_created_at_hostname_idx` ON `session`(`website_id`, `created_at`, `hostname`);
-- CreateIndex
CREATE INDEX `session_website_id_created_at_browser_idx` ON `session`(`website_id`, `created_at`, `browser`);
-- CreateIndex
CREATE INDEX `session_website_id_created_at_os_idx` ON `session`(`website_id`, `created_at`, `os`);
-- CreateIndex
CREATE INDEX `session_website_id_created_at_device_idx` ON `session`(`website_id`, `created_at`, `device`);
-- CreateIndex
CREATE INDEX `session_website_id_created_at_screen_idx` ON `session`(`website_id`, `created_at`, `screen`);
-- CreateIndex
CREATE INDEX `session_website_id_created_at_language_idx` ON `session`(`website_id`, `created_at`, `language`);
-- CreateIndex
CREATE INDEX `session_website_id_created_at_country_idx` ON `session`(`website_id`, `created_at`, `country`);
-- CreateIndex
CREATE INDEX `session_website_id_created_at_subdivision1_idx` ON `session`(`website_id`, `created_at`, `subdivision1`);
-- CreateIndex
CREATE INDEX `session_website_id_created_at_city_idx` ON `session`(`website_id`, `created_at`, `city`);
-- CreateIndex
CREATE INDEX `website_event_website_id_created_at_url_path_idx` ON `website_event`(`website_id`, `created_at`, `url_path`);
-- CreateIndex
CREATE INDEX `website_event_website_id_created_at_url_query_idx` ON `website_event`(`website_id`, `created_at`, `url_query`);
-- CreateIndex
CREATE INDEX `website_event_website_id_created_at_referrer_domain_idx` ON `website_event`(`website_id`, `created_at`, `referrer_domain`);
-- CreateIndex
CREATE INDEX `website_event_website_id_created_at_page_title_idx` ON `website_event`(`website_id`, `created_at`, `page_title`);
-- CreateIndex
CREATE INDEX `website_event_website_id_created_at_event_name_idx` ON `website_event`(`website_id`, `created_at`, `event_name`);

View file

@ -1,29 +0,0 @@
/*
Warnings:
- You are about to drop the `team_website` table. If the table is not empty, all the data it contains will be lost.
*/
-- AlterTable
ALTER TABLE `team` ADD COLUMN `deleted_at` TIMESTAMP(0) NULL,
ADD COLUMN `logo_url` VARCHAR(2183) NULL;
-- AlterTable
ALTER TABLE `user` ADD COLUMN `display_name` VARCHAR(255) NULL,
ADD COLUMN `logo_url` VARCHAR(2183) NULL;
-- AlterTable
ALTER TABLE `website` ADD COLUMN `created_by` VARCHAR(36) NULL,
ADD COLUMN `team_id` VARCHAR(36) NULL;
-- MigrateData
UPDATE `website` SET created_by = user_id WHERE team_id IS NULL;
-- DropTable
DROP TABLE `team_website`;
-- CreateIndex
CREATE INDEX `website_team_id_idx` ON `website`(`team_id`);
-- CreateIndex
CREATE INDEX `website_created_by_idx` ON `website`(`created_by`);

View file

@ -1,22 +0,0 @@
-- AlterTable
ALTER TABLE `website_event` ADD COLUMN `visit_id` VARCHAR(36) NULL;
UPDATE `website_event` we
JOIN (SELECT DISTINCT
s.session_id,
s.visit_time,
BIN_TO_UUID(RANDOM_BYTES(16) & 0xffffffffffff0fff3fffffffffffffff | 0x00000000000040008000000000000000) uuid
FROM (SELECT DISTINCT session_id,
DATE_FORMAT(created_at, '%Y-%m-%d %H:00:00') visit_time
FROM `website_event`) s) a
ON we.session_id = a.session_id and DATE_FORMAT(we.created_at, '%Y-%m-%d %H:00:00') = a.visit_time
SET we.visit_id = a.uuid
WHERE we.visit_id IS NULL;
ALTER TABLE `website_event` MODIFY `visit_id` VARCHAR(36) NOT NULL;
-- CreateIndex
CREATE INDEX `website_event_visit_id_idx` ON `website_event`(`visit_id`);
-- CreateIndex
CREATE INDEX `website_event_website_id_visit_id_created_at_idx` ON `website_event`(`website_id`, `visit_id`, `created_at`);

View file

@ -1,20 +0,0 @@
-- DropIndex
DROP INDEX `event_data_website_id_created_at_event_key_idx` ON `event_data`;
-- DropIndex
DROP INDEX `event_data_website_id_website_event_id_created_at_idx` ON `event_data`;
-- AlterTable
ALTER TABLE `event_data` RENAME COLUMN `event_key` TO `data_key`;
-- AlterTable
ALTER TABLE `session_data` RENAME COLUMN `event_key` TO `data_key`;
-- CreateIndex
CREATE INDEX `event_data_website_id_created_at_data_key_idx` ON `event_data`(`website_id`, `created_at`, `data_key`);
-- CreateIndex
CREATE INDEX `session_data_session_id_created_at_idx` ON `session_data`(`session_id`, `created_at`);
-- CreateIndex
CREATE INDEX `session_data_website_id_created_at_data_key_idx` ON `session_data`(`website_id`, `created_at`, `data_key`);

View file

@ -1,5 +0,0 @@
-- AlterTable
ALTER TABLE `website_event` ADD COLUMN `tag` VARCHAR(50) NULL;
-- CreateIndex
CREATE INDEX `website_event_website_id_created_at_tag_idx` ON `website_event`(`website_id`, `created_at`, `tag`);

View file

@ -1,3 +0,0 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "mysql"

View file

@ -1,222 +0,0 @@
generator client {
provider = "prisma-client-js"
binaryTargets = ["native"]
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma"
}
model User {
id String @id @unique @map("user_id") @db.VarChar(36)
username String @unique @db.VarChar(255)
password String @db.VarChar(60)
role String @map("role") @db.VarChar(50)
logoUrl String? @map("logo_url") @db.VarChar(2183)
displayName String? @map("display_name") @db.VarChar(255)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
deletedAt DateTime? @map("deleted_at") @db.Timestamp(0)
websiteUser Website[] @relation("user")
websiteCreateUser Website[] @relation("createUser")
teamUser TeamUser[]
report Report[]
@@map("user")
}
model Session {
id String @id @unique @map("session_id") @db.VarChar(36)
websiteId String @map("website_id") @db.VarChar(36)
hostname String? @db.VarChar(100)
browser String? @db.VarChar(20)
os String? @db.VarChar(20)
device String? @db.VarChar(20)
screen String? @db.VarChar(11)
language String? @db.VarChar(35)
country String? @db.Char(2)
subdivision1 String? @db.Char(20)
subdivision2 String? @db.VarChar(50)
city String? @db.VarChar(50)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
websiteEvent WebsiteEvent[]
sessionData SessionData[]
@@index([createdAt])
@@index([websiteId])
@@index([websiteId, createdAt])
@@index([websiteId, createdAt, hostname])
@@index([websiteId, createdAt, browser])
@@index([websiteId, createdAt, os])
@@index([websiteId, createdAt, device])
@@index([websiteId, createdAt, screen])
@@index([websiteId, createdAt, language])
@@index([websiteId, createdAt, country])
@@index([websiteId, createdAt, subdivision1])
@@index([websiteId, createdAt, city])
@@map("session")
}
model Website {
id String @id @unique @map("website_id") @db.VarChar(36)
name String @db.VarChar(100)
domain String? @db.VarChar(500)
shareId String? @unique @map("share_id") @db.VarChar(50)
resetAt DateTime? @map("reset_at") @db.Timestamp(0)
userId String? @map("user_id") @db.VarChar(36)
teamId String? @map("team_id") @db.VarChar(36)
createdBy String? @map("created_by") @db.VarChar(36)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
deletedAt DateTime? @map("deleted_at") @db.Timestamp(0)
user User? @relation("user", fields: [userId], references: [id])
createUser User? @relation("createUser", fields: [createdBy], references: [id])
team Team? @relation(fields: [teamId], references: [id])
eventData EventData[]
report Report[]
sessionData SessionData[]
@@index([userId])
@@index([teamId])
@@index([createdAt])
@@index([shareId])
@@index([createdBy])
@@map("website")
}
model WebsiteEvent {
id String @id() @map("event_id") @db.VarChar(36)
websiteId String @map("website_id") @db.VarChar(36)
sessionId String @map("session_id") @db.VarChar(36)
visitId String @map("visit_id") @db.VarChar(36)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
urlPath String @map("url_path") @db.VarChar(500)
urlQuery String? @map("url_query") @db.VarChar(500)
referrerPath String? @map("referrer_path") @db.VarChar(500)
referrerQuery String? @map("referrer_query") @db.VarChar(500)
referrerDomain String? @map("referrer_domain") @db.VarChar(500)
pageTitle String? @map("page_title") @db.VarChar(500)
eventType Int @default(1) @map("event_type") @db.UnsignedInt
eventName String? @map("event_name") @db.VarChar(50)
tag String? @db.VarChar(50)
eventData EventData[]
session Session @relation(fields: [sessionId], references: [id])
@@index([createdAt])
@@index([sessionId])
@@index([visitId])
@@index([websiteId])
@@index([websiteId, createdAt])
@@index([websiteId, createdAt, urlPath])
@@index([websiteId, createdAt, urlQuery])
@@index([websiteId, createdAt, referrerDomain])
@@index([websiteId, createdAt, pageTitle])
@@index([websiteId, createdAt, eventName])
@@index([websiteId, createdAt, tag])
@@index([websiteId, sessionId, createdAt])
@@index([websiteId, visitId, createdAt])
@@map("website_event")
}
model EventData {
id String @id() @map("event_data_id") @db.VarChar(36)
websiteId String @map("website_id") @db.VarChar(36)
websiteEventId String @map("website_event_id") @db.VarChar(36)
dataKey String @map("data_key") @db.VarChar(500)
stringValue String? @map("string_value") @db.VarChar(500)
numberValue Decimal? @map("number_value") @db.Decimal(19, 4)
dateValue DateTime? @map("date_value") @db.Timestamp(0)
dataType Int @map("data_type") @db.UnsignedInt
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
website Website @relation(fields: [websiteId], references: [id])
websiteEvent WebsiteEvent @relation(fields: [websiteEventId], references: [id])
@@index([createdAt])
@@index([websiteId])
@@index([websiteEventId])
@@index([websiteId, createdAt])
@@index([websiteId, createdAt, dataKey])
@@map("event_data")
}
model SessionData {
id String @id() @map("session_data_id") @db.VarChar(36)
websiteId String @map("website_id") @db.VarChar(36)
sessionId String @map("session_id") @db.VarChar(36)
dataKey String @map("data_key") @db.VarChar(500)
stringValue String? @map("string_value") @db.VarChar(500)
numberValue Decimal? @map("number_value") @db.Decimal(19, 4)
dateValue DateTime? @map("date_value") @db.Timestamp(0)
dataType Int @map("data_type") @db.UnsignedInt
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
website Website @relation(fields: [websiteId], references: [id])
session Session @relation(fields: [sessionId], references: [id])
@@index([createdAt])
@@index([websiteId])
@@index([sessionId])
@@index([sessionId, createdAt])
@@index([websiteId, createdAt, dataKey])
@@map("session_data")
}
model Team {
id String @id() @unique() @map("team_id") @db.VarChar(36)
name String @db.VarChar(50)
accessCode String? @unique @map("access_code") @db.VarChar(50)
logoUrl String? @map("logo_url") @db.VarChar(2183)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
deletedAt DateTime? @map("deleted_at") @db.Timestamp(0)
website Website[]
teamUser TeamUser[]
@@index([accessCode])
@@map("team")
}
model TeamUser {
id String @id() @unique() @map("team_user_id") @db.VarChar(36)
teamId String @map("team_id") @db.VarChar(36)
userId String @map("user_id") @db.VarChar(36)
role String @map("role") @db.VarChar(50)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
team Team @relation(fields: [teamId], references: [id])
user User @relation(fields: [userId], references: [id])
@@index([teamId])
@@index([userId])
@@map("team_user")
}
model Report {
id String @id() @unique() @map("report_id") @db.VarChar(36)
userId String @map("user_id") @db.VarChar(36)
websiteId String @map("website_id") @db.VarChar(36)
type String @map("type") @db.VarChar(200)
name String @map("name") @db.VarChar(200)
description String @map("description") @db.VarChar(500)
parameters String @map("parameters") @db.VarChar(6000)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0)
user User @relation(fields: [userId], references: [id])
website Website @relation(fields: [websiteId], references: [id])
@@index([userId])
@@index([websiteId])
@@index([type])
@@index([name])
@@map("report")
}

View file

@ -0,0 +1,49 @@
-----------------------------------------------------
-- PostgreSQL
-----------------------------------------------------
UPDATE "website_event" we
SET fbclid = LEFT(url.fbclid, 255),
gclid = LEFT(url.gclid, 255),
li_fat_id = LEFT(url.li_fat_id, 255),
msclkid = LEFT(url.msclkid, 255),
ttclid = LEFT(url.ttclid, 255),
twclid = LEFT(url.twclid, 255),
utm_campaign = LEFT(url.utm_campaign, 255),
utm_content = LEFT(url.utm_content, 255),
utm_medium = LEFT(url.utm_medium, 255),
utm_source = LEFT(url.utm_source, 255),
utm_term = LEFT(url.utm_term, 255)
FROM (SELECT event_id, website_id, session_id,
(regexp_matches(url_query, '(?:[&?]|^)fbclid=([^&]+)', 'i'))[1] AS fbclid,
(regexp_matches(url_query, '(?:[&?]|^)gclid=([^&]+)', 'i'))[1] AS gclid,
(regexp_matches(url_query, '(?:[&?]|^)li_fat_id=([^&]+)', 'i'))[1] AS li_fat_id,
(regexp_matches(url_query, '(?:[&?]|^)msclkid=([^&]+)', 'i'))[1] AS msclkid,
(regexp_matches(url_query, '(?:[&?]|^)ttclid=([^&]+)', 'i'))[1] AS ttclid,
(regexp_matches(url_query, '(?:[&?]|^)twclid=([^&]+)', 'i'))[1] AS twclid,
(regexp_matches(url_query, '(?:[&?]|^)utm_campaign=([^&]+)', 'i'))[1] AS utm_campaign,
(regexp_matches(url_query, '(?:[&?]|^)utm_content=([^&]+)', 'i'))[1] AS utm_content,
(regexp_matches(url_query, '(?:[&?]|^)utm_medium=([^&]+)', 'i'))[1] AS utm_medium,
(regexp_matches(url_query, '(?:[&?]|^)utm_source=([^&]+)', 'i'))[1] AS utm_source,
(regexp_matches(url_query, '(?:[&?]|^)utm_term=([^&]+)', 'i'))[1] AS utm_term
FROM "website_event"
WHERE url_query IS NOT NULL) url
WHERE we.event_id = url.event_id
and we.session_id = url.session_id
and we.website_id = url.website_id;
-----------------------------------------------------
-- MySQL
-----------------------------------------------------
UPDATE `website_event`
SET fbclid = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)fbclid=[^&]+'), '=', -1), '&', 1), 255),
gclid = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)gclid=[^&]+'), '=', -1), '&', 1), 255),
li_fat_id = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)li_fat_id=[^&]+'), '=', -1), '&', 1), 255),
msclkid = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)msclkid=[^&]+'), '=', -1), '&', 1), 255),
ttclid = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)ttclid=[^&]+'), '=', -1), '&', 1), 255),
twclid = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)twclid=[^&]+'), '=', -1), '&', 1), 255),
utm_campaign = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)utm_campaign=[^&]+'), '=', -1), '&', 1), 255),
utm_content = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)utm_content=[^&]+'), '=', -1), '&', 1), 255),
utm_medium = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)utm_medium=[^&]+'), '=', -1), '&', 1), 255),
utm_source = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)utm_source=[^&]+'), '=', -1), '&', 1), 255),
utm_term = LEFT(SUBSTRING_INDEX(SUBSTRING_INDEX(REGEXP_SUBSTR(url_query, '(?:[&?]|^)utm_term=[^&]+'), '=', -1), '&', 1), 255)
WHERE url_query IS NOT NULL;

View file

@ -0,0 +1,41 @@
-----------------------------------------------------
-- PostgreSQL
-----------------------------------------------------
INSERT INTO "revenue"
SELECT gen_random_uuid() revenue_id,
ed.website_id,
we.session_id,
we.event_id,
we.event_name,
currency.string_value currency,
coalesce(ed.number_value, cast(ed.string_value as numeric(19,4))) revenue,
ed.created_at
FROM event_data ed
JOIN website_event we
ON we.event_id = ed.website_event_id
JOIN (SELECT website_event_id, string_value
FROM event_data
WHERE data_key ilike '%currency%') currency
ON currency.website_event_id = ed.website_event_id
WHERE ed.data_key ilike '%revenue%';
-----------------------------------------------------
-- MySQL
-----------------------------------------------------
INSERT INTO `revenue`
SELECT UUID() revenue_id,
ed.website_id,
we.session_id,
we.event_id,
we.event_name,
currency.string_value currency,
coalesce(ed.number_value, cast(ed.string_value as decimal(19,4))) revenue,
ed.created_at
FROM event_data ed
JOIN website_event we
ON we.event_id = ed.website_event_id
JOIN (SELECT website_event_id, string_value
FROM event_data
WHERE data_key like '%currency%') currency
ON currency.website_event_id = ed.website_event_id
WHERE ed.data_key like '%revenue%';

View file

@ -1,3 +0,0 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"

View file

@ -1,12 +1,11 @@
---
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
image: ghcr.io/umami-software/umami:latest
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://umami:umami@db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: replace-me-with-a-random-string
depends_on:
db:

View file

@ -1,47 +0,0 @@
import { NextResponse } from 'next/server';
export const config = {
matcher: '/:path*',
};
function customCollectEndpoint(req) {
const collectEndpoint = process.env.COLLECT_API_ENDPOINT;
if (collectEndpoint) {
const url = req.nextUrl.clone();
const { pathname } = url;
if (pathname.endsWith(collectEndpoint)) {
url.pathname = '/api/send';
return NextResponse.rewrite(url);
}
}
}
function customScriptName(req) {
const scriptName = process.env.TRACKER_SCRIPT_NAME;
if (scriptName) {
const url = req.nextUrl.clone();
const { pathname } = url;
const names = scriptName.split(',').map(name => name.trim().replace(/^\/+/, ''));
if (names.find(name => pathname.endsWith(name))) {
url.pathname = '/script.js';
return NextResponse.rewrite(url);
}
}
}
export default function middleware(req) {
const fns = [customCollectEndpoint, customScriptName];
for (const fn of fns) {
const res = fn(req);
if (res) {
return res;
}
}
return NextResponse.next();
}

78
docker/middleware.ts Normal file
View file

@ -0,0 +1,78 @@
import { type NextRequest, NextResponse } from 'next/server';
export const config = {
matcher: '/:path*',
};
const TRACKER_PATH = '/script.js';
const COLLECT_PATH = '/api/send';
const LOGIN_PATH = '/login';
const apiHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': 'GET, DELETE, POST, PUT',
'Access-Control-Max-Age': process.env.CORS_MAX_AGE || '86400',
'Cache-Control': 'no-cache',
};
const trackerHeaders = {
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'public, max-age=86400, must-revalidate',
};
function customCollectEndpoint(request: NextRequest) {
const collectEndpoint = process.env.COLLECT_API_ENDPOINT;
if (collectEndpoint) {
const url = request.nextUrl.clone();
if (url.pathname.endsWith(collectEndpoint)) {
url.pathname = COLLECT_PATH;
return NextResponse.rewrite(url, { headers: apiHeaders });
}
}
}
function customScriptName(request: NextRequest) {
const scriptName = process.env.TRACKER_SCRIPT_NAME;
if (scriptName) {
const url = request.nextUrl.clone();
const names = scriptName.split(',').map(name => name.trim().replace(/^\/+/, ''));
if (names.find(name => url.pathname.endsWith(name))) {
url.pathname = TRACKER_PATH;
return NextResponse.rewrite(url, { headers: trackerHeaders });
}
}
}
function customScriptUrl(request: NextRequest) {
const scriptUrl = process.env.TRACKER_SCRIPT_URL;
if (scriptUrl && request.nextUrl.pathname.endsWith(TRACKER_PATH)) {
return NextResponse.rewrite(scriptUrl, { headers: trackerHeaders });
}
}
function disableLogin(request: NextRequest) {
const loginDisabled = process.env.DISABLE_LOGIN;
if (loginDisabled && request.nextUrl.pathname.endsWith(LOGIN_PATH)) {
return new NextResponse('Access denied', { status: 403 });
}
}
export default function middleware(req: NextRequest) {
const fns = [customCollectEndpoint, customScriptName, customScriptUrl, disableLogin];
for (const fn of fns) {
const res = fn(req);
if (res) {
return res;
}
}
return NextResponse.next();
}

View file

@ -4,4 +4,7 @@ export default {
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
},
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
};

View file

@ -1,6 +0,0 @@
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}

View file

@ -1,61 +0,0 @@
{
"cs-CZ": ["label.reset", "metrics.device.tablet"],
"de-CH": [
"label.admin",
"label.analytics",
"label.desktop",
"label.details",
"label.domain",
"label.laptop",
"label.tablet",
"label.name",
"label.sessions",
"label.team",
"label.team-id",
"label.teams"
],
"de-DE": [
"label.admin",
"label.analytics",
"label.desktop",
"label.details",
"label.domain",
"label.laptop",
"label.tablet",
"label.name",
"label.sessions",
"label.team",
"label.team-id",
"label.teams"
],
"en-GB": "*",
"fr-FR": ["metrics.actions", "metrics.pages"],
"lt-LT": [
"metrics.device.desktop",
"metrics.device.laptop",
"metrics.referrers",
"message.powered-by"
],
"mn-MN": ["label.max", "label.min", "label.os", "label.query", "label.url", "label.urls"],
"nb-NO": ["label.administrator", "label.dashboard"],
"nl-NL": [
"label.analytics",
"label.browsers",
"label.laptop",
"label.tablet",
"label.team",
"label.team-id",
"label.teams",
"label.website-id",
"label.websites"
],
"it-IT": [
"label.password",
"label.reset",
"message.powered-by",
"metrics.device.desktop",
"metrics.device.tablet",
"metrics.filter.raw"
],
"pt-PT": ["label.websites", "metrics.device.desktop", "metrics.device.tablet"]
}

3
next-env.d.ts vendored
View file

@ -1,5 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View file

@ -1,220 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires */
require('dotenv').config();
const pkg = require('./package.json');
const TRACKER_SCRIPT = '/script.js';
const basePath = process.env.BASE_PATH;
const collectApiEndpoint = process.env.COLLECT_API_ENDPOINT;
const cloudMode = process.env.CLOUD_MODE;
const cloudUrl = process.env.CLOUD_URL;
const corsMaxAge = process.env.CORS_MAX_AGE;
const defaultLocale = process.env.DEFAULT_LOCALE;
const disableLogin = process.env.DISABLE_LOGIN;
const disableUI = process.env.DISABLE_UI;
const forceSSL = process.env.FORCE_SSL;
const frameAncestors = process.env.ALLOWED_FRAME_URLS;
const privateMode = process.env.PRIVATE_MODE;
const trackerScriptName = process.env.TRACKER_SCRIPT_NAME;
const trackerScriptURL = process.env.TRACKER_SCRIPT_URL;
const contentSecurityPolicy = [
`default-src 'self'`,
`img-src * data:`,
`script-src 'self' 'unsafe-eval' 'unsafe-inline'`,
`style-src 'self' 'unsafe-inline'`,
`connect-src 'self' api.umami.is cloud.umami.is`,
`frame-ancestors 'self' ${frameAncestors}`,
];
const defaultHeaders = [
{
key: 'X-DNS-Prefetch-Control',
value: 'on',
},
{
key: 'Content-Security-Policy',
value: contentSecurityPolicy
.join(';')
.replace(/\s{2,}/g, ' ')
.trim(),
},
];
if (forceSSL) {
defaultHeaders.push({
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload',
});
}
const trackerHeaders = [
{
key: 'Access-Control-Allow-Origin',
value: '*',
},
{
key: 'Cache-Control',
value: 'public, max-age=86400, must-revalidate',
},
];
const headers = [
{
source: '/api/:path*',
headers: [
{ key: 'Access-Control-Allow-Origin', value: '*' },
{ key: 'Access-Control-Allow-Headers', value: '*' },
{ key: 'Access-Control-Allow-Methods', value: 'GET, DELETE, POST, PUT' },
{ key: 'Access-Control-Max-Age', value: corsMaxAge || '86400' },
],
},
{
source: '/:path*',
headers: defaultHeaders,
},
{
source: TRACKER_SCRIPT,
headers: trackerHeaders,
},
];
const rewrites = [];
if (trackerScriptURL) {
rewrites.push({
source: TRACKER_SCRIPT,
destination: trackerScriptURL,
});
}
if (collectApiEndpoint) {
rewrites.push({
source: collectApiEndpoint,
destination: '/api/send',
});
}
const redirects = [
{
source: '/settings',
destination: '/settings/websites',
permanent: true,
},
{
source: '/teams/:id',
destination: '/teams/:id/dashboard',
permanent: true,
},
{
source: '/teams/:id/settings',
destination: '/teams/:id/settings/team',
permanent: true,
},
];
// Adding rewrites + headers for all alternative tracker script names.
if (trackerScriptName) {
const names = trackerScriptName?.split(',').map(name => name.trim());
if (names) {
names.forEach(name => {
const normalizedSource = `/${name.replace(/^\/+/, '')}`;
rewrites.push({
source: normalizedSource,
destination: TRACKER_SCRIPT,
});
headers.push({
source: normalizedSource,
headers: trackerHeaders,
});
});
}
}
if (cloudMode && cloudUrl) {
redirects.push({
source: '/settings/:path*',
destination: `${cloudUrl}/settings/:path*`,
permanent: false,
});
redirects.push({
source: '/teams/:id/settings/:path*',
destination: `${cloudUrl}/teams/:id/settings/:path*`,
permanent: false,
});
if (disableLogin) {
redirects.push({
source: '/login',
destination: cloudUrl,
permanent: false,
});
}
}
/** @type {import('next').NextConfig} */
const config = {
reactStrictMode: false,
env: {
basePath,
cloudMode,
cloudUrl,
configUrl: '/config',
currentVersion: pkg.version,
defaultLocale,
disableLogin,
disableUI,
privateMode,
},
basePath,
output: 'standalone',
eslint: {
ignoreDuringBuilds: true,
},
typescript: {
ignoreBuildErrors: true,
},
experimental: {
turbo: {
rules: {
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
},
},
},
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
issuer: /\.(js|ts)x?$/,
use: ['@svgr/webpack'],
});
return config;
},
async headers() {
return headers;
},
async rewrites() {
return [
...rewrites,
{
source: '/telemetry.js',
destination: '/api/scripts/telemetry',
},
{
source: '/teams/:teamId/:path((?!settings).*)*',
destination: '/:path*',
},
];
},
async redirects() {
return [...redirects];
},
};
module.exports = config;

202
next.config.ts Normal file
View file

@ -0,0 +1,202 @@
import 'dotenv/config';
import pkg from './package.json' with { type: 'json' };
const TRACKER_SCRIPT = '/script.js';
const basePath = process.env.BASE_PATH || '';
const cloudMode = process.env.CLOUD_MODE || '';
const cloudUrl = process.env.CLOUD_URL || '';
const collectApiEndpoint = process.env.COLLECT_API_ENDPOINT || '';
const corsMaxAge = process.env.CORS_MAX_AGE || '';
const defaultLocale = process.env.DEFAULT_LOCALE || '';
const forceSSL = process.env.FORCE_SSL || '';
const frameAncestors = process.env.ALLOWED_FRAME_URLS || '';
const trackerScriptName = process.env.TRACKER_SCRIPT_NAME || '';
const trackerScriptURL = process.env.TRACKER_SCRIPT_URL || '';
const contentSecurityPolicy = `
default-src 'self';
img-src 'self' https: data:;
script-src 'self' 'unsafe-eval' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
connect-src 'self' https:;
frame-ancestors 'self' ${frameAncestors};
`;
const defaultHeaders = [
{
key: 'X-DNS-Prefetch-Control',
value: 'on',
},
{
key: 'Content-Security-Policy',
value: contentSecurityPolicy.replace(/\s{2,}/g, ' ').trim(),
},
];
if (forceSSL) {
defaultHeaders.push({
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload',
});
}
const trackerHeaders = [
{
key: 'Access-Control-Allow-Origin',
value: '*',
},
{
key: 'Cache-Control',
value: 'public, max-age=86400, must-revalidate',
},
];
const apiHeaders = [
{
key: 'Access-Control-Allow-Origin',
value: '*',
},
{
key: 'Access-Control-Allow-Headers',
value: '*',
},
{
key: 'Access-Control-Allow-Methods',
value: 'GET, DELETE, POST, PUT',
},
{
key: 'Access-Control-Max-Age',
value: corsMaxAge || '86400',
},
{
key: 'Cache-Control',
value: 'no-cache',
},
];
const headers = [
{
source: '/api/:path*',
headers: apiHeaders,
},
{
source: '/:path*',
headers: defaultHeaders,
},
{
source: TRACKER_SCRIPT,
headers: trackerHeaders,
},
];
const rewrites = [];
if (trackerScriptURL) {
rewrites.push({
source: TRACKER_SCRIPT,
destination: trackerScriptURL,
});
}
if (collectApiEndpoint) {
headers.push({
source: collectApiEndpoint,
headers: apiHeaders,
});
rewrites.push({
source: collectApiEndpoint,
destination: '/api/send',
});
}
const redirects = [
{
source: '/settings',
destination: '/settings/preferences',
permanent: false,
},
{
source: '/teams/:id',
destination: '/teams/:id/websites',
permanent: false,
},
{
source: '/teams/:id/settings',
destination: '/teams/:id/settings/preferences',
permanent: false,
},
{
source: '/admin',
destination: '/admin/users',
permanent: false,
},
];
// Adding rewrites + headers for all alternative tracker script names.
if (trackerScriptName) {
const names = trackerScriptName?.split(',').map(name => name.trim());
if (names) {
names.forEach(name => {
const normalizedSource = `/${name.replace(/^\/+/, '')}`;
rewrites.push({
source: normalizedSource,
destination: TRACKER_SCRIPT,
});
headers.push({
source: normalizedSource,
headers: trackerHeaders,
});
});
}
}
if (cloudMode) {
rewrites.push({
source: '/script.js',
destination: 'https://cloud.umami.is/script.js',
});
}
/** @type {import('next').NextConfig} */
export default {
reactStrictMode: false,
env: {
basePath,
cloudMode,
cloudUrl,
currentVersion: pkg.version,
defaultLocale,
},
basePath,
output: 'standalone',
eslint: {
ignoreDuringBuilds: true,
},
typescript: {
ignoreBuildErrors: true,
},
async headers() {
return headers;
},
async rewrites() {
return [
...rewrites,
{
source: '/telemetry.js',
destination: '/api/scripts/telemetry',
},
{
source: '/teams/:teamId/:path*',
destination: '/:path*',
},
];
},
async redirects() {
return [...redirects];
},
};

View file

@ -1,24 +1,10 @@
{
"name": "@umami/components",
"version": "0.1.0",
"version": "0.130.0",
"description": "Umami React components.",
"author": "Mike Cao <mike@mikecao.com>",
"license": "MIT",
"type": "module",
"main": "./index.js",
"types": "./index.d.ts",
"peerDependencies": {
"@tanstack/react-query": "^4.33.0",
"classnames": "^2.3.1",
"colord": "^2.9.2",
"date-fns-tz": "^1.1.4",
"immer": "^9.0.12",
"moment-timezone": "^0.5.35",
"next": "^13.4.0",
"next-basics": "^0.36.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-intl": "^5.24.7",
"zustand": "^4.3.8"
}
"types": "./index.d.ts"
}

View file

@ -1,7 +1,7 @@
{
"name": "umami",
"version": "2.16.1",
"description": "A simple, fast, privacy-focused alternative to Google Analytics.",
"version": "3.0.2",
"description": "A modern, privacy-focused alternative to Google Analytics.",
"author": "Umami Software, Inc. <hello@umami.is>",
"license": "MIT",
"homepage": "https://umami.is",
@ -9,20 +9,23 @@
"type": "git",
"url": "https://github.com/umami-software/umami.git"
},
"type": "module",
"scripts": {
"dev": "next dev -p 3000 --turbo",
"dev": "next dev -p 3001 --turbo",
"build": "npm-run-all check-env build-db check-db build-tracker build-geo build-app",
"start": "next start",
"build-docker": "npm-run-all build-db build-tracker build-geo build-app",
"start-docker": "npm-run-all check-db update-tracker start-server",
"start-env": "node scripts/start-env.js",
"start-server": "node server.js",
"build-app": "next build",
"build-components": "rollup -c rollup.components.config.mjs",
"build-tracker": "rollup -c rollup.tracker.config.mjs",
"build-db": "npm-run-all copy-db-files build-db-client",
"build-lang": "npm-run-all format-lang compile-lang clean-lang download-country-names download-language-names",
"build-app": "next build --turbo",
"build-icons": "svgr ./src/assets --out-dir src/components/svg --typescript",
"build-components": "tsup",
"build-tracker": "rollup -c rollup.tracker.config.js",
"build-prisma-client": "node scripts/build-prisma-client.js",
"build-lang": "npm-run-all format-lang compile-lang download-country-names download-language-names clean-lang",
"build-geo": "node scripts/build-geo.js",
"build-db": "npm-run-all build-db-client build-prisma-client",
"build-db-schema": "prisma db pull",
"build-db-client": "prisma generate",
"update-tracker": "node scripts/update-tracker.js",
@ -35,50 +38,46 @@
"generate-lang": "npm-run-all extract-messages merge-messages",
"format-lang": "node scripts/format-lang.js",
"compile-lang": "formatjs compile-folder --ast build/messages public/intl/messages",
"clean-lang": "prettier --write ./public/intl/messages/*.json",
"check-lang": "node scripts/check-lang.js",
"clean-lang": "prettier --write ./public/intl/**/*.json",
"download-country-names": "node scripts/download-country-names.js",
"download-language-names": "node scripts/download-language-names.js",
"change-password": "node scripts/change-password.js",
"lint": "next lint --quiet",
"prepare": "node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky install",
"postbuild": "node scripts/postbuild.js",
"test": "jest",
"cypress-open": "cypress open cypress run",
"cypress-run": "cypress run cypress run"
"cypress-run": "cypress run cypress run",
"seed-data": "tsx scripts/seed-data.ts",
"lint": "biome lint .",
"format": "biome format --write .",
"check": "biome check --write"
},
"lint-staged": {
"**/*.{js,jsx,ts,tsx}": [
"prettier --write",
"eslint"
],
"**/*.css": [
"stylelint --fix",
"prettier --write"
],
"**/*.json": [
"prettier --write"
"**/*.{js,jsx,ts,tsx,json,css}": [
"biome check --write --no-errors-on-unmatched --files-ignore-unknown=true"
]
},
"cacheDirectories": [
".next/cache"
],
"dependencies": {
"@clickhouse/client": "^1.10.1",
"@clickhouse/client": "^1.12.0",
"@date-fns/utc": "^1.2.0",
"@dicebear/collection": "^9.2.1",
"@dicebear/core": "^9.2.1",
"@fontsource/inter": "^4.5.15",
"@dicebear/collection": "^9.2.3",
"@dicebear/core": "^9.2.3",
"@fontsource/inter": "^5.2.8",
"@hello-pangea/dnd": "^17.0.0",
"@prisma/client": "6.1.0",
"@prisma/extension-read-replicas": "^0.4.0",
"@react-spring/web": "^9.7.3",
"@tanstack/react-query": "^5.28.6",
"@umami/prisma-client": "^0.14.0",
"@umami/redis-client": "^0.26.0",
"bcryptjs": "^2.4.3",
"chalk": "^4.1.1",
"chart.js": "^4.4.2",
"@prisma/adapter-pg": "^6.18.0",
"@prisma/client": "^6.18.0",
"@prisma/extension-read-replicas": "^0.4.1",
"@react-spring/web": "^10.0.3",
"@svgr/cli": "^8.1.0",
"@tanstack/react-query": "^5.90.11",
"@umami/react-zen": "^0.211.0",
"@umami/redis-client": "^0.29.0",
"bcryptjs": "^3.0.2",
"chalk": "^5.6.2",
"chart.js": "^4.5.1",
"chartjs-adapter-date-fns": "^3.0.0",
"classnames": "^2.3.1",
"colord": "^2.9.2",
@ -86,100 +85,90 @@
"cross-spawn": "^7.0.3",
"date-fns": "^2.23.0",
"date-fns-tz": "^1.1.4",
"debug": "^4.3.4",
"debug": "^4.4.3",
"del": "^6.0.0",
"detect-browser": "^5.2.0",
"dotenv": "^10.0.0",
"eslint-plugin-promise": "^6.1.1",
"fs-extra": "^10.0.1",
"immer": "^9.0.12",
"ipaddr.js": "^2.0.1",
"dotenv": "^17.2.3",
"esbuild": "^0.25.11",
"fs-extra": "^11.3.2",
"immer": "^10.2.0",
"ipaddr.js": "^2.3.0",
"is-ci": "^3.0.1",
"is-docker": "^3.0.0",
"is-localhost-ip": "^1.4.0",
"isbot": "^5.1.16",
"is-localhost-ip": "^2.0.0",
"isbot": "^5.1.31",
"jsonwebtoken": "^9.0.2",
"jszip": "^3.10.1",
"kafkajs": "^2.1.0",
"maxmind": "^4.3.24",
"md5": "^2.3.0",
"next": "15.0.4",
"lucide-react": "^0.543.0",
"maxmind": "^5.0.0",
"next": "^15.5.7",
"node-fetch": "^3.2.8",
"npm-run-all": "^4.1.5",
"prisma": "6.1.0",
"pure-rand": "^6.1.0",
"react": "^19.0.0",
"react-basics": "^0.126.0",
"react-dom": "^19.0.0",
"papaparse": "^5.5.3",
"pg": "^8.16.3",
"prisma": "^6.18.0",
"pure-rand": "^7.0.1",
"react": "^19.2.1",
"react-dom": "^19.2.1",
"react-error-boundary": "^4.0.4",
"react-intl": "^6.5.5",
"react-intl": "^7.1.14",
"react-simple-maps": "^2.3.0",
"react-use-measure": "^2.0.4",
"react-window": "^1.8.6",
"request-ip": "^3.3.0",
"semver": "^7.5.4",
"semver": "^7.7.3",
"serialize-error": "^12.0.0",
"thenby": "^1.3.4",
"uuid": "^9.0.0",
"zod": "^3.24.1",
"zustand": "^4.5.5"
"ua-parser-js": "^2.0.6",
"uuid": "^11.1.0",
"zod": "^4.1.13",
"zustand": "^5.0.9"
},
"devDependencies": {
"@biomejs/biome": "^2.3.8",
"@formatjs/cli": "^4.2.29",
"@netlify/plugin-nextjs": "^5.8.1",
"@netlify/plugin-nextjs": "^5.15.1",
"@rollup/plugin-alias": "^5.0.0",
"@rollup/plugin-commonjs": "^25.0.4",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.2.0",
"@rollup/plugin-replace": "^5.0.2",
"@svgr/rollup": "^8.1.0",
"@svgr/webpack": "^8.1.0",
"@types/cypress": "^1.1.3",
"@types/jest": "^29.5.14",
"@types/node": "^22.13.4",
"@types/react": "^19.0.8",
"@types/react-dom": "^19.0.2",
"@types/react-intl": "^3.0.0",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.3.0",
"@types/jest": "^30.0.0",
"@types/node": "^24.9.2",
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.2",
"@types/react-window": "^1.8.8",
"@typescript-eslint/eslint-plugin": "^6.7.3",
"@typescript-eslint/parser": "^6.7.3",
"cross-env": "^7.0.3",
"babel-plugin-react-compiler": "19.1.0-rc.2",
"cross-env": "^10.1.0",
"cypress": "^13.6.6",
"esbuild": "^0.25.0",
"eslint": "^8.33.0",
"eslint-config-next": "^14.0.4",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-css-modules": "^2.12.0",
"eslint-plugin-cypress": "^2.15.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jest": "^27.9.0",
"eslint-plugin-prettier": "^4.0.0",
"extract-react-intl-messages": "^4.1.1",
"husky": "^8.0.3",
"husky": "^9.1.7",
"jest": "^29.7.0",
"lint-staged": "^14.0.1",
"postcss": "^8.4.31",
"lint-staged": "^16.2.6",
"postcss": "^8.5.6",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-import": "^15.1.0",
"postcss-preset-env": "7.8.3",
"postcss-rtlcss": "^4.0.1",
"prettier": "^2.6.2",
"prompts": "2.4.2",
"rollup": "^3.28.0",
"rollup": "^4.52.5",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-delete": "^2.0.0",
"rollup-plugin-dts": "^5.3.1",
"rollup-plugin-esbuild": "^5.0.0",
"rollup-plugin-node-externals": "^6.1.1",
"rollup-plugin-delete": "^3.0.1",
"rollup-plugin-dts": "^6.3.0",
"rollup-plugin-node-externals": "^8.1.1",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-terser": "^7.0.2",
"stylelint": "^15.10.1",
"stylelint-config-css-modules": "^4.4.0",
"stylelint-config-css-modules": "^4.5.1",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-recommended": "^14.0.0",
"tar": "^6.1.2",
"ts-jest": "^29.1.2",
"ts-jest": "^29.4.6",
"ts-node": "^10.9.1",
"typescript": "^5.5.3"
"tsup": "^8.5.0",
"tsx": "^4.19.0",
"typescript": "^5.9.3"
}
}

15102
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load diff

10
pnpm-workspace.yaml Normal file
View file

@ -0,0 +1,10 @@
packages:
- '**'
ignoredBuiltDependencies:
- cypress
- esbuild
- sharp
onlyBuiltDependencies:
- '@prisma/client'
- '@prisma/engines'
- prisma

50
podman/README.md Normal file
View file

@ -0,0 +1,50 @@
# How to deploy umami on podman
## How to use
1. Rename `env.sample` to `.env`
2. Edit `.env` file. At the minimum set the passwords.
3. Start umami by running `podman-compose up -d`.
If you need to stop umami, you can do so by running `podman-compose down`.
### Install systemd service (optional)
If you want to install a systemd service to run umami, you can use the provided
systemd service.
Edit `umami.service` and change these two variables:
WorkingDirectory=/opt/apps/umami
EnvironmentFile=/opt/apps/umami/.env
`WorkingDirectory` should be changed to the path in which `podman-compose.yml`
is located.
`EnvironmentFile` should be changed to the path in which your `.env`file is
located.
You can run the script `install-systemd-user-service` to install the systemd
service under the current user.
./install-systemd-user-service
Note: this script will enable the service and also start it. So it will assume
that umami is not currently running. If you started it previously, bring it
down using:
podman-compose down
## Compatibility
These files should be compatible with podman 4.3+.
I have tested this on Debian GNU/Linux 12 (bookworm) and with the podman that
is distributed with the official Debian stable mirrors (podman
v4.3.1+ds1-8+deb12u1, podman-compose v1.0.3-3).

16
podman/env.sample Normal file
View file

@ -0,0 +1,16 @@
# Rename this file to .env and modify the values
#
# Connection string for Umamis database.
# If you use the bundled DB container, "db" is the hostname.
DATABASE_URL=postgresql://umami:replace-me-with-a-random-string@db:5432/umami
# Database type (e.g. postgresql)
DATABASE_TYPE=postgresql
# A secret string used by Umami (replace with a strong random string)
APP_SECRET=replace-me-with-a-random-string
# Postgres container defaults.
POSTGRES_DB=umami
POSTGRES_USER=umami
POSTGRES_PASSWORD=replace-me-with-a-random-string

View file

@ -0,0 +1,10 @@
#!/bin/bash
set -e
service_name="umami"
mkdir -p ~/.config/systemd/user
cp $service_name.service ~/.config/systemd/user
systemctl --user daemon-reload
systemctl --user enable $service_name.service
systemctl --user start $service_name.service

41
podman/podman-compose.yml Normal file
View file

@ -0,0 +1,41 @@
version: "3.8"
services:
umami:
container_name: umami
image: ghcr.io/umami-software/umami:postgresql-latest
ports:
- "127.0.0.1:3000:3000"
environment:
DATABASE_URL: ${DATABASE_URL}
DATABASE_TYPE: ${DATABASE_TYPE}
APP_SECRET: ${APP_SECRET}
depends_on:
db:
condition: service_healthy
init: true
restart: always
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/api/heartbeat || exit 1"]
interval: 5s
timeout: 5s
retries: 5
db:
container_name: umami-db
image: docker.io/library/postgres:15-alpine
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- umami-db-data:/var/lib/postgresql/data:Z
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
volumes:
umami-db-data:

14
podman/umami.service Normal file
View file

@ -0,0 +1,14 @@
[Unit]
Description=Umami Container Stack via Podman-Compose
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/apps/umami
EnvironmentFile=/opt/apps/umami/.env
ExecStart=/usr/bin/podman-compose -f podman-compose.yml up -d
ExecStop=/usr/bin/podman-compose -f podman-compose.yml down
RemainAfterExit=yes
[Install]
WantedBy=default.target

View file

@ -1,4 +1,4 @@
module.exports = {
export default {
plugins: [
'postcss-flexbugs-fixes',
[

8
prisma.config.ts Normal file
View file

@ -0,0 +1,8 @@
import 'dotenv/config';
import { defineConfig, env } from 'prisma/config';
export default defineConfig({
datasource: {
url: env('DATABASE_URL'),
},
});

View file

@ -0,0 +1,13 @@
-- AlterTable
ALTER TABLE "website_event"
ADD COLUMN "fbclid" VARCHAR(255),
ADD COLUMN "gclid" VARCHAR(255),
ADD COLUMN "li_fat_id" VARCHAR(255),
ADD COLUMN "msclkid" VARCHAR(255),
ADD COLUMN "ttclid" VARCHAR(255),
ADD COLUMN "twclid" VARCHAR(255),
ADD COLUMN "utm_campaign" VARCHAR(255),
ADD COLUMN "utm_content" VARCHAR(255),
ADD COLUMN "utm_medium" VARCHAR(255),
ADD COLUMN "utm_source" VARCHAR(255),
ADD COLUMN "utm_term" VARCHAR(255);

View file

@ -0,0 +1,25 @@
-- AlterTable
ALTER TABLE "website_event" ADD COLUMN "hostname" VARCHAR(100);
-- DataMigration
UPDATE "website_event" w
SET hostname = s.hostname
FROM "session" s
WHERE s.website_id = w.website_id
and s.session_id = w.session_id;
-- DropIndex
DROP INDEX IF EXISTS "session_website_id_created_at_hostname_idx";
DROP INDEX IF EXISTS "session_website_id_created_at_subdivision1_idx";
-- AlterTable
ALTER TABLE "session" RENAME COLUMN "subdivision1" TO "region";
ALTER TABLE "session" DROP COLUMN "subdivision2";
ALTER TABLE "session" DROP COLUMN "hostname";
-- CreateIndex
CREATE INDEX "website_event_website_id_created_at_hostname_idx" ON "website_event"("website_id", "created_at", "hostname");
CREATE INDEX "session_website_id_created_at_region_idx" ON "session"("website_id", "created_at", "region");

View file

@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "session" ADD COLUMN "distinct_id" VARCHAR(50);
-- AlterTable
ALTER TABLE "session_data" ADD COLUMN "distinct_id" VARCHAR(50);

View file

@ -0,0 +1,18 @@
-- CreateTable
CREATE TABLE "segment" (
"segment_id" UUID NOT NULL,
"website_id" UUID NOT NULL,
"type" VARCHAR(200) NOT NULL,
"name" VARCHAR(200) NOT NULL,
"parameters" JSONB NOT NULL,
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ(6),
CONSTRAINT "segment_pkey" PRIMARY KEY ("segment_id")
);
-- CreateIndex
CREATE UNIQUE INDEX "segment_segment_id_key" ON "segment"("segment_id");
-- CreateIndex
CREATE INDEX "segment_website_id_idx" ON "segment"("website_id");

View file

@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "report"
ALTER COLUMN "parameters" SET DATA TYPE JSONB USING parameters::JSONB;

View file

@ -0,0 +1,28 @@
-- CreateTable
CREATE TABLE "revenue" (
"revenue_id" UUID NOT NULL,
"website_id" UUID NOT NULL,
"session_id" UUID NOT NULL,
"event_id" UUID NOT NULL,
"event_name" VARCHAR(50) NOT NULL,
"currency" VARCHAR(100) NOT NULL,
"revenue" DECIMAL(19,4),
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "revenue_pkey" PRIMARY KEY ("revenue_id")
);
-- CreateIndex
CREATE UNIQUE INDEX "revenue_revenue_id_key" ON "revenue"("revenue_id");
-- CreateIndex
CREATE INDEX "revenue_website_id_idx" ON "revenue"("website_id");
-- CreateIndex
CREATE INDEX "revenue_session_id_idx" ON "revenue"("session_id");
-- CreateIndex
CREATE INDEX "revenue_website_id_created_at_idx" ON "revenue"("website_id", "created_at");
-- CreateIndex
CREATE INDEX "revenue_website_id_session_id_created_at_idx" ON "revenue"("website_id", "session_id", "created_at");

View file

@ -0,0 +1,119 @@
-- AlterTable
ALTER TABLE "report" ALTER COLUMN "type" SET DATA TYPE VARCHAR(50);
-- AlterTable
ALTER TABLE "revenue" ALTER COLUMN "currency" SET DATA TYPE VARCHAR(10);
-- AlterTable
ALTER TABLE "segment" ALTER COLUMN "type" SET DATA TYPE VARCHAR(50);
-- CreateTable
CREATE TABLE "link" (
"link_id" UUID NOT NULL,
"name" VARCHAR(100) NOT NULL,
"url" VARCHAR(500) NOT NULL,
"slug" VARCHAR(100) NOT NULL,
"user_id" UUID,
"team_id" UUID,
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ(6),
"deleted_at" TIMESTAMPTZ(6),
CONSTRAINT "link_pkey" PRIMARY KEY ("link_id")
);
-- CreateTable
CREATE TABLE "pixel" (
"pixel_id" UUID NOT NULL,
"name" VARCHAR(100) NOT NULL,
"slug" VARCHAR(100) NOT NULL,
"user_id" UUID,
"team_id" UUID,
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ(6),
"deleted_at" TIMESTAMPTZ(6),
CONSTRAINT "pixel_pkey" PRIMARY KEY ("pixel_id")
);
-- CreateIndex
CREATE UNIQUE INDEX "link_link_id_key" ON "link"("link_id");
-- CreateIndex
CREATE UNIQUE INDEX "link_slug_key" ON "link"("slug");
-- CreateIndex
CREATE INDEX "link_slug_idx" ON "link"("slug");
-- CreateIndex
CREATE INDEX "link_user_id_idx" ON "link"("user_id");
-- CreateIndex
CREATE INDEX "link_team_id_idx" ON "link"("team_id");
-- CreateIndex
CREATE INDEX "link_created_at_idx" ON "link"("created_at");
-- CreateIndex
CREATE UNIQUE INDEX "pixel_pixel_id_key" ON "pixel"("pixel_id");
-- CreateIndex
CREATE UNIQUE INDEX "pixel_slug_key" ON "pixel"("slug");
-- CreateIndex
CREATE INDEX "pixel_slug_idx" ON "pixel"("slug");
-- CreateIndex
CREATE INDEX "pixel_user_id_idx" ON "pixel"("user_id");
-- CreateIndex
CREATE INDEX "pixel_team_id_idx" ON "pixel"("team_id");
-- CreateIndex
CREATE INDEX "pixel_created_at_idx" ON "pixel"("created_at");
-- DataMigration Funnel
DELETE FROM "report" WHERE type = 'funnel' and jsonb_array_length(parameters->'steps') = 1;
UPDATE "report" SET parameters = parameters - 'websiteId' - 'dateRange' - 'urls' WHERE type = 'funnel';
UPDATE "report"
SET parameters = jsonb_set(
parameters,
'{steps}',
(
SELECT jsonb_agg(
CASE
WHEN step->>'type' = 'url'
THEN jsonb_set(step, '{type}', '"path"')
ELSE step
END
)
FROM jsonb_array_elements(parameters->'steps') step
)
)
WHERE type = 'funnel'
and parameters @> '{"steps":[{"type":"url"}]}';
-- DataMigration Goals
UPDATE "report" SET type = 'goal' WHERE type = 'goals';
INSERT INTO "report" (report_id, user_id, website_id, type, name, description, parameters, created_at, updated_at)
SELECT gen_random_uuid(),
user_id,
website_id,
'goal',
concat(name, ' - ', elem ->> 'value'),
description,
jsonb_build_object(
'type', CASE WHEN elem ->> 'type' = 'url' THEN 'path'
ELSE elem ->> 'type' END,
'value', elem ->> 'value'
) AS parameters,
created_at,
updated_at
FROM "report"
CROSS JOIN LATERAL jsonb_array_elements(parameters -> 'goals') elem
WHERE type = 'goal'
and elem ->> 'type' IN ('event', 'url');
DELETE FROM "report" WHERE type = 'goal' and parameters ? 'goals';

View file

@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "postgresql"

View file

@ -1,6 +1,7 @@
generator client {
provider = "prisma-client-js"
binaryTargets = ["native"]
provider = "prisma-client"
output = "../src/generated/prisma"
engineType = "client"
}
datasource db {
@ -20,43 +21,44 @@ model User {
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
websiteUser Website[] @relation("user")
websiteCreateUser Website[] @relation("createUser")
teamUser TeamUser[]
report Report[]
websites Website[] @relation("user")
createdBy Website[] @relation("createUser")
links Link[] @relation("user")
pixels Pixel[] @relation("user")
teams TeamUser[]
reports Report[]
@@map("user")
}
model Session {
id String @id @unique @map("session_id") @db.Uuid
websiteId String @map("website_id") @db.Uuid
hostname String? @db.VarChar(100)
browser String? @db.VarChar(20)
os String? @db.VarChar(20)
device String? @db.VarChar(20)
screen String? @db.VarChar(11)
language String? @db.VarChar(35)
country String? @db.Char(2)
subdivision1 String? @db.VarChar(20)
subdivision2 String? @db.VarChar(50)
city String? @db.VarChar(50)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
id String @id @unique @map("session_id") @db.Uuid
websiteId String @map("website_id") @db.Uuid
browser String? @db.VarChar(20)
os String? @db.VarChar(20)
device String? @db.VarChar(20)
screen String? @db.VarChar(11)
language String? @db.VarChar(35)
country String? @db.Char(2)
region String? @db.VarChar(20)
city String? @db.VarChar(50)
distinctId String? @map("distinct_id") @db.VarChar(50)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
websiteEvent WebsiteEvent[]
sessionData SessionData[]
websiteEvents WebsiteEvent[]
sessionData SessionData[]
revenue Revenue[]
@@index([createdAt])
@@index([websiteId])
@@index([websiteId, createdAt])
@@index([websiteId, createdAt, hostname])
@@index([websiteId, createdAt, browser])
@@index([websiteId, createdAt, os])
@@index([websiteId, createdAt, device])
@@index([websiteId, createdAt, screen])
@@index([websiteId, createdAt, language])
@@index([websiteId, createdAt, country])
@@index([websiteId, createdAt, subdivision1])
@@index([websiteId, createdAt, region])
@@index([websiteId, createdAt, city])
@@map("session")
}
@ -78,7 +80,9 @@ model Website {
createUser User? @relation("createUser", fields: [createdBy], references: [id])
team Team? @relation(fields: [teamId], references: [id])
eventData EventData[]
report Report[]
reports Report[]
revenue Revenue[]
segments Segment[]
sessionData SessionData[]
@@index([userId])
@ -97,13 +101,25 @@ model WebsiteEvent {
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
urlPath String @map("url_path") @db.VarChar(500)
urlQuery String? @map("url_query") @db.VarChar(500)
utmSource String? @map("utm_source") @db.VarChar(255)
utmMedium String? @map("utm_medium") @db.VarChar(255)
utmCampaign String? @map("utm_campaign") @db.VarChar(255)
utmContent String? @map("utm_content") @db.VarChar(255)
utmTerm String? @map("utm_term") @db.VarChar(255)
referrerPath String? @map("referrer_path") @db.VarChar(500)
referrerQuery String? @map("referrer_query") @db.VarChar(500)
referrerDomain String? @map("referrer_domain") @db.VarChar(500)
pageTitle String? @map("page_title") @db.VarChar(500)
gclid String? @db.VarChar(255)
fbclid String? @db.VarChar(255)
msclkid String? @db.VarChar(255)
ttclid String? @db.VarChar(255)
lifatid String? @map("li_fat_id") @db.VarChar(255)
twclid String? @db.VarChar(255)
eventType Int @default(1) @map("event_type") @db.Integer
eventName String? @map("event_name") @db.VarChar(50)
tag String? @db.VarChar(50)
hostname String? @db.VarChar(100)
eventData EventData[]
session Session @relation(fields: [sessionId], references: [id])
@ -121,6 +137,7 @@ model WebsiteEvent {
@@index([websiteId, createdAt, tag])
@@index([websiteId, sessionId, createdAt])
@@index([websiteId, visitId, createdAt])
@@index([websiteId, createdAt, hostname])
@@map("website_event")
}
@ -155,6 +172,7 @@ model SessionData {
numberValue Decimal? @map("number_value") @db.Decimal(19, 4)
dateValue DateTime? @map("date_value") @db.Timestamptz(6)
dataType Int @map("data_type") @db.Integer
distinctId String? @map("distinct_id") @db.VarChar(50)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
website Website @relation(fields: [websiteId], references: [id])
@ -177,8 +195,10 @@ model Team {
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
website Website[]
teamUser TeamUser[]
websites Website[]
members TeamUser[]
links Link[]
pixels Pixel[]
@@index([accessCode])
@@map("team")
@ -188,7 +208,7 @@ model TeamUser {
id String @id() @unique() @map("team_user_id") @db.Uuid
teamId String @map("team_id") @db.Uuid
userId String @map("user_id") @db.Uuid
role String @map("role") @db.VarChar(50)
role String @db.VarChar(50)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
@ -204,10 +224,10 @@ model Report {
id String @id() @unique() @map("report_id") @db.Uuid
userId String @map("user_id") @db.Uuid
websiteId String @map("website_id") @db.Uuid
type String @map("type") @db.VarChar(200)
name String @map("name") @db.VarChar(200)
description String @map("description") @db.VarChar(500)
parameters String @map("parameters") @db.VarChar(6000)
type String @db.VarChar(50)
name String @db.VarChar(200)
description String @db.VarChar(500)
parameters Json
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
@ -220,3 +240,79 @@ model Report {
@@index([name])
@@map("report")
}
model Segment {
id String @id() @unique() @map("segment_id") @db.Uuid
websiteId String @map("website_id") @db.Uuid
type String @db.VarChar(50)
name String @db.VarChar(200)
parameters Json
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
website Website @relation(fields: [websiteId], references: [id])
@@index([websiteId])
@@map("segment")
}
model Revenue {
id String @id() @unique() @map("revenue_id") @db.Uuid
websiteId String @map("website_id") @db.Uuid
sessionId String @map("session_id") @db.Uuid
eventId String @map("event_id") @db.Uuid
eventName String @map("event_name") @db.VarChar(50)
currency String @db.VarChar(10)
revenue Decimal? @db.Decimal(19, 4)
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
website Website @relation(fields: [websiteId], references: [id])
session Session @relation(fields: [sessionId], references: [id])
@@index([websiteId])
@@index([sessionId])
@@index([websiteId, createdAt])
@@index([websiteId, sessionId, createdAt])
@@map("revenue")
}
model Link {
id String @id() @unique() @map("link_id") @db.Uuid
name String @db.VarChar(100)
url String @db.VarChar(500)
slug String @unique() @db.VarChar(100)
userId String? @map("user_id") @db.Uuid
teamId String? @map("team_id") @db.Uuid
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
user User? @relation("user", fields: [userId], references: [id])
team Team? @relation(fields: [teamId], references: [id])
@@index([slug])
@@index([userId])
@@index([teamId])
@@index([createdAt])
@@map("link")
}
model Pixel {
id String @id() @unique() @map("pixel_id") @db.Uuid
name String @db.VarChar(100)
slug String @unique() @db.VarChar(100)
userId String? @map("user_id") @db.Uuid
teamId String? @map("team_id") @db.Uuid
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6)
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
user User? @relation("user", fields: [userId], references: [id])
team Team? @relation(fields: [teamId], references: [id])
@@index([slug])
@@index([userId])
@@index([teamId])
@@index([createdAt])
@@map("pixel")
}

View file

@ -7202,7 +7202,7 @@
]
]
},
"id": "-99"
"id": "XKX"
},
{
"type": "Feature",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before After
Before After

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -97,6 +97,7 @@
"CN": "\u041a\u0438\u0442\u0430\u0439",
"CC": "\u041a\u043e\u043a\u043e\u0441\u043e\u0432\u0438 \u043e\u0441\u0442\u0440\u043e\u0432\u0438 (\u043e\u0441\u0442\u0440\u043e\u0432\u0438 \u041a\u0438\u0439\u043b\u0438\u043d\u0433)",
"CO": "\u041a\u043e\u043b\u0443\u043c\u0431\u0438\u044f",
"XK": "\u041a\u043e\u0441\u043e\u0432\u043e",
"KM": "\u041a\u043e\u043c\u043e\u0440\u0441\u043a\u0438 \u043e\u0441\u0442\u0440\u043e\u0432\u0438",
"CG": "\u041a\u043e\u043d\u0433\u043e (\u0411\u0440\u0430\u0437\u0430\u0432\u0438\u043b)",
"CD": "\u041a\u043e\u043d\u0433\u043e (\u041a\u0438\u043d\u0448\u0430\u0441\u0430)",

File diff suppressed because one or more lines are too long

View file

@ -119,6 +119,7 @@
"CO": "Kolumbija",
"KM": "Komori",
"CG": "Kongo",
"XK": "Kosovo",
"CR": "Kostarika",
"CU": "Kuba",
"CK": "Kukova ostrva",

View file

@ -1 +1,252 @@
{"AF":"Afganistan","AL":"Alb\u00e0nia","DE":"Alemanya","DZ":"Alg\u00e8ria","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Ant\u00e0rtida","AG":"Antigua i Barbuda","SA":"Ar\u00e0bia Saudita","AR":"Argentina","AM":"Arm\u00e8nia","AW":"Aruba","AU":"Austr\u00e0lia","AT":"\u00c0ustria","AZ":"Azerbaidjan","BS":"Bahames","BH":"Bahrain","BD":"Bangladesh","BB":"Barbados","BY":"Belar\u00fas","BE":"B\u00e8lgica","BZ":"Belize","BJ":"Ben\u00edn","BM":"Bermudes","BT":"Bhutan","BO":"Bol\u00edvia","BA":"B\u00f2snia i Hercegovina","BW":"Botswana","BV":"Bouvet","BR":"Brasil","BN":"Brunei","BG":"Bulg\u00e0ria","BF":"Burkina Faso","BI":"Burundi","KH":"Cambodja","CM":"Camerun","CA":"Canad\u00e0","CV":"Cap Verd","BQ":"Carib Neerland\u00e8s","VA":"Ciutat del Vatic\u00e0","CO":"Col\u00f2mbia","KM":"Comores","CG":"Congo - Brazzaville","CD":"Congo - Kinshasa","KP":"Corea del Nord","KR":"Corea del Sud","CR":"Costa Rica","CI":"C\u00f4te d\u2019Ivoire","HR":"Cro\u00e0cia","CU":"Cuba","CW":"Cura\u00e7ao","DK":"Dinamarca","DJ":"Djibouti","DM":"Dominica","EG":"Egipte","SV":"El Salvador","AE":"Emirats \u00c0rabs Units","EC":"Equador","ER":"Eritrea","SK":"Eslov\u00e0quia","SI":"Eslov\u00e8nia","ES":"Espanya","US":"Estats Units","EE":"Est\u00f2nia","SZ":"eSwatini","ET":"Eti\u00f2pia","FJ":"Fiji","PH":"Filipines","FI":"Finl\u00e0ndia","FR":"Fran\u00e7a","GA":"Gabon","GM":"G\u00e0mbia","GE":"Ge\u00f2rgia","GH":"Ghana","GI":"Gibraltar","GR":"Gr\u00e8cia","GD":"Grenada","GL":"Groenl\u00e0ndia","GP":"Guadeloupe","GF":"Guaiana Francesa","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea Bissau","GQ":"Guinea Equatorial","GY":"Guyana","HT":"Hait\u00ed","HN":"Hondures","HK":"Hong Kong (RAE Xina)","HU":"Hongria","YE":"Iemen","CX":"Illa Christmas","RE":"Illa de la Reuni\u00f3","IM":"Illa de Man","HM":"Illa Heard i Illes McDonald","AX":"Illes \u00c5land","KY":"Illes Caiman","CC":"Illes Cocos","CK":"Illes Cook","FO":"Illes F\u00e8roe","GS":"Illes Ge\u00f2rgia del Sud i Sandwich del Sud","FK":"Illes Malvines","MP":"Illes Mariannes del Nord","MH":"Illes Marshall","UM":"Illes Perif\u00e8riques Menors dels EUA","PN":"Illes Pitcairn","SB":"Illes Salom\u00f3","TC":"Illes Turks i Caicos","VG":"Illes Verges Brit\u00e0niques","VI":"Illes Verges Nord-americanes","IN":"\u00cdndia","ID":"Indon\u00e8sia","IR":"Iran","IQ":"Iraq","IE":"Irlanda","IS":"Isl\u00e0ndia","IL":"Israel","IT":"It\u00e0lia","JM":"Jamaica","JP":"Jap\u00f3","JE":"Jersey","JO":"Jord\u00e0nia","KZ":"Kazakhstan","KE":"Kenya","KG":"Kirguizistan","KI":"Kiribati","KW":"Kuwait","LA":"Laos","LS":"Lesotho","LV":"Let\u00f2nia","LB":"L\u00edban","LR":"Lib\u00e8ria","LY":"L\u00edbia","LI":"Liechtenstein","LT":"Litu\u00e0nia","LU":"Luxemburg","MO":"Macau (RAE Xina)","MK":"Maced\u00f2nia del Nord","MG":"Madagascar","MY":"Mal\u00e0isia","MW":"Malawi","MV":"Maldives","ML":"Mali","MT":"Malta","MA":"Marroc","MQ":"Martinica","MU":"Maurici","MR":"Maurit\u00e0nia","YT":"Mayotte","MX":"M\u00e8xic","FM":"Micron\u00e8sia","MZ":"Mo\u00e7ambic","MD":"Mold\u00e0via","MC":"M\u00f2naco","MN":"Mong\u00f2lia","ME":"Montenegro","MS":"Montserrat","MM":"Myanmar (Birm\u00e0nia)","NA":"Nam\u00edbia","NR":"Nauru","NP":"Nepal","NI":"Nicaragua","NE":"N\u00edger","NG":"Nig\u00e8ria","NU":"Niue","NF":"Norfolk","NO":"Noruega","NC":"Nova Caled\u00f2nia","NZ":"Nova Zelanda","OM":"Oman","NL":"Pa\u00efsos Baixos","PK":"Pakistan","PW":"Palau","PA":"Panam\u00e0","PG":"Papua Nova Guinea","PY":"Paraguai","PE":"Per\u00fa","PF":"Polin\u00e8sia Francesa","PL":"Pol\u00f2nia","PT":"Portugal","PR":"Puerto Rico","QA":"Qatar","GB":"Regne Unit","CF":"Rep\u00fablica Centreafricana","ZA":"Rep\u00fablica de Sud-\u00e0frica","DO":"Rep\u00fablica Dominicana","RO":"Romania","RW":"Ruanda","RU":"R\u00fassia","EH":"S\u00e0hara Occidental","BL":"Saint Barth\u00e9lemy","KN":"Saint Christopher i Nevis","SH":"Saint Helena","LC":"Saint Lucia","MF":"Saint Martin","VC":"Saint Vincent i les Grenadines","PM":"Saint-Pierre-et-Miquelon","WS":"Samoa","AS":"Samoa Nord-americana","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 i Pr\u00edncipe","SN":"Senegal","RS":"S\u00e8rbia","SC":"Seychelles","SL":"Sierra Leone","SG":"Singapur","SX":"Sint Maarten","SY":"S\u00edria","SO":"Som\u00e0lia","LK":"Sri Lanka","SD":"Sudan","SS":"Sudan del Sud","SE":"Su\u00e8cia","CH":"Su\u00efssa","SR":"Surinam","SJ":"Svalbard i Jan Mayen","TJ":"Tadjikistan","TH":"Tail\u00e0ndia","TW":"Taiwan","TZ":"Tanz\u00e0nia","IO":"Territori Brit\u00e0nic de l\u2019Oce\u00e0 \u00cdndic","TF":"Territoris Australs Francesos","PS":"Territoris palestins","TL":"Timor Oriental","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinitat i Tobago","TN":"Tun\u00edsia","TM":"Turkmenistan","TR":"Turquia","TV":"Tuvalu","TD":"Txad","CZ":"Tx\u00e8quia","UA":"Ucra\u00efna","UG":"Uganda","UY":"Uruguai","UZ":"Uzbekistan","VU":"Vanuatu","VE":"Vene\u00e7uela","VN":"Vietnam","WF":"Wallis i Futuna","CL":"Xile","CN":"Xina","CY":"Xipre","ZM":"Z\u00e0mbia","ZW":"Zimb\u00e0bue"}
{
"AF": "Afganistan",
"AL": "Alb\u00e0nia",
"DE": "Alemanya",
"DZ": "Alg\u00e8ria",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguilla",
"AQ": "Ant\u00e0rtida",
"AG": "Antigua i Barbuda",
"SA": "Ar\u00e0bia Saudita",
"AR": "Argentina",
"AM": "Arm\u00e8nia",
"AW": "Aruba",
"AU": "Austr\u00e0lia",
"AT": "\u00c0ustria",
"AZ": "Azerbaidjan",
"BS": "Bahames",
"BH": "Bahrain",
"BD": "Bangladesh",
"BB": "Barbados",
"BY": "Belar\u00fas",
"BE": "B\u00e8lgica",
"BZ": "Belize",
"BJ": "Ben\u00edn",
"BM": "Bermudes",
"BT": "Bhutan",
"BO": "Bol\u00edvia",
"BA": "B\u00f2snia i Hercegovina",
"BW": "Botswana",
"BV": "Bouvet",
"BR": "Brasil",
"BN": "Brunei",
"BG": "Bulg\u00e0ria",
"BF": "Burkina Faso",
"BI": "Burundi",
"KH": "Cambodja",
"CM": "Camerun",
"CA": "Canad\u00e0",
"CV": "Cap Verd",
"BQ": "Carib Neerland\u00e8s",
"VA": "Ciutat del Vatic\u00e0",
"CO": "Col\u00f2mbia",
"KM": "Comores",
"CG": "Congo - Brazzaville",
"CD": "Congo - Kinshasa",
"KP": "Corea del Nord",
"KR": "Corea del Sud",
"CR": "Costa Rica",
"CI": "C\u00f4te d\u2019Ivoire",
"HR": "Cro\u00e0cia",
"CU": "Cuba",
"CW": "Cura\u00e7ao",
"DK": "Dinamarca",
"DJ": "Djibouti",
"DM": "Dominica",
"EG": "Egipte",
"SV": "El Salvador",
"AE": "Emirats \u00c0rabs Units",
"EC": "Equador",
"ER": "Eritrea",
"SK": "Eslov\u00e0quia",
"SI": "Eslov\u00e8nia",
"ES": "Espanya",
"US": "Estats Units",
"EE": "Est\u00f2nia",
"SZ": "eSwatini",
"ET": "Eti\u00f2pia",
"FJ": "Fiji",
"PH": "Filipines",
"FI": "Finl\u00e0ndia",
"FR": "Fran\u00e7a",
"GA": "Gabon",
"GM": "G\u00e0mbia",
"GE": "Ge\u00f2rgia",
"GH": "Ghana",
"GI": "Gibraltar",
"GR": "Gr\u00e8cia",
"GD": "Grenada",
"GL": "Groenl\u00e0ndia",
"GP": "Guadeloupe",
"GF": "Guaiana Francesa",
"GU": "Guam",
"GT": "Guatemala",
"GG": "Guernsey",
"GN": "Guinea",
"GW": "Guinea Bissau",
"GQ": "Guinea Equatorial",
"GY": "Guyana",
"HT": "Hait\u00ed",
"HN": "Hondures",
"HK": "Hong Kong (RAE Xina)",
"HU": "Hongria",
"YE": "Iemen",
"CX": "Illa Christmas",
"RE": "Illa de la Reuni\u00f3",
"IM": "Illa de Man",
"HM": "Illa Heard i Illes McDonald",
"AX": "Illes \u00c5land",
"KY": "Illes Caiman",
"CC": "Illes Cocos",
"CK": "Illes Cook",
"FO": "Illes F\u00e8roe",
"GS": "Illes Ge\u00f2rgia del Sud i Sandwich del Sud",
"FK": "Illes Malvines",
"MP": "Illes Mariannes del Nord",
"MH": "Illes Marshall",
"UM": "Illes Perif\u00e8riques Menors dels EUA",
"PN": "Illes Pitcairn",
"SB": "Illes Salom\u00f3",
"TC": "Illes Turks i Caicos",
"VG": "Illes Verges Brit\u00e0niques",
"VI": "Illes Verges Nord-americanes",
"IN": "\u00cdndia",
"ID": "Indon\u00e8sia",
"IR": "Iran",
"IQ": "Iraq",
"IE": "Irlanda",
"IS": "Isl\u00e0ndia",
"IL": "Israel",
"IT": "It\u00e0lia",
"JM": "Jamaica",
"JP": "Jap\u00f3",
"JE": "Jersey",
"JO": "Jord\u00e0nia",
"KZ": "Kazakhstan",
"KE": "Kenya",
"KG": "Kirguizistan",
"KI": "Kiribati",
"XK": "Kosovo",
"KW": "Kuwait",
"LA": "Laos",
"LS": "Lesotho",
"LV": "Let\u00f2nia",
"LB": "L\u00edban",
"LR": "Lib\u00e8ria",
"LY": "L\u00edbia",
"LI": "Liechtenstein",
"LT": "Litu\u00e0nia",
"LU": "Luxemburg",
"MO": "Macau (RAE Xina)",
"MK": "Maced\u00f2nia del Nord",
"MG": "Madagascar",
"MY": "Mal\u00e0isia",
"MW": "Malawi",
"MV": "Maldives",
"ML": "Mali",
"MT": "Malta",
"MA": "Marroc",
"MQ": "Martinica",
"MU": "Maurici",
"MR": "Maurit\u00e0nia",
"YT": "Mayotte",
"MX": "M\u00e8xic",
"FM": "Micron\u00e8sia",
"MZ": "Mo\u00e7ambic",
"MD": "Mold\u00e0via",
"MC": "M\u00f2naco",
"MN": "Mong\u00f2lia",
"ME": "Montenegro",
"MS": "Montserrat",
"MM": "Myanmar (Birm\u00e0nia)",
"NA": "Nam\u00edbia",
"NR": "Nauru",
"NP": "Nepal",
"NI": "Nicaragua",
"NE": "N\u00edger",
"NG": "Nig\u00e8ria",
"NU": "Niue",
"NF": "Norfolk",
"NO": "Noruega",
"NC": "Nova Caled\u00f2nia",
"NZ": "Nova Zelanda",
"OM": "Oman",
"NL": "Pa\u00efsos Baixos",
"PK": "Pakistan",
"PW": "Palau",
"PA": "Panam\u00e0",
"PG": "Papua Nova Guinea",
"PY": "Paraguai",
"PE": "Per\u00fa",
"PF": "Polin\u00e8sia Francesa",
"PL": "Pol\u00f2nia",
"PT": "Portugal",
"PR": "Puerto Rico",
"QA": "Qatar",
"GB": "Regne Unit",
"CF": "Rep\u00fablica Centreafricana",
"ZA": "Rep\u00fablica de Sud-\u00e0frica",
"DO": "Rep\u00fablica Dominicana",
"RO": "Romania",
"RW": "Ruanda",
"RU": "R\u00fassia",
"EH": "S\u00e0hara Occidental",
"BL": "Saint Barth\u00e9lemy",
"KN": "Saint Christopher i Nevis",
"SH": "Saint Helena",
"LC": "Saint Lucia",
"MF": "Saint Martin",
"VC": "Saint Vincent i les Grenadines",
"PM": "Saint-Pierre-et-Miquelon",
"WS": "Samoa",
"AS": "Samoa Nord-americana",
"SM": "San Marino",
"ST": "S\u00e3o Tom\u00e9 i Pr\u00edncipe",
"SN": "Senegal",
"RS": "S\u00e8rbia",
"SC": "Seychelles",
"SL": "Sierra Leone",
"SG": "Singapur",
"SX": "Sint Maarten",
"SY": "S\u00edria",
"SO": "Som\u00e0lia",
"LK": "Sri Lanka",
"SD": "Sudan",
"SS": "Sudan del Sud",
"SE": "Su\u00e8cia",
"CH": "Su\u00efssa",
"SR": "Surinam",
"SJ": "Svalbard i Jan Mayen",
"TJ": "Tadjikistan",
"TH": "Tail\u00e0ndia",
"TW": "Taiwan",
"TZ": "Tanz\u00e0nia",
"IO": "Territori Brit\u00e0nic de l\u2019Oce\u00e0 \u00cdndic",
"TF": "Territoris Australs Francesos",
"PS": "Territoris palestins",
"TL": "Timor Oriental",
"TG": "Togo",
"TK": "Tokelau",
"TO": "Tonga",
"TT": "Trinitat i Tobago",
"TN": "Tun\u00edsia",
"TM": "Turkmenistan",
"TR": "Turquia",
"TV": "Tuvalu",
"TD": "Txad",
"CZ": "Tx\u00e8quia",
"UA": "Ucra\u00efna",
"UG": "Uganda",
"UY": "Uruguai",
"UZ": "Uzbekistan",
"VU": "Vanuatu",
"VE": "Vene\u00e7uela",
"VN": "Vietnam",
"WF": "Wallis i Futuna",
"CL": "Xile",
"CN": "Xina",
"CY": "Xipre",
"ZM": "Z\u00e0mbia",
"ZW": "Zimb\u00e0bue"
}

File diff suppressed because one or more lines are too long

View file

@ -1 +1,252 @@
{"AF":"Afghanistan","AL":"Albanien","DZ":"Algeriet","AS":"Amerikansk Samoa","UM":"Amerikanske overs\u00f8iske \u00f8er","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Antarktis","AG":"Antigua og Barbuda","AR":"Argentina","AM":"Armenien","AW":"Aruba","AZ":"Aserbajdsjan","AU":"Australien","BS":"Bahamas","BH":"Bahrain","BD":"Bangladesh","BB":"Barbados","BE":"Belgien","BZ":"Belize","BJ":"Benin","BM":"Bermuda","BT":"Bhutan","BO":"Bolivia","BA":"Bosnien-Hercegovina","BW":"Botswana","BV":"Bouvet\u00f8en","BR":"Brasilien","BN":"Brunei","BG":"Bulgarien","BF":"Burkina Faso","BI":"Burundi","KH":"Cambodja","CM":"Cameroun","CA":"Canada","KY":"Cayman\u00f8erne","CL":"Chile","CC":"Cocos\u00f8erne","CO":"Colombia","KM":"Comorerne","CG":"Congo-Brazzaville","CD":"Congo-Kinshasa","CK":"Cook\u00f8erne","CR":"Costa Rica","CU":"Cuba","CW":"Cura\u00e7ao","CY":"Cypern","DK":"Danmark","VI":"De Amerikanske Jomfru\u00f8er","VG":"De Britiske Jomfru\u00f8er","AE":"De Forenede Arabiske Emirater","TF":"De Franske Besiddelser i Det Sydlige Indiske Ocean og Antarktis","PS":"De pal\u00e6stinensiske omr\u00e5der","BQ":"De tidligere Nederlandske Antiller","CF":"Den Centralafrikanske Republik","DO":"Den Dominikanske Republik","IO":"Det Britiske Territorium i Det Indiske Ocean","DJ":"Djibouti","DM":"Dominica","EC":"Ecuador","EG":"Egypten","SV":"El Salvador","CI":"Elfenbenskysten","ER":"Eritrea","EE":"Estland","SZ":"Eswatini","ET":"Etiopien","FK":"Falklands\u00f8erne","FJ":"Fiji","PH":"Filippinerne","FI":"Finland","FR":"Frankrig","GF":"Fransk Guyana","PF":"Fransk Polynesien","FO":"F\u00e6r\u00f8erne","GA":"Gabon","GM":"Gambia","GE":"Georgien","GH":"Ghana","GI":"Gibraltar","GD":"Grenada","GR":"Gr\u00e6kenland","GL":"Gr\u00f8nland","GP":"Guadeloupe","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea-Bissau","GY":"Guyana","HT":"Haiti","HM":"Heard Island og McDonald Islands","NL":"Holland","HN":"Honduras","BY":"Hviderusland","IN":"Indien","ID":"Indonesien","IQ":"Irak","IR":"Iran","IE":"Irland","IS":"Island","IM":"Isle of Man","IL":"Israel","IT":"Italien","JM":"Jamaica","JP":"Japan","JE":"Jersey","JO":"Jordan","CX":"Jule\u00f8en","CV":"Kap Verde","KZ":"Kasakhstan","KE":"Kenya","CN":"Kina","KG":"Kirgisistan","KI":"Kiribati","HR":"Kroatien","KW":"Kuwait","LA":"Laos","LS":"Lesotho","LV":"Letland","LB":"Libanon","LR":"Liberia","LY":"Libyen","LI":"Liechtenstein","LT":"Litauen","LU":"Luxembourg","MG":"Madagaskar","MW":"Malawi","MY":"Malaysia","MV":"Maldiverne","ML":"Mali","MT":"Malta","MA":"Marokko","MH":"Marshall\u00f8erne","MQ":"Martinique","MR":"Mauretanien","MU":"Mauritius","YT":"Mayotte","MX":"Mexico","FM":"Mikronesien","MD":"Moldova","MC":"Monaco","MN":"Mongoliet","ME":"Montenegro","MS":"Montserrat","MZ":"Mozambique","MM":"Myanmar (Burma)","NA":"Namibia","NR":"Nauru","NP":"Nepal","NZ":"New Zealand","NI":"Nicaragua","NE":"Niger","NG":"Nigeria","NU":"Niue","KP":"Nordkorea","MK":"Nordmakedonien","MP":"Nordmarianerne","NF":"Norfolk Island","NO":"Norge","NC":"Ny Kaledonien","OM":"Oman","PK":"Pakistan","PW":"Palau","PA":"Panama","PG":"Papua Ny Guinea","PY":"Paraguay","PE":"Peru","PN":"Pitcairn","PL":"Polen","PT":"Portugal","PR":"Puerto Rico","QA":"Qatar","RE":"R\u00e9union","RO":"Rum\u00e6nien","RU":"Rusland","RW":"Rwanda","BL":"Saint Barth\u00e9lemy","KN":"Saint Kitts og Nevis","LC":"Saint Lucia","MF":"Saint Martin","PM":"Saint Pierre og Miquelon","VC":"Saint Vincent og Grenadinerne","SB":"Salomon\u00f8erne","WS":"Samoa","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 og Pr\u00edncipe","HK":"SAR Hongkong","MO":"SAR Macao","SA":"Saudi-Arabien","CH":"Schweiz","SN":"Senegal","RS":"Serbien","SC":"Seychellerne","SL":"Sierra Leone","SG":"Singapore","SX":"Sint Maarten","SK":"Slovakiet","SI":"Slovenien","SO":"Somalia","GS":"South Georgia og De Sydlige Sandwich\u00f8er","ES":"Spanien","LK":"Sri Lanka","SH":"St. Helena","GB":"Storbritannien","SD":"Sudan","SR":"Surinam","SJ":"Svalbard og Jan Mayen","SE":"Sverige","ZA":"Sydafrika","KR":"Sydkorea","SS":"Sydsudan","SY":"Syrien","TJ":"Tadsjikistan","TW":"Taiwan","TZ":"Tanzania","TD":"Tchad","TH":"Thailand","TL":"Timor-Leste","CZ":"Tjekkiet","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad og Tobago","TN":"Tunesien","TM":"Turkmenistan","TC":"Turks- og Caicos\u00f8erne","TV":"Tuvalu","TR":"Tyrkiet","DE":"Tyskland","UG":"Uganda","UA":"Ukraine","HU":"Ungarn","UY":"Uruguay","US":"USA","UZ":"Usbekistan","VU":"Vanuatu","VA":"Vatikanstaten","VE":"Venezuela","EH":"Vestsahara","VN":"Vietnam","WF":"Wallis og Futuna","YE":"Yemen","ZM":"Zambia","ZW":"Zimbabwe","GQ":"\u00c6kvatorialguinea","AT":"\u00d8strig","AX":"\u00c5land"}
{
"AF": "Afghanistan",
"AL": "Albanien",
"DZ": "Algeriet",
"AS": "Amerikansk Samoa",
"UM": "Amerikanske overs\u00f8iske \u00f8er",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguilla",
"AQ": "Antarktis",
"AG": "Antigua og Barbuda",
"AR": "Argentina",
"AM": "Armenien",
"AW": "Aruba",
"AZ": "Aserbajdsjan",
"AU": "Australien",
"BS": "Bahamas",
"BH": "Bahrain",
"BD": "Bangladesh",
"BB": "Barbados",
"BE": "Belgien",
"BZ": "Belize",
"BJ": "Benin",
"BM": "Bermuda",
"BT": "Bhutan",
"BO": "Bolivia",
"BA": "Bosnien-Hercegovina",
"BW": "Botswana",
"BV": "Bouvet\u00f8en",
"BR": "Brasilien",
"BN": "Brunei",
"BG": "Bulgarien",
"BF": "Burkina Faso",
"BI": "Burundi",
"KH": "Cambodja",
"CM": "Cameroun",
"CA": "Canada",
"KY": "Cayman\u00f8erne",
"CL": "Chile",
"CC": "Cocos\u00f8erne",
"CO": "Colombia",
"KM": "Comorerne",
"CG": "Congo-Brazzaville",
"CD": "Congo-Kinshasa",
"CK": "Cook\u00f8erne",
"CR": "Costa Rica",
"CU": "Cuba",
"CW": "Cura\u00e7ao",
"CY": "Cypern",
"DK": "Danmark",
"VI": "De Amerikanske Jomfru\u00f8er",
"VG": "De Britiske Jomfru\u00f8er",
"AE": "De Forenede Arabiske Emirater",
"TF": "De Franske Besiddelser i Det Sydlige Indiske Ocean og Antarktis",
"PS": "De pal\u00e6stinensiske omr\u00e5der",
"BQ": "De tidligere Nederlandske Antiller",
"CF": "Den Centralafrikanske Republik",
"DO": "Den Dominikanske Republik",
"IO": "Det Britiske Territorium i Det Indiske Ocean",
"DJ": "Djibouti",
"DM": "Dominica",
"EC": "Ecuador",
"EG": "Egypten",
"SV": "El Salvador",
"CI": "Elfenbenskysten",
"ER": "Eritrea",
"EE": "Estland",
"SZ": "Eswatini",
"ET": "Etiopien",
"FK": "Falklands\u00f8erne",
"FJ": "Fiji",
"PH": "Filippinerne",
"FI": "Finland",
"FR": "Frankrig",
"GF": "Fransk Guyana",
"PF": "Fransk Polynesien",
"FO": "F\u00e6r\u00f8erne",
"GA": "Gabon",
"GM": "Gambia",
"GE": "Georgien",
"GH": "Ghana",
"GI": "Gibraltar",
"GD": "Grenada",
"GR": "Gr\u00e6kenland",
"GL": "Gr\u00f8nland",
"GP": "Guadeloupe",
"GU": "Guam",
"GT": "Guatemala",
"GG": "Guernsey",
"GN": "Guinea",
"GW": "Guinea-Bissau",
"GY": "Guyana",
"HT": "Haiti",
"HM": "Heard Island og McDonald Islands",
"NL": "Holland",
"HN": "Honduras",
"BY": "Hviderusland",
"IN": "Indien",
"ID": "Indonesien",
"IQ": "Irak",
"IR": "Iran",
"IE": "Irland",
"IS": "Island",
"IM": "Isle of Man",
"IL": "Israel",
"IT": "Italien",
"JM": "Jamaica",
"JP": "Japan",
"JE": "Jersey",
"JO": "Jordan",
"CX": "Jule\u00f8en",
"CV": "Kap Verde",
"KZ": "Kasakhstan",
"KE": "Kenya",
"CN": "Kina",
"KG": "Kirgisistan",
"KI": "Kiribati",
"XK": "Kosovo",
"HR": "Kroatien",
"KW": "Kuwait",
"LA": "Laos",
"LS": "Lesotho",
"LV": "Letland",
"LB": "Libanon",
"LR": "Liberia",
"LY": "Libyen",
"LI": "Liechtenstein",
"LT": "Litauen",
"LU": "Luxembourg",
"MG": "Madagaskar",
"MW": "Malawi",
"MY": "Malaysia",
"MV": "Maldiverne",
"ML": "Mali",
"MT": "Malta",
"MA": "Marokko",
"MH": "Marshall\u00f8erne",
"MQ": "Martinique",
"MR": "Mauretanien",
"MU": "Mauritius",
"YT": "Mayotte",
"MX": "Mexico",
"FM": "Mikronesien",
"MD": "Moldova",
"MC": "Monaco",
"MN": "Mongoliet",
"ME": "Montenegro",
"MS": "Montserrat",
"MZ": "Mozambique",
"MM": "Myanmar (Burma)",
"NA": "Namibia",
"NR": "Nauru",
"NP": "Nepal",
"NZ": "New Zealand",
"NI": "Nicaragua",
"NE": "Niger",
"NG": "Nigeria",
"NU": "Niue",
"KP": "Nordkorea",
"MK": "Nordmakedonien",
"MP": "Nordmarianerne",
"NF": "Norfolk Island",
"NO": "Norge",
"NC": "Ny Kaledonien",
"OM": "Oman",
"PK": "Pakistan",
"PW": "Palau",
"PA": "Panama",
"PG": "Papua Ny Guinea",
"PY": "Paraguay",
"PE": "Peru",
"PN": "Pitcairn",
"PL": "Polen",
"PT": "Portugal",
"PR": "Puerto Rico",
"QA": "Qatar",
"RE": "R\u00e9union",
"RO": "Rum\u00e6nien",
"RU": "Rusland",
"RW": "Rwanda",
"BL": "Saint Barth\u00e9lemy",
"KN": "Saint Kitts og Nevis",
"LC": "Saint Lucia",
"MF": "Saint Martin",
"PM": "Saint Pierre og Miquelon",
"VC": "Saint Vincent og Grenadinerne",
"SB": "Salomon\u00f8erne",
"WS": "Samoa",
"SM": "San Marino",
"ST": "S\u00e3o Tom\u00e9 og Pr\u00edncipe",
"HK": "SAR Hongkong",
"MO": "SAR Macao",
"SA": "Saudi-Arabien",
"CH": "Schweiz",
"SN": "Senegal",
"RS": "Serbien",
"SC": "Seychellerne",
"SL": "Sierra Leone",
"SG": "Singapore",
"SX": "Sint Maarten",
"SK": "Slovakiet",
"SI": "Slovenien",
"SO": "Somalia",
"GS": "South Georgia og De Sydlige Sandwich\u00f8er",
"ES": "Spanien",
"LK": "Sri Lanka",
"SH": "St. Helena",
"GB": "Storbritannien",
"SD": "Sudan",
"SR": "Surinam",
"SJ": "Svalbard og Jan Mayen",
"SE": "Sverige",
"ZA": "Sydafrika",
"KR": "Sydkorea",
"SS": "Sydsudan",
"SY": "Syrien",
"TJ": "Tadsjikistan",
"TW": "Taiwan",
"TZ": "Tanzania",
"TD": "Tchad",
"TH": "Thailand",
"TL": "Timor-Leste",
"CZ": "Tjekkiet",
"TG": "Togo",
"TK": "Tokelau",
"TO": "Tonga",
"TT": "Trinidad og Tobago",
"TN": "Tunesien",
"TM": "Turkmenistan",
"TC": "Turks- og Caicos\u00f8erne",
"TV": "Tuvalu",
"TR": "Tyrkiet",
"DE": "Tyskland",
"UG": "Uganda",
"UA": "Ukraine",
"HU": "Ungarn",
"UY": "Uruguay",
"US": "USA",
"UZ": "Usbekistan",
"VU": "Vanuatu",
"VA": "Vatikanstaten",
"VE": "Venezuela",
"EH": "Vestsahara",
"VN": "Vietnam",
"WF": "Wallis og Futuna",
"YE": "Yemen",
"ZM": "Zambia",
"ZW": "Zimbabwe",
"GQ": "\u00c6kvatorialguinea",
"AT": "\u00d8strig",
"AX": "\u00c5land"
}

View file

@ -1 +1,252 @@
{"AF":"Afghanistan","EG":"\u00c4gypten","AX":"\u00c5landinseln","AL":"Albanien","DZ":"Algerien","AS":"Amerikanisch-Samoa","VI":"Amerikanische Jungferninseln","UM":"Amerikanische \u00dcberseeinseln","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Antarktis","AG":"Antigua und Barbuda","GQ":"\u00c4quatorialguinea","AR":"Argentinien","AM":"Armenien","AW":"Aruba","AZ":"Aserbaidschan","ET":"\u00c4thiopien","AU":"Australien","BS":"Bahamas","BH":"Bahrain","BD":"Bangladesch","BB":"Barbados","BE":"Belgien","BZ":"Belize","BJ":"Benin","BM":"Bermuda","BT":"Bhutan","BO":"Bolivien","BQ":"Bonaire, Sint Eustatius und Saba","BA":"Bosnien und Herzegowina","BW":"Botswana","BV":"Bouvetinsel","BR":"Brasilien","VG":"Britische Jungferninseln","IO":"Britisches Territorium im Indischen Ozean","BN":"Brunei","BG":"Bulgarien","BF":"Burkina Faso","BI":"Burundi","CL":"Chile","CN":"China","CK":"Cookinseln","CR":"Costa Rica","CI":"C\u00f4te d\u2019Ivoire","CW":"Cura\u00e7ao","DK":"D\u00e4nemark","DE":"Deutschland","DM":"Dominica","DO":"Dominikanische Republik","DJ":"Dschibuti","EC":"Ecuador","SV":"El Salvador","ER":"Eritrea","EE":"Estland","SZ":"Eswatini","FK":"Falklandinseln","FO":"F\u00e4r\u00f6er","FJ":"Fidschi","FI":"Finnland","FR":"Frankreich","GF":"Franz\u00f6sisch-Guayana","PF":"Franz\u00f6sisch-Polynesien","TF":"Franz\u00f6sische S\u00fcd- und Antarktisgebiete","GA":"Gabun","GM":"Gambia","GE":"Georgien","GH":"Ghana","GI":"Gibraltar","GD":"Grenada","GR":"Griechenland","GL":"Gr\u00f6nland","GB":"Grossbritannien","GP":"Guadeloupe","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea-Bissau","GY":"Guyana","HT":"Haiti","HM":"Heard und McDonaldinseln","HN":"Honduras","IN":"Indien","ID":"Indonesien","IQ":"Irak","IR":"Iran","IE":"Irland","IS":"Island","IM":"Isle of Man","IL":"Israel","IT":"Italien","JM":"Jamaika","JP":"Japan","YE":"Jemen","JE":"Jersey","JO":"Jordanien","KY":"Kaimaninseln","KH":"Kambodscha","CM":"Kamerun","CA":"Kanada","CV":"Kapverden","KZ":"Kasachstan","QA":"Katar","KE":"Kenia","KG":"Kirgisistan","KI":"Kiribati","CC":"Kokosinseln","CO":"Kolumbien","KM":"Komoren","CG":"Kongo-Brazzaville","CD":"Kongo-Kinshasa","HR":"Kroatien","CU":"Kuba","KW":"Kuwait","LA":"Laos","LS":"Lesotho","LV":"Lettland","LB":"Libanon","LR":"Liberia","LY":"Libyen","LI":"Liechtenstein","LT":"Litauen","LU":"Luxemburg","MG":"Madagaskar","MW":"Malawi","MY":"Malaysia","MV":"Malediven","ML":"Mali","MT":"Malta","MA":"Marokko","MH":"Marshallinseln","MQ":"Martinique","MR":"Mauretanien","MU":"Mauritius","YT":"Mayotte","MX":"Mexiko","FM":"Mikronesien","MC":"Monaco","MN":"Mongolei","ME":"Montenegro","MS":"Montserrat","MZ":"Mosambik","MM":"Myanmar","NA":"Namibia","NR":"Nauru","NP":"Nepal","NC":"Neukaledonien","NZ":"Neuseeland","NI":"Nicaragua","NL":"Niederlande","NE":"Niger","NG":"Nigeria","NU":"Niue","KP":"Nordkorea","MP":"N\u00f6rdliche Marianen","MK":"Nordmazedonien","NF":"Norfolkinsel","NO":"Norwegen","OM":"Oman","AT":"\u00d6sterreich","TL":"Osttimor","PK":"Pakistan","PS":"Pal\u00e4stinensische Autonomiegebiete","PW":"Palau","PA":"Panama","PG":"Papua-Neuguinea","PY":"Paraguay","PE":"Peru","PH":"Philippinen","PN":"Pitcairninseln","PL":"Polen","PT":"Portugal","PR":"Puerto Rico","MD":"Republik Moldau","RE":"R\u00e9union","RW":"Ruanda","RO":"Rum\u00e4nien","RU":"Russland","SB":"Salomon-Inseln","ZM":"Sambia","WS":"Samoa","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 und Pr\u00edncipe","SA":"Saudi-Arabien","SE":"Schweden","CH":"Schweiz","SN":"Senegal","RS":"Serbien","SC":"Seychellen","SL":"Sierra Leone","SG":"Singapur","SX":"Sint Maarten","SK":"Slowakei","SI":"Slowenien","SO":"Somalia","HK":"Sonderverwaltungsregion Hongkong","MO":"Sonderverwaltungsregion Macau","ES":"Spanien","SJ":"Spitzbergen und Jan Mayen","LK":"Sri Lanka","BL":"St. Barth\u00e9lemy","SH":"St. Helena","KN":"St. Kitts und Nevis","LC":"St. Lucia","MF":"St. Martin","PM":"St. Pierre und Miquelon","VC":"St. Vincent und die Grenadinen","ZA":"S\u00fcdafrika","SD":"Sudan","GS":"S\u00fcdgeorgien und die S\u00fcdlichen Sandwichinseln","KR":"S\u00fcdkorea","SS":"S\u00fcdsudan","SR":"Suriname","SY":"Syrien","TJ":"Tadschikistan","TW":"Taiwan","TZ":"Tansania","TH":"Thailand","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad und Tobago","TD":"Tschad","CZ":"Tschechien","TN":"Tunesien","TR":"T\u00fcrkei","TM":"Turkmenistan","TC":"Turks- und Caicosinseln","TV":"Tuvalu","UG":"Uganda","UA":"Ukraine","HU":"Ungarn","UY":"Uruguay","UZ":"Usbekistan","VU":"Vanuatu","VA":"Vatikanstadt","VE":"Venezuela","AE":"Vereinigte Arabische Emirate","US":"Vereinigte Staaten","VN":"Vietnam","WF":"Wallis und Futuna","CX":"Weihnachtsinsel","BY":"Weissrussland","EH":"Westsahara","CF":"Zentralafrikanische Republik","ZW":"Zimbabwe","CY":"Zypern"}
{
"AF": "Afghanistan",
"EG": "\u00c4gypten",
"AX": "\u00c5landinseln",
"AL": "Albanien",
"DZ": "Algerien",
"AS": "Amerikanisch-Samoa",
"VI": "Amerikanische Jungferninseln",
"UM": "Amerikanische \u00dcberseeinseln",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguilla",
"AQ": "Antarktis",
"AG": "Antigua und Barbuda",
"GQ": "\u00c4quatorialguinea",
"AR": "Argentinien",
"AM": "Armenien",
"AW": "Aruba",
"AZ": "Aserbaidschan",
"ET": "\u00c4thiopien",
"AU": "Australien",
"BS": "Bahamas",
"BH": "Bahrain",
"BD": "Bangladesch",
"BB": "Barbados",
"BE": "Belgien",
"BZ": "Belize",
"BJ": "Benin",
"BM": "Bermuda",
"BT": "Bhutan",
"BO": "Bolivien",
"BQ": "Bonaire, Sint Eustatius und Saba",
"BA": "Bosnien und Herzegowina",
"BW": "Botswana",
"BV": "Bouvetinsel",
"BR": "Brasilien",
"VG": "Britische Jungferninseln",
"IO": "Britisches Territorium im Indischen Ozean",
"BN": "Brunei",
"BG": "Bulgarien",
"BF": "Burkina Faso",
"BI": "Burundi",
"CL": "Chile",
"CN": "China",
"CK": "Cookinseln",
"CR": "Costa Rica",
"CI": "C\u00f4te d\u2019Ivoire",
"CW": "Cura\u00e7ao",
"DK": "D\u00e4nemark",
"DE": "Deutschland",
"DM": "Dominica",
"DO": "Dominikanische Republik",
"DJ": "Dschibuti",
"EC": "Ecuador",
"SV": "El Salvador",
"ER": "Eritrea",
"EE": "Estland",
"SZ": "Eswatini",
"FK": "Falklandinseln",
"FO": "F\u00e4r\u00f6er",
"FJ": "Fidschi",
"FI": "Finnland",
"FR": "Frankreich",
"GF": "Franz\u00f6sisch-Guayana",
"PF": "Franz\u00f6sisch-Polynesien",
"TF": "Franz\u00f6sische S\u00fcd- und Antarktisgebiete",
"GA": "Gabun",
"GM": "Gambia",
"GE": "Georgien",
"GH": "Ghana",
"GI": "Gibraltar",
"GD": "Grenada",
"GR": "Griechenland",
"GL": "Gr\u00f6nland",
"GB": "Grossbritannien",
"GP": "Guadeloupe",
"GU": "Guam",
"GT": "Guatemala",
"GG": "Guernsey",
"GN": "Guinea",
"GW": "Guinea-Bissau",
"GY": "Guyana",
"HT": "Haiti",
"HM": "Heard und McDonaldinseln",
"HN": "Honduras",
"IN": "Indien",
"ID": "Indonesien",
"IQ": "Irak",
"IR": "Iran",
"IE": "Irland",
"IS": "Island",
"IM": "Isle of Man",
"IL": "Israel",
"IT": "Italien",
"JM": "Jamaika",
"JP": "Japan",
"YE": "Jemen",
"JE": "Jersey",
"JO": "Jordanien",
"KY": "Kaimaninseln",
"KH": "Kambodscha",
"CM": "Kamerun",
"CA": "Kanada",
"CV": "Kapverden",
"KZ": "Kasachstan",
"QA": "Katar",
"KE": "Kenia",
"KG": "Kirgisistan",
"KI": "Kiribati",
"CC": "Kokosinseln",
"CO": "Kolumbien",
"KM": "Komoren",
"CG": "Kongo-Brazzaville",
"CD": "Kongo-Kinshasa",
"XK": "Kosovo",
"HR": "Kroatien",
"CU": "Kuba",
"KW": "Kuwait",
"LA": "Laos",
"LS": "Lesotho",
"LV": "Lettland",
"LB": "Libanon",
"LR": "Liberia",
"LY": "Libyen",
"LI": "Liechtenstein",
"LT": "Litauen",
"LU": "Luxemburg",
"MG": "Madagaskar",
"MW": "Malawi",
"MY": "Malaysia",
"MV": "Malediven",
"ML": "Mali",
"MT": "Malta",
"MA": "Marokko",
"MH": "Marshallinseln",
"MQ": "Martinique",
"MR": "Mauretanien",
"MU": "Mauritius",
"YT": "Mayotte",
"MX": "Mexiko",
"FM": "Mikronesien",
"MC": "Monaco",
"MN": "Mongolei",
"ME": "Montenegro",
"MS": "Montserrat",
"MZ": "Mosambik",
"MM": "Myanmar",
"NA": "Namibia",
"NR": "Nauru",
"NP": "Nepal",
"NC": "Neukaledonien",
"NZ": "Neuseeland",
"NI": "Nicaragua",
"NL": "Niederlande",
"NE": "Niger",
"NG": "Nigeria",
"NU": "Niue",
"KP": "Nordkorea",
"MP": "N\u00f6rdliche Marianen",
"MK": "Nordmazedonien",
"NF": "Norfolkinsel",
"NO": "Norwegen",
"OM": "Oman",
"AT": "\u00d6sterreich",
"TL": "Osttimor",
"PK": "Pakistan",
"PS": "Pal\u00e4stinensische Autonomiegebiete",
"PW": "Palau",
"PA": "Panama",
"PG": "Papua-Neuguinea",
"PY": "Paraguay",
"PE": "Peru",
"PH": "Philippinen",
"PN": "Pitcairninseln",
"PL": "Polen",
"PT": "Portugal",
"PR": "Puerto Rico",
"MD": "Republik Moldau",
"RE": "R\u00e9union",
"RW": "Ruanda",
"RO": "Rum\u00e4nien",
"RU": "Russland",
"SB": "Salomon-Inseln",
"ZM": "Sambia",
"WS": "Samoa",
"SM": "San Marino",
"ST": "S\u00e3o Tom\u00e9 und Pr\u00edncipe",
"SA": "Saudi-Arabien",
"SE": "Schweden",
"CH": "Schweiz",
"SN": "Senegal",
"RS": "Serbien",
"SC": "Seychellen",
"SL": "Sierra Leone",
"SG": "Singapur",
"SX": "Sint Maarten",
"SK": "Slowakei",
"SI": "Slowenien",
"SO": "Somalia",
"HK": "Sonderverwaltungsregion Hongkong",
"MO": "Sonderverwaltungsregion Macau",
"ES": "Spanien",
"SJ": "Spitzbergen und Jan Mayen",
"LK": "Sri Lanka",
"BL": "St. Barth\u00e9lemy",
"SH": "St. Helena",
"KN": "St. Kitts und Nevis",
"LC": "St. Lucia",
"MF": "St. Martin",
"PM": "St. Pierre und Miquelon",
"VC": "St. Vincent und die Grenadinen",
"ZA": "S\u00fcdafrika",
"SD": "Sudan",
"GS": "S\u00fcdgeorgien und die S\u00fcdlichen Sandwichinseln",
"KR": "S\u00fcdkorea",
"SS": "S\u00fcdsudan",
"SR": "Suriname",
"SY": "Syrien",
"TJ": "Tadschikistan",
"TW": "Taiwan",
"TZ": "Tansania",
"TH": "Thailand",
"TG": "Togo",
"TK": "Tokelau",
"TO": "Tonga",
"TT": "Trinidad und Tobago",
"TD": "Tschad",
"CZ": "Tschechien",
"TN": "Tunesien",
"TR": "T\u00fcrkei",
"TM": "Turkmenistan",
"TC": "Turks- und Caicosinseln",
"TV": "Tuvalu",
"UG": "Uganda",
"UA": "Ukraine",
"HU": "Ungarn",
"UY": "Uruguay",
"UZ": "Usbekistan",
"VU": "Vanuatu",
"VA": "Vatikanstadt",
"VE": "Venezuela",
"AE": "Vereinigte Arabische Emirate",
"US": "Vereinigte Staaten",
"VN": "Vietnam",
"WF": "Wallis und Futuna",
"CX": "Weihnachtsinsel",
"BY": "Weissrussland",
"EH": "Westsahara",
"CF": "Zentralafrikanische Republik",
"ZW": "Zimbabwe",
"CY": "Zypern"
}

View file

@ -1 +1,252 @@
{"AF":"Afghanistan","EG":"\u00c4gypten","AX":"\u00c5landinseln","AL":"Albanien","DZ":"Algerien","AS":"Amerikanisch-Samoa","VI":"Amerikanische Jungferninseln","UM":"Amerikanische \u00dcberseeinseln","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Antarktis","AG":"Antigua und Barbuda","GQ":"\u00c4quatorialguinea","AR":"Argentinien","AM":"Armenien","AW":"Aruba","AZ":"Aserbaidschan","ET":"\u00c4thiopien","AU":"Australien","BS":"Bahamas","BH":"Bahrain","BD":"Bangladesch","BB":"Barbados","BY":"Belarus","BE":"Belgien","BZ":"Belize","BJ":"Benin","BM":"Bermuda","BT":"Bhutan","BO":"Bolivien","BQ":"Bonaire, Sint Eustatius und Saba","BA":"Bosnien und Herzegowina","BW":"Botsuana","BV":"Bouvetinsel","BR":"Brasilien","VG":"Britische Jungferninseln","IO":"Britisches Territorium im Indischen Ozean","BN":"Brunei Darussalam","BG":"Bulgarien","BF":"Burkina Faso","BI":"Burundi","CV":"Cabo Verde","CL":"Chile","CN":"China","CK":"Cookinseln","CR":"Costa Rica","CI":"C\u00f4te d\u2019Ivoire","CW":"Cura\u00e7ao","DK":"D\u00e4nemark","DE":"Deutschland","DM":"Dominica","DO":"Dominikanische Republik","DJ":"Dschibuti","EC":"Ecuador","SV":"El Salvador","ER":"Eritrea","EE":"Estland","SZ":"Eswatini","FK":"Falklandinseln","FO":"F\u00e4r\u00f6er","FJ":"Fidschi","FI":"Finnland","FR":"Frankreich","GF":"Franz\u00f6sisch-Guayana","PF":"Franz\u00f6sisch-Polynesien","TF":"Franz\u00f6sische S\u00fcd- und Antarktisgebiete","GA":"Gabun","GM":"Gambia","GE":"Georgien","GH":"Ghana","GI":"Gibraltar","GD":"Grenada","GR":"Griechenland","GL":"Gr\u00f6nland","GP":"Guadeloupe","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea-Bissau","GY":"Guyana","HT":"Haiti","HM":"Heard und McDonaldinseln","HN":"Honduras","IN":"Indien","ID":"Indonesien","IQ":"Irak","IR":"Iran","IE":"Irland","IS":"Island","IM":"Isle of Man","IL":"Israel","IT":"Italien","JM":"Jamaika","JP":"Japan","YE":"Jemen","JE":"Jersey","JO":"Jordanien","KY":"Kaimaninseln","KH":"Kambodscha","CM":"Kamerun","CA":"Kanada","KZ":"Kasachstan","QA":"Katar","KE":"Kenia","KG":"Kirgisistan","KI":"Kiribati","CC":"Kokosinseln","CO":"Kolumbien","KM":"Komoren","CG":"Kongo-Brazzaville","CD":"Kongo-Kinshasa","HR":"Kroatien","CU":"Kuba","KW":"Kuwait","LA":"Laos","LS":"Lesotho","LV":"Lettland","LB":"Libanon","LR":"Liberia","LY":"Libyen","LI":"Liechtenstein","LT":"Litauen","LU":"Luxemburg","MG":"Madagaskar","MW":"Malawi","MY":"Malaysia","MV":"Malediven","ML":"Mali","MT":"Malta","MA":"Marokko","MH":"Marshallinseln","MQ":"Martinique","MR":"Mauretanien","MU":"Mauritius","YT":"Mayotte","MX":"Mexiko","FM":"Mikronesien","MC":"Monaco","MN":"Mongolei","ME":"Montenegro","MS":"Montserrat","MZ":"Mosambik","MM":"Myanmar","NA":"Namibia","NR":"Nauru","NP":"Nepal","NC":"Neukaledonien","NZ":"Neuseeland","NI":"Nicaragua","NL":"Niederlande","NE":"Niger","NG":"Nigeria","NU":"Niue","KP":"Nordkorea","MP":"N\u00f6rdliche Marianen","MK":"Nordmazedonien","NF":"Norfolkinsel","NO":"Norwegen","OM":"Oman","AT":"\u00d6sterreich","PK":"Pakistan","PS":"Pal\u00e4stinensische Autonomiegebiete","PW":"Palau","PA":"Panama","PG":"Papua-Neuguinea","PY":"Paraguay","PE":"Peru","PH":"Philippinen","PN":"Pitcairninseln","PL":"Polen","PT":"Portugal","PR":"Puerto Rico","MD":"Republik Moldau","RE":"R\u00e9union","RW":"Ruanda","RO":"Rum\u00e4nien","RU":"Russland","SB":"Salomonen","ZM":"Sambia","WS":"Samoa","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 und Pr\u00edncipe","SA":"Saudi-Arabien","SE":"Schweden","CH":"Schweiz","SN":"Senegal","RS":"Serbien","SC":"Seychellen","SL":"Sierra Leone","ZW":"Simbabwe","SG":"Singapur","SX":"Sint Maarten","SK":"Slowakei","SI":"Slowenien","SO":"Somalia","HK":"Sonderverwaltungsregion Hongkong","MO":"Sonderverwaltungsregion Macau","ES":"Spanien","SJ":"Spitzbergen und Jan Mayen","LK":"Sri Lanka","BL":"St. Barth\u00e9lemy","SH":"St. Helena","KN":"St. Kitts und Nevis","LC":"St. Lucia","MF":"St. Martin","PM":"St. Pierre und Miquelon","VC":"St. Vincent und die Grenadinen","ZA":"S\u00fcdafrika","SD":"Sudan","GS":"S\u00fcdgeorgien und die S\u00fcdlichen Sandwichinseln","KR":"S\u00fcdkorea","SS":"S\u00fcdsudan","SR":"Suriname","SY":"Syrien","TJ":"Tadschikistan","TW":"Taiwan","TZ":"Tansania","TH":"Thailand","TL":"Timor-Leste","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad und Tobago","TD":"Tschad","CZ":"Tschechien","TN":"Tunesien","TR":"T\u00fcrkei","TM":"Turkmenistan","TC":"Turks- und Caicosinseln","TV":"Tuvalu","UG":"Uganda","UA":"Ukraine","HU":"Ungarn","UY":"Uruguay","UZ":"Usbekistan","VU":"Vanuatu","VA":"Vatikanstadt","VE":"Venezuela","AE":"Vereinigte Arabische Emirate","US":"Vereinigte Staaten","GB":"Vereinigtes K\u00f6nigreich","VN":"Vietnam","WF":"Wallis und Futuna","CX":"Weihnachtsinsel","EH":"Westsahara","CF":"Zentralafrikanische Republik","CY":"Zypern"}
{
"AF": "Afghanistan",
"EG": "\u00c4gypten",
"AX": "\u00c5landinseln",
"AL": "Albanien",
"DZ": "Algerien",
"AS": "Amerikanisch-Samoa",
"VI": "Amerikanische Jungferninseln",
"UM": "Amerikanische \u00dcberseeinseln",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguilla",
"AQ": "Antarktis",
"AG": "Antigua und Barbuda",
"GQ": "\u00c4quatorialguinea",
"AR": "Argentinien",
"AM": "Armenien",
"AW": "Aruba",
"AZ": "Aserbaidschan",
"ET": "\u00c4thiopien",
"AU": "Australien",
"BS": "Bahamas",
"BH": "Bahrain",
"BD": "Bangladesch",
"BB": "Barbados",
"BY": "Belarus",
"BE": "Belgien",
"BZ": "Belize",
"BJ": "Benin",
"BM": "Bermuda",
"BT": "Bhutan",
"BO": "Bolivien",
"BQ": "Bonaire, Sint Eustatius und Saba",
"BA": "Bosnien und Herzegowina",
"BW": "Botsuana",
"BV": "Bouvetinsel",
"BR": "Brasilien",
"VG": "Britische Jungferninseln",
"IO": "Britisches Territorium im Indischen Ozean",
"BN": "Brunei Darussalam",
"BG": "Bulgarien",
"BF": "Burkina Faso",
"BI": "Burundi",
"CV": "Cabo Verde",
"CL": "Chile",
"CN": "China",
"CK": "Cookinseln",
"CR": "Costa Rica",
"CI": "C\u00f4te d\u2019Ivoire",
"CW": "Cura\u00e7ao",
"DK": "D\u00e4nemark",
"DE": "Deutschland",
"DM": "Dominica",
"DO": "Dominikanische Republik",
"DJ": "Dschibuti",
"EC": "Ecuador",
"SV": "El Salvador",
"ER": "Eritrea",
"EE": "Estland",
"SZ": "Eswatini",
"FK": "Falklandinseln",
"FO": "F\u00e4r\u00f6er",
"FJ": "Fidschi",
"FI": "Finnland",
"FR": "Frankreich",
"GF": "Franz\u00f6sisch-Guayana",
"PF": "Franz\u00f6sisch-Polynesien",
"TF": "Franz\u00f6sische S\u00fcd- und Antarktisgebiete",
"GA": "Gabun",
"GM": "Gambia",
"GE": "Georgien",
"GH": "Ghana",
"GI": "Gibraltar",
"GD": "Grenada",
"GR": "Griechenland",
"GL": "Gr\u00f6nland",
"GP": "Guadeloupe",
"GU": "Guam",
"GT": "Guatemala",
"GG": "Guernsey",
"GN": "Guinea",
"GW": "Guinea-Bissau",
"GY": "Guyana",
"HT": "Haiti",
"HM": "Heard und McDonaldinseln",
"HN": "Honduras",
"IN": "Indien",
"ID": "Indonesien",
"IQ": "Irak",
"IR": "Iran",
"IE": "Irland",
"IS": "Island",
"IM": "Isle of Man",
"IL": "Israel",
"IT": "Italien",
"JM": "Jamaika",
"JP": "Japan",
"YE": "Jemen",
"JE": "Jersey",
"JO": "Jordanien",
"KY": "Kaimaninseln",
"KH": "Kambodscha",
"CM": "Kamerun",
"CA": "Kanada",
"KZ": "Kasachstan",
"QA": "Katar",
"KE": "Kenia",
"KG": "Kirgisistan",
"KI": "Kiribati",
"CC": "Kokosinseln",
"CO": "Kolumbien",
"KM": "Komoren",
"CG": "Kongo-Brazzaville",
"CD": "Kongo-Kinshasa",
"XK": "Kosovo",
"HR": "Kroatien",
"CU": "Kuba",
"KW": "Kuwait",
"LA": "Laos",
"LS": "Lesotho",
"LV": "Lettland",
"LB": "Libanon",
"LR": "Liberia",
"LY": "Libyen",
"LI": "Liechtenstein",
"LT": "Litauen",
"LU": "Luxemburg",
"MG": "Madagaskar",
"MW": "Malawi",
"MY": "Malaysia",
"MV": "Malediven",
"ML": "Mali",
"MT": "Malta",
"MA": "Marokko",
"MH": "Marshallinseln",
"MQ": "Martinique",
"MR": "Mauretanien",
"MU": "Mauritius",
"YT": "Mayotte",
"MX": "Mexiko",
"FM": "Mikronesien",
"MC": "Monaco",
"MN": "Mongolei",
"ME": "Montenegro",
"MS": "Montserrat",
"MZ": "Mosambik",
"MM": "Myanmar",
"NA": "Namibia",
"NR": "Nauru",
"NP": "Nepal",
"NC": "Neukaledonien",
"NZ": "Neuseeland",
"NI": "Nicaragua",
"NL": "Niederlande",
"NE": "Niger",
"NG": "Nigeria",
"NU": "Niue",
"KP": "Nordkorea",
"MP": "N\u00f6rdliche Marianen",
"MK": "Nordmazedonien",
"NF": "Norfolkinsel",
"NO": "Norwegen",
"OM": "Oman",
"AT": "\u00d6sterreich",
"PK": "Pakistan",
"PS": "Pal\u00e4stinensische Autonomiegebiete",
"PW": "Palau",
"PA": "Panama",
"PG": "Papua-Neuguinea",
"PY": "Paraguay",
"PE": "Peru",
"PH": "Philippinen",
"PN": "Pitcairninseln",
"PL": "Polen",
"PT": "Portugal",
"PR": "Puerto Rico",
"MD": "Republik Moldau",
"RE": "R\u00e9union",
"RW": "Ruanda",
"RO": "Rum\u00e4nien",
"RU": "Russland",
"SB": "Salomonen",
"ZM": "Sambia",
"WS": "Samoa",
"SM": "San Marino",
"ST": "S\u00e3o Tom\u00e9 und Pr\u00edncipe",
"SA": "Saudi-Arabien",
"SE": "Schweden",
"CH": "Schweiz",
"SN": "Senegal",
"RS": "Serbien",
"SC": "Seychellen",
"SL": "Sierra Leone",
"ZW": "Simbabwe",
"SG": "Singapur",
"SX": "Sint Maarten",
"SK": "Slowakei",
"SI": "Slowenien",
"SO": "Somalia",
"HK": "Sonderverwaltungsregion Hongkong",
"MO": "Sonderverwaltungsregion Macau",
"ES": "Spanien",
"SJ": "Spitzbergen und Jan Mayen",
"LK": "Sri Lanka",
"BL": "St. Barth\u00e9lemy",
"SH": "St. Helena",
"KN": "St. Kitts und Nevis",
"LC": "St. Lucia",
"MF": "St. Martin",
"PM": "St. Pierre und Miquelon",
"VC": "St. Vincent und die Grenadinen",
"ZA": "S\u00fcdafrika",
"SD": "Sudan",
"GS": "S\u00fcdgeorgien und die S\u00fcdlichen Sandwichinseln",
"KR": "S\u00fcdkorea",
"SS": "S\u00fcdsudan",
"SR": "Suriname",
"SY": "Syrien",
"TJ": "Tadschikistan",
"TW": "Taiwan",
"TZ": "Tansania",
"TH": "Thailand",
"TL": "Timor-Leste",
"TG": "Togo",
"TK": "Tokelau",
"TO": "Tonga",
"TT": "Trinidad und Tobago",
"TD": "Tschad",
"CZ": "Tschechien",
"TN": "Tunesien",
"TR": "T\u00fcrkei",
"TM": "Turkmenistan",
"TC": "Turks- und Caicosinseln",
"TV": "Tuvalu",
"UG": "Uganda",
"UA": "Ukraine",
"HU": "Ungarn",
"UY": "Uruguay",
"UZ": "Usbekistan",
"VU": "Vanuatu",
"VA": "Vatikanstadt",
"VE": "Venezuela",
"AE": "Vereinigte Arabische Emirate",
"US": "Vereinigte Staaten",
"GB": "Vereinigtes K\u00f6nigreich",
"VN": "Vietnam",
"WF": "Wallis und Futuna",
"CX": "Weihnachtsinsel",
"EH": "Westsahara",
"CF": "Zentralafrikanische Republik",
"CY": "Zypern"
}

File diff suppressed because one or more lines are too long

View file

@ -1 +1,252 @@
{"AF":"Afghanistan","AX":"\u00c5land Islands","AL":"Albania","DZ":"Algeria","AS":"American Samoa","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Antarctica","AG":"Antigua & Barbuda","AR":"Argentina","AM":"Armenia","AW":"Aruba","AU":"Australia","AT":"Austria","AZ":"Azerbaijan","BS":"Bahamas","BH":"Bahrain","BD":"Bangladesh","BB":"Barbados","BY":"Belarus","BE":"Belgium","BZ":"Belize","BJ":"Benin","BM":"Bermuda","BT":"Bhutan","BO":"Bolivia","BA":"Bosnia & Herzegovina","BW":"Botswana","BV":"Bouvet Island","BR":"Brazil","IO":"British Indian Ocean Territory","VG":"British Virgin Islands","BN":"Brunei","BG":"Bulgaria","BF":"Burkina Faso","BI":"Burundi","KH":"Cambodia","CM":"Cameroon","CA":"Canada","CV":"Cape Verde","BQ":"Caribbean Netherlands","KY":"Cayman Islands","CF":"Central African Republic","TD":"Chad","CL":"Chile","CN":"China","CX":"Christmas Island","CC":"Cocos (Keeling) Islands","CO":"Colombia","KM":"Comoros","CG":"Congo - Brazzaville","CD":"Congo - Kinshasa","CK":"Cook Islands","CR":"Costa Rica","CI":"C\u00f4te d\u2019Ivoire","HR":"Croatia","CU":"Cuba","CW":"Cura\u00e7ao","CY":"Cyprus","CZ":"Czechia","DK":"Denmark","DJ":"Djibouti","DM":"Dominica","DO":"Dominican Republic","EC":"Ecuador","EG":"Egypt","SV":"El Salvador","GQ":"Equatorial Guinea","ER":"Eritrea","EE":"Estonia","SZ":"Eswatini","ET":"Ethiopia","FK":"Falkland Islands","FO":"Faroe Islands","FJ":"Fiji","FI":"Finland","FR":"France","GF":"French Guiana","PF":"French Polynesia","TF":"French Southern Territories","GA":"Gabon","GM":"Gambia","GE":"Georgia","DE":"Germany","GH":"Ghana","GI":"Gibraltar","GR":"Greece","GL":"Greenland","GD":"Grenada","GP":"Guadeloupe","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea-Bissau","GY":"Guyana","HT":"Haiti","HM":"Heard & McDonald Islands","HN":"Honduras","HK":"Hong Kong SAR China","HU":"Hungary","IS":"Iceland","IN":"India","ID":"Indonesia","IR":"Iran","IQ":"Iraq","IE":"Ireland","IM":"Isle of Man","IL":"Israel","IT":"Italy","JM":"Jamaica","JP":"Japan","JE":"Jersey","JO":"Jordan","KZ":"Kazakhstan","KE":"Kenya","KI":"Kiribati","KW":"Kuwait","KG":"Kyrgyzstan","LA":"Laos","LV":"Latvia","LB":"Lebanon","LS":"Lesotho","LR":"Liberia","LY":"Libya","LI":"Liechtenstein","LT":"Lithuania","LU":"Luxembourg","MO":"Macao SAR China","MG":"Madagascar","MW":"Malawi","MY":"Malaysia","MV":"Maldives","ML":"Mali","MT":"Malta","MH":"Marshall Islands","MQ":"Martinique","MR":"Mauritania","MU":"Mauritius","YT":"Mayotte","MX":"Mexico","FM":"Micronesia","MD":"Moldova","MC":"Monaco","MN":"Mongolia","ME":"Montenegro","MS":"Montserrat","MA":"Morocco","MZ":"Mozambique","MM":"Myanmar (Burma)","NA":"Namibia","NR":"Nauru","NP":"Nepal","NL":"Netherlands","NC":"New Caledonia","NZ":"New Zealand","NI":"Nicaragua","NE":"Niger","NG":"Nigeria","NU":"Niue","NF":"Norfolk Island","KP":"North Korea","MK":"North Macedonia","MP":"Northern Mariana Islands","NO":"Norway","OM":"Oman","PK":"Pakistan","PW":"Palau","PS":"Palestinian Territories","PA":"Panama","PG":"Papua New Guinea","PY":"Paraguay","PE":"Peru","PH":"Philippines","PN":"Pitcairn Islands","PL":"Poland","PT":"Portugal","PR":"Puerto Rico","QA":"Qatar","RE":"R\u00e9union","RO":"Romania","RU":"Russia","RW":"Rwanda","WS":"Samoa","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 & Pr\u00edncipe","SA":"Saudi Arabia","SN":"Senegal","RS":"Serbia","SC":"Seychelles","SL":"Sierra Leone","SG":"Singapore","SX":"Sint Maarten","SK":"Slovakia","SI":"Slovenia","SB":"Solomon Islands","SO":"Somalia","ZA":"South Africa","GS":"South Georgia & South Sandwich Islands","KR":"South Korea","SS":"South Sudan","ES":"Spain","LK":"Sri Lanka","BL":"St. Barth\u00e9lemy","SH":"St. Helena","KN":"St. Kitts & Nevis","LC":"St. Lucia","MF":"St. Martin","PM":"St. Pierre & Miquelon","VC":"St. Vincent & Grenadines","SD":"Sudan","SR":"Suriname","SJ":"Svalbard & Jan Mayen","SE":"Sweden","CH":"Switzerland","SY":"Syria","TW":"Taiwan","TJ":"Tajikistan","TZ":"Tanzania","TH":"Thailand","TL":"Timor-Leste","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad & Tobago","TN":"Tunisia","TR":"Turkey","TM":"Turkmenistan","TC":"Turks & Caicos Islands","TV":"Tuvalu","UM":"U.S. Outlying Islands","VI":"U.S. Virgin Islands","UG":"Uganda","UA":"Ukraine","AE":"United Arab Emirates","GB":"United Kingdom","US":"United States","UY":"Uruguay","UZ":"Uzbekistan","VU":"Vanuatu","VA":"Vatican City","VE":"Venezuela","VN":"Vietnam","WF":"Wallis & Futuna","EH":"Western Sahara","YE":"Yemen","ZM":"Zambia","ZW":"Zimbabwe"}
{
"AF": "Afghanistan",
"AX": "\u00c5land Islands",
"AL": "Albania",
"DZ": "Algeria",
"AS": "American Samoa",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguilla",
"AQ": "Antarctica",
"AG": "Antigua & Barbuda",
"AR": "Argentina",
"AM": "Armenia",
"AW": "Aruba",
"AU": "Australia",
"AT": "Austria",
"AZ": "Azerbaijan",
"BS": "Bahamas",
"BH": "Bahrain",
"BD": "Bangladesh",
"BB": "Barbados",
"BY": "Belarus",
"BE": "Belgium",
"BZ": "Belize",
"BJ": "Benin",
"BM": "Bermuda",
"BT": "Bhutan",
"BO": "Bolivia",
"BA": "Bosnia & Herzegovina",
"BW": "Botswana",
"BV": "Bouvet Island",
"BR": "Brazil",
"IO": "British Indian Ocean Territory",
"VG": "British Virgin Islands",
"BN": "Brunei",
"BG": "Bulgaria",
"BF": "Burkina Faso",
"BI": "Burundi",
"KH": "Cambodia",
"CM": "Cameroon",
"CA": "Canada",
"CV": "Cape Verde",
"BQ": "Caribbean Netherlands",
"KY": "Cayman Islands",
"CF": "Central African Republic",
"TD": "Chad",
"CL": "Chile",
"CN": "China",
"CX": "Christmas Island",
"CC": "Cocos (Keeling) Islands",
"CO": "Colombia",
"KM": "Comoros",
"CG": "Congo - Brazzaville",
"CD": "Congo - Kinshasa",
"CK": "Cook Islands",
"CR": "Costa Rica",
"CI": "C\u00f4te d\u2019Ivoire",
"HR": "Croatia",
"CU": "Cuba",
"CW": "Cura\u00e7ao",
"CY": "Cyprus",
"CZ": "Czechia",
"DK": "Denmark",
"DJ": "Djibouti",
"DM": "Dominica",
"DO": "Dominican Republic",
"EC": "Ecuador",
"EG": "Egypt",
"SV": "El Salvador",
"GQ": "Equatorial Guinea",
"ER": "Eritrea",
"EE": "Estonia",
"SZ": "Eswatini",
"ET": "Ethiopia",
"FK": "Falkland Islands",
"FO": "Faroe Islands",
"FJ": "Fiji",
"FI": "Finland",
"FR": "France",
"GF": "French Guiana",
"PF": "French Polynesia",
"TF": "French Southern Territories",
"GA": "Gabon",
"GM": "Gambia",
"GE": "Georgia",
"DE": "Germany",
"GH": "Ghana",
"GI": "Gibraltar",
"GR": "Greece",
"GL": "Greenland",
"GD": "Grenada",
"GP": "Guadeloupe",
"GU": "Guam",
"GT": "Guatemala",
"GG": "Guernsey",
"GN": "Guinea",
"GW": "Guinea-Bissau",
"GY": "Guyana",
"HT": "Haiti",
"HM": "Heard & McDonald Islands",
"HN": "Honduras",
"HK": "Hong Kong SAR China",
"HU": "Hungary",
"IS": "Iceland",
"IN": "India",
"ID": "Indonesia",
"IR": "Iran",
"IQ": "Iraq",
"IE": "Ireland",
"IM": "Isle of Man",
"IL": "Israel",
"IT": "Italy",
"JM": "Jamaica",
"JP": "Japan",
"JE": "Jersey",
"JO": "Jordan",
"KZ": "Kazakhstan",
"KE": "Kenya",
"KI": "Kiribati",
"XK": "Kosovo",
"KW": "Kuwait",
"KG": "Kyrgyzstan",
"LA": "Laos",
"LV": "Latvia",
"LB": "Lebanon",
"LS": "Lesotho",
"LR": "Liberia",
"LY": "Libya",
"LI": "Liechtenstein",
"LT": "Lithuania",
"LU": "Luxembourg",
"MO": "Macao SAR China",
"MG": "Madagascar",
"MW": "Malawi",
"MY": "Malaysia",
"MV": "Maldives",
"ML": "Mali",
"MT": "Malta",
"MH": "Marshall Islands",
"MQ": "Martinique",
"MR": "Mauritania",
"MU": "Mauritius",
"YT": "Mayotte",
"MX": "Mexico",
"FM": "Micronesia",
"MD": "Moldova",
"MC": "Monaco",
"MN": "Mongolia",
"ME": "Montenegro",
"MS": "Montserrat",
"MA": "Morocco",
"MZ": "Mozambique",
"MM": "Myanmar (Burma)",
"NA": "Namibia",
"NR": "Nauru",
"NP": "Nepal",
"NL": "Netherlands",
"NC": "New Caledonia",
"NZ": "New Zealand",
"NI": "Nicaragua",
"NE": "Niger",
"NG": "Nigeria",
"NU": "Niue",
"NF": "Norfolk Island",
"KP": "North Korea",
"MK": "North Macedonia",
"MP": "Northern Mariana Islands",
"NO": "Norway",
"OM": "Oman",
"PK": "Pakistan",
"PW": "Palau",
"PS": "Palestinian Territories",
"PA": "Panama",
"PG": "Papua New Guinea",
"PY": "Paraguay",
"PE": "Peru",
"PH": "Philippines",
"PN": "Pitcairn Islands",
"PL": "Poland",
"PT": "Portugal",
"PR": "Puerto Rico",
"QA": "Qatar",
"RE": "R\u00e9union",
"RO": "Romania",
"RU": "Russia",
"RW": "Rwanda",
"WS": "Samoa",
"SM": "San Marino",
"ST": "S\u00e3o Tom\u00e9 & Pr\u00edncipe",
"SA": "Saudi Arabia",
"SN": "Senegal",
"RS": "Serbia",
"SC": "Seychelles",
"SL": "Sierra Leone",
"SG": "Singapore",
"SX": "Sint Maarten",
"SK": "Slovakia",
"SI": "Slovenia",
"SB": "Solomon Islands",
"SO": "Somalia",
"ZA": "South Africa",
"GS": "South Georgia & South Sandwich Islands",
"KR": "South Korea",
"SS": "South Sudan",
"ES": "Spain",
"LK": "Sri Lanka",
"BL": "St. Barth\u00e9lemy",
"SH": "St. Helena",
"KN": "St. Kitts & Nevis",
"LC": "St. Lucia",
"MF": "St. Martin",
"PM": "St. Pierre & Miquelon",
"VC": "St. Vincent & Grenadines",
"SD": "Sudan",
"SR": "Suriname",
"SJ": "Svalbard & Jan Mayen",
"SE": "Sweden",
"CH": "Switzerland",
"SY": "Syria",
"TW": "Taiwan",
"TJ": "Tajikistan",
"TZ": "Tanzania",
"TH": "Thailand",
"TL": "Timor-Leste",
"TG": "Togo",
"TK": "Tokelau",
"TO": "Tonga",
"TT": "Trinidad & Tobago",
"TN": "Tunisia",
"TR": "Turkey",
"TM": "Turkmenistan",
"TC": "Turks & Caicos Islands",
"TV": "Tuvalu",
"UM": "U.S. Outlying Islands",
"VI": "U.S. Virgin Islands",
"UG": "Uganda",
"UA": "Ukraine",
"AE": "United Arab Emirates",
"GB": "United Kingdom",
"US": "United States",
"UY": "Uruguay",
"UZ": "Uzbekistan",
"VU": "Vanuatu",
"VA": "Vatican City",
"VE": "Venezuela",
"VN": "Vietnam",
"WF": "Wallis & Futuna",
"EH": "Western Sahara",
"YE": "Yemen",
"ZM": "Zambia",
"ZW": "Zimbabwe"
}

View file

@ -1 +1,252 @@
{"AF":"Afghanistan","AX":"\u00c5land Islands","AL":"Albania","DZ":"Algeria","AS":"American Samoa","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Antarctica","AG":"Antigua & Barbuda","AR":"Argentina","AM":"Armenia","AW":"Aruba","AU":"Australia","AT":"Austria","AZ":"Azerbaijan","BS":"Bahamas","BH":"Bahrain","BD":"Bangladesh","BB":"Barbados","BY":"Belarus","BE":"Belgium","BZ":"Belize","BJ":"Benin","BM":"Bermuda","BT":"Bhutan","BO":"Bolivia","BA":"Bosnia & Herzegovina","BW":"Botswana","BV":"Bouvet Island","BR":"Brazil","IO":"British Indian Ocean Territory","VG":"British Virgin Islands","BN":"Brunei","BG":"Bulgaria","BF":"Burkina Faso","BI":"Burundi","KH":"Cambodia","CM":"Cameroon","CA":"Canada","CV":"Cape Verde","BQ":"Caribbean Netherlands","KY":"Cayman Islands","CF":"Central African Republic","TD":"Chad","CL":"Chile","CN":"China","CX":"Christmas Island","CC":"Cocos (Keeling) Islands","CO":"Colombia","KM":"Comoros","CG":"Congo - Brazzaville","CD":"Congo - Kinshasa","CK":"Cook Islands","CR":"Costa Rica","CI":"C\u00f4te d\u2019Ivoire","HR":"Croatia","CU":"Cuba","CW":"Cura\u00e7ao","CY":"Cyprus","CZ":"Czechia","DK":"Denmark","DJ":"Djibouti","DM":"Dominica","DO":"Dominican Republic","EC":"Ecuador","EG":"Egypt","SV":"El Salvador","GQ":"Equatorial Guinea","ER":"Eritrea","EE":"Estonia","SZ":"Eswatini","ET":"Ethiopia","FK":"Falkland Islands","FO":"Faroe Islands","FJ":"Fiji","FI":"Finland","FR":"France","GF":"French Guiana","PF":"French Polynesia","TF":"French Southern Territories","GA":"Gabon","GM":"Gambia","GE":"Georgia","DE":"Germany","GH":"Ghana","GI":"Gibraltar","GR":"Greece","GL":"Greenland","GD":"Grenada","GP":"Guadeloupe","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea-Bissau","GY":"Guyana","HT":"Haiti","HM":"Heard & McDonald Islands","HN":"Honduras","HK":"Hong Kong SAR China","HU":"Hungary","IS":"Iceland","IN":"India","ID":"Indonesia","IR":"Iran","IQ":"Iraq","IE":"Ireland","IM":"Isle of Man","IL":"Israel","IT":"Italy","JM":"Jamaica","JP":"Japan","JE":"Jersey","JO":"Jordan","KZ":"Kazakhstan","KE":"Kenya","KI":"Kiribati","KW":"Kuwait","KG":"Kyrgyzstan","LA":"Laos","LV":"Latvia","LB":"Lebanon","LS":"Lesotho","LR":"Liberia","LY":"Libya","LI":"Liechtenstein","LT":"Lithuania","LU":"Luxembourg","MO":"Macao SAR China","MG":"Madagascar","MW":"Malawi","MY":"Malaysia","MV":"Maldives","ML":"Mali","MT":"Malta","MH":"Marshall Islands","MQ":"Martinique","MR":"Mauritania","MU":"Mauritius","YT":"Mayotte","MX":"Mexico","FM":"Micronesia","MD":"Moldova","MC":"Monaco","MN":"Mongolia","ME":"Montenegro","MS":"Montserrat","MA":"Morocco","MZ":"Mozambique","MM":"Myanmar (Burma)","NA":"Namibia","NR":"Nauru","NP":"Nepal","NL":"Netherlands","NC":"New Caledonia","NZ":"New Zealand","NI":"Nicaragua","NE":"Niger","NG":"Nigeria","NU":"Niue","NF":"Norfolk Island","KP":"North Korea","MK":"North Macedonia","MP":"Northern Mariana Islands","NO":"Norway","OM":"Oman","PK":"Pakistan","PW":"Palau","PS":"Palestinian Territories","PA":"Panama","PG":"Papua New Guinea","PY":"Paraguay","PE":"Peru","PH":"Philippines","PN":"Pitcairn Islands","PL":"Poland","PT":"Portugal","PR":"Puerto Rico","QA":"Qatar","RE":"R\u00e9union","RO":"Romania","RU":"Russia","RW":"Rwanda","WS":"Samoa","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 & Pr\u00edncipe","SA":"Saudi Arabia","SN":"Senegal","RS":"Serbia","SC":"Seychelles","SL":"Sierra Leone","SG":"Singapore","SX":"Sint Maarten","SK":"Slovakia","SI":"Slovenia","SB":"Solomon Islands","SO":"Somalia","ZA":"South Africa","GS":"South Georgia & South Sandwich Islands","KR":"South Korea","SS":"South Sudan","ES":"Spain","LK":"Sri Lanka","BL":"St. Barth\u00e9lemy","SH":"St. Helena","KN":"St. Kitts & Nevis","LC":"St. Lucia","MF":"St. Martin","PM":"St. Pierre & Miquelon","VC":"St. Vincent & Grenadines","SD":"Sudan","SR":"Suriname","SJ":"Svalbard & Jan Mayen","SE":"Sweden","CH":"Switzerland","SY":"Syria","TW":"Taiwan","TJ":"Tajikistan","TZ":"Tanzania","TH":"Thailand","TL":"Timor-Leste","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad & Tobago","TN":"Tunisia","TR":"Turkey","TM":"Turkmenistan","TC":"Turks & Caicos Islands","TV":"Tuvalu","UM":"U.S. Outlying Islands","VI":"U.S. Virgin Islands","UG":"Uganda","UA":"Ukraine","AE":"United Arab Emirates","GB":"United Kingdom","US":"United States","UY":"Uruguay","UZ":"Uzbekistan","VU":"Vanuatu","VA":"Vatican City","VE":"Venezuela","VN":"Vietnam","WF":"Wallis & Futuna","EH":"Western Sahara","YE":"Yemen","ZM":"Zambia","ZW":"Zimbabwe"}
{
"AF": "Afghanistan",
"AX": "\u00c5land Islands",
"AL": "Albania",
"DZ": "Algeria",
"AS": "American Samoa",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguilla",
"AQ": "Antarctica",
"AG": "Antigua & Barbuda",
"AR": "Argentina",
"AM": "Armenia",
"AW": "Aruba",
"AU": "Australia",
"AT": "Austria",
"AZ": "Azerbaijan",
"BS": "Bahamas",
"BH": "Bahrain",
"BD": "Bangladesh",
"BB": "Barbados",
"BY": "Belarus",
"BE": "Belgium",
"BZ": "Belize",
"BJ": "Benin",
"BM": "Bermuda",
"BT": "Bhutan",
"BO": "Bolivia",
"BA": "Bosnia & Herzegovina",
"BW": "Botswana",
"BV": "Bouvet Island",
"BR": "Brazil",
"IO": "British Indian Ocean Territory",
"VG": "British Virgin Islands",
"BN": "Brunei",
"BG": "Bulgaria",
"BF": "Burkina Faso",
"BI": "Burundi",
"KH": "Cambodia",
"CM": "Cameroon",
"CA": "Canada",
"CV": "Cape Verde",
"BQ": "Caribbean Netherlands",
"KY": "Cayman Islands",
"CF": "Central African Republic",
"TD": "Chad",
"CL": "Chile",
"CN": "China",
"CX": "Christmas Island",
"CC": "Cocos (Keeling) Islands",
"CO": "Colombia",
"KM": "Comoros",
"CG": "Congo - Brazzaville",
"CD": "Congo - Kinshasa",
"CK": "Cook Islands",
"CR": "Costa Rica",
"CI": "C\u00f4te d\u2019Ivoire",
"HR": "Croatia",
"CU": "Cuba",
"CW": "Cura\u00e7ao",
"CY": "Cyprus",
"CZ": "Czechia",
"DK": "Denmark",
"DJ": "Djibouti",
"DM": "Dominica",
"DO": "Dominican Republic",
"EC": "Ecuador",
"EG": "Egypt",
"SV": "El Salvador",
"GQ": "Equatorial Guinea",
"ER": "Eritrea",
"EE": "Estonia",
"SZ": "Eswatini",
"ET": "Ethiopia",
"FK": "Falkland Islands",
"FO": "Faroe Islands",
"FJ": "Fiji",
"FI": "Finland",
"FR": "France",
"GF": "French Guiana",
"PF": "French Polynesia",
"TF": "French Southern Territories",
"GA": "Gabon",
"GM": "Gambia",
"GE": "Georgia",
"DE": "Germany",
"GH": "Ghana",
"GI": "Gibraltar",
"GR": "Greece",
"GL": "Greenland",
"GD": "Grenada",
"GP": "Guadeloupe",
"GU": "Guam",
"GT": "Guatemala",
"GG": "Guernsey",
"GN": "Guinea",
"GW": "Guinea-Bissau",
"GY": "Guyana",
"HT": "Haiti",
"HM": "Heard & McDonald Islands",
"HN": "Honduras",
"HK": "Hong Kong SAR China",
"HU": "Hungary",
"IS": "Iceland",
"IN": "India",
"ID": "Indonesia",
"IR": "Iran",
"IQ": "Iraq",
"IE": "Ireland",
"IM": "Isle of Man",
"IL": "Israel",
"IT": "Italy",
"JM": "Jamaica",
"JP": "Japan",
"JE": "Jersey",
"JO": "Jordan",
"KZ": "Kazakhstan",
"KE": "Kenya",
"KI": "Kiribati",
"XK": "Kosovo",
"KW": "Kuwait",
"KG": "Kyrgyzstan",
"LA": "Laos",
"LV": "Latvia",
"LB": "Lebanon",
"LS": "Lesotho",
"LR": "Liberia",
"LY": "Libya",
"LI": "Liechtenstein",
"LT": "Lithuania",
"LU": "Luxembourg",
"MO": "Macao SAR China",
"MG": "Madagascar",
"MW": "Malawi",
"MY": "Malaysia",
"MV": "Maldives",
"ML": "Mali",
"MT": "Malta",
"MH": "Marshall Islands",
"MQ": "Martinique",
"MR": "Mauritania",
"MU": "Mauritius",
"YT": "Mayotte",
"MX": "Mexico",
"FM": "Micronesia",
"MD": "Moldova",
"MC": "Monaco",
"MN": "Mongolia",
"ME": "Montenegro",
"MS": "Montserrat",
"MA": "Morocco",
"MZ": "Mozambique",
"MM": "Myanmar (Burma)",
"NA": "Namibia",
"NR": "Nauru",
"NP": "Nepal",
"NL": "Netherlands",
"NC": "New Caledonia",
"NZ": "New Zealand",
"NI": "Nicaragua",
"NE": "Niger",
"NG": "Nigeria",
"NU": "Niue",
"NF": "Norfolk Island",
"KP": "North Korea",
"MK": "North Macedonia",
"MP": "Northern Mariana Islands",
"NO": "Norway",
"OM": "Oman",
"PK": "Pakistan",
"PW": "Palau",
"PS": "Palestinian Territories",
"PA": "Panama",
"PG": "Papua New Guinea",
"PY": "Paraguay",
"PE": "Peru",
"PH": "Philippines",
"PN": "Pitcairn Islands",
"PL": "Poland",
"PT": "Portugal",
"PR": "Puerto Rico",
"QA": "Qatar",
"RE": "R\u00e9union",
"RO": "Romania",
"RU": "Russia",
"RW": "Rwanda",
"WS": "Samoa",
"SM": "San Marino",
"ST": "S\u00e3o Tom\u00e9 & Pr\u00edncipe",
"SA": "Saudi Arabia",
"SN": "Senegal",
"RS": "Serbia",
"SC": "Seychelles",
"SL": "Sierra Leone",
"SG": "Singapore",
"SX": "Sint Maarten",
"SK": "Slovakia",
"SI": "Slovenia",
"SB": "Solomon Islands",
"SO": "Somalia",
"ZA": "South Africa",
"GS": "South Georgia & South Sandwich Islands",
"KR": "South Korea",
"SS": "South Sudan",
"ES": "Spain",
"LK": "Sri Lanka",
"BL": "St. Barth\u00e9lemy",
"SH": "St. Helena",
"KN": "St. Kitts & Nevis",
"LC": "St. Lucia",
"MF": "St. Martin",
"PM": "St. Pierre & Miquelon",
"VC": "St. Vincent & Grenadines",
"SD": "Sudan",
"SR": "Suriname",
"SJ": "Svalbard & Jan Mayen",
"SE": "Sweden",
"CH": "Switzerland",
"SY": "Syria",
"TW": "Taiwan",
"TJ": "Tajikistan",
"TZ": "Tanzania",
"TH": "Thailand",
"TL": "Timor-Leste",
"TG": "Togo",
"TK": "Tokelau",
"TO": "Tonga",
"TT": "Trinidad & Tobago",
"TN": "Tunisia",
"TR": "Turkey",
"TM": "Turkmenistan",
"TC": "Turks & Caicos Islands",
"TV": "Tuvalu",
"UM": "U.S. Outlying Islands",
"VI": "U.S. Virgin Islands",
"UG": "Uganda",
"UA": "Ukraine",
"AE": "United Arab Emirates",
"GB": "United Kingdom",
"US": "United States",
"UY": "Uruguay",
"UZ": "Uzbekistan",
"VU": "Vanuatu",
"VA": "Vatican City",
"VE": "Venezuela",
"VN": "Vietnam",
"WF": "Wallis & Futuna",
"EH": "Western Sahara",
"YE": "Yemen",
"ZM": "Zambia",
"ZW": "Zimbabwe"
}

View file

@ -129,6 +129,7 @@
"KE": "Kenia",
"KG": "Kirguist\u00e1n",
"KI": "Kiribati",
"XK": "Kosovo",
"KW": "Kuwait",
"LA": "Laos",
"LS": "Lesoto",

View file

@ -1 +1,252 @@
{"AF":"Afganist\u00e1n","AL":"Albania","DE":"Alemania","AD":"Andorra","AO":"Angola","AI":"Anguila","AQ":"Ant\u00e1rtida","AG":"Antigua y Barbuda","SA":"Arabia Saudita","DZ":"Argelia","AR":"Argentina","AM":"Armenia","AW":"Aruba","AU":"Australia","AT":"Austria","AZ":"Azerbaiy\u00e1n","BS":"Bahamas","BD":"Banglad\u00e9s","BB":"Barbados","BH":"Bar\u00e9in","BE":"B\u00e9lgica","BZ":"Belice","BJ":"Ben\u00edn","BM":"Bermudas","BY":"Bielorrusia","BO":"Bolivia","BA":"Bosnia y Herzegovina","BW":"Botsuana","BR":"Brasil","BN":"Brun\u00e9i","BG":"Bulgaria","BF":"Burkina Faso","BI":"Burundi","BT":"But\u00e1n","CV":"Cabo Verde","KH":"Camboya","CM":"Camer\u00fan","CA":"Canad\u00e1","BQ":"Caribe neerland\u00e9s","QA":"Catar","TD":"Chad","CZ":"Chequia","CL":"Chile","CN":"China","CY":"Chipre","VA":"Ciudad del Vaticano","CO":"Colombia","KM":"Comoras","CG":"Congo","KP":"Corea del Norte","KR":"Corea del Sur","CR":"Costa Rica","CI":"C\u00f4te d\u2019Ivoire","HR":"Croacia","CU":"Cuba","CW":"Curazao","DK":"Dinamarca","DM":"Dominica","EC":"Ecuador","EG":"Egipto","SV":"El Salvador","AE":"Emiratos \u00c1rabes Unidos","ER":"Eritrea","SK":"Eslovaquia","SI":"Eslovenia","ES":"Espa\u00f1a","US":"Estados Unidos","EE":"Estonia","SZ":"Eswatini","ET":"Etiop\u00eda","PH":"Filipinas","FI":"Finlandia","FJ":"Fiyi","FR":"Francia","GA":"Gab\u00f3n","GM":"Gambia","GE":"Georgia","GH":"Ghana","GI":"Gibraltar","GD":"Granada","GR":"Grecia","GL":"Groenlandia","GP":"Guadalupe","GU":"Guam","GT":"Guatemala","GF":"Guayana Francesa","GG":"Guernsey","GN":"Guinea","GQ":"Guinea Ecuatorial","GW":"Guinea-Bis\u00e1u","GY":"Guyana","HT":"Hait\u00ed","HN":"Honduras","HU":"Hungr\u00eda","IN":"India","ID":"Indonesia","IQ":"Irak","IR":"Ir\u00e1n","IE":"Irlanda","BV":"Isla Bouvet","IM":"Isla de Man","CX":"Isla de Navidad","NF":"Isla Norfolk","IS":"Islandia","AX":"Islas \u00c5land","KY":"Islas Caim\u00e1n","CC":"Islas Cocos","CK":"Islas Cook","FO":"Islas Feroe","GS":"Islas Georgia del Sur y Sandwich del Sur","HM":"Islas Heard y McDonald","FK":"Islas Malvinas","MP":"Islas Marianas del Norte","MH":"Islas Marshall","UM":"Islas menores alejadas de EE. UU.","PN":"Islas Pitcairn","SB":"Islas Salom\u00f3n","TC":"Islas Turcas y Caicos","VG":"Islas V\u00edrgenes Brit\u00e1nicas","VI":"Islas V\u00edrgenes de EE. UU.","IL":"Israel","IT":"Italia","JM":"Jamaica","JP":"Jap\u00f3n","JE":"Jersey","JO":"Jordania","KZ":"Kazajist\u00e1n","KE":"Kenia","KG":"Kirguist\u00e1n","KI":"Kiribati","KW":"Kuwait","LA":"Laos","LS":"Lesoto","LV":"Letonia","LB":"L\u00edbano","LR":"Liberia","LY":"Libia","LI":"Liechtenstein","LT":"Lituania","LU":"Luxemburgo","MK":"Macedonia del Norte","MG":"Madagascar","MY":"Malasia","MW":"Malaui","MV":"Maldivas","ML":"Mali","MT":"Malta","MA":"Marruecos","MQ":"Martinica","MU":"Mauricio","MR":"Mauritania","YT":"Mayotte","MX":"M\u00e9xico","FM":"Micronesia","MD":"Moldavia","MC":"M\u00f3naco","MN":"Mongolia","ME":"Montenegro","MS":"Montserrat","MZ":"Mozambique","MM":"Myanmar (Birmania)","NA":"Namibia","NR":"Nauru","NP":"Nepal","NI":"Nicaragua","NE":"N\u00edger","NG":"Nigeria","NU":"Niue","NO":"Noruega","NC":"Nueva Caledonia","NZ":"Nueva Zelanda","OM":"Om\u00e1n","NL":"Pa\u00edses Bajos","PK":"Pakist\u00e1n","PW":"Palaos","PA":"Panam\u00e1","PG":"Pap\u00faa Nueva Guinea","PY":"Paraguay","PE":"Per\u00fa","PF":"Polinesia Francesa","PL":"Polonia","PT":"Portugal","PR":"Puerto Rico","HK":"RAE de Hong Kong (China)","MO":"RAE de Macao (China)","GB":"Reino Unido","CF":"Rep\u00fablica Centroafricana","CD":"Rep\u00fablica Democr\u00e1tica del Congo","DO":"Rep\u00fablica Dominicana","RE":"Reuni\u00f3n","RW":"Ruanda","RO":"Rumania","RU":"Rusia","EH":"S\u00e1hara Occidental","WS":"Samoa","AS":"Samoa Americana","BL":"San Bartolom\u00e9","KN":"San Crist\u00f3bal y Nieves","SM":"San Marino","MF":"San Mart\u00edn","PM":"San Pedro y Miquel\u00f3n","VC":"San Vicente y las Granadinas","SH":"Santa Elena","LC":"Santa Luc\u00eda","ST":"Santo Tom\u00e9 y Pr\u00edncipe","SN":"Senegal","RS":"Serbia","SC":"Seychelles","SL":"Sierra Leona","SG":"Singapur","SX":"Sint Maarten","SY":"Siria","SO":"Somalia","LK":"Sri Lanka","ZA":"Sud\u00e1frica","SD":"Sud\u00e1n","SS":"Sud\u00e1n del Sur","SE":"Suecia","CH":"Suiza","SR":"Surinam","SJ":"Svalbard y Jan Mayen","TH":"Tailandia","TW":"Taiw\u00e1n","TZ":"Tanzania","TJ":"Tayikist\u00e1n","IO":"Territorio Brit\u00e1nico del Oc\u00e9ano \u00cdndico","TF":"Territorios Australes Franceses","PS":"Territorios Palestinos","TL":"Timor-Leste","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad y Tobago","TN":"T\u00fanez","TM":"Turkmenist\u00e1n","TR":"Turqu\u00eda","TV":"Tuvalu","UA":"Ucrania","UG":"Uganda","UY":"Uruguay","UZ":"Uzbekist\u00e1n","VU":"Vanuatu","VE":"Venezuela","VN":"Vietnam","WF":"Wallis y Futuna","YE":"Yemen","DJ":"Yibuti","ZM":"Zambia","ZW":"Zimbabue"}
{
"AF": "Afganist\u00e1n",
"AL": "Albania",
"DE": "Alemania",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguila",
"AQ": "Ant\u00e1rtida",
"AG": "Antigua y Barbuda",
"SA": "Arabia Saudita",
"DZ": "Argelia",
"AR": "Argentina",
"AM": "Armenia",
"AW": "Aruba",
"AU": "Australia",
"AT": "Austria",
"AZ": "Azerbaiy\u00e1n",
"BS": "Bahamas",
"BD": "Banglad\u00e9s",
"BB": "Barbados",
"BH": "Bar\u00e9in",
"BE": "B\u00e9lgica",
"BZ": "Belice",
"BJ": "Ben\u00edn",
"BM": "Bermudas",
"BY": "Bielorrusia",
"BO": "Bolivia",
"BA": "Bosnia y Herzegovina",
"BW": "Botsuana",
"BR": "Brasil",
"BN": "Brun\u00e9i",
"BG": "Bulgaria",
"BF": "Burkina Faso",
"BI": "Burundi",
"BT": "But\u00e1n",
"CV": "Cabo Verde",
"KH": "Camboya",
"CM": "Camer\u00fan",
"CA": "Canad\u00e1",
"BQ": "Caribe neerland\u00e9s",
"QA": "Catar",
"TD": "Chad",
"CZ": "Chequia",
"CL": "Chile",
"CN": "China",
"CY": "Chipre",
"VA": "Ciudad del Vaticano",
"CO": "Colombia",
"KM": "Comoras",
"CG": "Congo",
"KP": "Corea del Norte",
"KR": "Corea del Sur",
"CR": "Costa Rica",
"CI": "C\u00f4te d\u2019Ivoire",
"HR": "Croacia",
"CU": "Cuba",
"CW": "Curazao",
"DK": "Dinamarca",
"DM": "Dominica",
"EC": "Ecuador",
"EG": "Egipto",
"SV": "El Salvador",
"AE": "Emiratos \u00c1rabes Unidos",
"ER": "Eritrea",
"SK": "Eslovaquia",
"SI": "Eslovenia",
"ES": "Espa\u00f1a",
"US": "Estados Unidos",
"EE": "Estonia",
"SZ": "Eswatini",
"ET": "Etiop\u00eda",
"PH": "Filipinas",
"FI": "Finlandia",
"FJ": "Fiyi",
"FR": "Francia",
"GA": "Gab\u00f3n",
"GM": "Gambia",
"GE": "Georgia",
"GH": "Ghana",
"GI": "Gibraltar",
"GD": "Granada",
"GR": "Grecia",
"GL": "Groenlandia",
"GP": "Guadalupe",
"GU": "Guam",
"GT": "Guatemala",
"GF": "Guayana Francesa",
"GG": "Guernsey",
"GN": "Guinea",
"GQ": "Guinea Ecuatorial",
"GW": "Guinea-Bis\u00e1u",
"GY": "Guyana",
"HT": "Hait\u00ed",
"HN": "Honduras",
"HU": "Hungr\u00eda",
"IN": "India",
"ID": "Indonesia",
"IQ": "Irak",
"IR": "Ir\u00e1n",
"IE": "Irlanda",
"BV": "Isla Bouvet",
"IM": "Isla de Man",
"CX": "Isla de Navidad",
"NF": "Isla Norfolk",
"IS": "Islandia",
"AX": "Islas \u00c5land",
"KY": "Islas Caim\u00e1n",
"CC": "Islas Cocos",
"CK": "Islas Cook",
"FO": "Islas Feroe",
"GS": "Islas Georgia del Sur y Sandwich del Sur",
"HM": "Islas Heard y McDonald",
"FK": "Islas Malvinas",
"MP": "Islas Marianas del Norte",
"MH": "Islas Marshall",
"UM": "Islas menores alejadas de EE. UU.",
"PN": "Islas Pitcairn",
"SB": "Islas Salom\u00f3n",
"TC": "Islas Turcas y Caicos",
"VG": "Islas V\u00edrgenes Brit\u00e1nicas",
"VI": "Islas V\u00edrgenes de EE. UU.",
"IL": "Israel",
"IT": "Italia",
"JM": "Jamaica",
"JP": "Jap\u00f3n",
"JE": "Jersey",
"JO": "Jordania",
"KZ": "Kazajist\u00e1n",
"KE": "Kenia",
"KG": "Kirguist\u00e1n",
"KI": "Kiribati",
"XK": "Kosovo",
"KW": "Kuwait",
"LA": "Laos",
"LS": "Lesoto",
"LV": "Letonia",
"LB": "L\u00edbano",
"LR": "Liberia",
"LY": "Libia",
"LI": "Liechtenstein",
"LT": "Lituania",
"LU": "Luxemburgo",
"MK": "Macedonia del Norte",
"MG": "Madagascar",
"MY": "Malasia",
"MW": "Malaui",
"MV": "Maldivas",
"ML": "Mali",
"MT": "Malta",
"MA": "Marruecos",
"MQ": "Martinica",
"MU": "Mauricio",
"MR": "Mauritania",
"YT": "Mayotte",
"MX": "M\u00e9xico",
"FM": "Micronesia",
"MD": "Moldavia",
"MC": "M\u00f3naco",
"MN": "Mongolia",
"ME": "Montenegro",
"MS": "Montserrat",
"MZ": "Mozambique",
"MM": "Myanmar (Birmania)",
"NA": "Namibia",
"NR": "Nauru",
"NP": "Nepal",
"NI": "Nicaragua",
"NE": "N\u00edger",
"NG": "Nigeria",
"NU": "Niue",
"NO": "Noruega",
"NC": "Nueva Caledonia",
"NZ": "Nueva Zelanda",
"OM": "Om\u00e1n",
"NL": "Pa\u00edses Bajos",
"PK": "Pakist\u00e1n",
"PW": "Palaos",
"PA": "Panam\u00e1",
"PG": "Pap\u00faa Nueva Guinea",
"PY": "Paraguay",
"PE": "Per\u00fa",
"PF": "Polinesia Francesa",
"PL": "Polonia",
"PT": "Portugal",
"PR": "Puerto Rico",
"HK": "RAE de Hong Kong (China)",
"MO": "RAE de Macao (China)",
"GB": "Reino Unido",
"CF": "Rep\u00fablica Centroafricana",
"CD": "Rep\u00fablica Democr\u00e1tica del Congo",
"DO": "Rep\u00fablica Dominicana",
"RE": "Reuni\u00f3n",
"RW": "Ruanda",
"RO": "Rumania",
"RU": "Rusia",
"EH": "S\u00e1hara Occidental",
"WS": "Samoa",
"AS": "Samoa Americana",
"BL": "San Bartolom\u00e9",
"KN": "San Crist\u00f3bal y Nieves",
"SM": "San Marino",
"MF": "San Mart\u00edn",
"PM": "San Pedro y Miquel\u00f3n",
"VC": "San Vicente y las Granadinas",
"SH": "Santa Elena",
"LC": "Santa Luc\u00eda",
"ST": "Santo Tom\u00e9 y Pr\u00edncipe",
"SN": "Senegal",
"RS": "Serbia",
"SC": "Seychelles",
"SL": "Sierra Leona",
"SG": "Singapur",
"SX": "Sint Maarten",
"SY": "Siria",
"SO": "Somalia",
"LK": "Sri Lanka",
"ZA": "Sud\u00e1frica",
"SD": "Sud\u00e1n",
"SS": "Sud\u00e1n del Sur",
"SE": "Suecia",
"CH": "Suiza",
"SR": "Surinam",
"SJ": "Svalbard y Jan Mayen",
"TH": "Tailandia",
"TW": "Taiw\u00e1n",
"TZ": "Tanzania",
"TJ": "Tayikist\u00e1n",
"IO": "Territorio Brit\u00e1nico del Oc\u00e9ano \u00cdndico",
"TF": "Territorios Australes Franceses",
"PS": "Territorios Palestinos",
"TL": "Timor-Leste",
"TG": "Togo",
"TK": "Tokelau",
"TO": "Tonga",
"TT": "Trinidad y Tobago",
"TN": "T\u00fanez",
"TM": "Turkmenist\u00e1n",
"TR": "Turqu\u00eda",
"TV": "Tuvalu",
"UA": "Ucrania",
"UG": "Uganda",
"UY": "Uruguay",
"UZ": "Uzbekist\u00e1n",
"VU": "Vanuatu",
"VE": "Venezuela",
"VN": "Vietnam",
"WF": "Wallis y Futuna",
"YE": "Yemen",
"DJ": "Yibuti",
"ZM": "Zambia",
"ZW": "Zimbabue"
}

File diff suppressed because one or more lines are too long

View file

@ -1 +1,252 @@
{"AF":"Afganistan","AX":"Ahvenanmaa","NL":"Alankomaat","AL":"Albania","DZ":"Algeria","AS":"Amerikan Samoa","AD":"Andorra","AO":"Angola","AI":"Anguilla","AQ":"Antarktis","AG":"Antigua ja Barbuda","AE":"Arabiemiirikunnat","AR":"Argentiina","AM":"Armenia","AW":"Aruba","AU":"Australia","AZ":"Azerbaid\u017ean","BS":"Bahama","BH":"Bahrain","BD":"Bangladesh","BB":"Barbados","BE":"Belgia","BZ":"Belize","BJ":"Benin","BM":"Bermuda","BT":"Bhutan","BO":"Bolivia","BA":"Bosnia ja Hertsegovina","BW":"Botswana","BV":"Bouvet\u2019nsaari","BR":"Brasilia","IO":"Brittil\u00e4inen Intian valtameren alue","VG":"Brittil\u00e4iset Neitsytsaaret","BN":"Brunei","BG":"Bulgaria","BF":"Burkina Faso","BI":"Burundi","KY":"Caymansaaret","CL":"Chile","CK":"Cookinsaaret","CR":"Costa Rica","CW":"Cura\u00e7ao","DJ":"Djibouti","DM":"Dominica","DO":"Dominikaaninen tasavalta","EC":"Ecuador","EG":"Egypti","SV":"El Salvador","ER":"Eritrea","ES":"Espanja","ZA":"Etel\u00e4-Afrikka","GS":"Etel\u00e4-Georgia ja Etel\u00e4iset Sandwichsaaret","KR":"Etel\u00e4-Korea","SS":"Etel\u00e4-Sudan","ET":"Etiopia","FK":"Falklandinsaaret","FJ":"Fid\u017ei","PH":"Filippiinit","FO":"F\u00e4rsaaret","GA":"Gabon","GM":"Gambia","GE":"Georgia","GH":"Ghana","GI":"Gibraltar","GD":"Grenada","GL":"Gr\u00f6nlanti","GP":"Guadeloupe","GU":"Guam","GT":"Guatemala","GG":"Guernsey","GN":"Guinea","GW":"Guinea-Bissau","GY":"Guyana","HT":"Haiti","HM":"Heard ja McDonaldinsaaret","HN":"Honduras","HK":"Hongkong \u2013 Kiinan e.h.a.","SJ":"Huippuvuoret ja Jan Mayen","ID":"Indonesia","IN":"Intia","IQ":"Irak","IR":"Iran","IE":"Irlanti","IS":"Islanti","GB":"Iso-Britannia","IL":"Israel","IT":"Italia","TL":"It\u00e4-Timor","AT":"It\u00e4valta","JM":"Jamaika","JP":"Japani","YE":"Jemen","JE":"Jersey","JO":"Jordania","CX":"Joulusaari","KH":"Kambod\u017ea","CM":"Kamerun","CA":"Kanada","CV":"Kap Verde","BQ":"Karibian Alankomaat","KZ":"Kazakstan","KE":"Kenia","CF":"Keski-Afrikan tasavalta","CN":"Kiina","KG":"Kirgisia","KI":"Kiribati","CO":"Kolumbia","KM":"Komorit","CD":"Kongon demokraattinen tasavalta","CG":"Kongon tasavalta","CC":"Kookossaaret (Keelingsaaret)","GR":"Kreikka","HR":"Kroatia","CU":"Kuuba","KW":"Kuwait","CY":"Kypros","LA":"Laos","LV":"Latvia","LS":"Lesotho","LB":"Libanon","LR":"Liberia","LY":"Libya","LI":"Liechtenstein","LT":"Liettua","LU":"Luxemburg","EH":"L\u00e4nsi-Sahara","MO":"Macao \u2013 Kiinan e.h.a.","MG":"Madagaskar","MW":"Malawi","MV":"Malediivit","MY":"Malesia","ML":"Mali","MT":"Malta","IM":"Mansaari","MA":"Marokko","MH":"Marshallinsaaret","MQ":"Martinique","MR":"Mauritania","MU":"Mauritius","YT":"Mayotte","MX":"Meksiko","FM":"Mikronesian liittovaltio","MD":"Moldova","MC":"Monaco","MN":"Mongolia","ME":"Montenegro","MS":"Montserrat","MZ":"Mosambik","MM":"Myanmar (Burma)","NA":"Namibia","NR":"Nauru","NP":"Nepal","NI":"Nicaragua","NE":"Niger","NG":"Nigeria","NU":"Niue","NF":"Norfolkinsaari","NO":"Norja","CI":"Norsunluurannikko","OM":"Oman","PK":"Pakistan","PW":"Palau","PS":"Palestiinalaisalueet","PA":"Panama","PG":"Papua-Uusi-Guinea","PY":"Paraguay","PE":"Peru","PN":"Pitcairn","KP":"Pohjois-Korea","MK":"Pohjois-Makedonia","MP":"Pohjois-Mariaanit","PT":"Portugali","PR":"Puerto Rico","PL":"Puola","GQ":"P\u00e4iv\u00e4ntasaajan Guinea","QA":"Qatar","FR":"Ranska","TF":"Ranskan etel\u00e4iset alueet","GF":"Ranskan Guayana","PF":"Ranskan Polynesia","RE":"R\u00e9union","RO":"Romania","RW":"Ruanda","SE":"Ruotsi","SH":"Saint Helena","KN":"Saint Kitts ja Nevis","LC":"Saint Lucia","VC":"Saint Vincent ja Grenadiinit","BL":"Saint-Barth\u00e9lemy","MF":"Saint-Martin","PM":"Saint-Pierre ja Miquelon","DE":"Saksa","SB":"Salomonsaaret","ZM":"Sambia","WS":"Samoa","SM":"San Marino","ST":"S\u00e3o Tom\u00e9 ja Pr\u00edncipe","SA":"Saudi-Arabia","SN":"Senegal","RS":"Serbia","SC":"Seychellit","SL":"Sierra Leone","SG":"Singapore","SX":"Sint Maarten","SK":"Slovakia","SI":"Slovenia","SO":"Somalia","LK":"Sri Lanka","SD":"Sudan","FI":"Suomi","SR":"Suriname","CH":"Sveitsi","SZ":"Swazimaa","SY":"Syyria","TJ":"Tad\u017eikistan","TW":"Taiwan","TZ":"Tansania","DK":"Tanska","TH":"Thaimaa","TG":"Togo","TK":"Tokelau","TO":"Tonga","TT":"Trinidad ja Tobago","TD":"T\u0161ad","CZ":"T\u0161ekki","TN":"Tunisia","TR":"Turkki","TM":"Turkmenistan","TC":"Turks- ja Caicossaaret","TV":"Tuvalu","UG":"Uganda","UA":"Ukraina","HU":"Unkari","UY":"Uruguay","NC":"Uusi-Kaledonia","NZ":"Uusi-Seelanti","UZ":"Uzbekistan","BY":"Valko-Ven\u00e4j\u00e4","VU":"Vanuatu","VA":"Vatikaani","VE":"Venezuela","RU":"Ven\u00e4j\u00e4","VN":"Vietnam","EE":"Viro","WF":"Wallis ja Futuna","US":"Yhdysvallat","UM":"Yhdysvaltain erillissaaret","VI":"Yhdysvaltain Neitsytsaaret","ZW":"Zimbabwe"}
{
"AF": "Afganistan",
"AX": "Ahvenanmaa",
"NL": "Alankomaat",
"AL": "Albania",
"DZ": "Algeria",
"AS": "Amerikan Samoa",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguilla",
"AQ": "Antarktis",
"AG": "Antigua ja Barbuda",
"AE": "Arabiemiirikunnat",
"AR": "Argentiina",
"AM": "Armenia",
"AW": "Aruba",
"AU": "Australia",
"AZ": "Azerbaid\u017ean",
"BS": "Bahama",
"BH": "Bahrain",
"BD": "Bangladesh",
"BB": "Barbados",
"BE": "Belgia",
"BZ": "Belize",
"BJ": "Benin",
"BM": "Bermuda",
"BT": "Bhutan",
"BO": "Bolivia",
"BA": "Bosnia ja Hertsegovina",
"BW": "Botswana",
"BV": "Bouvet\u2019nsaari",
"BR": "Brasilia",
"IO": "Brittil\u00e4inen Intian valtameren alue",
"VG": "Brittil\u00e4iset Neitsytsaaret",
"BN": "Brunei",
"BG": "Bulgaria",
"BF": "Burkina Faso",
"BI": "Burundi",
"KY": "Caymansaaret",
"CL": "Chile",
"CK": "Cookinsaaret",
"CR": "Costa Rica",
"CW": "Cura\u00e7ao",
"DJ": "Djibouti",
"DM": "Dominica",
"DO": "Dominikaaninen tasavalta",
"EC": "Ecuador",
"EG": "Egypti",
"SV": "El Salvador",
"ER": "Eritrea",
"ES": "Espanja",
"ZA": "Etel\u00e4-Afrikka",
"GS": "Etel\u00e4-Georgia ja Etel\u00e4iset Sandwichsaaret",
"KR": "Etel\u00e4-Korea",
"SS": "Etel\u00e4-Sudan",
"ET": "Etiopia",
"FK": "Falklandinsaaret",
"FJ": "Fid\u017ei",
"PH": "Filippiinit",
"FO": "F\u00e4rsaaret",
"GA": "Gabon",
"GM": "Gambia",
"GE": "Georgia",
"GH": "Ghana",
"GI": "Gibraltar",
"GD": "Grenada",
"GL": "Gr\u00f6nlanti",
"GP": "Guadeloupe",
"GU": "Guam",
"GT": "Guatemala",
"GG": "Guernsey",
"GN": "Guinea",
"GW": "Guinea-Bissau",
"GY": "Guyana",
"HT": "Haiti",
"HM": "Heard ja McDonaldinsaaret",
"HN": "Honduras",
"HK": "Hongkong \u2013 Kiinan e.h.a.",
"SJ": "Huippuvuoret ja Jan Mayen",
"ID": "Indonesia",
"IN": "Intia",
"IQ": "Irak",
"IR": "Iran",
"IE": "Irlanti",
"IS": "Islanti",
"GB": "Iso-Britannia",
"IL": "Israel",
"IT": "Italia",
"TL": "It\u00e4-Timor",
"AT": "It\u00e4valta",
"JM": "Jamaika",
"JP": "Japani",
"YE": "Jemen",
"JE": "Jersey",
"JO": "Jordania",
"CX": "Joulusaari",
"KH": "Kambod\u017ea",
"CM": "Kamerun",
"CA": "Kanada",
"CV": "Kap Verde",
"BQ": "Karibian Alankomaat",
"KZ": "Kazakstan",
"KE": "Kenia",
"CF": "Keski-Afrikan tasavalta",
"CN": "Kiina",
"KG": "Kirgisia",
"KI": "Kiribati",
"CO": "Kolumbia",
"KM": "Komorit",
"CD": "Kongon demokraattinen tasavalta",
"CG": "Kongon tasavalta",
"CC": "Kookossaaret (Keelingsaaret)",
"XK": "Kosovo",
"GR": "Kreikka",
"HR": "Kroatia",
"CU": "Kuuba",
"KW": "Kuwait",
"CY": "Kypros",
"LA": "Laos",
"LV": "Latvia",
"LS": "Lesotho",
"LB": "Libanon",
"LR": "Liberia",
"LY": "Libya",
"LI": "Liechtenstein",
"LT": "Liettua",
"LU": "Luxemburg",
"EH": "L\u00e4nsi-Sahara",
"MO": "Macao \u2013 Kiinan e.h.a.",
"MG": "Madagaskar",
"MW": "Malawi",
"MV": "Malediivit",
"MY": "Malesia",
"ML": "Mali",
"MT": "Malta",
"IM": "Mansaari",
"MA": "Marokko",
"MH": "Marshallinsaaret",
"MQ": "Martinique",
"MR": "Mauritania",
"MU": "Mauritius",
"YT": "Mayotte",
"MX": "Meksiko",
"FM": "Mikronesian liittovaltio",
"MD": "Moldova",
"MC": "Monaco",
"MN": "Mongolia",
"ME": "Montenegro",
"MS": "Montserrat",
"MZ": "Mosambik",
"MM": "Myanmar (Burma)",
"NA": "Namibia",
"NR": "Nauru",
"NP": "Nepal",
"NI": "Nicaragua",
"NE": "Niger",
"NG": "Nigeria",
"NU": "Niue",
"NF": "Norfolkinsaari",
"NO": "Norja",
"CI": "Norsunluurannikko",
"OM": "Oman",
"PK": "Pakistan",
"PW": "Palau",
"PS": "Palestiinalaisalueet",
"PA": "Panama",
"PG": "Papua-Uusi-Guinea",
"PY": "Paraguay",
"PE": "Peru",
"PN": "Pitcairn",
"KP": "Pohjois-Korea",
"MK": "Pohjois-Makedonia",
"MP": "Pohjois-Mariaanit",
"PT": "Portugali",
"PR": "Puerto Rico",
"PL": "Puola",
"GQ": "P\u00e4iv\u00e4ntasaajan Guinea",
"QA": "Qatar",
"FR": "Ranska",
"TF": "Ranskan etel\u00e4iset alueet",
"GF": "Ranskan Guayana",
"PF": "Ranskan Polynesia",
"RE": "R\u00e9union",
"RO": "Romania",
"RW": "Ruanda",
"SE": "Ruotsi",
"SH": "Saint Helena",
"KN": "Saint Kitts ja Nevis",
"LC": "Saint Lucia",
"VC": "Saint Vincent ja Grenadiinit",
"BL": "Saint-Barth\u00e9lemy",
"MF": "Saint-Martin",
"PM": "Saint-Pierre ja Miquelon",
"DE": "Saksa",
"SB": "Salomonsaaret",
"ZM": "Sambia",
"WS": "Samoa",
"SM": "San Marino",
"ST": "S\u00e3o Tom\u00e9 ja Pr\u00edncipe",
"SA": "Saudi-Arabia",
"SN": "Senegal",
"RS": "Serbia",
"SC": "Seychellit",
"SL": "Sierra Leone",
"SG": "Singapore",
"SX": "Sint Maarten",
"SK": "Slovakia",
"SI": "Slovenia",
"SO": "Somalia",
"LK": "Sri Lanka",
"SD": "Sudan",
"FI": "Suomi",
"SR": "Suriname",
"CH": "Sveitsi",
"SZ": "Swazimaa",
"SY": "Syyria",
"TJ": "Tad\u017eikistan",
"TW": "Taiwan",
"TZ": "Tansania",
"DK": "Tanska",
"TH": "Thaimaa",
"TG": "Togo",
"TK": "Tokelau",
"TO": "Tonga",
"TT": "Trinidad ja Tobago",
"TD": "T\u0161ad",
"CZ": "T\u0161ekki",
"TN": "Tunisia",
"TR": "Turkki",
"TM": "Turkmenistan",
"TC": "Turks- ja Caicossaaret",
"TV": "Tuvalu",
"UG": "Uganda",
"UA": "Ukraina",
"HU": "Unkari",
"UY": "Uruguay",
"NC": "Uusi-Kaledonia",
"NZ": "Uusi-Seelanti",
"UZ": "Uzbekistan",
"BY": "Valko-Ven\u00e4j\u00e4",
"VU": "Vanuatu",
"VA": "Vatikaani",
"VE": "Venezuela",
"RU": "Ven\u00e4j\u00e4",
"VN": "Vietnam",
"EE": "Viro",
"WF": "Wallis ja Futuna",
"US": "Yhdysvallat",
"UM": "Yhdysvaltain erillissaaret",
"VI": "Yhdysvaltain Neitsytsaaret",
"ZW": "Zimbabwe"
}

Some files were not shown because too many files have changed in this diff Show more