wagtail-cookie-consent 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (19) hide show
  1. wagtail_cookie_consent-0.1.0/PKG-INFO +215 -0
  2. wagtail_cookie_consent-0.1.0/README.md +182 -0
  3. wagtail_cookie_consent-0.1.0/pyproject.toml +70 -0
  4. wagtail_cookie_consent-0.1.0/pyproject.toml.orig +76 -0
  5. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/__init__.py +2 -0
  6. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/apps.py +12 -0
  7. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/banner.py +87 -0
  8. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/checks.py +39 -0
  9. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/migrations/0001_initial.py +97 -0
  10. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/migrations/__init__.py +0 -0
  11. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/models.py +105 -0
  12. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/static/wagtail_cookie_consent/js/cookie-consent.js +141 -0
  13. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/static/wagtail_cookie_consent/vendor/LICENSE +21 -0
  14. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/static/wagtail_cookie_consent/vendor/README.md +5 -0
  15. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/static/wagtail_cookie_consent/vendor/cookieconsent.css +1 -0
  16. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/static/wagtail_cookie_consent/vendor/cookieconsent.umd.js +7 -0
  17. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/templates/wagtail_cookie_consent/cookie_consent.html +4 -0
  18. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/templatetags/__init__.py +0 -0
  19. wagtail_cookie_consent-0.1.0/src/wagtail_cookie_consent/templatetags/wagtail_cookie_consent.py +31 -0
@@ -0,0 +1,215 @@
1
+ Metadata-Version: 2.4
2
+ Name: wagtail-cookie-consent
3
+ Version: 0.1.0
4
+ Summary: A cookie consent banner for Wagtail, set up in the Wagtail admin.
5
+ Author: Limitless Horizons Development, LLC
6
+ License-Expression: BSD-3-Clause
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Programming Language :: Python :: 3.15
17
+ Classifier: Framework :: Django
18
+ Classifier: Framework :: Django :: 5.2
19
+ Classifier: Framework :: Django :: 6.0
20
+ Classifier: Framework :: Django :: 6.1
21
+ Classifier: Framework :: Wagtail
22
+ Classifier: Framework :: Wagtail :: 7
23
+ Classifier: Framework :: Wagtail :: 8
24
+ Requires-Dist: django>=5.2
25
+ Requires-Dist: wagtail>=7.4
26
+ Requires-Python: >=3.11
27
+ Project-URL: Homepage, https://github.com/Limitless-Horizons/wagtail-cookie-consent
28
+ Project-URL: Repository, https://github.com/Limitless-Horizons/wagtail-cookie-consent
29
+ Project-URL: Changelog, https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/CHANGELOG.md
30
+ Project-URL: Documentation, https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/README.md
31
+ Project-URL: Issues, https://github.com/Limitless-Horizons/wagtail-cookie-consent/issues
32
+ Description-Content-Type: text/markdown
33
+
34
+ # Wagtail cookie consent
35
+
36
+ A cookie consent banner for Wagtail. Our ultimate goal is everything you need to do to set up the banner, you do through the Wagtail admin.
37
+
38
+ Claude Code was used with oversight by the maintainer.
39
+
40
+ ## Summary of Purpose
41
+
42
+ “Wagtail cookie consent” adds a cookie consent banner to a Wagtail site, and tells the rest of the page what each visitor chose. Who sees the banner, which categories it asks about and what it says are set in the admin UI.
43
+
44
+ The banner is [vanilla-cookieconsent](https://github.com/orestbida/cookieconsent), which ships inside the package, so nothing loads from a third party.
45
+
46
+ It doesn't block or load other scripts for you, and it doesn't delete cookies another script has set: your analytics or other code acts on the visitor's choice (see [Acting on the choice](#acting-on-the-choice)). It also doesn't decide what your site has to ask about; check the rules that apply to your site.
47
+
48
+ ## Progress so far
49
+
50
+ - A banner on a visitor's first visit, with **Accept all**, **Necessary only** and **Customize**. Accepting and refusing are equally easy, and the category switches start off.
51
+ - The choice is remembered for 182 days, in a cookie on the visitor's device.
52
+ - A **Cookie settings** link reopens the choices, so a visitor can change or withdraw them at any time.
53
+ - The choice is announced to the page when it's made, when it changes, and on each later page load.
54
+ - The banner is kept out of preview views automatically (non-configurable).
55
+ - Settings available under Settings → Cookie consent, per the table below.
56
+
57
+ ## Settings reference
58
+
59
+ Each site has its own settings, under **Settings → Cookie consent**.
60
+
61
+ | Setting | Default | What it does |
62
+ |---|---|---|
63
+ | Show the banner to | Everyone | **Everyone:** each visitor gets the banner on their first visit. **No one:** the banner and the Cookie settings link are off. |
64
+ | Categories shown: Analytics | On | When on, visitors choose whether to allow analytics cookies. |
65
+ | Categories shown: Marketing | On | When on, visitors choose whether to allow marketing cookies, such as those of embedded videos and ads. |
66
+ | Title | Blank | The banner's title. Blank means the default, “We use cookies”. |
67
+ | Text | Blank | The banner's text. Blank means the default text. |
68
+ | Privacy notice | None | A page the banner links to. |
69
+
70
+ Show only the categories your site uses. With neither checked there's nothing to ask, so the banner is off. Necessary cookies are always on, and visitors aren't asked about them.
71
+
72
+ When you change the categories shown, visitors who've already chosen are asked again.
73
+
74
+ ## Requirements
75
+
76
+ - Wagtail 7.4, 8.0 or 8.1, with the [Python and Django versions](https://docs.wagtail.org/en/stable/releases/upgrading.html#compatible-django-python-versions) each of them supports
77
+ - `wagtail.contrib.settings`, which comes with Wagtail
78
+ - `django.template.context_processors.request` in your template settings. Wagtail's project template has it. Without it, the banner doesn't load.
79
+
80
+ ## Installation
81
+
82
+ 1. Install the package:
83
+
84
+ ```sh
85
+ pip install wagtail-cookie-consent
86
+ ```
87
+
88
+ 2. Add it to `INSTALLED_APPS`, with `wagtail.contrib.settings`:
89
+
90
+ ```python
91
+ INSTALLED_APPS = [
92
+ # ...
93
+ "wagtail.contrib.settings",
94
+ "wagtail_cookie_consent",
95
+ # ...
96
+ ]
97
+ ```
98
+
99
+ 3. Create its table:
100
+
101
+ ```sh
102
+ python manage.py migrate
103
+ ```
104
+
105
+ 4. Add the banner to `<head>` in your base template, and the Cookie settings link where you want it, such as the footer:
106
+
107
+ ```django
108
+ {% load wagtail_cookie_consent %}
109
+ <!doctype html>
110
+ <html>
111
+ <head>
112
+ <meta charset="utf-8">
113
+ {% cookie_consent %}
114
+ ...
115
+ </head>
116
+ <body>
117
+ ...
118
+ <footer>{% cookie_settings_link %}</footer>
119
+ </body>
120
+ </html>
121
+ ```
122
+
123
+ 5. In the Wagtail admin, go to **Settings → Cookie consent** and choose the categories your site uses.
124
+
125
+ The banner's scripts and stylesheet are among the package's static files. On a deployed site, run `collectstatic` after you install or upgrade the package, as for any app's static files.
126
+
127
+ ## Usage
128
+
129
+ ### The Cookie settings link
130
+
131
+ `{% cookie_settings_link %}` renders a button that reopens the visitor's choices. Give it your own label and HTML attributes:
132
+
133
+ ```django
134
+ {% cookie_settings_link "Cookies" class="footer-link" %}
135
+ ```
136
+
137
+ It has to come from this tag, or carry the same `data-cc="show-preferencesModal"` attribute, so it can't be an ordinary link an editor adds in the CMS. When the banner is off, the tag renders nothing.
138
+
139
+ ### Acting on the choice
140
+
141
+ The banner announces the visitor's choice as a `wagtail-cookie-consent:change` event on `document`. Its `detail` has `true` or `false` for each category your site shows:
142
+
143
+ ```js
144
+ document.addEventListener("wagtail-cookie-consent:change", (event) => {
145
+ if (event.detail.analytics) {
146
+ // The visitor allows analytics cookies.
147
+ }
148
+ });
149
+ ```
150
+
151
+ The event is sent when the visitor chooses, when they change their choice, and on each page load once a choice is stored. Before a visitor has chosen, no event is sent.
152
+
153
+ A stored choice is announced as soon as `{% cookie_consent %}` runs, and again once the banner has loaded. Add your listener before `{% cookie_consent %}` to hear it at the earliest, and make it safe to run more than once.
154
+
155
+ [wagtail-google-tag](https://github.com/Limitless-Horizons/wagtail-google-tag) listens for this event and updates Google's Consent Mode with it. Put `{% google_tag %}` before `{% cookie_consent %}`.
156
+
157
+ ### Colors
158
+
159
+ The banner's colors come from vanilla-cookieconsent's CSS variables. Set them in your own stylesheet, loaded after `{% cookie_consent %}`:
160
+
161
+ ```css
162
+ #cc-main {
163
+ --cc-bg: #ffffff;
164
+ --cc-primary-color: #1f2937;
165
+ --cc-btn-primary-bg: #0f766e;
166
+ --cc-btn-primary-hover-bg: #115e59;
167
+ }
168
+ ```
169
+
170
+ Its [documentation](https://cookieconsent.orestbida.com/advanced/ui-customization.html) lists the variables.
171
+
172
+ ### Templates outside your base template
173
+
174
+ A template that doesn't extend your base template, such as a 404 page, needs the banner too:
175
+
176
+ ```django
177
+ {% load wagtail_cookie_consent %}
178
+ ...
179
+ {% cookie_consent %}
180
+ ```
181
+
182
+ ### Automated browsers
183
+
184
+ The banner hides itself from automated browsers and crawlers. To see it in browser tests, set this in your test settings:
185
+
186
+ ```python
187
+ WAGTAIL_COOKIE_CONSENT_HIDE_FROM_BOTS = False
188
+ ```
189
+
190
+ ### Content Security Policy
191
+
192
+ Everything loads from your own static files: there are no third-party addresses and no inline scripts.
193
+
194
+ ## Troubleshooting
195
+
196
+ - **No banner on the page:** “Show the banner to” is “No one”, no category is checked, the page is a preview, or `collectstatic` hasn't run. Run `python manage.py check` too: it warns when the request isn't in the template context.
197
+ - **No banner, though it's on:** you've already chosen. Use the Cookie settings link, or delete the `cc_cookie` cookie.
198
+ - **No banner in browser tests:** see [Automated browsers](#automated-browsers).
199
+
200
+ ## Privacy notes
201
+
202
+ The visitor's choice is stored in a cookie named `cc_cookie` on their own device, for 182 days. It's a cookie of your own site. The package doesn't read it on the server, keeps no record of choices, and sends nothing to a third party.
203
+
204
+ ## Links
205
+
206
+ - [Changelog](https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/CHANGELOG.md)
207
+ - [Contributing](https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/CONTRIBUTING.md)
208
+ - [Security policy](https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/SECURITY.md)
209
+ - [Agents](https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/AGENTS.md)
210
+
211
+ ## License
212
+
213
+ BSD-3-Clause. See [LICENSE](https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/LICENSE).
214
+
215
+ vanilla-cookieconsent is included under the MIT license. Its license is in the package, next to its files.
@@ -0,0 +1,182 @@
1
+ # Wagtail cookie consent
2
+
3
+ A cookie consent banner for Wagtail. Our ultimate goal is everything you need to do to set up the banner, you do through the Wagtail admin.
4
+
5
+ Claude Code was used with oversight by the maintainer.
6
+
7
+ ## Summary of Purpose
8
+
9
+ “Wagtail cookie consent” adds a cookie consent banner to a Wagtail site, and tells the rest of the page what each visitor chose. Who sees the banner, which categories it asks about and what it says are set in the admin UI.
10
+
11
+ The banner is [vanilla-cookieconsent](https://github.com/orestbida/cookieconsent), which ships inside the package, so nothing loads from a third party.
12
+
13
+ It doesn't block or load other scripts for you, and it doesn't delete cookies another script has set: your analytics or other code acts on the visitor's choice (see [Acting on the choice](#acting-on-the-choice)). It also doesn't decide what your site has to ask about; check the rules that apply to your site.
14
+
15
+ ## Progress so far
16
+
17
+ - A banner on a visitor's first visit, with **Accept all**, **Necessary only** and **Customize**. Accepting and refusing are equally easy, and the category switches start off.
18
+ - The choice is remembered for 182 days, in a cookie on the visitor's device.
19
+ - A **Cookie settings** link reopens the choices, so a visitor can change or withdraw them at any time.
20
+ - The choice is announced to the page when it's made, when it changes, and on each later page load.
21
+ - The banner is kept out of preview views automatically (non-configurable).
22
+ - Settings available under Settings → Cookie consent, per the table below.
23
+
24
+ ## Settings reference
25
+
26
+ Each site has its own settings, under **Settings → Cookie consent**.
27
+
28
+ | Setting | Default | What it does |
29
+ |---|---|---|
30
+ | Show the banner to | Everyone | **Everyone:** each visitor gets the banner on their first visit. **No one:** the banner and the Cookie settings link are off. |
31
+ | Categories shown: Analytics | On | When on, visitors choose whether to allow analytics cookies. |
32
+ | Categories shown: Marketing | On | When on, visitors choose whether to allow marketing cookies, such as those of embedded videos and ads. |
33
+ | Title | Blank | The banner's title. Blank means the default, “We use cookies”. |
34
+ | Text | Blank | The banner's text. Blank means the default text. |
35
+ | Privacy notice | None | A page the banner links to. |
36
+
37
+ Show only the categories your site uses. With neither checked there's nothing to ask, so the banner is off. Necessary cookies are always on, and visitors aren't asked about them.
38
+
39
+ When you change the categories shown, visitors who've already chosen are asked again.
40
+
41
+ ## Requirements
42
+
43
+ - Wagtail 7.4, 8.0 or 8.1, with the [Python and Django versions](https://docs.wagtail.org/en/stable/releases/upgrading.html#compatible-django-python-versions) each of them supports
44
+ - `wagtail.contrib.settings`, which comes with Wagtail
45
+ - `django.template.context_processors.request` in your template settings. Wagtail's project template has it. Without it, the banner doesn't load.
46
+
47
+ ## Installation
48
+
49
+ 1. Install the package:
50
+
51
+ ```sh
52
+ pip install wagtail-cookie-consent
53
+ ```
54
+
55
+ 2. Add it to `INSTALLED_APPS`, with `wagtail.contrib.settings`:
56
+
57
+ ```python
58
+ INSTALLED_APPS = [
59
+ # ...
60
+ "wagtail.contrib.settings",
61
+ "wagtail_cookie_consent",
62
+ # ...
63
+ ]
64
+ ```
65
+
66
+ 3. Create its table:
67
+
68
+ ```sh
69
+ python manage.py migrate
70
+ ```
71
+
72
+ 4. Add the banner to `<head>` in your base template, and the Cookie settings link where you want it, such as the footer:
73
+
74
+ ```django
75
+ {% load wagtail_cookie_consent %}
76
+ <!doctype html>
77
+ <html>
78
+ <head>
79
+ <meta charset="utf-8">
80
+ {% cookie_consent %}
81
+ ...
82
+ </head>
83
+ <body>
84
+ ...
85
+ <footer>{% cookie_settings_link %}</footer>
86
+ </body>
87
+ </html>
88
+ ```
89
+
90
+ 5. In the Wagtail admin, go to **Settings → Cookie consent** and choose the categories your site uses.
91
+
92
+ The banner's scripts and stylesheet are among the package's static files. On a deployed site, run `collectstatic` after you install or upgrade the package, as for any app's static files.
93
+
94
+ ## Usage
95
+
96
+ ### The Cookie settings link
97
+
98
+ `{% cookie_settings_link %}` renders a button that reopens the visitor's choices. Give it your own label and HTML attributes:
99
+
100
+ ```django
101
+ {% cookie_settings_link "Cookies" class="footer-link" %}
102
+ ```
103
+
104
+ It has to come from this tag, or carry the same `data-cc="show-preferencesModal"` attribute, so it can't be an ordinary link an editor adds in the CMS. When the banner is off, the tag renders nothing.
105
+
106
+ ### Acting on the choice
107
+
108
+ The banner announces the visitor's choice as a `wagtail-cookie-consent:change` event on `document`. Its `detail` has `true` or `false` for each category your site shows:
109
+
110
+ ```js
111
+ document.addEventListener("wagtail-cookie-consent:change", (event) => {
112
+ if (event.detail.analytics) {
113
+ // The visitor allows analytics cookies.
114
+ }
115
+ });
116
+ ```
117
+
118
+ The event is sent when the visitor chooses, when they change their choice, and on each page load once a choice is stored. Before a visitor has chosen, no event is sent.
119
+
120
+ A stored choice is announced as soon as `{% cookie_consent %}` runs, and again once the banner has loaded. Add your listener before `{% cookie_consent %}` to hear it at the earliest, and make it safe to run more than once.
121
+
122
+ [wagtail-google-tag](https://github.com/Limitless-Horizons/wagtail-google-tag) listens for this event and updates Google's Consent Mode with it. Put `{% google_tag %}` before `{% cookie_consent %}`.
123
+
124
+ ### Colors
125
+
126
+ The banner's colors come from vanilla-cookieconsent's CSS variables. Set them in your own stylesheet, loaded after `{% cookie_consent %}`:
127
+
128
+ ```css
129
+ #cc-main {
130
+ --cc-bg: #ffffff;
131
+ --cc-primary-color: #1f2937;
132
+ --cc-btn-primary-bg: #0f766e;
133
+ --cc-btn-primary-hover-bg: #115e59;
134
+ }
135
+ ```
136
+
137
+ Its [documentation](https://cookieconsent.orestbida.com/advanced/ui-customization.html) lists the variables.
138
+
139
+ ### Templates outside your base template
140
+
141
+ A template that doesn't extend your base template, such as a 404 page, needs the banner too:
142
+
143
+ ```django
144
+ {% load wagtail_cookie_consent %}
145
+ ...
146
+ {% cookie_consent %}
147
+ ```
148
+
149
+ ### Automated browsers
150
+
151
+ The banner hides itself from automated browsers and crawlers. To see it in browser tests, set this in your test settings:
152
+
153
+ ```python
154
+ WAGTAIL_COOKIE_CONSENT_HIDE_FROM_BOTS = False
155
+ ```
156
+
157
+ ### Content Security Policy
158
+
159
+ Everything loads from your own static files: there are no third-party addresses and no inline scripts.
160
+
161
+ ## Troubleshooting
162
+
163
+ - **No banner on the page:** “Show the banner to” is “No one”, no category is checked, the page is a preview, or `collectstatic` hasn't run. Run `python manage.py check` too: it warns when the request isn't in the template context.
164
+ - **No banner, though it's on:** you've already chosen. Use the Cookie settings link, or delete the `cc_cookie` cookie.
165
+ - **No banner in browser tests:** see [Automated browsers](#automated-browsers).
166
+
167
+ ## Privacy notes
168
+
169
+ The visitor's choice is stored in a cookie named `cc_cookie` on their own device, for 182 days. It's a cookie of your own site. The package doesn't read it on the server, keeps no record of choices, and sends nothing to a third party.
170
+
171
+ ## Links
172
+
173
+ - [Changelog](https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/CHANGELOG.md)
174
+ - [Contributing](https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/CONTRIBUTING.md)
175
+ - [Security policy](https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/SECURITY.md)
176
+ - [Agents](https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/AGENTS.md)
177
+
178
+ ## License
179
+
180
+ BSD-3-Clause. See [LICENSE](https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/LICENSE).
181
+
182
+ vanilla-cookieconsent is included under the MIT license. Its license is in the package, next to its files.
@@ -0,0 +1,70 @@
1
+ [project]
2
+ name = "wagtail-cookie-consent"
3
+ version = "0.1.0"
4
+ description = "A cookie consent banner for Wagtail, set up in the Wagtail admin."
5
+ readme = "README.md"
6
+ license = "BSD-3-Clause"
7
+ classifiers = [
8
+ "Development Status :: 3 - Alpha",
9
+ "Intended Audience :: Developers",
10
+ "Operating System :: OS Independent",
11
+ "Programming Language :: Python",
12
+ "Programming Language :: Python :: 3",
13
+ "Programming Language :: Python :: 3.11",
14
+ "Programming Language :: Python :: 3.12",
15
+ "Programming Language :: Python :: 3.13",
16
+ "Programming Language :: Python :: 3.14",
17
+ "Programming Language :: Python :: 3.15",
18
+ "Framework :: Django",
19
+ "Framework :: Django :: 5.2",
20
+ "Framework :: Django :: 6.0",
21
+ "Framework :: Django :: 6.1",
22
+ "Framework :: Wagtail",
23
+ "Framework :: Wagtail :: 7",
24
+ "Framework :: Wagtail :: 8",
25
+ ]
26
+ requires-python = ">=3.11"
27
+ dependencies = [
28
+ "django>=5.2",
29
+ "wagtail>=7.4",
30
+ ]
31
+
32
+ [[project.authors]]
33
+ name = "Limitless Horizons Development, LLC"
34
+
35
+ [project.urls]
36
+ Homepage = "https://github.com/Limitless-Horizons/wagtail-cookie-consent"
37
+ Repository = "https://github.com/Limitless-Horizons/wagtail-cookie-consent"
38
+ Changelog = "https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/CHANGELOG.md"
39
+ Documentation = "https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/README.md"
40
+ Issues = "https://github.com/Limitless-Horizons/wagtail-cookie-consent/issues"
41
+
42
+ [dependency-groups]
43
+ dev = [
44
+ "dj-database-url>=3.1.2",
45
+ "pytest>=8.1.1",
46
+ "pytest-cov>=7.1.0",
47
+ "pytest-django>=4.12.0",
48
+ "ruff>=0.15.9",
49
+ ]
50
+
51
+ [build-system]
52
+ requires = ["uv_build>=0.12.6,<0.13"]
53
+ build-backend = "uv_build"
54
+
55
+ [tool.uv.build-backend]
56
+ module-name = "wagtail_cookie_consent"
57
+ source-exclude = [
58
+ "wagtail_cookie_consent/static_src",
59
+ "wagtail_cookie_consent/test",
60
+ "testmanage.py",
61
+ ".*",
62
+ "prettier.config.js",
63
+ "*.json",
64
+ "*.ini",
65
+ "*.yml",
66
+ ]
67
+
68
+ [tool.pytest.ini_options]
69
+ DJANGO_SETTINGS_MODULE = "wagtail_cookie_consent.test.settings"
70
+ testpaths = ["tests"]
@@ -0,0 +1,76 @@
1
+ [project]
2
+ name = "wagtail-cookie-consent"
3
+ version = "0.1.0"
4
+ description = "A cookie consent banner for Wagtail, set up in the Wagtail admin."
5
+ readme = "README.md"
6
+ license = "BSD-3-Clause"
7
+ authors = [{ name = "Limitless Horizons Development, LLC" }]
8
+ classifiers = [
9
+ # Update this based on your project's status.
10
+ # See: https://pypi.org/classifiers/
11
+ "Development Status :: 3 - Alpha",
12
+ "Intended Audience :: Developers",
13
+ "Operating System :: OS Independent",
14
+ "Programming Language :: Python",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.11",
17
+ "Programming Language :: Python :: 3.12",
18
+ "Programming Language :: Python :: 3.13",
19
+ "Programming Language :: Python :: 3.14",
20
+ "Programming Language :: Python :: 3.15",
21
+ "Framework :: Django",
22
+ "Framework :: Django :: 5.2",
23
+ "Framework :: Django :: 6.0",
24
+ "Framework :: Django :: 6.1",
25
+ "Framework :: Wagtail",
26
+ "Framework :: Wagtail :: 7",
27
+ "Framework :: Wagtail :: 8",
28
+ ]
29
+ # See: https://devguide.python.org/versions/#supported-versions
30
+ requires-python = ">=3.11"
31
+ dependencies = [
32
+ # https://www.djangoproject.com/download/#supported-versions
33
+ "django>=5.2",
34
+ # https://github.com/wagtail/wagtail/wiki/Release-schedule
35
+ # https://docs.wagtail.org/en/latest/releases/upgrading.html#compatible-django-python-versions
36
+ "wagtail>=7.4",
37
+ ]
38
+
39
+ [project.urls]
40
+ Homepage = "https://github.com/Limitless-Horizons/wagtail-cookie-consent"
41
+ Repository = "https://github.com/Limitless-Horizons/wagtail-cookie-consent"
42
+ Changelog = "https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/CHANGELOG.md"
43
+ Documentation = "https://github.com/Limitless-Horizons/wagtail-cookie-consent/blob/main/README.md"
44
+ Issues = "https://github.com/Limitless-Horizons/wagtail-cookie-consent/issues"
45
+ # Add funding link if needed.
46
+ # Funding = "https://github.com/Limitless-Horizons/wagtail-cookie-consent"
47
+
48
+ [dependency-groups]
49
+ dev = [
50
+ "dj-database-url>=3.1.2",
51
+ "pytest>=8.1.1",
52
+ "pytest-cov>=7.1.0",
53
+ "pytest-django>=4.12.0",
54
+ "ruff>=0.15.9",
55
+ ]
56
+
57
+ [build-system]
58
+ requires = ["uv_build>=0.12.6,<0.13"]
59
+ build-backend = "uv_build"
60
+
61
+ [tool.uv.build-backend]
62
+ module-name = "wagtail_cookie_consent"
63
+ source-exclude = [
64
+ "wagtail_cookie_consent/static_src",
65
+ "wagtail_cookie_consent/test",
66
+ "testmanage.py",
67
+ ".*",
68
+ "prettier.config.js",
69
+ "*.json",
70
+ "*.ini",
71
+ "*.yml",
72
+ ]
73
+
74
+ [tool.pytest.ini_options]
75
+ DJANGO_SETTINGS_MODULE = "wagtail_cookie_consent.test.settings"
76
+ testpaths = ["tests"]
@@ -0,0 +1,2 @@
1
+ VERSION = (0, 1, 0)
2
+ __version__ = ".".join(map(str, VERSION))
@@ -0,0 +1,12 @@
1
+ from django.apps import AppConfig
2
+ from django.utils.translation import gettext_lazy as _
3
+
4
+
5
+ class WagtailCookieConsentAppConfig(AppConfig):
6
+ label = "wagtail_cookie_consent"
7
+ name = "wagtail_cookie_consent"
8
+ verbose_name = _("Cookie consent")
9
+ default_auto_field = "django.db.models.BigAutoField"
10
+
11
+ def ready(self):
12
+ from . import checks # noqa: F401
@@ -0,0 +1,87 @@
1
+ """
2
+ What the {% cookie_consent %} template tag renders: whether the banner is on
3
+ for this request, and the configuration the browser script gets.
4
+ """
5
+
6
+ from django.conf import settings
7
+ from django.utils.translation import gettext as _
8
+
9
+ from .models import CookieConsentSettings
10
+
11
+
12
+ def get_settings(request):
13
+ """This site's settings, or the defaults when the request has no site."""
14
+ try:
15
+ return CookieConsentSettings.for_request(request)
16
+ except CookieConsentSettings.DoesNotExist:
17
+ return CookieConsentSettings()
18
+
19
+
20
+ def banner_settings(context):
21
+ """This site's settings when the banner is on for this request, or None:
22
+ no request, a preview, "No one", or no category to ask about."""
23
+ request = context.get("request")
24
+ if request is None or getattr(request, "is_preview", False):
25
+ return None
26
+ site_settings = get_settings(request)
27
+ return site_settings if site_settings.banner_is_on() else None
28
+
29
+
30
+ def wording(site_settings):
31
+ """The banner's text. The title and text come from the admin when they're
32
+ set there; everything else is translatable default wording."""
33
+ return {
34
+ "title": site_settings.title or _("We use cookies"),
35
+ "description": site_settings.text
36
+ or _(
37
+ "Some cookies are needed for this site to work. With your "
38
+ "permission, we'd also like to use optional cookies. You can change "
39
+ "your choice at any time under Cookie settings."
40
+ ),
41
+ "acceptAll": _("Accept all"),
42
+ "necessaryOnly": _("Necessary only"),
43
+ "customize": _("Customize"),
44
+ "settingsTitle": _("Cookie settings"),
45
+ "save": _("Save my choices"),
46
+ "close": _("Close"),
47
+ "necessaryTitle": _("Necessary"),
48
+ "necessaryText": _(
49
+ "Needed for the site to work, such as keeping you signed in and "
50
+ "protecting forms. They're always on."
51
+ ),
52
+ "analyticsTitle": _("Analytics"),
53
+ "analyticsText": _(
54
+ "Help us understand how the site is used, so we can improve it."
55
+ ),
56
+ "marketingTitle": _("Marketing"),
57
+ "marketingText": _(
58
+ "Used by embedded content, such as videos, and by advertising."
59
+ ),
60
+ }
61
+
62
+
63
+ def privacy_link(site_settings, request):
64
+ page = site_settings.privacy_page
65
+ if page is None:
66
+ return None
67
+ # On a site in several languages, the page in the visitor's language.
68
+ page = page.localized
69
+ if not page.live:
70
+ return None
71
+ return {"url": page.get_url(request), "label": page.title}
72
+
73
+
74
+ def banner_config(context):
75
+ """The browser script's configuration, or None when the banner is off."""
76
+ site_settings = banner_settings(context)
77
+ if site_settings is None:
78
+ return None
79
+ return {
80
+ "categories": site_settings.categories(),
81
+ "revision": site_settings.revision(),
82
+ "text": wording(site_settings),
83
+ "privacy": privacy_link(site_settings, context["request"]),
84
+ "hideFromBots": getattr(
85
+ settings, "WAGTAIL_COOKIE_CONSENT_HIDE_FROM_BOTS", True
86
+ ),
87
+ }
@@ -0,0 +1,39 @@
1
+ from django.apps import apps
2
+ from django.core.checks import Error, Warning, register
3
+ from django.template import engines
4
+ from django.template.backends.django import DjangoTemplates
5
+
6
+
7
+ @register()
8
+ def settings_app_installed(app_configs, **kwargs):
9
+ if apps.is_installed("wagtail.contrib.settings"):
10
+ return []
11
+ return [
12
+ Error(
13
+ "wagtail_cookie_consent needs wagtail.contrib.settings.",
14
+ hint='Add "wagtail.contrib.settings" to INSTALLED_APPS.',
15
+ id="wagtail_cookie_consent.E001",
16
+ )
17
+ ]
18
+
19
+
20
+ @register()
21
+ def request_context_processor_enabled(app_configs, **kwargs):
22
+ """Without the request in the template context, the banner doesn't load."""
23
+ django_engines = [
24
+ engine for engine in engines.all() if isinstance(engine, DjangoTemplates)
25
+ ]
26
+ if not django_engines or any(
27
+ "django.template.context_processors.request" in engine.engine.context_processors
28
+ for engine in django_engines
29
+ ):
30
+ return []
31
+ return [
32
+ Warning(
33
+ "wagtail_cookie_consent needs the request in the template context, "
34
+ "or the banner doesn't load.",
35
+ hint='Add "django.template.context_processors.request" to the '
36
+ "context_processors of your TEMPLATES setting.",
37
+ id="wagtail_cookie_consent.W001",
38
+ )
39
+ ]
@@ -0,0 +1,97 @@
1
+ # Generated by Django 5.2 on 2026-11-11 17:06
2
+
3
+ import django.db.models.deletion
4
+
5
+ from django.db import migrations, models
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+ initial = True
10
+
11
+ dependencies = [
12
+ ("wagtailcore", "0097_baselogentry_uuid_action_timestamp_indexes"),
13
+ ]
14
+
15
+ operations = [
16
+ migrations.CreateModel(
17
+ name="CookieConsentSettings",
18
+ fields=[
19
+ (
20
+ "id",
21
+ models.BigAutoField(
22
+ auto_created=True,
23
+ primary_key=True,
24
+ serialize=False,
25
+ verbose_name="ID",
26
+ ),
27
+ ),
28
+ (
29
+ "show_to",
30
+ models.CharField(
31
+ choices=[("everyone", "Everyone"), ("no_one", "No one")],
32
+ default="everyone",
33
+ help_text="Everyone: each visitor gets the banner on their first visit. No one: the banner and the Cookie settings link are off.",
34
+ max_length=20,
35
+ verbose_name="show the banner to",
36
+ ),
37
+ ),
38
+ (
39
+ "show_analytics",
40
+ models.BooleanField(
41
+ default=True,
42
+ help_text="When this is on, visitors choose whether to allow analytics cookies.",
43
+ verbose_name="analytics",
44
+ ),
45
+ ),
46
+ (
47
+ "show_marketing",
48
+ models.BooleanField(
49
+ default=True,
50
+ help_text="When this is on, visitors choose whether to allow marketing cookies, such as those of embedded videos and ads.",
51
+ verbose_name="marketing",
52
+ ),
53
+ ),
54
+ (
55
+ "title",
56
+ models.CharField(
57
+ blank=True,
58
+ help_text='Leave it blank for the default: "We use cookies".',
59
+ max_length=255,
60
+ verbose_name="title",
61
+ ),
62
+ ),
63
+ (
64
+ "text",
65
+ models.TextField(
66
+ blank=True,
67
+ help_text="Leave it blank for the default text.",
68
+ verbose_name="text",
69
+ ),
70
+ ),
71
+ (
72
+ "privacy_page",
73
+ models.ForeignKey(
74
+ blank=True,
75
+ help_text="The banner links to this page.",
76
+ null=True,
77
+ on_delete=django.db.models.deletion.SET_NULL,
78
+ related_name="+",
79
+ to="wagtailcore.page",
80
+ verbose_name="privacy notice",
81
+ ),
82
+ ),
83
+ (
84
+ "site",
85
+ models.OneToOneField(
86
+ editable=False,
87
+ on_delete=django.db.models.deletion.CASCADE,
88
+ to="wagtailcore.site",
89
+ ),
90
+ ),
91
+ ],
92
+ options={
93
+ "verbose_name": "Cookie consent",
94
+ "verbose_name_plural": "Cookie consent",
95
+ },
96
+ ),
97
+ ]
@@ -0,0 +1,105 @@
1
+ from django.db import models
2
+ from django.utils.translation import gettext_lazy as _
3
+ from wagtail.admin.panels import FieldPanel, MultiFieldPanel
4
+ from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
5
+
6
+
7
+ @register_setting(icon="lock")
8
+ class CookieConsentSettings(BaseSiteSetting):
9
+ class ShowTo(models.TextChoices):
10
+ EVERYONE = "everyone", _("Everyone")
11
+ NO_ONE = "no_one", _("No one")
12
+
13
+ show_to = models.CharField(
14
+ _("show the banner to"),
15
+ max_length=20,
16
+ choices=ShowTo.choices,
17
+ default=ShowTo.EVERYONE,
18
+ help_text=_(
19
+ "Everyone: each visitor gets the banner on their first visit. "
20
+ "No one: the banner and the Cookie settings link are off."
21
+ ),
22
+ )
23
+ show_analytics = models.BooleanField(
24
+ _("analytics"),
25
+ default=True,
26
+ help_text=_(
27
+ "When this is on, visitors choose whether to allow analytics cookies."
28
+ ),
29
+ )
30
+ show_marketing = models.BooleanField(
31
+ _("marketing"),
32
+ default=True,
33
+ help_text=_(
34
+ "When this is on, visitors choose whether to allow marketing cookies, "
35
+ "such as those of embedded videos and ads."
36
+ ),
37
+ )
38
+ title = models.CharField(
39
+ _("title"),
40
+ max_length=255,
41
+ blank=True,
42
+ help_text=_('Leave it blank for the default: "We use cookies".'),
43
+ )
44
+ text = models.TextField(
45
+ _("text"),
46
+ blank=True,
47
+ help_text=_("Leave it blank for the default text."),
48
+ )
49
+ privacy_page = models.ForeignKey(
50
+ "wagtailcore.Page",
51
+ verbose_name=_("privacy notice"),
52
+ null=True,
53
+ blank=True,
54
+ on_delete=models.SET_NULL,
55
+ related_name="+",
56
+ help_text=_("The banner links to this page."),
57
+ )
58
+
59
+ select_related = ["privacy_page"]
60
+
61
+ panels = [
62
+ FieldPanel("show_to"),
63
+ MultiFieldPanel(
64
+ [
65
+ FieldPanel("show_analytics"),
66
+ FieldPanel("show_marketing"),
67
+ ],
68
+ heading=_("Categories shown"),
69
+ help_text=_(
70
+ "Necessary cookies are always on, and visitors aren't asked about "
71
+ "them. With neither category checked there's nothing to ask, so "
72
+ "the banner is off."
73
+ ),
74
+ ),
75
+ MultiFieldPanel(
76
+ [
77
+ FieldPanel("title"),
78
+ FieldPanel("text"),
79
+ FieldPanel("privacy_page"),
80
+ ],
81
+ heading=_("Wording"),
82
+ ),
83
+ ]
84
+
85
+ class Meta:
86
+ verbose_name = _("Cookie consent")
87
+ verbose_name_plural = _("Cookie consent")
88
+
89
+ def categories(self):
90
+ """The categories visitors are asked about, in the banner's order."""
91
+ shown = []
92
+ if self.show_analytics:
93
+ shown.append("analytics")
94
+ if self.show_marketing:
95
+ shown.append("marketing")
96
+ return shown
97
+
98
+ def revision(self):
99
+ """A number that changes when the categories shown change. A visitor's
100
+ stored choice counts only for the revision it was made under, so
101
+ they're asked again when what's asked changes."""
102
+ return (1 if self.show_analytics else 0) + (2 if self.show_marketing else 0)
103
+
104
+ def banner_is_on(self):
105
+ return self.show_to == self.ShowTo.EVERYONE and bool(self.categories())
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Wagtail cookie consent: runs the vanilla-cookieconsent banner with the
3
+ * site's settings, and announces the visitor's choice as a
4
+ * "wagtail-cookie-consent:change" event on document. The event's detail has
5
+ * one true or false value for each category the site shows, for example
6
+ * { analytics: true, marketing: false }.
7
+ *
8
+ * The choice is announced when the visitor makes or changes it, and on each
9
+ * page load once one is stored. A stored choice is announced as soon as this
10
+ * script runs, before the banner library has loaded, so that scripts waiting
11
+ * for it (such as an analytics tag) hear it early.
12
+ */
13
+ (() => {
14
+ const configElement = document.getElementById(
15
+ 'wagtail-cookie-consent-config',
16
+ );
17
+ if (!configElement || configElement.dataset.started) return;
18
+ configElement.dataset.started = 'true';
19
+
20
+ const config = JSON.parse(configElement.textContent);
21
+ const text = config.text;
22
+
23
+ // The banner library's own cookie.
24
+ const COOKIE_NAME = 'cc_cookie';
25
+
26
+ const announce = (accepted) => {
27
+ const detail = {};
28
+ config.categories.forEach((category) => {
29
+ detail[category] = accepted.includes(category);
30
+ });
31
+ document.dispatchEvent(
32
+ new CustomEvent('wagtail-cookie-consent:change', { detail }),
33
+ );
34
+ };
35
+
36
+ /**
37
+ * The categories in a stored choice, or null when there's none. A choice
38
+ * made under another revision (the site has since changed the categories it
39
+ * shows) doesn't count: the banner asks again.
40
+ */
41
+ const storedCategories = () => {
42
+ const match = document.cookie.match(
43
+ new RegExp(`(?:^|;\\s*)${COOKIE_NAME}=([^;]+)`),
44
+ );
45
+ if (!match) return null;
46
+ try {
47
+ const stored = JSON.parse(decodeURIComponent(match[1]));
48
+ return stored.consentId &&
49
+ stored.revision === config.revision &&
50
+ Array.isArray(stored.categories)
51
+ ? stored.categories
52
+ : null;
53
+ } catch {
54
+ return null;
55
+ }
56
+ };
57
+
58
+ const stored = storedCategories();
59
+ if (stored) announce(stored);
60
+
61
+ // The banner library puts its text in the page as HTML.
62
+ const escape = (value) =>
63
+ String(value).replace(
64
+ /[&<>"']/g,
65
+ (character) =>
66
+ ({
67
+ '&': '&amp;',
68
+ '<': '&lt;',
69
+ '>': '&gt;',
70
+ '"': '&quot;',
71
+ "'": '&#39;',
72
+ })[character],
73
+ );
74
+
75
+ const privacyLink = config.privacy
76
+ ? `<a href="${escape(config.privacy.url)}">${escape(config.privacy.label)}</a>`
77
+ : '';
78
+
79
+ const categories = { necessary: { enabled: true, readOnly: true } };
80
+ const sections = [
81
+ {
82
+ description: [escape(text.description), privacyLink]
83
+ .filter(Boolean)
84
+ .join(' '),
85
+ },
86
+ {
87
+ title: escape(text.necessaryTitle),
88
+ description: escape(text.necessaryText),
89
+ linkedCategory: 'necessary',
90
+ },
91
+ ];
92
+ config.categories.forEach((category) => {
93
+ categories[category] = {};
94
+ sections.push({
95
+ title: escape(text[`${category}Title`]),
96
+ description: escape(text[`${category}Text`]),
97
+ linkedCategory: category,
98
+ });
99
+ });
100
+
101
+ const run = () => {
102
+ if (!window.CookieConsent) return;
103
+ window.CookieConsent.run({
104
+ hideFromBots: config.hideFromBots,
105
+ revision: config.revision,
106
+ categories,
107
+ onConsent: ({ cookie }) => announce(cookie.categories),
108
+ onChange: ({ cookie }) => announce(cookie.categories),
109
+ language: {
110
+ default: 'en',
111
+ translations: {
112
+ en: {
113
+ consentModal: {
114
+ title: escape(text.title),
115
+ description: escape(text.description),
116
+ acceptAllBtn: escape(text.acceptAll),
117
+ acceptNecessaryBtn: escape(text.necessaryOnly),
118
+ showPreferencesBtn: escape(text.customize),
119
+ footer: privacyLink,
120
+ },
121
+ preferencesModal: {
122
+ title: escape(text.settingsTitle),
123
+ acceptAllBtn: escape(text.acceptAll),
124
+ acceptNecessaryBtn: escape(text.necessaryOnly),
125
+ savePreferencesBtn: escape(text.save),
126
+ closeIconLabel: escape(text.close),
127
+ sections,
128
+ },
129
+ },
130
+ },
131
+ },
132
+ });
133
+ };
134
+
135
+ // The library's script is deferred, so it's there by DOMContentLoaded.
136
+ if (document.readyState === 'loading') {
137
+ document.addEventListener('DOMContentLoaded', run);
138
+ } else {
139
+ run();
140
+ }
141
+ })();
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020-2025 Orest Bida
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,5 @@
1
+ # vanilla-cookieconsent
2
+
3
+ `cookieconsent.umd.js` and `cookieconsent.css` are the unmodified `dist` files of
4
+ [vanilla-cookieconsent](https://github.com/orestbida/cookieconsent) 3.3.0, from its
5
+ npm package. They're under the MIT license in `LICENSE`, next to this file.
@@ -0,0 +1 @@
1
+ #cc-main{background:transparent;color:var(--cc-primary-color);font-family:var(--cc-font-family);font-size:16px;font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;position:relative;line-height:1.15;-webkit-text-size-adjust:100%;z-index:var(--cc-z-index);position:fixed}#cc-main :after,#cc-main :before,#cc-main a,#cc-main button,#cc-main div,#cc-main h2,#cc-main input,#cc-main label,#cc-main p,#cc-main span{all:unset;box-sizing:border-box}#cc-main .pm__badge,#cc-main button{all:initial;box-sizing:border-box;color:unset;visibility:unset}#cc-main .pm__badge,#cc-main a,#cc-main button,#cc-main input{font-family:inherit;font-size:100%;line-height:normal;margin:0;outline:revert;outline-offset:2px;cursor:pointer;overflow:hidden;-webkit-appearance:none;appearance:none}#cc-main svg{display:block;width:auto;height:auto;overflow:hidden;fill:none;width:100%}#cc-main path{fill:inherit;stroke:inherit;stroke-width:inherit}#cc-main caption,#cc-main table,#cc-main tbody,#cc-main td,#cc-main th,#cc-main thead,#cc-main tr{all:revert;font-family:inherit;font-weight:inherit;color:inherit;font-size:inherit}:host,:root{--cc-font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--cc-modal-border-radius:.5rem;--cc-btn-border-radius:.4rem;--cc-modal-transition-duration:.25s;--cc-link-color:var(--cc-btn-primary-bg);--cc-modal-margin:1rem;--cc-z-index:2147483647;--cc-bg:#fff;--cc-primary-color:#2c2f31;--cc-secondary-color:#5e6266;--cc-btn-primary-bg:#30363c;--cc-btn-primary-color:#fff;--cc-btn-primary-border-color:var(--cc-btn-primary-bg);--cc-btn-primary-hover-bg:#000;--cc-btn-primary-hover-color:#fff;--cc-btn-primary-hover-border-color:var(--cc-btn-primary-hover-bg);--cc-btn-secondary-bg:#eaeff2;--cc-btn-secondary-color:var(--cc-primary-color);--cc-btn-secondary-border-color:var(--cc-btn-secondary-bg);--cc-btn-secondary-hover-bg:#d4dae0;--cc-btn-secondary-hover-color:#000;--cc-btn-secondary-hover-border-color:#d4dae0;--cc-separator-border-color:#f0f4f7;--cc-toggle-on-bg:var(--cc-btn-primary-bg);--cc-toggle-off-bg:#667481;--cc-toggle-on-knob-bg:#fff;--cc-toggle-off-knob-bg:var(--cc-toggle-on-knob-bg);--cc-toggle-enabled-icon-color:var(--cc-bg);--cc-toggle-disabled-icon-color:var(--cc-bg);--cc-toggle-readonly-bg:#d5dee2;--cc-toggle-readonly-knob-bg:#fff;--cc-toggle-readonly-knob-icon-color:var(--cc-toggle-readonly-bg);--cc-section-category-border:var(--cc-cookie-category-block-bg);--cc-cookie-category-block-bg:#f0f4f7;--cc-cookie-category-block-border:#f0f4f7;--cc-cookie-category-block-hover-bg:#e9eff4;--cc-cookie-category-block-hover-border:#e9eff4;--cc-cookie-category-expanded-block-bg:transparent;--cc-cookie-category-expanded-block-hover-bg:#dee4e9;--cc-overlay-bg:rgba(0,0,0,.65);--cc-webkit-scrollbar-bg:var(--cc-section-category-border);--cc-webkit-scrollbar-hover-bg:var(--cc-btn-primary-hover-bg);--cc-footer-bg:var(--cc-btn-secondary-bg);--cc-footer-color:var(--cc-secondary-color);--cc-footer-border-color:#e4eaed;--cc-pm-toggle-border-radius:4em}#cc-main.cc--rtl{direction:rtl}#cc-main .cm__title,#cc-main a,#cc-main b,#cc-main em,#cc-main strong{font-weight:600}#cc-main button>span{pointer-events:none}#cc-main .cc__link,#cc-main a{font-weight:600;position:relative;background-image:linear-gradient(currentColor,currentColor);background-position:0 100%;background-repeat:no-repeat;background-size:0 1px;transition:background-size .25s,color .25s}#cc-main .cc__link:hover,#cc-main a:hover{color:var(--cc-primary-color);background-size:100% 1px}#cc-main .cc__link{color:var(--cc-link-color)}#cc-main .cm__desc,#cc-main .pm__body{scrollbar-width:thin;overscroll-behavior:auto contain}@media screen and (min-width:640px){#cc-main ::-webkit-scrollbar,#cc-main ::-webkit-scrollbar-thumb,#cc-main ::-webkit-scrollbar-track{all:revert}#cc-main ::-webkit-scrollbar-thumb{border:.25rem solid var(--cc-bg);-webkit-background-clip:padding-box;background-clip:padding-box;border-radius:1rem;background:var(--cc-toggle-readonly-bg)}#cc-main ::-webkit-scrollbar-thumb:hover{background:var(--cc-toggle-off-bg)}#cc-main ::-webkit-scrollbar{background:transparent;width:12px}}html.disable--interaction.show--consent,html.disable--interaction.show--consent body{height:auto!important;overflow:hidden!important}@media(prefers-reduced-motion){#cc-main{--cc-modal-transition-duration:0s}}.cc--darkmode{--cc-bg:#161a1c;--cc-primary-color:#ebf3f6;--cc-secondary-color:#aebbc5;--cc-btn-primary-bg:#c2d0e0;--cc-btn-primary-color:var(--cc-bg);--cc-btn-primary-border-color:var(--cc-btn-primary-bg);--cc-btn-primary-hover-bg:#98a7b6;--cc-btn-primary-hover-color:#000;--cc-btn-primary-hover-border-color:var(--cc-btn-primary-hover-bg);--cc-btn-secondary-bg:#242c31;--cc-btn-secondary-color:var(--cc-primary-color);--cc-btn-secondary-border-color:var(--cc-btn-secondary-bg);--cc-btn-secondary-hover-bg:#353d43;--cc-btn-secondary-hover-color:#fff;--cc-btn-secondary-hover-border-color:var(--cc-btn-secondary-hover-bg);--cc-separator-border-color:#222a30;--cc-toggle-on-bg:var(--cc-btn-primary-bg);--cc-toggle-off-bg:#525f6b;--cc-toggle-on-knob-bg:var(--cc-btn-primary-color);--cc-toggle-off-knob-bg:var(--cc-btn-primary-color);--cc-toggle-enabled-icon-color:var(--cc-btn-primary-color);--cc-toggle-disabled-icon-color:var(--cc-btn-primary-color);--cc-toggle-readonly-bg:#343e45;--cc-toggle-readonly-knob-bg:#5f6b72;--cc-toggle-readonly-knob-icon-color:var(--cc-toggle-readonly-bg);--cc-section-category-border:#1e2428;--cc-cookie-category-block-bg:#1e2428;--cc-cookie-category-block-border:var(--cc-section-category-border);--cc-cookie-category-block-hover-bg:#242c31;--cc-cookie-category-block-hover-border:#232a2f;--cc-cookie-category-expanded-block-bg:transparent;--cc-cookie-category-expanded-block-hover-bg:var(--cc-toggle-readonly-bg);--cc-overlay-bg:rgba(0,0,0,.65);--cc-webkit-scrollbar-bg:var(--cc-section-category-border);--cc-webkit-scrollbar-hover-bg:var(--cc-btn-primary-hover-bg);--cc-footer-bg:#0c0e0f;--cc-footer-color:var(--cc-secondary-color);--cc-footer-border-color:#060809}.cc--darkmode #cc-main{color-scheme:dark}#cc-main .cm{position:fixed;max-width:24rem;display:flex;flex-direction:column;background:var(--cc-bg);border-radius:var(--cc-modal-border-radius);z-index:1;overflow:hidden;box-shadow:0 .625em 1.875em rgba(0,0,2,.3);visibility:hidden;opacity:0;transform:translateY(1.6em)}#cc-main .cm--top{top:var(--cc-modal-margin)}#cc-main .cm--middle{top:50%;transform:translateY(calc(-50% + 1.6em))}#cc-main .cm--bottom{bottom:var(--cc-modal-margin)}#cc-main .cm--center{left:var(--cc-modal-margin);right:var(--cc-modal-margin);margin:0 auto;width:unset}#cc-main .cm--left{left:var(--cc-modal-margin);margin-right:var(--cc-modal-margin)}#cc-main .cm--right{right:var(--cc-modal-margin);margin-left:var(--cc-modal-margin)}#cc-main .cm__body{position:relative;display:flex;flex-direction:column;justify-content:space-between}#cc-main .cm__btns,#cc-main .cm__links{width:unset;padding:1rem 1.3rem}#cc-main .cm__texts{display:flex;flex-direction:column;justify-content:center;flex:1;padding:1rem 0 0}#cc-main .cm__desc,#cc-main .cm__title{padding:0 1.3rem}#cc-main .cm__title{font-size:1.05em}#cc-main .cm__title+.cm__desc{margin-top:1.1em}#cc-main .cm__desc{color:var(--cc-secondary-color);line-height:1.5;font-size:.9em;max-height:40vh;overflow-x:visible;overflow-y:auto;padding-bottom:1em}#cc-main .cm__btns{display:flex;flex-direction:column;justify-content:center;border-top:1px solid var(--cc-separator-border-color)}#cc-main .cm__btn-group{display:grid;grid-auto-columns:minmax(0,1fr)}#cc-main .cm__btn+.cm__btn,#cc-main .cm__btn-group+.cm__btn-group{margin-top:.375rem}#cc-main .cm--flip .cm__btn+.cm__btn,#cc-main .cm--flip .cm__btn-group+.cm__btn-group{margin-top:0;margin-bottom:.375rem}#cc-main .cm--inline .cm__btn+.cm__btn{margin-top:0;margin-left:.375rem}#cc-main .cm--inline.cm--flip .cm__btn+.cm__btn{margin-bottom:0;margin-left:0;margin-right:.375rem}#cc-main .cm--inline.cm--flip .cm__btn-group+.cm__btn-group{margin-right:0;margin-bottom:.375rem}#cc-main .cm--wide .cm__btn+.cm__btn,#cc-main .cm--wide .cm__btn-group+.cm__btn-group{margin-top:0;margin-left:.375rem}#cc-main .cm--wide.cm--flip .cm__btn+.cm__btn,#cc-main .cm--wide.cm--flip .cm__btn-group+.cm__btn-group{margin-bottom:0;margin-right:.375rem}#cc-main .cm--bar:not(.cm--inline) .cm__btn-group--uneven,#cc-main .cm--wide .cm__btn-group--uneven{display:flex;flex:1;justify-content:space-between}#cc-main .cm--bar:not(.cm--inline).cm--flip .cm__btn-group--uneven,#cc-main .cm--wide.cm--flip .cm__btn-group--uneven{flex-direction:row-reverse}#cc-main .cm__btn{color:var(--cc-btn-primary-color);background:var(--cc-btn-primary-bg);border:1px solid var(--cc-btn-primary-border-color);text-align:center;font-weight:600;font-size:.82em;min-height:42px;padding:.5em 1em;border-radius:var(--cc-btn-border-radius)}#cc-main .cm__btn:hover{color:var(--cc-btn-primary-hover-color);background:var(--cc-btn-primary-hover-bg);border-color:var(--cc-btn-primary-hover-border-color)}#cc-main .cm__btn--secondary{color:var(--cc-btn-secondary-color);background:var(--cc-btn-secondary-bg);border-color:var(--cc-btn-secondary-border-color)}#cc-main .cm__btn--secondary:hover{color:var(--cc-btn-secondary-hover-color);background:var(--cc-btn-secondary-hover-bg);border-color:var(--cc-btn-secondary-hover-border-color)}#cc-main .cm__btn--close{display:none;position:absolute;right:0;top:0;width:42px;height:42px;border-radius:0;border-bottom-left-radius:var(--cc-btn-border-radius);border-top:none;border-right:none;padding:0!important;min-width:auto!important;font-size:1em;overflow:hidden}#cc-main .cm__btn--close svg{stroke:var(--cc-btn-primary-color);transform:scale(.5);transition:stroke .15s}#cc-main .cm__btn--close:hover svg{stroke:var(--cc-btn-primary-hover-color)}#cc-main .cm__btn--close.cm__btn--secondary svg{stroke:var(--cc-btn-secondary-color)}#cc-main .cm__btn--close.cm__btn--secondary:hover svg{stroke:var(--cc-btn-secondary-hover-color)}#cc-main .cm__btn--close+.cm__texts .cm__title{padding-right:3rem}#cc-main .cm--bar .cm__btn-group,#cc-main .cm--box.cm--wide .cm__btn-group,#cc-main .cm--inline .cm__btn-group{grid-auto-flow:column}#cc-main .cm__footer{color:var(--cc-footer-color);background:var(--cc-footer-bg);border-top:1px solid var(--cc-footer-border-color);padding:.4em 0 .5em}#cc-main .cm__links{padding-top:0;padding-bottom:0;display:flex;flex-direction:row}#cc-main .cm__link-group{font-size:.8em;display:flex;flex-direction:row;width:100%}#cc-main .cm__link-group>*+*{margin-left:1.3rem}#cc-main .cm--flip .cm__btn:last-child{grid-row:1}#cc-main .cm--bar.cm--flip .cm__btn:last-child,#cc-main .cm--box.cm--wide.cm--flip .cm__btn:last-child,#cc-main .cm--inline.cm--flip .cm__btn:last-child{grid-column:1}#cc-main .cm--box .cm__btn--close{display:block}#cc-main .cm--box.cm--flip .cm__btns{flex-direction:column-reverse}#cc-main .cm--box.cm--wide{max-width:36em}#cc-main .cm--box.cm--wide .cm__btns{flex-direction:row;justify-content:space-between}#cc-main .cm--box.cm--wide .cm__btn{min-width:120px;padding-right:1.8em;padding-left:1.8em}#cc-main .cm--box.cm--wide.cm--flip .cm__btns{flex-direction:row-reverse}#cc-main .cm--cloud{width:unset;max-width:54em}#cc-main .cm--cloud .cm__body{flex-direction:row}#cc-main .cm--cloud .cm__texts{flex:1}#cc-main .cm--cloud .cm__desc{max-height:9.4em}#cc-main .cm--cloud .cm__btns{border-top:none;border-left:1px solid var(--cc-separator-border-color);max-width:23em}#cc-main .cm--cloud .cm__btn-group{flex-direction:column}#cc-main .cm--cloud .cm__btn{min-width:19em}#cc-main .cm--cloud.cm--flip .cm__btn-group,#cc-main .cm--cloud.cm--flip .cm__btns{flex-direction:column-reverse}#cc-main .cm--cloud.cm--inline .cm__btn-group{flex-direction:row}#cc-main .cm--cloud.cm--inline .cm__btn{min-width:10em}#cc-main .cm--cloud.cm--inline.cm--flip .cm__btn-group{flex-direction:row-reverse}#cc-main .cm--bar{max-width:unset;width:100vw;left:0;right:0;margin:0;transform:translateY(0);border-radius:0;opacity:1;--cc-modal-transition-duration:.35s}#cc-main .cm--bar.cm--top{top:0;transform:translateY(-100%)}#cc-main .cm--bar.cm--bottom{bottom:0;transform:translateY(100%)}#cc-main .cm--bar .cm__body,#cc-main .cm--bar .cm__links{max-width:55em;margin:0 auto;width:100%}#cc-main .cm--bar .cm__body{padding:.5em 0 .9em}#cc-main .cm--bar .cm__btns{border-top:none;flex-direction:row;justify-content:space-between}#cc-main .cm--bar:not(.cm--inline) .cm__btn+.cm__btn,#cc-main .cm--bar:not(.cm--inline) .cm__btn-group+.cm__btn-group{margin-top:0;margin-left:.375rem}#cc-main .cm--bar .cm__btn{min-width:120px;padding-right:2em;padding-left:2em}#cc-main .cm--bar.cm--flip:not(.cm--inline) .cm__btn+.cm__btn,#cc-main .cm--bar.cm--flip:not(.cm--inline) .cm__btn-group+.cm__btn-group{margin-bottom:0;margin-left:0;margin-right:.375rem}#cc-main .cm--bar.cm--flip .cm__btns{flex-direction:row-reverse}#cc-main .cm--bar.cm--inline .cm__body,#cc-main .cm--bar.cm--inline .cm__links{max-width:74em}#cc-main .cm--bar.cm--inline .cm__body{padding:0;flex-direction:row}#cc-main .cm--bar.cm--inline .cm__btns{flex-direction:column;justify-content:center;max-width:23em}#cc-main .cm--bar.cm--inline.cm--flip .cm__btns{flex-direction:column-reverse}#cc-main .cc--anim .cm,#cc-main .cc--anim.cm-wrapper:before{transition:opacity var(--cc-modal-transition-duration) ease,visibility var(--cc-modal-transition-duration) ease,transform var(--cc-modal-transition-duration) ease}#cc-main .cc--anim .cm__btn,#cc-main .cc--anim .cm__close{transition:background-color .15s,border-color .15s,color .15s}.disable--interaction #cc-main .cm-wrapper:before{content:"";opacity:0;visibility:hidden;position:fixed;left:0;right:0;top:0;bottom:0;z-index:0;background:var(--cc-overlay-bg)}.show--consent #cc-main .cc--anim .cm{opacity:1;visibility:visible!important;transform:translateY(0)}.show--consent #cc-main .cc--anim .cm--middle{transform:translateY(-50%)}.show--consent #cc-main .cc--anim .cm--bar{transform:translateY(0)}.show--consent #cc-main .cc--anim.cm-wrapper:before{opacity:1;visibility:visible}#cc-main.cc--rtl .cm__btn--close{right:unset;left:0;border-bottom-left-radius:unset;border-bottom-right-radius:var(--cc-btn-border-radius)}#cc-main.cc--rtl .cm__btn--close+.cm__texts .cm__title{padding-right:1.3rem;padding-left:3rem!important}#cc-main.cc--rtl .cm--inline .cm__btn+.cm__btn{margin-left:0;margin-right:.375rem}#cc-main.cc--rtl .cm--inline.cm--flip .cm__btn+.cm__btn{margin-left:.375rem;margin-right:0}#cc-main.cc--rtl .cm:not(.cm--inline).cm--bar .cm__btn+.cm__btn,#cc-main.cc--rtl .cm:not(.cm--inline).cm--bar .cm__btn-group+.cm__btn-group,#cc-main.cc--rtl .cm:not(.cm--inline).cm--wide .cm__btn+.cm__btn,#cc-main.cc--rtl .cm:not(.cm--inline).cm--wide .cm__btn-group+.cm__btn-group{margin-left:0;margin-right:.375rem}#cc-main.cc--rtl .cm:not(.cm--inline).cm--bar.cm--flip .cm__btn+.cm__btn,#cc-main.cc--rtl .cm:not(.cm--inline).cm--wide.cm--flip .cm__btn+.cm__btn{margin-left:.375rem;margin-right:0}#cc-main.cc--rtl .cm__link-group>*+*{margin-left:0;margin-right:1.3rem}@media screen and (max-width:640px){#cc-main{--cc-modal-margin:.5em}#cc-main .cm{max-width:none!important;width:auto!important}#cc-main .cm__body{flex-direction:column!important;padding:0!important}#cc-main .cm__btns,#cc-main .cm__desc,#cc-main .cm__links,#cc-main .cm__title{padding-left:1.1rem!important;padding-right:1.1rem!important}#cc-main .cm__btns{flex-direction:column!important;max-width:none!important;min-width:auto!important;border-left:none!important;border-top:1px solid var(--cc-separator-border-color)!important}#cc-main .cm__btn+.cm__btn,#cc-main .cm__btn-group+.cm__btn-group{margin:.375rem 0 0!important}#cc-main .cm--flip .cm__btn+.cm__btn,#cc-main .cm--flip .cm__btn-group+.cm__btn-group{margin-top:0!important;margin-bottom:.375rem!important}#cc-main .cm__btn-group{display:flex!important;flex-direction:column!important;min-width:auto!important}#cc-main .cm__btn{flex:auto!important}#cc-main .cm__link-group{justify-content:center!important}#cc-main .cm--flip .cm__btn-group,#cc-main .cm--flip .cm__btns{flex-direction:column-reverse!important}}#cc-main .pm-wrapper{position:relative;z-index:2}#cc-main .pm{position:fixed;display:flex;width:100%;width:unset;background:var(--cc-bg);flex-direction:column;border-radius:var(--cc-modal-border-radius);opacity:0;visibility:hidden;overflow:hidden;z-index:1;box-shadow:0 .625em 1.875em rgba(0,0,2,.3)}#cc-main .pm__body,#cc-main .pm__footer,#cc-main .pm__header{padding:1em 1.4em}#cc-main .pm__header{display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid var(--cc-separator-border-color)}#cc-main .pm__title{display:flex;align-items:center;flex:1;font-weight:600;margin-right:2em}#cc-main .pm__close-btn{width:calc(40px);height:calc(40px);position:relative;background:var(--cc-btn-secondary-bg);border-radius:var(--cc-btn-border-radius);border:1px solid var(--cc-btn-secondary-border-color);transition:all .15s}#cc-main .pm__close-btn span{display:flex;height:100%;width:100%}#cc-main .pm__close-btn svg{stroke:var(--cc-btn-secondary-color);transform:scale(.5);transition:stroke .15s}#cc-main .pm__close-btn:hover{border-color:var(--cc-btn-secondary-hover-border-color);background:var(--cc-btn-secondary-hover-bg)}#cc-main .pm__close-btn:hover svg{stroke:var(--cc-btn-secondary-hover-color)}#cc-main .pm__body{flex:1;overflow-y:auto}#cc-main .pm__section,#cc-main .pm__section--toggle{display:flex;flex-direction:column;margin-bottom:.5em;border-radius:var(--cc-btn-border-radius)}#cc-main .pm__section--toggle .pm__section-desc-wrapper{overflow:hidden;margin-top:0!important;display:none;border:1px solid var(--cc-cookie-category-block-border);border-top:none;border-radius:var(--cc-btn-border-radius);border-top-left-radius:0;border-top-right-radius:0}#cc-main .pm__section{padding:1em;border:1px solid var(--cc-separator-border-color);transition:background-color .25s,border-color .25s}#cc-main .pm__section:first-child{transition:none;padding:0;margin-top:0;border:none;margin-bottom:2em}#cc-main .pm__section:not(:first-child):hover{background:var(--cc-cookie-category-block-bg);border-color:var(--cc-cookie-category-block-border)}#cc-main .pm__section-toggles+.pm__section{margin-top:2em}#cc-main .pm__section--toggle{background:var(--cc-cookie-category-block-bg);border-top:none;margin-bottom:.375rem}#cc-main .pm__section--toggle .pm__section-title{width:100%;display:flex;justify-content:space-between;align-items:center;background:var(--cc-cookie-category-block-bg);position:relative;padding:1.1em 5.4em 1.1em 1.2em;border:1px solid var(--cc-cookie-category-block-border);transition:background-color .25s,border-color .25s;min-height:58px}#cc-main .pm__section--toggle .pm__section-title:hover{background:var(--cc-cookie-category-block-hover-bg);border-color:var(--cc-cookie-category-block-hover-border)}#cc-main .pm__section--toggle .pm__section-desc{padding:1em;margin-top:0}#cc-main .pm__section--toggle.is-expanded{--cc-cookie-category-block-bg:var(--cc-cookie-category-expanded-block-bg);--cc-cookie-category-block-border:var(--cc-cookie-category-expanded-block-hover-bg)}#cc-main .pm__section--toggle.is-expanded .pm__section-title{border-bottom-left-radius:0;border-bottom-right-radius:0}#cc-main .pm__section--toggle.is-expanded .pm__section-arrow svg{transform:scale(.5) rotate(180deg)}#cc-main .pm__section--toggle.is-expanded .pm__section-desc-wrapper{display:flex}#cc-main .pm__section--expandable .pm__section-title{padding-left:3.4em;cursor:pointer}#cc-main .pm__section--expandable .pm__section-arrow{width:20px;height:20px;position:absolute;left:18px;background:var(--cc-toggle-readonly-bg);display:flex;justify-content:center;border-radius:100%;pointer-events:none}#cc-main .pm__section--expandable .pm__section-arrow svg{stroke:var(--cc-btn-secondary-color);transform:scale(.5)}#cc-main .pm__badge,#cc-main .pm__section-title-wrapper{position:relative;display:flex;align-items:center}#cc-main .pm__section-title-wrapper+.pm__section-desc-wrapper{margin-top:.85em}#cc-main .pm__section-title{font-weight:600;border-radius:var(--cc-btn-border-radius);font-size:.95em}#cc-main .pm__badge{flex:none;margin-left:1em;border-radius:5em;font-weight:600;font-size:.8em;background:var(--cc-btn-secondary-bg);color:var(--cc-secondary-color);height:23px;width:auto;min-width:23px;text-align:center;justify-content:center;padding:0 .6em 1px;white-space:nowrap;overflow:hidden}#cc-main .pm__service-counter{padding:0;width:23px;background:var(--cc-btn-primary-bg);color:var(--cc-btn-primary-color)}#cc-main .pm__service-counter[data-counterlabel]{padding:0 .6em 1px;width:auto}#cc-main .section__toggle,#cc-main .section__toggle-wrapper,#cc-main .toggle__icon,#cc-main .toggle__label{width:50px;height:23px;border-radius:var(--cc-pm-toggle-border-radius);transform:translateZ(0)}#cc-main .section__toggle-wrapper{position:absolute;right:18px;cursor:pointer;z-index:1}#cc-main .toggle-service{position:relative;right:0;width:42px;height:19px}#cc-main .toggle-service .section__toggle,#cc-main .toggle-service .toggle__icon,#cc-main .toggle-service .toggle__label{width:42px;height:19px}#cc-main .toggle-service .toggle__icon{position:relative}#cc-main .toggle-service .toggle__icon-circle{height:19px;width:19px}#cc-main .toggle-service .section__toggle:checked~.toggle__icon .toggle__icon-circle{transform:translateX(23px)}#cc-main .pm__section--toggle:nth-child(2) .section__toggle-wrapper:after{display:none!important}#cc-main .section__toggle{position:absolute;cursor:pointer;display:block;top:50%;left:0;min-height:24px;translate:0 -50%;margin:0;border:0}#cc-main .section__toggle:disabled{cursor:not-allowed}#cc-main .toggle__icon{position:absolute;background:var(--cc-toggle-off-bg);box-shadow:0 0 0 1px var(--cc-toggle-off-bg);transition:all .25s;pointer-events:none;display:flex;flex-direction:row}#cc-main .toggle__icon-circle{position:absolute;display:block;left:0;top:0;width:23px;height:23px;border:none;background:var(--cc-toggle-off-knob-bg);box-shadow:0 1px 2px rgba(24,32,3,.36);transition:transform .25s,background-color .25s;border-radius:var(--cc-pm-toggle-border-radius)}#cc-main .toggle__icon-off,#cc-main .toggle__icon-on{height:100%;position:absolute;width:100%;transition:opacity .15s}#cc-main .toggle__icon-on{opacity:0;transform:rotate(45deg)}#cc-main .toggle__icon-on svg{stroke:var(--cc-toggle-on-bg);transform:scale(.55) rotate(-45deg)}#cc-main .section__toggle:checked~.toggle__icon .toggle__icon-on,#cc-main .toggle__icon-off{opacity:1}#cc-main .toggle__icon-off svg{stroke:var(--cc-toggle-off-bg);transform:scale(.55)}#cc-main .section__toggle:checked~.toggle__icon{background:var(--cc-toggle-on-bg);box-shadow:0 0 0 1px var(--cc-toggle-on-bg)}#cc-main .section__toggle:checked~.toggle__icon .toggle__icon-circle{transform:translateX(27px);background-color:var(--cc-toggle-on-knob-bg)}#cc-main .section__toggle:checked~.toggle__icon .toggle__icon-off{opacity:0}#cc-main .section__toggle:checked:disabled~.toggle__icon{background:var(--cc-toggle-readonly-bg);box-shadow:0 0 0 1px var(--cc-toggle-readonly-bg)}#cc-main .section__toggle:checked:disabled~.toggle__icon .toggle__icon-circle{background:var(--cc-toggle-readonly-knob-bg);box-shadow:none}#cc-main .section__toggle:checked:disabled~.toggle__icon svg{stroke:var(--cc-toggle-readonly-knob-icon-color)}#cc-main .toggle__label{position:absolute;top:0;z-index:-1;opacity:0;pointer-events:none;overflow:hidden}#cc-main .pm__section-desc-wrapper{display:flex;flex-direction:column;font-size:.9em;color:var(--cc-secondary-color)}#cc-main .pm__section-desc-wrapper>:not(:last-child){border-bottom:1px solid var(--cc-cookie-category-block-border)}#cc-main .pm__section-services{display:flex;flex-direction:column}#cc-main .pm__service{padding:.4em 1.2em;position:relative;display:flex;justify-content:space-between;transition:background-color .15s;align-items:center}#cc-main .pm__service:hover{background-color:var(--cc-cookie-category-block-hover-bg)}#cc-main .pm__service-header{display:flex;align-items:center;width:100%;margin-right:1em}#cc-main .pm__service-icon{min-width:8px;height:8px;border:2px solid;border-radius:100%;margin-left:6px;margin-right:20px;margin-top:1px}#cc-main .pm__service-title{font-size:.95em;word-break:break-word;width:100%}#cc-main .pm__section-desc{line-height:1.5em}#cc-main .pm__section-table{text-align:left;border-collapse:collapse;width:100%;padding:0;margin:0;overflow:hidden;font-size:.9em}#cc-main .pm__table-caption{text-align:left}#cc-main .pm__table-caption,#cc-main .pm__table-head>tr{font-weight:600;color:var(--cc-primary-color);border-bottom:1px dashed var(--cc-separator-border-color)}#cc-main .pm__table-tr{transition:background-color .15s}#cc-main .pm__table-tr:hover{background:var(--cc-cookie-category-block-hover-bg)}#cc-main .pm__table-caption,#cc-main .pm__table-td,#cc-main .pm__table-th{padding:.625em;vertical-align:top;padding-left:1.2em}#cc-main .pm__footer{display:flex;justify-content:space-between;border-top:1px solid var(--cc-separator-border-color)}#cc-main .pm__btn-group{display:flex}#cc-main .pm__btn+.pm__btn,#cc-main .pm__btn-group+.pm__btn-group{margin-left:.375rem}#cc-main .pm--flip .pm__btn+.pm__btn,#cc-main .pm--flip .pm__btn-group+.pm__btn-group{margin-left:0;margin-right:.375rem}#cc-main .pm__btn{color:var(--cc-btn-primary-color);background:var(--cc-btn-primary-bg);border:1px solid var(--cc-btn-primary-border-color);text-align:center;flex:auto;min-width:110px;font-weight:600;font-size:.82em;padding:.5em 1.5em;min-height:42px;border-radius:var(--cc-btn-border-radius);transition:background-color .15s,border-color .15s,color .15s}#cc-main .pm__btn:hover{background:var(--cc-btn-primary-hover-bg);border-color:var(--cc-btn-primary-hover-border-color);color:var(--cc-btn-primary-hover-color)}#cc-main .pm__btn--secondary{color:var(--cc-btn-secondary-color);background:var(--cc-btn-secondary-bg);border-color:var(--cc-btn-secondary-border-color)}#cc-main .pm__btn--secondary:hover{background:var(--cc-btn-secondary-hover-bg);border-color:var(--cc-btn-secondary-hover-border-color);color:var(--cc-btn-secondary-hover-color)}#cc-main .pm--box{left:var(--cc-modal-margin);right:var(--cc-modal-margin);margin:0 auto;top:50%;max-width:43em;max-height:37.5em;height:calc(100% - 2em);transform:translateY(calc(-50% + 1.6em))}#cc-main .pm--box.pm--flip .pm__btn-group,#cc-main .pm--box.pm--flip .pm__footer{flex-direction:row-reverse}#cc-main .pm--bar{top:0;bottom:0;border-radius:0;height:100%;max-height:none;max-width:29em;width:100%;margin:0;opacity:1;--cc-modal-transition-duration:.35s}#cc-main .pm--bar .pm__section-table,#cc-main .pm--bar .pm__table-body,#cc-main .pm--bar .pm__table-td,#cc-main .pm--bar .pm__table-th,#cc-main .pm--bar .pm__table-tr{display:block}#cc-main .pm--bar .pm__table-head{display:none}#cc-main .pm--bar .pm__table-caption{display:block}#cc-main .pm--bar .pm__table-tr:not(:last-child){border-bottom:1px solid var(--cc-separator-border-color)}#cc-main .pm--bar .pm__table-td{display:flex;justify-content:space-between}#cc-main .pm--bar .pm__table-td:before{content:attr(data-column);padding-right:2em;font-weight:600;color:var(--cc-primary-color);overflow:hidden;text-overflow:ellipsis;flex:1;min-width:100px}#cc-main .pm--bar .pm__table-td>div{flex:3}#cc-main .pm--bar:not(.pm--wide) .pm__body,#cc-main .pm--bar:not(.pm--wide) .pm__footer,#cc-main .pm--bar:not(.pm--wide) .pm__header{padding:1em 1.3em}#cc-main .pm--bar:not(.pm--wide) .pm__btn-group,#cc-main .pm--bar:not(.pm--wide) .pm__footer{flex-direction:column}#cc-main .pm--bar:not(.pm--wide) .pm__btn+.pm__btn,#cc-main .pm--bar:not(.pm--wide) .pm__btn-group+.pm__btn-group{margin:.375rem 0 0}#cc-main .pm--bar:not(.pm--wide).pm--flip .pm__btn-group,#cc-main .pm--bar:not(.pm--wide).pm--flip .pm__footer{flex-direction:column-reverse}#cc-main .pm--bar:not(.pm--wide).pm--flip .pm__btn+.pm__btn,#cc-main .pm--bar:not(.pm--wide).pm--flip .pm__btn-group+.pm__btn-group{margin-bottom:.375rem;margin-top:0}#cc-main .pm--bar:not(.pm--wide) .pm__badge{display:none}#cc-main .pm--bar.pm--left{left:0;transform:translateX(-100%)}#cc-main .pm--bar.pm--right{right:0;transform:translateX(100%)}#cc-main .pm--bar.pm--wide{max-width:35em}#cc-main .pm--bar.pm--wide .pm__body,#cc-main .pm--bar.pm--wide .pm__footer,#cc-main .pm--bar.pm--wide .pm__header{padding:1em 1.4em}#cc-main .pm--bar.pm--wide.pm--flip .pm__btn-group,#cc-main .pm--bar.pm--wide.pm--flip .pm__footer{flex-direction:row-reverse}#cc-main .pm-overlay{content:"";position:fixed;left:0;right:0;top:0;bottom:0;z-index:1;background:var(--cc-overlay-bg);opacity:0;visibility:hidden}#cc-main .cc--anim .pm,#cc-main .cc--anim .pm-overlay{transition:opacity var(--cc-modal-transition-duration) ease,visibility var(--cc-modal-transition-duration) ease,transform var(--cc-modal-transition-duration) ease}.show--preferences #cc-main .cc--anim .pm{opacity:1;visibility:visible!important}.show--preferences #cc-main .cc--anim .pm--box{transform:translateY(-50%)}.show--preferences #cc-main .cc--anim .pm--bar{transform:translateX(0)}.show--preferences #cc-main .cc--anim .pm-overlay{opacity:1;visibility:visible}#cc-main.cc--rtl .pm__service-header{margin-right:0;margin-left:1em}#cc-main.cc--rtl .pm__section-arrow{left:unset;right:18px}#cc-main.cc--rtl .section__toggle-wrapper{right:unset;left:18px;transform-origin:left}#cc-main.cc--rtl .toggle-service{left:0}#cc-main.cc--rtl .pm__service-icon{margin-right:5px;margin-left:20px}#cc-main.cc--rtl .pm__section--toggle .pm__section-title{padding-left:5.4em;padding-right:1.2em}#cc-main.cc--rtl .pm__section--expandable .pm__section-title{padding-right:3.4em}#cc-main.cc--rtl .pm__badge{margin-left:unset;margin-right:1em}#cc-main.cc--rtl .toggle__icon-circle{transform:translateX(27px)}#cc-main.cc--rtl .toggle-service .toggle__icon-circle{transform:translateX(23px)}#cc-main.cc--rtl .section__toggle:checked~.toggle__icon .toggle__icon-circle{transform:translateX(0)}#cc-main.cc--rtl .pm__table-td,#cc-main.cc--rtl .pm__table-th{text-align:right;padding-left:unset;padding-right:1.2em}#cc-main.cc--rtl .pm__table-td{padding-left:unset;padding-right:1.2em}#cc-main.cc--rtl .pm__table-td:before{padding-right:unset;padding-left:2em}#cc-main.cc--rtl .pm__btn+.pm__btn,#cc-main.cc--rtl .pm__btn-group+.pm__btn-group{margin-left:0;margin-right:.375rem}#cc-main.cc--rtl .pm--flip .pm__btn+.pm__btn,#cc-main.cc--rtl .pm--flip .pm__btn-group+.pm__btn-group{margin-left:.375rem;margin-right:0}#cc-main.cc--rtl .pm--flip.pm--bar:not(.pm--wide) .pm__btn+.pm__btn,#cc-main.cc--rtl .pm--flip.pm--bar:not(.pm--wide) .pm__btn-group+.pm__btn-group{margin-left:0}@media screen and (max-width:640px){#cc-main .pm{left:0;right:0;top:0;bottom:0;max-height:100%;height:auto;transform:translateY(1.6em);border-radius:0;max-width:none!important}#cc-main .pm__body,#cc-main .pm__footer,#cc-main .pm__header{padding:.9em!important}#cc-main .pm__badge{display:none}#cc-main .pm__section-table,#cc-main .pm__table-body,#cc-main .pm__table-caption,#cc-main .pm__table-td,#cc-main .pm__table-th,#cc-main .pm__table-tr{display:block}#cc-main .pm__table-head{display:none}#cc-main .pm__table-tr:not(:last-child){border-bottom:1px solid var(--cc-separator-border-color)}#cc-main .pm__table-td{display:flex;justify-content:space-between}#cc-main .pm__table-td:before{content:attr(data-column);padding-right:2em;font-weight:600;color:var(--cc-primary-color);overflow:hidden;text-overflow:ellipsis;flex:1;min-width:100px}#cc-main .pm__table-td>div{flex:3}#cc-main .pm__btn-group,#cc-main .pm__footer{flex-direction:column!important}#cc-main .pm__btn-group{display:flex!important}#cc-main .pm__btn+.pm__btn,#cc-main .pm__btn-group+.pm__btn-group{margin:.375rem 0 0!important}#cc-main .pm--flip .pm__btn+.pm__btn,#cc-main .pm--flip .pm__btn-group+.pm__btn-group{margin-top:0!important;margin-bottom:.375rem!important}#cc-main .pm--flip .pm__btn-group,#cc-main .pm--flip .pm__footer{flex-direction:column-reverse!important}.show--preferences #cc-main .cc--anim .pm{transform:translateY(0)!important}}
@@ -0,0 +1,7 @@
1
+ /*!
2
+ * CookieConsent 3.3.0
3
+ * https://github.com/orestbida/cookieconsent
4
+ * Author Orest Bida
5
+ * Released under the MIT License
6
+ */
7
+ var e,t;e=this,t=function(e){'use strict';const t='opt-in',o='opt-out',n='show--consent',s='show--preferences',a='disable--interaction',c='data-category',r='div',i='button',l='aria-hidden',d='btn-group',_='click',f='data-role',u='consentModal',p='preferencesModal';class m{constructor(){this.t={mode:t,revision:0,autoShow:!0,lazyHtmlGeneration:!0,autoClearCookies:!0,manageScriptTags:!0,hideFromBots:!0,respectGpc:!1,cookie:{name:'cc_cookie',expiresAfterDays:182,domain:'',path:'/',secure:!0,sameSite:'Lax'}},this.o={i:{},l:'',_:{},u:{},p:{},m:[],v:!1,h:null,C:null,S:null,M:'',T:!0,D:!1,k:!1,N:!1,A:!1,H:[],j:!1,I:!0,V:[],F:!1,L:'',O:!1,P:[],R:[],B:[],$:[],G:!1,J:!1,U:!1,q:[],K:[],W:[],X:{},Y:{},Z:{},ee:{},te:{},oe:[]},this.ne={se:{},ae:{}},this.ce={},this.re={ie:'cc:onFirstConsent',le:'cc:onConsent',de:'cc:onChange',_e:'cc:onModalShow',fe:'cc:onModalHide',ue:'cc:onModalReady'}}}const g=new m,b=(e,t)=>e.indexOf(t),v=(e,t)=>-1!==b(e,t),h=e=>Object.keys(e),y=e=>Array.from(new Set(e)),C=e=>{if('object'!=typeof e||null===e)return e;if(e instanceof Date)return new Date(e.getTime());let t=Array.isArray(e)?[]:{};for(let o in e){let n=e[o];t[o]=C(n)}return t},w=(e,t)=>{const o=e||[],n=t||[];return o.filter(e=>!v(n,e)).concat(n.filter(e=>!v(o,e)))},S=()=>document.activeElement,x=e=>e.preventDefault(),M=(e,t)=>e.querySelectorAll(t),T=e=>e.dispatchEvent(new Event('change')),D=(e,t)=>{const o=document.createElement(e);return e===i&&(o.type=e),t&&H(o,t),o},E=(e,t,o)=>e.setAttribute(t,o),k=(e,t,o)=>{e.removeAttribute(o?'data-'+t:t)},N=(e,t,o)=>e.getAttribute(o?'data-'+t:t),A=(e,t)=>e.appendChild(t),H=(e,t)=>e.classList.add(t),j=(e,t)=>H(e,'cm__'+t),I=(e,t)=>H(e,'pm__'+t),V=(e,t)=>e.classList.remove(t),F=(e,t,o,n)=>{e.addEventListener(t,o),n&&g.o.m.push({pe:e,me:t,ge:o})},L=(e,t,o)=>{e&&(t&&(e.tabIndex=-1),e.focus({preventScroll:o}),t&&e.removeAttribute('tabindex'))},O=()=>{const{be:e,ve:t}=g.ne;return[...new Set([e,t])].filter(e=>e)},P=(e,t,o=O())=>{for(const n of o)n.classList.toggle(e,!!t)};let R;const B=e=>{clearTimeout(R);const t=O();e?P(a,!0,t):R=setTimeout(()=>{P(a,!1,t)},500)},$=e=>Array.isArray(e),G=e=>'string'==typeof e,J=e=>!!e&&'object'==typeof e&&!$(e),U=e=>'function'==typeof e,z=()=>{const e=g.ne.se;if(!e)return[];let t=[];for(let o in e)e[o].checked&&t.push(o);return t},q=()=>g.t.respectGpc&&g.o.T&&!0===navigator.globalPrivacyControl,K=(e,t,o)=>{const n=g.o;return!!n.O[e].readOnly||(o?t?v(n.Y[e],t):v(n.R,e):v(n.$,e))},Q=e=>{const{se:t,ae:o}=g.ne;for(const n in t){const s=[];t[n].checked=K(n,'',e);for(const t in o[n]){const a=o[n][t];a.checked=K(n,t,e),a.checked&&s.push(t)}g.o.Z[n]=s}},W=e=>{g.o.R=y(e),g.o.L=(()=>{let e='custom';const{R:t,P:o,B:n}=g.o,s=t.length;return s===o.length?e='all':s===n.length&&(e='necessary'),e})()},X=(e,t)=>dispatchEvent(new CustomEvent(e,{detail:t})),Y=(e,t,o)=>{const{de:n,le:s,ie:a,fe:c,ue:r,_e:i}=g.ce,l=g.re;if(t){const n={modalName:t};return e===l._e?U(i)&&i(n):e===l.fe?U(c)&&c(n):(n.modal=o,U(r)&&r(n)),X(e,n)}const d={cookie:g.o.p};e===l.ie?U(a)&&a(C(d)):e===l.le?U(s)&&s(C(d)):(d.changedCategories=g.o.V,d.changedServices=g.o.ee,U(n)&&n(C(d))),X(e,C(d))},Z=()=>{const{R:e,Y:t,ee:o,P:n,X:s,oe:a,V:r}=g.o;for(const e of n){const n=o[e],a=n&&n.length>0?n:t[e]||[];for(const o of a){const n=s[e][o];if(!n)continue;const{onAccept:a,onReject:c}=n;!n.he&&v(t[e],o)?(n.he=!0,U(a)&&a()):n.he&&!v(t[e],o)&&(n.he=!1,U(c)&&c())}}if(!g.t.manageScriptTags)return;const i=(n,s)=>{if(s>=n.length)return;const l=a[s];if(l.ye)return i(n,s+1);const d=l.Ce,_=l.we,f=l.Se,u=v(e,_),p=!!f&&v(t[_],f);if(!f&&!l.xe&&u||!f&&l.xe&&!u&&v(r,_)||f&&!l.xe&&p||f&&l.xe&&!p&&v(o[_]||[],f)){l.ye=!0;const e=N(d,'type',!0);k(d,'type',!!e),k(d,c);let t=N(d,'src',!0);t&&k(d,'src',!0);const o=D('script');o.textContent=d.innerHTML;for(const{nodeName:e}of d.attributes)E(o,e,d[e]||N(d,e));e&&(o.type=e),t?o.src=t:t=d.src;const a=!!t&&(!e||['text/javascript','module'].includes(e));if(a&&(o.onload=o.onerror=()=>{i(n,++s)}),d.replaceWith(o),a)return}i(n,++s)};i(a,0)},ee=(e,t,o,n)=>{const s='accept-',{show:a,showPreferences:c,hide:r,hidePreferences:i,acceptCategory:l}=t,d=e||document,f=e=>M(d,`[data-cc="${e}"]`),u=(e,t)=>{x(e),l(t),i(),r()},p=f('show-preferencesModal'),m=f('show-consentModal'),b=f(s+'all'),v=f(s+'necessary'),h=f(s+'custom'),y=g.t.lazyHtmlGeneration;for(const e of p)E(e,'aria-haspopup','dialog'),F(e,_,e=>{x(e),c()},!0),y&&(F(e,'mouseenter',e=>{x(e),g.o.A||o(t,n)},!0),F(e,'focus',()=>{g.o.A||o(t,n)},!0));for(let e of m)E(e,'aria-haspopup','dialog'),F(e,_,e=>{x(e),a(!0)},!0);for(let e of b)F(e,_,e=>{u(e,'all')},!0);for(let e of h)F(e,_,e=>{u(e)},!0);for(let e of v)F(e,_,e=>{u(e,[])},!0)},te=e=>{const t=g.ne,o=g.o;(e=>{const n=e===t.Me,s=o.i.disablePageInteraction?t.be:n?t.Te:t.be;F(s,'keydown',s=>{if('Tab'!==s.key||!(n?o.k&&!o.N:o.N))return;const a=S(),c=n?o.q:o.K;if(0!==c.length)if(s.shiftKey){const o=n?t.De:t.Ee;a!==c[0]&&a!==o&&e.contains(a)||(x(s),L(c[1]))}else a!==c[1]&&e.contains(a)||(x(s),L(c[0]))},!0)})(e)},oe=['[href]',i,'input','details','[tabindex]'].map(e=>e+':not([tabindex="-1"])').join(','),ne=e=>{const{o:t,ne:o}=g,n=(e,t)=>{const o=M(e,oe);t[0]=o[0],t[1]=o[o.length-1]};1===e&&t.D&&n(o.Me,t.q),2===e&&t.A&&n(o.ke,t.K)},se=['M 19.5 4.5 L 4.5 19.5 M 4.5 4.501 L 19.5 19.5','M 3.572 13.406 L 8.281 18.115 L 20.428 5.885','M 21.999 6.94 L 11.639 17.18 L 2.001 6.82 '],ae=(e=0,t=1.5)=>`<svg aria-hidden="true" viewBox="0 0 24 24" stroke-width="${t}"><path d="${se[e]}"/></svg>`,ce='bottom',re='left',ie='center',le='right',de='inline',_e='wide',fe='pm--',ue=['middle','top',ce],pe=[re,ie,le],me={box:{Ne:[_e,de],Ae:ue,He:pe,je:ce,Ie:le},cloud:{Ne:[de],Ae:ue,He:pe,je:ce,Ie:ie},bar:{Ne:[de],Ae:ue.slice(1),He:[],je:ce,Ie:''}},ge={box:{Ne:[],Ae:[],He:[],je:'',Ie:''},bar:{Ne:[_e],Ae:[],He:[re,le],je:'',Ie:re}},be=e=>{const t=g.o.i.guiOptions,o=t&&t.consentModal,n=t&&t.preferencesModal;0===e&&ve(g.ne.Me,me,o,'cm--','box','cm'),1===e&&ve(g.ne.ke,ge,n,fe,'box','pm')},ve=(e,t,o,n,s,a)=>{e.className=a;const c=o&&o.layout,r=o&&o.position,i=o&&o.flipButtons,l=!o||!1!==o.equalWeightButtons,d=c&&c.split(' ')||[],_=d[0],f=d[1],u=_ in t?_:s,p=t[u],m=v(p.Ne,f)&&f,b=r&&r.split(' ')||[],h=b[0],y=n===fe?b[0]:b[1],C=v(p.Ae,h)?h:p.je,w=v(p.He,y)?y:p.Ie,S=t=>{t&&H(e,n+t)};S(u),S(m),S(C),S(w),i&&S('flip');const x=a+'__btn--secondary';if('cm'===a){const{Ve:e,Fe:t}=g.ne;e&&(l?V(e,x):H(e,x)),t&&(l?V(t,x):H(t,x))}else{const{Le:e}=g.ne;e&&(l?V(e,x):H(e,x))}},he=(e,t)=>{const o=g.o,n=g.ne,{hide:s,hidePreferences:a,acceptCategory:c}=e,u=e=>{c(e),a(),s()},m=o.u&&o.u.preferencesModal;if(!m)return;const b=m.title,v=m.closeIconLabel,y=m.acceptAllBtn,C=m.acceptNecessaryBtn,w=m.savePreferencesBtn,S=m.sections||[],x=y||C||w;if(n.Oe)n.Pe=D(r,'pm__body');else{n.Oe=D(r,'pm-wrapper');const e=D('div','pm-overlay');A(n.Oe,e),F(e,_,a),n.ke=D(r,'pm'),E(n.ke,'role','dialog'),E(n.ke,l,!0),E(n.ke,'aria-modal',!0),E(n.ke,'aria-labelledby','pm__title'),F(n.be,'keydown',e=>{'Escape'===e.key&&a()},!0),n.Re=D(r,'pm__header'),n.Be=D('h2','pm__title'),n.Be.id='pm__title',n.$e=D(i,'pm__close-btn'),E(n.$e,'aria-label',m.closeIconLabel||''),F(n.$e,_,a),n.Ge=D('span'),n.Ge.innerHTML=ae(),A(n.$e,n.Ge),n.Je=D(r,'pm__body'),n.Ue=D(r,'pm__footer'),n.ze=D(r),n.qe=D(r),I(n.ze,d),I(n.qe,d),A(n.Ue,n.ze),A(n.Ue,n.qe),A(n.Re,n.Be),A(n.Re,n.$e),n.Ee=n.Be,E(n.Ee,'tabIndex',-1),A(n.ke,n.Re),A(n.ke,n.Je),A(n.Oe,n.ke)}let M;b&&(n.Be.innerHTML=b,v&&E(n.$e,'aria-label',v)),S.forEach((e,t)=>{const s=e.title,a=e.description,c=e.linkedCategory,d=c&&o.O[c],_=e.cookieTable,f=_&&_.body,u=f&&f.length>0,p=!!d,g=p&&o.X[c],b=J(g)&&h(g)||[],v=p&&!!s&&(!!a||!!u||h(g).length>0),y=b.length,C=c+'-desc',w=D(r,'pm__section');let S,x;if((v||a)&&(S=D(r,'pm__section-desc-wrapper')),v&&y>0&&A(S,ye(g,b,d,c)),s){const e=D(r);if(x=D(p?i:r),I(e,'section-title-wrapper'),I(x,'section-title'),x.innerHTML=s,A(e,x),p){w.className+='--toggle';const t=Me(s,c,d),o=m.serviceCounterLabel;if(y>0&&G(o)&&A(x,Ce(y,o)),v){const t=D('span');t.innerHTML=ae(2,3.5),I(t,'section-arrow'),A(e,t),I(w,'section--expandable'),E(x,'aria-expanded',!1),E(x,'aria-controls',C)}A(e,t)}else E(x,'role','heading'),E(x,'aria-level','3');A(w,e)}if(a){const e=D('p','pm__section-desc');e.innerHTML=a,A(S,e)}v&&(E(S,l,'true'),S.id=C,we(x,w,S),u&&A(S,Se(_,t))),(v||a)&&A(w,S);const T=n.Pe||n.Je;p?(M||(M=D(r,'pm__section-toggles')),M.appendChild(w)):M=null,A(T,M||w)}),y&&(n.Ke||(n.Ke=D(i,'pm__btn'),E(n.Ke,f,'all'),A(n.ze,n.Ke),F(n.Ke,_,()=>u('all'))),n.Ke.innerHTML=y),C&&(n.Le||(n.Le=D(i,'pm__btn'),E(n.Le,f,'necessary'),A(n.ze,n.Le),F(n.Le,_,()=>u([]))),n.Le.innerHTML=C),w&&(n.Qe||(n.Qe=D(i,'pm__btn'),I(n.Qe,'btn--secondary'),E(n.Qe,f,'save'),A(n.qe,n.Qe),F(n.Qe,_,()=>u())),n.Qe.innerHTML=w),n.Pe&&(n.ke.replaceChild(n.Pe,n.Je),n.Je=n.Pe),x&&A(n.ke,n.Ue),be(1),o.A||(o.A=!0,Y(g.re.ue,p,n.ke),t(),A(n.Te,n.Oe),te(n.ke),setTimeout(()=>H(n.Oe,'cc--anim'),100)),ne(2)},ye=(e,t,o,n)=>{const s=D(r,'pm__section-services');for(const a of t){const t=e[a],c=t&&t.label||a,i=D(r),l=D(r),d=D(r),_=D(r);I(i,'service'),I(_,'service-title'),I(l,'service-header'),I(d,'service-icon');const f=Me(c,a,o,!0,n);_.innerHTML=c,A(l,d),A(l,_),A(i,l),A(i,f),A(s,i)}return s},Ce=(e,t)=>{const o=D('span','pm__badge');if(I(o,'service-counter'),E(o,l,!0),E(o,'data-servicecounter',e),t){const n=t.split('|');t=n.length>1&&e>1?n[1]:n[0],E(o,'data-counterlabel',t)}return o.innerHTML=e+(t?' '+t:''),o},we=(e,t,o)=>{F(e,_,()=>{t.classList.contains('is-expanded')?(V(t,'is-expanded'),E(e,'aria-expanded','false'),E(o,l,'true')):(H(t,'is-expanded'),E(e,'aria-expanded','true'),k(o,l))})},Se=(e,t)=>{const o=D('table'),n=D('thead'),s=D('tbody'),a=e.caption;if(a){const e=D('caption','pm__table-caption');e.innerHTML=a,o.appendChild(e)}I(o,'section-table'),I(n,'table-head'),I(s,'table-body');const c=e.headers,i=h(c),l=g.ne.We.createDocumentFragment(),d=D('tr');for(const e of i){const o=c[e],n=D('th');n.id='cc__row-'+e+t,E(n,'scope','col'),I(n,'table-th'),n.innerHTML=o,A(l,n)}A(d,l),A(n,d);const _=g.ne.We.createDocumentFragment();for(const o of e.body){const e=D('tr','pm__table-tr');for(const n of i){const s=c[n],a=o[n],i=D('td'),l=D(r);I(i,'table-td'),E(i,'data-column',s),E(i,'headers','cc__row-'+n+t),l.insertAdjacentHTML('beforeend',a),A(i,l),A(e,i)}A(_,e)}return A(s,_),A(o,n),A(o,s),o},xe=e=>{const t=D('template');t.innerHTML=e;let o='';for(const e of t.content.childNodes)e.nodeType===Node.TEXT_NODE&&(o+=e.textContent);return o};function Me(e,t,o,n,s){const a=g.o,r=g.ne,i=D('label'),d=D('input'),f=D('span'),u=D('span'),p=D('span'),m=D('span'),b=D('span');return m.innerHTML=ae(1,3),b.innerHTML=ae(0,3),d.type='checkbox',H(i,'section__toggle-wrapper'),H(d,'section__toggle'),H(m,'toggle__icon-on'),H(b,'toggle__icon-off'),H(f,'toggle__icon'),H(u,'toggle__icon-circle'),H(p,'toggle__label'),E(f,l,'true'),n?(H(i,'toggle-service'),E(d,c,s),d.name='cc-'+s+'-'+t,r.ae[s][t]=d):(d.name='cc-'+t,r.se[t]=d),n?(e=>{F(d,'change',()=>{const t=r.ae[e],o=r.se[e];a.Z[e]=[];for(let o in t){const n=t[o];n.checked&&a.Z[e].push(n.value)}o.checked=a.Z[e].length>0})})(s):(e=>{F(d,_,()=>{const t=r.ae[e],o=d.checked;a.Z[e]=[];for(let n in t)t[n].checked=o,o&&a.Z[e].push(n)})})(t),d.value=t,p.textContent=xe(e),A(u,b),A(u,m),A(f,u),d.checked=n?K(s,t,!a.T):K(t,'',!a.T),o.readOnly&&(d.disabled=!0),A(i,d),A(i,f),A(i,p),i}const Te=()=>{const e=D('span');return g.ne.Xe||(g.ne.Xe=e),e},De=(e,t)=>{const o=g.o,n=g.ne,{hide:s,showPreferences:a,acceptCategory:c}=e,p=o.u&&o.u.consentModal;if(!p)return;const m=p.acceptAllBtn,b=p.acceptNecessaryBtn,v=p.showPreferencesBtn,h=p.closeIconLabel,y=p.footer,C=p.label,w=p.title,S=e=>{s(),c(e)};if(!n.Ye){n.Ye=D(r),n.Me=D(r),n.Ze=D(r),n.et=D(r),n.tt=D(r),H(n.Ye,'cm-wrapper'),H(n.Me,'cm'),j(n.Ze,'body'),j(n.et,'texts'),j(n.tt,'btns'),E(n.Me,l,'true'),o.v?(E(n.Me,'role','dialog'),E(n.Me,'aria-modal','true')):E(n.Me,'role','region'),!C&&w&&(E(n.Me,'aria-labelledby','cm__title'),E(n.Me,'aria-describedby','cm__desc'));const e='box',t=o.i.guiOptions,s=t&&t.consentModal,a=(s&&s.layout||e).split(' ')[0]===e;w&&h&&a&&(n.Fe||(n.Fe=D(i),n.Fe.innerHTML=ae(),j(n.Fe,'btn'),j(n.Fe,'btn--close'),F(n.Fe,_,()=>{S([])}),A(n.Ze,n.Fe))),A(n.Ze,n.et),A(n.Me,n.Ze),A(n.Ye,n.Me),n.De=n.Me,E(n.De,'tabIndex',-1)}C&&E(n.Me,'aria-label',C),n.Fe&&h&&E(n.Fe,'aria-label',h),w&&(n.ot||(n.ot=D('h2'),n.ot.className=n.ot.id='cm__title',A(n.et,n.ot)),n.ot.innerHTML=w);let x=p.description;if(x&&(o.j&&(x=x.replace('{{revisionMessage}}',o.I?'':p.revisionMessage||'')),n.nt||(n.nt=D('p'),n.nt.className=n.nt.id='cm__desc',A(n.et,n.nt)),n.nt.innerHTML=x),m&&(n.st||(n.st=D(i),A(n.st,Te()),j(n.st,'btn'),E(n.st,f,'all'),F(n.st,_,()=>{S('all')})),n.st.firstElementChild.innerHTML=m),b&&(n.Ve||(n.Ve=D(i),A(n.Ve,Te()),j(n.Ve,'btn'),E(n.Ve,f,'necessary'),F(n.Ve,_,()=>{S([])})),n.Ve.firstElementChild.innerHTML=b),v&&(n.ct||(n.ct=D(i),A(n.ct,Te()),j(n.ct,'btn'),j(n.ct,'btn--secondary'),E(n.ct,f,'show'),E(n.ct,'aria-haspopup','dialog'),F(n.ct,'mouseenter',()=>{o.A||he(e,t)}),F(n.ct,_,a)),n.ct.firstElementChild.innerHTML=v),n.rt||(n.rt=D(r,'cm__'+d),A(n.tt,n.rt)),n.st&&A(n.rt,n.st),n.Ve&&A(n.rt,n.Ve),n.ct&&(n.Ve&&n.st?(n.it||(n.it=D(r,'cm__'+d),A(n.tt,n.it)),V(n.rt,'cm__'+d+'--uneven'),A(n.it,n.ct)):(A(n.rt,n.ct),j(n.rt,d+'--uneven'))),(n.st||n.Ve||n.ct)&&A(n.Ze,n.tt),y){if(!n.lt){let e=D(r),t=D(r);n.lt=D(r),j(e,'footer'),j(t,'links'),j(n.lt,'link-group'),A(t,n.lt),A(e,t),A(n.Me,e)}n.lt.innerHTML=y}be(0),o.D||(o.D=!0,Y(g.re.ue,u,n.Me),t(),A(n.Te,n.Ye),te(n.Me)),ne(1),ee(n.Ze,e,he,t)},Ee=e=>{if(!G(e))return null;const t=g.o._,o=e=>Object.prototype.hasOwnProperty.call(t,e);if(o(e))return e;let n=e.slice(0,2);return o(n)?n:null},ke=()=>g.o.l||g.o.i.language.default,Ne=e=>{e&&(g.o.l=e)},Ae=async e=>{const t=g.o;let o=Ee(e)??ke(),n=t._[o];if(G(n)?n=await je(n):U(n)&&(n=await n()),!n)throw`Could not load translation for the '${o}' language`;return t.u=n,Ne(o),!0},He=()=>{let e=g.o.i.language.rtl,t=g.ne.Te;e&&t&&($(e)||(e=[e]),v(e,g.o.l)?H(t,'cc--rtl'):V(t,'cc--rtl'))},je=async e=>{try{const t=await fetch(e);return t.ok&&await t.json()}catch(e){return console.error(e),!1}},Ie=()=>{const e=g.ne;e.Te||(e.Te=D(r),e.Te.id='cc-main',e.Te.setAttribute('data-nosnippet',''),He(),(e.ve||e.We.body||e.be).appendChild(e.Te))},Ve=(e,t)=>{try{return e()}catch(e){return!t&&console.warn('CookieConsent:',e),!1}},Fe=e=>Ve(()=>localStorage.removeItem(e)),Le=(e,t)=>{if(t instanceof RegExp)return e.filter(e=>t.test(e));{const o=b(e,t);return o>-1?[e[o]]:[]}},Oe=(e,o)=>{const n=g.o;(e||o)&&Z(),e&&(Y(g.re.ie),Y(g.re.le),g.t.mode===t)?n.F=!1:(o&&Y(g.re.de),n.F&&(n.F=!1,location.reload()))},Pe=e=>{const{hostname:t,protocol:o}=location,{name:n,path:s,domain:a,sameSite:c,useLocalStorage:r,secure:i}=g.t.cookie,l=e?Ue():864e5*ze(),d=new Date;d.setTime(d.getTime()+l),g.o.p.expirationTime=d.getTime();const _=JSON.stringify(g.o.p);let f=n+'='+encodeURIComponent(_)+(0!==l?'; expires='+d.toUTCString():'')+'; Path='+s+'; SameSite='+c;a&&v(t,'.')&&(f+='; Domain='+a),i&&'https:'===o&&(f+='; Secure'),r?((e,t)=>{Ve(()=>localStorage.setItem(e,t))})(n,_):document.cookie=f,g.o.p},Re=(e,t,o)=>{if(0===e.length)return;const n=o||g.t.cookie.domain||location.hostname,s=t||g.t.cookie.path,a='www.'===n.slice(0,4),c=a&&n.substring(4),r=(e,t)=>{t&&'.'!==t.slice(0,1)&&(t='.'+t),document.cookie=e+'=; path='+s+(t?'; domain='+t:'')+'; expires=Thu, 01 Jan 1970 00:00:01 GMT;'};for(const t of e)r(t,o),o||r(t,n),a&&r(t,c)},Be=e=>{const t=e||g.t.cookie.name,o=g.t.cookie.useLocalStorage;return((e,t)=>{let o;return o=Ve(()=>JSON.parse(t?e:decodeURIComponent(e)),!0),J(o)?o:{}})(o?(n=t,Ve(()=>localStorage.getItem(n))||''):$e(t,!0),o);var n},$e=(e,t)=>{const o=e.replace(/[.*+?^${}()|[\]\\]/g,'\\$&'),n=document.cookie.match('(^|;)\\s*'+o+'\\s*=\\s*([^;]+)');return n?t?n.pop():e:''},Ge=e=>{const t=document.cookie.split(/;\s*/),o=[];for(const n of t){let t=n.split('=')[0];e?Ve(()=>{e.test(t)&&o.push(t)}):o.push(t)}return o},Je=()=>([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16)),Ue=()=>{const e=g.o.S,t=e?new Date-e:0;return 864e5*ze()-t},ze=()=>{const e=g.t.cookie.expiresAfterDays;return U(e)?e(g.o.L):e},qe=(e,t,n)=>{((e,t)=>{const{P:o,R:n,B:s,A:a,Z:c,$:r,X:i,T:l}=g.o;let d=[];if(e)$(e)?d.push(...e):G(e)&&(d='all'===e?o:[e]);else if(d=l?[...n,...r]:[...n],a){const e=g.ne.se;d=[...z(),...d.filter(t=>!e[t])]}if(d=d.filter(e=>v(o,e)&&!v(t,e)),e)for(const e of o)c[e]=v(d,e)?h(i[e]):[];d.push(...s),W(d)})(e,t),(()=>{const e=g.o,{Z:t,B:o,Y:n,X:s,P:a}=e,c=a;e.te=C(n);for(const e of c){const a=s[e],c=h(a);0!==c.length&&(n[e]=y(v(o,e)?c:t[e]||[]))}})(),(e=>{const t=g.o;t.V=g.t.mode===o&&t.T?w(t.$,t.R):w(t.R,t.p.categories);let n=t.V.length>0,s=!1;for(const e of t.P)t.ee[e]=w(t.Y[e],t.te[e]),t.ee[e].length>0&&(s=!0);Q(!0),t.C||(t.C=new Date),t.M||(t.M=Je()),t.p={categories:C(t.R),revision:g.t.revision,data:t.h,consentTimestamp:t.C.toISOString(),consentId:t.M,services:C(t.Y),languageCode:g.o.l},t.S&&(t.p.lastConsentTimestamp=t.S.toISOString());let a=!1;const c=n||s;var r;(t.T||c)&&(t.T&&(t.T=!1,a=!0),t.S=t.S?new Date:t.C,t.p.lastConsentTimestamp=t.S.toISOString(),Pe(),g.t.autoClearCookies&&(a||c)&&(e=>{const t=g.o,o=Ge(),n=(e=>{const t=g.o;return(e?t.P:t.V).filter(e=>{const o=t.O[e];return!!o&&!o.readOnly&&!!o.autoClear})})(e);for(const e in t.ee)for(const n of t.ee[e]){const s=t.X[e][n],a=s&&s.cookies;if(!v(t.Y[e],n)&&a)for(const e of a){const t=Le(o,e.name);Re(t,e.path,e.domain)}}for(const s of n){const n=t.O[s].autoClear,a=n&&n.cookies||[],c=v(t.V,s),r=!v(t.R,s),i=c&&r;if(e?r:i){n.reloadPage&&i&&(t.F=!0);for(const e of a){const t=Le(o,e.name);Re(t,e.path,e.domain)}}}})(a)),e?(r=()=>t===g.o&&Oe(a,c),requestAnimationFrame(()=>setTimeout(r))):Oe(a,c)})(n)},Ke=(e,t=[])=>qe(e,t),Qe=()=>!g.o.T||g.t.mode===o,We=(e,t,o)=>{let n=[];const s=e=>{if(G(e)){let t=$e(e);''!==t&&n.push(t)}else n.push(...Ge(e))};if($(e))for(let t of e)s(t);else s(e);Re(n,t,o)},Xe=e=>{const{ne:t,o:o}=g;o.k||(o.D||!e&&!o.T||De(ot,Ie),o.D&&(o.k=!0,o.J=S(),o.v&&B(!0),P(n,!0),k(t.Me,l),setTimeout(()=>{H(t.Ye,'cc--anim')},100),setTimeout(()=>{L(t.De,!1,!0)},200),Y(g.re._e,u)))},Ye=()=>{const{ne:e,o:t,re:o}=g;t.k&&(t.k=!1,t.v&&B(),L(e.Xe,!0,!0),P(n),E(e.Me,l,'true'),L(t.J),t.J=null,setTimeout(()=>V(e.Ye,'cc--anim'),100),Y(o.fe,u))},Ze=()=>{const{ne:e,o:t}=g;t.N||(t.A||he(ot,Ie),t.A&&(t.N=!0,t.k?t.U=S():t.J=S(),P(s,!0),k(e.ke,l),setTimeout(()=>{L(e.Ee,!1,!0)},200),Y(g.re._e,p)))},et=()=>Q(st()),tt=()=>{const e=g.o;e.N&&(e.N=!1,et(),L(g.ne.Ge,!0,!0),P(s),E(g.ne.ke,l,'true'),e.k?(L(e.U,!1,!0),e.U=null):(L(e.J),e.J=null),Y(g.re.fe,p))},ot={show:Xe,hide:Ye,showPreferences:Ze,hidePreferences:tt,acceptCategory:e=>qe(e,[],!0)},nt=(e,t)=>{const o=Be(t);return e?o[e]:o},st=()=>!g.o.T,at=e=>{const t=e&&new Date(e);return t&&!isNaN(t)?t:void 0};e.acceptCategory=Ke,e.acceptService=(e,t)=>{const{P:o,X:n}=g.o;if(!(e&&t&&G(t)&&v(o,t)&&0!==h(n[t]).length))return!1;((e,t)=>{const o=g.o,{X:n,Z:s,A:a}=o,c=g.ne.ae[t]||{},r=g.ne.se[t],i=h(n[t]);if(s[t]=[],G(e)){if('all'===e){if(s[t].push(...i),a)for(let e in c)c[e].checked=!0,T(c[e])}else if(v(i,e)&&s[t].push(e),a)for(let t in c)c[t].checked=e===t,T(c[t])}else if($(e))for(let o of i){const n=v(e,o),a=c[o];n&&s[t].push(o),a&&(a.checked=n,T(a))}const l=0===s[t].length;o.R=l?o.R.filter(e=>e!==t):y([...o.R,t]),r&&(r.checked=!l,T(r))})(e,t),Ke()},e.acceptedCategory=e=>{const t=Qe()?g.o.R:[];return v(t,e)},e.acceptedService=(e,t)=>{const o=Qe()&&g.o.Y[t]||[];return v(o,e)},e.eraseCookies=We,e.getConfig=e=>{const t=g.t,o=g.o.i;return e?t[e]||o[e]:{...t,...o,cookie:{...t.cookie}}},e.getCookie=nt,e.getUserPreferences=()=>{const{accepted:e,rejected:t}=(()=>{const{T:e,R:t,P:o}=g.o;return{accepted:t,rejected:e?[]:o.filter(e=>!v(t,e))}})(),o=(()=>{const e={},t={},{T:o,P:n,X:s,R:a,Y:c}=g.o;for(const r of n)e[r]=v(a,r)?c[r]:[],t[r]=o?[]:w(e[r],h(s[r]));return{accepted:e,rejected:t}})();return C({acceptType:g.o.L,acceptedCategories:e,rejectedCategories:t,acceptedServices:o.accepted,rejectedServices:o.rejected})},e.hide=Ye,e.hidePreferences=tt,e.loadScript=(e,t)=>{let o=[...document.scripts].find(t=>N(t,'src')===e);return new Promise(n=>{if(o)return n(!0);if(o=D('script'),J(t))for(const e in t)E(o,e,t[e]);o.onload=()=>n(!0),o.onerror=()=>{o.remove(),n(!1)},o.src=e,A(document.head,o)})},e.reset=e=>{const{Te:t}=g.ne,{name:o,path:c,domain:r,useLocalStorage:i}=g.t.cookie;e&&(i?Fe(o):We(o,c,r));for(const{pe:e,me:t,ge:o}of g.o.m)e.removeEventListener(t,o);t&&t.remove();for(const e of O())e.classList.remove(a,s,n);const l=new m;for(const e in g)g[e]=l[e];window._ccRun=!1},e.run=async e=>{const{o:t,t:n,re:s}=g,a=window;if(!a._ccRun){if(a._ccRun=!0,(e=>{const{ne:t,t:n,o:s}=g,a=n,r=s,{cookie:i}=a,l=g.ce,d=e.cookie,_=e.categories||{},f=h(_),u=navigator,p=document;t.We=p,t.be=p.documentElement;const m=e.root;t.ve=m&&G(m)?p.querySelector(m):m,i.domain=location.hostname,r.i=e,r.O=_,r.P=f,r._=e.language.translations,r.v=!!e.disablePageInteraction,l.ie=e.onFirstConsent,l.le=e.onConsent,l.de=e.onChange,l.fe=e.onModalHide,l._e=e.onModalShow,l.ue=e.onModalReady;const{mode:b,autoShow:y,lazyHtmlGeneration:C,autoClearCookies:w,revision:S,manageScriptTags:x,hideFromBots:T,respectGpc:D}=e;b===o&&(a.mode=b),'boolean'==typeof w&&(a.autoClearCookies=w),'boolean'==typeof x&&(a.manageScriptTags=x),'number'==typeof S&&S>=0&&(a.revision=S,r.j=!0),'boolean'==typeof y&&(a.autoShow=y),'boolean'==typeof C&&(a.lazyHtmlGeneration=C),!1===T&&(a.hideFromBots=!1),!0===a.hideFromBots&&u&&(r.G=u.userAgent&&/bot|crawl|spider|slurp|teoma/i.test(u.userAgent)||u.webdriver),'boolean'==typeof D&&(a.respectGpc=D),J(d)&&(a.cookie={...i,...d}),a.autoClearCookies,r.j,a.manageScriptTags,(e=>{const{O:t,X:o,Y:n,Z:s,B:a}=g.o;for(let c of e){const e=t[c],r=e.services||{},i=J(r)&&h(r)||[];o[c]={},n[c]=[],s[c]=[],e.readOnly&&(a.push(c),n[c]=i),g.ne.ae[c]={};for(let e of i){const t=r[e];t.he=!1,o[c][e]=t}}})(f),(()=>{if(!g.t.manageScriptTags)return;const e=g.o,t=M(document,'script['+c+']');for(const o of t){let t=N(o,c),n=o.dataset.service||'',s=!1;if(t&&'!'===t.charAt(0)&&(t=t.slice(1),s=!0),'!'===n.charAt(0)&&(n=n.slice(1),s=!0),v(e.P,t)&&(e.oe.push({Ce:o,ye:!1,xe:s,we:t,Se:n}),n)){const o=e.X[t];o[n]||(o[n]={he:!1})}}})(),Ne((()=>{const e=g.o.i.language.autoDetect;if(e){const t={browser:navigator.languages&&navigator.languages.length?navigator.languages:[navigator.language],document:[document.documentElement.lang]}[e];if($(t))for(const e of t){const t=Ee(e);if(t)return t}}return ke()})())})(e),t.G)return;(()=>{const e=g.o,t=g.t;let n=Be();t.cookie.useLocalStorage&&(new Date).getTime()>(n.expirationTime||0)&&(Fe(t.cookie.name),n={});const{categories:s,services:a,consentId:c,consentTimestamp:r,lastConsentTimestamp:i,data:l,revision:d}=n,_=$(s);e.p=n,e.M=c;const f=!!c&&G(c);if(e.C=at(r),e.S=at(i),e.h=void 0!==l?l:null,e.j&&f&&d!==t.revision&&(e.I=!1),e.T=!(f&&e.I&&e.C&&e.S&&_),e.T,(()=>{const e=g.o;for(const t of e.P){const n=e.O[t];if(n.readOnly||n.enabled&&!q()){e.$.push(t);const n=e.X[t]||{};for(let s in n)e.Z[t].push(s),e.i.mode!==o||v(e.Y[t],s)||e.Y[t].push(s)}}})(),e.T)t.mode===o&&(e.R=[...e.$]);else{for(const t of e.P){const o=a&&a[t],n=h(e.X[t]);v(e.B,t)?e.Y[t]=n:$(o)?e.Y[t]=o.filter(e=>v(n,e)):v(s,t)||(e.Y[t]=[])}e.Z={...e.Y},W([...e.B,...s.filter(t=>v(e.P,t))])}})();const i=st();let l;if(await Ae().catch(e=>{l=e})&&(ee(null,r=ot,he,Ie),g.o.T&&!g.t.lazyHtmlGeneration&&De(r,Ie),g.t.lazyHtmlGeneration||he(r,Ie),!n.autoShow||st()||q()||Xe(!0)),i?(Z(),Y(s.le)):n.mode===o&&Z(),l)throw l}var r},e.setCookieData=e=>{let t,o=e.value,n=e.mode,s=!1;const a=g.o;if('update'===n){a.h=t=nt('data');const e=typeof t==typeof o;if(e&&'object'==typeof t){!t&&(t={});for(let e in o)t[e]!==o[e]&&(t[e]=o[e],s=!0)}else!e&&t||t===o||(t=o,s=!0)}else t=o,s=!0;return s&&(a.h=t,a.p.data=t,Pe(!0)),s},e.setLanguage=async(e,t)=>{if(!Ee(e))return!1;const o=g.o;return!(e===ke()&&!0!==t||!await Ae(e)||(o.D&&De(ot,Ie),o.A&&(et(),he(ot,Ie)),He(),0))},e.show=Xe,e.showPreferences=Ze,e.validConsent=st,e.validCookie=e=>''!==$e(e,!0)},'object'==typeof exports&&'undefined'!=typeof module?t(exports):'function'==typeof define&&define.amd?define(['exports'],t):t((e='undefined'!=typeof globalThis?globalThis:e||self).CookieConsent={});
@@ -0,0 +1,4 @@
1
+ {% load static %}{% if config %}{{ config|json_script:"wagtail-cookie-consent-config" }}
2
+ <link rel="stylesheet" href="{% static 'wagtail_cookie_consent/vendor/cookieconsent.css' %}">
3
+ <script src="{% static 'wagtail_cookie_consent/js/cookie-consent.js' %}"></script>
4
+ <script src="{% static 'wagtail_cookie_consent/vendor/cookieconsent.umd.js' %}" defer></script>{% endif %}
@@ -0,0 +1,31 @@
1
+ from django import template
2
+ from django.forms.utils import flatatt
3
+ from django.utils.html import format_html
4
+ from django.utils.translation import gettext as _
5
+
6
+ from ..banner import banner_config, banner_settings
7
+
8
+
9
+ register = template.Library()
10
+
11
+
12
+ @register.inclusion_tag(
13
+ "wagtail_cookie_consent/cookie_consent.html", takes_context=True
14
+ )
15
+ def cookie_consent(context):
16
+ """The consent banner. It renders nothing when the banner is off."""
17
+ return {"config": banner_config(context)}
18
+
19
+
20
+ @register.simple_tag(takes_context=True)
21
+ def cookie_settings_link(context, label=None, **attrs):
22
+ """A button that reopens the banner's settings, so a visitor can change
23
+ their choice. It renders nothing when the banner is off. Keyword arguments
24
+ become HTML attributes, for example class="..."."""
25
+ if banner_settings(context) is None:
26
+ return ""
27
+ return format_html(
28
+ '<button type="button" data-cc="show-preferencesModal"{}>{}</button>',
29
+ flatatt(attrs),
30
+ label or _("Cookie settings"),
31
+ )