diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac52643 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +/node_modules/ +.idea +yarn-error.log diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..958b5a3 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v14 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..34940f6 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +*.hbs +Resources/Public +Resources/Private/Fusion +Resources/Private/JavaScript/*Compiled.js +Resources/Private/KlaroTranslations/*.yml diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..e0703ac --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "phpVersion": "7.2" +} diff --git a/Classes/DataSource/ConsentGroupsDataSource.php b/Classes/DataSource/ConsentGroupsDataSource.php new file mode 100644 index 0000000..f132b21 --- /dev/null +++ b/Classes/DataSource/ConsentGroupsDataSource.php @@ -0,0 +1,33 @@ +groups as $name => $group) { + $label = isset($group["title"]) + ? $CookieCutterConfig->translate($group["title"]) + : $name; + $options[$name] = ['label' => $label]; + } + return $options; + } +} diff --git a/Classes/Eel/Helper/CookieCutter.php b/Classes/Eel/Helper/CookieCutter.php new file mode 100644 index 0000000..2f6d079 --- /dev/null +++ b/Classes/Eel/Helper/CookieCutter.php @@ -0,0 +1,367 @@ +replaceTags("iframe", $markup, function ($tag) { + // IMPORTANT: keep the order here or update all tests! + $tag = $this->addNeverBlockAttribute($tag); + return $tag; + }); + } + + public function neverBlockScripts(string $markup): string + { + return $this->replaceTags("script", $markup, function ($tag) { + // IMPORTANT: keep the order here or update all tests! + $tag = $this->addNeverBlockAttribute($tag); + return $tag; + }); + } + + /** + * @param string $markup + * @return string + */ + public function blockIframes( + string $markup, + bool $enabled = true, + string $groupOverride = null + ): string { + if (!$enabled) { + return $markup; + } + + return $this->replaceTags("iframe", $markup, function ( + $tag, + $blockConfig + ) use ($groupOverride) { + // IMPORTANT: keep the order here or update all tests! + $tag = TagHelper::tagRenameAttribute( + $tag, + TagHelper::SRC, + TagHelper::DATA_SRC + ); + $tag = $this->addDataNameAttribute( + $tag, + $blockConfig, + $groupOverride + ); + $tag = TagHelper::tagAddAttribute($tag, "style", "display: none;"); + $tag = $this->addDataOptionsAttribute($tag, $blockConfig); + + return $tag; + }); + } + + /** + * @param string $markup + * @return string + */ + public function blockScripts( + string $markup, + bool $enabled = true, + string $groupOverride = null + ): string { + if (!$enabled) { + return $markup; + } + + return $this->replaceTags("script", $markup, function ( + $tag, + $blockConfig + ) use ($groupOverride) { + // IMPORTANT: keep the order here or update all tests! + $tag = TagHelper::tagRenameAttribute( + $tag, + TagHelper::SRC, + TagHelper::DATA_SRC + ); + $hasType = TagHelper::tagHasAttribute($tag, TagHelper::TYPE); + if (TagHelper::tagHasAttribute($tag, TagHelper::DATA_SRC)) { + if ($hasType) { + $tag = TagHelper::tagRenameAttribute( + $tag, + TagHelper::TYPE, + TagHelper::DATA_TYPE + ); + $tag = TagHelper::tagAddAttribute( + $tag, + TagHelper::TYPE, + TagHelper::TEXT_PLAIN + ); + } + } else { + // nor src so we have to "break" the tag by setting the type + if ($hasType) { + $tag = TagHelper::tagRenameAttribute( + $tag, + TagHelper::TYPE, + TagHelper::DATA_TYPE + ); + $tag = TagHelper::tagAddAttribute( + $tag, + TagHelper::TYPE, + TagHelper::TEXT_PLAIN + ); + } else { + $tag = TagHelper::tagAddAttribute( + $tag, + TagHelper::TYPE, + TagHelper::TEXT_PLAIN + ); + $tag = TagHelper::tagAddAttribute( + $tag, + TagHelper::DATA_TYPE, + TagHelper::TEXT_JAVASCRIPT + ); + } + } + $tag = $this->addDataNameAttribute( + $tag, + $blockConfig, + $groupOverride + ); + $tag = $this->addDataOptionsAttribute($tag, $blockConfig); + + return $tag; + }); + } + + private function addNeverBlockAttribute(string $tag): string + { + if (!TagHelper::tagHasAttribute($tag, TagHelper::DATA_NEVER_BLOCK)) { + return TagHelper::tagAddAttribute( + $tag, + TagHelper::DATA_NEVER_BLOCK + ); + } + return $tag; + } + + private function addDataNameAttribute( + string $tag, + array $blockConfig, + string $groupOverride = null + ): string { + if (!TagHelper::tagHasAttribute($tag, TagHelper::DATA_NAME)) { + $value = $groupOverride + ? $groupOverride + : $blockConfig[self::SETTINGS_GROUP]; + return TagHelper::tagAddAttribute( + $tag, + TagHelper::DATA_NAME, + $value + ); + } + return $tag; + } + + private function addDataOptionsAttribute( + string $tag, + array $blockConfig + ): string { + if (isset($blockConfig[self::SETTINGS_OPTIONS])) { + $encodedOptions = htmlspecialchars( + json_encode($blockConfig[self::SETTINGS_OPTIONS]), + ENT_QUOTES, + 'UTF-8' + ); + return TagHelper::tagAddAttribute( + $tag, + TagHelper::DATA_OPTIONS, + $encodedOptions + ); + } + + return $tag; + } + + /** + * @param string $haystack + * @param string $needle + * @return bool + */ + private function tagContains(string $haystack, string $needle): bool + { + return !!strpos($haystack, $needle) !== false; + } + + /** + * @param string $tag + * @return array + */ + private function getBlockConfig(string $tag): array + { + if (!$this->patterns) { + return $this->buildBlockConfigForPatternConfig(); + } + + foreach ($this->patterns as $pattern => $config) { + if ($this->tagContains($tag, $pattern)) { + return $this->buildBlockConfigForPatternConfig($config); + } + } + return $this->buildBlockConfigForPatternConfig(); + } + + /** + * @param array|null $config + * @return array + */ + private function buildBlockConfigForPatternConfig( + array $config = null + ): array { + $fallbackBlocked = isset($this->block) ? $this->block : false; + $fallbackGroup = isset($this->defaultGroup) + ? $this->defaultGroup + : self::DEFAULT_GROUP; + + // no config early return + if (!$config) { + return [ + self::SETTINGS_BLOCK => $fallbackBlocked, + self::SETTINGS_GROUP => $fallbackGroup, + ]; + } + + $blocked = isset($config[self::SETTINGS_BLOCK]) + ? $config[self::SETTINGS_BLOCK] + : $fallbackBlocked; + $group = isset($config[self::SETTINGS_GROUP]) + ? $config[self::SETTINGS_GROUP] + : $fallbackGroup; + $options = isset($config[self::SETTINGS_OPTIONS]) + ? $config[self::SETTINGS_OPTIONS] + : null; + + return [ + self::SETTINGS_BLOCK => $blocked, + self::SETTINGS_GROUP => $group, + self::SETTINGS_OPTIONS => $options, + ]; + } + + /** + * @param string $tagName + * @param string $text + * @param callable $hitCallback + * @return string + */ + private function replaceTags( + string $tagName, + string $text, + callable $hitCallback + ): string { + $regex = '/<' . $tagName . '.*?>/'; + + return preg_replace_callback( + $regex, + function ($hits) use ($hitCallback) { + $tag = $hits[0]; + + if (!$hitCallback) { + return $tag; + } + + $neverBlock = $this->tagContains( + $tag, + TagHelper::DATA_NEVER_BLOCK + ); + if ($neverBlock) { + return $tag; + } + + $hasBlockingAttributes = + TagHelper::tagHasAttribute($tag, TagHelper::DATA_SRC) || + TagHelper::tagHasAttribute( + $tag, + TagHelper::TYPE, + TagHelper::TEXT_PLAIN + ) || + TagHelper::tagHasAttribute( + $tag, + TagHelper::DATA_TYPE, + TagHelper::TEXT_JAVASCRIPT + ); + // We do not check if TagHelper::DATA_NAME is present, because we might want the editor + // to choose a group, e.g. in the inspector and still block tags. + if ($hasBlockingAttributes) { + return $tag; + } + + $blockConfig = $this->getBlockConfig($tag); + + if ($blockConfig[self::SETTINGS_BLOCK]) { + return call_user_func($hitCallback, $tag, $blockConfig); + } else { + return $tag; + } + }, + $text + ); + } + + private function validateGroup(string $name = null) + { + if ($name && !isset($this->groups[$name])) { + throw new \InvalidArgumentException( + 'The group "' . + $name . + '" could not be found in your config. Expected config for "Sandstorm.CookieCutter.groups.' . + $name . + '"', + 1596469884 + ); + } + } + + /** + * All methods are considered safe, i.e. can be executed from within Eel + * + * @param string $methodName + * @return boolean + */ + public function allowsCallOfMethod($methodName) + { + return true; + } +} diff --git a/Classes/Eel/Helper/CookieCutterConfig.php b/Classes/Eel/Helper/CookieCutterConfig.php new file mode 100644 index 0000000..7d02313 --- /dev/null +++ b/Classes/Eel/Helper/CookieCutterConfig.php @@ -0,0 +1,33 @@ +setting($path); + if ($settingsValue) { + return (new TranslationHelper())->translate($settingsValue); + } else { + return (new TranslationHelper())->translate($path); + } + } + + /** + * All methods are considered safe, i.e. can be executed from within Eel + * + * @param string $methodName + * @return boolean + */ + public function allowsCallOfMethod($methodName) + { + return true; + } +} diff --git a/Classes/FusionObjects/ConfigImplementation.php b/Classes/FusionObjects/ConfigImplementation.php new file mode 100644 index 0000000..41bf482 --- /dev/null +++ b/Classes/FusionObjects/ConfigImplementation.php @@ -0,0 +1,208 @@ + $groupConfig) { + $translations[$name] = $this->buildAppTranslation($groupConfig); + array_push($apps, $this->buildAppConfig($name, $groupConfig)); + } + + if ($purposes && sizeof($purposes)) { + $translations["purposes"] = $purposes; + } + } + + $replaceVariables = [ + '$php_replaced__apps' => json_encode($apps, JSON_PRETTY_PRINT), + '$php_replaced__translations' => json_encode( + $translations, + JSON_PRETTY_PRINT + ), + '$php_replaced__handleConsentOptions' => json_encode( + $handleConsentOptions, + JSON_PRETTY_PRINT + ), + + '$php_replaced__storageMethod' => $this->toJsString($storageMethod), + '$php_replaced__cookieName' => $this->toJsString($cookieName), + '$php_replaced__cookieExpiresAfterDays' => $cookieExpiresAfterDays, + '$php_replaced__cookieDomain' => $this->toJsString($cookieDomain), + '$php_replaced__privacyPolicyUrl' => $this->toJsString( + $privacyPolicyUrl + ), + '$php_replaced__default' => $this->toJsBoolean($default), + '$php_replaced__mustConsent' => $this->toJsBoolean($mustConsent), + '$php_replaced__acceptAll' => $this->toJsBoolean($acceptAll), + '$php_replaced__hideDeclineAll' => $this->toJsBoolean( + $hideDeclineAll + ), + ]; + + return $this->renderConfig($replaceVariables); + } + + private function renderConfig(array $variables): string + { + $fileConents = file_get_contents( + 'resource://Sandstorm.CookieCutter/Private/JavaScript/klaroConfigTemplateCompiled.js' + ); + $template = preg_replace(self::PHP_REMOVE_REGEX, "", $fileConents); + + $result = strtr($template, $variables); + // We need to convert the placeholder, to an actual function name in the template. + // We do this in a separate step as json_encode does not support removing "" + $result = preg_replace( + self::CONSENT_HANDLER_PLACEHOLDER_REGEX, + "handleConsent", + $result + ); + + return $result; + } + + private function toJsString(?string $string): string + { + if (!$string) { + return "null"; + } + return '"' . $string . '"'; + } + + private function toJsBoolean(bool $bool): string + { + return $bool ? "true" : "false"; + } + + private function buildAppConfig(string $name, array $groupConfig): array + { + $result = [ + "name" => $name, + "title" => isset($groupConfig["title"]) + ? $groupConfig["title"] + : $name, + "purposes" => + isset($groupConfig["purposes"]) && + is_array($groupConfig["purposes"]) + ? $groupConfig["purposes"] + : [], + "callback" => self::CONSENT_HANDLER_PLACEHOLDER, + "cookies" => + isset($groupConfig[self::CONSENT_CONFIG]["cookies"]) && + is_array($groupConfig[self::CONSENT_CONFIG]["cookies"]) + ? $groupConfig[self::CONSENT_CONFIG]["cookies"] + : [], + ]; + + if (isset($groupConfig[self::CONSENT_CONFIG]["default"])) { + $result["default"] = $groupConfig[self::CONSENT_CONFIG]["default"]; + } + + if (isset($groupConfig[self::CONSENT_CONFIG]["required"])) { + $result["required"] = + $groupConfig[self::CONSENT_CONFIG]["required"]; + } + + return $result; + } + + private function buildAppTranslation(array $groupConfig): array + { + $result = []; + if (isset($groupConfig["title"])) { + $result["title"] = $groupConfig["title"]; + } + if (isset($groupConfig["description"])) { + $result["description"] = $groupConfig["description"]; + } + return $result; + } +} diff --git a/Classes/TagHelper.php b/Classes/TagHelper.php new file mode 100644 index 0000000..3d1cfe4 --- /dev/null +++ b/Classes/TagHelper.php @@ -0,0 +1,185 @@ +" or "/>" + + /** + * @return string + */ + private static function buildMatchEndOfOpeningTagReqex(): string + { + return '/(?<[a-z]+.*?)(?>|\/>)/'; + } + + /** + * @param string $name + * @return string + */ + private static function buildMatchAttributeNameWithAnyValueReqex( + string $name + ): string { + $nameQuoted = self::escapeReqexCharsInString($name); + return '/(?
<.*? )(?' .
+            $nameQuoted .
+            ')(?=")(?.*?)(?".*?>)/';
+    }
+
+    /**
+     * @param string $name
+     * @return string
+     */
+    private static function buildMatchAttributeNameReqex(string $name): string
+    {
+        $nameQuoted = self::escapeReqexCharsInString($name);
+        return '/(?
<.*? )(?' . $nameQuoted . ')(?.*?>)/';
+    }
+
+    /**
+     * @param string $name
+     * @param string $value
+     * @return string
+     */
+    private static function buildMatchAttributeNameWithSpecificValueReqex(
+        string $name,
+        string $value
+    ): string {
+        $nameQuoted = self::escapeReqexCharsInString($name);
+        $valueQuoted = self::escapeReqexCharsInString($value);
+        return '/(?
<.*? )(?' .
+            $nameQuoted .
+            ')(?=")(?' .
+            $valueQuoted .
+            ')(?".*?>)/';
+    }
+}
diff --git a/Configuration/NodeTypes.Mixin.ConsentGroup.yaml b/Configuration/NodeTypes.Mixin.ConsentGroup.yaml
new file mode 100644
index 0000000..5151cdf
--- /dev/null
+++ b/Configuration/NodeTypes.Mixin.ConsentGroup.yaml
@@ -0,0 +1,15 @@
+"Sandstorm.CookieCutter:Mixin.ConsentGroup":
+  abstract: true
+  properties:
+    consentGroup:
+      type: string
+      ui:
+        label: "Groups"
+        reloadIfChanged: true
+        inspector:
+          group: "html"
+          position: "200"
+          editor: Neos.Neos/Inspector/Editors/SelectBoxEditor
+          editorOptions:
+            placeholder: Choose
+            dataSourceIdentifier: sandstorm-consent-groups
diff --git a/Configuration/Settings.Translations.yaml b/Configuration/Settings.Translations.yaml
new file mode 100644
index 0000000..edcd64d
--- /dev/null
+++ b/Configuration/Settings.Translations.yaml
@@ -0,0 +1,41 @@
+################################################################################################
+# IMPORTANT: This file was auto-generated as part of the build process to convert translations #
+# provided by klaro. -> see package.json -> "yarn run build:translations"                      #
+################################################################################################
+
+Sandstorm:
+  CookieCutter:
+    translations:
+      consentModal:
+        title: "Sandstorm.CookieCutter:Klaro:consentModal.title"
+        description: "Sandstorm.CookieCutter:Klaro:consentModal.description"
+        privacyPolicy:
+          name: "Sandstorm.CookieCutter:Klaro:consentModal.privacyPolicy.name"
+          text: "Sandstorm.CookieCutter:Klaro:consentModal.privacyPolicy.text"
+      consentNotice:
+        changeDescription: "Sandstorm.CookieCutter:Klaro:consentNotice.changeDescription"
+        description: "Sandstorm.CookieCutter:Klaro:consentNotice.description"
+        learnMore: "Sandstorm.CookieCutter:Klaro:consentNotice.learnMore"
+        privacyPolicy:
+          name: "Sandstorm.CookieCutter:Klaro:consentNotice.privacyPolicy.name"
+        imprint:
+          name: "Sandstorm.CookieCutter:Klaro:consentNotice.imprint.name"
+      ok: "Sandstorm.CookieCutter:Klaro:ok"
+      save: "Sandstorm.CookieCutter:Klaro:save"
+      decline: "Sandstorm.CookieCutter:Klaro:decline"
+      close: "Sandstorm.CookieCutter:Klaro:close"
+      acceptAll: "Sandstorm.CookieCutter:Klaro:acceptAll"
+      acceptSelected: "Sandstorm.CookieCutter:Klaro:acceptSelected"
+      app:
+        disableAll:
+          title: "Sandstorm.CookieCutter:Klaro:app.disableAll.title"
+          description: "Sandstorm.CookieCutter:Klaro:app.disableAll.description"
+        optOut:
+          title: "Sandstorm.CookieCutter:Klaro:app.optOut.title"
+          description: "Sandstorm.CookieCutter:Klaro:app.optOut.description"
+        required:
+          title: "Sandstorm.CookieCutter:Klaro:app.required.title"
+          description: "Sandstorm.CookieCutter:Klaro:app.required.description"
+        purposes: "Sandstorm.CookieCutter:Klaro:app.purposes"
+        purpose: "Sandstorm.CookieCutter:Klaro:app.purpose"
+      poweredBy: "Sandstorm.CookieCutter:Klaro:poweredBy"
diff --git a/Configuration/Settings.yaml b/Configuration/Settings.yaml
new file mode 100644
index 0000000..bb601d4
--- /dev/null
+++ b/Configuration/Settings.yaml
@@ -0,0 +1,73 @@
+Neos:
+  Neos:
+    fusion:
+      autoInclude:
+        "Sandstorm.CookieCutter": true
+  Fusion:
+    defaultContext:
+      "CookieCutter": Sandstorm\CookieCutter\Eel\Helper\CookieCutter
+      "CookieCutterConfig": Sandstorm\CookieCutter\Eel\Helper\CookieCutterConfig
+
+Sandstorm:
+  CookieCutter:
+    consent:
+      privacyPolicyUrl: /privacy
+      storageMethod: cookie
+      cookieName: cookie_cutter
+      cookieExpiresAfterDays: 120
+      cookieDomain: .nip.io
+      mustConsent: true
+      # button in consent modal next to save button
+      acceptAll: true
+      # button in consent modal on the right -> decline
+      hideDeclineAll: false
+      default: true
+    groups:
+      default:
+        title: Sandstorm.CookieCutter:Groups:default.title
+        description: Sandstorm.CookieCutter:Groups:default.description
+        consent:
+          required: true
+          cookies:
+            - /^ga/i
+      media:
+        title: Sandstorm.CookieCutter:Groups:media.title
+        description: Sandstorm.CookieCutter:Groups:media.description
+        purposes:
+          - videoembeds
+          - analytics
+    purposes:
+      analytics: Analytics
+      videoembeds: Video Embeds
+    elements:
+      block: true
+      group: default
+      options:
+        message: Sandstorm.CookieCutter:Elements:options.message
+        messageClass: block-them-all-message
+      patterns:
+        # Slick
+        "Packages/Unikka.Slick":
+          type: script
+          block: false
+
+        # Jonnitto.Plyr
+        "Packages/Jonnitto.Plyr":
+          type: script
+          group: media
+          block: true
+        "https://www.youtube.com/embed/":
+          type: iframe
+          block: true
+          group: media
+
+        # anchor.fm
+        #                "https://anchor.fm":
+        #                    type: iframe
+        #                    group: media
+        #                    block: true
+
+        # Neos
+        "Packages/Neos.Neos":
+          type: script
+          block: false
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..4f05b89
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,7 @@
+Copyright 2020 sandstorm|media
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
index 6be0464..91abc9d 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,19 @@
 # Sandstorm.CookieCutter
+
+This Neos package provides a general approach for blocking elements like script tags and iframes before the markup reaches the browser and therefore provides a general approach for blocking cookies or other concepts of tracking user behaviour. It also provides a UI in the browser for displaying a cookie-consent and partially unblocking groups of elements.
+
+**This is what you can do so far:**
+
+* verbosely block elements on the server before the markup is send to the client
+* choose between two blocking approaches:
+    * block everything and whitelist exceptions (recommended)
+    * blacklist elements to be blocked
+* block elements from all packages, without the need to customize or override
+* block content created by editors, e.g. if they copy pasted HTML snippetss
+* enable/disable groups of elements through a cookie consent in the frontend
+* localize the frontend using Settings.yaml and Xliff or directly use content translated by your editors
+* start with useful defaults concerning configuration and styling
+* easily customize when needed
+
+
+WIP
diff --git a/Resources/Private/Fusion/Config.Translations.fusion b/Resources/Private/Fusion/Config.Translations.fusion
new file mode 100644
index 0000000..c0c2094
--- /dev/null
+++ b/Resources/Private/Fusion/Config.Translations.fusion
@@ -0,0 +1,31 @@
+################################################################################################
+# IMPORTANT: This file was auto-generated as part of the build process to convert translations #
+# provided by klaro. -> see package.json -> "yarn run build:translations"                      #
+################################################################################################
+
+prototype(Sandstorm.CookieCutter:Config.Translations) < prototype(Neos.Fusion:DataStructure) {
+    consentModal.title = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.consentModal.title")}
+    consentModal.description = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.consentModal.description")}
+    consentModal.privacyPolicy.name = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.consentModal.privacyPolicy.name")}
+    consentModal.privacyPolicy.text = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.consentModal.privacyPolicy.text")}
+    consentNotice.changeDescription = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.consentNotice.changeDescription")}
+    consentNotice.description = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.consentNotice.description")}
+    consentNotice.learnMore = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.consentNotice.learnMore")}
+    consentNotice.privacyPolicy.name = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.consentNotice.privacyPolicy.name")}
+    consentNotice.imprint.name = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.consentNotice.imprint.name")}
+    ok = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.ok")}
+    save = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.save")}
+    decline = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.decline")}
+    close = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.close")}
+    acceptAll = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.acceptAll")}
+    acceptSelected = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.acceptSelected")}
+    app.disableAll.title = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.app.disableAll.title")}
+    app.disableAll.description = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.app.disableAll.description")}
+    app.optOut.title = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.app.optOut.title")}
+    app.optOut.description = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.app.optOut.description")}
+    app.required.title = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.app.required.title")}
+    app.required.description = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.app.required.description")}
+    app.purposes = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.app.purposes")}
+    app.purpose = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.app.purpose")}
+    poweredBy = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.poweredBy")}
+}
diff --git a/Resources/Private/Fusion/Config.fusion b/Resources/Private/Fusion/Config.fusion
new file mode 100644
index 0000000..42bfbe9
--- /dev/null
+++ b/Resources/Private/Fusion/Config.fusion
@@ -0,0 +1,42 @@
+prototype(Sandstorm.CookieCutter:Config) {
+    @class = 'Sandstorm\\CookieCutter\\FusionObjects\\ConfigImplementation'
+
+    translations = Sandstorm.CookieCutter:Config.Translations
+
+    handleConsentOptions.message = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.elements.options.message")}
+    handleConsentOptions.messageClass = ${Configuration.setting("Sandstorm.CookieCutter.elements.options.messageClass")}
+
+    consent = Neos.Fusion:DataStructure {
+        privacyPolicyUrl = ${Configuration.setting("Sandstorm.CookieCutter.consent.privacyPolicyUrl")}
+        storageMethod = ${Configuration.setting("Sandstorm.CookieCutter.consent.storageMethod")}
+        cookieName = ${Configuration.setting("Sandstorm.CookieCutter.consent.cookieName")}
+        cookieExpiresAfterDays = ${Configuration.setting("Sandstorm.CookieCutter.consent.cookieExpiresAfterDays")}
+        cookieDomain = ${Configuration.setting("Sandstorm.CookieCutter.consent.cookieDomain")}
+        default = ${Configuration.setting("Sandstorm.CookieCutter.consent.default")}
+        mustConsent = ${Configuration.setting("Sandstorm.CookieCutter.consent.mustConsent")}
+        acceptAll = ${Configuration.setting("Sandstorm.CookieCutter.consent.acceptAll")}
+        hideDeclineAll = ${Configuration.setting("Sandstorm.CookieCutter.consent.hideDeclineAll")}
+    }
+
+    groups = Neos.Fusion:Map {
+        items = ${Configuration.setting("Sandstorm.CookieCutter.groups")}
+        itemRenderer = Neos.Fusion:DataStructure {
+            name = ${itemKey}
+            title = ${CookieCutterConfig.translate(item.title)}
+            description = ${CookieCutterConfig.translate(item.description)}
+            purposes = ${item.purposes}
+            consent = Neos.Fusion:DataStructure {
+                required = ${item.consent.required}
+                default = ${item.consent.default}
+                cookies = ${item.consent.cookies}
+            }
+        }
+    }
+
+    purposes = Neos.Fusion:Map {
+        items = ${Configuration.setting("Sandstorm.CookieCutter.purposes")}
+        itemRenderer = Neos.Fusion:Value {
+            value = ${CookieCutterConfig.translate(item)}
+        }
+    }
+}
diff --git a/Resources/Private/Fusion/Consent.fusion b/Resources/Private/Fusion/Consent.fusion
new file mode 100644
index 0000000..2f617d9
--- /dev/null
+++ b/Resources/Private/Fusion/Consent.fusion
@@ -0,0 +1,20 @@
+# Klaro cookie consent, see https://klaro.kiprotect.com/
+prototype(Sandstorm.CookieCutter:Consent) < prototype(Neos.Fusion:Component) {
+    config = Sandstorm.CookieCutter:Config
+    js = Neos.Fusion:ResourceUri {
+        path = 'resource://Sandstorm.CookieCutter/Public/Klaro/klaro-no-css_v0.4.27.js'
+    }
+
+    css = Neos.Fusion:ResourceUri {
+        path = 'resource://Sandstorm.CookieCutter/Public/Klaro/klaro_v0.4.27.min.css'
+    }
+
+
+
+    renderer = afx`
+        
+        
+        
+    `
+    @process.neverBlockScripts = ${CookieCutter.neverBlockScripts(value)}
+}
diff --git a/Resources/Private/Fusion/Root.fusion b/Resources/Private/Fusion/Root.fusion
new file mode 100644
index 0000000..fe1d560
--- /dev/null
+++ b/Resources/Private/Fusion/Root.fusion
@@ -0,0 +1 @@
+include: **/*.fusion
diff --git a/Resources/Private/JavaScript/klaroConfigTemplate.js b/Resources/Private/JavaScript/klaroConfigTemplate.js
new file mode 100644
index 0000000..8132705
--- /dev/null
+++ b/Resources/Private/JavaScript/klaroConfigTemplate.js
@@ -0,0 +1,226 @@
+/* PHP_REMOVE_START */
+
+// Here we define variables to have a valid JS file, which makes development
+// more fun. They will later be replaced by the `ConsentConfigImplementation.php`.
+// We prefix variables with `$php_replaced__` to show that they will be replaced.
+
+// This file will be processed the following way:
+//
+// 1. (manually) Make sure you create an new build of this file to get a template that also works
+//    in old browsers -> `yarn run build:template`. This will create a file "klaroConfigTemplateCompiled.js".
+//    This file will be processed in the next steps!
+//
+// 2. ConsentConfigImplementation.php will remove content between "PHP_REMOVE_START" and "PHP_REMOVE_END"
+//    to remove variable definitions, that are only used for a better dev experience.
+//
+// 3. ConsentConfigImplementation.php will remove the callback placeholder for all apps with the actual callback.
+//    This is necessary as we are using json_encode. Json files do not support Js variables or callbacks.
+//
+//    Before:    { "name": "default", "title": "Default", "callback": "### CONSENT_HANDLER ###" }
+//    After:     { "name": "default", "title": "Default", "callback": handleConsent }
+//
+// IMPORTANT FOR DEV: When changing the template make sure to flush the cache, otherwise changes will not
+// show in the browser, even after reloading!
+
+var $php_replaced__apps,
+    $php_replaced__translations,
+    $php_replaced__privacyPolicyUrl,
+    $php_replaced__cookieDomain,
+    $php_replaced__cookieExpiresAfterDays,
+    $php_replaced__storageMethod,
+    $php_replaced__cookieName,
+    $php_replaced__mustConsent,
+    $php_replaced__default,
+    $php_replaced__acceptAll,
+    $php_replaced__hideDeclineAll;
+var $php_replaced__handleConsentOptions = {
+    message: "Message",
+    messageClass: "messageClass",
+};
+
+/* PHP_REMOVE_END */
+
+(function () {
+    window.klaroConfig = {
+        // IMPORTANT: we disable the language handling of klaro because
+        // we want to use translations provided the Neos-way
+        lang: "all",
+
+        // How Klaro should store the user's preferences. It can be either 'cookie'
+        // (the default) or 'localStorage'.
+        storageMethod: $php_replaced__storageMethod,
+
+        // You can customize the name of the cookie that Klaro uses for storing
+        // user consent decisions. If undefined, Klaro will use 'klaro'.
+        cookieName: $php_replaced__cookieName,
+
+        // You can also set a custom expiration time for the Klaro cookie.
+        // By default, it will expire after 120 days.
+        cookieExpiresAfterDays: $php_replaced__cookieExpiresAfterDays,
+
+        // You can change to cookie domain for the consent manager itself.
+        // Use this if you want to get consent once for multiple matching domains.
+        // If undefined, Klaro will use the current domain.
+        cookieDomain: $php_replaced__cookieDomain,
+
+        // Put a link to your privacy policy here (relative or absolute).
+        privacyPolicy: $php_replaced__privacyPolicyUrl,
+
+        // Defines the default state for applications (true=enabled by default).
+        default: $php_replaced__default,
+
+        // If "mustConsent" is set to true, Klaro will directly display the consent
+        // manager modal and not allow the user to close it before having actively
+        // consented or declines the use of third-party apps.
+        mustConsent: $php_replaced__mustConsent,
+
+        // Show "accept all" to accept all apps instead of "ok" that only accepts
+        // required and "default: true" apps
+        acceptAll: $php_replaced__acceptAll,
+
+        // replace "decline" with cookie manager modal
+        hideDeclineAll: $php_replaced__hideDeclineAll,
+
+        translations: {
+            all: $php_replaced__translations,
+        },
+
+        apps: $php_replaced__apps,
+    };
+
+    function handleConsent(consent, app) {
+        // We nee a stable class to identify messages so we can remove them later.
+        const PERMANENT_MESSAGE_CLASS = "block-them-all-message";
+        // -> see Settings.yaml and/or Config.fusion
+        const handleConsentOptions = $php_replaced__handleConsentOptions;
+
+        if (consent) {
+            removeMessagesForConsentGroup(app.name);
+            unhideIframesForGroup(app.name);
+        } else {
+            let options = null;
+            document
+                .querySelectorAll(`*[data-name="${app.name}"]`)
+                .forEach((element) => {
+                    try {
+                        // more robust handling of maybe broken JSON
+                        options = JSON.parse(element.dataset.options);
+                    } catch (e) {
+                        // Do nothing
+                    }
+
+                    // 1. We set default values
+                    let message =
+                        handleConsentOptions.message || "NO MESSAGE CONFIGURED";
+                    let messageClass = buildMessageClass(
+                        handleConsentOptions.messageClass
+                    );
+                    let messagePosition = "before";
+                    let targetElements = [];
+
+                    if (element.tagName === "IFRAME") {
+                        targetElements = [element];
+                    }
+
+                    // 2. We override some, if options are present
+                    if (options) {
+                        message = options.message || message;
+                        messageClass = options.messageClass
+                            ? buildMessageClass(options.messageClass)
+                            : messageClass;
+                        messagePosition = options.messagePosition
+                            ? options.messagePosition
+                            : messagePosition;
+                        targetElements = options.target
+                            ? Array.from(
+                                  document.querySelectorAll(options.target)
+                              )
+                            : targetElements;
+                    }
+
+                    if (targetElements.length) {
+                        targetElements.forEach((element) =>
+                            addMessage(
+                                element,
+                                message,
+                                app,
+                                messagePosition,
+                                messageClass
+                            )
+                        );
+                    }
+                });
+        }
+        function removeMessagesForConsentGroup(group) {
+            const messageSelector = `.${PERMANENT_MESSAGE_CLASS}[data-name="${group}"]`;
+            document.querySelectorAll(messageSelector).forEach((item) => {
+                item.remove();
+            });
+        }
+
+        function unhideIframesForGroup(group) {
+            const iframeSelector = `iframe[data-name="${group}"]`;
+            document.querySelectorAll(iframeSelector).forEach((item) => {
+                item.style.display = "block";
+            });
+        }
+
+        function buildMessageClass(messageClass) {
+            if (messageClass && messageClass !== PERMANENT_MESSAGE_CLASS) {
+                return `${PERMANENT_MESSAGE_CLASS} ${handleConsentOptions.messageClass}`;
+            }
+            return PERMANENT_MESSAGE_CLASS;
+        }
+
+        function addMessage(
+            targetElement,
+            message,
+            app,
+            messagePosition,
+            messageClass
+        ) {
+            const newElement = document.createElement("div");
+            const classNames = messageClass.split(" ");
+            const innerClassNames = classNames.map(
+                (className) => className + "__inner"
+            );
+            newElement.innerHTML = `
${message.replace("{group}", app.title)}
`; + newElement.onclick = function () { + klaro.show(); + }; + newElement.style.cursor = "pointer"; + newElement.dataset.name = app.name; + + if (messageClass) { + newElement.classList.add(...classNames); + } + + switch (messagePosition) { + case "before": { + targetElement.parentElement.insertBefore( + newElement, + targetElement + ); + break; + } + case "after": { + targetElement.parentElement.insertAfter( + newElement, + targetElement + ); + break; + } + case "prepend": { + targetElement.prepend(newElement); + break; + } + case "append": { + targetElement.append(newElement); + break; + } + } + } + } +})(); diff --git a/Resources/Private/JavaScript/klaroConfigTemplateCompiled.js b/Resources/Private/JavaScript/klaroConfigTemplateCompiled.js new file mode 100644 index 0000000..6135e14 --- /dev/null +++ b/Resources/Private/JavaScript/klaroConfigTemplateCompiled.js @@ -0,0 +1,194 @@ +"use strict"; + +function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } + +function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } + +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + +function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } + +function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } + +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + +/* PHP_REMOVE_START */ +// Here we define variables to have a valid JS file, which makes development +// more fun. They will later be replaced by the `ConsentConfigImplementation.php`. +// We prefix variables with `$php_replaced__` to show that they will be replaced. +// This file will be processed the following way: +// +// 1. (manually) Make sure you create an new build of this file to get a template that also works +// in old browsers -> `yarn run build:template`. This will create a file "klaroConfigTemplateCompiled.js". +// This file will be processed in the next steps! +// +// 2. ConsentConfigImplementation.php will remove content between "PHP_REMOVE_START" and "PHP_REMOVE_END" +// to remove variable definitions, that are only used for a better dev experience. +// +// 3. ConsentConfigImplementation.php will remove the callback placeholder for all apps with the actual callback. +// This is necessary as we are using json_encode. Json files do not support Js variables or callbacks. +// +// Before: { "name": "default", "title": "Default", "callback": "### CONSENT_HANDLER ###" } +// After: { "name": "default", "title": "Default", "callback": handleConsent } +// +// IMPORTANT FOR DEV: When changing the template make sure to flush the cache, otherwise changes will not +// show in the browser, even after reloading! +var $php_replaced__apps, $php_replaced__translations, $php_replaced__privacyPolicyUrl, $php_replaced__cookieDomain, $php_replaced__cookieExpiresAfterDays, $php_replaced__storageMethod, $php_replaced__cookieName, $php_replaced__mustConsent, $php_replaced__default, $php_replaced__acceptAll, $php_replaced__hideDeclineAll; +var $php_replaced__handleConsentOptions = { + message: "Message", + messageClass: "messageClass" +}; +/* PHP_REMOVE_END */ + +(function () { + window.klaroConfig = { + // IMPORTANT: we disable the language handling of klaro because + // we want to use translations provided the Neos-way + lang: "all", + // How Klaro should store the user's preferences. It can be either 'cookie' + // (the default) or 'localStorage'. + storageMethod: $php_replaced__storageMethod, + // You can customize the name of the cookie that Klaro uses for storing + // user consent decisions. If undefined, Klaro will use 'klaro'. + cookieName: $php_replaced__cookieName, + // You can also set a custom expiration time for the Klaro cookie. + // By default, it will expire after 120 days. + cookieExpiresAfterDays: $php_replaced__cookieExpiresAfterDays, + // You can change to cookie domain for the consent manager itself. + // Use this if you want to get consent once for multiple matching domains. + // If undefined, Klaro will use the current domain. + cookieDomain: $php_replaced__cookieDomain, + // Put a link to your privacy policy here (relative or absolute). + privacyPolicy: $php_replaced__privacyPolicyUrl, + // Defines the default state for applications (true=enabled by default). + default: $php_replaced__default, + // If "mustConsent" is set to true, Klaro will directly display the consent + // manager modal and not allow the user to close it before having actively + // consented or declines the use of third-party apps. + mustConsent: $php_replaced__mustConsent, + // Show "accept all" to accept all apps instead of "ok" that only accepts + // required and "default: true" apps + acceptAll: $php_replaced__acceptAll, + // replace "decline" with cookie manager modal + hideDeclineAll: $php_replaced__hideDeclineAll, + translations: { + all: $php_replaced__translations + }, + apps: $php_replaced__apps + }; + + function handleConsent(consent, app) { + // We nee a stable class to identify messages so we can remove them later. + var PERMANENT_MESSAGE_CLASS = "block-them-all-message"; // -> see Settings.yaml and/or Config.fusion + + var handleConsentOptions = $php_replaced__handleConsentOptions; + + if (consent) { + removeMessagesForConsentGroup(app.name); + unhideIframesForGroup(app.name); + } else { + var options = null; + document.querySelectorAll("*[data-name=\"".concat(app.name, "\"]")).forEach(function (element) { + try { + // more robust handling of maybe broken JSON + options = JSON.parse(element.dataset.options); + } catch (e) {// Do nothing + } // 1. We set default values + + + var message = handleConsentOptions.message || "NO MESSAGE CONFIGURED"; + var messageClass = buildMessageClass(handleConsentOptions.messageClass); + var messagePosition = "before"; + var targetElements = []; + + if (element.tagName === "IFRAME") { + targetElements = [element]; + } // 2. We override some, if options are present + + + if (options) { + message = options.message || message; + messageClass = options.messageClass ? buildMessageClass(options.messageClass) : messageClass; + messagePosition = options.messagePosition ? options.messagePosition : messagePosition; + targetElements = options.target ? Array.from(document.querySelectorAll(options.target)) : targetElements; + } + + if (targetElements.length) { + targetElements.forEach(function (element) { + return addMessage(element, message, app, messagePosition, messageClass); + }); + } + }); + } + + function removeMessagesForConsentGroup(group) { + var messageSelector = ".".concat(PERMANENT_MESSAGE_CLASS, "[data-name=\"").concat(group, "\"]"); + document.querySelectorAll(messageSelector).forEach(function (item) { + item.remove(); + }); + } + + function unhideIframesForGroup(group) { + var iframeSelector = "iframe[data-name=\"".concat(group, "\"]"); + document.querySelectorAll(iframeSelector).forEach(function (item) { + item.style.display = "block"; + }); + } + + function buildMessageClass(messageClass) { + if (messageClass && messageClass !== PERMANENT_MESSAGE_CLASS) { + return "".concat(PERMANENT_MESSAGE_CLASS, " ").concat(handleConsentOptions.messageClass); + } + + return PERMANENT_MESSAGE_CLASS; + } + + function addMessage(targetElement, message, app, messagePosition, messageClass) { + var newElement = document.createElement("div"); + var classNames = messageClass.split(" "); + var innerClassNames = classNames.map(function (className) { + return className + "__inner"; + }); + newElement.innerHTML = "
").concat(message.replace("{group}", app.title), "
"); + + newElement.onclick = function () { + klaro.show(); + }; + + newElement.style.cursor = "pointer"; + newElement.dataset.name = app.name; + + if (messageClass) { + var _newElement$classList; + + (_newElement$classList = newElement.classList).add.apply(_newElement$classList, _toConsumableArray(classNames)); + } + + switch (messagePosition) { + case "before": + { + targetElement.parentElement.insertBefore(newElement, targetElement); + break; + } + + case "after": + { + targetElement.parentElement.insertAfter(newElement, targetElement); + break; + } + + case "prepend": + { + targetElement.prepend(newElement); + break; + } + + case "append": + { + targetElement.append(newElement); + break; + } + } + } + } +})(); diff --git a/Resources/Private/KlaroTranslations/build/build.js b/Resources/Private/KlaroTranslations/build/build.js new file mode 100644 index 0000000..7dea878 --- /dev/null +++ b/Resources/Private/KlaroTranslations/build/build.js @@ -0,0 +1,161 @@ +var fs = require("fs"); +var path = require("path"); +const Handlebars = require("handlebars"); +const yaml = require("js-yaml"); + +const templateDir = __dirname; +const klaroTranslationsDir = path.join(__dirname, "../"); +const fusionTranslationFile = path.join( + __dirname, + "../../Fusion", + "Config.Translations.fusion" +); +const settingsYamlTranslationFile = path.join( + __dirname, + "../../../../Configuration", + "Settings.Translations.yaml" +); +const xlfTranslationsDir = path.join(__dirname, "../../Translations"); +const xlfName = "Klaro"; +``; +const autoGeneratedNotice = ` +################################################################################################ +# IMPORTANT: This file was auto-generated as part of the build process to convert translations # +# provided by klaro. -> see package.json -> "yarn run build:translations" # +################################################################################################ + +`; + +const fusionTemplate = Handlebars.compile( + fs.readFileSync(path.join(templateDir, "fusionTemplate.hbs"), { + encoding: "utf-8", + }) +); + +const xlfTemplate = Handlebars.compile( + fs.readFileSync(path.join(templateDir, "xlfTemplate.hbs"), { + encoding: "utf-8", + }) +); + +const enJson = yaml.safeLoad( + fs.readFileSync(path.join(klaroTranslationsDir, "en.yml"), { + encoding: "utf-8", + }) +); +const enFlattened = flattenJson(enJson); + +fs.readdir(klaroTranslationsDir, function (err, files) { + files + .filter((file) => file.indexOf(".yml") >= 0) + .forEach((file) => { + const language = file.replace(".yml", ""); + const json = yaml.safeLoad( + fs.readFileSync(path.join(klaroTranslationsDir, file), "utf8") + ); + const flattened = flattenJson(json); + const xlfUnits = buildXlfUnits(flattened, language); + + if (language === "en") { + const fusion = fusionTemplate({ + units: xlfUnits, + }); + fs.writeFileSync(fusionTranslationFile, fusion, { + encoding: "utf8", + flag: "w", + }); + + const settingsYaml = yaml.safeDump({ + Sandstorm: { + CookieCutter: { + translations: jsonToYamlWithPath( + json, + `Sandstorm.CookieCutter:${xlfName}:` + ), + }, + }, + }); + fs.writeFileSync( + settingsYamlTranslationFile, + autoGeneratedNotice + settingsYaml, + { encoding: "utf8", flag: "w" } + ); + } + + const xlf = xlfTemplate({ + units: xlfUnits, + source: "en", + target: language !== "en" ? language : undefined, + }); + const dir = path.join(xlfTranslationsDir, language); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir); + } + fs.writeFileSync(path.join(dir, `${xlfName}.xlf`), xlf, { + encoding: "utf8", + flag: "w", + }); + }); +}); + +function buildXlfUnits(flattened, language) { + return Object.keys(flattened).map((key) => { + if (language !== "en") { + return { + id: key, + target: flattened[key], + source: enFlattened[key], + language: language, + }; + } else { + return { + id: key, + source: flattened[key], + language: language, + }; + } + }); +} + +function flattenJson(data) { + var result = {}; + function recurse(cur, prop) { + if (Object(cur) !== cur) { + result[prop] = cur; + } else if (Array.isArray(cur)) { + for (var i = 0, l = cur.length; i < l; i++) + recurse(cur[i], prop ? prop + "." + i : "" + i); + if (l == 0) result[prop] = []; + } else { + var isEmpty = true; + for (var p in cur) { + isEmpty = false; + recurse(cur[p], prop ? prop + "." + p : p); + } + if (isEmpty) result[prop] = {}; + } + } + recurse(data, ""); + return result; +} + +function jsonToYamlWithPath(data, path = "") { + let clonedData = JSON.parse(JSON.stringify(data)); + function recurse(current, path) { + if (typeof current === "object") { + for (let property in current) { + if (current.hasOwnProperty(property)) { + if (typeof current[property] === "object") { + recurse(current[property], path + property + "."); + } else { + current[property] = path + property; + } + } + } + } + } + + recurse(clonedData, path); + + return clonedData; +} diff --git a/Resources/Private/KlaroTranslations/build/fusionTemplate.hbs b/Resources/Private/KlaroTranslations/build/fusionTemplate.hbs new file mode 100644 index 0000000..2cc7217 --- /dev/null +++ b/Resources/Private/KlaroTranslations/build/fusionTemplate.hbs @@ -0,0 +1,10 @@ +################################################################################################ +# IMPORTANT: This file was auto-generated as part of the build process to convert translations # +# provided by klaro. -> see package.json -> "yarn run build:translations" # +################################################################################################ + +prototype(Sandstorm.CookieCutter:Config.Translations) < prototype(Neos.Fusion:DataStructure) { + {{#each units}} + {{this.id}} = ${CookieCutterConfig.translate("Sandstorm.CookieCutter.translations.{{this.id}}")} + {{/each}} +} diff --git a/Resources/Private/KlaroTranslations/build/xlfTemplate.hbs b/Resources/Private/KlaroTranslations/build/xlfTemplate.hbs new file mode 100644 index 0000000..d426808 --- /dev/null +++ b/Resources/Private/KlaroTranslations/build/xlfTemplate.hbs @@ -0,0 +1,25 @@ + + + {{#if target}} + + {{else}} + + {{/if}} + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + {{#each units}} + + {{this.source}} + {{#if this.target}} + {{this.target}} + {{/if}} + + {{/each}} + + + diff --git a/Resources/Private/KlaroTranslations/ca.yml b/Resources/Private/KlaroTranslations/ca.yml new file mode 100644 index 0000000..801b447 --- /dev/null +++ b/Resources/Private/KlaroTranslations/ca.yml @@ -0,0 +1,34 @@ +consentModal: + title: Informació que recopilem + description: > + Aquí podeu veure i personalitzar la informació que recopilem sobre vós. + privacyPolicy: + name: política de privadesa + text: > + Per a més informació, consulteu la nostra {privacyPolicy}. +consentNotice: + changeDescription: Hi ha hagut canvis des de la vostra darrera visita. Actualitzeu el vostre consentiment. + description: > + Recopilem i processem la vostra informació personal amb les següents finalitats: {purposes}. + learnMore: Saber-ne més + privacyPolicy: + name: política de privadesa + imprint: + name: Empremta +ok: Accepta +save: Desa +decline: Rebutja +close: Tanca +app: + disableAll: + title: Habilita/deshabilita totes les aplicacions + description: Useu aquest botó per a habilitar o deshabilitar totes les aplicacions. + optOut: + title: (opt-out) + description: Aquesta aplicació es carrega per defecte, però podeu desactivar-la + required: + title: (necessària) + description: Aquesta aplicació es necessita sempre + purposes: Finalitats + purpose: Finalitat +poweredBy: Funciona amb Klaro! diff --git a/Resources/Private/KlaroTranslations/da.yml b/Resources/Private/KlaroTranslations/da.yml new file mode 100644 index 0000000..13d774b --- /dev/null +++ b/Resources/Private/KlaroTranslations/da.yml @@ -0,0 +1,34 @@ +consentModal: + title: Informationer, som vi gemmer + description: > + Her kan du se og ændre, hvilke informationer vi gemmer om dig. + privacyPolicy: + name: Flere informationer finde du under {privacyPolicy}. + text: > + databeskyttelseserklæring +consentNotice: + changeDescription: Der har været ændringer siden dit sidste besøg. Opdater dit valg. + description: > + Vi gemmer og behandler dine personlige oplysninger til følgende formål: {purposes}. + learnMore: Læs mere + privacyPolicy: + name: Datenschutzerklärung +ok: Ok +save: Gem +decline: Afvis +close: Luk +acceptSelected: Tillad udvalgte +acceptAll: Tillad alle +app: + disableAll: + title: Aktiver/deaktiver alle applikatione + description: Brug denne kontakt til at aktivere/deaktivere alle apps. + optOut: + title: Opt-Out + description: Denne applikation indlæses som standard (men du kan deaktivere den). + required: + title: (Altid nødvendig) + description: Denne applikation er altid nødvendig. + purposes: Formål + purpose: Formål +poweredBy: Realiseret med Klaro! diff --git a/Resources/Private/KlaroTranslations/de.yml b/Resources/Private/KlaroTranslations/de.yml new file mode 100644 index 0000000..654f8a1 --- /dev/null +++ b/Resources/Private/KlaroTranslations/de.yml @@ -0,0 +1,36 @@ +consentModal: + title: Informationen, die wir speichern + description: > + Hier können Sie einsehen und anpassen, welche Information wir über Sie speichern. + privacyPolicy: + name: Datenschutzerklärung + text: > + Weitere Details finden Sie in unserer {privacyPolicy}. +consentNotice: + changeDescription: Es gab Änderungen seit Ihrem letzten Besuch, bitte aktualisieren Sie Ihre Auswahl. + description: > + Wir speichern und verarbeiten Ihre personenbezogenen Informationen für folgende Zwecke: {purposes}. + learnMore: Mehr erfahren + privacyPolicy: + name: Datenschutzerklärung + imprint: + name: Impressum +ok: OK +save: Speichern +decline: Ablehnen +close: Schließen +acceptSelected: Auswahl speichern +acceptAll: Allen zustimmen +app: + disableAll: + title: Alle Anwendungen aktivieren/deaktivieren + description: Nutzen Sie diesen Schalter, um alle Apps zu aktivieren/deaktivieren. + optOut: + title: (Opt-Out) + description: Diese Anwendung wird standardmäßig geladen (Sie können diese aber deaktivieren) + required: + title: (immer notwendig) + description: Diese Anwendung wird immer benötigt + purposes: Zwecke + purpose: Zweck +poweredBy: Realisiert mit Klaro! diff --git a/Resources/Private/KlaroTranslations/el.yml b/Resources/Private/KlaroTranslations/el.yml new file mode 100644 index 0000000..50e18b9 --- /dev/null +++ b/Resources/Private/KlaroTranslations/el.yml @@ -0,0 +1,32 @@ +consentModal: + title: Πληροφορίες που συλλέγουμε + description: > + Εδώ μπορείς να δεις και να ρυθμίσεις τις πληροφορίες που συλλέγουμε σχετικά με εσένα + privacyPolicy: + name: Πολιτική Απορρήτου + text: > + Για περισσότερες πληροφορίες, παρακαλώ διαβάστε την {privacyPolicy}. +consentNotice: + changeDescription: Πραγματοποιήθηκαν αλλαγές μετά την τελευταία σας επίσκεψη παρακαλούμε ανανεώστε την συγκατάθεση σας + description: > + Συγκεντρώνουμε και επεξεργαζόμαστε τα προσωπικά δεδομένα σας για τους παρακάτω λόγους: {purposes}. + learnMore: Περισσότερα + privacyPolicy: + name: Πολιτική Απορρήτου +ok: OK +save: Αποθήκευση +decline: Απόρριπτω +close: Κλείσιμο +app: + disableAll: + title: Για όλες τις εφαρμογές + description: Χρησιμοποίησε αυτό τον διακόπτη για να ενεργοποιήσεις/απενεργοποιήσεις όλες τις εφαρμογές + optOut: + title: (μη απαιτούμενο) + description: Είναι προκαθορισμένο να φορτώνεται, άλλα μπορεί να παραληφθεί + required: + title: (απαιτούμενο) + description: Δεν γίνεται να λειτουργήσει σωστά η εφαρμογή χωρίς αυτό + purposes: Σκοποί + purpose: Σκοπός +poweredBy: Υποστηρίζεται από το Klaro! diff --git a/Resources/Private/KlaroTranslations/en.yml b/Resources/Private/KlaroTranslations/en.yml new file mode 100644 index 0000000..1ea34a7 --- /dev/null +++ b/Resources/Private/KlaroTranslations/en.yml @@ -0,0 +1,36 @@ +consentModal: + title: Information that we collect + description: > + Here you can see and customize the information that we collect about you. + privacyPolicy: + name: privacy policy + text: > + To learn more, please read our {privacyPolicy}. +consentNotice: + changeDescription: There were changes since your last visit, please update your consent. + description: > + We collect and process your personal information for the following purposes: {purposes}. + learnMore: Customize + privacyPolicy: + name: privacy policy + imprint: + name: Imprint +ok: Accept +save: Save +decline: Decline +close: Close +acceptAll: Accept all +acceptSelected: Accept selected +app: + disableAll: + title: Toggle all apps + description: Use this switch to enable/disable all apps. + optOut: + title: (opt-out) + description: This app is loaded by default (but you can opt out) + required: + title: (always required) + description: This application is always required + purposes: Purposes + purpose: Purpose +poweredBy: Powered by Klaro! diff --git a/Resources/Private/KlaroTranslations/es.yml b/Resources/Private/KlaroTranslations/es.yml new file mode 100644 index 0000000..c0c4e15 --- /dev/null +++ b/Resources/Private/KlaroTranslations/es.yml @@ -0,0 +1,34 @@ +consentModal: + title: Información que recopilamos + description: > + Aquí puede ver y personalizar la información que recopilamos sobre usted. + privacyPolicy: + name: política de privacidad + text: > + Para más información consulte nuestra {privacyPolicy}. +consentNotice: + changeDescription: Ha habido cambios desde su última visita, por favor, actualice su consentimiento. + description: > + Recopilamos y procesamos su información personal con los siguientes fines: {purposes}. + learnMore: Más información + privacyPolicy: + name: política de privacidad + imprint: + name: Imprimir +ok: Aceptar +save: Guardar +decline: Rechazar +close: Cerrar +app: + disableAll: + title: Habilitar/deshabilitar todas las aplicaciones + description: Use este botón para habilitar o deshabilitar todas las aplicaciones. + optOut: + title: (opt-out) + description: Esta aplicación se carga de forma predeterminada (pero puede desactivarla) + required: + title: (necesaria) + description: Esta aplicación se necesita siempre + purposes: Fines + purpose: Fin +poweredBy: Powered by Klaro! diff --git a/Resources/Private/KlaroTranslations/fi.yml b/Resources/Private/KlaroTranslations/fi.yml new file mode 100644 index 0000000..db2501e --- /dev/null +++ b/Resources/Private/KlaroTranslations/fi.yml @@ -0,0 +1,33 @@ +consentModal: + title: Keräämämme tiedot + description: > + Voit tarkastella ja muokata sinusta keräämiämme tietoja. + privacyPolicy: + name: tietosuojasivultamme + text: > + Voit lukea lisätietoja {privacyPolicy}. +consentNotice: + changeDescription: Olemme tehneet muutoksia ehtoihin viime vierailusi jälkeen, tarkista ehdot. + description: > + Keräämme ja käsittelemme henkilötietoja seuraaviin tarkoituksiin: {purposes}. + learnMore: Lue lisää + privacyPolicy: + name: tietosuojasivultamme +ok: Hyväksy +save: Tallenna +decline: Hylkää +close: Sulje +app: + disableAll: + title: Valitse kaikki + description: Aktivoi kaikki päälle/pois. + optOut: + title: (ladataan oletuksena) + description: Ladataan oletuksena (mutta voit ottaa sen pois päältä) + required: + title: (vaaditaan) + description: Sivusto vaatii tämän aina + purposes: Käyttötarkoitukset + purpose: Käyttötarkoitus +poweredBy: Palvelun tarjoaa Klaro! + diff --git a/Resources/Private/KlaroTranslations/fr.yml b/Resources/Private/KlaroTranslations/fr.yml new file mode 100644 index 0000000..ea9ce1f --- /dev/null +++ b/Resources/Private/KlaroTranslations/fr.yml @@ -0,0 +1,36 @@ +consentModal: + title: Les informations que nous collectons + description: > + Ici, vous pouvez voir et personnaliser les informations que nous collectons sur vous. + privacyPolicy: + name: politique de confidentialité + text: > + Pour en savoir plus, merci de lire notre {privacyPolicy}. +consentNotice: + changeDescription: Des modifications ont eu lieu depuis votre dernière visite, merci de mettre à jour votre consentement. + description: > + Nous collectons et traitons vos informations personnelles dans le but suivant : {purposes}. + learnMore: En savoir plus + privacyPolicy: + name: politique de confidentialité + imprint: + name: Imprimer +ok: OK +save: Sauvegarder +decline: Refuser +close: Fermer +acceptAll: Tout accepter +acceptSelected: Accepter la sélection +app: + disableAll: + title: Changer toutes les options + description: Utiliser ce bouton pour activer/désactiver toutes les options + optOut: + title: (opt-out) + description: Cette application est chargée par défaut (mais vous pouvez la désactiver) + required: + title: (toujours requis) + description: Cette application est toujours requise + purposes: Utilisations + purpose: Utilisation +poweredBy: Propulsé par Klaro! diff --git a/Resources/Private/KlaroTranslations/hr.yml b/Resources/Private/KlaroTranslations/hr.yml new file mode 100644 index 0000000..1f47393 --- /dev/null +++ b/Resources/Private/KlaroTranslations/hr.yml @@ -0,0 +1,32 @@ +consentModal: + title: Informacije koje prikupljamo + description: > + Ovdje možete vidjeti i podesiti informacije koje prikupljamo o Vama. + privacyPolicy: + name: pravila privatnosti + text: > + Za više informacije pročitajte naša {privacyPolicy}. +consentNotice: + changeDescription: Došlo je do promjena od Vaše posljednjeg posjećivanja web stranice, molimo Vas da ažurirate svoja odobrenja. + description: > + Mi prikupljamo i procesiramo Vaše osobne podatke radi slijedećeg: {purposes}. + learnMore: Saznajte više + privacyPolicy: + name: pravila privatnosti +ok: U redu +save: Spremi +decline: Odbij +close: Zatvori +app: + disableAll: + title: Izmeijeni sve + description: Koristite ovaj prekidač da omogućite/onemogućite sve aplikacije odjednom. + optOut: + title: (onemogućite) + description: Ova aplikacija je učitana automatski (ali je možete onemogućiti) + required: + title: (obavezna) + description: Ova aplikacija je uvijek obavezna. + purposes: Svrhe + purpose: Svrha +poweredBy: Pokreće Klaro! diff --git a/Resources/Private/KlaroTranslations/hu.yml b/Resources/Private/KlaroTranslations/hu.yml new file mode 100644 index 0000000..f7e954a --- /dev/null +++ b/Resources/Private/KlaroTranslations/hu.yml @@ -0,0 +1,32 @@ +consentModal: + title: Információk, amiket gyűjtünk + description: > + Itt láthatod és testreszabhatod az rólad gyűjtött információkat. + privacyPolicy: + name: adatvédelmi irányelveinket + text: > + További információért kérjük, olvassd el az {privacyPolicy}. +consentNotice: + changeDescription: Az utolsó látogatás óta változások történtek, kérjük, frissítsd a hozzájárulásodat. + description: > + Az személyes adataidat összegyűjtjük és feldolgozzuk az alábbi célokra: {purposes}. + learnMore: Tudj meg többet + privacyPolicy: + name: adatvédelmi irányelveinket +ok: Elfogad +save: Save +decline: Mentés +close: Elvet +app: + disableAll: + title: Összes app átkapcsolása + description: Használd ezt a kapcsolót az összes alkalmazás engedélyezéséhez/letiltásához. + optOut: + title: (leiratkozás) + description: Ez az alkalmazás alapértelmezés szerint betöltött (de ki lehet kapcsolni) + required: + title: (mindig kötelező) + description: Ez az alkalmazás mindig kötelező + purposes: Célok + purpose: Cél +poweredBy: Powered by Klaro! diff --git a/Resources/Private/KlaroTranslations/it.yml b/Resources/Private/KlaroTranslations/it.yml new file mode 100644 index 0000000..0fd979d --- /dev/null +++ b/Resources/Private/KlaroTranslations/it.yml @@ -0,0 +1,34 @@ +consentModal: + title: Informazioni che raccogliamo + description: > + Qui puoi vedere e scegliere le informazioni che raccogliamo su di te. + privacyPolicy: + name: policy privacy + text: > + Per saperne di più, leggi la nostra {privacyPolicy}. +consentNotice: + changeDescription: Ci sono stati cambiamenti dalla tua ultima visita, aggiorna il tuo consenso. + description: > + Raccogliamo ed elaboriamo le vostre informazioni personali per i seguenti scopi: {purposes}. + learnMore: Scopri di più + privacyPolicy: + name: policy privacy + imprint: + name: Impronta +ok: OK +save: Salva +decline: Rifiuta +close: Chiudi +app: + disableAll: + title: Cambia per tutte le app + description: Usa questo interruttore per abilitare/disabilitare tutte le app. + optOut: + title: (opt-out) + description: Quest'applicazione è caricata di default (ma puoi disattivarla) + required: + title: (sempre richiesto) + description: Quest'applicazione è sempre richiesta + purposes: Scopi + purpose: Scopo +poweredBy: Realizzato da Klaro! diff --git a/Resources/Private/KlaroTranslations/nl.yml b/Resources/Private/KlaroTranslations/nl.yml new file mode 100644 index 0000000..60113e0 --- /dev/null +++ b/Resources/Private/KlaroTranslations/nl.yml @@ -0,0 +1,34 @@ +consentModal: + title: Informatie die we verzamelen + description: > + Hier kunt u de informatie bekijken en aanpassen die we over u verzamelen. + privacyPolicy: + name: privacybeleid + text: > + Lees ons privacybeleid voor meer informatie {privacyPolicy}. +consentNotice: + changeDescription: Er waren wijzigingen sinds uw laatste bezoek, werk uw voorkeuren bij. + description: > + Wij verzamelen en verwerken uw persoonlijke gegevens voor de volgende doeleinden: {purposes}. + learnMore: Lees meer + privacyPolicy: + name: privacybeleid + imprint: + name: Afdruk +ok: OK +save: Opslaan +decline: Afwijzen +close: Sluiten +app: + disableAll: + title: Alle opties in/uit schakelen + description: Gebruik deze schakeloptie om alle apps in/uit te schakelen. + optOut: + title: (afmelden) + description: Deze app is standaard geladen (maar je kunt je afmelden) + required: + title: (altijd verplicht) + description: Deze applicatie is altijd vereist + purposes: Doeleinden + purpose: Doeleinde +poweredBy: Aangedreven door Klaro! diff --git a/Resources/Private/KlaroTranslations/no.yml b/Resources/Private/KlaroTranslations/no.yml new file mode 100644 index 0000000..0b339fd --- /dev/null +++ b/Resources/Private/KlaroTranslations/no.yml @@ -0,0 +1,33 @@ +consentModal: + title: Informasjon vi samler inn + description: > + Her kan du se og velge hvilken informasjon vi samler inn om deg. + privacyPolicy: + name: personvernerklæring + text: > + For å lære mer, vennligst les vår {privacyPolicy}. +consentNotice: + changeDescription: Det har skjedd endringer siden ditt siste besøk, vennligst oppdater ditt samtykke. + description: > + Vi samler inn og prosesserer din personlige informasjon av følgende årsaker: {purposes}. + learnMore: Lær mer + privacyPolicy: + name: personvernerklæring +ok: OK +save: Opslaan +decline: Avslå +acceptAll: Godtar alle +acceptSelected: Godtar valgt +app: + disableAll: + title: Bytt alle apper + description: Bruk denne for å skru av/på alle apper. + optOut: + title: (opt-out) + description: Denne appen er lastet som standard (men du kan skru det av) + required: + title: (alltid påkrevd) + description: Denne applikasjonen er alltid påkrevd + purposes: Årsaker + purpose: Årsak +poweredBy: Laget med Klaro! diff --git a/Resources/Private/KlaroTranslations/pl.yml b/Resources/Private/KlaroTranslations/pl.yml new file mode 100644 index 0000000..8b0c382 --- /dev/null +++ b/Resources/Private/KlaroTranslations/pl.yml @@ -0,0 +1,34 @@ +consentModal: + title: Informacje, które zbieramy + description: > + Tutaj możesz zobaczyć i dostosować informacje, które zbieramy o Tobie. + privacyPolicy: + name: polityka prywatności + text: > + Aby dowiedzieć się więcej, przeczytaj naszą {privacyPolicy}. +consentNotice: + changeDescription: Nastąpiły zmiany od Twojej ostatniej wizyty, zaktualizuj swoją zgodę. + description: > + Zbieramy i przetwarzamy dane osobowe w następujących celach: {purposes}. + learnMore: Dowiedz się więcej + privacyPolicy: + name: polityka prywatności + imprint: + name: Odcisk +ok: OK +save: Zapisz +decline: Rezygnacja +close: Zamknij +app: + disableAll: + title: Przełącz dla wszystkich aplikacji + description: Użyj przełącznika, aby włączyć/wyłączyć wszystkie aplikacje. + optOut: + title: (rezygnacja) + description: Ta aplikacja jest domyślnie ładowana (ale możesz zrezygnować) + required: + title: (zawsze wymagane) + description: Ta alikacja jest zawsze wymagana + purposes: Cele + purpose: Cel +poweredBy: Napędzany przez Klaro! diff --git a/Resources/Private/KlaroTranslations/ro.yml b/Resources/Private/KlaroTranslations/ro.yml new file mode 100644 index 0000000..60e1603 --- /dev/null +++ b/Resources/Private/KlaroTranslations/ro.yml @@ -0,0 +1,31 @@ +consentModal: + title: Informațiile pe care le colectăm + description: > + Aici puteți vedea și personaliza informațiile pe care le colectăm despre dvs. + privacyPolicy: + name: politica privacy + text: > + Pentru a afla mai multe, vă rugăm să citiți {privacyPolicy}. +consentNotice: + changeDescription: Au existat modificări de la ultima vizită, vă rugăm să actualizați consimțământul. + description: > + Colectăm și procesăm informațiile dvs. personale în următoarele scopuri: {purposes}. + learnMore: Află mai multe + privacyPolicy: + name: politica privacy +ok: OK +save: Salvează +decline: Renunță +app: + disableAll: + title: Comutați între toate aplicațiile + description: Utilizați acest switch pentru a activa/dezactiva toate aplicațiile. + optOut: + title: (opt-out) + description: Această aplicație este încărcată în mod implicit (dar puteți renunța) + required: + title: (întotdeauna necesar) + description: Această aplicație este întotdeauna necesară + purposes: Scopuri + purpose: Scop +poweredBy: Realizat de Klaro! diff --git a/Resources/Private/KlaroTranslations/ru.yml b/Resources/Private/KlaroTranslations/ru.yml new file mode 100644 index 0000000..c7d84cc --- /dev/null +++ b/Resources/Private/KlaroTranslations/ru.yml @@ -0,0 +1,34 @@ +consentModal: + title: Информация, которую мы сохраняем + description: > + Здесь вы можете просмотреть и настроить, какую информацию о вас мы храним. + privacyPolicy: + name: Соглашение + text: > + Чтобы узнать больше, пожалуйста, прочитайте наше {privacyPolicy}. +consentNotice: + changeDescription: Со времени вашего последнего визита произошли изменения, обновите своё согласие. + description: > + Мы собираем и обрабатываем вашу личную информацию для следующих целей: {purposes}. + learnMore: Настроить + privacyPolicy: + name: политика конфиденциальности +ok: Принять +save: Сохранить +decline: Отклонить +close: Закрыть +acceptAll: Принять всё +acceptSelected: Принять выбранные +app: + disableAll: + title: Переключить все приложения + description: Используйте этот переключатель, чтобы включить/отключить все приложения. + optOut: + title: (отказаться) + description: Это приложение включено по умолчанию (но вы можете отказаться) + required: + title: (всегда обязательный) + description: Это обязательное приложение + purposes: Намерения + purpose: Намерение +poweredBy: Работает на Кларо! diff --git a/Resources/Private/KlaroTranslations/sr.yml b/Resources/Private/KlaroTranslations/sr.yml new file mode 100644 index 0000000..a739d2b --- /dev/null +++ b/Resources/Private/KlaroTranslations/sr.yml @@ -0,0 +1,32 @@ +consentModal: + title: Informacije koje prikupljamo + description: > + Ovde možete videti i podesiti informacije koje prikupljamo o Vama. + privacyPolicy: + name: politiku privatnosti + text: > + Za više informacije pročitajte našu {privacyPolicy}. +consentNotice: + changeDescription: Došlo je do promena od Vaše poslednje posete, molimo Vas da ažurirate svoja odobrenja. + description: > + Mi prikupljamo i procesiramo Vaše lične podatke radi sledećeg: {purposes}. + learnMore: Saznajte više + privacyPolicy: + name: politiku privatnosti +ok: U redu +save: Sačuvaj +decline: Odbij +close: Zatvori +app: + disableAll: + title: Izmeni sve + description: Koristite ovaj prekidač da omogućite/onesposobite sve aplikacije odjednom. + optOut: + title: (onesposobite) + description: Ova aplikacija je učitana automatski (ali je možete onesposobiti) + required: + title: (neophodna) + description: Ova aplikacija je uvek neophodna. + purposes: Svrhe + purpose: Svrha +poweredBy: Pokreće Klaro! diff --git a/Resources/Private/KlaroTranslations/sr_cyrl.yml b/Resources/Private/KlaroTranslations/sr_cyrl.yml new file mode 100644 index 0000000..b687c80 --- /dev/null +++ b/Resources/Private/KlaroTranslations/sr_cyrl.yml @@ -0,0 +1,32 @@ +consentModal: + title: Информације које прикупљамо + description: > + Овде можете видет и подесити информације које прикупљамо о Вама. + privacyPolicy: + name: политику приватности + text: > + За више информација прочитајте нашу {privacyPolicy}. +consentNotice: + changeDescription: Дошло је до промена од Ваше последнје посете, молимо Вас да ажурирате своја одобрења. + description: > + Ми прикупљамо и процесирамо Ваше личне податке ради следећег: {purposes}. + learnMore: Сазнајте више + privacyPolicy: + name: политику приватности +ok: У реду +save: Сачувај +decline: Одбиј +close: Затвори +app: + disableAll: + title: Измени све + description: Користите овај прекидач да омогућите/онеспособите све апликације одједном. + optOut: + title: (онеспособите) + description: Ова апликација је учитана аутоматски (али је можете онеспособити) + required: + title: (неопходна) + description: Ова апликација је увек неопходна. + purposes: Сврхе + purpose: Сврха +poweredBy: Покреће Кларо! diff --git a/Resources/Private/KlaroTranslations/sv.yml b/Resources/Private/KlaroTranslations/sv.yml new file mode 100644 index 0000000..de3b0ad --- /dev/null +++ b/Resources/Private/KlaroTranslations/sv.yml @@ -0,0 +1,34 @@ +consentModal: + title: Information som vi samlar + description: > + Här kan du se och anpassa vilken information vi samlar om dig. + privacyPolicy: + name: Integritetspolicy + text: > + För att veta mer, läs vår {privacyPolicy}. +consentNotice: + changeDescription: Det har skett förändringar sedan ditt senaste besök, var god uppdatera ditt medgivande. + description: > + Vi samlar och bearbetar din personliga data i följande syften: {purposes}. + learnMore: Läs mer + privacyPolicy: + name: Integritetspolicy +ok: OK +save: Spara +decline: Avböj +acceptAll: Acceptera alla +acceptSelected: Acceptera markerat +close: Stäng +app: + disableAll: + title: Ändra för alla appar + description: Använd detta reglage för att aktivera/avaktivera samtliga appar. + optOut: + title: (Avaktivera) + description: Den här appen laddas som standardinställning (men du kan avaktivera den) + required: + title: (Krävs alltid) + description: Den här applikationen krävs alltid + purposes: Syften + purpose: Syfte +poweredBy: Körs på Klaro! diff --git a/Resources/Private/KlaroTranslations/tr.yml b/Resources/Private/KlaroTranslations/tr.yml new file mode 100644 index 0000000..17c3555 --- /dev/null +++ b/Resources/Private/KlaroTranslations/tr.yml @@ -0,0 +1,32 @@ +consentModal: + title: Sakladığımız bilgiler + description: > + Hakkınızda topladığımız bilgileri burada görebilir ve özelleştirebilirsiniz. + privacyPolicy: + name: Gizlilik Politikası + text: > + Daha fazlası için lütfen {privacyPolicy} sayfamızı okuyun. +consentNotice: + changeDescription: Son ziyaretinizden bu yana değişiklikler oldu, lütfen seçiminizi güncelleyin. + description: > + Kişisel bilgilerinizi aşağıdaki amaçlarla saklıyor ve işliyoruz: {purposes}. + learnMore: Daha fazla bilgi + privacyPolicy: + name: Gizlilik Politikası +ok: Tamam +save: Kaydet +decline: Reddet +close: Kapat +app: + disableAll: + title: Tüm uygulamaları aç/kapat + description: Toplu açma/kapama için bu düğmeyi kullanabilirsin. + optOut: + title: (isteğe bağlı) + description: Bu uygulama varsayılanda yüklendi (ancak iptal edebilirsin) + required: + title: (her zaman gerekli) + description: Bu uygulama her zaman gerekli + purposes: Amaçlar + purpose: Amaç +poweredBy: Klaro tarafından geliştirildi! diff --git a/Resources/Private/Scss/Klaro/_klaro.scss b/Resources/Private/Scss/Klaro/_klaro.scss new file mode 100644 index 0000000..0a3c12b --- /dev/null +++ b/Resources/Private/Scss/Klaro/_klaro.scss @@ -0,0 +1,299 @@ +.klaro { + .cookie-modal, + .cookie-notice { + @import "switch.scss"; + + font-size: 14px; + + .slider { + box-shadow: $cc_panel__boxShadow; + } + + a { + color: $cc_link__color; + text-decoration: none; + } + + p, + strong, + h1, + h2, + ul, + li { + font-family: inherit; + color: $cc_text__color; + } + + p, + h1, + h2, + ul, + li { + display: block; + text-align: left; + margin: 0; + padding: 0; + margin-top: 0.7em; + } + + .cm-link { + padding-left: 4px; + vertical-align: middle; + } + + .cm-btn { + padding: 6px 10px; + margin-right: 0.5em; + + border: $cc_button__border; + border-radius: $cc_button__borderRadius; + background: $cc_button__backgroundColor; + color: $cc_button__color; + + cursor: pointer; + + &:disabled { + opacity: 0.5; + } + + &.cm-btn-sm { + padding: 0.4em; + font-size: 1em; + } + + &.cm-btn-close { + background: red; + color: red; + } + + &.cm-btn-success { + border: $cc_buttonSuccess__border; + background: $cc_buttonSuccess__backgroundColor; + color: $cc_buttonSuccess__color; + } + + &.cm-btn-info { + // no need for this type of button to look different + border: $cc_buttonSuccess__border; + background: $cc_buttonSuccess__backgroundColor; + color: $cc_buttonSuccess__color; + } + + &.cm-btn-right { + float: right; + margin-left: 0.5em; + margin-right: 0; + } + } + } + + .cookie-modal { + width: 100%; + height: 100%; + position: fixed; + overflow: hidden; + left: 0; + top: 0; + z-index: $cc_panel__zIndex; + + .cm-bg { + background: $cc_backdrop__backgroundColor; + height: 100%; + width: 100%; + position: fixed; + top: 0; + left: 0; + } + + .cm-modal { + z-index: $cc_panel__zIndex + 1; + box-shadow: $cc_panel__boxShadow; + + @media (min-width: 1024px) { + border-radius: $cc_panel__borderRadius; + position: relative; + margin: 0 auto; + max-width: 640px; + height: auto; + width: auto; + } + + width: 100%; + max-height: 98%; + + top: 50%; + transform: translateY(-50%); + + position: fixed; + overflow: auto; + background: $cc_panel__backgroundColor; + color: $cc_text__color; + + .hide { + border: none; + background: none; + svg { + stroke: $cc_text__color; + } + position: absolute; + top: 20px; + right: 20px; + // Avoid getting overlapped by the heading, if external CSS sets: + // h1 { position: relative } + // See: https://github.com/KIProtect/klaro/issues/135 + z-index: 1; + } + + .cm-footer { + padding: 1.5em; + border-top: $cc_separator__border; + + &-buttons { + &::before, + &::after { + content: " "; + display: table; + } + + &::after { + clear: both; + } + } + + .cm-powered-by { + font-size: 0.8em; + padding-top: 4px; + text-align: center; + + a { + color: $cc_textMuted__color; + } + } + } + + .cm-header { + padding: 1.5em; + padding-right: 24px; + border-bottom: $cc_separator__border; + h1 { + margin: 0; + font-size: 2em; + display: block; + &.title { + padding-right: 20px; + } + } + } + + .cm-body { + padding: 1.5rem; + ul { + display: block; + } + span { + display: inline-block; + width: auto; + } + ul.cm-apps { + padding: 0; + margin: 0; + li.cm-app { + &:first-child { + margin-top: 0; + } + position: relative; + line-height: 20px; + vertical-align: middle; + padding-left: 60px; + min-height: 40px; + .switch { + position: absolute; + left: 0; + } + p { + margin-top: 0; + } + + p.purposes { + font-size: 0.8em; + color: $cc_textMuted__color; + } + + &.cm-toggle-all { + border-top: $cc_separator__border; + padding-top: 1em; + } + + span.cm-app-title { + font-weight: 600; + } + + span.cm-opt-out, + span.cm-required { + padding-left: 0.2em; + font-size: 0.8em; + color: $cc_textMuted__color; + } + } + } + } + } + } + + .cookie-notice { + background: $cc_panel__backgroundColor; + z-index: $cc_panel__zIndex - 1; + + position: fixed; + width: 100%; + bottom: 0; + right: 0; + + @media (min-width: 990px) { + box-shadow: $cc_panel__boxShadow; + border-radius: $cc_panel__borderRadius; + position: fixed; + bottom: 20px; + right: 20px; + max-width: 300px; + } + + @media (max-width: 989px) { + border: none; + border-radius: 0; + } + + .cn-body { + margin-bottom: 0; + margin-right: 0; + bottom: 0; + + padding: 1em; + padding-top: 0; + + p { + margin-bottom: 0.5em; + } + + p.cn-changes { + text-decoration: underline; + } + + .cn-learn-more { + display: inline-block; + } + + p.cn-ok { + padding-top: 0.5em; + margin: 0; + display: flex; + align-items: center; + justify-content: flex-start; + } + } + } + + .cookie-notice-hidden { + display: none !important; + } +} diff --git a/Resources/Private/Scss/Klaro/_switch.scss b/Resources/Private/Scss/Klaro/_switch.scss new file mode 100644 index 0000000..8df452c --- /dev/null +++ b/Resources/Private/Scss/Klaro/_switch.scss @@ -0,0 +1,90 @@ +// THIS FILE WAS COPIED AS IS FROM https://github.com/kiprotect/klaro + +.switch { + position: relative; + display: inline-block; + width: 50px; + height: 30px; +} + +.cm-app-input:checked + .cm-app-label .slider { + background-color: $cc_switch__backgroundColor; +} + +.cm-app-input.required:checked + .cm-app-label .slider { + opacity: 0.3; + background-color: $cc_switch__backgroundColor; + cursor: not-allowed; +} + +.slider { + box-shadow: $cc_panel__boxShadow; +} + +.cm-app-input { + position: absolute; + top: 0; + left: 0; + opacity: 0; + width: 50px; + height: 30px; +} + +.cm-app-label { + /* The slider */ + .slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + -webkit-transition: 0.4s; + transition: 0.4s; + width: 50px; + display: inline-block; + } + + .slider:before { + position: absolute; + content: ""; + height: 20px; + width: 20px; + left: 5px; + bottom: 5px; + background-color: white; + -webkit-transition: 0.4s; + transition: 0.4s; + } + + /* Rounded sliders */ + .slider.round { + border-radius: 30px; + } + + .slider.round:before { + border-radius: 50%; + } + + input:focus + .slider { + box-shadow: 0 0 1px red; + } + + input:checked + .slider:before { + -webkit-transform: translateX(20px); + -ms-transform: translateX(20px); + transform: translateX(20px); + } +} + +.cm-app-input:focus + .cm-app-label .slider { + box-shadow: 0 4px 6px 0 rgba(125, 125, 125, 0.2), + 5px 5px 10px 0 rgba(125, 125, 125, 0.19); +} + +.cm-app-input:checked + .cm-app-label .slider:before { + -webkit-transform: translateX(20px); + -ms-transform: translateX(20px); + transform: translateX(20px); +} diff --git a/Resources/Private/Scss/_Styles.scss b/Resources/Private/Scss/_Styles.scss new file mode 100644 index 0000000..34c0a06 --- /dev/null +++ b/Resources/Private/Scss/_Styles.scss @@ -0,0 +1,25 @@ +$cc_backdrop__backgroundColor: rgba(0, 0, 0, 0.5) !default; +$cc_panel__borderRadius: 4px !default; +$cc_panel__boxShadow: 0 4px 6px 0 rgba(0, 0, 0, 0.2), + 5px 5px 10px 0 rgba(0, 0, 0, 0.19) !default; +$cc_panel__zIndex: 1000 !default; +$cc_panel__backgroundColor: #333 !default; + +$cc_separator__border: 1px solid #555 !default; + +$cc_link__color: #00aa3e !default; +$cc_text__color: #eee !default; +$cc_textMuted__color: #999 !default; + +$cc_switch__backgroundColor: #0885ba !default; + +$cc_button__backgroundColor: #555 !default; +$cc_button__color: #fff !default; +$cc_button__border: none !default; +$cc_button__borderRadius: 4px !default; + +$cc_buttonSuccess__backgroundColor: #00aa3e !default; +$cc_buttonSuccess__color: $cc_button__color !default; +$cc_buttonSuccess__border: none !default; + +@import "./Klaro/klaro.scss"; diff --git a/Resources/Private/Translations/ca/Klaro.xlf b/Resources/Private/Translations/ca/Klaro.xlf new file mode 100644 index 0000000..c17c1d7 --- /dev/null +++ b/Resources/Private/Translations/ca/Klaro.xlf @@ -0,0 +1,107 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Informació que recopilem + + + Here you can see and customize the information that we collect about you. + + Aquí podeu veure i personalitzar la informació que recopilem sobre vós. + + + + privacy policy + política de privadesa + + + To learn more, please read our {privacyPolicy}. + + Per a més informació, consulteu la nostra {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Hi ha hagut canvis des de la vostra darrera visita. Actualitzeu el vostre consentiment. + + + We collect and process your personal information for the following purposes: {purposes}. + + Recopilem i processem la vostra informació personal amb les següents finalitats: {purposes}. + + + + Customize + Saber-ne més + + + privacy policy + política de privadesa + + + Imprint + Empremta + + + Accept + Accepta + + + Save + Desa + + + Decline + Rebutja + + + Close + Tanca + + + Toggle all apps + Habilita/deshabilita totes les aplicacions + + + Use this switch to enable/disable all apps. + Useu aquest botó per a habilitar o deshabilitar totes les aplicacions. + + + (opt-out) + (opt-out) + + + This app is loaded by default (but you can opt out) + Aquesta aplicació es carrega per defecte, però podeu desactivar-la + + + (always required) + (necessària) + + + This application is always required + Aquesta aplicació es necessita sempre + + + Purposes + Finalitats + + + Purpose + Finalitat + + + Powered by Klaro! + Funciona amb Klaro! + + + + diff --git a/Resources/Private/Translations/da/Klaro.xlf b/Resources/Private/Translations/da/Klaro.xlf new file mode 100644 index 0000000..5287f12 --- /dev/null +++ b/Resources/Private/Translations/da/Klaro.xlf @@ -0,0 +1,111 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Informationer, som vi gemmer + + + Here you can see and customize the information that we collect about you. + + Her kan du se og ændre, hvilke informationer vi gemmer om dig. + + + + privacy policy + Flere informationer finde du under {privacyPolicy}. + + + To learn more, please read our {privacyPolicy}. + + databeskyttelseserklæring + + + + There were changes since your last visit, please update your consent. + Der har været ændringer siden dit sidste besøg. Opdater dit valg. + + + We collect and process your personal information for the following purposes: {purposes}. + + Vi gemmer og behandler dine personlige oplysninger til følgende formål: {purposes}. + + + + Customize + Læs mere + + + privacy policy + Datenschutzerklärung + + + Accept + Ok + + + Save + Gem + + + Decline + Afvis + + + Close + Luk + + + Accept selected + Tillad udvalgte + + + Accept all + Tillad alle + + + Toggle all apps + Aktiver/deaktiver alle applikatione + + + Use this switch to enable/disable all apps. + Brug denne kontakt til at aktivere/deaktivere alle apps. + + + (opt-out) + Opt-Out + + + This app is loaded by default (but you can opt out) + Denne applikation indlæses som standard (men du kan deaktivere den). + + + (always required) + (Altid nødvendig) + + + This application is always required + Denne applikation er altid nødvendig. + + + Purposes + Formål + + + Purpose + Formål + + + Powered by Klaro! + Realiseret med Klaro! + + + + diff --git a/Resources/Private/Translations/de/Elements.xlf b/Resources/Private/Translations/de/Elements.xlf new file mode 100644 index 0000000..3de1c43 --- /dev/null +++ b/Resources/Private/Translations/de/Elements.xlf @@ -0,0 +1,15 @@ + + + + + + + Content was blocked.
Please activate "{group}" in your Cookie settings.]]> + + + Inhalte wurden blockiert.
Bitte aktiviere "{group}" in den Cookie-Einstellungen.]]> +
+
+ +
+
diff --git a/Resources/Private/Translations/de/Klaro.xlf b/Resources/Private/Translations/de/Klaro.xlf new file mode 100644 index 0000000..a793a7d --- /dev/null +++ b/Resources/Private/Translations/de/Klaro.xlf @@ -0,0 +1,115 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Informationen, die wir speichern + + + Here you can see and customize the information that we collect about you. + + Hier können Sie einsehen und anpassen, welche Information wir über Sie speichern. + + + + privacy policy + Datenschutzerklärung + + + To learn more, please read our {privacyPolicy}. + + Weitere Details finden Sie in unserer {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Es gab Änderungen seit Ihrem letzten Besuch, bitte aktualisieren Sie Ihre Auswahl. + + + We collect and process your personal information for the following purposes: {purposes}. + + Wir speichern und verarbeiten Ihre personenbezogenen Informationen für folgende Zwecke: {purposes}. + + + + Customize + Mehr erfahren + + + privacy policy + Datenschutzerklärung + + + Imprint + Impressum + + + Accept + OK + + + Save + Speichern + + + Decline + Ablehnen + + + Close + Schließen + + + Accept selected + Auswahl speichern + + + Accept all + Allen zustimmen + + + Toggle all apps + Alle Anwendungen aktivieren/deaktivieren + + + Use this switch to enable/disable all apps. + Nutzen Sie diesen Schalter, um alle Apps zu aktivieren/deaktivieren. + + + (opt-out) + (Opt-Out) + + + This app is loaded by default (but you can opt out) + Diese Anwendung wird standardmäßig geladen (Sie können diese aber deaktivieren) + + + (always required) + (immer notwendig) + + + This application is always required + Diese Anwendung wird immer benötigt + + + Purposes + Zwecke + + + Purpose + Zweck + + + Powered by Klaro! + Realisiert mit Klaro! + + + + diff --git a/Resources/Private/Translations/el/Klaro.xlf b/Resources/Private/Translations/el/Klaro.xlf new file mode 100644 index 0000000..8943bdb --- /dev/null +++ b/Resources/Private/Translations/el/Klaro.xlf @@ -0,0 +1,103 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Πληροφορίες που συλλέγουμε + + + Here you can see and customize the information that we collect about you. + + Εδώ μπορείς να δεις και να ρυθμίσεις τις πληροφορίες που συλλέγουμε σχετικά με εσένα + + + + privacy policy + Πολιτική Απορρήτου + + + To learn more, please read our {privacyPolicy}. + + Για περισσότερες πληροφορίες, παρακαλώ διαβάστε την {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Πραγματοποιήθηκαν αλλαγές μετά την τελευταία σας επίσκεψη παρακαλούμε ανανεώστε την συγκατάθεση σας + + + We collect and process your personal information for the following purposes: {purposes}. + + Συγκεντρώνουμε και επεξεργαζόμαστε τα προσωπικά δεδομένα σας για τους παρακάτω λόγους: {purposes}. + + + + Customize + Περισσότερα + + + privacy policy + Πολιτική Απορρήτου + + + Accept + OK + + + Save + Αποθήκευση + + + Decline + Απόρριπτω + + + Close + Κλείσιμο + + + Toggle all apps + Για όλες τις εφαρμογές + + + Use this switch to enable/disable all apps. + Χρησιμοποίησε αυτό τον διακόπτη για να ενεργοποιήσεις/απενεργοποιήσεις όλες τις εφαρμογές + + + (opt-out) + (μη απαιτούμενο) + + + This app is loaded by default (but you can opt out) + Είναι προκαθορισμένο να φορτώνεται, άλλα μπορεί να παραληφθεί + + + (always required) + (απαιτούμενο) + + + This application is always required + Δεν γίνεται να λειτουργήσει σωστά η εφαρμογή χωρίς αυτό + + + Purposes + Σκοποί + + + Purpose + Σκοπός + + + Powered by Klaro! + Υποστηρίζεται από το Klaro! + + + + diff --git a/Resources/Private/Translations/en/Elements.xlf b/Resources/Private/Translations/en/Elements.xlf new file mode 100644 index 0000000..15de4c6 --- /dev/null +++ b/Resources/Private/Translations/en/Elements.xlf @@ -0,0 +1,12 @@ + + + + + + + Content was blocked.
Please activate "{group}" in your Cookie settings.]]> + +
+ +
+
diff --git a/Resources/Private/Translations/en/Groups.xlf b/Resources/Private/Translations/en/Groups.xlf new file mode 100644 index 0000000..94e7dc0 --- /dev/null +++ b/Resources/Private/Translations/en/Groups.xlf @@ -0,0 +1,20 @@ + + + + + + Default + + + Default Description + + + + Media + + + Media Description + + + + diff --git a/Resources/Private/Translations/en/Klaro.xlf b/Resources/Private/Translations/en/Klaro.xlf new file mode 100644 index 0000000..cbdf6ac --- /dev/null +++ b/Resources/Private/Translations/en/Klaro.xlf @@ -0,0 +1,88 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + + + Here you can see and customize the information that we collect about you. + + + + privacy policy + + + To learn more, please read our {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + + + We collect and process your personal information for the following purposes: {purposes}. + + + + Customize + + + privacy policy + + + Imprint + + + Accept + + + Save + + + Decline + + + Close + + + Accept all + + + Accept selected + + + Toggle all apps + + + Use this switch to enable/disable all apps. + + + (opt-out) + + + This app is loaded by default (but you can opt out) + + + (always required) + + + This application is always required + + + Purposes + + + Purpose + + + Powered by Klaro! + + + + diff --git a/Resources/Private/Translations/es/Klaro.xlf b/Resources/Private/Translations/es/Klaro.xlf new file mode 100644 index 0000000..366cefc --- /dev/null +++ b/Resources/Private/Translations/es/Klaro.xlf @@ -0,0 +1,107 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Información que recopilamos + + + Here you can see and customize the information that we collect about you. + + Aquí puede ver y personalizar la información que recopilamos sobre usted. + + + + privacy policy + política de privacidad + + + To learn more, please read our {privacyPolicy}. + + Para más información consulte nuestra {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Ha habido cambios desde su última visita, por favor, actualice su consentimiento. + + + We collect and process your personal information for the following purposes: {purposes}. + + Recopilamos y procesamos su información personal con los siguientes fines: {purposes}. + + + + Customize + Más información + + + privacy policy + política de privacidad + + + Imprint + Imprimir + + + Accept + Aceptar + + + Save + Guardar + + + Decline + Rechazar + + + Close + Cerrar + + + Toggle all apps + Habilitar/deshabilitar todas las aplicaciones + + + Use this switch to enable/disable all apps. + Use este botón para habilitar o deshabilitar todas las aplicaciones. + + + (opt-out) + (opt-out) + + + This app is loaded by default (but you can opt out) + Esta aplicación se carga de forma predeterminada (pero puede desactivarla) + + + (always required) + (necesaria) + + + This application is always required + Esta aplicación se necesita siempre + + + Purposes + Fines + + + Purpose + Fin + + + Powered by Klaro! + Powered by Klaro! + + + + diff --git a/Resources/Private/Translations/fi/Klaro.xlf b/Resources/Private/Translations/fi/Klaro.xlf new file mode 100644 index 0000000..54c85cb --- /dev/null +++ b/Resources/Private/Translations/fi/Klaro.xlf @@ -0,0 +1,103 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Keräämämme tiedot + + + Here you can see and customize the information that we collect about you. + + Voit tarkastella ja muokata sinusta keräämiämme tietoja. + + + + privacy policy + tietosuojasivultamme + + + To learn more, please read our {privacyPolicy}. + + Voit lukea lisätietoja {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Olemme tehneet muutoksia ehtoihin viime vierailusi jälkeen, tarkista ehdot. + + + We collect and process your personal information for the following purposes: {purposes}. + + Keräämme ja käsittelemme henkilötietoja seuraaviin tarkoituksiin: {purposes}. + + + + Customize + Lue lisää + + + privacy policy + tietosuojasivultamme + + + Accept + Hyväksy + + + Save + Tallenna + + + Decline + Hylkää + + + Close + Sulje + + + Toggle all apps + Valitse kaikki + + + Use this switch to enable/disable all apps. + Aktivoi kaikki päälle/pois. + + + (opt-out) + (ladataan oletuksena) + + + This app is loaded by default (but you can opt out) + Ladataan oletuksena (mutta voit ottaa sen pois päältä) + + + (always required) + (vaaditaan) + + + This application is always required + Sivusto vaatii tämän aina + + + Purposes + Käyttötarkoitukset + + + Purpose + Käyttötarkoitus + + + Powered by Klaro! + Palvelun tarjoaa Klaro! + + + + diff --git a/Resources/Private/Translations/fr/Klaro.xlf b/Resources/Private/Translations/fr/Klaro.xlf new file mode 100644 index 0000000..30c7a52 --- /dev/null +++ b/Resources/Private/Translations/fr/Klaro.xlf @@ -0,0 +1,115 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Les informations que nous collectons + + + Here you can see and customize the information that we collect about you. + + Ici, vous pouvez voir et personnaliser les informations que nous collectons sur vous. + + + + privacy policy + politique de confidentialité + + + To learn more, please read our {privacyPolicy}. + + Pour en savoir plus, merci de lire notre {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Des modifications ont eu lieu depuis votre dernière visite, merci de mettre à jour votre consentement. + + + We collect and process your personal information for the following purposes: {purposes}. + + Nous collectons et traitons vos informations personnelles dans le but suivant : {purposes}. + + + + Customize + En savoir plus + + + privacy policy + politique de confidentialité + + + Imprint + Imprimer + + + Accept + OK + + + Save + Sauvegarder + + + Decline + Refuser + + + Close + Fermer + + + Accept all + Tout accepter + + + Accept selected + Accepter la sélection + + + Toggle all apps + Changer toutes les options + + + Use this switch to enable/disable all apps. + Utiliser ce bouton pour activer/désactiver toutes les options + + + (opt-out) + (opt-out) + + + This app is loaded by default (but you can opt out) + Cette application est chargée par défaut (mais vous pouvez la désactiver) + + + (always required) + (toujours requis) + + + This application is always required + Cette application est toujours requise + + + Purposes + Utilisations + + + Purpose + Utilisation + + + Powered by Klaro! + Propulsé par Klaro! + + + + diff --git a/Resources/Private/Translations/hr/Klaro.xlf b/Resources/Private/Translations/hr/Klaro.xlf new file mode 100644 index 0000000..7f234f5 --- /dev/null +++ b/Resources/Private/Translations/hr/Klaro.xlf @@ -0,0 +1,103 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Informacije koje prikupljamo + + + Here you can see and customize the information that we collect about you. + + Ovdje možete vidjeti i podesiti informacije koje prikupljamo o Vama. + + + + privacy policy + pravila privatnosti + + + To learn more, please read our {privacyPolicy}. + + Za više informacije pročitajte naša {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Došlo je do promjena od Vaše posljednjeg posjećivanja web stranice, molimo Vas da ažurirate svoja odobrenja. + + + We collect and process your personal information for the following purposes: {purposes}. + + Mi prikupljamo i procesiramo Vaše osobne podatke radi slijedećeg: {purposes}. + + + + Customize + Saznajte više + + + privacy policy + pravila privatnosti + + + Accept + U redu + + + Save + Spremi + + + Decline + Odbij + + + Close + Zatvori + + + Toggle all apps + Izmeijeni sve + + + Use this switch to enable/disable all apps. + Koristite ovaj prekidač da omogućite/onemogućite sve aplikacije odjednom. + + + (opt-out) + (onemogućite) + + + This app is loaded by default (but you can opt out) + Ova aplikacija je učitana automatski (ali je možete onemogućiti) + + + (always required) + (obavezna) + + + This application is always required + Ova aplikacija je uvijek obavezna. + + + Purposes + Svrhe + + + Purpose + Svrha + + + Powered by Klaro! + Pokreće Klaro! + + + + diff --git a/Resources/Private/Translations/hu/Klaro.xlf b/Resources/Private/Translations/hu/Klaro.xlf new file mode 100644 index 0000000..7b86d2c --- /dev/null +++ b/Resources/Private/Translations/hu/Klaro.xlf @@ -0,0 +1,103 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Információk, amiket gyűjtünk + + + Here you can see and customize the information that we collect about you. + + Itt láthatod és testreszabhatod az rólad gyűjtött információkat. + + + + privacy policy + adatvédelmi irányelveinket + + + To learn more, please read our {privacyPolicy}. + + További információért kérjük, olvassd el az {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Az utolsó látogatás óta változások történtek, kérjük, frissítsd a hozzájárulásodat. + + + We collect and process your personal information for the following purposes: {purposes}. + + Az személyes adataidat összegyűjtjük és feldolgozzuk az alábbi célokra: {purposes}. + + + + Customize + Tudj meg többet + + + privacy policy + adatvédelmi irányelveinket + + + Accept + Elfogad + + + Save + Save + + + Decline + Mentés + + + Close + Elvet + + + Toggle all apps + Összes app átkapcsolása + + + Use this switch to enable/disable all apps. + Használd ezt a kapcsolót az összes alkalmazás engedélyezéséhez/letiltásához. + + + (opt-out) + (leiratkozás) + + + This app is loaded by default (but you can opt out) + Ez az alkalmazás alapértelmezés szerint betöltött (de ki lehet kapcsolni) + + + (always required) + (mindig kötelező) + + + This application is always required + Ez az alkalmazás mindig kötelező + + + Purposes + Célok + + + Purpose + Cél + + + Powered by Klaro! + Powered by Klaro! + + + + diff --git a/Resources/Private/Translations/it/Klaro.xlf b/Resources/Private/Translations/it/Klaro.xlf new file mode 100644 index 0000000..712ab4c --- /dev/null +++ b/Resources/Private/Translations/it/Klaro.xlf @@ -0,0 +1,107 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Informazioni che raccogliamo + + + Here you can see and customize the information that we collect about you. + + Qui puoi vedere e scegliere le informazioni che raccogliamo su di te. + + + + privacy policy + policy privacy + + + To learn more, please read our {privacyPolicy}. + + Per saperne di più, leggi la nostra {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Ci sono stati cambiamenti dalla tua ultima visita, aggiorna il tuo consenso. + + + We collect and process your personal information for the following purposes: {purposes}. + + Raccogliamo ed elaboriamo le vostre informazioni personali per i seguenti scopi: {purposes}. + + + + Customize + Scopri di più + + + privacy policy + policy privacy + + + Imprint + Impronta + + + Accept + OK + + + Save + Salva + + + Decline + Rifiuta + + + Close + Chiudi + + + Toggle all apps + Cambia per tutte le app + + + Use this switch to enable/disable all apps. + Usa questo interruttore per abilitare/disabilitare tutte le app. + + + (opt-out) + (opt-out) + + + This app is loaded by default (but you can opt out) + Quest'applicazione è caricata di default (ma puoi disattivarla) + + + (always required) + (sempre richiesto) + + + This application is always required + Quest'applicazione è sempre richiesta + + + Purposes + Scopi + + + Purpose + Scopo + + + Powered by Klaro! + Realizzato da Klaro! + + + + diff --git a/Resources/Private/Translations/nl/Klaro.xlf b/Resources/Private/Translations/nl/Klaro.xlf new file mode 100644 index 0000000..3b7b125 --- /dev/null +++ b/Resources/Private/Translations/nl/Klaro.xlf @@ -0,0 +1,107 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Informatie die we verzamelen + + + Here you can see and customize the information that we collect about you. + + Hier kunt u de informatie bekijken en aanpassen die we over u verzamelen. + + + + privacy policy + privacybeleid + + + To learn more, please read our {privacyPolicy}. + + Lees ons privacybeleid voor meer informatie {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Er waren wijzigingen sinds uw laatste bezoek, werk uw voorkeuren bij. + + + We collect and process your personal information for the following purposes: {purposes}. + + Wij verzamelen en verwerken uw persoonlijke gegevens voor de volgende doeleinden: {purposes}. + + + + Customize + Lees meer + + + privacy policy + privacybeleid + + + Imprint + Afdruk + + + Accept + OK + + + Save + Opslaan + + + Decline + Afwijzen + + + Close + Sluiten + + + Toggle all apps + Alle opties in/uit schakelen + + + Use this switch to enable/disable all apps. + Gebruik deze schakeloptie om alle apps in/uit te schakelen. + + + (opt-out) + (afmelden) + + + This app is loaded by default (but you can opt out) + Deze app is standaard geladen (maar je kunt je afmelden) + + + (always required) + (altijd verplicht) + + + This application is always required + Deze applicatie is altijd vereist + + + Purposes + Doeleinden + + + Purpose + Doeleinde + + + Powered by Klaro! + Aangedreven door Klaro! + + + + diff --git a/Resources/Private/Translations/no/Klaro.xlf b/Resources/Private/Translations/no/Klaro.xlf new file mode 100644 index 0000000..cdbefa9 --- /dev/null +++ b/Resources/Private/Translations/no/Klaro.xlf @@ -0,0 +1,107 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Informasjon vi samler inn + + + Here you can see and customize the information that we collect about you. + + Her kan du se og velge hvilken informasjon vi samler inn om deg. + + + + privacy policy + personvernerklæring + + + To learn more, please read our {privacyPolicy}. + + For å lære mer, vennligst les vår {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Det har skjedd endringer siden ditt siste besøk, vennligst oppdater ditt samtykke. + + + We collect and process your personal information for the following purposes: {purposes}. + + Vi samler inn og prosesserer din personlige informasjon av følgende årsaker: {purposes}. + + + + Customize + Lær mer + + + privacy policy + personvernerklæring + + + Accept + OK + + + Save + Opslaan + + + Decline + Avslå + + + Accept all + Godtar alle + + + Accept selected + Godtar valgt + + + Toggle all apps + Bytt alle apper + + + Use this switch to enable/disable all apps. + Bruk denne for å skru av/på alle apper. + + + (opt-out) + (opt-out) + + + This app is loaded by default (but you can opt out) + Denne appen er lastet som standard (men du kan skru det av) + + + (always required) + (alltid påkrevd) + + + This application is always required + Denne applikasjonen er alltid påkrevd + + + Purposes + Årsaker + + + Purpose + Årsak + + + Powered by Klaro! + Laget med Klaro! + + + + diff --git a/Resources/Private/Translations/pl/Klaro.xlf b/Resources/Private/Translations/pl/Klaro.xlf new file mode 100644 index 0000000..1012079 --- /dev/null +++ b/Resources/Private/Translations/pl/Klaro.xlf @@ -0,0 +1,107 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Informacje, które zbieramy + + + Here you can see and customize the information that we collect about you. + + Tutaj możesz zobaczyć i dostosować informacje, które zbieramy o Tobie. + + + + privacy policy + polityka prywatności + + + To learn more, please read our {privacyPolicy}. + + Aby dowiedzieć się więcej, przeczytaj naszą {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Nastąpiły zmiany od Twojej ostatniej wizyty, zaktualizuj swoją zgodę. + + + We collect and process your personal information for the following purposes: {purposes}. + + Zbieramy i przetwarzamy dane osobowe w następujących celach: {purposes}. + + + + Customize + Dowiedz się więcej + + + privacy policy + polityka prywatności + + + Imprint + Odcisk + + + Accept + OK + + + Save + Zapisz + + + Decline + Rezygnacja + + + Close + Zamknij + + + Toggle all apps + Przełącz dla wszystkich aplikacji + + + Use this switch to enable/disable all apps. + Użyj przełącznika, aby włączyć/wyłączyć wszystkie aplikacje. + + + (opt-out) + (rezygnacja) + + + This app is loaded by default (but you can opt out) + Ta aplikacja jest domyślnie ładowana (ale możesz zrezygnować) + + + (always required) + (zawsze wymagane) + + + This application is always required + Ta alikacja jest zawsze wymagana + + + Purposes + Cele + + + Purpose + Cel + + + Powered by Klaro! + Napędzany przez Klaro! + + + + diff --git a/Resources/Private/Translations/ro/Klaro.xlf b/Resources/Private/Translations/ro/Klaro.xlf new file mode 100644 index 0000000..e0e368d --- /dev/null +++ b/Resources/Private/Translations/ro/Klaro.xlf @@ -0,0 +1,99 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Informațiile pe care le colectăm + + + Here you can see and customize the information that we collect about you. + + Aici puteți vedea și personaliza informațiile pe care le colectăm despre dvs. + + + + privacy policy + politica privacy + + + To learn more, please read our {privacyPolicy}. + + Pentru a afla mai multe, vă rugăm să citiți {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Au existat modificări de la ultima vizită, vă rugăm să actualizați consimțământul. + + + We collect and process your personal information for the following purposes: {purposes}. + + Colectăm și procesăm informațiile dvs. personale în următoarele scopuri: {purposes}. + + + + Customize + Află mai multe + + + privacy policy + politica privacy + + + Accept + OK + + + Save + Salvează + + + Decline + Renunță + + + Toggle all apps + Comutați între toate aplicațiile + + + Use this switch to enable/disable all apps. + Utilizați acest switch pentru a activa/dezactiva toate aplicațiile. + + + (opt-out) + (opt-out) + + + This app is loaded by default (but you can opt out) + Această aplicație este încărcată în mod implicit (dar puteți renunța) + + + (always required) + (întotdeauna necesar) + + + This application is always required + Această aplicație este întotdeauna necesară + + + Purposes + Scopuri + + + Purpose + Scop + + + Powered by Klaro! + Realizat de Klaro! + + + + diff --git a/Resources/Private/Translations/ru/Klaro.xlf b/Resources/Private/Translations/ru/Klaro.xlf new file mode 100644 index 0000000..195bff3 --- /dev/null +++ b/Resources/Private/Translations/ru/Klaro.xlf @@ -0,0 +1,111 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Информация, которую мы сохраняем + + + Here you can see and customize the information that we collect about you. + + Здесь вы можете просмотреть и настроить, какую информацию о вас мы храним. + + + + privacy policy + Соглашение + + + To learn more, please read our {privacyPolicy}. + + Чтобы узнать больше, пожалуйста, прочитайте наше {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Со времени вашего последнего визита произошли изменения, обновите своё согласие. + + + We collect and process your personal information for the following purposes: {purposes}. + + Мы собираем и обрабатываем вашу личную информацию для следующих целей: {purposes}. + + + + Customize + Настроить + + + privacy policy + политика конфиденциальности + + + Accept + Принять + + + Save + Сохранить + + + Decline + Отклонить + + + Close + Закрыть + + + Accept all + Принять всё + + + Accept selected + Принять выбранные + + + Toggle all apps + Переключить все приложения + + + Use this switch to enable/disable all apps. + Используйте этот переключатель, чтобы включить/отключить все приложения. + + + (opt-out) + (отказаться) + + + This app is loaded by default (but you can opt out) + Это приложение включено по умолчанию (но вы можете отказаться) + + + (always required) + (всегда обязательный) + + + This application is always required + Это обязательное приложение + + + Purposes + Намерения + + + Purpose + Намерение + + + Powered by Klaro! + Работает на Кларо! + + + + diff --git a/Resources/Private/Translations/sr/Klaro.xlf b/Resources/Private/Translations/sr/Klaro.xlf new file mode 100644 index 0000000..c17330d --- /dev/null +++ b/Resources/Private/Translations/sr/Klaro.xlf @@ -0,0 +1,103 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Informacije koje prikupljamo + + + Here you can see and customize the information that we collect about you. + + Ovde možete videti i podesiti informacije koje prikupljamo o Vama. + + + + privacy policy + politiku privatnosti + + + To learn more, please read our {privacyPolicy}. + + Za više informacije pročitajte našu {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Došlo je do promena od Vaše poslednje posete, molimo Vas da ažurirate svoja odobrenja. + + + We collect and process your personal information for the following purposes: {purposes}. + + Mi prikupljamo i procesiramo Vaše lične podatke radi sledećeg: {purposes}. + + + + Customize + Saznajte više + + + privacy policy + politiku privatnosti + + + Accept + U redu + + + Save + Sačuvaj + + + Decline + Odbij + + + Close + Zatvori + + + Toggle all apps + Izmeni sve + + + Use this switch to enable/disable all apps. + Koristite ovaj prekidač da omogućite/onesposobite sve aplikacije odjednom. + + + (opt-out) + (onesposobite) + + + This app is loaded by default (but you can opt out) + Ova aplikacija je učitana automatski (ali je možete onesposobiti) + + + (always required) + (neophodna) + + + This application is always required + Ova aplikacija je uvek neophodna. + + + Purposes + Svrhe + + + Purpose + Svrha + + + Powered by Klaro! + Pokreće Klaro! + + + + diff --git a/Resources/Private/Translations/sr_cyrl/Klaro.xlf b/Resources/Private/Translations/sr_cyrl/Klaro.xlf new file mode 100644 index 0000000..c492a07 --- /dev/null +++ b/Resources/Private/Translations/sr_cyrl/Klaro.xlf @@ -0,0 +1,103 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Информације које прикупљамо + + + Here you can see and customize the information that we collect about you. + + Овде можете видет и подесити информације које прикупљамо о Вама. + + + + privacy policy + политику приватности + + + To learn more, please read our {privacyPolicy}. + + За више информација прочитајте нашу {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Дошло је до промена од Ваше последнје посете, молимо Вас да ажурирате своја одобрења. + + + We collect and process your personal information for the following purposes: {purposes}. + + Ми прикупљамо и процесирамо Ваше личне податке ради следећег: {purposes}. + + + + Customize + Сазнајте више + + + privacy policy + политику приватности + + + Accept + У реду + + + Save + Сачувај + + + Decline + Одбиј + + + Close + Затвори + + + Toggle all apps + Измени све + + + Use this switch to enable/disable all apps. + Користите овај прекидач да омогућите/онеспособите све апликације одједном. + + + (opt-out) + (онеспособите) + + + This app is loaded by default (but you can opt out) + Ова апликација је учитана аутоматски (али је можете онеспособити) + + + (always required) + (неопходна) + + + This application is always required + Ова апликација је увек неопходна. + + + Purposes + Сврхе + + + Purpose + Сврха + + + Powered by Klaro! + Покреће Кларо! + + + + diff --git a/Resources/Private/Translations/sv/Klaro.xlf b/Resources/Private/Translations/sv/Klaro.xlf new file mode 100644 index 0000000..83842b7 --- /dev/null +++ b/Resources/Private/Translations/sv/Klaro.xlf @@ -0,0 +1,111 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Information som vi samlar + + + Here you can see and customize the information that we collect about you. + + Här kan du se och anpassa vilken information vi samlar om dig. + + + + privacy policy + Integritetspolicy + + + To learn more, please read our {privacyPolicy}. + + För att veta mer, läs vår {privacyPolicy}. + + + + There were changes since your last visit, please update your consent. + Det har skett förändringar sedan ditt senaste besök, var god uppdatera ditt medgivande. + + + We collect and process your personal information for the following purposes: {purposes}. + + Vi samlar och bearbetar din personliga data i följande syften: {purposes}. + + + + Customize + Läs mer + + + privacy policy + Integritetspolicy + + + Accept + OK + + + Save + Spara + + + Decline + Avböj + + + Accept all + Acceptera alla + + + Accept selected + Acceptera markerat + + + Close + Stäng + + + Toggle all apps + Ändra för alla appar + + + Use this switch to enable/disable all apps. + Använd detta reglage för att aktivera/avaktivera samtliga appar. + + + (opt-out) + (Avaktivera) + + + This app is loaded by default (but you can opt out) + Den här appen laddas som standardinställning (men du kan avaktivera den) + + + (always required) + (Krävs alltid) + + + This application is always required + Den här applikationen krävs alltid + + + Purposes + Syften + + + Purpose + Syfte + + + Powered by Klaro! + Körs på Klaro! + + + + diff --git a/Resources/Private/Translations/tr/Klaro.xlf b/Resources/Private/Translations/tr/Klaro.xlf new file mode 100644 index 0000000..7454988 --- /dev/null +++ b/Resources/Private/Translations/tr/Klaro.xlf @@ -0,0 +1,103 @@ + + + + + ################################################################################################ + # IMPORTANT: This file was auto-generated as part of the build process to convert translations # + # provided by klaro. -> see package.json -> "yarn run build:translations" # + ################################################################################################ + + + + Information that we collect + Sakladığımız bilgiler + + + Here you can see and customize the information that we collect about you. + + Hakkınızda topladığımız bilgileri burada görebilir ve özelleştirebilirsiniz. + + + + privacy policy + Gizlilik Politikası + + + To learn more, please read our {privacyPolicy}. + + Daha fazlası için lütfen {privacyPolicy} sayfamızı okuyun. + + + + There were changes since your last visit, please update your consent. + Son ziyaretinizden bu yana değişiklikler oldu, lütfen seçiminizi güncelleyin. + + + We collect and process your personal information for the following purposes: {purposes}. + + Kişisel bilgilerinizi aşağıdaki amaçlarla saklıyor ve işliyoruz: {purposes}. + + + + Customize + Daha fazla bilgi + + + privacy policy + Gizlilik Politikası + + + Accept + Tamam + + + Save + Kaydet + + + Decline + Reddet + + + Close + Kapat + + + Toggle all apps + Tüm uygulamaları aç/kapat + + + Use this switch to enable/disable all apps. + Toplu açma/kapama için bu düğmeyi kullanabilirsin. + + + (opt-out) + (isteğe bağlı) + + + This app is loaded by default (but you can opt out) + Bu uygulama varsayılanda yüklendi (ancak iptal edebilirsin) + + + (always required) + (her zaman gerekli) + + + This application is always required + Bu uygulama her zaman gerekli + + + Purposes + Amaçlar + + + Purpose + Amaç + + + Powered by Klaro! + Klaro tarafından geliştirildi! + + + + diff --git a/Resources/Public/Klaro/klaro-no-css_v0.4.27.js b/Resources/Public/Klaro/klaro-no-css_v0.4.27.js new file mode 100644 index 0000000..e81f2d3 --- /dev/null +++ b/Resources/Public/Klaro/klaro-no-css_v0.4.27.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.klaro=t():e.klaro=t()}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=167)}([function(e,t,n){var r=n(3),o=n(24).f,i=n(11),a=n(16),c=n(58),s=n(81),u=n(62);e.exports=function(e,t){var n,l,p,f,d,v=e.target,y=e.global,h=e.stat;if(n=y?r:h?r[v]||c(v,{}):(r[v]||{}).prototype)for(l in t){if(f=t[l],p=e.noTargetGet?(d=o(n,l))&&d.value:n[l],!u(y?l:v+(h?".":"#")+l,e.forced)&&void 0!==p){if(typeof f==typeof p)continue;s(f,p)}(e.sham||p&&p.sham)&&i(f,"sham",!0),a(n,l,f,e)}}},function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t,n){var r=n(3),o=n(59),i=n(7),a=n(40),c=n(63),s=n(88),u=o("wks"),l=r.Symbol,p=s?l:l&&l.withoutSetter||a;e.exports=function(e){return i(u,e)||(c&&i(l,e)?u[e]=l[e]:u[e]=p("Symbol."+e)),u[e]}},function(e,t,n){(function(t){var n=function(e){return e&&e.Math==Math&&e};e.exports=n("object"==typeof globalThis&&globalThis)||n("object"==typeof window&&window)||n("object"==typeof self&&self)||n("object"==typeof t&&t)||Function("return this")()}).call(this,n(139))},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t,n){var r=n(1);e.exports=!r((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},function(e,t,n){var r=n(4);e.exports=function(e){if(!r(e))throw TypeError(String(e)+" is not an object");return e}},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){var r=n(5),o=n(77),i=n(6),a=n(38),c=Object.defineProperty;t.f=r?c:function(e,t,n){if(i(e),t=a(t,!0),i(n),o)try{return c(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported");return"value"in n&&(e[t]=n.value),e}},function(e,t,n){"use strict";var r=n(10),o=n(91),i=n(32),a=n(25),c=n(64),s=a.set,u=a.getterFor("Array Iterator");e.exports=c(Array,"Array",(function(e,t){s(this,{type:"Array Iterator",target:r(e),index:0,kind:t})}),(function(){var e=u(this),t=e.target,n=e.kind,r=e.index++;return!t||r>=t.length?(e.target=void 0,{value:void 0,done:!0}):"keys"==n?{value:r,done:!1}:"values"==n?{value:t[r],done:!1}:{value:[r,t[r]],done:!1}}),"values"),i.Arguments=i.Array,o("keys"),o("values"),o("entries")},function(e,t,n){var r=n(37),o=n(19);e.exports=function(e){return r(o(e))}},function(e,t,n){var r=n(5),o=n(8),i=n(27);e.exports=r?function(e,t,n){return o.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){var r=n(42),o=Math.min;e.exports=function(e){return e>0?o(r(e),9007199254740991):0}},function(e,t,n){var r=n(68),o=n(16),i=n(147);r||o(Object.prototype,"toString",i,{unsafe:!0})},function(e,t,n){"use strict";var r=n(106).charAt,o=n(25),i=n(64),a=o.set,c=o.getterFor("String Iterator");i(String,"String",(function(e){a(this,{type:"String Iterator",string:String(e),index:0})}),(function(){var e,t=c(this),n=t.string,o=t.index;return o>=n.length?{value:void 0,done:!0}:(e=r(n,o),t.index+=e.length,{value:e,done:!1})}))},function(e,t,n){var r=n(3),o=n(107),i=n(9),a=n(11),c=n(2),s=c("iterator"),u=c("toStringTag"),l=i.values;for(var p in o){var f=r[p],d=f&&f.prototype;if(d){if(d[s]!==l)try{a(d,s,l)}catch(e){d[s]=l}if(d[u]||a(d,u,p),o[p])for(var v in i)if(d[v]!==i[v])try{a(d,v,i[v])}catch(e){d[v]=i[v]}}}},function(e,t,n){var r=n(3),o=n(11),i=n(7),a=n(58),c=n(79),s=n(25),u=s.get,l=s.enforce,p=String(String).split("String");(e.exports=function(e,t,n,c){var s=!!c&&!!c.unsafe,u=!!c&&!!c.enumerable,f=!!c&&!!c.noTargetGet;"function"==typeof n&&("string"!=typeof t||i(n,"name")||o(n,"name",t),l(n).source=p.join("string"==typeof t?t:"")),e!==r?(s?!f&&e[t]&&(u=!0):delete e[t],u?e[t]=n:o(e,t,n)):u?e[t]=n:a(t,n)})(Function.prototype,"toString",(function(){return"function"==typeof this&&u(this).source||c(this)}))},function(e,t,n){var r=n(19);e.exports=function(e){return Object(r(e))}},function(e,t,n){"use strict";var r=n(16),o=n(6),i=n(1),a=n(69),c=RegExp.prototype,s=c.toString,u=i((function(){return"/a/b"!=s.call({source:"a",flags:"b"})})),l="toString"!=s.name;(u||l)&&r(RegExp.prototype,"toString",(function(){var e=o(this),t=String(e.source),n=e.flags;return"/"+t+"/"+String(void 0===n&&e instanceof RegExp&&!("flags"in c)?a.call(e):n)}),{unsafe:!0})},function(e,t){e.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){"use strict";var r=n(0),o=n(3),i=n(26),a=n(29),c=n(5),s=n(63),u=n(88),l=n(1),p=n(7),f=n(43),d=n(4),v=n(6),y=n(17),h=n(10),m=n(38),g=n(27),b=n(31),_=n(46),k=n(41),w=n(149),x=n(61),S=n(24),j=n(8),O=n(57),A=n(11),P=n(16),E=n(59),C=n(39),z=n(30),T=n(40),D=n(2),R=n(108),N=n(109),I=n(47),M=n(25),L=n(51).forEach,U=C("hidden"),q=D("toPrimitive"),F=M.set,H=M.getterFor("Symbol"),B=Object.prototype,K=o.Symbol,W=i("JSON","stringify"),$=S.f,V=j.f,G=w.f,Z=O.f,Q=E("symbols"),Y=E("op-symbols"),J=E("string-to-symbol-registry"),X=E("symbol-to-string-registry"),ee=E("wks"),te=o.QObject,ne=!te||!te.prototype||!te.prototype.findChild,re=c&&l((function(){return 7!=b(V({},"a",{get:function(){return V(this,"a",{value:7}).a}})).a}))?function(e,t,n){var r=$(B,t);r&&delete B[t],V(e,t,n),r&&e!==B&&V(B,t,r)}:V,oe=function(e,t){var n=Q[e]=b(K.prototype);return F(n,{type:"Symbol",tag:e,description:t}),c||(n.description=t),n},ie=u?function(e){return"symbol"==typeof e}:function(e){return Object(e)instanceof K},ae=function(e,t,n){e===B&&ae(Y,t,n),v(e);var r=m(t,!0);return v(n),p(Q,r)?(n.enumerable?(p(e,U)&&e[U][r]&&(e[U][r]=!1),n=b(n,{enumerable:g(0,!1)})):(p(e,U)||V(e,U,g(1,{})),e[U][r]=!0),re(e,r,n)):V(e,r,n)},ce=function(e,t){v(e);var n=h(t),r=_(n).concat(pe(n));return L(r,(function(t){c&&!se.call(n,t)||ae(e,t,n[t])})),e},se=function(e){var t=m(e,!0),n=Z.call(this,t);return!(this===B&&p(Q,t)&&!p(Y,t))&&(!(n||!p(this,t)||!p(Q,t)||p(this,U)&&this[U][t])||n)},ue=function(e,t){var n=h(e),r=m(t,!0);if(n!==B||!p(Q,r)||p(Y,r)){var o=$(n,r);return!o||!p(Q,r)||p(n,U)&&n[U][r]||(o.enumerable=!0),o}},le=function(e){var t=G(h(e)),n=[];return L(t,(function(e){p(Q,e)||p(z,e)||n.push(e)})),n},pe=function(e){var t=e===B,n=G(t?Y:h(e)),r=[];return L(n,(function(e){!p(Q,e)||t&&!p(B,e)||r.push(Q[e])})),r};(s||(P((K=function(){if(this instanceof K)throw TypeError("Symbol is not a constructor");var e=arguments.length&&void 0!==arguments[0]?String(arguments[0]):void 0,t=T(e),n=function(e){this===B&&n.call(Y,e),p(this,U)&&p(this[U],t)&&(this[U][t]=!1),re(this,t,g(1,e))};return c&&ne&&re(B,t,{configurable:!0,set:n}),oe(t,e)}).prototype,"toString",(function(){return H(this).tag})),P(K,"withoutSetter",(function(e){return oe(T(e),e)})),O.f=se,j.f=ae,S.f=ue,k.f=w.f=le,x.f=pe,R.f=function(e){return oe(D(e),e)},c&&(V(K.prototype,"description",{configurable:!0,get:function(){return H(this).description}}),a||P(B,"propertyIsEnumerable",se,{unsafe:!0}))),r({global:!0,wrap:!0,forced:!s,sham:!s},{Symbol:K}),L(_(ee),(function(e){N(e)})),r({target:"Symbol",stat:!0,forced:!s},{for:function(e){var t=String(e);if(p(J,t))return J[t];var n=K(t);return J[t]=n,X[n]=t,n},keyFor:function(e){if(!ie(e))throw TypeError(e+" is not a symbol");if(p(X,e))return X[e]},useSetter:function(){ne=!0},useSimple:function(){ne=!1}}),r({target:"Object",stat:!0,forced:!s,sham:!c},{create:function(e,t){return void 0===t?b(e):ce(b(e),t)},defineProperty:ae,defineProperties:ce,getOwnPropertyDescriptor:ue}),r({target:"Object",stat:!0,forced:!s},{getOwnPropertyNames:le,getOwnPropertySymbols:pe}),r({target:"Object",stat:!0,forced:l((function(){x.f(1)}))},{getOwnPropertySymbols:function(e){return x.f(y(e))}}),W)&&r({target:"JSON",stat:!0,forced:!s||l((function(){var e=K();return"[null]"!=W([e])||"{}"!=W({a:e})||"{}"!=W(Object(e))}))},{stringify:function(e,t,n){for(var r,o=[e],i=1;arguments.length>i;)o.push(arguments[i++]);if(r=t,(d(t)||void 0!==e)&&!ie(e))return f(t)||(t=function(e,t){if("function"==typeof r&&(t=r.call(this,e,t)),!ie(t))return t}),o[1]=t,W.apply(null,o)}});K.prototype[q]||A(K.prototype,q,K.prototype.valueOf),I(K,"Symbol"),z[U]=!0},function(e,t,n){"use strict";var r=n(0),o=n(5),i=n(3),a=n(7),c=n(4),s=n(8).f,u=n(81),l=i.Symbol;if(o&&"function"==typeof l&&(!("description"in l.prototype)||void 0!==l().description)){var p={},f=function(){var e=arguments.length<1||void 0===arguments[0]?void 0:String(arguments[0]),t=this instanceof f?new l(e):void 0===e?l():l(e);return""===e&&(p[t]=!0),t};u(f,l);var d=f.prototype=l.prototype;d.constructor=f;var v=d.toString,y="Symbol(test)"==String(l("test")),h=/^Symbol\((.*)\)[^)]+$/;s(d,"description",{configurable:!0,get:function(){var e=c(this)?this.valueOf():this,t=v.call(e);if(a(p,e))return"";var n=y?t.slice(7,-1):t.replace(h,"$1");return""===n?void 0:n}}),r({global:!0,forced:!0},{Symbol:f})}},function(e,t,n){n(109)("iterator")},function(e,t,n){var r=n(5),o=n(8).f,i=Function.prototype,a=i.toString,c=/^\s*function ([^ (]*)/;r&&!("name"in i)&&o(i,"name",{configurable:!0,get:function(){try{return a.call(this).match(c)[1]}catch(e){return""}}})},function(e,t,n){var r=n(5),o=n(57),i=n(27),a=n(10),c=n(38),s=n(7),u=n(77),l=Object.getOwnPropertyDescriptor;t.f=r?l:function(e,t){if(e=a(e),t=c(t,!0),u)try{return l(e,t)}catch(e){}if(s(e,t))return i(!o.f.call(e,t),e[t])}},function(e,t,n){var r,o,i,a=n(140),c=n(3),s=n(4),u=n(11),l=n(7),p=n(39),f=n(30),d=c.WeakMap;if(a){var v=new d,y=v.get,h=v.has,m=v.set;r=function(e,t){return m.call(v,e,t),t},o=function(e){return y.call(v,e)||{}},i=function(e){return h.call(v,e)}}else{var g=p("state");f[g]=!0,r=function(e,t){return u(e,g,t),t},o=function(e){return l(e,g)?e[g]:{}},i=function(e){return l(e,g)}}e.exports={set:r,get:o,has:i,enforce:function(e){return i(e)?o(e):r(e,{})},getterFor:function(e){return function(t){var n;if(!s(t)||(n=o(t)).type!==e)throw TypeError("Incompatible receiver, "+e+" required");return n}}}},function(e,t,n){var r=n(83),o=n(3),i=function(e){return"function"==typeof e?e:void 0};e.exports=function(e,t){return arguments.length<2?i(r[e])||i(o[e]):r[e]&&r[e][t]||o[e]&&o[e][t]}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},function(e,t){e.exports=!1},function(e,t){e.exports={}},function(e,t,n){var r,o=n(6),i=n(141),a=n(60),c=n(30),s=n(142),u=n(78),l=n(39),p=l("IE_PROTO"),f=function(){},d=function(e){return"'; + $expected = + ''; + $actual = $blockExternalContentHelper->blockScripts($markup); + self::assertEquals($expected, $actual); + + // selfclosing + $markup = ''; + $expected = + ''; + $actual = $blockExternalContentHelper->blockScripts($markup); + self::assertEquals($expected, $actual); + + // ### '; + $expected = + ''; + $actual = $blockExternalContentHelper->blockScripts($markup); + self::assertEquals($expected, $actual); + + // ### '; + $expected = + ''; + $actual = $blockExternalContentHelper->blockScripts($markup); + self::assertEquals($expected, $actual); + + // selfclosing + $markup = ''; + $expected = + ''; + $actual = $blockExternalContentHelper->blockScripts($markup); + self::assertEquals($expected, $actual); + + $markup = + ''; + $expected = + ''; + $actual = $blockExternalContentHelper->blockIframes($markup); + self::assertEquals($expected, $actual); + } + + /** + * @test + */ + public function tagsWillUseGroupFromEelHelperAndNotSettings() + { + $blockExternalContentHelper = new CookieCutter(); + ObjectAccess::setProperty( + $blockExternalContentHelper, + CookieCutter::SETTINGS_BLOCK_ALL, + true, + true + ); + + $markup = ''; + $expected = ''; + $actual = $blockExternalContentHelper->blockScripts( + $markup, + true, + "foo" + ); + self::assertEquals($expected, $actual); + + $markup = ''; + $expected = + ''; + $actual = $blockExternalContentHelper->blockIframes( + $markup, + true, + "bar" + ); + self::assertEquals($expected, $actual); + } + + /** + * @test + */ + public function strangeScriptTagsWillNeverBeBlocked() + { + $blockExternalContentHelper = new CookieCutter(); + ObjectAccess::setProperty( + $blockExternalContentHelper, + CookieCutter::SETTINGS_BLOCK_ALL, + true, + true + ); + + // Do nothing -> keep the type as it is not "text/javascript" + + $markup = ''; + $expected = ''; + $actual = $blockExternalContentHelper->blockScripts($markup); + self::assertEquals($expected, $actual); + } + + /** + * @test + */ + public function alreadyBlockedScriptTagsWillNeverBeBlocked() + { + $blockExternalContentHelper = new CookieCutter(); + ObjectAccess::setProperty( + $blockExternalContentHelper, + CookieCutter::SETTINGS_BLOCK_ALL, + true, + true + ); + + $markup = + ''; + $actual = $blockExternalContentHelper->blockScripts($markup); + self::assertEquals($markup, $actual); + + $markup = + ''; + $actual = $blockExternalContentHelper->blockScripts($markup); + self::assertEquals($markup, $actual); + } + + /** + * @test + */ + public function markedTagsWillNeverBeBlocked() + { + $blockExternalContentHelper = new CookieCutter(); + + ObjectAccess::setProperty( + $blockExternalContentHelper, + CookieCutter::SETTINGS_BLOCK_ALL, + true, + true + ); + + $markup = ''; + $actualWithDataAttribute = $blockExternalContentHelper->neverBlockScripts( + $markup + ); + $actualNotBlocked = $blockExternalContentHelper->neverBlockScripts( + $actualWithDataAttribute + ); + $expected = ''; + + self::assertEquals($expected, $actualWithDataAttribute); + self::assertEquals($expected, $actualNotBlocked); + + $markup = ''; + $expected = + ''; + $actual = $blockExternalContentHelper->blockIframes($markup); + + self::assertEquals($expected, $actual); + + $markup = '